@conceptcraft/mindframes 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +165 -116
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/brand.ts","../src/commands/login.ts","../src/lib/config.ts","../src/lib/output.ts","../src/lib/feature-cache.ts","../src/lib/auth.ts","../src/types/index.ts","../src/lib/api.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":["#!/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 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 * 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","/**\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 * 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 * 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 { brand } from \"./brand.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 * Prints clear instructions for authentication (agent-friendly, no interactive prompts)\n */\nexport async function requireAuth(): Promise<void> {\n if (!hasAuth()) {\n const cmd = brand.commands[0];\n const envVar = brand.apiKeyEnvVar;\n\n console.error(chalk.red(\"✗ Not authenticated.\"));\n console.error();\n console.error(chalk.bold(\"To authenticate, run:\"));\n console.error(chalk.cyan(` ${cmd} login`));\n console.error();\n console.error(chalk.gray(`Or set ${envVar} environment variable.`));\n\n process.exit(EXIT_CODES.AUTH_ERROR);\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 * 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 * 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 BatchTTSRequest,\n BatchTTSResult,\n TTSVoicesResponse,\n MusicGenerationRequest,\n MusicGenerationResult,\n AudioMixRequest,\n AudioMixResult,\n ImageSearchRequest,\n ImageSearchResponse,\n VideoSearchRequest,\n VideoSearchResponse,\n MusicRequest,\n MusicResult,\n MusicStatus,\n MixRequest,\n MixResult,\n ImageSearchQuery,\n ImageSearchResult,\n StockVideoSearchQuery,\n StockVideoSearchResult,\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/cli/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/cli/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 * Generate speech for multiple texts in batch (processed in chunks of 5 on backend with retry)\n */\nexport async function generateSpeechBatch(batchRequest: BatchTTSRequest): Promise<BatchTTSResult> {\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/batch`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(batchRequest),\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 const result = await response.json();\n \n // Convert base64 audio data back to Buffer\n result.results = result.results.map((r: any) => ({\n ...r,\n audioData: Buffer.from(r.audioData, 'base64'),\n }));\n\n return result;\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 * 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 cmd: brand.commands[0],\n pkg: brand.packageName,\n url: brand.apiUrl,\n name: 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 { 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","/**\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 } = context;\n const envPrefix = name.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n\n return `---\nname: ${name}\ndescription: ${name} 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# ${name} 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**IMPORTANT:** Most commands require authentication. If a command fails with \"Not authenticated\", run:\n\n\\`\\`\\`bash\n${cmd} login\n\\`\\`\\`\n\nThis opens a browser for OAuth login. Alternatively, set an API key:\n\n\\`\\`\\`bash\nexport ${envPrefix}_API_KEY=\"your-key-here\"\n\\`\\`\\`\n\n**Verify authentication:**\n\\`\\`\\`bash\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 THUMBNAIL_RULES = `Consider creating separate thumbnail component with Remotion (can be captured with remotion still, not used in actual video).\n\n**High-CTR principles:**\n- Expressive faces (emotion, not neutral) boost CTR 20-30%\n- High contrast, bold colors (yellow, orange stand out)\n- Simple: 3 main elements max (face + text + 1 visual)\n- Mobile-first: readable at 320px width (70% of views)\n- Minimal text: 3-5 words, bold legible fonts (60-80px)\n- Rule of thirds composition\n\n**Specs:** 1280x720, <2MB, 16:9 ratio\n\nCan capture: \\`pnpm exec remotion still ThumbnailScene out/thumb.png\\`\n`;\n\nexport const MOTION_DESIGN_GUIDELINES = `# Motion Design Principles\n\n**Core Philosophy:** \"Atomic, Kinetic Construction\" - nothing is static. Elements arrive and leave via physics-based transitions.\n\n## Design System Approach\n\n**Separate content from logic:**\n- Theme object: colors (primary, accent, background, text), fonts, corner radiuses in config\n- Scene object: define by duration in frames and content type, not timecodes\n- Avoid hardcoding: colors, text, data values can be passed via props or config file\n\n## Animation Physics (Spring-Based)\n\n**Spring Pop:**\n- UI cards, bubbles, logos \"pop\" with bounce\n- \\`spring()\\` function works well: low mass (0.5), moderate damping (10-12), high stiffness (100-200)\n- Spring value can map to scale (0 to 1) and opacity (0 to 1)\n- Consider \\`transform-origin\\` placement (center for bubbles, top for dropdowns)\n\n**Kinetic Typography:**\n- Text entering line-by-line or word-by-word (not all at once)\n- Can split text into arrays, stagger with delays (index * 5 frames)\n- \\`interpolate()\\` works for opacity [0,1] and translateY [20px, 0px] - slide up\n- Cubic easing works well for slide-up motion\n\n**Constructed UI:**\n- Building UI from HTML/CSS divs works better than screenshots\n- If user shares project: study actual UI components (buttons, cards, modals) and implement pixel-perfect recreations - match colors, fonts, shadows, border-radius\n- Bar charts: can animate height/width from 0% to target\n- Line charts: can animate SVG path \\`stroke-dashoffset\\`\n- Donut charts: can animate \\`stroke-dasharray\\` of SVG circle\n- Numbers: counter component interpolating from 0 to target over 30-60 frames\n\n## Visual Composition\n\n**Background Ambience:**\n- Static backgrounds feel flat - consider faint dots/patterns\n- Slow oscillation works well: \\`Math.sin(frame / 100)\\` applied to position/rotation for \"floating\" effect\n- Parallax adds depth: background moves slower than foreground\n\n**SVG Handling:**\n- Inline SVGs allow control of fill color via theme (better than img tags)\n- Chat bubbles can be constructed with SVG paths or heavy border-radius\n- Animating bubble \"tail\" separately adds polish\n\n**Scene Transitions:**\n- Scenes can slide or camera can \"pan\" to new area\n- Slide-out approach: Scene A \\`translateX\\` 0% to -100%, Scene B 100% to 0%\n- Spatial pan approach: place scenes on giant canvas, animate parent container transform\n\n## Suggested Component Architecture\n\nConsider these reusable patterns:\n- KineticText: text, delay, style props - handles word-splitting and stagger\n- SmartCard: container with Spring Pop entry and glassmorphism styles\n- AnimatedCounter: from, to, duration props - number ticking\n- ProgressBar/ChartElement: percentage, color props - growth animation from 0\n\n**Motion Blur (optional):** Can simulate by stretching element in direction of movement on fast transitions.\n`;\n\nexport const SVG_ANIMATION_GUIDELINES = `# SVG Line Animation (Write-On Effect)\n\n**Core Concept:** \"Invisible Ink Rule\" - lines draw in (don't fade in), as if hand-drawn in real-time.\n\n**Animation approach:**\n- Setting \\`pathLength=\"1\"\\` on SVG path elements normalizes length\n- Animating \\`strokeDashoffset\\` from 1 (hidden) to 0 (drawn) creates write-on effect\n- \\`strokeDasharray: 1\\` with interpolate \\`[1, 0]\\` over 20-30 frames works well\n- \\`stroke-linecap=\"round\"\\` creates friendly hand-drawn look\n\n**Draw & vanish sequence:**\n- Draw in: 20 frames (offset 1→0)\n- Hold: 10 frames\n- Draw out: fade opacity or continue offset\n\n**Reusable component pattern:**\n- Props: path data (d), color, width, delay, type (underline/spark/circle/arrow)\n- Pre-defined path dictionaries work better than generating random coordinates\n- Positioning with top/left/scale/rotation props for text accents\n`;\n\nexport const ASSET_USAGE_GUIDELINES = `# Asset Usage & Optimization\n\n**For project-specific videos:** Study the project first - extract logos, colors, fonts, actual UI components. Recreate components pixel-perfect in Remotion (match exact colors, shadows, border-radius, fonts). Use project's actual branding and design system for authentic look.\n\n**CLI provides flexible asset search** - images and videos can be used creatively throughout compositions.\n\n**Video assets (from CLI video search):**\n- Full-screen backgrounds (with overlays/text)\n- Embedded in UI cards or windows alongside text\n- Picture-in-picture style elements\n- Background layers with reduced opacity\n- Transitional footage between scenes\n\n**Image assets (from CLI image search):**\n- Scene backgrounds (static or with animation)\n- Embedded elements within compositions\n- UI component content (cards, panels)\n- Layered for depth and parallax effects\n\n**Dynamic backgrounds (Three.js/WebGL):**\n- Three.js/React Three Fiber for performance-optimized animated backgrounds\n- Particle systems, procedural gradients, geometric patterns\n- SVG animations for abstract shapes and patterns\n- WebGL shaders for dynamic effects\n- Combines well with static assets for depth\n\n**Best approach:** Mix CLI assets (images/videos) with generated elements (Three.js, SVG) for rich, performant compositions.\n`;\n\nexport const VIDEO_RULE_CONTENTS: RuleContent[] = [\n {\n filename: \"thumbnails.md\",\n content: THUMBNAIL_RULES,\n },\n {\n filename: \"motion-design.md\",\n content: MOTION_DESIGN_GUIDELINES,\n },\n {\n filename: \"svg-animations.md\",\n content: SVG_ANIMATION_GUIDELINES,\n },\n {\n filename: \"asset-usage.md\",\n content: ASSET_USAGE_GUIDELINES,\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 { THUMBNAIL_RULES, MOTION_DESIGN_GUIDELINES, SVG_ANIMATION_GUIDELINES, ASSET_USAGE_GUIDELINES } from \"./rules/video/content.js\";\n\nexport function generateVideoSkillContent(context: SkillContext): string {\n const { name, cmd } = 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# ${name} Video Creation CLI\n\nGenerate video assets (voiceover, music, images, stock videos) and render with Remotion.\n\n---\n\n## Prerequisites\n\n**Authenticate:**\n\\`\\`\\`bash\n${cmd} login\n\\`\\`\\`\n\n---\n\n## Video Creation Workflow\n\n### 1. Generate Assets\n\nGenerate voiceover, music, and visual assets:\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 },\n { \n \"name\": \"Demo\", \n \"script\": \"Our AI analyzes your data in real-time, surfacing insights that matter.\"\n }\n ],\n \"voice\": \"Kore\"\n}\nSCENES\n\\`\\`\\`\n\n**Output:**\n- \\`public/audio/*.wav\\` - scene voiceovers\n- \\`public/audio/music.mp3\\` - background music\n- \\`public/video-manifest.json\\` - timing, metadata, timeline\n\n### 2. Initialize Remotion (MANDATORY)\n\nScaffold the template and copy assets:\n\n\\`\\`\\`bash\ncd .. && ${cmd} video init my-video\ncd my-video\n# Assets are now in public/ directory\n\\`\\`\\`\n\n### 3. Render Video\n\n**For landscape videos (16:9):**\n\\`\\`\\`bash\npnpm exec remotion render FullVideo out/video.mp4\n\\`\\`\\`\n\n**For vertical videos (9:16) with captions:**\n\\`\\`\\`bash\npnpm exec remotion render CaptionedVideo out/tiktok.mp4 \\\\\n --props='{\"timeline\":'$(cat public/video-manifest.json | jq -c .timeline)',\"showCaptions\":true}'\n\\`\\`\\`\n\n### 4. Generate & Inject Thumbnail\n\n${THUMBNAIL_RULES}\n\n\\`\\`\\`bash\n${cmd} video thumbnail out/video.mp4 --image out/thumb.png\n\\`\\`\\`\n\n---\n\n${MOTION_DESIGN_GUIDELINES}\n\n---\n\n${SVG_ANIMATION_GUIDELINES}\n\n---\n\n${ASSET_USAGE_GUIDELINES}\n\n---\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 } = 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# ${name} Presentation Creation 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, generateSpeechBatch } 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 // Generate approximate character timestamps\n const chars = text.split('');\n const charDuration = durationInSeconds / chars.length;\n const approximateTimestamps: TTSTimestamps = {\n characters: chars,\n characterStartTimesSeconds: chars.map((_, i) => i * charDuration),\n characterEndTimesSeconds: chars.map((_, i) => (i + 1) * charDuration),\n };\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 timestamps: approximateTimestamps, // Always include timestamps (approximate if needed)\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 // Extract character timestamps for this section\n const sectionTimestamps: TTSTimestamps = {\n characters: characters.slice(startCharIndex, endCharIndex + 1),\n characterStartTimesSeconds: characterStartTimesSeconds\n .slice(startCharIndex, endCharIndex + 1)\n .map(t => t - startTime), // Make relative to section start\n characterEndTimesSeconds: characterEndTimesSeconds\n .slice(startCharIndex, endCharIndex + 1)\n .map(t => t - startTime), // Make relative to section start\n };\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 timestamps: sectionTimestamps, // Add section-specific timestamps\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\n/**\n * Convert scenes to Remotion timeline format\n */\nfunction createTimelineFromScenes(scenes: SceneSection[]): any {\n const timeline = {\n shortTitle: \"Video\",\n elements: [] as any[],\n audio: [] as any[],\n text: [] as any[]\n };\n\n let zoomIn = true;\n\n scenes.forEach((scene) => {\n const startMs = scene.startTime * 1000;\n const endMs = scene.endTime * 1000;\n const durationMs = scene.durationInSeconds * 1000;\n\n // Add media element if present\n if (scene.imagePath) {\n timeline.elements.push({\n startMs,\n endMs,\n imageUrl: scene.imagePath,\n enterTransition: 'blur',\n exitTransition: 'blur',\n animations: [{\n type: 'scale',\n from: zoomIn ? 1.3 : 1,\n to: zoomIn ? 1 : 1.3,\n startMs: 0,\n endMs: durationMs,\n }]\n });\n zoomIn = !zoomIn;\n } else if (scene.videoPath) {\n timeline.elements.push({\n startMs,\n endMs,\n videoUrl: scene.videoPath,\n enterTransition: 'blur',\n exitTransition: 'blur',\n animations: []\n });\n }\n\n // Add audio\n if (scene.audioPath) {\n timeline.audio.push({\n startMs,\n endMs,\n audioUrl: scene.audioPath\n });\n }\n\n // Add text with timestamps\n if (scene.timestamps) {\n timeline.text.push({\n startMs,\n endMs,\n text: scene.text,\n position: 'bottom',\n animations: [],\n timestamps: scene.timestamps\n });\n }\n });\n\n return timeline;\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 timestamps?: TTSTimestamps; // Character-level timestamps for captions\n}\n\ninterface VideoManifest {\n music?: MusicInfo; // Optional - may not be present if generation fails\n images: ImageInfo[];\n videos: StockVideoInfo[];\n scenes: SceneSection[];\n timeline: any; // Remotion timeline format\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 // Collect all TTS requests\n const ttsRequests = scenesInput.scenes.map((scene, i) => ({\n text: scene.script,\n id: `scene-${i}`,\n }));\n\n // Generate all speech in batch\n if (spinner) spinner.text = \"Generating speech for all scenes...\";\n const batchResult = await generateSpeechBatch({\n texts: ttsRequests,\n options: {\n voice,\n voiceSettings: scenesInput.voiceSettings,\n },\n });\n\n totalCost += batchResult.totalCost;\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 const ttsResult = batchResult.results[i];\n\n // Save audio file\n if (spinner) spinner.text = `[${scene.name}] Saving audio...`;\n const audioPath = join(audioDir, `${filename}.${ttsResult.format}`);\n await writeFile(audioPath, ttsResult.audioData);\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 timestamps: ttsResult.timestamps, // Character-level timestamps for captions\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 Remotion timeline BEFORE music generation\n if (spinner) spinner.text = \"Creating timeline...\";\n const timeline = createTimelineFromScenes(scenes);\n \n // Calculate actual video duration from timeline (max end time across all elements)\n const videoEndTimeMs = Math.max(\n timeline.audio.length > 0 ? Math.max(...timeline.audio.map((a: any) => a.endMs)) : 0,\n timeline.text.length > 0 ? Math.max(...timeline.text.map((t: any) => t.endMs)) : 0,\n timeline.elements.length > 0 ? Math.max(...timeline.elements.map((e: any) => e.endMs)) : 0\n );\n \n const actualVideoDuration = videoEndTimeMs / 1000; // Convert ms to seconds\n\n // Generate music AFTER timeline is created, using ACTUAL video duration\n // Request exact duration without buffer to see what API returns\n const musicDuration = Math.min(30, Math.ceil(actualVideoDuration));\n\n console.log(`[Music Generation] Requesting music:`, {\n prompt: musicPrompt,\n requestedDuration: musicDuration,\n totalAudioDuration: totalDuration,\n actualVideoDuration: actualVideoDuration,\n timelineDurationMs: videoEndTimeMs,\n });\n\n let musicInfo: MusicInfo | undefined;\n \n // Skip music generation if video is too short (ElevenLabs requires minimum 3 seconds)\n if (musicDuration < 3) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`Video duration (${actualVideoDuration.toFixed(1)}s) is too short for music generation (minimum 3s).`);\n warn(`Skipping music generation...`);\n spinner?.start();\n }\n } else {\n try {\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 throw new Error(musicResult.error || \"Unknown 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 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 < actualVideoDuration) {\n warn(`Music duration (${actualMusicDuration.toFixed(1)}s) is shorter than video duration (${actualVideoDuration.toFixed(1)}s).`);\n warn(`Consider using audio looping or extending music in Remotion.`);\n }\n\n spinner?.start();\n }\n } catch (musicError: any) {\n spinner?.stop();\n warn(`Music generation failed: ${musicError.message}`);\n warn(`Continuing without background music...`);\n if (spinner && format === \"human\") spinner?.start();\n }\n }\n\n // Write manifest\n if (spinner) spinner.text = \"Writing manifest...\";\n const totalDurationInFrames = Math.round(actualVideoDuration * DEFAULT_FPS);\n \n const manifest: VideoManifest = {\n music: musicInfo,\n images: allImages,\n videos: allVideos,\n scenes,\n timeline, // Include Remotion timeline in manifest\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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","names":["Command","chalk","cmd","chalk","table","Conf","chalk","cmd","chalk","error","resolve","Conf","resolve","chalk","whoami","Command","Command","Command","chalk","confirm","ora","Command","chalk","confirm","ora","config","Command","chalk","chalk","ora","chalk","ora","error","readFileSync","Command","chalk","open","resolve","Command","Command","Command","chalk","Command","chalk","Command","confirm","Command","confirm","Command","resolve","ora","Command","ora","resolve","Command","resolve","basename","ora","Command","resolve","basename","ora","Command","chalk","ora","Command","chalk","brand","ora","Command","chalk","ora","Command","ora","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","cmd","cmd","cmd","existsSync","resolve","resolve","existsSync","Command","chalk","Command","ora","writeFile","Command","ora","writeFile","Command","ora","writeFile","buffer","writeFile","generateCommand","Command","ora","Command","ora","writeFile","outputResult","downloadFile","writeFile","Command","ora","statusCommand","Command","ora","Command","ora","Command","ora","writeFile","readFile","join","resolve","readStdin","resolve","downloadFile","buffer","writeFile","createCommand","Command","ora","readFile","join","searchCommand","Command","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/brand.ts","../src/commands/login.ts","../src/lib/config.ts","../src/lib/output.ts","../src/lib/feature-cache.ts","../src/lib/auth.ts","../src/types/index.ts","../src/lib/api.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":["#!/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 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 * 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","/**\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 * 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 * 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 { brand } from \"./brand.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 * Prints clear instructions for authentication (agent-friendly, no interactive prompts)\n */\nexport async function requireAuth(): Promise<void> {\n if (!hasAuth()) {\n const cmd = brand.commands[0];\n const envVar = brand.apiKeyEnvVar;\n\n console.error(chalk.red(\"✗ Not authenticated.\"));\n console.error();\n console.error(chalk.bold(\"To authenticate, run:\"));\n console.error(chalk.cyan(` ${cmd} login`));\n console.error();\n console.error(chalk.gray(`Or set ${envVar} environment variable.`));\n\n process.exit(EXIT_CODES.AUTH_ERROR);\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 * 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 * 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 BatchTTSRequest,\n BatchTTSResult,\n TTSVoicesResponse,\n MusicGenerationRequest,\n MusicGenerationResult,\n AudioMixRequest,\n AudioMixResult,\n ImageSearchRequest,\n ImageSearchResponse,\n VideoSearchRequest,\n VideoSearchResponse,\n MusicRequest,\n MusicResult,\n MusicStatus,\n MixRequest,\n MixResult,\n ImageSearchQuery,\n ImageSearchResult,\n StockVideoSearchQuery,\n StockVideoSearchResult,\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/cli/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/cli/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 * Generate speech for multiple texts in batch (processed in chunks of 5 on backend with retry)\n */\nexport async function generateSpeechBatch(batchRequest: BatchTTSRequest): Promise<BatchTTSResult> {\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/batch`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n },\n body: JSON.stringify(batchRequest),\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 const result = await response.json();\n \n // Convert base64 audio data back to Buffer\n result.results = result.results.map((r: any) => ({\n ...r,\n audioData: Buffer.from(r.audioData, 'base64'),\n }));\n\n return result;\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 * Generate an image from a prompt (uses Google AI / Gemini)\n */\nexport interface ImageGenerateRequest {\n prompt: string;\n options?: {\n providers?: string[];\n model?: string;\n width?: number;\n height?: number;\n };\n}\n\nexport interface ImageGenerateResponse {\n success: boolean;\n data: {\n url: string;\n prompt: string;\n cost: number;\n };\n requestId: string;\n}\n\nexport async function generateImage(\n generateRequest: ImageGenerateRequest\n): Promise<ImageGenerateResponse> {\n return request<ImageGenerateResponse>(\"/api/cli/images/generate\", {\n method: \"POST\",\n body: generateRequest,\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 * 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 cmd: brand.commands[0],\n pkg: brand.packageName,\n url: brand.apiUrl,\n name: 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 { 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","/**\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 } = context;\n const envPrefix = name.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n\n return `---\nname: ${cmd}\ndescription: ${name} 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 (${cmd}-video, ${cmd}-presentation) for detailed workflows.\n---\n\n# ${name} 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**IMPORTANT:** Most commands require authentication. If a command fails with \"Not authenticated\", run:\n\n\\`\\`\\`bash\n${cmd} login\n\\`\\`\\`\n\nThis opens a browser for OAuth login. Alternatively, set an API key:\n\n\\`\\`\\`bash\nexport ${envPrefix}_API_KEY=\"your-key-here\"\n\\`\\`\\`\n\n**Verify authentication:**\n\\`\\`\\`bash\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 \"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 (Gemini)\n${cmd} tts generate \\\\\n -t \"Professional narration\" \\\\\n -v Puck \\\\\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:** \\`elevenlabs\\` (default), \\`gemini\\`, \\`openai\\`\n**Voices by provider:**\n- ElevenLabs: \\`Rachel\\`, \\`Josh\\`, \\`Adam\\`, \\`Bella\\` (or voice IDs)\n- Gemini: \\`Kore\\`, \\`Puck\\`, \\`Charon\\`, \\`Aoede\\`\n- OpenAI: \\`alloy\\`, \\`nova\\`, \\`echo\\`, \\`onyx\\`\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 (version files: v1, v2, v3...)\ncd product-demo\nnpx remotion render FullVideo out/FullVideo-v1.mp4\n${cmd} video thumbnail out/FullVideo-v1.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 THUMBNAIL_RULES = `## Thumbnail\n\nA thumbnail is auto-generated during \\`video create\\` and saved to \\`public/thumbnail.jpg\\`.\n\n**Inject into video:**\n\\`\\`\\`bash\n# Already done by: ${\"{cmd}\"} video thumbnail out/video.mp4 --image public/thumbnail.jpg\n\\`\\`\\`\n\n**High-CTR principles:**\n- Expressive faces (emotion, not neutral) boost CTR 20-30%\n- High contrast, bold colors (yellow, orange stand out)\n- Simple: 3 main elements max (face + text + 1 visual)\n- Mobile-first: readable at 320px width\n- Minimal text: 3-5 words max\n\n**Specs:** 1280x720, <2MB, 16:9 ratio\n`;\n\nexport const MOTION_DESIGN_GUIDELINES = `# Motion Design Principles\n\n**Core Philosophy:** \"Atomic, Kinetic Construction\" - nothing is static. Elements arrive and leave via physics-based transitions.\n\n## Design System Approach\n\n**Separate content from logic:**\n- Theme object: colors (primary, accent, background, text), fonts, corner radiuses in config\n- Scene object: define by duration in frames and content type, not timecodes\n- Avoid hardcoding: colors, text, data values can be passed via props or config file\n\n## Animation Physics (Spring-Based)\n\n**Spring Pop:**\n- UI cards, bubbles, logos \"pop\" with bounce\n- \\`spring()\\` function works well: low mass (0.5), moderate damping (10-12), high stiffness (100-200)\n- Spring value can map to scale (0 to 1) and opacity (0 to 1)\n- Consider \\`transform-origin\\` placement (center for bubbles, top for dropdowns)\n\n**Kinetic Typography:**\n- Text entering line-by-line or word-by-word (not all at once)\n- Can split text into arrays, stagger with delays (index * 5 frames)\n- \\`interpolate()\\` works for opacity [0,1] and translateY [20px, 0px] - slide up\n- Cubic easing works well for slide-up motion\n\n**Constructed UI:**\n- Building UI from HTML/CSS divs works better than screenshots\n- If user shares project: study actual UI components (buttons, cards, modals) and implement pixel-perfect recreations - match colors, fonts, shadows, border-radius\n- Bar charts: can animate height/width from 0% to target\n- Line charts: can animate SVG path \\`stroke-dashoffset\\`\n- Donut charts: can animate \\`stroke-dasharray\\` of SVG circle\n- Numbers: counter component interpolating from 0 to target over 30-60 frames\n\n## Visual Composition\n\n**Background Ambience:**\n- Static backgrounds feel flat - consider faint dots/patterns\n- Slow oscillation works well: \\`Math.sin(frame / 100)\\` applied to position/rotation for \"floating\" effect\n- Parallax adds depth: background moves slower than foreground\n\n**SVG Handling:**\n- Inline SVGs allow control of fill color via theme (better than img tags)\n- Chat bubbles can be constructed with SVG paths or heavy border-radius\n- Animating bubble \"tail\" separately adds polish\n\n**Scene Transitions:**\n- Scenes can slide or camera can \"pan\" to new area\n- Slide-out approach: Scene A \\`translateX\\` 0% to -100%, Scene B 100% to 0%\n- Spatial pan approach: place scenes on giant canvas, animate parent container transform\n\n## Suggested Component Architecture\n\nConsider these reusable patterns:\n- KineticText: text, delay, style props - handles word-splitting and stagger\n- SmartCard: container with Spring Pop entry and glassmorphism styles\n- AnimatedCounter: from, to, duration props - number ticking\n- ProgressBar/ChartElement: percentage, color props - growth animation from 0\n\n**Motion Blur (optional):** Can simulate by stretching element in direction of movement on fast transitions.\n`;\n\nexport const SVG_ANIMATION_GUIDELINES = `# SVG Line Animation (Write-On Effect)\n\n**Core Concept:** \"Invisible Ink Rule\" - lines draw in (don't fade in), as if hand-drawn in real-time.\n\n**Animation approach:**\n- Setting \\`pathLength=\"1\"\\` on SVG path elements normalizes length\n- Animating \\`strokeDashoffset\\` from 1 (hidden) to 0 (drawn) creates write-on effect\n- \\`strokeDasharray: 1\\` with interpolate \\`[1, 0]\\` over 20-30 frames works well\n- \\`stroke-linecap=\"round\"\\` creates friendly hand-drawn look\n\n**Draw & vanish sequence:**\n- Draw in: 20 frames (offset 1→0)\n- Hold: 10 frames\n- Draw out: fade opacity or continue offset\n\n**Reusable component pattern:**\n- Props: path data (d), color, width, delay, type (underline/spark/circle/arrow)\n- Pre-defined path dictionaries work better than generating random coordinates\n- Positioning with top/left/scale/rotation props for text accents\n`;\n\nexport const ASSET_USAGE_GUIDELINES = `# Asset Usage & Optimization\n\n**For project-specific videos:** Study the project first - extract logos, colors, fonts, actual UI components. Recreate components pixel-perfect in Remotion (match exact colors, shadows, border-radius, fonts). Use project's actual branding and design system for authentic look.\n\n**CLI provides flexible asset search** - images and videos can be used creatively throughout compositions.\n\n**Video assets (from CLI video search):**\n- Full-screen backgrounds (with overlays/text)\n- Embedded in UI cards or windows alongside text\n- Picture-in-picture style elements\n- Background layers with reduced opacity\n- Transitional footage between scenes\n\n**Image assets (from CLI image search):**\n- Scene backgrounds (static or with animation)\n- Embedded elements within compositions\n- UI component content (cards, panels)\n- Layered for depth and parallax effects\n\n**Dynamic backgrounds (Three.js/WebGL):**\n- Three.js/React Three Fiber for performance-optimized animated backgrounds\n- Particle systems, procedural gradients, geometric patterns\n- SVG animations for abstract shapes and patterns\n- WebGL shaders for dynamic effects\n- Combines well with static assets for depth\n\n**Best approach:** Mix CLI assets (images/videos) with generated elements (Three.js, SVG) for rich, performant compositions.\n`;\n\nexport const VIDEO_RULE_CONTENTS: RuleContent[] = [\n {\n filename: \"thumbnails.md\",\n content: THUMBNAIL_RULES,\n },\n {\n filename: \"motion-design.md\",\n content: MOTION_DESIGN_GUIDELINES,\n },\n {\n filename: \"svg-animations.md\",\n content: SVG_ANIMATION_GUIDELINES,\n },\n {\n filename: \"asset-usage.md\",\n content: ASSET_USAGE_GUIDELINES,\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 { MOTION_DESIGN_GUIDELINES, SVG_ANIMATION_GUIDELINES, ASSET_USAGE_GUIDELINES } from \"./rules/video/content.js\";\n\nexport function generateVideoSkillContent(context: SkillContext): string {\n const { name, cmd } = context;\n\n return `---\nname: ${cmd}-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# ${name} Video Creation CLI\n\nGenerate video assets (voiceover, music, images, stock videos) and render with Remotion.\n\n---\n\n## Prerequisites\n\n**Authenticate:**\n\\`\\`\\`bash\n${cmd} login\n\\`\\`\\`\n\n---\n\n## Video Creation Workflow\n\n### 1. Generate Assets\n\nGenerate voiceover, music, images, and thumbnail:\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 },\n {\n \"name\": \"Demo\",\n \"script\": \"Our AI analyzes your data in real-time, surfacing insights that matter.\"\n }\n ]\n}\nSCENES\n\\`\\`\\`\n\n**Output:**\n- \\`public/audio/*.wav\\` - scene voiceovers\n- \\`public/audio/music.mp3\\` - background music\n- \\`public/images/*.jpg\\` - scene images (if imageQuery provided)\n- \\`public/thumbnail.jpg\\` - auto-generated thumbnail\n- \\`public/video-manifest.json\\` - **complete timeline ready to use**\n\n### 2. Initialize Remotion (MANDATORY)\n\nScaffold the template and copy assets:\n\n\\`\\`\\`bash\ncd .. && ${cmd} video init my-video\ncd my-video\n# Assets are now in public/ directory\n\\`\\`\\`\n\n### 3. Render Video\n\n**IMPORTANT:**\n- The \\`video-manifest.json\\` already contains the complete \\`timeline\\` - **no need to build or transform anything**\n- Just pass \\`timeline\\` directly to the composition\n- Always version output files: \\`out/video-v1.mp4\\`, \\`out/video-v2.mp4\\`, etc.\n\n**YouTube (landscape 16:9, NO captions):**\n\\`\\`\\`bash\nnpx remotion render YouTubeVideo out/youtube-v1.mp4 \\\\\n --props='{\"timeline\":'$(cat public/video-manifest.json | jq -c .timeline)',\"showCaptions\":false}'\n\\`\\`\\`\n\n**TikTok/Reels/Shorts (vertical 9:16, WITH captions):**\n\\`\\`\\`bash\nnpx remotion render TikTokVideo out/tiktok-v1.mp4 \\\\\n --props='{\"timeline\":'$(cat public/video-manifest.json | jq -c .timeline)',\"showCaptions\":true}'\n\\`\\`\\`\n\n### Video Compositions\n\n| Composition | Dimensions | Captions | Use Case |\n|-------------|------------|----------|----------|\n| \\`YouTubeVideo\\` | 1920x1080 (16:9) | No | YouTube, Vimeo, traditional video |\n| \\`TikTokVideo\\` | 1080x1920 (9:16) | Yes (word-by-word) | TikTok, Reels, Shorts |\n\n**Same timeline, different output formats.** Both use the exact same \\`timeline\\` from \\`video-manifest.json\\`.\n\n### 4. Embed Thumbnail\n\nThumbnail is auto-generated during \\`video create\\`. Inject into final video:\n\n\\`\\`\\`bash\n${cmd} video thumbnail out/youtube-v1.mp4 --image public/thumbnail.jpg\n\\`\\`\\`\n\n**High-CTR thumbnail principles:**\n- Expressive faces boost CTR 20-30%\n- High contrast, bold colors (yellow, orange)\n- Simple: 3 elements max\n- Mobile-first: readable at 320px\n- Specs: 1280x720, <2MB\n\n---\n\n${MOTION_DESIGN_GUIDELINES}\n\n---\n\n${SVG_ANIMATION_GUIDELINES}\n\n---\n\n${ASSET_USAGE_GUIDELINES}\n\n---\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 } = context;\n\n return `---\nname: ${cmd}-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# ${name} Presentation Creation 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 * NOTE: Currently only ElevenLabs provider is supported.\n * Other providers (openai, gemini) are commented out for now.\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 } from \"../types/index.js\";\nimport { EXIT_CODES } from \"../types/index.js\";\n\n// Default ElevenLabs voice ID (Rachel)\nconst DEFAULT_ELEVENLABS_VOICE_ID = \"21m00Tcm4TlvDq8ikWAM\";\n\ninterface GenerateOptions {\n text: string;\n voiceId?: string;\n // voice?: string; // Commented out - use voiceId for ElevenLabs\n // provider?: string; // Commented out - only ElevenLabs for now\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 (uses ElevenLabs)\")\n .requiredOption(\"-t, --text <text>\", \"Text to convert to speech\")\n .requiredOption(\"-o, --output <path>\", \"Output file path\")\n .option(\"--voice-id <voiceId>\", `ElevenLabs voice ID (default: ${DEFAULT_ELEVENLABS_VOICE_ID})`)\n // .option(\"-v, --voice <voice>\", \"Voice name or ID (e.g., Kore, Rachel, alloy)\") // Commented out - use --voice-id\n // .option(\"-p, --provider <provider>\", \"Provider: gemini, elevenlabs, openai\") // Commented out - only ElevenLabs\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 // Use provided voiceId or fall back to default ElevenLabs voice\n const voiceId = options.voiceId || DEFAULT_ELEVENLABS_VOICE_ID;\n\n const result = await generateSpeech({\n text: options.text,\n options: {\n provider: \"elevenlabs\", // Currently only ElevenLabs is supported\n voiceId,\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 (currently only ElevenLabs)\")\n // .option(\"-p, --provider <provider>\", \"Filter by provider: gemini, elevenlabs, openai\") // Commented out - only ElevenLabs\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 // Currently only show ElevenLabs voices\n const provider = \"elevenlabs\";\n\n if (options.format === \"json\") {\n const providerVoices = result.voices[provider as keyof typeof result.voices];\n printJson(providerVoices || []);\n return;\n }\n\n // Human format - only show ElevenLabs\n const voices = result.voices[provider as keyof typeof result.voices];\n if (!voices || voices.length === 0) {\n info(\"No ElevenLabs voices available\");\n return;\n }\n\n console.log();\n console.log(`ELEVENLABS 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 } 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, generateSpeechBatch, generateImage } 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 // Generate approximate character timestamps\n const chars = text.split('');\n const charDuration = durationInSeconds / chars.length;\n const approximateTimestamps: TTSTimestamps = {\n characters: chars,\n characterStartTimesSeconds: chars.map((_, i) => i * charDuration),\n characterEndTimesSeconds: chars.map((_, i) => (i + 1) * charDuration),\n };\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 timestamps: approximateTimestamps, // Always include timestamps (approximate if needed)\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 // Extract character timestamps for this section\n const sectionTimestamps: TTSTimestamps = {\n characters: characters.slice(startCharIndex, endCharIndex + 1),\n characterStartTimesSeconds: characterStartTimesSeconds\n .slice(startCharIndex, endCharIndex + 1)\n .map(t => t - startTime), // Make relative to section start\n characterEndTimesSeconds: characterEndTimesSeconds\n .slice(startCharIndex, endCharIndex + 1)\n .map(t => t - startTime), // Make relative to section start\n };\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 timestamps: sectionTimestamps, // Add section-specific timestamps\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\n/**\n * Convert scenes to Remotion timeline format\n */\nfunction createTimelineFromScenes(scenes: SceneSection[]): any {\n const timeline = {\n shortTitle: \"Video\",\n elements: [] as any[],\n audio: [] as any[],\n text: [] as any[]\n };\n\n let zoomIn = true;\n\n scenes.forEach((scene) => {\n const startMs = scene.startTime * 1000;\n const endMs = scene.endTime * 1000;\n const durationMs = scene.durationInSeconds * 1000;\n\n // Add media element if present\n if (scene.imagePath) {\n timeline.elements.push({\n startMs,\n endMs,\n imageUrl: scene.imagePath,\n enterTransition: 'blur',\n exitTransition: 'blur',\n animations: [{\n type: 'scale',\n from: zoomIn ? 1.3 : 1,\n to: zoomIn ? 1 : 1.3,\n startMs: 0,\n endMs: durationMs,\n }]\n });\n zoomIn = !zoomIn;\n } else if (scene.videoPath) {\n timeline.elements.push({\n startMs,\n endMs,\n videoUrl: scene.videoPath,\n enterTransition: 'blur',\n exitTransition: 'blur',\n animations: []\n });\n }\n\n // Add audio\n if (scene.audioPath) {\n timeline.audio.push({\n startMs,\n endMs,\n audioUrl: scene.audioPath\n });\n }\n\n // Add text with timestamps\n if (scene.timestamps) {\n timeline.text.push({\n startMs,\n endMs,\n text: scene.text,\n position: 'bottom',\n animations: [],\n timestamps: scene.timestamps\n });\n }\n });\n\n return timeline;\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 timestamps?: TTSTimestamps; // Character-level timestamps for captions\n}\n\ninterface VideoManifest {\n music?: MusicInfo; // Optional - may not be present if generation fails\n thumbnail?: string; // Path to generated thumbnail\n images: ImageInfo[];\n videos: StockVideoInfo[];\n scenes: SceneSection[];\n timeline: any; // Remotion timeline format\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 ID (ElevenLabs: Rachel, Josh, Adam; OpenAI: alloy, nova; Gemini: Kore, Puck)\")\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 // Collect all TTS requests\n const ttsRequests = scenesInput.scenes.map((scene, i) => ({\n text: scene.script,\n id: `scene-${i}`,\n }));\n\n // Generate all speech in batch\n if (spinner) spinner.text = \"Generating speech for all scenes...\";\n const batchResult = await generateSpeechBatch({\n texts: ttsRequests,\n options: {\n voice,\n voiceSettings: scenesInput.voiceSettings,\n },\n });\n\n totalCost += batchResult.totalCost;\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 const ttsResult = batchResult.results[i];\n\n // Save audio file\n if (spinner) spinner.text = `[${scene.name}] Saving audio...`;\n const audioPath = join(audioDir, `${filename}.${ttsResult.format}`);\n await writeFile(audioPath, ttsResult.audioData);\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 timestamps: ttsResult.timestamps, // Character-level timestamps for captions\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 Remotion timeline BEFORE music generation\n if (spinner) spinner.text = \"Creating timeline...\";\n const timeline = createTimelineFromScenes(scenes);\n \n // Calculate actual video duration from timeline (max end time across all elements)\n const videoEndTimeMs = Math.max(\n timeline.audio.length > 0 ? Math.max(...timeline.audio.map((a: any) => a.endMs)) : 0,\n timeline.text.length > 0 ? Math.max(...timeline.text.map((t: any) => t.endMs)) : 0,\n timeline.elements.length > 0 ? Math.max(...timeline.elements.map((e: any) => e.endMs)) : 0\n );\n \n const actualVideoDuration = videoEndTimeMs / 1000; // Convert ms to seconds\n\n // Generate music AFTER timeline is created, using ACTUAL video duration\n // Music API supports 3-300 seconds\n const musicDuration = Math.min(300, Math.ceil(actualVideoDuration));\n\n console.log(`[Music Generation] Requesting music:`, {\n prompt: musicPrompt,\n requestedDuration: musicDuration,\n totalAudioDuration: totalDuration,\n actualVideoDuration: actualVideoDuration,\n timelineDurationMs: videoEndTimeMs,\n });\n\n let musicInfo: MusicInfo | undefined;\n let thumbnailPath: string | undefined;\n\n // Generate music and thumbnail in parallel\n if (spinner) spinner.text = \"Generating music and thumbnail...\";\n\n // Create thumbnail prompt from first scene\n const firstScene = scenes[0];\n const thumbnailPrompt = `YouTube thumbnail, bold text overlay, high contrast, vibrant colors, 16:9 aspect ratio: ${firstScene?.text?.slice(0, 100) || 'video thumbnail'}`;\n\n // Start both generations in parallel\n const parallelTasks: Promise<any>[] = [];\n\n // Music generation task (only if duration >= 3s)\n const musicTask = (async () => {\n if (musicDuration < 3) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`Video duration (${actualVideoDuration.toFixed(1)}s) is too short for music generation (minimum 3s).`);\n spinner?.start();\n }\n return null;\n }\n\n try {\n let musicResult = await generateMusic({\n prompt: musicPrompt,\n duration: musicDuration,\n });\n\n if (musicResult.status !== \"completed\" && musicResult.status !== \"failed\") {\n musicResult = await pollForCompletion(\n () => checkMusicStatus(musicResult.requestId),\n 60,\n 2000\n );\n }\n\n if (musicResult.status === \"failed\") {\n throw new Error(musicResult.error || \"Unknown error\");\n }\n\n const musicPath = join(audioDir, \"music.mp3\");\n if (musicResult.audioUrl) {\n await downloadFile(musicResult.audioUrl, musicPath);\n }\n\n return {\n path: \"audio/music.mp3\",\n duration: musicResult.duration || musicDuration,\n prompt: musicPrompt,\n cost: musicResult.cost || 0,\n };\n } catch (err: any) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`Music generation failed: ${err.message}`);\n spinner?.start();\n }\n return null;\n }\n })();\n parallelTasks.push(musicTask);\n\n // Thumbnail generation task\n const thumbnailTask = (async () => {\n try {\n const result = await generateImage({\n prompt: thumbnailPrompt,\n options: {\n width: 1280,\n height: 720,\n },\n });\n\n if (result.success && result.data.url) {\n const thumbPath = join(options.output, \"thumbnail.jpg\");\n await downloadFile(result.data.url, thumbPath);\n totalCost += result.data.cost || 0;\n return thumbPath;\n }\n return null;\n } catch (err: any) {\n if (format === \"human\") {\n spinner?.stop();\n warn(`Thumbnail generation failed: ${err.message}`);\n spinner?.start();\n }\n return null;\n }\n })();\n parallelTasks.push(thumbnailTask);\n\n // Wait for both to complete\n const [musicResult, thumbResult] = await Promise.all(parallelTasks);\n\n if (musicResult) {\n musicInfo = musicResult;\n totalCost += musicResult.cost || 0;\n if (format === \"human\") {\n spinner?.stop();\n success(`Music: ${join(audioDir, \"music.mp3\")} (${musicResult.duration}s)`);\n if (musicResult.duration < actualVideoDuration) {\n warn(`Music duration (${musicResult.duration.toFixed(1)}s) is shorter than video duration (${actualVideoDuration.toFixed(1)}s).`);\n }\n spinner?.start();\n }\n }\n\n if (thumbResult) {\n thumbnailPath = thumbResult;\n if (format === \"human\") {\n spinner?.stop();\n success(`Thumbnail: ${thumbnailPath}`);\n spinner?.start();\n }\n }\n\n // Write manifest\n if (spinner) spinner.text = \"Writing manifest...\";\n const totalDurationInFrames = Math.round(actualVideoDuration * DEFAULT_FPS);\n \n const manifest: VideoManifest = {\n music: musicInfo,\n thumbnail: thumbnailPath ? \"thumbnail.jpg\" : undefined,\n images: allImages,\n videos: allVideos,\n scenes,\n timeline, // Include Remotion timeline in manifest\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 npm 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(\"npm\", [\"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(`npm 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 (FPS is already 30fps by default)\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\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 @ 30fps)\");\n }\n console.log();\n info(\"Next steps:\");\n info(` cd ${name}`);\n if (!options.install) {\n info(\" npm install\");\n }\n info(\" npm run dev # Preview in Remotion Studio\");\n info(\" cc video create ... # Generate assets to public/\");\n if (options.type === \"tiktok\") {\n info(\" npx remotion render TikTokVideo out/tiktok.mp4 --props='{...}' # Render TikTok video\");\n } else {\n info(\" npx remotion render YouTubeVideo out/youtube.mp4 --props='{...}' # Render YouTube 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 \"remotion\", \"still\",\n options.composition,\n thumbnailPath,\n `--frame=${frameNum}`,\n ];\n\n try {\n execSync(`npx ${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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","names":["Command","chalk","cmd","chalk","table","Conf","chalk","cmd","chalk","error","resolve","Conf","resolve","chalk","whoami","Command","Command","Command","chalk","confirm","ora","Command","chalk","confirm","ora","config","Command","chalk","chalk","ora","chalk","ora","error","readFileSync","Command","chalk","open","resolve","Command","Command","Command","chalk","Command","chalk","Command","confirm","Command","confirm","Command","resolve","ora","Command","ora","resolve","Command","resolve","basename","ora","Command","resolve","basename","ora","Command","chalk","ora","Command","chalk","brand","ora","Command","chalk","ora","Command","ora","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","cmd","cmd","cmd","existsSync","resolve","resolve","existsSync","Command","chalk","Command","ora","writeFile","Command","ora","writeFile","Command","ora","writeFile","buffer","writeFile","generateCommand","Command","ora","Command","ora","writeFile","outputResult","downloadFile","writeFile","Command","ora","statusCommand","Command","ora","Command","ora","Command","ora","writeFile","readFile","join","resolve","readStdin","resolve","downloadFile","buffer","writeFile","createCommand","Command","ora","readFile","join","musicResult","searchCommand","Command","chalk"]}
|