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 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 v2.1.0
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.1.0';
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 - Clean, Professional, No Garbage
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
- * - McKinsey/BCG consulting style (WHITE background, strong hierarchy)
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 = 'mckinsey' | 'dark' | 'minimal' | 'corporate' | 'startup';
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 based on presentation type.
789
- * @param presentationType - The type of deck being created (determines theme)
790
- * @param themeOverride - Optional explicit theme override
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, themeOverride?: ThemeStyle);
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
- * McKinsey-style print HTML (white background, professional).
843
+ * Light theme print HTML (professional, white background).
816
844
  */
817
- private getMcKinseyPrintHTML;
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
- * Professional CSS - McKinsey/BCG consulting style.
903
+ * Generate CSS with colors from Knowledge Base.
876
904
  */
877
905
  private getCSS;
878
906
  /**
879
- * McKinsey/BCG Consulting Style - WHITE background, professional hierarchy.
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 getMcKinseyCSS;
917
+ private getLightThemeCSS;
882
918
  /**
883
- * Dark theme CSS (legacy).
919
+ * Dark theme CSS with KB palette colors.
884
920
  */
885
- private getDarkCSS;
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, themeOverride?: ThemeStyle): RendererV2;
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.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 - Clean, Professional, No Garbage
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
- * - McKinsey/BCG consulting style (WHITE background, strong hierarchy)
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 = 'mckinsey' | 'dark' | 'minimal' | 'corporate' | 'startup';
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 based on presentation type.
789
- * @param presentationType - The type of deck being created (determines theme)
790
- * @param themeOverride - Optional explicit theme override
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, themeOverride?: ThemeStyle);
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
- * McKinsey-style print HTML (white background, professional).
843
+ * Light theme print HTML (professional, white background).
816
844
  */
817
- private getMcKinseyPrintHTML;
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
- * Professional CSS - McKinsey/BCG consulting style.
903
+ * Generate CSS with colors from Knowledge Base.
876
904
  */
877
905
  private getCSS;
878
906
  /**
879
- * McKinsey/BCG Consulting Style - WHITE background, professional hierarchy.
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 getMcKinseyCSS;
917
+ private getLightThemeCSS;
882
918
  /**
883
- * Dark theme CSS (legacy).
919
+ * Dark theme CSS with KB palette colors.
884
920
  */
885
- private getDarkCSS;
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, themeOverride?: ThemeStyle): RendererV2;
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.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 MODE_CONFIGS = {
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: 100,
93764
- // Not 20!
93763
+ maxWordsPerSlide: 80,
93764
+ // KB: words_per_slide.max
93765
93765
  minBulletsToKeep: 3
93766
93766
  },
93767
- // Keynotes: fewer words, more impact
93768
- keynote: {
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
- // Default: consulting style
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 = MODE_CONFIGS[presentationType] || MODE_CONFIGS.default;
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 THEMES = {
94162
- mckinsey: {
94163
- style: "mckinsey",
94164
- primaryColor: "#003366",
94165
- // McKinsey blue
94166
- accentColor: "#0066cc",
94167
- description: "White background, professional hierarchy - for consulting/analysis decks"
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
- dark: {
94170
- style: "dark",
94171
- primaryColor: "#1a1a2e",
94172
- accentColor: "#4a9eff",
94173
- description: "Dark dramatic theme - for keynotes and tech presentations"
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
- minimal: {
94176
- style: "minimal",
94177
- primaryColor: "#333333",
94178
- accentColor: "#0066cc",
94179
- description: "Clean minimal white - for training and documentation"
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
- corporate: {
94182
- style: "mckinsey",
94183
- // Uses McKinsey CSS but with different branding potential
94184
- primaryColor: "#1a365d",
94185
- accentColor: "#3182ce",
94186
- description: "Professional corporate - for executive presentations"
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
- startup: {
94189
- style: "dark",
94190
- primaryColor: "#0d1117",
94191
- accentColor: "#58a6ff",
94192
- description: "Modern dark - for pitch decks and product demos"
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
- var PRESENTATION_TYPE_TO_THEME = {
94196
- // Keynotes Dark dramatic style (TED talks, big stage)
94197
- ted_keynote: "dark",
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 based on presentation type.
94216
- * @param presentationType - The type of deck being created (determines theme)
94217
- * @param themeOverride - Optional explicit theme override
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", themeOverride) {
94262
+ constructor(presentationType = "consulting_deck", kb) {
94220
94263
  this.presentationType = presentationType;
94221
- const themeStyle = themeOverride || PRESENTATION_TYPE_TO_THEME[presentationType] || "mckinsey";
94222
- this.theme = THEMES[themeStyle] || THEMES.mckinsey;
94223
- console.log(`[RendererV2] Using "${this.theme.style}" theme for "${presentationType}" deck`);
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 === "mckinsey") {
94314
- return this.getMcKinseyPrintHTML(title, slidesHtml);
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
- * McKinsey-style print HTML (white background, professional).
94409
+ * Light theme print HTML (professional, white background).
94320
94410
  */
94321
- getMcKinseyPrintHTML(title, slidesHtml) {
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
94975
95065
  }
94976
95066
  /**
94977
- * Professional CSS - McKinsey/BCG consulting style.
95067
+ * Generate CSS with colors from Knowledge Base.
94978
95068
  */
94979
95069
  getCSS() {
94980
- if (this.theme.style === "mckinsey") {
94981
- return this.getMcKinseyCSS();
95070
+ if (this.theme.style === "light") {
95071
+ return this.getLightThemeCSS();
94982
95072
  }
94983
- return this.getDarkCSS();
95073
+ return this.getDarkThemeCSS();
94984
95074
  }
94985
95075
  /**
94986
- * McKinsey/BCG Consulting Style - WHITE background, professional hierarchy.
95076
+ * Generate CSS variables from KB palette.
94987
95077
  */
94988
- getMcKinseyCSS() {
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
- /* McKinsey Consulting Theme - Clean White, Strong Hierarchy */
95085
+ /* ${this.theme.paletteName} Theme - Loaded from Knowledge Base */
94991
95086
  :root {
94992
- --bg-primary: #ffffff;
94993
- --bg-secondary: #f8f9fa;
94994
- --bg-accent: #e9ecef;
94995
- --text-primary: #1a1a1a;
94996
- --text-secondary: #333333;
94997
- --text-muted: #666666;
94998
- --mckinsey-blue: #003366;
94999
- --accent-blue: #0066cc;
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: #003366;
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 (legacy).
95390
+ * Dark theme CSS with KB palette colors.
95276
95391
  */
95277
- getDarkCSS() {
95392
+ getDarkThemeCSS() {
95278
95393
  return `
95279
- /* Professional Dark Theme - No Random Images */
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", themeOverride) {
95503
- return new RendererV2(presentationType, themeOverride);
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: "startup",
95511
- consulting_classic: "mckinsey",
95512
- executive_professional: "mckinsey",
95513
- strategy_growth: "minimal"
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] || "mckinsey";
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.options.themeOverride);
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 ASSESSMENT_WEIGHTS = {
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 = ASSESSMENT_WEIGHTS[key];
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.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 MODE_CONFIGS = {
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: 100,
2048
- // Not 20!
2047
+ maxWordsPerSlide: 80,
2048
+ // KB: words_per_slide.max
2049
2049
  minBulletsToKeep: 3
2050
2050
  },
2051
- // Keynotes: fewer words, more impact
2052
- keynote: {
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
- // Default: consulting style
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 = MODE_CONFIGS[presentationType] || MODE_CONFIGS.default;
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 THEMES = {
2446
- mckinsey: {
2447
- style: "mckinsey",
2448
- primaryColor: "#003366",
2449
- // McKinsey blue
2450
- accentColor: "#0066cc",
2451
- description: "White background, professional hierarchy - for consulting/analysis decks"
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
- dark: {
2454
- style: "dark",
2455
- primaryColor: "#1a1a2e",
2456
- accentColor: "#4a9eff",
2457
- description: "Dark dramatic theme - for keynotes and tech presentations"
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
- minimal: {
2460
- style: "minimal",
2461
- primaryColor: "#333333",
2462
- accentColor: "#0066cc",
2463
- description: "Clean minimal white - for training and documentation"
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
- corporate: {
2466
- style: "mckinsey",
2467
- // Uses McKinsey CSS but with different branding potential
2468
- primaryColor: "#1a365d",
2469
- accentColor: "#3182ce",
2470
- description: "Professional corporate - for executive presentations"
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
- startup: {
2473
- style: "dark",
2474
- primaryColor: "#0d1117",
2475
- accentColor: "#58a6ff",
2476
- description: "Modern dark - for pitch decks and product demos"
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
- var PRESENTATION_TYPE_TO_THEME = {
2480
- // Keynotes Dark dramatic style (TED talks, big stage)
2481
- ted_keynote: "dark",
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 based on presentation type.
2500
- * @param presentationType - The type of deck being created (determines theme)
2501
- * @param themeOverride - Optional explicit theme override
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", themeOverride) {
2546
+ constructor(presentationType = "consulting_deck", kb) {
2504
2547
  this.presentationType = presentationType;
2505
- const themeStyle = themeOverride || PRESENTATION_TYPE_TO_THEME[presentationType] || "mckinsey";
2506
- this.theme = THEMES[themeStyle] || THEMES.mckinsey;
2507
- console.log(`[RendererV2] Using "${this.theme.style}" theme for "${presentationType}" deck`);
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 === "mckinsey") {
2598
- return this.getMcKinseyPrintHTML(title, slidesHtml);
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
- * McKinsey-style print HTML (white background, professional).
2693
+ * Light theme print HTML (professional, white background).
2604
2694
  */
2605
- getMcKinseyPrintHTML(title, slidesHtml) {
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
3259
3349
  }
3260
3350
  /**
3261
- * Professional CSS - McKinsey/BCG consulting style.
3351
+ * Generate CSS with colors from Knowledge Base.
3262
3352
  */
3263
3353
  getCSS() {
3264
- if (this.theme.style === "mckinsey") {
3265
- return this.getMcKinseyCSS();
3354
+ if (this.theme.style === "light") {
3355
+ return this.getLightThemeCSS();
3266
3356
  }
3267
- return this.getDarkCSS();
3357
+ return this.getDarkThemeCSS();
3268
3358
  }
3269
3359
  /**
3270
- * McKinsey/BCG Consulting Style - WHITE background, professional hierarchy.
3360
+ * Generate CSS variables from KB palette.
3271
3361
  */
3272
- getMcKinseyCSS() {
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
- /* McKinsey Consulting Theme - Clean White, Strong Hierarchy */
3369
+ /* ${this.theme.paletteName} Theme - Loaded from Knowledge Base */
3275
3370
  :root {
3276
- --bg-primary: #ffffff;
3277
- --bg-secondary: #f8f9fa;
3278
- --bg-accent: #e9ecef;
3279
- --text-primary: #1a1a1a;
3280
- --text-secondary: #333333;
3281
- --text-muted: #666666;
3282
- --mckinsey-blue: #003366;
3283
- --accent-blue: #0066cc;
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: #003366;
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 (legacy).
3674
+ * Dark theme CSS with KB palette colors.
3560
3675
  */
3561
- getDarkCSS() {
3676
+ getDarkThemeCSS() {
3562
3677
  return `
3563
- /* Professional Dark Theme - No Random Images */
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", themeOverride) {
3787
- return new RendererV2(presentationType, themeOverride);
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: "startup",
3795
- consulting_classic: "mckinsey",
3796
- executive_professional: "mckinsey",
3797
- strategy_growth: "minimal"
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] || "mckinsey";
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.options.themeOverride);
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 ASSESSMENT_WEIGHTS = {
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 = ASSESSMENT_WEIGHTS[key];
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.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.0.0",
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",