claude-presentation-master 2.1.2 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,276 +1,249 @@
1
- import PptxGenJS from 'pptxgenjs';
2
-
3
1
  /**
4
2
  * Claude Presentation Master - Type Definitions
5
- * @module types
6
- */
7
- /**
8
- * Legacy presentation mode (for backwards compatibility)
9
- * @deprecated Use PresentationType for granular control
3
+ *
4
+ * Clean rewrite: All types for KB-driven presentation generation.
5
+ * Every decision comes from the Knowledge Base - no hardcoded fallbacks.
10
6
  */
11
- type PresentationMode = 'keynote' | 'business';
12
7
  /**
13
- * Granular presentation types with distinct validation rules.
14
- * Each type is a "swim lane" with its own word limits, expert methodologies,
15
- * and scoring weights. These are mutually exclusive.
8
+ * The 7 distinct presentation types, each with its own validation rules.
9
+ * These come from KB path: presentation_types.<type>
16
10
  */
17
11
  type PresentationType = 'ted_keynote' | 'sales_pitch' | 'consulting_deck' | 'investment_banking' | 'investor_pitch' | 'technical_presentation' | 'all_hands';
18
- type OutputFormat = 'html' | 'pptx';
19
- type ThemeName = 'default' | 'light-corporate' | 'modern-tech' | 'minimal' | 'warm' | 'creative';
20
- interface PresentationConfig {
21
- /** Input content (Markdown, JSON, YAML, or plain text) */
22
- content: string;
23
- /** Content format */
24
- contentType: 'markdown' | 'json' | 'yaml' | 'text';
25
- /**
26
- * Legacy presentation mode (backwards compatible)
27
- * @deprecated Use `presentationType` for granular control
28
- */
29
- mode: PresentationMode;
30
- /**
31
- * Granular presentation type with distinct validation rules.
32
- * If specified, this overrides `mode` for validation purposes.
33
- */
34
- presentationType?: PresentationType;
35
- /** Target audience (used for auto-detecting presentation type) */
36
- audience?: 'board_of_directors' | 'sales_prospect' | 'investors_vcs' | 'general_audience_keynote' | 'technical_team' | 'all_hands_meeting';
37
- /** Presentation goal (used for auto-detecting presentation type) */
38
- goal?: 'get_approval' | 'inform_educate' | 'persuade_sell' | 'inspire_motivate' | 'report_results' | 'raise_funding';
39
- /** Output formats to generate */
40
- format: OutputFormat[];
41
- /** Visual theme */
42
- theme?: ThemeName;
43
- /** Minimum QA score required (0-100, default: 95) */
44
- qaThreshold?: number;
45
- /** Skip QA validation (NOT RECOMMENDED) */
46
- skipQA?: boolean;
47
- /** Presentation title */
48
- title: string;
49
- /** Author name */
50
- author?: string;
51
- /** Subject/description */
52
- subject?: string;
53
- /** Output directory */
54
- output?: string;
55
- /** Minify HTML output */
56
- minify?: boolean;
57
- /** Custom CSS to inject */
58
- customCSS?: string;
59
- /** Custom Handlebars templates */
60
- customTemplates?: Record<string, string>;
61
- }
62
12
  /**
63
- * Validation rules specific to a presentation type.
64
- * Loaded from the knowledge base.
13
+ * Legacy mode for backwards compatibility
65
14
  */
66
- interface PresentationTypeRules {
67
- id: PresentationType;
68
- name: string;
69
- description: string;
70
- wordsPerSlide: {
71
- min: number;
72
- max: number;
73
- ideal: number;
74
- };
75
- whitespace: {
76
- min: number;
77
- ideal: number;
78
- max?: number;
79
- };
80
- bulletsPerSlide: {
81
- max: number;
82
- };
83
- actionTitlesRequired: boolean;
84
- sourcesRequired: boolean;
85
- scoringWeights: {
86
- visual_quality: number;
87
- content_quality: number;
88
- expert_compliance: number;
89
- accessibility: number;
90
- };
91
- }
92
- type SlideType = 'title' | 'agenda' | 'section-divider' | 'thank-you' | 'big-idea' | 'single-statement' | 'big-number' | 'full-image' | 'quote' | 'two-column' | 'three-column' | 'bullet-points' | 'screenshot' | 'screenshot-left' | 'screenshot-right' | 'comparison' | 'timeline' | 'process' | 'metrics-grid' | 'pricing' | 'team' | 'features' | 'chart' | 'table' | 'social-proof' | 'case-study' | 'cta';
15
+ type PresentationMode = 'keynote' | 'business';
16
+ type OutputFormat = 'html' | 'pptx';
17
+ type SlideType = 'title' | 'title_impact' | 'agenda' | 'section_divider' | 'thank_you' | 'single_statement' | 'big_idea' | 'big_number' | 'full_image' | 'quote' | 'star_moment' | 'call_to_action' | 'three_points' | 'bullet_points' | 'two_column' | 'three_column' | 'comparison' | 'timeline' | 'process' | 'metrics_grid' | 'data_insight' | 'problem_statement' | 'solution_overview' | 'social_proof' | 'testimonial' | 'pricing' | 'demo_screenshot' | 'executive_summary_scr' | 'mece_breakdown' | 'recommendation' | 'risks_mitigation' | 'next_steps' | 'credentials' | 'valuation_summary' | 'football_field' | 'comparable_companies' | 'precedent_transactions' | 'dcf_summary' | 'waterfall_bridge' | 'sources_uses' | 'situation_overview' | 'risk_factors' | 'process_timeline';
93
18
  interface Slide {
94
19
  /** Slide index (0-based) */
95
20
  index: number;
96
- /** Slide type */
21
+ /** Slide type from KB */
97
22
  type: SlideType;
98
- /** Slide data for template rendering */
23
+ /** Slide content */
99
24
  data: SlideData;
100
- /** CSS classes to apply */
101
- classes?: string[];
102
- /** Custom styles */
103
- styles?: Record<string, string>;
25
+ /** Slide-level score (must be >= 95) */
26
+ score?: SlideScore;
104
27
  /** Speaker notes */
105
28
  notes?: string;
106
29
  }
107
30
  interface SlideData {
108
- /** Main title */
31
+ /** Main title (action title for consulting, emotional for keynote) */
109
32
  title?: string;
110
33
  /** Subtitle */
111
34
  subtitle?: string;
112
- /** Body content */
35
+ /** Body text */
113
36
  body?: string;
114
37
  /** Bullet points */
115
38
  bullets?: string[];
116
- /** Key message */
39
+ /** Key message / takeaway */
117
40
  keyMessage?: string;
118
- /** Images */
119
- images?: ImageData[];
120
- /** Metrics/KPIs */
121
- metrics?: MetricData[];
122
41
  /** Quote text */
123
42
  quote?: string;
124
43
  /** Quote attribution */
125
44
  attribution?: string;
126
- /** Source citation */
45
+ /** Metrics for metrics_grid */
46
+ metrics?: MetricData[];
47
+ /** Source citation (required for consulting/IB) */
127
48
  source?: string;
49
+ /** Callout text (for data slides) */
50
+ callout?: string;
51
+ /** Background image path (local file or URL) */
52
+ image?: string;
128
53
  /** Additional custom data */
129
54
  [key: string]: unknown;
130
55
  }
131
- interface ImageData {
132
- src: string;
133
- alt: string;
134
- caption?: string;
135
- }
136
56
  interface MetricData {
137
57
  value: string | number;
138
58
  label: string;
139
59
  change?: string;
140
60
  trend?: 'up' | 'down' | 'neutral';
141
61
  }
142
- interface QAResults {
143
- /** Visual quality results */
144
- visual: VisualQAResults;
145
- /** Content quality results */
146
- content: ContentQAResults;
147
- /** Expert methodology compliance */
148
- expert: ExpertQAResults;
149
- /** Accessibility compliance */
150
- accessibility: AccessibilityResults;
151
- /** Overall pass/fail */
62
+ interface SlideScore {
63
+ /** Total score (0-100) - must be >= 95 */
64
+ total: number;
65
+ /** Visual quality score (weighted per type) */
66
+ visual: CategoryScore;
67
+ /** Content quality score (weighted per type) */
68
+ content: CategoryScore;
69
+ /** Expert compliance score (weighted per type) */
70
+ expert: CategoryScore;
71
+ /** Accessibility score (weighted per type) */
72
+ accessibility: CategoryScore;
73
+ /** Did this slide pass? */
152
74
  passed: boolean;
153
- /** List of issues found */
154
- issues: QAIssue[];
75
+ /** Specific violations found */
76
+ violations: Violation[];
155
77
  }
156
- interface VisualQAResults {
157
- /** Whitespace percentage (target: 35%+ keynote, 25%+ business) */
158
- whitespacePercentage: number;
159
- /** Layout balance score (0-1) */
160
- layoutBalance: number;
161
- /** Contrast ratio (target: 4.5+) */
162
- contrastRatio: number;
163
- /** Number of font families used (target: ≤2) */
164
- fontFamilies: number;
165
- /** Number of colors used */
166
- colorCount: number;
167
- /** Screenshots of each slide */
168
- screenshots: Buffer[];
169
- /** Per-slide visual scores */
170
- perSlide: SlideVisualScore[];
171
- }
172
- interface SlideVisualScore {
173
- slideIndex: number;
174
- whitespace: number;
175
- balance: number;
176
- contrast: number;
78
+ interface CategoryScore {
79
+ /** Raw score (0-100) */
80
+ score: number;
81
+ /** Weight for this category (from KB) */
82
+ weight: number;
83
+ /** Weighted contribution to total */
84
+ weighted: number;
85
+ /** Checks that passed */
86
+ passed: string[];
87
+ /** Checks that failed */
88
+ failed: string[];
89
+ }
90
+ interface Violation {
91
+ /** Severity level */
92
+ severity: 'critical' | 'major' | 'minor';
93
+ /** Category */
94
+ category: 'visual' | 'content' | 'expert' | 'accessibility';
95
+ /** KB path that was violated */
96
+ kbPath: string;
97
+ /** What was expected (from KB) */
98
+ expected: string;
99
+ /** What was found */
100
+ actual: string;
101
+ /** How to fix it */
102
+ fix: string;
103
+ }
104
+ interface DeckScore {
105
+ /** Overall deck score (0-100) */
106
+ total: number;
107
+ /** Individual slide scores */
108
+ slideScores: SlideScore[];
109
+ /** Holistic checks */
110
+ holistic: HolisticScore;
111
+ /** Did the deck pass? */
177
112
  passed: boolean;
178
- issues: string[];
179
- }
180
- interface ContentQAResults {
181
- /** Per-slide content analysis */
182
- perSlide: SlideContentScore[];
183
- /** Glance test results */
184
- glanceTest: GlanceTestResult[];
185
- /** Signal-to-noise ratio results */
186
- signalNoise: SignalNoiseResult[];
187
- /** One idea per slide validation */
188
- oneIdea: OneIdeaResult[];
189
- }
190
- interface SlideContentScore {
191
- slideIndex: number;
192
- wordCount: number;
193
- withinLimit: boolean;
194
- hasActionTitle: boolean;
195
- issues: string[];
113
+ /** Deck-level violations */
114
+ violations: Violation[];
115
+ }
116
+ interface HolisticScore {
117
+ /** Narrative flow (Sparkline, SCQA) */
118
+ narrativeFlow: number;
119
+ /** Visual consistency */
120
+ visualConsistency: number;
121
+ /** Has required elements (STAR moment, CTA, etc.) */
122
+ requiredElements: number;
123
+ /** No anti-patterns */
124
+ antiPatternFree: number;
125
+ }
126
+ interface KBPresentationType {
127
+ id: PresentationType;
128
+ name: string;
129
+ description: string;
130
+ use_for: string[];
131
+ primary_experts: string[];
132
+ validation_rules: KBValidationRules;
133
+ slide_types_allowed: string[];
134
+ required_elements: string[];
135
+ anti_patterns: string[];
136
+ color_palette: string;
137
+ typography: KBTypography;
138
+ scoring_weights: KBScoringWeights;
139
+ }
140
+ interface KBValidationRules {
141
+ words_per_slide: {
142
+ min: number;
143
+ max: number;
144
+ ideal: number;
145
+ };
146
+ whitespace: {
147
+ min: number;
148
+ ideal: number;
149
+ max?: number;
150
+ };
151
+ bullets_per_slide: {
152
+ max: number;
153
+ };
154
+ action_titles_required: boolean;
155
+ sources_required: boolean;
156
+ callouts_required?: boolean;
157
+ dense_data_allowed?: boolean;
196
158
  }
197
- interface GlanceTestResult {
198
- slideIndex: number;
199
- keyMessage: string;
200
- wordCount: number;
201
- readingTime: number;
202
- passed: boolean;
203
- recommendation?: string;
159
+ interface KBTypography {
160
+ titles?: string;
161
+ body?: string;
162
+ action_title?: string;
163
+ section_headers?: string;
164
+ data_labels?: string;
165
+ max_fonts: number;
166
+ }
167
+ interface KBScoringWeights {
168
+ visual_quality: number;
169
+ content_quality: number;
170
+ expert_compliance: number;
171
+ accessibility: number;
204
172
  }
205
- interface SignalNoiseResult {
206
- slideIndex: number;
207
- signalCount: number;
208
- noiseCount: number;
209
- signalRatio: number;
210
- passed: boolean;
211
- noiseElements: string[];
173
+ interface KBScoringRubric {
174
+ total_points: number;
175
+ passing_threshold: number;
176
+ categories: {
177
+ visual_quality: KBScoringCategory;
178
+ content_quality: KBScoringCategory;
179
+ expert_compliance: KBScoringCategory;
180
+ accessibility: KBScoringCategory;
181
+ };
212
182
  }
213
- interface OneIdeaResult {
214
- slideIndex: number;
215
- ideaCount: number;
216
- mainIdea: string;
217
- passed: boolean;
218
- conflictingIdeas?: string[];
183
+ interface KBScoringCategory {
184
+ weight: number;
185
+ checks: Record<string, KBCheck>;
219
186
  }
220
- interface ExpertQAResults {
221
- /** Nancy Duarte validation */
222
- duarte: ExpertValidation;
223
- /** Garr Reynolds validation */
224
- reynolds: ExpertValidation;
225
- /** Carmine Gallo validation */
226
- gallo: ExpertValidation;
227
- /** Chris Anderson validation */
228
- anderson: ExpertValidation;
187
+ interface KBCheck {
188
+ points: number;
189
+ description: string;
190
+ validation?: string;
229
191
  }
230
- interface ExpertValidation {
231
- expertName: string;
232
- principlesChecked: string[];
233
- passed: boolean;
234
- score: number;
235
- violations: string[];
192
+ interface KBExpert {
193
+ name: string;
194
+ core_principles: Record<string, KBPrinciple>;
236
195
  }
237
- interface AccessibilityResults {
238
- /** WCAG compliance level achieved */
239
- wcagLevel: 'A' | 'AA' | 'AAA' | 'FAIL';
240
- /** Contrast issues found */
241
- contrastIssues: ContrastIssue[];
242
- /** Font size issues */
243
- fontSizeIssues: FontSizeIssue[];
244
- /** Focus state coverage */
245
- focusCoverage: number;
246
- /** Color-blind safety */
247
- colorBlindSafe: boolean;
196
+ interface KBPrinciple {
197
+ description: string;
198
+ rules?: string[];
199
+ examples?: string[];
248
200
  }
249
- interface ContrastIssue {
250
- slideIndex: number;
251
- element: string;
252
- foreground: string;
253
- background: string;
254
- ratio: number;
255
- required: number;
201
+ interface ContentAnalysis {
202
+ /** Detected presentation type */
203
+ detectedType: PresentationType;
204
+ /** Extracted title */
205
+ title: string;
206
+ /** Sections found */
207
+ sections: ContentSection[];
208
+ /** Key messages */
209
+ keyMessages: string[];
210
+ /** Data points (metrics, percentages) */
211
+ dataPoints: DataPoint[];
212
+ /** SCQA structure if detected */
213
+ scqa?: SCQAStructure;
214
+ /** Sparkline moments */
215
+ sparkline?: SparklineStructure;
216
+ }
217
+ interface ContentSection {
218
+ /** Section header */
219
+ header: string;
220
+ /** Header level (1-6) */
221
+ level: number;
222
+ /** Raw content */
223
+ content: string;
224
+ /** Extracted bullets */
225
+ bullets: string[];
226
+ /** Metrics in this section */
227
+ metrics: DataPoint[];
228
+ }
229
+ interface DataPoint {
230
+ value: string;
231
+ numericValue?: number;
232
+ type: 'currency' | 'percentage' | 'number' | 'time';
233
+ context: string;
234
+ label?: string;
256
235
  }
257
- interface FontSizeIssue {
258
- slideIndex: number;
259
- element: string;
260
- actualSize: number;
261
- minimumSize: number;
236
+ interface SCQAStructure {
237
+ situation: string;
238
+ complication: string;
239
+ question: string;
240
+ answer: string;
262
241
  }
263
- interface QAIssue {
264
- /** Issue severity */
265
- severity: 'error' | 'warning' | 'info';
266
- /** Issue category */
267
- category: 'visual' | 'content' | 'expert' | 'accessibility';
268
- /** Slide index (if applicable) */
269
- slideIndex?: number;
270
- /** Issue description */
271
- message: string;
272
- /** Suggested fix */
273
- suggestion?: string;
242
+ interface SparklineStructure {
243
+ whatIs: string[];
244
+ whatCouldBe: string[];
245
+ starMoment?: string;
246
+ callToAdventure: string;
274
247
  }
275
248
  interface PresentationResult {
276
249
  /** Generated outputs */
@@ -278,1786 +251,1191 @@ interface PresentationResult {
278
251
  html?: string;
279
252
  pptx?: Buffer;
280
253
  };
281
- /** QA validation results */
282
- qaResults: QAResults;
283
- /** Overall QA score (0-100) */
284
- score: number;
285
- /** Presentation metadata */
254
+ /** Slides generated */
255
+ slides: Slide[];
256
+ /** Final deck score */
257
+ score: DeckScore;
258
+ /** Metadata */
286
259
  metadata: PresentationMetadata;
287
260
  }
288
261
  interface PresentationMetadata {
289
- /** Presentation title */
290
262
  title: string;
291
- /** Author */
292
263
  author: string;
293
- /** Generation timestamp */
264
+ presentationType: PresentationType;
294
265
  generatedAt: string;
295
- /** Presentation mode */
296
- mode: PresentationMode;
297
- /** Total slide count */
298
266
  slideCount: number;
299
- /** Total word count */
300
- wordCount: number;
301
- /** Average words per slide */
267
+ totalWords: number;
302
268
  avgWordsPerSlide: number;
303
- /** Estimated presentation duration (minutes) */
304
- estimatedDuration: number;
305
- /** Themes/frameworks used */
306
- frameworks: string[];
307
- }
308
- interface ContentAnalysis {
309
- /** SCQA structure extracted */
310
- scqa: SCQAStructure;
311
- /** Sparkline narrative arc */
312
- sparkline: SparklineStructure;
313
- /** Key messages identified */
314
- keyMessages: string[];
315
- /** Generated action titles */
316
- titles: string[];
317
- /** STAR moments identified */
318
- starMoments: string[];
319
- /** Estimated slide count */
320
- estimatedSlideCount: number;
321
- }
322
- interface SCQAStructure {
323
- situation: string;
324
- complication: string;
325
- question: string;
326
- answer: string;
327
- }
328
- interface SparklineStructure {
329
- whatIs: string[];
330
- whatCouldBe: string[];
331
- callToAdventure: string;
332
- }
333
- declare class ValidationError extends Error {
334
- errors: string[];
335
- constructor(errors: string[], message?: string);
336
- }
337
- declare class QAFailureError extends Error {
338
- score: number;
339
- threshold: number;
340
- qaResults: QAResults;
341
- constructor(score: number, threshold: number, qaResults: QAResults, message?: string);
342
- getIssues(): string[];
343
- }
344
- declare class TemplateNotFoundError extends Error {
345
- templatePath: string;
346
- constructor(templatePath: string, message?: string);
269
+ kbVersion: string;
347
270
  }
348
271
 
349
272
  /**
350
- * Score Calculator - QA Score Computation
273
+ * KnowledgeGateway - Single Point of Access to the Knowledge Base
351
274
  *
352
- * Calculates presentation quality scores based on:
353
- * - Visual quality (35%)
354
- * - Content quality (30%)
355
- * - Expert methodology compliance (25%)
356
- * - Accessibility (10%)
275
+ * CRITICAL DESIGN PRINCIPLE: NO FALLBACKS
276
+ * If data is missing from KB, we FAIL with a clear error.
277
+ * Every decision in this application comes from the KB.
357
278
  */
358
279
 
359
- interface ScoreBreakdown {
360
- visual: number;
361
- content: number;
362
- expert: number;
363
- accessibility: number;
364
- total: number;
365
- penalties: number;
366
- details: ScoreDetail[];
367
- }
368
- interface ScoreDetail {
369
- category: string;
370
- check: string;
371
- score: number;
372
- maxScore: number;
373
- notes?: string;
280
+ /**
281
+ * Result wrapper that includes KB path for debugging
282
+ */
283
+ interface KBResult<T> {
284
+ value: T;
285
+ kbPath: string;
374
286
  }
375
- declare class ScoreCalculator {
376
- private readonly weights;
377
- /**
378
- * Calculate overall QA score from results.
379
- */
380
- calculate(results: QAResults): number;
381
- /**
382
- * Get detailed score breakdown.
383
- */
384
- getBreakdown(results: QAResults): ScoreBreakdown;
385
- /**
386
- * Calculate visual quality score.
387
- */
388
- private calculateVisualScore;
389
- /**
390
- * Calculate content quality score.
391
- */
392
- private calculateContentScore;
393
- /**
394
- * Calculate expert methodology compliance score.
395
- */
396
- private calculateExpertScore;
397
- /**
398
- * Calculate accessibility compliance score.
399
- */
400
- private calculateAccessibilityScore;
401
- /**
402
- * Calculate penalties from issues.
403
- */
404
- private calculatePenalties;
287
+ /**
288
+ * KnowledgeGateway - The ONLY way to access KB data
289
+ */
290
+ declare class KnowledgeGateway {
291
+ private data;
292
+ private loaded;
293
+ private version;
405
294
  /**
406
- * Get human-readable grade from score.
295
+ * Load the knowledge base from YAML.
296
+ * MUST be called before any queries.
407
297
  */
408
- getGrade(score: number): string;
298
+ load(): Promise<void>;
409
299
  /**
410
- * Get pass/fail status.
300
+ * Get KB version
411
301
  */
412
- isPassing(score: number, threshold?: number): boolean;
302
+ getVersion(): string;
413
303
  /**
414
- * Format score for display.
304
+ * Get complete presentation type configuration.
305
+ * @throws KBQueryError if type not found
415
306
  */
416
- formatScore(score: number): string;
307
+ getPresentationType(type: PresentationType): KBResult<KBPresentationType>;
417
308
  /**
418
- * Generate summary report.
309
+ * Get validation rules for a presentation type.
310
+ * @throws KBQueryError if rules not found
419
311
  */
420
- generateReport(results: QAResults): string;
421
- }
422
-
423
- /**
424
- * QA Engine - Real Visual Quality Validation
425
- *
426
- * Unlike fake validation systems, this engine ACTUALLY tests:
427
- * - Visual quality using Playwright screenshots + Canvas API
428
- * - Layout balance and whitespace distribution
429
- * - WCAG contrast compliance
430
- * - Expert methodology adherence
431
- */
432
-
433
- declare class QAEngine {
434
- private browser;
312
+ getValidationRules(type: PresentationType): KBResult<KBValidationRules>;
435
313
  /**
436
- * Validate a presentation.
314
+ * Get word limits for a presentation type.
437
315
  */
438
- validate(presentation: string | Buffer, options?: {
439
- mode?: 'keynote' | 'business';
440
- strictMode?: boolean;
441
- threshold?: number;
442
- }): Promise<QAResults>;
316
+ getWordLimits(type: PresentationType): KBResult<{
317
+ min: number;
318
+ max: number;
319
+ ideal: number;
320
+ }>;
443
321
  /**
444
- * Calculate overall QA score.
322
+ * Get whitespace requirements.
445
323
  */
446
- calculateScore(results: QAResults): number;
324
+ getWhitespaceRules(type: PresentationType): KBResult<{
325
+ min: number;
326
+ ideal: number;
327
+ max?: number;
328
+ }>;
447
329
  /**
448
- * Create empty QA results (for when QA is skipped).
330
+ * Get scoring weights for a presentation type.
449
331
  */
450
- createEmptyResults(): QAResults;
451
- private runVisualTests;
452
- private runContentTests;
453
- private runExpertTests;
454
- private createExpertResult;
455
- private runAccessibilityTests;
456
- private calculateVisualScore;
457
- private calculateContentScore;
458
- private calculateExpertScore;
459
- private calculateA11yScore;
460
- private collectIssues;
461
- private initBrowser;
462
- private closeBrowser;
463
- }
464
-
465
- /**
466
- * PowerPoint Validator - PPTX Quality Validation
467
- *
468
- * Validates PowerPoint presentations for:
469
- * - Layout correctness
470
- * - Content quality (word counts, readability)
471
- * - Formatting consistency (fonts, colors)
472
- * - Accessibility compliance
473
- * - Expert methodology adherence
474
- *
475
- * THIS IS A MANDATORY VALIDATION - NO PPTX EXPORT WITHOUT PASSING
476
- */
477
-
478
- interface PPTXValidationResult {
479
- passed: boolean;
480
- score: number;
481
- issues: PPTXIssue[];
482
- perSlide: SlideValidationResult[];
483
- summary: ValidationSummary;
484
- }
485
- interface PPTXIssue {
486
- severity: 'error' | 'warning' | 'info';
487
- category: 'layout' | 'content' | 'formatting' | 'accessibility' | 'expert';
488
- slideIndex?: number;
489
- message: string;
490
- suggestion?: string;
491
- }
492
- interface SlideValidationResult {
493
- slideIndex: number;
494
- type: string;
495
- passed: boolean;
496
- score: number;
497
- issues: PPTXIssue[];
498
- metrics: {
499
- wordCount: number;
500
- hasTitle: boolean;
501
- hasContent: boolean;
502
- estimatedReadingTime: number;
503
- layoutScore: number;
504
- };
505
- }
506
- interface ValidationSummary {
507
- totalSlides: number;
508
- passedSlides: number;
509
- failedSlides: number;
510
- totalErrors: number;
511
- totalWarnings: number;
512
- categories: {
513
- layout: number;
514
- content: number;
515
- formatting: number;
516
- accessibility: number;
517
- expert: number;
518
- };
519
- }
520
- declare class PPTXValidator {
332
+ getScoringWeights(type: PresentationType): KBResult<KBScoringWeights>;
521
333
  /**
522
- * Validate a set of slides before PPTX generation.
523
- * This validation is MANDATORY - export will fail if score < threshold.
334
+ * Get allowed slide types for a presentation type.
524
335
  */
525
- validate(slides: Slide[], options: {
526
- mode: 'keynote' | 'business';
527
- threshold?: number;
528
- strictMode?: boolean;
529
- }): Promise<PPTXValidationResult>;
336
+ getAllowedSlideTypes(type: PresentationType): KBResult<string[]>;
530
337
  /**
531
- * Validate a single slide.
338
+ * Get required elements for a presentation type.
532
339
  */
533
- private validateSlide;
340
+ getRequiredElements(type: PresentationType): KBResult<string[]>;
534
341
  /**
535
- * Validate cross-slide consistency.
342
+ * Get anti-patterns to avoid for a presentation type.
536
343
  */
537
- private validateCrossSlide;
344
+ getAntiPatterns(type: PresentationType): KBResult<string[]>;
538
345
  /**
539
- * Validate against expert methodologies.
346
+ * Get the scoring rubric.
540
347
  */
541
- private validateExpertMethodologies;
348
+ getScoringRubric(): KBResult<KBScoringRubric>;
542
349
  /**
543
- * Count words in slide content.
350
+ * Get passing threshold (default: 95).
544
351
  */
545
- private countWords;
352
+ getPassingThreshold(): KBResult<number>;
546
353
  /**
547
- * Check if slide has meaningful content.
354
+ * Get expert methodology.
548
355
  */
549
- private hasContent;
356
+ getExpert(name: string): KBResult<KBExpert>;
550
357
  /**
551
- * Count distinct ideas in a slide.
358
+ * Get Nancy Duarte's glance test rules.
552
359
  */
553
- private countIdeas;
360
+ getGlanceTest(): KBResult<{
361
+ description: string;
362
+ word_limit: number;
363
+ }>;
554
364
  /**
555
- * Calculate layout score for a slide.
365
+ * Get Duarte's Sparkline framework.
556
366
  */
557
- private calculateLayoutScore;
367
+ getSparkline(): KBResult<Record<string, unknown>>;
558
368
  /**
559
- * Calculate overall validation score.
369
+ * Get Minto's SCQA framework.
560
370
  */
561
- private calculateScore;
371
+ getSCQA(): KBResult<Record<string, unknown>>;
562
372
  /**
563
- * Build validation summary.
373
+ * Get Miller's Law (7±2 items).
564
374
  */
565
- private buildSummary;
375
+ getMillersLaw(): KBResult<{
376
+ principle: string;
377
+ application: string[];
378
+ }>;
566
379
  /**
567
- * Convert PPTX validation result to standard QAResults format.
380
+ * Get accessibility requirements.
568
381
  */
569
- toQAResults(result: PPTXValidationResult, mode: 'keynote' | 'business'): QAResults;
570
- private createExpertValidation;
382
+ getAccessibilityRules(): KBResult<Record<string, unknown>>;
571
383
  /**
572
- * Generate human-readable validation report.
384
+ * Get contrast ratio requirements.
573
385
  */
574
- generateReport(result: PPTXValidationResult): string;
575
- }
576
-
577
- /**
578
- * Auto-Remediation Engine
579
- *
580
- * Instead of blocking on QA failures, this engine automatically fixes issues
581
- * and iterates until the presentation passes quality thresholds.
582
- *
583
- * Philosophy: NEVER fail - always deliver a working, quality presentation.
584
- *
585
- * Remediation strategies:
586
- * - Too many words → Summarize/split slides
587
- * - Poor whitespace → Adjust layout
588
- * - Failed glance test → Shorten titles
589
- * - Too many bullets → Consolidate or split
590
- * - Missing structure → Add required slides
591
- * - Accessibility issues → Fix contrast/font sizes
592
- */
593
-
594
- interface RemediationChange {
595
- slideIndex: number;
596
- type: RemediationType;
597
- description: string;
598
- before?: string;
599
- after?: string;
600
- }
601
- type RemediationType = 'word_reduction' | 'slide_split' | 'title_shortening' | 'bullet_consolidation' | 'layout_adjustment' | 'structure_addition' | 'font_size_increase' | 'content_enhancement' | 'whitespace_improvement';
602
- declare class AutoRemediation {
603
- private changes;
386
+ getContrastRequirements(): KBResult<{
387
+ normal_text: string;
388
+ large_text: string;
389
+ }>;
604
390
  /**
605
- * Automatically remediate slides until they pass QA.
391
+ * Get minimum font sizes.
606
392
  */
607
- remediate(slides: Slide[], issues: QAIssue[] | PPTXIssue[], options: {
608
- mode: 'keynote' | 'business';
609
- targetScore: number;
610
- }): Promise<Slide[]>;
393
+ getFontSizeRequirements(): KBResult<Record<string, string>>;
611
394
  /**
612
- * Get the changes that were applied during remediation.
395
+ * Get Tufte's data-ink ratio rules.
613
396
  */
614
- getChanges(): RemediationChange[];
397
+ getDataInkRules(): KBResult<Record<string, unknown>>;
615
398
  /**
616
- * Remediate word count issues - the most common problem.
399
+ * Get chartjunk to avoid.
617
400
  */
618
- private remediateWordCount;
401
+ getChartjunk(): KBResult<string[]>;
619
402
  /**
620
- * Remediate glance test failures - title too long.
403
+ * Get Cialdini's 6 Principles of Influence.
621
404
  */
622
- private remediateGlanceTest;
405
+ getCialdiniPrinciples(): KBResult<Record<string, unknown>>;
623
406
  /**
624
- * Remediate bullet point issues.
407
+ * Get specific Cialdini principle by name.
625
408
  */
626
- private remediateBullets;
409
+ getCialdiniPrinciple(name: string): KBResult<Record<string, unknown>>;
627
410
  /**
628
- * Remediate structural issues - missing title slide, conclusion, etc.
411
+ * Get all Gestalt principles.
629
412
  */
630
- private remediateStructure;
413
+ getGestaltPrinciples(): KBResult<Record<string, unknown>>;
631
414
  /**
632
- * Remediate accessibility issues.
415
+ * Get specific Gestalt principle by name.
633
416
  */
634
- private remediateAccessibility;
417
+ getGestaltPrinciple(name: string): KBResult<Record<string, unknown>>;
635
418
  /**
636
- * Group issues by their primary type.
419
+ * Get Gestalt proximity principle (for layout checks).
637
420
  */
638
- private groupIssuesByType;
421
+ getGestaltProximity(): KBResult<Record<string, unknown>>;
639
422
  /**
640
- * Shorten text to approximately N words while preserving meaning.
423
+ * Get Gestalt similarity principle (for consistency checks).
641
424
  */
642
- private shortenText;
425
+ getGestaltSimilarity(): KBResult<Record<string, unknown>>;
643
426
  /**
644
- * Shorten a title to N words, keeping the key message.
427
+ * Get Gestalt figure-ground principle (for visual impact checks).
645
428
  */
646
- private shortenTitle;
429
+ getGestaltFigureGround(): KBResult<Record<string, unknown>>;
647
430
  /**
648
- * Consolidate bullets by combining related ones.
431
+ * Query any KB path directly.
432
+ * @throws KBQueryError if path not found
649
433
  */
650
- private consolidateBullets;
434
+ queryRequired<T>(path: string): KBResult<T>;
651
435
  /**
652
- * Reindex slides after insertion/deletion.
436
+ * Query any KB path directly (optional - returns null if not found).
653
437
  */
654
- private reindexSlides;
438
+ queryOptional<T>(path: string): KBResult<T | null>;
655
439
  /**
656
- * Count words in a slide.
440
+ * Ensure KB is loaded.
657
441
  */
658
- private countWords;
442
+ private ensureLoaded;
659
443
  /**
660
- * Deep clone slides array.
444
+ * Query a dotted path in the KB.
661
445
  */
662
- private deepClone;
446
+ private query;
663
447
  /**
664
- * Generate remediation report.
448
+ * Create a KB query error.
665
449
  */
666
- generateReport(): string;
450
+ private error;
667
451
  }
668
-
669
452
  /**
670
- * Hallucination Detector
671
- *
672
- * Verifies that all facts, statistics, and claims in the presentation
673
- * are sourced from the original content. ZERO TOLERANCE for hallucinations.
674
- *
675
- * Checks:
676
- * - Numbers and statistics must appear in source content
677
- * - Company names must be in source content
678
- * - Dates and timelines must be verifiable
679
- * - Quotes must be exact matches
680
- * - Claims must be supported by source material
681
- *
682
- * Philosophy: If it's not in the source, it shouldn't be in the presentation.
453
+ * Get the singleton KnowledgeGateway instance.
683
454
  */
684
-
685
- interface FactCheckResult {
686
- passed: boolean;
687
- score: number;
688
- totalFacts: number;
689
- verifiedFacts: number;
690
- unverifiedFacts: number;
691
- issues: FactCheckIssue[];
692
- warnings: FactCheckWarning[];
693
- }
694
- interface FactCheckIssue {
695
- slideIndex: number;
696
- slideTitle: string;
697
- fact: string;
698
- type: 'number' | 'statistic' | 'company' | 'date' | 'quote' | 'claim';
699
- severity: 'error' | 'warning';
700
- message: string;
701
- suggestion: string;
702
- }
703
- interface FactCheckWarning {
704
- slideIndex: number;
705
- message: string;
706
- }
707
- declare class HallucinationDetector {
708
- private numberPattern;
709
- private percentagePattern;
710
- private datePattern;
711
- private companyPattern;
712
- private quotePattern;
713
- /**
714
- * Check all slides against source content for hallucinations.
715
- */
716
- checkForHallucinations(slides: Slide[], sourceContent: string, analysis: ContentAnalysis): Promise<FactCheckResult>;
717
- /**
718
- * Generate a fact-check report.
719
- */
720
- generateReport(result: FactCheckResult): string;
721
- /**
722
- * Auto-remediate hallucinations by removing unverified facts.
723
- */
724
- remediate(slides: Slide[], result: FactCheckResult): Slide[];
725
- private normalizeText;
726
- private getSlideText;
727
- private extractNumbers;
728
- private extractCompanies;
729
- private extractDates;
730
- private isNumberInSource;
731
- private isCompanyInSource;
732
- private isDateInSource;
733
- private isCommonWord;
734
- private checkForUnsupportedClaims;
735
- private getPlaceholder;
736
- }
455
+ declare function getKB(): KnowledgeGateway;
456
+ /**
457
+ * Initialize and return the KB (async).
458
+ */
459
+ declare function initKB(): Promise<KnowledgeGateway>;
737
460
 
738
461
  /**
739
- * Presentation Engine - Main Orchestrator
740
- *
741
- * Coordinates content analysis, slide generation, and QA validation
742
- * to produce world-class presentations.
462
+ * ContentAnalyzer - Parse and Analyze Input Content
743
463
  *
744
- * PHILOSOPHY: NEVER FAIL - ALWAYS DELIVER
745
- *
746
- * Instead of blocking on QA failures, this engine:
747
- * 1. Validates the presentation
748
- * 2. If issues found, automatically remediates them
749
- * 3. Re-validates
750
- * 4. Repeats until it passes (max 5 iterations)
751
- * 5. ALWAYS delivers a working presentation
464
+ * Parses markdown/text input and extracts:
465
+ * - Sections with headers
466
+ * - Bullets and key points
467
+ * - Data points (metrics, percentages, currencies)
468
+ * - Detects presentation type from content signals
469
+ * - Identifies SCQA structure if present
470
+ * - Identifies Sparkline moments
752
471
  */
753
472
 
754
- declare class PresentationEngine {
755
- private contentAnalyzer;
756
- private slideFactory;
757
- private templateEngine;
758
- private scoreCalculator;
759
- private typeDetector;
760
- private strategyFactory;
761
- private qaEngine;
762
- private pptxValidator;
763
- private htmlLayoutValidator;
764
- private autoRemediation;
765
- private hallucinationDetector;
766
- private htmlGenerator;
767
- private pptxGenerator;
473
+ declare class ContentAnalyzer {
474
+ private kb;
475
+ private initialized;
768
476
  constructor();
477
+ initialize(): Promise<void>;
769
478
  /**
770
- * Generate a presentation from content.
771
- *
772
- * GUARANTEED DELIVERY:
773
- * - Validates presentation quality
774
- * - Automatically fixes any issues found
775
- * - Iterates until quality threshold is met
776
- * - ALWAYS returns a working presentation
777
- *
778
- * @param config - Presentation configuration
779
- * @returns Presentation result with outputs, QA results, and score
479
+ * Analyze content and return structured analysis.
780
480
  */
781
- generate(config: PresentationConfig): Promise<PresentationResult>;
481
+ analyze(content: string, contentType?: 'markdown' | 'text'): Promise<ContentAnalysis>;
782
482
  /**
783
- * Validate slides and automatically remediate until they pass.
784
- * Includes hallucination detection to ensure all facts are sourced.
483
+ * Parse content into sections based on headers.
785
484
  */
786
- private validateAndRemediate;
485
+ private parseSections;
787
486
  /**
788
- * Validate presentation configuration.
487
+ * Extract title from content.
789
488
  */
790
- private validateConfig;
489
+ private extractTitle;
791
490
  /**
792
- * Count words in a slide.
491
+ * Extract bullet points from content.
492
+ * Strips markdown formatting (**bold**, *italic*, `code`) from bullet text.
793
493
  */
794
- private countWords;
494
+ private extractBullets;
795
495
  /**
796
- * Build presentation metadata.
496
+ * Strip markdown formatting from text.
497
+ * Converts **bold**, *italic*, `code`, [links](url) to plain text.
797
498
  */
798
- private buildMetadata;
499
+ private stripMarkdown;
799
500
  /**
800
- * Detect which expert frameworks were applied.
501
+ * Extract data points (metrics, percentages, currencies, numbers).
801
502
  */
802
- private detectFrameworks;
503
+ private extractDataPoints;
803
504
  /**
804
- * Get QA Engine for external access.
505
+ * Get surrounding context for a data point.
805
506
  */
806
- getQAEngine(): QAEngine;
507
+ private getContext;
807
508
  /**
808
- * Get PPTX Validator for external access.
509
+ * Parse numeric value from string (handles M/B/K suffixes).
809
510
  */
810
- getPPTXValidator(): PPTXValidator;
511
+ private parseNumericValue;
811
512
  /**
812
- * Get Score Calculator for external access.
513
+ * Extract key messages from sections.
813
514
  */
814
- getScoreCalculator(): ScoreCalculator;
515
+ private extractKeyMessages;
516
+ /**
517
+ * Detect presentation type based on content signals.
518
+ */
519
+ private detectPresentationType;
815
520
  /**
816
- * Get Auto Remediation for external access.
521
+ * Identify SCQA (Situation, Complication, Question, Answer) structure.
817
522
  */
818
- getAutoRemediation(): AutoRemediation;
523
+ private identifySCQA;
819
524
  /**
820
- * Get Hallucination Detector for external access.
525
+ * Identify Sparkline (What Is / What Could Be) structure.
821
526
  */
822
- getHallucinationDetector(): HallucinationDetector;
527
+ private identifySparkline;
823
528
  }
529
+ declare function getContentAnalyzer(): ContentAnalyzer;
530
+ declare function initContentAnalyzer(): Promise<ContentAnalyzer>;
824
531
 
825
532
  /**
826
- * Content Analyzer - Extracts Structure from Raw Content
533
+ * SlideGenerator - Generate Slides with Visual Intent
534
+ *
535
+ * Takes ContentAnalysis and generates slides with:
536
+ * - Appropriate slide types based on content
537
+ * - Visual intent (emphasis, layout hints)
538
+ * - Respect for KB word limits and rules
539
+ * - SCQA/Sparkline narrative structure when detected
827
540
  *
828
- * Uses expert methodologies to analyze content and extract:
829
- * - SCQA structure (Barbara Minto)
830
- * - Sparkline narrative arc (Nancy Duarte)
831
- * - Key messages (Rule of Three)
832
- * - STAR moments
833
- * - Action titles
541
+ * ALL decisions come from the Knowledge Base. NO hardcoded fallbacks.
834
542
  */
835
543
 
836
- declare class ContentAnalyzer {
837
- private readonly situationSignals;
838
- private readonly complicationSignals;
839
- private readonly questionSignals;
840
- private readonly answerSignals;
841
- private readonly whatIsSignals;
842
- private readonly whatCouldBeSignals;
843
- /**
844
- * Analyze content and extract structural elements.
845
- */
846
- analyze(content: string, contentType: string): Promise<ContentAnalysis>;
847
- /**
848
- * Parse content based on its type.
849
- */
850
- private parseContent;
851
- /**
852
- * Parse markdown content to plain text (preserving structure hints).
853
- */
854
- private parseMarkdown;
855
- /**
856
- * Parse JSON content.
857
- */
858
- private parseJSON;
859
- /**
860
- * Parse YAML content.
861
- */
862
- private parseYAML;
863
- /**
864
- * Flatten object to text.
865
- */
866
- private flattenObject;
867
- /**
868
- * Split text into paragraphs.
869
- */
870
- private splitIntoParagraphs;
871
- /**
872
- * Split text into sentences.
873
- */
874
- private splitIntoSentences;
544
+ declare class SlideGenerator {
545
+ private kb;
546
+ private vds;
547
+ private initialized;
548
+ private wordLimits;
549
+ private bulletLimit;
550
+ private allowedSlideTypes;
551
+ constructor();
552
+ initialize(): Promise<void>;
875
553
  /**
876
- * Extract SCQA structure (Barbara Minto's Pyramid Principle).
554
+ * Generate slides from content analysis.
877
555
  */
878
- private extractSCQA;
556
+ generate(analysis: ContentAnalysis, presentationType: PresentationType): Promise<Slide[]>;
557
+ private loadRulesForType;
879
558
  /**
880
- * Extract Sparkline structure (Nancy Duarte).
559
+ * Create title slide.
881
560
  */
882
- private extractSparkline;
561
+ private createTitleSlide;
883
562
  /**
884
- * Extract key messages (max 3 - Rule of Three).
563
+ * Create agenda slide.
885
564
  */
886
- private extractKeyMessages;
565
+ private createAgendaSlide;
887
566
  /**
888
- * Generate action titles (McKinsey-style).
567
+ * Create SCQA slides (Situation, Complication, Question, Answer).
889
568
  */
890
- private generateActionTitles;
569
+ private createSCQASlides;
891
570
  /**
892
- * Transform a statement into an action title.
571
+ * Create slides for a content section.
893
572
  */
894
- private transformToActionTitle;
573
+ private createSectionSlides;
895
574
  /**
896
- * Identify STAR moments (Something They'll Always Remember).
575
+ * Create metrics grid slide from data points.
897
576
  */
898
- private identifyStarMoments;
577
+ private createMetricsSlide;
899
578
  /**
900
- * Estimate slide count based on content.
579
+ * Create metrics grid slide from a section.
901
580
  */
902
- private estimateSlideCount;
903
- private containsSignals;
904
- private extractRelevantSentence;
905
- private truncateToSentence;
906
- private truncateToWords;
907
- private capitalizeFirst;
908
- }
909
-
910
- /**
911
- * Slide Factory - Creates Slides from Content Analysis
912
- *
913
- * Generates slide structures based on:
914
- * - Presentation mode (keynote vs business)
915
- * - Presentation type (7 specialized strategies)
916
- * - Content analysis results
917
- * - Expert methodology recommendations
918
- */
919
-
920
- declare class SlideFactory {
921
- private readonly templates;
922
- private readonly strategyFactory;
923
- constructor();
581
+ private createMetricsGridSlide;
924
582
  /**
925
- * Create slides from analyzed content.
926
- * If presentationType is provided, uses the specialized strategy.
927
- * Otherwise, falls back to mode-based generation.
583
+ * Create STAR moment slide (Something They'll Always Remember).
928
584
  */
929
- createSlides(analysis: ContentAnalysis, mode: PresentationMode, presentationType?: PresentationType): Promise<Slide[]>;
585
+ private createStarMomentSlide;
930
586
  /**
931
- * Create a title slide.
587
+ * Create call to action slide.
932
588
  */
933
- private createTitleSlide;
589
+ private createCallToActionSlide;
934
590
  /**
935
- * Create an agenda slide.
591
+ * Create thank you / closing slide.
936
592
  */
937
- private createAgendaSlide;
593
+ private createThankYouSlide;
938
594
  /**
939
- * Create a context/situation slide.
595
+ * Determine the best slide type for a section.
940
596
  */
941
- private createContextSlide;
597
+ private determineSlideType;
942
598
  /**
943
- * Create a problem/complication slide.
599
+ * Check if presentation type favors minimal slides.
944
600
  */
945
- private createProblemSlide;
601
+ private isMinimalType;
946
602
  /**
947
- * Create a key message slide.
603
+ * Strip all markdown syntax from text for clean slide content.
604
+ * This is called on ALL text going into slides to prevent raw markdown.
948
605
  */
949
- private createMessageSlide;
606
+ private stripMarkdownSyntax;
950
607
  /**
951
- * Create a STAR moment slide.
608
+ * Clean bullets - strip markdown and extract complete, meaningful phrases.
609
+ * CRITICAL: Never truncate mid-sentence. Keep bullets SHORT (3-5 words each).
610
+ * For sales_pitch with max 30 words: 4 bullets × 5 words = 20 words (leaves room for title)
952
611
  */
953
- private createStarMomentSlide;
612
+ private cleanBullets;
954
613
  /**
955
- * Create a solution/answer slide.
614
+ * Truncate text to word limit, stripping markdown first.
615
+ * NEVER adds "..." - just takes the complete words that fit.
956
616
  */
957
- private createSolutionSlide;
617
+ private truncateToWordLimit;
958
618
  /**
959
- * Create a call-to-action slide.
619
+ * Extract a key statement from content (first sentence or bold text).
960
620
  */
961
- private createCTASlide;
621
+ private extractKeyStatement;
962
622
  /**
963
- * Create a thank you slide.
623
+ * Extract a key message from title and body for single_statement slides.
624
+ * Returns a concise, impactful message that provides substance.
964
625
  */
965
- private createThankYouSlide;
626
+ private extractKeyMessage;
966
627
  /**
967
- * Initialize slide templates with constraints.
628
+ * Extract a label from context (nearby text around a data point).
968
629
  */
969
- private initializeTemplates;
630
+ private extractLabelFromContext;
970
631
  /**
971
- * Truncate text to max length at word boundary.
632
+ * Detect trend from context (up, down, neutral).
972
633
  */
973
- private truncate;
634
+ private detectTrend;
974
635
  /**
975
- * Extract an action title from a message.
636
+ * Split array into chunks.
976
637
  */
977
- private extractActionTitle;
638
+ private chunkArray;
978
639
  /**
979
- * Extract bullet points from text.
640
+ * Generate meaningful titles for chunked bullet lists.
641
+ * Instead of "Title (continued)", create contextual subtitles.
980
642
  */
981
- private extractBullets;
643
+ private generateChunkTitles;
982
644
  /**
983
- * Remove a statistic from text.
645
+ * Extract a meaningful subtitle from bullet content.
984
646
  */
985
- private removeStatistic;
647
+ private extractSubtitleFromBullets;
986
648
  }
649
+ declare function getSlideGenerator(): SlideGenerator;
650
+ declare function initSlideGenerator(): Promise<SlideGenerator>;
987
651
 
988
652
  /**
989
- * Template Engine - Handlebars Template Rendering
653
+ * VisualDesignSystem - KB-Driven Visual Design Configuration
990
654
  *
991
- * Renders slide data into HTML using Handlebars templates.
992
- * Supports custom templates and helper functions.
655
+ * CRITICAL: ALL design decisions come from the Knowledge Base.
656
+ * This module queries KB for colors, typography, gradients, layouts.
657
+ * NO hardcoded fallbacks.
993
658
  */
994
659
 
995
- interface TemplateConfig {
996
- customTemplates?: Record<string, string>;
997
- theme?: ThemeName;
660
+ interface ColorPalette {
661
+ name: string;
662
+ background: string;
663
+ primary: string;
664
+ secondary: string;
665
+ accent: string;
666
+ text: string;
667
+ useCase: string;
668
+ contrastRatio: string;
669
+ }
670
+ interface Typography {
671
+ titles: string;
672
+ headlines?: string;
673
+ body: string;
674
+ maxFonts: number;
675
+ fontPairing?: string;
676
+ actionTitle?: string;
677
+ sectionHeaders?: string;
678
+ dataLabels?: string;
679
+ }
680
+ interface LayoutRules {
681
+ whitespace: string;
682
+ wordsPerSlide: string;
683
+ elementsPerSlide?: string;
684
+ requiresActionTitles?: boolean;
685
+ requiresSources?: boolean;
686
+ requiresCallouts?: boolean;
687
+ }
688
+ interface GradientDefinition {
689
+ name: string;
690
+ css: string;
691
+ angle?: number;
692
+ stops: Array<{
693
+ color: string;
694
+ position: string;
695
+ }>;
696
+ }
697
+ interface SlideLayout {
698
+ name: string;
699
+ purpose: string;
700
+ elements: string[];
701
+ wordLimit?: number;
702
+ grid?: {
703
+ columns: number;
704
+ rows?: number;
705
+ gap: string;
706
+ };
998
707
  }
999
- declare class TemplateEngine {
1000
- private handlebars;
1001
- private templates;
1002
- private partials;
708
+ interface VisualTheme {
709
+ presentationType: PresentationType;
710
+ mode: 'keynote' | 'business';
711
+ palette: ColorPalette;
712
+ typography: Typography;
713
+ layout: LayoutRules;
714
+ gradients: GradientDefinition[];
715
+ cssVariables: Record<string, string>;
716
+ }
717
+ declare class VisualDesignSystem {
718
+ private kb;
719
+ private initialized;
1003
720
  constructor();
1004
721
  /**
1005
- * Render a slide to HTML.
722
+ * Initialize the design system (loads KB)
723
+ */
724
+ initialize(): Promise<void>;
725
+ /**
726
+ * Get complete visual theme for a presentation type.
1006
727
  */
1007
- render(slide: Slide, config?: TemplateConfig): string;
728
+ getTheme(type: PresentationType): Promise<VisualTheme>;
1008
729
  /**
1009
- * Render multiple slides.
730
+ * Determine mode (keynote vs business) for a presentation type.
1010
731
  */
1011
- renderAll(slides: Slide[], config?: TemplateConfig): string[];
732
+ private getModeForType;
1012
733
  /**
1013
- * Prepare template context with computed properties.
734
+ * Get color palette for presentation type from KB.
1014
735
  */
1015
- private prepareContext;
736
+ private getPaletteForType;
1016
737
  /**
1017
- * Build CSS class list for slide.
738
+ * Get typography rules for mode from KB.
1018
739
  */
1019
- private buildClassList;
740
+ private getTypographyForMode;
1020
741
  /**
1021
- * Build inline style string.
742
+ * Get layout rules for mode from KB.
1022
743
  */
1023
- private buildStyleString;
744
+ private getLayoutRulesForMode;
1024
745
  /**
1025
- * Register Handlebars helpers.
746
+ * Get gradient definitions for presentation type.
1026
747
  */
1027
- private registerHelpers;
748
+ private getGradientsForType;
1028
749
  /**
1029
- * Register reusable partials.
750
+ * Build CSS custom properties for the theme.
1030
751
  */
1031
- private registerPartials;
752
+ private buildCSSVariables;
1032
753
  /**
1033
- * Compile built-in templates.
754
+ * Get slide layout templates from KB.
1034
755
  */
1035
- private compileTemplates;
756
+ getSlideLayouts(type: PresentationType): Promise<SlideLayout[]>;
1036
757
  /**
1037
- * Render fallback for unknown slide types.
758
+ * Generate complete CSS for the theme.
1038
759
  */
1039
- private renderFallback;
760
+ generateCSS(theme: VisualTheme): string;
761
+ private lightenColor;
762
+ private darkenColor;
763
+ private hexToRgb;
1040
764
  /**
1041
- * Convert camelCase to kebab-case.
765
+ * Get contrasting text color for a given background color.
766
+ * Returns white or black based on luminance.
1042
767
  */
1043
- private kebabCase;
768
+ private getContrastColor;
1044
769
  }
770
+ declare function getVisualDesignSystem(): VisualDesignSystem;
771
+ declare function initVisualDesignSystem(): Promise<VisualDesignSystem>;
1045
772
 
1046
773
  /**
1047
- * Accessibility Validator - WCAG Compliance Testing
774
+ * SlideQualityReviewer - THE HEART OF THE QUALITATIVE REVIEW SYSTEM
1048
775
  *
1049
- * Provides comprehensive accessibility validation using:
1050
- * - Axe-core for automated WCAG testing
1051
- * - Custom contrast ratio validation
1052
- * - Font size compliance
1053
- * - Keyboard navigation coverage
1054
- * - Color-blind safety checks
776
+ * This is NOT a mechanical checker. It evaluates REAL quality.
777
+ * A slide ONLY passes at 95+ if:
778
+ * 1. You would personally present it without changes
779
+ * 2. It follows expert principles (Duarte, Reynolds, Tufte)
780
+ * 3. It looks professionally designed
781
+ * 4. It clearly communicates its message
782
+ * 5. It fits the overall presentation
1055
783
  *
1056
- * MANDATORY: All presentations must meet WCAG AA minimum.
784
+ * ALL rules come from the Knowledge Base. NO hardcoded fallbacks.
1057
785
  */
1058
786
 
1059
- interface A11yValidationResult {
1060
- passed: boolean;
1061
- wcagLevel: 'A' | 'AA' | 'AAA' | 'FAIL';
787
+ type QualityLevel = 'excellent' | 'good' | 'acceptable' | 'poor' | 'failing';
788
+ interface QualitativeAssessment {
789
+ /** Score (0-100) */
1062
790
  score: number;
1063
- issues: A11yIssue[];
1064
- axeResults?: AxeResult[];
1065
- contrastIssues: ContrastIssue[];
1066
- fontSizeIssues: FontSizeIssue[];
1067
- keyboardIssues: KeyboardIssue[];
1068
- colorBlindSafe: boolean;
1069
- }
1070
- interface A11yIssue {
1071
- severity: 'critical' | 'serious' | 'moderate' | 'minor';
1072
- type: 'contrast' | 'font-size' | 'keyboard' | 'aria' | 'structure' | 'color';
1073
- slideIndex?: number;
1074
- element?: string;
1075
- message: string;
1076
- wcagCriteria?: string;
1077
- suggestion?: string;
1078
- }
1079
- interface AxeResult {
1080
- id: string;
1081
- impact: 'critical' | 'serious' | 'moderate' | 'minor';
1082
- description: string;
1083
- nodes: number;
1084
- }
1085
- interface KeyboardIssue {
1086
- slideIndex: number;
1087
- element: string;
791
+ /** Quality level */
792
+ level: QualityLevel;
793
+ /** WHY this score - specific reasoning */
794
+ reasoning: string;
795
+ /** KB reference for this assessment */
796
+ kbReference?: string;
797
+ }
798
+ interface QualitativeSlideReview {
799
+ /** Overall qualitative score (0-100, must be >= 95) */
800
+ score: number;
801
+ /** Would you be proud to present this? */
802
+ wouldPresent: boolean;
803
+ /** Detailed qualitative assessments */
804
+ assessments: {
805
+ visualImpact: QualitativeAssessment;
806
+ contentClarity: QualitativeAssessment;
807
+ layoutBalance: QualitativeAssessment;
808
+ typographyHierarchy: QualitativeAssessment;
809
+ whitespaceUsage: QualitativeAssessment;
810
+ colorHarmony: QualitativeAssessment;
811
+ audienceAppropriate: QualitativeAssessment;
812
+ };
813
+ /** Specific issues found */
814
+ issues: QualityIssue[];
815
+ /** What would make this slide better */
816
+ improvements: string[];
817
+ }
818
+ interface QualityIssue {
819
+ severity: 'critical' | 'major' | 'minor';
820
+ category: 'visual' | 'content' | 'layout' | 'typography' | 'accessibility';
1088
821
  issue: string;
1089
- }
1090
- declare class AccessibilityValidator {
1091
- private browser;
1092
- /**
1093
- * Validate accessibility of an HTML presentation.
1094
- */
1095
- validate(html: string, options?: {
1096
- targetLevel?: 'A' | 'AA' | 'AAA';
1097
- projectionMode?: boolean;
1098
- }): Promise<A11yValidationResult>;
1099
- /**
1100
- * Check color contrast compliance.
1101
- */
1102
- private checkContrast;
1103
- /**
1104
- * Check font size compliance.
1105
- */
1106
- private checkFontSizes;
822
+ fix: string;
823
+ kbReference?: string;
824
+ }
825
+ declare class SlideQualityReviewer {
826
+ private kb;
827
+ private initialized;
828
+ private wordLimits;
829
+ private whitespaceRules;
830
+ private bulletLimit;
831
+ private glanceTestSeconds;
832
+ private hasCialdini;
833
+ private hasGestalt;
834
+ private hasTufteDataInk;
835
+ private chartjunkToAvoid;
836
+ constructor();
837
+ initialize(): Promise<void>;
1107
838
  /**
1108
- * Check keyboard navigation accessibility.
839
+ * Review a slide qualitatively.
1109
840
  */
1110
- private checkKeyboardNavigation;
841
+ review(slide: Slide, presentationType: PresentationType): Promise<QualitativeSlideReview>;
1111
842
  /**
1112
- * Check document structure accessibility.
843
+ * Convert qualitative review to SlideScore format.
1113
844
  */
1114
- private checkStructure;
845
+ toSlideScore(review: QualitativeSlideReview): SlideScore;
846
+ private loadRulesForType;
1115
847
  /**
1116
- * Check color-blind safety.
848
+ * Visual Impact (25%): Does this slide command attention appropriately?
1117
849
  */
1118
- private checkColorBlindSafety;
850
+ private assessVisualImpact;
1119
851
  /**
1120
- * Calculate contrast ratio between two colors.
852
+ * Content Clarity (20%): Can you understand the message in 3 seconds?
1121
853
  */
1122
- private calculateContrastRatio;
854
+ private assessContentClarity;
1123
855
  /**
1124
- * Calculate relative luminance of a color.
856
+ * Get all text content from a slide for analysis.
1125
857
  */
1126
- private getRelativeLuminance;
858
+ private getAllTextContent;
1127
859
  /**
1128
- * Determine WCAG compliance level.
860
+ * Layout Balance (15%): Is visual weight distributed appropriately?
1129
861
  */
1130
- private determineWCAGLevel;
862
+ private assessLayoutBalance;
1131
863
  /**
1132
- * Calculate accessibility score.
864
+ * Typography Hierarchy (15%): Is there clear primary/secondary/tertiary hierarchy?
1133
865
  */
1134
- private calculateScore;
866
+ private assessTypographyHierarchy;
1135
867
  /**
1136
- * Generate accessibility report.
868
+ * Whitespace Usage (10%): Is whitespace used purposefully?
1137
869
  */
1138
- generateReport(result: A11yValidationResult): string;
1139
- private initBrowser;
1140
- private closeBrowser;
1141
- }
1142
-
1143
- /**
1144
- * HTML Layout Validator - Bulletproof Viewport Enforcement
1145
- *
1146
- * This validator TESTS rendered HTML presentations to VERIFY:
1147
- * 1. No content overflows the slide boundaries
1148
- * 2. All text is readable (not clipped)
1149
- * 3. All elements fit within the viewport
1150
- * 4. No horizontal scrolling is needed
1151
- *
1152
- * PHILOSOPHY: VERIFY, DON'T GUESS
1153
- * - Uses Playwright to actually render the presentation
1154
- * - Measures real DOM elements
1155
- * - Checks computed styles
1156
- * - Takes screenshots as evidence
1157
- *
1158
- * THIS IS MANDATORY - No HTML export without passing layout validation
1159
- */
1160
- interface LayoutValidationResult {
1161
- passed: boolean;
1162
- score: number;
1163
- issues: LayoutIssue[];
1164
- perSlide: SlideLayoutResult[];
1165
- screenshots?: Buffer[];
1166
- }
1167
- interface LayoutIssue {
1168
- severity: 'error' | 'warning' | 'info';
1169
- slideIndex: number;
1170
- element?: string;
1171
- message: string;
1172
- suggestion: string;
1173
- measurements?: {
1174
- elementWidth?: number;
1175
- elementHeight?: number;
1176
- viewportWidth?: number;
1177
- viewportHeight?: number;
1178
- overflow?: {
1179
- x: number;
1180
- y: number;
1181
- };
1182
- };
1183
- }
1184
- interface SlideLayoutResult {
1185
- slideIndex: number;
1186
- passed: boolean;
1187
- score: number;
1188
- issues: LayoutIssue[];
1189
- measurements: {
1190
- contentHeight: number;
1191
- viewportHeight: number;
1192
- contentWidth: number;
1193
- viewportWidth: number;
1194
- overflowY: number;
1195
- overflowX: number;
1196
- hasScrollbar: boolean;
1197
- clippedElements: string[];
1198
- };
1199
- }
1200
- declare class HTMLLayoutValidator {
1201
- private playwright;
870
+ private assessWhitespaceUsage;
1202
871
  /**
1203
- * Validate HTML presentation layout using real browser rendering.
1204
- * This is the MANDATORY check before any HTML export.
872
+ * Color Harmony (10%): Do colors work together within the theme?
1205
873
  */
1206
- validate(html: string): Promise<LayoutValidationResult>;
874
+ private assessColorHarmony;
1207
875
  /**
1208
- * Validate a single slide's layout using Playwright.
876
+ * Audience Appropriateness (5%): Is the visual style right for this audience?
1209
877
  */
1210
- private validateSlide;
878
+ private assessAudienceAppropriate;
879
+ private isMinimalType;
880
+ private isDenseType;
881
+ private countWords;
882
+ private countLongWords;
1211
883
  /**
1212
- * Static HTML analysis fallback when Playwright isn't available.
1213
- * Analyzes CSS and HTML structure without rendering.
884
+ * Detect raw markdown syntax that should have been rendered to HTML.
885
+ * Returns array of issue descriptions.
1214
886
  */
1215
- private validateStaticHTML;
887
+ private detectRawMarkdown;
1216
888
  /**
1217
- * Generate remediation suggestions for layout issues.
889
+ * Check if slide type is appropriate for its content.
890
+ * Returns issue description if mismatched.
1218
891
  */
1219
- generateRemediationPlan(result: LayoutValidationResult): string[];
892
+ private checkSlideTypeMismatch;
893
+ private scoreToLevel;
894
+ private collectIssues;
895
+ private mapAssessmentToCategory;
896
+ private mapIssueCategory;
897
+ private generateImprovements;
898
+ private createCategoryScore;
1220
899
  }
900
+ declare function getSlideQualityReviewer(): SlideQualityReviewer;
901
+ declare function initSlideQualityReviewer(): Promise<SlideQualityReviewer>;
1221
902
 
1222
903
  /**
1223
- * Presentation Type Detector
904
+ * DeckQualityReviewer - HOLISTIC DECK QUALITY REVIEW
1224
905
  *
1225
- * Determines the appropriate presentation type based on:
1226
- * 1. Explicit presentationType configuration
1227
- * 2. Audience specification
1228
- * 3. Goal specification
1229
- * 4. Keyword analysis of content
1230
- * 5. Legacy mode fallback
906
+ * After all slides pass individual review, this evaluates the deck as a whole:
907
+ * 1. Narrative Flow (30%) - Does it tell a coherent story?
908
+ * 2. Visual Consistency (25%) - Is the same theme applied throughout?
909
+ * 3. Pacing & Rhythm (20%) - Is there variety and appropriate density?
910
+ * 4. Opening & Closing (15%) - Are first/last slides the strongest?
911
+ * 5. Overall Impression (10%) - Would you hire/invest based on this?
1231
912
  *
1232
- * Each presentation type has distinct validation rules that do not conflict.
913
+ * ALL rules come from the Knowledge Base. NO hardcoded fallbacks.
1233
914
  */
1234
915
 
1235
- /**
1236
- * Validation rules for each presentation type
1237
- */
1238
- declare const PRESENTATION_TYPE_RULES: Record<PresentationType, PresentationTypeRules>;
1239
- declare class TypeDetector {
1240
- /**
1241
- * Detect the presentation type from configuration.
1242
- * Priority:
1243
- * 1. Explicit presentationType
1244
- * 2. Audience mapping
1245
- * 3. Goal mapping
1246
- * 4. Content keyword analysis
1247
- * 5. Legacy mode fallback
1248
- */
1249
- detectType(config: PresentationConfig): PresentationType;
1250
- /**
1251
- * Detect presentation type from keyword analysis.
1252
- */
1253
- private detectFromKeywords;
1254
- /**
1255
- * Get validation rules for a presentation type.
1256
- */
1257
- getRules(type: PresentationType): PresentationTypeRules;
916
+ type DeckQualityLevel = 'excellent' | 'good' | 'acceptable' | 'poor' | 'failing';
917
+ interface DeckAssessment {
918
+ /** Score (0-100) */
919
+ score: number;
920
+ /** Quality level */
921
+ level: DeckQualityLevel;
922
+ /** WHY this score - specific reasoning */
923
+ reasoning: string;
924
+ /** KB reference for this assessment */
925
+ kbReference?: string;
926
+ }
927
+ interface QualitativeDeckReview {
928
+ /** Overall deck score (0-100, must be >= 95) */
929
+ score: number;
930
+ /** Would this deck impress the target audience? */
931
+ wouldImpress: boolean;
932
+ /** Detailed assessments */
933
+ assessments: {
934
+ narrativeFlow: DeckAssessment;
935
+ visualConsistency: DeckAssessment;
936
+ pacingRhythm: DeckAssessment;
937
+ openingClosing: DeckAssessment;
938
+ overallImpression: DeckAssessment;
939
+ };
940
+ /** Individual slide reviews */
941
+ slideReviews: QualitativeSlideReview[];
942
+ /** Deck-level issues */
943
+ issues: DeckIssue[];
944
+ /** Deck-level improvements */
945
+ improvements: string[];
946
+ }
947
+ interface DeckIssue {
948
+ severity: 'critical' | 'major' | 'minor';
949
+ category: 'narrative' | 'visual' | 'pacing' | 'structure';
950
+ issue: string;
951
+ fix: string;
952
+ affectedSlides?: number[];
953
+ kbReference?: string;
954
+ }
955
+ declare class DeckQualityReviewer {
956
+ private kb;
957
+ private slideReviewer;
958
+ private initialized;
959
+ private requiredElements;
960
+ private antiPatterns;
961
+ private hasSparkline;
962
+ private hasSCQA;
963
+ constructor();
964
+ initialize(): Promise<void>;
1258
965
  /**
1259
- * Get all available presentation types.
966
+ * Review the entire deck qualitatively.
1260
967
  */
1261
- getAvailableTypes(): PresentationType[];
968
+ review(slides: Slide[], presentationType: PresentationType): Promise<QualitativeDeckReview>;
1262
969
  /**
1263
- * Map legacy mode to a presentation type.
970
+ * Convert qualitative review to DeckScore format.
1264
971
  */
1265
- modeToType(mode: 'keynote' | 'business'): PresentationType;
972
+ toDeckScore(review: QualitativeDeckReview): DeckScore;
973
+ private loadRulesForType;
1266
974
  /**
1267
- * Map presentation type back to legacy mode for compatibility.
975
+ * Narrative Flow (30%): Does the presentation tell a coherent story?
1268
976
  */
1269
- typeToMode(type: PresentationType): 'keynote' | 'business';
977
+ private assessNarrativeFlow;
1270
978
  /**
1271
- * Get word limits for a presentation type.
979
+ * Visual Consistency (25%): Is the same theme applied throughout?
1272
980
  */
1273
- getWordLimits(type: PresentationType): {
1274
- min: number;
1275
- max: number;
1276
- ideal: number;
1277
- };
981
+ private assessVisualConsistency;
1278
982
  /**
1279
- * Check if action titles are required for a type.
983
+ * Pacing & Rhythm (20%): Is there variety in slide types and density?
1280
984
  */
1281
- requiresActionTitles(type: PresentationType): boolean;
985
+ private assessPacingRhythm;
1282
986
  /**
1283
- * Check if sources are required for a type.
987
+ * Opening & Closing (15%): Are the first and last slides the strongest?
1284
988
  */
1285
- requiresSources(type: PresentationType): boolean;
989
+ private assessOpeningClosing;
1286
990
  /**
1287
- * Get scoring weights for a presentation type.
991
+ * Overall Impression (10%): Would you hire/invest based on this?
1288
992
  */
1289
- getScoringWeights(type: PresentationType): {
1290
- visual_quality: number;
1291
- content_quality: number;
1292
- expert_compliance: number;
1293
- accessibility: number;
1294
- };
993
+ private assessOverallImpression;
994
+ private scoreToLevel;
995
+ private calculateVariance;
996
+ private getMissingRequiredElements;
997
+ private collectDeckIssues;
998
+ private mapAssessmentToCategory;
999
+ private mapDeckCategory;
1000
+ private generateDeckImprovements;
1001
+ private calculateRequiredElementsScore;
1002
+ private calculateAntiPatternScore;
1295
1003
  }
1004
+ declare function getDeckQualityReviewer(): DeckQualityReviewer;
1005
+ declare function initDeckQualityReviewer(): Promise<DeckQualityReviewer>;
1296
1006
 
1297
1007
  /**
1298
- * Execution Strategy Types
1008
+ * Remediator - Fix Failing Slides
1299
1009
  *
1300
- * Types for the presentation execution strategy system.
1301
- */
1302
-
1303
- /**
1304
- * A blueprint for a single slide in a presentation.
1305
- */
1306
- interface SlideBlueprint {
1307
- /** Unique identifier for this slide in the sequence */
1308
- id: string;
1309
- /** Human-readable name */
1310
- name: string;
1311
- /** Slide type to use */
1312
- type: SlideType;
1313
- /** Is this slide required or optional? */
1314
- required: boolean;
1315
- /** Purpose of this slide (for content guidance) */
1316
- purpose: string;
1317
- /** Data fields this slide needs */
1318
- requiredData: string[];
1319
- /** Optional data fields */
1320
- optionalData: string[];
1321
- /** Word count constraints */
1322
- wordLimits: {
1323
- min: number;
1324
- max: number;
1325
- ideal: number;
1326
- };
1327
- /** Expert principles that apply to this slide */
1328
- expertPrinciples: string[];
1329
- /** Visual design notes */
1330
- designNotes: string[];
1331
- /** Example content (for guidance) */
1332
- example?: {
1333
- title?: string;
1334
- subtitle?: string;
1335
- bullets?: string[];
1336
- body?: string;
1337
- };
1338
- }
1339
- /**
1340
- * A content transformation rule.
1341
- */
1342
- interface ContentTransform {
1343
- /** What to look for in the source content */
1344
- sourcePattern: string | RegExp;
1345
- /** How to transform it */
1346
- transform: (match: string, analysis: ContentAnalysis) => string;
1347
- /** Description of the transformation */
1348
- description: string;
1349
- }
1350
- /**
1351
- * An execution strategy for a presentation type.
1352
- */
1353
- interface ExecutionStrategy {
1354
- /** Presentation type this strategy is for */
1355
- type: PresentationType;
1356
- /** Human-readable name */
1357
- name: string;
1358
- /** Description */
1359
- description: string;
1360
- /** Expert methodologies to apply */
1361
- experts: {
1362
- primary: string;
1363
- secondary: string[];
1364
- };
1365
- /** The slide sequence (ordered list of blueprints) */
1366
- slideSequence: SlideBlueprint[];
1367
- /** Content transformation rules */
1368
- contentTransforms: ContentTransform[];
1369
- /** Quality benchmarks */
1370
- qualityBenchmarks: {
1371
- minScore: number;
1372
- criticalChecks: string[];
1373
- excellenceIndicators: string[];
1374
- };
1375
- /**
1376
- * Generate slides from content analysis.
1377
- */
1378
- generateSlides(analysis: ContentAnalysis): Promise<Slide[]>;
1379
- /**
1380
- * Validate slides against this strategy's requirements.
1381
- */
1382
- validateSlides(slides: Slide[]): {
1383
- passed: boolean;
1384
- score: number;
1385
- issues: string[];
1386
- suggestions: string[];
1387
- };
1388
- /**
1389
- * Apply expert methodology transformations.
1390
- */
1391
- applyExpertMethodology(slides: Slide[]): Slide[];
1392
- }
1393
-
1394
- /**
1395
- * Strategy Factory
1010
+ * When a slide fails qualitative review (< 95), this module attempts to fix it.
1011
+ * Maximum 3 remediation attempts per slide.
1012
+ *
1013
+ * Remediation strategies are based on the specific quality issues identified:
1014
+ * - Visual Impact: Increase title prominence, add visual elements
1015
+ * - Content Clarity: Reduce word count, simplify messaging
1016
+ * - Layout Balance: Redistribute content, improve alignment
1017
+ * - Typography Hierarchy: Adjust text sizes, create clearer hierarchy
1018
+ * - Whitespace Usage: Remove content or split slide
1019
+ * - Color Harmony: Ensure colors match theme
1020
+ * - Audience Appropriateness: Adjust density for audience
1396
1021
  *
1397
- * Selects the appropriate execution strategy based on presentation type.
1398
- * Each strategy encapsulates world-class expertise for its domain.
1022
+ * ALL rules come from the Knowledge Base. NO hardcoded fallbacks.
1399
1023
  */
1400
1024
 
1401
- /**
1402
- * Factory for creating presentation execution strategies.
1403
- */
1404
- declare class StrategyFactory {
1405
- private strategies;
1025
+ interface RemediationResult {
1026
+ /** Was remediation successful? */
1027
+ success: boolean;
1028
+ /** Original slide */
1029
+ originalSlide: Slide;
1030
+ /** Remediated slide (or original if failed) */
1031
+ remediatedSlide: Slide;
1032
+ /** Number of attempts made */
1033
+ attempts: number;
1034
+ /** Final score after remediation */
1035
+ finalScore: number;
1036
+ /** Review after remediation */
1037
+ finalReview: QualitativeSlideReview;
1038
+ /** Actions taken during remediation */
1039
+ actions: RemediationAction[];
1040
+ /** Why remediation failed (if it did) */
1041
+ failureReason?: string;
1042
+ }
1043
+ interface RemediationAction {
1044
+ /** What was done */
1045
+ action: string;
1046
+ /** Which issue it addressed */
1047
+ targetIssue: string;
1048
+ /** Score before this action */
1049
+ scoreBefore: number;
1050
+ /** Score after this action */
1051
+ scoreAfter: number;
1052
+ /** Was this action effective? */
1053
+ effective: boolean;
1054
+ }
1055
+ declare class Remediator {
1056
+ private kb;
1057
+ private reviewer;
1058
+ private initialized;
1059
+ private wordLimits;
1060
+ private bulletLimit;
1061
+ private maxAttempts;
1062
+ private targetScore;
1406
1063
  constructor();
1064
+ initialize(): Promise<void>;
1407
1065
  /**
1408
- * Get the execution strategy for a presentation type.
1066
+ * Attempt to remediate a failing slide.
1409
1067
  */
1410
- getStrategy(type: PresentationType): ExecutionStrategy;
1068
+ remediate(slide: Slide, presentationType: PresentationType, initialReview: QualitativeSlideReview): Promise<RemediationResult>;
1411
1069
  /**
1412
- * Get all available strategies.
1070
+ * Batch remediate multiple slides.
1413
1071
  */
1414
- getAllStrategies(): ExecutionStrategy[];
1415
- /**
1416
- * Get strategy descriptions for user guidance.
1417
- */
1418
- getStrategyDescriptions(): Record<PresentationType, string>;
1419
- /**
1420
- * Get the primary expert for a presentation type.
1421
- */
1422
- getPrimaryExpert(type: PresentationType): string;
1423
- /**
1424
- * Get all experts for a presentation type.
1425
- */
1426
- getAllExperts(type: PresentationType): string[];
1072
+ remediateBatch(slides: Slide[], reviews: QualitativeSlideReview[], presentationType: PresentationType): Promise<RemediationResult[]>;
1073
+ private loadRulesForType;
1074
+ private prioritizeIssues;
1075
+ private applyFix;
1076
+ private fixVisualIssue;
1077
+ private fixContentIssue;
1078
+ private fixLayoutIssue;
1079
+ private fixTypographyIssue;
1080
+ private fixAccessibilityIssue;
1081
+ private cloneSlide;
1082
+ private truncateToWords;
1083
+ private isMinimalType;
1084
+ private countWords;
1427
1085
  }
1086
+ declare function getRemediator(): Remediator;
1087
+ declare function initRemediator(): Promise<Remediator>;
1428
1088
 
1429
1089
  /**
1430
- * Reveal.js Generator - HTML Presentation Output
1090
+ * Renderer - Premium HTML/PPTX Output Generation
1091
+ *
1092
+ * Renders slides to high-quality outputs:
1093
+ * - HTML: Reveal.js with premium CSS from KB
1094
+ * - PPTX: PowerPoint (future implementation)
1431
1095
  *
1432
- * Generates complete Reveal.js presentations with:
1433
- * - Responsive layouts
1434
- * - Animations
1435
- * - Speaker notes
1436
- * - Custom themes
1437
- * - Chart.js integration
1438
- * - Mermaid diagrams
1096
+ * ALL styling comes from the Knowledge Base and VisualDesignSystem.
1097
+ * NO hardcoded styles.
1439
1098
  */
1440
1099
 
1441
- declare class RevealJsGenerator {
1442
- private templateEngine;
1443
- private defaultRevealConfig;
1100
+ interface RenderOptions {
1101
+ /** Presentation title */
1102
+ title: string;
1103
+ /** Author name */
1104
+ author?: string;
1105
+ /** Presentation type */
1106
+ presentationType: PresentationType;
1107
+ /** Metadata */
1108
+ metadata?: PresentationMetadata;
1109
+ /** Local images to use as backgrounds */
1110
+ images?: string[];
1111
+ /** Base path for resolving relative image paths */
1112
+ imageBasePath?: string;
1113
+ }
1114
+ interface RenderResult {
1115
+ html?: string;
1116
+ pptx?: Buffer;
1117
+ }
1118
+ declare class Renderer {
1119
+ private kb;
1120
+ private vds;
1121
+ private initialized;
1122
+ private readonly slideImageKeywords;
1444
1123
  constructor();
1124
+ initialize(): Promise<void>;
1445
1125
  /**
1446
- * Generate complete Reveal.js HTML presentation.
1126
+ * Render slides to specified formats.
1447
1127
  */
1448
- generate(slides: Slide[], config: PresentationConfig): Promise<string>;
1128
+ render(slides: Slide[], formats: OutputFormat[], options: RenderOptions): Promise<RenderResult>;
1129
+ private renderHTML;
1130
+ private generateCSS;
1131
+ private renderSlide;
1132
+ private renderTitleSlide;
1133
+ private renderSectionDivider;
1134
+ private renderMetricsSlide;
1135
+ private renderQuoteSlide;
1136
+ private renderStarMomentSlide;
1137
+ private renderCTASlide;
1138
+ private renderThankYouSlide;
1139
+ private renderTwoColumnSlide;
1140
+ private renderThreeColumnSlide;
1141
+ private renderContentSlide;
1142
+ private renderPPTX;
1143
+ private formatCSSVariables;
1144
+ private escapeHTML;
1449
1145
  /**
1450
- * Build the complete HTML document.
1146
+ * Generate a background image URL based on slide type and content.
1147
+ * Priority: 1) slide.data.image, 2) local images array, 3) Picsum fallback
1451
1148
  */
1452
- private buildDocument;
1149
+ private getBackgroundImageUrl;
1453
1150
  /**
1454
- * Get base styles for slides.
1455
- *
1456
- * BULLETPROOF OVERFLOW PROTECTION:
1457
- * 1. All slides use height: 100vh to match viewport exactly
1458
- * 2. overflow: hidden on slide sections clips content at boundaries
1459
- * 3. All child elements use flex-shrink: 1 and min-height: 0 to allow shrinking
1460
- * 4. Tables use max-height with overflow: auto for scrolling if needed
1461
- * 5. Two-column layouts use smaller font sizes to prevent overflow
1151
+ * Resolve an image path - handles relative paths, absolute paths, and URLs.
1462
1152
  */
1463
- private getBaseStyles;
1153
+ private resolveImagePath;
1464
1154
  /**
1465
- * Get theme-specific styles.
1155
+ * Generate fallback image URL using Picsum with smart seeding.
1466
1156
  */
1467
- private getThemeStyles;
1157
+ private getFallbackImageUrl;
1468
1158
  /**
1469
- * Get animation styles.
1159
+ * Convert markdown syntax to HTML.
1160
+ * Handles: bold, italic, code, links, and basic formatting.
1161
+ * Called BEFORE escapeHTML to preserve markdown-generated HTML tags.
1470
1162
  */
1471
- private getAnimationStyles;
1163
+ private renderMarkdown;
1472
1164
  /**
1473
- * Escape HTML entities.
1165
+ * Clean up broken/truncated markdown that can't be properly rendered.
1166
+ * Removes partial code blocks, inline tables, etc.
1474
1167
  */
1475
- private escapeHtml;
1168
+ private cleanBrokenMarkdown;
1476
1169
  /**
1477
- * Basic HTML minification.
1170
+ * Render markdown tables to HTML tables.
1478
1171
  */
1479
- private minifyHtml;
1172
+ private renderMarkdownTables;
1173
+ /**
1174
+ * Build an HTML table from markdown table rows.
1175
+ */
1176
+ private buildHTMLTable;
1480
1177
  }
1178
+ declare function getRenderer(): Renderer;
1179
+ declare function initRenderer(): Promise<Renderer>;
1481
1180
 
1482
1181
  /**
1483
- * PowerPoint Generator - PPTX Presentation Output
1182
+ * NanoBanana Pro Image Generation Provider
1183
+ *
1184
+ * Integrates with Google Gemini's image generation capabilities via NanoBanana Pro.
1185
+ * Generates high-quality hero images, concept illustrations, and visual assets
1186
+ * for presentation slides.
1187
+ *
1188
+ * Requires: GOOGLE_AI_API_KEY environment variable
1484
1189
  *
1485
- * Generates PowerPoint presentations using PptxGenJS with:
1486
- * - Professional layouts
1487
- * - Embedded charts
1488
- * - Images
1489
- * - Consistent styling
1190
+ * Usage:
1191
+ * const provider = createNanoBananaProvider();
1192
+ * if (await provider.isAvailable()) {
1193
+ * const imageUrl = await provider.generateHeroImage('AI revolution');
1194
+ * }
1490
1195
  */
1491
-
1492
- type PptxSlide = ReturnType<PptxGenJS['addSlide']>;
1493
- declare const COLORS: {
1494
- primary: string;
1495
- secondary: string;
1496
- accent: string;
1497
- highlight: string;
1498
- white: string;
1499
- lightGray: string;
1500
- };
1501
- declare class PowerPointGenerator {
1502
- private chartProvider;
1503
- /**
1504
- * Generate a PowerPoint presentation.
1505
- */
1506
- generate(slides: Slide[], config: PresentationConfig): Promise<Buffer>;
1507
- /**
1508
- * Add a slide to the presentation.
1509
- */
1510
- private addSlide;
1511
- /**
1512
- * Add title slide.
1513
- */
1514
- private addTitleSlide;
1515
- /**
1516
- * Add big idea / single statement slide.
1517
- */
1518
- private addBigIdeaSlide;
1519
- /**
1520
- * Add big number slide.
1521
- */
1522
- private addBigNumberSlide;
1523
- /**
1524
- * Add quote slide.
1525
- */
1526
- private addQuoteSlide;
1527
- /**
1528
- * Add bullet points slide.
1529
- */
1530
- private addBulletSlide;
1531
- /**
1532
- * Add two-column slide.
1533
- */
1534
- private addTwoColumnSlide;
1535
- /**
1536
- * Add metrics grid slide.
1537
- */
1538
- private addMetricsSlide;
1196
+ interface ImageGenerationRequest {
1197
+ /** The concept or topic to visualize */
1198
+ concept: string;
1199
+ /** Image style/type */
1200
+ style: 'hero' | 'concept' | 'icon' | 'background' | 'diagram';
1201
+ /** Presentation type for context */
1202
+ presentationType?: string;
1203
+ /** Aspect ratio */
1204
+ aspectRatio?: '16:9' | '4:3' | '1:1' | '9:16';
1205
+ /** Color scheme preference */
1206
+ colorScheme?: 'dark' | 'light' | 'vibrant' | 'muted';
1207
+ }
1208
+ interface ImageGenerationResult {
1209
+ /** Whether generation succeeded */
1210
+ success: boolean;
1211
+ /** Generated image URL or base64 data */
1212
+ imageUrl?: string;
1213
+ /** Base64 encoded image data */
1214
+ imageData?: string;
1215
+ /** MIME type of the image */
1216
+ mimeType?: string;
1217
+ /** Error message if failed */
1218
+ error?: string;
1219
+ /** Prompt used for generation */
1220
+ promptUsed?: string;
1221
+ }
1222
+ interface NanoBananaConfig {
1223
+ /** Google AI API key (defaults to GOOGLE_AI_API_KEY env var) */
1224
+ apiKey?: string;
1225
+ /** Model to use (defaults to gemini-2.0-flash-exp for image generation) */
1226
+ model?: string;
1227
+ /** Timeout in milliseconds */
1228
+ timeout?: number;
1229
+ /** Enable verbose logging */
1230
+ verbose?: boolean;
1231
+ }
1232
+ /**
1233
+ * NanoBanana Pro image generation provider.
1234
+ * Uses Google Gemini's image generation capabilities.
1235
+ */
1236
+ declare class NanoBananaProvider {
1237
+ readonly name = "NanoBanana Pro";
1238
+ private apiKey;
1239
+ private model;
1240
+ private timeout;
1241
+ private verbose;
1242
+ constructor(config?: NanoBananaConfig);
1539
1243
  /**
1540
- * Add metrics to a slide at specified position.
1244
+ * Check if NanoBanana is available (API key present).
1541
1245
  */
1542
- private addMetricsToSlide;
1246
+ isAvailable(): Promise<boolean>;
1543
1247
  /**
1544
- * Add thank you slide.
1248
+ * Generate a hero image for a slide.
1545
1249
  */
1546
- private addThankYouSlide;
1250
+ generateHeroImage(concept: string): Promise<ImageGenerationResult>;
1547
1251
  /**
1548
- * Add agenda slide.
1252
+ * Generate a concept illustration.
1549
1253
  */
1550
- private addAgendaSlide;
1254
+ generateConceptImage(concept: string): Promise<ImageGenerationResult>;
1551
1255
  /**
1552
- * Add section divider slide.
1256
+ * Generate an icon or symbol.
1553
1257
  */
1554
- private addSectionDividerSlide;
1258
+ generateIcon(concept: string): Promise<ImageGenerationResult>;
1555
1259
  /**
1556
- * Add default slide (fallback).
1260
+ * Generate a background image.
1557
1261
  */
1558
- private addDefaultSlide;
1262
+ generateBackground(concept: string, colorScheme?: 'dark' | 'light'): Promise<ImageGenerationResult>;
1559
1263
  /**
1560
- * Add image placeholder.
1264
+ * Generate an image based on request parameters.
1561
1265
  */
1562
- private addImagePlaceholder;
1266
+ generate(request: ImageGenerationRequest): Promise<ImageGenerationResult>;
1563
1267
  /**
1564
- * Convert layout position to PptxGenJS text props.
1268
+ * Build an optimized prompt for image generation.
1565
1269
  */
1566
- private positionToProps;
1270
+ private buildPrompt;
1567
1271
  /**
1568
- * Add Football Field Valuation Chart (IB Standard)
1569
- * Shows valuation ranges across different methodologies
1272
+ * Call the Gemini API for image generation.
1570
1273
  */
1571
- addFootballFieldChart(pptxSlide: PptxSlide, data: {
1572
- title: string;
1573
- methodologies: Array<{
1574
- name: string;
1575
- low: number;
1576
- mid: number;
1577
- high: number;
1578
- color?: string;
1579
- }>;
1580
- currentPrice?: number;
1581
- }, bounds: {
1582
- x: number;
1583
- y: number;
1584
- w: number;
1585
- h: number;
1586
- }, colors?: typeof COLORS): void;
1587
- /**
1588
- * Add Waterfall Chart (IB Standard)
1589
- * Shows incremental changes leading to a final value
1590
- */
1591
- addWaterfallChart(pptxSlide: PptxSlide, data: {
1592
- title: string;
1593
- startLabel: string;
1594
- startValue: number;
1595
- steps: Array<{
1596
- label: string;
1597
- value: number;
1598
- isTotal?: boolean;
1599
- }>;
1600
- endLabel?: string;
1601
- }, bounds: {
1602
- x: number;
1603
- y: number;
1604
- w: number;
1605
- h: number;
1606
- }, colors?: typeof COLORS): void;
1607
- /**
1608
- * Add Sources & Uses Table (IB Standard)
1609
- * Common in M&A presentations
1610
- */
1611
- addSourcesUsesTable(pptxSlide: PptxSlide, data: {
1612
- title: string;
1613
- sources: Array<{
1614
- label: string;
1615
- amount: number;
1616
- percentage?: number;
1617
- }>;
1618
- uses: Array<{
1619
- label: string;
1620
- amount: number;
1621
- percentage?: number;
1622
- }>;
1623
- }, bounds: {
1624
- x: number;
1625
- y: number;
1626
- w: number;
1627
- h: number;
1628
- }, colors?: typeof COLORS): void;
1629
- /**
1630
- * Add Comparable Companies Table (Comps - IB Standard)
1631
- */
1632
- addCompsTable(pptxSlide: PptxSlide, data: {
1633
- title: string;
1634
- columns: string[];
1635
- companies: Array<{
1636
- name: string;
1637
- values: (string | number)[];
1638
- highlight?: boolean;
1639
- }>;
1640
- medianRow?: boolean;
1641
- }, bounds: {
1642
- x: number;
1643
- y: number;
1644
- w: number;
1645
- h: number;
1646
- }, colors?: typeof COLORS): void;
1274
+ private callGeminiAPI;
1647
1275
  }
1648
-
1649
1276
  /**
1650
- * Image Provider - Pluggable Image Generation
1651
- *
1652
- * Provides multiple strategies for obtaining images:
1653
- * - Local: User-provided paths/URLs
1654
- * - Placeholder: Uses picsum.photos (no API key)
1655
- * - Unsplash: Free API (50 req/hour, optional key)
1656
- * - AI: Claude Code integration (when available)
1657
- */
1658
- interface ImageRequest {
1659
- /** Description of desired image */
1660
- description: string;
1661
- /** Desired width */
1662
- width?: number;
1663
- /** Desired height */
1664
- height?: number;
1665
- /** Style hints (e.g., 'professional', 'minimal', 'vibrant') */
1666
- style?: string;
1667
- /** Category for filtering (e.g., 'business', 'technology', 'nature') */
1668
- category?: string;
1669
- }
1670
- interface ImageResult {
1671
- /** URL or data URI of the image */
1672
- src: string;
1673
- /** Alt text for accessibility */
1674
- alt: string;
1675
- /** Attribution if required */
1676
- attribution?: string;
1677
- /** Whether this is a placeholder */
1678
- isPlaceholder?: boolean;
1679
- }
1680
- interface ImageProvider {
1681
- /** Provider name */
1682
- name: string;
1683
- /** Check if provider is available */
1684
- isAvailable(): Promise<boolean>;
1685
- /** Get an image matching the request */
1686
- getImage(request: ImageRequest): Promise<ImageResult>;
1687
- /** Get multiple images */
1688
- getImages(requests: ImageRequest[]): Promise<ImageResult[]>;
1689
- }
1690
- /**
1691
- * Local Image Provider - Uses user-provided images
1692
- */
1693
- declare class LocalImageProvider implements ImageProvider {
1694
- name: string;
1695
- private images;
1696
- constructor(imageMap?: Record<string, string>);
1697
- isAvailable(): Promise<boolean>;
1698
- getImage(request: ImageRequest): Promise<ImageResult>;
1699
- getImages(requests: ImageRequest[]): Promise<ImageResult[]>;
1700
- private getPlaceholderUrl;
1701
- /** Register an image for later use */
1702
- registerImage(name: string, src: string): void;
1703
- }
1704
- /**
1705
- * Placeholder Image Provider - Uses picsum.photos (no API key needed)
1706
- */
1707
- declare class PlaceholderImageProvider implements ImageProvider {
1708
- name: string;
1709
- isAvailable(): Promise<boolean>;
1710
- getImage(request: ImageRequest): Promise<ImageResult>;
1711
- getImages(requests: ImageRequest[]): Promise<ImageResult[]>;
1712
- private hashString;
1713
- }
1714
- /**
1715
- * Unsplash Image Provider - Uses Unsplash API (free tier: 50 req/hour)
1277
+ * Create a new NanoBanana provider instance.
1716
1278
  */
1717
- declare class UnsplashImageProvider implements ImageProvider {
1718
- name: string;
1719
- private accessKey?;
1720
- private baseUrl;
1721
- constructor(accessKey?: string);
1722
- isAvailable(): Promise<boolean>;
1723
- getImage(request: ImageRequest): Promise<ImageResult>;
1724
- getImages(requests: ImageRequest[]): Promise<ImageResult[]>;
1725
- private getSourceImage;
1726
- private delay;
1727
- }
1728
- /**
1729
- * Composite Image Provider - Tries providers in order
1730
- */
1731
- declare class CompositeImageProvider implements ImageProvider {
1732
- name: string;
1733
- private providers;
1734
- constructor(providers: ImageProvider[]);
1735
- isAvailable(): Promise<boolean>;
1736
- getImage(request: ImageRequest): Promise<ImageResult>;
1737
- getImages(requests: ImageRequest[]): Promise<ImageResult[]>;
1738
- }
1279
+ declare function createNanoBananaProvider(config?: NanoBananaConfig): NanoBananaProvider;
1739
1280
  /**
1740
- * Create default image provider chain
1281
+ * Get a pre-built prompt for a specific image type.
1282
+ * Useful for customization or debugging.
1741
1283
  */
1742
- declare function createDefaultImageProvider(options?: {
1743
- localImages?: Record<string, string>;
1744
- unsplashKey?: string;
1745
- }): ImageProvider;
1284
+ declare function getNanoBananaPrompt(style: 'hero' | 'concept' | 'icon' | 'background' | 'diagram', concept: string, presentationType?: string): string;
1746
1285
 
1747
1286
  /**
1748
- * Chart Provider - Pluggable Chart Generation
1287
+ * CodeQualityValidator - Detects Hardcoded Values in Source Code
1749
1288
  *
1750
- * Provides multiple strategies for creating charts:
1751
- * - ChartJS: Embedded in HTML (no API needed)
1752
- * - QuickChart: Remote rendering (no API key needed)
1753
- * - Mermaid: Diagrams and flowcharts (no API needed)
1754
- */
1755
- type ChartType = 'bar' | 'line' | 'pie' | 'doughnut' | 'radar' | 'polarArea' | 'scatter' | 'bubble';
1756
- interface ChartDataset {
1757
- label: string;
1758
- data: number[];
1759
- backgroundColor?: string | string[];
1760
- borderColor?: string | string[];
1761
- borderWidth?: number;
1762
- }
1763
- interface ChartData {
1764
- labels: string[];
1765
- datasets: ChartDataset[];
1766
- }
1767
- interface ChartRequest {
1768
- /** Chart type */
1769
- type: ChartType;
1770
- /** Chart data */
1771
- data: ChartData;
1772
- /** Chart title */
1773
- title?: string;
1774
- /** Width in pixels */
1775
- width?: number;
1776
- /** Height in pixels */
1777
- height?: number;
1778
- /** Show legend */
1779
- showLegend?: boolean;
1780
- /** Animation enabled (HTML only) */
1781
- animated?: boolean;
1782
- /** Color palette to use */
1783
- palette?: 'default' | 'professional' | 'vibrant' | 'monochrome';
1784
- }
1785
- interface ChartResult {
1786
- /** HTML for embedding (Chart.js canvas) */
1787
- html?: string;
1788
- /** Image URL for static contexts (PPTX) */
1789
- imageUrl?: string;
1790
- /** Base64 data URI */
1791
- dataUri?: string;
1792
- /** Chart title for accessibility */
1793
- title: string;
1794
- }
1795
- interface ChartProvider {
1796
- /** Provider name */
1797
- name: string;
1798
- /** Check if provider is available */
1799
- isAvailable(): Promise<boolean>;
1800
- /** Generate a chart */
1801
- generateChart(request: ChartRequest): Promise<ChartResult>;
1802
- }
1803
- /**
1804
- * Chart.js Provider - Generates embedded Chart.js HTML
1805
- * No API needed - runs in browser
1806
- */
1807
- declare class ChartJsProvider implements ChartProvider {
1808
- name: string;
1809
- isAvailable(): Promise<boolean>;
1810
- generateChart(request: ChartRequest): Promise<ChartResult>;
1811
- }
1812
- /**
1813
- * QuickChart Provider - Uses quickchart.io for image generation
1814
- * No API key needed - free service
1815
- */
1816
- declare class QuickChartProvider implements ChartProvider {
1817
- name: string;
1818
- private baseUrl;
1819
- isAvailable(): Promise<boolean>;
1820
- generateChart(request: ChartRequest): Promise<ChartResult>;
1821
- }
1822
- /**
1823
- * Mermaid Provider - Generates diagrams using Mermaid.js
1824
- * No API needed - renders in browser
1825
- */
1826
- declare class MermaidProvider implements ChartProvider {
1827
- name: string;
1828
- isAvailable(): Promise<boolean>;
1829
- generateChart(request: ChartRequest): Promise<ChartResult>;
1830
- /**
1831
- * Generate a Mermaid diagram
1832
- */
1833
- generateDiagram(definition: string, title?: string): Promise<ChartResult>;
1834
- /**
1835
- * Generate flowchart from steps
1836
- */
1837
- generateFlowchart(steps: {
1838
- id: string;
1839
- label: string;
1840
- next?: string[];
1841
- }[]): string;
1842
- /**
1843
- * Generate timeline from events
1844
- */
1845
- generateTimeline(events: {
1846
- date: string;
1847
- title: string;
1848
- }[]): string;
1849
- }
1850
- /**
1851
- * Composite Chart Provider
1852
- */
1853
- declare class CompositeChartProvider implements ChartProvider {
1854
- name: string;
1855
- private htmlProvider;
1856
- private imageProvider;
1857
- private mermaidProvider;
1858
- constructor();
1859
- isAvailable(): Promise<boolean>;
1860
- generateChart(request: ChartRequest): Promise<ChartResult>;
1861
- generateDiagram(definition: string, title?: string): Promise<ChartResult>;
1862
- generateFlowchart(steps: {
1863
- id: string;
1864
- label: string;
1865
- next?: string[];
1866
- }[]): string;
1867
- generateTimeline(events: {
1868
- date: string;
1869
- title: string;
1870
- }[]): string;
1871
- }
1872
- /**
1873
- * Create default chart provider
1874
- */
1875
- declare function createDefaultChartProvider(): CompositeChartProvider;
1876
-
1877
- /**
1878
- * Knowledge Base - RuVector Expert Principles Loader
1289
+ * This validator scans TypeScript/JavaScript source files for hardcoded CSS values,
1290
+ * colors, and dimensions that should be coming from the Knowledge Base.
1879
1291
  *
1880
- * Loads and provides access to the 6,300+ line expert knowledge base
1881
- * containing methodologies from 40+ presentation experts.
1292
+ * RATIONALE: ALL styling decisions must come from the KB. Hardcoded values:
1293
+ * 1. Break the single-source-of-truth principle
1294
+ * 2. Make theme changes inconsistent
1295
+ * 3. Bypass QA validation
1296
+ * 4. Create maintenance nightmares
1882
1297
  *
1883
- * This runs WITHOUT any API - it's static data bundled with the package.
1298
+ * This validator catches these careless errors at build/test time.
1884
1299
  */
1885
- interface ExpertPrinciple {
1886
- name: string;
1887
- description: string;
1888
- validation?: string[];
1889
- examples?: string[];
1890
- }
1891
- interface ExpertMethodology {
1892
- name: string;
1893
- principles: ExpertPrinciple[];
1894
- slideTypes?: string[];
1895
- wordLimits?: {
1896
- min?: number;
1897
- max?: number;
1898
- };
1300
+ interface HardcodedViolation {
1301
+ file: string;
1302
+ line: number;
1303
+ column: number;
1304
+ type: 'color' | 'dimension' | 'font' | 'shadow' | 'rgba' | 'gradient';
1305
+ value: string;
1306
+ context: string;
1307
+ severity: 'error' | 'warning';
1308
+ suggestion: string;
1899
1309
  }
1900
- interface AutomatedQA {
1901
- scoringRubric: {
1902
- totalPoints: number;
1903
- passingThreshold: number;
1904
- categories: Record<string, {
1905
- weight: number;
1906
- checks: Record<string, unknown>;
1907
- }>;
1310
+ interface ValidationResult {
1311
+ passed: boolean;
1312
+ violations: HardcodedViolation[];
1313
+ summary: {
1314
+ totalFiles: number;
1315
+ filesWithViolations: number;
1316
+ totalViolations: number;
1317
+ byType: Record<string, number>;
1318
+ bySeverity: Record<string, number>;
1908
1319
  };
1909
1320
  }
1910
- declare class KnowledgeBase {
1911
- private data;
1912
- private loaded;
1913
- /**
1914
- * Load the knowledge base from the bundled YAML file.
1915
- */
1916
- load(): Promise<void>;
1321
+ declare class CodeQualityValidator {
1322
+ private srcDir;
1323
+ private violations;
1324
+ constructor(srcDir: string);
1917
1325
  /**
1918
- * Get expert methodology by name.
1326
+ * Validate all TypeScript files in the source directory.
1919
1327
  */
1920
- getExpert(name: string): ExpertMethodology | undefined;
1328
+ validate(): Promise<ValidationResult>;
1921
1329
  /**
1922
- * Get all expert names.
1330
+ * Validate a single file for hardcoded values.
1923
1331
  */
1924
- getExpertNames(): string[];
1332
+ private validateFile;
1333
+ private checkForHexColors;
1334
+ private checkForRgbaColors;
1335
+ private checkForDimensions;
1336
+ private checkForGradients;
1337
+ private findTypeScriptFiles;
1338
+ private shouldSkipFile;
1339
+ private isExemptLine;
1340
+ private buildResult;
1925
1341
  /**
1926
- * Get framework recommendation for audience.
1342
+ * Format validation results for console output.
1927
1343
  */
1928
- getFrameworkForAudience(audience: string): {
1929
- primaryFramework: string;
1930
- secondaryFramework?: string;
1931
- slideTypes: string[];
1932
- } | undefined;
1933
- /**
1934
- * Get framework recommendation for goal.
1935
- */
1936
- getFrameworkForGoal(goal: string): {
1937
- primaryFramework: string;
1938
- secondaryFramework?: string;
1939
- slideTypes: string[];
1940
- } | undefined;
1941
- /**
1942
- * Get QA scoring rubric.
1943
- */
1944
- getScoringRubric(): AutomatedQA['scoringRubric'] | undefined;
1945
- /**
1946
- * Get mode configuration (keynote or business).
1947
- */
1948
- getModeConfig(mode: 'keynote' | 'business'): unknown;
1949
- /**
1950
- * Get slide type configuration.
1951
- */
1952
- getSlideType(type: string): unknown;
1953
- /**
1954
- * Get the knowledge base version.
1955
- */
1956
- getVersion(): string;
1957
- /**
1958
- * Validate a slide against expert principles.
1959
- */
1960
- validateAgainstExpert(expertName: string, slideData: {
1961
- wordCount: number;
1962
- hasActionTitle: boolean;
1963
- bulletCount: number;
1964
- }): {
1965
- passed: boolean;
1966
- violations: string[];
1967
- };
1968
- /**
1969
- * Ensure knowledge base is loaded.
1970
- */
1971
- private ensureLoaded;
1972
- /**
1973
- * Get default data if YAML can't be loaded.
1974
- */
1975
- private getDefaultData;
1344
+ formatResults(result: ValidationResult): string;
1976
1345
  }
1977
1346
  /**
1978
- * Get the knowledge base singleton.
1347
+ * Run code quality validation on the source directory.
1979
1348
  */
1980
- declare function getKnowledgeBase(): KnowledgeBase;
1981
-
1349
+ declare function validateCodeQuality(srcDir: string): Promise<ValidationResult>;
1982
1350
  /**
1983
- * Claude Presentation Master
1984
- *
1985
- * Generate world-class presentations using expert methodologies from
1986
- * Duarte, Reynolds, Gallo, and Anderson. Enforces rigorous quality
1987
- * standards through real visual validation.
1988
- *
1989
- * @packageDocumentation
1990
- * @module claude-presentation-master
1991
- * @author Stuart Kerr <stuart@isovision.ai>
1992
- * @license MIT
1351
+ * Run validation and print results to console.
1993
1352
  */
1353
+ declare function runCodeQualityCheck(srcDir: string): Promise<boolean>;
1994
1354
 
1995
1355
  /**
1996
- * Generate a presentation from content.
1997
- *
1998
- * @example
1999
- * ```typescript
2000
- * import { generate } from '@isovision/claude-presentation-master';
2001
- *
2002
- * const result = await generate({
2003
- * content: '# My Presentation\n\n...',
2004
- * contentType: 'markdown',
2005
- * mode: 'keynote',
2006
- * format: ['html', 'pptx'],
2007
- * qaThreshold: 95,
2008
- * title: 'My Amazing Presentation'
2009
- * });
2010
- *
2011
- * console.log(`Score: ${result.score}/100`);
2012
- * ```
2013
- *
2014
- * @param config - Presentation configuration
2015
- * @returns Presentation result with outputs, QA results, and score
2016
- * @throws {ValidationError} If input validation fails
2017
- * @throws {QAFailureError} If QA score is below threshold
2018
- */
2019
- declare function generate(config: PresentationConfig): Promise<PresentationResult>;
2020
- /**
2021
- * Validate an existing presentation.
2022
- *
2023
- * @example
2024
- * ```typescript
2025
- * import { validate } from '@isovision/claude-presentation-master';
2026
- * import fs from 'fs';
1356
+ * Claude Presentation Master - Main API
2027
1357
  *
2028
- * const html = fs.readFileSync('presentation.html', 'utf-8');
2029
- * const result = await validate(html, { mode: 'keynote' });
1358
+ * Entry point for the qualitative-first presentation engine.
1359
+ * Every slide must score 95/100 based on REAL qualitative excellence.
2030
1360
  *
2031
- * console.log(`Score: ${result.score}/100`);
2032
- * console.log(`Passed: ${result.passed}`);
2033
- * ```
1361
+ * Flow:
1362
+ * 1. ContentAnalyzer -> Parse and detect structure
1363
+ * 2. SlideGenerator -> Generate slides with visual intent
1364
+ * 3. SlideQualityReviewer -> Qualitative review per slide (must pass 95)
1365
+ * 4. Remediator -> Fix failing slides (3 attempts max)
1366
+ * 5. DeckQualityReviewer -> Holistic deck review (must pass 95)
1367
+ * 6. Renderer -> Premium HTML/PPTX output
2034
1368
  *
2035
- * @param presentation - HTML string or file buffer
2036
- * @param options - Validation options
2037
- * @returns QA validation results
2038
- */
2039
- declare function validate(presentation: string | Buffer, options?: {
2040
- mode?: 'keynote' | 'business';
2041
- threshold?: number;
2042
- strictMode?: boolean;
2043
- }): Promise<QAResults & {
2044
- score: number;
2045
- }>;
2046
- /**
2047
- * Get the version of the package.
1369
+ * ALL decisions come from the Knowledge Base. NO hardcoded fallbacks.
2048
1370
  */
1371
+
2049
1372
  declare const VERSION = "2.0.0";
1373
+ interface GenerateOptions {
1374
+ /** Input content (Markdown, text, etc.) */
1375
+ content: string;
1376
+ /** Content type */
1377
+ contentType?: 'markdown' | 'text';
1378
+ /** Output formats to generate */
1379
+ format?: OutputFormat[];
1380
+ /** Output directory */
1381
+ outputDir?: string;
1382
+ /** Presentation title (optional, will be detected from content) */
1383
+ title?: string;
1384
+ /** Author name */
1385
+ author?: string;
1386
+ /** Explicit presentation type (optional, will be detected from content) */
1387
+ presentationType?: PresentationType;
1388
+ /** Legacy mode (maps to presentation type) */
1389
+ mode?: PresentationMode;
1390
+ /** Minimum score threshold (default: 95) */
1391
+ qaThreshold?: number;
1392
+ /** Skip remediation (fail fast) */
1393
+ skipRemediation?: boolean;
1394
+ /** Verbose logging */
1395
+ verbose?: boolean;
1396
+ /** Local images to use as backgrounds (paths relative to output or absolute URLs) */
1397
+ images?: string[];
1398
+ /** Base path for resolving relative image paths */
1399
+ imageBasePath?: string;
1400
+ }
1401
+ interface GenerateResult {
1402
+ /** Generated outputs */
1403
+ outputs: {
1404
+ html?: string;
1405
+ pptx?: Buffer;
1406
+ };
1407
+ /** Final slides */
1408
+ slides: Slide[];
1409
+ /** Overall score (0-100) */
1410
+ score: number;
1411
+ /** Detailed deck score */
1412
+ deckScore?: QualitativeDeckReview | undefined;
1413
+ /** Metadata */
1414
+ metadata: {
1415
+ title: string;
1416
+ author: string;
1417
+ presentationType: PresentationType;
1418
+ generatedAt: string;
1419
+ slideCount: number;
1420
+ totalWords: number;
1421
+ avgWordsPerSlide: number;
1422
+ };
1423
+ /** Remediation results (if any slides were fixed) */
1424
+ remediations?: RemediationResult[] | undefined;
1425
+ /** Any warnings (non-fatal issues) */
1426
+ warnings?: string[] | undefined;
1427
+ }
2050
1428
  /**
2051
- * Default export for convenience.
1429
+ * Generate a presentation from content.
1430
+ *
1431
+ * This is the main entry point. It orchestrates:
1432
+ * 1. Content analysis
1433
+ * 2. Slide generation
1434
+ * 3. Qualitative review (95/100 threshold)
1435
+ * 4. Remediation (3 attempts per failing slide)
1436
+ * 5. Deck-level review
1437
+ * 6. Rendering to HTML/PPTX
2052
1438
  */
2053
- declare const _default: {
2054
- generate: typeof generate;
2055
- validate: typeof validate;
2056
- PresentationEngine: typeof PresentationEngine;
2057
- QAEngine: typeof QAEngine;
2058
- PPTXValidator: typeof PPTXValidator;
2059
- AccessibilityValidator: typeof AccessibilityValidator;
2060
- VERSION: string;
2061
- };
1439
+ declare function generate(options: GenerateOptions): Promise<GenerateResult>;
2062
1440
 
2063
- export { type AccessibilityResults, AccessibilityValidator, AutoRemediation, type ChartData, type ChartDataset, ChartJsProvider, type ChartProvider, type ChartRequest, type ChartResult, type ChartType, CompositeChartProvider, CompositeImageProvider, type ContentAnalysis, ContentAnalyzer, type ContentQAResults, type ContentTransform, type ContrastIssue, type ExecutionStrategy, type ExpertQAResults, type ExpertValidation, type FontSizeIssue, type GlanceTestResult, HTMLLayoutValidator, HallucinationDetector, type ImageData, type ImageProvider, type ImageRequest, type ImageResult, KnowledgeBase, LocalImageProvider, MermaidProvider, type MetricData, type OneIdeaResult, type OutputFormat, PPTXValidator, PRESENTATION_TYPE_RULES, PlaceholderImageProvider, PowerPointGenerator, type PresentationConfig, PresentationEngine, type PresentationMetadata, type PresentationMode, type PresentationResult, type PresentationType, type PresentationTypeRules, QAEngine, QAFailureError, type QAIssue, type QAResults, QuickChartProvider, RevealJsGenerator, type SCQAStructure, ScoreCalculator, type SignalNoiseResult, type Slide, type SlideBlueprint, type SlideContentScore, type SlideData, SlideFactory, type SlideType, type SlideVisualScore, type SparklineStructure, StrategyFactory, TemplateEngine, TemplateNotFoundError, type ThemeName, TypeDetector, UnsplashImageProvider, VERSION, ValidationError, type VisualQAResults, createDefaultChartProvider, createDefaultImageProvider, _default as default, generate, getKnowledgeBase, validate };
1441
+ export { CodeQualityValidator, type ValidationResult as CodeValidationResult, type ContentAnalysis, ContentAnalyzer, DeckQualityReviewer, type DeckScore, type GenerateOptions, type GenerateResult, type HardcodedViolation, type ImageGenerationRequest, type ImageGenerationResult, KnowledgeGateway, type NanoBananaConfig, NanoBananaProvider, type OutputFormat, type PresentationMetadata, type PresentationMode, type PresentationResult, type PresentationType, type QualitativeDeckReview, type QualitativeSlideReview, type RemediationResult, Remediator, Renderer, type Slide, SlideGenerator, SlideQualityReviewer, type SlideScore, VERSION, type Violation, VisualDesignSystem, createNanoBananaProvider, generate, getContentAnalyzer, getDeckQualityReviewer, getKB, getNanoBananaPrompt, getRemediator, getRenderer, getSlideGenerator, getSlideQualityReviewer, getVisualDesignSystem, initContentAnalyzer, initDeckQualityReviewer, initKB, initRemediator, initRenderer, initSlideGenerator, initSlideQualityReviewer, initVisualDesignSystem, runCodeQualityCheck, validateCodeQuality };