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/README.md +37 -7
- package/assets/presentation-engine.css +71 -0
- package/assets/presentation-knowledge.yaml +1131 -9
- package/assets/screenshots/example-consulting.html +91 -0
- package/assets/screenshots/example-consulting.png +0 -0
- package/assets/screenshots/example-keynote.html +32 -0
- package/assets/screenshots/example-keynote.png +0 -0
- package/assets/screenshots/example-sales.html +64 -0
- package/assets/screenshots/example-sales.png +0 -0
- package/bin/cli.js +61 -19
- package/dist/index.d.mts +1049 -1671
- package/dist/index.d.ts +1049 -1671
- package/dist/index.js +4874 -10924
- package/dist/index.mjs +4846 -10893
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,276 +1,249 @@
|
|
|
1
|
-
import PptxGenJS from 'pptxgenjs';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Claude Presentation Master - Type Definitions
|
|
5
|
-
*
|
|
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
|
-
*
|
|
14
|
-
*
|
|
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
|
-
*
|
|
64
|
-
* Loaded from the knowledge base.
|
|
13
|
+
* Legacy mode for backwards compatibility
|
|
65
14
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
|
23
|
+
/** Slide content */
|
|
99
24
|
data: SlideData;
|
|
100
|
-
/**
|
|
101
|
-
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
143
|
-
/**
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
|
|
151
|
-
/**
|
|
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
|
-
/**
|
|
154
|
-
|
|
75
|
+
/** Specific violations found */
|
|
76
|
+
violations: Violation[];
|
|
155
77
|
}
|
|
156
|
-
interface
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
mainIdea: string;
|
|
217
|
-
passed: boolean;
|
|
218
|
-
conflictingIdeas?: string[];
|
|
183
|
+
interface KBScoringCategory {
|
|
184
|
+
weight: number;
|
|
185
|
+
checks: Record<string, KBCheck>;
|
|
219
186
|
}
|
|
220
|
-
interface
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
231
|
-
|
|
232
|
-
|
|
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
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
236
|
+
interface SCQAStructure {
|
|
237
|
+
situation: string;
|
|
238
|
+
complication: string;
|
|
239
|
+
question: string;
|
|
240
|
+
answer: string;
|
|
262
241
|
}
|
|
263
|
-
interface
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
/**
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
score:
|
|
285
|
-
/**
|
|
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
|
-
|
|
264
|
+
presentationType: PresentationType;
|
|
294
265
|
generatedAt: string;
|
|
295
|
-
/** Presentation mode */
|
|
296
|
-
mode: PresentationMode;
|
|
297
|
-
/** Total slide count */
|
|
298
266
|
slideCount: number;
|
|
299
|
-
|
|
300
|
-
wordCount: number;
|
|
301
|
-
/** Average words per slide */
|
|
267
|
+
totalWords: number;
|
|
302
268
|
avgWordsPerSlide: number;
|
|
303
|
-
|
|
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
|
-
*
|
|
273
|
+
* KnowledgeGateway - Single Point of Access to the Knowledge Base
|
|
351
274
|
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
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
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
*
|
|
295
|
+
* Load the knowledge base from YAML.
|
|
296
|
+
* MUST be called before any queries.
|
|
407
297
|
*/
|
|
408
|
-
|
|
298
|
+
load(): Promise<void>;
|
|
409
299
|
/**
|
|
410
|
-
* Get
|
|
300
|
+
* Get KB version
|
|
411
301
|
*/
|
|
412
|
-
|
|
302
|
+
getVersion(): string;
|
|
413
303
|
/**
|
|
414
|
-
*
|
|
304
|
+
* Get complete presentation type configuration.
|
|
305
|
+
* @throws KBQueryError if type not found
|
|
415
306
|
*/
|
|
416
|
-
|
|
307
|
+
getPresentationType(type: PresentationType): KBResult<KBPresentationType>;
|
|
417
308
|
/**
|
|
418
|
-
*
|
|
309
|
+
* Get validation rules for a presentation type.
|
|
310
|
+
* @throws KBQueryError if rules not found
|
|
419
311
|
*/
|
|
420
|
-
|
|
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
|
-
*
|
|
314
|
+
* Get word limits for a presentation type.
|
|
437
315
|
*/
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
316
|
+
getWordLimits(type: PresentationType): KBResult<{
|
|
317
|
+
min: number;
|
|
318
|
+
max: number;
|
|
319
|
+
ideal: number;
|
|
320
|
+
}>;
|
|
443
321
|
/**
|
|
444
|
-
*
|
|
322
|
+
* Get whitespace requirements.
|
|
445
323
|
*/
|
|
446
|
-
|
|
324
|
+
getWhitespaceRules(type: PresentationType): KBResult<{
|
|
325
|
+
min: number;
|
|
326
|
+
ideal: number;
|
|
327
|
+
max?: number;
|
|
328
|
+
}>;
|
|
447
329
|
/**
|
|
448
|
-
*
|
|
330
|
+
* Get scoring weights for a presentation type.
|
|
449
331
|
*/
|
|
450
|
-
|
|
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
|
-
*
|
|
523
|
-
* This validation is MANDATORY - export will fail if score < threshold.
|
|
334
|
+
* Get allowed slide types for a presentation type.
|
|
524
335
|
*/
|
|
525
|
-
|
|
526
|
-
mode: 'keynote' | 'business';
|
|
527
|
-
threshold?: number;
|
|
528
|
-
strictMode?: boolean;
|
|
529
|
-
}): Promise<PPTXValidationResult>;
|
|
336
|
+
getAllowedSlideTypes(type: PresentationType): KBResult<string[]>;
|
|
530
337
|
/**
|
|
531
|
-
*
|
|
338
|
+
* Get required elements for a presentation type.
|
|
532
339
|
*/
|
|
533
|
-
|
|
340
|
+
getRequiredElements(type: PresentationType): KBResult<string[]>;
|
|
534
341
|
/**
|
|
535
|
-
*
|
|
342
|
+
* Get anti-patterns to avoid for a presentation type.
|
|
536
343
|
*/
|
|
537
|
-
|
|
344
|
+
getAntiPatterns(type: PresentationType): KBResult<string[]>;
|
|
538
345
|
/**
|
|
539
|
-
*
|
|
346
|
+
* Get the scoring rubric.
|
|
540
347
|
*/
|
|
541
|
-
|
|
348
|
+
getScoringRubric(): KBResult<KBScoringRubric>;
|
|
542
349
|
/**
|
|
543
|
-
*
|
|
350
|
+
* Get passing threshold (default: 95).
|
|
544
351
|
*/
|
|
545
|
-
|
|
352
|
+
getPassingThreshold(): KBResult<number>;
|
|
546
353
|
/**
|
|
547
|
-
*
|
|
354
|
+
* Get expert methodology.
|
|
548
355
|
*/
|
|
549
|
-
|
|
356
|
+
getExpert(name: string): KBResult<KBExpert>;
|
|
550
357
|
/**
|
|
551
|
-
*
|
|
358
|
+
* Get Nancy Duarte's glance test rules.
|
|
552
359
|
*/
|
|
553
|
-
|
|
360
|
+
getGlanceTest(): KBResult<{
|
|
361
|
+
description: string;
|
|
362
|
+
word_limit: number;
|
|
363
|
+
}>;
|
|
554
364
|
/**
|
|
555
|
-
*
|
|
365
|
+
* Get Duarte's Sparkline framework.
|
|
556
366
|
*/
|
|
557
|
-
|
|
367
|
+
getSparkline(): KBResult<Record<string, unknown>>;
|
|
558
368
|
/**
|
|
559
|
-
*
|
|
369
|
+
* Get Minto's SCQA framework.
|
|
560
370
|
*/
|
|
561
|
-
|
|
371
|
+
getSCQA(): KBResult<Record<string, unknown>>;
|
|
562
372
|
/**
|
|
563
|
-
*
|
|
373
|
+
* Get Miller's Law (7±2 items).
|
|
564
374
|
*/
|
|
565
|
-
|
|
375
|
+
getMillersLaw(): KBResult<{
|
|
376
|
+
principle: string;
|
|
377
|
+
application: string[];
|
|
378
|
+
}>;
|
|
566
379
|
/**
|
|
567
|
-
*
|
|
380
|
+
* Get accessibility requirements.
|
|
568
381
|
*/
|
|
569
|
-
|
|
570
|
-
private createExpertValidation;
|
|
382
|
+
getAccessibilityRules(): KBResult<Record<string, unknown>>;
|
|
571
383
|
/**
|
|
572
|
-
*
|
|
384
|
+
* Get contrast ratio requirements.
|
|
573
385
|
*/
|
|
574
|
-
|
|
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
|
-
*
|
|
391
|
+
* Get minimum font sizes.
|
|
606
392
|
*/
|
|
607
|
-
|
|
608
|
-
mode: 'keynote' | 'business';
|
|
609
|
-
targetScore: number;
|
|
610
|
-
}): Promise<Slide[]>;
|
|
393
|
+
getFontSizeRequirements(): KBResult<Record<string, string>>;
|
|
611
394
|
/**
|
|
612
|
-
* Get
|
|
395
|
+
* Get Tufte's data-ink ratio rules.
|
|
613
396
|
*/
|
|
614
|
-
|
|
397
|
+
getDataInkRules(): KBResult<Record<string, unknown>>;
|
|
615
398
|
/**
|
|
616
|
-
*
|
|
399
|
+
* Get chartjunk to avoid.
|
|
617
400
|
*/
|
|
618
|
-
|
|
401
|
+
getChartjunk(): KBResult<string[]>;
|
|
619
402
|
/**
|
|
620
|
-
*
|
|
403
|
+
* Get Cialdini's 6 Principles of Influence.
|
|
621
404
|
*/
|
|
622
|
-
|
|
405
|
+
getCialdiniPrinciples(): KBResult<Record<string, unknown>>;
|
|
623
406
|
/**
|
|
624
|
-
*
|
|
407
|
+
* Get specific Cialdini principle by name.
|
|
625
408
|
*/
|
|
626
|
-
|
|
409
|
+
getCialdiniPrinciple(name: string): KBResult<Record<string, unknown>>;
|
|
627
410
|
/**
|
|
628
|
-
*
|
|
411
|
+
* Get all Gestalt principles.
|
|
629
412
|
*/
|
|
630
|
-
|
|
413
|
+
getGestaltPrinciples(): KBResult<Record<string, unknown>>;
|
|
631
414
|
/**
|
|
632
|
-
*
|
|
415
|
+
* Get specific Gestalt principle by name.
|
|
633
416
|
*/
|
|
634
|
-
|
|
417
|
+
getGestaltPrinciple(name: string): KBResult<Record<string, unknown>>;
|
|
635
418
|
/**
|
|
636
|
-
*
|
|
419
|
+
* Get Gestalt proximity principle (for layout checks).
|
|
637
420
|
*/
|
|
638
|
-
|
|
421
|
+
getGestaltProximity(): KBResult<Record<string, unknown>>;
|
|
639
422
|
/**
|
|
640
|
-
*
|
|
423
|
+
* Get Gestalt similarity principle (for consistency checks).
|
|
641
424
|
*/
|
|
642
|
-
|
|
425
|
+
getGestaltSimilarity(): KBResult<Record<string, unknown>>;
|
|
643
426
|
/**
|
|
644
|
-
*
|
|
427
|
+
* Get Gestalt figure-ground principle (for visual impact checks).
|
|
645
428
|
*/
|
|
646
|
-
|
|
429
|
+
getGestaltFigureGround(): KBResult<Record<string, unknown>>;
|
|
647
430
|
/**
|
|
648
|
-
*
|
|
431
|
+
* Query any KB path directly.
|
|
432
|
+
* @throws KBQueryError if path not found
|
|
649
433
|
*/
|
|
650
|
-
|
|
434
|
+
queryRequired<T>(path: string): KBResult<T>;
|
|
651
435
|
/**
|
|
652
|
-
*
|
|
436
|
+
* Query any KB path directly (optional - returns null if not found).
|
|
653
437
|
*/
|
|
654
|
-
|
|
438
|
+
queryOptional<T>(path: string): KBResult<T | null>;
|
|
655
439
|
/**
|
|
656
|
-
*
|
|
440
|
+
* Ensure KB is loaded.
|
|
657
441
|
*/
|
|
658
|
-
private
|
|
442
|
+
private ensureLoaded;
|
|
659
443
|
/**
|
|
660
|
-
*
|
|
444
|
+
* Query a dotted path in the KB.
|
|
661
445
|
*/
|
|
662
|
-
private
|
|
446
|
+
private query;
|
|
663
447
|
/**
|
|
664
|
-
*
|
|
448
|
+
* Create a KB query error.
|
|
665
449
|
*/
|
|
666
|
-
|
|
450
|
+
private error;
|
|
667
451
|
}
|
|
668
|
-
|
|
669
452
|
/**
|
|
670
|
-
*
|
|
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
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
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
|
|
755
|
-
private
|
|
756
|
-
private
|
|
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
|
-
*
|
|
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
|
-
|
|
481
|
+
analyze(content: string, contentType?: 'markdown' | 'text'): Promise<ContentAnalysis>;
|
|
782
482
|
/**
|
|
783
|
-
*
|
|
784
|
-
* Includes hallucination detection to ensure all facts are sourced.
|
|
483
|
+
* Parse content into sections based on headers.
|
|
785
484
|
*/
|
|
786
|
-
private
|
|
485
|
+
private parseSections;
|
|
787
486
|
/**
|
|
788
|
-
*
|
|
487
|
+
* Extract title from content.
|
|
789
488
|
*/
|
|
790
|
-
private
|
|
489
|
+
private extractTitle;
|
|
791
490
|
/**
|
|
792
|
-
*
|
|
491
|
+
* Extract bullet points from content.
|
|
492
|
+
* Strips markdown formatting (**bold**, *italic*, `code`) from bullet text.
|
|
793
493
|
*/
|
|
794
|
-
private
|
|
494
|
+
private extractBullets;
|
|
795
495
|
/**
|
|
796
|
-
*
|
|
496
|
+
* Strip markdown formatting from text.
|
|
497
|
+
* Converts **bold**, *italic*, `code`, [links](url) to plain text.
|
|
797
498
|
*/
|
|
798
|
-
private
|
|
499
|
+
private stripMarkdown;
|
|
799
500
|
/**
|
|
800
|
-
*
|
|
501
|
+
* Extract data points (metrics, percentages, currencies, numbers).
|
|
801
502
|
*/
|
|
802
|
-
private
|
|
503
|
+
private extractDataPoints;
|
|
803
504
|
/**
|
|
804
|
-
* Get
|
|
505
|
+
* Get surrounding context for a data point.
|
|
805
506
|
*/
|
|
806
|
-
|
|
507
|
+
private getContext;
|
|
807
508
|
/**
|
|
808
|
-
*
|
|
509
|
+
* Parse numeric value from string (handles M/B/K suffixes).
|
|
809
510
|
*/
|
|
810
|
-
|
|
511
|
+
private parseNumericValue;
|
|
811
512
|
/**
|
|
812
|
-
*
|
|
513
|
+
* Extract key messages from sections.
|
|
813
514
|
*/
|
|
814
|
-
|
|
515
|
+
private extractKeyMessages;
|
|
516
|
+
/**
|
|
517
|
+
* Detect presentation type based on content signals.
|
|
518
|
+
*/
|
|
519
|
+
private detectPresentationType;
|
|
815
520
|
/**
|
|
816
|
-
*
|
|
521
|
+
* Identify SCQA (Situation, Complication, Question, Answer) structure.
|
|
817
522
|
*/
|
|
818
|
-
|
|
523
|
+
private identifySCQA;
|
|
819
524
|
/**
|
|
820
|
-
*
|
|
525
|
+
* Identify Sparkline (What Is / What Could Be) structure.
|
|
821
526
|
*/
|
|
822
|
-
|
|
527
|
+
private identifySparkline;
|
|
823
528
|
}
|
|
529
|
+
declare function getContentAnalyzer(): ContentAnalyzer;
|
|
530
|
+
declare function initContentAnalyzer(): Promise<ContentAnalyzer>;
|
|
824
531
|
|
|
825
532
|
/**
|
|
826
|
-
*
|
|
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
|
-
*
|
|
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
|
|
837
|
-
private
|
|
838
|
-
private
|
|
839
|
-
private
|
|
840
|
-
private
|
|
841
|
-
private
|
|
842
|
-
private
|
|
843
|
-
|
|
844
|
-
|
|
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
|
-
*
|
|
554
|
+
* Generate slides from content analysis.
|
|
877
555
|
*/
|
|
878
|
-
|
|
556
|
+
generate(analysis: ContentAnalysis, presentationType: PresentationType): Promise<Slide[]>;
|
|
557
|
+
private loadRulesForType;
|
|
879
558
|
/**
|
|
880
|
-
*
|
|
559
|
+
* Create title slide.
|
|
881
560
|
*/
|
|
882
|
-
private
|
|
561
|
+
private createTitleSlide;
|
|
883
562
|
/**
|
|
884
|
-
*
|
|
563
|
+
* Create agenda slide.
|
|
885
564
|
*/
|
|
886
|
-
private
|
|
565
|
+
private createAgendaSlide;
|
|
887
566
|
/**
|
|
888
|
-
*
|
|
567
|
+
* Create SCQA slides (Situation, Complication, Question, Answer).
|
|
889
568
|
*/
|
|
890
|
-
private
|
|
569
|
+
private createSCQASlides;
|
|
891
570
|
/**
|
|
892
|
-
*
|
|
571
|
+
* Create slides for a content section.
|
|
893
572
|
*/
|
|
894
|
-
private
|
|
573
|
+
private createSectionSlides;
|
|
895
574
|
/**
|
|
896
|
-
*
|
|
575
|
+
* Create metrics grid slide from data points.
|
|
897
576
|
*/
|
|
898
|
-
private
|
|
577
|
+
private createMetricsSlide;
|
|
899
578
|
/**
|
|
900
|
-
*
|
|
579
|
+
* Create metrics grid slide from a section.
|
|
901
580
|
*/
|
|
902
|
-
private
|
|
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
|
|
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
|
-
|
|
585
|
+
private createStarMomentSlide;
|
|
930
586
|
/**
|
|
931
|
-
* Create
|
|
587
|
+
* Create call to action slide.
|
|
932
588
|
*/
|
|
933
|
-
private
|
|
589
|
+
private createCallToActionSlide;
|
|
934
590
|
/**
|
|
935
|
-
* Create
|
|
591
|
+
* Create thank you / closing slide.
|
|
936
592
|
*/
|
|
937
|
-
private
|
|
593
|
+
private createThankYouSlide;
|
|
938
594
|
/**
|
|
939
|
-
*
|
|
595
|
+
* Determine the best slide type for a section.
|
|
940
596
|
*/
|
|
941
|
-
private
|
|
597
|
+
private determineSlideType;
|
|
942
598
|
/**
|
|
943
|
-
*
|
|
599
|
+
* Check if presentation type favors minimal slides.
|
|
944
600
|
*/
|
|
945
|
-
private
|
|
601
|
+
private isMinimalType;
|
|
946
602
|
/**
|
|
947
|
-
*
|
|
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
|
|
606
|
+
private stripMarkdownSyntax;
|
|
950
607
|
/**
|
|
951
|
-
*
|
|
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
|
|
612
|
+
private cleanBullets;
|
|
954
613
|
/**
|
|
955
|
-
*
|
|
614
|
+
* Truncate text to word limit, stripping markdown first.
|
|
615
|
+
* NEVER adds "..." - just takes the complete words that fit.
|
|
956
616
|
*/
|
|
957
|
-
private
|
|
617
|
+
private truncateToWordLimit;
|
|
958
618
|
/**
|
|
959
|
-
*
|
|
619
|
+
* Extract a key statement from content (first sentence or bold text).
|
|
960
620
|
*/
|
|
961
|
-
private
|
|
621
|
+
private extractKeyStatement;
|
|
962
622
|
/**
|
|
963
|
-
*
|
|
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
|
|
626
|
+
private extractKeyMessage;
|
|
966
627
|
/**
|
|
967
|
-
*
|
|
628
|
+
* Extract a label from context (nearby text around a data point).
|
|
968
629
|
*/
|
|
969
|
-
private
|
|
630
|
+
private extractLabelFromContext;
|
|
970
631
|
/**
|
|
971
|
-
*
|
|
632
|
+
* Detect trend from context (up, down, neutral).
|
|
972
633
|
*/
|
|
973
|
-
private
|
|
634
|
+
private detectTrend;
|
|
974
635
|
/**
|
|
975
|
-
*
|
|
636
|
+
* Split array into chunks.
|
|
976
637
|
*/
|
|
977
|
-
private
|
|
638
|
+
private chunkArray;
|
|
978
639
|
/**
|
|
979
|
-
*
|
|
640
|
+
* Generate meaningful titles for chunked bullet lists.
|
|
641
|
+
* Instead of "Title (continued)", create contextual subtitles.
|
|
980
642
|
*/
|
|
981
|
-
private
|
|
643
|
+
private generateChunkTitles;
|
|
982
644
|
/**
|
|
983
|
-
*
|
|
645
|
+
* Extract a meaningful subtitle from bullet content.
|
|
984
646
|
*/
|
|
985
|
-
private
|
|
647
|
+
private extractSubtitleFromBullets;
|
|
986
648
|
}
|
|
649
|
+
declare function getSlideGenerator(): SlideGenerator;
|
|
650
|
+
declare function initSlideGenerator(): Promise<SlideGenerator>;
|
|
987
651
|
|
|
988
652
|
/**
|
|
989
|
-
*
|
|
653
|
+
* VisualDesignSystem - KB-Driven Visual Design Configuration
|
|
990
654
|
*
|
|
991
|
-
*
|
|
992
|
-
*
|
|
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
|
|
996
|
-
|
|
997
|
-
|
|
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
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
728
|
+
getTheme(type: PresentationType): Promise<VisualTheme>;
|
|
1008
729
|
/**
|
|
1009
|
-
*
|
|
730
|
+
* Determine mode (keynote vs business) for a presentation type.
|
|
1010
731
|
*/
|
|
1011
|
-
|
|
732
|
+
private getModeForType;
|
|
1012
733
|
/**
|
|
1013
|
-
*
|
|
734
|
+
* Get color palette for presentation type from KB.
|
|
1014
735
|
*/
|
|
1015
|
-
private
|
|
736
|
+
private getPaletteForType;
|
|
1016
737
|
/**
|
|
1017
|
-
*
|
|
738
|
+
* Get typography rules for mode from KB.
|
|
1018
739
|
*/
|
|
1019
|
-
private
|
|
740
|
+
private getTypographyForMode;
|
|
1020
741
|
/**
|
|
1021
|
-
*
|
|
742
|
+
* Get layout rules for mode from KB.
|
|
1022
743
|
*/
|
|
1023
|
-
private
|
|
744
|
+
private getLayoutRulesForMode;
|
|
1024
745
|
/**
|
|
1025
|
-
*
|
|
746
|
+
* Get gradient definitions for presentation type.
|
|
1026
747
|
*/
|
|
1027
|
-
private
|
|
748
|
+
private getGradientsForType;
|
|
1028
749
|
/**
|
|
1029
|
-
*
|
|
750
|
+
* Build CSS custom properties for the theme.
|
|
1030
751
|
*/
|
|
1031
|
-
private
|
|
752
|
+
private buildCSSVariables;
|
|
1032
753
|
/**
|
|
1033
|
-
*
|
|
754
|
+
* Get slide layout templates from KB.
|
|
1034
755
|
*/
|
|
1035
|
-
|
|
756
|
+
getSlideLayouts(type: PresentationType): Promise<SlideLayout[]>;
|
|
1036
757
|
/**
|
|
1037
|
-
*
|
|
758
|
+
* Generate complete CSS for the theme.
|
|
1038
759
|
*/
|
|
1039
|
-
|
|
760
|
+
generateCSS(theme: VisualTheme): string;
|
|
761
|
+
private lightenColor;
|
|
762
|
+
private darkenColor;
|
|
763
|
+
private hexToRgb;
|
|
1040
764
|
/**
|
|
1041
|
-
*
|
|
765
|
+
* Get contrasting text color for a given background color.
|
|
766
|
+
* Returns white or black based on luminance.
|
|
1042
767
|
*/
|
|
1043
|
-
private
|
|
768
|
+
private getContrastColor;
|
|
1044
769
|
}
|
|
770
|
+
declare function getVisualDesignSystem(): VisualDesignSystem;
|
|
771
|
+
declare function initVisualDesignSystem(): Promise<VisualDesignSystem>;
|
|
1045
772
|
|
|
1046
773
|
/**
|
|
1047
|
-
*
|
|
774
|
+
* SlideQualityReviewer - THE HEART OF THE QUALITATIVE REVIEW SYSTEM
|
|
1048
775
|
*
|
|
1049
|
-
*
|
|
1050
|
-
*
|
|
1051
|
-
*
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
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
|
-
*
|
|
784
|
+
* ALL rules come from the Knowledge Base. NO hardcoded fallbacks.
|
|
1057
785
|
*/
|
|
1058
786
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
787
|
+
type QualityLevel = 'excellent' | 'good' | 'acceptable' | 'poor' | 'failing';
|
|
788
|
+
interface QualitativeAssessment {
|
|
789
|
+
/** Score (0-100) */
|
|
1062
790
|
score: number;
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
}
|
|
1070
|
-
interface
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
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
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
private
|
|
1103
|
-
|
|
1104
|
-
|
|
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
|
-
*
|
|
839
|
+
* Review a slide qualitatively.
|
|
1109
840
|
*/
|
|
1110
|
-
|
|
841
|
+
review(slide: Slide, presentationType: PresentationType): Promise<QualitativeSlideReview>;
|
|
1111
842
|
/**
|
|
1112
|
-
*
|
|
843
|
+
* Convert qualitative review to SlideScore format.
|
|
1113
844
|
*/
|
|
1114
|
-
|
|
845
|
+
toSlideScore(review: QualitativeSlideReview): SlideScore;
|
|
846
|
+
private loadRulesForType;
|
|
1115
847
|
/**
|
|
1116
|
-
*
|
|
848
|
+
* Visual Impact (25%): Does this slide command attention appropriately?
|
|
1117
849
|
*/
|
|
1118
|
-
private
|
|
850
|
+
private assessVisualImpact;
|
|
1119
851
|
/**
|
|
1120
|
-
*
|
|
852
|
+
* Content Clarity (20%): Can you understand the message in 3 seconds?
|
|
1121
853
|
*/
|
|
1122
|
-
private
|
|
854
|
+
private assessContentClarity;
|
|
1123
855
|
/**
|
|
1124
|
-
*
|
|
856
|
+
* Get all text content from a slide for analysis.
|
|
1125
857
|
*/
|
|
1126
|
-
private
|
|
858
|
+
private getAllTextContent;
|
|
1127
859
|
/**
|
|
1128
|
-
*
|
|
860
|
+
* Layout Balance (15%): Is visual weight distributed appropriately?
|
|
1129
861
|
*/
|
|
1130
|
-
private
|
|
862
|
+
private assessLayoutBalance;
|
|
1131
863
|
/**
|
|
1132
|
-
*
|
|
864
|
+
* Typography Hierarchy (15%): Is there clear primary/secondary/tertiary hierarchy?
|
|
1133
865
|
*/
|
|
1134
|
-
private
|
|
866
|
+
private assessTypographyHierarchy;
|
|
1135
867
|
/**
|
|
1136
|
-
*
|
|
868
|
+
* Whitespace Usage (10%): Is whitespace used purposefully?
|
|
1137
869
|
*/
|
|
1138
|
-
|
|
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
|
-
*
|
|
1204
|
-
* This is the MANDATORY check before any HTML export.
|
|
872
|
+
* Color Harmony (10%): Do colors work together within the theme?
|
|
1205
873
|
*/
|
|
1206
|
-
|
|
874
|
+
private assessColorHarmony;
|
|
1207
875
|
/**
|
|
1208
|
-
*
|
|
876
|
+
* Audience Appropriateness (5%): Is the visual style right for this audience?
|
|
1209
877
|
*/
|
|
1210
|
-
private
|
|
878
|
+
private assessAudienceAppropriate;
|
|
879
|
+
private isMinimalType;
|
|
880
|
+
private isDenseType;
|
|
881
|
+
private countWords;
|
|
882
|
+
private countLongWords;
|
|
1211
883
|
/**
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
884
|
+
* Detect raw markdown syntax that should have been rendered to HTML.
|
|
885
|
+
* Returns array of issue descriptions.
|
|
1214
886
|
*/
|
|
1215
|
-
private
|
|
887
|
+
private detectRawMarkdown;
|
|
1216
888
|
/**
|
|
1217
|
-
*
|
|
889
|
+
* Check if slide type is appropriate for its content.
|
|
890
|
+
* Returns issue description if mismatched.
|
|
1218
891
|
*/
|
|
1219
|
-
|
|
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
|
-
*
|
|
904
|
+
* DeckQualityReviewer - HOLISTIC DECK QUALITY REVIEW
|
|
1224
905
|
*
|
|
1225
|
-
*
|
|
1226
|
-
* 1.
|
|
1227
|
-
* 2.
|
|
1228
|
-
* 3.
|
|
1229
|
-
* 4.
|
|
1230
|
-
* 5.
|
|
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
|
-
*
|
|
913
|
+
* ALL rules come from the Knowledge Base. NO hardcoded fallbacks.
|
|
1233
914
|
*/
|
|
1234
915
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
*/
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
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
|
-
*
|
|
966
|
+
* Review the entire deck qualitatively.
|
|
1260
967
|
*/
|
|
1261
|
-
|
|
968
|
+
review(slides: Slide[], presentationType: PresentationType): Promise<QualitativeDeckReview>;
|
|
1262
969
|
/**
|
|
1263
|
-
*
|
|
970
|
+
* Convert qualitative review to DeckScore format.
|
|
1264
971
|
*/
|
|
1265
|
-
|
|
972
|
+
toDeckScore(review: QualitativeDeckReview): DeckScore;
|
|
973
|
+
private loadRulesForType;
|
|
1266
974
|
/**
|
|
1267
|
-
*
|
|
975
|
+
* Narrative Flow (30%): Does the presentation tell a coherent story?
|
|
1268
976
|
*/
|
|
1269
|
-
|
|
977
|
+
private assessNarrativeFlow;
|
|
1270
978
|
/**
|
|
1271
|
-
*
|
|
979
|
+
* Visual Consistency (25%): Is the same theme applied throughout?
|
|
1272
980
|
*/
|
|
1273
|
-
|
|
1274
|
-
min: number;
|
|
1275
|
-
max: number;
|
|
1276
|
-
ideal: number;
|
|
1277
|
-
};
|
|
981
|
+
private assessVisualConsistency;
|
|
1278
982
|
/**
|
|
1279
|
-
*
|
|
983
|
+
* Pacing & Rhythm (20%): Is there variety in slide types and density?
|
|
1280
984
|
*/
|
|
1281
|
-
|
|
985
|
+
private assessPacingRhythm;
|
|
1282
986
|
/**
|
|
1283
|
-
*
|
|
987
|
+
* Opening & Closing (15%): Are the first and last slides the strongest?
|
|
1284
988
|
*/
|
|
1285
|
-
|
|
989
|
+
private assessOpeningClosing;
|
|
1286
990
|
/**
|
|
1287
|
-
*
|
|
991
|
+
* Overall Impression (10%): Would you hire/invest based on this?
|
|
1288
992
|
*/
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
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
|
-
*
|
|
1008
|
+
* Remediator - Fix Failing Slides
|
|
1299
1009
|
*
|
|
1300
|
-
*
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
*
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
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
|
-
*
|
|
1066
|
+
* Attempt to remediate a failing slide.
|
|
1409
1067
|
*/
|
|
1410
|
-
|
|
1068
|
+
remediate(slide: Slide, presentationType: PresentationType, initialReview: QualitativeSlideReview): Promise<RemediationResult>;
|
|
1411
1069
|
/**
|
|
1412
|
-
*
|
|
1070
|
+
* Batch remediate multiple slides.
|
|
1413
1071
|
*/
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1433
|
-
*
|
|
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
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
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
|
-
*
|
|
1126
|
+
* Render slides to specified formats.
|
|
1447
1127
|
*/
|
|
1448
|
-
|
|
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
|
-
*
|
|
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
|
|
1149
|
+
private getBackgroundImageUrl;
|
|
1453
1150
|
/**
|
|
1454
|
-
*
|
|
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
|
|
1153
|
+
private resolveImagePath;
|
|
1464
1154
|
/**
|
|
1465
|
-
*
|
|
1155
|
+
* Generate fallback image URL using Picsum with smart seeding.
|
|
1466
1156
|
*/
|
|
1467
|
-
private
|
|
1157
|
+
private getFallbackImageUrl;
|
|
1468
1158
|
/**
|
|
1469
|
-
*
|
|
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
|
|
1163
|
+
private renderMarkdown;
|
|
1472
1164
|
/**
|
|
1473
|
-
*
|
|
1165
|
+
* Clean up broken/truncated markdown that can't be properly rendered.
|
|
1166
|
+
* Removes partial code blocks, inline tables, etc.
|
|
1474
1167
|
*/
|
|
1475
|
-
private
|
|
1168
|
+
private cleanBrokenMarkdown;
|
|
1476
1169
|
/**
|
|
1477
|
-
*
|
|
1170
|
+
* Render markdown tables to HTML tables.
|
|
1478
1171
|
*/
|
|
1479
|
-
private
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1190
|
+
* Usage:
|
|
1191
|
+
* const provider = createNanoBananaProvider();
|
|
1192
|
+
* if (await provider.isAvailable()) {
|
|
1193
|
+
* const imageUrl = await provider.generateHeroImage('AI revolution');
|
|
1194
|
+
* }
|
|
1490
1195
|
*/
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
private
|
|
1535
|
-
|
|
1536
|
-
|
|
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
|
-
*
|
|
1244
|
+
* Check if NanoBanana is available (API key present).
|
|
1541
1245
|
*/
|
|
1542
|
-
|
|
1246
|
+
isAvailable(): Promise<boolean>;
|
|
1543
1247
|
/**
|
|
1544
|
-
*
|
|
1248
|
+
* Generate a hero image for a slide.
|
|
1545
1249
|
*/
|
|
1546
|
-
|
|
1250
|
+
generateHeroImage(concept: string): Promise<ImageGenerationResult>;
|
|
1547
1251
|
/**
|
|
1548
|
-
*
|
|
1252
|
+
* Generate a concept illustration.
|
|
1549
1253
|
*/
|
|
1550
|
-
|
|
1254
|
+
generateConceptImage(concept: string): Promise<ImageGenerationResult>;
|
|
1551
1255
|
/**
|
|
1552
|
-
*
|
|
1256
|
+
* Generate an icon or symbol.
|
|
1553
1257
|
*/
|
|
1554
|
-
|
|
1258
|
+
generateIcon(concept: string): Promise<ImageGenerationResult>;
|
|
1555
1259
|
/**
|
|
1556
|
-
*
|
|
1260
|
+
* Generate a background image.
|
|
1557
1261
|
*/
|
|
1558
|
-
|
|
1262
|
+
generateBackground(concept: string, colorScheme?: 'dark' | 'light'): Promise<ImageGenerationResult>;
|
|
1559
1263
|
/**
|
|
1560
|
-
*
|
|
1264
|
+
* Generate an image based on request parameters.
|
|
1561
1265
|
*/
|
|
1562
|
-
|
|
1266
|
+
generate(request: ImageGenerationRequest): Promise<ImageGenerationResult>;
|
|
1563
1267
|
/**
|
|
1564
|
-
*
|
|
1268
|
+
* Build an optimized prompt for image generation.
|
|
1565
1269
|
*/
|
|
1566
|
-
private
|
|
1270
|
+
private buildPrompt;
|
|
1567
1271
|
/**
|
|
1568
|
-
*
|
|
1569
|
-
* Shows valuation ranges across different methodologies
|
|
1272
|
+
* Call the Gemini API for image generation.
|
|
1570
1273
|
*/
|
|
1571
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
1281
|
+
* Get a pre-built prompt for a specific image type.
|
|
1282
|
+
* Useful for customization or debugging.
|
|
1741
1283
|
*/
|
|
1742
|
-
declare function
|
|
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
|
-
*
|
|
1287
|
+
* CodeQualityValidator - Detects Hardcoded Values in Source Code
|
|
1749
1288
|
*
|
|
1750
|
-
*
|
|
1751
|
-
*
|
|
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
|
-
*
|
|
1881
|
-
*
|
|
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
|
|
1298
|
+
* This validator catches these careless errors at build/test time.
|
|
1884
1299
|
*/
|
|
1885
|
-
interface
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
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
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
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
|
|
1911
|
-
private
|
|
1912
|
-
private
|
|
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
|
-
*
|
|
1326
|
+
* Validate all TypeScript files in the source directory.
|
|
1919
1327
|
*/
|
|
1920
|
-
|
|
1328
|
+
validate(): Promise<ValidationResult>;
|
|
1921
1329
|
/**
|
|
1922
|
-
*
|
|
1330
|
+
* Validate a single file for hardcoded values.
|
|
1923
1331
|
*/
|
|
1924
|
-
|
|
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
|
-
*
|
|
1342
|
+
* Format validation results for console output.
|
|
1927
1343
|
*/
|
|
1928
|
-
|
|
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
|
-
*
|
|
1347
|
+
* Run code quality validation on the source directory.
|
|
1979
1348
|
*/
|
|
1980
|
-
declare function
|
|
1981
|
-
|
|
1349
|
+
declare function validateCodeQuality(srcDir: string): Promise<ValidationResult>;
|
|
1982
1350
|
/**
|
|
1983
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
2029
|
-
*
|
|
1358
|
+
* Entry point for the qualitative-first presentation engine.
|
|
1359
|
+
* Every slide must score 95/100 based on REAL qualitative excellence.
|
|
2030
1360
|
*
|
|
2031
|
-
*
|
|
2032
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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 {
|
|
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 };
|