claude-presentation-master 4.0.0 → 4.2.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/bin/cli.js +2 -2
- package/dist/index.d.mts +54 -16
- package/dist/index.d.ts +54 -16
- package/dist/index.js +248 -107
- package/dist/index.mjs +248 -107
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -20,7 +20,7 @@ const args = process.argv.slice(2);
|
|
|
20
20
|
|
|
21
21
|
// Help text
|
|
22
22
|
const helpText = `
|
|
23
|
-
Claude Presentation Master
|
|
23
|
+
Claude Presentation Master v4.2.0
|
|
24
24
|
Generate world-class presentations using expert methodologies
|
|
25
25
|
|
|
26
26
|
100% FREE • Zero API Keys • Runs Locally
|
|
@@ -85,7 +85,7 @@ For more information: https://github.com/Stuinfla/claude-presentation-master
|
|
|
85
85
|
`;
|
|
86
86
|
|
|
87
87
|
// Version
|
|
88
|
-
const version = '2.
|
|
88
|
+
const version = '4.2.0';
|
|
89
89
|
|
|
90
90
|
// Parse arguments
|
|
91
91
|
function parseArgs(args) {
|
package/dist/index.d.mts
CHANGED
|
@@ -692,10 +692,27 @@ interface MetricData {
|
|
|
692
692
|
label: string;
|
|
693
693
|
trend?: 'up' | 'down' | 'neutral';
|
|
694
694
|
}
|
|
695
|
+
interface ModeConfig {
|
|
696
|
+
maxBulletsPerSlide: number;
|
|
697
|
+
maxWordsPerSlide: number;
|
|
698
|
+
minBulletsToKeep: number;
|
|
699
|
+
}
|
|
695
700
|
declare class SlideGeneratorV2 {
|
|
696
701
|
private config;
|
|
697
702
|
private presentationType;
|
|
703
|
+
/**
|
|
704
|
+
* Create a slide generator with default configs.
|
|
705
|
+
* For KB-driven configs, use createSlideGeneratorV2WithConfig() instead.
|
|
706
|
+
*/
|
|
698
707
|
constructor(presentationType?: PresentationType);
|
|
708
|
+
/**
|
|
709
|
+
* Override config with KB-loaded values at runtime.
|
|
710
|
+
*/
|
|
711
|
+
setConfig(config: ModeConfig): void;
|
|
712
|
+
/**
|
|
713
|
+
* Get current config (useful for debugging).
|
|
714
|
+
*/
|
|
715
|
+
getConfig(): ModeConfig;
|
|
699
716
|
/**
|
|
700
717
|
* Generate slides from markdown content.
|
|
701
718
|
* Simple, correct, no garbage.
|
|
@@ -770,26 +787,37 @@ declare class SlideGeneratorV2 {
|
|
|
770
787
|
declare function createSlideGeneratorV2(type?: PresentationType): SlideGeneratorV2;
|
|
771
788
|
|
|
772
789
|
/**
|
|
773
|
-
* Renderer V2 -
|
|
790
|
+
* Renderer V2 - KB-Driven Visual Excellence
|
|
774
791
|
*
|
|
775
792
|
* Renders slides to HTML and PDF with:
|
|
776
793
|
* - Tables as actual tables (not mangled metrics)
|
|
777
794
|
* - Complete bullets (never truncated)
|
|
778
795
|
* - Clean professional CSS (no random stock photos)
|
|
779
|
-
* -
|
|
796
|
+
* - Color palettes loaded from Knowledge Base per presentation type
|
|
797
|
+
* - Typography and spacing from KB
|
|
780
798
|
* - Automatic PDF generation alongside HTML
|
|
781
799
|
*/
|
|
782
800
|
|
|
783
|
-
type ThemeStyle = '
|
|
801
|
+
type ThemeStyle = 'light' | 'dark';
|
|
784
802
|
declare class RendererV2 {
|
|
785
803
|
private theme;
|
|
786
804
|
private presentationType;
|
|
805
|
+
private kb;
|
|
787
806
|
/**
|
|
788
|
-
* Create renderer with theme
|
|
789
|
-
* @param presentationType - The type of deck being created (determines
|
|
790
|
-
* @param
|
|
807
|
+
* Create renderer with theme loaded from Knowledge Base.
|
|
808
|
+
* @param presentationType - The type of deck being created (determines palette)
|
|
809
|
+
* @param kb - Knowledge Base gateway (optional, will use global if not provided)
|
|
791
810
|
*/
|
|
792
|
-
constructor(presentationType?: PresentationType,
|
|
811
|
+
constructor(presentationType?: PresentationType, kb?: KnowledgeGateway);
|
|
812
|
+
/**
|
|
813
|
+
* Load theme configuration from Knowledge Base.
|
|
814
|
+
* Falls back to hardcoded values only if KB fails.
|
|
815
|
+
*/
|
|
816
|
+
private loadThemeFromKB;
|
|
817
|
+
/**
|
|
818
|
+
* Default palette mapping per presentation type (used if KB doesn't specify).
|
|
819
|
+
*/
|
|
820
|
+
private getDefaultPaletteName;
|
|
793
821
|
/**
|
|
794
822
|
* Render slides to complete HTML document.
|
|
795
823
|
*/
|
|
@@ -812,9 +840,9 @@ declare class RendererV2 {
|
|
|
812
840
|
*/
|
|
813
841
|
private renderForPrint;
|
|
814
842
|
/**
|
|
815
|
-
*
|
|
843
|
+
* Light theme print HTML (professional, white background).
|
|
816
844
|
*/
|
|
817
|
-
private
|
|
845
|
+
private getLightPrintHTML;
|
|
818
846
|
/**
|
|
819
847
|
* Dark theme print HTML (legacy).
|
|
820
848
|
*/
|
|
@@ -872,17 +900,25 @@ declare class RendererV2 {
|
|
|
872
900
|
*/
|
|
873
901
|
private escapeHtml;
|
|
874
902
|
/**
|
|
875
|
-
*
|
|
903
|
+
* Generate CSS with colors from Knowledge Base.
|
|
876
904
|
*/
|
|
877
905
|
private getCSS;
|
|
878
906
|
/**
|
|
879
|
-
*
|
|
907
|
+
* Generate CSS variables from KB palette.
|
|
908
|
+
*/
|
|
909
|
+
private getCSSVariables;
|
|
910
|
+
/**
|
|
911
|
+
* Lighten or darken a hex color.
|
|
912
|
+
*/
|
|
913
|
+
private lightenColor;
|
|
914
|
+
/**
|
|
915
|
+
* Light theme CSS (consulting style) with KB palette colors.
|
|
880
916
|
*/
|
|
881
|
-
private
|
|
917
|
+
private getLightThemeCSS;
|
|
882
918
|
/**
|
|
883
|
-
* Dark theme CSS
|
|
919
|
+
* Dark theme CSS with KB palette colors.
|
|
884
920
|
*/
|
|
885
|
-
private
|
|
921
|
+
private getDarkThemeCSS;
|
|
886
922
|
}
|
|
887
923
|
/**
|
|
888
924
|
* Create a renderer with theme matched to the presentation type.
|
|
@@ -897,7 +933,7 @@ declare class RendererV2 {
|
|
|
897
933
|
* - product_demo, investor_pitch → Startup (modern dark)
|
|
898
934
|
* - executive_briefing → Corporate (professional)
|
|
899
935
|
*/
|
|
900
|
-
declare function createRendererV2(presentationType?: PresentationType,
|
|
936
|
+
declare function createRendererV2(presentationType?: PresentationType, kb?: KnowledgeGateway): RendererV2;
|
|
901
937
|
|
|
902
938
|
/**
|
|
903
939
|
* PresentationEngineV2 - Knowledge-Driven Excellence
|
|
@@ -1221,6 +1257,8 @@ declare class SlideQualityReviewer {
|
|
|
1221
1257
|
private whitespaceRules;
|
|
1222
1258
|
private bulletLimit;
|
|
1223
1259
|
private glanceTestSeconds;
|
|
1260
|
+
private assessmentWeights;
|
|
1261
|
+
private _loggedWeights;
|
|
1224
1262
|
private hasCialdini;
|
|
1225
1263
|
private hasGestalt;
|
|
1226
1264
|
private hasTufteDataInk;
|
|
@@ -1767,7 +1805,7 @@ declare function runCodeQualityCheck(srcDir: string): Promise<boolean>;
|
|
|
1767
1805
|
* ALL decisions come from the Knowledge Base. NO hardcoded fallbacks.
|
|
1768
1806
|
*/
|
|
1769
1807
|
|
|
1770
|
-
declare const VERSION = "2.0
|
|
1808
|
+
declare const VERSION = "4.2.0";
|
|
1771
1809
|
interface GenerateOptions {
|
|
1772
1810
|
/** Input content (Markdown, text, etc.) */
|
|
1773
1811
|
content: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -692,10 +692,27 @@ interface MetricData {
|
|
|
692
692
|
label: string;
|
|
693
693
|
trend?: 'up' | 'down' | 'neutral';
|
|
694
694
|
}
|
|
695
|
+
interface ModeConfig {
|
|
696
|
+
maxBulletsPerSlide: number;
|
|
697
|
+
maxWordsPerSlide: number;
|
|
698
|
+
minBulletsToKeep: number;
|
|
699
|
+
}
|
|
695
700
|
declare class SlideGeneratorV2 {
|
|
696
701
|
private config;
|
|
697
702
|
private presentationType;
|
|
703
|
+
/**
|
|
704
|
+
* Create a slide generator with default configs.
|
|
705
|
+
* For KB-driven configs, use createSlideGeneratorV2WithConfig() instead.
|
|
706
|
+
*/
|
|
698
707
|
constructor(presentationType?: PresentationType);
|
|
708
|
+
/**
|
|
709
|
+
* Override config with KB-loaded values at runtime.
|
|
710
|
+
*/
|
|
711
|
+
setConfig(config: ModeConfig): void;
|
|
712
|
+
/**
|
|
713
|
+
* Get current config (useful for debugging).
|
|
714
|
+
*/
|
|
715
|
+
getConfig(): ModeConfig;
|
|
699
716
|
/**
|
|
700
717
|
* Generate slides from markdown content.
|
|
701
718
|
* Simple, correct, no garbage.
|
|
@@ -770,26 +787,37 @@ declare class SlideGeneratorV2 {
|
|
|
770
787
|
declare function createSlideGeneratorV2(type?: PresentationType): SlideGeneratorV2;
|
|
771
788
|
|
|
772
789
|
/**
|
|
773
|
-
* Renderer V2 -
|
|
790
|
+
* Renderer V2 - KB-Driven Visual Excellence
|
|
774
791
|
*
|
|
775
792
|
* Renders slides to HTML and PDF with:
|
|
776
793
|
* - Tables as actual tables (not mangled metrics)
|
|
777
794
|
* - Complete bullets (never truncated)
|
|
778
795
|
* - Clean professional CSS (no random stock photos)
|
|
779
|
-
* -
|
|
796
|
+
* - Color palettes loaded from Knowledge Base per presentation type
|
|
797
|
+
* - Typography and spacing from KB
|
|
780
798
|
* - Automatic PDF generation alongside HTML
|
|
781
799
|
*/
|
|
782
800
|
|
|
783
|
-
type ThemeStyle = '
|
|
801
|
+
type ThemeStyle = 'light' | 'dark';
|
|
784
802
|
declare class RendererV2 {
|
|
785
803
|
private theme;
|
|
786
804
|
private presentationType;
|
|
805
|
+
private kb;
|
|
787
806
|
/**
|
|
788
|
-
* Create renderer with theme
|
|
789
|
-
* @param presentationType - The type of deck being created (determines
|
|
790
|
-
* @param
|
|
807
|
+
* Create renderer with theme loaded from Knowledge Base.
|
|
808
|
+
* @param presentationType - The type of deck being created (determines palette)
|
|
809
|
+
* @param kb - Knowledge Base gateway (optional, will use global if not provided)
|
|
791
810
|
*/
|
|
792
|
-
constructor(presentationType?: PresentationType,
|
|
811
|
+
constructor(presentationType?: PresentationType, kb?: KnowledgeGateway);
|
|
812
|
+
/**
|
|
813
|
+
* Load theme configuration from Knowledge Base.
|
|
814
|
+
* Falls back to hardcoded values only if KB fails.
|
|
815
|
+
*/
|
|
816
|
+
private loadThemeFromKB;
|
|
817
|
+
/**
|
|
818
|
+
* Default palette mapping per presentation type (used if KB doesn't specify).
|
|
819
|
+
*/
|
|
820
|
+
private getDefaultPaletteName;
|
|
793
821
|
/**
|
|
794
822
|
* Render slides to complete HTML document.
|
|
795
823
|
*/
|
|
@@ -812,9 +840,9 @@ declare class RendererV2 {
|
|
|
812
840
|
*/
|
|
813
841
|
private renderForPrint;
|
|
814
842
|
/**
|
|
815
|
-
*
|
|
843
|
+
* Light theme print HTML (professional, white background).
|
|
816
844
|
*/
|
|
817
|
-
private
|
|
845
|
+
private getLightPrintHTML;
|
|
818
846
|
/**
|
|
819
847
|
* Dark theme print HTML (legacy).
|
|
820
848
|
*/
|
|
@@ -872,17 +900,25 @@ declare class RendererV2 {
|
|
|
872
900
|
*/
|
|
873
901
|
private escapeHtml;
|
|
874
902
|
/**
|
|
875
|
-
*
|
|
903
|
+
* Generate CSS with colors from Knowledge Base.
|
|
876
904
|
*/
|
|
877
905
|
private getCSS;
|
|
878
906
|
/**
|
|
879
|
-
*
|
|
907
|
+
* Generate CSS variables from KB palette.
|
|
908
|
+
*/
|
|
909
|
+
private getCSSVariables;
|
|
910
|
+
/**
|
|
911
|
+
* Lighten or darken a hex color.
|
|
912
|
+
*/
|
|
913
|
+
private lightenColor;
|
|
914
|
+
/**
|
|
915
|
+
* Light theme CSS (consulting style) with KB palette colors.
|
|
880
916
|
*/
|
|
881
|
-
private
|
|
917
|
+
private getLightThemeCSS;
|
|
882
918
|
/**
|
|
883
|
-
* Dark theme CSS
|
|
919
|
+
* Dark theme CSS with KB palette colors.
|
|
884
920
|
*/
|
|
885
|
-
private
|
|
921
|
+
private getDarkThemeCSS;
|
|
886
922
|
}
|
|
887
923
|
/**
|
|
888
924
|
* Create a renderer with theme matched to the presentation type.
|
|
@@ -897,7 +933,7 @@ declare class RendererV2 {
|
|
|
897
933
|
* - product_demo, investor_pitch → Startup (modern dark)
|
|
898
934
|
* - executive_briefing → Corporate (professional)
|
|
899
935
|
*/
|
|
900
|
-
declare function createRendererV2(presentationType?: PresentationType,
|
|
936
|
+
declare function createRendererV2(presentationType?: PresentationType, kb?: KnowledgeGateway): RendererV2;
|
|
901
937
|
|
|
902
938
|
/**
|
|
903
939
|
* PresentationEngineV2 - Knowledge-Driven Excellence
|
|
@@ -1221,6 +1257,8 @@ declare class SlideQualityReviewer {
|
|
|
1221
1257
|
private whitespaceRules;
|
|
1222
1258
|
private bulletLimit;
|
|
1223
1259
|
private glanceTestSeconds;
|
|
1260
|
+
private assessmentWeights;
|
|
1261
|
+
private _loggedWeights;
|
|
1224
1262
|
private hasCialdini;
|
|
1225
1263
|
private hasGestalt;
|
|
1226
1264
|
private hasTufteDataInk;
|
|
@@ -1767,7 +1805,7 @@ declare function runCodeQualityCheck(srcDir: string): Promise<boolean>;
|
|
|
1767
1805
|
* ALL decisions come from the Knowledge Base. NO hardcoded fallbacks.
|
|
1768
1806
|
*/
|
|
1769
1807
|
|
|
1770
|
-
declare const VERSION = "2.0
|
|
1808
|
+
declare const VERSION = "4.2.0";
|
|
1771
1809
|
interface GenerateOptions {
|
|
1772
1810
|
/** Input content (Markdown, text, etc.) */
|
|
1773
1811
|
content: string;
|
package/dist/index.js
CHANGED
|
@@ -93756,21 +93756,52 @@ async function initSlideGenerator() {
|
|
|
93756
93756
|
|
|
93757
93757
|
// src/core/SlideGeneratorV2.ts
|
|
93758
93758
|
var import_marked = require("marked");
|
|
93759
|
-
var
|
|
93760
|
-
// Consulting decks: 40-80 words per slide is NORMAL
|
|
93759
|
+
var DEFAULT_CONFIGS = {
|
|
93760
|
+
// Consulting decks: 40-80 words per slide is NORMAL (from KB)
|
|
93761
93761
|
consulting_deck: {
|
|
93762
93762
|
maxBulletsPerSlide: 7,
|
|
93763
|
-
maxWordsPerSlide:
|
|
93764
|
-
//
|
|
93763
|
+
maxWordsPerSlide: 80,
|
|
93764
|
+
// KB: words_per_slide.max
|
|
93765
93765
|
minBulletsToKeep: 3
|
|
93766
93766
|
},
|
|
93767
|
-
|
|
93768
|
-
|
|
93767
|
+
investment_banking: {
|
|
93768
|
+
maxBulletsPerSlide: 8,
|
|
93769
|
+
maxWordsPerSlide: 120,
|
|
93770
|
+
// KB: words_per_slide.max
|
|
93771
|
+
minBulletsToKeep: 3
|
|
93772
|
+
},
|
|
93773
|
+
// Keynotes: fewer words, more impact (from KB)
|
|
93774
|
+
ted_keynote: {
|
|
93769
93775
|
maxBulletsPerSlide: 4,
|
|
93776
|
+
maxWordsPerSlide: 15,
|
|
93777
|
+
// KB: words_per_slide.max
|
|
93778
|
+
minBulletsToKeep: 2
|
|
93779
|
+
},
|
|
93780
|
+
sales_pitch: {
|
|
93781
|
+
maxBulletsPerSlide: 5,
|
|
93770
93782
|
maxWordsPerSlide: 30,
|
|
93783
|
+
// KB: words_per_slide.max
|
|
93784
|
+
minBulletsToKeep: 2
|
|
93785
|
+
},
|
|
93786
|
+
investor_pitch: {
|
|
93787
|
+
maxBulletsPerSlide: 5,
|
|
93788
|
+
maxWordsPerSlide: 50,
|
|
93789
|
+
// KB: words_per_slide.max
|
|
93771
93790
|
minBulletsToKeep: 2
|
|
93772
93791
|
},
|
|
93773
|
-
|
|
93792
|
+
technical_presentation: {
|
|
93793
|
+
maxBulletsPerSlide: 6,
|
|
93794
|
+
maxWordsPerSlide: 100,
|
|
93795
|
+
// KB: words_per_slide.max
|
|
93796
|
+
minBulletsToKeep: 3
|
|
93797
|
+
},
|
|
93798
|
+
all_hands: {
|
|
93799
|
+
maxBulletsPerSlide: 5,
|
|
93800
|
+
maxWordsPerSlide: 40,
|
|
93801
|
+
// KB: words_per_slide.max
|
|
93802
|
+
minBulletsToKeep: 2
|
|
93803
|
+
},
|
|
93804
|
+
// Default: fallback
|
|
93774
93805
|
default: {
|
|
93775
93806
|
maxBulletsPerSlide: 6,
|
|
93776
93807
|
maxWordsPerSlide: 80,
|
|
@@ -93780,9 +93811,25 @@ var MODE_CONFIGS = {
|
|
|
93780
93811
|
var SlideGeneratorV2 = class {
|
|
93781
93812
|
config;
|
|
93782
93813
|
presentationType;
|
|
93814
|
+
/**
|
|
93815
|
+
* Create a slide generator with default configs.
|
|
93816
|
+
* For KB-driven configs, use createSlideGeneratorV2WithConfig() instead.
|
|
93817
|
+
*/
|
|
93783
93818
|
constructor(presentationType = "consulting_deck") {
|
|
93784
93819
|
this.presentationType = presentationType;
|
|
93785
|
-
this.config =
|
|
93820
|
+
this.config = DEFAULT_CONFIGS[presentationType] || DEFAULT_CONFIGS.default;
|
|
93821
|
+
}
|
|
93822
|
+
/**
|
|
93823
|
+
* Override config with KB-loaded values at runtime.
|
|
93824
|
+
*/
|
|
93825
|
+
setConfig(config2) {
|
|
93826
|
+
this.config = config2;
|
|
93827
|
+
}
|
|
93828
|
+
/**
|
|
93829
|
+
* Get current config (useful for debugging).
|
|
93830
|
+
*/
|
|
93831
|
+
getConfig() {
|
|
93832
|
+
return this.config;
|
|
93786
93833
|
}
|
|
93787
93834
|
/**
|
|
93788
93835
|
* Generate slides from markdown content.
|
|
@@ -94158,69 +94205,112 @@ function createSlideGeneratorV2(type = "consulting_deck") {
|
|
|
94158
94205
|
|
|
94159
94206
|
// src/output/RendererV2.ts
|
|
94160
94207
|
var import_fs8 = require("fs");
|
|
94161
|
-
var
|
|
94162
|
-
|
|
94163
|
-
|
|
94164
|
-
|
|
94165
|
-
|
|
94166
|
-
|
|
94167
|
-
|
|
94208
|
+
var FALLBACK_PALETTES = {
|
|
94209
|
+
consulting_classic: {
|
|
94210
|
+
background: "#FAFAF9",
|
|
94211
|
+
primary: "#0F172A",
|
|
94212
|
+
secondary: "#475569",
|
|
94213
|
+
accent: "#0369A1",
|
|
94214
|
+
text: "#18181B",
|
|
94215
|
+
name: "Consulting Classic"
|
|
94168
94216
|
},
|
|
94169
|
-
|
|
94170
|
-
|
|
94171
|
-
|
|
94172
|
-
|
|
94173
|
-
|
|
94217
|
+
dark_executive: {
|
|
94218
|
+
background: "#18181B",
|
|
94219
|
+
primary: "#FAFAFA",
|
|
94220
|
+
secondary: "#A1A1AA",
|
|
94221
|
+
accent: "#F59E0B",
|
|
94222
|
+
text: "#F4F4F5",
|
|
94223
|
+
name: "Dark Executive"
|
|
94174
94224
|
},
|
|
94175
|
-
|
|
94176
|
-
|
|
94177
|
-
|
|
94178
|
-
|
|
94179
|
-
|
|
94225
|
+
modern_business: {
|
|
94226
|
+
background: "#F8FAFC",
|
|
94227
|
+
primary: "#1E293B",
|
|
94228
|
+
secondary: "#64748B",
|
|
94229
|
+
accent: "#0891B2",
|
|
94230
|
+
text: "#0F172A",
|
|
94231
|
+
name: "Modern Business"
|
|
94180
94232
|
},
|
|
94181
|
-
|
|
94182
|
-
|
|
94183
|
-
|
|
94184
|
-
|
|
94185
|
-
|
|
94186
|
-
|
|
94233
|
+
executive_professional: {
|
|
94234
|
+
background: "#F5F5F4",
|
|
94235
|
+
primary: "#1E3A5F",
|
|
94236
|
+
secondary: "#64748B",
|
|
94237
|
+
accent: "#D97706",
|
|
94238
|
+
text: "#1F2937",
|
|
94239
|
+
name: "Executive Professional"
|
|
94187
94240
|
},
|
|
94188
|
-
|
|
94189
|
-
|
|
94190
|
-
|
|
94191
|
-
|
|
94192
|
-
|
|
94241
|
+
strategy_growth: {
|
|
94242
|
+
background: "#FAF9F7",
|
|
94243
|
+
primary: "#292524",
|
|
94244
|
+
secondary: "#78716C",
|
|
94245
|
+
accent: "#059669",
|
|
94246
|
+
text: "#1C1917",
|
|
94247
|
+
name: "Strategy Growth"
|
|
94193
94248
|
}
|
|
94194
94249
|
};
|
|
94195
|
-
|
|
94196
|
-
|
|
94197
|
-
|
|
94198
|
-
// Sales → Dark dramatic style (persuasion, impact)
|
|
94199
|
-
sales_pitch: "dark",
|
|
94200
|
-
// Consulting/Analysis decks → McKinsey white style (data-heavy, professional)
|
|
94201
|
-
consulting_deck: "mckinsey",
|
|
94202
|
-
// Investment Banking → McKinsey style (financial, dense data)
|
|
94203
|
-
investment_banking: "mckinsey",
|
|
94204
|
-
// Investor Pitch → Startup dark style (modern, VC audiences)
|
|
94205
|
-
investor_pitch: "startup",
|
|
94206
|
-
// Technical → Dark style (engineering audiences like dark mode)
|
|
94207
|
-
technical_presentation: "dark",
|
|
94208
|
-
// All Hands → Minimal clean style (readable, accessible)
|
|
94209
|
-
all_hands: "minimal"
|
|
94210
|
-
};
|
|
94250
|
+
function getPaletteStyle(paletteName) {
|
|
94251
|
+
return paletteName === "dark_executive" ? "dark" : "light";
|
|
94252
|
+
}
|
|
94211
94253
|
var RendererV2 = class {
|
|
94212
94254
|
theme;
|
|
94213
94255
|
presentationType;
|
|
94256
|
+
kb;
|
|
94214
94257
|
/**
|
|
94215
|
-
* Create renderer with theme
|
|
94216
|
-
* @param presentationType - The type of deck being created (determines
|
|
94217
|
-
* @param
|
|
94258
|
+
* Create renderer with theme loaded from Knowledge Base.
|
|
94259
|
+
* @param presentationType - The type of deck being created (determines palette)
|
|
94260
|
+
* @param kb - Knowledge Base gateway (optional, will use global if not provided)
|
|
94218
94261
|
*/
|
|
94219
|
-
constructor(presentationType = "consulting_deck",
|
|
94262
|
+
constructor(presentationType = "consulting_deck", kb) {
|
|
94220
94263
|
this.presentationType = presentationType;
|
|
94221
|
-
|
|
94222
|
-
this.theme =
|
|
94223
|
-
console.log(`[RendererV2] Using "${this.theme.
|
|
94264
|
+
this.kb = kb || getKB();
|
|
94265
|
+
this.theme = this.loadThemeFromKB(presentationType);
|
|
94266
|
+
console.log(`[RendererV2] Using "${this.theme.paletteName}" palette (${this.theme.style} style) for "${presentationType}" deck`);
|
|
94267
|
+
}
|
|
94268
|
+
/**
|
|
94269
|
+
* Load theme configuration from Knowledge Base.
|
|
94270
|
+
* Falls back to hardcoded values only if KB fails.
|
|
94271
|
+
*/
|
|
94272
|
+
loadThemeFromKB(type) {
|
|
94273
|
+
try {
|
|
94274
|
+
const paletteName = this.kb.queryOptional(`presentation_types.${type}.color_palette`).value || this.getDefaultPaletteName(type);
|
|
94275
|
+
const kbPalette = this.kb.queryOptional(`color_palettes.${paletteName}`).value;
|
|
94276
|
+
if (kbPalette) {
|
|
94277
|
+
console.log(`[RendererV2] Loaded "${paletteName}" palette from KB: bg=${kbPalette.background}, accent=${kbPalette.accent}`);
|
|
94278
|
+
return {
|
|
94279
|
+
style: getPaletteStyle(paletteName),
|
|
94280
|
+
palette: kbPalette,
|
|
94281
|
+
paletteName
|
|
94282
|
+
};
|
|
94283
|
+
}
|
|
94284
|
+
const fallback = FALLBACK_PALETTES[paletteName] ?? FALLBACK_PALETTES.consulting_classic;
|
|
94285
|
+
console.log(`[RendererV2] Using fallback "${paletteName}" palette`);
|
|
94286
|
+
return {
|
|
94287
|
+
style: getPaletteStyle(paletteName),
|
|
94288
|
+
palette: fallback,
|
|
94289
|
+
paletteName
|
|
94290
|
+
};
|
|
94291
|
+
} catch {
|
|
94292
|
+
const defaultPalette = FALLBACK_PALETTES.consulting_classic;
|
|
94293
|
+
return {
|
|
94294
|
+
style: "light",
|
|
94295
|
+
palette: defaultPalette,
|
|
94296
|
+
paletteName: "consulting_classic"
|
|
94297
|
+
};
|
|
94298
|
+
}
|
|
94299
|
+
}
|
|
94300
|
+
/**
|
|
94301
|
+
* Default palette mapping per presentation type (used if KB doesn't specify).
|
|
94302
|
+
*/
|
|
94303
|
+
getDefaultPaletteName(type) {
|
|
94304
|
+
const defaults = {
|
|
94305
|
+
ted_keynote: "dark_executive",
|
|
94306
|
+
sales_pitch: "modern_business",
|
|
94307
|
+
consulting_deck: "consulting_classic",
|
|
94308
|
+
investment_banking: "executive_professional",
|
|
94309
|
+
investor_pitch: "modern_business",
|
|
94310
|
+
technical_presentation: "dark_executive",
|
|
94311
|
+
all_hands: "strategy_growth"
|
|
94312
|
+
};
|
|
94313
|
+
return defaults[type] || "consulting_classic";
|
|
94224
94314
|
}
|
|
94225
94315
|
/**
|
|
94226
94316
|
* Render slides to complete HTML document.
|
|
@@ -94310,15 +94400,15 @@ ${slidesHtml}
|
|
|
94310
94400
|
const content = this.renderSlideContent(slide);
|
|
94311
94401
|
return `<div class="slide slide-${slide.type}">${content}</div>`;
|
|
94312
94402
|
}).join("\n");
|
|
94313
|
-
if (this.theme.style === "
|
|
94314
|
-
return this.
|
|
94403
|
+
if (this.theme.style === "light") {
|
|
94404
|
+
return this.getLightPrintHTML(title, slidesHtml);
|
|
94315
94405
|
}
|
|
94316
94406
|
return this.getDarkPrintHTML(title, slidesHtml);
|
|
94317
94407
|
}
|
|
94318
94408
|
/**
|
|
94319
|
-
*
|
|
94409
|
+
* Light theme print HTML (professional, white background).
|
|
94320
94410
|
*/
|
|
94321
|
-
|
|
94411
|
+
getLightPrintHTML(title, slidesHtml) {
|
|
94322
94412
|
return `<!DOCTYPE html>
|
|
94323
94413
|
<html lang="en">
|
|
94324
94414
|
<head>
|
|
@@ -94974,34 +95064,59 @@ ${content}
|
|
|
94974
95064
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
94975
95065
|
}
|
|
94976
95066
|
/**
|
|
94977
|
-
*
|
|
95067
|
+
* Generate CSS with colors from Knowledge Base.
|
|
94978
95068
|
*/
|
|
94979
95069
|
getCSS() {
|
|
94980
|
-
if (this.theme.style === "
|
|
94981
|
-
return this.
|
|
95070
|
+
if (this.theme.style === "light") {
|
|
95071
|
+
return this.getLightThemeCSS();
|
|
94982
95072
|
}
|
|
94983
|
-
return this.
|
|
95073
|
+
return this.getDarkThemeCSS();
|
|
94984
95074
|
}
|
|
94985
95075
|
/**
|
|
94986
|
-
*
|
|
95076
|
+
* Generate CSS variables from KB palette.
|
|
94987
95077
|
*/
|
|
94988
|
-
|
|
95078
|
+
getCSSVariables() {
|
|
95079
|
+
const p = this.theme.palette;
|
|
95080
|
+
const isLight = this.theme.style === "light";
|
|
95081
|
+
const bgSecondary = isLight ? this.lightenColor(p.background, -5) : this.lightenColor(p.background, 10);
|
|
95082
|
+
const bgAccent = isLight ? this.lightenColor(p.background, -10) : this.lightenColor(p.background, 15);
|
|
95083
|
+
const textMuted = isLight ? this.lightenColor(p.text, 40) : this.lightenColor(p.text, -30);
|
|
94989
95084
|
return `
|
|
94990
|
-
/*
|
|
95085
|
+
/* ${this.theme.paletteName} Theme - Loaded from Knowledge Base */
|
|
94991
95086
|
:root {
|
|
94992
|
-
--
|
|
94993
|
-
--bg-
|
|
94994
|
-
--bg-
|
|
94995
|
-
--
|
|
94996
|
-
--text-
|
|
94997
|
-
--text-
|
|
94998
|
-
--
|
|
94999
|
-
--
|
|
95087
|
+
--kb-palette: "${this.theme.paletteName}";
|
|
95088
|
+
--bg-primary: ${p.background};
|
|
95089
|
+
--bg-secondary: ${bgSecondary};
|
|
95090
|
+
--bg-accent: ${bgAccent};
|
|
95091
|
+
--text-primary: ${p.text};
|
|
95092
|
+
--text-secondary: ${p.secondary};
|
|
95093
|
+
--text-muted: ${textMuted};
|
|
95094
|
+
--color-primary: ${p.primary};
|
|
95095
|
+
--color-accent: ${p.accent};
|
|
95096
|
+
--accent-blue: ${p.accent};
|
|
95000
95097
|
--accent-green: #28a745;
|
|
95001
95098
|
--accent-red: #dc3545;
|
|
95002
|
-
--border-color: #dee2e6;
|
|
95003
|
-
--header-bar:
|
|
95004
|
-
}
|
|
95099
|
+
--border-color: ${isLight ? "#dee2e6" : "rgba(255,255,255,0.1)"};
|
|
95100
|
+
--header-bar: ${p.primary};
|
|
95101
|
+
}`;
|
|
95102
|
+
}
|
|
95103
|
+
/**
|
|
95104
|
+
* Lighten or darken a hex color.
|
|
95105
|
+
*/
|
|
95106
|
+
lightenColor(hex, percent) {
|
|
95107
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
95108
|
+
const amt = Math.round(2.55 * percent);
|
|
95109
|
+
const R = Math.max(0, Math.min(255, (num >> 16) + amt));
|
|
95110
|
+
const G = Math.max(0, Math.min(255, (num >> 8 & 255) + amt));
|
|
95111
|
+
const B = Math.max(0, Math.min(255, (num & 255) + amt));
|
|
95112
|
+
return `#${(16777216 + R * 65536 + G * 256 + B).toString(16).slice(1)}`;
|
|
95113
|
+
}
|
|
95114
|
+
/**
|
|
95115
|
+
* Light theme CSS (consulting style) with KB palette colors.
|
|
95116
|
+
*/
|
|
95117
|
+
getLightThemeCSS() {
|
|
95118
|
+
return `
|
|
95119
|
+
${this.getCSSVariables()}
|
|
95005
95120
|
|
|
95006
95121
|
.reveal {
|
|
95007
95122
|
font-family: 'Georgia', 'Times New Roman', serif;
|
|
@@ -95272,23 +95387,11 @@ ${content}
|
|
|
95272
95387
|
`;
|
|
95273
95388
|
}
|
|
95274
95389
|
/**
|
|
95275
|
-
* Dark theme CSS
|
|
95390
|
+
* Dark theme CSS with KB palette colors.
|
|
95276
95391
|
*/
|
|
95277
|
-
|
|
95392
|
+
getDarkThemeCSS() {
|
|
95278
95393
|
return `
|
|
95279
|
-
|
|
95280
|
-
:root {
|
|
95281
|
-
--bg-primary: #1a1a2e;
|
|
95282
|
-
--bg-secondary: #16213e;
|
|
95283
|
-
--bg-accent: #0f3460;
|
|
95284
|
-
--text-primary: #ffffff;
|
|
95285
|
-
--text-secondary: rgba(255, 255, 255, 0.85);
|
|
95286
|
-
--text-muted: rgba(255, 255, 255, 0.6);
|
|
95287
|
-
--accent-blue: #4a9eff;
|
|
95288
|
-
--accent-green: #00d4aa;
|
|
95289
|
-
--accent-orange: #ff9f43;
|
|
95290
|
-
--border-color: rgba(255, 255, 255, 0.1);
|
|
95291
|
-
}
|
|
95394
|
+
${this.getCSSVariables()}
|
|
95292
95395
|
|
|
95293
95396
|
.reveal {
|
|
95294
95397
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
@@ -95499,18 +95602,18 @@ ${content}
|
|
|
95499
95602
|
`;
|
|
95500
95603
|
}
|
|
95501
95604
|
};
|
|
95502
|
-
function createRendererV2(presentationType = "consulting_deck",
|
|
95503
|
-
return new RendererV2(presentationType,
|
|
95605
|
+
function createRendererV2(presentationType = "consulting_deck", kb) {
|
|
95606
|
+
return new RendererV2(presentationType, kb);
|
|
95504
95607
|
}
|
|
95505
95608
|
|
|
95506
95609
|
// src/core/PresentationEngineV2.ts
|
|
95507
95610
|
var import_fs9 = require("fs");
|
|
95508
95611
|
var PALETTE_TO_THEME = {
|
|
95509
95612
|
dark_executive: "dark",
|
|
95510
|
-
modern_business: "
|
|
95511
|
-
consulting_classic: "
|
|
95512
|
-
executive_professional: "
|
|
95513
|
-
strategy_growth: "
|
|
95613
|
+
modern_business: "light",
|
|
95614
|
+
consulting_classic: "light",
|
|
95615
|
+
executive_professional: "light",
|
|
95616
|
+
strategy_growth: "light"
|
|
95514
95617
|
};
|
|
95515
95618
|
async function loadDesignSpecsFromKB(kb, type) {
|
|
95516
95619
|
const typeConfig = kb.queryRequired(`presentation_types.${type}`);
|
|
@@ -95521,7 +95624,7 @@ async function loadDesignSpecsFromKB(kb, type) {
|
|
|
95521
95624
|
const typography = typeConfig.value.typography;
|
|
95522
95625
|
const primaryExperts = typeConfig.value.primary_experts;
|
|
95523
95626
|
const colorPalette = typeConfig.value.color_palette || "consulting_classic";
|
|
95524
|
-
const theme = PALETTE_TO_THEME[colorPalette] || "
|
|
95627
|
+
const theme = PALETTE_TO_THEME[colorPalette] || "light";
|
|
95525
95628
|
const scoringWeights = typeConfig.value.scoring_weights;
|
|
95526
95629
|
let structure = "General presentation structure";
|
|
95527
95630
|
if (primaryExperts.some((e) => e.includes("Minto") || e.includes("McKinsey"))) {
|
|
@@ -95658,7 +95761,7 @@ Summary: ${review.summary}`
|
|
|
95658
95761
|
);
|
|
95659
95762
|
}
|
|
95660
95763
|
this.log("Step 7: Rendering output...");
|
|
95661
|
-
const renderer = createRendererV2(presentationType, this.
|
|
95764
|
+
const renderer = createRendererV2(presentationType, this.kb);
|
|
95662
95765
|
const html = renderer.render(slides, title || "Presentation");
|
|
95663
95766
|
this.log(`
|
|
95664
95767
|
SUCCESS: Generated ${slides.length} slides scoring ${review.overallScore}/100`);
|
|
@@ -96014,7 +96117,7 @@ Output: ${htmlPath}`);
|
|
|
96014
96117
|
}
|
|
96015
96118
|
|
|
96016
96119
|
// src/qa/SlideQualityReviewer.ts
|
|
96017
|
-
var
|
|
96120
|
+
var DEFAULT_ASSESSMENT_WEIGHTS = {
|
|
96018
96121
|
visualImpact: 0.25,
|
|
96019
96122
|
contentClarity: 0.2,
|
|
96020
96123
|
layoutBalance: 0.15,
|
|
@@ -96023,6 +96126,29 @@ var ASSESSMENT_WEIGHTS = {
|
|
|
96023
96126
|
colorHarmony: 0.1,
|
|
96024
96127
|
audienceAppropriate: 0.05
|
|
96025
96128
|
};
|
|
96129
|
+
function computeWeightsFromKB(kbWeights) {
|
|
96130
|
+
const totalKB = kbWeights.visual_quality + kbWeights.content_quality + kbWeights.expert_compliance + kbWeights.accessibility;
|
|
96131
|
+
const vq = kbWeights.visual_quality / totalKB;
|
|
96132
|
+
const cq = kbWeights.content_quality / totalKB;
|
|
96133
|
+
const ec = kbWeights.expert_compliance / totalKB;
|
|
96134
|
+
const ac = kbWeights.accessibility / totalKB;
|
|
96135
|
+
return {
|
|
96136
|
+
visualImpact: vq * 0.6,
|
|
96137
|
+
// 60% of visual_quality
|
|
96138
|
+
colorHarmony: vq * 0.4,
|
|
96139
|
+
// 40% of visual_quality
|
|
96140
|
+
contentClarity: cq * 0.8,
|
|
96141
|
+
// 80% of content_quality
|
|
96142
|
+
audienceAppropriate: cq * 0.2,
|
|
96143
|
+
// 20% of content_quality
|
|
96144
|
+
layoutBalance: ec * 0.5,
|
|
96145
|
+
// 50% of expert_compliance
|
|
96146
|
+
typographyHierarchy: ec * 0.5,
|
|
96147
|
+
// 50% of expert_compliance
|
|
96148
|
+
whitespaceUsage: ac
|
|
96149
|
+
// 100% of accessibility
|
|
96150
|
+
};
|
|
96151
|
+
}
|
|
96026
96152
|
var SlideQualityReviewer = class {
|
|
96027
96153
|
kb;
|
|
96028
96154
|
initialized = false;
|
|
@@ -96031,6 +96157,9 @@ var SlideQualityReviewer = class {
|
|
|
96031
96157
|
whitespaceRules;
|
|
96032
96158
|
bulletLimit;
|
|
96033
96159
|
glanceTestSeconds;
|
|
96160
|
+
// KB-loaded scoring weights (computed from KB per presentation type)
|
|
96161
|
+
assessmentWeights = DEFAULT_ASSESSMENT_WEIGHTS;
|
|
96162
|
+
_loggedWeights = null;
|
|
96034
96163
|
// Expert rules from KB
|
|
96035
96164
|
hasCialdini = false;
|
|
96036
96165
|
hasGestalt = false;
|
|
@@ -96061,7 +96190,7 @@ var SlideQualityReviewer = class {
|
|
|
96061
96190
|
};
|
|
96062
96191
|
let totalScore = 0;
|
|
96063
96192
|
for (const [key, assessment] of Object.entries(assessments)) {
|
|
96064
|
-
const weight =
|
|
96193
|
+
const weight = this.assessmentWeights[key];
|
|
96065
96194
|
totalScore += assessment.score * weight;
|
|
96066
96195
|
}
|
|
96067
96196
|
const score = Math.round(totalScore);
|
|
@@ -96116,6 +96245,18 @@ var SlideQualityReviewer = class {
|
|
|
96116
96245
|
this.wordLimits = wordLimitsResult.value;
|
|
96117
96246
|
const whitespaceResult = this.kb.getWhitespaceRules(type);
|
|
96118
96247
|
this.whitespaceRules = whitespaceResult.value;
|
|
96248
|
+
try {
|
|
96249
|
+
const weightsResult = this.kb.getScoringWeights(type);
|
|
96250
|
+
const kbWeights = weightsResult.value;
|
|
96251
|
+
this.assessmentWeights = computeWeightsFromKB(kbWeights);
|
|
96252
|
+
if (!this._loggedWeights?.has(type)) {
|
|
96253
|
+
console.log(`[QA] Loaded scoring weights for ${type}: visual=${kbWeights.visual_quality}%, content=${kbWeights.content_quality}%, expert=${kbWeights.expert_compliance}%, accessibility=${kbWeights.accessibility}%`);
|
|
96254
|
+
if (!this._loggedWeights) this._loggedWeights = /* @__PURE__ */ new Set();
|
|
96255
|
+
this._loggedWeights.add(type);
|
|
96256
|
+
}
|
|
96257
|
+
} catch {
|
|
96258
|
+
this.assessmentWeights = DEFAULT_ASSESSMENT_WEIGHTS;
|
|
96259
|
+
}
|
|
96119
96260
|
try {
|
|
96120
96261
|
const glanceResult = this.kb.getGlanceTest();
|
|
96121
96262
|
this.glanceTestSeconds = 3;
|
|
@@ -99409,7 +99550,7 @@ if (typeof process !== "undefined" && process.argv[1]?.includes("CodeQualityVali
|
|
|
99409
99550
|
}
|
|
99410
99551
|
|
|
99411
99552
|
// src/index.ts
|
|
99412
|
-
var VERSION = "2.0
|
|
99553
|
+
var VERSION = "4.2.0";
|
|
99413
99554
|
async function generate(options) {
|
|
99414
99555
|
const {
|
|
99415
99556
|
content,
|
package/dist/index.mjs
CHANGED
|
@@ -2040,21 +2040,52 @@ async function initSlideGenerator() {
|
|
|
2040
2040
|
|
|
2041
2041
|
// src/core/SlideGeneratorV2.ts
|
|
2042
2042
|
import { marked } from "marked";
|
|
2043
|
-
var
|
|
2044
|
-
// Consulting decks: 40-80 words per slide is NORMAL
|
|
2043
|
+
var DEFAULT_CONFIGS = {
|
|
2044
|
+
// Consulting decks: 40-80 words per slide is NORMAL (from KB)
|
|
2045
2045
|
consulting_deck: {
|
|
2046
2046
|
maxBulletsPerSlide: 7,
|
|
2047
|
-
maxWordsPerSlide:
|
|
2048
|
-
//
|
|
2047
|
+
maxWordsPerSlide: 80,
|
|
2048
|
+
// KB: words_per_slide.max
|
|
2049
2049
|
minBulletsToKeep: 3
|
|
2050
2050
|
},
|
|
2051
|
-
|
|
2052
|
-
|
|
2051
|
+
investment_banking: {
|
|
2052
|
+
maxBulletsPerSlide: 8,
|
|
2053
|
+
maxWordsPerSlide: 120,
|
|
2054
|
+
// KB: words_per_slide.max
|
|
2055
|
+
minBulletsToKeep: 3
|
|
2056
|
+
},
|
|
2057
|
+
// Keynotes: fewer words, more impact (from KB)
|
|
2058
|
+
ted_keynote: {
|
|
2053
2059
|
maxBulletsPerSlide: 4,
|
|
2060
|
+
maxWordsPerSlide: 15,
|
|
2061
|
+
// KB: words_per_slide.max
|
|
2062
|
+
minBulletsToKeep: 2
|
|
2063
|
+
},
|
|
2064
|
+
sales_pitch: {
|
|
2065
|
+
maxBulletsPerSlide: 5,
|
|
2054
2066
|
maxWordsPerSlide: 30,
|
|
2067
|
+
// KB: words_per_slide.max
|
|
2068
|
+
minBulletsToKeep: 2
|
|
2069
|
+
},
|
|
2070
|
+
investor_pitch: {
|
|
2071
|
+
maxBulletsPerSlide: 5,
|
|
2072
|
+
maxWordsPerSlide: 50,
|
|
2073
|
+
// KB: words_per_slide.max
|
|
2055
2074
|
minBulletsToKeep: 2
|
|
2056
2075
|
},
|
|
2057
|
-
|
|
2076
|
+
technical_presentation: {
|
|
2077
|
+
maxBulletsPerSlide: 6,
|
|
2078
|
+
maxWordsPerSlide: 100,
|
|
2079
|
+
// KB: words_per_slide.max
|
|
2080
|
+
minBulletsToKeep: 3
|
|
2081
|
+
},
|
|
2082
|
+
all_hands: {
|
|
2083
|
+
maxBulletsPerSlide: 5,
|
|
2084
|
+
maxWordsPerSlide: 40,
|
|
2085
|
+
// KB: words_per_slide.max
|
|
2086
|
+
minBulletsToKeep: 2
|
|
2087
|
+
},
|
|
2088
|
+
// Default: fallback
|
|
2058
2089
|
default: {
|
|
2059
2090
|
maxBulletsPerSlide: 6,
|
|
2060
2091
|
maxWordsPerSlide: 80,
|
|
@@ -2064,9 +2095,25 @@ var MODE_CONFIGS = {
|
|
|
2064
2095
|
var SlideGeneratorV2 = class {
|
|
2065
2096
|
config;
|
|
2066
2097
|
presentationType;
|
|
2098
|
+
/**
|
|
2099
|
+
* Create a slide generator with default configs.
|
|
2100
|
+
* For KB-driven configs, use createSlideGeneratorV2WithConfig() instead.
|
|
2101
|
+
*/
|
|
2067
2102
|
constructor(presentationType = "consulting_deck") {
|
|
2068
2103
|
this.presentationType = presentationType;
|
|
2069
|
-
this.config =
|
|
2104
|
+
this.config = DEFAULT_CONFIGS[presentationType] || DEFAULT_CONFIGS.default;
|
|
2105
|
+
}
|
|
2106
|
+
/**
|
|
2107
|
+
* Override config with KB-loaded values at runtime.
|
|
2108
|
+
*/
|
|
2109
|
+
setConfig(config) {
|
|
2110
|
+
this.config = config;
|
|
2111
|
+
}
|
|
2112
|
+
/**
|
|
2113
|
+
* Get current config (useful for debugging).
|
|
2114
|
+
*/
|
|
2115
|
+
getConfig() {
|
|
2116
|
+
return this.config;
|
|
2070
2117
|
}
|
|
2071
2118
|
/**
|
|
2072
2119
|
* Generate slides from markdown content.
|
|
@@ -2442,69 +2489,112 @@ function createSlideGeneratorV2(type = "consulting_deck") {
|
|
|
2442
2489
|
|
|
2443
2490
|
// src/output/RendererV2.ts
|
|
2444
2491
|
import { writeFileSync } from "fs";
|
|
2445
|
-
var
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2492
|
+
var FALLBACK_PALETTES = {
|
|
2493
|
+
consulting_classic: {
|
|
2494
|
+
background: "#FAFAF9",
|
|
2495
|
+
primary: "#0F172A",
|
|
2496
|
+
secondary: "#475569",
|
|
2497
|
+
accent: "#0369A1",
|
|
2498
|
+
text: "#18181B",
|
|
2499
|
+
name: "Consulting Classic"
|
|
2452
2500
|
},
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2501
|
+
dark_executive: {
|
|
2502
|
+
background: "#18181B",
|
|
2503
|
+
primary: "#FAFAFA",
|
|
2504
|
+
secondary: "#A1A1AA",
|
|
2505
|
+
accent: "#F59E0B",
|
|
2506
|
+
text: "#F4F4F5",
|
|
2507
|
+
name: "Dark Executive"
|
|
2458
2508
|
},
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2509
|
+
modern_business: {
|
|
2510
|
+
background: "#F8FAFC",
|
|
2511
|
+
primary: "#1E293B",
|
|
2512
|
+
secondary: "#64748B",
|
|
2513
|
+
accent: "#0891B2",
|
|
2514
|
+
text: "#0F172A",
|
|
2515
|
+
name: "Modern Business"
|
|
2464
2516
|
},
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2517
|
+
executive_professional: {
|
|
2518
|
+
background: "#F5F5F4",
|
|
2519
|
+
primary: "#1E3A5F",
|
|
2520
|
+
secondary: "#64748B",
|
|
2521
|
+
accent: "#D97706",
|
|
2522
|
+
text: "#1F2937",
|
|
2523
|
+
name: "Executive Professional"
|
|
2471
2524
|
},
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2525
|
+
strategy_growth: {
|
|
2526
|
+
background: "#FAF9F7",
|
|
2527
|
+
primary: "#292524",
|
|
2528
|
+
secondary: "#78716C",
|
|
2529
|
+
accent: "#059669",
|
|
2530
|
+
text: "#1C1917",
|
|
2531
|
+
name: "Strategy Growth"
|
|
2477
2532
|
}
|
|
2478
2533
|
};
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
// Sales → Dark dramatic style (persuasion, impact)
|
|
2483
|
-
sales_pitch: "dark",
|
|
2484
|
-
// Consulting/Analysis decks → McKinsey white style (data-heavy, professional)
|
|
2485
|
-
consulting_deck: "mckinsey",
|
|
2486
|
-
// Investment Banking → McKinsey style (financial, dense data)
|
|
2487
|
-
investment_banking: "mckinsey",
|
|
2488
|
-
// Investor Pitch → Startup dark style (modern, VC audiences)
|
|
2489
|
-
investor_pitch: "startup",
|
|
2490
|
-
// Technical → Dark style (engineering audiences like dark mode)
|
|
2491
|
-
technical_presentation: "dark",
|
|
2492
|
-
// All Hands → Minimal clean style (readable, accessible)
|
|
2493
|
-
all_hands: "minimal"
|
|
2494
|
-
};
|
|
2534
|
+
function getPaletteStyle(paletteName) {
|
|
2535
|
+
return paletteName === "dark_executive" ? "dark" : "light";
|
|
2536
|
+
}
|
|
2495
2537
|
var RendererV2 = class {
|
|
2496
2538
|
theme;
|
|
2497
2539
|
presentationType;
|
|
2540
|
+
kb;
|
|
2498
2541
|
/**
|
|
2499
|
-
* Create renderer with theme
|
|
2500
|
-
* @param presentationType - The type of deck being created (determines
|
|
2501
|
-
* @param
|
|
2542
|
+
* Create renderer with theme loaded from Knowledge Base.
|
|
2543
|
+
* @param presentationType - The type of deck being created (determines palette)
|
|
2544
|
+
* @param kb - Knowledge Base gateway (optional, will use global if not provided)
|
|
2502
2545
|
*/
|
|
2503
|
-
constructor(presentationType = "consulting_deck",
|
|
2546
|
+
constructor(presentationType = "consulting_deck", kb) {
|
|
2504
2547
|
this.presentationType = presentationType;
|
|
2505
|
-
|
|
2506
|
-
this.theme =
|
|
2507
|
-
console.log(`[RendererV2] Using "${this.theme.
|
|
2548
|
+
this.kb = kb || getKB();
|
|
2549
|
+
this.theme = this.loadThemeFromKB(presentationType);
|
|
2550
|
+
console.log(`[RendererV2] Using "${this.theme.paletteName}" palette (${this.theme.style} style) for "${presentationType}" deck`);
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* Load theme configuration from Knowledge Base.
|
|
2554
|
+
* Falls back to hardcoded values only if KB fails.
|
|
2555
|
+
*/
|
|
2556
|
+
loadThemeFromKB(type) {
|
|
2557
|
+
try {
|
|
2558
|
+
const paletteName = this.kb.queryOptional(`presentation_types.${type}.color_palette`).value || this.getDefaultPaletteName(type);
|
|
2559
|
+
const kbPalette = this.kb.queryOptional(`color_palettes.${paletteName}`).value;
|
|
2560
|
+
if (kbPalette) {
|
|
2561
|
+
console.log(`[RendererV2] Loaded "${paletteName}" palette from KB: bg=${kbPalette.background}, accent=${kbPalette.accent}`);
|
|
2562
|
+
return {
|
|
2563
|
+
style: getPaletteStyle(paletteName),
|
|
2564
|
+
palette: kbPalette,
|
|
2565
|
+
paletteName
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
const fallback = FALLBACK_PALETTES[paletteName] ?? FALLBACK_PALETTES.consulting_classic;
|
|
2569
|
+
console.log(`[RendererV2] Using fallback "${paletteName}" palette`);
|
|
2570
|
+
return {
|
|
2571
|
+
style: getPaletteStyle(paletteName),
|
|
2572
|
+
palette: fallback,
|
|
2573
|
+
paletteName
|
|
2574
|
+
};
|
|
2575
|
+
} catch {
|
|
2576
|
+
const defaultPalette = FALLBACK_PALETTES.consulting_classic;
|
|
2577
|
+
return {
|
|
2578
|
+
style: "light",
|
|
2579
|
+
palette: defaultPalette,
|
|
2580
|
+
paletteName: "consulting_classic"
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Default palette mapping per presentation type (used if KB doesn't specify).
|
|
2586
|
+
*/
|
|
2587
|
+
getDefaultPaletteName(type) {
|
|
2588
|
+
const defaults = {
|
|
2589
|
+
ted_keynote: "dark_executive",
|
|
2590
|
+
sales_pitch: "modern_business",
|
|
2591
|
+
consulting_deck: "consulting_classic",
|
|
2592
|
+
investment_banking: "executive_professional",
|
|
2593
|
+
investor_pitch: "modern_business",
|
|
2594
|
+
technical_presentation: "dark_executive",
|
|
2595
|
+
all_hands: "strategy_growth"
|
|
2596
|
+
};
|
|
2597
|
+
return defaults[type] || "consulting_classic";
|
|
2508
2598
|
}
|
|
2509
2599
|
/**
|
|
2510
2600
|
* Render slides to complete HTML document.
|
|
@@ -2594,15 +2684,15 @@ ${slidesHtml}
|
|
|
2594
2684
|
const content = this.renderSlideContent(slide);
|
|
2595
2685
|
return `<div class="slide slide-${slide.type}">${content}</div>`;
|
|
2596
2686
|
}).join("\n");
|
|
2597
|
-
if (this.theme.style === "
|
|
2598
|
-
return this.
|
|
2687
|
+
if (this.theme.style === "light") {
|
|
2688
|
+
return this.getLightPrintHTML(title, slidesHtml);
|
|
2599
2689
|
}
|
|
2600
2690
|
return this.getDarkPrintHTML(title, slidesHtml);
|
|
2601
2691
|
}
|
|
2602
2692
|
/**
|
|
2603
|
-
*
|
|
2693
|
+
* Light theme print HTML (professional, white background).
|
|
2604
2694
|
*/
|
|
2605
|
-
|
|
2695
|
+
getLightPrintHTML(title, slidesHtml) {
|
|
2606
2696
|
return `<!DOCTYPE html>
|
|
2607
2697
|
<html lang="en">
|
|
2608
2698
|
<head>
|
|
@@ -3258,34 +3348,59 @@ ${content}
|
|
|
3258
3348
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3259
3349
|
}
|
|
3260
3350
|
/**
|
|
3261
|
-
*
|
|
3351
|
+
* Generate CSS with colors from Knowledge Base.
|
|
3262
3352
|
*/
|
|
3263
3353
|
getCSS() {
|
|
3264
|
-
if (this.theme.style === "
|
|
3265
|
-
return this.
|
|
3354
|
+
if (this.theme.style === "light") {
|
|
3355
|
+
return this.getLightThemeCSS();
|
|
3266
3356
|
}
|
|
3267
|
-
return this.
|
|
3357
|
+
return this.getDarkThemeCSS();
|
|
3268
3358
|
}
|
|
3269
3359
|
/**
|
|
3270
|
-
*
|
|
3360
|
+
* Generate CSS variables from KB palette.
|
|
3271
3361
|
*/
|
|
3272
|
-
|
|
3362
|
+
getCSSVariables() {
|
|
3363
|
+
const p = this.theme.palette;
|
|
3364
|
+
const isLight = this.theme.style === "light";
|
|
3365
|
+
const bgSecondary = isLight ? this.lightenColor(p.background, -5) : this.lightenColor(p.background, 10);
|
|
3366
|
+
const bgAccent = isLight ? this.lightenColor(p.background, -10) : this.lightenColor(p.background, 15);
|
|
3367
|
+
const textMuted = isLight ? this.lightenColor(p.text, 40) : this.lightenColor(p.text, -30);
|
|
3273
3368
|
return `
|
|
3274
|
-
/*
|
|
3369
|
+
/* ${this.theme.paletteName} Theme - Loaded from Knowledge Base */
|
|
3275
3370
|
:root {
|
|
3276
|
-
--
|
|
3277
|
-
--bg-
|
|
3278
|
-
--bg-
|
|
3279
|
-
--
|
|
3280
|
-
--text-
|
|
3281
|
-
--text-
|
|
3282
|
-
--
|
|
3283
|
-
--
|
|
3371
|
+
--kb-palette: "${this.theme.paletteName}";
|
|
3372
|
+
--bg-primary: ${p.background};
|
|
3373
|
+
--bg-secondary: ${bgSecondary};
|
|
3374
|
+
--bg-accent: ${bgAccent};
|
|
3375
|
+
--text-primary: ${p.text};
|
|
3376
|
+
--text-secondary: ${p.secondary};
|
|
3377
|
+
--text-muted: ${textMuted};
|
|
3378
|
+
--color-primary: ${p.primary};
|
|
3379
|
+
--color-accent: ${p.accent};
|
|
3380
|
+
--accent-blue: ${p.accent};
|
|
3284
3381
|
--accent-green: #28a745;
|
|
3285
3382
|
--accent-red: #dc3545;
|
|
3286
|
-
--border-color: #dee2e6;
|
|
3287
|
-
--header-bar:
|
|
3288
|
-
}
|
|
3383
|
+
--border-color: ${isLight ? "#dee2e6" : "rgba(255,255,255,0.1)"};
|
|
3384
|
+
--header-bar: ${p.primary};
|
|
3385
|
+
}`;
|
|
3386
|
+
}
|
|
3387
|
+
/**
|
|
3388
|
+
* Lighten or darken a hex color.
|
|
3389
|
+
*/
|
|
3390
|
+
lightenColor(hex, percent) {
|
|
3391
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
3392
|
+
const amt = Math.round(2.55 * percent);
|
|
3393
|
+
const R = Math.max(0, Math.min(255, (num >> 16) + amt));
|
|
3394
|
+
const G = Math.max(0, Math.min(255, (num >> 8 & 255) + amt));
|
|
3395
|
+
const B = Math.max(0, Math.min(255, (num & 255) + amt));
|
|
3396
|
+
return `#${(16777216 + R * 65536 + G * 256 + B).toString(16).slice(1)}`;
|
|
3397
|
+
}
|
|
3398
|
+
/**
|
|
3399
|
+
* Light theme CSS (consulting style) with KB palette colors.
|
|
3400
|
+
*/
|
|
3401
|
+
getLightThemeCSS() {
|
|
3402
|
+
return `
|
|
3403
|
+
${this.getCSSVariables()}
|
|
3289
3404
|
|
|
3290
3405
|
.reveal {
|
|
3291
3406
|
font-family: 'Georgia', 'Times New Roman', serif;
|
|
@@ -3556,23 +3671,11 @@ ${content}
|
|
|
3556
3671
|
`;
|
|
3557
3672
|
}
|
|
3558
3673
|
/**
|
|
3559
|
-
* Dark theme CSS
|
|
3674
|
+
* Dark theme CSS with KB palette colors.
|
|
3560
3675
|
*/
|
|
3561
|
-
|
|
3676
|
+
getDarkThemeCSS() {
|
|
3562
3677
|
return `
|
|
3563
|
-
|
|
3564
|
-
:root {
|
|
3565
|
-
--bg-primary: #1a1a2e;
|
|
3566
|
-
--bg-secondary: #16213e;
|
|
3567
|
-
--bg-accent: #0f3460;
|
|
3568
|
-
--text-primary: #ffffff;
|
|
3569
|
-
--text-secondary: rgba(255, 255, 255, 0.85);
|
|
3570
|
-
--text-muted: rgba(255, 255, 255, 0.6);
|
|
3571
|
-
--accent-blue: #4a9eff;
|
|
3572
|
-
--accent-green: #00d4aa;
|
|
3573
|
-
--accent-orange: #ff9f43;
|
|
3574
|
-
--border-color: rgba(255, 255, 255, 0.1);
|
|
3575
|
-
}
|
|
3678
|
+
${this.getCSSVariables()}
|
|
3576
3679
|
|
|
3577
3680
|
.reveal {
|
|
3578
3681
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
@@ -3783,18 +3886,18 @@ ${content}
|
|
|
3783
3886
|
`;
|
|
3784
3887
|
}
|
|
3785
3888
|
};
|
|
3786
|
-
function createRendererV2(presentationType = "consulting_deck",
|
|
3787
|
-
return new RendererV2(presentationType,
|
|
3889
|
+
function createRendererV2(presentationType = "consulting_deck", kb) {
|
|
3890
|
+
return new RendererV2(presentationType, kb);
|
|
3788
3891
|
}
|
|
3789
3892
|
|
|
3790
3893
|
// src/core/PresentationEngineV2.ts
|
|
3791
3894
|
import { writeFileSync as writeFileSync2 } from "fs";
|
|
3792
3895
|
var PALETTE_TO_THEME = {
|
|
3793
3896
|
dark_executive: "dark",
|
|
3794
|
-
modern_business: "
|
|
3795
|
-
consulting_classic: "
|
|
3796
|
-
executive_professional: "
|
|
3797
|
-
strategy_growth: "
|
|
3897
|
+
modern_business: "light",
|
|
3898
|
+
consulting_classic: "light",
|
|
3899
|
+
executive_professional: "light",
|
|
3900
|
+
strategy_growth: "light"
|
|
3798
3901
|
};
|
|
3799
3902
|
async function loadDesignSpecsFromKB(kb, type) {
|
|
3800
3903
|
const typeConfig = kb.queryRequired(`presentation_types.${type}`);
|
|
@@ -3805,7 +3908,7 @@ async function loadDesignSpecsFromKB(kb, type) {
|
|
|
3805
3908
|
const typography = typeConfig.value.typography;
|
|
3806
3909
|
const primaryExperts = typeConfig.value.primary_experts;
|
|
3807
3910
|
const colorPalette = typeConfig.value.color_palette || "consulting_classic";
|
|
3808
|
-
const theme = PALETTE_TO_THEME[colorPalette] || "
|
|
3911
|
+
const theme = PALETTE_TO_THEME[colorPalette] || "light";
|
|
3809
3912
|
const scoringWeights = typeConfig.value.scoring_weights;
|
|
3810
3913
|
let structure = "General presentation structure";
|
|
3811
3914
|
if (primaryExperts.some((e) => e.includes("Minto") || e.includes("McKinsey"))) {
|
|
@@ -3942,7 +4045,7 @@ Summary: ${review.summary}`
|
|
|
3942
4045
|
);
|
|
3943
4046
|
}
|
|
3944
4047
|
this.log("Step 7: Rendering output...");
|
|
3945
|
-
const renderer = createRendererV2(presentationType, this.
|
|
4048
|
+
const renderer = createRendererV2(presentationType, this.kb);
|
|
3946
4049
|
const html = renderer.render(slides, title || "Presentation");
|
|
3947
4050
|
this.log(`
|
|
3948
4051
|
SUCCESS: Generated ${slides.length} slides scoring ${review.overallScore}/100`);
|
|
@@ -4298,7 +4401,7 @@ Output: ${htmlPath}`);
|
|
|
4298
4401
|
}
|
|
4299
4402
|
|
|
4300
4403
|
// src/qa/SlideQualityReviewer.ts
|
|
4301
|
-
var
|
|
4404
|
+
var DEFAULT_ASSESSMENT_WEIGHTS = {
|
|
4302
4405
|
visualImpact: 0.25,
|
|
4303
4406
|
contentClarity: 0.2,
|
|
4304
4407
|
layoutBalance: 0.15,
|
|
@@ -4307,6 +4410,29 @@ var ASSESSMENT_WEIGHTS = {
|
|
|
4307
4410
|
colorHarmony: 0.1,
|
|
4308
4411
|
audienceAppropriate: 0.05
|
|
4309
4412
|
};
|
|
4413
|
+
function computeWeightsFromKB(kbWeights) {
|
|
4414
|
+
const totalKB = kbWeights.visual_quality + kbWeights.content_quality + kbWeights.expert_compliance + kbWeights.accessibility;
|
|
4415
|
+
const vq = kbWeights.visual_quality / totalKB;
|
|
4416
|
+
const cq = kbWeights.content_quality / totalKB;
|
|
4417
|
+
const ec = kbWeights.expert_compliance / totalKB;
|
|
4418
|
+
const ac = kbWeights.accessibility / totalKB;
|
|
4419
|
+
return {
|
|
4420
|
+
visualImpact: vq * 0.6,
|
|
4421
|
+
// 60% of visual_quality
|
|
4422
|
+
colorHarmony: vq * 0.4,
|
|
4423
|
+
// 40% of visual_quality
|
|
4424
|
+
contentClarity: cq * 0.8,
|
|
4425
|
+
// 80% of content_quality
|
|
4426
|
+
audienceAppropriate: cq * 0.2,
|
|
4427
|
+
// 20% of content_quality
|
|
4428
|
+
layoutBalance: ec * 0.5,
|
|
4429
|
+
// 50% of expert_compliance
|
|
4430
|
+
typographyHierarchy: ec * 0.5,
|
|
4431
|
+
// 50% of expert_compliance
|
|
4432
|
+
whitespaceUsage: ac
|
|
4433
|
+
// 100% of accessibility
|
|
4434
|
+
};
|
|
4435
|
+
}
|
|
4310
4436
|
var SlideQualityReviewer = class {
|
|
4311
4437
|
kb;
|
|
4312
4438
|
initialized = false;
|
|
@@ -4315,6 +4441,9 @@ var SlideQualityReviewer = class {
|
|
|
4315
4441
|
whitespaceRules;
|
|
4316
4442
|
bulletLimit;
|
|
4317
4443
|
glanceTestSeconds;
|
|
4444
|
+
// KB-loaded scoring weights (computed from KB per presentation type)
|
|
4445
|
+
assessmentWeights = DEFAULT_ASSESSMENT_WEIGHTS;
|
|
4446
|
+
_loggedWeights = null;
|
|
4318
4447
|
// Expert rules from KB
|
|
4319
4448
|
hasCialdini = false;
|
|
4320
4449
|
hasGestalt = false;
|
|
@@ -4345,7 +4474,7 @@ var SlideQualityReviewer = class {
|
|
|
4345
4474
|
};
|
|
4346
4475
|
let totalScore = 0;
|
|
4347
4476
|
for (const [key, assessment] of Object.entries(assessments)) {
|
|
4348
|
-
const weight =
|
|
4477
|
+
const weight = this.assessmentWeights[key];
|
|
4349
4478
|
totalScore += assessment.score * weight;
|
|
4350
4479
|
}
|
|
4351
4480
|
const score = Math.round(totalScore);
|
|
@@ -4400,6 +4529,18 @@ var SlideQualityReviewer = class {
|
|
|
4400
4529
|
this.wordLimits = wordLimitsResult.value;
|
|
4401
4530
|
const whitespaceResult = this.kb.getWhitespaceRules(type);
|
|
4402
4531
|
this.whitespaceRules = whitespaceResult.value;
|
|
4532
|
+
try {
|
|
4533
|
+
const weightsResult = this.kb.getScoringWeights(type);
|
|
4534
|
+
const kbWeights = weightsResult.value;
|
|
4535
|
+
this.assessmentWeights = computeWeightsFromKB(kbWeights);
|
|
4536
|
+
if (!this._loggedWeights?.has(type)) {
|
|
4537
|
+
console.log(`[QA] Loaded scoring weights for ${type}: visual=${kbWeights.visual_quality}%, content=${kbWeights.content_quality}%, expert=${kbWeights.expert_compliance}%, accessibility=${kbWeights.accessibility}%`);
|
|
4538
|
+
if (!this._loggedWeights) this._loggedWeights = /* @__PURE__ */ new Set();
|
|
4539
|
+
this._loggedWeights.add(type);
|
|
4540
|
+
}
|
|
4541
|
+
} catch {
|
|
4542
|
+
this.assessmentWeights = DEFAULT_ASSESSMENT_WEIGHTS;
|
|
4543
|
+
}
|
|
4403
4544
|
try {
|
|
4404
4545
|
const glanceResult = this.kb.getGlanceTest();
|
|
4405
4546
|
this.glanceTestSeconds = 3;
|
|
@@ -7693,7 +7834,7 @@ if (typeof process !== "undefined" && process.argv[1]?.includes("CodeQualityVali
|
|
|
7693
7834
|
}
|
|
7694
7835
|
|
|
7695
7836
|
// src/index.ts
|
|
7696
|
-
var VERSION = "2.0
|
|
7837
|
+
var VERSION = "4.2.0";
|
|
7697
7838
|
async function generate(options) {
|
|
7698
7839
|
const {
|
|
7699
7840
|
content,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-presentation-master",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Generate world-class presentations using expert methodologies from Duarte, Reynolds, Gallo, and Anderson. Enforces rigorous quality standards through real visual validation.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|