@pep/term-deck 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/term-deck.js +29 -12
- package/dist/bin/term-deck.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/term-deck.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { join } from 'path';
|
|
3
|
-
import 'url';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import matter from 'gray-matter';
|
|
6
6
|
import { mkdir, writeFile, rm, access, readFile, unlink } from 'fs/promises';
|
|
@@ -346,9 +346,10 @@ async function loadDeckConfig(slidesDir) {
|
|
|
346
346
|
};
|
|
347
347
|
}
|
|
348
348
|
try {
|
|
349
|
+
const fileUrl = pathToFileURL(configPath).href;
|
|
349
350
|
const isTest = process.env.NODE_ENV === "test" || process.env.VITEST === "true";
|
|
350
351
|
const cacheBuster = isTest ? `?t=${Date.now()}-${Math.random()}` : "";
|
|
351
|
-
const configModule = await import(
|
|
352
|
+
const configModule = await import(fileUrl + cacheBuster);
|
|
352
353
|
if (!configModule.default) {
|
|
353
354
|
throw new Error(`${configName} must export default config`);
|
|
354
355
|
}
|
|
@@ -1384,7 +1385,7 @@ var init_main = __esm({
|
|
|
1384
1385
|
init_esm_shims();
|
|
1385
1386
|
|
|
1386
1387
|
// package.json
|
|
1387
|
-
var version = "1.0.
|
|
1388
|
+
var version = "1.0.20";
|
|
1388
1389
|
|
|
1389
1390
|
// src/cli/commands/present.ts
|
|
1390
1391
|
init_esm_shims();
|
|
@@ -1829,16 +1830,32 @@ async function initDeck(name, theme) {
|
|
|
1829
1830
|
const slidesDir = join(deckDir, "slides");
|
|
1830
1831
|
await mkdir(slidesDir, { recursive: true });
|
|
1831
1832
|
await writeFile(join(slidesDir, ".gitkeep"), "");
|
|
1832
|
-
const configContent =
|
|
1833
|
+
const configContent = `// Deck configuration
|
|
1834
|
+
// See: https://github.com/PepijnSenders/term-deck
|
|
1835
|
+
|
|
1836
|
+
export default {
|
|
1833
1837
|
title: '${name}',
|
|
1834
|
-
|
|
1835
|
-
// theme
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1838
|
+
|
|
1839
|
+
// Default matrix/cyberpunk theme
|
|
1840
|
+
theme: {
|
|
1841
|
+
name: 'matrix',
|
|
1842
|
+
|
|
1843
|
+
colors: {
|
|
1844
|
+
primary: '#00cc66',
|
|
1845
|
+
accent: '#ff6600',
|
|
1846
|
+
background: '#0a0a0a',
|
|
1847
|
+
text: '#ffffff',
|
|
1848
|
+
muted: '#666666',
|
|
1849
|
+
},
|
|
1850
|
+
|
|
1851
|
+
gradients: {
|
|
1852
|
+
fire: ['#ff6600', '#ff3300', '#ff0066'],
|
|
1853
|
+
cool: ['#00ccff', '#0066ff', '#6600ff'],
|
|
1854
|
+
pink: ['#ff0066', '#ff0099', '#cc00ff'],
|
|
1855
|
+
},
|
|
1856
|
+
|
|
1857
|
+
glyphs: '\uFF71\uFF72\uFF73\uFF74\uFF75\uFF76\uFF77\uFF78\uFF79\uFF7A\uFF7B\uFF7C\uFF7D\uFF7E\uFF7F\uFF80\uFF81\uFF82\uFF83\uFF84\uFF85\uFF86\uFF87\uFF88\uFF89\uFF8A\uFF8B\uFF8C\uFF8D\uFF8E\uFF8F\uFF90\uFF91\uFF92\uFF93\uFF94\uFF95\uFF96\uFF97\uFF98\uFF99\uFF9A\uFF9B\uFF9C\uFF9D0123456789',
|
|
1858
|
+
},
|
|
1842
1859
|
}
|
|
1843
1860
|
`;
|
|
1844
1861
|
await writeFile(join(slidesDir, "deck.config.js"), configContent);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js","../../src/schemas/theme.ts","../../src/schemas/config.ts","../../src/schemas/validation.ts","../../src/schemas/slide.ts","../../src/core/slide.ts","../../src/core/deck-loader.ts","../../src/renderer/effects/matrix-rain.ts","../../src/renderer/window-manager.ts","../../src/core/theme-errors.ts","../../src/core/theme-colors.ts","../../src/core/theme.ts","../../src/core/utils/mermaid.ts","../../src/core/content-processor.ts","../../src/renderer/animations/constants.ts","../../src/renderer/animations/helpers/animation-utils.ts","../../src/renderer/animations/transitions/glitch-transition.ts","../../src/renderer/animations/transitions/fade-transition.ts","../../src/renderer/animations/transitions/typewriter-transition.ts","../../src/renderer/animations/transitions/instant-transition.ts","../../src/renderer/animations/transition-orchestrator.ts","../../src/renderer/animations/transitions.ts","../../src/renderer/text-generator.ts","../../src/renderer/slide-renderer.ts","../../src/renderer/screen.ts","../../src/presenter/notes-window.ts","../../src/presenter/navigation.ts","../../src/presenter/keyboard-controls.ts","../../src/presenter/main.ts","../../bin/term-deck.ts","../../package.json","../../src/cli/commands/present.ts","../../src/cli/errors.ts","../../src/cli/commands/export.ts","../../src/export/recorder.ts","../../src/export/recording-session.ts","../../src/export/presentation-exporter.ts","../../src/renderer/types/screen.ts","../../src/export/utils/virtual-terminal.ts","../../src/export/capture/screen-capture.ts","../../src/export/utils/color-conversion.ts","../../src/export/encoding/ffmpeg-encoder.ts","../../src/export/ansi-recorder.ts","../../src/cli/commands/init.ts"],"names":["z","path","init_slide","blessed","init_theme","convertMermaid","gradient","clearWindows","renderSlide","access","nextSlide","join","tmpdir","Command","mkdir","writeFile","present"],"mappings":"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","file":"term-deck.js","sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { z } from 'zod'\n\n/**\n * Schema for validating hex color strings.\n * Accepts 6-digit hex colors with # prefix (e.g., #ff0066)\n */\nexport const HexColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, {\n message: 'Color must be a valid hex color (e.g., #ff0066)',\n})\n\nexport type HexColor = z.infer<typeof HexColorSchema>\n\n/**\n * Schema for validating gradient color arrays.\n * A gradient requires at least 2 hex colors.\n */\nexport const GradientSchema = z.array(HexColorSchema).min(2, {\n message: 'Gradient must have at least 2 colors',\n})\n\nexport type Gradient = z.infer<typeof GradientSchema>\n\n/**\n * Schema for validating theme objects.\n * Defines the visual appearance of the presentation deck.\n */\nexport const ThemeSchema = z.object({\n // Theme metadata\n name: z.string().min(1, { message: 'Theme name is required' }),\n description: z.string().optional(),\n author: z.string().optional(),\n version: z.string().optional(),\n\n // Color palette\n colors: z.object({\n primary: HexColorSchema,\n secondary: HexColorSchema.optional(),\n accent: HexColorSchema,\n background: HexColorSchema,\n text: HexColorSchema,\n muted: HexColorSchema,\n success: HexColorSchema.optional(),\n warning: HexColorSchema.optional(),\n error: HexColorSchema.optional(),\n }),\n\n // Named gradients for bigText\n gradients: z.record(z.string(), GradientSchema).refine(\n (g) => Object.keys(g).length >= 1,\n { message: 'At least one gradient must be defined' }\n ),\n\n // Glyph set for matrix rain background\n glyphs: z.string().min(10, {\n message: 'Glyph set must have at least 10 characters',\n }),\n\n // Animation settings\n animations: z.object({\n // Speed multiplier (1.0 = normal, 0.5 = half speed, 2.0 = double speed)\n revealSpeed: z.number().min(0.1).max(5.0).default(1.0),\n // Matrix rain density (number of drops)\n matrixDensity: z.number().min(10).max(200).default(50),\n // Glitch effect iterations\n glitchIterations: z.number().min(1).max(20).default(5),\n // Delay between lines during reveal (ms)\n lineDelay: z.number().min(0).max(500).default(30),\n // Matrix rain update interval (ms)\n matrixInterval: z.number().min(20).max(200).default(80),\n }),\n\n // Window appearance\n window: z.object({\n // Border style\n borderStyle: z.enum(['line', 'double', 'rounded', 'none']).default('line'),\n // Shadow effect\n shadow: z.boolean().default(true),\n // Padding inside windows\n padding: z.object({\n top: z.number().min(0).max(5).default(1),\n bottom: z.number().min(0).max(5).default(1),\n left: z.number().min(0).max(10).default(2),\n right: z.number().min(0).max(10).default(2),\n }).optional(),\n }).optional(),\n})\n\nexport type Theme = z.infer<typeof ThemeSchema>\n\n// ============================================================================\n// Color Token System\n// ============================================================================\n\n/**\n * Valid color tokens for inline styling in slide body content.\n * Tokens can be either:\n * - Built-in colors: GREEN, ORANGE, CYAN, PINK, WHITE, GRAY\n * - Theme-mapped colors: PRIMARY, SECONDARY, ACCENT, MUTED, TEXT, BACKGROUND\n *\n * Usage in slides: {GREEN}colored text{/}\n */\nexport const ColorTokens = [\n 'GREEN',\n 'ORANGE',\n 'CYAN',\n 'PINK',\n 'WHITE',\n 'GRAY',\n 'PRIMARY', // Maps to theme.colors.primary\n 'SECONDARY', // Maps to theme.colors.secondary\n 'ACCENT', // Maps to theme.colors.accent\n 'MUTED', // Maps to theme.colors.muted\n 'TEXT', // Maps to theme.colors.text\n 'BACKGROUND', // Maps to theme.colors.background\n] as const\n\n/**\n * Type for valid color token names.\n */\nexport type ColorToken = typeof ColorTokens[number]\n\n/**\n * Pattern for matching color tokens in slide content.\n * Matches: {GREEN}, {ORANGE}, {CYAN}, {PINK}, {WHITE}, {GRAY},\n * {PRIMARY}, {SECONDARY}, {ACCENT}, {MUTED}, {TEXT}, {BACKGROUND}, {/}\n *\n * The {/} token closes any open color tag.\n */\nexport const COLOR_TOKEN_PATTERN = /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g\n\n// ============================================================================\n// Partial Theme for Extension\n// ============================================================================\n\n/**\n * Deep partial utility type that makes all nested properties optional.\n * Used for theme extension where only specific fields need to be overridden.\n */\nexport type DeepPartial<T> = T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>\n} : T\n\n/**\n * Partial theme type for use with theme.extend() functionality.\n * All fields (including nested) become optional.\n */\nexport type PartialTheme = DeepPartial<Theme>\n\n/**\n * Schema for validating partial theme objects.\n * All fields become optional recursively, allowing partial overrides.\n * Used for theme extension validation.\n */\nexport const PartialThemeSchema = ThemeSchema.deepPartial()\n\n// ============================================================================\n// Default Theme\n// ============================================================================\n\n/**\n * Default matrix/cyberpunk theme.\n * Used when no theme is specified or as a base for theme extension.\n */\nexport const DEFAULT_THEME: Theme = {\n name: 'matrix',\n description: 'Default cyberpunk/matrix theme',\n\n colors: {\n primary: '#00cc66',\n accent: '#ff6600',\n background: '#0a0a0a',\n text: '#ffffff',\n muted: '#666666',\n },\n\n gradients: {\n fire: ['#ff6600', '#ff3300', '#ff0066'],\n cool: ['#00ccff', '#0066ff', '#6600ff'],\n pink: ['#ff0066', '#ff0099', '#cc00ff'],\n hf: ['#99cc00', '#00cc66', '#00cccc'],\n },\n\n glyphs: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789',\n\n animations: {\n revealSpeed: 1.0,\n matrixDensity: 50,\n glitchIterations: 5,\n lineDelay: 30,\n matrixInterval: 80,\n },\n\n window: {\n borderStyle: 'line',\n shadow: true,\n padding: {\n top: 1,\n bottom: 1,\n left: 2,\n right: 2,\n },\n },\n}\n","import { z } from 'zod'\nimport { ThemeSchema } from './theme'\n\n/**\n * Schema for presentation settings.\n * Controls how the presentation behaves during runtime.\n */\nexport const SettingsSchema = z.object({\n // Start slide (0-indexed)\n startSlide: z.number().min(0).default(0),\n // Loop back to first slide after last\n loop: z.boolean().default(false),\n // Auto-advance slides (ms, 0 = disabled)\n autoAdvance: z.number().min(0).default(0),\n // Show slide numbers\n showSlideNumbers: z.boolean().default(false),\n // Show progress bar\n showProgress: z.boolean().default(false),\n})\n\nexport type Settings = z.infer<typeof SettingsSchema>\n\n/**\n * Schema for export settings.\n * Controls the output dimensions and quality of exported videos/GIFs.\n */\nexport const ExportSettingsSchema = z.object({\n // Output width in characters (min 80, max 400)\n width: z.number().min(80).max(400).default(120),\n // Output height in characters (min 24, max 100)\n height: z.number().min(24).max(100).default(40),\n // Frames per second for video (min 10, max 60)\n fps: z.number().min(10).max(60).default(30),\n})\n\nexport type ExportSettings = z.infer<typeof ExportSettingsSchema>\n\n/**\n * Schema for validating deck configuration (deck.config.ts).\n * Defines the complete configuration for a presentation deck.\n */\nexport const DeckConfigSchema = z.object({\n // Presentation metadata\n title: z.string().optional(),\n author: z.string().optional(),\n date: z.string().optional(),\n\n // Theme (already validated Theme object)\n theme: ThemeSchema,\n\n // Presentation settings\n settings: SettingsSchema.optional(),\n\n // Export settings\n export: ExportSettingsSchema.optional(),\n})\n\nexport type DeckConfig = z.infer<typeof DeckConfigSchema>\n","import { z, ZodError } from 'zod'\n\n/**\n * Custom error class for validation failures.\n * Extends Error with a specific name for easy identification.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/**\n * Format Zod errors into user-friendly messages.\n * Formats each issue with its field path and message.\n *\n * @param error - The ZodError to format\n * @param context - A description of what was being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns A formatted string with all validation issues\n *\n * @example\n * const error = new ZodError([...])\n * formatZodError(error, 'theme')\n * // Returns:\n * // \"Invalid theme:\n * // - colors.primary: Color must be a valid hex color (e.g., #ff0066)\n * // - name: Theme name is required\"\n */\nexport function formatZodError(error: ZodError, context: string): string {\n const issues = error.issues.map((issue) => {\n const path = issue.path.join('.')\n return ` - ${path ? `${path}: ` : ''}${issue.message}`\n })\n\n return `Invalid ${context}:\\n${issues.join('\\n')}`\n}\n\n/**\n * Parse data with a Zod schema and throw a ValidationError with friendly messages on failure.\n *\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @param context - A description of what's being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns The parsed and validated data\n * @throws {ValidationError} If validation fails\n *\n * @example\n * const theme = safeParse(ThemeSchema, rawData, 'theme')\n * // Throws ValidationError with formatted message if invalid\n */\nexport function safeParse<T>(\n schema: z.ZodSchema<T>,\n data: unknown,\n context: string\n): T {\n const result = schema.safeParse(data)\n\n if (!result.success) {\n throw new ValidationError(formatZodError(result.error, context))\n }\n\n return result.data\n}\n","import { z } from 'zod'\n\n/**\n * Schema for validating slide frontmatter.\n * Defines the metadata for a single slide.\n */\nexport const SlideFrontmatterSchema = z.object({\n // Required: window title\n title: z.string().min(1, {\n message: 'Slide must have a title',\n }),\n\n // ASCII art text (figlet) - can be a single line or multiple lines\n bigText: z.union([\n z.string(),\n z.array(z.string()),\n ]).optional(),\n\n // Which gradient to use for bigText\n gradient: z.string().optional(),\n\n // Override theme for this slide\n theme: z.string().optional(),\n\n // Transition effect\n transition: z.enum([\n 'glitch', // Default: glitch reveal line by line\n 'fade', // Fade in\n 'instant', // No animation\n 'typewriter', // Character by character\n ]).default('glitch'),\n\n // Custom metadata (ignored by renderer, useful for tooling)\n meta: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport type SlideFrontmatter = z.infer<typeof SlideFrontmatterSchema>\n\n/**\n * Schema for a complete slide after parsing.\n * Includes the parsed frontmatter, body content, optional notes, and metadata.\n */\nexport const SlideSchema = z.object({\n // Parsed frontmatter\n frontmatter: SlideFrontmatterSchema,\n // Markdown body content\n body: z.string(),\n // Presenter notes (extracted from <!-- notes --> block)\n notes: z.string().optional(),\n // Source file path\n sourcePath: z.string(),\n // Slide index in deck (0-indexed)\n index: z.number(),\n})\n\nexport type Slide = z.infer<typeof SlideSchema>\n","import matter from 'gray-matter'\nimport { readFile } from 'fs/promises'\nimport type { Slide } from '../schemas/slide.js'\nimport { SlideFrontmatterSchema, SlideSchema } from '../schemas/slide.js'\nimport { safeParse } from '../schemas/validation.js'\n\n/**\n * Raw parsed slide before validation.\n * This is the intermediate structure after parsing frontmatter\n * but before Zod validation.\n */\nexport interface RawSlide {\n frontmatter: Record<string, unknown>\n body: string\n notes?: string\n sourcePath: string\n}\n\n/**\n * Result of extracting notes from slide content.\n */\nexport interface ExtractedNotes {\n body: string\n notes?: string\n}\n\nconst NOTES_MARKER = '<!-- notes -->'\nconst NOTES_END_MARKER = '<!-- /notes -->'\n\n/**\n * Extract presenter notes from body content.\n *\n * Notes are delimited by `<!-- notes -->` marker.\n * An optional `<!-- /notes -->` end marker can be used to include\n * content after notes in the body.\n *\n * @param content - Raw body content from markdown file\n * @returns Object containing separated body and notes\n */\nexport function extractNotes(content: string): ExtractedNotes {\n const notesStart = content.indexOf(NOTES_MARKER)\n\n if (notesStart === -1) {\n return { body: content }\n }\n\n const body = content.slice(0, notesStart).trim()\n\n // Check for explicit end marker\n const notesEnd = content.indexOf(NOTES_END_MARKER, notesStart)\n\n let notes: string\n if (notesEnd !== -1) {\n notes = content.slice(notesStart + NOTES_MARKER.length, notesEnd).trim()\n } else {\n // Everything after marker is notes\n notes = content.slice(notesStart + NOTES_MARKER.length).trim()\n }\n\n return { body, notes: notes || undefined }\n}\n\n/**\n * Parse a single slide file.\n *\n * Reads the markdown file, extracts frontmatter using gray-matter,\n * extracts presenter notes, and validates the result against the schema.\n *\n * @param filePath - Path to the markdown slide file\n * @param index - The slide index in the deck (0-indexed)\n * @returns Validated Slide object\n * @throws {ValidationError} If frontmatter or slide validation fails\n */\nexport async function parseSlide(\n filePath: string,\n index: number\n): Promise<Slide> {\n // Read file content\n const content = await readFile(filePath, 'utf-8')\n\n // Parse frontmatter with gray-matter\n const { data, content: rawBody } = matter(content)\n\n // Extract notes from body\n const { body, notes } = extractNotes(rawBody)\n\n // Validate frontmatter\n const frontmatter = safeParse(\n SlideFrontmatterSchema,\n data,\n `frontmatter in ${filePath}`\n )\n\n // Build full slide object\n const slide = {\n frontmatter,\n body: body.trim(),\n notes: notes?.trim(),\n sourcePath: filePath,\n index,\n }\n\n // Validate complete slide and return\n return safeParse(SlideSchema, slide, `slide ${filePath}`)\n}\n\n/**\n * Error class for slide parsing failures.\n * Includes the file path of the slide that failed to parse and\n * optionally the underlying cause for error chaining.\n */\nexport class SlideParseError extends Error {\n /**\n * @param message - The error message describing what went wrong\n * @param filePath - Path to the slide file that failed to parse\n * @param cause - Optional underlying error that caused this failure\n */\n constructor(\n message: string,\n public readonly filePath: string,\n public override readonly cause?: Error\n ) {\n super(message)\n this.name = 'SlideParseError'\n }\n}\n\n/**\n * Format a slide parse error for user-friendly display.\n * Creates a multi-line message with the file path, error message,\n * and optional cause chain.\n *\n * @param error - The SlideParseError to format\n * @returns A formatted string suitable for console output\n *\n * @example\n * const error = new SlideParseError(\n * 'Missing required field: title',\n * '/slides/01-intro.md',\n * new Error('Validation failed')\n * )\n * console.log(formatSlideError(error))\n * // Error parsing slide: /slides/01-intro.md\n * // Missing required field: title\n * // Caused by: Validation failed\n */\nexport function formatSlideError(error: SlideParseError): string {\n let msg = `Error parsing slide: ${error.filePath}\\n`\n msg += ` ${error.message}\\n`\n\n if (error.cause) {\n msg += ` Caused by: ${error.cause.message}\\n`\n }\n\n return msg\n}\n","import { join } from 'path'\nimport fg from 'fast-glob'\nimport { access } from 'fs/promises'\nimport type { DeckConfig } from '../schemas/config.js'\nimport type { Slide } from '../schemas/slide.js'\nimport { DeckConfigSchema } from '../schemas/config.js'\nimport { safeParse } from '../schemas/validation.js'\nimport { DEFAULT_THEME } from '../schemas/theme.js'\nimport { parseSlide } from './slide.js'\n\n/**\n * Deck structure containing all slides and configuration.\n * Represents a complete presentation loaded from disk.\n */\nexport interface Deck {\n slides: Slide[]\n config: DeckConfig\n basePath: string\n}\n\n/**\n * Slide file info for sorting and loading.\n * Used during the slide discovery phase.\n */\nexport interface SlideFile {\n path: string\n name: string\n index: number\n}\n\n/**\n * Find and sort slide files in a directory.\n *\n * Finds all markdown files (*.md), excludes non-slide files like\n * README.md and files starting with underscore, and sorts them\n * numerically by filename (e.g., 01-intro.md, 02-content.md).\n *\n * @param dir - Directory to search for slide files\n * @returns Array of SlideFile objects sorted by filename\n */\nexport async function findSlideFiles(dir: string): Promise<SlideFile[]> {\n const pattern = join(dir, '*.md')\n const foundFiles = await fg(pattern, { onlyFiles: true })\n\n const files: SlideFile[] = []\n\n for (const filePath of foundFiles) {\n const name = filePath.split('/').pop() || ''\n\n // Skip non-slide files\n if (name === 'README.md' || name.startsWith('_')) {\n continue\n }\n\n files.push({\n path: filePath,\n name,\n index: 0, // Will be set after sorting\n })\n }\n\n // Sort by filename numerically (01-intro.md, 02-problem.md, etc.)\n files.sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true }))\n\n // Assign indices after sorting\n files.forEach((file, i) => {\n file.index = i\n })\n\n return files\n}\n\n/**\n * Load deck configuration from deck.config.js or deck.config.ts in slides directory.\n *\n * Looks for a deck.config.js (preferred) or deck.config.ts file in the specified directory.\n * If found, dynamically imports and validates it against DeckConfigSchema.\n * If not found, returns a default config with the DEFAULT_THEME.\n *\n * @param slidesDir - Directory to search for deck config file\n * @returns Validated DeckConfig object\n * @throws {ValidationError} If config file exists but fails validation\n */\nexport async function loadDeckConfig(slidesDir: string): Promise<DeckConfig> {\n // Try .js first (preferred for Node.js compatibility), then .ts (for dev with tsx)\n const configPaths = [\n { path: join(slidesDir, 'deck.config.js'), name: 'deck.config.js' },\n { path: join(slidesDir, 'deck.config.ts'), name: 'deck.config.ts' },\n ]\n\n let configPath: string | null = null\n let configName = 'deck.config.js'\n\n // Find which config file exists\n for (const config of configPaths) {\n try {\n await access(config.path)\n configPath = config.path\n configName = config.name\n break\n } catch {\n // File doesn't exist, try next\n continue\n }\n }\n\n // No config file found\n if (!configPath) {\n return {\n theme: DEFAULT_THEME,\n }\n }\n\n try {\n // Dynamic import of config\n // Add cache buster to prevent module caching in tests only\n // In production, we want normal module caching behavior\n const isTest = process.env.NODE_ENV === 'test' || process.env.VITEST === 'true'\n const cacheBuster = isTest ? `?t=${Date.now()}-${Math.random()}` : ''\n const configModule = await import(configPath + cacheBuster)\n\n if (!configModule.default) {\n throw new Error(`${configName} must export default config`)\n }\n\n // Validate config against schema\n return safeParse(DeckConfigSchema, configModule.default, configName)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n // No config file found, use defaults\n return { theme: DEFAULT_THEME }\n }\n throw error\n }\n}\n\n/**\n * Load a complete deck from a directory.\n *\n * Loads the deck configuration, finds all slide files, and parses\n * them in parallel. Returns a Deck object containing all slides,\n * the configuration, and the base path.\n *\n * @param slidesDir - Directory containing slide files and optional deck.config.ts\n * @returns Complete Deck object with slides, config, and basePath\n * @throws {ValidationError} If any slide fails to parse or validate\n */\nexport async function loadDeck(slidesDir: string): Promise<Deck> {\n // Load config first\n const config = await loadDeckConfig(slidesDir)\n\n // Find all markdown files\n const slideFiles = await findSlideFiles(slidesDir)\n\n // Parse all slides in parallel\n const slides = await Promise.all(\n slideFiles.map((file) => parseSlide(file.path, file.index))\n )\n\n return {\n slides,\n config,\n basePath: slidesDir,\n }\n}\n\n/**\n * Error class for deck loading failures.\n * Includes the directory path of the slides and optionally\n * the underlying cause for error chaining.\n */\nexport class DeckLoadError extends Error {\n /**\n * @param message - The error message describing what went wrong\n * @param slidesDir - Path to the directory that was being loaded\n * @param cause - Optional underlying error that caused this failure\n */\n constructor(\n message: string,\n public readonly slidesDir: string,\n public override readonly cause?: Error\n ) {\n super(message)\n this.name = 'DeckLoadError'\n }\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../../schemas/theme.js'\n\n/**\n * Matrix rain drop.\n * Represents a single falling column of glyphs in the matrix background.\n */\nexport interface MatrixDrop {\n /** Horizontal position (column) */\n x: number\n /** Vertical position (row, can be fractional for smooth animation) */\n y: number\n /** Fall speed (rows per animation frame) */\n speed: number\n /** Array of glyph characters forming the drop's trail */\n trail: string[]\n}\n\n/**\n * Matrix rain state.\n * Manages the matrix rain animation state and resources.\n */\nexport interface MatrixRainState {\n /** Box element for matrix rain background */\n matrixBox: blessed.Widgets.BoxElement\n /** Array of matrix rain drops for animation */\n matrixDrops: MatrixDrop[]\n /** Interval timer for matrix rain animation (null if stopped) */\n matrixInterval: ReturnType<typeof setInterval> | null\n /** Active theme for rendering */\n theme: Theme\n}\n\n/**\n * Generate a trail of random glyphs.\n * Randomly selects glyphs from the theme's glyph set to form a drop trail.\n *\n * @param glyphs - String of available glyphs to choose from\n * @param length - Number of characters in the trail\n * @returns Array of random glyph characters\n */\nfunction generateTrail(glyphs: string, length: number): string[] {\n return Array.from({ length }, () =>\n glyphs[Math.floor(Math.random() * glyphs.length)]\n )\n}\n\n/**\n * Render one frame of matrix rain.\n * Updates the matrix background with falling glyph trails.\n * This function is called repeatedly by the animation interval.\n *\n * @param screen - The blessed screen instance\n * @param state - Matrix rain state\n */\nexport function renderMatrixRain(\n screen: blessed.Widgets.Screen,\n state: MatrixRainState\n): void {\n const { matrixBox, matrixDrops, theme } = state\n const width = Math.max(20, (screen.width as number) || 80)\n const height = Math.max(10, (screen.height as number) || 24)\n\n // Create grid for positioning characters\n const grid: string[][] = Array.from({ length: height }, () =>\n Array(width).fill(' ')\n )\n\n // Update and render drops\n for (const drop of matrixDrops) {\n drop.y += drop.speed\n\n // Reset if off screen\n if (drop.y > height + drop.trail.length) {\n drop.y = -drop.trail.length\n drop.x = Math.floor(Math.random() * width)\n }\n\n // Draw trail\n for (let i = 0; i < drop.trail.length; i++) {\n const y = Math.floor(drop.y) - i\n if (y >= 0 && y < height && drop.x < width) {\n grid[y][drop.x] = drop.trail[i]\n }\n }\n }\n\n // Convert grid to string with colors\n let output = ''\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const char = grid[y][x]\n if (char !== ' ') {\n const brightness = Math.random() > 0.7 ? '{bold}' : ''\n output += `${brightness}{${theme.colors.primary}-fg}${char}{/}`\n } else {\n output += ' '\n }\n }\n if (y < height - 1) output += '\\n'\n }\n\n matrixBox.setContent(output)\n}\n\n/**\n * Initialize matrix rain drops.\n * Creates the initial set of drops and starts the animation loop.\n *\n * @param screen - The blessed screen instance\n * @param state - Matrix rain state to initialize\n */\nexport function initMatrixRain(\n screen: blessed.Widgets.Screen,\n state: MatrixRainState\n): void {\n const { theme } = state\n const width = (screen.width as number) || 80\n const height = (screen.height as number) || 24\n const density = theme.animations.matrixDensity\n\n state.matrixDrops = []\n\n for (let i = 0; i < density; i++) {\n state.matrixDrops.push({\n x: Math.floor(Math.random() * width),\n y: Math.floor(Math.random() * height),\n speed: 0.3 + Math.random() * 0.7,\n trail: generateTrail(theme.glyphs, 5 + Math.floor(Math.random() * 10)),\n })\n }\n\n // Start animation loop\n state.matrixInterval = setInterval(() => {\n renderMatrixRain(screen, state)\n screen.render()\n }, theme.animations.matrixInterval)\n}\n\n/**\n * Stop matrix rain animation.\n * Clears the animation interval and resets state.\n *\n * @param state - Matrix rain state to stop\n */\nexport function stopMatrixRain(state: MatrixRainState): void {\n if (state.matrixInterval) {\n clearInterval(state.matrixInterval)\n state.matrixInterval = null\n }\n}\n\n/**\n * Create matrix rain background box.\n * Creates a full-screen box element for the matrix rain effect.\n *\n * @param screen - The blessed screen instance\n * @returns The created matrix box element\n */\nexport function createMatrixBox(\n screen: blessed.Widgets.Screen\n): blessed.Widgets.BoxElement {\n const matrixBox = blessed.box({\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n tags: true,\n })\n screen.append(matrixBox)\n return matrixBox\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\n\n/**\n * Window creation options.\n * Configuration for creating slide windows with stacking effect.\n */\nexport interface WindowOptions {\n /** Window title displayed in the border */\n title: string\n /** Border color (defaults to theme-based cycling) */\n color?: string\n /** Window width (number for absolute, string for percentage) */\n width?: number | string\n /** Window height (number for absolute, string for percentage) */\n height?: number | string\n /** Top position (number for absolute, string for percentage) */\n top?: number | string\n /** Left position (number for absolute, string for percentage) */\n left?: number | string\n}\n\n/**\n * Get window border color based on index.\n * Cycles through theme colors and additional cyberpunk colors\n * to create a stacking effect with varied border colors.\n *\n * @param index - Window index in the stack\n * @param theme - Theme configuration\n * @returns Hex color string for the window border\n */\nexport function getWindowColor(index: number, theme: Theme): string {\n const colors = [\n theme.colors.primary,\n theme.colors.accent,\n theme.colors.secondary ?? theme.colors.primary,\n '#ff0066', // pink\n '#9966ff', // purple\n '#ffcc00', // yellow\n ]\n return colors[index % colors.length]\n}\n\n/**\n * Create a slide window with stacking effect.\n * Creates a bordered box element with theme-based styling,\n * random position for stacking effect, and adds it to the window stack.\n *\n * @param screen - The blessed screen instance\n * @param windowStack - Stack of existing windows\n * @param theme - Theme configuration\n * @param options - Window configuration options\n * @returns The created window box element\n */\nexport function createWindow(\n screen: blessed.Widgets.Screen,\n windowStack: blessed.Widgets.BoxElement[],\n theme: Theme,\n options: WindowOptions\n): blessed.Widgets.BoxElement {\n const windowIndex = windowStack.length\n const color = options.color ?? getWindowColor(windowIndex, theme)\n\n const screenWidth = (screen.width as number) || 120\n const screenHeight = (screen.height as number) || 40\n\n // Default dimensions: 75% width, 70% height\n const width = options.width ?? Math.floor(screenWidth * 0.75)\n const height = options.height ?? Math.floor(screenHeight * 0.7)\n\n // Random position within bounds (for stacking effect)\n const maxTop = Math.max(1, screenHeight - (height as number) - 2)\n const maxLeft = Math.max(1, screenWidth - (width as number) - 2)\n const top = options.top ?? Math.floor(Math.random() * maxTop)\n const left = options.left ?? Math.floor(Math.random() * maxLeft)\n\n const window = theme.window ?? { borderStyle: 'line', shadow: true }\n const padding = window.padding ?? { top: 1, bottom: 1, left: 2, right: 2 }\n\n const box = blessed.box({\n top,\n left,\n width,\n height,\n border: {\n type: window.borderStyle === 'none' ? undefined : 'line',\n },\n label: ` ${options.title} `,\n style: {\n fg: theme.colors.text,\n bg: theme.colors.background,\n border: { fg: color },\n label: { fg: color, bold: true },\n },\n padding,\n tags: true,\n shadow: window.shadow,\n })\n\n screen.append(box)\n windowStack.push(box)\n\n return box\n}\n\n/**\n * Clear all windows from stack.\n * Destroys all window elements in the stack and resets the stack to empty.\n * This is typically called when transitioning between slides.\n *\n * @param windowStack - The stack of windows to clear\n */\nexport function clearWindows(windowStack: blessed.Widgets.BoxElement[]): void {\n for (const window of windowStack) {\n window.destroy()\n }\n windowStack.length = 0\n}\n","import { ValidationError } from '../schemas/validation'\n\n/**\n * Error class for theme-related failures.\n * Includes optional source information (theme name and file path) for better debugging.\n */\nexport class ThemeError extends Error {\n /**\n * @param message - The error message\n * @param themeName - Optional name of the theme that caused the error\n * @param path - Optional path to the theme file or package\n */\n constructor(\n message: string,\n public readonly themeName?: string,\n public readonly path?: string\n ) {\n super(message)\n this.name = 'ThemeError'\n }\n}\n\n/**\n * Format any error into a user-friendly ThemeError.\n * Handles ValidationError, generic Error, and unknown error types.\n *\n * @param error - The error to format\n * @param source - Description of the theme source (e.g., file path or package name)\n * @returns A ThemeError with a user-friendly message\n *\n * @example\n * try {\n * await loadThemeFromFile('./theme.yml')\n * } catch (error) {\n * throw formatThemeError(error, './theme.yml')\n * }\n */\nexport function formatThemeError(error: unknown, source: string): ThemeError {\n if (error instanceof ValidationError) {\n return new ThemeError(\n `Invalid theme from ${source}:\\n${error.message}`,\n undefined,\n source\n )\n }\n\n if (error instanceof Error) {\n return new ThemeError(\n `Failed to load theme from ${source}: ${error.message}`,\n undefined,\n source\n )\n }\n\n return new ThemeError(`Unknown error loading theme from ${source}`)\n}\n","import gradient from 'gradient-string'\nimport type { Theme } from '../schemas/theme'\n\n/**\n * Function type for applying a gradient to text.\n * Returns ANSI-colored text with the gradient applied.\n */\nexport interface GradientFunction {\n (text: string): string\n}\n\n/**\n * Built-in color mappings for color tokens in slide content.\n * These are fixed colors that don't change with the theme.\n */\nexport const BUILTIN_COLORS: Record<string, string> = {\n GREEN: '#00cc66',\n ORANGE: '#ff6600',\n CYAN: '#00ccff',\n PINK: '#ff0066',\n WHITE: '#ffffff',\n GRAY: '#666666',\n}\n\n/**\n * Create gradient functions from theme gradients.\n * Returns an object mapping gradient names to gradient functions that can be\n * applied to text to produce ANSI-colored output.\n *\n * @param theme - The theme containing gradient definitions\n * @returns Record mapping gradient names to gradient functions\n *\n * @example\n * const gradients = createGradients(theme)\n * const styledText = gradients.fire('Hello World')\n */\nexport function createGradients(theme: Theme): Record<string, GradientFunction> {\n const gradients: Record<string, GradientFunction> = {}\n\n for (const [name, colors] of Object.entries(theme.gradients)) {\n gradients[name] = gradient(colors)\n }\n\n return gradients\n}\n\n/**\n * Apply a gradient to text by name.\n * Looks up the gradient in the theme and applies it to the text.\n * Falls back gracefully if the gradient doesn't exist.\n *\n * @param text - The text to apply the gradient to\n * @param gradientName - The name of the gradient to use\n * @param theme - The theme containing gradient definitions\n * @returns The text with gradient applied, or unstyled text if gradient not found\n *\n * @example\n * const styledText = applyGradient('Hello World', 'fire', theme)\n */\nexport function applyGradient(\n text: string,\n gradientName: string,\n theme: Theme\n): string {\n const colors = theme.gradients[gradientName]\n\n if (!colors) {\n // Fall back gracefully - return unstyled text\n return text\n }\n\n return gradient(colors)(text)\n}\n\n/**\n * Resolve a color token to its hex value.\n * Theme colors (PRIMARY, ACCENT, etc.) are resolved from the theme.\n * Built-in colors (GREEN, ORANGE, etc.) use fixed values.\n *\n * @param token - The color token to resolve (e.g., 'PRIMARY', 'GREEN')\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns The hex color value\n *\n * @example\n * const color = resolveColorToken('PRIMARY', theme) // '#00cc66'\n * const color = resolveColorToken('GREEN', theme) // '#00cc66'\n */\nexport function resolveColorToken(token: string, theme: Theme): string {\n // Check theme colors first\n switch (token) {\n case 'PRIMARY':\n return theme.colors.primary\n case 'SECONDARY':\n return theme.colors.secondary ?? theme.colors.primary\n case 'ACCENT':\n return theme.colors.accent\n case 'MUTED':\n return theme.colors.muted\n case 'TEXT':\n return theme.colors.text\n case 'BACKGROUND':\n return theme.colors.background\n }\n\n // Fall back to built-in colors\n return BUILTIN_COLORS[token] ?? theme.colors.text\n}\n\n/**\n * Convert color tokens in content to blessed tags.\n * Transforms tokens like {GREEN} to blessed color tags like {#00cc66-fg}.\n * Preserves closing tags {/} as-is.\n *\n * @param content - The content with color tokens\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns Content with color tokens converted to blessed tags\n *\n * @example\n * const content = '{GREEN}Hello{/} {ORANGE}World{/}'\n * const result = colorTokensToBlessedTags(content, theme)\n * // '{#00cc66-fg}Hello{/} {#ff6600-fg}World{/}'\n */\nexport function colorTokensToBlessedTags(content: string, theme: Theme): string {\n return content.replace(\n /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g,\n (_, token) => {\n if (token === '/') {\n return '{/}' // Close tag\n }\n const color = resolveColorToken(token, theme)\n return `{${color}-fg}`\n }\n )\n}\n","import { parse as parseYaml } from 'yaml'\nimport deepmerge from 'deepmerge'\nimport type { Theme, PartialTheme } from '../schemas/theme'\nimport { ThemeSchema } from '../schemas/theme'\nimport { safeParse } from '../schemas/validation'\n\n/**\n * Theme object with extension capability.\n * Extends the base Theme type with an extend() method that allows\n * Tailwind-style theme customization.\n */\nexport interface ThemeObject extends Theme {\n /**\n * Create a new theme by merging overrides into this theme.\n * Uses deep merge with array replacement strategy.\n *\n * @param overrides - Partial theme object with values to override\n * @returns A new ThemeObject with the merged values\n *\n * @example\n * const custom = matrix.extend({\n * colors: { primary: '#ff0066' }\n * })\n *\n * @example\n * // Chained extensions\n * const custom = matrix\n * .extend({ colors: { primary: '#ff0066' } })\n * .extend({ animations: { revealSpeed: 0.5 } })\n */\n extend(overrides: PartialTheme): ThemeObject\n}\n\n/**\n * Create a ThemeObject from validated Theme and overrides.\n * Internal helper that merges themes and adds the extend() method.\n *\n * @param base - A validated Theme object\n * @param overrides - Partial theme with values to override\n * @returns A ThemeObject with extension capability\n */\nexport function createThemeFromMerge(base: Theme, overrides: PartialTheme): ThemeObject {\n // Deep merge, with overrides taking precedence\n const merged = deepmerge(base, overrides, {\n // Arrays should be replaced, not concatenated\n arrayMerge: (_, source) => source,\n }) as Theme\n\n // Re-validate the merged result\n const validated = safeParse(ThemeSchema, merged, 'merged theme')\n\n return {\n ...validated,\n extend(newOverrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, newOverrides)\n },\n }\n}\n\n/**\n * Create a theme from a YAML string.\n * Parses the YAML, validates it against ThemeSchema, and returns a ThemeObject\n * with extension capability.\n *\n * @param yaml - The YAML string containing the theme definition\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the YAML syntax is invalid\n * @throws {ValidationError} If the parsed data doesn't match ThemeSchema\n *\n * @example\n * const theme = createTheme(`\n * name: custom\n * colors:\n * primary: \"#ff0066\"\n * accent: \"#00ff66\"\n * background: \"#000000\"\n * text: \"#ffffff\"\n * muted: \"#666666\"\n * gradients:\n * main:\n * - \"#ff0066\"\n * - \"#00ff66\"\n * glyphs: \"0123456789ABCDEF\"\n * animations:\n * revealSpeed: 1.0\n * matrixDensity: 30\n * glitchIterations: 3\n * lineDelay: 20\n * matrixInterval: 100\n * `)\n */\nexport function createTheme(yaml: string): ThemeObject {\n const parsed = parseYaml(yaml)\n const validated = safeParse(ThemeSchema, parsed, 'theme')\n\n return {\n ...validated,\n extend(overrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, overrides)\n },\n }\n}\n\n// Re-export commonly used functions for convenience\nexport { ThemeError, formatThemeError } from './theme-errors'\nexport {\n createGradients,\n applyGradient,\n resolveColorToken,\n colorTokensToBlessedTags,\n BUILTIN_COLORS,\n} from './theme-colors'\nexport type { GradientFunction } from './theme-colors'\n","import { mermaidToAscii as convertMermaid } from 'mermaid-ascii'\n\n/**\n * Pattern to match mermaid code blocks in markdown content.\n * Captures the diagram code inside the block.\n *\n * Matches: ```mermaid\\n<content>```\n * Group 1: The mermaid diagram code\n */\nconst MERMAID_BLOCK_PATTERN = /```mermaid\\n([\\s\\S]*?)```/g\n\n/**\n * Check if content contains mermaid diagrams.\n *\n * @param content - The markdown content to check\n * @returns true if the content contains at least one mermaid code block\n */\nexport function hasMermaidDiagrams(content: string): boolean {\n // Reset pattern since we use global flag\n MERMAID_BLOCK_PATTERN.lastIndex = 0\n return MERMAID_BLOCK_PATTERN.test(content)\n}\n\n/**\n * Extract all mermaid blocks from content.\n *\n * Finds all mermaid code blocks and extracts the diagram code\n * (without the ```mermaid and ``` delimiters).\n *\n * @param content - The markdown content to search\n * @returns Array of mermaid diagram code strings (trimmed)\n */\nexport function extractMermaidBlocks(content: string): string[] {\n const blocks: string[] = []\n let match: RegExpExecArray | null\n\n // Reset pattern before use\n MERMAID_BLOCK_PATTERN.lastIndex = 0\n\n while ((match = MERMAID_BLOCK_PATTERN.exec(content)) !== null) {\n blocks.push(match[1].trim())\n }\n\n return blocks\n}\n\n/**\n * Format a mermaid parsing error as ASCII.\n *\n * Creates a visually recognizable error block showing the\n * first few lines of the diagram with a border.\n *\n * @param code - The mermaid diagram code that failed to parse\n * @param _error - The error that occurred (unused but kept for signature)\n * @returns ASCII art error block\n */\nexport function formatMermaidError(code: string, _error: unknown): string {\n const lines = [\n '┌─ Diagram (parse error) ─┐',\n '│ │',\n ]\n\n // Show first few lines of the diagram\n const codeLines = code.split('\\n').slice(0, 5)\n for (const line of codeLines) {\n const truncated = line.slice(0, 23).padEnd(23)\n lines.push(`│ ${truncated} │`)\n }\n\n if (code.split('\\n').length > 5) {\n lines.push('│ ... │')\n }\n\n lines.push('│ │')\n lines.push('└─────────────────────────┘')\n\n return lines.join('\\n')\n}\n\n/**\n * Convert mermaid diagram to ASCII art.\n *\n * Uses the mermaid-ascii library to convert mermaid diagram\n * syntax to ASCII art representation. Falls back to an error\n * block if parsing fails.\n *\n * @param mermaidCode - Raw mermaid diagram code\n * @returns ASCII art representation or error block\n */\nexport function mermaidToAscii(mermaidCode: string): string {\n try {\n return convertMermaid(mermaidCode)\n } catch (error) {\n // If parsing fails, return a formatted error block\n return formatMermaidError(mermaidCode, error)\n }\n}\n\n/**\n * Escape special regex characters in a string.\n *\n * @param str - String to escape\n * @returns Escaped string safe for use in RegExp\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Process all mermaid blocks in slide content.\n *\n * Finds all mermaid code blocks in the content and replaces them\n * with their ASCII art representation.\n *\n * @param content - The slide content potentially containing mermaid blocks\n * @returns Content with mermaid blocks replaced by ASCII art\n */\nexport function processMermaidDiagrams(content: string): string {\n if (!hasMermaidDiagrams(content)) {\n return content\n }\n\n // Find all blocks and convert\n let result = content\n const blocks = extractMermaidBlocks(content)\n\n for (const block of blocks) {\n const ascii = mermaidToAscii(block)\n\n // Replace mermaid block with ASCII\n // The pattern matches the code block including newlines\n result = result.replace(\n new RegExp('```mermaid\\\\n' + escapeRegex(block) + '\\\\n?```', 'g'),\n ascii\n )\n }\n\n return result\n}\n","/**\n * Content Processing Module\n *\n * Responsible for processing slide content through various transformations:\n * - Mermaid diagram conversion\n * - Color token resolution\n * - Text normalization\n *\n * This module follows the Single Responsibility Principle by focusing\n * solely on content transformation, separate from parsing and loading logic.\n */\n\nimport type { Theme } from '../schemas/theme.js'\nimport { colorTokensToBlessedTags } from './theme.js'\nimport { processMermaidDiagrams } from './utils/mermaid.js'\n\n/**\n * Process slide body content.\n *\n * Applies the full content processing pipeline:\n * 1. Process mermaid diagrams (convert to ASCII)\n * 2. Apply color tokens (convert to blessed tags)\n *\n * The order is important: mermaid diagrams are processed first so that\n * any color tokens they might contain are then converted to blessed tags.\n *\n * @param body - The slide body content to process\n * @param theme - The theme to use for color token resolution\n * @returns Processed content with mermaid converted and color tokens applied\n *\n * @example\n * const processed = await processSlideContent(\n * '{GREEN}Hello{/}\\n\\n```mermaid\\ngraph LR\\nA-->B\\n```',\n * theme\n * )\n * // Returns: '{#00cc66-fg}Hello{/}\\n\\n<ascii art>'\n */\nexport async function processSlideContent(\n body: string,\n theme: Theme\n): Promise<string> {\n // Process mermaid diagrams first\n let processed = processMermaidDiagrams(body)\n\n // Apply color tokens\n processed = colorTokensToBlessedTags(processed, theme)\n\n return processed\n}\n\n/**\n * Normalize bigText to array.\n *\n * Converts the bigText frontmatter field to a consistent array format\n * for use by the renderer. Handles:\n * - undefined → empty array\n * - string → single-element array\n * - string[] → pass through unchanged\n *\n * @param bigText - The bigText value from slide frontmatter\n * @returns Array of strings for rendering\n *\n * @example\n * normalizeBigText(undefined) // []\n * normalizeBigText('HELLO') // ['HELLO']\n * normalizeBigText(['A', 'B']) // ['A', 'B']\n */\nexport function normalizeBigText(bigText: string | string[] | undefined): string[] {\n if (!bigText) return []\n return Array.isArray(bigText) ? bigText : [bigText]\n}\n","/**\n * Characters used for glitch effect (avoiding box drawing).\n * These characters create a cyberpunk glitch aesthetic when scrambling text.\n * Includes: block characters, shapes, math symbols, Greek letters, and katakana.\n */\nexport const GLITCH_CHARS =\n '█▓▒░▀▄▌▐■□▪▫●○◊◘◙♦♣♠♥★☆⌂ⁿ²³ÆØ∞≈≠±×÷αβγδεζηθλμπσφωΔΣΩアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン'\n\n/**\n * Characters to never glitch.\n * Protects structural characters like spaces, punctuation, box drawing,\n * and arrows to maintain readability and layout integrity during glitch effects.\n */\nexport const PROTECTED_CHARS = new Set([\n ' ', '\\t', '\\n', '{', '}', '-', '/', '#', '[', ']', '(', ')', ':', ';',\n ',', '.', '!', '?', \"'\", '\"', '`', '_', '|', '\\\\', '<', '>', '=', '+',\n '*', '&', '^', '%', '$', '@', '~',\n // Box drawing\n '┌', '┐', '└', '┘', '│', '─', '├', '┤', '┬', '┴', '┼', '═', '║',\n '╔', '╗', '╚', '╝', '╠', '╣', '╦', '╩', '╬', '╭', '╮', '╯', '╰',\n // Arrows\n '→', '←', '↑', '↓', '▶', '◀', '▲', '▼', '►', '◄',\n])\n","import type blessed from 'neo-blessed'\n\n/**\n * Sleep helper for async animations.\n * Returns a promise that resolves after the specified delay.\n *\n * @param ms - Delay in milliseconds\n * @returns Promise that resolves after the delay\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Renders content to a blessed box and updates the screen.\n * Utility function to reduce code duplication across transitions.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The content string to render\n */\nexport function renderContent(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string\n): void {\n box.setContent(content)\n screen.render()\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { GLITCH_CHARS, PROTECTED_CHARS } from '../constants.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Glitch-reveal a single line of text.\n * Animates the transition from scrambled characters to the final text.\n * The scramble ratio decreases with each iteration, gradually revealing the text.\n * Protected characters (spaces, punctuation, box drawing) are never scrambled.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param currentLines - Array of already-revealed lines\n * @param newLine - The new line to glitch-reveal\n * @param iterations - Number of glitch iterations (default: 5)\n */\nexport async function glitchLine(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n currentLines: string[],\n newLine: string,\n iterations: number = 5\n): Promise<void> {\n for (let i = iterations; i >= 0; i--) {\n const scrambleRatio = i / iterations\n let scrambledLine = ''\n\n for (const char of newLine) {\n if (PROTECTED_CHARS.has(char)) {\n scrambledLine += char\n } else if (Math.random() < scrambleRatio) {\n scrambledLine += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)]\n } else {\n scrambledLine += char\n }\n }\n\n renderContent(box, screen, [...currentLines, scrambledLine].join('\\n'))\n await sleep(20)\n }\n}\n\n/**\n * Reveal content line by line with glitch effect.\n * Animates the transition of multi-line content by revealing each line\n * sequentially with a glitch effect. Uses theme-configured line delay\n * and glitch iteration count for consistent animation timing.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string (with newlines)\n * @param theme - Theme configuration for animation timing\n */\nexport async function lineByLineReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const lines = content.split('\\n')\n const revealedLines: string[] = []\n const lineDelay = theme.animations.lineDelay\n const glitchIterations = theme.animations.glitchIterations\n\n for (const line of lines) {\n await glitchLine(box, screen, revealedLines, line, glitchIterations)\n revealedLines.push(line)\n renderContent(box, screen, revealedLines.join('\\n'))\n\n // Delay between lines (skip for empty lines)\n if (line.trim()) {\n await sleep(lineDelay)\n }\n }\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { PROTECTED_CHARS } from '../constants.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Fade-in reveal (character by character, all at once).\n * Gradually reveals characters randomly across the entire content\n * to create a fade-in effect. Uses multiple steps with increasing\n * reveal probability for a smooth animation.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param theme - Theme configuration for animation timing\n */\nexport async function fadeInReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const steps = 10\n const delay = (theme.animations.lineDelay * 2) / steps\n\n for (let step = 0; step < steps; step++) {\n const revealRatio = step / steps\n let revealed = ''\n\n for (const char of content) {\n if (char === '\\n' || PROTECTED_CHARS.has(char) || Math.random() < revealRatio) {\n revealed += char\n } else {\n revealed += ' '\n }\n }\n\n renderContent(box, screen, revealed)\n await sleep(delay)\n }\n\n renderContent(box, screen, content)\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Typewriter reveal (character by character, sequentially).\n * Reveals content character by character in order, like a typewriter.\n * Skips delay for spaces and newlines to maintain smooth flow.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param theme - Theme configuration for animation timing\n */\nexport async function typewriterReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const charDelay = theme.animations.lineDelay / 5\n let revealed = ''\n\n for (const char of content) {\n revealed += char\n renderContent(box, screen, revealed)\n\n if (char !== ' ' && char !== '\\n') {\n await sleep(charDelay)\n }\n }\n}\n","import type blessed from 'neo-blessed'\nimport { renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Instant reveal (no animation).\n * Immediately displays the content without any transition effect.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n */\nexport function instantReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string\n): void {\n renderContent(box, screen, content)\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../schemas/theme.js'\nimport { lineByLineReveal } from './transitions/glitch-transition.js'\nimport { fadeInReveal } from './transitions/fade-transition.js'\nimport { typewriterReveal } from './transitions/typewriter-transition.js'\nimport { instantReveal } from './transitions/instant-transition.js'\n\n/**\n * Transition type for slide animations.\n * Defines the available transition effects for revealing slide content.\n */\nexport type TransitionType = 'glitch' | 'fade' | 'instant' | 'typewriter'\n\n/**\n * Apply transition effect to reveal content.\n * Dispatcher function that selects and applies the appropriate\n * transition animation based on the specified transition type.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param transition - The type of transition effect to apply\n * @param theme - Theme configuration for animation timing\n */\nexport async function applyTransition(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n transition: TransitionType,\n theme: Theme\n): Promise<void> {\n switch (transition) {\n case 'glitch':\n await lineByLineReveal(box, screen, content, theme)\n break\n\n case 'fade':\n await fadeInReveal(box, screen, content, theme)\n break\n\n case 'instant':\n instantReveal(box, screen, content)\n break\n\n case 'typewriter':\n await typewriterReveal(box, screen, content, theme)\n break\n\n default:\n instantReveal(box, screen, content)\n }\n}\n","/**\n * Transition animations module.\n * This module provides a clean interface for slide transition effects.\n *\n * The transitions have been refactored into focused, modular files:\n * - transition-orchestrator.ts: Main dispatcher and type definitions\n * - transitions/glitch-transition.ts: Glitch effect implementation\n * - transitions/fade-transition.ts: Fade effect implementation\n * - transitions/typewriter-transition.ts: Typewriter effect implementation\n * - transitions/instant-transition.ts: Instant (no animation) implementation\n * - helpers/animation-utils.ts: Shared animation utilities\n */\n\n// Re-export the main transition orchestrator\nexport { applyTransition, type TransitionType } from './transition-orchestrator.js'\n\n// Re-export individual transitions for direct use if needed\nexport { glitchLine, lineByLineReveal } from './transitions/glitch-transition.js'\nexport { fadeInReveal } from './transitions/fade-transition.js'\nexport { typewriterReveal } from './transitions/typewriter-transition.js'\nexport { instantReveal } from './transitions/instant-transition.js'\n","import figlet from 'figlet'\nimport gradient from 'gradient-string'\n\n/**\n * Generate ASCII art text with gradient.\n * Uses figlet to convert text to ASCII art and applies a gradient color effect.\n * This function is asynchronous because figlet uses a callback-based API.\n *\n * @param text - The text to convert to ASCII art\n * @param gradientColors - Array of hex colors for the gradient effect\n * @param font - Figlet font to use (defaults to 'Standard')\n * @returns Promise resolving to the gradient-colored ASCII art text\n */\nexport async function generateBigText(\n text: string,\n gradientColors: string[],\n font: string = 'Standard'\n): Promise<string> {\n return new Promise((resolve, reject) => {\n figlet.text(text, { font }, (err, result) => {\n if (err || !result) {\n reject(err ?? new Error('Failed to generate figlet text'))\n return\n }\n\n // Apply gradient\n const gradientFn = gradient(gradientColors)\n resolve(gradientFn(result))\n })\n })\n}\n\n/**\n * Generate multi-line big text (for arrays like ['SPEC', 'MACHINE']).\n * Creates ASCII art for each line separately and joins them with newlines.\n * Each line gets the same gradient applied independently.\n *\n * @param lines - Array of text strings to convert to ASCII art\n * @param gradientColors - Array of hex colors for the gradient effect\n * @param font - Figlet font to use (defaults to 'Standard')\n * @returns Promise resolving to the combined gradient-colored ASCII art\n */\nexport async function generateMultiLineBigText(\n lines: string[],\n gradientColors: string[],\n font: string = 'Standard'\n): Promise<string> {\n const results = await Promise.all(\n lines.map((line) => generateBigText(line, gradientColors, font))\n )\n return results.join('\\n')\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\nimport type { Slide } from '../schemas/slide.js'\nimport { normalizeBigText, processSlideContent } from '../core/content-processor.js'\nimport { applyTransition } from './animations/transitions.js'\nimport { generateMultiLineBigText } from './text-generator.js'\nimport { createWindow } from './window-manager.js'\n\n/**\n * Rendered slide content.\n * Structured content ready for display in a window.\n */\nexport interface RenderedContent {\n /** ASCII art big text (from figlet) */\n bigText?: string\n /** Main body content */\n body: string\n /** Mermaid diagram converted to ASCII */\n diagram?: string\n}\n\n/**\n * Render a slide to a window.\n * Creates a window, generates bigText if present, processes the body content,\n * and applies the specified transition effect to reveal the slide.\n *\n * @param screen - The blessed screen instance\n * @param windowStack - Stack of existing windows\n * @param theme - Active theme for rendering\n * @param slide - The slide to render\n * @returns The created window box element containing the rendered slide\n */\nexport async function renderSlide(\n screen: blessed.Widgets.Screen,\n windowStack: blessed.Widgets.BoxElement[],\n theme: Theme,\n slide: Slide\n): Promise<blessed.Widgets.BoxElement> {\n const { frontmatter, body } = slide\n\n // Create window\n const window = createWindow(screen, windowStack, theme, {\n title: frontmatter.title,\n })\n\n // Build content\n let content = ''\n\n // Big text (figlet)\n const bigTextLines = normalizeBigText(frontmatter.bigText)\n if (bigTextLines.length > 0) {\n const gradientName = frontmatter.gradient ?? 'fire'\n const gradientColors = theme.gradients[gradientName] ?? theme.gradients.fire\n\n const bigText = await generateMultiLineBigText(bigTextLines, gradientColors)\n content += bigText + '\\n\\n'\n }\n\n // Process body content (color tokens, mermaid)\n const processedBody = await processSlideContent(body, theme)\n content += processedBody\n\n // Apply transition\n const transition = frontmatter.transition ?? 'glitch'\n await applyTransition(window, screen, content, transition, theme)\n\n return window\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\nimport type { Slide } from '../schemas/slide.js'\nimport {\n type MatrixRainState,\n createMatrixBox,\n initMatrixRain,\n stopMatrixRain,\n} from './effects/matrix-rain.js'\nimport { type TransitionType } from './animations/transitions.js'\nimport {\n createWindow as createWindowInternal,\n clearWindows as clearWindowsInternal,\n type WindowOptions,\n} from './window-manager.js'\nimport { renderSlide as renderSlideInternal } from './slide-renderer.js'\nimport { generateBigText, generateMultiLineBigText } from './text-generator.js'\n\n// Re-export for backwards compatibility\nexport { type TransitionType, applyTransition } from './animations/transitions.js'\nexport { type WindowOptions, getWindowColor } from './window-manager.js'\nexport { generateBigText, generateMultiLineBigText } from './text-generator.js'\nexport { type RenderedContent } from './slide-renderer.js'\n\n/**\n * Main renderer state.\n * Manages the blessed screen, matrix rain background, window stack, and theme.\n */\nexport interface Renderer {\n /** The blessed screen instance */\n screen: blessed.Widgets.Screen\n /** Stack of window elements (slides render on top of each other) */\n windowStack: blessed.Widgets.BoxElement[]\n /** Active theme for rendering */\n theme: Theme\n /** Matrix rain animation state */\n matrixRain: MatrixRainState\n}\n\n/**\n * Create the main blessed screen.\n * Configures the screen with optimal settings for presentation:\n * - smartCSR: Enables smart cursor movement for efficient rendering\n * - fullUnicode: Enables full unicode support for glyphs\n * - altScreen: Uses alternate screen buffer (preserves terminal on exit)\n * - mouse: Disabled (keyboard-only navigation)\n *\n * @param title - Window title (defaults to 'term-deck')\n * @returns Configured blessed screen instance\n */\nexport function createScreen(title: string = 'term-deck'): blessed.Widgets.Screen {\n const screen = blessed.screen({\n smartCSR: true,\n title,\n fullUnicode: true,\n mouse: false,\n altScreen: true,\n })\n\n return screen\n}\n\n\n/**\n * Create the renderer with all components.\n * Initializes the blessed screen, matrix rain background box,\n * empty window stack, and starts the matrix rain animation.\n *\n * @param theme - Theme configuration for rendering\n * @returns Fully initialized Renderer instance\n */\nexport function createRenderer(theme: Theme): Renderer {\n const screen = createScreen()\n\n // Create matrix background box covering full screen\n const matrixBox = createMatrixBox(screen)\n\n const matrixRain: MatrixRainState = {\n matrixBox,\n matrixDrops: [],\n matrixInterval: null,\n theme,\n }\n\n const renderer: Renderer = {\n screen,\n windowStack: [],\n theme,\n matrixRain,\n }\n\n // Initialize matrix rain\n initMatrixRain(screen, matrixRain)\n\n return renderer\n}\n\n/**\n * Destroy renderer and cleanup resources.\n * Stops the matrix rain animation, destroys all windows in the stack,\n * and destroys the blessed screen to restore the terminal.\n *\n * @param renderer - The renderer instance to destroy\n */\nexport function destroyRenderer(renderer: Renderer): void {\n // Stop matrix rain animation\n stopMatrixRain(renderer.matrixRain)\n\n // Clear all windows\n clearWindowsInternal(renderer.windowStack)\n\n // Destroy the screen (restores terminal)\n renderer.screen.destroy()\n}\n\n/**\n * Create a slide window with stacking effect.\n * Creates a bordered box element with theme-based styling,\n * random position for stacking effect, and adds it to the window stack.\n *\n * @param renderer - The renderer instance\n * @param options - Window configuration options\n * @returns The created window box element\n */\nexport function createWindow(\n renderer: Renderer,\n options: WindowOptions\n): blessed.Widgets.BoxElement {\n return createWindowInternal(renderer.screen, renderer.windowStack, renderer.theme, options)\n}\n\n/**\n * Clear all windows from stack.\n * Destroys all window elements in the stack and resets the stack to empty.\n * This is typically called when transitioning between slides.\n *\n * @param renderer - The renderer instance containing the window stack\n */\nexport function clearWindows(renderer: Renderer): void {\n clearWindowsInternal(renderer.windowStack)\n}\n\n/**\n * Render a slide to a window.\n * Creates a window, generates bigText if present, processes the body content,\n * and applies the specified transition effect to reveal the slide.\n *\n * @param renderer - The renderer instance\n * @param slide - The slide to render\n * @returns The created window box element containing the rendered slide\n */\nexport async function renderSlide(\n renderer: Renderer,\n slide: Slide\n): Promise<blessed.Widgets.BoxElement> {\n return renderSlideInternal(renderer.screen, renderer.windowStack, renderer.theme, slide)\n}\n","import blessed from 'neo-blessed';\nimport { access } from 'fs/promises';\nimport type { Slide } from '../schemas/slide.js';\n\n/**\n * Notes window state (separate terminal)\n *\n * Represents a secondary display on a different TTY for presenter notes.\n * Shows current slide notes, slide number, and preview of next slide.\n */\nexport interface NotesWindow {\n screen: blessed.Widgets.Screen;\n contentBox: blessed.Widgets.BoxElement;\n tty: string; // TTY device path (e.g., '/dev/tty2')\n}\n\n/**\n * Find an available TTY for notes window\n *\n * This is a best-effort approach - user should specify with --notes-tty.\n * Searches common TTY paths on macOS and Linux.\n *\n * @returns Promise resolving to an available TTY path\n * @throws Error if no available TTY is found\n */\nasync function findAvailableTty(): Promise<string> {\n const candidates = [\n '/dev/ttys001',\n '/dev/ttys002',\n '/dev/ttys003',\n '/dev/pts/1',\n '/dev/pts/2',\n ];\n\n for (const tty of candidates) {\n try {\n await access(tty);\n return tty;\n } catch {\n // Continue to next candidate\n }\n }\n\n throw new Error(\n 'Could not find available TTY for notes window. ' +\n 'Open a second terminal, run `tty`, and pass the path with --notes-tty'\n );\n}\n\n/**\n * Create notes window on a separate TTY\n *\n * Creates a blessed screen on a different TTY device for displaying presenter notes.\n * If no TTY is specified, attempts to find one automatically.\n *\n * Usage: Open a second terminal and run `tty` to get the device path,\n * then pass it with --notes-tty /dev/ttys001\n *\n * @param ttyPath - Optional TTY device path (e.g., '/dev/ttys001')\n * @returns Promise resolving to the created notes window\n *\n * @example\n * ```typescript\n * // With explicit TTY path\n * const notesWindow = await createNotesWindow('/dev/ttys001');\n *\n * // Auto-detect TTY\n * const notesWindow = await createNotesWindow();\n * ```\n */\nexport async function createNotesWindow(ttyPath?: string): Promise<NotesWindow> {\n const blessed = (await import('neo-blessed')).default;\n const { openSync } = await import('node:fs');\n\n const tty = ttyPath ?? await findAvailableTty();\n\n const screen = blessed.screen({\n smartCSR: true,\n title: 'term-deck notes',\n fullUnicode: true,\n input: openSync(tty, 'r'),\n output: openSync(tty, 'w'),\n });\n\n const contentBox = blessed.box({\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n tags: true,\n padding: 2,\n style: {\n fg: '#ffffff',\n bg: '#1a1a1a',\n },\n });\n\n screen.append(contentBox);\n screen.render();\n\n return {\n screen,\n contentBox,\n tty,\n };\n}\n\n/**\n * Update notes window content for current slide\n *\n * Updates the notes window to display:\n * - Current slide number and title\n * - Presenter notes (or \"No notes\" if none exist)\n * - Preview of next slide title (or \"Last slide\" if at end)\n *\n * @param notesWindow - The notes window to update\n * @param currentSlide - The current slide being displayed\n * @param nextSlide - The next slide (if any)\n * @param currentIndex - Current slide index (0-based)\n * @param totalSlides - Total number of slides in the deck\n */\nexport function updateNotesWindow(\n notesWindow: NotesWindow,\n currentSlide: Slide,\n nextSlide: Slide | undefined,\n currentIndex: number,\n totalSlides: number\n): void {\n const { contentBox, screen } = notesWindow;\n\n let content = '';\n\n // Header\n content += `{bold}Slide ${currentIndex + 1} of ${totalSlides}{/bold}\\n`;\n content += `{gray-fg}${currentSlide.frontmatter.title}{/}\\n`;\n content += '\\n';\n content += '─'.repeat(50) + '\\n';\n content += '\\n';\n\n // Notes\n if (currentSlide.notes) {\n content += '{bold}PRESENTER NOTES:{/bold}\\n\\n';\n content += currentSlide.notes + '\\n';\n } else {\n content += '{gray-fg}No notes for this slide{/}\\n';\n }\n\n content += '\\n';\n content += '─'.repeat(50) + '\\n';\n content += '\\n';\n\n // Next slide preview\n if (nextSlide) {\n content += `{bold}NEXT:{/bold} \"${nextSlide.frontmatter.title}\"\\n`;\n } else {\n content += '{gray-fg}Last slide{/}\\n';\n }\n\n contentBox.setContent(content);\n screen.render();\n}\n\n/**\n * Toggle notes window visibility\n *\n * Toggles the visibility of the notes window between shown and hidden.\n *\n * @param notesWindow - The notes window to toggle\n */\nexport function toggleNotesVisibility(notesWindow: NotesWindow): void {\n const { contentBox, screen } = notesWindow;\n contentBox.toggle();\n screen.render();\n}\n\n/**\n * Destroy notes window and free resources\n *\n * @param notesWindow - The notes window to destroy\n */\nexport function destroyNotesWindow(notesWindow: NotesWindow): void {\n notesWindow.screen.destroy();\n}\n","import blessed from 'neo-blessed';\nimport type { Presenter } from './types.js';\nimport { renderSlide, clearWindows } from '../renderer/screen.js';\nimport { updateNotesWindow } from './notes-window.js';\n\n/**\n * Show a specific slide\n *\n * Renders the specified slide index and updates notes/progress.\n * Respects the isAnimating flag to prevent concurrent transitions.\n *\n * @param presenter - The presenter state\n * @param index - The slide index to show (0-based)\n */\nexport async function showSlide(presenter: Presenter, index: number): Promise<void> {\n if (presenter.isAnimating) return;\n if (index < 0 || index >= presenter.deck.slides.length) return;\n\n presenter.isAnimating = true;\n presenter.currentSlide = index;\n\n const slide = presenter.deck.slides[index];\n\n // Render slide\n await renderSlide(presenter.renderer, slide);\n presenter.renderer.screen.render();\n\n // Update notes window\n if (presenter.notesWindow) {\n const nextSlide = presenter.deck.slides[index + 1];\n updateNotesWindow(\n presenter.notesWindow,\n slide,\n nextSlide,\n index,\n presenter.deck.slides.length\n );\n }\n\n // Update progress bar\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, presenter.currentSlide, presenter.deck.slides.length);\n }\n\n presenter.isAnimating = false;\n}\n\n/**\n * Go to next slide\n *\n * Advances to the next slide in the deck. If at the last slide:\n * - If loop is enabled, wraps to first slide\n * - If loop is disabled, stays on last slide\n *\n * @param presenter - The presenter state\n */\nexport async function nextSlide(presenter: Presenter): Promise<void> {\n const nextIndex = presenter.currentSlide + 1;\n const { slides } = presenter.deck;\n const loop = presenter.deck.config.settings?.loop ?? false;\n\n if (nextIndex >= slides.length) {\n if (loop) {\n await showSlide(presenter, 0);\n }\n return;\n }\n\n await showSlide(presenter, nextIndex);\n}\n\n/**\n * Go to previous slide\n *\n * Goes back to the previous slide in the deck. If at the first slide:\n * - If loop is enabled, wraps to last slide\n * - If loop is disabled, stays on first slide\n *\n * To maintain the stacked window effect, this function clears all windows\n * and re-renders all slides from 0 up to the target slide.\n *\n * @param presenter - The presenter state\n */\nexport async function prevSlide(presenter: Presenter): Promise<void> {\n const prevIndex = presenter.currentSlide - 1;\n const { slides } = presenter.deck;\n const loop = presenter.deck.config.settings?.loop ?? false;\n\n if (prevIndex < 0) {\n if (loop) {\n // Clear and re-render all slides up to the last one\n clearWindows(presenter.renderer);\n for (let i = 0; i < slides.length; i++) {\n await renderSlide(presenter.renderer, slides[i]);\n }\n presenter.currentSlide = slides.length - 1;\n\n updateUIComponents(presenter, slides.length - 1);\n presenter.renderer.screen.render();\n }\n // If not looping, stay at current slide (index 0)\n return;\n }\n\n // Clear windows and re-render from start up to prevIndex\n clearWindows(presenter.renderer);\n for (let i = 0; i <= prevIndex; i++) {\n await renderSlide(presenter.renderer, slides[i]);\n }\n\n presenter.currentSlide = prevIndex;\n\n updateUIComponents(presenter, prevIndex);\n presenter.renderer.screen.render();\n}\n\n/**\n * Jump to a specific slide by index\n *\n * Jumps directly to the specified slide index. To maintain the stacked window\n * effect, this function clears all windows and re-renders all slides from 0\n * up to the target slide.\n *\n * Invalid indices (negative or beyond deck length) are ignored.\n *\n * @param presenter - The presenter state\n * @param index - The slide index to jump to (0-based)\n */\nexport async function jumpToSlide(presenter: Presenter, index: number): Promise<void> {\n // Check bounds - ignore invalid indices\n if (index < 0 || index >= presenter.deck.slides.length) return;\n\n // Clear all windows to prepare for re-rendering\n clearWindows(presenter.renderer);\n\n // Re-render slides 0 through target index to preserve stacking\n for (let i = 0; i <= index; i++) {\n await renderSlide(presenter.renderer, presenter.deck.slides[i]);\n }\n\n presenter.currentSlide = index;\n\n updateUIComponents(presenter, index);\n presenter.renderer.screen.render();\n}\n\n/**\n * Update progress bar\n *\n * Updates the progress bar to reflect the current slide position.\n * Progress is calculated as (current + 1) / total * 100.\n *\n * @param progressBar - The progress bar element to update\n * @param current - Current slide index (0-based)\n * @param total - Total number of slides\n */\nexport function updateProgress(\n progressBar: blessed.Widgets.ProgressBarElement,\n current: number,\n total: number\n): void {\n const progress = ((current + 1) / total) * 100;\n progressBar.setProgress(progress);\n}\n\n/**\n * Update UI components after slide change\n *\n * Updates the notes window and progress bar to reflect the current slide.\n * This centralizes the UI update logic used by navigation functions.\n *\n * @param presenter - The presenter state\n * @param currentIndex - Current slide index (0-based)\n */\nfunction updateUIComponents(presenter: Presenter, currentIndex: number): void {\n const { slides } = presenter.deck;\n const currentSlide = slides[currentIndex];\n const nextSlide = slides[currentIndex + 1];\n\n if (presenter.notesWindow) {\n updateNotesWindow(\n presenter.notesWindow,\n currentSlide,\n nextSlide,\n currentIndex,\n slides.length\n );\n }\n\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, currentIndex, slides.length);\n }\n}\n","import type { Presenter } from './types.js';\nimport { nextSlide, prevSlide, jumpToSlide } from './navigation.js';\nimport { toggleNotesVisibility } from './notes-window.js';\n\n/**\n * Setup keyboard event handlers\n *\n * Registers all keyboard controls for the presentation:\n * - Next slide: Space, Enter, Right, n\n * - Previous slide: Left, Backspace, p\n * - Jump to slide: 0-9\n * - Show slide list: l\n * - Toggle notes visibility: N\n * - Quit: q, Ctrl+C, Escape (handled in present() function)\n *\n * @param presenter - The presenter state\n */\nexport function setupControls(presenter: Presenter): void {\n const { screen } = presenter.renderer;\n\n // Next slide: Space, Enter, Right, n\n screen.key(['space', 'enter', 'right', 'n'], () => {\n nextSlide(presenter);\n });\n\n // Previous slide: Left, Backspace, p\n screen.key(['left', 'backspace', 'p'], () => {\n prevSlide(presenter);\n });\n\n // Jump to slide: 0-9\n screen.key(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], (ch) => {\n const index = parseInt(ch, 10);\n jumpToSlide(presenter, index);\n });\n\n // Show slide list: l\n screen.key(['l'], () => {\n showSlideList(presenter);\n });\n\n // Toggle notes visibility: N (only if notes window exists)\n screen.key(['N'], () => {\n if (presenter.notesWindow) {\n toggleNotesVisibility(presenter.notesWindow);\n }\n });\n\n // Note: quit keys (q, Ctrl+C, Escape) are handled in the present() function\n}\n\n/**\n * Show slide list overlay\n *\n * Displays an overlay showing all slides in the deck with the current slide marked.\n * User can press Escape, l, or q to close, or press a number key to jump to that slide.\n *\n * @param presenter - The presenter state\n */\nfunction showSlideList(presenter: Presenter): void {\n const { screen } = presenter.renderer;\n const { slides } = presenter.deck;\n\n // Build list content with current slide marker\n const listContent = slides\n .map((slide, i) => {\n const marker = i === presenter.currentSlide ? '▶ ' : ' ';\n return `${marker}${i}: ${slide.frontmatter.title}`;\n })\n .join('\\n');\n\n // Create overlay box centered on screen\n const listBox = screen.box({\n top: 'center',\n left: 'center',\n width: 50,\n height: Math.min(slides.length + 4, 20),\n border: { type: 'line' },\n label: ' SLIDES (press number or Esc) ',\n style: {\n fg: '#ffffff',\n bg: '#0a0a0a',\n border: { fg: '#ffcc00' },\n },\n padding: 1,\n tags: true,\n content: listContent,\n });\n\n screen.append(listBox);\n\n screen.render();\n\n // Close list helper\n const closeList = () => {\n listBox.destroy();\n screen.render();\n };\n\n // Close on Escape, l, or q\n screen.onceKey(['escape', 'l', 'q'], closeList);\n\n // Number keys jump to slide and close\n screen.onceKey(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], (ch) => {\n closeList();\n jumpToSlide(presenter, parseInt(ch ?? '0', 10));\n });\n}\n","import blessed from 'neo-blessed';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer } from '../renderer/screen.js';\nimport { createNotesWindow, destroyNotesWindow } from './notes-window.js';\nimport { setupControls } from './keyboard-controls.js';\nimport { showSlide, nextSlide, updateProgress } from './navigation.js';\nimport type { Presenter, PresentOptions } from './types.js';\n\nexport type { Presenter, PresentOptions };\n\n// Re-export navigation functions for backwards compatibility\nexport { jumpToSlide, prevSlide } from './navigation.js';\n\n/**\n * Start a presentation\n *\n * Loads the deck, creates the renderer, sets up keyboard controls,\n * and enters the main presentation loop.\n *\n * @param slidesDir - Directory containing markdown slides and deck.config.ts\n * @param options - Presentation options (startSlide, showNotes, notesTty, loop)\n * @returns Promise that resolves when the presentation ends (user quits)\n *\n * @example\n * ```typescript\n * await present('./slides', { startSlide: 0, showNotes: true });\n * ```\n */\nexport async function present(\n slidesDir: string,\n options: PresentOptions = {}\n): Promise<void> {\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create renderer\n const renderer = createRenderer(deck.config.theme);\n\n // Create presenter state\n const presenter: Presenter = {\n deck,\n renderer,\n currentSlide: options.startSlide ?? deck.config.settings?.startSlide ?? 0,\n isAnimating: false,\n notesWindow: null,\n autoAdvanceTimer: null,\n progressBar: null,\n };\n\n // Setup notes window if requested\n if (options.showNotes) {\n presenter.notesWindow = await createNotesWindow(options.notesTty);\n }\n\n // Setup progress bar if enabled\n if (deck.config.settings?.showProgress) {\n presenter.progressBar = createProgressBar(presenter);\n }\n\n // Setup keyboard controls\n setupControls(presenter);\n\n // Show first slide\n await showSlide(presenter, presenter.currentSlide);\n\n // Update progress bar\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, presenter.currentSlide, deck.slides.length);\n }\n\n // Start auto-advance if configured\n presenter.autoAdvanceTimer = startAutoAdvance(presenter);\n\n // Keep process alive until quit\n await new Promise<void>((resolve) => {\n renderer.screen.key(['q', 'C-c', 'escape'], () => {\n cleanup(presenter);\n resolve();\n });\n });\n}\n\n/**\n * Cleanup resources\n *\n * Destroys the notes window (if present), stops auto-advance timer,\n * and destroys the main renderer, freeing all resources and restoring the terminal.\n *\n * @param presenter - The presenter state to clean up\n */\nfunction cleanup(presenter: Presenter): void {\n stopAutoAdvance(presenter.autoAdvanceTimer);\n if (presenter.notesWindow) {\n destroyNotesWindow(presenter.notesWindow);\n }\n destroyRenderer(presenter.renderer);\n}\n\n/**\n * Start auto-advance timer\n *\n * Automatically advances to the next slide at a specified interval.\n * Respects the isAnimating flag to avoid advancing during animations.\n * Returns null if auto-advance is disabled (interval <= 0).\n *\n * @param presenter - The presenter state\n * @returns Timer object if auto-advance is enabled, null otherwise\n */\nfunction startAutoAdvance(presenter: Presenter): ReturnType<typeof setInterval> | null {\n const interval = presenter.deck.config.settings?.autoAdvance;\n\n // Auto-advance disabled if interval is undefined, 0, or negative\n if (!interval || interval <= 0) {\n return null;\n }\n\n // Start interval timer\n return setInterval(() => {\n // Only advance if not currently animating\n if (!presenter.isAnimating) {\n nextSlide(presenter);\n }\n }, interval);\n}\n\n/**\n * Stop auto-advance timer\n *\n * Clears the auto-advance interval timer if it exists.\n *\n * @param timer - The timer to stop (can be null)\n */\nfunction stopAutoAdvance(timer: ReturnType<typeof setInterval> | null): void {\n if (timer) {\n clearInterval(timer);\n }\n}\n\n/**\n * Create progress bar at bottom of screen\n *\n * Creates a horizontal progress bar that shows presentation progress.\n * The bar is positioned at the bottom of the screen and fills from left\n * to right as the presentation advances.\n *\n * @param presenter - The presenter state\n * @returns Progress bar element\n */\nfunction createProgressBar(presenter: Presenter): blessed.Widgets.ProgressBarElement {\n const { screen } = presenter.renderer;\n\n const progressBar = blessed.progressbar({\n bottom: 0,\n left: 0,\n width: '100%',\n height: 1,\n style: {\n bg: '#333333',\n bar: { bg: '#00cc66' },\n },\n filled: 0,\n });\n\n screen.append(progressBar);\n\n return progressBar;\n}\n","#!/usr/bin/env node\n/**\n * CLI Entry Point for term-deck\n *\n * Terminal presentation tool with a cyberpunk aesthetic.\n * Provides commands for presenting, exporting, and initializing decks.\n */\n\nimport { Command } from 'commander';\nimport { version } from '../package.json';\nimport { presentCommand } from '../src/cli/commands/present.js';\nimport { exportCommand } from '../src/cli/commands/export.js';\nimport { initCommand } from '../src/cli/commands/init.js';\nimport { handleError } from '../src/cli/errors.js';\n\nconst program = new Command();\n\nprogram\n .name('term-deck')\n .description('Terminal presentation tool with a cyberpunk aesthetic')\n .version(version);\n\n// Register commands\nprogram.addCommand(presentCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(initCommand);\n\n// Default action: present if directory given, else show help\nprogram\n .argument('[dir]', 'Slides directory to present')\n .action(async (dir) => {\n if (dir) {\n // Default action: present the deck\n try {\n const { present } = await import('../src/presenter/main.js');\n await present(dir, {});\n } catch (error) {\n handleError(error);\n }\n } else {\n program.help();\n }\n });\n\nprogram.parse();\n","{\n \"name\": \"@pep/term-deck\",\n \"version\": \"1.0.18\",\n \"description\": \"Terminal presentation tool with a cyberpunk aesthetic\",\n \"type\": \"module\",\n \"bin\": {\n \"term-deck\": \"./dist/bin/term-deck.js\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"scripts\": {\n \"dev\": \"tsx bin/term-deck.ts\",\n \"build\": \"tsup\",\n \"prepublishOnly\": \"pnpm run build\",\n \"test\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"presentation\",\n \"terminal\",\n \"slides\",\n \"cli\",\n \"tui\",\n \"blessed\",\n \"cyberpunk\",\n \"markdown\"\n ],\n \"author\": \"Pepijn Senders\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/PepijnSenders/term-deck.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/PepijnSenders/term-deck/issues\"\n },\n \"homepage\": \"https://github.com/PepijnSenders/term-deck#readme\",\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"files\": [\n \"dist/\",\n \"themes/\",\n \"examples/\",\n \"LICENSE\",\n \"README.md\"\n ],\n \"dependencies\": {\n \"canvas\": \"^3.2.1\",\n \"commander\": \"^14.0.2\",\n \"deepmerge\": \"^4.3.1\",\n \"execa\": \"^9.6.1\",\n \"fast-glob\": \"^3.3.3\",\n \"figlet\": \"^1.9.4\",\n \"gradient-string\": \"^3.0.0\",\n \"gray-matter\": \"^4.0.3\",\n \"mermaid-ascii\": \"^1.0.0\",\n \"neo-blessed\": \"^0.2.0\",\n \"yaml\": \"^2.7.0\",\n \"zod\": \"^3.22.4\"\n },\n \"devDependencies\": {\n \"@types/figlet\": \"^1.5.8\",\n \"@types/node\": \"^22.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^2.1.8\"\n }\n}\n","/**\n * Present Command\n *\n * Starts a presentation with the given options.\n */\n\nimport { Command } from 'commander';\nimport { present } from '../../presenter/main.js';\nimport { handleError } from '../errors.js';\n\nexport const presentCommand = new Command('present')\n .description('Start a presentation')\n .argument('<dir>', 'Slides directory')\n .option('-s, --start <n>', 'Start at slide number', '0')\n .option('-n, --notes', 'Show presenter notes in separate terminal')\n .option('--notes-tty <path>', 'TTY device for notes window (e.g., /dev/ttys001)')\n .option('-l, --loop', 'Loop back to first slide after last')\n .action(async (dir, options) => {\n try {\n await present(dir, {\n startSlide: Number.parseInt(options.start, 10),\n showNotes: options.notes,\n notesTty: options.notesTty,\n loop: options.loop,\n });\n } catch (error) {\n handleError(error);\n }\n });\n","/**\n * CLI Error Handling\n *\n * Provides user-friendly error messages for various error types\n * that can occur during CLI operations.\n */\n\nimport { ValidationError } from '../schemas/validation.js';\nimport { SlideParseError } from '../core/slide.js';\nimport { DeckLoadError } from '../core/deck-loader.js';\nimport { ThemeError } from '../core/theme.js';\n\n/**\n * Handle CLI errors with user-friendly messages\n *\n * Converts various error types into readable console output\n * and exits with appropriate status code.\n */\nexport function handleError(error: unknown): never {\n if (error instanceof ValidationError) {\n console.error(`\\n${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof SlideParseError) {\n console.error(`\\nSlide error in ${error.filePath}:`);\n console.error(` ${error.message}`);\n if (error.cause) {\n const causeMessage = error.cause instanceof Error ? error.cause.message : String(error.cause);\n console.error(` Caused by: ${causeMessage}`);\n }\n process.exit(1);\n }\n\n if (error instanceof DeckLoadError) {\n console.error(`\\nFailed to load deck from ${error.slidesDir}:`);\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof ThemeError) {\n console.error('\\nTheme error:');\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof Error) {\n // Check for common issues\n if (error.message.includes('ENOENT')) {\n console.error('\\nFile or directory not found.');\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error.message.includes('ffmpeg')) {\n console.error('\\nffmpeg error:');\n console.error(` ${error.message}`);\n console.error('\\nMake sure ffmpeg is installed:');\n console.error(' macOS: brew install ffmpeg');\n console.error(' Ubuntu: sudo apt install ffmpeg');\n process.exit(1);\n }\n\n // Generic error\n console.error(`\\nError: ${error.message}`);\n\n if (process.env.DEBUG) {\n console.error(error.stack);\n }\n\n process.exit(1);\n }\n\n // Unknown error\n console.error('\\nUnknown error occurred');\n console.error(error);\n process.exit(1);\n}\n","/**\n * Export Command\n *\n * Exports a presentation to GIF or MP4 format.\n */\n\nimport { Command } from 'commander';\nimport { exportPresentation } from '../../export/recorder.js';\nimport { handleError } from '../errors.js';\n\nexport const exportCommand = new Command('export')\n .description('Export presentation to GIF or MP4')\n .argument('<dir>', 'Slides directory')\n .requiredOption('-o, --output <file>', 'Output file (.mp4 or .gif)')\n .option('-w, --width <n>', 'Terminal width in characters', '120')\n .option('-h, --height <n>', 'Terminal height in characters', '40')\n .option('--fps <n>', 'Frames per second', '30')\n .option('-t, --slide-time <n>', 'Seconds per slide', '3')\n .option('-q, --quality <n>', 'Quality 1-100 (video only)', '80')\n .action(async (dir, options) => {\n try {\n await exportPresentation(dir, {\n output: options.output,\n width: Number.parseInt(options.width, 10),\n height: Number.parseInt(options.height, 10),\n fps: Number.parseInt(options.fps, 10),\n slideTime: Number.parseFloat(options.slideTime),\n quality: Number.parseInt(options.quality, 10),\n });\n } catch (error) {\n handleError(error);\n }\n });\n","/**\n * Export API\n *\n * This module provides a unified public API for exporting presentations\n * to various formats (video, GIF, asciicast). It re-exports functionality\n * from focused sub-modules.\n *\n * For video/GIF export:\n * @see {presentation-exporter}\n *\n * For ANSI/asciicast export:\n * @see {ansi-recorder}\n *\n * For session management:\n * @see {recording-session}\n */\n\n// Type definitions\nexport type {\n ExportOptions,\n ExportFormat,\n AsciicastHeader,\n AsciicastFrame,\n} from './types.js';\n\n// Recording session management\nexport type { RecordingSession } from './recording-session.js';\nexport {\n createRecordingSession,\n saveFrame,\n cleanupSession,\n} from './recording-session.js';\n\n// Video/GIF export\nexport { exportPresentation } from './presentation-exporter.js';\n\n// ANSI recording\nexport type { AnsiRecordOptions } from './ansi-recorder.js';\nexport { recordAnsi } from './ansi-recorder.js';\n\n// FFmpeg utilities (re-exported for convenience)\nexport { checkFfmpeg, detectFormat } from './encoding/ffmpeg-encoder.js';\n","/**\n * Recording Session Management\n *\n * This module manages the lifecycle of a recording session, including\n * temporary directory creation, frame storage, and cleanup.\n */\n\nimport { writeFile, mkdir, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport type { ExportOptions } from './types.js';\n\n/**\n * Recording session state\n */\nexport interface RecordingSession {\n tempDir: string\n frameCount: number\n width: number\n height: number\n fps: number\n}\n\n/**\n * Create a new recording session\n *\n * @param options - Export options containing dimensions and fps\n * @returns A new recording session with temporary directory\n */\nexport async function createRecordingSession(\n options: ExportOptions\n): Promise<RecordingSession> {\n // Create temp directory for frames\n const tempDir = join(tmpdir(), `term-deck-export-${Date.now()}`);\n await mkdir(tempDir, { recursive: true });\n\n return {\n tempDir,\n frameCount: 0,\n width: options.width ?? 120,\n height: options.height ?? 40,\n fps: options.fps ?? 30,\n };\n}\n\n/**\n * Save a PNG frame to the recording session\n *\n * @param session - Active recording session\n * @param png - PNG image data as Uint8Array\n */\nexport async function saveFrame(\n session: RecordingSession,\n png: Uint8Array\n): Promise<void> {\n const frameNum = session.frameCount.toString().padStart(6, '0');\n const framePath = join(session.tempDir, `frame_${frameNum}.png`);\n\n await writeFile(framePath, png);\n session.frameCount++;\n}\n\n/**\n * Cleanup recording session by removing temporary directory\n *\n * @param session - Recording session to cleanup\n */\nexport async function cleanupSession(session: RecordingSession): Promise<void> {\n await rm(session.tempDir, { recursive: true, force: true });\n}\n","/**\n * Presentation Video Exporter\n *\n * This module handles exporting presentations to video (MP4) or GIF formats.\n * It orchestrates the rendering, frame capture, and video encoding process.\n */\n\nimport { join } from 'path';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer, renderSlide } from '../renderer/screen.js';\nimport { setScreenDimensions } from '../renderer/types/screen.js';\nimport { VirtualTerminal } from './utils/virtual-terminal.js';\nimport { captureScreen } from './capture/screen-capture.js';\nimport { checkFfmpeg, detectFormat, encodeVideo } from './encoding/ffmpeg-encoder.js';\nimport { createRecordingSession, saveFrame, cleanupSession } from './recording-session.js';\nimport type { ExportOptions, ExportFormat } from './types.js';\n\n/**\n * Encode recorded frames to video using ffmpeg\n *\n * @param tempDir - Directory containing frame images\n * @param output - Output file path\n * @param format - Export format (mp4 or gif)\n * @param fps - Frames per second\n * @param quality - Video quality (1-100)\n */\nasync function encodeFramesToVideo(\n tempDir: string,\n output: string,\n format: ExportFormat,\n fps: number,\n quality?: number\n): Promise<void> {\n const inputPattern = join(tempDir, 'frame_%06d.png');\n\n await encodeVideo({\n inputPattern,\n output,\n format,\n fps,\n quality\n });\n}\n\n/**\n * Export a presentation to video or GIF format\n *\n * @param slidesDir - Directory containing slide markdown files\n * @param options - Export options (output path, dimensions, fps, etc.)\n */\nexport async function exportPresentation(\n slidesDir: string,\n options: ExportOptions\n): Promise<void> {\n // Check ffmpeg is available\n await checkFfmpeg();\n\n // Detect format from output extension\n const format = detectFormat(options.output);\n\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create recording session\n const session = await createRecordingSession(options);\n\n // Create virtual terminal for rendering\n const vt = new VirtualTerminal(session.width, session.height);\n\n // Create renderer (headless mode)\n const renderer = createRenderer(deck.config.theme);\n\n // Set screen dimensions for export\n setScreenDimensions(renderer.screen, session.width, session.height);\n\n const slideTime = options.slideTime ?? 3; // seconds per slide\n const framesPerSlide = session.fps * slideTime;\n\n console.log(`Exporting ${deck.slides.length} slides...`);\n\n try {\n for (let i = 0; i < deck.slides.length; i++) {\n const slide = deck.slides[i];\n console.log(` Slide ${i + 1}/${deck.slides.length}: ${slide.frontmatter.title}`);\n\n // Render slide\n await renderSlide(renderer, slide);\n\n // Capture frames for this slide\n for (let f = 0; f < framesPerSlide; f++) {\n // Update screen (needed for animations like matrix rain)\n renderer.screen.render();\n\n // Capture to virtual terminal\n captureScreen(renderer.screen, vt);\n\n // Save frame as PNG\n const png = await vt.toPng();\n await saveFrame(session, png);\n }\n }\n\n // Encode video\n console.log('Encoding video...');\n await encodeFramesToVideo(\n session.tempDir,\n options.output,\n format,\n session.fps,\n options.quality\n );\n\n console.log(`Exported to ${options.output}`);\n } finally {\n // Cleanup\n destroyRenderer(renderer);\n await cleanupSession(session);\n }\n}\n","/**\n * Screen Type Extensions\n *\n * This module extends the blessed Screen type to include properties that\n * exist at runtime but aren't typed in the @types/blessed package.\n */\n\nimport type blessed from 'neo-blessed';\n\n/**\n * Extended Screen interface that includes width and height properties.\n * These properties exist on blessed Screen objects at runtime but aren't\n * included in the TypeScript type definitions.\n */\nexport interface ExtendedScreen extends blessed.Widgets.Screen {\n width: number\n height: number\n}\n\n/**\n * Type guard to check if a screen has width and height properties\n */\nexport function hasScreenDimensions(\n screen: blessed.Widgets.Screen\n): screen is ExtendedScreen {\n return (\n typeof (screen as any).width === 'number' &&\n typeof (screen as any).height === 'number'\n );\n}\n\n/**\n * Safely set screen dimensions\n *\n * @param screen - Blessed screen instance\n * @param width - Width in characters\n * @param height - Height in characters\n */\nexport function setScreenDimensions(\n screen: blessed.Widgets.Screen,\n width: number,\n height: number\n): void {\n (screen as ExtendedScreen).width = width;\n (screen as ExtendedScreen).height = height;\n}\n","/**\n * Virtual Terminal Buffer\n *\n * Provides an in-memory representation of a terminal screen with character\n * and color information. Used for capturing terminal output for export.\n */\n\n/**\n * Virtual terminal buffer for capturing frames\n *\n * Maintains a 2D grid of characters and their colors, which can be\n * rendered to PNG images for video export.\n */\nexport class VirtualTerminal {\n private buffer: string[][]\n private colors: string[][]\n\n constructor(\n public width: number,\n public height: number\n ) {\n this.buffer = Array.from({ length: height }, () =>\n Array(width).fill(' ')\n )\n this.colors = Array.from({ length: height }, () =>\n Array(width).fill('#ffffff')\n )\n }\n\n /**\n * Set character at position with optional color\n */\n setChar(x: number, y: number, char: string, color: string = '#ffffff'): void {\n if (x >= 0 && x < this.width && y >= 0 && y < this.height) {\n this.buffer[y][x] = char\n this.colors[y][x] = color\n }\n }\n\n /**\n * Clear the buffer to blank spaces\n */\n clear(): void {\n for (let y = 0; y < this.height; y++) {\n for (let x = 0; x < this.width; x++) {\n this.buffer[y][x] = ' '\n this.colors[y][x] = '#ffffff'\n }\n }\n }\n\n /**\n * Get buffer contents as plain text string\n */\n toString(): string {\n return this.buffer.map((row) => row.join('')).join('\\n')\n }\n\n /**\n * Get the raw character buffer\n */\n getBuffer(): string[][] {\n return this.buffer\n }\n\n /**\n * Get the color buffer\n */\n getColors(): string[][] {\n return this.colors\n }\n\n /**\n * Convert buffer to PNG image data\n */\n async toPng(): Promise<Uint8Array> {\n return renderTerminalToPng(this.buffer, this.colors, this.width, this.height)\n }\n}\n\n// Character dimensions in pixels (monospace font)\nconst CHAR_WIDTH = 10\nconst CHAR_HEIGHT = 20\n\n/**\n * Render terminal buffer to PNG using canvas\n *\n * @param buffer - 2D array of characters\n * @param colors - 2D array of hex color codes\n * @param width - Terminal width in characters\n * @param height - Terminal height in characters\n * @returns PNG image data as Uint8Array\n */\nasync function renderTerminalToPng(\n buffer: string[][],\n colors: string[][],\n width: number,\n height: number\n): Promise<Uint8Array> {\n // Dynamic import to avoid bundling issues\n const { createCanvas } = await import('canvas')\n\n const canvas = createCanvas(width * CHAR_WIDTH, height * CHAR_HEIGHT)\n const ctx = canvas.getContext('2d')\n\n // Background\n ctx.fillStyle = '#0a0a0a'\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n // Set font\n ctx.font = `${CHAR_HEIGHT - 4}px monospace`\n ctx.textBaseline = 'top'\n\n // Render each character\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const char = buffer[y][x]\n const color = colors[y][x]\n\n if (char !== ' ') {\n ctx.fillStyle = color\n ctx.fillText(char, x * CHAR_WIDTH, y * CHAR_HEIGHT + 2)\n }\n }\n }\n\n return canvas.toBuffer('image/png')\n}\n","/**\n * Screen Capture Module\n *\n * Handles capturing blessed screen content to various formats.\n * Separated from recorder.ts to follow Single Responsibility Principle.\n */\n\nimport { hexToAnsi256, extractColor } from '../utils/color-conversion.js';\nimport type { VirtualTerminal } from '../utils/virtual-terminal.js';\n\n/**\n * Capture blessed screen content to virtual terminal\n *\n * This parses the blessed screen's internal buffer and writes it to a VirtualTerminal.\n * Each cell contains a character and color information that gets extracted and applied.\n *\n * @param screen - The neo-blessed screen to capture\n * @param vt - The virtual terminal to write to\n */\nexport function captureScreen(\n screen: any, // neo-blessed screen type\n vt: VirtualTerminal\n): void {\n const lines = screen.lines || [];\n\n for (let y = 0; y < Math.min(lines.length, vt.height); y++) {\n const line = lines[y];\n if (!line) continue;\n\n for (let x = 0; x < Math.min(line.length, vt.width); x++) {\n const cell = line[x];\n if (!cell) continue;\n\n // Cell format: [char, attr] or just char\n const char = Array.isArray(cell) ? cell[0] : cell;\n const attr = Array.isArray(cell) ? cell[1] : null;\n\n // Extract color from attr (blessed-specific format)\n const color = extractColor(attr) || '#ffffff';\n\n vt.setChar(x, y, char || ' ', color);\n }\n }\n}\n\n/**\n * Capture blessed screen content as ANSI escape sequence string\n *\n * This generates a string with ANSI color codes that can be played back\n * in a terminal or saved to an asciicast file.\n *\n * @param screen - The neo-blessed screen to capture\n * @returns ANSI-encoded string representation of the screen\n */\nexport function captureScreenAsAnsi(screen: any): string {\n const lines = screen.lines || [];\n const output: string[] = [];\n\n // Clear screen and reset cursor\n output.push('\\x1b[2J\\x1b[H');\n\n for (let y = 0; y < lines.length; y++) {\n const line = lines[y];\n if (!line) {\n output.push('\\n');\n continue;\n }\n\n let lineStr = '';\n let lastColor: string | null = null;\n\n for (let x = 0; x < line.length; x++) {\n const cell = line[x];\n if (!cell) {\n lineStr += ' ';\n continue;\n }\n\n // Cell format: [char, attr] or just char\n const char = Array.isArray(cell) ? cell[0] : cell;\n const attr = Array.isArray(cell) ? cell[1] : null;\n\n // Extract color\n const color = extractColor(attr);\n\n // Apply color if changed\n if (color && color !== lastColor) {\n // Convert hex to ANSI 256-color code\n lineStr += hexToAnsi256(color);\n lastColor = color;\n }\n\n lineStr += char || ' ';\n }\n\n // Reset color at end of line\n if (lastColor) {\n lineStr += '\\x1b[0m';\n }\n\n output.push(lineStr);\n if (y < lines.length - 1) {\n output.push('\\n');\n }\n }\n\n return output.join('');\n}\n","/**\n * Color Conversion Utilities\n *\n * Utilities for converting between hex colors, ANSI 256-color codes,\n * and extracting colors from blessed cell attributes.\n */\n\n/**\n * Convert hex color to ANSI 256-color escape sequence\n *\n * @param hex - Hex color string (e.g., '#ff0000')\n * @returns ANSI escape sequence for foreground color\n */\nexport function hexToAnsi256(hex: string): string {\n const r = Number.parseInt(hex.slice(1, 3), 16)\n const g = Number.parseInt(hex.slice(3, 5), 16)\n const b = Number.parseInt(hex.slice(5, 7), 16)\n\n const rIndex = Math.round(r / 51)\n const gIndex = Math.round(g / 51)\n const bIndex = Math.round(b / 51)\n\n const colorCode = 16 + (rIndex * 36) + (gIndex * 6) + bIndex\n\n return `\\x1b[38;5;${colorCode}m`\n}\n\n/**\n * Convert ANSI 256 color code to hex\n *\n * @param code - ANSI 256-color code (0-255)\n * @returns Hex color string\n */\nexport function ansi256ToHex(code: number): string {\n const standard16 = [\n '#000000', '#800000', '#008000', '#808000',\n '#000080', '#800080', '#008080', '#c0c0c0',\n '#808080', '#ff0000', '#00ff00', '#ffff00',\n '#0000ff', '#ff00ff', '#00ffff', '#ffffff',\n ]\n\n if (code < 16) {\n return standard16[code]\n }\n\n if (code < 232) {\n const n = code - 16\n const r = Math.floor(n / 36) * 51\n const g = Math.floor((n % 36) / 6) * 51\n const b = (n % 6) * 51\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`\n }\n\n const gray = (code - 232) * 10 + 8\n const hex = gray.toString(16).padStart(2, '0')\n return `#${hex}${hex}${hex}`\n}\n\n/**\n * Extract hex color from blessed attribute\n *\n * @param attr - Blessed cell attribute object\n * @returns Hex color string or null if not found\n */\nexport function extractColor(attr: any): string | null {\n if (!attr) return null\n\n if (typeof attr === 'object' && attr.fg !== undefined) {\n if (typeof attr.fg === 'string' && attr.fg.startsWith('#')) {\n return attr.fg\n }\n if (typeof attr.fg === 'number') {\n return ansi256ToHex(attr.fg)\n }\n }\n\n return null\n}\n","/**\n * FFmpeg Video Encoder\n *\n * This module handles video encoding using ffmpeg. It supports both MP4 and GIF formats,\n * with configurable quality settings and optimized encoding parameters.\n *\n * Responsibilities:\n * - Check ffmpeg availability\n * - Encode frame sequences to MP4 format\n * - Encode frame sequences to GIF format with palette optimization\n */\n\nimport { execa } from 'execa';\nimport { writeFile, unlink } from 'fs/promises';\n\n/**\n * Export format types\n */\nexport type ExportFormat = 'mp4' | 'gif';\n\n/**\n * Encoding options for video export\n */\nexport interface EncodingOptions {\n /** Input frame pattern (e.g., '/tmp/frames/frame_%06d.png') */\n inputPattern: string;\n /** Output file path */\n output: string;\n /** Format to encode to */\n format: ExportFormat;\n /** Frames per second */\n fps: number;\n /** Quality setting (1-100, only used for MP4) */\n quality?: number;\n}\n\n/**\n * Check if ffmpeg is available on the system\n *\n * @throws Error with installation instructions if ffmpeg is not found\n */\nexport async function checkFfmpeg(): Promise<void> {\n try {\n await execa('which', ['ffmpeg']);\n } catch {\n throw new Error(\n 'ffmpeg not found. Install it with:\\n' +\n ' macOS: brew install ffmpeg\\n' +\n ' Ubuntu: sudo apt install ffmpeg'\n );\n }\n}\n\n/**\n * Detect export format from filename extension\n *\n * @param output - The output file path\n * @returns The export format ('mp4' or 'gif')\n * @throws Error if the file extension is not .mp4 or .gif\n */\nexport function detectFormat(output: string): ExportFormat {\n if (output.endsWith('.gif')) return 'gif';\n if (output.endsWith('.mp4')) return 'mp4';\n\n throw new Error(\n `Unknown output format for ${output}. Use .mp4 or .gif extension.`\n );\n}\n\n/**\n * Encode frame sequence to video using ffmpeg\n *\n * Routes to the appropriate encoder based on the format.\n *\n * @param options - Encoding options including input pattern, output path, format, and quality\n */\nexport async function encodeVideo(options: EncodingOptions): Promise<void> {\n const { inputPattern, output, format, fps, quality } = options;\n\n if (format === 'mp4') {\n await encodeMp4(inputPattern, output, fps, quality ?? 80);\n } else {\n await encodeGif(inputPattern, output, fps);\n }\n}\n\n/**\n * Encode frame sequence to MP4 format\n *\n * Uses H.264 codec with CRF (Constant Rate Factor) quality control.\n * CRF ranges from 0 (lossless) to 51 (worst quality).\n * Quality parameter (1-100) is mapped to CRF (18-51) where higher quality = lower CRF.\n *\n * @param input - Input frame pattern (e.g., 'frame_%06d.png')\n * @param output - Output MP4 file path\n * @param fps - Frames per second\n * @param quality - Quality setting (1-100), defaults to 80\n */\nasync function encodeMp4(\n input: string,\n output: string,\n fps: number,\n quality: number\n): Promise<void> {\n // CRF: 0 = lossless, 51 = worst. ~18-23 is good quality\n // Map quality (1-100) to CRF (51-18)\n const crf = Math.round(51 - (quality / 100) * 33);\n\n await execa('ffmpeg', [\n '-y', // Overwrite output file\n '-framerate', fps.toString(),\n '-i', input,\n '-c:v', 'libx264', // H.264 codec\n '-crf', crf.toString(),\n '-pix_fmt', 'yuv420p', // Pixel format for compatibility\n output\n ]);\n}\n\n/**\n * Encode frame sequence to GIF format\n *\n * Uses two-pass encoding for better quality:\n * 1. Generate optimized color palette from input frames\n * 2. Encode using the generated palette with dithering\n *\n * This approach produces much better quality GIFs than single-pass encoding.\n *\n * @param input - Input frame pattern (e.g., 'frame_%06d.png')\n * @param output - Output GIF file path\n * @param fps - Frames per second\n */\nasync function encodeGif(\n input: string,\n output: string,\n fps: number\n): Promise<void> {\n const { tmpdir } = await import('os');\n const { join } = await import('path');\n\n // Two-pass encoding for better quality GIF\n const paletteFile = join(tmpdir(), `palette-${Date.now()}.png`);\n\n try {\n // Pass 1: Generate palette with diff stats mode for better color selection\n await execa('ffmpeg', [\n '-y',\n '-framerate', fps.toString(),\n '-i', input,\n '-vf', `fps=${fps},scale=-1:-1:flags=lanczos,palettegen=stats_mode=diff`,\n paletteFile\n ]);\n\n // Pass 2: Encode with palette using Bayer dithering\n await execa('ffmpeg', [\n '-y',\n '-framerate', fps.toString(),\n '-i', input,\n '-i', paletteFile,\n '-lavfi', `fps=${fps},scale=-1:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle`,\n output\n ]);\n } finally {\n // Cleanup palette file\n try {\n await unlink(paletteFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n","/**\n * ANSI Recording Module\n *\n * This module handles recording presentations as ANSI text files using the\n * asciicast v2 format. This format doesn't require ffmpeg or canvas and can\n * be played back with asciinema.\n *\n * @see https://docs.asciinema.org/manual/asciicast/v2/\n */\n\nimport { writeFile } from 'fs/promises';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer, renderSlide } from '../renderer/screen.js';\nimport { setScreenDimensions } from '../renderer/types/screen.js';\nimport { captureScreenAsAnsi } from './capture/screen-capture.js';\nimport type { AsciicastHeader, AsciicastFrame } from './types.js';\n\n/**\n * Options for ANSI recording\n */\nexport interface AnsiRecordOptions {\n /** Time per slide in seconds */\n slideTime?: number\n /** Terminal width in characters */\n width?: number\n /** Terminal height in characters */\n height?: number\n}\n\n/**\n * Record presentation as ANSI text file (asciicast format)\n *\n * This is an alternative to video export that doesn't require ffmpeg or canvas.\n * The output can be played back with asciinema: `asciinema play output.cast`\n *\n * @param slidesDir - Directory containing slide markdown files\n * @param output - Output file path (e.g., 'presentation.cast')\n * @param options - Recording options (dimensions and timing)\n */\nexport async function recordAnsi(\n slidesDir: string,\n output: string,\n options: AnsiRecordOptions = {}\n): Promise<void> {\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create renderer (headless mode)\n const renderer = createRenderer(deck.config.theme);\n\n // Set screen dimensions if specified\n const width = options.width ?? 120;\n const height = options.height ?? 40;\n setScreenDimensions(renderer.screen, width, height);\n\n const slideTime = options.slideTime ?? 3;\n const frames: AsciicastFrame[] = [];\n let currentTime = 0;\n\n console.log(`Recording ${deck.slides.length} slides to asciicast format...`);\n\n try {\n for (let i = 0; i < deck.slides.length; i++) {\n const slide = deck.slides[i];\n console.log(` Slide ${i + 1}/${deck.slides.length}: ${slide.frontmatter.title}`);\n\n // Render slide\n await renderSlide(renderer, slide);\n\n // Capture screen as ANSI string\n const content = captureScreenAsAnsi(renderer.screen);\n\n // Add frame with timestamp\n frames.push([currentTime, 'o', content]);\n currentTime += slideTime;\n }\n\n // Write asciicast file\n const header: AsciicastHeader = {\n version: 2,\n width,\n height,\n timestamp: Math.floor(Date.now() / 1000),\n env: { TERM: 'xterm-256color' },\n };\n\n // Format: header on first line, then one frame per line\n const lines = [JSON.stringify(header)];\n for (const frame of frames) {\n lines.push(JSON.stringify(frame));\n }\n\n await writeFile(output, lines.join('\\n') + '\\n');\n\n console.log(`Recorded to ${output}`);\n console.log(`Play with: asciinema play ${output}`);\n } finally {\n destroyRenderer(renderer);\n }\n}\n","/**\n * Init Command\n *\n * Creates a new presentation deck with sample slides and configuration.\n */\n\nimport { Command } from 'commander';\nimport { join } from 'node:path';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { handleError } from '../errors.js';\n\nexport const initCommand = new Command('init')\n .description('Create a new presentation deck')\n .argument('<name>', 'Deck name (will create directory)')\n .option('-t, --theme <name>', 'Theme to use', 'matrix')\n .action(async (name, options) => {\n try {\n await initDeck(name, options.theme);\n console.log(`Created deck: ${name}/`);\n console.log('\\nNext steps:');\n console.log(` cd ${name}/slides`);\n console.log(' term-deck present .');\n } catch (error) {\n handleError(error);\n }\n });\n\n/**\n * Initialize a new deck directory\n *\n * Creates the directory structure, configuration file, sample slides,\n * and README for a new presentation deck.\n */\nexport async function initDeck(name: string, theme: string): Promise<void> {\n const deckDir = join(process.cwd(), name);\n const slidesDir = join(deckDir, 'slides');\n\n // Create directories\n await mkdir(slidesDir, { recursive: true });\n await writeFile(join(slidesDir, '.gitkeep'), '');\n\n // Create deck.config.js\n const configContent = `export default {\n title: '${name}',\n // Uncomment to use a custom theme:\n // theme: {\n // colors: {\n // primary: '#00ff00',\n // secondary: '#00ffff',\n // background: '#000000',\n // },\n // },\n}\n`;\n await writeFile(join(slidesDir, 'deck.config.js'), configContent);\n\n // Create sample slides\n const slide1 = `---\ntitle: ${name.toUpperCase()}\nbigText: ${name.toUpperCase()}\ngradient: fire\n---\n\n{GREEN}Welcome to your presentation{/}\n\nPress {CYAN}Space{/} or {CYAN}→{/} to advance\n`;\n\n const slide2 = `---\ntitle: SLIDE TWO\nbigText: HELLO\ngradient: cool\n---\n\n{WHITE}This is the second slide{/}\n\n- Point one\n- Point two\n- Point three\n\n<!-- notes -->\nRemember to explain each point clearly.\n`;\n\n const slide3 = `---\ntitle: THE END\nbigText: FIN\ngradient: pink\n---\n\n{ORANGE}Thank you!{/}\n\nPress {CYAN}q{/} to exit\n`;\n\n await writeFile(join(slidesDir, '01-intro.md'), slide1);\n await writeFile(join(slidesDir, '02-content.md'), slide2);\n await writeFile(join(slidesDir, '03-end.md'), slide3);\n\n // Create README\n const readme = `# ${name}\n\nA term-deck presentation.\n\n## Usage\n\n\\`\\`\\`bash\ncd slides\nterm-deck present .\n\\`\\`\\`\n\n## Export\n\n\\`\\`\\`bash\nterm-deck export slides/ -o ${name}.mp4\nterm-deck export slides/ -o ${name}.gif\n\\`\\`\\`\n\n## Hotkeys\n\n| Key | Action |\n|-----|--------|\n| Space / → | Next slide |\n| ← | Previous slide |\n| 0-9 | Jump to slide |\n| l | Show slide list |\n| q | Quit |\n`;\n\n await writeFile(join(deckDir, 'README.md'), readme);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js","../../src/schemas/theme.ts","../../src/schemas/config.ts","../../src/schemas/validation.ts","../../src/schemas/slide.ts","../../src/core/slide.ts","../../src/core/deck-loader.ts","../../src/renderer/effects/matrix-rain.ts","../../src/renderer/window-manager.ts","../../src/core/theme-errors.ts","../../src/core/theme-colors.ts","../../src/core/theme.ts","../../src/core/utils/mermaid.ts","../../src/core/content-processor.ts","../../src/renderer/animations/constants.ts","../../src/renderer/animations/helpers/animation-utils.ts","../../src/renderer/animations/transitions/glitch-transition.ts","../../src/renderer/animations/transitions/fade-transition.ts","../../src/renderer/animations/transitions/typewriter-transition.ts","../../src/renderer/animations/transitions/instant-transition.ts","../../src/renderer/animations/transition-orchestrator.ts","../../src/renderer/animations/transitions.ts","../../src/renderer/text-generator.ts","../../src/renderer/slide-renderer.ts","../../src/renderer/screen.ts","../../src/presenter/notes-window.ts","../../src/presenter/navigation.ts","../../src/presenter/keyboard-controls.ts","../../src/presenter/main.ts","../../bin/term-deck.ts","../../package.json","../../src/cli/commands/present.ts","../../src/cli/errors.ts","../../src/cli/commands/export.ts","../../src/export/recorder.ts","../../src/export/recording-session.ts","../../src/export/presentation-exporter.ts","../../src/renderer/types/screen.ts","../../src/export/utils/virtual-terminal.ts","../../src/export/capture/screen-capture.ts","../../src/export/utils/color-conversion.ts","../../src/export/encoding/ffmpeg-encoder.ts","../../src/export/ansi-recorder.ts","../../src/cli/commands/init.ts"],"names":["z","path","init_slide","blessed","init_theme","convertMermaid","gradient","clearWindows","renderSlide","access","nextSlide","join","tmpdir","Command","mkdir","writeFile","present"],"mappings":"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","file":"term-deck.js","sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { z } from 'zod'\n\n/**\n * Schema for validating hex color strings.\n * Accepts 6-digit hex colors with # prefix (e.g., #ff0066)\n */\nexport const HexColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, {\n message: 'Color must be a valid hex color (e.g., #ff0066)',\n})\n\nexport type HexColor = z.infer<typeof HexColorSchema>\n\n/**\n * Schema for validating gradient color arrays.\n * A gradient requires at least 2 hex colors.\n */\nexport const GradientSchema = z.array(HexColorSchema).min(2, {\n message: 'Gradient must have at least 2 colors',\n})\n\nexport type Gradient = z.infer<typeof GradientSchema>\n\n/**\n * Schema for validating theme objects.\n * Defines the visual appearance of the presentation deck.\n */\nexport const ThemeSchema = z.object({\n // Theme metadata\n name: z.string().min(1, { message: 'Theme name is required' }),\n description: z.string().optional(),\n author: z.string().optional(),\n version: z.string().optional(),\n\n // Color palette\n colors: z.object({\n primary: HexColorSchema,\n secondary: HexColorSchema.optional(),\n accent: HexColorSchema,\n background: HexColorSchema,\n text: HexColorSchema,\n muted: HexColorSchema,\n success: HexColorSchema.optional(),\n warning: HexColorSchema.optional(),\n error: HexColorSchema.optional(),\n }),\n\n // Named gradients for bigText\n gradients: z.record(z.string(), GradientSchema).refine(\n (g) => Object.keys(g).length >= 1,\n { message: 'At least one gradient must be defined' }\n ),\n\n // Glyph set for matrix rain background\n glyphs: z.string().min(10, {\n message: 'Glyph set must have at least 10 characters',\n }),\n\n // Animation settings\n animations: z.object({\n // Speed multiplier (1.0 = normal, 0.5 = half speed, 2.0 = double speed)\n revealSpeed: z.number().min(0.1).max(5.0).default(1.0),\n // Matrix rain density (number of drops)\n matrixDensity: z.number().min(10).max(200).default(50),\n // Glitch effect iterations\n glitchIterations: z.number().min(1).max(20).default(5),\n // Delay between lines during reveal (ms)\n lineDelay: z.number().min(0).max(500).default(30),\n // Matrix rain update interval (ms)\n matrixInterval: z.number().min(20).max(200).default(80),\n }),\n\n // Window appearance\n window: z.object({\n // Border style\n borderStyle: z.enum(['line', 'double', 'rounded', 'none']).default('line'),\n // Shadow effect\n shadow: z.boolean().default(true),\n // Padding inside windows\n padding: z.object({\n top: z.number().min(0).max(5).default(1),\n bottom: z.number().min(0).max(5).default(1),\n left: z.number().min(0).max(10).default(2),\n right: z.number().min(0).max(10).default(2),\n }).optional(),\n }).optional(),\n})\n\nexport type Theme = z.infer<typeof ThemeSchema>\n\n// ============================================================================\n// Color Token System\n// ============================================================================\n\n/**\n * Valid color tokens for inline styling in slide body content.\n * Tokens can be either:\n * - Built-in colors: GREEN, ORANGE, CYAN, PINK, WHITE, GRAY\n * - Theme-mapped colors: PRIMARY, SECONDARY, ACCENT, MUTED, TEXT, BACKGROUND\n *\n * Usage in slides: {GREEN}colored text{/}\n */\nexport const ColorTokens = [\n 'GREEN',\n 'ORANGE',\n 'CYAN',\n 'PINK',\n 'WHITE',\n 'GRAY',\n 'PRIMARY', // Maps to theme.colors.primary\n 'SECONDARY', // Maps to theme.colors.secondary\n 'ACCENT', // Maps to theme.colors.accent\n 'MUTED', // Maps to theme.colors.muted\n 'TEXT', // Maps to theme.colors.text\n 'BACKGROUND', // Maps to theme.colors.background\n] as const\n\n/**\n * Type for valid color token names.\n */\nexport type ColorToken = typeof ColorTokens[number]\n\n/**\n * Pattern for matching color tokens in slide content.\n * Matches: {GREEN}, {ORANGE}, {CYAN}, {PINK}, {WHITE}, {GRAY},\n * {PRIMARY}, {SECONDARY}, {ACCENT}, {MUTED}, {TEXT}, {BACKGROUND}, {/}\n *\n * The {/} token closes any open color tag.\n */\nexport const COLOR_TOKEN_PATTERN = /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g\n\n// ============================================================================\n// Partial Theme for Extension\n// ============================================================================\n\n/**\n * Deep partial utility type that makes all nested properties optional.\n * Used for theme extension where only specific fields need to be overridden.\n */\nexport type DeepPartial<T> = T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>\n} : T\n\n/**\n * Partial theme type for use with theme.extend() functionality.\n * All fields (including nested) become optional.\n */\nexport type PartialTheme = DeepPartial<Theme>\n\n/**\n * Schema for validating partial theme objects.\n * All fields become optional recursively, allowing partial overrides.\n * Used for theme extension validation.\n */\nexport const PartialThemeSchema = ThemeSchema.deepPartial()\n\n// ============================================================================\n// Default Theme\n// ============================================================================\n\n/**\n * Default matrix/cyberpunk theme.\n * Used when no theme is specified or as a base for theme extension.\n */\nexport const DEFAULT_THEME: Theme = {\n name: 'matrix',\n description: 'Default cyberpunk/matrix theme',\n\n colors: {\n primary: '#00cc66',\n accent: '#ff6600',\n background: '#0a0a0a',\n text: '#ffffff',\n muted: '#666666',\n },\n\n gradients: {\n fire: ['#ff6600', '#ff3300', '#ff0066'],\n cool: ['#00ccff', '#0066ff', '#6600ff'],\n pink: ['#ff0066', '#ff0099', '#cc00ff'],\n hf: ['#99cc00', '#00cc66', '#00cccc'],\n },\n\n glyphs: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789',\n\n animations: {\n revealSpeed: 1.0,\n matrixDensity: 50,\n glitchIterations: 5,\n lineDelay: 30,\n matrixInterval: 80,\n },\n\n window: {\n borderStyle: 'line',\n shadow: true,\n padding: {\n top: 1,\n bottom: 1,\n left: 2,\n right: 2,\n },\n },\n}\n","import { z } from 'zod'\nimport { ThemeSchema } from './theme'\n\n/**\n * Schema for presentation settings.\n * Controls how the presentation behaves during runtime.\n */\nexport const SettingsSchema = z.object({\n // Start slide (0-indexed)\n startSlide: z.number().min(0).default(0),\n // Loop back to first slide after last\n loop: z.boolean().default(false),\n // Auto-advance slides (ms, 0 = disabled)\n autoAdvance: z.number().min(0).default(0),\n // Show slide numbers\n showSlideNumbers: z.boolean().default(false),\n // Show progress bar\n showProgress: z.boolean().default(false),\n})\n\nexport type Settings = z.infer<typeof SettingsSchema>\n\n/**\n * Schema for export settings.\n * Controls the output dimensions and quality of exported videos/GIFs.\n */\nexport const ExportSettingsSchema = z.object({\n // Output width in characters (min 80, max 400)\n width: z.number().min(80).max(400).default(120),\n // Output height in characters (min 24, max 100)\n height: z.number().min(24).max(100).default(40),\n // Frames per second for video (min 10, max 60)\n fps: z.number().min(10).max(60).default(30),\n})\n\nexport type ExportSettings = z.infer<typeof ExportSettingsSchema>\n\n/**\n * Schema for validating deck configuration (deck.config.ts).\n * Defines the complete configuration for a presentation deck.\n */\nexport const DeckConfigSchema = z.object({\n // Presentation metadata\n title: z.string().optional(),\n author: z.string().optional(),\n date: z.string().optional(),\n\n // Theme (already validated Theme object)\n theme: ThemeSchema,\n\n // Presentation settings\n settings: SettingsSchema.optional(),\n\n // Export settings\n export: ExportSettingsSchema.optional(),\n})\n\nexport type DeckConfig = z.infer<typeof DeckConfigSchema>\n","import { z, ZodError } from 'zod'\n\n/**\n * Custom error class for validation failures.\n * Extends Error with a specific name for easy identification.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/**\n * Format Zod errors into user-friendly messages.\n * Formats each issue with its field path and message.\n *\n * @param error - The ZodError to format\n * @param context - A description of what was being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns A formatted string with all validation issues\n *\n * @example\n * const error = new ZodError([...])\n * formatZodError(error, 'theme')\n * // Returns:\n * // \"Invalid theme:\n * // - colors.primary: Color must be a valid hex color (e.g., #ff0066)\n * // - name: Theme name is required\"\n */\nexport function formatZodError(error: ZodError, context: string): string {\n const issues = error.issues.map((issue) => {\n const path = issue.path.join('.')\n return ` - ${path ? `${path}: ` : ''}${issue.message}`\n })\n\n return `Invalid ${context}:\\n${issues.join('\\n')}`\n}\n\n/**\n * Parse data with a Zod schema and throw a ValidationError with friendly messages on failure.\n *\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @param context - A description of what's being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns The parsed and validated data\n * @throws {ValidationError} If validation fails\n *\n * @example\n * const theme = safeParse(ThemeSchema, rawData, 'theme')\n * // Throws ValidationError with formatted message if invalid\n */\nexport function safeParse<T>(\n schema: z.ZodSchema<T>,\n data: unknown,\n context: string\n): T {\n const result = schema.safeParse(data)\n\n if (!result.success) {\n throw new ValidationError(formatZodError(result.error, context))\n }\n\n return result.data\n}\n","import { z } from 'zod'\n\n/**\n * Schema for validating slide frontmatter.\n * Defines the metadata for a single slide.\n */\nexport const SlideFrontmatterSchema = z.object({\n // Required: window title\n title: z.string().min(1, {\n message: 'Slide must have a title',\n }),\n\n // ASCII art text (figlet) - can be a single line or multiple lines\n bigText: z.union([\n z.string(),\n z.array(z.string()),\n ]).optional(),\n\n // Which gradient to use for bigText\n gradient: z.string().optional(),\n\n // Override theme for this slide\n theme: z.string().optional(),\n\n // Transition effect\n transition: z.enum([\n 'glitch', // Default: glitch reveal line by line\n 'fade', // Fade in\n 'instant', // No animation\n 'typewriter', // Character by character\n ]).default('glitch'),\n\n // Custom metadata (ignored by renderer, useful for tooling)\n meta: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport type SlideFrontmatter = z.infer<typeof SlideFrontmatterSchema>\n\n/**\n * Schema for a complete slide after parsing.\n * Includes the parsed frontmatter, body content, optional notes, and metadata.\n */\nexport const SlideSchema = z.object({\n // Parsed frontmatter\n frontmatter: SlideFrontmatterSchema,\n // Markdown body content\n body: z.string(),\n // Presenter notes (extracted from <!-- notes --> block)\n notes: z.string().optional(),\n // Source file path\n sourcePath: z.string(),\n // Slide index in deck (0-indexed)\n index: z.number(),\n})\n\nexport type Slide = z.infer<typeof SlideSchema>\n","import matter from 'gray-matter'\nimport { readFile } from 'fs/promises'\nimport type { Slide } from '../schemas/slide.js'\nimport { SlideFrontmatterSchema, SlideSchema } from '../schemas/slide.js'\nimport { safeParse } from '../schemas/validation.js'\n\n/**\n * Raw parsed slide before validation.\n * This is the intermediate structure after parsing frontmatter\n * but before Zod validation.\n */\nexport interface RawSlide {\n frontmatter: Record<string, unknown>\n body: string\n notes?: string\n sourcePath: string\n}\n\n/**\n * Result of extracting notes from slide content.\n */\nexport interface ExtractedNotes {\n body: string\n notes?: string\n}\n\nconst NOTES_MARKER = '<!-- notes -->'\nconst NOTES_END_MARKER = '<!-- /notes -->'\n\n/**\n * Extract presenter notes from body content.\n *\n * Notes are delimited by `<!-- notes -->` marker.\n * An optional `<!-- /notes -->` end marker can be used to include\n * content after notes in the body.\n *\n * @param content - Raw body content from markdown file\n * @returns Object containing separated body and notes\n */\nexport function extractNotes(content: string): ExtractedNotes {\n const notesStart = content.indexOf(NOTES_MARKER)\n\n if (notesStart === -1) {\n return { body: content }\n }\n\n const body = content.slice(0, notesStart).trim()\n\n // Check for explicit end marker\n const notesEnd = content.indexOf(NOTES_END_MARKER, notesStart)\n\n let notes: string\n if (notesEnd !== -1) {\n notes = content.slice(notesStart + NOTES_MARKER.length, notesEnd).trim()\n } else {\n // Everything after marker is notes\n notes = content.slice(notesStart + NOTES_MARKER.length).trim()\n }\n\n return { body, notes: notes || undefined }\n}\n\n/**\n * Parse a single slide file.\n *\n * Reads the markdown file, extracts frontmatter using gray-matter,\n * extracts presenter notes, and validates the result against the schema.\n *\n * @param filePath - Path to the markdown slide file\n * @param index - The slide index in the deck (0-indexed)\n * @returns Validated Slide object\n * @throws {ValidationError} If frontmatter or slide validation fails\n */\nexport async function parseSlide(\n filePath: string,\n index: number\n): Promise<Slide> {\n // Read file content\n const content = await readFile(filePath, 'utf-8')\n\n // Parse frontmatter with gray-matter\n const { data, content: rawBody } = matter(content)\n\n // Extract notes from body\n const { body, notes } = extractNotes(rawBody)\n\n // Validate frontmatter\n const frontmatter = safeParse(\n SlideFrontmatterSchema,\n data,\n `frontmatter in ${filePath}`\n )\n\n // Build full slide object\n const slide = {\n frontmatter,\n body: body.trim(),\n notes: notes?.trim(),\n sourcePath: filePath,\n index,\n }\n\n // Validate complete slide and return\n return safeParse(SlideSchema, slide, `slide ${filePath}`)\n}\n\n/**\n * Error class for slide parsing failures.\n * Includes the file path of the slide that failed to parse and\n * optionally the underlying cause for error chaining.\n */\nexport class SlideParseError extends Error {\n /**\n * @param message - The error message describing what went wrong\n * @param filePath - Path to the slide file that failed to parse\n * @param cause - Optional underlying error that caused this failure\n */\n constructor(\n message: string,\n public readonly filePath: string,\n public override readonly cause?: Error\n ) {\n super(message)\n this.name = 'SlideParseError'\n }\n}\n\n/**\n * Format a slide parse error for user-friendly display.\n * Creates a multi-line message with the file path, error message,\n * and optional cause chain.\n *\n * @param error - The SlideParseError to format\n * @returns A formatted string suitable for console output\n *\n * @example\n * const error = new SlideParseError(\n * 'Missing required field: title',\n * '/slides/01-intro.md',\n * new Error('Validation failed')\n * )\n * console.log(formatSlideError(error))\n * // Error parsing slide: /slides/01-intro.md\n * // Missing required field: title\n * // Caused by: Validation failed\n */\nexport function formatSlideError(error: SlideParseError): string {\n let msg = `Error parsing slide: ${error.filePath}\\n`\n msg += ` ${error.message}\\n`\n\n if (error.cause) {\n msg += ` Caused by: ${error.cause.message}\\n`\n }\n\n return msg\n}\n","import { join } from 'path'\nimport { pathToFileURL } from 'url'\nimport fg from 'fast-glob'\nimport { access } from 'fs/promises'\nimport type { DeckConfig } from '../schemas/config.js'\nimport type { Slide } from '../schemas/slide.js'\nimport { DeckConfigSchema } from '../schemas/config.js'\nimport { safeParse } from '../schemas/validation.js'\nimport { DEFAULT_THEME } from '../schemas/theme.js'\nimport { parseSlide } from './slide.js'\n\n/**\n * Deck structure containing all slides and configuration.\n * Represents a complete presentation loaded from disk.\n */\nexport interface Deck {\n slides: Slide[]\n config: DeckConfig\n basePath: string\n}\n\n/**\n * Slide file info for sorting and loading.\n * Used during the slide discovery phase.\n */\nexport interface SlideFile {\n path: string\n name: string\n index: number\n}\n\n/**\n * Find and sort slide files in a directory.\n *\n * Finds all markdown files (*.md), excludes non-slide files like\n * README.md and files starting with underscore, and sorts them\n * numerically by filename (e.g., 01-intro.md, 02-content.md).\n *\n * @param dir - Directory to search for slide files\n * @returns Array of SlideFile objects sorted by filename\n */\nexport async function findSlideFiles(dir: string): Promise<SlideFile[]> {\n const pattern = join(dir, '*.md')\n const foundFiles = await fg(pattern, { onlyFiles: true })\n\n const files: SlideFile[] = []\n\n for (const filePath of foundFiles) {\n const name = filePath.split('/').pop() || ''\n\n // Skip non-slide files\n if (name === 'README.md' || name.startsWith('_')) {\n continue\n }\n\n files.push({\n path: filePath,\n name,\n index: 0, // Will be set after sorting\n })\n }\n\n // Sort by filename numerically (01-intro.md, 02-problem.md, etc.)\n files.sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true }))\n\n // Assign indices after sorting\n files.forEach((file, i) => {\n file.index = i\n })\n\n return files\n}\n\n/**\n * Load deck configuration from deck.config.js or deck.config.ts in slides directory.\n *\n * Looks for a deck.config.js (preferred) or deck.config.ts file in the specified directory.\n * If found, dynamically imports and validates it against DeckConfigSchema.\n * If not found, returns a default config with the DEFAULT_THEME.\n *\n * @param slidesDir - Directory to search for deck config file\n * @returns Validated DeckConfig object\n * @throws {ValidationError} If config file exists but fails validation\n */\nexport async function loadDeckConfig(slidesDir: string): Promise<DeckConfig> {\n // Try .js first (preferred for Node.js compatibility), then .ts (for dev with tsx)\n const configPaths = [\n { path: join(slidesDir, 'deck.config.js'), name: 'deck.config.js' },\n { path: join(slidesDir, 'deck.config.ts'), name: 'deck.config.ts' },\n ]\n\n let configPath: string | null = null\n let configName = 'deck.config.js'\n\n // Find which config file exists\n for (const config of configPaths) {\n try {\n await access(config.path)\n configPath = config.path\n configName = config.name\n break\n } catch {\n // File doesn't exist, try next\n continue\n }\n }\n\n // No config file found\n if (!configPath) {\n return {\n theme: DEFAULT_THEME,\n }\n }\n\n try {\n // Dynamic import of config\n // Convert file path to file:// URL for ES module imports\n const fileUrl = pathToFileURL(configPath).href\n\n // Add cache buster to prevent module caching in tests only\n // In production, we want normal module caching behavior\n const isTest = process.env.NODE_ENV === 'test' || process.env.VITEST === 'true'\n const cacheBuster = isTest ? `?t=${Date.now()}-${Math.random()}` : ''\n const configModule = await import(fileUrl + cacheBuster)\n\n if (!configModule.default) {\n throw new Error(`${configName} must export default config`)\n }\n\n // Validate config against schema\n return safeParse(DeckConfigSchema, configModule.default, configName)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n // No config file found, use defaults\n return { theme: DEFAULT_THEME }\n }\n throw error\n }\n}\n\n/**\n * Load a complete deck from a directory.\n *\n * Loads the deck configuration, finds all slide files, and parses\n * them in parallel. Returns a Deck object containing all slides,\n * the configuration, and the base path.\n *\n * @param slidesDir - Directory containing slide files and optional deck.config.ts\n * @returns Complete Deck object with slides, config, and basePath\n * @throws {ValidationError} If any slide fails to parse or validate\n */\nexport async function loadDeck(slidesDir: string): Promise<Deck> {\n // Load config first\n const config = await loadDeckConfig(slidesDir)\n\n // Find all markdown files\n const slideFiles = await findSlideFiles(slidesDir)\n\n // Parse all slides in parallel\n const slides = await Promise.all(\n slideFiles.map((file) => parseSlide(file.path, file.index))\n )\n\n return {\n slides,\n config,\n basePath: slidesDir,\n }\n}\n\n/**\n * Error class for deck loading failures.\n * Includes the directory path of the slides and optionally\n * the underlying cause for error chaining.\n */\nexport class DeckLoadError extends Error {\n /**\n * @param message - The error message describing what went wrong\n * @param slidesDir - Path to the directory that was being loaded\n * @param cause - Optional underlying error that caused this failure\n */\n constructor(\n message: string,\n public readonly slidesDir: string,\n public override readonly cause?: Error\n ) {\n super(message)\n this.name = 'DeckLoadError'\n }\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../../schemas/theme.js'\n\n/**\n * Matrix rain drop.\n * Represents a single falling column of glyphs in the matrix background.\n */\nexport interface MatrixDrop {\n /** Horizontal position (column) */\n x: number\n /** Vertical position (row, can be fractional for smooth animation) */\n y: number\n /** Fall speed (rows per animation frame) */\n speed: number\n /** Array of glyph characters forming the drop's trail */\n trail: string[]\n}\n\n/**\n * Matrix rain state.\n * Manages the matrix rain animation state and resources.\n */\nexport interface MatrixRainState {\n /** Box element for matrix rain background */\n matrixBox: blessed.Widgets.BoxElement\n /** Array of matrix rain drops for animation */\n matrixDrops: MatrixDrop[]\n /** Interval timer for matrix rain animation (null if stopped) */\n matrixInterval: ReturnType<typeof setInterval> | null\n /** Active theme for rendering */\n theme: Theme\n}\n\n/**\n * Generate a trail of random glyphs.\n * Randomly selects glyphs from the theme's glyph set to form a drop trail.\n *\n * @param glyphs - String of available glyphs to choose from\n * @param length - Number of characters in the trail\n * @returns Array of random glyph characters\n */\nfunction generateTrail(glyphs: string, length: number): string[] {\n return Array.from({ length }, () =>\n glyphs[Math.floor(Math.random() * glyphs.length)]\n )\n}\n\n/**\n * Render one frame of matrix rain.\n * Updates the matrix background with falling glyph trails.\n * This function is called repeatedly by the animation interval.\n *\n * @param screen - The blessed screen instance\n * @param state - Matrix rain state\n */\nexport function renderMatrixRain(\n screen: blessed.Widgets.Screen,\n state: MatrixRainState\n): void {\n const { matrixBox, matrixDrops, theme } = state\n const width = Math.max(20, (screen.width as number) || 80)\n const height = Math.max(10, (screen.height as number) || 24)\n\n // Create grid for positioning characters\n const grid: string[][] = Array.from({ length: height }, () =>\n Array(width).fill(' ')\n )\n\n // Update and render drops\n for (const drop of matrixDrops) {\n drop.y += drop.speed\n\n // Reset if off screen\n if (drop.y > height + drop.trail.length) {\n drop.y = -drop.trail.length\n drop.x = Math.floor(Math.random() * width)\n }\n\n // Draw trail\n for (let i = 0; i < drop.trail.length; i++) {\n const y = Math.floor(drop.y) - i\n if (y >= 0 && y < height && drop.x < width) {\n grid[y][drop.x] = drop.trail[i]\n }\n }\n }\n\n // Convert grid to string with colors\n let output = ''\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const char = grid[y][x]\n if (char !== ' ') {\n const brightness = Math.random() > 0.7 ? '{bold}' : ''\n output += `${brightness}{${theme.colors.primary}-fg}${char}{/}`\n } else {\n output += ' '\n }\n }\n if (y < height - 1) output += '\\n'\n }\n\n matrixBox.setContent(output)\n}\n\n/**\n * Initialize matrix rain drops.\n * Creates the initial set of drops and starts the animation loop.\n *\n * @param screen - The blessed screen instance\n * @param state - Matrix rain state to initialize\n */\nexport function initMatrixRain(\n screen: blessed.Widgets.Screen,\n state: MatrixRainState\n): void {\n const { theme } = state\n const width = (screen.width as number) || 80\n const height = (screen.height as number) || 24\n const density = theme.animations.matrixDensity\n\n state.matrixDrops = []\n\n for (let i = 0; i < density; i++) {\n state.matrixDrops.push({\n x: Math.floor(Math.random() * width),\n y: Math.floor(Math.random() * height),\n speed: 0.3 + Math.random() * 0.7,\n trail: generateTrail(theme.glyphs, 5 + Math.floor(Math.random() * 10)),\n })\n }\n\n // Start animation loop\n state.matrixInterval = setInterval(() => {\n renderMatrixRain(screen, state)\n screen.render()\n }, theme.animations.matrixInterval)\n}\n\n/**\n * Stop matrix rain animation.\n * Clears the animation interval and resets state.\n *\n * @param state - Matrix rain state to stop\n */\nexport function stopMatrixRain(state: MatrixRainState): void {\n if (state.matrixInterval) {\n clearInterval(state.matrixInterval)\n state.matrixInterval = null\n }\n}\n\n/**\n * Create matrix rain background box.\n * Creates a full-screen box element for the matrix rain effect.\n *\n * @param screen - The blessed screen instance\n * @returns The created matrix box element\n */\nexport function createMatrixBox(\n screen: blessed.Widgets.Screen\n): blessed.Widgets.BoxElement {\n const matrixBox = blessed.box({\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n tags: true,\n })\n screen.append(matrixBox)\n return matrixBox\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\n\n/**\n * Window creation options.\n * Configuration for creating slide windows with stacking effect.\n */\nexport interface WindowOptions {\n /** Window title displayed in the border */\n title: string\n /** Border color (defaults to theme-based cycling) */\n color?: string\n /** Window width (number for absolute, string for percentage) */\n width?: number | string\n /** Window height (number for absolute, string for percentage) */\n height?: number | string\n /** Top position (number for absolute, string for percentage) */\n top?: number | string\n /** Left position (number for absolute, string for percentage) */\n left?: number | string\n}\n\n/**\n * Get window border color based on index.\n * Cycles through theme colors and additional cyberpunk colors\n * to create a stacking effect with varied border colors.\n *\n * @param index - Window index in the stack\n * @param theme - Theme configuration\n * @returns Hex color string for the window border\n */\nexport function getWindowColor(index: number, theme: Theme): string {\n const colors = [\n theme.colors.primary,\n theme.colors.accent,\n theme.colors.secondary ?? theme.colors.primary,\n '#ff0066', // pink\n '#9966ff', // purple\n '#ffcc00', // yellow\n ]\n return colors[index % colors.length]\n}\n\n/**\n * Create a slide window with stacking effect.\n * Creates a bordered box element with theme-based styling,\n * random position for stacking effect, and adds it to the window stack.\n *\n * @param screen - The blessed screen instance\n * @param windowStack - Stack of existing windows\n * @param theme - Theme configuration\n * @param options - Window configuration options\n * @returns The created window box element\n */\nexport function createWindow(\n screen: blessed.Widgets.Screen,\n windowStack: blessed.Widgets.BoxElement[],\n theme: Theme,\n options: WindowOptions\n): blessed.Widgets.BoxElement {\n const windowIndex = windowStack.length\n const color = options.color ?? getWindowColor(windowIndex, theme)\n\n const screenWidth = (screen.width as number) || 120\n const screenHeight = (screen.height as number) || 40\n\n // Default dimensions: 75% width, 70% height\n const width = options.width ?? Math.floor(screenWidth * 0.75)\n const height = options.height ?? Math.floor(screenHeight * 0.7)\n\n // Random position within bounds (for stacking effect)\n const maxTop = Math.max(1, screenHeight - (height as number) - 2)\n const maxLeft = Math.max(1, screenWidth - (width as number) - 2)\n const top = options.top ?? Math.floor(Math.random() * maxTop)\n const left = options.left ?? Math.floor(Math.random() * maxLeft)\n\n const window = theme.window ?? { borderStyle: 'line', shadow: true }\n const padding = window.padding ?? { top: 1, bottom: 1, left: 2, right: 2 }\n\n const box = blessed.box({\n top,\n left,\n width,\n height,\n border: {\n type: window.borderStyle === 'none' ? undefined : 'line',\n },\n label: ` ${options.title} `,\n style: {\n fg: theme.colors.text,\n bg: theme.colors.background,\n border: { fg: color },\n label: { fg: color, bold: true },\n },\n padding,\n tags: true,\n shadow: window.shadow,\n })\n\n screen.append(box)\n windowStack.push(box)\n\n return box\n}\n\n/**\n * Clear all windows from stack.\n * Destroys all window elements in the stack and resets the stack to empty.\n * This is typically called when transitioning between slides.\n *\n * @param windowStack - The stack of windows to clear\n */\nexport function clearWindows(windowStack: blessed.Widgets.BoxElement[]): void {\n for (const window of windowStack) {\n window.destroy()\n }\n windowStack.length = 0\n}\n","import { ValidationError } from '../schemas/validation'\n\n/**\n * Error class for theme-related failures.\n * Includes optional source information (theme name and file path) for better debugging.\n */\nexport class ThemeError extends Error {\n /**\n * @param message - The error message\n * @param themeName - Optional name of the theme that caused the error\n * @param path - Optional path to the theme file or package\n */\n constructor(\n message: string,\n public readonly themeName?: string,\n public readonly path?: string\n ) {\n super(message)\n this.name = 'ThemeError'\n }\n}\n\n/**\n * Format any error into a user-friendly ThemeError.\n * Handles ValidationError, generic Error, and unknown error types.\n *\n * @param error - The error to format\n * @param source - Description of the theme source (e.g., file path or package name)\n * @returns A ThemeError with a user-friendly message\n *\n * @example\n * try {\n * await loadThemeFromFile('./theme.yml')\n * } catch (error) {\n * throw formatThemeError(error, './theme.yml')\n * }\n */\nexport function formatThemeError(error: unknown, source: string): ThemeError {\n if (error instanceof ValidationError) {\n return new ThemeError(\n `Invalid theme from ${source}:\\n${error.message}`,\n undefined,\n source\n )\n }\n\n if (error instanceof Error) {\n return new ThemeError(\n `Failed to load theme from ${source}: ${error.message}`,\n undefined,\n source\n )\n }\n\n return new ThemeError(`Unknown error loading theme from ${source}`)\n}\n","import gradient from 'gradient-string'\nimport type { Theme } from '../schemas/theme'\n\n/**\n * Function type for applying a gradient to text.\n * Returns ANSI-colored text with the gradient applied.\n */\nexport interface GradientFunction {\n (text: string): string\n}\n\n/**\n * Built-in color mappings for color tokens in slide content.\n * These are fixed colors that don't change with the theme.\n */\nexport const BUILTIN_COLORS: Record<string, string> = {\n GREEN: '#00cc66',\n ORANGE: '#ff6600',\n CYAN: '#00ccff',\n PINK: '#ff0066',\n WHITE: '#ffffff',\n GRAY: '#666666',\n}\n\n/**\n * Create gradient functions from theme gradients.\n * Returns an object mapping gradient names to gradient functions that can be\n * applied to text to produce ANSI-colored output.\n *\n * @param theme - The theme containing gradient definitions\n * @returns Record mapping gradient names to gradient functions\n *\n * @example\n * const gradients = createGradients(theme)\n * const styledText = gradients.fire('Hello World')\n */\nexport function createGradients(theme: Theme): Record<string, GradientFunction> {\n const gradients: Record<string, GradientFunction> = {}\n\n for (const [name, colors] of Object.entries(theme.gradients)) {\n gradients[name] = gradient(colors)\n }\n\n return gradients\n}\n\n/**\n * Apply a gradient to text by name.\n * Looks up the gradient in the theme and applies it to the text.\n * Falls back gracefully if the gradient doesn't exist.\n *\n * @param text - The text to apply the gradient to\n * @param gradientName - The name of the gradient to use\n * @param theme - The theme containing gradient definitions\n * @returns The text with gradient applied, or unstyled text if gradient not found\n *\n * @example\n * const styledText = applyGradient('Hello World', 'fire', theme)\n */\nexport function applyGradient(\n text: string,\n gradientName: string,\n theme: Theme\n): string {\n const colors = theme.gradients[gradientName]\n\n if (!colors) {\n // Fall back gracefully - return unstyled text\n return text\n }\n\n return gradient(colors)(text)\n}\n\n/**\n * Resolve a color token to its hex value.\n * Theme colors (PRIMARY, ACCENT, etc.) are resolved from the theme.\n * Built-in colors (GREEN, ORANGE, etc.) use fixed values.\n *\n * @param token - The color token to resolve (e.g., 'PRIMARY', 'GREEN')\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns The hex color value\n *\n * @example\n * const color = resolveColorToken('PRIMARY', theme) // '#00cc66'\n * const color = resolveColorToken('GREEN', theme) // '#00cc66'\n */\nexport function resolveColorToken(token: string, theme: Theme): string {\n // Check theme colors first\n switch (token) {\n case 'PRIMARY':\n return theme.colors.primary\n case 'SECONDARY':\n return theme.colors.secondary ?? theme.colors.primary\n case 'ACCENT':\n return theme.colors.accent\n case 'MUTED':\n return theme.colors.muted\n case 'TEXT':\n return theme.colors.text\n case 'BACKGROUND':\n return theme.colors.background\n }\n\n // Fall back to built-in colors\n return BUILTIN_COLORS[token] ?? theme.colors.text\n}\n\n/**\n * Convert color tokens in content to blessed tags.\n * Transforms tokens like {GREEN} to blessed color tags like {#00cc66-fg}.\n * Preserves closing tags {/} as-is.\n *\n * @param content - The content with color tokens\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns Content with color tokens converted to blessed tags\n *\n * @example\n * const content = '{GREEN}Hello{/} {ORANGE}World{/}'\n * const result = colorTokensToBlessedTags(content, theme)\n * // '{#00cc66-fg}Hello{/} {#ff6600-fg}World{/}'\n */\nexport function colorTokensToBlessedTags(content: string, theme: Theme): string {\n return content.replace(\n /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g,\n (_, token) => {\n if (token === '/') {\n return '{/}' // Close tag\n }\n const color = resolveColorToken(token, theme)\n return `{${color}-fg}`\n }\n )\n}\n","import { parse as parseYaml } from 'yaml'\nimport deepmerge from 'deepmerge'\nimport type { Theme, PartialTheme } from '../schemas/theme'\nimport { ThemeSchema } from '../schemas/theme'\nimport { safeParse } from '../schemas/validation'\n\n/**\n * Theme object with extension capability.\n * Extends the base Theme type with an extend() method that allows\n * Tailwind-style theme customization.\n */\nexport interface ThemeObject extends Theme {\n /**\n * Create a new theme by merging overrides into this theme.\n * Uses deep merge with array replacement strategy.\n *\n * @param overrides - Partial theme object with values to override\n * @returns A new ThemeObject with the merged values\n *\n * @example\n * const custom = matrix.extend({\n * colors: { primary: '#ff0066' }\n * })\n *\n * @example\n * // Chained extensions\n * const custom = matrix\n * .extend({ colors: { primary: '#ff0066' } })\n * .extend({ animations: { revealSpeed: 0.5 } })\n */\n extend(overrides: PartialTheme): ThemeObject\n}\n\n/**\n * Create a ThemeObject from validated Theme and overrides.\n * Internal helper that merges themes and adds the extend() method.\n *\n * @param base - A validated Theme object\n * @param overrides - Partial theme with values to override\n * @returns A ThemeObject with extension capability\n */\nexport function createThemeFromMerge(base: Theme, overrides: PartialTheme): ThemeObject {\n // Deep merge, with overrides taking precedence\n const merged = deepmerge(base, overrides, {\n // Arrays should be replaced, not concatenated\n arrayMerge: (_, source) => source,\n }) as Theme\n\n // Re-validate the merged result\n const validated = safeParse(ThemeSchema, merged, 'merged theme')\n\n return {\n ...validated,\n extend(newOverrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, newOverrides)\n },\n }\n}\n\n/**\n * Create a theme from a YAML string.\n * Parses the YAML, validates it against ThemeSchema, and returns a ThemeObject\n * with extension capability.\n *\n * @param yaml - The YAML string containing the theme definition\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the YAML syntax is invalid\n * @throws {ValidationError} If the parsed data doesn't match ThemeSchema\n *\n * @example\n * const theme = createTheme(`\n * name: custom\n * colors:\n * primary: \"#ff0066\"\n * accent: \"#00ff66\"\n * background: \"#000000\"\n * text: \"#ffffff\"\n * muted: \"#666666\"\n * gradients:\n * main:\n * - \"#ff0066\"\n * - \"#00ff66\"\n * glyphs: \"0123456789ABCDEF\"\n * animations:\n * revealSpeed: 1.0\n * matrixDensity: 30\n * glitchIterations: 3\n * lineDelay: 20\n * matrixInterval: 100\n * `)\n */\nexport function createTheme(yaml: string): ThemeObject {\n const parsed = parseYaml(yaml)\n const validated = safeParse(ThemeSchema, parsed, 'theme')\n\n return {\n ...validated,\n extend(overrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, overrides)\n },\n }\n}\n\n// Re-export commonly used functions for convenience\nexport { ThemeError, formatThemeError } from './theme-errors'\nexport {\n createGradients,\n applyGradient,\n resolveColorToken,\n colorTokensToBlessedTags,\n BUILTIN_COLORS,\n} from './theme-colors'\nexport type { GradientFunction } from './theme-colors'\n","import { mermaidToAscii as convertMermaid } from 'mermaid-ascii'\n\n/**\n * Pattern to match mermaid code blocks in markdown content.\n * Captures the diagram code inside the block.\n *\n * Matches: ```mermaid\\n<content>```\n * Group 1: The mermaid diagram code\n */\nconst MERMAID_BLOCK_PATTERN = /```mermaid\\n([\\s\\S]*?)```/g\n\n/**\n * Check if content contains mermaid diagrams.\n *\n * @param content - The markdown content to check\n * @returns true if the content contains at least one mermaid code block\n */\nexport function hasMermaidDiagrams(content: string): boolean {\n // Reset pattern since we use global flag\n MERMAID_BLOCK_PATTERN.lastIndex = 0\n return MERMAID_BLOCK_PATTERN.test(content)\n}\n\n/**\n * Extract all mermaid blocks from content.\n *\n * Finds all mermaid code blocks and extracts the diagram code\n * (without the ```mermaid and ``` delimiters).\n *\n * @param content - The markdown content to search\n * @returns Array of mermaid diagram code strings (trimmed)\n */\nexport function extractMermaidBlocks(content: string): string[] {\n const blocks: string[] = []\n let match: RegExpExecArray | null\n\n // Reset pattern before use\n MERMAID_BLOCK_PATTERN.lastIndex = 0\n\n while ((match = MERMAID_BLOCK_PATTERN.exec(content)) !== null) {\n blocks.push(match[1].trim())\n }\n\n return blocks\n}\n\n/**\n * Format a mermaid parsing error as ASCII.\n *\n * Creates a visually recognizable error block showing the\n * first few lines of the diagram with a border.\n *\n * @param code - The mermaid diagram code that failed to parse\n * @param _error - The error that occurred (unused but kept for signature)\n * @returns ASCII art error block\n */\nexport function formatMermaidError(code: string, _error: unknown): string {\n const lines = [\n '┌─ Diagram (parse error) ─┐',\n '│ │',\n ]\n\n // Show first few lines of the diagram\n const codeLines = code.split('\\n').slice(0, 5)\n for (const line of codeLines) {\n const truncated = line.slice(0, 23).padEnd(23)\n lines.push(`│ ${truncated} │`)\n }\n\n if (code.split('\\n').length > 5) {\n lines.push('│ ... │')\n }\n\n lines.push('│ │')\n lines.push('└─────────────────────────┘')\n\n return lines.join('\\n')\n}\n\n/**\n * Convert mermaid diagram to ASCII art.\n *\n * Uses the mermaid-ascii library to convert mermaid diagram\n * syntax to ASCII art representation. Falls back to an error\n * block if parsing fails.\n *\n * @param mermaidCode - Raw mermaid diagram code\n * @returns ASCII art representation or error block\n */\nexport function mermaidToAscii(mermaidCode: string): string {\n try {\n return convertMermaid(mermaidCode)\n } catch (error) {\n // If parsing fails, return a formatted error block\n return formatMermaidError(mermaidCode, error)\n }\n}\n\n/**\n * Escape special regex characters in a string.\n *\n * @param str - String to escape\n * @returns Escaped string safe for use in RegExp\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Process all mermaid blocks in slide content.\n *\n * Finds all mermaid code blocks in the content and replaces them\n * with their ASCII art representation.\n *\n * @param content - The slide content potentially containing mermaid blocks\n * @returns Content with mermaid blocks replaced by ASCII art\n */\nexport function processMermaidDiagrams(content: string): string {\n if (!hasMermaidDiagrams(content)) {\n return content\n }\n\n // Find all blocks and convert\n let result = content\n const blocks = extractMermaidBlocks(content)\n\n for (const block of blocks) {\n const ascii = mermaidToAscii(block)\n\n // Replace mermaid block with ASCII\n // The pattern matches the code block including newlines\n result = result.replace(\n new RegExp('```mermaid\\\\n' + escapeRegex(block) + '\\\\n?```', 'g'),\n ascii\n )\n }\n\n return result\n}\n","/**\n * Content Processing Module\n *\n * Responsible for processing slide content through various transformations:\n * - Mermaid diagram conversion\n * - Color token resolution\n * - Text normalization\n *\n * This module follows the Single Responsibility Principle by focusing\n * solely on content transformation, separate from parsing and loading logic.\n */\n\nimport type { Theme } from '../schemas/theme.js'\nimport { colorTokensToBlessedTags } from './theme.js'\nimport { processMermaidDiagrams } from './utils/mermaid.js'\n\n/**\n * Process slide body content.\n *\n * Applies the full content processing pipeline:\n * 1. Process mermaid diagrams (convert to ASCII)\n * 2. Apply color tokens (convert to blessed tags)\n *\n * The order is important: mermaid diagrams are processed first so that\n * any color tokens they might contain are then converted to blessed tags.\n *\n * @param body - The slide body content to process\n * @param theme - The theme to use for color token resolution\n * @returns Processed content with mermaid converted and color tokens applied\n *\n * @example\n * const processed = await processSlideContent(\n * '{GREEN}Hello{/}\\n\\n```mermaid\\ngraph LR\\nA-->B\\n```',\n * theme\n * )\n * // Returns: '{#00cc66-fg}Hello{/}\\n\\n<ascii art>'\n */\nexport async function processSlideContent(\n body: string,\n theme: Theme\n): Promise<string> {\n // Process mermaid diagrams first\n let processed = processMermaidDiagrams(body)\n\n // Apply color tokens\n processed = colorTokensToBlessedTags(processed, theme)\n\n return processed\n}\n\n/**\n * Normalize bigText to array.\n *\n * Converts the bigText frontmatter field to a consistent array format\n * for use by the renderer. Handles:\n * - undefined → empty array\n * - string → single-element array\n * - string[] → pass through unchanged\n *\n * @param bigText - The bigText value from slide frontmatter\n * @returns Array of strings for rendering\n *\n * @example\n * normalizeBigText(undefined) // []\n * normalizeBigText('HELLO') // ['HELLO']\n * normalizeBigText(['A', 'B']) // ['A', 'B']\n */\nexport function normalizeBigText(bigText: string | string[] | undefined): string[] {\n if (!bigText) return []\n return Array.isArray(bigText) ? bigText : [bigText]\n}\n","/**\n * Characters used for glitch effect (avoiding box drawing).\n * These characters create a cyberpunk glitch aesthetic when scrambling text.\n * Includes: block characters, shapes, math symbols, Greek letters, and katakana.\n */\nexport const GLITCH_CHARS =\n '█▓▒░▀▄▌▐■□▪▫●○◊◘◙♦♣♠♥★☆⌂ⁿ²³ÆØ∞≈≠±×÷αβγδεζηθλμπσφωΔΣΩアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン'\n\n/**\n * Characters to never glitch.\n * Protects structural characters like spaces, punctuation, box drawing,\n * and arrows to maintain readability and layout integrity during glitch effects.\n */\nexport const PROTECTED_CHARS = new Set([\n ' ', '\\t', '\\n', '{', '}', '-', '/', '#', '[', ']', '(', ')', ':', ';',\n ',', '.', '!', '?', \"'\", '\"', '`', '_', '|', '\\\\', '<', '>', '=', '+',\n '*', '&', '^', '%', '$', '@', '~',\n // Box drawing\n '┌', '┐', '└', '┘', '│', '─', '├', '┤', '┬', '┴', '┼', '═', '║',\n '╔', '╗', '╚', '╝', '╠', '╣', '╦', '╩', '╬', '╭', '╮', '╯', '╰',\n // Arrows\n '→', '←', '↑', '↓', '▶', '◀', '▲', '▼', '►', '◄',\n])\n","import type blessed from 'neo-blessed'\n\n/**\n * Sleep helper for async animations.\n * Returns a promise that resolves after the specified delay.\n *\n * @param ms - Delay in milliseconds\n * @returns Promise that resolves after the delay\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Renders content to a blessed box and updates the screen.\n * Utility function to reduce code duplication across transitions.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The content string to render\n */\nexport function renderContent(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string\n): void {\n box.setContent(content)\n screen.render()\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { GLITCH_CHARS, PROTECTED_CHARS } from '../constants.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Glitch-reveal a single line of text.\n * Animates the transition from scrambled characters to the final text.\n * The scramble ratio decreases with each iteration, gradually revealing the text.\n * Protected characters (spaces, punctuation, box drawing) are never scrambled.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param currentLines - Array of already-revealed lines\n * @param newLine - The new line to glitch-reveal\n * @param iterations - Number of glitch iterations (default: 5)\n */\nexport async function glitchLine(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n currentLines: string[],\n newLine: string,\n iterations: number = 5\n): Promise<void> {\n for (let i = iterations; i >= 0; i--) {\n const scrambleRatio = i / iterations\n let scrambledLine = ''\n\n for (const char of newLine) {\n if (PROTECTED_CHARS.has(char)) {\n scrambledLine += char\n } else if (Math.random() < scrambleRatio) {\n scrambledLine += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)]\n } else {\n scrambledLine += char\n }\n }\n\n renderContent(box, screen, [...currentLines, scrambledLine].join('\\n'))\n await sleep(20)\n }\n}\n\n/**\n * Reveal content line by line with glitch effect.\n * Animates the transition of multi-line content by revealing each line\n * sequentially with a glitch effect. Uses theme-configured line delay\n * and glitch iteration count for consistent animation timing.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string (with newlines)\n * @param theme - Theme configuration for animation timing\n */\nexport async function lineByLineReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const lines = content.split('\\n')\n const revealedLines: string[] = []\n const lineDelay = theme.animations.lineDelay\n const glitchIterations = theme.animations.glitchIterations\n\n for (const line of lines) {\n await glitchLine(box, screen, revealedLines, line, glitchIterations)\n revealedLines.push(line)\n renderContent(box, screen, revealedLines.join('\\n'))\n\n // Delay between lines (skip for empty lines)\n if (line.trim()) {\n await sleep(lineDelay)\n }\n }\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { PROTECTED_CHARS } from '../constants.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Fade-in reveal (character by character, all at once).\n * Gradually reveals characters randomly across the entire content\n * to create a fade-in effect. Uses multiple steps with increasing\n * reveal probability for a smooth animation.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param theme - Theme configuration for animation timing\n */\nexport async function fadeInReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const steps = 10\n const delay = (theme.animations.lineDelay * 2) / steps\n\n for (let step = 0; step < steps; step++) {\n const revealRatio = step / steps\n let revealed = ''\n\n for (const char of content) {\n if (char === '\\n' || PROTECTED_CHARS.has(char) || Math.random() < revealRatio) {\n revealed += char\n } else {\n revealed += ' '\n }\n }\n\n renderContent(box, screen, revealed)\n await sleep(delay)\n }\n\n renderContent(box, screen, content)\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../../schemas/theme.js'\nimport { sleep, renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Typewriter reveal (character by character, sequentially).\n * Reveals content character by character in order, like a typewriter.\n * Skips delay for spaces and newlines to maintain smooth flow.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param theme - Theme configuration for animation timing\n */\nexport async function typewriterReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n theme: Theme\n): Promise<void> {\n const charDelay = theme.animations.lineDelay / 5\n let revealed = ''\n\n for (const char of content) {\n revealed += char\n renderContent(box, screen, revealed)\n\n if (char !== ' ' && char !== '\\n') {\n await sleep(charDelay)\n }\n }\n}\n","import type blessed from 'neo-blessed'\nimport { renderContent } from '../helpers/animation-utils.js'\n\n/**\n * Instant reveal (no animation).\n * Immediately displays the content without any transition effect.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n */\nexport function instantReveal(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string\n): void {\n renderContent(box, screen, content)\n}\n","import type blessed from 'neo-blessed'\nimport type { Theme } from '../../schemas/theme.js'\nimport { lineByLineReveal } from './transitions/glitch-transition.js'\nimport { fadeInReveal } from './transitions/fade-transition.js'\nimport { typewriterReveal } from './transitions/typewriter-transition.js'\nimport { instantReveal } from './transitions/instant-transition.js'\n\n/**\n * Transition type for slide animations.\n * Defines the available transition effects for revealing slide content.\n */\nexport type TransitionType = 'glitch' | 'fade' | 'instant' | 'typewriter'\n\n/**\n * Apply transition effect to reveal content.\n * Dispatcher function that selects and applies the appropriate\n * transition animation based on the specified transition type.\n *\n * @param box - The blessed box element to render into\n * @param screen - The blessed screen for rendering\n * @param content - The complete content string to reveal\n * @param transition - The type of transition effect to apply\n * @param theme - Theme configuration for animation timing\n */\nexport async function applyTransition(\n box: blessed.Widgets.BoxElement,\n screen: blessed.Widgets.Screen,\n content: string,\n transition: TransitionType,\n theme: Theme\n): Promise<void> {\n switch (transition) {\n case 'glitch':\n await lineByLineReveal(box, screen, content, theme)\n break\n\n case 'fade':\n await fadeInReveal(box, screen, content, theme)\n break\n\n case 'instant':\n instantReveal(box, screen, content)\n break\n\n case 'typewriter':\n await typewriterReveal(box, screen, content, theme)\n break\n\n default:\n instantReveal(box, screen, content)\n }\n}\n","/**\n * Transition animations module.\n * This module provides a clean interface for slide transition effects.\n *\n * The transitions have been refactored into focused, modular files:\n * - transition-orchestrator.ts: Main dispatcher and type definitions\n * - transitions/glitch-transition.ts: Glitch effect implementation\n * - transitions/fade-transition.ts: Fade effect implementation\n * - transitions/typewriter-transition.ts: Typewriter effect implementation\n * - transitions/instant-transition.ts: Instant (no animation) implementation\n * - helpers/animation-utils.ts: Shared animation utilities\n */\n\n// Re-export the main transition orchestrator\nexport { applyTransition, type TransitionType } from './transition-orchestrator.js'\n\n// Re-export individual transitions for direct use if needed\nexport { glitchLine, lineByLineReveal } from './transitions/glitch-transition.js'\nexport { fadeInReveal } from './transitions/fade-transition.js'\nexport { typewriterReveal } from './transitions/typewriter-transition.js'\nexport { instantReveal } from './transitions/instant-transition.js'\n","import figlet from 'figlet'\nimport gradient from 'gradient-string'\n\n/**\n * Generate ASCII art text with gradient.\n * Uses figlet to convert text to ASCII art and applies a gradient color effect.\n * This function is asynchronous because figlet uses a callback-based API.\n *\n * @param text - The text to convert to ASCII art\n * @param gradientColors - Array of hex colors for the gradient effect\n * @param font - Figlet font to use (defaults to 'Standard')\n * @returns Promise resolving to the gradient-colored ASCII art text\n */\nexport async function generateBigText(\n text: string,\n gradientColors: string[],\n font: string = 'Standard'\n): Promise<string> {\n return new Promise((resolve, reject) => {\n figlet.text(text, { font }, (err, result) => {\n if (err || !result) {\n reject(err ?? new Error('Failed to generate figlet text'))\n return\n }\n\n // Apply gradient\n const gradientFn = gradient(gradientColors)\n resolve(gradientFn(result))\n })\n })\n}\n\n/**\n * Generate multi-line big text (for arrays like ['SPEC', 'MACHINE']).\n * Creates ASCII art for each line separately and joins them with newlines.\n * Each line gets the same gradient applied independently.\n *\n * @param lines - Array of text strings to convert to ASCII art\n * @param gradientColors - Array of hex colors for the gradient effect\n * @param font - Figlet font to use (defaults to 'Standard')\n * @returns Promise resolving to the combined gradient-colored ASCII art\n */\nexport async function generateMultiLineBigText(\n lines: string[],\n gradientColors: string[],\n font: string = 'Standard'\n): Promise<string> {\n const results = await Promise.all(\n lines.map((line) => generateBigText(line, gradientColors, font))\n )\n return results.join('\\n')\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\nimport type { Slide } from '../schemas/slide.js'\nimport { normalizeBigText, processSlideContent } from '../core/content-processor.js'\nimport { applyTransition } from './animations/transitions.js'\nimport { generateMultiLineBigText } from './text-generator.js'\nimport { createWindow } from './window-manager.js'\n\n/**\n * Rendered slide content.\n * Structured content ready for display in a window.\n */\nexport interface RenderedContent {\n /** ASCII art big text (from figlet) */\n bigText?: string\n /** Main body content */\n body: string\n /** Mermaid diagram converted to ASCII */\n diagram?: string\n}\n\n/**\n * Render a slide to a window.\n * Creates a window, generates bigText if present, processes the body content,\n * and applies the specified transition effect to reveal the slide.\n *\n * @param screen - The blessed screen instance\n * @param windowStack - Stack of existing windows\n * @param theme - Active theme for rendering\n * @param slide - The slide to render\n * @returns The created window box element containing the rendered slide\n */\nexport async function renderSlide(\n screen: blessed.Widgets.Screen,\n windowStack: blessed.Widgets.BoxElement[],\n theme: Theme,\n slide: Slide\n): Promise<blessed.Widgets.BoxElement> {\n const { frontmatter, body } = slide\n\n // Create window\n const window = createWindow(screen, windowStack, theme, {\n title: frontmatter.title,\n })\n\n // Build content\n let content = ''\n\n // Big text (figlet)\n const bigTextLines = normalizeBigText(frontmatter.bigText)\n if (bigTextLines.length > 0) {\n const gradientName = frontmatter.gradient ?? 'fire'\n const gradientColors = theme.gradients[gradientName] ?? theme.gradients.fire\n\n const bigText = await generateMultiLineBigText(bigTextLines, gradientColors)\n content += bigText + '\\n\\n'\n }\n\n // Process body content (color tokens, mermaid)\n const processedBody = await processSlideContent(body, theme)\n content += processedBody\n\n // Apply transition\n const transition = frontmatter.transition ?? 'glitch'\n await applyTransition(window, screen, content, transition, theme)\n\n return window\n}\n","import blessed from 'neo-blessed'\nimport type { Theme } from '../schemas/theme.js'\nimport type { Slide } from '../schemas/slide.js'\nimport {\n type MatrixRainState,\n createMatrixBox,\n initMatrixRain,\n stopMatrixRain,\n} from './effects/matrix-rain.js'\nimport { type TransitionType } from './animations/transitions.js'\nimport {\n createWindow as createWindowInternal,\n clearWindows as clearWindowsInternal,\n type WindowOptions,\n} from './window-manager.js'\nimport { renderSlide as renderSlideInternal } from './slide-renderer.js'\nimport { generateBigText, generateMultiLineBigText } from './text-generator.js'\n\n// Re-export for backwards compatibility\nexport { type TransitionType, applyTransition } from './animations/transitions.js'\nexport { type WindowOptions, getWindowColor } from './window-manager.js'\nexport { generateBigText, generateMultiLineBigText } from './text-generator.js'\nexport { type RenderedContent } from './slide-renderer.js'\n\n/**\n * Main renderer state.\n * Manages the blessed screen, matrix rain background, window stack, and theme.\n */\nexport interface Renderer {\n /** The blessed screen instance */\n screen: blessed.Widgets.Screen\n /** Stack of window elements (slides render on top of each other) */\n windowStack: blessed.Widgets.BoxElement[]\n /** Active theme for rendering */\n theme: Theme\n /** Matrix rain animation state */\n matrixRain: MatrixRainState\n}\n\n/**\n * Create the main blessed screen.\n * Configures the screen with optimal settings for presentation:\n * - smartCSR: Enables smart cursor movement for efficient rendering\n * - fullUnicode: Enables full unicode support for glyphs\n * - altScreen: Uses alternate screen buffer (preserves terminal on exit)\n * - mouse: Disabled (keyboard-only navigation)\n *\n * @param title - Window title (defaults to 'term-deck')\n * @returns Configured blessed screen instance\n */\nexport function createScreen(title: string = 'term-deck'): blessed.Widgets.Screen {\n const screen = blessed.screen({\n smartCSR: true,\n title,\n fullUnicode: true,\n mouse: false,\n altScreen: true,\n })\n\n return screen\n}\n\n\n/**\n * Create the renderer with all components.\n * Initializes the blessed screen, matrix rain background box,\n * empty window stack, and starts the matrix rain animation.\n *\n * @param theme - Theme configuration for rendering\n * @returns Fully initialized Renderer instance\n */\nexport function createRenderer(theme: Theme): Renderer {\n const screen = createScreen()\n\n // Create matrix background box covering full screen\n const matrixBox = createMatrixBox(screen)\n\n const matrixRain: MatrixRainState = {\n matrixBox,\n matrixDrops: [],\n matrixInterval: null,\n theme,\n }\n\n const renderer: Renderer = {\n screen,\n windowStack: [],\n theme,\n matrixRain,\n }\n\n // Initialize matrix rain\n initMatrixRain(screen, matrixRain)\n\n return renderer\n}\n\n/**\n * Destroy renderer and cleanup resources.\n * Stops the matrix rain animation, destroys all windows in the stack,\n * and destroys the blessed screen to restore the terminal.\n *\n * @param renderer - The renderer instance to destroy\n */\nexport function destroyRenderer(renderer: Renderer): void {\n // Stop matrix rain animation\n stopMatrixRain(renderer.matrixRain)\n\n // Clear all windows\n clearWindowsInternal(renderer.windowStack)\n\n // Destroy the screen (restores terminal)\n renderer.screen.destroy()\n}\n\n/**\n * Create a slide window with stacking effect.\n * Creates a bordered box element with theme-based styling,\n * random position for stacking effect, and adds it to the window stack.\n *\n * @param renderer - The renderer instance\n * @param options - Window configuration options\n * @returns The created window box element\n */\nexport function createWindow(\n renderer: Renderer,\n options: WindowOptions\n): blessed.Widgets.BoxElement {\n return createWindowInternal(renderer.screen, renderer.windowStack, renderer.theme, options)\n}\n\n/**\n * Clear all windows from stack.\n * Destroys all window elements in the stack and resets the stack to empty.\n * This is typically called when transitioning between slides.\n *\n * @param renderer - The renderer instance containing the window stack\n */\nexport function clearWindows(renderer: Renderer): void {\n clearWindowsInternal(renderer.windowStack)\n}\n\n/**\n * Render a slide to a window.\n * Creates a window, generates bigText if present, processes the body content,\n * and applies the specified transition effect to reveal the slide.\n *\n * @param renderer - The renderer instance\n * @param slide - The slide to render\n * @returns The created window box element containing the rendered slide\n */\nexport async function renderSlide(\n renderer: Renderer,\n slide: Slide\n): Promise<blessed.Widgets.BoxElement> {\n return renderSlideInternal(renderer.screen, renderer.windowStack, renderer.theme, slide)\n}\n","import blessed from 'neo-blessed';\nimport { access } from 'fs/promises';\nimport type { Slide } from '../schemas/slide.js';\n\n/**\n * Notes window state (separate terminal)\n *\n * Represents a secondary display on a different TTY for presenter notes.\n * Shows current slide notes, slide number, and preview of next slide.\n */\nexport interface NotesWindow {\n screen: blessed.Widgets.Screen;\n contentBox: blessed.Widgets.BoxElement;\n tty: string; // TTY device path (e.g., '/dev/tty2')\n}\n\n/**\n * Find an available TTY for notes window\n *\n * This is a best-effort approach - user should specify with --notes-tty.\n * Searches common TTY paths on macOS and Linux.\n *\n * @returns Promise resolving to an available TTY path\n * @throws Error if no available TTY is found\n */\nasync function findAvailableTty(): Promise<string> {\n const candidates = [\n '/dev/ttys001',\n '/dev/ttys002',\n '/dev/ttys003',\n '/dev/pts/1',\n '/dev/pts/2',\n ];\n\n for (const tty of candidates) {\n try {\n await access(tty);\n return tty;\n } catch {\n // Continue to next candidate\n }\n }\n\n throw new Error(\n 'Could not find available TTY for notes window. ' +\n 'Open a second terminal, run `tty`, and pass the path with --notes-tty'\n );\n}\n\n/**\n * Create notes window on a separate TTY\n *\n * Creates a blessed screen on a different TTY device for displaying presenter notes.\n * If no TTY is specified, attempts to find one automatically.\n *\n * Usage: Open a second terminal and run `tty` to get the device path,\n * then pass it with --notes-tty /dev/ttys001\n *\n * @param ttyPath - Optional TTY device path (e.g., '/dev/ttys001')\n * @returns Promise resolving to the created notes window\n *\n * @example\n * ```typescript\n * // With explicit TTY path\n * const notesWindow = await createNotesWindow('/dev/ttys001');\n *\n * // Auto-detect TTY\n * const notesWindow = await createNotesWindow();\n * ```\n */\nexport async function createNotesWindow(ttyPath?: string): Promise<NotesWindow> {\n const blessed = (await import('neo-blessed')).default;\n const { openSync } = await import('node:fs');\n\n const tty = ttyPath ?? await findAvailableTty();\n\n const screen = blessed.screen({\n smartCSR: true,\n title: 'term-deck notes',\n fullUnicode: true,\n input: openSync(tty, 'r'),\n output: openSync(tty, 'w'),\n });\n\n const contentBox = blessed.box({\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n tags: true,\n padding: 2,\n style: {\n fg: '#ffffff',\n bg: '#1a1a1a',\n },\n });\n\n screen.append(contentBox);\n screen.render();\n\n return {\n screen,\n contentBox,\n tty,\n };\n}\n\n/**\n * Update notes window content for current slide\n *\n * Updates the notes window to display:\n * - Current slide number and title\n * - Presenter notes (or \"No notes\" if none exist)\n * - Preview of next slide title (or \"Last slide\" if at end)\n *\n * @param notesWindow - The notes window to update\n * @param currentSlide - The current slide being displayed\n * @param nextSlide - The next slide (if any)\n * @param currentIndex - Current slide index (0-based)\n * @param totalSlides - Total number of slides in the deck\n */\nexport function updateNotesWindow(\n notesWindow: NotesWindow,\n currentSlide: Slide,\n nextSlide: Slide | undefined,\n currentIndex: number,\n totalSlides: number\n): void {\n const { contentBox, screen } = notesWindow;\n\n let content = '';\n\n // Header\n content += `{bold}Slide ${currentIndex + 1} of ${totalSlides}{/bold}\\n`;\n content += `{gray-fg}${currentSlide.frontmatter.title}{/}\\n`;\n content += '\\n';\n content += '─'.repeat(50) + '\\n';\n content += '\\n';\n\n // Notes\n if (currentSlide.notes) {\n content += '{bold}PRESENTER NOTES:{/bold}\\n\\n';\n content += currentSlide.notes + '\\n';\n } else {\n content += '{gray-fg}No notes for this slide{/}\\n';\n }\n\n content += '\\n';\n content += '─'.repeat(50) + '\\n';\n content += '\\n';\n\n // Next slide preview\n if (nextSlide) {\n content += `{bold}NEXT:{/bold} \"${nextSlide.frontmatter.title}\"\\n`;\n } else {\n content += '{gray-fg}Last slide{/}\\n';\n }\n\n contentBox.setContent(content);\n screen.render();\n}\n\n/**\n * Toggle notes window visibility\n *\n * Toggles the visibility of the notes window between shown and hidden.\n *\n * @param notesWindow - The notes window to toggle\n */\nexport function toggleNotesVisibility(notesWindow: NotesWindow): void {\n const { contentBox, screen } = notesWindow;\n contentBox.toggle();\n screen.render();\n}\n\n/**\n * Destroy notes window and free resources\n *\n * @param notesWindow - The notes window to destroy\n */\nexport function destroyNotesWindow(notesWindow: NotesWindow): void {\n notesWindow.screen.destroy();\n}\n","import blessed from 'neo-blessed';\nimport type { Presenter } from './types.js';\nimport { renderSlide, clearWindows } from '../renderer/screen.js';\nimport { updateNotesWindow } from './notes-window.js';\n\n/**\n * Show a specific slide\n *\n * Renders the specified slide index and updates notes/progress.\n * Respects the isAnimating flag to prevent concurrent transitions.\n *\n * @param presenter - The presenter state\n * @param index - The slide index to show (0-based)\n */\nexport async function showSlide(presenter: Presenter, index: number): Promise<void> {\n if (presenter.isAnimating) return;\n if (index < 0 || index >= presenter.deck.slides.length) return;\n\n presenter.isAnimating = true;\n presenter.currentSlide = index;\n\n const slide = presenter.deck.slides[index];\n\n // Render slide\n await renderSlide(presenter.renderer, slide);\n presenter.renderer.screen.render();\n\n // Update notes window\n if (presenter.notesWindow) {\n const nextSlide = presenter.deck.slides[index + 1];\n updateNotesWindow(\n presenter.notesWindow,\n slide,\n nextSlide,\n index,\n presenter.deck.slides.length\n );\n }\n\n // Update progress bar\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, presenter.currentSlide, presenter.deck.slides.length);\n }\n\n presenter.isAnimating = false;\n}\n\n/**\n * Go to next slide\n *\n * Advances to the next slide in the deck. If at the last slide:\n * - If loop is enabled, wraps to first slide\n * - If loop is disabled, stays on last slide\n *\n * @param presenter - The presenter state\n */\nexport async function nextSlide(presenter: Presenter): Promise<void> {\n const nextIndex = presenter.currentSlide + 1;\n const { slides } = presenter.deck;\n const loop = presenter.deck.config.settings?.loop ?? false;\n\n if (nextIndex >= slides.length) {\n if (loop) {\n await showSlide(presenter, 0);\n }\n return;\n }\n\n await showSlide(presenter, nextIndex);\n}\n\n/**\n * Go to previous slide\n *\n * Goes back to the previous slide in the deck. If at the first slide:\n * - If loop is enabled, wraps to last slide\n * - If loop is disabled, stays on first slide\n *\n * To maintain the stacked window effect, this function clears all windows\n * and re-renders all slides from 0 up to the target slide.\n *\n * @param presenter - The presenter state\n */\nexport async function prevSlide(presenter: Presenter): Promise<void> {\n const prevIndex = presenter.currentSlide - 1;\n const { slides } = presenter.deck;\n const loop = presenter.deck.config.settings?.loop ?? false;\n\n if (prevIndex < 0) {\n if (loop) {\n // Clear and re-render all slides up to the last one\n clearWindows(presenter.renderer);\n for (let i = 0; i < slides.length; i++) {\n await renderSlide(presenter.renderer, slides[i]);\n }\n presenter.currentSlide = slides.length - 1;\n\n updateUIComponents(presenter, slides.length - 1);\n presenter.renderer.screen.render();\n }\n // If not looping, stay at current slide (index 0)\n return;\n }\n\n // Clear windows and re-render from start up to prevIndex\n clearWindows(presenter.renderer);\n for (let i = 0; i <= prevIndex; i++) {\n await renderSlide(presenter.renderer, slides[i]);\n }\n\n presenter.currentSlide = prevIndex;\n\n updateUIComponents(presenter, prevIndex);\n presenter.renderer.screen.render();\n}\n\n/**\n * Jump to a specific slide by index\n *\n * Jumps directly to the specified slide index. To maintain the stacked window\n * effect, this function clears all windows and re-renders all slides from 0\n * up to the target slide.\n *\n * Invalid indices (negative or beyond deck length) are ignored.\n *\n * @param presenter - The presenter state\n * @param index - The slide index to jump to (0-based)\n */\nexport async function jumpToSlide(presenter: Presenter, index: number): Promise<void> {\n // Check bounds - ignore invalid indices\n if (index < 0 || index >= presenter.deck.slides.length) return;\n\n // Clear all windows to prepare for re-rendering\n clearWindows(presenter.renderer);\n\n // Re-render slides 0 through target index to preserve stacking\n for (let i = 0; i <= index; i++) {\n await renderSlide(presenter.renderer, presenter.deck.slides[i]);\n }\n\n presenter.currentSlide = index;\n\n updateUIComponents(presenter, index);\n presenter.renderer.screen.render();\n}\n\n/**\n * Update progress bar\n *\n * Updates the progress bar to reflect the current slide position.\n * Progress is calculated as (current + 1) / total * 100.\n *\n * @param progressBar - The progress bar element to update\n * @param current - Current slide index (0-based)\n * @param total - Total number of slides\n */\nexport function updateProgress(\n progressBar: blessed.Widgets.ProgressBarElement,\n current: number,\n total: number\n): void {\n const progress = ((current + 1) / total) * 100;\n progressBar.setProgress(progress);\n}\n\n/**\n * Update UI components after slide change\n *\n * Updates the notes window and progress bar to reflect the current slide.\n * This centralizes the UI update logic used by navigation functions.\n *\n * @param presenter - The presenter state\n * @param currentIndex - Current slide index (0-based)\n */\nfunction updateUIComponents(presenter: Presenter, currentIndex: number): void {\n const { slides } = presenter.deck;\n const currentSlide = slides[currentIndex];\n const nextSlide = slides[currentIndex + 1];\n\n if (presenter.notesWindow) {\n updateNotesWindow(\n presenter.notesWindow,\n currentSlide,\n nextSlide,\n currentIndex,\n slides.length\n );\n }\n\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, currentIndex, slides.length);\n }\n}\n","import type { Presenter } from './types.js';\nimport { nextSlide, prevSlide, jumpToSlide } from './navigation.js';\nimport { toggleNotesVisibility } from './notes-window.js';\n\n/**\n * Setup keyboard event handlers\n *\n * Registers all keyboard controls for the presentation:\n * - Next slide: Space, Enter, Right, n\n * - Previous slide: Left, Backspace, p\n * - Jump to slide: 0-9\n * - Show slide list: l\n * - Toggle notes visibility: N\n * - Quit: q, Ctrl+C, Escape (handled in present() function)\n *\n * @param presenter - The presenter state\n */\nexport function setupControls(presenter: Presenter): void {\n const { screen } = presenter.renderer;\n\n // Next slide: Space, Enter, Right, n\n screen.key(['space', 'enter', 'right', 'n'], () => {\n nextSlide(presenter);\n });\n\n // Previous slide: Left, Backspace, p\n screen.key(['left', 'backspace', 'p'], () => {\n prevSlide(presenter);\n });\n\n // Jump to slide: 0-9\n screen.key(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], (ch) => {\n const index = parseInt(ch, 10);\n jumpToSlide(presenter, index);\n });\n\n // Show slide list: l\n screen.key(['l'], () => {\n showSlideList(presenter);\n });\n\n // Toggle notes visibility: N (only if notes window exists)\n screen.key(['N'], () => {\n if (presenter.notesWindow) {\n toggleNotesVisibility(presenter.notesWindow);\n }\n });\n\n // Note: quit keys (q, Ctrl+C, Escape) are handled in the present() function\n}\n\n/**\n * Show slide list overlay\n *\n * Displays an overlay showing all slides in the deck with the current slide marked.\n * User can press Escape, l, or q to close, or press a number key to jump to that slide.\n *\n * @param presenter - The presenter state\n */\nfunction showSlideList(presenter: Presenter): void {\n const { screen } = presenter.renderer;\n const { slides } = presenter.deck;\n\n // Build list content with current slide marker\n const listContent = slides\n .map((slide, i) => {\n const marker = i === presenter.currentSlide ? '▶ ' : ' ';\n return `${marker}${i}: ${slide.frontmatter.title}`;\n })\n .join('\\n');\n\n // Create overlay box centered on screen\n const listBox = screen.box({\n top: 'center',\n left: 'center',\n width: 50,\n height: Math.min(slides.length + 4, 20),\n border: { type: 'line' },\n label: ' SLIDES (press number or Esc) ',\n style: {\n fg: '#ffffff',\n bg: '#0a0a0a',\n border: { fg: '#ffcc00' },\n },\n padding: 1,\n tags: true,\n content: listContent,\n });\n\n screen.append(listBox);\n\n screen.render();\n\n // Close list helper\n const closeList = () => {\n listBox.destroy();\n screen.render();\n };\n\n // Close on Escape, l, or q\n screen.onceKey(['escape', 'l', 'q'], closeList);\n\n // Number keys jump to slide and close\n screen.onceKey(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], (ch) => {\n closeList();\n jumpToSlide(presenter, parseInt(ch ?? '0', 10));\n });\n}\n","import blessed from 'neo-blessed';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer } from '../renderer/screen.js';\nimport { createNotesWindow, destroyNotesWindow } from './notes-window.js';\nimport { setupControls } from './keyboard-controls.js';\nimport { showSlide, nextSlide, updateProgress } from './navigation.js';\nimport type { Presenter, PresentOptions } from './types.js';\n\nexport type { Presenter, PresentOptions };\n\n// Re-export navigation functions for backwards compatibility\nexport { jumpToSlide, prevSlide } from './navigation.js';\n\n/**\n * Start a presentation\n *\n * Loads the deck, creates the renderer, sets up keyboard controls,\n * and enters the main presentation loop.\n *\n * @param slidesDir - Directory containing markdown slides and deck.config.ts\n * @param options - Presentation options (startSlide, showNotes, notesTty, loop)\n * @returns Promise that resolves when the presentation ends (user quits)\n *\n * @example\n * ```typescript\n * await present('./slides', { startSlide: 0, showNotes: true });\n * ```\n */\nexport async function present(\n slidesDir: string,\n options: PresentOptions = {}\n): Promise<void> {\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create renderer\n const renderer = createRenderer(deck.config.theme);\n\n // Create presenter state\n const presenter: Presenter = {\n deck,\n renderer,\n currentSlide: options.startSlide ?? deck.config.settings?.startSlide ?? 0,\n isAnimating: false,\n notesWindow: null,\n autoAdvanceTimer: null,\n progressBar: null,\n };\n\n // Setup notes window if requested\n if (options.showNotes) {\n presenter.notesWindow = await createNotesWindow(options.notesTty);\n }\n\n // Setup progress bar if enabled\n if (deck.config.settings?.showProgress) {\n presenter.progressBar = createProgressBar(presenter);\n }\n\n // Setup keyboard controls\n setupControls(presenter);\n\n // Show first slide\n await showSlide(presenter, presenter.currentSlide);\n\n // Update progress bar\n if (presenter.progressBar) {\n updateProgress(presenter.progressBar, presenter.currentSlide, deck.slides.length);\n }\n\n // Start auto-advance if configured\n presenter.autoAdvanceTimer = startAutoAdvance(presenter);\n\n // Keep process alive until quit\n await new Promise<void>((resolve) => {\n renderer.screen.key(['q', 'C-c', 'escape'], () => {\n cleanup(presenter);\n resolve();\n });\n });\n}\n\n/**\n * Cleanup resources\n *\n * Destroys the notes window (if present), stops auto-advance timer,\n * and destroys the main renderer, freeing all resources and restoring the terminal.\n *\n * @param presenter - The presenter state to clean up\n */\nfunction cleanup(presenter: Presenter): void {\n stopAutoAdvance(presenter.autoAdvanceTimer);\n if (presenter.notesWindow) {\n destroyNotesWindow(presenter.notesWindow);\n }\n destroyRenderer(presenter.renderer);\n}\n\n/**\n * Start auto-advance timer\n *\n * Automatically advances to the next slide at a specified interval.\n * Respects the isAnimating flag to avoid advancing during animations.\n * Returns null if auto-advance is disabled (interval <= 0).\n *\n * @param presenter - The presenter state\n * @returns Timer object if auto-advance is enabled, null otherwise\n */\nfunction startAutoAdvance(presenter: Presenter): ReturnType<typeof setInterval> | null {\n const interval = presenter.deck.config.settings?.autoAdvance;\n\n // Auto-advance disabled if interval is undefined, 0, or negative\n if (!interval || interval <= 0) {\n return null;\n }\n\n // Start interval timer\n return setInterval(() => {\n // Only advance if not currently animating\n if (!presenter.isAnimating) {\n nextSlide(presenter);\n }\n }, interval);\n}\n\n/**\n * Stop auto-advance timer\n *\n * Clears the auto-advance interval timer if it exists.\n *\n * @param timer - The timer to stop (can be null)\n */\nfunction stopAutoAdvance(timer: ReturnType<typeof setInterval> | null): void {\n if (timer) {\n clearInterval(timer);\n }\n}\n\n/**\n * Create progress bar at bottom of screen\n *\n * Creates a horizontal progress bar that shows presentation progress.\n * The bar is positioned at the bottom of the screen and fills from left\n * to right as the presentation advances.\n *\n * @param presenter - The presenter state\n * @returns Progress bar element\n */\nfunction createProgressBar(presenter: Presenter): blessed.Widgets.ProgressBarElement {\n const { screen } = presenter.renderer;\n\n const progressBar = blessed.progressbar({\n bottom: 0,\n left: 0,\n width: '100%',\n height: 1,\n style: {\n bg: '#333333',\n bar: { bg: '#00cc66' },\n },\n filled: 0,\n });\n\n screen.append(progressBar);\n\n return progressBar;\n}\n","#!/usr/bin/env node\n/**\n * CLI Entry Point for term-deck\n *\n * Terminal presentation tool with a cyberpunk aesthetic.\n * Provides commands for presenting, exporting, and initializing decks.\n */\n\nimport { Command } from 'commander';\nimport { version } from '../package.json';\nimport { presentCommand } from '../src/cli/commands/present.js';\nimport { exportCommand } from '../src/cli/commands/export.js';\nimport { initCommand } from '../src/cli/commands/init.js';\nimport { handleError } from '../src/cli/errors.js';\n\nconst program = new Command();\n\nprogram\n .name('term-deck')\n .description('Terminal presentation tool with a cyberpunk aesthetic')\n .version(version);\n\n// Register commands\nprogram.addCommand(presentCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(initCommand);\n\n// Default action: present if directory given, else show help\nprogram\n .argument('[dir]', 'Slides directory to present')\n .action(async (dir) => {\n if (dir) {\n // Default action: present the deck\n try {\n const { present } = await import('../src/presenter/main.js');\n await present(dir, {});\n } catch (error) {\n handleError(error);\n }\n } else {\n program.help();\n }\n });\n\nprogram.parse();\n","{\n \"name\": \"@pep/term-deck\",\n \"version\": \"1.0.20\",\n \"description\": \"Terminal presentation tool with a cyberpunk aesthetic\",\n \"type\": \"module\",\n \"bin\": {\n \"term-deck\": \"./dist/bin/term-deck.js\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"scripts\": {\n \"dev\": \"tsx bin/term-deck.ts\",\n \"build\": \"tsup\",\n \"prepublishOnly\": \"pnpm run build\",\n \"test\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"presentation\",\n \"terminal\",\n \"slides\",\n \"cli\",\n \"tui\",\n \"blessed\",\n \"cyberpunk\",\n \"markdown\"\n ],\n \"author\": \"Pepijn Senders\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/PepijnSenders/term-deck.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/PepijnSenders/term-deck/issues\"\n },\n \"homepage\": \"https://github.com/PepijnSenders/term-deck#readme\",\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"files\": [\n \"dist/\",\n \"themes/\",\n \"examples/\",\n \"LICENSE\",\n \"README.md\"\n ],\n \"dependencies\": {\n \"canvas\": \"^3.2.1\",\n \"commander\": \"^14.0.2\",\n \"deepmerge\": \"^4.3.1\",\n \"execa\": \"^9.6.1\",\n \"fast-glob\": \"^3.3.3\",\n \"figlet\": \"^1.9.4\",\n \"gradient-string\": \"^3.0.0\",\n \"gray-matter\": \"^4.0.3\",\n \"mermaid-ascii\": \"^1.0.0\",\n \"neo-blessed\": \"^0.2.0\",\n \"yaml\": \"^2.7.0\",\n \"zod\": \"^3.22.4\"\n },\n \"devDependencies\": {\n \"@types/figlet\": \"^1.5.8\",\n \"@types/node\": \"^22.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^2.1.8\"\n }\n}\n","/**\n * Present Command\n *\n * Starts a presentation with the given options.\n */\n\nimport { Command } from 'commander';\nimport { present } from '../../presenter/main.js';\nimport { handleError } from '../errors.js';\n\nexport const presentCommand = new Command('present')\n .description('Start a presentation')\n .argument('<dir>', 'Slides directory')\n .option('-s, --start <n>', 'Start at slide number', '0')\n .option('-n, --notes', 'Show presenter notes in separate terminal')\n .option('--notes-tty <path>', 'TTY device for notes window (e.g., /dev/ttys001)')\n .option('-l, --loop', 'Loop back to first slide after last')\n .action(async (dir, options) => {\n try {\n await present(dir, {\n startSlide: Number.parseInt(options.start, 10),\n showNotes: options.notes,\n notesTty: options.notesTty,\n loop: options.loop,\n });\n } catch (error) {\n handleError(error);\n }\n });\n","/**\n * CLI Error Handling\n *\n * Provides user-friendly error messages for various error types\n * that can occur during CLI operations.\n */\n\nimport { ValidationError } from '../schemas/validation.js';\nimport { SlideParseError } from '../core/slide.js';\nimport { DeckLoadError } from '../core/deck-loader.js';\nimport { ThemeError } from '../core/theme.js';\n\n/**\n * Handle CLI errors with user-friendly messages\n *\n * Converts various error types into readable console output\n * and exits with appropriate status code.\n */\nexport function handleError(error: unknown): never {\n if (error instanceof ValidationError) {\n console.error(`\\n${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof SlideParseError) {\n console.error(`\\nSlide error in ${error.filePath}:`);\n console.error(` ${error.message}`);\n if (error.cause) {\n const causeMessage = error.cause instanceof Error ? error.cause.message : String(error.cause);\n console.error(` Caused by: ${causeMessage}`);\n }\n process.exit(1);\n }\n\n if (error instanceof DeckLoadError) {\n console.error(`\\nFailed to load deck from ${error.slidesDir}:`);\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof ThemeError) {\n console.error('\\nTheme error:');\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof Error) {\n // Check for common issues\n if (error.message.includes('ENOENT')) {\n console.error('\\nFile or directory not found.');\n console.error(` ${error.message}`);\n process.exit(1);\n }\n\n if (error.message.includes('ffmpeg')) {\n console.error('\\nffmpeg error:');\n console.error(` ${error.message}`);\n console.error('\\nMake sure ffmpeg is installed:');\n console.error(' macOS: brew install ffmpeg');\n console.error(' Ubuntu: sudo apt install ffmpeg');\n process.exit(1);\n }\n\n // Generic error\n console.error(`\\nError: ${error.message}`);\n\n if (process.env.DEBUG) {\n console.error(error.stack);\n }\n\n process.exit(1);\n }\n\n // Unknown error\n console.error('\\nUnknown error occurred');\n console.error(error);\n process.exit(1);\n}\n","/**\n * Export Command\n *\n * Exports a presentation to GIF or MP4 format.\n */\n\nimport { Command } from 'commander';\nimport { exportPresentation } from '../../export/recorder.js';\nimport { handleError } from '../errors.js';\n\nexport const exportCommand = new Command('export')\n .description('Export presentation to GIF or MP4')\n .argument('<dir>', 'Slides directory')\n .requiredOption('-o, --output <file>', 'Output file (.mp4 or .gif)')\n .option('-w, --width <n>', 'Terminal width in characters', '120')\n .option('-h, --height <n>', 'Terminal height in characters', '40')\n .option('--fps <n>', 'Frames per second', '30')\n .option('-t, --slide-time <n>', 'Seconds per slide', '3')\n .option('-q, --quality <n>', 'Quality 1-100 (video only)', '80')\n .action(async (dir, options) => {\n try {\n await exportPresentation(dir, {\n output: options.output,\n width: Number.parseInt(options.width, 10),\n height: Number.parseInt(options.height, 10),\n fps: Number.parseInt(options.fps, 10),\n slideTime: Number.parseFloat(options.slideTime),\n quality: Number.parseInt(options.quality, 10),\n });\n } catch (error) {\n handleError(error);\n }\n });\n","/**\n * Export API\n *\n * This module provides a unified public API for exporting presentations\n * to various formats (video, GIF, asciicast). It re-exports functionality\n * from focused sub-modules.\n *\n * For video/GIF export:\n * @see {presentation-exporter}\n *\n * For ANSI/asciicast export:\n * @see {ansi-recorder}\n *\n * For session management:\n * @see {recording-session}\n */\n\n// Type definitions\nexport type {\n ExportOptions,\n ExportFormat,\n AsciicastHeader,\n AsciicastFrame,\n} from './types.js';\n\n// Recording session management\nexport type { RecordingSession } from './recording-session.js';\nexport {\n createRecordingSession,\n saveFrame,\n cleanupSession,\n} from './recording-session.js';\n\n// Video/GIF export\nexport { exportPresentation } from './presentation-exporter.js';\n\n// ANSI recording\nexport type { AnsiRecordOptions } from './ansi-recorder.js';\nexport { recordAnsi } from './ansi-recorder.js';\n\n// FFmpeg utilities (re-exported for convenience)\nexport { checkFfmpeg, detectFormat } from './encoding/ffmpeg-encoder.js';\n","/**\n * Recording Session Management\n *\n * This module manages the lifecycle of a recording session, including\n * temporary directory creation, frame storage, and cleanup.\n */\n\nimport { writeFile, mkdir, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport type { ExportOptions } from './types.js';\n\n/**\n * Recording session state\n */\nexport interface RecordingSession {\n tempDir: string\n frameCount: number\n width: number\n height: number\n fps: number\n}\n\n/**\n * Create a new recording session\n *\n * @param options - Export options containing dimensions and fps\n * @returns A new recording session with temporary directory\n */\nexport async function createRecordingSession(\n options: ExportOptions\n): Promise<RecordingSession> {\n // Create temp directory for frames\n const tempDir = join(tmpdir(), `term-deck-export-${Date.now()}`);\n await mkdir(tempDir, { recursive: true });\n\n return {\n tempDir,\n frameCount: 0,\n width: options.width ?? 120,\n height: options.height ?? 40,\n fps: options.fps ?? 30,\n };\n}\n\n/**\n * Save a PNG frame to the recording session\n *\n * @param session - Active recording session\n * @param png - PNG image data as Uint8Array\n */\nexport async function saveFrame(\n session: RecordingSession,\n png: Uint8Array\n): Promise<void> {\n const frameNum = session.frameCount.toString().padStart(6, '0');\n const framePath = join(session.tempDir, `frame_${frameNum}.png`);\n\n await writeFile(framePath, png);\n session.frameCount++;\n}\n\n/**\n * Cleanup recording session by removing temporary directory\n *\n * @param session - Recording session to cleanup\n */\nexport async function cleanupSession(session: RecordingSession): Promise<void> {\n await rm(session.tempDir, { recursive: true, force: true });\n}\n","/**\n * Presentation Video Exporter\n *\n * This module handles exporting presentations to video (MP4) or GIF formats.\n * It orchestrates the rendering, frame capture, and video encoding process.\n */\n\nimport { join } from 'path';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer, renderSlide } from '../renderer/screen.js';\nimport { setScreenDimensions } from '../renderer/types/screen.js';\nimport { VirtualTerminal } from './utils/virtual-terminal.js';\nimport { captureScreen } from './capture/screen-capture.js';\nimport { checkFfmpeg, detectFormat, encodeVideo } from './encoding/ffmpeg-encoder.js';\nimport { createRecordingSession, saveFrame, cleanupSession } from './recording-session.js';\nimport type { ExportOptions, ExportFormat } from './types.js';\n\n/**\n * Encode recorded frames to video using ffmpeg\n *\n * @param tempDir - Directory containing frame images\n * @param output - Output file path\n * @param format - Export format (mp4 or gif)\n * @param fps - Frames per second\n * @param quality - Video quality (1-100)\n */\nasync function encodeFramesToVideo(\n tempDir: string,\n output: string,\n format: ExportFormat,\n fps: number,\n quality?: number\n): Promise<void> {\n const inputPattern = join(tempDir, 'frame_%06d.png');\n\n await encodeVideo({\n inputPattern,\n output,\n format,\n fps,\n quality\n });\n}\n\n/**\n * Export a presentation to video or GIF format\n *\n * @param slidesDir - Directory containing slide markdown files\n * @param options - Export options (output path, dimensions, fps, etc.)\n */\nexport async function exportPresentation(\n slidesDir: string,\n options: ExportOptions\n): Promise<void> {\n // Check ffmpeg is available\n await checkFfmpeg();\n\n // Detect format from output extension\n const format = detectFormat(options.output);\n\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create recording session\n const session = await createRecordingSession(options);\n\n // Create virtual terminal for rendering\n const vt = new VirtualTerminal(session.width, session.height);\n\n // Create renderer (headless mode)\n const renderer = createRenderer(deck.config.theme);\n\n // Set screen dimensions for export\n setScreenDimensions(renderer.screen, session.width, session.height);\n\n const slideTime = options.slideTime ?? 3; // seconds per slide\n const framesPerSlide = session.fps * slideTime;\n\n console.log(`Exporting ${deck.slides.length} slides...`);\n\n try {\n for (let i = 0; i < deck.slides.length; i++) {\n const slide = deck.slides[i];\n console.log(` Slide ${i + 1}/${deck.slides.length}: ${slide.frontmatter.title}`);\n\n // Render slide\n await renderSlide(renderer, slide);\n\n // Capture frames for this slide\n for (let f = 0; f < framesPerSlide; f++) {\n // Update screen (needed for animations like matrix rain)\n renderer.screen.render();\n\n // Capture to virtual terminal\n captureScreen(renderer.screen, vt);\n\n // Save frame as PNG\n const png = await vt.toPng();\n await saveFrame(session, png);\n }\n }\n\n // Encode video\n console.log('Encoding video...');\n await encodeFramesToVideo(\n session.tempDir,\n options.output,\n format,\n session.fps,\n options.quality\n );\n\n console.log(`Exported to ${options.output}`);\n } finally {\n // Cleanup\n destroyRenderer(renderer);\n await cleanupSession(session);\n }\n}\n","/**\n * Screen Type Extensions\n *\n * This module extends the blessed Screen type to include properties that\n * exist at runtime but aren't typed in the @types/blessed package.\n */\n\nimport type blessed from 'neo-blessed';\n\n/**\n * Extended Screen interface that includes width and height properties.\n * These properties exist on blessed Screen objects at runtime but aren't\n * included in the TypeScript type definitions.\n */\nexport interface ExtendedScreen extends blessed.Widgets.Screen {\n width: number\n height: number\n}\n\n/**\n * Type guard to check if a screen has width and height properties\n */\nexport function hasScreenDimensions(\n screen: blessed.Widgets.Screen\n): screen is ExtendedScreen {\n return (\n typeof (screen as any).width === 'number' &&\n typeof (screen as any).height === 'number'\n );\n}\n\n/**\n * Safely set screen dimensions\n *\n * @param screen - Blessed screen instance\n * @param width - Width in characters\n * @param height - Height in characters\n */\nexport function setScreenDimensions(\n screen: blessed.Widgets.Screen,\n width: number,\n height: number\n): void {\n (screen as ExtendedScreen).width = width;\n (screen as ExtendedScreen).height = height;\n}\n","/**\n * Virtual Terminal Buffer\n *\n * Provides an in-memory representation of a terminal screen with character\n * and color information. Used for capturing terminal output for export.\n */\n\n/**\n * Virtual terminal buffer for capturing frames\n *\n * Maintains a 2D grid of characters and their colors, which can be\n * rendered to PNG images for video export.\n */\nexport class VirtualTerminal {\n private buffer: string[][]\n private colors: string[][]\n\n constructor(\n public width: number,\n public height: number\n ) {\n this.buffer = Array.from({ length: height }, () =>\n Array(width).fill(' ')\n )\n this.colors = Array.from({ length: height }, () =>\n Array(width).fill('#ffffff')\n )\n }\n\n /**\n * Set character at position with optional color\n */\n setChar(x: number, y: number, char: string, color: string = '#ffffff'): void {\n if (x >= 0 && x < this.width && y >= 0 && y < this.height) {\n this.buffer[y][x] = char\n this.colors[y][x] = color\n }\n }\n\n /**\n * Clear the buffer to blank spaces\n */\n clear(): void {\n for (let y = 0; y < this.height; y++) {\n for (let x = 0; x < this.width; x++) {\n this.buffer[y][x] = ' '\n this.colors[y][x] = '#ffffff'\n }\n }\n }\n\n /**\n * Get buffer contents as plain text string\n */\n toString(): string {\n return this.buffer.map((row) => row.join('')).join('\\n')\n }\n\n /**\n * Get the raw character buffer\n */\n getBuffer(): string[][] {\n return this.buffer\n }\n\n /**\n * Get the color buffer\n */\n getColors(): string[][] {\n return this.colors\n }\n\n /**\n * Convert buffer to PNG image data\n */\n async toPng(): Promise<Uint8Array> {\n return renderTerminalToPng(this.buffer, this.colors, this.width, this.height)\n }\n}\n\n// Character dimensions in pixels (monospace font)\nconst CHAR_WIDTH = 10\nconst CHAR_HEIGHT = 20\n\n/**\n * Render terminal buffer to PNG using canvas\n *\n * @param buffer - 2D array of characters\n * @param colors - 2D array of hex color codes\n * @param width - Terminal width in characters\n * @param height - Terminal height in characters\n * @returns PNG image data as Uint8Array\n */\nasync function renderTerminalToPng(\n buffer: string[][],\n colors: string[][],\n width: number,\n height: number\n): Promise<Uint8Array> {\n // Dynamic import to avoid bundling issues\n const { createCanvas } = await import('canvas')\n\n const canvas = createCanvas(width * CHAR_WIDTH, height * CHAR_HEIGHT)\n const ctx = canvas.getContext('2d')\n\n // Background\n ctx.fillStyle = '#0a0a0a'\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n // Set font\n ctx.font = `${CHAR_HEIGHT - 4}px monospace`\n ctx.textBaseline = 'top'\n\n // Render each character\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const char = buffer[y][x]\n const color = colors[y][x]\n\n if (char !== ' ') {\n ctx.fillStyle = color\n ctx.fillText(char, x * CHAR_WIDTH, y * CHAR_HEIGHT + 2)\n }\n }\n }\n\n return canvas.toBuffer('image/png')\n}\n","/**\n * Screen Capture Module\n *\n * Handles capturing blessed screen content to various formats.\n * Separated from recorder.ts to follow Single Responsibility Principle.\n */\n\nimport { hexToAnsi256, extractColor } from '../utils/color-conversion.js';\nimport type { VirtualTerminal } from '../utils/virtual-terminal.js';\n\n/**\n * Capture blessed screen content to virtual terminal\n *\n * This parses the blessed screen's internal buffer and writes it to a VirtualTerminal.\n * Each cell contains a character and color information that gets extracted and applied.\n *\n * @param screen - The neo-blessed screen to capture\n * @param vt - The virtual terminal to write to\n */\nexport function captureScreen(\n screen: any, // neo-blessed screen type\n vt: VirtualTerminal\n): void {\n const lines = screen.lines || [];\n\n for (let y = 0; y < Math.min(lines.length, vt.height); y++) {\n const line = lines[y];\n if (!line) continue;\n\n for (let x = 0; x < Math.min(line.length, vt.width); x++) {\n const cell = line[x];\n if (!cell) continue;\n\n // Cell format: [char, attr] or just char\n const char = Array.isArray(cell) ? cell[0] : cell;\n const attr = Array.isArray(cell) ? cell[1] : null;\n\n // Extract color from attr (blessed-specific format)\n const color = extractColor(attr) || '#ffffff';\n\n vt.setChar(x, y, char || ' ', color);\n }\n }\n}\n\n/**\n * Capture blessed screen content as ANSI escape sequence string\n *\n * This generates a string with ANSI color codes that can be played back\n * in a terminal or saved to an asciicast file.\n *\n * @param screen - The neo-blessed screen to capture\n * @returns ANSI-encoded string representation of the screen\n */\nexport function captureScreenAsAnsi(screen: any): string {\n const lines = screen.lines || [];\n const output: string[] = [];\n\n // Clear screen and reset cursor\n output.push('\\x1b[2J\\x1b[H');\n\n for (let y = 0; y < lines.length; y++) {\n const line = lines[y];\n if (!line) {\n output.push('\\n');\n continue;\n }\n\n let lineStr = '';\n let lastColor: string | null = null;\n\n for (let x = 0; x < line.length; x++) {\n const cell = line[x];\n if (!cell) {\n lineStr += ' ';\n continue;\n }\n\n // Cell format: [char, attr] or just char\n const char = Array.isArray(cell) ? cell[0] : cell;\n const attr = Array.isArray(cell) ? cell[1] : null;\n\n // Extract color\n const color = extractColor(attr);\n\n // Apply color if changed\n if (color && color !== lastColor) {\n // Convert hex to ANSI 256-color code\n lineStr += hexToAnsi256(color);\n lastColor = color;\n }\n\n lineStr += char || ' ';\n }\n\n // Reset color at end of line\n if (lastColor) {\n lineStr += '\\x1b[0m';\n }\n\n output.push(lineStr);\n if (y < lines.length - 1) {\n output.push('\\n');\n }\n }\n\n return output.join('');\n}\n","/**\n * Color Conversion Utilities\n *\n * Utilities for converting between hex colors, ANSI 256-color codes,\n * and extracting colors from blessed cell attributes.\n */\n\n/**\n * Convert hex color to ANSI 256-color escape sequence\n *\n * @param hex - Hex color string (e.g., '#ff0000')\n * @returns ANSI escape sequence for foreground color\n */\nexport function hexToAnsi256(hex: string): string {\n const r = Number.parseInt(hex.slice(1, 3), 16)\n const g = Number.parseInt(hex.slice(3, 5), 16)\n const b = Number.parseInt(hex.slice(5, 7), 16)\n\n const rIndex = Math.round(r / 51)\n const gIndex = Math.round(g / 51)\n const bIndex = Math.round(b / 51)\n\n const colorCode = 16 + (rIndex * 36) + (gIndex * 6) + bIndex\n\n return `\\x1b[38;5;${colorCode}m`\n}\n\n/**\n * Convert ANSI 256 color code to hex\n *\n * @param code - ANSI 256-color code (0-255)\n * @returns Hex color string\n */\nexport function ansi256ToHex(code: number): string {\n const standard16 = [\n '#000000', '#800000', '#008000', '#808000',\n '#000080', '#800080', '#008080', '#c0c0c0',\n '#808080', '#ff0000', '#00ff00', '#ffff00',\n '#0000ff', '#ff00ff', '#00ffff', '#ffffff',\n ]\n\n if (code < 16) {\n return standard16[code]\n }\n\n if (code < 232) {\n const n = code - 16\n const r = Math.floor(n / 36) * 51\n const g = Math.floor((n % 36) / 6) * 51\n const b = (n % 6) * 51\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`\n }\n\n const gray = (code - 232) * 10 + 8\n const hex = gray.toString(16).padStart(2, '0')\n return `#${hex}${hex}${hex}`\n}\n\n/**\n * Extract hex color from blessed attribute\n *\n * @param attr - Blessed cell attribute object\n * @returns Hex color string or null if not found\n */\nexport function extractColor(attr: any): string | null {\n if (!attr) return null\n\n if (typeof attr === 'object' && attr.fg !== undefined) {\n if (typeof attr.fg === 'string' && attr.fg.startsWith('#')) {\n return attr.fg\n }\n if (typeof attr.fg === 'number') {\n return ansi256ToHex(attr.fg)\n }\n }\n\n return null\n}\n","/**\n * FFmpeg Video Encoder\n *\n * This module handles video encoding using ffmpeg. It supports both MP4 and GIF formats,\n * with configurable quality settings and optimized encoding parameters.\n *\n * Responsibilities:\n * - Check ffmpeg availability\n * - Encode frame sequences to MP4 format\n * - Encode frame sequences to GIF format with palette optimization\n */\n\nimport { execa } from 'execa';\nimport { writeFile, unlink } from 'fs/promises';\n\n/**\n * Export format types\n */\nexport type ExportFormat = 'mp4' | 'gif';\n\n/**\n * Encoding options for video export\n */\nexport interface EncodingOptions {\n /** Input frame pattern (e.g., '/tmp/frames/frame_%06d.png') */\n inputPattern: string;\n /** Output file path */\n output: string;\n /** Format to encode to */\n format: ExportFormat;\n /** Frames per second */\n fps: number;\n /** Quality setting (1-100, only used for MP4) */\n quality?: number;\n}\n\n/**\n * Check if ffmpeg is available on the system\n *\n * @throws Error with installation instructions if ffmpeg is not found\n */\nexport async function checkFfmpeg(): Promise<void> {\n try {\n await execa('which', ['ffmpeg']);\n } catch {\n throw new Error(\n 'ffmpeg not found. Install it with:\\n' +\n ' macOS: brew install ffmpeg\\n' +\n ' Ubuntu: sudo apt install ffmpeg'\n );\n }\n}\n\n/**\n * Detect export format from filename extension\n *\n * @param output - The output file path\n * @returns The export format ('mp4' or 'gif')\n * @throws Error if the file extension is not .mp4 or .gif\n */\nexport function detectFormat(output: string): ExportFormat {\n if (output.endsWith('.gif')) return 'gif';\n if (output.endsWith('.mp4')) return 'mp4';\n\n throw new Error(\n `Unknown output format for ${output}. Use .mp4 or .gif extension.`\n );\n}\n\n/**\n * Encode frame sequence to video using ffmpeg\n *\n * Routes to the appropriate encoder based on the format.\n *\n * @param options - Encoding options including input pattern, output path, format, and quality\n */\nexport async function encodeVideo(options: EncodingOptions): Promise<void> {\n const { inputPattern, output, format, fps, quality } = options;\n\n if (format === 'mp4') {\n await encodeMp4(inputPattern, output, fps, quality ?? 80);\n } else {\n await encodeGif(inputPattern, output, fps);\n }\n}\n\n/**\n * Encode frame sequence to MP4 format\n *\n * Uses H.264 codec with CRF (Constant Rate Factor) quality control.\n * CRF ranges from 0 (lossless) to 51 (worst quality).\n * Quality parameter (1-100) is mapped to CRF (18-51) where higher quality = lower CRF.\n *\n * @param input - Input frame pattern (e.g., 'frame_%06d.png')\n * @param output - Output MP4 file path\n * @param fps - Frames per second\n * @param quality - Quality setting (1-100), defaults to 80\n */\nasync function encodeMp4(\n input: string,\n output: string,\n fps: number,\n quality: number\n): Promise<void> {\n // CRF: 0 = lossless, 51 = worst. ~18-23 is good quality\n // Map quality (1-100) to CRF (51-18)\n const crf = Math.round(51 - (quality / 100) * 33);\n\n await execa('ffmpeg', [\n '-y', // Overwrite output file\n '-framerate', fps.toString(),\n '-i', input,\n '-c:v', 'libx264', // H.264 codec\n '-crf', crf.toString(),\n '-pix_fmt', 'yuv420p', // Pixel format for compatibility\n output\n ]);\n}\n\n/**\n * Encode frame sequence to GIF format\n *\n * Uses two-pass encoding for better quality:\n * 1. Generate optimized color palette from input frames\n * 2. Encode using the generated palette with dithering\n *\n * This approach produces much better quality GIFs than single-pass encoding.\n *\n * @param input - Input frame pattern (e.g., 'frame_%06d.png')\n * @param output - Output GIF file path\n * @param fps - Frames per second\n */\nasync function encodeGif(\n input: string,\n output: string,\n fps: number\n): Promise<void> {\n const { tmpdir } = await import('os');\n const { join } = await import('path');\n\n // Two-pass encoding for better quality GIF\n const paletteFile = join(tmpdir(), `palette-${Date.now()}.png`);\n\n try {\n // Pass 1: Generate palette with diff stats mode for better color selection\n await execa('ffmpeg', [\n '-y',\n '-framerate', fps.toString(),\n '-i', input,\n '-vf', `fps=${fps},scale=-1:-1:flags=lanczos,palettegen=stats_mode=diff`,\n paletteFile\n ]);\n\n // Pass 2: Encode with palette using Bayer dithering\n await execa('ffmpeg', [\n '-y',\n '-framerate', fps.toString(),\n '-i', input,\n '-i', paletteFile,\n '-lavfi', `fps=${fps},scale=-1:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle`,\n output\n ]);\n } finally {\n // Cleanup palette file\n try {\n await unlink(paletteFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n","/**\n * ANSI Recording Module\n *\n * This module handles recording presentations as ANSI text files using the\n * asciicast v2 format. This format doesn't require ffmpeg or canvas and can\n * be played back with asciinema.\n *\n * @see https://docs.asciinema.org/manual/asciicast/v2/\n */\n\nimport { writeFile } from 'fs/promises';\nimport { loadDeck } from '../core/deck-loader.js';\nimport { createRenderer, destroyRenderer, renderSlide } from '../renderer/screen.js';\nimport { setScreenDimensions } from '../renderer/types/screen.js';\nimport { captureScreenAsAnsi } from './capture/screen-capture.js';\nimport type { AsciicastHeader, AsciicastFrame } from './types.js';\n\n/**\n * Options for ANSI recording\n */\nexport interface AnsiRecordOptions {\n /** Time per slide in seconds */\n slideTime?: number\n /** Terminal width in characters */\n width?: number\n /** Terminal height in characters */\n height?: number\n}\n\n/**\n * Record presentation as ANSI text file (asciicast format)\n *\n * This is an alternative to video export that doesn't require ffmpeg or canvas.\n * The output can be played back with asciinema: `asciinema play output.cast`\n *\n * @param slidesDir - Directory containing slide markdown files\n * @param output - Output file path (e.g., 'presentation.cast')\n * @param options - Recording options (dimensions and timing)\n */\nexport async function recordAnsi(\n slidesDir: string,\n output: string,\n options: AnsiRecordOptions = {}\n): Promise<void> {\n // Load deck\n const deck = await loadDeck(slidesDir);\n\n if (deck.slides.length === 0) {\n throw new Error(`No slides found in ${slidesDir}`);\n }\n\n // Create renderer (headless mode)\n const renderer = createRenderer(deck.config.theme);\n\n // Set screen dimensions if specified\n const width = options.width ?? 120;\n const height = options.height ?? 40;\n setScreenDimensions(renderer.screen, width, height);\n\n const slideTime = options.slideTime ?? 3;\n const frames: AsciicastFrame[] = [];\n let currentTime = 0;\n\n console.log(`Recording ${deck.slides.length} slides to asciicast format...`);\n\n try {\n for (let i = 0; i < deck.slides.length; i++) {\n const slide = deck.slides[i];\n console.log(` Slide ${i + 1}/${deck.slides.length}: ${slide.frontmatter.title}`);\n\n // Render slide\n await renderSlide(renderer, slide);\n\n // Capture screen as ANSI string\n const content = captureScreenAsAnsi(renderer.screen);\n\n // Add frame with timestamp\n frames.push([currentTime, 'o', content]);\n currentTime += slideTime;\n }\n\n // Write asciicast file\n const header: AsciicastHeader = {\n version: 2,\n width,\n height,\n timestamp: Math.floor(Date.now() / 1000),\n env: { TERM: 'xterm-256color' },\n };\n\n // Format: header on first line, then one frame per line\n const lines = [JSON.stringify(header)];\n for (const frame of frames) {\n lines.push(JSON.stringify(frame));\n }\n\n await writeFile(output, lines.join('\\n') + '\\n');\n\n console.log(`Recorded to ${output}`);\n console.log(`Play with: asciinema play ${output}`);\n } finally {\n destroyRenderer(renderer);\n }\n}\n","/**\n * Init Command\n *\n * Creates a new presentation deck with sample slides and configuration.\n */\n\nimport { Command } from 'commander';\nimport { join } from 'node:path';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { handleError } from '../errors.js';\n\nexport const initCommand = new Command('init')\n .description('Create a new presentation deck')\n .argument('<name>', 'Deck name (will create directory)')\n .option('-t, --theme <name>', 'Theme to use', 'matrix')\n .action(async (name, options) => {\n try {\n await initDeck(name, options.theme);\n console.log(`Created deck: ${name}/`);\n console.log('\\nNext steps:');\n console.log(` cd ${name}/slides`);\n console.log(' term-deck present .');\n } catch (error) {\n handleError(error);\n }\n });\n\n/**\n * Initialize a new deck directory\n *\n * Creates the directory structure, configuration file, sample slides,\n * and README for a new presentation deck.\n */\nexport async function initDeck(name: string, theme: string): Promise<void> {\n const deckDir = join(process.cwd(), name);\n const slidesDir = join(deckDir, 'slides');\n\n // Create directories\n await mkdir(slidesDir, { recursive: true });\n await writeFile(join(slidesDir, '.gitkeep'), '');\n\n // Create deck.config.js with valid default theme\n const configContent = `// Deck configuration\n// See: https://github.com/PepijnSenders/term-deck\n\nexport default {\n title: '${name}',\n\n // Default matrix/cyberpunk theme\n theme: {\n name: 'matrix',\n\n colors: {\n primary: '#00cc66',\n accent: '#ff6600',\n background: '#0a0a0a',\n text: '#ffffff',\n muted: '#666666',\n },\n\n gradients: {\n fire: ['#ff6600', '#ff3300', '#ff0066'],\n cool: ['#00ccff', '#0066ff', '#6600ff'],\n pink: ['#ff0066', '#ff0099', '#cc00ff'],\n },\n\n glyphs: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789',\n },\n}\n`;\n await writeFile(join(slidesDir, 'deck.config.js'), configContent);\n\n // Create sample slides\n const slide1 = `---\ntitle: ${name.toUpperCase()}\nbigText: ${name.toUpperCase()}\ngradient: fire\n---\n\n{GREEN}Welcome to your presentation{/}\n\nPress {CYAN}Space{/} or {CYAN}→{/} to advance\n`;\n\n const slide2 = `---\ntitle: SLIDE TWO\nbigText: HELLO\ngradient: cool\n---\n\n{WHITE}This is the second slide{/}\n\n- Point one\n- Point two\n- Point three\n\n<!-- notes -->\nRemember to explain each point clearly.\n`;\n\n const slide3 = `---\ntitle: THE END\nbigText: FIN\ngradient: pink\n---\n\n{ORANGE}Thank you!{/}\n\nPress {CYAN}q{/} to exit\n`;\n\n await writeFile(join(slidesDir, '01-intro.md'), slide1);\n await writeFile(join(slidesDir, '02-content.md'), slide2);\n await writeFile(join(slidesDir, '03-end.md'), slide3);\n\n // Create README\n const readme = `# ${name}\n\nA term-deck presentation.\n\n## Usage\n\n\\`\\`\\`bash\ncd slides\nterm-deck present .\n\\`\\`\\`\n\n## Export\n\n\\`\\`\\`bash\nterm-deck export slides/ -o ${name}.mp4\nterm-deck export slides/ -o ${name}.gif\n\\`\\`\\`\n\n## Hotkeys\n\n| Key | Action |\n|-----|--------|\n| Space / → | Next slide |\n| ← | Previous slide |\n| 0-9 | Jump to slide |\n| l | Show slide list |\n| q | Quit |\n`;\n\n await writeFile(join(deckDir, 'README.md'), readme);\n}\n"]}
|