UNPKG

hatch-slidev-builder-mcp

Version:

A comprehensive MCP server for creating Slidev presentations with component library, interactive elements, and team collaboration features

60 lines (59 loc) 10.4 kB
/** * Enhanced Slidev Builder Tool with 4-Layer Architecture * Combines Content Intelligence, Layout Optimization, Asset Intelligence, and Style Orchestration */ import { z } from 'zod'; import { SlidevBuilderOrchestrator } from '../layers/SlidevOrchestrator.js'; import path from 'path'; import fs from 'fs/promises'; const generateIntelligentDeckSchema = z.object({ content: z.string().describe('The main content or description for the presentation'), title: z.string().describe('Title of the presentation'), audience: z.enum(['executive', 'technical', 'general']).describe('Target audience type'), presentation_type: z.enum(['business', 'technical', 'creative', 'educational']).describe('Type of presentation'), brand_guidelines: z.string().optional().describe('Brand guidelines to follow (e.g., "hatch_corporate")'), output_dir: z.string().describe('Output directory for the generated presentation'), time_constraint: z.number().optional().describe('Time constraint in minutes'), accessibility_requirements: z.array(z.string()).optional().describe('Specific accessibility requirements'), enable_ai_enhancement: z.boolean().default(true).describe('Enable AI-powered content enhancement'), include_speaker_notes: z.boolean().default(false).describe('Include speaker notes for each slide') }); export async function generateIntelligentDeck(args) { try { console.log('🚀 Starting Intelligent Slide Deck Generation...'); // Prepare the generation request const request = { content: args.content, audience: args.audience, presentation_type: args.presentation_type, brand_guidelines: args.brand_guidelines || 'hatch_corporate', time_constraint: args.time_constraint, accessibility_requirements: args.accessibility_requirements || [] }; // Generate slides using 4-layer orchestrator const result = await SlidevBuilderOrchestrator.generateSlideDeck(request); // Create output directory await fs.mkdir(args.output_dir, { recursive: true }); // Generate slides.md file const slidesContent = this.generateSlidesMarkdown(args.title, result); await fs.writeFile(path.join(args.output_dir, 'slides.md'), slidesContent); // Generate package.json const packageJson = this.generatePackageJson(args.title); await fs.writeFile(path.join(args.output_dir, 'package.json'), JSON.stringify(packageJson, null, 2)); // Generate theme configuration const themeConfig = this.generateThemeConfig(result.slides[0]?.style); await fs.writeFile(path.join(args.output_dir, 'theme.config.ts'), themeConfig); // Generate custom CSS const customCSS = this.generateCustomCSS(result.slides); await fs.writeFile(path.join(args.output_dir, 'style.css'), customCSS); // Generate speaker notes if requested if (args.include_speaker_notes) { const speakerNotes = this.generateSpeakerNotes(result); await fs.writeFile(path.join(args.output_dir, 'speaker-notes.md'), speakerNotes); } n; n; } finally { } } // Generate presentation analysis report\n const analysisReport = this.generateAnalysisReport(result);\n await fs.writeFile(path.join(args.output_dir, 'presentation-analysis.json'), JSON.stringify(analysisReport, null, 2));\n \n console.log('✅ Intelligent Slide Deck Generation Complete!');\n \n return {\n success: true,\n output_directory: args.output_dir,\n slides_generated: result.slides.length,\n estimated_duration: `${Math.round(result.presentation_metadata.estimated_duration / 60)} minutes`,\n quality_score: `${Math.round(result.quality_metrics.overall_score * 100)}%`,\n accessibility_score: `${Math.round(result.presentation_metadata.accessibility_score * 100)}%`,\n brand_compliance: `${Math.round(result.presentation_metadata.brand_compliance * 100)}%`,\n optimization_suggestions: result.optimization_suggestions,\n files_created: [\n 'slides.md',\n 'package.json', \n 'theme.config.ts',\n 'style.css',\n ...(args.include_speaker_notes ? ['speaker-notes.md'] : []),\n 'presentation-analysis.json'\n ],\n next_steps: [\n 'Run `npm install` to install dependencies',\n 'Run `npm run dev` to start development server',\n 'Run `npm run build` to build for production',\n 'Run `npm run export` to export as PDF'\n ]\n };\n \n } catch (error) {\n console.error('❌ Error generating intelligent deck:', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n troubleshooting: [\n 'Check that the output directory is writable',\n 'Ensure all required dependencies are installed',\n 'Verify the content input is properly formatted',\n 'Check network connectivity for asset downloads'\n ]\n };\n }\n}\n\n/**\n * Generate the main slides.md file\n */\nfunction generateSlidesMarkdown(title: string, result: any): string {\n const frontmatter = `---\ntheme: hatch-corporate\nbackground: false\nclass: text-center\nhighlighter: shiki\nlineNumbers: false\ninfo: |\n ## ${title}\n \n Generated with HAIA+ Slidev Builder\n 4-Layer Architecture: Content → Layout → Assets → Style\n \ndrawings:\n persist: false\ntransition: slide-left\ntitle: ${title}\nmdc: true\n---\n\n`;\n \n const slidesMarkdown = result.slides\n .map((slide: any) => slide.markdown)\n .join('\\n\\n---\\n\\n');\n \n return frontmatter + slidesMarkdown;\n}\n\n/**\n * Generate package.json for the presentation\n */\nfunction generatePackageJson(title: string) {\n return {\n \"name\": title.toLowerCase().replace(/\\s+/g, '-'),\n \"version\": \"1.0.0\",\n \"description\": `${title} - Generated with HAIA+ Slidev Builder`,\n \"scripts\": {\n \"dev\": \"slidev\",\n \"build\": \"slidev build\",\n \"export\": \"slidev export\",\n \"export-pdf\": \"slidev export --format pdf\",\n \"export-png\": \"slidev export --format png\",\n \"preview\": \"slidev preview\"\n },\n \"dependencies\": {\n \"@slidev/cli\": \"^0.48.0\",\n \"@slidev/theme-default\": \"latest\"\n },\n \"devDependencies\": {\n \"@slidev/types\": \"latest\"\n }\n };\n}\n\n/**\n * Generate theme configuration\n */\nfunction generateThemeConfig(styleRecommendation: any): string {\n return `import { defineTheme } from '@slidev/types'\n\nexport default defineTheme({\n name: 'hatch-corporate-enhanced',\n colorSchema: 'auto',\n layouts: {\n default: './layouts/default.vue',\n cover: './layouts/cover.vue',\n center: './layouts/center.vue',\n 'two-cols': './layouts/two-cols.vue'\n },\n tokens: {\n // Hatch Corporate Colors\n primary: '#095078',\n secondary: '#ACBCC8', \n accent: '#E84B37',\n accentAlt: '#E75300',\n gray: '#425563',\n lightGray: '#A0AEC0',\n background: '#f4f4f4',\n white: '#FFFFFF'\n }\n})\n`;\n}\n\n/**\n * Generate custom CSS combining all style recommendations\n */\nfunction generateCustomCSS(slides: any[]): string {\n const baseCSS = slides[0]?.style?.css_framework || '';\n \n return `/* HAIA+ Slidev Builder - Enhanced Styles */\n/* Generated with 4-Layer Architecture */\n\n${baseCSS}\n\n/* Additional enhancements */\n.slidev-layout {\n background: var(--hatch-background);\n font-family: var(--font-primary);\n}\n\n.slide-enter-active,\n.slide-leave-active {\n transition: all 0.3s ease;\n}\n\n.slide-enter-from {\n opacity: 0;\n transform: translateX(30px);\n}\n\n.slide-leave-to {\n opacity: 0;\n transform: translateX(-30px);\n}\n\n/* Print styles */\n@media print {\n .slide {\n break-inside: avoid;\n page-break-inside: avoid;\n }\n}\n`;\n}\n\n/**\n * Generate speaker notes\n */\nfunction generateSpeakerNotes(result: any): string {\n let notes = `# Speaker Notes\\n\\n## Presentation Overview\\n\\n- **Total Slides:** ${result.presentation_metadata.total_slides}\\n- **Estimated Duration:** ${Math.round(result.presentation_metadata.estimated_duration / 60)} minutes\\n- **Quality Score:** ${Math.round(result.quality_metrics.overall_score * 100)}%\\n\\n---\\n\\n`;\n \n result.slides.forEach((slide: any, index: number) => {\n notes += `## Slide ${index + 1}: ${slide.title}\\n\\n`;\n notes += `**Type:** ${slide.type}\\n`;\n notes += `**Estimated Time:** ${slide.estimated_time} seconds\\n\\n`;\n notes += `**Key Points:**\\n${slide.content.split(', ').map((point: string) => `- ${point}`).join('\\n')}\\n\\n`;\n notes += `**Layout Strategy:** ${slide.layout.reason}\\n\\n`;\n notes += `**Asset Strategy:** ${slide.assets.reasoning}\\n\\n`;\n notes += `**Style Strategy:** ${slide.style.reasoning}\\n\\n`;\n notes += `---\\n\\n`;\n });\n \n return notes;\n}\n\n/**\n * Generate analysis report\n */\nfunction generateAnalysisReport(result: any) {\n return {\n generation_timestamp: new Date().toISOString(),\n methodology: \"4-Layer Architecture\",\n layers: {\n \"1_content_intelligence\": \"Analyzed content structure using proven frameworks\",\n \"2_layout_optimization\": \"Applied responsive design patterns and visual hierarchy\",\n \"3_asset_intelligence\": \"Curated assets with semantic matching and brand compliance\",\n \"4_style_orchestration\": \"Generated cohesive design system with Hatch branding\"\n },\n presentation_metadata: result.presentation_metadata,\n quality_metrics: result.quality_metrics,\n optimization_suggestions: result.optimization_suggestions,\n slides_analysis: result.slides.map((slide: any) => ({\n id: slide.id,\n type: slide.type,\n title: slide.title,\n layout_confidence: slide.layout.confidence_score,\n asset_confidence: slide.assets.confidence_score,\n accessibility_score: slide.layout.accessibility_score\n }))\n };\n}\n\nexport const generateIntelligentDeckTool = {\n name: 'generate_intelligent_deck',\n description: 'Generate a complete Slidev presentation using 4-layer architecture: Content Intelligence, Layout Optimization, Asset Intelligence, and Style Orchestration',\n inputSchema: generateIntelligentDeckSchema\n};\n"