@conceptcraft/mindframes 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/postinstall.js +52 -0
- package/dist/index.js +1529 -1162
- package/dist/index.js.map +1 -1
- package/package.json +14 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/config.ts","../src/lib/output.ts","../src/types/media.ts","../src/types/index.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/feature-cache.ts","../src/commands/login.ts","../src/index.ts","../src/lib/brand.ts","../src/commands/logout.ts","../src/commands/config.ts","../src/commands/create.ts","../src/lib/streaming.ts","../src/commands/list.ts","../src/commands/get.ts","../src/commands/delete.ts","../src/commands/export.ts","../src/commands/import.ts","../src/commands/branding.ts","../src/commands/derive.ts","../src/commands/ideas.ts","../src/commands/whoami.ts","../src/commands/skill/index.ts","../src/commands/skill/sections/frontmatter.ts","../src/commands/skill/sections/header.ts","../src/commands/skill/sections/prerequisites.ts","../src/commands/skill/sections/workflow.ts","../src/commands/skill/sections/create-command.ts","../src/commands/skill/sections/create-options.ts","../src/commands/skill/sections/other-commands.ts","../src/commands/skill/sections/examples.ts","../src/commands/skill/sections/output.ts","../src/commands/skill/sections/best-practices.ts","../src/commands/skill/sections/file-types.ts","../src/commands/skill/sections/troubleshooting.ts","../src/commands/skill/sections/video-creation.ts","../src/commands/skill/generate-content.ts","../src/commands/skill/installer.ts","../src/commands/skill/editors.ts","../src/commands/skill/rules/video/content.ts","../src/commands/tts.ts","../src/commands/music.ts","../src/commands/mix.ts","../src/commands/image.ts","../src/commands/video.ts"],"sourcesContent":["/**\n * Configuration Management\n * Handles reading/writing CLI config from ~/.conceptcraft/config.json\n */\n\nimport Conf from \"conf\";\nimport type { CLIConfig } from \"../types/index.js\";\n\nconst DEFAULT_API_URL = \"https://www.mindframes.app\";\n\nconst schema = {\n apiKey: {\n type: \"string\" as const,\n },\n apiUrl: {\n type: \"string\" as const,\n default: DEFAULT_API_URL,\n },\n defaultTeamId: {\n type: \"string\" as const,\n },\n // OAuth tokens (preferred over API key)\n accessToken: {\n type: \"string\" as const,\n },\n refreshToken: {\n type: \"string\" as const,\n },\n tokenExpiresAt: {\n type: \"number\" as const,\n },\n // OAuth client registration (cached per-server)\n clientId: {\n type: \"string\" as const,\n },\n clientSecret: {\n type: \"string\" as const,\n },\n};\n\nconst config = new Conf<CLIConfig>({\n projectName: \"mindframes\",\n schema,\n});\n\nexport function getConfig(): CLIConfig {\n return {\n apiKey: getApiKey(),\n apiUrl: getApiUrl(),\n defaultTeamId: config.get(\"defaultTeamId\"),\n accessToken: config.get(\"accessToken\"),\n refreshToken: config.get(\"refreshToken\"),\n tokenExpiresAt: config.get(\"tokenExpiresAt\"),\n clientId: config.get(\"clientId\"),\n clientSecret: config.get(\"clientSecret\"),\n };\n}\n\nexport function getApiKey(): string | undefined {\n // Environment variable takes precedence\n const envKey = process.env.CC_MINDFRAMES_API_KEY ?? process.env.CONCEPTCRAFT_API_KEY;\n if (envKey) {\n return envKey;\n }\n return config.get(\"apiKey\");\n}\n\nexport function setApiKey(key: string): void {\n config.set(\"apiKey\", key);\n}\n\nexport function getApiUrl(): string {\n const envUrl = process.env.NEXT_PUBLIC_API_URL ?? process.env.CONCEPTCRAFT_API_URL;\n if (envUrl) {\n return envUrl;\n }\n return config.get(\"apiUrl\") ?? DEFAULT_API_URL;\n}\n\nexport function setApiUrl(url: string): void {\n config.set(\"apiUrl\", url);\n}\n\nexport function getDefaultTeamId(): string | undefined {\n return config.get(\"defaultTeamId\");\n}\n\nexport function setDefaultTeamId(teamId: string): void {\n config.set(\"defaultTeamId\", teamId);\n}\n\nexport function clearConfig(): void {\n config.clear();\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nexport function hasApiKey(): boolean {\n return !!getApiKey();\n}\n\n// OAuth token management\nexport function getAccessToken(): string | undefined {\n return config.get(\"accessToken\");\n}\n\nexport function getRefreshToken(): string | undefined {\n return config.get(\"refreshToken\");\n}\n\nexport function getTokenExpiresAt(): number | undefined {\n return config.get(\"tokenExpiresAt\");\n}\n\nexport function setOAuthTokens(\n accessToken: string,\n refreshToken: string,\n expiresIn: number\n): void {\n config.set(\"accessToken\", accessToken);\n config.set(\"refreshToken\", refreshToken);\n // Store expiry as absolute timestamp (with 60s buffer for safety)\n config.set(\"tokenExpiresAt\", Date.now() + (expiresIn - 60) * 1000);\n}\n\nexport function clearOAuthTokens(): void {\n config.delete(\"accessToken\");\n config.delete(\"refreshToken\");\n config.delete(\"tokenExpiresAt\");\n}\n\nexport function isTokenExpired(): boolean {\n const expiresAt = config.get(\"tokenExpiresAt\");\n if (!expiresAt) return true;\n return Date.now() >= expiresAt;\n}\n\nexport function hasOAuthTokens(): boolean {\n return !!config.get(\"accessToken\") && !!config.get(\"refreshToken\");\n}\n\n// OAuth client registration (cached)\nexport function getClientId(): string | undefined {\n return config.get(\"clientId\");\n}\n\nexport function getClientSecret(): string | undefined {\n return config.get(\"clientSecret\");\n}\n\nexport function setOAuthClient(clientId: string, clientSecret: string): void {\n config.set(\"clientId\", clientId);\n config.set(\"clientSecret\", clientSecret);\n}\n\nexport function clearOAuthClient(): void {\n config.delete(\"clientId\");\n config.delete(\"clientSecret\");\n}\n\nexport { config };\n","/**\n * Output Formatting\n * Handles different output modes (human, json, table, quiet)\n */\n\nimport chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport type { OutputFormat, PresentationListItem, Branding } from \"../types/index.js\";\nimport { getApiUrl } from \"./config.js\";\n\n// Check if running in a TTY (interactive terminal)\nexport function isTTY(): boolean {\n return process.stdout.isTTY ?? false;\n}\n\n// Format output based on mode\nexport function formatOutput<T>(\n data: T,\n format: OutputFormat = \"human\",\n humanFormatter?: (data: T) => string\n): string {\n switch (format) {\n case \"json\":\n return JSON.stringify(data, null, 2);\n case \"quiet\":\n return \"\";\n case \"human\":\n default:\n if (humanFormatter) {\n return humanFormatter(data);\n }\n return String(data);\n }\n}\n\n// Success message\nexport function success(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.log(chalk.green(\"✓\"), message);\n}\n\n// Error message\nexport function error(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") {\n console.error(JSON.stringify({ error: message }));\n return;\n }\n console.error(chalk.red(\"✗\"), message);\n}\n\n// Warning message\nexport function warn(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.warn(chalk.yellow(\"⚠\"), message);\n}\n\n// Info message\nexport function info(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n// Debug message\nexport function debug(message: string, isDebug = false): void {\n if (!isDebug) return;\n console.log(chalk.gray(\"[DEBUG]\"), message);\n}\n\n// Build view URL from slug\nexport function buildViewUrl(slug?: string, language = \"en\"): string {\n if (!slug) return \"N/A\";\n const apiUrl = getApiUrl();\n return `${apiUrl}/${language}/view/presentations/${slug}`;\n}\n\n// Format presentation list as table\nexport function formatPresentationTable(\n presentations: PresentationListItem[],\n options: { showLinks?: boolean; language?: string } = {}\n): string {\n const { showLinks = false, language = \"en\" } = options;\n\n const truncate = (str: string, len: number) =>\n str.length > len ? str.slice(0, len - 1) + \"…\" : str;\n\n // Format date/time as \"Jan 18, 1:04 AM\"\n const shortDateTime = (dateStr: string) => {\n try {\n const d = new Date(dateStr);\n return d.toLocaleString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n }).replace(\" at \", \", \");\n } catch {\n return \"-\";\n }\n };\n\n if (showLinks) {\n // Detail format: all columns + URL\n const table = new Table({\n head: [\n chalk.cyan(\"Slug\"),\n chalk.cyan(\"Title\"),\n chalk.cyan(\"Slides\"),\n chalk.cyan(\"Created\"),\n chalk.cyan(\"URL\"),\n ],\n });\n\n for (const p of presentations) {\n table.push([\n truncate(p.slug || p.id.slice(0, 8), 30),\n truncate(p.title || \"Untitled\", 22),\n String(p.numberOfSlides || \"-\"),\n shortDateTime(p.createdAt),\n buildViewUrl(p.slug, language),\n ]);\n }\n\n return table.toString();\n }\n\n // Standard compact format without URLs\n const table = new Table({\n head: [\n chalk.cyan(\"Slug\"),\n chalk.cyan(\"Title\"),\n chalk.cyan(\"Slides\"),\n chalk.cyan(\"Mode\"),\n chalk.cyan(\"Created\"),\n ],\n colWidths: [32, 28, 8, 11, 18],\n });\n\n for (const p of presentations) {\n table.push([\n p.slug || p.id.slice(0, 8),\n p.title || \"Untitled\",\n String(p.numberOfSlides || \"-\"),\n p.mode || \"-\",\n shortDateTime(p.createdAt),\n ]);\n }\n\n return table.toString();\n}\n\n// Format presentation list as slugs only (for scripting)\nexport function formatPresentationIds(presentations: PresentationListItem[]): string {\n return presentations.map((p) => p.slug || p.id).join(\"\\n\");\n}\n\n// Format branding list as table\nexport function formatBrandingTable(brandings: Branding[]): string {\n // Sort: defaults first, then by createdAt descending (most recent first)\n const sorted = [...brandings].sort((a, b) => {\n if (a.isDefault && !b.isDefault) return -1;\n if (!a.isDefault && b.isDefault) return 1;\n // Sort by createdAt descending (most recent first)\n const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return dateB - dateA;\n });\n\n // Normalize URL for display (ensure https://)\n const formatUrl = (url?: string) => {\n if (!url) return \"-\";\n try {\n const u = new URL(url);\n return u.href;\n } catch {\n // If not a valid URL, try adding https://\n return url.startsWith(\"http\") ? url : `https://${url}`;\n }\n };\n\n const table = new Table({\n head: [\n chalk.cyan(\"Name\"),\n chalk.cyan(\"Source\"),\n chalk.cyan(\"Color\"),\n chalk.cyan(\"Logo\"),\n chalk.cyan(\"Default\"),\n chalk.cyan(\"ID\"),\n ],\n });\n\n for (const b of sorted) {\n const colorDisplay = b.primaryColor\n ? `${chalk.bgHex(b.primaryColor)(\" \")} ${b.primaryColor}`\n : \"-\";\n table.push([\n b.name,\n formatUrl(b.sourceUrl),\n colorDisplay,\n b.logoUrl ? chalk.green(\"✓\") : chalk.gray(\"✗\"),\n b.isDefault ? chalk.green(\"★\") : \"\",\n b.id,\n ]);\n }\n\n return table.toString();\n}\n\n// Format date for display\nexport function formatDate(dateStr: string): string {\n try {\n const date = new Date(dateStr);\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\n// Print header for commands\nexport function header(text: string): void {\n console.log();\n console.log(chalk.bold(text));\n console.log(chalk.gray(\"─\".repeat(text.length)));\n}\n\n// Print key-value pair\nexport function keyValue(key: string, value: string | number | undefined): void {\n console.log(` ${chalk.gray(key + \":\")} ${value ?? \"-\"}`);\n}\n\n// Create progress bar string\nexport function progressBar(current: number, total: number, width = 30, showPercentage = true): string {\n const percentage = Math.min(100, Math.round((current / total) * 100));\n const filled = Math.round((width * current) / total);\n const empty = width - filled;\n\n const bar = chalk.green(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n return showPercentage ? `[${bar}] ${percentage}%` : `[${bar}]`;\n}\n\n// Format JSON for output\nexport function formatJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\n// Print JSON to stdout\nexport function printJson(data: unknown): void {\n console.log(formatJson(data));\n}\n","/**\n * Media Types\n * Types for TTS, music generation, audio mixing, and image search\n */\n\n// TTS types\nexport type TTSProvider = \"elevenlabs\" | \"openai\" | \"gemini\" | \"google\";\n\nexport interface TTSTimestamps {\n characters: string[];\n characterStartTimesSeconds: number[];\n characterEndTimesSeconds: number[];\n}\n\nexport interface TTSRequest {\n text: string;\n options?: {\n provider?: TTSProvider;\n voice?: string;\n model?: string;\n speed?: number; // 0.25-4.0\n };\n}\n\nexport interface TTSResult {\n audioData: Buffer;\n duration: number;\n cost: number;\n provider: string;\n format: string;\n timestamps?: TTSTimestamps; // Character-level timing from TTS API\n}\n\nexport interface TTSVoice {\n id: string;\n name: string;\n description: string;\n}\n\nexport interface TTSVoicesResponse {\n voices: {\n gemini: TTSVoice[];\n elevenlabs: TTSVoice[];\n openai: TTSVoice[];\n };\n}\n\n// Music generation types\nexport interface MusicGenerationRequest {\n prompt: string;\n duration: number; // 3-30 seconds\n options?: {\n provider?: string; // 'elevenlabs' (default)\n instrumental?: boolean;\n style?: string;\n tempo?: number; // BPM 60-180\n format?: \"mp3\" | \"wav\" | \"flac\" | \"ogg\";\n };\n}\n\nexport interface MusicGenerationResult {\n requestId: string;\n status: \"pending\" | \"processing\" | \"completed\" | \"failed\";\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n}\n\n// Audio mixing types\nexport type AudioMixOperation =\n | \"add-to-video\"\n | \"mix-tracks\"\n | \"extract-audio\"\n | \"replace-audio\"\n | \"overlay\";\n\nexport interface AudioInput {\n url: string;\n role?: \"video\" | \"voice\" | \"music\" | \"background\";\n volume?: number; // 0-5\n startTime?: number;\n endTime?: number;\n}\n\nexport interface AudioMixRequest {\n operation: AudioMixOperation;\n inputs: AudioInput[];\n options?: {\n musicVolume?: number; // 0-1, default 0.25\n voiceVolume?: number; // 0-2, default 1.0\n fadeOutMusic?: boolean;\n outputFormat?: string;\n };\n}\n\nexport interface AudioMixResult {\n requestId: string;\n status: \"pending\" | \"processing\" | \"completed\" | \"failed\";\n outputUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n}\n\n// Image search types\nexport interface ImageSearchRequest {\n query: string;\n options?: {\n providers?: string[];\n maxResults?: number;\n size?: \"small\" | \"medium\" | \"large\" | \"any\";\n safeSearch?: boolean;\n };\n}\n\nexport interface ImageSearchResultItem {\n url: string;\n width: number;\n height: number;\n title?: string;\n thumbnailUrl?: string;\n sourceUrl?: string;\n author?: string;\n provider: string;\n}\n\nexport interface ImageSearchResponse {\n success: boolean;\n data: {\n results: Array<{\n providerId: number;\n providerName: string;\n status: string;\n results: ImageSearchResultItem[];\n cost: number;\n }>;\n totalCost: number;\n };\n requestId: string;\n}\n\n// Video search types\nexport interface VideoSearchRequest {\n query: string;\n options?: {\n providers?: string[];\n maxResults?: number;\n orientation?: \"landscape\" | \"portrait\" | \"square\" | \"any\";\n license?: \"free\" | \"premium\" | \"any\";\n };\n}\n\nexport interface VideoSearchResultItem {\n id: string;\n title: string;\n description?: string;\n thumbnailUrl: string;\n previewUrl?: string;\n downloadUrl?: string;\n duration: number;\n width: number;\n height: number;\n fps?: number;\n provider: string;\n sourceUrl: string;\n author?: string;\n license?: string;\n}\n\nexport interface VideoSearchResponse {\n success: boolean;\n data: {\n results: Array<{\n providerId: number;\n providerName: string;\n status: string;\n results: VideoSearchResultItem[];\n cost: number;\n }>;\n totalCost: number;\n };\n requestId: string;\n}\n\n","/**\n * CLI Types and Interfaces\n */\n\n// Re-export media types\nexport * from \"./media.js\";\n\nexport interface CLIConfig {\n apiKey?: string;\n apiUrl: string;\n defaultTeamId?: string;\n // OAuth tokens (preferred over API key)\n accessToken?: string;\n refreshToken?: string;\n tokenExpiresAt?: number; // Unix timestamp in ms\n // OAuth client registration (cached)\n clientId?: string;\n clientSecret?: string;\n}\n\nexport interface OAuthTokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token: string;\n scope: string;\n}\n\nexport interface OAuthClientRegistration {\n client_id: string;\n client_secret: string;\n client_id_issued_at: number;\n client_secret_expires_at: number;\n client_name: string;\n redirect_uris: string[];\n grant_types: string[];\n response_types: string[];\n token_endpoint_auth_method: string;\n scope: string;\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n}\n\nexport interface Presentation {\n id: string;\n slug: string;\n title: string;\n description?: string;\n numberOfSlides: number;\n mode?: string;\n createdAt: string;\n documentCreatedAt?: string;\n updatedAt?: string;\n viewUrl?: string;\n}\n\n/** File upload result from S3 */\nexport interface FileUploadResult {\n id: string;\n name: string;\n url: string;\n size: number;\n type: string;\n selected: boolean;\n}\n\n/** Presentation goal/purpose */\nexport type PresentationGoal =\n | \"inform\"\n | \"persuade\"\n | \"train\"\n | \"learn\"\n | \"entertain\"\n | \"report\";\n\nexport interface PresentationCreateOptions {\n topic: string;\n slideCount?: number;\n mode?: GenerationMode;\n tone?: GenerationTone;\n amount?: GenerationAmount;\n audience?: string;\n language?: string;\n brandId?: string;\n brandUrl?: string;\n sources?: string[];\n stdinContent?: string;\n /** Direct text context to include */\n context?: string;\n /** Path to a file containing context */\n contextFile?: string;\n stylingMode?: StylingMode;\n /** URL to use as a style reference (e.g., template image) */\n referenceUrl?: string;\n /** AI thinking depth: quick, moderate, deep, profound */\n thinkingDepth?: ThinkingDepth;\n /** Files uploaded to S3 (from --file option) */\n uploadedFiles?: FileUploadResult[];\n /** Presentation goal: inform, persuade, train, learn, entertain, report */\n goal?: PresentationGoal;\n /** Custom goal description (overrides preset goal) */\n customGoal?: string;\n /** Team ID to create presentation for (allows switching teams) */\n teamId?: string;\n /** Theme customization options */\n theme?: ThemeOptions;\n}\n\n/** AI thinking depth for content generation */\nexport type ThinkingDepth = \"quick\" | \"moderate\" | \"deep\" | \"profound\";\n\n/** Preset theme options */\nexport type ThemePreset = \"blue\" | \"violet\" | \"rose\" | \"orange\" | \"green\";\n\n/** Background decoration styles */\nexport type DecorationStyle = \"none\" | \"waves-bottom-left\" | \"waves-top-right\" | \"blob-corners\" | \"minimal\";\n\n/** Custom color overrides in hex format */\nexport interface ThemeCustomColors {\n primary?: string;\n secondary?: string;\n accent?: string;\n background?: string;\n foreground?: string;\n}\n\n/** Theme customization options for slide generation */\nexport interface ThemeOptions {\n /** Preset theme name */\n preset?: ThemePreset;\n /** Custom colors in hex format (e.g., \"#0066CC\") */\n custom?: ThemeCustomColors;\n /** Decoration style for slide backgrounds */\n decorations?: DecorationStyle;\n}\n\n/** Generation quality/speed mode */\nexport type GenerationMode =\n | \"best\"\n | \"balanced\"\n | \"fast\"\n | \"ultrafast\"\n | \"instant\";\n\n/** Presentation tone/style */\nexport type GenerationTone =\n | \"creative\"\n | \"professional\"\n | \"educational\"\n | \"formal\"\n | \"casual\";\n\n/** Content amount/density */\nexport type GenerationAmount = \"minimal\" | \"concise\" | \"detailed\" | \"extensive\";\n\nexport type StylingMode = \"freeform\" | \"brand-only\" | \"brand-plus-style\" | \"style-only\" | \"no-styling\";\n\nexport interface PresentationListItem {\n id: string;\n slug: string;\n title: string;\n numberOfSlides: number;\n mode?: string;\n createdAt: string;\n}\n\nexport interface CreatePresentationResponse {\n presentation: Presentation;\n viewUrl: string;\n}\n\nexport interface StreamEvent {\n type: string;\n data: unknown;\n}\n\nexport interface SlideProgressEvent {\n current: number;\n total: number;\n}\n\nexport interface Branding {\n id: string;\n name: string;\n logoUrl?: string;\n primaryColor?: string;\n isDefault: boolean;\n sourceUrl?: string;\n createdAt?: string;\n}\n\nexport interface BrandingExtractResult {\n id: string;\n brandData: Record<string, unknown>;\n}\n\nexport interface ExportOptions {\n includeImages?: boolean;\n includeBranding?: boolean;\n includeExternal?: boolean;\n}\n\nexport interface ImportOptions {\n dryRun?: boolean;\n overwrite?: boolean;\n remapIds?: boolean;\n}\n\nexport interface ImportResult {\n success: boolean;\n presentationId?: string;\n documentId?: string;\n errors?: Array<{ type: string; message: string }>;\n warnings?: string[];\n statistics?: {\n slidesImported: number;\n imagesUploaded: number;\n totalTimeMs: number;\n };\n}\n\nexport interface BlogGenerationOptions {\n targetWordCount?: number;\n tone?: \"professional\" | \"casual\" | \"educational\";\n targetAudience?: string;\n blogFormat?: string;\n customInstructions?: string;\n includeImages?: boolean;\n includeTableOfContents?: boolean;\n language?: string;\n}\n\nexport interface DeriveOptions {\n format?: OutputFormat;\n count?: number;\n mode?: string;\n}\n\nexport type OutputFormat = \"human\" | \"json\" | \"quiet\" | \"markdown\" | \"table\" | \"ids\";\n\nexport interface CLIOptions {\n output?: OutputFormat;\n debug?: boolean;\n noColor?: boolean;\n noStream?: boolean;\n}\n\nexport const EXIT_CODES = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n AUTH_ERROR: 2,\n NOT_FOUND: 3,\n RATE_LIMIT: 4,\n NETWORK_ERROR: 5,\n INVALID_INPUT: 6,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n","/**\n * Authentication Helpers\n * Handles OAuth tokens and API key validation\n */\n\nimport chalk from \"chalk\";\nimport {\n hasApiKey,\n getApiKey,\n getConfigPath,\n hasOAuthTokens,\n getAccessToken,\n getRefreshToken,\n isTokenExpired,\n setOAuthTokens,\n clearOAuthTokens,\n getClientId,\n getApiUrl,\n} from \"./config.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\nimport type { OAuthTokenResponse } from \"../types/index.js\";\n\n/**\n * Refresh OAuth access token using refresh token\n */\nasync function refreshAccessToken(): Promise<string | null> {\n const refreshToken = getRefreshToken();\n const clientId = getClientId();\n const apiUrl = getApiUrl();\n\n if (!refreshToken || !clientId) {\n return null;\n }\n\n try {\n // Fetch token endpoint from metadata\n const metaResponse = await fetch(`${apiUrl}/.well-known/oauth-authorization-server`);\n if (!metaResponse.ok) {\n return null;\n }\n const metadata = await metaResponse.json();\n\n // Refresh the token\n const params = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: clientId,\n });\n\n const response = await fetch(metadata.token_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: params.toString(),\n });\n\n if (!response.ok) {\n // Refresh token may be expired or revoked\n clearOAuthTokens();\n return null;\n }\n\n const tokens: OAuthTokenResponse = await response.json();\n setOAuthTokens(tokens.access_token, tokens.refresh_token, tokens.expires_in);\n return tokens.access_token;\n } catch {\n return null;\n }\n}\n\n/**\n * Get a valid access token, refreshing if needed\n * Returns null if no valid token available\n */\nexport async function getValidAccessToken(): Promise<string | null> {\n if (!hasOAuthTokens()) {\n return null;\n }\n\n if (isTokenExpired()) {\n // Try to refresh\n return refreshAccessToken();\n }\n\n return getAccessToken() || null;\n}\n\n/**\n * Check if the CLI is authenticated (OAuth or API key)\n */\nexport function hasAuth(): boolean {\n return hasOAuthTokens() || hasApiKey();\n}\n\n/**\n * Get the authentication method being used\n */\nexport function getAuthMethod(): \"oauth\" | \"apiKey\" | \"none\" {\n if (hasOAuthTokens()) return \"oauth\";\n if (hasApiKey()) return \"apiKey\";\n return \"none\";\n}\n\n/**\n * Check if the CLI is authenticated and exit if not\n * Prompts user to login if not authenticated\n */\nexport async function requireAuth(): Promise<void> {\n if (!hasAuth()) {\n // Dynamic import to avoid circular dependency\n const { confirm } = await import(\"@inquirer/prompts\");\n\n try {\n const shouldLogin = await confirm({\n message: chalk.red(\"Not authenticated.\") + \" Log in now?\",\n default: true,\n });\n\n if (!shouldLogin) {\n console.log(chalk.gray(\"\\nTip: You can also set CC_MINDFRAMES_API_KEY environment variable.\"));\n process.exit(EXIT_CODES.AUTH_ERROR);\n }\n\n // Run login flow\n const { runLoginFlow } = await import(\"../commands/login.js\");\n await runLoginFlow({ browser: true });\n } catch {\n // User cancelled (Ctrl+C)\n process.exit(EXIT_CODES.AUTH_ERROR);\n }\n }\n}\n\n/**\n * Mask API key for display (show first 10 and last 4 chars)\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 14) {\n return \"****\";\n }\n return `${key.slice(0, 10)}...${key.slice(-4)}`;\n}\n\n/**\n * Get masked API key for display\n */\nexport function getMaskedApiKey(): string | undefined {\n const key = getApiKey();\n if (!key) return undefined;\n return maskApiKey(key);\n}\n\n/**\n * Validate API key format\n * Accepts:\n * - Better Auth API keys: cc_slides_*\n * - MCP API keys: mcp_*\n * - Legacy formats: cc_sk_*, sk_*\n */\nexport function isValidApiKeyFormat(key: string): boolean {\n // API keys should start with specific prefixes\n const validPrefixes = [\"cc_slides_\", \"mcp_\", \"cc_sk_\", \"sk_\"];\n return validPrefixes.some((prefix) => key.startsWith(prefix));\n}\n\n","/**\n * API Client\n * Handles HTTP requests to the ConceptCraft API\n * Supports OAuth tokens (preferred) and API keys (fallback)\n */\n\nimport { getApiKey, getApiUrl } from \"./config.js\";\nimport { getValidAccessToken, hasAuth, getAuthMethod } from \"./auth.js\";\nimport { readFileSync, statSync } from \"fs\";\nimport { basename } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport type {\n ApiResponse,\n Presentation,\n PresentationListItem,\n PresentationCreateOptions,\n Branding,\n BrandingExtractResult,\n ExportOptions,\n ImportResult,\n BlogGenerationOptions,\n EXIT_CODES,\n FileUploadResult,\n TTSRequest,\n TTSResult,\n TTSVoicesResponse,\n MusicGenerationRequest,\n MusicGenerationResult,\n AudioMixRequest,\n AudioMixResult,\n ImageSearchRequest,\n ImageSearchResponse,\n VideoSearchRequest,\n VideoSearchResponse,\n} from \"../types/index.js\";\n\n/**\n * Get authorization headers for API requests\n * Prefers OAuth tokens, falls back to API key\n */\nasync function getAuthHeaders(): Promise<Record<string, string>> {\n // Try OAuth first (preferred)\n const accessToken = await getValidAccessToken();\n if (accessToken) {\n return { Authorization: `Bearer ${accessToken}` };\n }\n\n // Fall back to API key\n const apiKey = getApiKey();\n if (apiKey) {\n return { \"x-api-key\": apiKey };\n }\n\n return {};\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public statusCode: number,\n public exitCode: number = 1\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\ninterface RequestOptions {\n method?: \"GET\" | \"POST\" | \"DELETE\" | \"PUT\" | \"PATCH\";\n body?: unknown;\n headers?: Record<string, string>;\n stream?: boolean;\n}\n\nasync function request<T>(\n endpoint: string,\n options: RequestOptions = {}\n): Promise<T> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2 // AUTH_ERROR\n );\n }\n\n const authHeaders = await getAuthHeaders();\n const url = `${apiUrl}${endpoint}`;\n const headers: Record<string, string> = {\n ...authHeaders,\n ...options.headers,\n };\n\n if (options.body && !options.stream) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method: options.method ?? \"GET\",\n headers,\n };\n\n if (options.body) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, fetchOptions);\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5 // NETWORK_ERROR\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n let exitCode = 1; // GENERAL_ERROR\n\n switch (response.status) {\n case 401:\n exitCode = 2; // AUTH_ERROR\n break;\n case 403:\n exitCode = 2; // AUTH_ERROR (forbidden)\n break;\n case 404:\n exitCode = 3; // NOT_FOUND\n break;\n case 429:\n exitCode = 4; // RATE_LIMIT\n break;\n case 500:\n exitCode = 1; // SERVER_ERROR\n break;\n }\n\n // Ensure we always have an error message\n const message = errorText.trim() || `HTTP ${response.status}: ${response.statusText || \"Server error\"}`;\n throw new ApiError(message, response.status, exitCode);\n }\n\n if (options.stream) {\n return response as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text() as unknown as T;\n}\n\n// Streaming request for SSE endpoints\nexport async function streamRequest(\n endpoint: string,\n body: unknown\n): Promise<Response> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n const url = `${apiUrl}${endpoint}`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n let exitCode = 1;\n\n switch (response.status) {\n case 401:\n exitCode = 2;\n break;\n case 403:\n exitCode = 2;\n break;\n case 404:\n exitCode = 3;\n break;\n case 429:\n exitCode = 4;\n break;\n }\n\n throw new ApiError(errorText, response.status, exitCode);\n }\n\n return response;\n}\n\n// File Upload APIs\n\n/**\n * Get MIME type from file extension\n * Simple mapping without external dependencies\n */\nfunction getMimeType(filePath: string): string {\n const ext = filePath.toLowerCase().split(\".\").pop();\n const mimeTypes: Record<string, string> = {\n // Documents\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n // Images\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n // Text\n txt: \"text/plain\",\n md: \"text/markdown\",\n csv: \"text/csv\",\n json: \"application/json\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n ts: \"text/x-typescript\",\n py: \"text/x-python\",\n };\n return mimeTypes[ext || \"\"] || \"application/octet-stream\";\n}\n\n/**\n * Upload a single file to S3 via the CLI upload endpoint\n * Returns metadata in the format expected by contentSources.uploadedFiles\n */\nexport async function uploadFile(filePath: string): Promise<FileUploadResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n // Read file metadata\n const stat = statSync(filePath);\n const fileName = basename(filePath);\n const mimeType = getMimeType(filePath);\n\n // Step 1: Get presigned URL from API\n const presignedResponse = await fetch(`${apiUrl}/api/cli/files/upload`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n fileMetadata: {\n name: fileName,\n type: mimeType,\n size: stat.size,\n },\n }),\n });\n\n if (!presignedResponse.ok) {\n const errorText = await presignedResponse.text();\n throw new ApiError(\n errorText || \"Failed to get upload URL\",\n presignedResponse.status,\n 1\n );\n }\n\n const presigned = await presignedResponse.json();\n\n // Step 2: Upload file to S3 using presigned POST\n const fileBuffer = readFileSync(filePath);\n const formData = new FormData();\n\n // Add all presigned fields first (order matters for S3)\n for (const [key, value] of Object.entries(presigned.fields || {})) {\n formData.append(key, value as string);\n }\n\n // Add the file last (required by S3)\n const blob = new Blob([fileBuffer], { type: mimeType });\n formData.append(\"file\", blob, fileName);\n\n const uploadResponse = await fetch(presigned.url, {\n method: \"POST\",\n body: formData,\n });\n\n if (!uploadResponse.ok) {\n throw new ApiError(\n \"Failed to upload file to storage\",\n uploadResponse.status,\n 1\n );\n }\n\n // Return in the format expected by contentSources.uploadedFiles\n return {\n id: randomUUID(),\n name: fileName,\n url: presigned.fileUrl,\n size: stat.size,\n type: mimeType,\n selected: true,\n };\n}\n\n/**\n * Upload multiple files with optional progress callback\n */\nexport async function uploadFiles(\n filePaths: string[],\n onProgress?: (completed: number, total: number, fileName: string) => void\n): Promise<FileUploadResult[]> {\n const results: FileUploadResult[] = [];\n\n for (let i = 0; i < filePaths.length; i++) {\n const filePath = filePaths[i];\n const fileName = basename(filePath);\n\n onProgress?.(i, filePaths.length, fileName);\n\n const result = await uploadFile(filePath);\n results.push(result);\n }\n\n onProgress?.(filePaths.length, filePaths.length, \"\");\n return results;\n}\n\n// Presentation APIs\nexport async function createPresentation(\n options: PresentationCreateOptions\n): Promise<Response> {\n const body: Record<string, unknown> = {\n topic: options.topic,\n slideCount: options.slideCount ?? 10,\n mode: options.mode ?? \"balanced\",\n tone: options.tone ?? \"professional\",\n amount: options.amount ?? \"concise\",\n audience: options.audience ?? \"General Audience\",\n language: options.language ?? \"en\",\n stylingMode: options.stylingMode ?? \"freeform\",\n };\n\n // Add optional reference URL for styling\n if (options.referenceUrl) {\n body.referenceUrl = options.referenceUrl;\n }\n\n // Add thinking depth\n if (options.thinkingDepth) {\n body.thinkingDepth = options.thinkingDepth;\n }\n\n // Add goal\n if (options.goal) {\n body.goal = options.goal;\n }\n if (options.customGoal) {\n body.goal = options.customGoal; // Custom goal overrides preset\n }\n\n // Build contentSources with all context data\n const uploadedFiles: Array<any> = [];\n const contextFiles: Array<{ url?: string; content?: string; title?: string; mime?: string }> = [];\n\n // Add S3-uploaded files (from --file option)\n if (options.uploadedFiles && options.uploadedFiles.length > 0) {\n uploadedFiles.push(...options.uploadedFiles);\n }\n\n // Add URLs to scrape as contextFiles\n if (options.sources && options.sources.length > 0) {\n for (const url of options.sources) {\n contextFiles.push({ url });\n }\n }\n\n // Add stdin content as inline uploaded file\n if (options.stdinContent) {\n uploadedFiles.push({\n id: `stdin-${Date.now()}`,\n content: options.stdinContent,\n title: \"Piped Content\",\n mime: \"text/plain\",\n selected: true,\n });\n }\n\n // Add direct context as inline uploaded file\n if (options.context) {\n uploadedFiles.push({\n id: `context-${Date.now()}`,\n content: options.context,\n title: \"Context\",\n mime: \"text/plain\",\n selected: true,\n });\n }\n\n // Only include contentSources if we have data\n if (uploadedFiles.length > 0 || contextFiles.length > 0) {\n body.contentSources = {\n uploadedFiles,\n contextFiles,\n };\n }\n\n if (options.brandId) {\n body.designBrandReference = options.brandId;\n }\n\n // Add team ID if specified (allows switching teams)\n if (options.teamId) {\n body.teamId = options.teamId;\n }\n\n // Add theme options for customizing colors and decorations\n if (options.theme) {\n body.theme = options.theme;\n }\n\n return streamRequest(\"/api/slides/skills/create-presentation\", body);\n}\n\nexport async function listPresentations(\n teamId?: string,\n limit = 20\n): Promise<PresentationListItem[]> {\n const params = new URLSearchParams();\n params.set(\"limit\", String(limit));\n // Pass teamId if specified (allows switching teams)\n if (teamId) {\n params.set(\"teamId\", teamId);\n }\n\n // Use CLI-specific endpoint with API key auth\n // If teamId not specified, server uses API key's default team\n const response = await request<{ presentations: PresentationListItem[]; totalCount: number }>(\n `/api/cli/presentations?${params}`\n );\n return response.presentations;\n}\n\n// Get presentation by slug or ID\nexport async function getPresentation(slugOrId: string): Promise<Presentation> {\n return request<Presentation>(`/api/cli/presentation/${slugOrId}`);\n}\n\n// Delete presentation by slug or ID\nexport async function deletePresentation(slugOrId: string): Promise<void> {\n await request<string>(`/api/cli/presentation/${slugOrId}`, { method: \"DELETE\" });\n}\n\n// Export/Import APIs\nexport async function exportPresentation(\n presentationId: string,\n options: ExportOptions = {}\n): Promise<ArrayBuffer> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const response = await fetch(`${apiUrl}/api/presentations/export`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n presentationId,\n options: {\n includeImages: options.includeImages ?? true,\n includeBranding: options.includeBranding ?? true,\n downloadExternalImages: options.includeExternal ?? true,\n },\n }),\n });\n\n if (!response.ok) {\n throw new ApiError(\n await response.text(),\n response.status,\n response.status === 404 ? 3 : 1\n );\n }\n\n return response.arrayBuffer();\n}\n\nexport async function importPresentation(\n fileBuffer: Buffer,\n fileName: string,\n options: { dryRun?: boolean } = {}\n): Promise<ImportResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const formData = new FormData();\n const blob = new Blob([fileBuffer], { type: \"application/zip\" });\n formData.append(\"file\", blob, fileName);\n formData.append(\n \"options\",\n JSON.stringify({\n dryRun: options.dryRun ?? false,\n remapIds: true,\n })\n );\n\n const response = await fetch(`${apiUrl}/api/presentations/import`, {\n method: \"POST\",\n headers: authHeaders,\n body: formData,\n });\n\n const result = await response.json();\n\n if (!response.ok) {\n throw new ApiError(\n result.errors?.[0]?.message ?? \"Import failed\",\n response.status,\n 1\n );\n }\n\n return result;\n}\n\n// Branding APIs\nexport async function listBrandings(): Promise<{ brandings: Branding[] }> {\n return request<{ brandings: Branding[] }>(\"/api/branding\");\n}\n\nexport interface BrandingDetail {\n id: string;\n name: string;\n sourceUrl?: string;\n isDefault: boolean;\n createdAt?: string;\n primaryColor?: string;\n colors: Array<{ hex: string; role?: string }>;\n logoUrl?: string;\n logos: Record<string, unknown>;\n typography: Record<string, unknown>;\n confidence?: number;\n extractionMethod?: string;\n brandData?: Record<string, unknown>;\n}\n\nexport async function getBranding(id: string): Promise<BrandingDetail> {\n return request<BrandingDetail>(`/api/branding/${id}`);\n}\n\nexport async function extractBranding(\n url: string,\n teamId?: string\n): Promise<BrandingExtractResult> {\n return request<BrandingExtractResult>(\"/api/branding/extract\", {\n method: \"POST\",\n body: { url, teamId },\n });\n}\n\n// User/Team APIs\nexport interface WhoamiResponse {\n user: {\n id: string;\n email: string;\n username?: string;\n firstName?: string;\n lastName?: string;\n role?: string;\n };\n currentTeam: {\n id: string;\n name: string;\n planName: string;\n isOwner: boolean;\n } | null;\n teams: Array<{\n id: string;\n name: string;\n planName: string;\n role: string;\n isCurrent: boolean;\n }>;\n authType: \"session\" | \"apiKey\";\n}\n\nexport async function whoami(): Promise<WhoamiResponse> {\n return request<WhoamiResponse>(\"/api/cli/whoami\");\n}\n\n// Feature flags\nexport interface FeatureFlags {\n deckToBlog: boolean;\n deckToTweets: boolean;\n linkedInCarousel: boolean;\n redTeamQuestions: boolean;\n presenterCheatSheet: boolean;\n}\n\nexport async function getFeatureFlags(): Promise<FeatureFlags> {\n return request<FeatureFlags>(\"/api/cli/features\");\n}\n\n// Derivative content APIs\nexport async function generateBlog(\n presentationId: string,\n documentCreatedAt: string,\n options: BlogGenerationOptions = {}\n): Promise<Response> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'mindframes login' or set CC_MINDFRAMES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const response = await fetch(\n `${apiUrl}/api/presentations/${presentationId}/generate-blog`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n documentCreatedAt,\n targetWordCount: options.targetWordCount ?? 300,\n tone: options.tone ?? \"professional\",\n language: options.language ?? \"en\",\n targetAudience: options.targetAudience ?? \"General Audience\",\n blogFormat: options.blogFormat ?? \"narrative\",\n customInstructions: options.customInstructions ?? \"\",\n includeImages: options.includeImages ?? true,\n includeTableOfContents: options.includeTableOfContents ?? false,\n }),\n }\n );\n\n if (!response.ok) {\n throw new ApiError(\n await response.text(),\n response.status,\n response.status === 404 ? 3 : 1\n );\n }\n\n return response;\n}\n\n// Generation limits API\nexport interface GenerationLimits {\n teamId: string;\n planName: string;\n limits: Record<string, number>;\n usage: Record<string, number>;\n remaining: Record<string, number>;\n canGenerate: Record<string, boolean>;\n availableModes: string[];\n maxSlidesPerPresentation: number;\n maxStorageBytes: number;\n storageUsedBytes: number;\n}\n\n/**\n * Check generation limits before creating a presentation\n * Returns limits info including whether the specified mode can be used\n * @param teamId - Optional team ID to check limits for (if switching teams)\n */\nexport async function checkLimits(teamId?: string): Promise<GenerationLimits> {\n const params = new URLSearchParams();\n if (teamId) {\n params.set(\"teamId\", teamId);\n }\n const query = params.toString();\n return request<GenerationLimits>(`/api/cli/limits${query ? `?${query}` : \"\"}`);\n}\n\n/**\n * Validate that generation is possible with the specified mode and slide count\n * Throws ApiError if generation is not allowed\n * @param teamId - Optional team ID to validate for (if switching teams)\n */\nexport async function validateGeneration(\n mode: string,\n slideCount: number,\n teamId?: string\n): Promise<GenerationLimits> {\n const limits = await checkLimits(teamId);\n\n // Check if mode is available\n if (!limits.canGenerate[mode]) {\n const remaining = limits.remaining[mode] ?? 0;\n const limit = limits.limits[mode] ?? 0;\n\n if (limit === 0) {\n throw new ApiError(\n `The \"${mode}\" mode is not available on your ${limits.planName} plan. Available modes: ${limits.availableModes.join(\", \") || \"none\"}`,\n 403,\n 2\n );\n }\n\n throw new ApiError(\n `You have reached your ${mode} generation limit for this billing cycle (${limits.usage[mode] ?? 0}/${limit} used). Try a different mode: ${limits.availableModes.join(\", \") || \"none available\"}`,\n 403,\n 4\n );\n }\n\n // Check slide count\n if (slideCount > limits.maxSlidesPerPresentation) {\n throw new ApiError(\n `Maximum ${limits.maxSlidesPerPresentation} slides allowed on your ${limits.planName} plan (requested: ${slideCount})`,\n 403,\n 6\n );\n }\n\n return limits;\n}\n\n// ============================================================================\n// Media APIs (TTS, Music, Mix, Image Search)\n// ============================================================================\n\n/**\n * Generate speech from text using TTS\n */\nexport async function generateSpeech(ttsRequest: TTSRequest): Promise<TTSResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n \"Not authenticated. Run 'cc login' or set CC_SLIDES_API_KEY environment variable.\",\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n let response: Response;\n try {\n response = await fetch(`${apiUrl}/api/cli/tts`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(ttsRequest),\n });\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n let errorMessage: string;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || errorText;\n } catch {\n errorMessage = errorText;\n }\n throw new ApiError(errorMessage, response.status, response.status === 401 ? 2 : 1);\n }\n\n // TTS returns binary audio data with metadata in headers\n const audioData = Buffer.from(await response.arrayBuffer());\n const duration = parseFloat(response.headers.get(\"X-Duration-Seconds\") || \"0\");\n const cost = parseFloat(response.headers.get(\"X-Cost-USD\") || \"0\");\n const provider = response.headers.get(\"X-Provider\") || \"unknown\";\n const format = response.headers.get(\"X-Audio-Format\") || \"mp3\";\n\n // Parse timestamps if available (for audio-video sync)\n let timestamps: TTSResult[\"timestamps\"];\n const timestampsHeader = response.headers.get(\"X-Timestamps\");\n if (timestampsHeader) {\n try {\n timestamps = JSON.parse(timestampsHeader);\n } catch {\n // Ignore parse errors, timestamps are optional\n }\n }\n\n return {\n audioData,\n duration,\n cost,\n provider,\n format,\n timestamps,\n };\n}\n\n/**\n * Get available TTS voices\n */\nexport async function getVoices(): Promise<TTSVoicesResponse> {\n return request<TTSVoicesResponse>(\"/api/cli/tts\");\n}\n\n/**\n * Generate music from a text prompt\n */\nexport async function generateMusic(\n musicRequest: MusicGenerationRequest\n): Promise<MusicGenerationResult> {\n interface MusicApiResponse {\n success: boolean;\n data: {\n id: string;\n status: string;\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n };\n }\n\n const response = await request<MusicApiResponse>(\"/api/cli/music\", {\n method: \"POST\",\n body: musicRequest,\n });\n\n if (!response.data) {\n throw new ApiError(`Invalid API response: ${JSON.stringify(response)}`, 500, 1);\n }\n\n return {\n requestId: response.data.id,\n status: response.data.status as MusicGenerationResult[\"status\"],\n audioUrl: response.data.audioUrl,\n duration: response.data.duration,\n cost: response.data.cost,\n error: response.data.error,\n };\n}\n\n/**\n * Check status of a music generation request\n */\nexport async function checkMusicStatus(requestId: string): Promise<MusicGenerationResult> {\n interface MusicApiResponse {\n success: boolean;\n data: {\n id: string;\n status: string;\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n };\n }\n\n const response = await request<MusicApiResponse>(\n `/api/cli/music?requestId=${encodeURIComponent(requestId)}`\n );\n\n return {\n requestId: response.data.id,\n status: response.data.status as MusicGenerationResult[\"status\"],\n audioUrl: response.data.audioUrl,\n duration: response.data.duration,\n cost: response.data.cost,\n error: response.data.error,\n };\n}\n\n/**\n * Mix audio tracks\n */\nexport async function mixAudio(mixRequest: AudioMixRequest): Promise<AudioMixResult> {\n return request<AudioMixResult>(\"/api/cli/mix\", {\n method: \"POST\",\n body: mixRequest,\n });\n}\n\n/**\n * Check status of an audio mix request\n */\nexport async function checkMixStatus(requestId: string): Promise<AudioMixResult> {\n return request<AudioMixResult>(\n `/api/cli/mix?requestId=${encodeURIComponent(requestId)}`\n );\n}\n\n/**\n * Search for images\n */\nexport async function searchImages(\n searchRequest: ImageSearchRequest\n): Promise<ImageSearchResponse> {\n return request<ImageSearchResponse>(\"/api/cli/images/search\", {\n method: \"POST\",\n body: searchRequest,\n });\n}\n\n/**\n * Search for videos\n */\nexport async function searchVideos(\n searchRequest: VideoSearchRequest\n): Promise<VideoSearchResponse> {\n return request<VideoSearchResponse>(\"/api/cli/videos/search\", {\n method: \"POST\",\n body: searchRequest,\n });\n}\n\n/**\n * Poll for completion of an async operation\n */\nexport async function pollForCompletion<T extends { status: string }>(\n checkFn: () => Promise<T>,\n maxAttempts = 60,\n intervalMs = 2000\n): Promise<T> {\n for (let i = 0; i < maxAttempts; i++) {\n const result = await checkFn();\n if (result.status === \"completed\" || result.status === \"failed\") {\n return result;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new ApiError(\"Operation timed out\", 408, 1);\n}\n\nexport { request };\n","/**\n * Feature Flag Cache\n * Provides instant synchronous access to feature flags with stale-while-revalidate pattern\n *\n * Cache states:\n * - Fresh (< 1h): Return immediately\n * - Stale (1h-24h): Return immediately + background refresh\n * - Expired (> 24h): Return null (must fetch blocking on first command)\n * - Empty: Commands hidden until first auth\n */\n\nimport Conf from \"conf\";\nimport { getFeatureFlags, type FeatureFlags } from \"./api.js\";\nimport { hasApiKey, getApiKey } from \"./config.js\";\n\ninterface CachedFlags {\n flags: FeatureFlags;\n fetchedAt: number;\n apiKeyHash?: string; // Invalidate if key changes\n}\n\nconst cache = new Conf<{ featureFlags?: CachedFlags }>({\n projectName: \"conceptcraft\",\n configName: \"feature-cache\",\n});\n\nconst FRESH_TTL = 60 * 60 * 1000; // 1 hour\nconst STALE_TTL = 24 * 60 * 60 * 1000; // 24 hours\n\n/**\n * Simple hash for API key to detect changes\n */\nfunction hashApiKey(key: string): string {\n let hash = 0;\n for (let i = 0; i < key.length; i++) {\n const char = key.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash.toString(16);\n}\n\n/**\n * SYNC: Read from local cache (instant)\n * Returns cached flags or null if cache is empty/expired/invalid\n */\nexport function getCachedFlags(): FeatureFlags | null {\n if (!hasApiKey()) return null;\n\n const cached = cache.get(\"featureFlags\");\n if (!cached) return null;\n\n // Check if API key changed\n const currentKeyHash = hashApiKey(getApiKey()!);\n if (cached.apiKeyHash && cached.apiKeyHash !== currentKeyHash) {\n // API key changed, invalidate cache\n invalidateCache();\n return null;\n }\n\n const age = Date.now() - cached.fetchedAt;\n\n // Expired cache (> 24h) - treat as no cache\n if (age > STALE_TTL) return null;\n\n // Stale cache (1h-24h) - return but trigger background refresh\n if (age > FRESH_TTL) {\n refreshInBackground();\n }\n\n return cached.flags;\n}\n\n/**\n * ASYNC: Background refresh (non-blocking)\n * Silently updates cache without blocking the main thread\n */\nexport function refreshInBackground(): void {\n // Fire and forget\n fetchAndCache().catch(() => {\n // Silently fail - next command will try again\n });\n}\n\n/**\n * ASYNC: Fetch and update cache\n * Use after auth operations to populate cache\n */\nexport async function fetchAndCache(): Promise<FeatureFlags> {\n const flags = await getFeatureFlags();\n const apiKey = getApiKey();\n\n cache.set(\"featureFlags\", {\n flags,\n fetchedAt: Date.now(),\n apiKeyHash: apiKey ? hashApiKey(apiKey) : undefined,\n });\n\n return flags;\n}\n\n/**\n * Clear cache (on logout, key change, etc.)\n */\nexport function invalidateCache(): void {\n cache.delete(\"featureFlags\");\n}\n\n/**\n * Get cache file path (for debugging)\n */\nexport function getCachePath(): string {\n return cache.path;\n}\n\n/**\n * Check if cache exists and is not expired\n */\nexport function hasCachedFlags(): boolean {\n return getCachedFlags() !== null;\n}\n","/**\n * Login Command\n * OAuth 2.1 authentication flow with PKCE\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport http from \"http\";\nimport { randomBytes, createHash } from \"crypto\";\nimport open from \"open\";\nimport {\n getApiUrl,\n setOAuthTokens,\n setOAuthClient,\n getClientId,\n getClientSecret,\n hasOAuthTokens,\n setDefaultTeamId,\n} from \"../lib/config.js\";\nimport { success, error, info, warn, keyValue } from \"../lib/output.js\";\nimport { fetchAndCache } from \"../lib/feature-cache.js\";\nimport type { OAuthTokenResponse, OAuthClientRegistration } from \"../types/index.js\";\n\nconst CLI_CLIENT_NAME = \"ConceptCraft CLI\";\nconst CALLBACK_PORT_START = 8765;\nconst CALLBACK_PORT_END = 8775;\n\n/**\n * Generate PKCE code verifier (43-128 chars, URL-safe)\n */\nfunction generateCodeVerifier(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\n/**\n * Generate PKCE code challenge from verifier (S256)\n */\nfunction generateCodeChallenge(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\n/**\n * Generate state parameter for CSRF protection\n */\nfunction generateState(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n/**\n * Find an available port for the callback server\n */\nasync function findAvailablePort(start: number, end: number): Promise<number> {\n for (let port = start; port <= end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const server = http.createServer();\n server.listen(port, () => {\n server.close(() => resolve());\n });\n server.on(\"error\", reject);\n });\n return port;\n } catch {\n continue;\n }\n }\n throw new Error(`No available port found between ${start} and ${end}`);\n}\n\n/**\n * Fetch OAuth authorization server metadata\n */\nasync function getAuthServerMetadata(apiUrl: string): Promise<{\n authorization_endpoint: string;\n token_endpoint: string;\n registration_endpoint: string;\n}> {\n const response = await fetch(`${apiUrl}/.well-known/oauth-authorization-server`);\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth metadata: ${response.status}`);\n }\n return response.json();\n}\n\n/**\n * Register OAuth client dynamically (RFC 7591)\n */\nasync function registerClient(\n registrationEndpoint: string,\n redirectUri: string\n): Promise<OAuthClientRegistration> {\n const response = await fetch(registrationEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_name: CLI_CLIENT_NAME,\n redirect_uris: [redirectUri],\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\", // Public client with PKCE\n scope: \"presentations:read presentations:write\",\n }),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`Client registration failed: ${err}`);\n }\n\n return response.json();\n}\n\n/**\n * Exchange authorization code for tokens\n */\nasync function exchangeCodeForTokens(\n tokenEndpoint: string,\n code: string,\n codeVerifier: string,\n redirectUri: string,\n clientId: string\n): Promise<OAuthTokenResponse> {\n const params = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: codeVerifier,\n });\n\n const response = await fetch(tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: params.toString(),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`Token exchange failed: ${err}`);\n }\n\n return response.json();\n}\n\n/**\n * Start local callback server and wait for OAuth callback\n */\nfunction startCallbackServer(\n port: number,\n expectedState: string\n): Promise<{ code: string; state: string }> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let settled = false;\n\n const cleanup = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timeoutId);\n process.off(\"SIGINT\", onCancel);\n process.off(\"SIGTERM\", onCancel);\n server.close();\n };\n\n const onCancel = () => {\n cleanup();\n reject(new Error(\"Login cancelled\"));\n };\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || \"\", `http://localhost:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const errorParam = url.searchParams.get(\"error\");\n const errorDescription = url.searchParams.get(\"error_description\");\n\n // Send HTML response to browser\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n\n if (errorParam) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>${errorDescription || errorParam}</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(errorDescription || errorParam));\n return;\n }\n\n if (!code || !state) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>Missing authorization code or state</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(\"Missing authorization code or state\"));\n return;\n }\n\n if (state !== expectedState) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>State mismatch - possible CSRF attack</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(\"State mismatch\"));\n return;\n }\n\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Successful</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #16a34a;\">Login Successful!</h1>\n <p>You can close this window and return to the terminal.</p>\n </body>\n </html>\n `);\n\n cleanup();\n resolve({ code, state });\n });\n\n server.listen(port);\n\n // Handle Ctrl+C\n process.once(\"SIGINT\", onCancel);\n process.once(\"SIGTERM\", onCancel);\n\n // Timeout after 5 minutes\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error(\"Login timed out - no callback received within 5 minutes\"));\n }, 5 * 60 * 1000);\n });\n}\n\n/**\n * Fetch user info after login\n */\nasync function fetchWhoami(apiUrl: string, accessToken: string): Promise<{\n user: { email: string };\n teams: Array<{ id: string; name: string; planName: string; role: string; isCurrent: boolean }>;\n currentTeam: { id: string; name: string; planName: string } | null;\n}> {\n const response = await fetch(`${apiUrl}/api/cli/whoami`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch user info: ${response.status}`);\n }\n return response.json();\n}\n\n/**\n * Run the OAuth login flow\n * Exported so it can be called from requireAuth() prompt\n */\nexport async function runLoginFlow(options: { browser: boolean }): Promise<void> {\n const apiUrl = getApiUrl();\n let spinner = ora(\"Discovering OAuth server...\").start();\n\n try {\n // Step 1: Discover OAuth endpoints\n const metadata = await getAuthServerMetadata(apiUrl);\n spinner.succeed(\"Connecting to \" + apiUrl);\n\n // Step 2: Find available port for callback\n const port = await findAvailablePort(CALLBACK_PORT_START, CALLBACK_PORT_END);\n const redirectUri = `http://localhost:${port}/callback`;\n\n // Step 3: Register client (or use cached)\n let clientId = getClientId();\n let clientSecret = getClientSecret();\n\n if (!clientId) {\n const client = await registerClient(metadata.registration_endpoint, redirectUri);\n clientId = client.client_id;\n clientSecret = client.client_secret;\n setOAuthClient(clientId, clientSecret);\n }\n\n // Step 4: Generate PKCE parameters\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Step 5: Build authorization URL\n const authParams = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n scope: \"presentations:read presentations:write\",\n state,\n code_challenge: codeChallenge,\n code_challenge_method: \"S256\",\n });\n\n const authUrl = `${metadata.authorization_endpoint}?${authParams}`;\n\n // Step 6: Open browser and wait for callback\n if (options.browser) {\n info(\"Opening browser...\");\n await open(authUrl);\n } else {\n console.log(chalk.bold(\"Open this URL in your browser:\"));\n console.log(chalk.cyan(authUrl));\n }\n\n const callbackPromise = startCallbackServer(port, state);\n const { code } = await callbackPromise;\n\n // Step 7: Exchange code for tokens\n spinner = ora(\"Completing login...\").start();\n const tokens = await exchangeCodeForTokens(\n metadata.token_endpoint,\n code,\n codeVerifier,\n redirectUri,\n clientId\n );\n\n // Step 8: Store tokens\n setOAuthTokens(tokens.access_token, tokens.refresh_token, tokens.expires_in);\n\n // Step 9: Fetch user info and set default team\n const whoami = await fetchWhoami(apiUrl, tokens.access_token);\n spinner.succeed(\"Logged in!\");\n\n console.log();\n keyValue(\"Logged in as\", whoami.user.email);\n\n if (whoami.currentTeam) {\n setDefaultTeamId(whoami.currentTeam.id);\n keyValue(\"Team\", `${whoami.currentTeam.name} (${whoami.currentTeam.planName})`);\n }\n\n // Cache feature flags\n try {\n await fetchAndCache();\n } catch {\n // Non-critical\n }\n\n console.log();\n success(\"You're all set!\");\n console.log();\n } catch (err) {\n spinner.fail(\"Login failed\");\n error(err instanceof Error ? err.message : String(err));\n throw err; // Re-throw so caller can handle\n }\n}\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Authenticate with ConceptCraft (opens browser)\")\n .option(\"--no-browser\", \"Print URL instead of opening browser\")\n .action(async (options: { browser: boolean }) => {\n console.log();\n\n // Check if already logged in\n if (hasOAuthTokens()) {\n warn(\"You are already logged in.\");\n info(\"Run 'conceptcraft logout' to log out first, or continue to re-authenticate.\");\n console.log();\n }\n\n try {\n await runLoginFlow(options);\n process.exit(0);\n } catch {\n process.exit(1);\n }\n });\n","#!/usr/bin/env node\n/**\n * Slides CLI\n * A CLI tool for creating and managing AI-powered presentations\n * Supports whitelabeling for different brands (Conceptcraft, Mindframes, etc.)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\n\n// Import brand config (detects brand from command name)\nimport { brand } from \"./lib/brand.js\";\n\n// Import commands\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { configCommand } from \"./commands/config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { getCommand } from \"./commands/get.js\";\nimport { deleteCommand } from \"./commands/delete.js\";\nimport { exportCommand } from \"./commands/export.js\";\nimport { importCommand } from \"./commands/import.js\";\nimport { brandingCommand } from \"./commands/branding.js\";\nimport { buildDeriveCommand } from \"./commands/derive.js\";\nimport { ideasCommand } from \"./commands/ideas.js\";\nimport { whoamiCommand } from \"./commands/whoami.js\";\nimport { skillCommand } from \"./commands/skill.js\";\nimport { ttsCommand } from \"./commands/tts.js\";\nimport { musicCommand } from \"./commands/music.js\";\nimport { mixAudioCommand } from \"./commands/mix.js\";\nimport { imageCommand } from \"./commands/image.js\";\nimport { videoCommand } from \"./commands/video.js\";\n\n// Package version (injected by tsup at build time from package.json)\ndeclare const __VERSION__: string;\nconst VERSION = __VERSION__;\n\n// Synchronous startup - no async main() for instant --help response\nconst program = new Command();\n\n// Use the primary command name from brand config\nconst cmdName = brand.commands[0];\n\nprogram\n .name(cmdName)\n .description(brand.description)\n .version(VERSION, \"-v, --version\", \"Show version number\")\n .option(\"--debug\", \"Enable debug logging\")\n .option(\"--no-color\", \"Disable colored output\")\n .configureOutput({\n outputError: (str, write) => {\n write(chalk.red(str));\n },\n });\n\n// Register static commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(createCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(getCommand);\nprogram.addCommand(deleteCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(importCommand);\nprogram.addCommand(brandingCommand);\nprogram.addCommand(ideasCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(skillCommand);\nprogram.addCommand(ttsCommand);\nprogram.addCommand(musicCommand);\nprogram.addCommand(mixAudioCommand);\nprogram.addCommand(imageCommand);\nprogram.addCommand(videoCommand);\n\n// Build derive command from cached feature flags (synchronous, instant)\nconst deriveCommand = buildDeriveCommand();\n// Only add derive if it has subcommands (user has access to features)\nif (deriveCommand.commands.length > 0) {\n program.addCommand(deriveCommand);\n}\n\n// Handle unknown commands\nprogram.on(\"command:*\", (operands) => {\n console.error(chalk.red(`Error: Unknown command '${operands[0]}'`));\n console.error();\n console.error(`Run '${cmdName} --help' to see available commands.`);\n process.exit(1);\n});\n\n// Add examples to help text\nprogram.addHelpText(\n \"after\",\n `\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Log in (opens browser)\")}\n $ ${cmdName} login\n\n ${chalk.gray(\"# Create a presentation (recommended pattern)\")}\n $ ${cmdName} create \"Q4 Business Review\" \\\\\n -n 12 -m best \\\\\n --audience \"Executive leadership team\" \\\\\n --context \"Revenue: $50M (+25% YoY), New customers: 150\"\n\n ${chalk.gray(\"# Create from a file\")}\n $ ${cmdName} create \"Product Launch\" \\\\\n -n 10 -m balanced \\\\\n --audience \"Sales team and partners\" \\\\\n --context-file ./launch-brief.md\n\n ${chalk.gray(\"# Create from URLs\")}\n $ ${cmdName} create \"Market Analysis\" \\\\\n -n 15 -m best \\\\\n --audience \"Strategy team\" \\\\\n --sources https://example.com/report.pdf\n\n ${chalk.gray(\"# List and export\")}\n $ ${cmdName} list --format table\n $ ${cmdName} export <slug> -o backup.zip\n\n${chalk.bold(\"Authentication:\")}\n Run '${cmdName} login' to authenticate (recommended).\n Or set CC_MINDFRAMES_API_KEY environment variable for API key auth.\n\n${chalk.bold(\"More Info:\")}\n ${chalk.blue(brand.docsUrl)}\n`\n);\n\n// Parse and execute\nprogram.parse();\n","/**\n * Brand Configuration\n * Supports whitelabeling for different products (Conceptcraft, Mindframes, etc.)\n */\n\nimport path from \"path\";\n\nexport interface BrandConfig {\n id: string;\n name: string;\n displayName: string;\n description: string;\n commands: string[];\n apiUrl: string;\n docsUrl: string;\n packageName: string;\n configDir: string;\n}\n\nconst BRANDS: Record<string, BrandConfig> = {\n conceptcraft: {\n id: \"conceptcraft\",\n name: \"conceptcraft\",\n displayName: \"ConceptCraft\",\n description: \"CLI tool for ConceptCraft presentation generation\",\n commands: [\"cc\", \"conceptcraft\"],\n apiUrl: \"https://conceptcraft.ai\",\n docsUrl: \"https://docs.conceptcraft.ai\",\n packageName: \"@conceptcraft/cli\",\n configDir: \".conceptcraft\",\n },\n mindframes: {\n id: \"mindframes\",\n name: \"mindframes\",\n displayName: \"Mindframes\",\n description: \"CLI tool for Mindframes presentation generation\",\n commands: [\"mf\", \"mindframes\"],\n apiUrl: \"https://mindframes.app\",\n docsUrl: \"https://docs.mindframes.app\",\n packageName: \"@mindframes/cli\",\n configDir: \".mindframes\",\n },\n};\n\n// Map command aliases to brand IDs\nconst COMMAND_TO_BRAND: Record<string, string> = {\n cc: \"conceptcraft\",\n conceptcraft: \"conceptcraft\",\n mf: \"mindframes\",\n mindframes: \"mindframes\",\n};\n\n/**\n * Detect brand from the command used to invoke the CLI\n */\nexport function detectBrand(): BrandConfig {\n // Get the binary name from argv[1] (the executed script path)\n const binaryPath = process.argv[1] || \"\";\n const binaryName = path.basename(binaryPath).replace(/\\.(js|ts)$/, \"\");\n\n // Check if running via symlink (cc, mf, etc.) or directly (cli.js)\n const brandId = COMMAND_TO_BRAND[binaryName];\n\n if (brandId) {\n return BRANDS[brandId];\n }\n\n // Fallback: check if any command name is in the path\n for (const [cmd, id] of Object.entries(COMMAND_TO_BRAND)) {\n if (binaryPath.includes(`/${cmd}`) || binaryPath.includes(`\\\\${cmd}`)) {\n return BRANDS[id];\n }\n }\n\n // Default to mindframes (for cc-mindframes repo)\n return BRANDS.mindframes;\n}\n\n/**\n * Get brand config by ID\n */\nexport function getBrandById(id: string): BrandConfig | undefined {\n return BRANDS[id];\n}\n\n/**\n * Current brand (detected at startup)\n */\nexport const brand = detectBrand();\n","/**\n * Logout Command\n * Clear OAuth tokens and optionally API key\n */\n\nimport { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport {\n clearOAuthTokens,\n hasOAuthTokens,\n hasApiKey,\n clearConfig,\n} from \"../lib/config.js\";\nimport { invalidateCache } from \"../lib/feature-cache.js\";\nimport { success, info, warn } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Log out and clear authentication\")\n .option(\"--all\", \"Clear all config including API key\")\n .action(async (options: { all?: boolean }) => {\n console.log();\n\n const hasTokens = hasOAuthTokens();\n const hasKey = hasApiKey();\n\n if (!hasTokens && !hasKey) {\n warn(\"You are not logged in.\");\n console.log();\n return;\n }\n\n if (options.all) {\n try {\n const confirmed = await confirm({\n message: \"Clear all configuration including API key?\",\n default: false,\n });\n\n if (confirmed) {\n clearConfig();\n invalidateCache();\n success(\"All configuration cleared.\");\n } else {\n info(\"Cancelled.\");\n }\n } catch {\n info(\"Cancelled.\");\n }\n } else {\n // Just clear OAuth tokens, keep API key for enthusiasts\n clearOAuthTokens();\n invalidateCache();\n success(\"Logged out successfully.\");\n\n if (hasKey) {\n info(\"Note: Your API key is still configured. Use --all to clear everything.\");\n }\n }\n\n console.log();\n });\n","/**\n * Config Command\n * Manages CLI configuration (API key, URL, etc.)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { input, password, confirm, select } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport {\n getConfig,\n setApiKey,\n setApiUrl,\n setDefaultTeamId,\n getConfigPath,\n clearConfig,\n getApiUrl,\n getDefaultTeamId,\n} from \"../lib/config.js\";\nimport { getMaskedApiKey, isValidApiKeyFormat } from \"../lib/auth.js\";\nimport { whoami } from \"../lib/api.js\";\nimport { fetchAndCache, invalidateCache, getCachePath } from \"../lib/feature-cache.js\";\nimport { success, error, info, keyValue, header, warn } from \"../lib/output.js\";\n\nexport const configCommand = new Command(\"config\")\n .description(\"Manage CLI configuration\")\n .addCommand(\n new Command(\"init\")\n .description(\"Initialize configuration interactively\")\n .action(async () => {\n console.log();\n console.log(chalk.bold(\"ConceptCraft CLI Configuration\"));\n console.log(chalk.gray(\"─\".repeat(35)));\n console.log();\n\n try {\n // Get API key\n const apiKey = await password({\n message: \"Enter your API key:\",\n mask: \"*\",\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return \"API key is required\";\n }\n if (!isValidApiKeyFormat(value.trim())) {\n return \"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'\";\n }\n return true;\n },\n });\n\n setApiKey(apiKey.trim());\n\n // Optionally set custom API URL\n const useCustomUrl = await confirm({\n message: \"Use a custom API URL? (default: www.mindframes.app)\",\n default: false,\n });\n\n if (useCustomUrl) {\n const customUrl = await input({\n message: \"Enter API URL:\",\n default: getApiUrl(),\n validate: (value) => {\n try {\n new URL(value);\n return true;\n } catch {\n return \"Invalid URL format\";\n }\n },\n });\n setApiUrl(customUrl);\n }\n\n // Verify API key and fetch team info\n console.log();\n const spinner = ora(\"Verifying API key...\").start();\n\n try {\n const result = await whoami();\n spinner.succeed(\"API key verified!\");\n\n console.log();\n info(`Logged in as: ${result.user.email}`);\n\n // Handle team selection\n if (result.teams.length === 0) {\n warn(\"No teams found for this user.\");\n } else if (result.teams.length === 1) {\n // Single team - auto-select\n const team = result.teams[0];\n setDefaultTeamId(team.id);\n info(`Team: ${team.name} (${team.planName})`);\n } else {\n // Multiple teams - prompt for selection\n console.log();\n info(`You have access to ${result.teams.length} teams.`);\n\n const selectedTeamId = await select({\n message: \"Select your default team:\",\n choices: result.teams.map((team) => ({\n name: `${team.name} (${team.planName}) - ${team.role}${team.isCurrent ? \" [current]\" : \"\"}`,\n value: team.id,\n })),\n default: result.currentTeam?.id,\n });\n\n setDefaultTeamId(selectedTeamId);\n const selectedTeam = result.teams.find((t) => t.id === selectedTeamId);\n success(`Selected team: ${selectedTeam?.name}`);\n }\n\n // Fetch and cache feature flags for instant command availability\n try {\n await fetchAndCache();\n } catch {\n // Non-critical - flags will be fetched on next command\n }\n } catch (apiErr) {\n spinner.fail(\"Failed to verify API key\");\n warn(\n `Could not verify API key: ${apiErr instanceof Error ? apiErr.message : String(apiErr)}`\n );\n warn(\"You may need to set the team ID manually: mindframes config set team-id <id>\");\n }\n\n console.log();\n success(\"Configuration saved!\");\n info(`Config file: ${getConfigPath()}`);\n console.log();\n } catch (err) {\n // User cancelled\n if ((err as Error).name === \"ExitPromptError\") {\n console.log();\n info(\"Configuration cancelled.\");\n return;\n }\n throw err;\n }\n })\n )\n .addCommand(\n new Command(\"show\")\n .description(\"Show current configuration\")\n .option(\"--verify\", \"Verify API key and show team details\")\n .action(async (options: { verify?: boolean }) => {\n const config = getConfig();\n\n header(\"Current Configuration\");\n console.log();\n keyValue(\"API Key\", getMaskedApiKey() ?? chalk.red(\"Not set\"));\n keyValue(\"API URL\", config.apiUrl);\n keyValue(\"Default Team ID\", config.defaultTeamId ?? chalk.gray(\"Not set\"));\n console.log();\n keyValue(\"Config file\", getConfigPath());\n\n // If --verify flag is passed and we have an API key, fetch team details\n if (options.verify && config.apiKey) {\n console.log();\n const spinner = ora(\"Verifying...\").start();\n try {\n const result = await whoami();\n spinner.succeed(\"Verified\");\n console.log();\n keyValue(\"User\", result.user.email);\n if (result.currentTeam) {\n keyValue(\"Current Team\", `${result.currentTeam.name} (${result.currentTeam.planName})`);\n }\n if (result.teams.length > 1) {\n keyValue(\"Total Teams\", String(result.teams.length));\n }\n } catch (err) {\n spinner.fail(\"Verification failed\");\n warn(err instanceof Error ? err.message : String(err));\n }\n }\n console.log();\n })\n )\n .addCommand(\n new Command(\"set\")\n .description(\"Set a configuration value\")\n .argument(\"<key>\", \"Configuration key (api-key, api-url, team-id)\")\n .argument(\"<value>\", \"Value to set\")\n .action(async (key: string, value: string) => {\n switch (key) {\n case \"api-key\":\n if (!isValidApiKeyFormat(value)) {\n error(\"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'\");\n process.exit(6);\n }\n setApiKey(value);\n invalidateCache(); // Invalidate since key changed\n success(\"API key updated\");\n // Refresh feature flags in background\n fetchAndCache().catch(() => {});\n break;\n\n case \"api-url\":\n try {\n new URL(value);\n setApiUrl(value);\n success(`API URL set to: ${value}`);\n } catch {\n error(\"Invalid URL format\");\n process.exit(6);\n }\n break;\n\n case \"team-id\":\n setDefaultTeamId(value);\n success(`Default team ID set to: ${value}`);\n break;\n\n default:\n error(`Unknown config key: ${key}`);\n console.log(chalk.gray(\"Valid keys: api-key, api-url, team-id\"));\n process.exit(6);\n }\n })\n )\n .addCommand(\n new Command(\"clear\")\n .description(\"Clear all configuration\")\n .action(async () => {\n try {\n const confirmed = await confirm({\n message: \"Are you sure you want to clear all configuration?\",\n default: false,\n });\n\n if (confirmed) {\n clearConfig();\n invalidateCache();\n success(\"Configuration cleared\");\n } else {\n info(\"Cancelled\");\n }\n } catch {\n info(\"Cancelled\");\n }\n })\n )\n .addCommand(\n new Command(\"refresh\")\n .description(\"Refresh cached feature flags\")\n .action(async () => {\n const spinner = ora(\"Refreshing feature flags...\").start();\n try {\n await fetchAndCache();\n spinner.succeed(\"Feature flags refreshed\");\n info(\"Run 'conceptcraft --help' to see updated commands\");\n } catch (err) {\n spinner.fail(\"Failed to refresh\");\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n })\n )\n .addCommand(\n new Command(\"path\")\n .description(\"Show configuration file path\")\n .option(\"--cache\", \"Show feature cache file path\")\n .action((options: { cache?: boolean }) => {\n if (options.cache) {\n console.log(getCachePath());\n } else {\n console.log(getConfigPath());\n }\n })\n );\n","/**\n * Create Command\n * Creates a new presentation with streaming progress\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { createPresentation, uploadFiles, validateGeneration } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { streamWithProgress } from \"../lib/streaming.js\";\nimport { success, error, keyValue, header, buildViewUrl } from \"../lib/output.js\";\nimport type {\n GenerationMode,\n GenerationTone,\n GenerationAmount,\n StylingMode,\n OutputFormat,\n ThinkingDepth,\n PresentationGoal,\n FileUploadResult,\n ThemePreset,\n DecorationStyle,\n ThemeOptions,\n} from \"../types/index.js\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { resolve } from \"path\";\n\ninterface CreateOptions {\n slides: string;\n mode: GenerationMode;\n tone: GenerationTone;\n amount: GenerationAmount;\n audience: string;\n language: string;\n brand?: string;\n sources?: string[];\n context?: string;\n contextFile?: string;\n stdin?: boolean;\n styling: StylingMode;\n referenceUrl?: string;\n thinkingDepth: ThinkingDepth;\n output: OutputFormat;\n noStream?: boolean;\n debug?: boolean;\n // New options\n file?: string[];\n goal?: string;\n customGoal?: string;\n teamId?: string;\n // Theme options\n theme?: ThemePreset;\n primaryColor?: string;\n secondaryColor?: string;\n accentColor?: string;\n backgroundColor?: string;\n foregroundColor?: string;\n decorations?: DecorationStyle;\n // Browser options\n open?: boolean;\n}\n\nconst VALID_GOALS: PresentationGoal[] = [\n \"inform\",\n \"persuade\",\n \"train\",\n \"learn\",\n \"entertain\",\n \"report\",\n];\n\nexport const createCommand = new Command(\"create\")\n .description(\"Create a new presentation\")\n .argument(\"<topic>\", \"The topic or title for the presentation\")\n .option(\"-n, --slides <count>\", \"Number of slides (1-20)\", \"10\")\n .option(\n \"-m, --mode <mode>\",\n \"Generation quality mode (best, balanced, fast, ultrafast, instant)\",\n \"balanced\"\n )\n .option(\n \"-t, --tone <tone>\",\n \"Presentation tone (creative, professional, educational, formal, casual)\",\n \"professional\"\n )\n .option(\n \"--amount <amount>\",\n \"Content density (minimal, concise, detailed, extensive)\",\n \"concise\"\n )\n .option(\"--audience <text>\", \"Target audience description\", \"General Audience\")\n .option(\"-l, --language <lang>\", \"Output language\", \"en\")\n .option(\"-b, --brand <id|url>\", \"Branding ID or URL to extract from\")\n // Context/Source options\n .option(\n \"-c, --context <text>\",\n \"Text context to inform slide content (e.g., research notes, key facts)\"\n )\n .option(\n \"--context-file <path>\",\n \"Path to a file containing context (text, markdown, or JSON)\"\n )\n .option(\n \"--sources <urls...>\",\n \"URLs to scrape for context (space-separated). Content will be fetched and used\"\n )\n .option(\"--stdin\", \"Read context content from stdin (pipe data into the command)\")\n // File upload options\n .option(\n \"-f, --file <paths...>\",\n \"Files to upload (PDF, PPTX, DOCX, images). Use multiple times for multiple files\"\n )\n // Goal options\n .option(\n \"-g, --goal <type>\",\n \"Presentation goal (inform, persuade, train, learn, entertain, report)\"\n )\n .option(\n \"--custom-goal <text>\",\n \"Custom goal description (overrides --goal)\"\n )\n // Styling options\n .option(\n \"--styling <mode>\",\n \"Styling mode (freeform, brand-only, brand-plus-style, style-only, no-styling)\",\n \"freeform\"\n )\n .option(\n \"--reference-url <url>\",\n \"URL to an image or template to use as a style reference\"\n )\n // Generation options\n .option(\n \"--thinking-depth <depth>\",\n \"AI thinking depth (quick, moderate, deep, profound)\",\n \"moderate\"\n )\n // Theme options\n .option(\n \"--theme <preset>\",\n \"Color theme preset (blue, violet, rose, orange, green)\"\n )\n .option(\"--primary-color <hex>\", \"Primary color in hex (e.g., #0066CC)\")\n .option(\"--secondary-color <hex>\", \"Secondary color in hex\")\n .option(\"--accent-color <hex>\", \"Accent color in hex\")\n .option(\"--background-color <hex>\", \"Background color in hex\")\n .option(\"--foreground-color <hex>\", \"Foreground/text color in hex\")\n .option(\n \"--decorations <style>\",\n \"Background decoration style (none, waves-bottom-left, waves-top-right, blob-corners, minimal)\"\n )\n .option(\"-o, --output <format>\", \"Output format (human, json, quiet)\", \"human\")\n .option(\"--no-stream\", \"Wait for completion without progress display\")\n .option(\"--debug\", \"Enable debug logging\")\n .option(\"--team-id <id>\", \"Team ID to create presentation for (switch teams)\")\n .option(\"--open\", \"Open the presentation in browser after creation\")\n .addHelpText(\n \"after\",\n `\n${chalk.bold(\"Recommended Usage:\")}\n Always specify slides (-n), mode (-m), audience, and context for best results.\n\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Content from PDF + style from image reference\")}\n $ conceptcraft create \"Quarterly Report\" \\\\\n --file ./report.pdf \\\\\n --reference-url https://example.com/style-template.png \\\\\n -n 12 -m best --audience \"Executive team\"\n\n ${chalk.gray(\"# Upload content files (PDF, PPTX, DOCX)\")}\n $ conceptcraft create \"Product Demo\" \\\\\n --file ./existing-deck.pptx --file ./specs.pdf \\\\\n --goal persuade --audience \"Enterprise buyers\"\n\n ${chalk.gray(\"# Inline context with custom styling\")}\n $ conceptcraft create \"Q4 Business Review\" \\\\\n -n 12 -m best --goal inform \\\\\n --context \"Revenue: $50M (+25% YoY), EBITDA: $8M\" \\\\\n --reference-url https://example.com/brand-style.jpg\n\n ${chalk.gray(\"# Research presentation from URLs\")}\n $ conceptcraft create \"AI Industry Trends\" \\\\\n -n 10 -m best -t educational \\\\\n --sources https://example.com/ai-report.pdf\n\n ${chalk.gray(\"# Pipe content from another command\")}\n $ cat meeting-notes.md | conceptcraft create \"Meeting Summary\" \\\\\n -n 6 -m balanced --goal inform\n\n${chalk.bold(\"Content Options (what to include in slides):\")}\n -f, --file <paths...> Upload files for content extraction (PDF, PPTX, DOCX)\n -c, --context <text> Inline text (key facts, data points)\n --context-file <path> Read content from file (markdown, text, JSON)\n --sources <urls...> URLs to scrape for content\n --stdin Pipe content from another command\n\n${chalk.bold(\"Styling Options (how slides look):\")}\n --reference-url <url> ${chalk.yellow(\"Image URL to guide visual style\")} (colors, layout, feel)\n --styling <mode> freeform, brand-only, style-only, no-styling\n -b, --brand <id> Apply saved brand settings\n\n ${chalk.gray(\"NOTE: --file uploads provide CONTENT (data, text to include)\")}\n ${chalk.gray(\" --reference-url provides STYLE (visual design inspiration)\")}\n\n${chalk.bold(\"Goal Options:\")}\n -g, --goal <type> inform, persuade, train, learn, entertain, report\n --custom-goal <text> Custom goal description\n\n${chalk.bold(\"Theme Options:\")}\n --theme <preset> Preset color scheme (blue, violet, rose, orange, green)\n --primary-color <hex> Primary brand color (e.g., #0066CC)\n --secondary-color <hex> Secondary color for accents\n --decorations <style> Background style (none, waves-bottom-left, waves-top-right, blob-corners, minimal)\n\n ${chalk.gray(\"Example: Apply corporate colors\")}\n $ conceptcraft create \"Brand Deck\" \\\\\n --theme blue --primary-color \"#1E40AF\" --decorations waves-bottom-left\n\n${chalk.bold(\"Mode Reference:\")}\n best Highest quality, thorough research (recommended for important decks)\n balanced Good quality with reasonable speed (default)\n fast Quick generation, less refinement\n ultrafast Very quick, minimal processing\n instant Fastest, basic output (theme options work best with instant mode)\n`\n )\n .action(async (topic: string, options: CreateOptions) => {\n await requireAuth();\n\n const slideCount = parseInt(options.slides, 10);\n if (isNaN(slideCount) || slideCount < 1 || slideCount > 20) {\n error(\"Slide count must be between 1 and 20\");\n process.exit(6);\n }\n\n const validModes: GenerationMode[] = [\n \"best\",\n \"balanced\",\n \"fast\",\n \"ultrafast\",\n \"instant\",\n ];\n if (!validModes.includes(options.mode)) {\n error(\n `Invalid mode: ${options.mode}. Valid modes: ${validModes.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validTones: GenerationTone[] = [\n \"creative\",\n \"professional\",\n \"educational\",\n \"formal\",\n \"casual\",\n ];\n if (!validTones.includes(options.tone)) {\n error(\n `Invalid tone: ${options.tone}. Valid tones: ${validTones.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validAmounts: GenerationAmount[] = [\n \"minimal\",\n \"concise\",\n \"detailed\",\n \"extensive\",\n ];\n if (!validAmounts.includes(options.amount)) {\n error(\n `Invalid amount: ${options.amount}. Valid amounts: ${validAmounts.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validStyling: StylingMode[] = [\n \"freeform\",\n \"brand-only\",\n \"brand-plus-style\",\n \"style-only\",\n \"no-styling\",\n ];\n if (!validStyling.includes(options.styling)) {\n error(\n `Invalid styling: ${options.styling}. Valid modes: ${validStyling.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validThinkingDepths: ThinkingDepth[] = [\n \"quick\",\n \"moderate\",\n \"deep\",\n \"profound\",\n ];\n if (!validThinkingDepths.includes(options.thinkingDepth)) {\n error(\n `Invalid thinking depth: ${options.thinkingDepth}. Valid depths: ${validThinkingDepths.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate goal option\n if (options.goal && !VALID_GOALS.includes(options.goal as PresentationGoal)) {\n error(\n `Invalid goal: ${options.goal}. Valid goals: ${VALID_GOALS.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate theme options\n const validThemePresets: ThemePreset[] = [\"blue\", \"violet\", \"rose\", \"orange\", \"green\"];\n if (options.theme && !validThemePresets.includes(options.theme)) {\n error(\n `Invalid theme: ${options.theme}. Valid themes: ${validThemePresets.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validDecorations: DecorationStyle[] = [\n \"none\",\n \"waves-bottom-left\",\n \"waves-top-right\",\n \"blob-corners\",\n \"minimal\",\n ];\n if (options.decorations && !validDecorations.includes(options.decorations)) {\n error(\n `Invalid decorations: ${options.decorations}. Valid styles: ${validDecorations.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate hex color format\n const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;\n const colorOptions = [\n { name: \"primary-color\", value: options.primaryColor },\n { name: \"secondary-color\", value: options.secondaryColor },\n { name: \"accent-color\", value: options.accentColor },\n { name: \"background-color\", value: options.backgroundColor },\n { name: \"foreground-color\", value: options.foregroundColor },\n ];\n for (const { name, value } of colorOptions) {\n if (value && !hexColorRegex.test(value)) {\n error(`Invalid ${name}: ${value}. Must be a hex color (e.g., #0066CC or #06C)`);\n process.exit(6);\n }\n }\n\n // Build theme object if any theme options provided\n let theme: ThemeOptions | undefined;\n const hasCustomColors =\n options.primaryColor ||\n options.secondaryColor ||\n options.accentColor ||\n options.backgroundColor ||\n options.foregroundColor;\n\n if (options.theme || hasCustomColors || options.decorations) {\n theme = {};\n if (options.theme) {\n theme.preset = options.theme;\n }\n if (hasCustomColors) {\n theme.custom = {};\n if (options.primaryColor) theme.custom.primary = options.primaryColor;\n if (options.secondaryColor) theme.custom.secondary = options.secondaryColor;\n if (options.accentColor) theme.custom.accent = options.accentColor;\n if (options.backgroundColor) theme.custom.background = options.backgroundColor;\n if (options.foregroundColor) theme.custom.foreground = options.foregroundColor;\n }\n if (options.decorations) {\n theme.decorations = options.decorations;\n }\n }\n\n // Preflight check: validate generation limits BEFORE uploading files\n // This prevents wasting time/bandwidth on uploads if generation will fail\n try {\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n process.stdout.write(chalk.gray(\"Checking generation limits... \"));\n }\n const limits = await validateGeneration(options.mode, slideCount, options.teamId);\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(chalk.green(\"✓\"));\n console.log(\n chalk.gray(\n ` Plan: ${limits.planName} | ${options.mode}: ${limits.remaining[options.mode]}/${limits.limits[options.mode]} remaining`\n )\n );\n }\n } catch (err) {\n if (options.output === \"json\") {\n console.log(\n JSON.stringify({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n })\n );\n } else {\n console.log(chalk.red(\"✗\"));\n error(err instanceof Error ? err.message : String(err));\n }\n process.exit((err as any).exitCode ?? 1);\n }\n\n // Validate files exist before uploading\n let uploadedFiles: FileUploadResult[] = [];\n if (options.file && options.file.length > 0) {\n // Validate all files exist first\n for (const filePath of options.file) {\n const resolved = resolve(filePath);\n if (!existsSync(resolved)) {\n error(`File not found: ${filePath}`);\n process.exit(6);\n }\n }\n\n // Upload files with progress\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(chalk.gray(`\\nUploading ${options.file.length} file(s)...`));\n }\n\n try {\n uploadedFiles = await uploadFiles(\n options.file.map((f) => resolve(f)),\n (completed, total, fileName) => {\n if (options.output !== \"json\" && options.output !== \"quiet\" && fileName) {\n process.stdout.write(\n `\\r ${chalk.cyan(\"⬆\")} Uploading: ${fileName} (${completed + 1}/${total})`\n );\n }\n }\n );\n\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(`\\r ${chalk.green(\"✓\")} Uploaded ${uploadedFiles.length} file(s) `);\n }\n } catch (err) {\n error(\n `Failed to upload files: ${err instanceof Error ? err.message : String(err)}`\n );\n process.exit(1);\n }\n }\n\n // Auto-detect stdin content (or explicit --stdin flag)\n let stdinContent: string | undefined;\n const hasStdinData = !process.stdin.isTTY;\n if (options.stdin || hasStdinData) {\n stdinContent = await readStdin();\n if (options.stdin && !stdinContent) {\n error(\"No content received from stdin\");\n process.exit(6);\n }\n }\n\n // Read context from file if specified\n let contextContent: string | undefined = options.context;\n if (options.contextFile) {\n try {\n contextContent = readFileSync(options.contextFile, \"utf-8\");\n if (!contextContent.trim()) {\n error(`Context file is empty: ${options.contextFile}`);\n process.exit(6);\n }\n } catch (err) {\n error(`Failed to read context file: ${options.contextFile}`);\n process.exit(6);\n }\n }\n\n // Handle brand URL vs ID\n let brandId = options.brand;\n if (options.brand && isUrl(options.brand)) {\n // Brand URL provided - would need to extract first\n // For now, we'll pass it as-is and let the API handle it\n brandId = options.brand;\n }\n\n // Context is required for meaningful slide generation\n const hasContext =\n stdinContent ||\n contextContent ||\n (options.sources && options.sources.length > 0) ||\n uploadedFiles.length > 0;\n\n if (!hasContext) {\n error(\"Context is required to create a presentation.\");\n console.log();\n console.log(chalk.gray(\"Provide context using one of these methods:\"));\n console.log(chalk.gray(\" -f, --file <paths...> Upload files (PDF, PPTX, images)\"));\n console.log(chalk.gray(\" -c, --context <text> Direct text context\"));\n console.log(chalk.gray(\" --context-file <path> Read from a file\"));\n console.log(chalk.gray(\" --sources <urls...> URLs to scrape\"));\n console.log(chalk.gray(\" cat file | conceptcraft Pipe content\"));\n console.log();\n console.log(chalk.gray(\"Example:\"));\n console.log(chalk.cyan(\" conceptcraft create \\\"Q4 Report\\\" --file ./report.pdf\"));\n console.log(chalk.cyan(\" conceptcraft create \\\"Q4 Report\\\" --context \\\"Revenue: $10M, Growth: 25%\\\"\"));\n process.exit(6);\n }\n\n try {\n const response = await createPresentation({\n topic,\n slideCount,\n mode: options.mode,\n tone: options.tone,\n amount: options.amount,\n audience: options.audience,\n language: options.language,\n brandId,\n sources: options.sources,\n stdinContent,\n context: contextContent,\n stylingMode: options.styling,\n referenceUrl: options.referenceUrl,\n thinkingDepth: options.thinkingDepth,\n // New options\n uploadedFiles: uploadedFiles.length > 0 ? uploadedFiles : undefined,\n goal: options.goal as PresentationGoal | undefined,\n customGoal: options.customGoal,\n teamId: options.teamId,\n theme,\n });\n\n const result = await streamWithProgress(response, topic, {\n slideCount,\n mode: options.mode,\n tone: options.tone,\n language: options.language,\n noStream: options.noStream,\n debug: options.debug,\n quiet: options.output === \"quiet\",\n json: options.output === \"json\",\n });\n\n // Output result\n if (options.output === \"json\") {\n console.log(\n JSON.stringify(\n {\n success: true,\n presentation: {\n slug: result.slug,\n title: result.title ?? topic,\n slidesCount: result.slidesCount,\n elapsedSeconds: result.elapsedSeconds,\n totalTokens: result.totalTokens,\n },\n viewUrl: buildViewUrl(result.slug, options.language),\n },\n null,\n 2\n )\n );\n } else {\n // Show success output for both \"human\" and \"quiet\" modes\n // (quiet only hides the progress bar, not the final result)\n console.log();\n success(\"Presentation created successfully\");\n console.log();\n keyValue(\"Title\", result.title ?? topic);\n keyValue(\"Slides\", String(result.slidesCount ?? slideCount));\n // Show generation stats\n const stats: string[] = [];\n if (result.elapsedSeconds) {\n const mins = Math.floor(result.elapsedSeconds / 60);\n const secs = result.elapsedSeconds % 60;\n stats.push(mins > 0 ? `${mins}m ${secs}s` : `${secs}s`);\n }\n if (result.totalTokens) {\n stats.push(`${result.totalTokens.toLocaleString()} tokens`);\n }\n if (stats.length > 0) {\n keyValue(\"Generated in\", stats.join(\" · \"));\n }\n console.log();\n // Prominently display the URL\n const viewUrl = buildViewUrl(result.slug, options.language);\n if (viewUrl !== \"N/A\") {\n console.log(chalk.bold(\" Open: \") + chalk.cyan.underline(viewUrl));\n\n // Open browser if --open flag is set\n if (options.open) {\n const open = await import(\"open\");\n await open.default(viewUrl);\n }\n }\n console.log();\n }\n } catch (err) {\n if (options.output === \"json\") {\n console.log(\n JSON.stringify({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n })\n );\n } else {\n error(err instanceof Error ? err.message : String(err));\n }\n process.exit((err as any).exitCode ?? 1);\n }\n });\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n process.stdin.setEncoding(\"utf8\");\n\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n\n // Set a timeout for stdin\n setTimeout(() => {\n resolve(data.trim());\n }, 100);\n });\n}\n\nfunction isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return str.startsWith(\"http://\") || str.startsWith(\"https://\");\n }\n}\n","/**\n * SSE Streaming Handler\n * Handles Server-Sent Events from the create-presentation endpoint\n */\n\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { isTTY, progressBar } from \"./output.js\";\n\nexport interface StreamCallbacks {\n onProgress?: (current: number, total: number) => void;\n onSlide?: (slideNumber: number, totalSlides: number) => void;\n onPhase?: (phase: string, percentage: number) => void;\n onTokens?: (tokens: number) => void;\n onEstimatedTime?: (seconds: number) => void;\n onData?: (type: string, data: unknown) => void;\n onComplete?: (data: CompleteData) => void;\n onError?: (error: string) => void;\n}\n\nexport interface CompleteData {\n id?: string;\n slug?: string;\n title?: string;\n slidesCount?: number;\n elapsedSeconds?: number;\n totalTokens?: number;\n}\n\ninterface SSEData {\n type: string;\n data: unknown;\n}\n\n/**\n * Parse and handle SSE stream from the API\n */\nexport async function handleStream(\n response: Response,\n callbacks: StreamCallbacks,\n options: { noStream?: boolean; debug?: boolean } = {}\n): Promise<CompleteData> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new TextDecoder();\n let documentId: string | undefined;\n let slug: string | undefined;\n let title: string | undefined;\n let totalSlides = 0;\n let currentSlide = 0;\n let totalTokens = 0;\n let slideTokens: Record<string, number> = {};\n\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n // Skip [DONE] marker\n if (event.data === \"[DONE]\") return;\n\n try {\n // The event.data should be JSON\n const parsed: SSEData = JSON.parse(event.data);\n const { type, data } = parsed;\n\n if (options.debug) {\n console.log(chalk.gray(`[SSE] ${type}:`), data);\n }\n\n callbacks.onData?.(type, data);\n\n switch (type) {\n case \"data-id\":\n documentId = data as string;\n break;\n\n case \"data-slug\":\n slug = data as string;\n break;\n\n case \"data-title\":\n title = data as string;\n break;\n\n case \"data-slides-number-of-slides\":\n totalSlides = data as number;\n break;\n\n case \"data-slide-progress\": {\n const progress = data as { current: number; total: number };\n currentSlide = progress.current;\n totalSlides = progress.total;\n callbacks.onProgress?.(currentSlide, totalSlides);\n callbacks.onSlide?.(currentSlide, totalSlides);\n break;\n }\n\n case \"data-overall-progress\": {\n // Format: {\"percentage\":50,\"phase\":\"slide-generation\",\"details\":{\"slides\":{\"complete\":3,\"total\":6}}}\n const progress = data as {\n percentage: number;\n phase: string;\n details?: { slides?: { complete: number; total: number } };\n };\n // Update phase\n callbacks.onPhase?.(progress.phase, progress.percentage);\n // Update slide progress\n if (progress.details?.slides) {\n currentSlide = progress.details.slides.complete;\n totalSlides = progress.details.slides.total;\n callbacks.onProgress?.(currentSlide, totalSlides);\n callbacks.onSlide?.(currentSlide, totalSlides);\n }\n break;\n }\n\n case \"data-structure-tokens\": {\n // Cumulative structure tokens\n totalTokens = data as number;\n callbacks.onTokens?.(totalTokens);\n break;\n }\n\n case \"data-slide-meta-tokens\": {\n // Format: \"slideId:tokens\"\n const [slideId, tokens] = (data as string).split(\":\");\n if (slideId && tokens) {\n slideTokens[slideId] = parseInt(tokens, 10);\n // Calculate total: structure tokens + all slide tokens\n const allSlideTokens = Object.values(slideTokens).reduce((sum, t) => sum + t, 0);\n totalTokens = Math.max(totalTokens, allSlideTokens);\n callbacks.onTokens?.(totalTokens + allSlideTokens);\n }\n break;\n }\n\n case \"data-generation-meta-estimated-time\": {\n callbacks.onEstimatedTime?.(data as number);\n break;\n }\n\n case \"data-finish\":\n callbacks.onComplete?.({\n id: documentId,\n slug,\n title,\n slidesCount: totalSlides,\n });\n break;\n\n case \"error\":\n // Only report errors with actual messages\n if (data) {\n callbacks.onError?.(data as string);\n }\n break;\n }\n } catch (e) {\n // Not valid JSON, might be SSE text data\n if (options.debug) {\n console.log(chalk.gray(\"[SSE Raw]\"), event.data);\n }\n }\n },\n });\n\n // Read the stream\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n\n if (result.value) {\n const chunk = decoder.decode(result.value, { stream: true });\n parser.feed(chunk);\n }\n }\n\n return {\n id: documentId,\n slug,\n title,\n slidesCount: totalSlides,\n };\n}\n\n/**\n * Create presentation with progress display\n */\nexport async function streamWithProgress(\n response: Response,\n topic: string,\n options: {\n slideCount: number;\n mode: string;\n tone?: string;\n language: string;\n noStream?: boolean;\n debug?: boolean;\n quiet?: boolean;\n json?: boolean;\n }\n): Promise<CompleteData> {\n // In quiet mode, we only hide the progress bar, not the header or final output\n const useTTY = isTTY() && !options.noStream && !options.quiet && !options.json;\n\n if (!options.json) {\n console.log();\n console.log(chalk.bold(`Creating presentation: \"${topic}\"`));\n console.log(\n chalk.gray(\n `Quality: ${options.mode} | Tone: ${options.tone ?? \"professional\"} | Slides: ${options.slideCount} | Language: ${options.language}`\n )\n );\n console.log();\n }\n\n let spinner: ReturnType<typeof ora> | undefined;\n let lastProgress = \"\";\n let currentPhase = \"Preparing\";\n let currentPercentage = 0;\n let currentSlides = { done: 0, total: options.slideCount };\n let currentTokens = 0;\n let estimatedTime = 0;\n let startTime = Date.now();\n let timer: ReturnType<typeof setInterval> | undefined;\n\n // Format time as M:SS (fixed 4 chars: \"0:00\" to \"9:59\", then \"10:00\"+)\n const formatTime = (seconds: number): string => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, \"0\")}`;\n };\n\n // Get elapsed seconds\n const getElapsed = () => Math.floor((Date.now() - startTime) / 1000);\n\n // Get time remaining (or \"—:——\" if not estimated yet)\n const getRemaining = (): string => {\n if (!estimatedTime) return \" —:——\";\n const remaining = Math.max(0, estimatedTime - getElapsed());\n if (remaining === 0 && currentPercentage < 100) return \"soon!\";\n return formatTime(remaining);\n };\n\n // Format tokens (fixed 5 chars: \" 0tk\" to \"99.9k\")\n const formatTokens = (tokens: number): string => {\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}k`.padStart(5, \" \");\n }\n return `${tokens}tk`.padStart(5, \" \");\n };\n\n // User-friendly phase names (fixed 9 chars for stability)\n const getPhaseLabel = (phase: string): string => {\n const phaseMap: Record<string, string> = {\n \"structure-generation\": \"Planning \",\n \"slide-generation\": \"Writing \",\n \"image-generation\": \"Images \",\n \"assembling\": \"Finishing\",\n \"completed\": \"Done \",\n };\n return phaseMap[phase] || \"Working \";\n };\n\n // Build stable progress line (all fixed width)\n // Format: [████████░░░░░░░░░░░░░░░░] 45% Planning 3/10 1.2k 0:45 left\n const buildProgressLine = () => {\n const bar = progressBar(currentPercentage, 100, 20, false);\n const pct = String(currentPercentage).padStart(3, \" \");\n const phase = getPhaseLabel(currentPhase);\n const slides = `${String(currentSlides.done).padStart(2, \" \")}/${String(currentSlides.total).padEnd(2, \" \")}`;\n const tokens = formatTokens(currentTokens);\n const elapsed = formatTime(getElapsed()).padStart(5, \" \");\n const remaining = getRemaining().padStart(5, \" \");\n\n return `${bar} ${chalk.bold(pct)}${chalk.gray(\"%\")} ${chalk.cyan(phase)} ${chalk.gray(slides)} ${chalk.yellow(tokens)} ${chalk.gray(elapsed)} ${chalk.green(remaining + \" left\")}`;\n };\n\n if (useTTY) {\n spinner = ora({\n text: buildProgressLine(),\n spinner: \"dots\",\n }).start();\n\n // Update display every 100ms for smooth animation\n timer = setInterval(() => {\n if (spinner && spinner.isSpinning) {\n spinner.text = buildProgressLine();\n }\n }, 100);\n }\n\n const result = await handleStream(\n response,\n {\n onProgress: (current, total) => {\n currentSlides = { done: current, total };\n if (!useTTY && !options.quiet && !options.json) {\n const progress = `${currentPhase.trim()}: slide ${current}/${total}`;\n if (progress !== lastProgress) {\n console.log(progress);\n lastProgress = progress;\n }\n }\n },\n onPhase: (phase, percentage) => {\n currentPhase = getPhaseLabel(phase);\n currentPercentage = percentage;\n },\n onTokens: (tokens) => {\n currentTokens = tokens;\n },\n onEstimatedTime: (seconds) => {\n estimatedTime = seconds;\n },\n onError: (error) => {\n if (timer) clearInterval(timer);\n if (spinner) {\n spinner.fail(chalk.red(`Error: ${error}`));\n } else if (!options.json) {\n console.error(chalk.red(`Error: ${error}`));\n }\n },\n onComplete: (data) => {\n if (timer) clearInterval(timer);\n if (spinner) {\n currentPercentage = 100;\n currentPhase = \"Done\";\n spinner.succeed(buildProgressLine());\n } else if (!options.json) {\n // Show completion message in both human and quiet modes\n const tokenStr = currentTokens > 0 ? ` | ${currentTokens.toLocaleString()} tokens` : \"\";\n console.log(`Done! [${formatTime(getElapsed())}${tokenStr}]`);\n }\n },\n },\n { debug: options.debug }\n );\n\n // Return result with elapsed time and tokens\n return {\n ...result,\n elapsedSeconds: getElapsed(),\n totalTokens: currentTokens,\n };\n}\n\n/**\n * Stream text content (for blog generation, etc.)\n * Handles plain text streaming from toTextStreamResponse()\n */\nexport async function streamTextContent(\n response: Response,\n options: { quiet?: boolean } = {}\n): Promise<string> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new TextDecoder();\n let content = \"\";\n\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n\n if (result.value) {\n const chunk = decoder.decode(result.value, { stream: true });\n content += chunk;\n if (!options.quiet) {\n process.stdout.write(chunk);\n }\n }\n }\n\n if (!options.quiet) {\n console.log(); // Final newline\n }\n\n return content;\n}\n","/**\n * List Command\n * Lists presentations for the current user/team\n */\n\nimport { Command } from \"commander\";\nimport { listPresentations } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getDefaultTeamId } from \"../lib/config.js\";\nimport {\n formatPresentationTable,\n formatPresentationIds,\n error,\n info,\n} from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface ListOptions {\n limit: string;\n format: OutputFormat | \"ids\" | \"table\";\n sort?: string;\n teamId?: string;\n detail?: boolean;\n language: string;\n}\n\nexport const listCommand = new Command(\"list\")\n .description(\"List presentations\")\n .option(\"-n, --limit <count>\", \"Number of results to return\", \"20\")\n .option(\n \"-f, --format <format>\",\n \"Output format (table, json, ids)\",\n \"table\"\n )\n .option(\"--sort <field>\", \"Sort by field (created, updated, title)\")\n .option(\"--team-id <id>\", \"Team ID (uses default if not specified)\")\n .option(\"-d, --detail\", \"Show detailed output including URLs\")\n .option(\"-l, --language <lang>\", \"Language for URLs\", \"en\")\n .action(async (options: ListOptions) => {\n await requireAuth();\n\n const limit = parseInt(options.limit, 10);\n if (isNaN(limit) || limit < 1) {\n error(\"Invalid limit value\");\n process.exit(6);\n }\n\n const teamId = options.teamId ?? getDefaultTeamId();\n\n if (!teamId) {\n error(\n \"Team ID required. Set a default with 'mindframes config set team-id <id>' or use --team-id\"\n );\n process.exit(6);\n }\n\n try {\n const presentations = await listPresentations(teamId, limit);\n\n if (presentations.length === 0) {\n if (options.format === \"json\") {\n console.log(JSON.stringify([]));\n } else if (options.format !== \"ids\") {\n info(\"No presentations found\");\n }\n return;\n }\n\n // Sort if requested\n if (options.sort) {\n presentations.sort((a, b) => {\n switch (options.sort) {\n case \"created\":\n return (\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n );\n case \"title\":\n return (a.title || \"\").localeCompare(b.title || \"\");\n default:\n return 0;\n }\n });\n }\n\n switch (options.format) {\n case \"json\":\n console.log(JSON.stringify(presentations, null, 2));\n break;\n case \"ids\":\n console.log(formatPresentationIds(presentations));\n break;\n case \"table\":\n default:\n console.log(formatPresentationTable(presentations, {\n showLinks: options.detail,\n language: options.language,\n }));\n break;\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Get Command\n * Gets details of a specific presentation\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { getPresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { error, header, keyValue, formatDate, buildViewUrl } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface GetOptions {\n format: OutputFormat | \"summary\" | \"full\";\n include?: string;\n language: string;\n}\n\nexport const getCommand = new Command(\"get\")\n .description(\"Get presentation details\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\n \"-f, --format <format>\",\n \"Output format (summary, full, json)\",\n \"summary\"\n )\n .option(\"--include <fields>\", \"Fields to include (comma-separated: slides,styling)\")\n .option(\"-l, --language <lang>\", \"Language for view URL\", \"en\")\n .action(async (slug: string, options: GetOptions) => {\n await requireAuth();\n\n try {\n const presentation = await getPresentation(slug);\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(presentation, null, 2));\n return;\n }\n\n const viewUrl = buildViewUrl(presentation.slug, options.language);\n\n header(\"Presentation Details\");\n console.log();\n keyValue(\"Slug\", presentation.slug);\n keyValue(\"Title\", presentation.title || \"Untitled\");\n keyValue(\"Description\", presentation.description || chalk.gray(\"None\"));\n keyValue(\"Slides\", String(presentation.numberOfSlides || \"-\"));\n keyValue(\"Mode\", presentation.mode || \"-\");\n keyValue(\"Created\", formatDate(presentation.createdAt));\n if (presentation.updatedAt) {\n keyValue(\"Updated\", formatDate(presentation.updatedAt));\n }\n console.log();\n if (viewUrl !== \"N/A\") {\n console.log(chalk.bold(\" Open: \") + chalk.cyan.underline(viewUrl));\n }\n console.log();\n\n if (options.format === \"full\" && options.include?.includes(\"slides\")) {\n console.log(chalk.gray(\"(Full slide content available in JSON format)\"));\n console.log();\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Delete Command\n * Deletes a presentation\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { deletePresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { success, error, warn } from \"../lib/output.js\";\n\ninterface DeleteOptions {\n force?: boolean;\n quiet?: boolean;\n}\n\nexport const deleteCommand = new Command(\"delete\")\n .description(\"Delete a presentation\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\"-f, --force\", \"Skip confirmation prompt\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (slug: string, options: DeleteOptions) => {\n await requireAuth();\n\n // Confirm deletion unless --force is used\n if (!options.force) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete presentation \"${slug}\"?`,\n default: false,\n });\n\n if (!confirmed) {\n if (!options.quiet) {\n warn(\"Deletion cancelled\");\n }\n return;\n }\n } catch {\n if (!options.quiet) {\n warn(\"Deletion cancelled\");\n }\n return;\n }\n }\n\n try {\n await deletePresentation(slug);\n\n if (!options.quiet) {\n success(`Presentation \"${slug}\" deleted`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Export Command\n * Exports a presentation to a ZIP file\n */\n\nimport { Command } from \"commander\";\nimport { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { exportPresentation, getPresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { success, error, info } from \"../lib/output.js\";\n\ninterface ExportOptions {\n output?: string;\n includeImages?: boolean;\n includeBranding?: boolean;\n noExternal?: boolean;\n}\n\nexport const exportCommand = new Command(\"export\")\n .description(\"Export a presentation to ZIP\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--include-images\", \"Include images (default: true)\", true)\n .option(\"--include-branding\", \"Include branding (default: true)\", true)\n .option(\"--no-external\", \"Skip external image downloads\")\n .action(async (slug: string, options: ExportOptions) => {\n await requireAuth();\n\n const spinner = ora(\"Fetching presentation...\").start();\n\n try {\n // Get presentation info - this also validates access and gets the ID\n const presentation = await getPresentation(slug);\n const title = presentation.title || slug;\n const presentationId = presentation.id;\n\n // Generate filename from slug (cleaner than title)\n const sanitizedSlug = slug\n .replace(/[^a-z0-9-]/gi, \"_\")\n .toLowerCase()\n .substring(0, 50);\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const defaultFileName = `${sanitizedSlug}_${timestamp}.zip`;\n\n const outputPath = options.output\n ? resolve(options.output)\n : resolve(process.cwd(), defaultFileName);\n\n spinner.text = `Exporting \"${title}\"...`;\n\n const buffer = await exportPresentation(presentationId, {\n includeImages: options.includeImages,\n includeBranding: options.includeBranding,\n includeExternal: !options.noExternal,\n });\n\n spinner.text = \"Saving file...\";\n\n await writeFile(outputPath, Buffer.from(buffer));\n\n spinner.succeed(\"Export complete!\");\n console.log();\n info(`File saved: ${outputPath}`);\n info(`Size: ${formatBytes(buffer.byteLength)}`);\n console.log();\n } catch (err) {\n spinner.fail(\"Export failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","/**\n * Import Command\n * Imports a presentation from a ZIP file\n */\n\nimport { Command } from \"commander\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve, basename } from \"node:path\";\nimport ora from \"ora\";\nimport { importPresentation, whoami } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { error, warn, info, keyValue } from \"../lib/output.js\";\nimport { getApiUrl } from \"../lib/config.js\";\n\ninterface ImportOptions {\n dryRun?: boolean;\n overwrite?: boolean;\n remapIds?: boolean;\n}\n\nconst cmd = new Command(\"import\")\n .description(\"Import a presentation from ZIP (admin only)\")\n .argument(\"<file>\", \"Path to ZIP file\");\n\n// Hide from help output (admin-only command)\n(cmd as any)._hidden = true;\n\nexport const importCommand = cmd\n .option(\"--dry-run\", \"Validate without importing\")\n .option(\"--overwrite\", \"Overwrite existing presentations\")\n .option(\"--remap-ids\", \"Generate new IDs (default: true)\", true)\n .action(async (file: string, options: ImportOptions) => {\n await requireAuth();\n\n // Check if user is admin\n try {\n const me = await whoami();\n if (me.user.role !== \"admin\") {\n error(\"This command is only available to administrators\");\n process.exit(2);\n }\n } catch (err) {\n error(\"Failed to verify permissions\");\n process.exit(2);\n }\n\n const filePath = resolve(file);\n const fileName = basename(filePath);\n\n if (!fileName.endsWith(\".zip\")) {\n error(\"File must be a ZIP archive\");\n process.exit(6);\n }\n\n const spinner = ora(\"Reading file...\").start();\n\n try {\n const fileBuffer = await readFile(filePath);\n\n if (options.dryRun) {\n spinner.text = \"Validating...\";\n } else {\n spinner.text = \"Importing presentation...\";\n }\n\n const result = await importPresentation(fileBuffer, fileName, {\n dryRun: options.dryRun,\n });\n\n if (result.success) {\n if (options.dryRun) {\n spinner.succeed(\"Validation passed!\");\n console.log();\n info(\"The file is valid and can be imported.\");\n\n if (result.statistics) {\n console.log();\n keyValue(\"Slides\", String(result.statistics.slidesImported));\n keyValue(\"Images\", String(result.statistics.imagesUploaded));\n }\n } else {\n spinner.succeed(\"Import complete!\");\n console.log();\n keyValue(\"Presentation ID\", result.presentationId ?? \"N/A\");\n keyValue(\"Document ID\", result.documentId ?? \"N/A\");\n\n if (result.statistics) {\n keyValue(\"Slides imported\", String(result.statistics.slidesImported));\n keyValue(\"Images uploaded\", String(result.statistics.imagesUploaded));\n keyValue(\"Time\", `${result.statistics.totalTimeMs}ms`);\n }\n\n if (result.presentationId) {\n const apiUrl = getApiUrl();\n keyValue(\"View URL\", `${apiUrl}/p/${result.presentationId}`);\n }\n }\n\n if (result.warnings && result.warnings.length > 0) {\n console.log();\n for (const warning of result.warnings) {\n warn(warning);\n }\n }\n\n console.log();\n } else {\n spinner.fail(\"Import failed\");\n console.log();\n\n if (result.errors) {\n for (const err of result.errors) {\n error(`${err.type}: ${err.message}`);\n }\n }\n\n process.exit(1);\n }\n } catch (err) {\n spinner.fail(\"Import failed\");\n\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n error(`File not found: ${filePath}`);\n process.exit(3);\n }\n\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Branding Command\n * Manages brand profiles\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { listBrandings, extractBranding, getBranding } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getDefaultTeamId } from \"../lib/config.js\";\nimport {\n formatBrandingTable,\n success,\n error,\n info,\n keyValue,\n header,\n} from \"../lib/output.js\";\n\ninterface ListOptions {\n format?: \"table\" | \"json\";\n}\n\ninterface ExtractOptions {\n teamId?: string;\n save?: boolean;\n}\n\nexport const brandingCommand = new Command(\"branding\")\n .description(\"Manage brand profiles\")\n .addCommand(\n new Command(\"list\")\n .description(\"List brand profiles\")\n .option(\"-f, --format <format>\", \"Output format (table, json)\", \"table\")\n .action(async (options: ListOptions) => {\n await requireAuth();\n\n try {\n const result = await listBrandings();\n\n if (result.brandings.length === 0) {\n if (options.format === \"json\") {\n console.log(JSON.stringify([]));\n } else {\n info(\"No brand profiles found\");\n console.log();\n console.log(\n chalk.gray(\n \"Create one with: conceptcraft branding extract <url>\"\n )\n );\n }\n return;\n }\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(result.brandings, null, 2));\n } else {\n console.log(formatBrandingTable(result.brandings));\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"get\")\n .description(\"Get brand profile details\")\n .argument(\"<id>\", \"Brand profile ID\")\n .option(\"-f, --format <format>\", \"Output format (summary, json)\", \"summary\")\n .action(async (id: string, options: { format?: string }) => {\n await requireAuth();\n\n try {\n const brand = await getBranding(id);\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(brand, null, 2));\n } else {\n header(\"Brand Profile\");\n console.log();\n keyValue(\"ID\", brand.id);\n keyValue(\"Name\", brand.name);\n keyValue(\"Source URL\", brand.sourceUrl ?? chalk.gray(\"None\"));\n keyValue(\"Default\", brand.isDefault ? chalk.green(\"Yes\") : \"No\");\n if (brand.createdAt) {\n keyValue(\"Created\", new Date(brand.createdAt).toLocaleString());\n }\n console.log();\n\n // Colors with visual swatches\n if (brand.primaryColor || brand.colors.length > 0) {\n console.log(chalk.bold(\" Colors\"));\n if (brand.primaryColor) {\n const swatch = chalk.bgHex(brand.primaryColor)(\" \");\n console.log(` Primary: ${swatch} ${brand.primaryColor}`);\n }\n if (brand.colors.length > 0) {\n console.log(\" Palette:\");\n for (const c of brand.colors.slice(0, 10)) {\n const swatch = chalk.bgHex(c.hex)(\" \");\n const role = c.role ? chalk.gray(` (${c.role})`) : \"\";\n console.log(` ${swatch} ${c.hex}${role}`);\n }\n }\n console.log();\n }\n\n // Logo\n if (brand.logoUrl) {\n console.log(chalk.bold(\" Logo\"));\n console.log(` ${brand.logoUrl}`);\n console.log();\n }\n\n // Typography\n const typo = brand.typography as Record<string, unknown>;\n if (typo && Object.keys(typo).length > 0) {\n console.log(chalk.bold(\" Typography\"));\n if (typo.primary || typo.headings) {\n console.log(` Headings: ${typo.primary || typo.headings || \"-\"}`);\n }\n if (typo.secondary || typo.body) {\n console.log(` Body: ${typo.secondary || typo.body || \"-\"}`);\n }\n console.log();\n }\n\n // Extraction info\n if (brand.confidence || brand.extractionMethod) {\n console.log(chalk.bold(\" Extraction\"));\n if (brand.confidence) {\n console.log(` Confidence: ${Math.round(brand.confidence * 100)}%`);\n }\n if (brand.extractionMethod) {\n console.log(` Method: ${brand.extractionMethod}`);\n }\n console.log();\n }\n\n console.log(chalk.gray(\" Use --format json for full details\"));\n console.log();\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"extract\")\n .description(\"Extract brand profile from a website\")\n .argument(\"<url>\", \"Website URL to extract branding from\")\n .option(\"--team-id <id>\", \"Team ID\")\n .option(\"--no-save\", \"Extract without saving\")\n .action(async (url: string, options: ExtractOptions) => {\n await requireAuth();\n\n // Validate URL\n try {\n new URL(url.startsWith(\"http\") ? url : `https://${url}`);\n } catch {\n error(\"Invalid URL format\");\n process.exit(6);\n }\n\n const fullUrl = url.startsWith(\"http\") ? url : `https://${url}`;\n const teamId = options.teamId ?? getDefaultTeamId();\n\n const spinner = ora({ text: `Extracting branding from ${fullUrl}...`, stream: process.stdout }).start();\n\n try {\n const result = await extractBranding(fullUrl, teamId);\n\n // Fetch full details\n const brand = await getBranding(result.id);\n spinner.succeed(\"Branding extracted!\");\n console.log();\n\n header(\"Brand Profile\");\n console.log();\n keyValue(\"ID\", brand.id);\n keyValue(\"Name\", brand.name);\n keyValue(\"Source URL\", brand.sourceUrl ?? fullUrl);\n console.log();\n\n // Colors with visual swatches\n if (brand.primaryColor || brand.colors.length > 0) {\n console.log(chalk.bold(\" Colors\"));\n if (brand.primaryColor) {\n const swatch = chalk.bgHex(brand.primaryColor)(\" \");\n console.log(` Primary: ${swatch} ${brand.primaryColor}`);\n }\n if (brand.colors.length > 0) {\n console.log(\" Palette:\");\n for (const c of brand.colors.slice(0, 6)) {\n const swatch = chalk.bgHex(c.hex)(\" \");\n const role = c.role ? chalk.gray(` (${c.role})`) : \"\";\n console.log(` ${swatch} ${c.hex}${role}`);\n }\n }\n console.log();\n }\n\n // Logo\n if (brand.logoUrl) {\n console.log(chalk.bold(\" Logo\"));\n console.log(` ${brand.logoUrl}`);\n console.log();\n }\n\n // Extraction info\n if (brand.confidence) {\n console.log(chalk.bold(\" Extraction\"));\n console.log(` Confidence: ${Math.round(brand.confidence * 100)}%`);\n console.log();\n }\n\n info(`Create a presentation with this brand: conceptcraft create \"Your Topic\" -b ${result.id}`);\n console.log();\n } catch (err) {\n spinner.fail(\"Extraction failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"set-default\")\n .description(\"Set a brand profile as default\")\n .argument(\"<id>\", \"Brand profile ID\")\n .action(async (id: string) => {\n await requireAuth();\n\n // This would need an API endpoint to set default\n // For now, show info about manual process\n info(\n `To set brand ${id} as default, use the web dashboard.`\n );\n console.log();\n console.log(\n chalk.gray(\n \"API support for setting default brand is coming soon.\"\n )\n );\n })\n );\n","/**\n * Derive Command\n * Generates derivative content from presentations (blog, tweets, etc.)\n * Commands are dynamically registered based on feature flags (cached locally)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { generateBlog, getPresentation, type FeatureFlags } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getCachedFlags } from \"../lib/feature-cache.js\";\nimport { streamTextContent } from \"../lib/streaming.js\";\nimport { error, info } from \"../lib/output.js\";\n\ninterface BlogOptions {\n words: string;\n tone: \"professional\" | \"casual\" | \"educational\";\n audience?: string;\n format: \"human\" | \"json\" | \"markdown\";\n instructions?: string;\n noImages?: boolean;\n toc?: boolean;\n}\n\ninterface TweetsOptions {\n count: string;\n format: \"human\" | \"json\";\n}\n\ninterface QuestionsOptions {\n count: string;\n format: \"human\" | \"json\";\n}\n\ninterface CheatsheetOptions {\n mode: string;\n format: \"human\" | \"json\" | \"markdown\";\n}\n\n/**\n * Create the blog subcommand\n */\nfunction createBlogCommand(): Command {\n return new Command(\"blog\")\n .description(\"Generate a blog post from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--words <count>\", \"Target word count (50-2000)\", \"300\")\n .option(\n \"--tone <tone>\",\n \"Writing tone (professional, casual, educational)\",\n \"professional\"\n )\n .option(\"--audience <text>\", \"Target audience description\")\n .option(\n \"-f, --format <format>\",\n \"Output format (human, json, markdown)\",\n \"human\"\n )\n .option(\"--instructions <text>\", \"Custom instructions for the blog\")\n .option(\"--no-images\", \"Exclude image references\")\n .option(\"--toc\", \"Include table of contents\")\n .action(async (presentationId: string, options: BlogOptions) => {\n await requireAuth();\n\n const wordCount = parseInt(options.words, 10);\n if (isNaN(wordCount) || wordCount < 50 || wordCount > 2000) {\n error(\"Word count must be between 50 and 2000\");\n process.exit(6);\n }\n\n const validTones = [\"professional\", \"casual\", \"educational\"];\n if (!validTones.includes(options.tone)) {\n error(`Invalid tone. Valid options: ${validTones.join(\", \")}`);\n process.exit(6);\n }\n\n const spinner = ora(\"Fetching presentation...\").start();\n\n try {\n const presentation = await getPresentation(presentationId);\n spinner.text = \"Generating blog post...\";\n\n const response = await generateBlog(\n presentation.id,\n presentation.documentCreatedAt || presentation.createdAt,\n {\n targetWordCount: wordCount,\n tone: options.tone,\n targetAudience: options.audience ?? \"General Audience\",\n customInstructions: options.instructions ?? \"\",\n includeImages: !options.noImages,\n includeTableOfContents: options.toc ?? false,\n }\n );\n\n const content = await streamTextContent(response, { quiet: true });\n spinner.succeed(\"Blog generated\");\n\n if (options.format === \"json\") {\n console.log(\n JSON.stringify(\n {\n presentationId,\n title: presentation.title,\n wordCount,\n tone: options.tone,\n content,\n },\n null,\n 2\n )\n );\n } else if (options.format === \"markdown\") {\n console.log(content);\n } else {\n console.log();\n console.log(chalk.bold(`Blog: ${presentation.title}`));\n console.log(chalk.gray(\"─\".repeat(40)));\n console.log();\n console.log(content);\n console.log();\n }\n } catch (err) {\n spinner.fail(\"Generation failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n}\n\n/**\n * Create the tweets subcommand\n */\nfunction createTweetsCommand(): Command {\n return new Command(\"tweets\")\n .description(\"Generate tweets from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--count <n>\", \"Number of tweets to generate\", \"5\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string, options: TweetsOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Tweet generation coming soon.\");\n });\n}\n\n/**\n * Create the linkedin subcommand\n */\nfunction createLinkedInCommand(): Command {\n return new Command(\"linkedin\")\n .description(\"Generate a LinkedIn carousel from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"LinkedIn carousel generation coming soon.\");\n });\n}\n\n/**\n * Create the questions subcommand\n */\nfunction createQuestionsCommand(): Command {\n return new Command(\"questions\")\n .description(\"Generate questions for a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--count <n>\", \"Number of questions\", \"10\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string, options: QuestionsOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Question generation coming soon.\");\n });\n}\n\n/**\n * Create the cheatsheet subcommand\n */\nfunction createCheatsheetCommand(): Command {\n return new Command(\"cheatsheet\")\n .description(\"Generate a presenter cheat sheet\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--mode <mode>\", \"Cheat sheet mode (qa-prep, talking-points)\", \"qa-prep\")\n .option(\n \"-f, --format <format>\",\n \"Output format (human, json, markdown)\",\n \"human\"\n )\n .action(async (presentationId: string, options: CheatsheetOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Cheat sheet generation coming soon.\");\n });\n}\n\n/**\n * Build the derive command with subcommands based on cached feature flags\n * This is SYNCHRONOUS - reads from local cache for instant startup\n */\nexport function buildDeriveCommand(): Command {\n const derive = new Command(\"derive\")\n .description(\"Generate derivative content from a presentation\");\n\n // Get cached flags (returns null if no cache or not authenticated)\n const flags = getCachedFlags();\n if (!flags) {\n // No cached flags - return empty derive command\n // Commands will appear after first successful auth + cache refresh\n return derive;\n }\n\n // Add subcommands based on feature access\n if (flags.deckToBlog) {\n derive.addCommand(createBlogCommand());\n }\n if (flags.deckToTweets) {\n derive.addCommand(createTweetsCommand());\n }\n if (flags.linkedInCarousel) {\n derive.addCommand(createLinkedInCommand());\n }\n if (flags.redTeamQuestions) {\n derive.addCommand(createQuestionsCommand());\n }\n if (flags.presenterCheatSheet) {\n derive.addCommand(createCheatsheetCommand());\n }\n\n return derive;\n}\n","/**\n * Ideas Command\n * Generates presentation topic ideas\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { info } from \"../lib/output.js\";\n\ninterface IdeasOptions {\n context?: string;\n count: string;\n format: \"human\" | \"json\";\n}\n\nexport const ideasCommand = new Command(\"ideas\")\n .description(\"Generate presentation topic ideas\")\n .option(\"--context <text>\", \"Custom context for idea generation\")\n .option(\"--count <n>\", \"Number of ideas to generate\", \"5\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (options: IdeasOptions) => {\n await requireAuth();\n\n info(\"Idea generation is available in the web dashboard.\");\n console.log();\n console.log(\n chalk.gray(\"The CLI will support idea generation in a future release.\")\n );\n console.log();\n console.log(\"For now, try these approaches:\");\n console.log(\n chalk.gray(\n \" 1. Visit the ConceptCraft dashboard and use the idea generator\"\n )\n );\n console.log(\n chalk.gray(\" 2. Create a presentation with a broad topic and refine it\")\n );\n console.log();\n });\n","/**\n * Whoami Command\n * Shows information about the authenticated user and their teams\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { whoami } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { refreshInBackground } from \"../lib/feature-cache.js\";\nimport { error, header, keyValue } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface WhoamiOptions {\n format: OutputFormat;\n}\n\nexport const whoamiCommand = new Command(\"whoami\")\n .description(\"Show current user and team information\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (options: WhoamiOptions) => {\n await requireAuth();\n\n try {\n const result = await whoami();\n\n // Refresh feature flags cache in background (non-blocking)\n refreshInBackground();\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Human-readable output\n header(\"User\");\n console.log();\n keyValue(\"Email\", result.user.email);\n if (result.user.username) {\n keyValue(\"Username\", result.user.username);\n }\n if (result.user.firstName || result.user.lastName) {\n keyValue(\n \"Name\",\n [result.user.firstName, result.user.lastName].filter(Boolean).join(\" \")\n );\n }\n keyValue(\"Auth Type\", result.authType === \"apiKey\" ? \"API Key\" : \"Session\");\n\n if (result.currentTeam) {\n console.log();\n header(\"Current Team\");\n console.log();\n keyValue(\"ID\", result.currentTeam.id);\n keyValue(\"Name\", result.currentTeam.name);\n keyValue(\"Plan\", result.currentTeam.planName);\n keyValue(\"Role\", result.currentTeam.isOwner ? \"Owner\" : \"Member\");\n }\n\n if (result.teams.length > 1) {\n console.log();\n header(\"All Teams\");\n console.log();\n for (const team of result.teams) {\n const current = team.isCurrent ? chalk.green(\" (current)\") : \"\";\n console.log(\n ` ${chalk.bold(team.name)}${current}`\n );\n console.log(\n chalk.gray(` ID: ${team.id} | Plan: ${team.planName} | Role: ${team.role}`)\n );\n }\n }\n\n console.log();\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Skill Command\n * Installs the CLI skill for Claude Code and other AI coding assistants\n * All content is dynamically generated from brand config\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { success, error, info, warn, keyValue } from \"../../lib/output.js\";\nimport { brand } from \"../../lib/brand.js\";\nimport { generateSkillContent } from \"./generate-content.js\";\nimport {\n installSkill,\n uninstallSkill,\n getSupportedEditorNames,\n} from \"./installer.js\";\n\nexport const skillCommand = new Command(\"skill\")\n .description(`Manage ${brand.displayName} skill for AI coding assistants`)\n .addHelpText(\n \"after\",\n `\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Install skill for all detected editors\")}\n $ ${brand.name} skill install\n\n ${chalk.gray(\"# Install to specific directory\")}\n $ ${brand.name} skill install --dir ~/.claude\n\n ${chalk.gray(\"# Show skill content\")}\n $ ${brand.name} skill show\n`\n );\n\nskillCommand\n .command(\"install\")\n .description(`Install the ${brand.displayName} skill for AI coding assistants`)\n .option(\"-d, --dir <path>\", \"Install to specific directory\")\n .option(\"-g, --global\", \"Install globally (to home directory)\", true)\n .option(\"-l, --local\", \"Install locally (to current directory)\")\n .option(\"-f, --force\", \"Overwrite existing skill files\")\n .action(async (options) => {\n const skillContent = generateSkillContent(brand);\n const result = installSkill(brand.name, skillContent, {\n dir: options.dir,\n local: options.local,\n force: options.force,\n });\n\n // Report results\n console.log();\n if (result.installed.length > 0) {\n success(\"Skill installed successfully\");\n console.log();\n keyValue(\"Installed to\", result.installed.join(\", \"));\n }\n\n if (result.skipped.length > 0) {\n console.log();\n info(`Skipped (already exists): ${result.skipped.join(\", \")}`);\n console.log(chalk.gray(\" Use --force to overwrite\"));\n }\n\n if (result.errors.length > 0) {\n console.log();\n for (const err of result.errors) {\n error(err);\n }\n }\n\n if (result.installed.length === 0 && result.skipped.length === 0 && result.errors.length === 0) {\n info(\"No supported AI coding assistants detected.\");\n console.log();\n console.log(chalk.gray(\"Supported editors: \" + getSupportedEditorNames().join(\", \")));\n console.log(chalk.gray(\"Use --dir <path> to install to a specific directory\"));\n }\n\n console.log();\n });\n\nskillCommand\n .command(\"show\")\n .description(\"Display the skill content\")\n .action(() => {\n console.log(generateSkillContent(brand));\n });\n\nskillCommand\n .command(\"uninstall\")\n .description(`Remove the ${brand.displayName} skill from AI coding assistants`)\n .option(\"-g, --global\", \"Uninstall globally (from home directory)\", true)\n .option(\"-l, --local\", \"Uninstall locally (from current directory)\")\n .action(async (options) => {\n const result = uninstallSkill(brand.name, { local: options.local });\n\n console.log();\n if (result.removed.length > 0) {\n success(\"Skill uninstalled\");\n keyValue(\"Removed from\", result.removed.join(\", \"));\n } else {\n info(\"No installed skills found\");\n }\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n warn(`Failed to remove: ${err}`);\n }\n }\n console.log();\n });\n\n// Re-export for external use\nexport { generateSkillContent } from \"./generate-content.js\";\nexport { installSkill, uninstallSkill } from \"./installer.js\";\nexport { SUPPORTED_EDITORS } from \"./editors.js\";\nexport type { SkillSection, SkillContext } from \"./types.js\";\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const frontmatter: SkillSection = {\n title: \"Frontmatter\",\n render: (ctx: SkillContext) => `---\nname: ${ctx.cmd}\ndescription: Use when user asks to create presentations (slides, decks, pitch decks) or videos (product demos, explainers, social content, promos). Also handles voiceover and music generation.\n---`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const header: SkillSection = {\n title: \"Header\",\n render: (ctx: SkillContext) => `# ${ctx.name} CLI\n\nCreate professional presentations directly from your terminal. The CLI generates AI-powered slides from any context you provide - text, files, URLs, or piped content.`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const prerequisites: SkillSection = {\n title: \"Prerequisites\",\n render: (ctx: SkillContext) => `## Prerequisites\n\n\\`\\`\\`bash\nnpm install -g ${ctx.pkg}\n${ctx.cmd} login # Authenticate (opens browser)\n${ctx.cmd} whoami # Verify auth\n\\`\\`\\`\n\n### Authentication\n\nIf not authenticated, run \\`${ctx.cmd} login\\` - it opens browser for OAuth.\nIf login fails or user declines, fall back to API key: \\`${ctx.cmd} config init\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const workflow: SkillSection = {\n title: \"Core Workflow\",\n render: (ctx: SkillContext) => `## Core Workflow\n\n1. **Gather context** - Read relevant files, code, or documentation\n2. **Create presentation** - Pass context to \\`${ctx.cmd} create\\`\n3. **Share URL** - Return the presentation link to the user`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const createCommand: SkillSection = {\n title: \"Create Command\",\n render: (ctx: SkillContext) => `## Commands\n\n### Create Presentation\n\nContext is **required**. Provide it via one of these methods:\n\n\\`\\`\\`bash\n# Upload files (PDFs, PPTX, images, docs)\n${ctx.cmd} create \"Product Overview\" --file ./deck.pptx --file ./logo.png\n\n# Direct text context\n${ctx.cmd} create \"Topic Title\" --context \"Key points, data, facts...\"\n\n# From a text file\n${ctx.cmd} create \"Topic Title\" --context-file ./notes.md\n\n# Pipe content (auto-detected)\ncat README.md | ${ctx.cmd} create \"Project Overview\"\n\n# From URLs (scraped automatically)\n${ctx.cmd} create \"Competitor Analysis\" --sources https://example.com/report\n\n# Combine multiple sources\ncat src/auth/*.ts | ${ctx.cmd} create \"Auth System\" \\\\\n --file ./architecture.png \\\\\n --context \"Focus on security patterns\"\n\\`\\`\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const createOptions: SkillSection = {\n title: \"Create Options\",\n render: (_ctx: SkillContext) => `### Create Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| \\`-n, --slides <count>\\` | Number of slides (1-20) | 10 |\n| \\`-m, --mode <mode>\\` | Quality: \\`instant\\`, \\`fast\\`, \\`balanced\\`, \\`best\\` | balanced |\n| \\`-t, --tone <tone>\\` | Tone: \\`professional\\`, \\`educational\\`, \\`creative\\`, \\`formal\\`, \\`casual\\` | professional |\n| \\`--amount <amount>\\` | Density: \\`minimal\\`, \\`concise\\`, \\`detailed\\`, \\`extensive\\` | concise |\n| \\`--audience <text>\\` | Target audience | General Audience |\n| \\`-g, --goal <type>\\` | Purpose: \\`inform\\`, \\`persuade\\`, \\`train\\`, \\`learn\\`, \\`entertain\\`, \\`report\\` | - |\n| \\`--custom-goal <text>\\` | Custom goal description | - |\n| \\`-f, --file <paths...>\\` | Files to upload (PDF, PPTX, images, docs) | - |\n| \\`-l, --language <lang>\\` | Output language | en |\n| \\`-b, --brand <id>\\` | Branding ID to apply | - |\n| \\`-o, --output <format>\\` | Output: \\`human\\`, \\`json\\`, \\`quiet\\` | human |`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const otherCommands: SkillSection = {\n title: \"Other Commands\",\n render: (ctx: SkillContext) => `### Other Commands\n\n\\`\\`\\`bash\n# Check authentication\n${ctx.cmd} whoami\n\n# List presentations\n${ctx.cmd} list\n${ctx.cmd} list --format json\n\n# Get presentation details\n${ctx.cmd} get <id-or-slug>\n\n# Export to ZIP\n${ctx.cmd} export <id-or-slug> -o presentation.zip\n\n# Import presentation\n${ctx.cmd} import ./presentation.zip\n\n# Manage branding\n${ctx.cmd} branding list\n${ctx.cmd} branding extract https://company.com\n\n# Install/manage this skill\n${ctx.cmd} skill install\n${ctx.cmd} skill show\n\\`\\`\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const examples: SkillSection = {\n title: \"Examples\",\n render: (ctx: SkillContext) => `## Examples\n\n### Present a Codebase Feature\n\n\\`\\`\\`bash\n# Read the relevant files and create presentation\ncat src/lib/auth.ts src/lib/session.ts | ${ctx.cmd} create \"Authentication System\" \\\\\n --slides 8 --tone educational --audience \"New developers\" \\\\\n --goal train\n\\`\\`\\`\n\n### Technical Documentation with Diagrams\n\n\\`\\`\\`bash\n${ctx.cmd} create \"API Reference\" \\\\\n --file ./docs/api.md \\\\\n --file ./diagrams/architecture.png \\\\\n --mode best --amount detailed \\\\\n --goal inform\n\\`\\`\\`\n\n### Quick Project Overview\n\n\\`\\`\\`bash\ncat README.md package.json | ${ctx.cmd} create \"Project Introduction\" \\\\\n -m instant --slides 5\n\\`\\`\\`\n\n### Sales Deck from Existing Presentation\n\n\\`\\`\\`bash\n${ctx.cmd} create \"Product Demo\" \\\\\n --file ./existing-deck.pptx \\\\\n --goal persuade \\\\\n --audience \"Enterprise buyers\" \\\\\n --tone professional\n\\`\\`\\`\n\n### Research Presentation\n\n\\`\\`\\`bash\n${ctx.cmd} create \"Market Analysis\" \\\\\n --file ./research.pdf \\\\\n --sources https://report.com/industry.pdf \\\\\n --tone formal --audience \"Executive team\" \\\\\n --goal report\n\\`\\`\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const output: SkillSection = {\n title: \"Output\",\n render: (ctx: SkillContext) => `## Output\n\nSuccessful creation returns:\n\\`\\`\\`\n✓ Presentation created successfully\n\n Title: Authentication System\n Slides: 8\n Generated in: 45s · 12,500 tokens\n\n Open: ${ctx.url}/en/view/presentations/auth-system-v1-abc123\n\\`\\`\\`\n\nFor scripting, use JSON output:\n\\`\\`\\`bash\nURL=$(${ctx.cmd} create \"Demo\" --context \"...\" -o json | jq -r '.viewUrl')\n\\`\\`\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const bestPractices: SkillSection = {\n title: \"Best Practices\",\n render: (_ctx: SkillContext) => `## Best Practices\n\n1. **Provide rich context** - More context = better slides. Include code, docs, data.\n2. **Use file uploads for binary content** - PDFs, images, PPTX files need \\`--file\\`.\n3. **Specify a goal** - Helps tailor the presentation structure and messaging.\n4. **Use appropriate mode** - \\`instant\\` for quick drafts, \\`best\\` for important presentations.\n5. **Specify audience** - Helps tailor complexity and terminology.\n6. **Combine sources** - Pipe multiple files for comprehensive presentations.`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const fileTypes: SkillSection = {\n title: \"Supported File Types\",\n render: (_ctx: SkillContext) => `## Supported File Types\n\n- **Documents**: PDF, DOCX, XLSX, PPTX\n- **Images**: JPEG, PNG, GIF, WebP\n- **Text**: Markdown, TXT, CSV, JSON`,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const troubleshooting: SkillSection = {\n title: \"Troubleshooting\",\n render: (ctx: SkillContext) => `## Troubleshooting\n\n\\`\\`\\`bash\n# Check if authenticated\n${ctx.cmd} whoami\n\n# Re-authenticate if needed\n${ctx.cmd} login\n\n# Debug mode\n${ctx.cmd} create \"Test\" --context \"test\" --debug\n\\`\\`\\``,\n};\n","import type { SkillSection, SkillContext } from \"../types.js\";\n\nexport const videoCreation: SkillSection = {\n title: \"Video Creation\",\n render: (ctx: SkillContext) => `## Video Creation\n\n### How to Create a Perfect Video\n\nVideos must feel like premium tech launches (Stripe, Apple, Linear) - **Kinetic Composition**, not slideshows.\n\n**Core Philosophy:** \"Nothing sits still. Everything is physics-based. Every pixel breathes.\"\n\n### Required Reading (The Motion Bible)\n\n| Rule | Why This Matters |\n|------|------------------|\n| [video-creation-guide.md](rules/video/video-creation-guide.md) | **The Motion Bible.** Camera rigs, 2.5D entrances, cursor physics, typography, backgrounds |\n| [failures.md](rules/video/failures.md) | **Avoid rejection.** 7 common mistakes that make videos look like slideshows |\n| [project-based.md](rules/video/project-based.md) | **Copy real components.** Eject actual UI code, strip logic, animate pixel-perfect |\n| [parameterization.md](rules/video/parameterization.md) | **Saves debugging.** Never hardcode frame numbers |\n| [layers.md](rules/video/layers.md) | **Prevents z-index bugs.** Background orbs → Vignette → CameraRig → Content |\n| [social-media.md](rules/video/social-media.md) | **Platform specs.** Resolution, aspect ratio, duration per platform |\n\n**Required:** \\`npx skills add https://github.com/remotion-dev/skills --skill remotion-best-practices\\`\n\n### Workflow\n\n#### Phase 1: Discovery\n\nExplore the project thoroughly - assets, components, branding, what makes this product/topic unique.\n\n#### Phase 2: Video Brief\n\nPresent a brief outline (scenes, duration, assets found) and get user approval before production.\n\n#### Phase 3: Production\n\n1. **Read video-creation-guide.md + project-based.md + remotion-best-practices**\n2. **Generate audio** - \\`${ctx.cmd} video create\\` with scenes JSON\n3. **Scaffold OUTSIDE project** - \\`cd .. && ${ctx.cmd} video init my-video\\`\n4. **Copy assets** - Logo, fonts, colors from project into video project\n5. **Implement kinetically** - Camera rig, 2.5D entrances, staggered lists, transitions\n6. **Verify checklist** - Is it kinetic or static?\n\n#### Phase 4: Render\n\nAuto-render when done: \\`pnpm exec remotion render FullVideo\\`\n\nOnly open Studio if user asks.\n\n### Kinetic Checklist\n\n- [ ] CameraRig wraps entire scene with drift/zoom\n- [ ] Every UI element uses 2.5D rotation entrance (\\`perspective + rotateX\\`)\n- [ ] Cursor moves in Bezier curves with overshoot\n- [ ] Lists/grids stagger (never appear all at once)\n- [ ] Text uses masked reveal or keyword animation\n- [ ] Background has moving orbs + vignette + noise\n- [ ] Something is moving on EVERY frame\n- [ ] No static resting states longer than 30 frames\n\n### Asset Generation\n\n\\`\\`\\`bash\ncat <<EOF | ${ctx.cmd} video create --output ./public\n{\n \"scenes\": [\n { \"name\": \"Hook\", \"script\": \"...\" },\n { \"name\": \"Demo\", \"script\": \"...\" },\n { \"name\": \"CTA\", \"script\": \"...\" }\n ],\n \"voice\": \"Kore\",\n \"musicPrompt\": \"upbeat corporate\"\n}\nEOF\n\\`\\`\\``,\n};\n","/**\n * Generate skill content by combining all sections\n */\n\nimport type { BrandConfig } from \"../../lib/brand.js\";\nimport type { SkillContext, SkillSection } from \"./types.js\";\nimport {\n frontmatter,\n header,\n prerequisites,\n workflow,\n createCommand,\n createOptions,\n otherCommands,\n examples,\n output,\n bestPractices,\n fileTypes,\n troubleshooting,\n videoCreation,\n} from \"./sections/index.js\";\n\n/**\n * Default section order for the presentation skill\n * Sections are rendered in this order, joined by double newlines\n */\nconst DEFAULT_SECTIONS: SkillSection[] = [\n frontmatter,\n header,\n prerequisites,\n workflow,\n createCommand,\n createOptions,\n otherCommands,\n examples,\n output,\n videoCreation,\n bestPractices,\n fileTypes,\n troubleshooting,\n];\n\n/**\n * Create a SkillContext from a BrandConfig\n */\nexport function createSkillContext(brand: BrandConfig): SkillContext {\n return {\n cmd: brand.name,\n pkg: brand.packageName,\n url: brand.apiUrl,\n name: brand.displayName,\n };\n}\n\n/**\n * Generate skill content from brand config\n * @param brand - Brand configuration\n * @param sections - Optional custom section order (defaults to presentation skill sections)\n */\nexport function generateSkillContent(\n brand: BrandConfig,\n sections: SkillSection[] = DEFAULT_SECTIONS\n): string {\n const ctx = createSkillContext(brand);\n\n return sections.map((section) => section.render(ctx)).join(\"\\n\\n\");\n}\n","/**\n * Skill installation utilities\n */\n\nimport { mkdirSync, writeFileSync, existsSync, rmSync } from \"fs\";\nimport { join, resolve, relative } from \"path\";\nimport { homedir } from \"os\";\nimport { SUPPORTED_EDITORS, type EditorConfig } from \"./editors.js\";\nimport { VIDEO_RULE_CONTENTS } from \"./rules/video/content.js\";\n\n/**\n * Validate that a path doesn't escape the base directory (prevent path traversal)\n * @throws Error if path would escape base directory\n */\nfunction validatePath(basePath: string, targetPath: string): string {\n const resolvedBase = resolve(basePath);\n const resolvedTarget = resolve(basePath, targetPath);\n const relativePath = relative(resolvedBase, resolvedTarget);\n\n // Check if the resolved path escapes the base directory\n if (relativePath.startsWith(\"..\") || resolve(resolvedTarget) !== resolvedTarget.replace(/\\.\\./g, \"\")) {\n throw new Error(`Invalid path: \"${targetPath}\" would escape base directory`);\n }\n\n return resolvedTarget;\n}\n\nexport interface InstallResult {\n installed: string[];\n skipped: string[];\n errors: string[];\n}\n\nexport interface InstallOptions {\n /** Install to specific directory */\n dir?: string;\n /** Install locally (current directory) instead of globally */\n local?: boolean;\n /** Overwrite existing skill files */\n force?: boolean;\n}\n\nexport interface RuleFile {\n /** Relative path within skill folder (e.g., \"rules/video/tiktok.md\") */\n path: string;\n /** File content */\n content: string;\n}\n\n/**\n * Get all rule files to install\n */\nexport function getRuleFiles(): RuleFile[] {\n const rules: RuleFile[] = [];\n\n // Video rules\n for (const rule of VIDEO_RULE_CONTENTS) {\n rules.push({\n path: `rules/video/${rule.filename}`,\n content: rule.content,\n });\n }\n\n return rules;\n}\n\n/**\n * Install skill file and rules to a specific path\n */\nexport function installSkillToPath(skillPath: string, content: string): void {\n const skillFile = join(skillPath, \"SKILL.md\");\n\n // Create directory\n mkdirSync(skillPath, { recursive: true });\n\n // Write skill file\n writeFileSync(skillFile, content, \"utf-8\");\n\n // Write rule files\n const rules = getRuleFiles();\n for (const rule of rules) {\n const rulePath = join(skillPath, rule.path);\n const ruleDir = join(skillPath, rule.path.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create rule directory\n mkdirSync(ruleDir, { recursive: true });\n\n // Write rule file\n writeFileSync(rulePath, rule.content, \"utf-8\");\n }\n}\n\n/**\n * Install skill to all detected editors or a specific directory\n */\nexport function installSkill(\n skillName: string,\n content: string,\n options: InstallOptions = {}\n): InstallResult {\n const result: InstallResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const baseDir = options.local ? process.cwd() : homedir();\n\n if (options.dir) {\n // Install to specific directory with path validation\n try {\n const resolvedDir = resolve(options.dir);\n const skillPath = validatePath(resolvedDir, join(\"skills\", skillName));\n installSkillToPath(skillPath, content);\n result.installed.push(options.dir);\n } catch (err) {\n result.errors.push(`${options.dir}: ${err instanceof Error ? err.message : String(err)}`);\n }\n } else {\n // Auto-detect and install to all supported editors\n for (const editor of SUPPORTED_EDITORS) {\n const editorDir = join(baseDir, editor.dir);\n const skillPath = join(editorDir, \"skills\", skillName);\n const skillFile = join(skillPath, \"SKILL.md\");\n\n // Check if editor directory exists (editor is installed)\n if (!existsSync(editorDir)) {\n continue;\n }\n\n // Check if skill already exists\n if (existsSync(skillFile) && !options.force) {\n result.skipped.push(editor.name);\n continue;\n }\n\n try {\n installSkillToPath(skillPath, content);\n result.installed.push(editor.name);\n } catch (err) {\n result.errors.push(`${editor.name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n }\n\n return result;\n}\n\nexport interface UninstallResult {\n removed: string[];\n errors: string[];\n}\n\n/**\n * Uninstall skill from all detected editors\n */\nexport function uninstallSkill(\n skillName: string,\n options: { local?: boolean } = {}\n): UninstallResult {\n const result: UninstallResult = {\n removed: [],\n errors: [],\n };\n const baseDir = options.local ? process.cwd() : homedir();\n\n for (const editor of SUPPORTED_EDITORS) {\n const skillPath = join(baseDir, editor.dir, \"skills\", skillName);\n if (existsSync(skillPath)) {\n try {\n rmSync(skillPath, { recursive: true });\n result.removed.push(editor.name);\n } catch (err) {\n result.errors.push(`${editor.name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get list of supported editor names\n */\nexport function getSupportedEditorNames(): string[] {\n return SUPPORTED_EDITORS.map((e) => e.name);\n}\n","/**\n * Supported AI coding editors/assistants configuration\n */\n\nexport interface EditorConfig {\n /** Display name of the editor */\n name: string;\n /** Directory name in home folder (e.g., \".claude\") */\n dir: string;\n}\n\n/**\n * List of supported AI coding assistants\n * Each entry defines where skills should be installed\n */\nexport const SUPPORTED_EDITORS: EditorConfig[] = [\n { name: \"Claude Code\", dir: \".claude\" },\n { name: \"Cursor\", dir: \".cursor\" },\n { name: \"Codex\", dir: \".codex\" },\n { name: \"OpenCode\", dir: \".opencode\" },\n { name: \"Windsurf\", dir: \".windsurf\" },\n { name: \"Agent\", dir: \".agent\" },\n];\n","/**\n * Video rule content - embedded markdown for each rule file\n * These are written to disk when the skill is installed\n */\n\nexport interface RuleContent {\n /** File name (e.g., \"social-media.md\") */\n filename: string;\n /** Markdown content */\n content: string;\n}\n\nexport const VIDEO_RULE_CONTENTS: RuleContent[] = [\n {\n filename: \"video-creation-guide.md\",\n content: `# Video Creation Guide\n\n> **ALSO READ:**\n> - [project-based.md](project-based.md) - How to extract and animate real project components pixel-perfect\n> - If installed, check \\`remotion-best-practices\\` skill for Remotion-specific patterns\n\n---\n\n# The \"Kinetic SaaS\" Motion Design System\n\n**Objective:** Replicate the high-energy, fluid feel of premium tech product videos (Stripe, Apple, Linear, Affable.ai).\n\n**Core Philosophy:** \"Nothing sits still. Everything is physics-based. Every pixel breathes.\"\n\nThis is the difference between **Static Composition** (slideshows) and **Kinetic Composition** (motion graphics). You must rebuild UI as individual animated layers and film with a virtual camera.\n\n---\n\n## 1. The Global Camera Rig (The \"Anti-Static\" Layer)\n\nEven when reading text, the screen is slowly zooming or panning.\n\n### Virtual Camera\n\nEvery scene must be wrapped in a \\`CameraRig\\` component:\n\n\\`\\`\\`tsx\nconst CameraRig: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const frame = useCurrentFrame();\n const { durationInFrames } = useVideoConfig();\n\n // The \"Drift\" - constant subtle movement\n const scale = interpolate(frame, [0, durationInFrames], [1.0, 1.05]);\n const rotation = interpolate(frame, [0, durationInFrames], [0, 0.5]);\n\n return (\n <AbsoluteFill style={{\n transform: \\`scale(\\${scale}) rotate(\\${rotation}deg)\\`,\n }}>\n {children}\n </AbsoluteFill>\n );\n};\n\\`\\`\\`\n\n### Zoom-Through Transitions\n\nTransitions are NOT just fades - they are camera movements:\n\n\\`\\`\\`tsx\n// Camera scales rapidly into an element (logo, dot) until it fills screen\nconst zoomThrough = interpolate(frame, [TRANSITION_START, TRANSITION_END], [1, 50]);\n// The element becomes the background for the next scene\n\\`\\`\\`\n\n---\n\n## 2. UI & Mockup Animation Rules (Rebuilding Reality)\n\nUI doesn't just fade in. It pops up with weight.\n\n### Priority: Use Real Project Components\n\n**If you're in a project folder, ALWAYS check for actual components first:**\n\n\\`\\`\\`bash\n# Before building ANY UI, explore the project\nls src/components/\nls src/app/\n\\`\\`\\`\n\n**When project components exist:**\n1. **Copy the actual component** into your Remotion project\n2. **Strip logic** (remove useState, API calls, event handlers)\n3. **Keep visuals identical** (same styles, colors, spacing)\n4. **Add animation props** (progress, isHovered, etc.)\n5. **Apply kinetic animation** using the rules below\n\nSee [project-based.md](project-based.md) for the full component extraction process.\n\n**This is the priority order:**\n1. ✅ Pixel-perfect copy of real project components (animated)\n2. ⚠️ Recreate UI from project's design system (colors, fonts, spacing)\n3. ❌ Generic mockups or stock images (ONLY for non-UI scenes like hooks)\n\n### The \"Pop-Up\" Entrance (2.5D Rotation)\n\n\\`\\`\\`tsx\n// Heavy spring for weighty feel\nconst progress = spring({\n frame,\n fps,\n config: { mass: 2, damping: 20, stiffness: 100 },\n});\n\n// Start tilted back, spring to flat\nconst rotateX = interpolate(progress, [0, 1], [20, 0]);\nconst y = interpolate(progress, [0, 1], [100, 0]);\nconst scale = interpolate(progress, [0, 1], [0.8, 1.0]);\n\n<div style={{\n transform: \\`perspective(1000px) rotateX(\\${rotateX}deg) translateY(\\${y}px) scale(\\${scale})\\`,\n}}>\n {uiComponent}\n</div>\n\\`\\`\\`\n\n### Cursor Simulation\n\n**Movement:** Never linear. Cursors move in **Bezier Curves** with an arc.\n\n\\`\\`\\`tsx\n// 1. Spring progress from start to end\nconst progress = spring({\n frame: frame - startFrame,\n fps,\n config: { damping: 20, stiffness: 80 }, // Slower, deliberate\n});\n\n// 2. Linear interpolation for X and Y\nconst linearX = interpolate(progress, [0, 1], [start.x, end.x]);\nconst linearY = interpolate(progress, [0, 1], [start.y, end.y]);\n\n// 3. THE ARC: Parabola that peaks mid-travel (this is the secret sauce)\nconst arcHeight = 100; // How much the cursor \"loops\"\nconst arcOffset = Math.sin(progress * Math.PI) * arcHeight;\n\n// 4. Apply arc to Y position\nconst cursorY = linearY - arcOffset;\n\\`\\`\\`\n\n**Click Interaction:**\n\\`\\`\\`tsx\n// On click:\n// 1. Cursor scales down\nconst cursorScale = isClicking ? 0.8 : 1;\n\n// 2. Button squishes\nconst buttonScaleX = isClicking ? 1.05 : 1;\nconst buttonScaleY = isClicking ? 0.95 : 1;\n\n// 3. Release both with spring\n\\`\\`\\`\n\n**Standard Cursor SVG:**\n\\`\\`\\`tsx\n// Mac-style cursor (use as reference, customize as needed)\n<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\">\n <path\n d=\"M4 4L11.5 26L16 17.5L25 25L27 23L18.5 15L28 11.5L4 4Z\"\n fill=\"black\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n</svg>\n\\`\\`\\`\n\n### Staggered Lists & Grids\n\n**Rule:** NEVER show a list or grid all at once.\n\n\\`\\`\\`tsx\nconst STAGGER_FRAMES = 4; // ~0.05s at 60fps\n\n{items.map((item, i) => {\n const delay = i * STAGGER_FRAMES;\n const progress = spring({\n frame: frame - delay,\n fps,\n config: { damping: 15, stiffness: 120 },\n });\n\n return (\n <div style={{\n opacity: progress,\n transform: \\`translateY(\\${interpolate(progress, [0, 1], [20, 0])}px)\\`,\n }}>\n {item}\n </div>\n );\n})}\n\\`\\`\\`\n\n---\n\n## 3. Kinetic Typography (Text that Hits)\n\nText doesn't fade. It slams in, changes fill, or slides up.\n\n### Pattern A: The \"Masked Reveal\"\n\nText rises from a floor:\n\n\\`\\`\\`tsx\n<div style={{ overflow: 'hidden', height: 80 }}>\n <h1 style={{\n transform: \\`translateY(\\${interpolate(progress, [0, 1], [100, 0])}%)\\`,\n }}>\n INTRODUCING\n </h1>\n</div>\n\\`\\`\\`\n\n### Pattern B: Variable Weight (Animate Keywords)\n\nDon't animate the whole sentence. Animate **keywords**:\n\n\\`\\`\\`tsx\n// \"Teams waste HOURS\" - only \"HOURS\" animates\n<p>\n Teams waste{' '}\n <span style={{\n transform: \\`scale(\\${interpolate(keywordProgress, [0, 1], [1, 1.2])})\\`,\n color: interpolateColors(keywordProgress, [0, 1], ['#F0F0F0', '#FF6B6B']),\n textShadow: \\`0 0 \\${glowProgress * 20}px rgba(255,107,107,0.5)\\`,\n }}>\n HOURS\n </span>\n</p>\n\\`\\`\\`\n\n### Pattern C: The \"Glitch/Tech\" Accent\n\nChromatic aberration on impact:\n\n\\`\\`\\`tsx\n// Duplicate text, offset by 2px with color channels, flash for 2 frames\n{isImpactFrame && (\n <>\n <span style={{ position: 'absolute', left: -2, color: '#FF0000', opacity: 0.5 }}>TEXT</span>\n <span style={{ position: 'absolute', left: 2, color: '#0000FF', opacity: 0.5 }}>TEXT</span>\n </>\n)}\n\\`\\`\\`\n\n### Text Colors\n\nNever pure white (\\`#FFF\\`). Use \\`#F0F0F0\\` with subtle gradient or shadow for depth.\n\n---\n\n## 4. Atmosphere & Backgrounds (The \"Deep Space\")\n\nBackground is never a solid color. It's deep black with floating colored orbs.\n\n### The \"Orb\" System\n\n\\`\\`\\`tsx\nconst MovingBackground: React.FC = () => {\n const frame = useCurrentFrame();\n\n // Orbs move in figure-8 or circular patterns\n const orb1X = Math.sin(frame / 60) * 200;\n const orb1Y = Math.cos(frame / 80) * 100;\n const orb2X = Math.sin(frame / 70 + Math.PI) * 150;\n const orb2Y = Math.cos(frame / 90 + Math.PI) * 120;\n\n return (\n <AbsoluteFill style={{ backgroundColor: '#0a0a0a' }}>\n {/* Orb 1 - Teal */}\n <div style={{\n position: 'absolute',\n width: 600,\n height: 600,\n borderRadius: '50%',\n background: 'radial-gradient(circle, rgba(20,184,166,0.3) 0%, transparent 70%)',\n filter: 'blur(100px)',\n transform: \\`translate(\\${orb1X}px, \\${orb1Y}px)\\`,\n left: '20%',\n top: '30%',\n }} />\n\n {/* Orb 2 - Purple */}\n <div style={{\n position: 'absolute',\n width: 500,\n height: 500,\n borderRadius: '50%',\n background: 'radial-gradient(circle, rgba(168,85,247,0.3) 0%, transparent 70%)',\n filter: 'blur(100px)',\n transform: \\`translate(\\${orb2X}px, \\${orb2Y}px)\\`,\n right: '20%',\n bottom: '20%',\n }} />\n </AbsoluteFill>\n );\n};\n\\`\\`\\`\n\n### Vignette & Noise\n\n\\`\\`\\`tsx\n// Noise texture overlay (5% opacity)\n<AbsoluteFill style={{\n backgroundImage: 'url(/noise.png)',\n opacity: 0.05,\n mixBlendMode: 'overlay',\n}} />\n\n// Vignette (dark corners)\n<AbsoluteFill style={{\n background: 'radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,0.8) 100%)',\n}} />\n\\`\\`\\`\n\n---\n\n## 5. Physics & Timing Reference\n\n### Spring Configs\n\n| Use Case | Config | Feel |\n|----------|--------|------|\n| Standard (snappy) | \\`{ mass: 1, damping: 15, stiffness: 120 }\\` | Smooth, professional |\n| Heavy (UI mockups) | \\`{ mass: 2, damping: 20, stiffness: 100 }\\` | Weighty, premium |\n| Bouncy (attention) | \\`{ mass: 1, damping: 10, stiffness: 150 }\\` | Playful overshoot |\n\n### Timing Values\n\n| Action | Frames | Notes |\n|--------|--------|-------|\n| Element entrance | 15-20 | Spring to rest |\n| Stagger gap | 3-5 | Between list items |\n| Hold on key info | 45-60 | Minimum read time |\n| Scene transition | 20-30 | Zoom-through |\n\n### The Golden Rule\n\nUse \\`interpolate(frame)\\` to ensure \\`scale\\` or \\`rotation\\` is changing on **EVERY frame**. No static resting states.\n\n---\n\n## 6. Micro-Tricks from Premium Videos\n\n### The \"Match Cut\"\n\nSmall circle zooms to fill screen, becomes next scene's background:\n\n\\`\\`\\`tsx\n// Circle element scales 50x to wipe to next scene\nconst circleScale = interpolate(frame, [MATCH_START, MATCH_END], [1, 50]);\n\\`\\`\\`\n\n### Search Bar Typing\n\nInclude blinking cursor:\n\n\\`\\`\\`tsx\nconst Typewriter: React.FC<{ text: string }> = ({ text }) => {\n const frame = useCurrentFrame();\n const charIndex = Math.floor(frame / 3); // 3 frames per char\n const showCursor = Math.floor(frame / 15) % 2 === 0; // Blink every 15 frames\n\n return (\n <span>\n {text.slice(0, charIndex)}\n {showCursor && <span style={{ opacity: 0.8 }}>|</span>}\n </span>\n );\n};\n\\`\\`\\`\n\n### The \"Card Fan\"\n\nStack cards, then fan out:\n\n\\`\\`\\`tsx\nconst cards = [\n { rotation: -5, x: -20 },\n { rotation: 0, x: 0 },\n { rotation: 5, x: 20 },\n];\n\n{cards.map((card, i) => {\n const fanProgress = spring({ frame: frame - 30, fps, config: { damping: 15, stiffness: 100 } });\n\n return (\n <div style={{\n position: 'absolute',\n transform: \\`rotate(\\${fanProgress * card.rotation}deg) translateX(\\${fanProgress * card.x}px)\\`,\n zIndex: i,\n }}>\n <ProfileCard />\n </div>\n );\n})}\n\\`\\`\\`\n\n---\n\n## 7. Strict Animation Guidelines (DO NOT DEVIATE)\n\n**ROLE:** Senior Motion Graphics Engineer for Remotion.\n**REFERENCE STYLE:** \"High-End SaaS Product Launch\" (e.g., Affable.ai, Linear.app).\n\n### Physics & Timing\n\n- **No Linear Motion:** All spatial movement (X, Y, Scale) must use \\`spring\\`.\n - *Standard Spring:* \\`{ mass: 1, damping: 15, stiffness: 120 }\\` (Snappy but smooth)\n - *Heavy Spring (Mockups):* \\`{ mass: 2, damping: 20, stiffness: 100 }\\` (Feels weighty)\n- **Continuous Flow:** Use \\`interpolate(frame)\\` to ensure \\`scale\\` or \\`rotation\\` is changing slightly on EVERY frame. No static resting states.\n\n### UI Component Behavior\n\n- **Entrance:** When a UI card enters, it must use **2.5D Rotation**.\n - *Code:* \\`transform: perspective(1000px) rotateX(\\${rotateX}deg) translateY(\\${y}px)\\`\n - *Values:* Start at \\`rotateX(20deg)\\` and \\`y(100px)\\`. Spring to \\`0\\`.\n- **Internal Staggering:** If the UI card contains a list or grid, use \\`<Sequence>\\` or \\`delay\\` to reveal items one by one (3 frame gap).\n- **Cursor Interaction:** If a cursor clicks a button:\n 1. Cursor scales \\`1 -> 0.8\\`\n 2. Button scales \\`1 -> 0.95\\`\n 3. Release both to \\`1\\` with a spring\n\n### Typography Patterns\n\n- **Pattern A (Headline):** \"Masked Slide Up\". Text translates Y from \\`100%\\` inside a clipped container.\n- **Pattern B (Keywords):** \"Scale & Glow\". Keywords scale to \\`1.1\\` and emit a \\`text-shadow\\`.\n- **Colors:** Text is never pure white (\\`#FFF\\`). Use \\`#F0F0F0\\` with a subtle gradient or shadow to add depth.\n\n### Background \"Aliveness\"\n\n- Create a \\`<MovingBackground>\\` component.\n- It must feature 2-3 \\`AbsoluteFill\\` gradient orbs that move in a continuous loop using \\`Math.sin(frame / slowFactor)\\`.\n- This ensures the video has \"depth\" behind the text.\n\n---\n\n## 8. Seamless Scene Transitions (No Hard Cuts)\n\nIn high-end motion design, transitions are rarely separate \"effects\" (like a cross-dissolve). The *outgoing* scene physically pushes, slides, or zooms into the *incoming* scene.\n\n### The \"Wipe\" Rule (No Hard Cuts)\n\n- **Forbidden:** Never let Scene A end at frame X and Scene B start at frame X+1 with a simple cut.\n- **Required:** Scene B must exist *above* Scene A (z-index) for at least 15-20 frames before the cut happens.\n- **Mechanism:** Scene B enters using a \"Wipe\" motion (sliding in from the bottom/right) or a \"Scale In\" (expanding from a dot).\n\n### The \"Zoom-Through\" Technique (Best for SaaS)\n\nAs Scene A ends, the camera must **accelerate** its zoom:\n\n\\`\\`\\`tsx\n// Scene A Action: At duration - 20 frames, zoom way in\nconst scaleA = interpolate(frame, [duration - 20, duration], [1.0, 5.0]);\n\n// Scene B Action: Starts at scale 0.5 and springs to 1.0\nconst scaleB = spring({ frame, fps, config: { damping: 14, stiffness: 120 } });\nconst scaleBValue = interpolate(scaleB, [0, 1], [0.5, 1]);\n\\`\\`\\`\n\nResult: It looks like the camera flew *through* Scene A to find Scene B behind it.\n\n### The \"Color Swipe\" (Safety Net)\n\nIf a complex match-cut is too hard, use a \"Curtain\":\n\n\\`\\`\\`tsx\n// A solid colored AbsoluteFill slides in from left, covers screen for 2 frames,\n// then slides out to the right, revealing Scene B\nconst curtainX = interpolate(frame, [0, 10, 12, 22], [-100, 0, 0, 100]);\n\\`\\`\\`\n\n### TransitionWrapper Component\n\nUse the \\`TransitionWrapper\\` from shared components:\n\n\\`\\`\\`tsx\nimport { TransitionWrapper } from './shared';\n\n// Types: 'slide' | 'zoom' | 'fade' | 'none'\n// enterFrom: 'left' | 'right' | 'bottom'\n\n<TransitionWrapper type=\"slide\" enterFrom=\"bottom\">\n <YourScene />\n</TransitionWrapper>\n\\`\\`\\`\n\n### Critical: Overlap Your Sequences\n\n**This is the most important part.** To make transitions work, you must overlap sequences slightly. If Scene 1 is 90 frames, start Scene 2 at frame 75 (15-frame overlap).\n\n\\`\\`\\`tsx\nexport const MyVideo = () => {\n return (\n <AbsoluteFill>\n {/* SCENE 1: Ends at frame 100 */}\n <Sequence from={0} durationInFrames={100}>\n <SceneOne />\n </Sequence>\n\n {/* SCENE 2: Starts at frame 85 (15 frames early!) */}\n {/* TransitionWrapper slides it ON TOP of Scene 1 */}\n <Sequence from={85} durationInFrames={150}>\n <TransitionWrapper type=\"slide\" enterFrom=\"bottom\">\n <SceneTwo />\n </TransitionWrapper>\n </Sequence>\n\n {/* SCENE 3: Starts early again */}\n <Sequence from={220} durationInFrames={150}>\n <TransitionWrapper type=\"zoom\">\n <SceneThree />\n </TransitionWrapper>\n </Sequence>\n </AbsoluteFill>\n );\n};\n\\`\\`\\`\n\n**Why this fixes the \"Light Switch\" effect:** Because Scene 2 physically slides *over* Scene 1 while Scene 1 is still visible underneath, your brain registers it as continuous movement rather than a \"cut.\"\n\n---\n\n## Quick Tips from Motion Devs\n\n- **Don't use white backgrounds.** The 2.5D lighting and shadows pop much better on dark grey or black backgrounds.\n- **Overlap delays.** If Title starts at frame 10 and Card starts at frame 30, the title hasn't finished moving when the card appears. This overlap is crucial for fluidity.\n- **High FPS.** Ensure your \\`remotion.config.ts\\` is set to 60fps for springs to look smooth.\n\n---\n\n## Self-Check: Is It Kinetic?\n\nBefore rendering, verify:\n\n- [ ] Camera rig wraps entire scene with drift/zoom\n- [ ] Every UI element uses 2.5D rotation entrance\n- [ ] Cursor moves in curves with overshoot\n- [ ] Lists/grids stagger (never appear all at once)\n- [ ] Text uses masked reveal or keyword animation\n- [ ] Background has moving orbs + vignette + noise\n- [ ] Something is moving on EVERY frame\n- [ ] No static resting states longer than 30 frames\n- [ ] Scene transitions overlap (no hard cuts between scenes)\n- [ ] TransitionWrapper used for slide/zoom entrances\n\nIf your video looks like PowerPoint slides with voiceover, **START OVER**.\n`,\n },\n {\n filename: \"failures.md\",\n content: `# Common Failures - READ THIS FIRST\n\nIf your video looks like any of these, START OVER.\n\n## FAILURE 1: Slideshow\n\n\\`\\`\\`\nWhat you made:\n- Background image\n- Text appears on top\n- Text disappears\n- New background image\n- More text\n\nThis is PowerPoint, not a video. REJECTED.\n\\`\\`\\`\n\n## FAILURE 2: Lorem Ipsum / Placeholder Content\n\n\\`\\`\\`\nWhat you made:\n- \"Lorem ipsum dolor sit amet...\"\n- \"Sample text here\"\n- Generic placeholder content\n\nUse REAL content from the project. REJECTED.\n\\`\\`\\`\n\n## FAILURE 3: Static UI Screenshot\n\n\\`\\`\\`\nWhat you made:\n- Screenshot of the app\n- Text overlay saying \"Our Dashboard\"\n- No motion, no interaction\n\nRecreate the UI in code and ANIMATE it. REJECTED.\n\\`\\`\\`\n\n## FAILURE 4: Elements Just Appearing\n\n\\`\\`\\`\nWhat you made:\n- Frame 0: nothing\n- Frame 1: element is fully visible\n- No transition, no animation\n\nEvery element must animate in with spring/easing. REJECTED.\n\\`\\`\\`\n\n## FAILURE 5: Hard Cuts Between Scenes (The \"Light Switch\" Effect)\n\n\\`\\`\\`\nWhat you made:\n- Scene 1 ends at frame 100\n- Scene 2 starts at frame 101\n- No overlap, no slide, no zoom-through\n- Feels like a light switching on/off\n\nFIX: Overlap sequences by 15-20 frames. Scene 2 must slide/zoom\nON TOP of Scene 1 while Scene 1 is still visible. Use TransitionWrapper.\nREJECTED.\n\\`\\`\\`\n\n## FAILURE 6: Static Camera\n\n\\`\\`\\`\nWhat you made:\n- Camera never moves\n- No drift, no zoom, no rotation\n- Feels like watching a screenshot\n\nCamera must ALWAYS be subtly moving. REJECTED.\n\\`\\`\\`\n\n## FAILURE 7: Linear Cursor Movement\n\n\\`\\`\\`\nWhat you made:\n- Cursor moves in straight lines\n- No overshoot on stops\n- Click has no feedback\n\nCursor must move in Bezier curves with overshoot. REJECTED.\n\\`\\`\\`\n`,\n },\n {\n filename: \"parameterization.md\",\n content: `# Parameterization (Critical)\n\nNever hardcode frame numbers. Use variables for all keyframes.\n\n## Why\n\nWhen you change timing early in video, everything else breaks if hardcoded.\n\n## Pattern\n\n\\`\\`\\`ts\n// Define keyframes as variables\nconst SCENE_START = 0;\nconst TITLE_IN = SCENE_START + 15;\nconst TITLE_HOLD = TITLE_IN + 60;\nconst TITLE_OUT = TITLE_HOLD + 15;\nconst SUBTITLE_IN = TITLE_IN + 20; // Relative to title\nconst SCENE_END = TITLE_OUT + 30;\n\n// Use in animations\nopacity: interpolate(frame, [TITLE_IN, TITLE_IN + 15], [0, 1])\n\\`\\`\\`\n\n## Scene Duration\n\n\\`\\`\\`ts\n// Calculate from keyframes, don't hardcode\nconst sceneDuration = SCENE_END - SCENE_START;\n\\`\\`\\`\n\n## Audio Sync\n\n\\`\\`\\`ts\n// If audio timestamp changes, only update one variable\nconst VOICEOVER_START = 45;\nconst VISUAL_CUE = VOICEOVER_START + 10; // Auto-adjusts\n\\`\\`\\`\n\n## Multi-Scene\n\n\\`\\`\\`ts\nconst SCENE_1_START = 0;\nconst SCENE_1_END = SCENE_1_START + 90;\nconst SCENE_2_START = SCENE_1_END - 15; // 15 frame overlap for transition\nconst SCENE_2_END = SCENE_2_START + 120;\n\\`\\`\\`\n`,\n },\n {\n filename: \"layers.md\",\n content: `# Layers & Composition\n\nExplicit z-index prevents visual bugs.\n\n## Z-Index Scale\n\n| Layer | Z-Index | Examples |\n|-------|---------|----------|\n| Background orbs | 0 | Moving gradients, noise |\n| Vignette | 1 | Dark corners overlay |\n| UI Base | 10 | Main UI container |\n| UI Elements | 20 | Buttons, cards, inputs |\n| Overlays | 30 | Modals, tooltips, highlights |\n| Text/Captions | 40 | Titles, labels |\n| Cursor | 50 | Mouse pointer |\n| Debug | 100 | Frame counter (remove in final) |\n\n## Composition Structure\n\n\\`\\`\\`tsx\n<AbsoluteFill>\n {/* Background layer */}\n <MovingBackground />\n\n {/* Vignette */}\n <Vignette />\n\n {/* Camera rig wraps all content */}\n <CameraRig>\n <Sequence from={0}>\n <Scene1 />\n </Sequence>\n <Sequence from={SCENE_2_START}>\n <Scene2 />\n </Sequence>\n </CameraRig>\n\n {/* Audio */}\n <Audio src={music} volume={0.3} />\n <Audio src={voiceover} />\n</AbsoluteFill>\n\\`\\`\\`\n\n## Overlapping Sequences\n\nFor zoom-through transitions, scenes overlap:\n\n\\`\\`\\`tsx\n<Sequence from={0} durationInFrames={100}>\n <Scene1 />\n</Sequence>\n<Sequence from={80} durationInFrames={100}> {/* 20 frame overlap */}\n <Scene2 />\n</Sequence>\n\\`\\`\\`\n`,\n },\n {\n filename: \"project-based.md\",\n content: `# Component Extraction (Critical for Product Videos)\n\nWhen creating a video for a project, **copy the actual components** - don't rebuild from scratch.\n\n## The Goal\n\nYour video should show the REAL product UI, pixel-perfect. Viewers should not be able to tell the difference between a screenshot and your video (except yours is animated with kinetic motion).\n\n## Process: Eject → Simplify → Animate\n\n### Step 1: Find Components to Feature\n\n\\`\\`\\`bash\n# Explore the project structure\nls src/components/\nls src/app/\n# Find the key UI: dashboards, forms, cards, modals, etc.\n\\`\\`\\`\n\n### Step 2: Copy Component Code\n\nCopy the actual component file into your Remotion project.\n\n### Step 3: Eject - Strip Logic, Keep Visuals\n\n\\`\\`\\`tsx\n// BEFORE: Original component from project\nexport function PricingCard({ plan, onSelect }) {\n const [loading, setLoading] = useState(false);\n const handleClick = async () => { /* API calls */ };\n return <div>...</div>;\n}\n\n// AFTER: Ejected for Remotion\nexport function PricingCard({ plan, progress, isHovered }) {\n // No useState, no API calls, no handlers\n // Just visual + animation props from Remotion\n\n const entranceProgress = spring({ frame: progress, fps, config: { mass: 2, damping: 20, stiffness: 100 } });\n const rotateX = interpolate(entranceProgress, [0, 1], [20, 0]);\n\n return (\n <div style={{\n transform: \\`perspective(1000px) rotateX(\\${rotateX}deg)\\`,\n // ... exact same visual styles as original\n }}>\n ...\n </div>\n );\n}\n\\`\\`\\`\n\n### Step 4: Add Kinetic Animation\n\nApply the rules from kinetic-saas.md:\n- 2.5D rotation entrance\n- Spring physics\n- Staggered children\n- Cursor interaction states\n\n### Step 5: Fill With Real Demo Data\n\n\\`\\`\\`tsx\n// Use realistic data that matches the product\nconst DEMO_PLANS = [\n { name: 'Starter', price: 9, features: ['5 projects', '10GB storage'] },\n { name: 'Pro', price: 29, features: ['Unlimited projects', '100GB storage', 'Priority support'] },\n];\n// NOT: \"Plan A\", \"$XX/mo\", \"Feature 1\"\n\\`\\`\\`\n\n## What to Copy\n\n| Find in Project | Copy to Video |\n|-----------------|---------------|\n| \\`tailwind.config.js\\` | Colors, fonts, spacing |\n| \\`globals.css\\` | CSS variables, font imports |\n| \\`/public/logo.svg\\` | Actual logo file |\n| \\`/src/components/*.tsx\\` | Component structure & styles |\n\n## Common Mistakes\n\n❌ Using placeholder colors like \\`#333\\`\n✅ Using exact project colors from tailwind config\n\n❌ Generic content: \"Feature 1\", \"Lorem ipsum\"\n✅ Real content: \"Unlimited projects\", \"Priority support\"\n\n❌ Building from scratch based on screenshots\n✅ Copying actual component code and ejecting it\n\n❌ Static fade-in animations\n✅ 2.5D rotation with spring physics (kinetic style)\n`,\n },\n {\n filename: \"social-media.md\",\n content: `# Social Media Video Guide (TikTok/Reels/Shorts)\n\n**Platforms:** TikTok, Instagram Reels, YouTube Shorts (all 9:16 vertical)\n\n**Philosophy:** \"Don't make ads. Make TikToks.\" Your video must look native to the platform - lo-fi beats polished.\n\n---\n\n## 1. The \"3-Second War\"\n\nYou have 3 seconds before the thumb scrolls. Win or lose everything.\n\n### Hook Requirements (0-3s)\n\n- **Text on screen in FRAME 1** - no waiting for audio\n- **Movement** - never start static\n- **Pattern interrupt** - something unexpected\n\n### Hook Types\n\n| Type | Description | Use For |\n|------|-------------|---------|\n| Face Close-Up | Tight on face, zoom out | Personal/story |\n| Green Screen | Speaker + background tweet/article | Commentary |\n| Text Slam | Bold text hits screen with sound | Listicles, tips |\n| Movement | Object thrown, quick zoom | Product demos |\n\n### Audio Hooks\n\nBad: \"Today I want to talk about...\"\nGood: \"Stop scrolling if you hate [X].\" / \"This feels illegal to know.\"\n\n---\n\n## 2. Pacing Rules (No Dead Air)\n\n| Rule | Implementation |\n|------|----------------|\n| Visual change every 2-3s | Cut, zoom, or new element every 60-90 frames |\n| No \"Millennial Pause\" | Never start with 1-2s of stillness |\n| Remove all breaths | Edit out pauses between sentences |\n| Jump cuts are native | Don't smooth-cut; jump cuts feel authentic |\n\n---\n\n## 3. Native Lo-Fi Aesthetic\n\n| Looks Like TV Ad (Bad) | Looks Native (Good) |\n|------------------------|---------------------|\n| Perfect lighting | Natural/ring light |\n| Broadcast fonts | Platform-native fonts |\n| Smooth transitions | Jump cuts |\n| Color graded | Raw, slightly oversaturated |\n\n### Native Font Stack\n\n\\`\\`\\`tsx\nconst NATIVE_FONT = \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\";\n\\`\\`\\`\n\n---\n\n## 4. Safe Zone Rules (CRITICAL)\n\nPlatform UI overlays your content. Plan for it.\n\n\\`\\`\\`\n1080x1920 Canvas\n+------------------------------------------+\n| TOP SAFE ZONE (150px) | <- Notch, status bar\n| ----------------------------------------|\n| |\n| CONTENT SAFE ZONE |\n| (60px left, 120px right margins) |\n| |\n| ----------------------------------------|\n| BOTTOM SAFE ZONE (384px / 20%) | <- Captions, username\n| [Icon strip on right: 120px] | <- Like, Comment, Share\n+------------------------------------------+\n\\`\\`\\`\n\n### Safe Zone Values\n\n\\`\\`\\`tsx\nconst SAFE_ZONE = {\n top: 150, // Notch/status bar\n bottom: 384, // 20% of 1920 - captions/username\n left: 60, // Edge safety\n right: 120, // Like/Comment/Share icons\n};\n\n// Captions must sit ABOVE bottom safe zone\nconst CAPTION_BOTTOM = 350; // px from bottom\n\\`\\`\\`\n\n### SafeZoneGuide Component\n\n\\`\\`\\`tsx\nconst SafeZoneGuide: React.FC = () => (\n <AbsoluteFill style={{ pointerEvents: \"none\" }}>\n {/* Top danger zone */}\n <div style={{\n position: \"absolute\", top: 0, left: 0, right: 0, height: 150,\n backgroundColor: \"rgba(255,0,0,0.2)\", borderBottom: \"2px dashed red\",\n }} />\n {/* Bottom danger zone */}\n <div style={{\n position: \"absolute\", bottom: 0, left: 0, right: 0, height: 384,\n backgroundColor: \"rgba(255,0,0,0.2)\", borderTop: \"2px dashed red\",\n }} />\n {/* Right icon strip */}\n <div style={{\n position: \"absolute\", top: 150, right: 0, bottom: 384, width: 120,\n backgroundColor: \"rgba(255,165,0,0.2)\", borderLeft: \"2px dashed orange\",\n }} />\n </AbsoluteFill>\n);\n\\`\\`\\`\n\n---\n\n## 5. Content Formats\n\n### Green Screen (Speaker + Background)\n\n\\`\\`\\`tsx\n<AbsoluteFill>\n <Img src={backgroundImage} style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }} />\n <div style={{\n position: \"absolute\", bottom: 400, left: 40,\n width: 300, height: 400, borderRadius: 20, overflow: \"hidden\",\n }}>\n <Video src={speakerVideo} />\n </div>\n</AbsoluteFill>\n\\`\\`\\`\n\n### Listicle (Rapid-Fire)\n\n\\`\\`\\`tsx\nconst FRAMES_PER_ITEM = 60; // 2 seconds per item\nconst currentIndex = Math.floor(frame / FRAMES_PER_ITEM);\n// Slam-in with spring animation for each item\n\\`\\`\\`\n\n### Visual ASMR (No Talking)\n\n- No voiceover, music only\n- Slow, deliberate cursor movements\n- Satisfying click feedback\n- Ken Burns zoom on details\n\n### POV Skit\n\n\\`\\`\\`tsx\n<div style={{ position: \"absolute\", top: 160, left: 40, right: 120, fontSize: 42 }}>\n POV: {setup}\n</div>\n\\`\\`\\`\n\n---\n\n## 6. TikTok Captions\n\nUse \\`@remotion/captions\\` with \\`createTikTokStyleCaptions\\`:\n\n\\`\\`\\`tsx\nimport { createTikTokStyleCaptions } from \"@remotion/captions\";\n\nconst { pages } = createTikTokStyleCaptions({\n captions: transcriptCaptions,\n combineTokensWithinMilliseconds: 1200, // Higher = more words per page\n});\n\\`\\`\\`\n\n### Word-by-Word Highlighting\n\n\\`\\`\\`tsx\n{page.tokens.map((token) => {\n const isActive = currentTimeMs >= token.fromMs && currentTimeMs < token.toMs;\n return (\n <span style={{\n color: isActive ? \"#FFD700\" : \"#fff\",\n fontSize: 64,\n fontWeight: 900,\n textTransform: \"uppercase\",\n }}>\n {token.text}\n </span>\n );\n})}\n\\`\\`\\`\n\n---\n\n## 7. Script Structure (60 Seconds)\n\n| Timestamp | Section | Purpose |\n|-----------|---------|---------|\n| 0:00-0:03 | **HOOK** | Pattern interrupt, bold claim |\n| 0:03-0:10 | **PROBLEM** | Agitate the pain point |\n| 0:10-0:40 | **SOLUTION** | Rapid value delivery |\n| 0:40-0:55 | **PROOF** | Show, don't tell |\n| 0:55-0:60 | **CTA** | Soft ask (Follow/Link in bio) |\n\n### CTA Best Practices\n\n| Do | Don't |\n|----|-------|\n| \"Follow for more tips\" | \"SMASH that like button\" |\n| \"Link in bio\" | \"Click the link below\" |\n| \"Save this for later\" | \"Subscribe to my channel\" |\n\n---\n\n## 8. Quick Reference\n\n### Platform Specs\n\n| Platform | Ratio | Resolution | Duration | FPS |\n|----------|-------|------------|----------|-----|\n| TikTok | 9:16 | 1080x1920 | 15-60s | 30 |\n| Reels | 9:16 | 1080x1920 | 15-90s | 30 |\n| Shorts | 9:16 | 1080x1920 | 15-60s | 30 |\n| YouTube | 16:9 | 1920x1080 | any | 30/60 |\n\n### Timing (30fps)\n\n| Action | Frames | Seconds |\n|--------|--------|---------|\n| Hook impact | 0-3 | 0-0.1s |\n| Text hold min | 45 | 1.5s |\n| Scene change max | 90 | 3s |\n| Ideal scene | 60 | 2s |\n\n### Self-Check\n\n- [ ] Text in FRAME 1 (no millennial pause)\n- [ ] Visual change every 2-3 seconds\n- [ ] All content within safe zones\n- [ ] Captions at bottom: 350px+\n- [ ] No content in bottom 20% or right 120px\n- [ ] Lo-fi aesthetic (not TV ad)\n- [ ] CTA is soft, not desperate\n- [ ] Duration 15-60 seconds\n`,\n },\n];\n","/**\n * TTS (Text-to-Speech) Command\n * Generate speech from text and list available voices\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { generateSpeech, getVoices } from \"../lib/api.js\";\nimport { success, error, info, printJson } from \"../lib/output.js\";\nimport type { OutputFormat, TTSProvider } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface GenerateOptions {\n text: string;\n voice?: string;\n provider?: string;\n model?: string;\n speed?: string;\n output: string;\n format: OutputFormat;\n}\n\nconst generateCommand = new Command(\"generate\")\n .description(\"Generate speech from text\")\n .requiredOption(\"-t, --text <text>\", \"Text to convert to speech\")\n .requiredOption(\"-o, --output <path>\", \"Output file path\")\n .option(\"-v, --voice <voice>\", \"Voice name or ID (e.g., Kore, Rachel, alloy)\")\n .option(\"-p, --provider <provider>\", \"Provider: gemini, elevenlabs, openai\")\n .option(\"-m, --model <model>\", \"Model (provider-specific)\")\n .option(\"-s, --speed <speed>\", \"Speech speed 0.25-4.0 (default: 1.0)\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: GenerateOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Generating speech...\").start() : null;\n\n // Parse speed if provided\n let speed: number | undefined;\n if (options.speed) {\n speed = parseFloat(options.speed);\n if (isNaN(speed) || speed < 0.25 || speed > 4) {\n spinner?.stop();\n error(\"Speed must be between 0.25 and 4.0\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n try {\n const result = await generateSpeech({\n text: options.text,\n options: {\n provider: options.provider as TTSProvider | undefined,\n voice: options.voice,\n model: options.model,\n speed,\n },\n });\n\n spinner?.stop();\n\n // Save audio file\n const outputPath = options.output.endsWith(`.${result.format}`)\n ? options.output\n : `${options.output}.${result.format}`;\n\n await writeFile(outputPath, result.audioData);\n\n if (format === \"json\") {\n printJson({\n status: \"completed\",\n output: outputPath,\n duration: result.duration,\n cost: result.cost,\n provider: result.provider,\n format: result.format,\n });\n return;\n }\n\n if (format === \"quiet\") {\n console.log(outputPath);\n return;\n }\n\n // Human format\n success(`Saved to: ${outputPath}`);\n info(`Duration: ${result.duration.toFixed(2)}s`);\n info(`Provider: ${result.provider}`);\n info(`Cost: $${result.cost.toFixed(6)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst voicesCommand = new Command(\"voices\")\n .description(\"List available voices\")\n .option(\"-p, --provider <provider>\", \"Filter by provider: gemini, elevenlabs, openai\")\n .option(\"-f, --format <format>\", \"Output format: human, json\", \"human\")\n .action(async (options: { provider?: string; format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Fetching voices...\").start() : null;\n\n try {\n const result = await getVoices();\n spinner?.stop();\n\n if (options.format === \"json\") {\n if (options.provider) {\n const providerVoices = result.voices[options.provider as keyof typeof result.voices];\n printJson(providerVoices || []);\n } else {\n printJson(result.voices);\n }\n return;\n }\n\n // Human format\n const providers = options.provider\n ? [options.provider]\n : [\"gemini\", \"elevenlabs\", \"openai\"];\n\n for (const provider of providers) {\n const voices = result.voices[provider as keyof typeof result.voices];\n if (!voices || voices.length === 0) continue;\n\n console.log();\n console.log(`${provider.toUpperCase()} Voices:`);\n console.log(\"-\".repeat(50));\n\n for (const voice of voices) {\n console.log(` ${voice.name} (${voice.id})`);\n console.log(` ${voice.description}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const ttsCommand = new Command(\"tts\")\n .description(\"Text-to-speech commands\")\n .addCommand(generateCommand)\n .addCommand(voicesCommand);\n","/**\n * Music Generation Command\n * Generate music from text prompts and check status\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { generateMusic, checkMusicStatus, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn } from \"../lib/output.js\";\nimport type { MusicGenerationResult, OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface GenerateOptions {\n prompt: string;\n duration: string;\n style?: string;\n provider?: string;\n output?: string;\n wait: boolean;\n format: OutputFormat;\n}\n\nfunction outputResult(result: MusicGenerationResult, format: OutputFormat): void {\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n if (result.audioUrl) {\n console.log(result.audioUrl);\n } else {\n console.log(result.requestId);\n }\n return;\n }\n\n // Human format\n info(`Request ID: ${result.requestId}`);\n info(`Status: ${result.status}`);\n if (result.duration) {\n info(`Duration: ${result.duration}s`);\n }\n if (result.audioUrl) {\n success(`Audio URL: ${result.audioUrl}`);\n }\n if (result.cost !== undefined) {\n info(`Cost: $${result.cost.toFixed(4)}`);\n }\n if (result.error) {\n error(`Error: ${result.error}`);\n }\n}\n\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n // Handle data URLs (base64 encoded)\n if (url.startsWith(\"data:\")) {\n const matches = url.match(/^data:[^;]+;base64,(.+)$/);\n if (!matches) {\n throw new Error(\"Invalid data URL format\");\n }\n const buffer = Buffer.from(matches[1], \"base64\");\n await writeFile(outputPath, buffer);\n return;\n }\n\n // Handle regular URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\nconst generateCommand = new Command(\"generate\")\n .description(\"Generate music from a text prompt\")\n .requiredOption(\"-p, --prompt <text>\", \"Music description\")\n .option(\"-d, --duration <seconds>\", \"Duration in seconds (3-30)\", \"30\")\n .option(\"-s, --style <style>\", \"Style preset\")\n .option(\"--provider <provider>\", \"Provider (elevenlabs, suno)\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--no-wait\", \"Do not wait for completion\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: GenerateOptions) => {\n const duration = parseInt(options.duration, 10);\n if (isNaN(duration) || duration < 3 || duration > 30) {\n error(\"Duration must be between 3 and 30 seconds\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Generating music...\").start() : null;\n\n try {\n const result = await generateMusic({\n prompt: options.prompt,\n duration,\n options: {\n provider: options.provider,\n style: options.style,\n },\n });\n\n if (!options.wait) {\n spinner?.stop();\n outputResult(result, format);\n return;\n }\n\n // Skip polling if already completed\n let finalResult = result;\n if (result.status !== \"completed\" && result.status !== \"failed\") {\n if (spinner) spinner.text = `Processing (ID: ${result.requestId})...`;\n\n finalResult = await pollForCompletion(\n () => checkMusicStatus(result.requestId),\n 60,\n 2000\n );\n }\n\n spinner?.stop();\n\n if (finalResult.status === \"failed\") {\n error(finalResult.error || \"Music generation failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n outputResult(finalResult, format);\n\n // Download if output path specified\n if (options.output && finalResult.audioUrl) {\n const downloadSpinner = format === \"human\" ? ora(\"Downloading...\").start() : null;\n try {\n await downloadFile(finalResult.audioUrl, options.output);\n downloadSpinner?.stop();\n if (format === \"human\") {\n success(`Saved to: ${options.output}`);\n }\n } catch (err) {\n downloadSpinner?.stop();\n warn(`Failed to download: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst statusCommand = new Command(\"status\")\n .description(\"Check status of a music generation request\")\n .argument(\"<id>\", \"Request ID\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (id: string, options: { format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Checking status...\").start() : null;\n\n try {\n const result = await checkMusicStatus(id);\n spinner?.stop();\n outputResult(result, options.format);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const musicCommand = new Command(\"music\")\n .description(\"Music generation commands\")\n .addCommand(generateCommand)\n .addCommand(statusCommand);\n","/**\n * Audio Mix Command\n * Mix audio tracks into video\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { mixAudio, checkMixStatus, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn } from \"../lib/output.js\";\nimport type { AudioMixResult, AudioInput, OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface MixOptions {\n video: string;\n music?: string;\n voice?: string;\n musicVolume: string;\n voiceVolume: string;\n output?: string;\n wait: boolean;\n format: OutputFormat;\n}\n\nfunction outputResult(result: AudioMixResult, format: OutputFormat): void {\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n if (result.outputUrl) {\n console.log(result.outputUrl);\n } else {\n console.log(result.requestId);\n }\n return;\n }\n\n // Human format\n info(`Request ID: ${result.requestId}`);\n info(`Status: ${result.status}`);\n if (result.duration) {\n info(`Duration: ${result.duration}s`);\n }\n if (result.outputUrl) {\n success(`Output URL: ${result.outputUrl}`);\n }\n if (result.cost !== undefined) {\n info(`Cost: $${result.cost.toFixed(4)}`);\n }\n if (result.error) {\n error(`Error: ${result.error}`);\n }\n}\n\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\nconst mixCommand = new Command(\"create\")\n .description(\"Mix audio tracks into a video\")\n .requiredOption(\"--video <url>\", \"Input video file/URL\")\n .option(\"--music <url>\", \"Background music file/URL\")\n .option(\"--voice <url>\", \"Voiceover file/URL\")\n .option(\"--music-volume <percent>\", \"Music volume 0-100\", \"50\")\n .option(\"--voice-volume <percent>\", \"Voice volume 0-100\", \"100\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--no-wait\", \"Do not wait for completion\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: MixOptions) => {\n if (!options.music && !options.voice) {\n error(\"At least one of --music or --voice must be provided\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const musicVolume = parseInt(options.musicVolume, 10) / 100;\n const voiceVolume = parseInt(options.voiceVolume, 10) / 100;\n\n if (isNaN(musicVolume) || musicVolume < 0 || musicVolume > 1) {\n error(\"Music volume must be between 0 and 100\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n if (isNaN(voiceVolume) || voiceVolume < 0 || voiceVolume > 2) {\n error(\"Voice volume must be between 0 and 200\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Mixing audio...\").start() : null;\n\n const inputs: AudioInput[] = [{ url: options.video, role: \"video\" }];\n\n if (options.music) {\n inputs.push({ url: options.music, role: \"background\", volume: musicVolume * 5 });\n }\n\n if (options.voice) {\n inputs.push({ url: options.voice, role: \"voice\", volume: voiceVolume * 2 });\n }\n\n try {\n const result = await mixAudio({\n operation: \"add-to-video\",\n inputs,\n options: {\n musicVolume,\n voiceVolume,\n },\n });\n\n if (!options.wait) {\n spinner?.stop();\n outputResult(result, format);\n return;\n }\n\n if (spinner) spinner.text = `Processing (ID: ${result.requestId})...`;\n\n const finalResult = await pollForCompletion(\n () => checkMixStatus(result.requestId),\n 120,\n 3000\n );\n\n spinner?.stop();\n\n if (finalResult.status === \"failed\") {\n error(finalResult.error || \"Audio mixing failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n outputResult(finalResult, format);\n\n // Download if output path specified\n if (options.output && finalResult.outputUrl) {\n const downloadSpinner = format === \"human\" ? ora(\"Downloading...\").start() : null;\n try {\n await downloadFile(finalResult.outputUrl, options.output);\n downloadSpinner?.stop();\n if (format === \"human\") {\n success(`Saved to: ${options.output}`);\n }\n } catch (err) {\n downloadSpinner?.stop();\n warn(`Failed to download: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst statusCommand = new Command(\"status\")\n .description(\"Check status of an audio mix request\")\n .argument(\"<id>\", \"Request ID\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (id: string, options: { format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Checking status...\").start() : null;\n\n try {\n const result = await checkMixStatus(id);\n spinner?.stop();\n outputResult(result, options.format);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const mixAudioCommand = new Command(\"mix\")\n .description(\"Audio mixing commands\")\n .addCommand(mixCommand)\n .addCommand(statusCommand);\n","/**\n * Image Search Command\n * Search for images using various providers\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { searchImages } from \"../lib/api.js\";\nimport { success, error, info, printJson } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface SearchOptions {\n query: string;\n maxResults?: string;\n size?: string;\n safeSearch?: boolean;\n format: OutputFormat;\n}\n\nconst searchCommand = new Command(\"search\")\n .description(\"Search for images\")\n .requiredOption(\"-q, --query <query>\", \"Search query\")\n .option(\"-n, --max-results <number>\", \"Maximum number of results (default: 10)\")\n .option(\"-s, --size <size>\", \"Image size: small, medium, large, any\", \"large\")\n .option(\"--safe-search\", \"Enable safe search (default: true)\", true)\n .option(\"--no-safe-search\", \"Disable safe search\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: SearchOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Searching for images...\").start() : null;\n\n // Parse max results\n let maxResults: number | undefined;\n if (options.maxResults) {\n maxResults = parseInt(options.maxResults, 10);\n if (isNaN(maxResults) || maxResults < 1) {\n spinner?.stop();\n error(\"Max results must be a positive number\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n try {\n const result = await searchImages({\n query: options.query,\n options: {\n maxResults: maxResults || 10,\n size: options.size as \"small\" | \"medium\" | \"large\" | \"any\",\n safeSearch: options.safeSearch,\n },\n });\n\n spinner?.stop();\n\n if (!result.success) {\n error(\"Search failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n // Flatten results from all providers\n const allImages = result.data.results.flatMap((providerResult) =>\n providerResult.results.map((img) => ({\n ...img,\n provider: providerResult.providerName,\n }))\n );\n\n if (format === \"json\") {\n printJson({\n success: true,\n query: options.query,\n totalResults: allImages.length,\n totalCost: result.data.totalCost,\n images: allImages,\n });\n return;\n }\n\n if (format === \"quiet\") {\n // Just print URLs\n for (const img of allImages) {\n console.log(img.url);\n }\n return;\n }\n\n // Human format\n if (allImages.length === 0) {\n info(\"No images found\");\n return;\n }\n\n success(`Found ${allImages.length} images for \"${options.query}\"`);\n console.log();\n\n for (let i = 0; i < allImages.length; i++) {\n const img = allImages[i];\n console.log(`[${i + 1}] ${img.title || \"Untitled\"}`);\n console.log(` URL: ${img.url}`);\n console.log(` Size: ${img.width}x${img.height}`);\n if (img.author) {\n console.log(` Author: ${img.author}`);\n }\n console.log(` Provider: ${img.provider}`);\n console.log();\n }\n\n info(`Total cost: $${result.data.totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const imageCommand = new Command(\"image\")\n .description(\"Image search commands\")\n .addCommand(searchCommand);\n","/**\n * Video Command\n * Create video assets (voiceover, music, images) in one command\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { mkdir, writeFile, readFile, access, rm, cp } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { execSync, spawn } from \"child_process\";\nimport { generateSpeech, generateMusic, checkMusicStatus, searchImages, searchVideos, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn } from \"../lib/output.js\";\nimport type { OutputFormat, TTSTimestamps } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\n// Default GitHub template for video projects\nconst DEFAULT_TEMPLATE = \"inizio-inc/remotion-composition\";\n\n// Default FPS for video generation\nconst DEFAULT_FPS = 30;\n\n/**\n * Parse script into sections based on sentence boundaries\n * Each sentence becomes its own section for granular scene control\n * Only very short sentences (< 5 words) get grouped together\n */\nfunction parseScriptIntoSections(script: string): string[] {\n // Split by explicit section markers first\n if (script.includes(\"---\") || script.includes(\"[Section\")) {\n const parts = script.split(/---|\\[Section \\d+\\]/i).filter(s => s.trim());\n if (parts.length > 1) {\n return parts.map(p => p.trim());\n }\n }\n\n // Split by sentences - each sentence is its own section\n const sentences = script\n .split(/(?<=[.!?])\\s+/)\n .map(s => s.trim())\n .filter(s => s.length > 0);\n\n // Only group VERY short sentences (< 5 words) with the next one\n const sections: string[] = [];\n let pendingShort = \"\";\n\n for (const sentence of sentences) {\n const wordCount = sentence.split(/\\s+/).length;\n\n if (pendingShort) {\n // Combine with previous short sentence\n sections.push(`${pendingShort} ${sentence}`);\n pendingShort = \"\";\n } else if (wordCount < 5 && sections.length < sentences.length - 1) {\n // Very short sentence - hold it to combine with next\n pendingShort = sentence;\n } else {\n // Normal sentence - its own section\n sections.push(sentence);\n }\n }\n\n // Don't forget pending short sentence\n if (pendingShort) {\n if (sections.length > 0) {\n // Append to last section\n sections[sections.length - 1] += ` ${pendingShort}`;\n } else {\n sections.push(pendingShort);\n }\n }\n\n return sections;\n}\n\n/**\n * Calculate section timing using TTS timestamps for exact audio sync\n * Falls back to word-proportion estimation if timestamps not available\n */\nfunction calculateSectionTiming(\n sections: string[],\n totalDuration: number,\n fps: number = DEFAULT_FPS,\n timestamps?: TTSTimestamps\n): SceneSection[] {\n // If we have timestamps, use them for exact timing\n if (timestamps && timestamps.characters.length > 0) {\n return calculateSectionTimingFromTimestamps(sections, timestamps, fps);\n }\n\n // Fallback: estimate based on word proportions\n const totalWords = sections.reduce((sum, s) => sum + s.split(/\\s+/).length, 0);\n \n let currentTime = 0;\n return sections.map((text, index) => {\n const wordCount = text.split(/\\s+/).length;\n const proportion = wordCount / totalWords;\n const durationInSeconds = totalDuration * proportion;\n const durationInFrames = Math.round(durationInSeconds * fps);\n \n const section: SceneSection = {\n id: index + 1,\n text,\n wordCount,\n startTime: currentTime,\n endTime: currentTime + durationInSeconds,\n durationInSeconds,\n durationInFrames,\n };\n \n currentTime += durationInSeconds;\n return section;\n });\n}\n\n/**\n * Calculate section timing from TTS character-level timestamps\n * Finds the exact start/end time for each section based on where its text appears in audio\n */\nfunction calculateSectionTimingFromTimestamps(\n sections: string[],\n timestamps: TTSTimestamps,\n fps: number\n): SceneSection[] {\n const { characters, characterStartTimesSeconds, characterEndTimesSeconds } = timestamps;\n const fullText = characters.join(\"\");\n \n const results: SceneSection[] = [];\n let charIndex = 0;\n\n for (let i = 0; i < sections.length; i++) {\n const sectionText = sections[i];\n const sectionLength = sectionText.length;\n \n // Find where this section starts in the character array\n // Skip whitespace between sections\n while (charIndex < characters.length && characters[charIndex].match(/^\\s*$/)) {\n charIndex++;\n }\n \n const startCharIndex = charIndex;\n const startTime = characterStartTimesSeconds[startCharIndex] || 0;\n \n // Move to end of this section\n charIndex += sectionLength;\n \n // Skip trailing whitespace to find the actual end\n let endCharIndex = charIndex - 1;\n while (endCharIndex > startCharIndex && characters[endCharIndex]?.match(/^\\s*$/)) {\n endCharIndex--;\n }\n \n const endTime = characterEndTimesSeconds[Math.min(endCharIndex, characterEndTimesSeconds.length - 1)] || startTime + 1;\n \n const durationInSeconds = endTime - startTime;\n const durationInFrames = Math.round(durationInSeconds * fps);\n \n results.push({\n id: i + 1,\n text: sectionText,\n wordCount: sectionText.split(/\\s+/).length,\n startTime,\n endTime,\n durationInSeconds,\n durationInFrames,\n });\n }\n\n return results;\n}\n\ninterface CreateOptions {\n script?: string;\n scriptFile?: string;\n topic?: string;\n duration?: string;\n voice: string;\n musicPrompt?: string;\n numImages: string;\n output: string;\n format: OutputFormat;\n}\n\ninterface SceneInput {\n name: string;\n script: string;\n imageQuery?: string;\n videoQuery?: string;\n}\n\ninterface ScenesInput {\n scenes: SceneInput[];\n voice?: string;\n musicPrompt?: string;\n}\n\n/**\n * Read stdin if available (for piped JSON input)\n */\nasync function readStdin(): Promise<string | null> {\n if (process.stdin.isTTY) {\n return null;\n }\n\n return new Promise((resolve) => {\n let data = \"\";\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => { data += chunk; });\n process.stdin.on(\"end\", () => resolve(data.trim() || null));\n process.stdin.on(\"error\", () => resolve(null));\n\n // Timeout after 100ms if no data (not piped)\n setTimeout(() => {\n if (!data) resolve(null);\n }, 100);\n });\n}\n\n/**\n * Convert scene name to filename (kebab-case)\n */\nfunction toFilename(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\ninterface VoiceoverInfo {\n path: string;\n duration: number;\n voice: string;\n provider: string;\n cost: number;\n timestamps?: TTSTimestamps; // Character-level timing for word-by-word sync\n}\n\ninterface MusicInfo {\n path: string;\n duration: number;\n prompt: string;\n cost: number;\n}\n\ninterface ImageInfo {\n path: string;\n url: string;\n width: number;\n height: number;\n query: string;\n}\n\ninterface StockVideoInfo {\n path: string;\n url: string;\n width: number;\n height: number;\n duration: number;\n query: string;\n}\n\ninterface SceneSection {\n id: number;\n name: string;\n text: string;\n wordCount: number;\n startTime: number;\n endTime: number;\n durationInSeconds: number;\n durationInFrames: number; // at 30fps\n audioPath?: string;\n imagePath?: string;\n videoPath?: string;\n}\n\ninterface VideoManifest {\n music: MusicInfo;\n images: ImageInfo[];\n videos: StockVideoInfo[];\n scenes: SceneSection[];\n totalDurationInFrames: number;\n fps: number;\n totalCost: number;\n createdAt: string;\n}\n\n/**\n * Download a file from URL to local path\n * Handles both regular URLs and data URLs (base64)\n */\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n // Handle data URLs (base64 encoded)\n if (url.startsWith(\"data:\")) {\n const matches = url.match(/^data:[^;]+;base64,(.+)$/);\n if (!matches) {\n throw new Error(\"Invalid data URL format\");\n }\n const buffer = Buffer.from(matches[1], \"base64\");\n await writeFile(outputPath, buffer);\n return;\n }\n\n // Handle regular URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\n/**\n * Get file extension from URL\n */\nfunction getExtension(url: string): string {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const ext = pathname.split(\".\").pop()?.toLowerCase();\n if (ext && [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\"].includes(ext)) {\n return ext;\n }\n } catch {\n // Ignore URL parsing errors\n }\n return \"jpg\"; // Default to jpg\n}\n\nconst createCommand = new Command(\"create\")\n .description(\"Create video assets (voiceover per scene, music, images)\")\n .option(\"-s, --script <text>\", \"Narration script (legacy single-script mode)\")\n .option(\"--script-file <path>\", \"Path to script file (legacy) or scenes JSON\")\n .option(\"-t, --topic <text>\", \"Topic for image search\")\n .option(\"-v, --voice <name>\", \"TTS voice (Kore, Puck, Rachel, alloy)\", \"Kore\")\n .option(\"-m, --music-prompt <text>\", \"Music description\")\n .option(\"-n, --num-images <number>\", \"Number of images to search/download\", \"5\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./public\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: CreateOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Initializing...\").start() : null;\n\n try {\n // Check for stdin JSON (piped scenes)\n const stdinData = await readStdin();\n let scenesInput: ScenesInput | null = null;\n\n if (stdinData) {\n try {\n const parsed = JSON.parse(stdinData);\n if (parsed.scenes && Array.isArray(parsed.scenes)) {\n scenesInput = parsed as ScenesInput;\n }\n } catch {\n // Not valid JSON, ignore\n }\n }\n\n // Also check if script-file is a JSON with scenes\n if (!scenesInput && options.scriptFile) {\n try {\n const fileContent = await readFile(options.scriptFile, \"utf-8\");\n const parsed = JSON.parse(fileContent);\n if (parsed.scenes && Array.isArray(parsed.scenes)) {\n scenesInput = parsed as ScenesInput;\n }\n } catch {\n // Not JSON or no scenes array, will handle as legacy\n }\n }\n\n // Determine mode and settings\n const voice = scenesInput?.voice || options.voice;\n const musicPrompt = scenesInput?.musicPrompt || options.musicPrompt || \"uplifting background music, positive energy\";\n\n // Create directories\n const audioDir = join(options.output, \"audio\");\n const imagesDir = join(options.output, \"images\");\n const videosDir = join(options.output, \"videos\");\n\n if (spinner) spinner.text = \"Creating directories...\";\n await mkdir(audioDir, { recursive: true });\n await mkdir(imagesDir, { recursive: true });\n await mkdir(videosDir, { recursive: true });\n\n let totalCost = 0;\n let scenes: SceneSection[] = [];\n let totalDuration = 0;\n const allImages: ImageInfo[] = [];\n const allVideos: StockVideoInfo[] = [];\n\n if (scenesInput && scenesInput.scenes.length > 0) {\n // === PER-SCENE MODE ===\n if (format === \"human\") {\n spinner?.stop();\n info(`Processing ${scenesInput.scenes.length} scenes...`);\n spinner?.start();\n }\n\n let currentTime = 0;\n\n for (let i = 0; i < scenesInput.scenes.length; i++) {\n const scene = scenesInput.scenes[i];\n const filename = toFilename(scene.name);\n\n // Generate TTS\n if (spinner) spinner.text = `[${scene.name}] Generating speech...`;\n\n const ttsResult = await generateSpeech({\n text: scene.script,\n options: { voice },\n });\n\n const audioPath = join(audioDir, `${filename}.${ttsResult.format}`);\n await writeFile(audioPath, ttsResult.audioData);\n totalCost += ttsResult.cost;\n\n const durationInSeconds = ttsResult.duration;\n const durationInFrames = Math.round(durationInSeconds * DEFAULT_FPS);\n\n const sceneData: SceneSection = {\n id: i + 1,\n name: scene.name,\n text: scene.script,\n wordCount: scene.script.split(/\\s+/).length,\n startTime: currentTime,\n endTime: currentTime + durationInSeconds,\n durationInSeconds,\n durationInFrames,\n audioPath: `audio/${filename}.${ttsResult.format}`,\n };\n\n // Fetch image if query provided\n if (scene.imageQuery) {\n if (spinner) spinner.text = `[${scene.name}] Searching image...`;\n try {\n const imageResults = await searchImages({\n query: scene.imageQuery,\n options: { maxResults: 1, size: \"large\", safeSearch: true },\n });\n const imgs = imageResults.data.results.flatMap((r) => r.results);\n totalCost += imageResults.data.totalCost;\n\n if (imgs.length > 0) {\n const img = imgs[0];\n const ext = getExtension(img.url);\n const imgFilename = `${filename}.${ext}`;\n const imgPath = join(imagesDir, imgFilename);\n\n await downloadFile(img.url, imgPath);\n sceneData.imagePath = `images/${imgFilename}`;\n allImages.push({\n path: `images/${imgFilename}`,\n url: img.url,\n width: img.width,\n height: img.height,\n query: scene.imageQuery,\n });\n }\n } catch (err) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`[${scene.name}] Image search failed: ${err instanceof Error ? err.message : \"Unknown\"}`);\n spinner?.start();\n }\n }\n }\n\n // Fetch video if query provided\n if (scene.videoQuery) {\n if (spinner) spinner.text = `[${scene.name}] Searching video...`;\n try {\n const videoResults = await searchVideos({\n query: scene.videoQuery,\n options: { maxResults: 1 },\n });\n const vids = videoResults.data.results.flatMap((r) => r.results);\n totalCost += videoResults.data.totalCost;\n\n if (vids.length > 0) {\n const vid = vids[0];\n const vidUrl = vid.previewUrl || vid.downloadUrl;\n if (vidUrl) {\n const vidFilename = `${filename}.mp4`;\n const vidPath = join(videosDir, vidFilename);\n\n await downloadFile(vidUrl, vidPath);\n sceneData.videoPath = `videos/${vidFilename}`;\n allVideos.push({\n path: `videos/${vidFilename}`,\n url: vidUrl,\n width: vid.width,\n height: vid.height,\n duration: vid.duration,\n query: scene.videoQuery,\n });\n }\n }\n } catch (err) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`[${scene.name}] Video search failed: ${err instanceof Error ? err.message : \"Unknown\"}`);\n spinner?.start();\n }\n }\n }\n\n scenes.push(sceneData);\n currentTime += durationInSeconds;\n totalDuration += durationInSeconds;\n\n if (format === \"human\") {\n spinner?.stop();\n const assets = [\n `audio: ${durationInSeconds.toFixed(1)}s`,\n sceneData.imagePath ? \"image\" : null,\n sceneData.videoPath ? \"video\" : null,\n ].filter(Boolean).join(\", \");\n success(` ${scene.name}: ${assets}`);\n spinner?.start();\n }\n }\n } else {\n // === LEGACY SINGLE-SCRIPT MODE ===\n let script = options.script;\n if (options.scriptFile) {\n try {\n script = await readFile(options.scriptFile, \"utf-8\");\n } catch (err) {\n spinner?.stop();\n error(`Failed to read script file: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n if (!script || script.trim().length === 0) {\n spinner?.stop();\n error(\"Provide scenes via stdin JSON, --script-file with scenes JSON, or --script for legacy mode\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n script = script.trim();\n // Topic extracted for potential future use (image search, etc.)\n const _topic = options.topic || script.split(\".\")[0].slice(0, 50);\n void _topic; // Silence unused variable warning\n\n if (spinner) spinner.text = \"Generating voiceover...\";\n const ttsResult = await generateSpeech({\n text: script,\n options: { voice },\n });\n\n const voiceoverPath = join(audioDir, `voiceover.${ttsResult.format}`);\n await writeFile(voiceoverPath, ttsResult.audioData);\n totalCost += ttsResult.cost;\n totalDuration = ttsResult.duration;\n\n // Parse into sections with estimated timing\n const sectionTexts = parseScriptIntoSections(script);\n const sectionsWithTiming = calculateSectionTiming(sectionTexts, ttsResult.duration, DEFAULT_FPS, ttsResult.timestamps);\n\n scenes = sectionsWithTiming.map((s, i) => ({\n ...s,\n name: `Section${i + 1}`,\n audioPath: `audio/voiceover.${ttsResult.format}`,\n }));\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Voiceover: ${voiceoverPath} (${ttsResult.duration.toFixed(1)}s)`);\n spinner?.start();\n }\n }\n\n // Generate music\n const musicDuration = Math.min(30, Math.ceil(totalDuration) + 5);\n\n if (spinner) spinner.text = \"Generating music...\";\n let musicResult = await generateMusic({\n prompt: musicPrompt,\n duration: musicDuration,\n });\n\n if (musicResult.status !== \"completed\" && musicResult.status !== \"failed\") {\n if (spinner) spinner.text = `Processing music (ID: ${musicResult.requestId})...`;\n musicResult = await pollForCompletion(\n () => checkMusicStatus(musicResult.requestId),\n 60,\n 2000\n );\n }\n\n if (musicResult.status === \"failed\") {\n spinner?.stop();\n error(`Music generation failed: ${musicResult.error || \"Unknown error\"}`);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n const musicPath = join(audioDir, \"music.mp3\");\n if (musicResult.audioUrl) {\n await downloadFile(musicResult.audioUrl, musicPath);\n }\n totalCost += musicResult.cost || 0;\n\n const musicInfo: MusicInfo = {\n path: \"audio/music.mp3\",\n duration: musicResult.duration || musicDuration,\n prompt: musicPrompt,\n cost: musicResult.cost || 0,\n };\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Music: ${musicPath} (${musicInfo.duration}s)`);\n spinner?.start();\n }\n\n // Write manifest\n if (spinner) spinner.text = \"Writing manifest...\";\n const totalDurationInFrames = Math.round(totalDuration * DEFAULT_FPS);\n const manifest: VideoManifest = {\n music: musicInfo,\n images: allImages,\n videos: allVideos,\n scenes,\n totalDurationInFrames,\n fps: DEFAULT_FPS,\n totalCost,\n createdAt: new Date().toISOString(),\n };\n\n const manifestPath = join(options.output, \"video-manifest.json\");\n await writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n\n spinner?.stop();\n\n if (format === \"json\") {\n printJson(manifest);\n return;\n }\n\n if (format === \"quiet\") {\n console.log(manifestPath);\n return;\n }\n\n // Human format summary\n console.log();\n success(\"Video assets created successfully!\");\n console.log();\n info(`Scenes: ${scenes.length} (${totalDurationInFrames} frames at ${DEFAULT_FPS}fps)`);\n for (const scene of scenes) {\n const assets = [\n scene.audioPath ? \"audio\" : null,\n scene.imagePath ? \"image\" : null,\n scene.videoPath ? \"video\" : null,\n ].filter(Boolean).join(\", \");\n info(` - ${scene.name}: ${scene.durationInSeconds.toFixed(1)}s [${assets}]`);\n }\n info(`Music: ${musicInfo.path} (${musicInfo.duration}s)`);\n info(`Manifest: ${manifestPath}`);\n console.log();\n info(`Total cost: $${totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\n/**\n * Video Search Command\n */\ninterface SearchOptions {\n maxResults: string;\n orientation: string;\n license: string;\n format: OutputFormat;\n}\n\nconst searchCommand = new Command(\"search\")\n .description(\"Search for stock videos\")\n .argument(\"<query>\", \"Search query\")\n .option(\"-n, --max-results <count>\", \"Maximum number of results\", \"10\")\n .option(\"-o, --orientation <type>\", \"Video orientation: landscape, portrait, square, any\", \"any\")\n .option(\"-l, --license <type>\", \"License type: free, premium, any\", \"any\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (query: string, options: SearchOptions) => {\n const { maxResults, orientation, license, format } = options;\n const spinner = format === \"human\" ? ora(\"Searching for videos...\").start() : null;\n\n try {\n const result = await searchVideos({\n query,\n options: {\n maxResults: parseInt(maxResults, 10),\n orientation: orientation as \"landscape\" | \"portrait\" | \"square\" | \"any\",\n license: license as \"free\" | \"premium\" | \"any\",\n },\n });\n\n spinner?.stop();\n\n // Flatten results from all providers\n const allVideos = result.data.results.flatMap((provider) => provider.results);\n\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n // Just output preview URLs\n allVideos.forEach((video) => {\n console.log(video.previewUrl || video.thumbnailUrl);\n });\n return;\n }\n\n // Human format\n if (allVideos.length === 0) {\n info(\"No videos found\");\n return;\n }\n\n success(`Found ${allVideos.length} videos for \"${query}\"`);\n console.log();\n\n allVideos.forEach((video, index) => {\n console.log(`[${index + 1}] ${video.title}`);\n console.log(` URL: ${video.previewUrl || video.thumbnailUrl}`);\n console.log(` Duration: ${video.duration}s | Size: ${video.width}x${video.height}`);\n console.log(` Provider: ${video.provider}`);\n console.log();\n });\n\n info(`Total cost: $${result.data.totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\n/**\n * Video Init Command\n * Scaffolds a new Remotion video project from the template\n */\ntype VideoType = \"landscape\" | \"tiktok\";\n\ninterface InitOptions {\n template: string;\n type: VideoType;\n install: boolean;\n format: OutputFormat;\n}\n\nconst initCommand = new Command(\"init\")\n .description(\"Create a new Remotion video project from template\")\n .argument(\"<name>\", \"Project directory name\")\n .option(\"-t, --template <repo>\", \"GitHub repo (user/repo)\", DEFAULT_TEMPLATE)\n .option(\"--type <type>\", \"Video type: landscape (16:9) or tiktok (9:16)\", \"landscape\")\n .option(\"--no-install\", \"Skip pnpm install\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (name: string, options: InitOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Initializing video project...\").start() : null;\n\n try {\n const targetDir = resolve(process.cwd(), name);\n\n // Check if directory already exists\n try {\n await access(targetDir);\n spinner?.stop();\n error(`Directory \"${name}\" already exists`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n } catch {\n // Directory doesn't exist, continue\n }\n\n // Validate template format to prevent command injection\n // Format: owner/repo or owner/repo#branch or owner/repo/subdir\n const templatePattern = /^[a-zA-Z0-9_-]+\\/[a-zA-Z0-9_.-]+(\\/[a-zA-Z0-9_.-]+)*(#[a-zA-Z0-9_.-]+)?$/;\n if (!templatePattern.test(options.template)) {\n spinner?.stop();\n error(`Invalid template format: \"${options.template}\". Expected format: owner/repo or owner/repo#branch`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n // Use degit to scaffold the project\n if (spinner) spinner.text = `Downloading template from ${options.template}...`;\n\n try {\n // Try using degit first (faster, no .git folder)\n execSync(`npx --yes degit ${options.template} \"${targetDir}\"`, {\n stdio: \"pipe\",\n });\n } catch {\n // Fallback to git clone + remove .git\n if (spinner) spinner.text = \"Cloning template...\";\n // Extract owner/repo (without subdir or branch) for git clone\n const repoMatch = options.template.match(/^([a-zA-Z0-9_-]+\\/[a-zA-Z0-9_.-]+)/);\n const repo = repoMatch ? repoMatch[1] : options.template;\n execSync(`git clone --depth 1 https://github.com/${repo}.git \"${targetDir}\"`, {\n stdio: \"pipe\",\n });\n await rm(join(targetDir, \".git\"), { recursive: true, force: true });\n }\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Template downloaded to ${name}/`);\n spinner?.start();\n }\n\n // Install dependencies\n if (options.install) {\n if (spinner) spinner.text = \"Installing dependencies...\";\n\n await new Promise<void>((resolvePromise, reject) => {\n const child = spawn(\"pnpm\", [\"install\"], {\n cwd: targetDir,\n stdio: \"pipe\",\n shell: true,\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolvePromise();\n } else {\n reject(new Error(`pnpm install failed with code ${code}`));\n }\n });\n\n child.on(\"error\", reject);\n });\n\n if (format === \"human\") {\n spinner?.stop();\n success(\"Dependencies installed\");\n spinner?.start();\n }\n }\n\n // Configure for TikTok format if specified\n if (options.type === \"tiktok\") {\n if (spinner) spinner.text = \"Configuring for TikTok (9:16)...\";\n\n const constantsPath = join(targetDir, \"types/constants.ts\");\n try {\n let constantsContent = await readFile(constantsPath, \"utf-8\");\n\n // Swap the default dimensions to TikTok\n constantsContent = constantsContent\n .replace(\n /export const VIDEO_WIDTH = 1920;/,\n \"export const VIDEO_WIDTH = 1080; // TikTok 9:16\"\n )\n .replace(\n /export const VIDEO_HEIGHT = 1080;/,\n \"export const VIDEO_HEIGHT = 1920; // TikTok 9:16\"\n )\n .replace(\n /export const VIDEO_FPS = 60;/,\n \"export const VIDEO_FPS = 30; // TikTok standard\"\n );\n\n await writeFile(constantsPath, constantsContent, \"utf-8\");\n\n if (format === \"human\") {\n spinner?.stop();\n success(\"Configured for TikTok (1080x1920 @ 30fps)\");\n spinner?.start();\n }\n } catch {\n // Constants file might have different structure, ignore\n }\n }\n\n spinner?.stop();\n\n // Output results\n if (format === \"json\") {\n printJson({\n name,\n path: targetDir,\n template: options.template,\n type: options.type,\n installed: options.install,\n });\n return;\n }\n\n if (format === \"quiet\") {\n console.log(targetDir);\n return;\n }\n\n // Human format\n console.log();\n success(`Video project \"${name}\" created successfully!`);\n if (options.type === \"tiktok\") {\n info(\"Format: TikTok/Reels/Shorts (1080x1920 @ 30fps)\");\n } else {\n info(\"Format: Landscape (1920x1080 @ 60fps)\");\n }\n console.log();\n info(\"Next steps:\");\n info(` cd ${name}`);\n if (!options.install) {\n info(\" pnpm install\");\n }\n info(\" pnpm dev # Preview in Remotion Studio\");\n info(\" cc video create ... # Generate assets to public/\");\n if (options.type === \"tiktok\") {\n info(\" pnpm exec remotion render TikTokVideo # Render TikTok video\");\n } else {\n info(\" pnpm exec remotion render FullVideo # Render final video\");\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const videoCommand = new Command(\"video\")\n .description(\"Video asset generation commands\")\n .addCommand(initCommand)\n .addCommand(createCommand)\n .addCommand(searchCommand);\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0hBX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsFX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+CX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwDX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8FX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["table","chalk","confirm","runLoginFlow","error","resolve","Conf","chalk","resolve","whoami","Command","chalk","cmd","Command","Command","chalk","confirm","ora","config","Command","chalk","chalk","ora","error","readFileSync","Command","chalk","open","resolve","Command","Command","chalk","Command","confirm","Command","resolve","ora","Command","resolve","basename","ora","Command","chalk","ora","brand","Command","chalk","ora","Command","ora","chalk","Command","chalk","Command","chalk","Command","chalk","header","createCommand","header","createCommand","brand","existsSync","resolve","resolve","existsSync","Command","chalk","Command","ora","writeFile","Command","ora","writeFile","buffer","generateCommand","Command","ora","writeFile","outputResult","downloadFile","statusCommand","Command","ora","Command","ora","writeFile","readFile","join","resolve","readStdin","downloadFile","buffer","createCommand","searchCommand","Command","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/brand.ts","../src/lib/config.ts","../src/lib/output.ts","../src/types/media.ts","../src/types/index.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/feature-cache.ts","../src/commands/login.ts","../src/index.ts","../src/commands/logout.ts","../src/commands/config.ts","../src/commands/create.ts","../src/lib/streaming.ts","../src/commands/list.ts","../src/commands/get.ts","../src/commands/delete.ts","../src/commands/export.ts","../src/commands/import.ts","../src/commands/branding.ts","../src/commands/derive.ts","../src/commands/ideas.ts","../src/commands/whoami.ts","../src/commands/skill/index.ts","../src/commands/skill/generate-main-skill.ts","../src/commands/skill/rules/video/content.ts","../src/commands/skill/generate-video-skill.ts","../src/commands/skill/generate-presentation-skill.ts","../src/commands/skill/installer.ts","../src/commands/skill/editors.ts","../src/commands/tts.ts","../src/commands/music.ts","../src/commands/mix.ts","../src/commands/image.ts","../src/commands/video.ts"],"sourcesContent":["/**\n * Brand Configuration\n * Supports whitelabeling for different products (Conceptcraft, Mindframes, etc.)\n */\n\nimport path from \"path\";\n\nexport interface BrandConfig {\n id: string;\n name: string;\n displayName: string;\n description: string;\n commands: string[];\n apiUrl: string;\n docsUrl: string;\n packageName: string;\n configDir: string;\n apiKeyEnvVar: string;\n apiUrlEnvVar: string;\n}\n\nconst BRANDS: Record<string, BrandConfig> = {\n conceptcraft: {\n id: \"conceptcraft\",\n name: \"conceptcraft\",\n displayName: \"ConceptCraft\",\n description: \"CLI tool for ConceptCraft presentation generation\",\n commands: [\"cc\", \"conceptcraft\"],\n apiUrl: \"https://conceptcraft.ai\",\n docsUrl: \"https://docs.conceptcraft.ai\",\n packageName: \"@conceptcraft/cli\",\n configDir: \".conceptcraft\",\n apiKeyEnvVar: \"CONCEPTCRAFT_API_KEY\",\n apiUrlEnvVar: \"CONCEPTCRAFT_API_URL\",\n },\n mindframes: {\n id: \"mindframes\",\n name: \"mindframes\",\n displayName: \"Mindframes\",\n description: \"CLI tool for Mindframes presentation generation\",\n commands: [\"mf\", \"mindframes\"],\n apiUrl: \"https://mindframes.app\",\n docsUrl: \"https://docs.mindframes.app\",\n packageName: \"@conceptcraft/mindframes\",\n configDir: \".mindframes\",\n apiKeyEnvVar: \"MINDFRAMES_API_KEY\",\n apiUrlEnvVar: \"MINDFRAMES_API_URL\",\n },\n};\n\n// Map command aliases to brand IDs\nconst COMMAND_TO_BRAND: Record<string, string> = {\n cc: \"conceptcraft\",\n conceptcraft: \"conceptcraft\",\n mf: \"mindframes\",\n mindframes: \"mindframes\",\n};\n\n/**\n * Detect brand from the command used to invoke the CLI\n */\nexport function detectBrand(): BrandConfig {\n // Get the binary name from argv[1] (the executed script path)\n const binaryPath = process.argv[1] || \"\";\n const binaryName = path.basename(binaryPath).replace(/\\.(js|ts)$/, \"\");\n\n // Check if running via symlink (cc, mf, etc.) or directly (cli.js)\n const brandId = COMMAND_TO_BRAND[binaryName];\n\n if (brandId) {\n return BRANDS[brandId];\n }\n\n // Fallback: check if any command name is in the path\n for (const [cmd, id] of Object.entries(COMMAND_TO_BRAND)) {\n if (binaryPath.includes(`/${cmd}`) || binaryPath.includes(`\\\\${cmd}`)) {\n return BRANDS[id];\n }\n }\n\n // Default to mindframes (for cc-mindframes repo)\n return BRANDS.mindframes;\n}\n\n/**\n * Get brand config by ID\n */\nexport function getBrandById(id: string): BrandConfig | undefined {\n return BRANDS[id];\n}\n\n/**\n * Current brand (detected at startup)\n */\nexport const brand = detectBrand();\n","/**\n * Configuration Management\n * Handles reading/writing CLI config from ~/.conceptcraft/config.json\n */\n\nimport Conf from \"conf\";\nimport { brand } from \"./brand.js\";\nimport type { CLIConfig } from \"../types/index.js\";\n\nconst DEFAULT_API_URL = \"https://www.mindframes.app\";\n\nconst schema = {\n apiKey: {\n type: \"string\" as const,\n },\n apiUrl: {\n type: \"string\" as const,\n default: DEFAULT_API_URL,\n },\n defaultTeamId: {\n type: \"string\" as const,\n },\n // OAuth tokens (preferred over API key)\n accessToken: {\n type: \"string\" as const,\n },\n refreshToken: {\n type: \"string\" as const,\n },\n tokenExpiresAt: {\n type: \"number\" as const,\n },\n // OAuth client registration (cached per-server)\n clientId: {\n type: \"string\" as const,\n },\n clientSecret: {\n type: \"string\" as const,\n },\n};\n\nconst config = new Conf<CLIConfig>({\n projectName: brand.name,\n schema,\n});\n\nexport function getConfig(): CLIConfig {\n return {\n apiKey: getApiKey(),\n apiUrl: getApiUrl(),\n defaultTeamId: config.get(\"defaultTeamId\"),\n accessToken: config.get(\"accessToken\"),\n refreshToken: config.get(\"refreshToken\"),\n tokenExpiresAt: config.get(\"tokenExpiresAt\"),\n clientId: config.get(\"clientId\"),\n clientSecret: config.get(\"clientSecret\"),\n };\n}\n\nexport function getApiKey(): string | undefined {\n // Environment variable takes precedence\n // Check brand-specific env var first, then fall back to legacy CC_SLIDES_API_KEY\n const envKey = process.env[brand.apiKeyEnvVar] ?? process.env.CC_SLIDES_API_KEY;\n if (envKey) {\n return envKey;\n }\n return config.get(\"apiKey\");\n}\n\nexport function setApiKey(key: string): void {\n config.set(\"apiKey\", key);\n}\n\nexport function getApiUrl(): string {\n // Check brand-specific env var first, then fall back to legacy CC_SLIDES_API_URL\n const envUrl = process.env[brand.apiUrlEnvVar] ?? process.env.CC_SLIDES_API_URL;\n if (envUrl) {\n return envUrl;\n }\n return config.get(\"apiUrl\") ?? DEFAULT_API_URL;\n}\n\nexport function setApiUrl(url: string): void {\n config.set(\"apiUrl\", url);\n}\n\nexport function getDefaultTeamId(): string | undefined {\n return config.get(\"defaultTeamId\");\n}\n\nexport function setDefaultTeamId(teamId: string): void {\n config.set(\"defaultTeamId\", teamId);\n}\n\nexport function clearConfig(): void {\n config.clear();\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nexport function hasApiKey(): boolean {\n return !!getApiKey();\n}\n\n// OAuth token management\nexport function getAccessToken(): string | undefined {\n return config.get(\"accessToken\");\n}\n\nexport function getRefreshToken(): string | undefined {\n return config.get(\"refreshToken\");\n}\n\nexport function getTokenExpiresAt(): number | undefined {\n return config.get(\"tokenExpiresAt\");\n}\n\nexport function setOAuthTokens(\n accessToken: string,\n refreshToken: string,\n expiresIn: number\n): void {\n config.set(\"accessToken\", accessToken);\n config.set(\"refreshToken\", refreshToken);\n // Store expiry as absolute timestamp (with 60s buffer for safety)\n config.set(\"tokenExpiresAt\", Date.now() + (expiresIn - 60) * 1000);\n}\n\nexport function clearOAuthTokens(): void {\n config.delete(\"accessToken\");\n config.delete(\"refreshToken\");\n config.delete(\"tokenExpiresAt\");\n}\n\nexport function isTokenExpired(): boolean {\n const expiresAt = config.get(\"tokenExpiresAt\");\n if (!expiresAt) return true;\n return Date.now() >= expiresAt;\n}\n\nexport function hasOAuthTokens(): boolean {\n return !!config.get(\"accessToken\") && !!config.get(\"refreshToken\");\n}\n\n// OAuth client registration (cached)\nexport function getClientId(): string | undefined {\n return config.get(\"clientId\");\n}\n\nexport function getClientSecret(): string | undefined {\n return config.get(\"clientSecret\");\n}\n\nexport function setOAuthClient(clientId: string, clientSecret: string): void {\n config.set(\"clientId\", clientId);\n config.set(\"clientSecret\", clientSecret);\n}\n\nexport function clearOAuthClient(): void {\n config.delete(\"clientId\");\n config.delete(\"clientSecret\");\n}\n\nexport { config };\n","/**\n * Output Formatting\n * Handles different output modes (human, json, table, quiet)\n */\n\nimport chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport type { OutputFormat, PresentationListItem, Branding } from \"../types/index.js\";\nimport { getApiUrl } from \"./config.js\";\n\n// Check if running in a TTY (interactive terminal)\nexport function isTTY(): boolean {\n return process.stdout.isTTY ?? false;\n}\n\n// Format output based on mode\nexport function formatOutput<T>(\n data: T,\n format: OutputFormat = \"human\",\n humanFormatter?: (data: T) => string\n): string {\n switch (format) {\n case \"json\":\n return JSON.stringify(data, null, 2);\n case \"quiet\":\n return \"\";\n case \"human\":\n default:\n if (humanFormatter) {\n return humanFormatter(data);\n }\n return String(data);\n }\n}\n\n// Success message\nexport function success(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.log(chalk.green(\"✓\"), message);\n}\n\n// Error message\nexport function error(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") {\n console.error(JSON.stringify({ error: message }));\n return;\n }\n console.error(chalk.red(\"✗\"), message);\n}\n\n// Warning message\nexport function warn(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.warn(chalk.yellow(\"⚠\"), message);\n}\n\n// Info message\nexport function info(message: string, format: OutputFormat = \"human\"): void {\n if (format === \"quiet\") return;\n if (format === \"json\") return;\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n// Debug message\nexport function debug(message: string, isDebug = false): void {\n if (!isDebug) return;\n console.log(chalk.gray(\"[DEBUG]\"), message);\n}\n\n// Build view URL from slug\nexport function buildViewUrl(slug?: string, language = \"en\"): string {\n if (!slug) return \"N/A\";\n const apiUrl = getApiUrl();\n return `${apiUrl}/${language}/view/presentations/${slug}`;\n}\n\n// Format presentation list as table\nexport function formatPresentationTable(\n presentations: PresentationListItem[],\n options: { showLinks?: boolean; language?: string } = {}\n): string {\n const { showLinks = false, language = \"en\" } = options;\n\n const truncate = (str: string, len: number) =>\n str.length > len ? str.slice(0, len - 1) + \"…\" : str;\n\n // Format date/time as \"Jan 18, 1:04 AM\"\n const shortDateTime = (dateStr: string) => {\n try {\n const d = new Date(dateStr);\n return d.toLocaleString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n }).replace(\" at \", \", \");\n } catch {\n return \"-\";\n }\n };\n\n if (showLinks) {\n // Detail format: all columns + URL\n const table = new Table({\n head: [\n chalk.cyan(\"Slug\"),\n chalk.cyan(\"Title\"),\n chalk.cyan(\"Slides\"),\n chalk.cyan(\"Created\"),\n chalk.cyan(\"URL\"),\n ],\n });\n\n for (const p of presentations) {\n table.push([\n truncate(p.slug || p.id.slice(0, 8), 30),\n truncate(p.title || \"Untitled\", 22),\n String(p.numberOfSlides || \"-\"),\n shortDateTime(p.createdAt),\n buildViewUrl(p.slug, language),\n ]);\n }\n\n return table.toString();\n }\n\n // Standard compact format without URLs\n const table = new Table({\n head: [\n chalk.cyan(\"Slug\"),\n chalk.cyan(\"Title\"),\n chalk.cyan(\"Slides\"),\n chalk.cyan(\"Mode\"),\n chalk.cyan(\"Created\"),\n ],\n colWidths: [32, 28, 8, 11, 18],\n });\n\n for (const p of presentations) {\n table.push([\n p.slug || p.id.slice(0, 8),\n p.title || \"Untitled\",\n String(p.numberOfSlides || \"-\"),\n p.mode || \"-\",\n shortDateTime(p.createdAt),\n ]);\n }\n\n return table.toString();\n}\n\n// Format presentation list as slugs only (for scripting)\nexport function formatPresentationIds(presentations: PresentationListItem[]): string {\n return presentations.map((p) => p.slug || p.id).join(\"\\n\");\n}\n\n// Format branding list as table\nexport function formatBrandingTable(brandings: Branding[]): string {\n // Sort: defaults first, then by createdAt descending (most recent first)\n const sorted = [...brandings].sort((a, b) => {\n if (a.isDefault && !b.isDefault) return -1;\n if (!a.isDefault && b.isDefault) return 1;\n // Sort by createdAt descending (most recent first)\n const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return dateB - dateA;\n });\n\n // Normalize URL for display (ensure https://)\n const formatUrl = (url?: string) => {\n if (!url) return \"-\";\n try {\n const u = new URL(url);\n return u.href;\n } catch {\n // If not a valid URL, try adding https://\n return url.startsWith(\"http\") ? url : `https://${url}`;\n }\n };\n\n const table = new Table({\n head: [\n chalk.cyan(\"Name\"),\n chalk.cyan(\"Source\"),\n chalk.cyan(\"Color\"),\n chalk.cyan(\"Logo\"),\n chalk.cyan(\"Default\"),\n chalk.cyan(\"ID\"),\n ],\n });\n\n for (const b of sorted) {\n const colorDisplay = b.primaryColor\n ? `${chalk.bgHex(b.primaryColor)(\" \")} ${b.primaryColor}`\n : \"-\";\n table.push([\n b.name,\n formatUrl(b.sourceUrl),\n colorDisplay,\n b.logoUrl ? chalk.green(\"✓\") : chalk.gray(\"✗\"),\n b.isDefault ? chalk.green(\"★\") : \"\",\n b.id,\n ]);\n }\n\n return table.toString();\n}\n\n// Format date for display\nexport function formatDate(dateStr: string): string {\n try {\n const date = new Date(dateStr);\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\n// Print header for commands\nexport function header(text: string): void {\n console.log();\n console.log(chalk.bold(text));\n console.log(chalk.gray(\"─\".repeat(text.length)));\n}\n\n// Print key-value pair\nexport function keyValue(key: string, value: string | number | undefined): void {\n console.log(` ${chalk.gray(key + \":\")} ${value ?? \"-\"}`);\n}\n\n// Create progress bar string\nexport function progressBar(current: number, total: number, width = 30, showPercentage = true): string {\n const percentage = Math.min(100, Math.round((current / total) * 100));\n const filled = Math.round((width * current) / total);\n const empty = width - filled;\n\n const bar = chalk.green(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n return showPercentage ? `[${bar}] ${percentage}%` : `[${bar}]`;\n}\n\n// Format JSON for output\nexport function formatJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\n// Print JSON to stdout\nexport function printJson(data: unknown): void {\n console.log(formatJson(data));\n}\n","/**\n * Media Types\n * Types for TTS, music generation, audio mixing, and image search\n */\n\n// TTS types\nexport type TTSProvider = \"elevenlabs\" | \"openai\" | \"gemini\" | \"google\";\n\nexport interface TTSTimestamps {\n characters: string[];\n characterStartTimesSeconds: number[];\n characterEndTimesSeconds: number[];\n}\n\nexport interface VoiceSettings {\n speed?: number; // 0.25-4.0, default 1.0\n stability?: number; // 0-1, default 0.5 (lower = more variation)\n similarity?: number; // 0-1, default 0.75 (voice consistency)\n style?: number; // 0-1, default 0.3 (higher = more expressive)\n}\n\nexport interface TTSRequest {\n text: string;\n options?: {\n provider?: TTSProvider;\n voice?: string;\n model?: string;\n speed?: number; // 0.25-4.0 (legacy, prefer voiceSettings)\n voiceSettings?: VoiceSettings;\n };\n}\n\nexport interface TTSResult {\n audioData: Buffer;\n duration: number;\n cost: number;\n provider: string;\n format: string;\n timestamps?: TTSTimestamps; // Character-level timing from TTS API\n}\n\nexport interface TTSVoice {\n id: string;\n name: string;\n description: string;\n}\n\nexport interface TTSVoicesResponse {\n voices: {\n gemini: TTSVoice[];\n elevenlabs: TTSVoice[];\n openai: TTSVoice[];\n };\n}\n\n// Music generation types\nexport interface MusicGenerationRequest {\n prompt: string;\n duration: number; // 3-30 seconds\n options?: {\n provider?: string; // 'elevenlabs' (default)\n instrumental?: boolean;\n style?: string;\n tempo?: number; // BPM 60-180\n format?: \"mp3\" | \"wav\" | \"flac\" | \"ogg\";\n };\n}\n\nexport interface MusicGenerationResult {\n requestId: string;\n status: \"pending\" | \"processing\" | \"completed\" | \"failed\";\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n}\n\n// Audio mixing types\nexport type AudioMixOperation =\n | \"add-to-video\"\n | \"mix-tracks\"\n | \"extract-audio\"\n | \"replace-audio\"\n | \"overlay\";\n\nexport interface AudioInput {\n url: string;\n role?: \"video\" | \"voice\" | \"music\" | \"background\";\n volume?: number; // 0-5\n startTime?: number;\n endTime?: number;\n}\n\nexport interface AudioMixRequest {\n operation: AudioMixOperation;\n inputs: AudioInput[];\n options?: {\n musicVolume?: number; // 0-1, default 0.25\n voiceVolume?: number; // 0-2, default 1.0\n fadeOutMusic?: boolean;\n outputFormat?: string;\n };\n}\n\nexport interface AudioMixResult {\n requestId: string;\n status: \"pending\" | \"processing\" | \"completed\" | \"failed\";\n outputUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n}\n\n// Image search types\nexport interface ImageSearchRequest {\n query: string;\n options?: {\n providers?: string[];\n maxResults?: number;\n size?: \"small\" | \"medium\" | \"large\" | \"any\";\n safeSearch?: boolean;\n };\n}\n\nexport interface ImageSearchResultItem {\n url: string;\n width: number;\n height: number;\n title?: string;\n thumbnailUrl?: string;\n sourceUrl?: string;\n author?: string;\n provider: string;\n}\n\nexport interface ImageSearchResponse {\n success: boolean;\n data: {\n results: Array<{\n providerId: number;\n providerName: string;\n status: string;\n results: ImageSearchResultItem[];\n cost: number;\n }>;\n totalCost: number;\n };\n requestId: string;\n}\n\n// Video search types\nexport interface VideoSearchRequest {\n query: string;\n options?: {\n providers?: string[];\n maxResults?: number;\n orientation?: \"landscape\" | \"portrait\" | \"square\" | \"any\";\n license?: \"free\" | \"premium\" | \"any\";\n };\n}\n\nexport interface VideoSearchResultItem {\n id: string;\n title: string;\n description?: string;\n thumbnailUrl: string;\n previewUrl?: string;\n downloadUrl?: string;\n duration: number;\n width: number;\n height: number;\n fps?: number;\n provider: string;\n sourceUrl: string;\n author?: string;\n license?: string;\n}\n\nexport interface VideoSearchResponse {\n success: boolean;\n data: {\n results: Array<{\n providerId: number;\n providerName: string;\n status: string;\n results: VideoSearchResultItem[];\n cost: number;\n }>;\n totalCost: number;\n };\n requestId: string;\n}\n\n","/**\n * CLI Types and Interfaces\n */\n\n// Re-export media types\nexport * from \"./media.js\";\n\nexport interface CLIConfig {\n apiKey?: string;\n apiUrl: string;\n defaultTeamId?: string;\n // OAuth tokens (preferred over API key)\n accessToken?: string;\n refreshToken?: string;\n tokenExpiresAt?: number; // Unix timestamp in ms\n // OAuth client registration (cached)\n clientId?: string;\n clientSecret?: string;\n}\n\nexport interface OAuthTokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token: string;\n scope: string;\n}\n\nexport interface OAuthClientRegistration {\n client_id: string;\n client_secret: string;\n client_id_issued_at: number;\n client_secret_expires_at: number;\n client_name: string;\n redirect_uris: string[];\n grant_types: string[];\n response_types: string[];\n token_endpoint_auth_method: string;\n scope: string;\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n}\n\nexport interface Presentation {\n id: string;\n slug: string;\n title: string;\n description?: string;\n numberOfSlides: number;\n mode?: string;\n createdAt: string;\n documentCreatedAt?: string;\n updatedAt?: string;\n viewUrl?: string;\n}\n\n/** File upload result from S3 */\nexport interface FileUploadResult {\n id: string;\n name: string;\n url: string;\n size: number;\n type: string;\n selected: boolean;\n}\n\n/** Presentation goal/purpose */\nexport type PresentationGoal =\n | \"inform\"\n | \"persuade\"\n | \"train\"\n | \"learn\"\n | \"entertain\"\n | \"report\";\n\nexport interface PresentationCreateOptions {\n topic: string;\n slideCount?: number;\n mode?: GenerationMode;\n tone?: GenerationTone;\n amount?: GenerationAmount;\n audience?: string;\n language?: string;\n brandId?: string;\n brandUrl?: string;\n sources?: string[];\n stdinContent?: string;\n /** Direct text context to include */\n context?: string;\n /** Path to a file containing context */\n contextFile?: string;\n stylingMode?: StylingMode;\n /** URL to use as a style reference (e.g., template image) */\n referenceUrl?: string;\n /** AI thinking depth: quick, moderate, deep, profound */\n thinkingDepth?: ThinkingDepth;\n /** Files uploaded to S3 (from --file option) */\n uploadedFiles?: FileUploadResult[];\n /** Presentation goal: inform, persuade, train, learn, entertain, report */\n goal?: PresentationGoal;\n /** Custom goal description (overrides preset goal) */\n customGoal?: string;\n /** Team ID to create presentation for (allows switching teams) */\n teamId?: string;\n /** Theme customization options */\n theme?: ThemeOptions;\n}\n\n/** AI thinking depth for content generation */\nexport type ThinkingDepth = \"quick\" | \"moderate\" | \"deep\" | \"profound\";\n\n/** Preset theme options */\nexport type ThemePreset = \"blue\" | \"violet\" | \"rose\" | \"orange\" | \"green\";\n\n/** Background decoration styles */\nexport type DecorationStyle = \"none\" | \"waves-bottom-left\" | \"waves-top-right\" | \"blob-corners\" | \"minimal\";\n\n/** Custom color overrides in hex format */\nexport interface ThemeCustomColors {\n primary?: string;\n secondary?: string;\n accent?: string;\n background?: string;\n foreground?: string;\n}\n\n/** Theme customization options for slide generation */\nexport interface ThemeOptions {\n /** Preset theme name */\n preset?: ThemePreset;\n /** Custom colors in hex format (e.g., \"#0066CC\") */\n custom?: ThemeCustomColors;\n /** Decoration style for slide backgrounds */\n decorations?: DecorationStyle;\n}\n\n/** Generation quality/speed mode */\nexport type GenerationMode =\n | \"best\"\n | \"balanced\"\n | \"fast\"\n | \"ultrafast\"\n | \"instant\";\n\n/** Presentation tone/style */\nexport type GenerationTone =\n | \"creative\"\n | \"professional\"\n | \"educational\"\n | \"formal\"\n | \"casual\";\n\n/** Content amount/density */\nexport type GenerationAmount = \"minimal\" | \"concise\" | \"detailed\" | \"extensive\";\n\nexport type StylingMode = \"freeform\" | \"brand-only\" | \"brand-plus-style\" | \"style-only\" | \"no-styling\";\n\nexport interface PresentationListItem {\n id: string;\n slug: string;\n title: string;\n numberOfSlides: number;\n mode?: string;\n createdAt: string;\n}\n\nexport interface CreatePresentationResponse {\n presentation: Presentation;\n viewUrl: string;\n}\n\nexport interface StreamEvent {\n type: string;\n data: unknown;\n}\n\nexport interface SlideProgressEvent {\n current: number;\n total: number;\n}\n\nexport interface Branding {\n id: string;\n name: string;\n logoUrl?: string;\n primaryColor?: string;\n isDefault: boolean;\n sourceUrl?: string;\n createdAt?: string;\n}\n\nexport interface BrandingExtractResult {\n id: string;\n brandData: Record<string, unknown>;\n}\n\nexport interface ExportOptions {\n includeImages?: boolean;\n includeBranding?: boolean;\n includeExternal?: boolean;\n}\n\nexport interface ImportOptions {\n dryRun?: boolean;\n overwrite?: boolean;\n remapIds?: boolean;\n}\n\nexport interface ImportResult {\n success: boolean;\n presentationId?: string;\n documentId?: string;\n errors?: Array<{ type: string; message: string }>;\n warnings?: string[];\n statistics?: {\n slidesImported: number;\n imagesUploaded: number;\n totalTimeMs: number;\n };\n}\n\nexport interface BlogGenerationOptions {\n targetWordCount?: number;\n tone?: \"professional\" | \"casual\" | \"educational\";\n targetAudience?: string;\n blogFormat?: string;\n customInstructions?: string;\n includeImages?: boolean;\n includeTableOfContents?: boolean;\n language?: string;\n}\n\nexport interface DeriveOptions {\n format?: OutputFormat;\n count?: number;\n mode?: string;\n}\n\nexport type OutputFormat = \"human\" | \"json\" | \"quiet\" | \"markdown\" | \"table\" | \"ids\";\n\nexport interface CLIOptions {\n output?: OutputFormat;\n debug?: boolean;\n noColor?: boolean;\n noStream?: boolean;\n}\n\nexport const EXIT_CODES = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n AUTH_ERROR: 2,\n NOT_FOUND: 3,\n RATE_LIMIT: 4,\n NETWORK_ERROR: 5,\n INVALID_INPUT: 6,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n","/**\n * Authentication Helpers\n * Handles OAuth tokens and API key validation\n */\n\nimport chalk from \"chalk\";\nimport {\n hasApiKey,\n getApiKey,\n getConfigPath,\n hasOAuthTokens,\n getAccessToken,\n getRefreshToken,\n isTokenExpired,\n setOAuthTokens,\n clearOAuthTokens,\n getClientId,\n getApiUrl,\n} from \"./config.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\nimport type { OAuthTokenResponse } from \"../types/index.js\";\n\n/**\n * Refresh OAuth access token using refresh token\n */\nasync function refreshAccessToken(): Promise<string | null> {\n const refreshToken = getRefreshToken();\n const clientId = getClientId();\n const apiUrl = getApiUrl();\n\n if (!refreshToken || !clientId) {\n return null;\n }\n\n try {\n // Fetch token endpoint from metadata\n const metaResponse = await fetch(`${apiUrl}/.well-known/oauth-authorization-server`);\n if (!metaResponse.ok) {\n return null;\n }\n const metadata = await metaResponse.json();\n\n // Refresh the token\n const params = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: clientId,\n });\n\n const response = await fetch(metadata.token_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: params.toString(),\n });\n\n if (!response.ok) {\n // Refresh token may be expired or revoked\n clearOAuthTokens();\n return null;\n }\n\n const tokens: OAuthTokenResponse = await response.json();\n setOAuthTokens(tokens.access_token, tokens.refresh_token, tokens.expires_in);\n return tokens.access_token;\n } catch {\n return null;\n }\n}\n\n/**\n * Get a valid access token, refreshing if needed\n * Returns null if no valid token available\n */\nexport async function getValidAccessToken(): Promise<string | null> {\n if (!hasOAuthTokens()) {\n return null;\n }\n\n if (isTokenExpired()) {\n // Try to refresh\n return refreshAccessToken();\n }\n\n return getAccessToken() || null;\n}\n\n/**\n * Check if the CLI is authenticated (OAuth or API key)\n */\nexport function hasAuth(): boolean {\n return hasOAuthTokens() || hasApiKey();\n}\n\n/**\n * Get the authentication method being used\n */\nexport function getAuthMethod(): \"oauth\" | \"apiKey\" | \"none\" {\n if (hasOAuthTokens()) return \"oauth\";\n if (hasApiKey()) return \"apiKey\";\n return \"none\";\n}\n\n/**\n * Check if the CLI is authenticated and exit if not\n * Prompts user to login if not authenticated\n */\nexport async function requireAuth(): Promise<void> {\n if (!hasAuth()) {\n // Dynamic import to avoid circular dependency\n const { confirm } = await import(\"@inquirer/prompts\");\n\n try {\n const shouldLogin = await confirm({\n message: chalk.red(\"Not authenticated.\") + \" Log in now?\",\n default: true,\n });\n\n if (!shouldLogin) {\n console.log(chalk.gray(\"\\nTip: You can also set CC_MINDFRAMES_API_KEY environment variable.\"));\n process.exit(EXIT_CODES.AUTH_ERROR);\n }\n\n // Run login flow\n const { runLoginFlow } = await import(\"../commands/login.js\");\n await runLoginFlow({ browser: true });\n } catch {\n // User cancelled (Ctrl+C)\n process.exit(EXIT_CODES.AUTH_ERROR);\n }\n }\n}\n\n/**\n * Mask API key for display (show first 10 and last 4 chars)\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 14) {\n return \"****\";\n }\n return `${key.slice(0, 10)}...${key.slice(-4)}`;\n}\n\n/**\n * Get masked API key for display\n */\nexport function getMaskedApiKey(): string | undefined {\n const key = getApiKey();\n if (!key) return undefined;\n return maskApiKey(key);\n}\n\n/**\n * Validate API key format\n * Accepts:\n * - Better Auth API keys: cc_slides_*\n * - MCP API keys: mcp_*\n * - Legacy formats: cc_sk_*, sk_*\n */\nexport function isValidApiKeyFormat(key: string): boolean {\n // API keys should start with specific prefixes\n const validPrefixes = [\"cc_slides_\", \"mcp_\", \"cc_sk_\", \"sk_\"];\n return validPrefixes.some((prefix) => key.startsWith(prefix));\n}\n\n","/**\n * API Client\n * Handles HTTP requests to the ConceptCraft API\n * Supports OAuth tokens (preferred) and API keys (fallback)\n */\n\nimport { getApiKey, getApiUrl } from \"./config.js\";\nimport { getValidAccessToken, hasAuth, getAuthMethod } from \"./auth.js\";\nimport { brand } from \"./brand.js\";\nimport { readFileSync, statSync } from \"fs\";\nimport { basename } from \"path\";\nimport { randomUUID } from \"crypto\";\nimport type {\n ApiResponse,\n Presentation,\n PresentationListItem,\n PresentationCreateOptions,\n Branding,\n BrandingExtractResult,\n ExportOptions,\n ImportResult,\n BlogGenerationOptions,\n EXIT_CODES,\n FileUploadResult,\n TTSRequest,\n TTSResult,\n TTSVoicesResponse,\n MusicGenerationRequest,\n MusicGenerationResult,\n AudioMixRequest,\n AudioMixResult,\n ImageSearchRequest,\n ImageSearchResponse,\n VideoSearchRequest,\n VideoSearchResponse,\n} from \"../types/index.js\";\n\n/**\n * Get authorization headers for API requests\n * Prefers OAuth tokens, falls back to API key\n */\nasync function getAuthHeaders(): Promise<Record<string, string>> {\n // Try OAuth first (preferred)\n const accessToken = await getValidAccessToken();\n if (accessToken) {\n return { Authorization: `Bearer ${accessToken}` };\n }\n\n // Fall back to API key\n const apiKey = getApiKey();\n if (apiKey) {\n return { \"x-api-key\": apiKey };\n }\n\n return {};\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public statusCode: number,\n public exitCode: number = 1\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\ninterface RequestOptions {\n method?: \"GET\" | \"POST\" | \"DELETE\" | \"PUT\" | \"PATCH\";\n body?: unknown;\n headers?: Record<string, string>;\n stream?: boolean;\n}\n\nasync function request<T>(\n endpoint: string,\n options: RequestOptions = {}\n): Promise<T> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2 // AUTH_ERROR\n );\n }\n\n const authHeaders = await getAuthHeaders();\n const url = `${apiUrl}${endpoint}`;\n const headers: Record<string, string> = {\n ...authHeaders,\n ...options.headers,\n };\n\n if (options.body && !options.stream) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method: options.method ?? \"GET\",\n headers,\n };\n\n if (options.body) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, fetchOptions);\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5 // NETWORK_ERROR\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n let exitCode = 1; // GENERAL_ERROR\n\n switch (response.status) {\n case 401:\n exitCode = 2; // AUTH_ERROR\n break;\n case 403:\n exitCode = 2; // AUTH_ERROR (forbidden)\n break;\n case 404:\n exitCode = 3; // NOT_FOUND\n break;\n case 429:\n exitCode = 4; // RATE_LIMIT\n break;\n case 500:\n exitCode = 1; // SERVER_ERROR\n break;\n }\n\n // Ensure we always have an error message\n const message = errorText.trim() || `HTTP ${response.status}: ${response.statusText || \"Server error\"}`;\n throw new ApiError(message, response.status, exitCode);\n }\n\n if (options.stream) {\n return response as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text() as unknown as T;\n}\n\n// Streaming request for SSE endpoints\nexport async function streamRequest(\n endpoint: string,\n body: unknown\n): Promise<Response> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n const url = `${apiUrl}${endpoint}`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n let exitCode = 1;\n\n switch (response.status) {\n case 401:\n exitCode = 2;\n break;\n case 403:\n exitCode = 2;\n break;\n case 404:\n exitCode = 3;\n break;\n case 429:\n exitCode = 4;\n break;\n }\n\n throw new ApiError(errorText, response.status, exitCode);\n }\n\n return response;\n}\n\n// File Upload APIs\n\n/**\n * Get MIME type from file extension\n * Simple mapping without external dependencies\n */\nfunction getMimeType(filePath: string): string {\n const ext = filePath.toLowerCase().split(\".\").pop();\n const mimeTypes: Record<string, string> = {\n // Documents\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n // Images\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n // Text\n txt: \"text/plain\",\n md: \"text/markdown\",\n csv: \"text/csv\",\n json: \"application/json\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n ts: \"text/x-typescript\",\n py: \"text/x-python\",\n };\n return mimeTypes[ext || \"\"] || \"application/octet-stream\";\n}\n\n/**\n * Upload a single file to S3 via the CLI upload endpoint\n * Returns metadata in the format expected by contentSources.uploadedFiles\n */\nexport async function uploadFile(filePath: string): Promise<FileUploadResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n // Read file metadata\n const stat = statSync(filePath);\n const fileName = basename(filePath);\n const mimeType = getMimeType(filePath);\n\n // Step 1: Get presigned URL from API\n const presignedResponse = await fetch(`${apiUrl}/api/cli/files/upload`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n fileMetadata: {\n name: fileName,\n type: mimeType,\n size: stat.size,\n },\n }),\n });\n\n if (!presignedResponse.ok) {\n const errorText = await presignedResponse.text();\n throw new ApiError(\n errorText || \"Failed to get upload URL\",\n presignedResponse.status,\n 1\n );\n }\n\n const presigned = await presignedResponse.json();\n\n // Step 2: Upload file to S3 using presigned POST\n const fileBuffer = readFileSync(filePath);\n const formData = new FormData();\n\n // Add all presigned fields first (order matters for S3)\n for (const [key, value] of Object.entries(presigned.fields || {})) {\n formData.append(key, value as string);\n }\n\n // Add the file last (required by S3)\n const blob = new Blob([fileBuffer], { type: mimeType });\n formData.append(\"file\", blob, fileName);\n\n const uploadResponse = await fetch(presigned.url, {\n method: \"POST\",\n body: formData,\n });\n\n if (!uploadResponse.ok) {\n throw new ApiError(\n \"Failed to upload file to storage\",\n uploadResponse.status,\n 1\n );\n }\n\n // Return in the format expected by contentSources.uploadedFiles\n return {\n id: randomUUID(),\n name: fileName,\n url: presigned.fileUrl,\n size: stat.size,\n type: mimeType,\n selected: true,\n };\n}\n\n/**\n * Upload multiple files with optional progress callback\n */\nexport async function uploadFiles(\n filePaths: string[],\n onProgress?: (completed: number, total: number, fileName: string) => void\n): Promise<FileUploadResult[]> {\n const results: FileUploadResult[] = [];\n\n for (let i = 0; i < filePaths.length; i++) {\n const filePath = filePaths[i];\n const fileName = basename(filePath);\n\n onProgress?.(i, filePaths.length, fileName);\n\n const result = await uploadFile(filePath);\n results.push(result);\n }\n\n onProgress?.(filePaths.length, filePaths.length, \"\");\n return results;\n}\n\n// Presentation APIs\nexport async function createPresentation(\n options: PresentationCreateOptions\n): Promise<Response> {\n const body: Record<string, unknown> = {\n topic: options.topic,\n slideCount: options.slideCount ?? 10,\n mode: options.mode ?? \"balanced\",\n tone: options.tone ?? \"professional\",\n amount: options.amount ?? \"concise\",\n audience: options.audience ?? \"General Audience\",\n language: options.language ?? \"en\",\n stylingMode: options.stylingMode ?? \"freeform\",\n };\n\n // Add optional reference URL for styling\n if (options.referenceUrl) {\n body.referenceUrl = options.referenceUrl;\n }\n\n // Add thinking depth\n if (options.thinkingDepth) {\n body.thinkingDepth = options.thinkingDepth;\n }\n\n // Add goal\n if (options.goal) {\n body.goal = options.goal;\n }\n if (options.customGoal) {\n body.goal = options.customGoal; // Custom goal overrides preset\n }\n\n // Build contentSources with all context data\n const uploadedFiles: Array<any> = [];\n const contextFiles: Array<{ url?: string; content?: string; title?: string; mime?: string }> = [];\n\n // Add S3-uploaded files (from --file option)\n if (options.uploadedFiles && options.uploadedFiles.length > 0) {\n uploadedFiles.push(...options.uploadedFiles);\n }\n\n // Add URLs to scrape as contextFiles\n if (options.sources && options.sources.length > 0) {\n for (const url of options.sources) {\n contextFiles.push({ url });\n }\n }\n\n // Add stdin content as inline uploaded file\n if (options.stdinContent) {\n uploadedFiles.push({\n id: `stdin-${Date.now()}`,\n content: options.stdinContent,\n title: \"Piped Content\",\n mime: \"text/plain\",\n selected: true,\n });\n }\n\n // Add direct context as inline uploaded file\n if (options.context) {\n uploadedFiles.push({\n id: `context-${Date.now()}`,\n content: options.context,\n title: \"Context\",\n mime: \"text/plain\",\n selected: true,\n });\n }\n\n // Only include contentSources if we have data\n if (uploadedFiles.length > 0 || contextFiles.length > 0) {\n body.contentSources = {\n uploadedFiles,\n contextFiles,\n };\n }\n\n if (options.brandId) {\n body.designBrandReference = options.brandId;\n }\n\n // Add team ID if specified (allows switching teams)\n if (options.teamId) {\n body.teamId = options.teamId;\n }\n\n // Add theme options for customizing colors and decorations\n if (options.theme) {\n body.theme = options.theme;\n }\n\n return streamRequest(\"/api/slides/skills/create-presentation\", body);\n}\n\nexport async function listPresentations(\n teamId?: string,\n limit = 20\n): Promise<PresentationListItem[]> {\n const params = new URLSearchParams();\n params.set(\"limit\", String(limit));\n // Pass teamId if specified (allows switching teams)\n if (teamId) {\n params.set(\"teamId\", teamId);\n }\n\n // Use CLI-specific endpoint with API key auth\n // If teamId not specified, server uses API key's default team\n const response = await request<{ presentations: PresentationListItem[]; totalCount: number }>(\n `/api/cli/presentations?${params}`\n );\n return response.presentations;\n}\n\n// Get presentation by slug or ID\nexport async function getPresentation(slugOrId: string): Promise<Presentation> {\n return request<Presentation>(`/api/cli/presentation/${slugOrId}`);\n}\n\n// Delete presentation by slug or ID\nexport async function deletePresentation(slugOrId: string): Promise<void> {\n await request<string>(`/api/cli/presentation/${slugOrId}`, { method: \"DELETE\" });\n}\n\n// Export/Import APIs\nexport async function exportPresentation(\n presentationId: string,\n options: ExportOptions = {}\n): Promise<ArrayBuffer> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const response = await fetch(`${apiUrl}/api/presentations/export`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n presentationId,\n options: {\n includeImages: options.includeImages ?? true,\n includeBranding: options.includeBranding ?? true,\n downloadExternalImages: options.includeExternal ?? true,\n },\n }),\n });\n\n if (!response.ok) {\n throw new ApiError(\n await response.text(),\n response.status,\n response.status === 404 ? 3 : 1\n );\n }\n\n return response.arrayBuffer();\n}\n\nexport async function importPresentation(\n fileBuffer: Buffer,\n fileName: string,\n options: { dryRun?: boolean } = {}\n): Promise<ImportResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const formData = new FormData();\n const blob = new Blob([fileBuffer], { type: \"application/zip\" });\n formData.append(\"file\", blob, fileName);\n formData.append(\n \"options\",\n JSON.stringify({\n dryRun: options.dryRun ?? false,\n remapIds: true,\n })\n );\n\n const response = await fetch(`${apiUrl}/api/presentations/import`, {\n method: \"POST\",\n headers: authHeaders,\n body: formData,\n });\n\n const result = await response.json();\n\n if (!response.ok) {\n throw new ApiError(\n result.errors?.[0]?.message ?? \"Import failed\",\n response.status,\n 1\n );\n }\n\n return result;\n}\n\n// Branding APIs\nexport async function listBrandings(): Promise<{ brandings: Branding[] }> {\n return request<{ brandings: Branding[] }>(\"/api/branding\");\n}\n\nexport interface BrandingDetail {\n id: string;\n name: string;\n sourceUrl?: string;\n isDefault: boolean;\n createdAt?: string;\n primaryColor?: string;\n colors: Array<{ hex: string; role?: string }>;\n logoUrl?: string;\n logos: Record<string, unknown>;\n typography: Record<string, unknown>;\n confidence?: number;\n extractionMethod?: string;\n brandData?: Record<string, unknown>;\n}\n\nexport async function getBranding(id: string): Promise<BrandingDetail> {\n return request<BrandingDetail>(`/api/branding/${id}`);\n}\n\nexport async function extractBranding(\n url: string,\n teamId?: string\n): Promise<BrandingExtractResult> {\n return request<BrandingExtractResult>(\"/api/branding/extract\", {\n method: \"POST\",\n body: { url, teamId },\n });\n}\n\n// User/Team APIs\nexport interface WhoamiResponse {\n user: {\n id: string;\n email: string;\n username?: string;\n firstName?: string;\n lastName?: string;\n role?: string;\n };\n currentTeam: {\n id: string;\n name: string;\n planName: string;\n isOwner: boolean;\n } | null;\n teams: Array<{\n id: string;\n name: string;\n planName: string;\n role: string;\n isCurrent: boolean;\n }>;\n authType: \"session\" | \"apiKey\";\n}\n\nexport async function whoami(): Promise<WhoamiResponse> {\n return request<WhoamiResponse>(\"/api/cli/whoami\");\n}\n\n// Feature flags\nexport interface FeatureFlags {\n deckToBlog: boolean;\n deckToTweets: boolean;\n linkedInCarousel: boolean;\n redTeamQuestions: boolean;\n presenterCheatSheet: boolean;\n}\n\nexport async function getFeatureFlags(): Promise<FeatureFlags> {\n return request<FeatureFlags>(\"/api/cli/features\");\n}\n\n// Derivative content APIs\nexport async function generateBlog(\n presentationId: string,\n documentCreatedAt: string,\n options: BlogGenerationOptions = {}\n): Promise<Response> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n const response = await fetch(\n `${apiUrl}/api/presentations/${presentationId}/generate-blog`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify({\n documentCreatedAt,\n targetWordCount: options.targetWordCount ?? 300,\n tone: options.tone ?? \"professional\",\n language: options.language ?? \"en\",\n targetAudience: options.targetAudience ?? \"General Audience\",\n blogFormat: options.blogFormat ?? \"narrative\",\n customInstructions: options.customInstructions ?? \"\",\n includeImages: options.includeImages ?? true,\n includeTableOfContents: options.includeTableOfContents ?? false,\n }),\n }\n );\n\n if (!response.ok) {\n throw new ApiError(\n await response.text(),\n response.status,\n response.status === 404 ? 3 : 1\n );\n }\n\n return response;\n}\n\n// Generation limits API\nexport interface GenerationLimits {\n teamId: string;\n planName: string;\n limits: Record<string, number>;\n usage: Record<string, number>;\n remaining: Record<string, number>;\n canGenerate: Record<string, boolean>;\n availableModes: string[];\n maxSlidesPerPresentation: number;\n maxStorageBytes: number;\n storageUsedBytes: number;\n}\n\n/**\n * Check generation limits before creating a presentation\n * Returns limits info including whether the specified mode can be used\n * @param teamId - Optional team ID to check limits for (if switching teams)\n */\nexport async function checkLimits(teamId?: string): Promise<GenerationLimits> {\n const params = new URLSearchParams();\n if (teamId) {\n params.set(\"teamId\", teamId);\n }\n const query = params.toString();\n return request<GenerationLimits>(`/api/cli/limits${query ? `?${query}` : \"\"}`);\n}\n\n/**\n * Validate that generation is possible with the specified mode and slide count\n * Throws ApiError if generation is not allowed\n * @param teamId - Optional team ID to validate for (if switching teams)\n */\nexport async function validateGeneration(\n mode: string,\n slideCount: number,\n teamId?: string\n): Promise<GenerationLimits> {\n const limits = await checkLimits(teamId);\n\n // Check if mode is available\n if (!limits.canGenerate[mode]) {\n const remaining = limits.remaining[mode] ?? 0;\n const limit = limits.limits[mode] ?? 0;\n\n if (limit === 0) {\n throw new ApiError(\n `The \"${mode}\" mode is not available on your ${limits.planName} plan. Available modes: ${limits.availableModes.join(\", \") || \"none\"}`,\n 403,\n 2\n );\n }\n\n throw new ApiError(\n `You have reached your ${mode} generation limit for this billing cycle (${limits.usage[mode] ?? 0}/${limit} used). Try a different mode: ${limits.availableModes.join(\", \") || \"none available\"}`,\n 403,\n 4\n );\n }\n\n // Check slide count\n if (slideCount > limits.maxSlidesPerPresentation) {\n throw new ApiError(\n `Maximum ${limits.maxSlidesPerPresentation} slides allowed on your ${limits.planName} plan (requested: ${slideCount})`,\n 403,\n 6\n );\n }\n\n return limits;\n}\n\n// ============================================================================\n// Media APIs (TTS, Music, Mix, Image Search)\n// ============================================================================\n\n/**\n * Generate speech from text using TTS\n */\nexport async function generateSpeech(ttsRequest: TTSRequest): Promise<TTSResult> {\n const apiUrl = getApiUrl();\n\n if (!hasAuth()) {\n throw new ApiError(\n `Not authenticated. Run '${brand.commands[0]} login' or set ${brand.apiKeyEnvVar} environment variable.`,\n 401,\n 2\n );\n }\n\n const authHeaders = await getAuthHeaders();\n\n let response: Response;\n try {\n response = await fetch(`${apiUrl}/api/cli/tts`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(ttsRequest),\n });\n } catch (error) {\n throw new ApiError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n 0,\n 5\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n let errorMessage: string;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || errorText;\n } catch {\n errorMessage = errorText;\n }\n throw new ApiError(errorMessage, response.status, response.status === 401 ? 2 : 1);\n }\n\n // TTS returns binary audio data with metadata in headers\n const audioData = Buffer.from(await response.arrayBuffer());\n const duration = parseFloat(response.headers.get(\"X-Duration-Seconds\") || \"0\");\n const cost = parseFloat(response.headers.get(\"X-Cost-USD\") || \"0\");\n const provider = response.headers.get(\"X-Provider\") || \"unknown\";\n const format = response.headers.get(\"X-Audio-Format\") || \"mp3\";\n\n // Parse timestamps if available (for audio-video sync)\n let timestamps: TTSResult[\"timestamps\"];\n const timestampsHeader = response.headers.get(\"X-Timestamps\");\n if (timestampsHeader) {\n try {\n timestamps = JSON.parse(timestampsHeader);\n } catch {\n // Ignore parse errors, timestamps are optional\n }\n }\n\n return {\n audioData,\n duration,\n cost,\n provider,\n format,\n timestamps,\n };\n}\n\n/**\n * Get available TTS voices\n */\nexport async function getVoices(): Promise<TTSVoicesResponse> {\n return request<TTSVoicesResponse>(\"/api/cli/tts\");\n}\n\n/**\n * Generate music from a text prompt\n */\nexport async function generateMusic(\n musicRequest: MusicGenerationRequest\n): Promise<MusicGenerationResult> {\n interface MusicApiResponse {\n success: boolean;\n data: {\n id: string;\n status: string;\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n };\n }\n\n const response = await request<MusicApiResponse>(\"/api/cli/music\", {\n method: \"POST\",\n body: musicRequest,\n });\n\n if (!response.data) {\n throw new ApiError(`Invalid API response: ${JSON.stringify(response)}`, 500, 1);\n }\n\n return {\n requestId: response.data.id,\n status: response.data.status as MusicGenerationResult[\"status\"],\n audioUrl: response.data.audioUrl,\n duration: response.data.duration,\n cost: response.data.cost,\n error: response.data.error,\n };\n}\n\n/**\n * Check status of a music generation request\n */\nexport async function checkMusicStatus(requestId: string): Promise<MusicGenerationResult> {\n interface MusicApiResponse {\n success: boolean;\n data: {\n id: string;\n status: string;\n audioUrl?: string;\n duration?: number;\n cost?: number;\n error?: string;\n };\n }\n\n const response = await request<MusicApiResponse>(\n `/api/cli/music?requestId=${encodeURIComponent(requestId)}`\n );\n\n return {\n requestId: response.data.id,\n status: response.data.status as MusicGenerationResult[\"status\"],\n audioUrl: response.data.audioUrl,\n duration: response.data.duration,\n cost: response.data.cost,\n error: response.data.error,\n };\n}\n\n/**\n * Mix audio tracks\n */\nexport async function mixAudio(mixRequest: AudioMixRequest): Promise<AudioMixResult> {\n return request<AudioMixResult>(\"/api/cli/mix\", {\n method: \"POST\",\n body: mixRequest,\n });\n}\n\n/**\n * Check status of an audio mix request\n */\nexport async function checkMixStatus(requestId: string): Promise<AudioMixResult> {\n return request<AudioMixResult>(\n `/api/cli/mix?requestId=${encodeURIComponent(requestId)}`\n );\n}\n\n/**\n * Search for images\n */\nexport async function searchImages(\n searchRequest: ImageSearchRequest\n): Promise<ImageSearchResponse> {\n return request<ImageSearchResponse>(\"/api/cli/images/search\", {\n method: \"POST\",\n body: searchRequest,\n });\n}\n\n/**\n * Search for videos\n */\nexport async function searchVideos(\n searchRequest: VideoSearchRequest\n): Promise<VideoSearchResponse> {\n return request<VideoSearchResponse>(\"/api/cli/videos/search\", {\n method: \"POST\",\n body: searchRequest,\n });\n}\n\n/**\n * Poll for completion of an async operation\n */\nexport async function pollForCompletion<T extends { status: string }>(\n checkFn: () => Promise<T>,\n maxAttempts = 60,\n intervalMs = 2000\n): Promise<T> {\n for (let i = 0; i < maxAttempts; i++) {\n const result = await checkFn();\n if (result.status === \"completed\" || result.status === \"failed\") {\n return result;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new ApiError(\"Operation timed out\", 408, 1);\n}\n\nexport { request };\n","/**\n * Feature Flag Cache\n * Provides instant synchronous access to feature flags with stale-while-revalidate pattern\n *\n * Cache states:\n * - Fresh (< 1h): Return immediately\n * - Stale (1h-24h): Return immediately + background refresh\n * - Expired (> 24h): Return null (must fetch blocking on first command)\n * - Empty: Commands hidden until first auth\n */\n\nimport Conf from \"conf\";\nimport { getFeatureFlags, type FeatureFlags } from \"./api.js\";\nimport { hasApiKey, getApiKey } from \"./config.js\";\n\ninterface CachedFlags {\n flags: FeatureFlags;\n fetchedAt: number;\n apiKeyHash?: string; // Invalidate if key changes\n}\n\nconst cache = new Conf<{ featureFlags?: CachedFlags }>({\n projectName: \"conceptcraft\",\n configName: \"feature-cache\",\n});\n\nconst FRESH_TTL = 60 * 60 * 1000; // 1 hour\nconst STALE_TTL = 24 * 60 * 60 * 1000; // 24 hours\n\n/**\n * Simple hash for API key to detect changes\n */\nfunction hashApiKey(key: string): string {\n let hash = 0;\n for (let i = 0; i < key.length; i++) {\n const char = key.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash.toString(16);\n}\n\n/**\n * SYNC: Read from local cache (instant)\n * Returns cached flags or null if cache is empty/expired/invalid\n */\nexport function getCachedFlags(): FeatureFlags | null {\n if (!hasApiKey()) return null;\n\n const cached = cache.get(\"featureFlags\");\n if (!cached) return null;\n\n // Check if API key changed\n const currentKeyHash = hashApiKey(getApiKey()!);\n if (cached.apiKeyHash && cached.apiKeyHash !== currentKeyHash) {\n // API key changed, invalidate cache\n invalidateCache();\n return null;\n }\n\n const age = Date.now() - cached.fetchedAt;\n\n // Expired cache (> 24h) - treat as no cache\n if (age > STALE_TTL) return null;\n\n // Stale cache (1h-24h) - return but trigger background refresh\n if (age > FRESH_TTL) {\n refreshInBackground();\n }\n\n return cached.flags;\n}\n\n/**\n * ASYNC: Background refresh (non-blocking)\n * Silently updates cache without blocking the main thread\n */\nexport function refreshInBackground(): void {\n // Fire and forget\n fetchAndCache().catch(() => {\n // Silently fail - next command will try again\n });\n}\n\n/**\n * ASYNC: Fetch and update cache\n * Use after auth operations to populate cache\n */\nexport async function fetchAndCache(): Promise<FeatureFlags> {\n const flags = await getFeatureFlags();\n const apiKey = getApiKey();\n\n cache.set(\"featureFlags\", {\n flags,\n fetchedAt: Date.now(),\n apiKeyHash: apiKey ? hashApiKey(apiKey) : undefined,\n });\n\n return flags;\n}\n\n/**\n * Clear cache (on logout, key change, etc.)\n */\nexport function invalidateCache(): void {\n cache.delete(\"featureFlags\");\n}\n\n/**\n * Get cache file path (for debugging)\n */\nexport function getCachePath(): string {\n return cache.path;\n}\n\n/**\n * Check if cache exists and is not expired\n */\nexport function hasCachedFlags(): boolean {\n return getCachedFlags() !== null;\n}\n","/**\n * Login Command\n * OAuth 2.1 authentication flow with PKCE\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport http from \"http\";\nimport { randomBytes, createHash } from \"crypto\";\nimport open from \"open\";\nimport {\n getApiUrl,\n setOAuthTokens,\n setOAuthClient,\n getClientId,\n getClientSecret,\n hasOAuthTokens,\n setDefaultTeamId,\n} from \"../lib/config.js\";\nimport { success, error, info, warn, keyValue } from \"../lib/output.js\";\nimport { fetchAndCache } from \"../lib/feature-cache.js\";\nimport type { OAuthTokenResponse, OAuthClientRegistration } from \"../types/index.js\";\n\nconst CLI_CLIENT_NAME = \"ConceptCraft CLI\";\nconst CALLBACK_PORT_START = 8765;\nconst CALLBACK_PORT_END = 8775;\n\n/**\n * Generate PKCE code verifier (43-128 chars, URL-safe)\n */\nfunction generateCodeVerifier(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\n/**\n * Generate PKCE code challenge from verifier (S256)\n */\nfunction generateCodeChallenge(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\n/**\n * Generate state parameter for CSRF protection\n */\nfunction generateState(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n/**\n * Find an available port for the callback server\n */\nasync function findAvailablePort(start: number, end: number): Promise<number> {\n for (let port = start; port <= end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const server = http.createServer();\n server.listen(port, () => {\n server.close(() => resolve());\n });\n server.on(\"error\", reject);\n });\n return port;\n } catch {\n continue;\n }\n }\n throw new Error(`No available port found between ${start} and ${end}`);\n}\n\n/**\n * Fetch OAuth authorization server metadata\n */\nasync function getAuthServerMetadata(apiUrl: string): Promise<{\n authorization_endpoint: string;\n token_endpoint: string;\n registration_endpoint: string;\n}> {\n const response = await fetch(`${apiUrl}/.well-known/oauth-authorization-server`);\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth metadata: ${response.status}`);\n }\n return response.json();\n}\n\n/**\n * Register OAuth client dynamically (RFC 7591)\n */\nasync function registerClient(\n registrationEndpoint: string,\n redirectUri: string\n): Promise<OAuthClientRegistration> {\n const response = await fetch(registrationEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_name: CLI_CLIENT_NAME,\n redirect_uris: [redirectUri],\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\", // Public client with PKCE\n scope: \"presentations:read presentations:write\",\n }),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`Client registration failed: ${err}`);\n }\n\n return response.json();\n}\n\n/**\n * Exchange authorization code for tokens\n */\nasync function exchangeCodeForTokens(\n tokenEndpoint: string,\n code: string,\n codeVerifier: string,\n redirectUri: string,\n clientId: string\n): Promise<OAuthTokenResponse> {\n const params = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: codeVerifier,\n });\n\n const response = await fetch(tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: params.toString(),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`Token exchange failed: ${err}`);\n }\n\n return response.json();\n}\n\n/**\n * Start local callback server and wait for OAuth callback\n */\nfunction startCallbackServer(\n port: number,\n expectedState: string\n): Promise<{ code: string; state: string }> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let settled = false;\n\n const cleanup = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timeoutId);\n process.off(\"SIGINT\", onCancel);\n process.off(\"SIGTERM\", onCancel);\n server.close();\n };\n\n const onCancel = () => {\n cleanup();\n reject(new Error(\"Login cancelled\"));\n };\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || \"\", `http://localhost:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const errorParam = url.searchParams.get(\"error\");\n const errorDescription = url.searchParams.get(\"error_description\");\n\n // Send HTML response to browser\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n\n if (errorParam) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>${errorDescription || errorParam}</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(errorDescription || errorParam));\n return;\n }\n\n if (!code || !state) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>Missing authorization code or state</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(\"Missing authorization code or state\"));\n return;\n }\n\n if (state !== expectedState) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Failed</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #dc2626;\">Login Failed</h1>\n <p>State mismatch - possible CSRF attack</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n cleanup();\n reject(new Error(\"State mismatch\"));\n return;\n }\n\n res.end(`\n <!DOCTYPE html>\n <html>\n <head><title>Login Successful</title></head>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #16a34a;\">Login Successful!</h1>\n <p>You can close this window and return to the terminal.</p>\n </body>\n </html>\n `);\n\n cleanup();\n resolve({ code, state });\n });\n\n server.listen(port);\n\n // Handle Ctrl+C\n process.once(\"SIGINT\", onCancel);\n process.once(\"SIGTERM\", onCancel);\n\n // Timeout after 5 minutes\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error(\"Login timed out - no callback received within 5 minutes\"));\n }, 5 * 60 * 1000);\n });\n}\n\n/**\n * Fetch user info after login\n */\nasync function fetchWhoami(apiUrl: string, accessToken: string): Promise<{\n user: { email: string };\n teams: Array<{ id: string; name: string; planName: string; role: string; isCurrent: boolean }>;\n currentTeam: { id: string; name: string; planName: string } | null;\n}> {\n const response = await fetch(`${apiUrl}/api/cli/whoami`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch user info: ${response.status}`);\n }\n return response.json();\n}\n\n/**\n * Run the OAuth login flow\n * Exported so it can be called from requireAuth() prompt\n */\nexport async function runLoginFlow(options: { browser: boolean }): Promise<void> {\n const apiUrl = getApiUrl();\n let spinner = ora(\"Discovering OAuth server...\").start();\n\n try {\n // Step 1: Discover OAuth endpoints\n const metadata = await getAuthServerMetadata(apiUrl);\n spinner.succeed(\"Connecting to \" + apiUrl);\n\n // Step 2: Find available port for callback\n const port = await findAvailablePort(CALLBACK_PORT_START, CALLBACK_PORT_END);\n const redirectUri = `http://localhost:${port}/callback`;\n\n // Step 3: Register client (or use cached)\n let clientId = getClientId();\n let clientSecret = getClientSecret();\n\n if (!clientId) {\n const client = await registerClient(metadata.registration_endpoint, redirectUri);\n clientId = client.client_id;\n clientSecret = client.client_secret;\n setOAuthClient(clientId, clientSecret);\n }\n\n // Step 4: Generate PKCE parameters\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Step 5: Build authorization URL\n const authParams = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n scope: \"presentations:read presentations:write\",\n state,\n code_challenge: codeChallenge,\n code_challenge_method: \"S256\",\n });\n\n const authUrl = `${metadata.authorization_endpoint}?${authParams}`;\n\n // Step 6: Open browser and wait for callback\n if (options.browser) {\n info(\"Opening browser...\");\n await open(authUrl);\n } else {\n console.log(chalk.bold(\"Open this URL in your browser:\"));\n console.log(chalk.cyan(authUrl));\n }\n\n const callbackPromise = startCallbackServer(port, state);\n const { code } = await callbackPromise;\n\n // Step 7: Exchange code for tokens\n spinner = ora(\"Completing login...\").start();\n const tokens = await exchangeCodeForTokens(\n metadata.token_endpoint,\n code,\n codeVerifier,\n redirectUri,\n clientId\n );\n\n // Step 8: Store tokens\n setOAuthTokens(tokens.access_token, tokens.refresh_token, tokens.expires_in);\n\n // Step 9: Fetch user info and set default team\n const whoami = await fetchWhoami(apiUrl, tokens.access_token);\n spinner.succeed(\"Logged in!\");\n\n console.log();\n keyValue(\"Logged in as\", whoami.user.email);\n\n if (whoami.currentTeam) {\n setDefaultTeamId(whoami.currentTeam.id);\n keyValue(\"Team\", `${whoami.currentTeam.name} (${whoami.currentTeam.planName})`);\n }\n\n // Cache feature flags\n try {\n await fetchAndCache();\n } catch {\n // Non-critical\n }\n\n console.log();\n success(\"You're all set!\");\n console.log();\n } catch (err) {\n spinner.fail(\"Login failed\");\n error(err instanceof Error ? err.message : String(err));\n throw err; // Re-throw so caller can handle\n }\n}\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Authenticate with ConceptCraft (opens browser)\")\n .option(\"--no-browser\", \"Print URL instead of opening browser\")\n .action(async (options: { browser: boolean }) => {\n console.log();\n\n // Check if already logged in\n if (hasOAuthTokens()) {\n warn(\"You are already logged in.\");\n info(\"Run 'conceptcraft logout' to log out first, or continue to re-authenticate.\");\n console.log();\n }\n\n try {\n await runLoginFlow(options);\n process.exit(0);\n } catch {\n process.exit(1);\n }\n });\n","#!/usr/bin/env node\n/**\n * Slides CLI\n * A CLI tool for creating and managing AI-powered presentations\n * Supports whitelabeling for different brands (Conceptcraft, Mindframes, etc.)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\n\n// Import brand config (detects brand from command name)\nimport { brand } from \"./lib/brand.js\";\n\n// Import commands\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { configCommand } from \"./commands/config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { getCommand } from \"./commands/get.js\";\nimport { deleteCommand } from \"./commands/delete.js\";\nimport { exportCommand } from \"./commands/export.js\";\nimport { importCommand } from \"./commands/import.js\";\nimport { brandingCommand } from \"./commands/branding.js\";\nimport { buildDeriveCommand } from \"./commands/derive.js\";\nimport { ideasCommand } from \"./commands/ideas.js\";\nimport { whoamiCommand } from \"./commands/whoami.js\";\nimport { skillCommand } from \"./commands/skill.js\";\nimport { ttsCommand } from \"./commands/tts.js\";\nimport { musicCommand } from \"./commands/music.js\";\nimport { mixAudioCommand } from \"./commands/mix.js\";\nimport { imageCommand } from \"./commands/image.js\";\nimport { videoCommand } from \"./commands/video.js\";\n\n// Package version (injected by tsup at build time from package.json)\ndeclare const __VERSION__: string;\nconst VERSION = __VERSION__;\n\n// Synchronous startup - no async main() for instant --help response\nconst program = new Command();\n\n// Use the primary command name from brand config\nconst cmdName = brand.commands[0];\n\nprogram\n .name(cmdName)\n .description(brand.description)\n .version(VERSION, \"-v, --version\", \"Show version number\")\n .option(\"--debug\", \"Enable debug logging\")\n .option(\"--no-color\", \"Disable colored output\")\n .configureOutput({\n outputError: (str, write) => {\n write(chalk.red(str));\n },\n });\n\n// Register static commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(createCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(getCommand);\nprogram.addCommand(deleteCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(importCommand);\nprogram.addCommand(brandingCommand);\nprogram.addCommand(ideasCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(skillCommand);\nprogram.addCommand(ttsCommand);\nprogram.addCommand(musicCommand);\nprogram.addCommand(mixAudioCommand);\nprogram.addCommand(imageCommand);\nprogram.addCommand(videoCommand);\n\n// Build derive command from cached feature flags (synchronous, instant)\nconst deriveCommand = buildDeriveCommand();\n// Only add derive if it has subcommands (user has access to features)\nif (deriveCommand.commands.length > 0) {\n program.addCommand(deriveCommand);\n}\n\n// Handle unknown commands\nprogram.on(\"command:*\", (operands) => {\n console.error(chalk.red(`Error: Unknown command '${operands[0]}'`));\n console.error();\n console.error(`Run '${cmdName} --help' to see available commands.`);\n process.exit(1);\n});\n\n// Add examples to help text\nprogram.addHelpText(\n \"after\",\n `\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Log in (opens browser)\")}\n $ ${cmdName} login\n\n ${chalk.gray(\"# Create a presentation (recommended pattern)\")}\n $ ${cmdName} create \"Q4 Business Review\" \\\\\n -n 12 -m best \\\\\n --audience \"Executive leadership team\" \\\\\n --context \"Revenue: $50M (+25% YoY), New customers: 150\"\n\n ${chalk.gray(\"# Create from a file\")}\n $ ${cmdName} create \"Product Launch\" \\\\\n -n 10 -m balanced \\\\\n --audience \"Sales team and partners\" \\\\\n --context-file ./launch-brief.md\n\n ${chalk.gray(\"# Create from URLs\")}\n $ ${cmdName} create \"Market Analysis\" \\\\\n -n 15 -m best \\\\\n --audience \"Strategy team\" \\\\\n --sources https://example.com/report.pdf\n\n ${chalk.gray(\"# List and export\")}\n $ ${cmdName} list --format table\n $ ${cmdName} export <slug> -o backup.zip\n\n${chalk.bold(\"Authentication:\")}\n Run '${cmdName} login' to authenticate (recommended).\n Or set CC_MINDFRAMES_API_KEY environment variable for API key auth.\n\n${chalk.bold(\"More Info:\")}\n ${chalk.blue(brand.docsUrl)}\n`\n);\n\n// Parse and execute\nprogram.parse();\n","/**\n * Logout Command\n * Clear OAuth tokens and optionally API key\n */\n\nimport { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport {\n clearOAuthTokens,\n hasOAuthTokens,\n hasApiKey,\n clearConfig,\n} from \"../lib/config.js\";\nimport { invalidateCache } from \"../lib/feature-cache.js\";\nimport { success, info, warn } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Log out and clear authentication\")\n .option(\"--all\", \"Clear all config including API key\")\n .action(async (options: { all?: boolean }) => {\n console.log();\n\n const hasTokens = hasOAuthTokens();\n const hasKey = hasApiKey();\n\n if (!hasTokens && !hasKey) {\n warn(\"You are not logged in.\");\n console.log();\n return;\n }\n\n if (options.all) {\n try {\n const confirmed = await confirm({\n message: \"Clear all configuration including API key?\",\n default: false,\n });\n\n if (confirmed) {\n clearConfig();\n invalidateCache();\n success(\"All configuration cleared.\");\n } else {\n info(\"Cancelled.\");\n }\n } catch {\n info(\"Cancelled.\");\n }\n } else {\n // Just clear OAuth tokens, keep API key for enthusiasts\n clearOAuthTokens();\n invalidateCache();\n success(\"Logged out successfully.\");\n\n if (hasKey) {\n info(\"Note: Your API key is still configured. Use --all to clear everything.\");\n }\n }\n\n console.log();\n });\n","/**\n * Config Command\n * Manages CLI configuration (API key, URL, etc.)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { input, password, confirm, select } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport {\n getConfig,\n setApiKey,\n setApiUrl,\n setDefaultTeamId,\n getConfigPath,\n clearConfig,\n getApiUrl,\n getDefaultTeamId,\n} from \"../lib/config.js\";\nimport { getMaskedApiKey, isValidApiKeyFormat } from \"../lib/auth.js\";\nimport { whoami } from \"../lib/api.js\";\nimport { fetchAndCache, invalidateCache, getCachePath } from \"../lib/feature-cache.js\";\nimport { success, error, info, keyValue, header, warn } from \"../lib/output.js\";\n\nexport const configCommand = new Command(\"config\")\n .description(\"Manage CLI configuration\")\n .addCommand(\n new Command(\"init\")\n .description(\"Initialize configuration interactively\")\n .action(async () => {\n console.log();\n console.log(chalk.bold(\"ConceptCraft CLI Configuration\"));\n console.log(chalk.gray(\"─\".repeat(35)));\n console.log();\n\n try {\n // Get API key\n const apiKey = await password({\n message: \"Enter your API key:\",\n mask: \"*\",\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return \"API key is required\";\n }\n if (!isValidApiKeyFormat(value.trim())) {\n return \"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'\";\n }\n return true;\n },\n });\n\n setApiKey(apiKey.trim());\n\n // Optionally set custom API URL\n const useCustomUrl = await confirm({\n message: \"Use a custom API URL? (default: www.mindframes.app)\",\n default: false,\n });\n\n if (useCustomUrl) {\n const customUrl = await input({\n message: \"Enter API URL:\",\n default: getApiUrl(),\n validate: (value) => {\n try {\n new URL(value);\n return true;\n } catch {\n return \"Invalid URL format\";\n }\n },\n });\n setApiUrl(customUrl);\n }\n\n // Verify API key and fetch team info\n console.log();\n const spinner = ora(\"Verifying API key...\").start();\n\n try {\n const result = await whoami();\n spinner.succeed(\"API key verified!\");\n\n console.log();\n info(`Logged in as: ${result.user.email}`);\n\n // Handle team selection\n if (result.teams.length === 0) {\n warn(\"No teams found for this user.\");\n } else if (result.teams.length === 1) {\n // Single team - auto-select\n const team = result.teams[0];\n setDefaultTeamId(team.id);\n info(`Team: ${team.name} (${team.planName})`);\n } else {\n // Multiple teams - prompt for selection\n console.log();\n info(`You have access to ${result.teams.length} teams.`);\n\n const selectedTeamId = await select({\n message: \"Select your default team:\",\n choices: result.teams.map((team) => ({\n name: `${team.name} (${team.planName}) - ${team.role}${team.isCurrent ? \" [current]\" : \"\"}`,\n value: team.id,\n })),\n default: result.currentTeam?.id,\n });\n\n setDefaultTeamId(selectedTeamId);\n const selectedTeam = result.teams.find((t) => t.id === selectedTeamId);\n success(`Selected team: ${selectedTeam?.name}`);\n }\n\n // Fetch and cache feature flags for instant command availability\n try {\n await fetchAndCache();\n } catch {\n // Non-critical - flags will be fetched on next command\n }\n } catch (apiErr) {\n spinner.fail(\"Failed to verify API key\");\n warn(\n `Could not verify API key: ${apiErr instanceof Error ? apiErr.message : String(apiErr)}`\n );\n warn(\"You may need to set the team ID manually: mindframes config set team-id <id>\");\n }\n\n console.log();\n success(\"Configuration saved!\");\n info(`Config file: ${getConfigPath()}`);\n console.log();\n } catch (err) {\n // User cancelled\n if ((err as Error).name === \"ExitPromptError\") {\n console.log();\n info(\"Configuration cancelled.\");\n return;\n }\n throw err;\n }\n })\n )\n .addCommand(\n new Command(\"show\")\n .description(\"Show current configuration\")\n .option(\"--verify\", \"Verify API key and show team details\")\n .action(async (options: { verify?: boolean }) => {\n const config = getConfig();\n\n header(\"Current Configuration\");\n console.log();\n keyValue(\"API Key\", getMaskedApiKey() ?? chalk.red(\"Not set\"));\n keyValue(\"API URL\", config.apiUrl);\n keyValue(\"Default Team ID\", config.defaultTeamId ?? chalk.gray(\"Not set\"));\n console.log();\n keyValue(\"Config file\", getConfigPath());\n\n // If --verify flag is passed and we have an API key, fetch team details\n if (options.verify && config.apiKey) {\n console.log();\n const spinner = ora(\"Verifying...\").start();\n try {\n const result = await whoami();\n spinner.succeed(\"Verified\");\n console.log();\n keyValue(\"User\", result.user.email);\n if (result.currentTeam) {\n keyValue(\"Current Team\", `${result.currentTeam.name} (${result.currentTeam.planName})`);\n }\n if (result.teams.length > 1) {\n keyValue(\"Total Teams\", String(result.teams.length));\n }\n } catch (err) {\n spinner.fail(\"Verification failed\");\n warn(err instanceof Error ? err.message : String(err));\n }\n }\n console.log();\n })\n )\n .addCommand(\n new Command(\"set\")\n .description(\"Set a configuration value\")\n .argument(\"<key>\", \"Configuration key (api-key, api-url, team-id)\")\n .argument(\"<value>\", \"Value to set\")\n .action(async (key: string, value: string) => {\n switch (key) {\n case \"api-key\":\n if (!isValidApiKeyFormat(value)) {\n error(\"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'\");\n process.exit(6);\n }\n setApiKey(value);\n invalidateCache(); // Invalidate since key changed\n success(\"API key updated\");\n // Refresh feature flags in background\n fetchAndCache().catch(() => {});\n break;\n\n case \"api-url\":\n try {\n new URL(value);\n setApiUrl(value);\n success(`API URL set to: ${value}`);\n } catch {\n error(\"Invalid URL format\");\n process.exit(6);\n }\n break;\n\n case \"team-id\":\n setDefaultTeamId(value);\n success(`Default team ID set to: ${value}`);\n break;\n\n default:\n error(`Unknown config key: ${key}`);\n console.log(chalk.gray(\"Valid keys: api-key, api-url, team-id\"));\n process.exit(6);\n }\n })\n )\n .addCommand(\n new Command(\"clear\")\n .description(\"Clear all configuration\")\n .action(async () => {\n try {\n const confirmed = await confirm({\n message: \"Are you sure you want to clear all configuration?\",\n default: false,\n });\n\n if (confirmed) {\n clearConfig();\n invalidateCache();\n success(\"Configuration cleared\");\n } else {\n info(\"Cancelled\");\n }\n } catch {\n info(\"Cancelled\");\n }\n })\n )\n .addCommand(\n new Command(\"refresh\")\n .description(\"Refresh cached feature flags\")\n .action(async () => {\n const spinner = ora(\"Refreshing feature flags...\").start();\n try {\n await fetchAndCache();\n spinner.succeed(\"Feature flags refreshed\");\n info(\"Run 'conceptcraft --help' to see updated commands\");\n } catch (err) {\n spinner.fail(\"Failed to refresh\");\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n })\n )\n .addCommand(\n new Command(\"path\")\n .description(\"Show configuration file path\")\n .option(\"--cache\", \"Show feature cache file path\")\n .action((options: { cache?: boolean }) => {\n if (options.cache) {\n console.log(getCachePath());\n } else {\n console.log(getConfigPath());\n }\n })\n );\n","/**\n * Create Command\n * Creates a new presentation with streaming progress\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { createPresentation, uploadFiles, validateGeneration } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { streamWithProgress } from \"../lib/streaming.js\";\nimport { success, error, keyValue, header, buildViewUrl } from \"../lib/output.js\";\nimport type {\n GenerationMode,\n GenerationTone,\n GenerationAmount,\n StylingMode,\n OutputFormat,\n ThinkingDepth,\n PresentationGoal,\n FileUploadResult,\n ThemePreset,\n DecorationStyle,\n ThemeOptions,\n} from \"../types/index.js\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { resolve } from \"path\";\n\ninterface CreateOptions {\n slides: string;\n mode: GenerationMode;\n tone: GenerationTone;\n amount: GenerationAmount;\n audience: string;\n language: string;\n brand?: string;\n sources?: string[];\n context?: string;\n contextFile?: string;\n stdin?: boolean;\n styling: StylingMode;\n referenceUrl?: string;\n thinkingDepth: ThinkingDepth;\n output: OutputFormat;\n noStream?: boolean;\n debug?: boolean;\n // New options\n file?: string[];\n goal?: string;\n customGoal?: string;\n teamId?: string;\n // Theme options\n theme?: ThemePreset;\n primaryColor?: string;\n secondaryColor?: string;\n accentColor?: string;\n backgroundColor?: string;\n foregroundColor?: string;\n decorations?: DecorationStyle;\n // Browser options\n open?: boolean;\n}\n\nconst VALID_GOALS: PresentationGoal[] = [\n \"inform\",\n \"persuade\",\n \"train\",\n \"learn\",\n \"entertain\",\n \"report\",\n];\n\nexport const createCommand = new Command(\"create\")\n .description(\"Create a new presentation\")\n .argument(\"<topic>\", \"The topic or title for the presentation\")\n .option(\"-n, --slides <count>\", \"Number of slides (1-20)\", \"10\")\n .option(\n \"-m, --mode <mode>\",\n \"Generation quality mode (best, balanced, fast, ultrafast, instant)\",\n \"balanced\"\n )\n .option(\n \"-t, --tone <tone>\",\n \"Presentation tone (creative, professional, educational, formal, casual)\",\n \"professional\"\n )\n .option(\n \"--amount <amount>\",\n \"Content density (minimal, concise, detailed, extensive)\",\n \"concise\"\n )\n .option(\"--audience <text>\", \"Target audience description\", \"General Audience\")\n .option(\"-l, --language <lang>\", \"Output language\", \"en\")\n .option(\"-b, --brand <id|url>\", \"Branding ID or URL to extract from\")\n // Context/Source options\n .option(\n \"-c, --context <text>\",\n \"Text context to inform slide content (e.g., research notes, key facts)\"\n )\n .option(\n \"--context-file <path>\",\n \"Path to a file containing context (text, markdown, or JSON)\"\n )\n .option(\n \"--sources <urls...>\",\n \"URLs to scrape for context (space-separated). Content will be fetched and used\"\n )\n .option(\"--stdin\", \"Read context content from stdin (pipe data into the command)\")\n // File upload options\n .option(\n \"-f, --file <paths...>\",\n \"Files to upload (PDF, PPTX, DOCX, images). Use multiple times for multiple files\"\n )\n // Goal options\n .option(\n \"-g, --goal <type>\",\n \"Presentation goal (inform, persuade, train, learn, entertain, report)\"\n )\n .option(\n \"--custom-goal <text>\",\n \"Custom goal description (overrides --goal)\"\n )\n // Styling options\n .option(\n \"--styling <mode>\",\n \"Styling mode (freeform, brand-only, brand-plus-style, style-only, no-styling)\",\n \"freeform\"\n )\n .option(\n \"--reference-url <url>\",\n \"URL to an image or template to use as a style reference\"\n )\n // Generation options\n .option(\n \"--thinking-depth <depth>\",\n \"AI thinking depth (quick, moderate, deep, profound)\",\n \"moderate\"\n )\n // Theme options\n .option(\n \"--theme <preset>\",\n \"Color theme preset (blue, violet, rose, orange, green)\"\n )\n .option(\"--primary-color <hex>\", \"Primary color in hex (e.g., #0066CC)\")\n .option(\"--secondary-color <hex>\", \"Secondary color in hex\")\n .option(\"--accent-color <hex>\", \"Accent color in hex\")\n .option(\"--background-color <hex>\", \"Background color in hex\")\n .option(\"--foreground-color <hex>\", \"Foreground/text color in hex\")\n .option(\n \"--decorations <style>\",\n \"Background decoration style (none, waves-bottom-left, waves-top-right, blob-corners, minimal)\"\n )\n .option(\"-o, --output <format>\", \"Output format (human, json, quiet)\", \"human\")\n .option(\"--no-stream\", \"Wait for completion without progress display\")\n .option(\"--debug\", \"Enable debug logging\")\n .option(\"--team-id <id>\", \"Team ID to create presentation for (switch teams)\")\n .option(\"--open\", \"Open the presentation in browser after creation\")\n .addHelpText(\n \"after\",\n `\n${chalk.bold(\"Recommended Usage:\")}\n Always specify slides (-n), mode (-m), audience, and context for best results.\n\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Content from PDF + style from image reference\")}\n $ conceptcraft create \"Quarterly Report\" \\\\\n --file ./report.pdf \\\\\n --reference-url https://example.com/style-template.png \\\\\n -n 12 -m best --audience \"Executive team\"\n\n ${chalk.gray(\"# Upload content files (PDF, PPTX, DOCX)\")}\n $ conceptcraft create \"Product Demo\" \\\\\n --file ./existing-deck.pptx --file ./specs.pdf \\\\\n --goal persuade --audience \"Enterprise buyers\"\n\n ${chalk.gray(\"# Inline context with custom styling\")}\n $ conceptcraft create \"Q4 Business Review\" \\\\\n -n 12 -m best --goal inform \\\\\n --context \"Revenue: $50M (+25% YoY), EBITDA: $8M\" \\\\\n --reference-url https://example.com/brand-style.jpg\n\n ${chalk.gray(\"# Research presentation from URLs\")}\n $ conceptcraft create \"AI Industry Trends\" \\\\\n -n 10 -m best -t educational \\\\\n --sources https://example.com/ai-report.pdf\n\n ${chalk.gray(\"# Pipe content from another command\")}\n $ cat meeting-notes.md | conceptcraft create \"Meeting Summary\" \\\\\n -n 6 -m balanced --goal inform\n\n${chalk.bold(\"Content Options (what to include in slides):\")}\n -f, --file <paths...> Upload files for content extraction (PDF, PPTX, DOCX)\n -c, --context <text> Inline text (key facts, data points)\n --context-file <path> Read content from file (markdown, text, JSON)\n --sources <urls...> URLs to scrape for content\n --stdin Pipe content from another command\n\n${chalk.bold(\"Styling Options (how slides look):\")}\n --reference-url <url> ${chalk.yellow(\"Image URL to guide visual style\")} (colors, layout, feel)\n --styling <mode> freeform, brand-only, style-only, no-styling\n -b, --brand <id> Apply saved brand settings\n\n ${chalk.gray(\"NOTE: --file uploads provide CONTENT (data, text to include)\")}\n ${chalk.gray(\" --reference-url provides STYLE (visual design inspiration)\")}\n\n${chalk.bold(\"Goal Options:\")}\n -g, --goal <type> inform, persuade, train, learn, entertain, report\n --custom-goal <text> Custom goal description\n\n${chalk.bold(\"Theme Options:\")}\n --theme <preset> Preset color scheme (blue, violet, rose, orange, green)\n --primary-color <hex> Primary brand color (e.g., #0066CC)\n --secondary-color <hex> Secondary color for accents\n --decorations <style> Background style (none, waves-bottom-left, waves-top-right, blob-corners, minimal)\n\n ${chalk.gray(\"Example: Apply corporate colors\")}\n $ conceptcraft create \"Brand Deck\" \\\\\n --theme blue --primary-color \"#1E40AF\" --decorations waves-bottom-left\n\n${chalk.bold(\"Mode Reference:\")}\n best Highest quality, thorough research (recommended for important decks)\n balanced Good quality with reasonable speed (default)\n fast Quick generation, less refinement\n ultrafast Very quick, minimal processing\n instant Fastest, basic output (theme options work best with instant mode)\n`\n )\n .action(async (topic: string, options: CreateOptions) => {\n await requireAuth();\n\n const slideCount = parseInt(options.slides, 10);\n if (isNaN(slideCount) || slideCount < 1 || slideCount > 20) {\n error(\"Slide count must be between 1 and 20\");\n process.exit(6);\n }\n\n const validModes: GenerationMode[] = [\n \"best\",\n \"balanced\",\n \"fast\",\n \"ultrafast\",\n \"instant\",\n ];\n if (!validModes.includes(options.mode)) {\n error(\n `Invalid mode: ${options.mode}. Valid modes: ${validModes.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validTones: GenerationTone[] = [\n \"creative\",\n \"professional\",\n \"educational\",\n \"formal\",\n \"casual\",\n ];\n if (!validTones.includes(options.tone)) {\n error(\n `Invalid tone: ${options.tone}. Valid tones: ${validTones.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validAmounts: GenerationAmount[] = [\n \"minimal\",\n \"concise\",\n \"detailed\",\n \"extensive\",\n ];\n if (!validAmounts.includes(options.amount)) {\n error(\n `Invalid amount: ${options.amount}. Valid amounts: ${validAmounts.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validStyling: StylingMode[] = [\n \"freeform\",\n \"brand-only\",\n \"brand-plus-style\",\n \"style-only\",\n \"no-styling\",\n ];\n if (!validStyling.includes(options.styling)) {\n error(\n `Invalid styling: ${options.styling}. Valid modes: ${validStyling.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validThinkingDepths: ThinkingDepth[] = [\n \"quick\",\n \"moderate\",\n \"deep\",\n \"profound\",\n ];\n if (!validThinkingDepths.includes(options.thinkingDepth)) {\n error(\n `Invalid thinking depth: ${options.thinkingDepth}. Valid depths: ${validThinkingDepths.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate goal option\n if (options.goal && !VALID_GOALS.includes(options.goal as PresentationGoal)) {\n error(\n `Invalid goal: ${options.goal}. Valid goals: ${VALID_GOALS.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate theme options\n const validThemePresets: ThemePreset[] = [\"blue\", \"violet\", \"rose\", \"orange\", \"green\"];\n if (options.theme && !validThemePresets.includes(options.theme)) {\n error(\n `Invalid theme: ${options.theme}. Valid themes: ${validThemePresets.join(\", \")}`\n );\n process.exit(6);\n }\n\n const validDecorations: DecorationStyle[] = [\n \"none\",\n \"waves-bottom-left\",\n \"waves-top-right\",\n \"blob-corners\",\n \"minimal\",\n ];\n if (options.decorations && !validDecorations.includes(options.decorations)) {\n error(\n `Invalid decorations: ${options.decorations}. Valid styles: ${validDecorations.join(\", \")}`\n );\n process.exit(6);\n }\n\n // Validate hex color format\n const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;\n const colorOptions = [\n { name: \"primary-color\", value: options.primaryColor },\n { name: \"secondary-color\", value: options.secondaryColor },\n { name: \"accent-color\", value: options.accentColor },\n { name: \"background-color\", value: options.backgroundColor },\n { name: \"foreground-color\", value: options.foregroundColor },\n ];\n for (const { name, value } of colorOptions) {\n if (value && !hexColorRegex.test(value)) {\n error(`Invalid ${name}: ${value}. Must be a hex color (e.g., #0066CC or #06C)`);\n process.exit(6);\n }\n }\n\n // Build theme object if any theme options provided\n let theme: ThemeOptions | undefined;\n const hasCustomColors =\n options.primaryColor ||\n options.secondaryColor ||\n options.accentColor ||\n options.backgroundColor ||\n options.foregroundColor;\n\n if (options.theme || hasCustomColors || options.decorations) {\n theme = {};\n if (options.theme) {\n theme.preset = options.theme;\n }\n if (hasCustomColors) {\n theme.custom = {};\n if (options.primaryColor) theme.custom.primary = options.primaryColor;\n if (options.secondaryColor) theme.custom.secondary = options.secondaryColor;\n if (options.accentColor) theme.custom.accent = options.accentColor;\n if (options.backgroundColor) theme.custom.background = options.backgroundColor;\n if (options.foregroundColor) theme.custom.foreground = options.foregroundColor;\n }\n if (options.decorations) {\n theme.decorations = options.decorations;\n }\n }\n\n // Preflight check: validate generation limits BEFORE uploading files\n // This prevents wasting time/bandwidth on uploads if generation will fail\n try {\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n process.stdout.write(chalk.gray(\"Checking generation limits... \"));\n }\n const limits = await validateGeneration(options.mode, slideCount, options.teamId);\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(chalk.green(\"✓\"));\n console.log(\n chalk.gray(\n ` Plan: ${limits.planName} | ${options.mode}: ${limits.remaining[options.mode]}/${limits.limits[options.mode]} remaining`\n )\n );\n }\n } catch (err) {\n if (options.output === \"json\") {\n console.log(\n JSON.stringify({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n })\n );\n } else {\n console.log(chalk.red(\"✗\"));\n error(err instanceof Error ? err.message : String(err));\n }\n process.exit((err as any).exitCode ?? 1);\n }\n\n // Validate files exist before uploading\n let uploadedFiles: FileUploadResult[] = [];\n if (options.file && options.file.length > 0) {\n // Validate all files exist first\n for (const filePath of options.file) {\n const resolved = resolve(filePath);\n if (!existsSync(resolved)) {\n error(`File not found: ${filePath}`);\n process.exit(6);\n }\n }\n\n // Upload files with progress\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(chalk.gray(`\\nUploading ${options.file.length} file(s)...`));\n }\n\n try {\n uploadedFiles = await uploadFiles(\n options.file.map((f) => resolve(f)),\n (completed, total, fileName) => {\n if (options.output !== \"json\" && options.output !== \"quiet\" && fileName) {\n process.stdout.write(\n `\\r ${chalk.cyan(\"⬆\")} Uploading: ${fileName} (${completed + 1}/${total})`\n );\n }\n }\n );\n\n if (options.output !== \"json\" && options.output !== \"quiet\") {\n console.log(`\\r ${chalk.green(\"✓\")} Uploaded ${uploadedFiles.length} file(s) `);\n }\n } catch (err) {\n error(\n `Failed to upload files: ${err instanceof Error ? err.message : String(err)}`\n );\n process.exit(1);\n }\n }\n\n // Auto-detect stdin content (or explicit --stdin flag)\n let stdinContent: string | undefined;\n const hasStdinData = !process.stdin.isTTY;\n if (options.stdin || hasStdinData) {\n stdinContent = await readStdin();\n if (options.stdin && !stdinContent) {\n error(\"No content received from stdin\");\n process.exit(6);\n }\n }\n\n // Read context from file if specified\n let contextContent: string | undefined = options.context;\n if (options.contextFile) {\n try {\n contextContent = readFileSync(options.contextFile, \"utf-8\");\n if (!contextContent.trim()) {\n error(`Context file is empty: ${options.contextFile}`);\n process.exit(6);\n }\n } catch (err) {\n error(`Failed to read context file: ${options.contextFile}`);\n process.exit(6);\n }\n }\n\n // Handle brand URL vs ID\n let brandId = options.brand;\n if (options.brand && isUrl(options.brand)) {\n // Brand URL provided - would need to extract first\n // For now, we'll pass it as-is and let the API handle it\n brandId = options.brand;\n }\n\n // Context is required for meaningful slide generation\n const hasContext =\n stdinContent ||\n contextContent ||\n (options.sources && options.sources.length > 0) ||\n uploadedFiles.length > 0;\n\n if (!hasContext) {\n error(\"Context is required to create a presentation.\");\n console.log();\n console.log(chalk.gray(\"Provide context using one of these methods:\"));\n console.log(chalk.gray(\" -f, --file <paths...> Upload files (PDF, PPTX, images)\"));\n console.log(chalk.gray(\" -c, --context <text> Direct text context\"));\n console.log(chalk.gray(\" --context-file <path> Read from a file\"));\n console.log(chalk.gray(\" --sources <urls...> URLs to scrape\"));\n console.log(chalk.gray(\" cat file | conceptcraft Pipe content\"));\n console.log();\n console.log(chalk.gray(\"Example:\"));\n console.log(chalk.cyan(\" conceptcraft create \\\"Q4 Report\\\" --file ./report.pdf\"));\n console.log(chalk.cyan(\" conceptcraft create \\\"Q4 Report\\\" --context \\\"Revenue: $10M, Growth: 25%\\\"\"));\n process.exit(6);\n }\n\n try {\n const response = await createPresentation({\n topic,\n slideCount,\n mode: options.mode,\n tone: options.tone,\n amount: options.amount,\n audience: options.audience,\n language: options.language,\n brandId,\n sources: options.sources,\n stdinContent,\n context: contextContent,\n stylingMode: options.styling,\n referenceUrl: options.referenceUrl,\n thinkingDepth: options.thinkingDepth,\n // New options\n uploadedFiles: uploadedFiles.length > 0 ? uploadedFiles : undefined,\n goal: options.goal as PresentationGoal | undefined,\n customGoal: options.customGoal,\n teamId: options.teamId,\n theme,\n });\n\n const result = await streamWithProgress(response, topic, {\n slideCount,\n mode: options.mode,\n tone: options.tone,\n language: options.language,\n noStream: options.noStream,\n debug: options.debug,\n quiet: options.output === \"quiet\",\n json: options.output === \"json\",\n });\n\n // Output result\n if (options.output === \"json\") {\n console.log(\n JSON.stringify(\n {\n success: true,\n presentation: {\n slug: result.slug,\n title: result.title ?? topic,\n slidesCount: result.slidesCount,\n elapsedSeconds: result.elapsedSeconds,\n totalTokens: result.totalTokens,\n },\n viewUrl: buildViewUrl(result.slug, options.language),\n },\n null,\n 2\n )\n );\n } else {\n // Show success output for both \"human\" and \"quiet\" modes\n // (quiet only hides the progress bar, not the final result)\n console.log();\n success(\"Presentation created successfully\");\n console.log();\n keyValue(\"Title\", result.title ?? topic);\n keyValue(\"Slides\", String(result.slidesCount ?? slideCount));\n // Show generation stats\n const stats: string[] = [];\n if (result.elapsedSeconds) {\n const mins = Math.floor(result.elapsedSeconds / 60);\n const secs = result.elapsedSeconds % 60;\n stats.push(mins > 0 ? `${mins}m ${secs}s` : `${secs}s`);\n }\n if (result.totalTokens) {\n stats.push(`${result.totalTokens.toLocaleString()} tokens`);\n }\n if (stats.length > 0) {\n keyValue(\"Generated in\", stats.join(\" · \"));\n }\n console.log();\n // Prominently display the URL\n const viewUrl = buildViewUrl(result.slug, options.language);\n if (viewUrl !== \"N/A\") {\n console.log(chalk.bold(\" Open: \") + chalk.cyan.underline(viewUrl));\n\n // Open browser if --open flag is set\n if (options.open) {\n const open = await import(\"open\");\n await open.default(viewUrl);\n }\n }\n console.log();\n }\n } catch (err) {\n if (options.output === \"json\") {\n console.log(\n JSON.stringify({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n })\n );\n } else {\n error(err instanceof Error ? err.message : String(err));\n }\n process.exit((err as any).exitCode ?? 1);\n }\n });\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n process.stdin.setEncoding(\"utf8\");\n\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n\n // Set a timeout for stdin\n setTimeout(() => {\n resolve(data.trim());\n }, 100);\n });\n}\n\nfunction isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return str.startsWith(\"http://\") || str.startsWith(\"https://\");\n }\n}\n","/**\n * SSE Streaming Handler\n * Handles Server-Sent Events from the create-presentation endpoint\n */\n\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { isTTY, progressBar } from \"./output.js\";\n\nexport interface StreamCallbacks {\n onProgress?: (current: number, total: number) => void;\n onSlide?: (slideNumber: number, totalSlides: number) => void;\n onPhase?: (phase: string, percentage: number) => void;\n onTokens?: (tokens: number) => void;\n onEstimatedTime?: (seconds: number) => void;\n onData?: (type: string, data: unknown) => void;\n onComplete?: (data: CompleteData) => void;\n onError?: (error: string) => void;\n}\n\nexport interface CompleteData {\n id?: string;\n slug?: string;\n title?: string;\n slidesCount?: number;\n elapsedSeconds?: number;\n totalTokens?: number;\n}\n\ninterface SSEData {\n type: string;\n data: unknown;\n}\n\n/**\n * Parse and handle SSE stream from the API\n */\nexport async function handleStream(\n response: Response,\n callbacks: StreamCallbacks,\n options: { noStream?: boolean; debug?: boolean } = {}\n): Promise<CompleteData> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new TextDecoder();\n let documentId: string | undefined;\n let slug: string | undefined;\n let title: string | undefined;\n let totalSlides = 0;\n let currentSlide = 0;\n let totalTokens = 0;\n let slideTokens: Record<string, number> = {};\n\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n // Skip [DONE] marker\n if (event.data === \"[DONE]\") return;\n\n try {\n // The event.data should be JSON\n const parsed: SSEData = JSON.parse(event.data);\n const { type, data } = parsed;\n\n if (options.debug) {\n console.log(chalk.gray(`[SSE] ${type}:`), data);\n }\n\n callbacks.onData?.(type, data);\n\n switch (type) {\n case \"data-id\":\n documentId = data as string;\n break;\n\n case \"data-slug\":\n slug = data as string;\n break;\n\n case \"data-title\":\n title = data as string;\n break;\n\n case \"data-slides-number-of-slides\":\n totalSlides = data as number;\n break;\n\n case \"data-slide-progress\": {\n const progress = data as { current: number; total: number };\n currentSlide = progress.current;\n totalSlides = progress.total;\n callbacks.onProgress?.(currentSlide, totalSlides);\n callbacks.onSlide?.(currentSlide, totalSlides);\n break;\n }\n\n case \"data-overall-progress\": {\n // Format: {\"percentage\":50,\"phase\":\"slide-generation\",\"details\":{\"slides\":{\"complete\":3,\"total\":6}}}\n const progress = data as {\n percentage: number;\n phase: string;\n details?: { slides?: { complete: number; total: number } };\n };\n // Update phase\n callbacks.onPhase?.(progress.phase, progress.percentage);\n // Update slide progress\n if (progress.details?.slides) {\n currentSlide = progress.details.slides.complete;\n totalSlides = progress.details.slides.total;\n callbacks.onProgress?.(currentSlide, totalSlides);\n callbacks.onSlide?.(currentSlide, totalSlides);\n }\n break;\n }\n\n case \"data-structure-tokens\": {\n // Cumulative structure tokens\n totalTokens = data as number;\n callbacks.onTokens?.(totalTokens);\n break;\n }\n\n case \"data-slide-meta-tokens\": {\n // Format: \"slideId:tokens\"\n const [slideId, tokens] = (data as string).split(\":\");\n if (slideId && tokens) {\n slideTokens[slideId] = parseInt(tokens, 10);\n // Calculate total: structure tokens + all slide tokens\n const allSlideTokens = Object.values(slideTokens).reduce((sum, t) => sum + t, 0);\n totalTokens = Math.max(totalTokens, allSlideTokens);\n callbacks.onTokens?.(totalTokens + allSlideTokens);\n }\n break;\n }\n\n case \"data-generation-meta-estimated-time\": {\n callbacks.onEstimatedTime?.(data as number);\n break;\n }\n\n case \"data-finish\":\n callbacks.onComplete?.({\n id: documentId,\n slug,\n title,\n slidesCount: totalSlides,\n });\n break;\n\n case \"error\":\n // Only report errors with actual messages\n if (data) {\n callbacks.onError?.(data as string);\n }\n break;\n }\n } catch (e) {\n // Not valid JSON, might be SSE text data\n if (options.debug) {\n console.log(chalk.gray(\"[SSE Raw]\"), event.data);\n }\n }\n },\n });\n\n // Read the stream\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n\n if (result.value) {\n const chunk = decoder.decode(result.value, { stream: true });\n parser.feed(chunk);\n }\n }\n\n return {\n id: documentId,\n slug,\n title,\n slidesCount: totalSlides,\n };\n}\n\n/**\n * Create presentation with progress display\n */\nexport async function streamWithProgress(\n response: Response,\n topic: string,\n options: {\n slideCount: number;\n mode: string;\n tone?: string;\n language: string;\n noStream?: boolean;\n debug?: boolean;\n quiet?: boolean;\n json?: boolean;\n }\n): Promise<CompleteData> {\n // In quiet mode, we only hide the progress bar, not the header or final output\n const useTTY = isTTY() && !options.noStream && !options.quiet && !options.json;\n\n if (!options.json) {\n console.log();\n console.log(chalk.bold(`Creating presentation: \"${topic}\"`));\n console.log(\n chalk.gray(\n `Quality: ${options.mode} | Tone: ${options.tone ?? \"professional\"} | Slides: ${options.slideCount} | Language: ${options.language}`\n )\n );\n console.log();\n }\n\n let spinner: ReturnType<typeof ora> | undefined;\n let lastProgress = \"\";\n let currentPhase = \"Preparing\";\n let currentPercentage = 0;\n let currentSlides = { done: 0, total: options.slideCount };\n let currentTokens = 0;\n let estimatedTime = 0;\n let startTime = Date.now();\n let timer: ReturnType<typeof setInterval> | undefined;\n\n // Format time as M:SS (fixed 4 chars: \"0:00\" to \"9:59\", then \"10:00\"+)\n const formatTime = (seconds: number): string => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, \"0\")}`;\n };\n\n // Get elapsed seconds\n const getElapsed = () => Math.floor((Date.now() - startTime) / 1000);\n\n // Get time remaining (or \"—:——\" if not estimated yet)\n const getRemaining = (): string => {\n if (!estimatedTime) return \" —:——\";\n const remaining = Math.max(0, estimatedTime - getElapsed());\n if (remaining === 0 && currentPercentage < 100) return \"soon!\";\n return formatTime(remaining);\n };\n\n // Format tokens (fixed 5 chars: \" 0tk\" to \"99.9k\")\n const formatTokens = (tokens: number): string => {\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}k`.padStart(5, \" \");\n }\n return `${tokens}tk`.padStart(5, \" \");\n };\n\n // User-friendly phase names (fixed 9 chars for stability)\n const getPhaseLabel = (phase: string): string => {\n const phaseMap: Record<string, string> = {\n \"structure-generation\": \"Planning \",\n \"slide-generation\": \"Writing \",\n \"image-generation\": \"Images \",\n \"assembling\": \"Finishing\",\n \"completed\": \"Done \",\n };\n return phaseMap[phase] || \"Working \";\n };\n\n // Build stable progress line (all fixed width)\n // Format: [████████░░░░░░░░░░░░░░░░] 45% Planning 3/10 1.2k 0:45 left\n const buildProgressLine = () => {\n const bar = progressBar(currentPercentage, 100, 20, false);\n const pct = String(currentPercentage).padStart(3, \" \");\n const phase = getPhaseLabel(currentPhase);\n const slides = `${String(currentSlides.done).padStart(2, \" \")}/${String(currentSlides.total).padEnd(2, \" \")}`;\n const tokens = formatTokens(currentTokens);\n const elapsed = formatTime(getElapsed()).padStart(5, \" \");\n const remaining = getRemaining().padStart(5, \" \");\n\n return `${bar} ${chalk.bold(pct)}${chalk.gray(\"%\")} ${chalk.cyan(phase)} ${chalk.gray(slides)} ${chalk.yellow(tokens)} ${chalk.gray(elapsed)} ${chalk.green(remaining + \" left\")}`;\n };\n\n if (useTTY) {\n spinner = ora({\n text: buildProgressLine(),\n spinner: \"dots\",\n }).start();\n\n // Update display every 100ms for smooth animation\n timer = setInterval(() => {\n if (spinner && spinner.isSpinning) {\n spinner.text = buildProgressLine();\n }\n }, 100);\n }\n\n const result = await handleStream(\n response,\n {\n onProgress: (current, total) => {\n currentSlides = { done: current, total };\n if (!useTTY && !options.quiet && !options.json) {\n const progress = `${currentPhase.trim()}: slide ${current}/${total}`;\n if (progress !== lastProgress) {\n console.log(progress);\n lastProgress = progress;\n }\n }\n },\n onPhase: (phase, percentage) => {\n currentPhase = getPhaseLabel(phase);\n currentPercentage = percentage;\n },\n onTokens: (tokens) => {\n currentTokens = tokens;\n },\n onEstimatedTime: (seconds) => {\n estimatedTime = seconds;\n },\n onError: (error) => {\n if (timer) clearInterval(timer);\n if (spinner) {\n spinner.fail(chalk.red(`Error: ${error}`));\n } else if (!options.json) {\n console.error(chalk.red(`Error: ${error}`));\n }\n },\n onComplete: (data) => {\n if (timer) clearInterval(timer);\n if (spinner) {\n currentPercentage = 100;\n currentPhase = \"Done\";\n spinner.succeed(buildProgressLine());\n } else if (!options.json) {\n // Show completion message in both human and quiet modes\n const tokenStr = currentTokens > 0 ? ` | ${currentTokens.toLocaleString()} tokens` : \"\";\n console.log(`Done! [${formatTime(getElapsed())}${tokenStr}]`);\n }\n },\n },\n { debug: options.debug }\n );\n\n // Return result with elapsed time and tokens\n return {\n ...result,\n elapsedSeconds: getElapsed(),\n totalTokens: currentTokens,\n };\n}\n\n/**\n * Stream text content (for blog generation, etc.)\n * Handles plain text streaming from toTextStreamResponse()\n */\nexport async function streamTextContent(\n response: Response,\n options: { quiet?: boolean } = {}\n): Promise<string> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new TextDecoder();\n let content = \"\";\n\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n\n if (result.value) {\n const chunk = decoder.decode(result.value, { stream: true });\n content += chunk;\n if (!options.quiet) {\n process.stdout.write(chunk);\n }\n }\n }\n\n if (!options.quiet) {\n console.log(); // Final newline\n }\n\n return content;\n}\n","/**\n * List Command\n * Lists presentations for the current user/team\n */\n\nimport { Command } from \"commander\";\nimport { listPresentations } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getDefaultTeamId } from \"../lib/config.js\";\nimport {\n formatPresentationTable,\n formatPresentationIds,\n error,\n info,\n} from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface ListOptions {\n limit: string;\n format: OutputFormat | \"ids\" | \"table\";\n sort?: string;\n teamId?: string;\n detail?: boolean;\n language: string;\n}\n\nexport const listCommand = new Command(\"list\")\n .description(\"List presentations\")\n .option(\"-n, --limit <count>\", \"Number of results to return\", \"20\")\n .option(\n \"-f, --format <format>\",\n \"Output format (table, json, ids)\",\n \"table\"\n )\n .option(\"--sort <field>\", \"Sort by field (created, updated, title)\")\n .option(\"--team-id <id>\", \"Team ID (uses default if not specified)\")\n .option(\"-d, --detail\", \"Show detailed output including URLs\")\n .option(\"-l, --language <lang>\", \"Language for URLs\", \"en\")\n .action(async (options: ListOptions) => {\n await requireAuth();\n\n const limit = parseInt(options.limit, 10);\n if (isNaN(limit) || limit < 1) {\n error(\"Invalid limit value\");\n process.exit(6);\n }\n\n const teamId = options.teamId ?? getDefaultTeamId();\n\n if (!teamId) {\n error(\n \"Team ID required. Set a default with 'mindframes config set team-id <id>' or use --team-id\"\n );\n process.exit(6);\n }\n\n try {\n const presentations = await listPresentations(teamId, limit);\n\n if (presentations.length === 0) {\n if (options.format === \"json\") {\n console.log(JSON.stringify([]));\n } else if (options.format !== \"ids\") {\n info(\"No presentations found\");\n }\n return;\n }\n\n // Sort if requested\n if (options.sort) {\n presentations.sort((a, b) => {\n switch (options.sort) {\n case \"created\":\n return (\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n );\n case \"title\":\n return (a.title || \"\").localeCompare(b.title || \"\");\n default:\n return 0;\n }\n });\n }\n\n switch (options.format) {\n case \"json\":\n console.log(JSON.stringify(presentations, null, 2));\n break;\n case \"ids\":\n console.log(formatPresentationIds(presentations));\n break;\n case \"table\":\n default:\n console.log(formatPresentationTable(presentations, {\n showLinks: options.detail,\n language: options.language,\n }));\n break;\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Get Command\n * Gets details of a specific presentation\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { getPresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { error, header, keyValue, formatDate, buildViewUrl } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface GetOptions {\n format: OutputFormat | \"summary\" | \"full\";\n include?: string;\n language: string;\n}\n\nexport const getCommand = new Command(\"get\")\n .description(\"Get presentation details\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\n \"-f, --format <format>\",\n \"Output format (summary, full, json)\",\n \"summary\"\n )\n .option(\"--include <fields>\", \"Fields to include (comma-separated: slides,styling)\")\n .option(\"-l, --language <lang>\", \"Language for view URL\", \"en\")\n .action(async (slug: string, options: GetOptions) => {\n await requireAuth();\n\n try {\n const presentation = await getPresentation(slug);\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(presentation, null, 2));\n return;\n }\n\n const viewUrl = buildViewUrl(presentation.slug, options.language);\n\n header(\"Presentation Details\");\n console.log();\n keyValue(\"Slug\", presentation.slug);\n keyValue(\"Title\", presentation.title || \"Untitled\");\n keyValue(\"Description\", presentation.description || chalk.gray(\"None\"));\n keyValue(\"Slides\", String(presentation.numberOfSlides || \"-\"));\n keyValue(\"Mode\", presentation.mode || \"-\");\n keyValue(\"Created\", formatDate(presentation.createdAt));\n if (presentation.updatedAt) {\n keyValue(\"Updated\", formatDate(presentation.updatedAt));\n }\n console.log();\n if (viewUrl !== \"N/A\") {\n console.log(chalk.bold(\" Open: \") + chalk.cyan.underline(viewUrl));\n }\n console.log();\n\n if (options.format === \"full\" && options.include?.includes(\"slides\")) {\n console.log(chalk.gray(\"(Full slide content available in JSON format)\"));\n console.log();\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Delete Command\n * Deletes a presentation\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { deletePresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { success, error, warn } from \"../lib/output.js\";\n\ninterface DeleteOptions {\n force?: boolean;\n quiet?: boolean;\n}\n\nexport const deleteCommand = new Command(\"delete\")\n .description(\"Delete a presentation\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\"-f, --force\", \"Skip confirmation prompt\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (slug: string, options: DeleteOptions) => {\n await requireAuth();\n\n // Confirm deletion unless --force is used\n if (!options.force) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete presentation \"${slug}\"?`,\n default: false,\n });\n\n if (!confirmed) {\n if (!options.quiet) {\n warn(\"Deletion cancelled\");\n }\n return;\n }\n } catch {\n if (!options.quiet) {\n warn(\"Deletion cancelled\");\n }\n return;\n }\n }\n\n try {\n await deletePresentation(slug);\n\n if (!options.quiet) {\n success(`Presentation \"${slug}\" deleted`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Export Command\n * Exports a presentation to a ZIP file\n */\n\nimport { Command } from \"commander\";\nimport { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { exportPresentation, getPresentation } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { success, error, info } from \"../lib/output.js\";\n\ninterface ExportOptions {\n output?: string;\n includeImages?: boolean;\n includeBranding?: boolean;\n noExternal?: boolean;\n}\n\nexport const exportCommand = new Command(\"export\")\n .description(\"Export a presentation to ZIP\")\n .argument(\"<slug>\", \"Presentation slug (e.g., my-presentation-v1-abc123)\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--include-images\", \"Include images (default: true)\", true)\n .option(\"--include-branding\", \"Include branding (default: true)\", true)\n .option(\"--no-external\", \"Skip external image downloads\")\n .action(async (slug: string, options: ExportOptions) => {\n await requireAuth();\n\n const spinner = ora(\"Fetching presentation...\").start();\n\n try {\n // Get presentation info - this also validates access and gets the ID\n const presentation = await getPresentation(slug);\n const title = presentation.title || slug;\n const presentationId = presentation.id;\n\n // Generate filename from slug (cleaner than title)\n const sanitizedSlug = slug\n .replace(/[^a-z0-9-]/gi, \"_\")\n .toLowerCase()\n .substring(0, 50);\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const defaultFileName = `${sanitizedSlug}_${timestamp}.zip`;\n\n const outputPath = options.output\n ? resolve(options.output)\n : resolve(process.cwd(), defaultFileName);\n\n spinner.text = `Exporting \"${title}\"...`;\n\n const buffer = await exportPresentation(presentationId, {\n includeImages: options.includeImages,\n includeBranding: options.includeBranding,\n includeExternal: !options.noExternal,\n });\n\n spinner.text = \"Saving file...\";\n\n await writeFile(outputPath, Buffer.from(buffer));\n\n spinner.succeed(\"Export complete!\");\n console.log();\n info(`File saved: ${outputPath}`);\n info(`Size: ${formatBytes(buffer.byteLength)}`);\n console.log();\n } catch (err) {\n spinner.fail(\"Export failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","/**\n * Import Command\n * Imports a presentation from a ZIP file\n */\n\nimport { Command } from \"commander\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve, basename } from \"node:path\";\nimport ora from \"ora\";\nimport { importPresentation, whoami } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { error, warn, info, keyValue } from \"../lib/output.js\";\nimport { getApiUrl } from \"../lib/config.js\";\n\ninterface ImportOptions {\n dryRun?: boolean;\n overwrite?: boolean;\n remapIds?: boolean;\n}\n\nconst cmd = new Command(\"import\")\n .description(\"Import a presentation from ZIP (admin only)\")\n .argument(\"<file>\", \"Path to ZIP file\");\n\n// Hide from help output (admin-only command)\n(cmd as any)._hidden = true;\n\nexport const importCommand = cmd\n .option(\"--dry-run\", \"Validate without importing\")\n .option(\"--overwrite\", \"Overwrite existing presentations\")\n .option(\"--remap-ids\", \"Generate new IDs (default: true)\", true)\n .action(async (file: string, options: ImportOptions) => {\n await requireAuth();\n\n // Check if user is admin\n try {\n const me = await whoami();\n if (me.user.role !== \"admin\") {\n error(\"This command is only available to administrators\");\n process.exit(2);\n }\n } catch (err) {\n error(\"Failed to verify permissions\");\n process.exit(2);\n }\n\n const filePath = resolve(file);\n const fileName = basename(filePath);\n\n if (!fileName.endsWith(\".zip\")) {\n error(\"File must be a ZIP archive\");\n process.exit(6);\n }\n\n const spinner = ora(\"Reading file...\").start();\n\n try {\n const fileBuffer = await readFile(filePath);\n\n if (options.dryRun) {\n spinner.text = \"Validating...\";\n } else {\n spinner.text = \"Importing presentation...\";\n }\n\n const result = await importPresentation(fileBuffer, fileName, {\n dryRun: options.dryRun,\n });\n\n if (result.success) {\n if (options.dryRun) {\n spinner.succeed(\"Validation passed!\");\n console.log();\n info(\"The file is valid and can be imported.\");\n\n if (result.statistics) {\n console.log();\n keyValue(\"Slides\", String(result.statistics.slidesImported));\n keyValue(\"Images\", String(result.statistics.imagesUploaded));\n }\n } else {\n spinner.succeed(\"Import complete!\");\n console.log();\n keyValue(\"Presentation ID\", result.presentationId ?? \"N/A\");\n keyValue(\"Document ID\", result.documentId ?? \"N/A\");\n\n if (result.statistics) {\n keyValue(\"Slides imported\", String(result.statistics.slidesImported));\n keyValue(\"Images uploaded\", String(result.statistics.imagesUploaded));\n keyValue(\"Time\", `${result.statistics.totalTimeMs}ms`);\n }\n\n if (result.presentationId) {\n const apiUrl = getApiUrl();\n keyValue(\"View URL\", `${apiUrl}/p/${result.presentationId}`);\n }\n }\n\n if (result.warnings && result.warnings.length > 0) {\n console.log();\n for (const warning of result.warnings) {\n warn(warning);\n }\n }\n\n console.log();\n } else {\n spinner.fail(\"Import failed\");\n console.log();\n\n if (result.errors) {\n for (const err of result.errors) {\n error(`${err.type}: ${err.message}`);\n }\n }\n\n process.exit(1);\n }\n } catch (err) {\n spinner.fail(\"Import failed\");\n\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n error(`File not found: ${filePath}`);\n process.exit(3);\n }\n\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Branding Command\n * Manages brand profiles\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { listBrandings, extractBranding, getBranding } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getDefaultTeamId } from \"../lib/config.js\";\nimport {\n formatBrandingTable,\n success,\n error,\n info,\n keyValue,\n header,\n} from \"../lib/output.js\";\n\ninterface ListOptions {\n format?: \"table\" | \"json\";\n}\n\ninterface ExtractOptions {\n teamId?: string;\n save?: boolean;\n}\n\nexport const brandingCommand = new Command(\"branding\")\n .description(\"Manage brand profiles\")\n .addCommand(\n new Command(\"list\")\n .description(\"List brand profiles\")\n .option(\"-f, --format <format>\", \"Output format (table, json)\", \"table\")\n .action(async (options: ListOptions) => {\n await requireAuth();\n\n try {\n const result = await listBrandings();\n\n if (result.brandings.length === 0) {\n if (options.format === \"json\") {\n console.log(JSON.stringify([]));\n } else {\n info(\"No brand profiles found\");\n console.log();\n console.log(\n chalk.gray(\n \"Create one with: conceptcraft branding extract <url>\"\n )\n );\n }\n return;\n }\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(result.brandings, null, 2));\n } else {\n console.log(formatBrandingTable(result.brandings));\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"get\")\n .description(\"Get brand profile details\")\n .argument(\"<id>\", \"Brand profile ID\")\n .option(\"-f, --format <format>\", \"Output format (summary, json)\", \"summary\")\n .action(async (id: string, options: { format?: string }) => {\n await requireAuth();\n\n try {\n const brand = await getBranding(id);\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(brand, null, 2));\n } else {\n header(\"Brand Profile\");\n console.log();\n keyValue(\"ID\", brand.id);\n keyValue(\"Name\", brand.name);\n keyValue(\"Source URL\", brand.sourceUrl ?? chalk.gray(\"None\"));\n keyValue(\"Default\", brand.isDefault ? chalk.green(\"Yes\") : \"No\");\n if (brand.createdAt) {\n keyValue(\"Created\", new Date(brand.createdAt).toLocaleString());\n }\n console.log();\n\n // Colors with visual swatches\n if (brand.primaryColor || brand.colors.length > 0) {\n console.log(chalk.bold(\" Colors\"));\n if (brand.primaryColor) {\n const swatch = chalk.bgHex(brand.primaryColor)(\" \");\n console.log(` Primary: ${swatch} ${brand.primaryColor}`);\n }\n if (brand.colors.length > 0) {\n console.log(\" Palette:\");\n for (const c of brand.colors.slice(0, 10)) {\n const swatch = chalk.bgHex(c.hex)(\" \");\n const role = c.role ? chalk.gray(` (${c.role})`) : \"\";\n console.log(` ${swatch} ${c.hex}${role}`);\n }\n }\n console.log();\n }\n\n // Logo\n if (brand.logoUrl) {\n console.log(chalk.bold(\" Logo\"));\n console.log(` ${brand.logoUrl}`);\n console.log();\n }\n\n // Typography\n const typo = brand.typography as Record<string, unknown>;\n if (typo && Object.keys(typo).length > 0) {\n console.log(chalk.bold(\" Typography\"));\n if (typo.primary || typo.headings) {\n console.log(` Headings: ${typo.primary || typo.headings || \"-\"}`);\n }\n if (typo.secondary || typo.body) {\n console.log(` Body: ${typo.secondary || typo.body || \"-\"}`);\n }\n console.log();\n }\n\n // Extraction info\n if (brand.confidence || brand.extractionMethod) {\n console.log(chalk.bold(\" Extraction\"));\n if (brand.confidence) {\n console.log(` Confidence: ${Math.round(brand.confidence * 100)}%`);\n }\n if (brand.extractionMethod) {\n console.log(` Method: ${brand.extractionMethod}`);\n }\n console.log();\n }\n\n console.log(chalk.gray(\" Use --format json for full details\"));\n console.log();\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"extract\")\n .description(\"Extract brand profile from a website\")\n .argument(\"<url>\", \"Website URL to extract branding from\")\n .option(\"--team-id <id>\", \"Team ID\")\n .option(\"--no-save\", \"Extract without saving\")\n .action(async (url: string, options: ExtractOptions) => {\n await requireAuth();\n\n // Validate URL\n try {\n new URL(url.startsWith(\"http\") ? url : `https://${url}`);\n } catch {\n error(\"Invalid URL format\");\n process.exit(6);\n }\n\n const fullUrl = url.startsWith(\"http\") ? url : `https://${url}`;\n const teamId = options.teamId ?? getDefaultTeamId();\n\n const spinner = ora({ text: `Extracting branding from ${fullUrl}...`, stream: process.stdout }).start();\n\n try {\n const result = await extractBranding(fullUrl, teamId);\n\n // Fetch full details\n const brand = await getBranding(result.id);\n spinner.succeed(\"Branding extracted!\");\n console.log();\n\n header(\"Brand Profile\");\n console.log();\n keyValue(\"ID\", brand.id);\n keyValue(\"Name\", brand.name);\n keyValue(\"Source URL\", brand.sourceUrl ?? fullUrl);\n console.log();\n\n // Colors with visual swatches\n if (brand.primaryColor || brand.colors.length > 0) {\n console.log(chalk.bold(\" Colors\"));\n if (brand.primaryColor) {\n const swatch = chalk.bgHex(brand.primaryColor)(\" \");\n console.log(` Primary: ${swatch} ${brand.primaryColor}`);\n }\n if (brand.colors.length > 0) {\n console.log(\" Palette:\");\n for (const c of brand.colors.slice(0, 6)) {\n const swatch = chalk.bgHex(c.hex)(\" \");\n const role = c.role ? chalk.gray(` (${c.role})`) : \"\";\n console.log(` ${swatch} ${c.hex}${role}`);\n }\n }\n console.log();\n }\n\n // Logo\n if (brand.logoUrl) {\n console.log(chalk.bold(\" Logo\"));\n console.log(` ${brand.logoUrl}`);\n console.log();\n }\n\n // Extraction info\n if (brand.confidence) {\n console.log(chalk.bold(\" Extraction\"));\n console.log(` Confidence: ${Math.round(brand.confidence * 100)}%`);\n console.log();\n }\n\n info(`Create a presentation with this brand: conceptcraft create \"Your Topic\" -b ${result.id}`);\n console.log();\n } catch (err) {\n spinner.fail(\"Extraction failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n })\n )\n .addCommand(\n new Command(\"set-default\")\n .description(\"Set a brand profile as default\")\n .argument(\"<id>\", \"Brand profile ID\")\n .action(async (id: string) => {\n await requireAuth();\n\n // This would need an API endpoint to set default\n // For now, show info about manual process\n info(\n `To set brand ${id} as default, use the web dashboard.`\n );\n console.log();\n console.log(\n chalk.gray(\n \"API support for setting default brand is coming soon.\"\n )\n );\n })\n );\n","/**\n * Derive Command\n * Generates derivative content from presentations (blog, tweets, etc.)\n * Commands are dynamically registered based on feature flags (cached locally)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { generateBlog, getPresentation, type FeatureFlags } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { getCachedFlags } from \"../lib/feature-cache.js\";\nimport { streamTextContent } from \"../lib/streaming.js\";\nimport { error, info } from \"../lib/output.js\";\n\ninterface BlogOptions {\n words: string;\n tone: \"professional\" | \"casual\" | \"educational\";\n audience?: string;\n format: \"human\" | \"json\" | \"markdown\";\n instructions?: string;\n noImages?: boolean;\n toc?: boolean;\n}\n\ninterface TweetsOptions {\n count: string;\n format: \"human\" | \"json\";\n}\n\ninterface QuestionsOptions {\n count: string;\n format: \"human\" | \"json\";\n}\n\ninterface CheatsheetOptions {\n mode: string;\n format: \"human\" | \"json\" | \"markdown\";\n}\n\n/**\n * Create the blog subcommand\n */\nfunction createBlogCommand(): Command {\n return new Command(\"blog\")\n .description(\"Generate a blog post from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--words <count>\", \"Target word count (50-2000)\", \"300\")\n .option(\n \"--tone <tone>\",\n \"Writing tone (professional, casual, educational)\",\n \"professional\"\n )\n .option(\"--audience <text>\", \"Target audience description\")\n .option(\n \"-f, --format <format>\",\n \"Output format (human, json, markdown)\",\n \"human\"\n )\n .option(\"--instructions <text>\", \"Custom instructions for the blog\")\n .option(\"--no-images\", \"Exclude image references\")\n .option(\"--toc\", \"Include table of contents\")\n .action(async (presentationId: string, options: BlogOptions) => {\n await requireAuth();\n\n const wordCount = parseInt(options.words, 10);\n if (isNaN(wordCount) || wordCount < 50 || wordCount > 2000) {\n error(\"Word count must be between 50 and 2000\");\n process.exit(6);\n }\n\n const validTones = [\"professional\", \"casual\", \"educational\"];\n if (!validTones.includes(options.tone)) {\n error(`Invalid tone. Valid options: ${validTones.join(\", \")}`);\n process.exit(6);\n }\n\n const spinner = ora(\"Fetching presentation...\").start();\n\n try {\n const presentation = await getPresentation(presentationId);\n spinner.text = \"Generating blog post...\";\n\n const response = await generateBlog(\n presentation.id,\n presentation.documentCreatedAt || presentation.createdAt,\n {\n targetWordCount: wordCount,\n tone: options.tone,\n targetAudience: options.audience ?? \"General Audience\",\n customInstructions: options.instructions ?? \"\",\n includeImages: !options.noImages,\n includeTableOfContents: options.toc ?? false,\n }\n );\n\n const content = await streamTextContent(response, { quiet: true });\n spinner.succeed(\"Blog generated\");\n\n if (options.format === \"json\") {\n console.log(\n JSON.stringify(\n {\n presentationId,\n title: presentation.title,\n wordCount,\n tone: options.tone,\n content,\n },\n null,\n 2\n )\n );\n } else if (options.format === \"markdown\") {\n console.log(content);\n } else {\n console.log();\n console.log(chalk.bold(`Blog: ${presentation.title}`));\n console.log(chalk.gray(\"─\".repeat(40)));\n console.log();\n console.log(content);\n console.log();\n }\n } catch (err) {\n spinner.fail(\"Generation failed\");\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n}\n\n/**\n * Create the tweets subcommand\n */\nfunction createTweetsCommand(): Command {\n return new Command(\"tweets\")\n .description(\"Generate tweets from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--count <n>\", \"Number of tweets to generate\", \"5\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string, options: TweetsOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Tweet generation coming soon.\");\n });\n}\n\n/**\n * Create the linkedin subcommand\n */\nfunction createLinkedInCommand(): Command {\n return new Command(\"linkedin\")\n .description(\"Generate a LinkedIn carousel from a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"LinkedIn carousel generation coming soon.\");\n });\n}\n\n/**\n * Create the questions subcommand\n */\nfunction createQuestionsCommand(): Command {\n return new Command(\"questions\")\n .description(\"Generate questions for a presentation\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--count <n>\", \"Number of questions\", \"10\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (presentationId: string, options: QuestionsOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Question generation coming soon.\");\n });\n}\n\n/**\n * Create the cheatsheet subcommand\n */\nfunction createCheatsheetCommand(): Command {\n return new Command(\"cheatsheet\")\n .description(\"Generate a presenter cheat sheet\")\n .argument(\"<slug>\", \"Presentation slug\")\n .option(\"--mode <mode>\", \"Cheat sheet mode (qa-prep, talking-points)\", \"qa-prep\")\n .option(\n \"-f, --format <format>\",\n \"Output format (human, json, markdown)\",\n \"human\"\n )\n .action(async (presentationId: string, options: CheatsheetOptions) => {\n await requireAuth();\n // TODO: Implement when API is ready\n info(\"Cheat sheet generation coming soon.\");\n });\n}\n\n/**\n * Build the derive command with subcommands based on cached feature flags\n * This is SYNCHRONOUS - reads from local cache for instant startup\n */\nexport function buildDeriveCommand(): Command {\n const derive = new Command(\"derive\")\n .description(\"Generate derivative content from a presentation\");\n\n // Get cached flags (returns null if no cache or not authenticated)\n const flags = getCachedFlags();\n if (!flags) {\n // No cached flags - return empty derive command\n // Commands will appear after first successful auth + cache refresh\n return derive;\n }\n\n // Add subcommands based on feature access\n if (flags.deckToBlog) {\n derive.addCommand(createBlogCommand());\n }\n if (flags.deckToTweets) {\n derive.addCommand(createTweetsCommand());\n }\n if (flags.linkedInCarousel) {\n derive.addCommand(createLinkedInCommand());\n }\n if (flags.redTeamQuestions) {\n derive.addCommand(createQuestionsCommand());\n }\n if (flags.presenterCheatSheet) {\n derive.addCommand(createCheatsheetCommand());\n }\n\n return derive;\n}\n","/**\n * Ideas Command\n * Generates presentation topic ideas\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { info } from \"../lib/output.js\";\n\ninterface IdeasOptions {\n context?: string;\n count: string;\n format: \"human\" | \"json\";\n}\n\nexport const ideasCommand = new Command(\"ideas\")\n .description(\"Generate presentation topic ideas\")\n .option(\"--context <text>\", \"Custom context for idea generation\")\n .option(\"--count <n>\", \"Number of ideas to generate\", \"5\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (options: IdeasOptions) => {\n await requireAuth();\n\n info(\"Idea generation is available in the web dashboard.\");\n console.log();\n console.log(\n chalk.gray(\"The CLI will support idea generation in a future release.\")\n );\n console.log();\n console.log(\"For now, try these approaches:\");\n console.log(\n chalk.gray(\n \" 1. Visit the ConceptCraft dashboard and use the idea generator\"\n )\n );\n console.log(\n chalk.gray(\" 2. Create a presentation with a broad topic and refine it\")\n );\n console.log();\n });\n","/**\n * Whoami Command\n * Shows information about the authenticated user and their teams\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { whoami } from \"../lib/api.js\";\nimport { requireAuth } from \"../lib/auth.js\";\nimport { refreshInBackground } from \"../lib/feature-cache.js\";\nimport { error, header, keyValue } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\n\ninterface WhoamiOptions {\n format: OutputFormat;\n}\n\nexport const whoamiCommand = new Command(\"whoami\")\n .description(\"Show current user and team information\")\n .option(\"-f, --format <format>\", \"Output format (human, json)\", \"human\")\n .action(async (options: WhoamiOptions) => {\n await requireAuth();\n\n try {\n const result = await whoami();\n\n // Refresh feature flags cache in background (non-blocking)\n refreshInBackground();\n\n if (options.format === \"json\") {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Human-readable output\n header(\"User\");\n console.log();\n keyValue(\"Email\", result.user.email);\n if (result.user.username) {\n keyValue(\"Username\", result.user.username);\n }\n if (result.user.firstName || result.user.lastName) {\n keyValue(\n \"Name\",\n [result.user.firstName, result.user.lastName].filter(Boolean).join(\" \")\n );\n }\n keyValue(\"Auth Type\", result.authType === \"apiKey\" ? \"API Key\" : \"Session\");\n\n if (result.currentTeam) {\n console.log();\n header(\"Current Team\");\n console.log();\n keyValue(\"ID\", result.currentTeam.id);\n keyValue(\"Name\", result.currentTeam.name);\n keyValue(\"Plan\", result.currentTeam.planName);\n keyValue(\"Role\", result.currentTeam.isOwner ? \"Owner\" : \"Member\");\n }\n\n if (result.teams.length > 1) {\n console.log();\n header(\"All Teams\");\n console.log();\n for (const team of result.teams) {\n const current = team.isCurrent ? chalk.green(\" (current)\") : \"\";\n console.log(\n ` ${chalk.bold(team.name)}${current}`\n );\n console.log(\n chalk.gray(` ID: ${team.id} | Plan: ${team.planName} | Role: ${team.role}`)\n );\n }\n }\n\n console.log();\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit((err as any).exitCode ?? 1);\n }\n });\n","/**\n * Skill Command\n * Installs CLI skills for Claude Code and other AI coding assistants\n * Supports main skill (overview), video skill, and presentation skill with white-labeled names\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { success, error, info, warn, keyValue } from \"../../lib/output.js\";\nimport { brand } from \"../../lib/brand.js\";\nimport { generateMainSkillContent } from \"./generate-main-skill.js\";\nimport { generateVideoSkillContent } from \"./generate-video-skill.js\";\nimport { generatePresentationSkillContent } from \"./generate-presentation-skill.js\";\nimport {\n installSkill,\n uninstallSkill,\n getSupportedEditorNames,\n} from \"./installer.js\";\n\n// Valid skill types\nconst SKILL_TYPES = [\"main\", \"video\", \"presentation\"] as const;\ntype SkillType = (typeof SKILL_TYPES)[number];\n\nconst skillContext = {\n name: brand.name,\n cmd: brand.commands[0],\n displayName: brand.displayName,\n};\n\nexport const skillCommand = new Command(\"skill\")\n .description(`Manage ${brand.displayName} skills for AI coding assistants`)\n .addHelpText(\n \"after\",\n `\n${chalk.bold(\"Skill Types:\")}\n ${chalk.cyan(\"main\")} Main CLI skill with all capabilities (TTS, music, images, videos, presentations)\n ${chalk.cyan(\"video\")} Detailed video creation workflow with Remotion/R3F patterns\n ${chalk.cyan(\"presentation\")} Detailed presentation creation workflow\n\n${chalk.bold(\"Examples:\")}\n ${chalk.gray(\"# Install main CLI skill (comprehensive overview)\")}\n $ ${brand.commands[0]} skill install main\n\n ${chalk.gray(\"# Install video skill\")}\n $ ${brand.commands[0]} skill install video\n\n ${chalk.gray(\"# Install presentation skill\")}\n $ ${brand.commands[0]} skill install presentation\n\n ${chalk.gray(\"# Install all skills\")}\n $ ${brand.commands[0]} skill install\n\n ${chalk.gray(\"# Install to specific directory\")}\n $ ${brand.commands[0]} skill install main --dir ~/.claude\n\n ${chalk.gray(\"# Show skill content\")}\n $ ${brand.commands[0]} skill show main\n`\n );\n\nskillCommand\n .command(\"install\")\n .description(`Install ${brand.displayName} skills for AI coding assistants`)\n .argument(\"[type]\", \"Skill type: main, video, presentation, or omit for all\")\n .option(\"-d, --dir <path>\", \"Install to specific directory\")\n .option(\"-g, --global\", \"Install globally (to home directory)\", true)\n .option(\"-l, --local\", \"Install locally (to current directory)\")\n .option(\"-f, --force\", \"Overwrite existing skill files\")\n .action(async (type: string | undefined, options) => {\n const skillsToInstall: Array<{ name: string; content: string }> = [];\n\n // Determine which skills to install\n if (!type || type === \"main\") {\n skillsToInstall.push({\n name: brand.name,\n content: generateMainSkillContent(skillContext),\n });\n }\n\n if (!type || type === \"video\") {\n skillsToInstall.push({\n name: `${brand.name}-video`,\n content: generateVideoSkillContent(skillContext),\n });\n }\n\n if (!type || type === \"presentation\") {\n skillsToInstall.push({\n name: `${brand.name}-presentation`,\n content: generatePresentationSkillContent(skillContext),\n });\n }\n\n if (type && !SKILL_TYPES.includes(type as SkillType)) {\n error(`Invalid skill type: ${type}. Must be one of: ${SKILL_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n // Install each skill\n console.log();\n for (const skill of skillsToInstall) {\n info(`Installing ${skill.name}...`);\n\n const result = installSkill(skill.name, skill.content, {\n dir: options.dir,\n local: options.local,\n force: options.force,\n });\n\n if (result.installed.length > 0) {\n success(`${skill.name} installed successfully`);\n keyValue(\" Installed to\", result.installed.join(\", \"));\n }\n\n if (result.skipped.length > 0) {\n info(` Skipped (already exists): ${result.skipped.join(\", \")}`);\n console.log(chalk.gray(\" Use --force to overwrite\"));\n }\n\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n error(` ${err}`);\n }\n }\n\n if (result.installed.length === 0 && result.skipped.length === 0 && result.errors.length === 0) {\n info(\" No supported AI coding assistants detected\");\n console.log(chalk.gray(\" Supported editors: \" + getSupportedEditorNames().join(\", \")));\n console.log(chalk.gray(\" Use --dir <path> to install to a specific directory\"));\n }\n\n console.log();\n }\n });\n\nskillCommand\n .command(\"show\")\n .description(\"Display skill content\")\n .argument(\"[type]\", \"Skill type: main, video, or presentation (default: main)\")\n .action((type: string = \"main\") => {\n if (type === \"main\") {\n console.log(generateMainSkillContent(skillContext));\n } else if (type === \"video\") {\n console.log(generateVideoSkillContent(skillContext));\n } else if (type === \"presentation\") {\n console.log(generatePresentationSkillContent(skillContext));\n } else {\n error(`Invalid skill type: ${type}. Must be one of: ${SKILL_TYPES.join(\", \")}`);\n process.exit(1);\n }\n });\n\nskillCommand\n .command(\"uninstall\")\n .description(`Remove ${brand.displayName} skills from AI coding assistants`)\n .argument(\"[type]\", \"Skill type: main, video, presentation, or omit for all\")\n .option(\"-g, --global\", \"Uninstall globally (from home directory)\", true)\n .option(\"-l, --local\", \"Uninstall locally (from current directory)\")\n .action(async (type: string | undefined, options) => {\n const skillsToRemove: string[] = [];\n\n // Determine which skills to remove\n if (!type || type === \"main\") {\n skillsToRemove.push(brand.name);\n }\n\n if (!type || type === \"video\") {\n skillsToRemove.push(`${brand.name}-video`);\n }\n\n if (!type || type === \"presentation\") {\n skillsToRemove.push(`${brand.name}-presentation`);\n }\n\n if (type && !SKILL_TYPES.includes(type as SkillType)) {\n error(`Invalid skill type: ${type}. Must be one of: ${SKILL_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n // Remove each skill\n console.log();\n for (const skillName of skillsToRemove) {\n const result = uninstallSkill(skillName, { local: options.local });\n\n if (result.removed.length > 0) {\n success(`${skillName} uninstalled`);\n keyValue(\" Removed from\", result.removed.join(\", \"));\n } else {\n info(` ${skillName} not found`);\n }\n\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n warn(` Failed to remove: ${err}`);\n }\n }\n }\n console.log();\n });\n\n// Re-export for external use\nexport { generateMainSkillContent } from \"./generate-main-skill.js\";\nexport { generateVideoSkillContent } from \"./generate-video-skill.js\";\nexport { generatePresentationSkillContent } from \"./generate-presentation-skill.js\";\nexport { installSkill, uninstallSkill } from \"./installer.js\";\nexport { SUPPORTED_EDITORS } from \"./editors.js\";\nexport type { SkillSection, SkillContext } from \"./types.js\";\n","/**\n * Main CLI Skill Content Generator\n * Generates a comprehensive skill.md that covers ALL CLI capabilities\n * This is the \"entry point\" skill that AI assistants should load first\n */\n\nimport type { SkillContext } from \"./types.js\";\n\nexport function generateMainSkillContent(context: SkillContext): string {\n const { name, cmd, displayName } = context;\n const envPrefix = name.toUpperCase().replace(/-/g, \"_\");\n\n return `---\nname: ${name}\ndescription: ${displayName} CLI for AI-powered content creation. Use when user needs to create presentations, generate video assets (voiceover, music, images, stock videos), use text-to-speech, mix audio, search stock media, or manage branding. This is the main entry point - load specialized skills (${name}-video, ${name}-presentation) for detailed workflows.\n---\n\n# ${displayName} CLI\n\nA comprehensive CLI for AI-powered content creation. Generate presentations, video assets, voiceovers, music, and search stock media - all from your terminal.\n\n**Install:** \\`npm install -g @${name}/cli\\` or \\`pnpm add -g @${name}/cli\\`\n\n---\n\n## Quick Reference\n\n| Task | Command |\n|------|---------|\n| Create presentation | \\`${cmd} create \"Topic\"\\` |\n| Generate video assets | \\`${cmd} video create < scenes.json\\` |\n| Text-to-speech | \\`${cmd} tts generate -t \"Text\" -o voice.mp3\\` |\n| Generate music | \\`${cmd} music generate -p \"upbeat corporate\"\\` |\n| Search images | \\`${cmd} image search -q \"mountain landscape\"\\` |\n| Search videos | \\`${cmd} video search \"ocean waves\"\\` |\n| Mix audio tracks | \\`${cmd} mix create --video v.mp4 --music m.mp3\\` |\n\n---\n\n## Authentication\n\n\\`\\`\\`bash\n# Login via OAuth (recommended)\n${cmd} login\n\n# Or set API key directly\nexport ${envPrefix}_API_KEY=\"your-key-here\"\n\n# Verify authentication\n${cmd} whoami\n\\`\\`\\`\n\n---\n\n## 1. Presentations\n\nCreate AI-powered presentations from text, files, URLs, or piped content.\n\n\\`\\`\\`bash\n# From topic\n${cmd} create \"AI-powered analytics platform\"\n\n# From file (PDF, PPTX, DOCX, Markdown)\n${cmd} create \"Quarterly Report\" --file report.pdf\n\n# From URL\n${cmd} create \"Product Overview\" --sources https://company.com/product\n\n# From piped content\ncat notes.md | ${cmd} create \"Meeting Summary\"\n\n# With options\n${cmd} create \"Pitch Deck\" \\\\\n --slides 10 \\\\\n --mode balanced \\\\\n --tone professional \\\\\n --audience \"Investors\" \\\\\n --brand my-company \\\\\n --open\n\\`\\`\\`\n\n**Key Options:**\n- \\`--slides <1-20>\\` - Number of slides (default: 10)\n- \\`--mode <instant|ultrafast|fast|balanced|best>\\` - Quality/speed tradeoff\n- \\`--tone <creative|professional|educational|formal|casual>\\`\n- \\`--file <paths...>\\` - Extract content from files\n- \\`--sources <urls...>\\` - Scrape URLs for context\n- \\`--brand <id|url>\\` - Apply branding\n- \\`--open\\` - Open in browser when done\n\n**Manage presentations:**\n\\`\\`\\`bash\n${cmd} list # List all presentations\n${cmd} get <slug> # Get details\n${cmd} export <slug> -o p.zip # Export to ZIP\n${cmd} delete <slug> # Delete\n\\`\\`\\`\n\n---\n\n## 2. Video Asset Generation\n\nGenerate voiceovers, music, and find stock media for video production. Works with Remotion or any video framework.\n\n### Generate All Assets at Once\n\n\\`\\`\\`bash\ncat <<'EOF' | ${cmd} video create --output ./public\n{\n \"scenes\": [\n {\n \"name\": \"Hook\",\n \"script\": \"Watch how we transformed complex workflows into a single click.\",\n \"imageQuery\": \"modern dashboard dark theme\",\n \"videoQuery\": \"abstract tech particles\"\n },\n {\n \"name\": \"Demo\",\n \"script\": \"Our AI analyzes data in real-time, surfacing insights that matter.\",\n \"imageQuery\": \"data visualization charts\"\n },\n {\n \"name\": \"CTA\",\n \"script\": \"Start your free trial today.\",\n \"imageQuery\": \"call to action button\"\n }\n ],\n \"voice\": \"Kore\",\n \"voiceSettings\": {\n \"speed\": 0.95,\n \"stability\": 0.4,\n \"style\": 0.6\n },\n \"musicPrompt\": \"upbeat corporate, positive energy, modern synth\"\n}\nEOF\n\\`\\`\\`\n\n**Output:** Per-scene voiceovers, background music, stock images/videos, and \\`video-manifest.json\\` with timing data.\n\n### Initialize Remotion Project\n\n\\`\\`\\`bash\n${cmd} video init my-video # 16:9 landscape\n${cmd} video init my-video --type tiktok # 9:16 vertical\n\\`\\`\\`\n\n### Embed Thumbnail\n\n\\`\\`\\`bash\n${cmd} video thumbnail video.mp4 --frame 60\n\\`\\`\\`\n\n---\n\n## 3. Text-to-Speech (TTS)\n\nConvert text to natural speech with multiple providers and voices.\n\n\\`\\`\\`bash\n# Basic usage\n${cmd} tts generate -t \"Hello world\" -o output.mp3\n\n# With voice selection\n${cmd} tts generate -t \"Welcome to the demo\" -v Rachel -o welcome.mp3\n\n# With provider and settings\n${cmd} tts generate \\\\\n -t \"Professional narration\" \\\\\n -v Kore \\\\\n -p gemini \\\\\n -s 0.9 \\\\\n -o narration.mp3\n\n# List available voices\n${cmd} tts voices\n${cmd} tts voices --provider elevenlabs\n\\`\\`\\`\n\n**Providers:** \\`gemini\\`, \\`elevenlabs\\`, \\`openai\\`\n**Popular voices:** \\`Kore\\`, \\`Puck\\`, \\`Rachel\\`, \\`alloy\\`\n**Speed range:** 0.25 - 4.0 (default: 1.0)\n\n---\n\n## 4. Music Generation\n\nGenerate AI music from text descriptions.\n\n\\`\\`\\`bash\n# Generate music\n${cmd} music generate -p \"upbeat corporate, modern synth\" --duration 30\n\n# Save to file\n${cmd} music generate -p \"calm ambient background\" -o music.mp3\n\n# Check generation status (for async operations)\n${cmd} music status <request-id>\n\\`\\`\\`\n\n**Duration:** 3-30 seconds\n**Providers:** \\`elevenlabs\\`, \\`suno\\`\n\n---\n\n## 5. Image Search\n\nSearch for stock images from multiple sources.\n\n\\`\\`\\`bash\n# Basic search\n${cmd} image search -q \"mountain landscape\"\n\n# With options\n${cmd} image search -q \"business team meeting\" \\\\\n --max-results 20 \\\\\n --size large \\\\\n --format json\n\n# Download for video project\n${cmd} image search -q \"tech abstract\" -n 5 --format json > images.json\n\\`\\`\\`\n\n**Options:**\n- \\`--max-results <n>\\` - Number of results (default: 10)\n- \\`--size <small|medium|large|any>\\` - Image size\n- \\`--safe-search / --no-safe-search\\` - Filter adult content\n\n---\n\n## 6. Video Search\n\nSearch for stock video clips.\n\n\\`\\`\\`bash\n# Basic search\n${cmd} video search \"ocean waves\"\n\n# With filters\n${cmd} video search \"city timelapse\" \\\\\n --max-results 5 \\\\\n --orientation landscape \\\\\n --license free\n\\`\\`\\`\n\n**Options:**\n- \\`--orientation <landscape|portrait|square|any>\\`\n- \\`--license <free|premium|any>\\`\n\n---\n\n## 7. Audio Mixing\n\nMix video with voiceover and background music.\n\n\\`\\`\\`bash\n# Mix audio tracks\n${cmd} mix create \\\\\n --video input.mp4 \\\\\n --voice voiceover.mp3 \\\\\n --music background.mp3 \\\\\n --music-volume 30 \\\\\n --voice-volume 100 \\\\\n -o final.mp4\n\n# Check mixing status\n${cmd} mix status <request-id>\n\\`\\`\\`\n\nMusic automatically loops to match video duration.\n\n---\n\n## 8. Branding\n\nManage brand profiles for consistent styling.\n\n\\`\\`\\`bash\n# List saved brands\n${cmd} branding list\n\n# Extract branding from website\n${cmd} branding extract https://company.com\n\n# Get brand details\n${cmd} branding get <brand-id>\n\n# Set default brand\n${cmd} branding set-default <brand-id>\n\n# Use in presentations\n${cmd} create \"Topic\" --brand my-company\n\\`\\`\\`\n\n---\n\n## 9. Configuration\n\n\\`\\`\\`bash\n# Interactive setup\n${cmd} config init\n\n# Show current config\n${cmd} config show\n${cmd} config show --verify # Verify API key\n\n# Set values\n${cmd} config set api-key <key>\n${cmd} config set team-id <id>\n\n# Clear config\n${cmd} config clear\n\n# Show config file location\n${cmd} config path\n\\`\\`\\`\n\n---\n\n## Output Formats\n\nAll commands support multiple output formats:\n\n\\`\\`\\`bash\n${cmd} <command> --format human # Default, colored terminal output\n${cmd} <command> --format json # Machine-readable JSON\n${cmd} <command> --format quiet # Minimal output, errors only\n\\`\\`\\`\n\n---\n\n## Environment Variables\n\n\\`\\`\\`bash\n${envPrefix}_API_KEY # API key for authentication\n${envPrefix}_API_URL # Custom API URL (optional)\n\\`\\`\\`\n\n---\n\n## Specialized Skills\n\nFor detailed workflows, load these skills:\n\n- **\\`${name}-video\\`** - Detailed video creation workflow, Remotion integration, composition rules, R3F/Three.js patterns\n- **\\`${name}-presentation\\`** - Detailed presentation creation, styling options, export formats\n\n---\n\n## Common Workflows\n\n### Video Production Pipeline\n\n\\`\\`\\`bash\n# 1. Initialize project\n${cmd} video init product-demo\n\n# 2. Generate assets\ncat scenes.json | ${cmd} video create -o product-demo/public\n\n# 3. Implement in Remotion (see ${name}-video skill)\n\n# 4. Render and add thumbnail\ncd product-demo\npnpm exec remotion render FullVideo\n${cmd} video thumbnail out/FullVideo.mp4 --frame 60\n\\`\\`\\`\n\n### Presentation from Research\n\n\\`\\`\\`bash\n# Gather content from multiple sources\n${cmd} create \"Market Analysis\" \\\\\n --file research.pdf \\\\\n --sources https://industry-report.com \\\\\n --context \"Focus on Q4 trends\" \\\\\n --slides 15 \\\\\n --tone professional \\\\\n --brand company \\\\\n --open\n\\`\\`\\`\n\n### Batch Image Collection\n\n\\`\\`\\`bash\n# Get images for video scenes\nfor query in \"hero shot\" \"team photo\" \"product showcase\"; do\n ${cmd} image search -q \"$query\" -n 3 --format json\ndone\n\\`\\`\\`\n\n---\n\n## Troubleshooting\n\n**Authentication issues:**\n\\`\\`\\`bash\n${cmd} whoami # Check current user\n${cmd} logout && ${cmd} login # Re-authenticate\n\\`\\`\\`\n\n**Check API status:**\n\\`\\`\\`bash\n${cmd} config show --verify\n\\`\\`\\`\n\n**Debug mode:**\n\\`\\`\\`bash\n${cmd} <command> --debug\n\\`\\`\\`\n\n---\n\n## Help\n\n\\`\\`\\`bash\n${cmd} --help # General help\n${cmd} <command> --help # Command-specific help\n${cmd} --version # Version info\n\\`\\`\\`\n`;\n}\n","/**\n * Video rule content - embedded markdown for each rule file\n * These are written to disk when the skill is installed\n */\n\nexport interface RuleContent {\n filename: string;\n content: string;\n}\n\nexport const VIDEO_RULE_CONTENTS: RuleContent[] = [\n {\n filename: \"video-creation-guide.md\",\n content: `# Video Creation Guide\n\n### Related Skills\n\nUse these installed skills for implementation details:\n- \\`remotion-best-practices\\` — Remotion patterns and API\n- \\`threejs-*\\` skills — for R3F/WebGL (particles, 3D elements)\n\n---\n\n## Core Rules\n\nYour task is not \"making slideshows\" — you are **simulating a real interface** that obeys cinematic physics.\n\n### Hard Constraints\n\n1. **No scene > 8 seconds** without cut or major action\n2. **No static pixels** — everything breathes, drifts, pulses\n3. **No linear interpolation** — use \\`spring()\\` physics\n4. **Scene overlap 15-20 frames** — no hard cuts\n5. **60 FPS mandatory** — 30fps looks choppy\n6. **No screenshots for UI** — rebuild in React/CSS\n\n---\n\n## Code Organization\n\n- Create separate files: \\`Button.tsx\\`, \\`Window.tsx\\`, \\`Cursor.tsx\\`\n- Use Zod schemas for props validation\n- Extract animation configs to constants\n\n\\`\\`\\`tsx\nimport { spring, interpolate, useCurrentFrame, useVideoConfig } from 'remotion';\n\n// ALWAYS use spring for element entrances\n// NEVER use magic numbers\n\\`\\`\\`\n\n---\n\n## Aesthetics (Linear/Stripe Style)\n\n\\`\\`\\`css\n/* Shadows - soft, expensive */\nbox-shadow: 0 20px 50px -12px rgba(0,0,0,0.5);\n\n/* Borders - thin, barely visible */\nborder: 1px solid rgba(255,255,255,0.1);\n\\`\\`\\`\n\n- Fonts: Inter or SF Pro\n- Never pure \\`#000000\\` — use \\`#050505\\`\n- Never pure \\`#FFFFFF\\` — use \\`#F0F0F0\\`\n\n---\n\n## Self-Check Before Render\n\n- [ ] Camera rig wraps entire scene with drift/zoom\n- [ ] Every UI element uses 2.5D rotation entrance\n- [ ] Cursor moves in curves with overshoot\n- [ ] Lists/grids stagger (never appear all at once)\n- [ ] Background has moving orbs + vignette + noise\n- [ ] Something is moving on EVERY frame\n- [ ] Scene transitions overlap (no hard cuts)\n\n**If your video looks like PowerPoint with voiceover — START OVER.**\n`,\n },\n {\n filename: \"animation-physics.md\",\n content: `# Animation Physics\n\n## Spring Configurations\n\n### Heavy UI (Modals, Sidebars)\n\\`\\`\\`tsx\nconfig: { mass: 1, stiffness: 100, damping: 15 }\n\\`\\`\\`\n\n### Light UI (Tooltips, Badges)\n\\`\\`\\`tsx\nconfig: { mass: 0.6, stiffness: 180, damping: 12 }\n\\`\\`\\`\n\n### Standard (Snappy)\n\\`\\`\\`tsx\nconfig: { mass: 1, damping: 15, stiffness: 120 }\n\\`\\`\\`\n\n---\n\n## Staggering\n\n**NEVER show a list all at once.**\n\n\\`\\`\\`tsx\nconst STAGGER_FRAMES = 3; // 3-5 frames between items\n\n{items.map((item, i) => {\n const delay = i * STAGGER_FRAMES;\n const progress = spring({\n frame: frame - delay,\n fps,\n config: { damping: 15, stiffness: 120 },\n });\n\n return (\n <div style={{\n opacity: progress,\n transform: \\`translateY(\\${interpolate(progress, [0, 1], [20, 0])}px)\\`,\n }}>\n {item}\n </div>\n );\n})}\n\\`\\`\\`\n\n---\n\n## Cursor Movement\n\n**Cursor NEVER moves in straight lines.**\n\n\\`\\`\\`tsx\nconst progress = spring({\n frame: frame - startFrame,\n fps,\n config: { damping: 20, stiffness: 80 },\n});\n\nconst linearX = interpolate(progress, [0, 1], [start.x, end.x]);\nconst linearY = interpolate(progress, [0, 1], [start.y, end.y]);\n\n// THE ARC: Parabola that peaks mid-travel\nconst arcHeight = 100;\nconst arcOffset = Math.sin(progress * Math.PI) * arcHeight;\nconst cursorY = linearY - arcOffset;\n\\`\\`\\`\n\n---\n\n## Click Interaction\n\n\\`\\`\\`tsx\n// On click:\nconst cursorScale = isClicking ? 0.95 : 1;\nconst buttonScaleX = isClicking ? 1.02 : 1;\nconst buttonScaleY = isClicking ? 0.95 : 1;\n// Release both with spring\n\\`\\`\\`\n\n---\n\n## Timing Reference\n\n| Action | Frames (60fps) |\n|--------|----------------|\n| Element entrance | 15-20 |\n| Stagger gap | 3-5 |\n| Hold on key info | 45-60 |\n| Scene transition | 20-30 |\n| Fast interaction | 15-20 |\n`,\n },\n {\n filename: \"scene-structure.md\",\n content: `# Scene Structure\n\n## SceneWrapper\n\n\\`\\`\\`tsx\n<SceneWrapper\n durationInFrames={300}\n transitionType=\"slideLeft\"\n cameraMotion=\"panRight\"\n>\n <FeatureLayer />\n <CursorLayer />\n <ParticleLayer />\n</SceneWrapper>\n\\`\\`\\`\n\n---\n\n## Layer Structure (Z-Index)\n\n| Layer | Z-Index |\n|-------|---------|\n| Background orbs | 0 |\n| Vignette | 1 |\n| UI Base | 10 |\n| UI Elements | 20 |\n| Overlays | 30 |\n| Text/Captions | 40 |\n| Cursor | 50 |\n\n---\n\n## Case Study: SaaS Task Tracker\n\n### Scene 1: \"The Hook\" (~5s)\n\n1. Dark background (\\`#0B0C10\\`), grid drifting\n2. Scattered circles magnetically attract → morph into logo\n3. Logo expands → becomes sidebar navigation\n\n### Scene 2: \"Micro-Interaction\" (~6s)\n\n1. Modal \"Create Issue\" appears\n2. Text types character by character (non-uniform speed)\n3. \\`CMD + K\\` hint glows, keys animate\n4. Cursor flies to \"Save\" in arc, slows on approach\n\n### Scene 3: \"The Connection\" (~5s)\n\n1. Task card grabbed, scales 1.05, shadow deepens\n2. Other cards spread apart\n3. **Match Cut:** Zoom into avatar → color fills screen → becomes mobile notification background\n\n---\n\n## Composition\n\n\\`\\`\\`tsx\n<AbsoluteFill>\n <MovingBackground />\n <Vignette />\n <CameraRig>\n <Sequence from={0} durationInFrames={100}>\n <Scene1 />\n </Sequence>\n <Sequence from={85} durationInFrames={150}> {/* 15 frame overlap! */}\n <Scene2 />\n </Sequence>\n </CameraRig>\n <Audio src={music} volume={0.3} />\n</AbsoluteFill>\n\\`\\`\\`\n`,\n },\n {\n filename: \"scene-transitions.md\",\n content: `# Scene Transitions\n\n**No FadeIn/FadeOut.** Only contextual transitions.\n\n---\n\n## Types\n\n### 1. Object Persistence\nSame chart transforms (data, color, scale) while UI changes around it.\n\n### 2. Mask Reveal\nButton expands to screen size via SVG \\`clipPath\\`.\n\n### 3. Speed Ramps\nScene A accelerates out, Scene B starts fast then slows.\n\n---\n\n## Match Cut Example\n\n\\`\\`\\`\nScene A: Zoom into avatar\n ↓\nAvatar color fills screen\n ↓\nScene B: That color IS the notification background\n\\`\\`\\`\n\n---\n\n## Overlapping Sequences (CRITICAL)\n\n\\`\\`\\`tsx\n<Sequence from={0} durationInFrames={100}>\n <SceneOne />\n</Sequence>\n<Sequence from={85} durationInFrames={150}> {/* 15 frames early! */}\n <SceneTwo />\n</Sequence>\n\\`\\`\\`\n\n---\n\n## TransitionSeries\n\n\\`\\`\\`tsx\nimport { TransitionSeries, linearTiming } from '@remotion/transitions';\nimport { slide } from '@remotion/transitions/slide';\n\n<TransitionSeries>\n <TransitionSeries.Sequence durationInFrames={100}>\n <SceneOne />\n </TransitionSeries.Sequence>\n <TransitionSeries.Transition\n presentation={slide({ direction: 'from-bottom' })}\n timing={linearTiming({ durationInFrames: 20 })}\n />\n <TransitionSeries.Sequence durationInFrames={150}>\n <SceneTwo />\n </TransitionSeries.Sequence>\n</TransitionSeries>\n\\`\\`\\`\n`,\n },\n {\n filename: \"polish-effects.md\",\n content: `# Polish Effects\n\n## Reflection (Glass Glint)\n\nDiagonal gradient sweeps every 5 seconds.\n\n\\`\\`\\`tsx\nconst cycleFrame = frame % 300;\nconst sweepProgress = interpolate(cycleFrame, [0, 60], [-100, 200], {\n extrapolateRight: 'clamp',\n});\n\\`\\`\\`\n\n---\n\n## Background Breathing\n\nBackground is NEVER static.\n\n\\`\\`\\`tsx\nconst orb1X = Math.sin(frame / 60) * 200;\nconst orb1Y = Math.cos(frame / 80) * 100;\n\\`\\`\\`\n\n---\n\n## Typewriter Effect\n\n\\`\\`\\`tsx\nconst charIndex = Math.floor(frame / 3);\nconst showCursor = Math.floor(frame / 15) % 2 === 0;\n\n<span>\n {text.slice(0, charIndex)}\n {showCursor && <span>|</span>}\n</span>\n\\`\\`\\`\n\n---\n\n## Vignette & Noise\n\n\\`\\`\\`tsx\n// Noise\n<AbsoluteFill style={{\n backgroundImage: 'url(/noise.png)',\n opacity: 0.03,\n mixBlendMode: 'overlay',\n}} />\n\n// Vignette\n<AbsoluteFill style={{\n background: 'radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,0.8) 100%)',\n}} />\n\\`\\`\\`\n`,\n },\n {\n filename: \"advanced-techniques.md\",\n content: `# Advanced Techniques\n\n## Audio-Reactive\n\n- **Kick:** \\`scale(1.005)\\` pulse\n- **Snare:** Trigger scene changes\n- **Hi-hats:** Cursor flicker, particle shimmer\n\n---\n\n## Motion Blur (Fake)\n\n\\`\\`\\`tsx\n// Trail: Render 3-4 copies with opacity 0.3, 1-frame delay\n\n// Or drop shadow for fast movement:\nfilter: \\`drop-shadow(\\${velocityX * 0.5}px \\${velocityY * 0.5}px 10px rgba(0,0,0,0.3))\\`\n\\`\\`\\`\n\n---\n\n## 3D Perspective\n\n\\`\\`\\`tsx\n<div style={{ perspective: '1000px' }}>\n <div style={{\n transform: 'rotateX(5deg) rotateY(10deg)',\n transformStyle: 'preserve-3d',\n }}>\n {/* Your UI */}\n </div>\n</div>\n\\`\\`\\`\n\n---\n\n## Kinetic Typography\n\n### Masked Reveal\n\\`\\`\\`tsx\n<div style={{ overflow: 'hidden', height: 80 }}>\n <h1 style={{\n transform: \\`translateY(\\${interpolate(progress, [0, 1], [100, 0])}%)\\`,\n }}>\n INTRODUCING\n </h1>\n</div>\n\\`\\`\\`\n\n### Keyword Animation\nAnimate keywords, not whole sentences.\n`,\n },\n {\n filename: \"remotion-config.md\",\n content: `# Remotion Configuration\n\n## FPS & Resolution\n\n- **60 FPS mandatory** — 30fps looks choppy\n- **1920×1080** Full HD\n- **Center:** \\`{x: 960, y: 540}\\`\n\n---\n\n## Timing\n\n- 1 second = 60 frames\n- Fast interaction = 15-20 frames\n- No scene > 8 seconds without action\n\n---\n\n## Entry-Action-Exit Structure\n\n| Phase | Duration |\n|-------|----------|\n| Entry | 0.0s - 0.5s |\n| Action | 0.5s - (duration - 1s) |\n| Exit | last 1s |\n\n---\n\n## Font Loading\n\n\\`\\`\\`tsx\nconst [handle] = useState(() => delayRender());\n\nuseEffect(() => {\n document.fonts.ready.then(() => {\n continueRender(handle);\n });\n}, [handle]);\n\\`\\`\\`\n\n---\n\n## Zod Schema\n\n\\`\\`\\`tsx\nexport const SceneSchema = z.object({\n titleText: z.string(),\n buttonColor: z.string(),\n cursorPath: z.array(z.object({ x: z.number(), y: z.number() })),\n});\n\\`\\`\\`\n\n---\n\n## SaaS Video Kit Components\n\n| Component | Purpose |\n|-----------|---------|\n| \\`MockWindow\\` | macOS window with traffic lights |\n| \\`SmartCursor\\` | Bezier curves + click physics |\n| \\`NotificationToast\\` | Slide in, wait, slide out |\n| \\`TypingText\\` | Typewriter with cursor |\n| \\`Placeholder\\` | For logos/icons |\n\n---\n\n## Code Rules\n\n1. No \\`transition: all 0.3s\\` — use \\`interpolate()\\` or \\`spring()\\`\n2. Use \\`AbsoluteFill\\` for layout\n3. No magic numbers — extract to constants\n`,\n },\n {\n filename: \"elite-production.md\",\n content: `# Elite Production\n\nFor Stripe/Apple/Linear quality.\n\n---\n\n## Global Lighting Engine\n\n\\`\\`\\`tsx\nconst lightSource = { x: 0.2, y: -0.5 };\nconst gradientAngle = Math.atan2(lightSource.y, lightSource.x) * (180 / Math.PI);\n\n<button style={{\n background: \\`linear-gradient(\\${gradientAngle}deg, rgba(255,255,255,0.1) 0%, transparent 50%)\\`,\n borderTop: '1px solid rgba(255,255,255,0.15)',\n boxShadow: \\`\\${-lightSource.x * 20}px \\${-lightSource.y * 20}px 40px rgba(0,0,0,0.3)\\`,\n}} />\n\\`\\`\\`\n\n---\n\n## Noise & Dithering\n\nEvery background needs noise overlay (opacity 0.02-0.05). Prevents YouTube banding.\n\n---\n\n## React Three Fiber\n\nFor particles, 3D globes — use WebGL via \\`@remotion/three\\`, not CSS 3D.\n\n\\`\\`\\`tsx\nimport { ThreeCanvas } from '@remotion/three';\n\n<AbsoluteFill>\n <HtmlUI />\n <ThreeCanvas>\n <Particles />\n </ThreeCanvas>\n</AbsoluteFill>\n\\`\\`\\`\n\nSee \\`threejs-*\\` skills for implementation.\n\n---\n\n## Virtual Camera Rig\n\nMove camera, not elements:\n\n\\`\\`\\`tsx\nconst CameraProvider = ({ children }) => {\n const frame = useCurrentFrame();\n const panX = interpolate(frame, [0, 300], [0, -100]);\n const zoom = interpolate(frame, [0, 300], [1, 1.05]);\n\n return (\n <div style={{\n transform: \\`translateX(\\${panX}px) scale(\\${zoom})\\`,\n transformOrigin: 'center',\n }}>\n {children}\n </div>\n );\n};\n\\`\\`\\`\n\n---\n\n## Motion Rules\n\n- **Overshoot:** Modal scales to 1.02, settles to 1.0\n- **Overlap:** Scene B starts 15 frames before Scene A ends\n`,\n },\n {\n filename: \"known-issues.md\",\n content: `# Known Issues & Fixes\n\n## 1. Music Ends Before Video Finishes\n\n**Problem:** Music duration is shorter than video duration, causing awkward silence at the end.\n\n**Solution:** Loop music in Remotion using the \\`loop\\` prop:\n\n\\`\\`\\`tsx\nimport { Audio } from 'remotion';\n\n<Audio src={musicSrc} volume={0.3} loop />\n\\`\\`\\`\n\n**How it works:**\n- Music automatically loops to fill video duration\n- Set volume to 0.3 (30% - less loud than voice)\n- Add fade out at the end for smooth ending\n\n---\n\n## 2. Music Transitions Sound Abrupt\n\n**Problem:** Music cuts harshly when scenes change or video ends.\n\n**Fix in Remotion:**\n\\`\\`\\`tsx\nimport { interpolate, Audio } from 'remotion';\n\n// Fade music in/out at scene boundaries\nconst musicVolume = interpolate(\n frame,\n [0, 30, totalFrames - 60, totalFrames],\n [0, 0.3, 0.3, 0],\n { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }\n);\n\n<Audio src={music} volume={musicVolume} />\n\\`\\`\\`\n\n---\n\n## 3. Scene Transitions Too Harsh\n\n**Problem:** Scenes change abruptly without smooth transitions.\n\n**Fix:** Use \\`@remotion/transitions\\` with overlapping:\n\\`\\`\\`tsx\nimport { TransitionSeries, springTiming } from '@remotion/transitions';\nimport { slide } from '@remotion/transitions/slide';\nimport { fade } from '@remotion/transitions/fade';\n\n<TransitionSeries>\n <TransitionSeries.Sequence durationInFrames={sceneA.frames}>\n <SceneA />\n </TransitionSeries.Sequence>\n <TransitionSeries.Transition\n presentation={slide({ direction: 'from-right' })}\n timing={springTiming({ config: { damping: 20 } })}\n />\n <TransitionSeries.Sequence durationInFrames={sceneB.frames}>\n <SceneB />\n </TransitionSeries.Sequence>\n</TransitionSeries>\n\\`\\`\\`\n\n---\n\n## 4. Voiceover Lacks Energy\n\n**Problem:** Voiceover sounds flat/monotone.\n\n**Fix:** Pass \\`voiceSettings\\` in scenes JSON:\n\\`\\`\\`json\n{\n \"scenes\": [...],\n \"voice\": \"Kore\",\n \"voiceSettings\": {\n \"style\": 0.6,\n \"stability\": 0.4,\n \"speed\": 0.95\n }\n}\n\\`\\`\\`\n\n- \\`style\\`: 0.5-0.7 for more expressive delivery\n- \\`stability\\`: 0.3-0.5 for more variation\n- \\`speed\\`: 0.9-1.0 slightly slower = more impactful\n\n---\n\n## 5. Video Duration Mismatch\n\n**Problem:** Brief says 30-45s but video is 20s (because scene duration = voiceover duration).\n\n**Fixes:**\n1. **Slow voice:** Use \\`speed: 0.85\\` in voiceSettings\n2. **Add padding in Remotion:** Hold last frame, add breathing room\n\\`\\`\\`tsx\n// Add 30 frames (0.5s) padding after voiceover ends\nconst paddedDuration = voiceoverFrames + 30;\n\\`\\`\\`\n3. **Brief should note:** \"Duration based on voiceover length\"\n\n---\n\n## 6. Not Using Project UI Components\n\n**Problem:** Generic UI instead of pixel-perfect project components.\n\n**Fix:** In Phase 1 Discovery:\n1. Find project's actual components (buttons, cards, modals, inputs)\n2. Copy their styles/structure into Remotion components\n3. Match colors, fonts, shadows, border-radius exactly\n\n\\`\\`\\`tsx\n// DON'T: Generic button\n<button style={{ background: 'blue' }}>Click</button>\n\n// DO: Match project's actual button\n<button style={{\n background: 'linear-gradient(135deg, #6366f1, #8b5cf6)',\n borderRadius: 8,\n padding: '12px 24px',\n boxShadow: '0 4px 14px rgba(99, 102, 241, 0.4)',\n border: '1px solid rgba(255,255,255,0.1)',\n}}>Click</button>\n\\`\\`\\`\n\n---\n\n## 7. Missing Physics & Lighting\n\n**Problem:** Video feels flat, no depth or motion.\n\n**Checklist:**\n- [ ] Global light source defined (affects all shadows/gradients)\n- [ ] Camera rig with subtle drift/zoom\n- [ ] Spring physics on ALL entrances (no linear)\n- [ ] Staggered animations (never all at once)\n- [ ] Background orbs/particles moving\n- [ ] Noise overlay (opacity 0.02-0.05)\n- [ ] Vignette for depth\n`,\n },\n];\n","/**\n * Video Skill Content Generator\n * Generates a single skill.md file with all video content merged\n */\n\nimport type { SkillContext } from \"./types.js\";\nimport { VIDEO_RULE_CONTENTS } from \"./rules/video/content.js\";\n\nexport function generateVideoSkillContent(context: SkillContext): string {\n const { name, cmd, displayName } = context;\n\n return `---\nname: ${name}-video\ndescription: Use when user asks to create videos (product demos, explainers, social content, promos). Handles video asset generation, Remotion implementation, and thumbnail embedding.\n---\n\n# ${displayName} Video Creation CLI\n\nCreate professional product videos directly from your terminal. The CLI generates AI-powered video assets (voiceover, music, images, stock videos) and provides tools for Remotion-based video production with React Three Fiber.\n\n**Stack:** Remotion (React video framework) + React Three Fiber (R3F) + Three.js for 3D/WebGL, particles, shaders, lighting.\n\nWe create **elite product videos** (Stripe, Apple, Linear quality) using physics-based animation, dynamic lighting, and pixel-perfect UI components rebuilt from the real project — never boring screenshots or static images.\n\n**Core Philosophy:** \"Nothing sits still. Everything is physics-based. Every pixel breathes.\"\n\n---\n\n## CRITICAL: Professional Composition Rules\n\n**These rules are MANDATORY for all marketing/product videos:**\n\n### ❌ NEVER DO:\n1. **Walls of text** - No dense paragraphs or lists longer than 3 lines\n2. **Flying/floating cards** - No random floating animations across the screen\n3. **Stretched layouts** - No elements awkwardly stretched to fill space\n4. **Truncated text** - Never show \"Text that gets cut off...\"\n5. **Information overload** - Max 1-2 key points visible at once\n6. **Amateur motion** - No PowerPoint-style \"fly in from left/right\"\n\n### ✅ ALWAYS DO:\n1. **Hierarchy first** - One clear focal point per scene (headline OR stat OR visual, not all)\n2. **Breathing room** - Generous whitespace (min 100px padding around elements)\n3. **Purposeful motion** - Cards appear with subtle spring (0-20px translateY), not fly across screen\n4. **Readable text** - Max 2-3 lines per card, 24px+ font size\n5. **Grid alignment** - Use invisible grid (3-column or 4-column layout)\n6. **Professional entrance** - Elements fade + slight translate (15px max), hold for 2-3s, then exit\n\n### Composition Examples:\n\n**❌ BAD - Wall of Text:**\n\\`\\`\\`tsx\n// DON'T: 10 bullet points crammed in a card\n<Card>\n <ul>\n {[...10items].map(item => <li>{item.longText}...</li>)}\n </ul>\n</Card>\n\\`\\`\\`\n\n**✅ GOOD - Single Focus:**\n\\`\\`\\`tsx\n// DO: One headline, one supporting stat\n<AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center' }}>\n <h1 style={{ fontSize: 72, marginBottom: 40 }}>12 hours wasted</h1>\n <p style={{ fontSize: 28, opacity: 0.7 }}>per week on manual tasks</p>\n</AbsoluteFill>\n\\`\\`\\`\n\n**❌ BAD - Flying Cards:**\n\\`\\`\\`tsx\n// DON'T: Cards flying from random positions\n<Card style={{\n transform: \\`translateX(\\${interpolate(progress, [0,1], [-500, 0])}px)\\` // Flies from left\n}} />\n\\`\\`\\`\n\n**✅ GOOD - Subtle Entrance:**\n\\`\\`\\`tsx\n// DO: Gentle spring entrance with minimal movement\nconst progress = spring({ frame: frame - startFrame, fps, config: { damping: 20, stiffness: 100 }});\n<Card style={{\n opacity: progress,\n transform: \\`translateY(\\${interpolate(progress, [0,1], [15, 0])}px)\\` // Subtle 15px drop\n}} />\n\\`\\`\\`\n\n### Layout Grid System:\n\n**Use 12-column grid (like Bootstrap):**\n\\`\\`\\`tsx\nconst GRID = {\n columns: 12,\n gutter: 40,\n padding: 120 // Edge padding\n};\n\n// Center 6 columns for main content\nconst contentWidth = (1920 - (GRID.padding * 2) - (GRID.gutter * 5)) / 2;\n\\`\\`\\`\n\n**Positioning anchors:**\n- **Top-left:** Brand logo, context (10% from edges)\n- **Center:** Primary headline/stat/demo (50% transform)\n- **Bottom:** CTA or tagline (10% from bottom)\n- **Never:** Random floating between these zones\n\n---\n\n## Prerequisites\n\nBefore using this skill, ensure you have:\n\n1. **Load related skills:**\n \\`\\`\\`\n remotion-best-practices\n threejs-fundamentals\n \\`\\`\\`\n\n2. **Authenticate:**\n \\`\\`\\`bash\n ${cmd} login\n \\`\\`\\`\n\n3. **Remotion installed** (if creating videos):\n \\`\\`\\`bash\n pnpm install remotion @remotion/cli\n \\`\\`\\`\n\n---\n\n## Video Creation Workflow\n\n### Phase 0: Load Skills (MANDATORY)\n\nBefore ANY video work, invoke these skills:\n\\`\\`\\`\nremotion-best-practices\nthreejs-fundamentals\n\\`\\`\\`\n\n### Phase 1: Discovery\n\nExplore current directory silently:\n- Understand what the product does (README, docs, code)\n- Find branding: logo, colors, fonts\n- Find UI components to copy into Remotion (buttons, cards, modals, etc.) — rebuild pixel-perfect, no screenshots\n\n### Phase 2: Video Brief\n\nPresent a brief outline (scenes ≤8s each, duration, assets found) and get user approval before production.\n\n### Phase 3: Production\n\n1. **Generate audio assets** - \\`${cmd} video create\\` with scenes JSON\n - IMPORTANT: Music is generated LAST after all voiceover/audio to ensure exact duration match\n2. **Scaffold OUTSIDE project** - \\`cd .. && ${cmd} video init my-video\\`\n3. **Copy assets + UI components** from project into video project\n4. **Implement** - follow rules below\n\n### Phase 4: Render & Thumbnail (REQUIRED)\n\n\\`\\`\\`bash\n# 1. Render the video (with voiceover and music already included)\npnpm exec remotion render FullVideo\n\n# 2. ALWAYS embed thumbnail before delivering\n${cmd} video thumbnail out/FullVideo.mp4 --frame 60\n\\`\\`\\`\n\n**Note:** Remotion videos include per-scene voiceovers and background music baked in during render.\n\n---\n\n## Asset Generation\n\nGenerate voiceover, music, and visual assets for each scene:\n\n\\`\\`\\`bash\ncat <<SCENES | ${cmd} video create --output ./public\n{\n \"scenes\": [\n { \n \"name\": \"Hook\", \n \"script\": \"Watch how we transformed this complex workflow into a single click.\",\n \"imageQuery\": \"modern dashboard interface dark theme\",\n \"videoQuery\": \"abstract tech particles animation\"\n },\n { \n \"name\": \"Demo\", \n \"script\": \"Our AI analyzes your data in real-time, surfacing insights that matter.\",\n \"imageQuery\": \"data visualization charts analytics\"\n },\n { \n \"name\": \"CTA\", \n \"script\": \"Start your free trial today. No credit card required.\",\n \"imageQuery\": \"call to action button modern\"\n }\n ],\n \"voice\": \"Kore\",\n \"voiceSettings\": {\n \"style\": 0.6,\n \"stability\": 0.4,\n \"speed\": 0.95\n },\n \"musicPrompt\": \"upbeat corporate, positive energy, modern synth\"\n}\nSCENES\n\\`\\`\\`\n\n**Output:**\n- \\`public/audio/Hook.mp3\\` - scene voiceovers\n- \\`public/audio/music.mp3\\` - background music (30s max)\n- \\`public/video-manifest.json\\` - timing and metadata\n- Stock images/videos (if requested)\n\n---\n\n## Core Video Rules\n\n${VIDEO_RULE_CONTENTS.map((rule) => rule.content).join('\\n\\n---\\n\\n')}\n\n## Useful Commands\n\n\\`\\`\\`bash\n# Generate video assets\n${cmd} video create < scenes.json\ncat scenes.json | ${cmd} video create --output ./public\n\n# Initialize Remotion project\n${cmd} video init my-video\n\n# Embed thumbnail\n${cmd} video thumbnail out/video.mp4 --frame 60\n\n# Search for stock assets\n${cmd} images search \"mountain landscape\" --limit 10\n${cmd} videos search \"ocean waves\" --limit 5\n\n# Generate audio\n${cmd} audio generate \"Your script here\" --voice Kore\n${cmd} music generate \"upbeat corporate\" --duration 30\n\\`\\`\\`\n\n---\n\n## Best Practices\n\n1. **Keep scenes under 8 seconds** without cuts or major action\n2. **Use spring physics** for all animations, never linear\n3. **Rebuild UI components** in React/CSS, no screenshots\n4. **Test with thumbnail embedding** before delivering\n5. **Music volume at 30%** (30-40% less loud than voice)\n6. **Read all video rules** in Phase 0 before implementation\n\n---\n\n## Troubleshooting\n\nIf you encounter issues:\n- Check authentication: \\`${cmd} whoami\\`\n- Verify asset generation: check \\`video-manifest.json\\`\n- Voiceover flat: increase style (0.5-0.7), decrease stability (0.3-0.5)\n- Duration mismatch: adjust \\`voiceSettings.speed\\` or add padding in Remotion\n\nFor detailed troubleshooting, see \"Known Issues\" section above.\n`;\n}\n","/**\n * Presentation Skill Content Generator\n * Generates skill.md for presentation generation\n */\n\nimport type { SkillContext } from \"./types.js\";\n\nexport function generatePresentationSkillContent(context: SkillContext): string {\n const { name, cmd, displayName } = context;\n\n return `---\nname: ${name}-presentation\ndescription: Use when user asks to create presentations (slides, decks, pitch decks). Generates AI-powered presentations with structured content and professional design.\n---\n\n# ${displayName} Presentation CLI\n\nCreate professional presentations (slides, decks, pitch decks) directly from your terminal. The CLI generates AI-powered slides from any context you provide - text, files, URLs, or piped content. Also supports searching for stock images and videos.\n\n---\n\n## Authentication\n\n\\`\\`\\`bash\n# Login via OAuth\n${cmd} login\n\n# Or set API key\nexport ${name.toUpperCase().replace(/-/g, '_')}_API_KEY=\"your-key-here\"\n\\`\\`\\`\n\n---\n\n## Creating Presentations\n\n### From Text\n\n\\`\\`\\`bash\n${cmd} create \"AI-powered product analytics platform\"\n\\`\\`\\`\n\n### From File\n\n\\`\\`\\`bash\n${cmd} create --file product-brief.md\n\\`\\`\\`\n\n### From URL\n\n\\`\\`\\`bash\n${cmd} create --url https://company.com/product\n\\`\\`\\`\n\n### From Piped Content\n\n\\`\\`\\`bash\ncat research.txt | ${cmd} create\npbpaste | ${cmd} create\n\\`\\`\\`\n\n### Advanced Options\n\n\\`\\`\\`bash\n${cmd} create \"Topic\" \\\\\n --slides 10 \\\\\n --style professional \\\\\n --branding my-brand \\\\\n --template minimal \\\\\n --output presentation.zip\n\\`\\`\\`\n\n---\n\n## Presentation Options\n\n- **\\`--slides <count>\\`** - Number of slides (default: 8-12 based on content)\n- **\\`--style <style>\\`** - Presentation style: professional, creative, minimal, corporate\n- **\\`--branding <name>\\`** - Use saved branding profile\n- **\\`--template <name>\\`** - Design template to use\n- **\\`--output <file>\\`** - Export to file (.zip, .pptx, .pdf)\n- **\\`--format <format>\\`** - Output format: human, json, quiet\n\n---\n\n## Managing Presentations\n\n\\`\\`\\`bash\n# List all presentations\n${cmd} list\n${cmd} list --format json\n\n# Get presentation details\n${cmd} get <id-or-slug>\n\n# Export presentation\n${cmd} export <id-or-slug> -o presentation.zip\n\n# Import presentation\n${cmd} import ./presentation.zip\n\n# Delete presentation\n${cmd} delete <id-or-slug>\n\\`\\`\\`\n\n---\n\n## Branding Management\n\n\\`\\`\\`bash\n# List saved brands\n${cmd} branding list\n\n# Extract branding from website\n${cmd} branding extract https://company.com\n\n# Use branding in presentation\n${cmd} create \"Topic\" --branding company-brand\n\\`\\`\\`\n\n---\n\n## Stock Asset Search\n\n\\`\\`\\`bash\n# Search for images\n${cmd} images search \"mountain landscape\" --limit 10\n${cmd} images search \"business team\" --format json\n\n# Search for videos\n${cmd} videos search \"ocean waves\" --limit 5\n${cmd} videos search \"city timelapse\" --orientation landscape\n\\`\\`\\`\n\n---\n\n## Best Practices\n\n1. **Provide context** - More input = better presentations\n2. **Use branding** - Extract and apply brand consistency\n3. **Review content** - AI-generated content should be reviewed\n4. **Export for sharing** - Use \\`--output\\` to create shareable files\n5. **Iterate** - Regenerate specific slides if needed\n\n---\n\n## Troubleshooting\n\n**Authentication Issues:**\n\\`\\`\\`bash\n# Check current user\n${cmd} whoami\n\n# Re-authenticate\n${cmd} logout\n${cmd} login\n\\`\\`\\`\n\n**Generation Failures:**\n- Ensure input is clear and has enough context\n- Try different styles or templates\n- Check API status and quotas\n\n**Export Issues:**\n- Verify output format is supported\n- Check file permissions in output directory\n- Ensure presentation ID is correct\n\n---\n\n## Examples\n\n**Quick pitch deck:**\n\\`\\`\\`bash\n${cmd} create \"SaaS analytics platform for e-commerce\" --slides 8 --style professional\n\\`\\`\\`\n\n**From product brief:**\n\\`\\`\\`bash\n${cmd} create --file brief.md --branding acme --output pitch.zip\n\\`\\`\\`\n\n**Research presentation:**\n\\`\\`\\`bash\ncat research-notes.txt | ${cmd} create --slides 15 --style minimal\n\\`\\`\\`\n`;\n}\n","/**\n * Skill installation utilities\n */\n\nimport { mkdirSync, writeFileSync, existsSync, rmSync } from \"fs\";\nimport { join, resolve, relative } from \"path\";\nimport { homedir } from \"os\";\nimport { SUPPORTED_EDITORS, type EditorConfig } from \"./editors.js\";\n\n/**\n * Validate that a path doesn't escape the base directory (prevent path traversal)\n * @throws Error if path would escape base directory\n */\nfunction validatePath(basePath: string, targetPath: string): string {\n const resolvedBase = resolve(basePath);\n const resolvedTarget = resolve(basePath, targetPath);\n const relativePath = relative(resolvedBase, resolvedTarget);\n\n // Check if the resolved path escapes the base directory\n if (relativePath.startsWith(\"..\") || resolve(resolvedTarget) !== resolvedTarget.replace(/\\.\\./g, \"\")) {\n throw new Error(`Invalid path: \"${targetPath}\" would escape base directory`);\n }\n\n return resolvedTarget;\n}\n\nexport interface InstallResult {\n installed: string[];\n skipped: string[];\n errors: string[];\n}\n\nexport interface InstallOptions {\n /** Install to specific directory */\n dir?: string;\n /** Install locally (current directory) instead of globally */\n local?: boolean;\n /** Overwrite existing skill files */\n force?: boolean;\n}\n\n/**\n * Install skill file to a specific path (single skill.md file, no subdirectories)\n */\nexport function installSkillToPath(skillPath: string, content: string): void {\n const skillFile = join(skillPath, \"SKILL.md\");\n\n // Create directory\n mkdirSync(skillPath, { recursive: true });\n\n // Write skill file\n writeFileSync(skillFile, content, \"utf-8\");\n}\n\n/**\n * Install skill to all detected editors or a specific directory\n */\nexport function installSkill(\n skillName: string,\n content: string,\n options: InstallOptions = {}\n): InstallResult {\n const result: InstallResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const baseDir = options.local ? process.cwd() : homedir();\n\n if (options.dir) {\n // Install to specific directory with path validation\n try {\n const resolvedDir = resolve(options.dir);\n const skillPath = validatePath(resolvedDir, join(\"skills\", skillName));\n installSkillToPath(skillPath, content);\n result.installed.push(options.dir);\n } catch (err) {\n result.errors.push(`${options.dir}: ${err instanceof Error ? err.message : String(err)}`);\n }\n } else {\n // Auto-detect and install to all supported editors\n for (const editor of SUPPORTED_EDITORS) {\n const editorDir = join(baseDir, editor.dir);\n const skillPath = join(editorDir, \"skills\", skillName);\n const skillFile = join(skillPath, \"SKILL.md\");\n\n // Check if editor directory exists (editor is installed)\n if (!existsSync(editorDir)) {\n continue;\n }\n\n // Check if skill already exists\n if (existsSync(skillFile) && !options.force) {\n result.skipped.push(editor.name);\n continue;\n }\n\n try {\n installSkillToPath(skillPath, content);\n result.installed.push(editor.name);\n } catch (err) {\n result.errors.push(`${editor.name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n }\n\n return result;\n}\n\nexport interface UninstallResult {\n removed: string[];\n errors: string[];\n}\n\n/**\n * Uninstall skill from all detected editors\n */\nexport function uninstallSkill(\n skillName: string,\n options: { local?: boolean } = {}\n): UninstallResult {\n const result: UninstallResult = {\n removed: [],\n errors: [],\n };\n const baseDir = options.local ? process.cwd() : homedir();\n\n for (const editor of SUPPORTED_EDITORS) {\n const skillPath = join(baseDir, editor.dir, \"skills\", skillName);\n if (existsSync(skillPath)) {\n try {\n rmSync(skillPath, { recursive: true });\n result.removed.push(editor.name);\n } catch (err) {\n result.errors.push(`${editor.name}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get list of supported editor names\n */\nexport function getSupportedEditorNames(): string[] {\n return SUPPORTED_EDITORS.map((e) => e.name);\n}\n","/**\n * Supported AI coding editors/assistants configuration\n */\n\nexport interface EditorConfig {\n /** Display name of the editor */\n name: string;\n /** Directory name in home folder (e.g., \".claude\") */\n dir: string;\n}\n\n/**\n * List of supported AI coding assistants\n * Each entry defines where skills should be installed\n */\nexport const SUPPORTED_EDITORS: EditorConfig[] = [\n { name: \"Claude Code\", dir: \".claude\" },\n { name: \"Cursor\", dir: \".cursor\" },\n { name: \"Codex\", dir: \".codex\" },\n { name: \"OpenCode\", dir: \".opencode\" },\n { name: \"Windsurf\", dir: \".windsurf\" },\n { name: \"Agent\", dir: \".agent\" },\n];\n","/**\n * TTS (Text-to-Speech) Command\n * Generate speech from text and list available voices\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { generateSpeech, getVoices } from \"../lib/api.js\";\nimport { success, error, info, printJson } from \"../lib/output.js\";\nimport type { OutputFormat, TTSProvider } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface GenerateOptions {\n text: string;\n voice?: string;\n provider?: string;\n model?: string;\n speed?: string;\n output: string;\n format: OutputFormat;\n}\n\nconst generateCommand = new Command(\"generate\")\n .description(\"Generate speech from text\")\n .requiredOption(\"-t, --text <text>\", \"Text to convert to speech\")\n .requiredOption(\"-o, --output <path>\", \"Output file path\")\n .option(\"-v, --voice <voice>\", \"Voice name or ID (e.g., Kore, Rachel, alloy)\")\n .option(\"-p, --provider <provider>\", \"Provider: gemini, elevenlabs, openai\")\n .option(\"-m, --model <model>\", \"Model (provider-specific)\")\n .option(\"-s, --speed <speed>\", \"Speech speed 0.25-4.0 (default: 1.0)\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: GenerateOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Generating speech...\").start() : null;\n\n // Parse speed if provided\n let speed: number | undefined;\n if (options.speed) {\n speed = parseFloat(options.speed);\n if (isNaN(speed) || speed < 0.25 || speed > 4) {\n spinner?.stop();\n error(\"Speed must be between 0.25 and 4.0\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n try {\n const result = await generateSpeech({\n text: options.text,\n options: {\n provider: options.provider as TTSProvider | undefined,\n voice: options.voice,\n model: options.model,\n speed,\n },\n });\n\n spinner?.stop();\n\n // Save audio file\n const outputPath = options.output.endsWith(`.${result.format}`)\n ? options.output\n : `${options.output}.${result.format}`;\n\n await writeFile(outputPath, result.audioData);\n\n if (format === \"json\") {\n printJson({\n status: \"completed\",\n output: outputPath,\n duration: result.duration,\n cost: result.cost,\n provider: result.provider,\n format: result.format,\n });\n return;\n }\n\n if (format === \"quiet\") {\n console.log(outputPath);\n return;\n }\n\n // Human format\n success(`Saved to: ${outputPath}`);\n info(`Duration: ${result.duration.toFixed(2)}s`);\n info(`Provider: ${result.provider}`);\n info(`Cost: $${result.cost.toFixed(6)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst voicesCommand = new Command(\"voices\")\n .description(\"List available voices\")\n .option(\"-p, --provider <provider>\", \"Filter by provider: gemini, elevenlabs, openai\")\n .option(\"-f, --format <format>\", \"Output format: human, json\", \"human\")\n .action(async (options: { provider?: string; format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Fetching voices...\").start() : null;\n\n try {\n const result = await getVoices();\n spinner?.stop();\n\n if (options.format === \"json\") {\n if (options.provider) {\n const providerVoices = result.voices[options.provider as keyof typeof result.voices];\n printJson(providerVoices || []);\n } else {\n printJson(result.voices);\n }\n return;\n }\n\n // Human format\n const providers = options.provider\n ? [options.provider]\n : [\"gemini\", \"elevenlabs\", \"openai\"];\n\n for (const provider of providers) {\n const voices = result.voices[provider as keyof typeof result.voices];\n if (!voices || voices.length === 0) continue;\n\n console.log();\n console.log(`${provider.toUpperCase()} Voices:`);\n console.log(\"-\".repeat(50));\n\n for (const voice of voices) {\n console.log(` ${voice.name} (${voice.id})`);\n console.log(` ${voice.description}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const ttsCommand = new Command(\"tts\")\n .description(\"Text-to-speech commands\")\n .addCommand(generateCommand)\n .addCommand(voicesCommand);\n","/**\n * Music Generation Command\n * Generate music from text prompts and check status\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { generateMusic, checkMusicStatus, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn } from \"../lib/output.js\";\nimport type { MusicGenerationResult, OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface GenerateOptions {\n prompt: string;\n duration: string;\n style?: string;\n provider?: string;\n output?: string;\n wait: boolean;\n format: OutputFormat;\n}\n\nfunction outputResult(result: MusicGenerationResult, format: OutputFormat): void {\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n if (result.audioUrl) {\n console.log(result.audioUrl);\n } else {\n console.log(result.requestId);\n }\n return;\n }\n\n // Human format\n info(`Request ID: ${result.requestId}`);\n info(`Status: ${result.status}`);\n if (result.duration) {\n info(`Duration: ${result.duration}s`);\n }\n if (result.audioUrl) {\n success(`Audio URL: ${result.audioUrl}`);\n }\n if (result.cost !== undefined) {\n info(`Cost: $${result.cost.toFixed(4)}`);\n }\n if (result.error) {\n error(`Error: ${result.error}`);\n }\n}\n\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n // Handle data URLs (base64 encoded)\n if (url.startsWith(\"data:\")) {\n const matches = url.match(/^data:[^;]+;base64,(.+)$/);\n if (!matches) {\n throw new Error(\"Invalid data URL format\");\n }\n const buffer = Buffer.from(matches[1], \"base64\");\n await writeFile(outputPath, buffer);\n return;\n }\n\n // Handle regular URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\nconst generateCommand = new Command(\"generate\")\n .description(\"Generate music from a text prompt\")\n .requiredOption(\"-p, --prompt <text>\", \"Music description\")\n .option(\"-d, --duration <seconds>\", \"Duration in seconds (3-30)\", \"30\")\n .option(\"-s, --style <style>\", \"Style preset\")\n .option(\"--provider <provider>\", \"Provider (elevenlabs, suno)\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--no-wait\", \"Do not wait for completion\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: GenerateOptions) => {\n const duration = parseInt(options.duration, 10);\n if (isNaN(duration) || duration < 3 || duration > 30) {\n error(\"Duration must be between 3 and 30 seconds\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Generating music...\").start() : null;\n\n try {\n const result = await generateMusic({\n prompt: options.prompt,\n duration,\n options: {\n provider: options.provider,\n style: options.style,\n },\n });\n\n if (!options.wait) {\n spinner?.stop();\n outputResult(result, format);\n return;\n }\n\n // Skip polling if already completed\n let finalResult = result;\n if (result.status !== \"completed\" && result.status !== \"failed\") {\n if (spinner) spinner.text = `Processing (ID: ${result.requestId})...`;\n\n finalResult = await pollForCompletion(\n () => checkMusicStatus(result.requestId),\n 60,\n 2000\n );\n }\n\n spinner?.stop();\n\n if (finalResult.status === \"failed\") {\n error(finalResult.error || \"Music generation failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n outputResult(finalResult, format);\n\n // Download if output path specified\n if (options.output && finalResult.audioUrl) {\n const downloadSpinner = format === \"human\" ? ora(\"Downloading...\").start() : null;\n try {\n await downloadFile(finalResult.audioUrl, options.output);\n downloadSpinner?.stop();\n if (format === \"human\") {\n success(`Saved to: ${options.output}`);\n }\n } catch (err) {\n downloadSpinner?.stop();\n warn(`Failed to download: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst statusCommand = new Command(\"status\")\n .description(\"Check status of a music generation request\")\n .argument(\"<id>\", \"Request ID\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (id: string, options: { format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Checking status...\").start() : null;\n\n try {\n const result = await checkMusicStatus(id);\n spinner?.stop();\n outputResult(result, options.format);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const musicCommand = new Command(\"music\")\n .description(\"Music generation commands\")\n .addCommand(generateCommand)\n .addCommand(statusCommand);\n","/**\n * Audio Mix Command\n * Mix audio tracks into video\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { writeFile } from \"fs/promises\";\nimport { mixAudio, checkMixStatus, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn } from \"../lib/output.js\";\nimport type { AudioMixResult, AudioInput, OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface MixOptions {\n video: string;\n music?: string;\n voice?: string;\n musicVolume: string;\n voiceVolume: string;\n output?: string;\n wait: boolean;\n format: OutputFormat;\n}\n\nfunction outputResult(result: AudioMixResult, format: OutputFormat): void {\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n if (result.outputUrl) {\n console.log(result.outputUrl);\n } else {\n console.log(result.requestId);\n }\n return;\n }\n\n // Human format\n info(`Request ID: ${result.requestId}`);\n info(`Status: ${result.status}`);\n if (result.duration) {\n info(`Duration: ${result.duration}s`);\n }\n if (result.outputUrl) {\n success(`Output URL: ${result.outputUrl}`);\n }\n if (result.cost !== undefined) {\n info(`Cost: $${result.cost.toFixed(4)}`);\n }\n if (result.error) {\n error(`Error: ${result.error}`);\n }\n}\n\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\nconst mixCommand = new Command(\"create\")\n .description(\"Mix audio tracks into a video (music will loop to match video duration)\")\n .requiredOption(\"--video <url>\", \"Input video file/URL\")\n .option(\"--music <url>\", \"Background music file/URL (will loop if shorter than video)\")\n .option(\"--voice <url>\", \"Voiceover file/URL\")\n .option(\"--music-volume <percent>\", \"Music volume 0-100 (default: 30, recommended for mix with voice)\", \"30\")\n .option(\"--voice-volume <percent>\", \"Voice volume 0-100\", \"100\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--no-wait\", \"Do not wait for completion\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: MixOptions) => {\n if (!options.music && !options.voice) {\n error(\"At least one of --music or --voice must be provided\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const musicVolume = parseInt(options.musicVolume, 10) / 100;\n const voiceVolume = parseInt(options.voiceVolume, 10) / 100;\n\n if (isNaN(musicVolume) || musicVolume < 0 || musicVolume > 1) {\n error(\"Music volume must be between 0 and 100\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n if (isNaN(voiceVolume) || voiceVolume < 0 || voiceVolume > 2) {\n error(\"Voice volume must be between 0 and 200\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Mixing audio...\").start() : null;\n\n const inputs: AudioInput[] = [{ url: options.video, role: \"video\" }];\n\n if (options.music) {\n inputs.push({ url: options.music, role: \"background\", volume: musicVolume * 5 });\n }\n\n if (options.voice) {\n inputs.push({ url: options.voice, role: \"voice\", volume: voiceVolume * 2 });\n }\n\n try {\n const result = await mixAudio({\n operation: \"add-to-video\",\n inputs,\n options: {\n musicVolume,\n voiceVolume,\n },\n });\n\n if (!options.wait) {\n spinner?.stop();\n outputResult(result, format);\n return;\n }\n\n if (spinner) spinner.text = `Processing (ID: ${result.requestId})...`;\n\n const finalResult = await pollForCompletion(\n () => checkMixStatus(result.requestId),\n 120,\n 3000\n );\n\n spinner?.stop();\n\n if (finalResult.status === \"failed\") {\n error(finalResult.error || \"Audio mixing failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n outputResult(finalResult, format);\n\n // Download if output path specified\n if (options.output && finalResult.outputUrl) {\n const downloadSpinner = format === \"human\" ? ora(\"Downloading...\").start() : null;\n try {\n await downloadFile(finalResult.outputUrl, options.output);\n downloadSpinner?.stop();\n if (format === \"human\") {\n success(`Saved to: ${options.output}`);\n }\n } catch (err) {\n downloadSpinner?.stop();\n warn(`Failed to download: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nconst statusCommand = new Command(\"status\")\n .description(\"Check status of an audio mix request\")\n .argument(\"<id>\", \"Request ID\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (id: string, options: { format: OutputFormat }) => {\n const spinner = options.format === \"human\" ? ora(\"Checking status...\").start() : null;\n\n try {\n const result = await checkMixStatus(id);\n spinner?.stop();\n outputResult(result, options.format);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const mixAudioCommand = new Command(\"mix\")\n .description(\"Audio mixing commands\")\n .addCommand(mixCommand)\n .addCommand(statusCommand);\n","/**\n * Image Search Command\n * Search for images using various providers\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { searchImages } from \"../lib/api.js\";\nimport { success, error, info, printJson } from \"../lib/output.js\";\nimport type { OutputFormat } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\ninterface SearchOptions {\n query: string;\n maxResults?: string;\n size?: string;\n safeSearch?: boolean;\n format: OutputFormat;\n}\n\nconst searchCommand = new Command(\"search\")\n .description(\"Search for images\")\n .requiredOption(\"-q, --query <query>\", \"Search query\")\n .option(\"-n, --max-results <number>\", \"Maximum number of results (default: 10)\")\n .option(\"-s, --size <size>\", \"Image size: small, medium, large, any\", \"large\")\n .option(\"--safe-search\", \"Enable safe search (default: true)\", true)\n .option(\"--no-safe-search\", \"Disable safe search\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: SearchOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Searching for images...\").start() : null;\n\n // Parse max results\n let maxResults: number | undefined;\n if (options.maxResults) {\n maxResults = parseInt(options.maxResults, 10);\n if (isNaN(maxResults) || maxResults < 1) {\n spinner?.stop();\n error(\"Max results must be a positive number\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n try {\n const result = await searchImages({\n query: options.query,\n options: {\n maxResults: maxResults || 10,\n size: options.size as \"small\" | \"medium\" | \"large\" | \"any\",\n safeSearch: options.safeSearch,\n },\n });\n\n spinner?.stop();\n\n if (!result.success) {\n error(\"Search failed\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n // Flatten results from all providers\n const allImages = result.data.results.flatMap((providerResult) =>\n providerResult.results.map((img) => ({\n ...img,\n provider: providerResult.providerName,\n }))\n );\n\n if (format === \"json\") {\n printJson({\n success: true,\n query: options.query,\n totalResults: allImages.length,\n totalCost: result.data.totalCost,\n images: allImages,\n });\n return;\n }\n\n if (format === \"quiet\") {\n // Just print URLs\n for (const img of allImages) {\n console.log(img.url);\n }\n return;\n }\n\n // Human format\n if (allImages.length === 0) {\n info(\"No images found\");\n return;\n }\n\n success(`Found ${allImages.length} images for \"${options.query}\"`);\n console.log();\n\n for (let i = 0; i < allImages.length; i++) {\n const img = allImages[i];\n console.log(`[${i + 1}] ${img.title || \"Untitled\"}`);\n console.log(` URL: ${img.url}`);\n console.log(` Size: ${img.width}x${img.height}`);\n if (img.author) {\n console.log(` Author: ${img.author}`);\n }\n console.log(` Provider: ${img.provider}`);\n console.log();\n }\n\n info(`Total cost: $${result.data.totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const imageCommand = new Command(\"image\")\n .description(\"Image search commands\")\n .addCommand(searchCommand);\n","/**\n * Video Command\n * Create video assets (voiceover, music, images) in one command\n */\n\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { mkdir, writeFile, readFile, access, rm, cp } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { execSync, spawn } from \"child_process\";\nimport ffmpegPath from \"ffmpeg-static\";\nimport { generateSpeech, generateMusic, checkMusicStatus, searchImages, searchVideos, pollForCompletion } from \"../lib/api.js\";\nimport { success, error, info, printJson, warn, keyValue } from \"../lib/output.js\";\nimport type { OutputFormat, TTSTimestamps } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\n// Default GitHub template for video projects\nconst DEFAULT_TEMPLATE = \"inizio-inc/remotion-composition\";\n\n// Default FPS for video generation\nconst DEFAULT_FPS = 30;\n\n/**\n * Parse script into sections based on sentence boundaries\n * Each sentence becomes its own section for granular scene control\n * Only very short sentences (< 5 words) get grouped together\n */\nfunction parseScriptIntoSections(script: string): string[] {\n // Split by explicit section markers first\n if (script.includes(\"---\") || script.includes(\"[Section\")) {\n const parts = script.split(/---|\\[Section \\d+\\]/i).filter(s => s.trim());\n if (parts.length > 1) {\n return parts.map(p => p.trim());\n }\n }\n\n // Split by sentences - each sentence is its own section\n const sentences = script\n .split(/(?<=[.!?])\\s+/)\n .map(s => s.trim())\n .filter(s => s.length > 0);\n\n // Only group VERY short sentences (< 5 words) with the next one\n const sections: string[] = [];\n let pendingShort = \"\";\n\n for (const sentence of sentences) {\n const wordCount = sentence.split(/\\s+/).length;\n\n if (pendingShort) {\n // Combine with previous short sentence\n sections.push(`${pendingShort} ${sentence}`);\n pendingShort = \"\";\n } else if (wordCount < 5 && sections.length < sentences.length - 1) {\n // Very short sentence - hold it to combine with next\n pendingShort = sentence;\n } else {\n // Normal sentence - its own section\n sections.push(sentence);\n }\n }\n\n // Don't forget pending short sentence\n if (pendingShort) {\n if (sections.length > 0) {\n // Append to last section\n sections[sections.length - 1] += ` ${pendingShort}`;\n } else {\n sections.push(pendingShort);\n }\n }\n\n return sections;\n}\n\n/**\n * Calculate section timing using TTS timestamps for exact audio sync\n * Falls back to word-proportion estimation if timestamps not available\n */\nfunction calculateSectionTiming(\n sections: string[],\n totalDuration: number,\n fps: number = DEFAULT_FPS,\n timestamps?: TTSTimestamps\n): SceneSection[] {\n // If we have timestamps, use them for exact timing\n if (timestamps && timestamps.characters.length > 0) {\n return calculateSectionTimingFromTimestamps(sections, timestamps, fps);\n }\n\n // Fallback: estimate based on word proportions\n const totalWords = sections.reduce((sum, s) => sum + s.split(/\\s+/).length, 0);\n \n let currentTime = 0;\n return sections.map((text, index) => {\n const wordCount = text.split(/\\s+/).length;\n const proportion = wordCount / totalWords;\n const durationInSeconds = totalDuration * proportion;\n const durationInFrames = Math.round(durationInSeconds * fps);\n \n const section: SceneSection = {\n id: index + 1,\n text,\n wordCount,\n startTime: currentTime,\n endTime: currentTime + durationInSeconds,\n durationInSeconds,\n durationInFrames,\n };\n \n currentTime += durationInSeconds;\n return section;\n });\n}\n\n/**\n * Calculate section timing from TTS character-level timestamps\n * Finds the exact start/end time for each section based on where its text appears in audio\n */\nfunction calculateSectionTimingFromTimestamps(\n sections: string[],\n timestamps: TTSTimestamps,\n fps: number\n): SceneSection[] {\n const { characters, characterStartTimesSeconds, characterEndTimesSeconds } = timestamps;\n const fullText = characters.join(\"\");\n \n const results: SceneSection[] = [];\n let charIndex = 0;\n\n for (let i = 0; i < sections.length; i++) {\n const sectionText = sections[i];\n const sectionLength = sectionText.length;\n \n // Find where this section starts in the character array\n // Skip whitespace between sections\n while (charIndex < characters.length && characters[charIndex].match(/^\\s*$/)) {\n charIndex++;\n }\n \n const startCharIndex = charIndex;\n const startTime = characterStartTimesSeconds[startCharIndex] || 0;\n \n // Move to end of this section\n charIndex += sectionLength;\n \n // Skip trailing whitespace to find the actual end\n let endCharIndex = charIndex - 1;\n while (endCharIndex > startCharIndex && characters[endCharIndex]?.match(/^\\s*$/)) {\n endCharIndex--;\n }\n \n const endTime = characterEndTimesSeconds[Math.min(endCharIndex, characterEndTimesSeconds.length - 1)] || startTime + 1;\n \n const durationInSeconds = endTime - startTime;\n const durationInFrames = Math.round(durationInSeconds * fps);\n \n results.push({\n id: i + 1,\n text: sectionText,\n wordCount: sectionText.split(/\\s+/).length,\n startTime,\n endTime,\n durationInSeconds,\n durationInFrames,\n });\n }\n\n return results;\n}\n\ninterface CreateOptions {\n script?: string;\n scriptFile?: string;\n topic?: string;\n duration?: string;\n voice: string;\n musicPrompt?: string;\n numImages: string;\n output: string;\n format: OutputFormat;\n}\n\ninterface SceneInput {\n name: string;\n script: string;\n imageQuery?: string;\n videoQuery?: string;\n}\n\ninterface VoiceSettings {\n speed?: number;\n stability?: number;\n similarity?: number;\n style?: number;\n}\n\ninterface ScenesInput {\n scenes: SceneInput[];\n voice?: string;\n musicPrompt?: string;\n voiceSettings?: VoiceSettings;\n}\n\n/**\n * Read stdin if available (for piped JSON input)\n */\nasync function readStdin(): Promise<string | null> {\n if (process.stdin.isTTY) {\n return null;\n }\n\n return new Promise((resolve) => {\n let data = \"\";\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => { data += chunk; });\n process.stdin.on(\"end\", () => resolve(data.trim() || null));\n process.stdin.on(\"error\", () => resolve(null));\n\n // Timeout after 100ms if no data (not piped)\n setTimeout(() => {\n if (!data) resolve(null);\n }, 100);\n });\n}\n\n/**\n * Convert scene name to filename (kebab-case)\n */\nfunction toFilename(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\ninterface VoiceoverInfo {\n path: string;\n duration: number;\n voice: string;\n provider: string;\n cost: number;\n timestamps?: TTSTimestamps; // Character-level timing for word-by-word sync\n}\n\ninterface MusicInfo {\n path: string;\n duration: number;\n prompt: string;\n cost: number;\n}\n\ninterface ImageInfo {\n path: string;\n url: string;\n width: number;\n height: number;\n query: string;\n}\n\ninterface StockVideoInfo {\n path: string;\n url: string;\n width: number;\n height: number;\n duration: number;\n query: string;\n}\n\ninterface SceneSection {\n id: number;\n name: string;\n text: string;\n wordCount: number;\n startTime: number;\n endTime: number;\n durationInSeconds: number;\n durationInFrames: number; // at 30fps\n audioPath?: string;\n imagePath?: string;\n videoPath?: string;\n}\n\ninterface VideoManifest {\n music: MusicInfo;\n images: ImageInfo[];\n videos: StockVideoInfo[];\n scenes: SceneSection[];\n totalDurationInFrames: number;\n fps: number;\n totalCost: number;\n createdAt: string;\n}\n\n/**\n * Download a file from URL to local path\n * Handles both regular URLs and data URLs (base64)\n */\nasync function downloadFile(url: string, outputPath: string): Promise<void> {\n // Handle data URLs (base64 encoded)\n if (url.startsWith(\"data:\")) {\n const matches = url.match(/^data:[^;]+;base64,(.+)$/);\n if (!matches) {\n throw new Error(\"Invalid data URL format\");\n }\n const buffer = Buffer.from(matches[1], \"base64\");\n await writeFile(outputPath, buffer);\n return;\n }\n\n // Handle regular URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n await writeFile(outputPath, Buffer.from(buffer));\n}\n\n/**\n * Get file extension from URL\n */\nfunction getExtension(url: string): string {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const ext = pathname.split(\".\").pop()?.toLowerCase();\n if (ext && [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\"].includes(ext)) {\n return ext;\n }\n } catch {\n // Ignore URL parsing errors\n }\n return \"jpg\"; // Default to jpg\n}\n\nconst createCommand = new Command(\"create\")\n .description(\"Create video assets (voiceover per scene, music, images)\")\n .option(\"-s, --script <text>\", \"Narration script (legacy single-script mode)\")\n .option(\"--script-file <path>\", \"Path to script file (legacy) or scenes JSON\")\n .option(\"-t, --topic <text>\", \"Topic for image search\")\n .option(\"-v, --voice <name>\", \"TTS voice (Kore, Puck, Rachel, alloy)\", \"Kore\")\n .option(\"-m, --music-prompt <text>\", \"Music description\")\n .option(\"-n, --num-images <number>\", \"Number of images to search/download\", \"5\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./public\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (options: CreateOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Initializing...\").start() : null;\n\n try {\n // Check for stdin JSON (piped scenes)\n const stdinData = await readStdin();\n let scenesInput: ScenesInput | null = null;\n\n if (stdinData) {\n try {\n const parsed = JSON.parse(stdinData);\n if (parsed.scenes && Array.isArray(parsed.scenes)) {\n scenesInput = parsed as ScenesInput;\n }\n } catch {\n // Not valid JSON, ignore\n }\n }\n\n // Also check if script-file is a JSON with scenes\n if (!scenesInput && options.scriptFile) {\n try {\n const fileContent = await readFile(options.scriptFile, \"utf-8\");\n const parsed = JSON.parse(fileContent);\n if (parsed.scenes && Array.isArray(parsed.scenes)) {\n scenesInput = parsed as ScenesInput;\n }\n } catch {\n // Not JSON or no scenes array, will handle as legacy\n }\n }\n\n // Determine mode and settings\n const voice = scenesInput?.voice || options.voice;\n const musicPrompt = scenesInput?.musicPrompt || options.musicPrompt || \"uplifting background music, positive energy\";\n\n // Create directories\n const audioDir = join(options.output, \"audio\");\n const imagesDir = join(options.output, \"images\");\n const videosDir = join(options.output, \"videos\");\n\n if (spinner) spinner.text = \"Creating directories...\";\n await mkdir(audioDir, { recursive: true });\n await mkdir(imagesDir, { recursive: true });\n await mkdir(videosDir, { recursive: true });\n\n let totalCost = 0;\n let scenes: SceneSection[] = [];\n let totalDuration = 0;\n const allImages: ImageInfo[] = [];\n const allVideos: StockVideoInfo[] = [];\n\n if (scenesInput && scenesInput.scenes.length > 0) {\n // === PER-SCENE MODE ===\n if (format === \"human\") {\n spinner?.stop();\n info(`Processing ${scenesInput.scenes.length} scenes...`);\n spinner?.start();\n }\n\n let currentTime = 0;\n\n for (let i = 0; i < scenesInput.scenes.length; i++) {\n const scene = scenesInput.scenes[i];\n const filename = toFilename(scene.name);\n\n // Generate TTS\n if (spinner) spinner.text = `[${scene.name}] Generating speech...`;\n\n const ttsResult = await generateSpeech({\n text: scene.script,\n options: {\n voice,\n voiceSettings: scenesInput.voiceSettings,\n },\n });\n\n const audioPath = join(audioDir, `${filename}.${ttsResult.format}`);\n await writeFile(audioPath, ttsResult.audioData);\n totalCost += ttsResult.cost;\n\n const durationInSeconds = ttsResult.duration;\n const durationInFrames = Math.round(durationInSeconds * DEFAULT_FPS);\n\n const sceneData: SceneSection = {\n id: i + 1,\n name: scene.name,\n text: scene.script,\n wordCount: scene.script.split(/\\s+/).length,\n startTime: currentTime,\n endTime: currentTime + durationInSeconds,\n durationInSeconds,\n durationInFrames,\n audioPath: `audio/${filename}.${ttsResult.format}`,\n };\n\n // Fetch image if query provided\n if (scene.imageQuery) {\n if (spinner) spinner.text = `[${scene.name}] Searching image...`;\n try {\n const imageResults = await searchImages({\n query: scene.imageQuery,\n options: { maxResults: 1, size: \"large\", safeSearch: true },\n });\n const imgs = imageResults.data.results.flatMap((r) => r.results);\n totalCost += imageResults.data.totalCost;\n\n if (imgs.length > 0) {\n const img = imgs[0];\n const ext = getExtension(img.url);\n const imgFilename = `${filename}.${ext}`;\n const imgPath = join(imagesDir, imgFilename);\n\n await downloadFile(img.url, imgPath);\n sceneData.imagePath = `images/${imgFilename}`;\n allImages.push({\n path: `images/${imgFilename}`,\n url: img.url,\n width: img.width,\n height: img.height,\n query: scene.imageQuery,\n });\n }\n } catch (err) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`[${scene.name}] Image search failed: ${err instanceof Error ? err.message : \"Unknown\"}`);\n spinner?.start();\n }\n }\n }\n\n // Fetch video if query provided\n if (scene.videoQuery) {\n if (spinner) spinner.text = `[${scene.name}] Searching video...`;\n try {\n const videoResults = await searchVideos({\n query: scene.videoQuery,\n options: { maxResults: 1, license: \"free\" },\n });\n const vids = videoResults.data.results.flatMap((r) => r.results);\n totalCost += videoResults.data.totalCost;\n\n if (vids.length > 0) {\n const vid = vids[0];\n const vidUrl = vid.previewUrl || vid.downloadUrl;\n if (vidUrl) {\n const vidFilename = `${filename}.mp4`;\n const vidPath = join(videosDir, vidFilename);\n\n await downloadFile(vidUrl, vidPath);\n sceneData.videoPath = `videos/${vidFilename}`;\n allVideos.push({\n path: `videos/${vidFilename}`,\n url: vidUrl,\n width: vid.width,\n height: vid.height,\n duration: vid.duration,\n query: scene.videoQuery,\n });\n }\n }\n } catch (err) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`[${scene.name}] Video search failed: ${err instanceof Error ? err.message : \"Unknown\"}`);\n spinner?.start();\n }\n }\n }\n\n scenes.push(sceneData);\n currentTime += durationInSeconds;\n totalDuration += durationInSeconds;\n\n if (format === \"human\") {\n spinner?.stop();\n const assets = [\n `audio: ${durationInSeconds.toFixed(1)}s`,\n sceneData.imagePath ? \"image\" : null,\n sceneData.videoPath ? \"video\" : null,\n ].filter(Boolean).join(\", \");\n success(` ${scene.name}: ${assets}`);\n spinner?.start();\n }\n }\n } else {\n // === LEGACY SINGLE-SCRIPT MODE ===\n let script = options.script;\n if (options.scriptFile) {\n try {\n script = await readFile(options.scriptFile, \"utf-8\");\n } catch (err) {\n spinner?.stop();\n error(`Failed to read script file: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n if (!script || script.trim().length === 0) {\n spinner?.stop();\n error(\"Provide scenes via stdin JSON, --script-file with scenes JSON, or --script for legacy mode\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n script = script.trim();\n // Topic extracted for potential future use (image search, etc.)\n const _topic = options.topic || script.split(\".\")[0].slice(0, 50);\n void _topic; // Silence unused variable warning\n\n if (spinner) spinner.text = \"Generating voiceover...\";\n const ttsResult = await generateSpeech({\n text: script,\n options: { voice },\n });\n\n const voiceoverPath = join(audioDir, `voiceover.${ttsResult.format}`);\n await writeFile(voiceoverPath, ttsResult.audioData);\n totalCost += ttsResult.cost;\n totalDuration = ttsResult.duration;\n\n // Parse into sections with estimated timing\n const sectionTexts = parseScriptIntoSections(script);\n const sectionsWithTiming = calculateSectionTiming(sectionTexts, ttsResult.duration, DEFAULT_FPS, ttsResult.timestamps);\n\n scenes = sectionsWithTiming.map((s, i) => ({\n ...s,\n name: `Section${i + 1}`,\n audioPath: `audio/voiceover.${ttsResult.format}`,\n }));\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Voiceover: ${voiceoverPath} (${ttsResult.duration.toFixed(1)}s)`);\n spinner?.start();\n }\n }\n\n // Generate music AFTER all audio assets are created\n // Request exact duration without buffer to see what API returns\n const musicDuration = Math.min(30, Math.ceil(totalDuration));\n\n console.log(`[Music Generation] Requesting music:`, {\n prompt: musicPrompt,\n requestedDuration: musicDuration,\n totalAudioDuration: totalDuration,\n });\n\n if (spinner) spinner.text = \"Generating music...\";\n let musicResult = await generateMusic({\n prompt: musicPrompt,\n duration: musicDuration,\n });\n\n if (musicResult.status !== \"completed\" && musicResult.status !== \"failed\") {\n if (spinner) spinner.text = `Processing music (ID: ${musicResult.requestId})...`;\n musicResult = await pollForCompletion(\n () => checkMusicStatus(musicResult.requestId),\n 60,\n 2000\n );\n }\n\n if (musicResult.status === \"failed\") {\n spinner?.stop();\n error(`Music generation failed: ${musicResult.error || \"Unknown error\"}`);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n const musicPath = join(audioDir, \"music.mp3\");\n if (musicResult.audioUrl) {\n await downloadFile(musicResult.audioUrl, musicPath);\n }\n totalCost += musicResult.cost || 0;\n\n const actualMusicDuration = musicResult.duration || musicDuration;\n\n console.log(`[Music Generation] Received music:`, {\n requestedDuration: musicDuration,\n returnedDuration: musicResult.duration,\n actualUsedDuration: actualMusicDuration,\n totalAudioDuration: totalDuration,\n difference: actualMusicDuration - totalDuration,\n audioUrl: musicResult.audioUrl?.substring(0, 50) + '...',\n });\n\n const musicInfo: MusicInfo = {\n path: \"audio/music.mp3\",\n duration: actualMusicDuration,\n prompt: musicPrompt,\n cost: musicResult.cost || 0,\n };\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Music: ${musicPath} (${musicInfo.duration}s)`);\n\n // Warn if music is shorter than video duration\n if (actualMusicDuration < totalDuration) {\n warn(`Music duration (${actualMusicDuration.toFixed(1)}s) is shorter than video duration (${totalDuration.toFixed(1)}s).`);\n warn(`Consider using audio looping or extending music in Remotion.`);\n }\n\n spinner?.start();\n }\n\n // Write manifest\n if (spinner) spinner.text = \"Writing manifest...\";\n const totalDurationInFrames = Math.round(totalDuration * DEFAULT_FPS);\n const manifest: VideoManifest = {\n music: musicInfo,\n images: allImages,\n videos: allVideos,\n scenes,\n totalDurationInFrames,\n fps: DEFAULT_FPS,\n totalCost,\n createdAt: new Date().toISOString(),\n };\n\n const manifestPath = join(options.output, \"video-manifest.json\");\n await writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n\n spinner?.stop();\n\n if (format === \"json\") {\n printJson(manifest);\n return;\n }\n\n if (format === \"quiet\") {\n console.log(manifestPath);\n return;\n }\n\n // Human format summary\n console.log();\n success(\"Video assets created successfully!\");\n console.log();\n info(`Scenes: ${scenes.length} (${totalDurationInFrames} frames at ${DEFAULT_FPS}fps)`);\n for (const scene of scenes) {\n const assets = [\n scene.audioPath ? \"audio\" : null,\n scene.imagePath ? \"image\" : null,\n scene.videoPath ? \"video\" : null,\n ].filter(Boolean).join(\", \");\n info(` - ${scene.name}: ${scene.durationInSeconds.toFixed(1)}s [${assets}]`);\n }\n info(`Music: ${musicInfo.path} (${musicInfo.duration}s)`);\n info(`Manifest: ${manifestPath}`);\n console.log();\n info(`Total cost: $${totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\n/**\n * Video Search Command\n */\ninterface SearchOptions {\n maxResults: string;\n orientation: string;\n license: string;\n format: OutputFormat;\n}\n\nconst searchCommand = new Command(\"search\")\n .description(\"Search for stock videos\")\n .argument(\"<query>\", \"Search query\")\n .option(\"-n, --max-results <count>\", \"Maximum number of results\", \"10\")\n .option(\"-o, --orientation <type>\", \"Video orientation: landscape, portrait, square, any\", \"any\")\n .option(\"-l, --license <type>\", \"License type: free, premium, any\", \"free\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (query: string, options: SearchOptions) => {\n const { maxResults, orientation, license, format } = options;\n const spinner = format === \"human\" ? ora(\"Searching for videos...\").start() : null;\n\n try {\n const result = await searchVideos({\n query,\n options: {\n maxResults: parseInt(maxResults, 10),\n orientation: orientation as \"landscape\" | \"portrait\" | \"square\" | \"any\",\n license: license as \"free\" | \"premium\" | \"any\",\n },\n });\n\n spinner?.stop();\n\n // Flatten results from all providers\n const allVideos = result.data.results.flatMap((provider) => provider.results);\n\n if (format === \"json\") {\n printJson(result);\n return;\n }\n\n if (format === \"quiet\") {\n // Just output preview URLs\n allVideos.forEach((video) => {\n console.log(video.previewUrl || video.thumbnailUrl);\n });\n return;\n }\n\n // Human format\n if (allVideos.length === 0) {\n info(\"No videos found\");\n return;\n }\n\n success(`Found ${allVideos.length} videos for \"${query}\"`);\n console.log();\n\n allVideos.forEach((video, index) => {\n console.log(`[${index + 1}] ${video.title}`);\n console.log(` URL: ${video.previewUrl || video.thumbnailUrl}`);\n console.log(` Duration: ${video.duration}s | Size: ${video.width}x${video.height}`);\n console.log(` Provider: ${video.provider}`);\n console.log();\n });\n\n info(`Total cost: $${result.data.totalCost.toFixed(4)}`);\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\n/**\n * Video Init Command\n * Scaffolds a new Remotion video project from the template\n */\ntype VideoType = \"landscape\" | \"tiktok\";\n\ninterface InitOptions {\n template: string;\n type: VideoType;\n install: boolean;\n format: OutputFormat;\n}\n\nconst initCommand = new Command(\"init\")\n .description(\"Create a new Remotion video project from template\")\n .argument(\"<name>\", \"Project directory name\")\n .option(\"-t, --template <repo>\", \"GitHub repo (user/repo)\", DEFAULT_TEMPLATE)\n .option(\"--type <type>\", \"Video type: landscape (16:9) or tiktok (9:16)\", \"landscape\")\n .option(\"--no-install\", \"Skip pnpm install\")\n .option(\"-f, --format <format>\", \"Output format: human, json, quiet\", \"human\")\n .action(async (name: string, options: InitOptions) => {\n const format = options.format as OutputFormat;\n const spinner = format === \"human\" ? ora(\"Initializing video project...\").start() : null;\n\n try {\n const targetDir = resolve(process.cwd(), name);\n\n // Check if directory already exists\n try {\n await access(targetDir);\n spinner?.stop();\n error(`Directory \"${name}\" already exists`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n } catch {\n // Directory doesn't exist, continue\n }\n\n // Validate template format to prevent command injection\n // Format: owner/repo or owner/repo#branch or owner/repo/subdir\n const templatePattern = /^[a-zA-Z0-9_-]+\\/[a-zA-Z0-9_.-]+(\\/[a-zA-Z0-9_.-]+)*(#[a-zA-Z0-9_.-]+)?$/;\n if (!templatePattern.test(options.template)) {\n spinner?.stop();\n error(`Invalid template format: \"${options.template}\". Expected format: owner/repo or owner/repo#branch`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n // Use degit to scaffold the project\n if (spinner) spinner.text = `Downloading template from ${options.template}...`;\n\n try {\n // Try using degit first (faster, no .git folder)\n execSync(`npx --yes degit ${options.template} \"${targetDir}\"`, {\n stdio: \"pipe\",\n });\n } catch {\n // Fallback to git clone + remove .git\n if (spinner) spinner.text = \"Cloning template...\";\n // Extract owner/repo (without subdir or branch) for git clone\n const repoMatch = options.template.match(/^([a-zA-Z0-9_-]+\\/[a-zA-Z0-9_.-]+)/);\n const repo = repoMatch ? repoMatch[1] : options.template;\n execSync(`git clone --depth 1 https://github.com/${repo}.git \"${targetDir}\"`, {\n stdio: \"pipe\",\n });\n await rm(join(targetDir, \".git\"), { recursive: true, force: true });\n }\n\n if (format === \"human\") {\n spinner?.stop();\n success(`Template downloaded to ${name}/`);\n spinner?.start();\n }\n\n // Install dependencies\n if (options.install) {\n if (spinner) spinner.text = \"Installing dependencies...\";\n\n await new Promise<void>((resolvePromise, reject) => {\n const child = spawn(\"pnpm\", [\"install\"], {\n cwd: targetDir,\n stdio: \"pipe\",\n shell: true,\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolvePromise();\n } else {\n reject(new Error(`pnpm install failed with code ${code}`));\n }\n });\n\n child.on(\"error\", reject);\n });\n\n if (format === \"human\") {\n spinner?.stop();\n success(\"Dependencies installed\");\n spinner?.start();\n }\n }\n\n // Configure for TikTok format if specified\n if (options.type === \"tiktok\") {\n if (spinner) spinner.text = \"Configuring for TikTok (9:16)...\";\n\n const constantsPath = join(targetDir, \"types/constants.ts\");\n try {\n let constantsContent = await readFile(constantsPath, \"utf-8\");\n\n // Swap the default dimensions to TikTok\n constantsContent = constantsContent\n .replace(\n /export const VIDEO_WIDTH = 1920;/,\n \"export const VIDEO_WIDTH = 1080; // TikTok 9:16\"\n )\n .replace(\n /export const VIDEO_HEIGHT = 1080;/,\n \"export const VIDEO_HEIGHT = 1920; // TikTok 9:16\"\n )\n .replace(\n /export const VIDEO_FPS = 60;/,\n \"export const VIDEO_FPS = 30; // TikTok standard\"\n );\n\n await writeFile(constantsPath, constantsContent, \"utf-8\");\n\n if (format === \"human\") {\n spinner?.stop();\n success(\"Configured for TikTok (1080x1920 @ 30fps)\");\n spinner?.start();\n }\n } catch {\n // Constants file might have different structure, ignore\n }\n }\n\n spinner?.stop();\n\n // Output results\n if (format === \"json\") {\n printJson({\n name,\n path: targetDir,\n template: options.template,\n type: options.type,\n installed: options.install,\n });\n return;\n }\n\n if (format === \"quiet\") {\n console.log(targetDir);\n return;\n }\n\n // Human format\n console.log();\n success(`Video project \"${name}\" created successfully!`);\n if (options.type === \"tiktok\") {\n info(\"Format: TikTok/Reels/Shorts (1080x1920 @ 30fps)\");\n } else {\n info(\"Format: Landscape (1920x1080 @ 60fps)\");\n }\n console.log();\n info(\"Next steps:\");\n info(` cd ${name}`);\n if (!options.install) {\n info(\" pnpm install\");\n }\n info(\" pnpm dev # Preview in Remotion Studio\");\n info(\" cc video create ... # Generate assets to public/\");\n if (options.type === \"tiktok\") {\n info(\" pnpm exec remotion render TikTokVideo # Render TikTok video\");\n } else {\n info(\" pnpm exec remotion render FullVideo # Render final video\");\n }\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\n// ============================================================================\n// THUMBNAIL COMMAND\n// ============================================================================\n\n/**\n * Get ffmpeg path - uses bundled ffmpeg-static\n */\nfunction getFfmpegPath(): string {\n if (!ffmpegPath) {\n throw new Error(\"ffmpeg-static binary not found. Try reinstalling the CLI.\");\n }\n return ffmpegPath;\n}\n\nconst thumbnailCommand = new Command(\"thumbnail\")\n .description(\"Embed a thumbnail/poster image into a video file for preview in Slack, Twitter, etc.\")\n .argument(\"<video>\", \"Video file to add thumbnail to (e.g., out/video.mp4)\")\n .option(\"-i, --image <path>\", \"Thumbnail image to embed (if not provided, extracts from video)\")\n .option(\"-f, --frame <number>\", \"Frame number to extract as thumbnail (default: 30)\", \"30\")\n .option(\"-c, --composition <id>\", \"Remotion composition to extract frame from (uses Remotion still)\")\n .option(\"-o, --output <path>\", \"Output video path (default: overwrites input)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-q, --quiet\", \"Only output the file path\")\n .action(async (videoPath: string, options) => {\n const format: OutputFormat = options.json ? \"json\" : options.quiet ? \"quiet\" : \"human\";\n const spinner = format === \"human\" ? ora(\"Processing...\").start() : null;\n\n try {\n // Get bundled ffmpeg path\n let ffmpeg: string;\n try {\n ffmpeg = getFfmpegPath();\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"ffmpeg not available\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n // Resolve video path\n const videoFullPath = resolve(process.cwd(), videoPath);\n try {\n await access(videoFullPath);\n } catch {\n spinner?.stop();\n error(`Video file not found: ${videoPath}`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n const frameNum = parseInt(options.frame, 10);\n if (isNaN(frameNum) || frameNum < 0) {\n spinner?.stop();\n error(\"Invalid frame number. Must be a non-negative integer.\");\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n\n let thumbnailPath = options.image;\n let tempThumbnail = false;\n\n // If no image provided, extract from video or composition\n if (!thumbnailPath) {\n const tempDir = join(process.cwd(), \".tmp-thumbnail\");\n await mkdir(tempDir, { recursive: true });\n thumbnailPath = join(tempDir, \"thumb.png\");\n tempThumbnail = true;\n\n if (options.composition) {\n // Extract from Remotion composition\n if (spinner) spinner.text = `Extracting frame ${frameNum} from ${options.composition}...`;\n\n const args = [\n \"exec\", \"remotion\", \"still\",\n options.composition,\n thumbnailPath,\n `--frame=${frameNum}`,\n ];\n\n try {\n execSync(`pnpm ${args.join(\" \")}`, {\n stdio: \"pipe\",\n cwd: process.cwd(),\n });\n } catch (err) {\n spinner?.stop();\n error(`Failed to extract frame from composition: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n } else {\n // Extract from video using ffmpeg\n if (spinner) spinner.text = `Extracting frame ${frameNum} from video...`;\n\n try {\n // Use select filter to get exact frame\n execSync(\n `\"${ffmpeg}\" -y -i \"${videoFullPath}\" -vf \"select=eq(n\\\\,${frameNum})\" -vframes 1 \"${thumbnailPath}\"`,\n { stdio: \"pipe\" }\n );\n } catch (err) {\n spinner?.stop();\n error(`Failed to extract frame from video: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n }\n } else {\n // Verify provided image exists\n thumbnailPath = resolve(process.cwd(), thumbnailPath);\n try {\n await access(thumbnailPath);\n } catch {\n spinner?.stop();\n error(`Thumbnail image not found: ${options.image}`);\n process.exit(EXIT_CODES.INVALID_INPUT);\n }\n }\n\n // Determine output path\n const outputPath = options.output\n ? resolve(process.cwd(), options.output)\n : videoFullPath;\n\n const needsTempOutput = outputPath === videoFullPath;\n const tempOutput = needsTempOutput\n ? videoFullPath.replace(/\\.mp4$/, \".thumb-temp.mp4\")\n : outputPath;\n\n // Embed thumbnail into video using ffmpeg\n if (spinner) spinner.text = \"Embedding thumbnail into video...\";\n\n try {\n // ffmpeg command to embed thumbnail as cover art\n execSync(\n `\"${ffmpeg}\" -y -i \"${videoFullPath}\" -i \"${thumbnailPath}\" -map 0 -map 1 -c copy -disposition:v:1 attached_pic \"${tempOutput}\"`,\n { stdio: \"pipe\" }\n );\n\n // If overwriting input, replace original\n if (needsTempOutput) {\n await rm(videoFullPath);\n await cp(tempOutput, videoFullPath);\n await rm(tempOutput);\n }\n } catch (err) {\n spinner?.stop();\n error(`Failed to embed thumbnail: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n // Clean up temp thumbnail if we created it\n if (tempThumbnail) {\n try {\n await rm(join(process.cwd(), \".tmp-thumbnail\"), { recursive: true });\n } catch {\n // Ignore cleanup errors\n }\n }\n\n spinner?.stop();\n\n const finalOutput = options.output || videoPath;\n\n if (format === \"json\") {\n printJson({\n video: finalOutput,\n thumbnail: options.image || `frame ${frameNum}`,\n composition: options.composition || null,\n });\n return;\n }\n\n if (format === \"quiet\") {\n console.log(resolve(process.cwd(), finalOutput));\n return;\n }\n\n // Human format\n console.log();\n success(`Thumbnail embedded: ${finalOutput}`);\n if (options.image) {\n keyValue(\"Thumbnail\", options.image);\n } else if (options.composition) {\n keyValue(\"Source\", `${options.composition} frame ${frameNum}`);\n } else {\n keyValue(\"Source\", `Video frame ${frameNum}`);\n }\n console.log();\n } catch (err) {\n spinner?.stop();\n error(err instanceof Error ? err.message : \"Failed to process thumbnail\");\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n });\n\nexport const videoCommand = new Command(\"video\")\n .description(\"Video asset generation commands\")\n .addCommand(initCommand)\n .addCommand(createCommand)\n .addCommand(searchCommand)\n .addCommand(thumbnailCommand);\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6FX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyEX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgEX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwDX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoDX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwEX;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["cmd","table","chalk","confirm","runLoginFlow","error","resolve","Conf","chalk","resolve","whoami","Command","chalk","Command","Command","chalk","confirm","ora","config","Command","chalk","chalk","ora","error","readFileSync","Command","chalk","open","resolve","Command","Command","chalk","Command","confirm","Command","resolve","ora","Command","resolve","basename","ora","Command","chalk","ora","brand","Command","chalk","ora","Command","ora","chalk","Command","chalk","Command","chalk","Command","chalk","cmd","cmd","cmd","existsSync","resolve","resolve","existsSync","Command","chalk","Command","ora","writeFile","Command","ora","writeFile","buffer","generateCommand","Command","ora","writeFile","outputResult","downloadFile","statusCommand","Command","ora","Command","ora","writeFile","readFile","join","resolve","readStdin","downloadFile","buffer","createCommand","searchCommand","Command","chalk"]}
|