@conceptcraft/mindframes 0.3.12 → 0.3.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 +51 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
3
|
-
var h={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"CLI tool for Mindframes presentation generation",commands:["mf","mindframes"],apiUrl:"https://www.mindframes.app",docsUrl:"https://docs.mindframes.ai",packageName:"@conceptcraft/mindframes",configDir:".mindframes",apiKeyEnvVar:"MINDFRAMES_API_KEY",apiUrlEnvVar:"MINDFRAMES_API_URL",codexSelfConnectorAppId:"asdk_app_6a2b9629c1608191970dcb3ab374ac55"};import ue from"chalk";import{Command as dd}from"commander";import{Command as ba}from"commander";import{randomUUID as un}from"crypto";import{readFileSync as aa,statSync as sa}from"fs";import{basename as xo}from"path";import xt from"chalk";import na from"conf";function uo(e={}){let n=(s,l)=>{let m=e[s];return m&&m.trim().length>0?m.trim():l},t=n("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),o=n("NEXT_PUBLIC_CLI_COMMAND","ccr"),r=n("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),i=n("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${r}`),a=t.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:r,name:i.replace(/^\./,""),displayName:t,description:`CLI tool for ${t} presentation generation`,commands:[o,r],apiUrl:n("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:n("NEXT_PUBLIC_DOCS_URL",`https://docs.${t.toLowerCase()}.ai`),packageName:n("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${a}_API_KEY`,apiUrlEnvVar:`${a}_API_URL`,codexSelfConnectorAppId:e.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var g=typeof h<"u"&&h?h:uo(process.env);var mo=g.apiUrl,oa={apiKey:{type:"string"},apiUrl:{type:"string",default:mo},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}},L=new na({projectName:g.name,schema:oa});function po(){return{apiKey:ye(),apiUrl:j(),defaultTeamId:L.get("defaultTeamId"),accessToken:L.get("accessToken"),refreshToken:L.get("refreshToken"),tokenExpiresAt:L.get("tokenExpiresAt"),clientId:L.get("clientId"),clientSecret:L.get("clientSecret")}}function ye(){let e=process.env[g.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return e||L.get("apiKey")}function cn(e){L.set("apiKey",e)}function j(){let e=process.env[g.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return e||(L.get("apiUrl")??mo)}function ln(e){L.set("apiUrl",e)}function ft(){return L.get("defaultTeamId")}function Pe(e){L.set("defaultTeamId",e)}function ht(){L.clear()}function it(){return L.path}function Ne(){return!!ye()}function go(){return L.get("accessToken")}function fo(){return L.get("refreshToken")}function yt(e,n,t){L.set("accessToken",e),L.set("refreshToken",n),L.set("tokenExpiresAt",Date.now()+(t-60)*1e3)}function bt(){L.delete("accessToken"),L.delete("refreshToken"),L.delete("tokenExpiresAt")}function ho(){let e=L.get("tokenExpiresAt");return e?Date.now()>=e:!0}function Ie(){return!!L.get("accessToken")&&!!L.get("refreshToken")}function wt(){return L.get("clientId")}function vt(){return L.get("clientSecret")}function yo(e,n){L.set("clientId",e),L.set("clientSecret",n)}var d={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function ra(){let e=fo(),n=wt(),t=j();if(!e||!n)return null;try{let o=await fetch(`${t}/.well-known/oauth-authorization-server`);if(!o.ok)return null;let r=await o.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:n}),a=vt();a&&i.set("client_secret",a);let s=await fetch(r.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!s.ok)return bt(),null;let l=await s.json();return yt(l.access_token,l.refresh_token,l.expires_in),l.access_token}catch{return null}}async function bo(){return Ie()?ho()?ra():go()||null:null}function ce(){return Ie()||Ne()}async function P(){if(!ce()){let e=g.commands[0],n=g.apiKeyEnvVar;console.error(xt.red("\u2717 Not authenticated.")),console.error(),console.error(xt.bold("To authenticate, run:")),console.error(xt.cyan(` ${e} login`)),console.error(),console.error(xt.gray(`Or set ${n} environment variable.`)),process.exit(d.AUTH_ERROR)}}function ia(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function wo(){let e=ye();if(e)return ia(e)}function dn(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(t=>e.startsWith(t))}async function pe(){let e=await bo();if(e)return{Authorization:`Bearer ${e}`};let n=ye();return n?{"x-api-key":n}:{}}var O=class extends Error{constructor(t,o,r=1,i="operation_failed",a=!1){super(t);this.statusCode=o;this.exitCode=r;this.errorCode=i;this.retryable=a;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},So="Idempotency-Key";function ca(e){return e&&e!=="GET"?{[So]:un()}:{}}async function z(e,n={}){let t=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let o=await pe(),r=`${t}${e}`,i={...o,...ca(n.method),...n.headers};n.body&&!n.stream&&(i["Content-Type"]="application/json");let a={method:n.method??"GET",headers:i};n.body&&(a.body=JSON.stringify(n.body));let s;try{s=await fetch(r,a)}catch(m){throw new O(`Network error: ${m instanceof Error?m.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!s.ok){let m=await s.text().catch(()=>""),p=da(m,s.status),w=1;switch(s.status){case 401:w=2;break;case 403:w=2;break;case 404:w=3;break;case 429:w=4;break;case 500:w=1;break}let I=`[${p.code}] ${p.message}`;throw new O(I,s.status,w,p.code,p.retryable)}return n.stream?s:s.headers.get("content-type")?.includes("application/json")?s.json():s.text()}function la(e){switch(e){case 400:return"invalid_input";case 401:return"authentication_required";case 402:return"insufficient_credits";case 403:return"access_denied";case 404:return"not_found";case 429:return"rate_limited";case 503:return"service_unavailable";default:return"operation_failed"}}function da(e,n){let t=la(n),o=e.trim()||`HTTP ${n}: The request could not be completed.`;try{let r=JSON.parse(e),i=typeof r.error=="object"&&r.error!==null?r.error:void 0;if(r.ok===!1&&typeof i?.code=="string"&&typeof i.message=="string")return{code:i.code,message:i.message,retryable:i.retryable===!0};if(typeof r.error=="string")return{code:/^[a-z][a-z0-9_]+$/.test(r.error)?r.error:t,message:typeof r.message=="string"?r.message:r.error,retryable:n===429||n>=500}}catch{}return{code:t,message:o,retryable:n===429||n>=500}}async function Co(){return z("/api/cli/capabilities")}async function D(e,n,t){let o=t?`?teamId=${encodeURIComponent(t)}`:"";return z(`/api/cli/tool-runs/${encodeURIComponent(e)}/${encodeURIComponent(n)}${o}`)}async function $(e,n){return z(`/api/cli/tools/${encodeURIComponent(e)}`,{body:n,method:"POST"})}async function ua(e,n,t=120){let o=0;for(let r=0;r<t;r++){let i;try{i=await D(e,n),o=0}catch(a){if(a instanceof O&&a.retryable&&o<2){o+=1,await new Promise(s=>setTimeout(s,2e3));continue}throw a instanceof O?new O(`${a.message} Request ID: ${n}.`,a.statusCode,a.exitCode,a.errorCode,a.retryable):new O(`${a instanceof Error?a.message:"Unknown error"} Request ID: ${n}.`,0,5,"poll_failed",!0)}if(i.done){if(i.error)throw new O(`[${i.error.code??"operation_failed"}] ${i.error.message} Request ID: ${n}.`,500,1,i.error.code??"operation_failed",i.error.retryable);return i}await new Promise(a=>setTimeout(a,(i.nextPollAfterSeconds??2)*1e3))}throw new O(`[operation_timed_out] The background operation timed out. Request ID: ${n}.`,408,1,"operation_timed_out",!0)}function St(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function ma(e){try{let t=new URL(e).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return t&&/^[a-z0-9]+$/.test(t)?t:void 0}catch{return}}function pa(e){let n=e.toLowerCase().split(".").pop();return{pdf:"application/pdf",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",txt:"text/plain",md:"text/markdown",csv:"text/csv",json:"application/json",html:"text/html",css:"text/css",js:"application/javascript",ts:"text/x-typescript",py:"text/x-python"}[n||""]||"application/octet-stream"}async function ga(e){let n=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let t=await pe(),o=sa(e),r=xo(e),i=pa(e),a=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify({fileMetadata:{name:r,type:i,size:o.size}})});if(!a.ok){let I=await a.text();throw new O(I||"Failed to get upload URL",a.status,1)}let s=await a.json(),l=aa(e),m=new FormData;for(let[I,f]of Object.entries(s.fields||{}))m.append(I,f);let p=new Blob([l],{type:i});m.append("file",p,r);let w=await fetch(s.url,{method:"POST",body:m});if(!w.ok)throw new O("Failed to upload file to storage",w.status,1);return{id:un(),name:r,url:s.fileUrl,size:o.size,type:i,selected:!0}}async function Io(e,n){let t=[];for(let o=0;o<e.length;o++){let r=e[o],i=xo(r);n?.(o,e.length,i);let a=await ga(r);t.push(a)}return n?.(e.length,e.length,""),t}async function Ro(e){let n={};for(let[o,r]of Object.entries(e))r!==void 0&&(n[o]=r);let t=n.designBrandReference??n.brandId??n.brandingId;return t!==void 0&&(n.designBrandReference=t,delete n.brandId,delete n.brandingId),$("createSlides",{...n,approvalReceipt:"cli:create"})}async function To(e,n=20){let t=new URLSearchParams;return t.set("limit",String(n)),e&&t.set("teamId",e),(await z(`/api/cli/presentations?${t}`)).presentations}async function xe(e){return z(`/api/cli/presentation/${encodeURIComponent(e)}`)}async function ko(e){await z(`/api/cli/presentation/${encodeURIComponent(e)}`,{method:"DELETE"})}async function Ao(e,n={}){let t=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let o=await pe(),r=await fetch(`${t}/api/presentations/export`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({presentationId:e,options:{includeImages:n.includeImages??!0,includeBranding:n.includeBranding??!0,downloadExternalImages:n.includeExternal??!0}})});if(!r.ok)throw new O(await r.text(),r.status,r.status===404?3:1);return r.arrayBuffer()}async function $o(e,n,t={}){let o=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let r=await pe(),i=new FormData,a=new Blob([e],{type:"application/zip"});i.append("file",a,n),i.append("options",JSON.stringify({dryRun:t.dryRun??!1,remapIds:!0}));let s=await fetch(`${o}/api/presentations/import`,{method:"POST",headers:r,body:i}),l=await s.json();if(!s.ok)throw new O(l.errors?.[0]?.message??"Import failed",s.status,1);return l}async function mn(){return z("/api/cli/branding")}async function Eo(e,n=25){let t=new URLSearchParams;return t.set("limit",String(n)),e&&t.set("search",e),z(`/api/cli/templates?${t}`)}async function Oo(e){return z(`/api/branding/${e}`)}async function Po(e,n,t){return $("extractBranding",{approvalReceipt:t,teamId:n,url:e})}async function be(){return z("/api/cli/whoami")}async function No(){return z("/api/cli/features")}async function Lo(e,n,t={}){let o=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let r=await pe(),i=await fetch(`${o}/api/presentations/${e}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({documentCreatedAt:n,targetWordCount:t.targetWordCount??300,tone:t.tone??"professional",language:t.language??"en",targetAudience:t.targetAudience??"General Audience",blogFormat:t.blogFormat??"narrative",customInstructions:t.customInstructions??"",includeImages:t.includeImages??!0,includeTableOfContents:t.includeTableOfContents??!1})});if(!i.ok)throw new O(await i.text(),i.status,i.status===404?3:1);return i}async function fa(e){let n=new URLSearchParams;e&&n.set("teamId",e);let t=n.toString();return z(`/api/cli/limits${t?`?${t}`:""}`)}async function Do(e,n,t){let o=await fa(t);if(!o.canGenerate[e]){let r=o.remaining[e]??0,i=o.limits[e]??0;throw i===0?new O(`The "${e}" mode is not available on your ${o.planName} plan. Available modes: ${o.availableModes.join(", ")||"none"}`,403,2):new O(`You have reached your ${e} generation limit for this billing cycle (${o.usage[e]??0}/${i} used). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,4)}if(o.maxSlidesPerPresentation!==-1&&n>o.maxSlidesPerPresentation)throw new O(`Maximum ${o.maxSlidesPerPresentation} slides allowed on your ${o.planName} plan (requested: ${n}). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,6);return o}function Uo(e){return e.replace(/[\u2014\u2013]/g,"-").replace(/[\u201C\u201D]/g,'"').replace(/[\u2018\u2019]/g,"'").replace(/\u2026/g,"...").replace(/\u00A0/g," ").replace(/[\u2010-\u2015]/g,"-").replace(/[\u2032\u2033]/g,"'")}async function Ct(e){let n=await $("generateSpeech",{approvalReceipt:"cli:tts-generate",...e,text:Uo(e.text)}),t=await ua("generateSpeech",n.runId),o=t.entity?.url;if(!o)throw new O(`Speech completed without an audio URL. Request ID: ${n.runId}.`,500);let r;try{r=await fetch(o)}catch(s){throw new O(`${s instanceof Error?s.message:"Failed to download speech audio"} Request ID: ${n.runId}.`,0,5,"download_failed",!0)}if(!r.ok)throw new O(`Failed to download speech audio. Request ID: ${n.runId}.`,r.status,5,"download_failed",r.status===429||r.status>=500);let i=t.output??{},a=e.options??{};return{audioData:Buffer.from(await r.arrayBuffer()),audioUrl:o,duration:0,cost:0,provider:Re(i.provider)??a.provider??"gemini",format:ma(o)??"mp3",requestId:n.runId,voiceId:Re(i.voice_id)??Re(i.voiceId),voice:Re(i.voice),model:Re(i.model),speed:ha(i.speed)??a.speed,language:Re(i.lang)??Re(i.language)??a.language,langApplied:vo(i.langApplied)??vo(i.lang_applied)}}function Re(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function ha(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function vo(e){return typeof e=="boolean"?e:void 0}async function Fo(e){let n=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let t=await pe(),o=un(),r={...e,texts:e.texts.map(s=>({...s,text:Uo(s.text)}))},i;try{i=await fetch(`${n}/api/cli/tts/batch`,{method:"POST",headers:{"Content-Type":"application/json",[So]:o,...t},body:JSON.stringify(r)})}catch(s){throw new O(`Network error: ${s instanceof Error?s.message:"Unknown error"}`,0,5)}if(!i.ok){let s=await i.text().catch(()=>"Unknown error"),l;try{let m=JSON.parse(s);l=m.error||m.message||s}catch{l=s}throw new O(l,i.status,i.status===401?2:1)}let a=await i.json();return a.results=a.results.map(s=>({...s,audioData:Buffer.from(s.audioData,"base64")})),a}async function _o(e){let n=e?`/api/cli/tts?provider=${e}`:"/api/cli/tts";return z(n)}async function It(e){return{requestId:(await $("generateMusic",{...e,approvalReceipt:"cli:music-generate"})).runId,status:"pending"}}async function at(e){let n=await D("generateMusic",e);return{requestId:e,status:St(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Vo(e){return{requestId:(await $("mixAudio",{...e,approvalReceipt:"cli:mix-create"})).runId,status:"pending"}}async function pn(e){let n=await D("mixAudio",e);return{requestId:e,status:St(n),outputUrl:n.entity?.url,error:n.error?.message}}async function Rt(e){return z("/api/cli/images/search",{method:"POST",body:e})}async function Mo(e){return z("/api/cli/images/generate",{method:"POST",body:e})}async function gn(e){return z("/api/cli/videos/search",{method:"POST",body:e})}async function K(e,n=60,t=2e3){let o=0;for(let r=0;r<n;r++){let i;try{i=await e(),o=0}catch(a){if(a instanceof O&&a.retryable&&o<2){o+=1,await new Promise(s=>setTimeout(s,t));continue}throw a}if(i.status==="completed"||i.status==="failed")return i;await new Promise(a=>setTimeout(a,t))}throw new O("Operation timed out",408,1)}async function jo(e,n){let t=await $("scrape",{teamId:n,url:e});return{data:{content:t.content,cost:t.totalCost??0,metadata:{description:"",format:"markdown",tokenUsage:Math.ceil(t.content.length/4)},title:t.title??"",url:t.url},success:!0}}async function qo(e){let n=await $("generateSfx",{...e,approvalReceipt:"cli:sfx-generate"});return{id:n.runId,requestId:n.runId,status:"pending"}}async function fn(e){let n=await D("generateSfx",e);return{id:n.entity?.id??e,requestId:e,status:St(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Bo(e){return $("listPresenterOptions",{...e?{voiceLanguage:e}:{}})}async function Go(e){return{requestId:(await $("generateAvatarVideo",{...e,approvalReceipt:"cli:avatar-generate"})).runId,status:"pending"}}async function hn(e){let n=await D("generateAvatarVideo",e);return{durationSec:typeof n.output?.durationSec=="number"?n.output.durationSec:null,error:n.error?.message,requestId:e,status:St(n),videoUrl:n.entity?.url}}async function Wo(e){return $("lipsyncVideo",{...e,approvalReceipt:"cli:video-lipsync"})}async function Ho(){return(await $("listTranslationLanguages",{})).languages}async function Jo(e){return $("translateVideo",{...e,approvalReceipt:"cli:video-translate"})}async function yn(e){return $("generateVideoPlan",{...e,approvalReceipt:"cli:video-plan"})}async function zo(e){return $("createVideo",{...e,approvalReceipt:"cli:video-create"})}async function Xo(e){return z("/api/cli/video/plan",{body:e,method:"POST"})}import F from"chalk";import bn from"cli-table3";function S(e,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.green("\u2713"),e)}function c(e,n="human"){if(n!=="quiet"){if(n==="json"){console.error(JSON.stringify({error:e}));return}console.error(F.red("\u2717"),e)}}function _(e,n="human"){n!=="quiet"&&n!=="json"&&console.warn(F.yellow("\u26A0"),e)}function u(e,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.blue("\u2139"),e)}function Le(e,n="en"){return e?`${j()}/${n}/view/presentations/${e}`:"N/A"}function Yo(e,n={}){let{showLinks:t=!1,language:o="en"}=n,r=(s,l)=>s.length>l?s.slice(0,l-1)+"\u2026":s,i=s=>{try{return new Date(s).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(t){let s=new bn({head:[F.cyan("Slug"),F.cyan("Title"),F.cyan("Slides"),F.cyan("Created"),F.cyan("URL")]});for(let l of e)s.push([r(l.slug||l.id.slice(0,8),30),r(l.title||"Untitled",22),String(l.numberOfSlides||"-"),i(l.createdAt),Le(l.slug,o)]);return s.toString()}let a=new bn({head:[F.cyan("Slug"),F.cyan("Title"),F.cyan("Slides"),F.cyan("Mode"),F.cyan("Created")],colWidths:[32,28,8,11,18]});for(let s of e)a.push([s.slug||s.id.slice(0,8),s.title||"Untitled",String(s.numberOfSlides||"-"),s.mode||"-",i(s.createdAt)]);return a.toString()}function Ko(e){return e.map(n=>n.slug||n.id).join(`
|
|
4
|
-
`)}function Qo(e){let n=[...e].sort((r,i)=>{if(r.isDefault&&!i.isDefault)return-1;if(!r.isDefault&&i.isDefault)return 1;let a=r.createdAt?new Date(r.createdAt).getTime():0;return(i.createdAt?new Date(i.createdAt).getTime():0)-a}),t=r=>{if(!r)return"-";try{return new URL(r).href}catch{return r.startsWith("http")?r:`https://${r}`}},o=new bn({head:[F.cyan("Name"),F.cyan("Source"),F.cyan("Color"),F.cyan("Logo"),F.cyan("Default"),F.cyan("ID")]});for(let r of n){let i=r.primaryColor?`${F.bgHex(r.primaryColor)(" ")} ${r.primaryColor}`:"-";o.push([r.name,t(r.sourceUrl),i,r.logoUrl?F.green("\u2713"):F.gray("\u2717"),r.isDefault?F.green("\u2605"):"",r.id])}return o.toString()}function wn(e){try{return new Date(e).toLocaleString()}catch{return e}}function ge(e){console.log(),console.log(F.bold(e)),console.log(F.gray("\u2500".repeat(e.length)))}function T(e,n){console.log(` ${F.gray(e+":")} ${n??"-"}`)}function ya(e){return JSON.stringify(e,null,2)}function x(e){console.log(ya(e))}var Zo=new ba("capabilities").description("List callable capabilities and their parity state").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{try{let n=await Co();if(e.format==="json"){x(n);return}for(let t of n.capabilities){if(e.format==="quiet"){console.log(t.name);continue}console.log(`${t.name} ${t.state} ${t.milestone}`)}}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}});import{mkdirSync as Sa,writeFileSync as Ca}from"fs";import{dirname as or,join as Ia}from"path";import{Command as Se}from"commander";import st from"chalk";import{input as Ra,password as Ta,confirm as rr,select as ka}from"@inquirer/prompts";import kt from"ora";import wa from"conf";var Tt=new wa({projectName:"conceptcraft",configName:"feature-cache"}),va=3600*1e3,xa=1440*60*1e3;function er(e){let n=0;for(let t=0;t<e.length;t++){let o=e.charCodeAt(t);n=(n<<5)-n+o,n=n&n}return n.toString(16)}function tr(){if(!Ne())return null;let e=Tt.get("featureFlags");if(!e)return null;let n=er(ye());if(e.apiKeyHash&&e.apiKeyHash!==n)return ke(),null;let t=Date.now()-e.fetchedAt;return t>xa?null:(t>va&&vn(),e.flags)}function vn(){Te().catch(()=>{})}async function Te(){let e=await No(),n=ye();return Tt.set("featureFlags",{flags:e,fetchedAt:Date.now(),apiKeyHash:n?er(n):void 0}),e}function ke(){Tt.delete("featureFlags")}function nr(){return Tt.path}var ir=new Se("config").description("Manage CLI configuration").addCommand(new Se("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(st.bold(`${g.displayName} CLI Configuration`)),console.log(st.gray("\u2500".repeat(35))),console.log();try{let e=await Ta({message:"Enter your API key:",mask:"*",validate:o=>!o||o.trim().length===0?"API key is required":dn(o.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(cn(e.trim()),await rr({message:`Use a custom API URL? (default: ${g.apiUrl.replace("https://","")})`,default:!1})){let o=await Ra({message:"Enter API URL:",default:j(),validate:r=>{try{return new URL(r),!0}catch{return"Invalid URL format"}}});ln(o)}console.log();let t=kt("Verifying API key...").start();try{let o=await be();if(t.succeed("API key verified!"),console.log(),u(`Logged in as: ${o.user.email}`),o.teams.length===0)_("No teams found for this user.");else if(o.teams.length===1){let r=o.teams[0];Pe(r.id),u(`Team: ${r.name} (${r.planName})`)}else{console.log(),u(`You have access to ${o.teams.length} teams.`);let r=await ka({message:"Select your default team:",choices:o.teams.map(a=>({name:`${a.name} (${a.planName}) - ${a.role}${a.isCurrent?" [current]":""}`,value:a.id})),default:o.currentTeam?.id});Pe(r);let i=o.teams.find(a=>a.id===r);S(`Selected team: ${i?.name}`)}try{await Te()}catch{}}catch(o){t.fail("Failed to verify API key"),_(`Could not verify API key: ${o instanceof Error?o.message:String(o)}`),_(`You may need to set the team ID manually: ${g.commands[0]} config set team-id <id>`)}console.log(),S("Configuration saved!"),u(`Config file: ${it()}`),console.log()}catch(e){if(e.name==="ExitPromptError"){console.log(),u("Configuration cancelled.");return}throw e}})).addCommand(new Se("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async e=>{let n=po();if(ge("Current Configuration"),console.log(),T("API Key",wo()??st.red("Not set")),T("API URL",n.apiUrl),T("Default Team ID",n.defaultTeamId??st.gray("Not set")),console.log(),T("Config file",it()),e.verify&&n.apiKey){console.log();let t=kt("Verifying...").start();try{let o=await be();t.succeed("Verified"),console.log(),T("User",o.user.email),o.currentTeam&&T("Current Team",`${o.currentTeam.name} (${o.currentTeam.planName})`),o.teams.length>1&&T("Total Teams",String(o.teams.length))}catch(o){t.fail("Verification failed"),_(o instanceof Error?o.message:String(o))}}console.log()})).addCommand(new Se("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(e,n)=>{switch(e){case"api-key":dn(n)||(c("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),cn(n),ke(),S("API key updated"),Te().catch(()=>{});break;case"api-url":try{new URL(n),ln(n),S(`API URL set to: ${n}`)}catch{c("Invalid URL format"),process.exit(6)}break;case"team-id":Pe(n),S(`Default team ID set to: ${n}`);break;default:c(`Unknown config key: ${e}`),console.log(st.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new Se("clear").description("Clear all configuration").action(async()=>{try{await rr({message:"Are you sure you want to clear all configuration?",default:!1})?(ht(),ke(),S("Configuration cleared")):u("Cancelled")}catch{u("Cancelled")}})).addCommand(new Se("refresh").description("Refresh cached feature flags").action(async()=>{let e=kt("Refreshing feature flags...").start();try{await Te(),e.succeed("Feature flags refreshed"),u(`Run '${g.commands[0]} --help' to see updated commands`)}catch(n){e.fail("Failed to refresh"),c(n instanceof Error?n.message:String(n)),process.exit(1)}})).addCommand(new Se("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(e=>{e.cache?console.log(nr()):console.log(it())})).addCommand(new Se("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let e=kt("Pulling settings...").start();try{let n=await pe(),t=await fetch(`${j()}/api/cli/settings`,{headers:n});if(!t.ok)throw new Error(`Request failed (HTTP ${t.status})`);let o=await t.text(),r=Ia(or(it()),"settings.toml");Sa(or(r),{recursive:!0}),Ca(r,o,"utf8"),e.succeed("Settings pulled"),u(`Written to ${r}`)}catch(n){e.fail("Failed to pull settings"),c(n instanceof Error?n.message:String(n)),process.exit(1)}}));import{Command as Aa}from"commander";import{confirm as $a}from"@inquirer/prompts";var ar=new Aa("delete").description("Delete a presentation").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --force","Skip confirmation prompt").option("-q, --quiet","Suppress output").action(async(e,n)=>{if(await P(),!n.force)try{if(!await $a({message:`Are you sure you want to delete presentation "${e}"?`,default:!1})){n.quiet||_("Deletion cancelled");return}}catch{n.quiet||_("Deletion cancelled");return}try{await ko(e),n.quiet||S(`Presentation "${e}" deleted`)}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as De}from"commander";import cr from"chalk";import Ea from"ora";import{createParser as Ou}from"eventsource-parser";import Nu from"chalk";import Du from"ora";async function sr(e,n={}){let t=e.body?.getReader();if(!t)throw new Error("Response body is not readable");let o=new TextDecoder,r="",i=!1;for(;!i;){let a=await t.read();if(i=a.done,a.value){let s=o.decode(a.value,{stream:!0});r+=s,n.quiet||process.stdout.write(s)}}return n.quiet||console.log(),r}function Oa(){return new De("blog").description("Generate a blog post from a presentation").argument("<slug>","Presentation slug").option("--words <count>","Target word count (50-2000)","300").option("--tone <tone>","Writing tone (professional, casual, educational)","professional").option("--audience <text>","Target audience description").option("-f, --format <format>","Output format (human, json, markdown)","human").option("--instructions <text>","Custom instructions for the blog").option("--no-images","Exclude image references").option("--toc","Include table of contents").action(async(e,n)=>{await P();let t=parseInt(n.words,10);(isNaN(t)||t<50||t>2e3)&&(c("Word count must be between 50 and 2000"),process.exit(6));let o=["professional","casual","educational"];o.includes(n.tone)||(c(`Invalid tone. Valid options: ${o.join(", ")}`),process.exit(6));let r=Ea("Fetching presentation...").start();try{let i=await xe(e);r.text="Generating blog post...";let a=await Lo(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:t,tone:n.tone,targetAudience:n.audience??"General Audience",customInstructions:n.instructions??"",includeImages:!n.noImages,includeTableOfContents:n.toc??!1}),s=await sr(a,{quiet:!0});r.succeed("Blog generated"),n.format==="json"?console.log(JSON.stringify({presentationId:e,title:i.title,wordCount:t,tone:n.tone,content:s},null,2)):n.format==="markdown"?console.log(s):(console.log(),console.log(cr.bold(`Blog: ${i.title}`)),console.log(cr.gray("\u2500".repeat(40))),console.log(),console.log(s),console.log())}catch(i){r.fail("Generation failed"),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}})}function Pa(){return new De("tweets").description("Generate tweets from a presentation").argument("<slug>","Presentation slug").option("--count <n>","Number of tweets to generate","5").option("-f, --format <format>","Output format (human, json)","human").action(async(e,n)=>{await P(),u("Tweet generation coming soon.")})}function Na(){return new De("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P(),u("LinkedIn carousel generation coming soon.")})}function La(){return new De("questions").description("Generate questions for a presentation").argument("<slug>","Presentation slug").option("--count <n>","Number of questions","10").option("-f, --format <format>","Output format (human, json)","human").action(async(e,n)=>{await P(),u("Question generation coming soon.")})}function Da(){return new De("cheatsheet").description("Generate a presenter cheat sheet").argument("<slug>","Presentation slug").option("--mode <mode>","Cheat sheet mode (qa-prep, talking-points)","qa-prep").option("-f, --format <format>","Output format (human, json, markdown)","human").action(async(e,n)=>{await P(),u("Cheat sheet generation coming soon.")})}function lr(){let e=new De("derive").description("Generate derivative content from a presentation"),n=tr();return n&&(n.deckToBlog&&e.addCommand(Oa()),n.deckToTweets&&e.addCommand(Pa()),n.linkedInCarousel&&e.addCommand(Na()),n.redTeamQuestions&&e.addCommand(La()),n.presenterCheatSheet&&e.addCommand(Da())),e}import{Command as Ua}from"commander";import{writeFile as Fa}from"fs/promises";import{resolve as dr}from"path";import _a from"ora";var ur=new Ua("export").description("Export a presentation to ZIP").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-o, --output <path>","Output file path").option("--include-images","Include images (default: true)",!0).option("--include-branding","Include branding (default: true)",!0).option("--no-external","Skip external image downloads").action(async(e,n)=>{await P();let t=_a("Fetching presentation...").start();try{let o=await xe(e),r=o.title||e,i=o.id,a=e.replace(/[^a-z0-9-]/gi,"_").toLowerCase().substring(0,50),s=new Date().toISOString().split("T")[0],l=`${a}_${s}.zip`,m=n.output?dr(n.output):dr(process.cwd(),l);t.text=`Exporting "${r}"...`;let p=await Ao(i,{includeImages:n.includeImages,includeBranding:n.includeBranding,includeExternal:!n.noExternal});t.text="Saving file...",await Fa(m,Buffer.from(p)),t.succeed("Export complete!"),console.log(),u(`File saved: ${m}`),u(`Size: ${Va(p.byteLength)}`),console.log()}catch(o){t.fail("Export failed"),c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});function Va(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}import{Command as Ma}from"commander";import xn from"chalk";var mr=new Ma("ideas").description("Generate presentation topic ideas").option("--context <text>","Custom context for idea generation").option("--count <n>","Number of ideas to generate","5").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P(),u("Idea generation is available in the web dashboard."),console.log(),console.log(xn.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(xn.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(xn.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{Command as ja}from"commander";import{readFile as qa}from"fs/promises";import{resolve as Ba,basename as Ga}from"path";import Wa from"ora";var pr=new ja("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");pr._hidden=!0;var gr=pr.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(e,n)=>{await P();try{(await be()).user.role!=="admin"&&(c("This command is only available to administrators"),process.exit(2))}catch{c("Failed to verify permissions"),process.exit(2)}let t=Ba(e),o=Ga(t);o.endsWith(".zip")||(c("File must be a ZIP archive"),process.exit(6));let r=Wa("Reading file...").start();try{let i=await qa(t);n.dryRun?r.text="Validating...":r.text="Importing presentation...";let a=await $o(i,o,{dryRun:n.dryRun});if(a.success){if(n.dryRun)r.succeed("Validation passed!"),console.log(),u("The file is valid and can be imported."),a.statistics&&(console.log(),T("Slides",String(a.statistics.slidesImported)),T("Images",String(a.statistics.imagesUploaded)));else if(r.succeed("Import complete!"),console.log(),T("Presentation ID",a.presentationId??"N/A"),T("Document ID",a.documentId??"N/A"),a.statistics&&(T("Slides imported",String(a.statistics.slidesImported)),T("Images uploaded",String(a.statistics.imagesUploaded)),T("Time",`${a.statistics.totalTimeMs}ms`)),a.presentationId){let s=j();T("View URL",`${s}/p/${a.presentationId}`)}if(a.warnings&&a.warnings.length>0){console.log();for(let s of a.warnings)_(s)}console.log()}else{if(r.fail("Import failed"),console.log(),a.errors)for(let s of a.errors)c(`${s.type}: ${s.message}`);process.exit(1)}}catch(i){r.fail("Import failed"),i.code==="ENOENT"&&(c(`File not found: ${t}`),process.exit(3)),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}});import{Command as Ha}from"commander";var fr=new Ha("list").description("List presentations").option("-n, --limit <count>","Number of results to return","20").option("-f, --format <format>","Output format (table, json, ids)","table").option("--sort <field>","Sort by field (created, updated, title)").option("--team-id <id>","Team ID (uses default if not specified)").option("-d, --detail","Show detailed output including URLs").option("-l, --language <lang>","Language for URLs","en").action(async e=>{await P();let n=parseInt(e.limit,10);(isNaN(n)||n<1)&&(c("Invalid limit value"),process.exit(6));let t=e.teamId??ft();t||(c("`Team ID required. Set a default with '${brand.commands[0]} config set team-id <id>' or use --team-id`"),process.exit(6));try{let o=await To(t,n);if(o.length===0){e.format==="json"?console.log(JSON.stringify([])):e.format!=="ids"&&u("No presentations found");return}switch(e.sort&&o.sort((r,i)=>{switch(e.sort){case"created":return new Date(i.createdAt).getTime()-new Date(r.createdAt).getTime();case"title":return(r.title||"").localeCompare(i.title||"");default:return 0}}),e.format){case"json":console.log(JSON.stringify(o,null,2));break;case"ids":console.log(Ko(o));break;default:console.log(Yo(o,{showLinks:e.detail,language:e.language}));break}}catch(o){c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});import{Command as Ja}from"commander";import hr from"chalk";import yr from"ora";import br from"http";import{randomBytes as wr,createHash as za}from"crypto";import Xa from"open";var Ya=`${g.displayName} CLI`,Ka=8765,Qa=8775;function Za(){return wr(32).toString("base64url")}function es(e){return za("sha256").update(e).digest("base64url")}function ts(){return wr(16).toString("hex")}async function ns(e,n){for(let t=e;t<=n;t++)try{return await new Promise((o,r)=>{let i=br.createServer();i.listen(t,()=>{i.close(()=>o())}),i.on("error",r)}),t}catch{continue}throw new Error(`No available port found between ${e} and ${n}`)}async function os(e){let n=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!n.ok)throw new Error(`Failed to fetch OAuth metadata: ${n.status}`);return n.json()}async function rs(e,n){let t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Ya,redirect_uris:[n],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:"presentations:read presentations:write"})});if(!t.ok){let o=await t.text();throw new Error(`Client registration failed: ${o}`)}return t.json()}async function is(e,n,t,o,r){let i=new URLSearchParams({grant_type:"authorization_code",code:n,redirect_uri:o,client_id:r,code_verifier:t}),a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!a.ok){let s=await a.text();throw new Error(`Token exchange failed: ${s}`)}return a.json()}function as(e,n){return new Promise((t,o)=>{let r,i=!1,a=()=>{i||(i=!0,clearTimeout(r),process.off("SIGINT",s),process.off("SIGTERM",s),l.close())},s=()=>{a(),o(new Error("Login cancelled"))},l=br.createServer((m,p)=>{let w=new URL(m.url||"",`http://localhost:${e}`);if(w.pathname!=="/callback"){p.writeHead(404),p.end("Not found");return}let I=w.searchParams.get("code"),f=w.searchParams.get("state"),R=w.searchParams.get("error"),b=w.searchParams.get("error_description");if(p.writeHead(200,{"Content-Type":"text/html"}),R){p.end(`
|
|
3
|
+
var h={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"CLI tool for Mindframes presentation generation",commands:["mf","mindframes"],apiUrl:"https://www.mindframes.app",docsUrl:"https://docs.mindframes.ai",packageName:"@conceptcraft/mindframes",configDir:".mindframes",apiKeyEnvVar:"MINDFRAMES_API_KEY",apiUrlEnvVar:"MINDFRAMES_API_URL",codexSelfConnectorAppId:"asdk_app_6a2b9629c1608191970dcb3ab374ac55"};import ue from"chalk";import{Command as Il}from"commander";import{Command as Pa}from"commander";import{randomUUID as pn}from"crypto";import{readFileSync as ba,statSync as wa}from"fs";import{basename as To}from"path";import{spawnSync as aa}from"child_process";import{existsSync as sa,mkdtempSync as ca,rmSync as da,writeFileSync as la}from"fs";import{tmpdir as ua}from"os";import{join as po}from"path";import dn from"ffmpeg-static";var ma=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function pa(e){let n=ma.exec(e);if(!n)return;let t=Number(n[1])*3600+Number(n[2])*60+Number(n[3]);return Number.isFinite(t)&&t>0?t:void 0}function go(e,n="audio"){if(e.length===0)return;let t=dn&&sa(dn)?dn:"ffmpeg",o=/^[a-z0-9]+$/i.test(n)?n:"audio",r=ca(po(ua(),"mf-tts-duration-")),i=po(r,`speech.${o}`);try{la(i,e);let a=aa(t,["-hide_banner","-i",i],{encoding:"utf8"});return a.error?void 0:pa(a.stderr??"")}finally{da(r,{force:!0,recursive:!0})}}import St from"chalk";import ga from"conf";function fo(e={}){let n=(s,d)=>{let u=e[s];return u&&u.trim().length>0?u.trim():d},t=n("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),o=n("NEXT_PUBLIC_CLI_COMMAND","ccr"),r=n("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),i=n("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${r}`),a=t.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:r,name:i.replace(/^\./,""),displayName:t,description:`CLI tool for ${t} presentation generation`,commands:[o,r],apiUrl:n("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:n("NEXT_PUBLIC_DOCS_URL",`https://docs.${t.toLowerCase()}.ai`),packageName:n("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${a}_API_KEY`,apiUrlEnvVar:`${a}_API_URL`,codexSelfConnectorAppId:e.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var g=typeof h<"u"&&h?h:fo(process.env);var ho=g.apiUrl,fa={apiKey:{type:"string"},apiUrl:{type:"string",default:ho},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}},D=new ga({projectName:g.name,schema:fa});function yo(){return{apiKey:be(),apiUrl:j(),defaultTeamId:D.get("defaultTeamId"),accessToken:D.get("accessToken"),refreshToken:D.get("refreshToken"),tokenExpiresAt:D.get("tokenExpiresAt"),clientId:D.get("clientId"),clientSecret:D.get("clientSecret")}}function be(){let e=process.env[g.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return e||D.get("apiKey")}function ln(e){D.set("apiKey",e)}function j(){let e=process.env[g.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return e||(D.get("apiUrl")??ho)}function un(e){D.set("apiUrl",e)}function ht(){return D.get("defaultTeamId")}function Pe(e){D.set("defaultTeamId",e)}function yt(){D.clear()}function it(){return D.path}function Ne(){return!!be()}function bo(){return D.get("accessToken")}function wo(){return D.get("refreshToken")}function bt(e,n,t){D.set("accessToken",e),D.set("refreshToken",n),D.set("tokenExpiresAt",Date.now()+(t-60)*1e3)}function wt(){D.delete("accessToken"),D.delete("refreshToken"),D.delete("tokenExpiresAt")}function vo(){let e=D.get("tokenExpiresAt");return e?Date.now()>=e:!0}function Te(){return!!D.get("accessToken")&&!!D.get("refreshToken")}function vt(){return D.get("clientId")}function xt(){return D.get("clientSecret")}function xo(e,n){D.set("clientId",e),D.set("clientSecret",n)}var l={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function ha(){let e=wo(),n=vt(),t=j();if(!e||!n)return null;try{let o=await fetch(`${t}/.well-known/oauth-authorization-server`);if(!o.ok)return null;let r=await o.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:n}),a=xt();a&&i.set("client_secret",a);let s=await fetch(r.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!s.ok)return wt(),null;let d=await s.json();return bt(d.access_token,d.refresh_token,d.expires_in),d.access_token}catch{return null}}async function So(){return Te()?vo()?ha():bo()||null:null}function ce(){return Te()||Ne()}async function P(){if(!ce()){let e=g.commands[0],n=g.apiKeyEnvVar;console.error(St.red("\u2717 Not authenticated.")),console.error(),console.error(St.bold("To authenticate, run:")),console.error(St.cyan(` ${e} login`)),console.error(),console.error(St.gray(`Or set ${n} environment variable.`)),process.exit(l.AUTH_ERROR)}}function ya(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function Co(){let e=be();if(e)return ya(e)}function mn(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(t=>e.startsWith(t))}async function ge(){let e=await So();if(e)return{Authorization:`Bearer ${e}`};let n=be();return n?{"x-api-key":n}:{}}var O=class extends Error{constructor(t,o,r=1,i="operation_failed",a=!1){super(t);this.statusCode=o;this.exitCode=r;this.errorCode=i;this.retryable=a;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},Ro="Idempotency-Key";function va(e){return e&&e!=="GET"?{[Ro]:pn()}:{}}async function z(e,n={}){let t=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let o=await ge(),r=`${t}${e}`,i={...o,...va(n.method),...n.headers};n.body&&!n.stream&&(i["Content-Type"]="application/json");let a={method:n.method??"GET",headers:i};n.body&&(a.body=JSON.stringify(n.body));let s;try{s=await fetch(r,a)}catch(u){throw new O(`Network error: ${u instanceof Error?u.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!s.ok){let u=await s.text().catch(()=>""),p=Sa(u,s.status),w=1;switch(s.status){case 401:w=2;break;case 403:w=2;break;case 404:w=3;break;case 429:w=4;break;case 500:w=1;break}let I=`[${p.code}] ${p.message}`;throw new O(I,s.status,w,p.code,p.retryable)}return n.stream?s:s.headers.get("content-type")?.includes("application/json")?s.json():s.text()}function xa(e){switch(e){case 400:return"invalid_input";case 401:return"authentication_required";case 402:return"insufficient_credits";case 403:return"access_denied";case 404:return"not_found";case 429:return"rate_limited";case 503:return"service_unavailable";default:return"operation_failed"}}function Sa(e,n){let t=xa(n),o=e.trim()||`HTTP ${n}: The request could not be completed.`;try{let r=JSON.parse(e),i=typeof r.error=="object"&&r.error!==null?r.error:void 0;if(r.ok===!1&&typeof i?.code=="string"&&typeof i.message=="string")return{code:i.code,message:i.message,retryable:i.retryable===!0};if(typeof r.error=="string")return{code:/^[a-z][a-z0-9_]+$/.test(r.error)?r.error:t,message:typeof r.message=="string"?r.message:r.error,retryable:n===429||n>=500}}catch{}return{code:t,message:o,retryable:n===429||n>=500}}async function ko(){return z("/api/cli/capabilities")}async function L(e,n,t){let o=t?`?teamId=${encodeURIComponent(t)}`:"";return z(`/api/cli/tool-runs/${encodeURIComponent(e)}/${encodeURIComponent(n)}${o}`)}async function $(e,n){return z(`/api/cli/tools/${encodeURIComponent(e)}`,{body:n,method:"POST"})}async function Ca(e,n,t=120){let o=0;for(let r=0;r<t;r++){let i;try{i=await L(e,n),o=0}catch(a){if(a instanceof O&&a.retryable&&o<2){o+=1,await new Promise(s=>setTimeout(s,2e3));continue}throw a instanceof O?new O(`${a.message} Request ID: ${n}.`,a.statusCode,a.exitCode,a.errorCode,a.retryable):new O(`${a instanceof Error?a.message:"Unknown error"} Request ID: ${n}.`,0,5,"poll_failed",!0)}if(i.done){if(i.error)throw new O(`[${i.error.code??"operation_failed"}] ${i.error.message} Request ID: ${n}.`,500,1,i.error.code??"operation_failed",i.error.retryable);return i}await new Promise(a=>setTimeout(a,(i.nextPollAfterSeconds??2)*1e3))}throw new O(`[operation_timed_out] The background operation timed out. Request ID: ${n}.`,408,1,"operation_timed_out",!0)}function Ct(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function Ia(e){try{let t=new URL(e).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return t&&/^[a-z0-9]+$/.test(t)?t:void 0}catch{return}}function Ta(e){let n=e.toLowerCase().split(".").pop();return{pdf:"application/pdf",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",txt:"text/plain",md:"text/markdown",csv:"text/csv",json:"application/json",html:"text/html",css:"text/css",js:"application/javascript",ts:"text/x-typescript",py:"text/x-python"}[n||""]||"application/octet-stream"}async function Ra(e){let n=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let t=await ge(),o=wa(e),r=To(e),i=Ta(e),a=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify({fileMetadata:{name:r,type:i,size:o.size}})});if(!a.ok){let I=await a.text();throw new O(I||"Failed to get upload URL",a.status,1)}let s=await a.json(),d=ba(e),u=new FormData;for(let[I,f]of Object.entries(s.fields||{}))u.append(I,f);let p=new Blob([d],{type:i});u.append("file",p,r);let w=await fetch(s.url,{method:"POST",body:u});if(!w.ok)throw new O("Failed to upload file to storage",w.status,1);return{id:pn(),name:r,url:s.fileUrl,size:o.size,type:i,selected:!0}}async function Ao(e,n){let t=[];for(let o=0;o<e.length;o++){let r=e[o],i=To(r);n?.(o,e.length,i);let a=await Ra(r);t.push(a)}return n?.(e.length,e.length,""),t}async function $o(e){let n={};for(let[o,r]of Object.entries(e))r!==void 0&&(n[o]=r);let t=n.designBrandReference??n.brandId??n.brandingId;return t!==void 0&&(n.designBrandReference=t,delete n.brandId,delete n.brandingId),$("createSlides",{...n,approvalReceipt:"cli:create"})}async function Eo(e,n=20){let t=new URLSearchParams;return t.set("limit",String(n)),e&&t.set("teamId",e),(await z(`/api/cli/presentations?${t}`)).presentations}async function Se(e){return z(`/api/cli/presentation/${encodeURIComponent(e)}`)}async function Oo(e){await z(`/api/cli/presentation/${encodeURIComponent(e)}`,{method:"DELETE"})}async function Po(e,n={}){let t=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let o=await ge(),r=await fetch(`${t}/api/presentations/export`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({presentationId:e,options:{includeImages:n.includeImages??!0,includeBranding:n.includeBranding??!0,downloadExternalImages:n.includeExternal??!0}})});if(!r.ok)throw new O(await r.text(),r.status,r.status===404?3:1);return r.arrayBuffer()}async function No(e,n,t={}){let o=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let r=await ge(),i=new FormData,a=new Blob([e],{type:"application/zip"});i.append("file",a,n),i.append("options",JSON.stringify({dryRun:t.dryRun??!1,remapIds:!0}));let s=await fetch(`${o}/api/presentations/import`,{method:"POST",headers:r,body:i}),d=await s.json();if(!s.ok)throw new O(d.errors?.[0]?.message??"Import failed",s.status,1);return d}async function gn(){return z("/api/cli/branding")}async function Do(e,n=25){let t=new URLSearchParams;return t.set("limit",String(n)),e&&t.set("search",e),z(`/api/cli/templates?${t}`)}async function Lo(e){return z(`/api/branding/${e}`)}async function Uo(e,n,t){return $("extractBranding",{approvalReceipt:t,teamId:n,url:e})}async function we(){return z("/api/cli/whoami")}async function Fo(){return z("/api/cli/features")}async function _o(e,n,t={}){let o=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let r=await ge(),i=await fetch(`${o}/api/presentations/${e}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({documentCreatedAt:n,targetWordCount:t.targetWordCount??300,tone:t.tone??"professional",language:t.language??"en",targetAudience:t.targetAudience??"General Audience",blogFormat:t.blogFormat??"narrative",customInstructions:t.customInstructions??"",includeImages:t.includeImages??!0,includeTableOfContents:t.includeTableOfContents??!1})});if(!i.ok)throw new O(await i.text(),i.status,i.status===404?3:1);return i}async function ka(e){let n=new URLSearchParams;e&&n.set("teamId",e);let t=n.toString();return z(`/api/cli/limits${t?`?${t}`:""}`)}async function Vo(e,n,t){let o=await ka(t);if(!o.canGenerate[e]){let r=o.remaining[e]??0,i=o.limits[e]??0;throw i===0?new O(`The "${e}" mode is not available on your ${o.planName} plan. Available modes: ${o.availableModes.join(", ")||"none"}`,403,2):new O(`You have reached your ${e} generation limit for this billing cycle (${o.usage[e]??0}/${i} used). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,4)}if(o.maxSlidesPerPresentation!==-1&&n>o.maxSlidesPerPresentation)throw new O(`Maximum ${o.maxSlidesPerPresentation} slides allowed on your ${o.planName} plan (requested: ${n}). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,6);return o}function Mo(e){return e.replace(/[\u2014\u2013]/g,"-").replace(/[\u201C\u201D]/g,'"').replace(/[\u2018\u2019]/g,"'").replace(/\u2026/g,"...").replace(/\u00A0/g," ").replace(/[\u2010-\u2015]/g,"-").replace(/[\u2032\u2033]/g,"'")}async function It(e){let n=await $("generateSpeech",{approvalReceipt:"cli:tts-generate",...e,text:Mo(e.text)}),t=await Ca("generateSpeech",n.runId),o=t.entity?.url;if(!o)throw new O(`Speech completed without an audio URL. Request ID: ${n.runId}.`,500);let r;try{r=await fetch(o)}catch(p){throw new O(`${p instanceof Error?p.message:"Failed to download speech audio"} Request ID: ${n.runId}.`,0,5,"download_failed",!0)}if(!r.ok)throw new O(`Failed to download speech audio. Request ID: ${n.runId}.`,r.status,5,"download_failed",r.status===429||r.status>=500);let i=t.output??{},a=e.options??{},s=pe(i.format)??Ia(o)??"mp3",d=Buffer.from(await r.arrayBuffer()),u=Aa(i.durationSec,i.duration,i.duration_s)??go(d,s);if(u===void 0)throw new O(`Speech completed without a measurable duration. Request ID: ${n.runId}.`,500,1,"invalid_audio_metadata");return{audioData:d,audioUrl:o,duration:u,cost:at(i.costUsd)??at(i.cost)??0,provider:pe(i.provider)??a.provider??"gemini",format:s,requestId:n.runId,voiceId:pe(i.voice_id)??pe(i.voiceId),voice:pe(i.voice),model:pe(i.model),speed:at(i.speed)??a.speed,language:pe(i.lang)??pe(i.language)??a.language,langApplied:Io(i.langApplied)??Io(i.lang_applied),timestamps:$a(i.timestamps),wordTimings:Ea(i.timestamps??i.timings)}}function Aa(...e){for(let n of e){let t=typeof n=="number"?n:typeof n=="string"&&n.trim()?Number(n):Number.NaN;if(Number.isFinite(t)&&t>0)return t}}function $a(e){if(!e||typeof e!="object"||Array.isArray(e))return;let n=e,t=n.characters,o=n.characterStartTimesSeconds??n.character_start_times_seconds,r=n.characterEndTimesSeconds??n.character_end_times_seconds;if(!(!Array.isArray(t)||!Array.isArray(o)||!Array.isArray(r))&&!(t.length===0||t.length!==o.length||t.length!==r.length||!t.every(i=>typeof i=="string")||!o.every(i=>typeof i=="number"&&Number.isFinite(i))||!r.every(i=>typeof i=="number"&&Number.isFinite(i))))return{characters:t,characterStartTimesSeconds:o,characterEndTimesSeconds:r}}function Ea(e){if(!Array.isArray(e))return;let n=e.flatMap(t=>{if(!t||typeof t!="object"||Array.isArray(t))return[];let o=t,r=pe(o.text)??pe(o.word),i=at(o.start),a=at(o.end);return r&&i!==void 0&&a!==void 0&&a>=i?[{text:r,start:i,end:a}]:[]});return n.length>0?n:void 0}function pe(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function at(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Io(e){return typeof e=="boolean"?e:void 0}async function jo(e){let n=j();if(!ce())throw new O(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let t=await ge(),o=pn(),r={...e,texts:e.texts.map(s=>({...s,text:Mo(s.text)}))},i;try{i=await fetch(`${n}/api/cli/tts/batch`,{method:"POST",headers:{"Content-Type":"application/json",[Ro]:o,...t},body:JSON.stringify(r)})}catch(s){throw new O(`Network error: ${s instanceof Error?s.message:"Unknown error"}`,0,5)}if(!i.ok){let s=await i.text().catch(()=>"Unknown error"),d;try{let u=JSON.parse(s);d=u.error||u.message||s}catch{d=s}throw new O(d,i.status,i.status===401?2:1)}let a=await i.json();return a.results=a.results.map(s=>({...s,audioData:Buffer.from(s.audioData,"base64")})),a}async function qo(e){let n=e?`/api/cli/tts?provider=${e}`:"/api/cli/tts";return z(n)}async function Tt(e){return{requestId:(await $("generateMusic",{...e,approvalReceipt:"cli:music-generate"})).runId,status:"pending"}}async function st(e){let n=await L("generateMusic",e);return{requestId:e,status:Ct(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Bo(e){return{requestId:(await $("mixAudio",{...e,approvalReceipt:"cli:mix-create"})).runId,status:"pending"}}async function fn(e){let n=await L("mixAudio",e);return{requestId:e,status:Ct(n),outputUrl:n.entity?.url,error:n.error?.message}}async function Rt(e){return z("/api/cli/images/search",{method:"POST",body:e})}async function Go(e){return z("/api/cli/images/generate",{method:"POST",body:e})}async function hn(e){return z("/api/cli/videos/search",{method:"POST",body:e})}async function K(e,n=60,t=2e3){let o=0;for(let r=0;r<n;r++){let i;try{i=await e(),o=0}catch(a){if(a instanceof O&&a.retryable&&o<2){o+=1,await new Promise(s=>setTimeout(s,t));continue}throw a}if(i.status==="completed"||i.status==="failed")return i;await new Promise(a=>setTimeout(a,t))}throw new O("Operation timed out",408,1)}async function Wo(e,n){let t=await $("scrape",{teamId:n,url:e});return{data:{content:t.content,cost:t.totalCost??0,metadata:{description:"",format:"markdown",tokenUsage:Math.ceil(t.content.length/4)},title:t.title??"",url:t.url},success:!0}}async function Ho(e){let n=await $("generateSfx",{...e,approvalReceipt:"cli:sfx-generate"});return{id:n.runId,requestId:n.runId,status:"pending"}}async function yn(e){let n=await L("generateSfx",e);return{id:n.entity?.id??e,requestId:e,status:Ct(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Jo(e){return $("listPresenterOptions",{...e?{voiceLanguage:e}:{}})}async function zo(e){return{requestId:(await $("generateAvatarVideo",{...e,approvalReceipt:"cli:avatar-generate"})).runId,status:"pending"}}async function bn(e){let n=await L("generateAvatarVideo",e);return{durationSec:typeof n.output?.durationSec=="number"?n.output.durationSec:null,error:n.error?.message,requestId:e,status:Ct(n),videoUrl:n.entity?.url}}async function Xo(e){return $("lipsyncVideo",{...e,approvalReceipt:"cli:video-lipsync"})}async function Yo(){return(await $("listTranslationLanguages",{})).languages}async function Ko(e){return $("translateVideo",{...e,approvalReceipt:"cli:video-translate"})}async function wn(e){return $("generateVideoPlan",{...e,approvalReceipt:"cli:video-plan"})}async function Qo(e){return $("createVideo",{...e,approvalReceipt:"cli:video-create"})}async function Zo(e){return z("/api/cli/video/plan",{body:e,method:"POST"})}import F from"chalk";import vn from"cli-table3";function S(e,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.green("\u2713"),e)}function c(e,n="human"){if(n!=="quiet"){if(n==="json"){console.error(JSON.stringify({error:e}));return}console.error(F.red("\u2717"),e)}}function _(e,n="human"){n!=="quiet"&&n!=="json"&&console.warn(F.yellow("\u26A0"),e)}function m(e,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.blue("\u2139"),e)}function De(e,n="en"){return e?`${j()}/${n}/view/presentations/${e}`:"N/A"}function er(e,n={}){let{showLinks:t=!1,language:o="en"}=n,r=(s,d)=>s.length>d?s.slice(0,d-1)+"\u2026":s,i=s=>{try{return new Date(s).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(t){let s=new vn({head:[F.cyan("Slug"),F.cyan("Title"),F.cyan("Slides"),F.cyan("Created"),F.cyan("URL")]});for(let d of e)s.push([r(d.slug||d.id.slice(0,8),30),r(d.title||"Untitled",22),String(d.numberOfSlides||"-"),i(d.createdAt),De(d.slug,o)]);return s.toString()}let a=new vn({head:[F.cyan("Slug"),F.cyan("Title"),F.cyan("Slides"),F.cyan("Mode"),F.cyan("Created")],colWidths:[32,28,8,11,18]});for(let s of e)a.push([s.slug||s.id.slice(0,8),s.title||"Untitled",String(s.numberOfSlides||"-"),s.mode||"-",i(s.createdAt)]);return a.toString()}function tr(e){return e.map(n=>n.slug||n.id).join(`
|
|
4
|
+
`)}function nr(e){let n=[...e].sort((r,i)=>{if(r.isDefault&&!i.isDefault)return-1;if(!r.isDefault&&i.isDefault)return 1;let a=r.createdAt?new Date(r.createdAt).getTime():0;return(i.createdAt?new Date(i.createdAt).getTime():0)-a}),t=r=>{if(!r)return"-";try{return new URL(r).href}catch{return r.startsWith("http")?r:`https://${r}`}},o=new vn({head:[F.cyan("Name"),F.cyan("Source"),F.cyan("Color"),F.cyan("Logo"),F.cyan("Default"),F.cyan("ID")]});for(let r of n){let i=r.primaryColor?`${F.bgHex(r.primaryColor)(" ")} ${r.primaryColor}`:"-";o.push([r.name,t(r.sourceUrl),i,r.logoUrl?F.green("\u2713"):F.gray("\u2717"),r.isDefault?F.green("\u2605"):"",r.id])}return o.toString()}function xn(e){try{return new Date(e).toLocaleString()}catch{return e}}function fe(e){console.log(),console.log(F.bold(e)),console.log(F.gray("\u2500".repeat(e.length)))}function R(e,n){console.log(` ${F.gray(e+":")} ${n??"-"}`)}function Oa(e){return JSON.stringify(e,null,2)}function x(e){console.log(Oa(e))}var or=new Pa("capabilities").description("List callable capabilities and their parity state").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{try{let n=await ko();if(e.format==="json"){x(n);return}for(let t of n.capabilities){if(e.format==="quiet"){console.log(t.name);continue}console.log(`${t.name} ${t.state} ${t.milestone}`)}}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}});import{mkdirSync as Ua,writeFileSync as Fa}from"fs";import{dirname as sr,join as _a}from"path";import{Command as Ce}from"commander";import ct from"chalk";import{input as Va,password as Ma,confirm as cr,select as ja}from"@inquirer/prompts";import At from"ora";import Na from"conf";var kt=new Na({projectName:"conceptcraft",configName:"feature-cache"}),Da=3600*1e3,La=1440*60*1e3;function rr(e){let n=0;for(let t=0;t<e.length;t++){let o=e.charCodeAt(t);n=(n<<5)-n+o,n=n&n}return n.toString(16)}function ir(){if(!Ne())return null;let e=kt.get("featureFlags");if(!e)return null;let n=rr(be());if(e.apiKeyHash&&e.apiKeyHash!==n)return ke(),null;let t=Date.now()-e.fetchedAt;return t>La?null:(t>Da&&Sn(),e.flags)}function Sn(){Re().catch(()=>{})}async function Re(){let e=await Fo(),n=be();return kt.set("featureFlags",{flags:e,fetchedAt:Date.now(),apiKeyHash:n?rr(n):void 0}),e}function ke(){kt.delete("featureFlags")}function ar(){return kt.path}var dr=new Ce("config").description("Manage CLI configuration").addCommand(new Ce("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(ct.bold(`${g.displayName} CLI Configuration`)),console.log(ct.gray("\u2500".repeat(35))),console.log();try{let e=await Ma({message:"Enter your API key:",mask:"*",validate:o=>!o||o.trim().length===0?"API key is required":mn(o.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(ln(e.trim()),await cr({message:`Use a custom API URL? (default: ${g.apiUrl.replace("https://","")})`,default:!1})){let o=await Va({message:"Enter API URL:",default:j(),validate:r=>{try{return new URL(r),!0}catch{return"Invalid URL format"}}});un(o)}console.log();let t=At("Verifying API key...").start();try{let o=await we();if(t.succeed("API key verified!"),console.log(),m(`Logged in as: ${o.user.email}`),o.teams.length===0)_("No teams found for this user.");else if(o.teams.length===1){let r=o.teams[0];Pe(r.id),m(`Team: ${r.name} (${r.planName})`)}else{console.log(),m(`You have access to ${o.teams.length} teams.`);let r=await ja({message:"Select your default team:",choices:o.teams.map(a=>({name:`${a.name} (${a.planName}) - ${a.role}${a.isCurrent?" [current]":""}`,value:a.id})),default:o.currentTeam?.id});Pe(r);let i=o.teams.find(a=>a.id===r);S(`Selected team: ${i?.name}`)}try{await Re()}catch{}}catch(o){t.fail("Failed to verify API key"),_(`Could not verify API key: ${o instanceof Error?o.message:String(o)}`),_(`You may need to set the team ID manually: ${g.commands[0]} config set team-id <id>`)}console.log(),S("Configuration saved!"),m(`Config file: ${it()}`),console.log()}catch(e){if(e.name==="ExitPromptError"){console.log(),m("Configuration cancelled.");return}throw e}})).addCommand(new Ce("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async e=>{let n=yo();if(fe("Current Configuration"),console.log(),R("API Key",Co()??ct.red("Not set")),R("API URL",n.apiUrl),R("Default Team ID",n.defaultTeamId??ct.gray("Not set")),console.log(),R("Config file",it()),e.verify&&n.apiKey){console.log();let t=At("Verifying...").start();try{let o=await we();t.succeed("Verified"),console.log(),R("User",o.user.email),o.currentTeam&&R("Current Team",`${o.currentTeam.name} (${o.currentTeam.planName})`),o.teams.length>1&&R("Total Teams",String(o.teams.length))}catch(o){t.fail("Verification failed"),_(o instanceof Error?o.message:String(o))}}console.log()})).addCommand(new Ce("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(e,n)=>{switch(e){case"api-key":mn(n)||(c("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),ln(n),ke(),S("API key updated"),Re().catch(()=>{});break;case"api-url":try{new URL(n),un(n),S(`API URL set to: ${n}`)}catch{c("Invalid URL format"),process.exit(6)}break;case"team-id":Pe(n),S(`Default team ID set to: ${n}`);break;default:c(`Unknown config key: ${e}`),console.log(ct.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new Ce("clear").description("Clear all configuration").action(async()=>{try{await cr({message:"Are you sure you want to clear all configuration?",default:!1})?(yt(),ke(),S("Configuration cleared")):m("Cancelled")}catch{m("Cancelled")}})).addCommand(new Ce("refresh").description("Refresh cached feature flags").action(async()=>{let e=At("Refreshing feature flags...").start();try{await Re(),e.succeed("Feature flags refreshed"),m(`Run '${g.commands[0]} --help' to see updated commands`)}catch(n){e.fail("Failed to refresh"),c(n instanceof Error?n.message:String(n)),process.exit(1)}})).addCommand(new Ce("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(e=>{e.cache?console.log(ar()):console.log(it())})).addCommand(new Ce("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let e=At("Pulling settings...").start();try{let n=await ge(),t=await fetch(`${j()}/api/cli/settings`,{headers:n});if(!t.ok)throw new Error(`Request failed (HTTP ${t.status})`);let o=await t.text(),r=_a(sr(it()),"settings.toml");Ua(sr(r),{recursive:!0}),Fa(r,o,"utf8"),e.succeed("Settings pulled"),m(`Written to ${r}`)}catch(n){e.fail("Failed to pull settings"),c(n instanceof Error?n.message:String(n)),process.exit(1)}}));import{Command as qa}from"commander";import{confirm as Ba}from"@inquirer/prompts";var lr=new qa("delete").description("Delete a presentation").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --force","Skip confirmation prompt").option("-q, --quiet","Suppress output").action(async(e,n)=>{if(await P(),!n.force)try{if(!await Ba({message:`Are you sure you want to delete presentation "${e}"?`,default:!1})){n.quiet||_("Deletion cancelled");return}}catch{n.quiet||_("Deletion cancelled");return}try{await Oo(e),n.quiet||S(`Presentation "${e}" deleted`)}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as Le}from"commander";import mr from"chalk";import Ga from"ora";import{createParser as Zu}from"eventsource-parser";import tm from"chalk";import om from"ora";async function ur(e,n={}){let t=e.body?.getReader();if(!t)throw new Error("Response body is not readable");let o=new TextDecoder,r="",i=!1;for(;!i;){let a=await t.read();if(i=a.done,a.value){let s=o.decode(a.value,{stream:!0});r+=s,n.quiet||process.stdout.write(s)}}return n.quiet||console.log(),r}function Wa(){return new Le("blog").description("Generate a blog post from a presentation").argument("<slug>","Presentation slug").option("--words <count>","Target word count (50-2000)","300").option("--tone <tone>","Writing tone (professional, casual, educational)","professional").option("--audience <text>","Target audience description").option("-f, --format <format>","Output format (human, json, markdown)","human").option("--instructions <text>","Custom instructions for the blog").option("--no-images","Exclude image references").option("--toc","Include table of contents").action(async(e,n)=>{await P();let t=parseInt(n.words,10);(isNaN(t)||t<50||t>2e3)&&(c("Word count must be between 50 and 2000"),process.exit(6));let o=["professional","casual","educational"];o.includes(n.tone)||(c(`Invalid tone. Valid options: ${o.join(", ")}`),process.exit(6));let r=Ga("Fetching presentation...").start();try{let i=await Se(e);r.text="Generating blog post...";let a=await _o(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:t,tone:n.tone,targetAudience:n.audience??"General Audience",customInstructions:n.instructions??"",includeImages:!n.noImages,includeTableOfContents:n.toc??!1}),s=await ur(a,{quiet:!0});r.succeed("Blog generated"),n.format==="json"?console.log(JSON.stringify({presentationId:e,title:i.title,wordCount:t,tone:n.tone,content:s},null,2)):n.format==="markdown"?console.log(s):(console.log(),console.log(mr.bold(`Blog: ${i.title}`)),console.log(mr.gray("\u2500".repeat(40))),console.log(),console.log(s),console.log())}catch(i){r.fail("Generation failed"),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}})}function Ha(){return new Le("tweets").description("Generate tweets from a presentation").argument("<slug>","Presentation slug").option("--count <n>","Number of tweets to generate","5").option("-f, --format <format>","Output format (human, json)","human").action(async(e,n)=>{await P(),m("Tweet generation coming soon.")})}function Ja(){return new Le("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P(),m("LinkedIn carousel generation coming soon.")})}function za(){return new Le("questions").description("Generate questions for a presentation").argument("<slug>","Presentation slug").option("--count <n>","Number of questions","10").option("-f, --format <format>","Output format (human, json)","human").action(async(e,n)=>{await P(),m("Question generation coming soon.")})}function Xa(){return new Le("cheatsheet").description("Generate a presenter cheat sheet").argument("<slug>","Presentation slug").option("--mode <mode>","Cheat sheet mode (qa-prep, talking-points)","qa-prep").option("-f, --format <format>","Output format (human, json, markdown)","human").action(async(e,n)=>{await P(),m("Cheat sheet generation coming soon.")})}function pr(){let e=new Le("derive").description("Generate derivative content from a presentation"),n=ir();return n&&(n.deckToBlog&&e.addCommand(Wa()),n.deckToTweets&&e.addCommand(Ha()),n.linkedInCarousel&&e.addCommand(Ja()),n.redTeamQuestions&&e.addCommand(za()),n.presenterCheatSheet&&e.addCommand(Xa())),e}import{Command as Ya}from"commander";import{writeFile as Ka}from"fs/promises";import{resolve as gr}from"path";import Qa from"ora";var fr=new Ya("export").description("Export a presentation to ZIP").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-o, --output <path>","Output file path").option("--include-images","Include images (default: true)",!0).option("--include-branding","Include branding (default: true)",!0).option("--no-external","Skip external image downloads").action(async(e,n)=>{await P();let t=Qa("Fetching presentation...").start();try{let o=await Se(e),r=o.title||e,i=o.id,a=e.replace(/[^a-z0-9-]/gi,"_").toLowerCase().substring(0,50),s=new Date().toISOString().split("T")[0],d=`${a}_${s}.zip`,u=n.output?gr(n.output):gr(process.cwd(),d);t.text=`Exporting "${r}"...`;let p=await Po(i,{includeImages:n.includeImages,includeBranding:n.includeBranding,includeExternal:!n.noExternal});t.text="Saving file...",await Ka(u,Buffer.from(p)),t.succeed("Export complete!"),console.log(),m(`File saved: ${u}`),m(`Size: ${Za(p.byteLength)}`),console.log()}catch(o){t.fail("Export failed"),c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});function Za(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}import{Command as es}from"commander";import Cn from"chalk";var hr=new es("ideas").description("Generate presentation topic ideas").option("--context <text>","Custom context for idea generation").option("--count <n>","Number of ideas to generate","5").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P(),m("Idea generation is available in the web dashboard."),console.log(),console.log(Cn.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(Cn.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(Cn.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{Command as ts}from"commander";import{readFile as ns}from"fs/promises";import{resolve as os,basename as rs}from"path";import is from"ora";var yr=new ts("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");yr._hidden=!0;var br=yr.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(e,n)=>{await P();try{(await we()).user.role!=="admin"&&(c("This command is only available to administrators"),process.exit(2))}catch{c("Failed to verify permissions"),process.exit(2)}let t=os(e),o=rs(t);o.endsWith(".zip")||(c("File must be a ZIP archive"),process.exit(6));let r=is("Reading file...").start();try{let i=await ns(t);n.dryRun?r.text="Validating...":r.text="Importing presentation...";let a=await No(i,o,{dryRun:n.dryRun});if(a.success){if(n.dryRun)r.succeed("Validation passed!"),console.log(),m("The file is valid and can be imported."),a.statistics&&(console.log(),R("Slides",String(a.statistics.slidesImported)),R("Images",String(a.statistics.imagesUploaded)));else if(r.succeed("Import complete!"),console.log(),R("Presentation ID",a.presentationId??"N/A"),R("Document ID",a.documentId??"N/A"),a.statistics&&(R("Slides imported",String(a.statistics.slidesImported)),R("Images uploaded",String(a.statistics.imagesUploaded)),R("Time",`${a.statistics.totalTimeMs}ms`)),a.presentationId){let s=j();R("View URL",`${s}/p/${a.presentationId}`)}if(a.warnings&&a.warnings.length>0){console.log();for(let s of a.warnings)_(s)}console.log()}else{if(r.fail("Import failed"),console.log(),a.errors)for(let s of a.errors)c(`${s.type}: ${s.message}`);process.exit(1)}}catch(i){r.fail("Import failed"),i.code==="ENOENT"&&(c(`File not found: ${t}`),process.exit(3)),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}});import{Command as as}from"commander";var wr=new as("list").description("List presentations").option("-n, --limit <count>","Number of results to return","20").option("-f, --format <format>","Output format (table, json, ids)","table").option("--sort <field>","Sort by field (created, updated, title)").option("--team-id <id>","Team ID (uses default if not specified)").option("-d, --detail","Show detailed output including URLs").option("-l, --language <lang>","Language for URLs","en").action(async e=>{await P();let n=parseInt(e.limit,10);(isNaN(n)||n<1)&&(c("Invalid limit value"),process.exit(6));let t=e.teamId??ht();t||(c("`Team ID required. Set a default with '${brand.commands[0]} config set team-id <id>' or use --team-id`"),process.exit(6));try{let o=await Eo(t,n);if(o.length===0){e.format==="json"?console.log(JSON.stringify([])):e.format!=="ids"&&m("No presentations found");return}switch(e.sort&&o.sort((r,i)=>{switch(e.sort){case"created":return new Date(i.createdAt).getTime()-new Date(r.createdAt).getTime();case"title":return(r.title||"").localeCompare(i.title||"");default:return 0}}),e.format){case"json":console.log(JSON.stringify(o,null,2));break;case"ids":console.log(tr(o));break;default:console.log(er(o,{showLinks:e.detail,language:e.language}));break}}catch(o){c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});import{Command as ss}from"commander";import vr from"chalk";import xr from"ora";import Sr from"http";import{randomBytes as Cr,createHash as cs}from"crypto";import ds from"open";var ls=`${g.displayName} CLI`,us=8765,ms=8775;function ps(){return Cr(32).toString("base64url")}function gs(e){return cs("sha256").update(e).digest("base64url")}function fs(){return Cr(16).toString("hex")}async function hs(e,n){for(let t=e;t<=n;t++)try{return await new Promise((o,r)=>{let i=Sr.createServer();i.listen(t,()=>{i.close(()=>o())}),i.on("error",r)}),t}catch{continue}throw new Error(`No available port found between ${e} and ${n}`)}async function ys(e){let n=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!n.ok)throw new Error(`Failed to fetch OAuth metadata: ${n.status}`);return n.json()}async function bs(e,n){let t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:ls,redirect_uris:[n],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:"presentations:read presentations:write"})});if(!t.ok){let o=await t.text();throw new Error(`Client registration failed: ${o}`)}return t.json()}async function ws(e,n,t,o,r){let i=new URLSearchParams({grant_type:"authorization_code",code:n,redirect_uri:o,client_id:r,code_verifier:t}),a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!a.ok){let s=await a.text();throw new Error(`Token exchange failed: ${s}`)}return a.json()}function vs(e,n){return new Promise((t,o)=>{let r,i=!1,a=()=>{i||(i=!0,clearTimeout(r),process.off("SIGINT",s),process.off("SIGTERM",s),d.close())},s=()=>{a(),o(new Error("Login cancelled"))},d=Sr.createServer((u,p)=>{let w=new URL(u.url||"",`http://localhost:${e}`);if(w.pathname!=="/callback"){p.writeHead(404),p.end("Not found");return}let I=w.searchParams.get("code"),f=w.searchParams.get("state"),T=w.searchParams.get("error"),b=w.searchParams.get("error_description");if(p.writeHead(200,{"Content-Type":"text/html"}),T){p.end(`
|
|
5
5
|
<!DOCTYPE html>
|
|
6
6
|
<html>
|
|
7
7
|
<head><title>Login Failed</title></head>
|
|
8
8
|
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
9
9
|
<h1 style="color: #dc2626;">Login Failed</h1>
|
|
10
|
-
<p>${b||
|
|
10
|
+
<p>${b||T}</p>
|
|
11
11
|
<p>You can close this window.</p>
|
|
12
12
|
</body>
|
|
13
13
|
</html>
|
|
14
|
-
`),a(),o(new Error(b||
|
|
14
|
+
`),a(),o(new Error(b||T));return}if(!I||!f){p.end(`
|
|
15
15
|
<!DOCTYPE html>
|
|
16
16
|
<html>
|
|
17
17
|
<head><title>Login Failed</title></head>
|
|
@@ -40,24 +40,24 @@ var h={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"C
|
|
|
40
40
|
<p>You can close this window and return to the terminal.</p>
|
|
41
41
|
</body>
|
|
42
42
|
</html>
|
|
43
|
-
`),a(),t({code:I,state:f})});
|
|
44
|
-
`)[0]??"";t(a?{bin:n,version:a}:null)})})}var
|
|
43
|
+
`),a(),t({code:I,state:f})});d.listen(e),process.once("SIGINT",s),process.once("SIGTERM",s),r=setTimeout(()=>{a(),o(new Error("Login timed out - no callback received within 5 minutes"))},300*1e3)})}async function xs(e,n){let t=await fetch(`${e}/api/cli/whoami`,{headers:{Authorization:`Bearer ${n}`}});if(!t.ok)throw new Error(`Failed to fetch user info: ${t.status}`);return t.json()}async function Ss(e){let n=j(),t=xr("Discovering OAuth server...").start();try{let o=await ys(n);t.succeed("Connecting to "+n);let r=await hs(us,ms),i=`http://localhost:${r}/callback`;console.log("Redirect URI: "+i),console.log("Authorization endpoint: "+o.authorization_endpoint),console.log("Token endpoint: "+o.token_endpoint),console.log("Registration endpoint: "+o.registration_endpoint);let a=vt(),s=xt();if(!a){let v=await bs(o.registration_endpoint,i);a=v.client_id,s=v.client_secret,xo(a,s)}let d=ps(),u=gs(d),p=fs(),w=new URLSearchParams({client_id:a,redirect_uri:i,response_type:"code",scope:"presentations:read presentations:write",state:p,code_challenge:u,code_challenge_method:"S256"}),I=`${o.authorization_endpoint}?${w}`;console.log("Authorization URL: "+I),e.browser?(m("Opening browser..."),await ds(I)):(console.log(vr.bold("Open this URL in your browser:")),console.log(vr.cyan(I)));let f=vs(r,p),{code:T}=await f;t=xr("Completing login...").start();let b=await ws(o.token_endpoint,T,d,i,a);bt(b.access_token,b.refresh_token,b.expires_in);let y=await xs(n,b.access_token);t.succeed("Logged in!"),console.log(),R("Logged in as",y.user.email),y.currentTeam&&(Pe(y.currentTeam.id),R("Team",`${y.currentTeam.name} (${y.currentTeam.planName})`));try{await Re()}catch{}console.log(),S("You're all set!"),console.log()}catch(o){throw t.fail("Login failed"),c(o instanceof Error?o.message:String(o)),o}}var Ir=new ss("login").description(`Authenticate with ${g.displayName} (opens browser)`).option("--no-browser","Print URL instead of opening browser").action(async e=>{console.log(),Te()&&(_("You are already logged in."),m(`Run '${g.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await Ss(e),process.exit(0)}catch{process.exit(1)}});import{Command as Cs}from"commander";import{confirm as Is}from"@inquirer/prompts";var Tr=new Cs("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async e=>{console.log();let n=Te(),t=Ne();if(!n&&!t){_("You are not logged in."),console.log();return}if(e.all)try{await Is({message:"Clear all configuration including API key?",default:!1})?(yt(),ke(),S("All configuration cleared.")):m("Cancelled.")}catch{m("Cancelled.")}else wt(),ke(),S("Logged out successfully."),t&&m("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as dc}from"os";import{join as lc}from"path";import de from"chalk";import{Command as uc}from"commander";import{spawn as Ts}from"child_process";import{existsSync as Rs,readdirSync as ks}from"fs";import{homedir as Ar}from"os";import{delimiter as Rr}from"path";import{query as As}from"@anthropic-ai/claude-agent-sdk";function ie(e){if(e===void 0)return null;if(typeof e=="string")return e.length>12e3?`${e.slice(0,12e3)}\u2026`:e;try{let n=JSON.stringify(e);return n.length<=12e3?e:{preview:`${n.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(e).slice(0,12e3)}}function $t(e){let n=typeof e=="string"?e:String(e??"");return n.length>12e3?`${n.slice(0,12e3)}\u2026`:n}function ae(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function U(e){return typeof e=="string"?e:""}function kr(e,n){let t=e.replace(/[/.]/g,"-");return`${Ar()}/.claude/projects/${t}/${n}.jsonl`}function $s(e){try{return ks(`${e}/.nvm/versions/node`).map(n=>`${e}/.nvm/versions/node/${n}/bin`).sort().reverse()}catch{return[]}}function Et(){let e=Ar(),n=[`${e}/.local/bin`,`${e}/.claude/local`,`${e}/.bun/bin`,`${e}/bin`,"/opt/homebrew/bin","/usr/local/bin",...$s(e)],o=(process.env.PATH??"").split(Rr);for(let r of n)o.includes(r)||o.push(r);return o.join(Rr)}async function Ot(e){let n=e??"claude";return new Promise(t=>{let o=Ts(n,["--version"],{env:{...process.env,PATH:Et()},stdio:["ignore","pipe","ignore"]}),r="";o.stdout.on("data",i=>{r+=i.toString("utf8")}),o.on("error",()=>t(null)),o.on("close",i=>{if(i!==0)return t(null);let a=r.trim().split(`
|
|
44
|
+
`)[0]??"";t(a?{bin:n,version:a}:null)})})}var Es=new Set(["","default","best"]);function In(e){let n=e.filter(i=>i.text.trim());if(n.length===0)return"";let t=n[n.length-1],o=n.slice(0,-1);return o.length===0?t.text:`<conversation-history>
|
|
45
45
|
${o.map(i=>`${i.role==="assistant"?"Assistant":"User"}: ${i.text}`).join(`
|
|
46
46
|
|
|
47
47
|
`)}
|
|
48
48
|
</conversation-history>
|
|
49
49
|
|
|
50
|
-
${t.text}`}function
|
|
51
|
-
`)[0]??"";n(i||null)})})}var
|
|
52
|
-
`)}catch{return[]}let t=new Set,o=new Map,r=null;for(let i of n){if(!i.trim())continue;let a;try{a=JSON.parse(i)}catch{continue}let s=ae(a.payload);if(a.type==="response_item"&&s.type==="custom_tool_call"){let
|
|
53
|
-
`);return a===-1?"":i.slice(a+1)}finally{
|
|
54
|
-
`):e&&typeof e=="object"?Object.values(e).map(
|
|
55
|
-
`):""}function
|
|
56
|
-
|
|
57
|
-
`),usage:a}}function
|
|
58
|
-
`,"utf8")}catch{}}function
|
|
59
|
-
`,"utf8")}catch{}}var
|
|
60
|
-
Stopping runner\u2026`)),n.abort()};process.on("SIGINT",t),process.on("SIGTERM",t);try{await
|
|
50
|
+
${t.text}`}function Tn(e,n){return n?e.messages.filter(o=>o.text.trim()).at(-1)?.text??"":In(e.messages)}function Os({abortController:e,input:n,resumeSessionId:t,workspace:o}){let r=(n.modelId??"").trim(),i=n.thinking??null,a={abortController:e,allowedTools:["WebSearch","WebFetch"],cwd:o,env:{...process.env,PATH:Et()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return Es.has(r)||(a.model=r),n.effort&&(a.effort=n.effort),i&&i!=="disabled"&&(a.thinking={display:"summarized",type:i==="enabled"?"enabled":"adaptive"}),t?a.resume=t:n.system?.trim()&&(a.systemPrompt=n.system),a}async function $r(e){let n=Tn(e.input,e.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let t=new AbortController,o=()=>t.abort();e.signal?.addEventListener("abort",o,{once:!0});let r=null,i=null,a=null,s=null,d=null,u=0,p=new Set;try{let f=As({prompt:n,options:Os({abortController:t,input:e.input,resumeSessionId:e.resumeSessionId,workspace:e.workspace})});for await(let T of f){let b=T;if(b.type==="system"&&b.subtype==="init"){typeof b.session_id=="string"&&(i=b.session_id,e.onEvent({eventType:"chat.session",payload:{sessionId:i,sessionPath:kr(e.workspace,i)}})),typeof b.model=="string"&&(r=b.model,e.onEvent({eventType:"chat.model",payload:{modelId:b.model}}));continue}if(b.type==="stream_event"){let y=b.event;if(y?.type!=="content_block_delta")continue;let v=y.delta;if(!v)continue;v.type==="text_delta"&&typeof v.text=="string"?(u+=v.text.length,e.onEvent({eventType:"chat.text.delta",payload:{text:v.text}})):v.type==="thinking_delta"&&typeof v.thinking=="string"&&e.onEvent({eventType:"chat.reasoning.delta",payload:{text:v.thinking}});continue}if(b.type==="assistant"){let y=ae(b.message),v=Array.isArray(y.content)?y.content:[];for(let E of v){let A=ae(E);if(A.type!=="tool_use")continue;let N=U(A.id),C=U(A.name);!N||!C||p.has(N)||(p.add(N),e.onEvent({eventType:"chat.tool.started",payload:{input:ie(A.input),toolCallId:N,toolName:C}}))}continue}if(b.type==="user"){let y=ae(b.message),v=Array.isArray(y.content)?y.content:[];for(let E of v){let A=ae(E);if(A.type!=="tool_result")continue;let N=U(A.tool_use_id);N&&e.onEvent({eventType:"chat.tool.completed",payload:{...A.is_error===!0?{errorText:typeof A.content=="string"?$t(A.content):"Claude tool call failed."}:{},output:ie(A.content),toolCallId:N}})}continue}b.type==="result"&&(typeof b.result=="string"&&(s=b.result),b.usage&&typeof b.usage=="object"&&(a=b.usage),typeof b.session_id=="string"&&(i=b.session_id),(b.is_error===!0||b.subtype!=="success")&&(d=typeof b.result=="string"&&b.result||`Claude turn failed (${String(b.subtype)}).`,e.onEvent({eventType:"chat.error",message:d,payload:{message:d}})))}}finally{e.signal?.removeEventListener("abort",o)}if(e.signal?.aborted)throw new Error("Chat turn cancelled.");if(d)throw new Error(d);let w=s??"";u===0&&w&&e.onEvent({eventType:"chat.text.delta",payload:{text:w}});let I=i?kr(e.workspace,i):null;return{modelId:r,sessionId:i,sessionPath:I&&Rs(I)?I:null,text:w,usage:a}}import{spawn as Ps}from"child_process";import{closeSync as Ns,fstatSync as Ds,openSync as Ls,readdirSync as Us,readSync as Fs}from"fs";import{homedir as _s}from"os";import{join as Er}from"path";import{Codex as Vs}from"@openai/codex-sdk";var Ms=["/Applications/Codex.app/Contents/Resources/codex"];async function Pt(e){let n=e?[e]:["codex",...Ms];for(let t of n){let o=await js(t);if(o)return{bin:t,version:o}}return null}function js(e){return new Promise(n=>{let t=Ps(e,["--version"],{env:{...process.env,PATH:Et()},stdio:["ignore","pipe","ignore"]}),o="";t.stdout.on("data",r=>{o+=r.toString("utf8")}),t.on("error",()=>n(null)),t.on("close",r=>{if(r!==0)return n(null);let i=o.trim().split(`
|
|
51
|
+
`)[0]??"";n(i||null)})})}var qs=24,Bs=4*1024*1024,Nr=new Set(["custom_tool_call","custom_tool_call_output","dynamic_tool_call","function_call"]);function Gs(e){let n;try{n=Ws(e).split(`
|
|
52
|
+
`)}catch{return[]}let t=new Set,o=new Map,r=null;for(let i of n){if(!i.trim())continue;let a;try{a=JSON.parse(i)}catch{continue}let s=ae(a.payload);if(a.type==="response_item"&&s.type==="custom_tool_call"){let d=U(s.call_id),u=U(s.input);d&&s.name==="exec"&&/\btools\.web__run\s*\(/.test(u)&&(t.add(d),r=d);continue}if(a.type==="event_msg"&&s.type==="web_search_end"){let d=U(s.call_id);if(!d||!r)continue;let u=U(s.query),p=ae(s.action),I={action:{...p,...u&&!U(p.query)?{query:u}:{}},query:u,sources:Or(s.results),toolCallId:d},f=o.get(r)??[];f.push(I),o.set(r,f);continue}if(a.type==="response_item"&&s.type==="custom_tool_call_output"){let d=U(s.call_id);if(!d||!t.has(d))continue;let u=Or(s.output);for(let p of o.get(d)??[])p.sources.length===0&&(p.sources=u);r===d&&(r=null)}}return Array.from(o.values()).flat()}function Ws(e){let n=Ls(e,"r");try{let t=Ds(n).size,o=Math.max(0,t-Bs),r=Buffer.alloc(t-o);Fs(n,r,0,r.length,o);let i=r.toString("utf8");if(o===0)return i;let a=i.indexOf(`
|
|
53
|
+
`);return a===-1?"":i.slice(a+1)}finally{Ns(n)}}function Or(e){let t=An(e).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],o=new Set,r=[];for(let i of t){let a=i.replace(/[.,;:!?]+$/,"");try{let s=new URL(a);if(s.protocol!=="http:"&&s.protocol!=="https:"||o.has(s.href))continue;if(o.add(s.href),r.push({type:"url",url:s.href}),r.length>=qs)break}catch{}}return r}function An(e){return typeof e=="string"?e:Array.isArray(e)?e.map(An).join(`
|
|
54
|
+
`):e&&typeof e=="object"?Object.values(e).map(An).join(`
|
|
55
|
+
`):""}function Rn(e,n){let t=ae(e),o=U(t.type),r=U(t.id),i=U(t.call_id)||U(t.tool_call_id),a=Nr.has(o)?i||r:r||i;if(!a)return null;if(o==="command_execution"){let s=U(t.command),d=U(t.status),u={exitCode:typeof t.exit_code=="number"?t.exit_code:null,output:ie(t.aggregated_output)};return{...n&&d==="failed"?{errorText:$t(t.aggregated_output)||"Command failed."}:{},input:{command:s},...n?{output:u}:{},toolCallId:a,toolName:"Bash"}}if(o==="mcp_tool_call"){let s=ae(t.error);return{...n&&U(s.message)?{errorText:U(s.message)}:{},input:ie(t.arguments),...n?{output:ie(t.result??{status:t.status??"completed"})}:{},toolCallId:a,toolName:U(t.tool)||U(t.name)||"Codex tool"}}if(o==="web_search"){let s=U(t.query);return{input:{query:s},...n?{output:{query:s}}:{},toolCallId:a,toolName:"web_search"}}if(o==="file_change"){let s=U(t.status);return{...n&&s==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:ie(t.changes)},...n?{output:{changes:ie(t.changes),status:s}}:{},toolCallId:a,toolName:"ApplyPatch"}}if(o==="custom_tool_call_output")return{input:{},...n?{output:ie(t.output)}:{},toolCallId:a,toolName:"Codex tool"};if(o==="custom_tool_call"||o==="dynamic_tool_call"||o==="function_call"){let s=U(t.name)||U(t.tool)||"Codex tool",d=t.input??t.arguments??{};return{input:s==="exec"&&typeof d=="string"?{command:d}:ie(d),...n?{output:ie(t.output??t.result??{status:t.status??"completed"})}:{},toolCallId:a,toolName:s}}return null}function kn(e,n=Er(_s(),".codex","sessions")){try{let o=Us(n,{recursive:!0}).find(r=>typeof r=="string"&&r.endsWith(`${e}.jsonl`));return o?Er(n,o):null}catch{return null}}function Hs(e,n){return n?Tn(e,n):In(e.messages)}function Js(e,n,t=g.codexSelfConnectorAppId){let o=n.system?.trim(),r={...o?{developer_instructions:o}:{},...t?{apps:{[t]:{enabled:!1}}}:{}};return{codexPathOverride:e,...Object.keys(r).length>0?{config:r}:{}}}var zs=new Set(["minimal","low","medium","high","xhigh"]);function Xs(e,n){let t={networkAccessEnabled:!0,sandboxMode:"workspace-write",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:n},o=(e.modelId??"").trim();return o&&o!=="default"&&(t.model=o),e.effort&&zs.has(e.effort)&&(t.modelReasoningEffort=e.effort),t}async function Dr(e){let n=Hs(e.input,e.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let t=new Vs(Js(e.bin,e.input)),o=Xs(e.input,e.workspace),r=e.resumeSessionId?t.resumeThread(e.resumeSessionId,o):t.startThread(o),i=e.resumeSessionId??null,a=null,s=null,d=[],u=new Set,p=new Set,w=null,I=b=>{w??=kn(b,e.sessionsRoot),e.onEvent({eventType:"chat.session",payload:{sessionId:b,sessionPath:w}})},f=b=>{i&&(w??=kn(i,e.sessionsRoot));let y=w?Gs(w):[],v=U(ae(b.input).query),E=Pr(v),A=y.find(N=>!u.has(N.toolCallId)&&Pr(N.query)===E)??y.find(N=>!u.has(N.toolCallId));A&&u.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:{...b,output:A?{action:A.action,query:A.query,sources:A.sources}:{action:{query:v,type:"search"},sourceListUnavailable:!0,sources:[]}}})},{events:T}=await r.runStreamed(n);i&&I(i);for await(let b of T){if(e.signal?.aborted)throw await T.return?.(void 0),new Error("Chat turn cancelled.");let y=b;if(y.type==="thread.started"){typeof y.thread_id=="string"&&(i=y.thread_id,I(y.thread_id));continue}if(y.type==="item.started"){let v=Rn(y.item,!1);if(v){e.onEvent({eventType:"chat.tool.started",payload:v});let E=ae(y.item);if(Nr.has(U(E.type))&&U(E.status)==="completed"){let A=Rn(E,!0);A&&(p.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:A}))}}continue}if(y.type==="item.completed"){let v=y.item;if(!v)continue;if(v.type==="agent_message"&&typeof v.text=="string")d.push(v.text),e.onEvent({eventType:"chat.text.delta",payload:{text:v.text}});else if(v.type==="reasoning"&&typeof v.text=="string")e.onEvent({eventType:"chat.reasoning.delta",payload:{text:v.text}});else{let E=Rn(v,!0);E&&(v.type==="web_search"?f(E):v.type==="custom_tool_call"&&p.has(E.toolCallId)||e.onEvent({eventType:"chat.tool.completed",payload:E}))}continue}if(y.type==="turn.completed"){y.usage&&typeof y.usage=="object"&&(a=y.usage);continue}if(y.type==="turn.failed"){let v=y.error;s=typeof v?.message=="string"&&v.message||"Codex turn failed.",e.onEvent({eventType:"chat.error",message:s,payload:{message:s}})}}if(s)throw new Error(s);return i=r.id??i,i&&(w??=kn(i,e.sessionsRoot)),{modelId:e.input.modelId??null,sessionId:i,sessionPath:w,text:d.join(`
|
|
56
|
+
|
|
57
|
+
`),usage:a}}function Pr(e){return e.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as ec}from"crypto";import{mkdir as tc}from"fs/promises";import{hostname as Dt,platform as nc}from"os";import{join as oc}from"path";var Ue=class extends Error{constructor(t,o,r=!1){super(t);this.statusCode=o;this.reRegister=r;this.name="RunnerApiError"}statusCode;reRegister};async function Fe(e,n={}){let t=await ge();n.body!==void 0&&(t["Content-Type"]="application/json");let o=new AbortController,r=setTimeout(()=>o.abort(),n.timeoutMs??3e4),i=()=>o.abort();n.signal?.addEventListener("abort",i,{once:!0});try{let a=await fetch(`${j()}${e}`,{body:n.body!==void 0?JSON.stringify(n.body):void 0,headers:t,method:n.method??"GET",signal:o.signal}),s=await a.text(),d={};try{d=s?JSON.parse(s):{}}catch{d={error:s.slice(0,300)}}if(!a.ok)throw new Ue(typeof d.error=="string"?d.error:`Runner API returned ${a.status}`,a.status,d.reRegister===!0);return d}finally{clearTimeout(r),n.signal?.removeEventListener("abort",i)}}async function Lr(e){await Fe("/api/runner/register",{body:e,method:"POST",timeoutMs:15e3})}async function Ur(e,n){return(await Fe(`/api/runner/work?runnerId=${encodeURIComponent(e)}`,{signal:n,timeoutMs:28e3})).job??null}async function Fr(e){await Fe("/api/runner/heartbeat",{body:{runnerId:e},method:"POST",timeoutMs:1e4})}async function _r(e,n){return{cancelRequested:(await Fe(`/api/runner/jobs/${encodeURIComponent(e)}/events`,{body:{events:n},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function $n(e,n,t){await Fe(`/api/runner/jobs/${encodeURIComponent(e)}/complete`,{body:{result:t,runnerId:n},method:"POST",timeoutMs:15e3})}async function Nt(e,n,t,o=!0){await Fe(`/api/runner/jobs/${encodeURIComponent(e)}/fail`,{body:{message:t,retryable:o,runnerId:n},method:"POST",timeoutMs:15e3})}import{mkdirSync as Ys,readFileSync as Ks,writeFileSync as Vr}from"fs";import{dirname as Qs,join as Zs}from"path";function En(e){return Zs(e,"sessions.json")}function On(e){try{let n=Ks(En(e),"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}return{}}function Mr(e,n,t){return n?On(e)[n]?.[t]??null:null}function jr(e,n,t,o){if(!(!n||!o))try{let r=En(e);Ys(Qs(r),{recursive:!0});let i=On(e);i[n]={...i[n],[t]:o},Vr(r,`${JSON.stringify(i,null," ")}
|
|
58
|
+
`,"utf8")}catch{}}function qr(e,n,t){if(n)try{let o=On(e);if(!o[n])return;delete o[n][t],Vr(En(e),`${JSON.stringify(o,null," ")}
|
|
59
|
+
`,"utf8")}catch{}}var rc=300,ic=3e4;async function Br(e){let[n,t]=await Promise.all([Ot(e.claudeBin),Pt(e.codexBin)]);if(!n&&!t)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");n?e.log(`Claude Code detected: ${n.version} (${n.bin})`):e.log("Claude Code not found \u2014 Claude turns will be declined."),t?e.log(`Codex detected: ${t.version} (${t.bin})`):e.log("Codex not found \u2014 Codex turns will be declined.");let o=[...n?["claude-code"]:[],...t?["codex"]:[]],r=`${Dt().split(".")[0]}-${ec().slice(0,8)}`,i=()=>Lr({capabilities:["chat_turn","proof"],claudeCodeVersion:n?.version??null,cliVersion:e.version,codexVersion:t?.version??null,hostname:Dt(),platform:nc(),runnerId:r,runtimes:o});for(await i(),e.log(`Registered as ${r} (runtimes: ${o.join(", ")}). Waiting for work\u2026`);!e.signal?.aborted;){let a=null;try{a=await Ur(r,e.signal)}catch(s){if(e.signal?.aborted)break;if(s instanceof Ue&&s.reRegister){e.log("Server asked for re-registration."),await i().catch(()=>{});continue}e.log(`Work poll failed (${s instanceof Error?s.message:"unknown"}); retrying\u2026`),await cc(e.pollBackoffMs??5e3,e.signal);continue}if(!a){if(e.once)continue;continue}if(e.log(`Claimed ${a.jobType} job ${a.runId}.`),await ac({claude:n,codex:t,job:a,options:e,runnerId:r}),e.once)break}}async function ac({claude:e,codex:n,job:t,options:o,runnerId:r}){let i=new AbortController,a=()=>i.abort();o.signal?.addEventListener("abort",a,{once:!0});let s=setInterval(()=>{Fr(r).catch(()=>{})},ic),d=[],u=!1,p=async()=>{if(u||d.length===0)return;u=!0;let f=d.splice(0,100);try{let{cancelRequested:T}=await _r(t.runId,f);T&&i.abort()}catch(T){T instanceof Ue&&T.statusCode===409&&i.abort()}finally{u=!1}},w=setInterval(()=>{p()},rc),I=f=>{d.push(f)};try{if(t.jobType==="runner.proof"){let f=typeof t.input.message=="string"?t.input.message:"proof";I({eventType:"proof.echo",payload:{message:f}}),await Pn(p,d),await $n(t.runId,r,{echo:f}),o.log(`Proof job ${t.runId} completed.`);return}if(t.jobType==="runner.chat_turn"){let f=t.input.runtime==="codex"?"codex":"claude-code",T=f==="codex"?n&&{detection:n,run:Dr}:e&&{detection:e,run:$r};if(!T){await Nt(t.runId,r,f==="codex"?"Codex is not available on this machine. Install the Codex app or CLI and log in, then retry.":"Claude Code is not available on this machine. Install it and log in, then retry.",!1);return}let b=typeof t.input.chatId=="string"&&t.input.chatId?t.input.chatId:null,y=oc(o.workspaceRoot,"chats",b??t.runId);await tc(y,{recursive:!0});let v=sc(t.input),E=C=>I({eventType:C.eventType,message:C.message??null,payload:C.eventType==="chat.session"?{host:Dt(),runtime:f,runtimeVersion:T.detection.version,...C.payload??{}}:C.payload??{}}),A=Mr(o.workspaceRoot,b,f),N;try{N=await T.run({bin:T.detection.bin,input:v,onEvent:E,resumeSessionId:A,signal:i.signal,workspace:y})}catch(C){if(!A||i.signal.aborted)throw C;o.log(`Resume of ${f} session failed (${C instanceof Error?C.message:"unknown"}); retrying fresh.`),qr(o.workspaceRoot,b,f),N=await T.run({bin:T.detection.bin,input:v,onEvent:E,resumeSessionId:null,signal:i.signal,workspace:y})}jr(o.workspaceRoot,b,f,N.sessionId),I({eventType:"chat.session",payload:{host:Dt(),runtime:f,runtimeVersion:T.detection.version,sessionId:N.sessionId,sessionPath:N.sessionPath}}),await Pn(p,d),await $n(t.runId,r,{modelId:N.modelId,runtime:f,runtimeVersion:T.detection.version,sessionId:N.sessionId,sessionPath:N.sessionPath,text:N.text,usage:N.usage??{}}),o.log(`Chat turn ${t.runId} (${f}) completed.`);return}await Nt(t.runId,r,`This runner does not support ${t.jobType} jobs. Update the desktop app / CLI.`,!1)}catch(f){let T=f instanceof Error?f.message:"Local runner job crashed.";o.log(`Job ${t.runId} failed: ${T}`),await Pn(p,d).catch(()=>{}),await Nt(t.runId,r,T).catch(()=>{})}finally{clearInterval(w),clearInterval(s),o.signal?.removeEventListener("abort",a)}}function sc(e){let n=Array.isArray(e.messages)?e.messages.map(t=>{if(!t||typeof t!="object")return null;let o=t;return{role:typeof o.role=="string"?o.role:"user",text:typeof o.text=="string"?o.text:""}}).filter(t=>!!t):[];return{effort:typeof e.effort=="string"?e.effort:null,messages:n,modelId:typeof e.modelId=="string"?e.modelId:null,system:typeof e.system=="string"?e.system:null,thinking:typeof e.thinking=="string"?e.thinking:null}}async function Pn(e,n){for(;n.length>0;)await e(),n.length>0&&await new Promise(t=>setTimeout(t,25))}function cc(e,n){return e<=0||n?.aborted?Promise.resolve():new Promise(t=>{let o=setTimeout(r,e);function r(){clearTimeout(o),n?.removeEventListener("abort",r),t()}n?.addEventListener("abort",r,{once:!0})})}function mc(){return lc(dc(),`.${g.commands[0]}-runner`,"runs")}var Lt=new uc("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");Lt.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[e,n]=await Promise.all([Ot(),Pt()]);if(console.log(e?de.green(`\u2713 Claude Code ${e.version}`):de.red("\u2717 Claude Code not found on PATH")),console.log(n?de.green(`\u2713 Codex ${n.version} (${n.bin})`):de.red("\u2717 Codex not found (PATH or Codex.app)")),!ce()){console.log(de.red(`\u2717 Not logged in. Run '${g.commands[0]} login' first.`)),process.exitCode=2;return}try{let t=await we();console.log(de.green(`\u2713 Logged in as ${t.user.email}`))}catch(t){console.log(de.red(`\u2717 Auth check failed: ${t instanceof Error?t.message:"unknown"}`)),process.exitCode=2}});Lt.command("start").description("Start the local runner (register + wait for work)").option("--once","Execute a single job, then exit").option("--workspace <dir>","Workspace root for job scratch directories").option("--claude-bin <path>","Path to the claude binary").option("--codex-bin <path>","Path to the codex binary").action(async e=>{ce()||(console.error(de.red(`Not authenticated. Run '${g.commands[0]} login' first.`)),process.exit(2));let n=new AbortController,t=()=>{console.log(de.gray(`
|
|
60
|
+
Stopping runner\u2026`)),n.abort()};process.on("SIGINT",t),process.on("SIGTERM",t);try{await Br({claudeBin:e.claudeBin,codexBin:e.codexBin,log:o=>console.log(de.gray(`[runner] ${o}`)),once:e.once,signal:n.signal,version:"0.3.13",workspaceRoot:e.workspace??mc()})}catch(o){console.error(de.red(o instanceof Error?o.message:String(o))),process.exit(1)}});import{Command as bc}from"commander";import V from"chalk";function Ut(e){let{name:n,cmd:t}=e,o=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return`---
|
|
61
61
|
name: ${n}
|
|
62
62
|
description: CLI with TTS (text-to-speech), AI music generation, sound effects, stock image/video search, audio mixing, URL scraping, and branding. Use when user asks for voiceover, narration, background music, sound effects, stock footage, or needs to scrape a website.
|
|
63
63
|
---
|
|
@@ -130,7 +130,7 @@ ${t} whoami
|
|
|
130
130
|
### Config
|
|
131
131
|
\`${t} config show\` \u2192 [references/config.md](references/config.md)
|
|
132
132
|
|
|
133
|
-
`}function
|
|
133
|
+
`}function Ft(e){let{name:n,cmd:t,mode:o="standalone"}=e,r=o==="studio";return`---
|
|
134
134
|
name: ${n}-video
|
|
135
135
|
description: Orchestrates video creation by coordinating specialized agents for branding, audio, and scene building. Gathers context, writes briefs, generates plans, and assembles Remotion videos. Use when user says "create a video", "make a promo", "product demo", "explainer video", "marketing video", "gather video assets", "video for my project", or "TikTok/Reels content".
|
|
136
136
|
---
|
|
@@ -644,7 +644,7 @@ The \`${t}\` CLI has tools for working with individual assets directly. This is
|
|
|
644
644
|
- **Audio mixing:** \`${t} mix\` \u2014 combine voice, music, and video tracks.
|
|
645
645
|
|
|
646
646
|
During the main workflow, branding and audio are handled by their dedicated agents. But for one-off fixes or user requests outside the workflow, use these commands directly.
|
|
647
|
-
`}function
|
|
647
|
+
`}function _t(e){let{name:n,cmd:t}=e;return`---
|
|
648
648
|
name: ${n}-presentation
|
|
649
649
|
description: Use when user asks to create presentations, slides, decks, pitch decks.
|
|
650
650
|
Researches the topic, gathers context, and generates AI-powered presentations via CLI.
|
|
@@ -864,7 +864,7 @@ ${t} import ./presentation.zip
|
|
|
864
864
|
- **Auth fails** \u2192 \`${t} logout && ${t} login\` (browser required)
|
|
865
865
|
- **"Context required"** \u2192 add \`--context\`, \`--file\`, or \`--context-file\`
|
|
866
866
|
- **Rate limit (429)** \u2192 check plan with \`${t} whoami\`
|
|
867
|
-
`}function
|
|
867
|
+
`}function Vt(e){let{name:n,cmd:t}=e;return`---
|
|
868
868
|
name: ${n}-presentation-edit
|
|
869
869
|
description: >
|
|
870
870
|
Use ONLY when editing an already-created presentation that has real slides:
|
|
@@ -2623,7 +2623,7 @@ ${t} config show --verify # Test API key
|
|
|
2623
2623
|
\`\`\`bash
|
|
2624
2624
|
${t} config set team-id <correct-team-id>
|
|
2625
2625
|
\`\`\`
|
|
2626
|
-
`}var
|
|
2626
|
+
`}var Nn={name:"video-ref-website-assets",description:"Extract maximum assets from websites for video production.",render:e=>`---
|
|
2627
2627
|
name: ${e.name}-video-ref-website-assets
|
|
2628
2628
|
description: Extract maximum assets from websites for video production.
|
|
2629
2629
|
---
|
|
@@ -2694,7 +2694,7 @@ agent-browser screenshot --path ./screenshots/hero.png
|
|
|
2694
2694
|
**Images 403/404** - may need referrer header: \`curl -e <site-url> -O <image-url>\`
|
|
2695
2695
|
|
|
2696
2696
|
**Lazy-loaded images** - use agent-browser to scroll and capture, or inspect network tab for actual URLs.
|
|
2697
|
-
`};var
|
|
2697
|
+
`};var Dn={name:"video-ref-brief-guide",description:"How to write video brief for server-side plan generation.",render:e=>`---
|
|
2698
2698
|
name: ${e.name}-video-ref-brief-guide
|
|
2699
2699
|
description: How to write video brief for server-side plan generation.
|
|
2700
2700
|
---
|
|
@@ -2755,7 +2755,7 @@ These will be rebuilt as lightweight animated versions for Remotion. Focus on vi
|
|
|
2755
2755
|
---
|
|
2756
2756
|
|
|
2757
2757
|
**IMPORTANT:** The brief contains ONLY the 6 sections above. Do NOT add "Suggested Scenes", "Scene Breakdown", or any other sections \u2014 scene planning happens server-side via \`video generate plan\`.
|
|
2758
|
-
`};var
|
|
2758
|
+
`};var Ln={name:"video-ref-source-scraping",description:"Extract content from various sources (YouTube, websites, Twitter).",render:e=>`---
|
|
2759
2759
|
name: ${e.name}-video-ref-source-scraping
|
|
2760
2760
|
description: Extract content from various sources (YouTube, websites, Twitter).
|
|
2761
2761
|
---
|
|
@@ -2791,19 +2791,19 @@ Extracts: tweet text, author info, media URLs
|
|
|
2791
2791
|
---
|
|
2792
2792
|
|
|
2793
2793
|
All scraped content is returned in markdown format.
|
|
2794
|
-
`};import{existsSync as Je,mkdirSync as
|
|
2794
|
+
`};import{existsSync as Je,mkdirSync as Mt,rmSync as Jr,writeFileSync as jt}from"fs";import{homedir as qt}from"os";import{basename as zr,join as ee,relative as pc,resolve as Ae}from"path";var he=[{name:"Claude Code",dir:".claude",provider:"claude"},{name:"GitHub Copilot",dir:".github",agentSuffix:".agent.md",provider:"copilot"},{name:"Cursor",dir:".cursor"},{name:"Codex",dir:".codex",agentSuffix:".toml",provider:"codex"},{name:"OpenCode",dir:".opencode"},{name:"Windsurf",dir:".windsurf"},{name:"Agent",dir:".agent"}];var gc={sonnet:"claude-sonnet-4.6",haiku:"claude-haiku-4.5",opus:"claude-opus-4.6"},fc=["permissionMode","skills","subagentType"];function hc(e){let n=e.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!n)return`developer_instructions = """
|
|
2795
2795
|
${e.replace(/"""/g,'\\"\\"\\"').trim()}
|
|
2796
2796
|
"""
|
|
2797
|
-
`;let t=n[1],o=n[2].trim(),r=
|
|
2797
|
+
`;let t=n[1],o=n[2].trim(),r=u=>t.match(new RegExp(`^${u}:\\s*(.+)$`,"m"))?.[1]?.trim().replace(/^["']|["']$/g,""),i=r("name")??"",a=r("description")??"",s=o.replace(/"""/g,'\\"\\"\\"');return`${[`name = ${JSON.stringify(i)}`,`description = ${JSON.stringify(a)}`,`developer_instructions = """
|
|
2798
2798
|
${s}
|
|
2799
2799
|
"""`].join(`
|
|
2800
2800
|
`)}
|
|
2801
|
-
`}function
|
|
2801
|
+
`}function Xr(e,n){if(n!=="copilot")return e;let t=e.match(/^---\n([\s\S]*?)\n---\n/);if(!t)return Wr(e);let o=t[1],r=e.slice((t.index??0)+t[0].length);o=o.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(a,s,d,u)=>`${s}${gc[d]??d}${u}`);for(let a of fc)o=o.replace(new RegExp(`^${a}:[^
|
|
2802
2802
|
]*
|
|
2803
|
-
?`,"m"),"");o=o.replace(/\n+$/,"");let i=
|
|
2803
|
+
?`,"m"),"");o=o.replace(/\n+$/,"");let i=Wr(r);return`---
|
|
2804
2804
|
${o}
|
|
2805
2805
|
---
|
|
2806
|
-
${i}`}function
|
|
2806
|
+
${i}`}function Gr(e,n){return n==="codex"?hc(e):Xr(e,n)}function Wr(e){return e.replace(/\bAskUserQuestion\b/g,"ask the user directly in your response").replace(/\*\*Construct the Task prompt:\*\*/g,"**Construct the Task prompt (must be fully self-contained \u2014 sub-agents cannot read this conversation's history):**").replace(/\*\*Wait for all agents to complete\*\*/g,"**Wait for all agents to complete** (monitor with `/tasks` in Copilot CLI)").replace("**Launch ALL scene agents in parallel**","**Launch ALL scene agents in parallel** \u2014 each agent must write to its own `Scene[NN][Name].tsx` file. Two agents writing to the same file will silently overwrite each other (no error). Verify unique filenames before spawning.")}function yc(e,n){let t=Ae(e),o=Ae(e,n);if(pc(t,o).startsWith("..")||Ae(o)!==o.replace(/\.\./g,""))throw new Error(`Invalid path: "${n}" would escape base directory`);return o}function Hr(e,n,t,o){let r=ee(e,"SKILL.md");if(Mt(e,{recursive:!0}),jt(r,Xr(n,o),"utf-8"),t&&t.length>0){let i=ee(e,"references");Mt(i,{recursive:!0});for(let a of t){let s=ee(i,`${a.name}.md`);jt(s,a.content,"utf-8")}}}function Bt(e,n,t={},o){let r={installed:[],skipped:[],errors:[]},i=t.local?process.cwd():qt();if(t.dir){let a=zr(Ae(t.dir)),s=he.find(d=>d.dir===a)?.provider;try{let d=Ae(t.dir),u=yc(d,ee("skills",e));Hr(u,n,o,s),r.installed.push(t.dir)}catch(d){r.errors.push(`${t.dir}: ${d instanceof Error?d.message:String(d)}`)}}else for(let a of he){let s=ee(i,a.dir),d=ee(s,"skills",e),u=ee(d,"SKILL.md");if(Je(s)){if(Je(u)&&!t.force){r.skipped.push(a.name);continue}try{Hr(d,n,o,a.provider),r.installed.push(a.name)}catch(p){r.errors.push(`${a.name}: ${p instanceof Error?p.message:String(p)}`)}}}return r}function Gt(e,n={}){let t={removed:[],errors:[]},o=n.local?process.cwd():qt();for(let r of he){let i=ee(o,r.dir,"skills",e);if(Je(i))try{Jr(i,{recursive:!0}),t.removed.push(r.name)}catch(a){t.errors.push(`${r.name}: ${a instanceof Error?a.message:String(a)}`)}}return t}function Yr(){return he.map(e=>e.name)}function Kr(e,n,t={}){let o={installed:[],skipped:[],errors:[]};if(t.dir){let a=zr(Ae(t.dir)),s=he.find(w=>w.dir===a),d=s?.agentSuffix??".md",u=ee(Ae(t.dir),"agents"),p=ee(u,`${e}${d}`);if(Je(p)&&!t.force)o.skipped.push(t.dir);else try{Mt(u,{recursive:!0}),jt(p,Gr(n,s?.provider),"utf-8"),o.installed.push(t.dir)}catch(w){o.errors.push(`${t.dir}: ${w instanceof Error?w.message:String(w)}`)}return o}let r=qt(),i=he.filter(a=>a.dir===".claude"||a.dir===".github"||a.dir===".codex");for(let a of i){let s=a.agentSuffix??".md",d=ee(r,a.dir,"agents"),u=ee(d,`${e}${s}`);if(Je(u)&&!t.force){o.skipped.push(a.name);continue}try{Mt(d,{recursive:!0}),jt(u,Gr(n,a.provider),"utf-8"),o.installed.push(a.name)}catch(p){o.errors.push(`${a.name}: ${p instanceof Error?p.message:String(p)}`)}}return o}function Qr(e){let n={removed:[],errors:[]},t=qt(),o=he.filter(r=>r.dir===".claude"||r.dir===".github"||r.dir===".codex");for(let r of o){let i=r.agentSuffix??".md",a=ee(t,r.dir,"agents",`${e}${i}`);if(Je(a))try{Jr(a),n.removed.push(r.name)}catch(s){n.errors.push(`${r.name}: ${s instanceof Error?s.message:String(s)}`)}}return n}function Un(){return`---
|
|
2807
2807
|
name: video-scene-reviewer
|
|
2808
2808
|
description: Strict QA reviewer for a single Remotion scene. Compares code against the video plan checking ColorGrading, transitions, icons, logos, spring physics, idle states, VO-sync, and phase structure. Returns a pass/fail checklist.
|
|
2809
2809
|
tools: Read, Glob
|
|
@@ -2900,7 +2900,7 @@ Priority fixes:
|
|
|
2900
2900
|
- Scene under 80 lines with 5+ seconds duration = flag as too simple
|
|
2901
2901
|
- Be specific in fixes: exact icon name, exact component, exact file
|
|
2902
2902
|
- 85% pass rate minimum. Below = not ready for render
|
|
2903
|
-
`}function
|
|
2903
|
+
`}function Fn(){return`---
|
|
2904
2904
|
name: video-scene-builder
|
|
2905
2905
|
description: Builds a single Remotion video scene (.tsx) from a video plan section. Receives global context, scene spec, audio timing, and rhythm cues. Writes the scene file, spawns a reviewer, and iterates until 85%+ quality. One agent per scene.
|
|
2906
2906
|
tools: Read, Write, Edit, Glob, Grep, Task, Bash
|
|
@@ -3083,7 +3083,7 @@ function AnimatedCamera() {
|
|
|
3083
3083
|
- Don't download assets \u2014 the main AI already did that
|
|
3084
3084
|
- Don't run render commands \u2014 the main AI handles that
|
|
3085
3085
|
- Don't modify video-plan.md \u2014 it's read-only to you
|
|
3086
|
-
`}function
|
|
3086
|
+
`}function _n(e){return`---
|
|
3087
3087
|
name: video-audio-director
|
|
3088
3088
|
description: Generates all audio assets (voiceover TTS, background music, sound effects) and builds the timing manifest that reconciles planned vs actual durations. One agent per video, runs before scene building.
|
|
3089
3089
|
tools: Read, Bash, Write
|
|
@@ -3243,7 +3243,7 @@ This saves money and time \u2014 generation is expensive, downloading is free.
|
|
|
3243
3243
|
- Don't choose voices \u2014 use the voice from your input
|
|
3244
3244
|
- Don't skip the timing manifest \u2014 it's the critical handoff to scene builders
|
|
3245
3245
|
- Don't re-generate audio if it was already generated successfully (see Error Handling above)
|
|
3246
|
-
`}function
|
|
3246
|
+
`}function Vn(){return`---
|
|
3247
3247
|
name: video-continuity-editor
|
|
3248
3248
|
description: Post-build cross-scene QA. Checks transition continuity, color grade flow, timing alignment between Main.tsx and manifest, import consistency, brand coherence, rhythm flow, and music cue alignment. Runs after all scenes are built.
|
|
3249
3249
|
tools: Read, Glob, Grep
|
|
@@ -3354,7 +3354,7 @@ FIXES:
|
|
|
3354
3354
|
- Focus on CROSS-SCENE issues. Per-scene quality is the reviewer's job.
|
|
3355
3355
|
- Be specific in fixes: exact file, exact line, exact component.
|
|
3356
3356
|
- 85% pass rate minimum.
|
|
3357
|
-
`}function
|
|
3357
|
+
`}function Mn(e){let n=e?.cmd??"mf";return`---
|
|
3358
3358
|
name: video-branding-director
|
|
3359
3359
|
description: Extracts brand identity (logos, colors, fonts) from a URL or existing profiles. Searches saved brands, extracts new ones via CLI, downloads assets locally, and writes branding.json. Returns success or failure. One agent per video, runs before brief/plan generation.
|
|
3360
3360
|
tools: Read, Bash, Write
|
|
@@ -3457,7 +3457,7 @@ Query: <what was searched/extracted>
|
|
|
3457
3457
|
- Download logos or images from websites directly (only from branding.json URLs after successful extraction)
|
|
3458
3458
|
- Create or edit branding.json by hand
|
|
3459
3459
|
- Ask the user questions \u2014 return failure to the orchestrator instead
|
|
3460
|
-
`}function
|
|
3460
|
+
`}function Zr(e){return`---
|
|
3461
3461
|
name: remotion-scene-craft
|
|
3462
3462
|
description: Remotion scene coding reference for scene builder agents. DO NOT load this directly \u2014 it is preloaded into video-scene-builder agents via frontmatter. Contains plan vocabulary decoder, 4-phase architecture, VO-sync, animation recipes.
|
|
3463
3463
|
---
|
|
@@ -3732,7 +3732,7 @@ const glow = interpolate(Math.sin(frame / fps * Math.PI * 2 / 2), [-1, 1], [0.1,
|
|
|
3732
3732
|
- Static scenes with no visual change for 2+ seconds -> Every 2s needs a visual event.
|
|
3733
3733
|
- Generic component substitution -> Plan says WhipPan, use WhipPan. Not slide() or wipe().
|
|
3734
3734
|
- Unused variables or imports -> Every \`const\`, \`import\`, and \`interpolate()\` call must be used in JSX/return. Remove what you don't use. Do NOT prefix with \`_\` \u2014 delete entirely.
|
|
3735
|
-
`}var
|
|
3735
|
+
`}var dt=["main","video","presentation","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","config"],Wt=["standalone","studio"],ei={cmd:g.commands[0],pkg:g.packageName,url:g.apiUrl,name:g.name},ze=new bc("skill").description(`Manage ${g.displayName} skills for AI coding assistants`).addHelpText("after",`
|
|
3736
3736
|
${V.bold("Skill Types:")}
|
|
3737
3737
|
${V.cyan("main")} Main CLI skill with all capabilities overview
|
|
3738
3738
|
${V.cyan("video")} Detailed video creation workflow with Remotion/R3F patterns
|
|
@@ -3768,51 +3768,51 @@ ${V.bold("Examples:")}
|
|
|
3768
3768
|
|
|
3769
3769
|
${V.gray("# Show skill content")}
|
|
3770
3770
|
$ ${g.commands[0]} skill show main
|
|
3771
|
-
`);ze.command("install").description(`Install ${g.displayName} skills for AI coding assistants`).argument("[type]","Skill type: main, video, presentation, or omit for all").option("-d, --dir <path>","Install to specific directory").option("-g, --global","Install globally (to home directory)",!0).option("-l, --local","Install locally (to current directory)").option("-f, --force","Overwrite existing skill files").option("-m, --mode <mode>","Skill mode: standalone (render to file) or studio (Studio Preview)","standalone").action(async(e,n)=>{n.mode&&!
|
|
3772
|
-
${lt.gray(i)}`:""}`)}console.log(),console.log(lt.gray(`Use one with: ${g.commands[0]} create "<topic>" --template <id>`))}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as ac}from"commander";import Vn from"chalk";var Qr=new ac("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P();try{let n=await be();if(vn(),e.format==="json"){console.log(JSON.stringify(n,null,2));return}ge("User"),console.log(),T("Email",n.user.email),n.user.username&&T("Username",n.user.username),(n.user.firstName||n.user.lastName)&&T("Name",[n.user.firstName,n.user.lastName].filter(Boolean).join(" "));let t=n.authType==="apiKey"?"API Key":n.authType==="oauth"?"OAuth":"Session";if(T("Auth Type",t),n.currentTeam&&(console.log(),ge("Current Team"),console.log(),T("ID",n.currentTeam.id),T("Name",n.currentTeam.name),T("Plan",n.currentTeam.planName),T("Role",n.currentTeam.isOwner?"Owner":"Member")),n.teams.length>1){console.log(),ge("All Teams"),console.log();for(let o of n.teams){let r=o.isCurrent?Vn.green(" (current)"):"";console.log(` ${Vn.bold(o.name)}${r}`),console.log(Vn.gray(` ID: ${o.id} | Plan: ${o.planName} | Role: ${o.role}`))}}console.log()}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}});function Zr(e){return e[0]==="--"?e.slice(1):e}import{Command as Mn}from"commander";function sc(e,n){return[...n,e]}var cc=new Mn("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",sc,[]).option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await $("createAdSet",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,brief:n.brief,hooks:n.hook.length?n.hook:[n.brief],style:n.style,teamId:n.teamId,title:e}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),lc=new Mn("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await D("createAdSet",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),ei=new Mn("ad-set").description("Ad set commands").addCommand(cc).addCommand(lc);import{Command as ni}from"commander";function ti(e){return new ni(e).description(e==="create"?"Create and activate a scheduled agent":"Create a reviewable agent recommendation").argument("<name>","Agent name").requiredOption("--instructions <markdown>","Agent instructions").option("--description <text>","Agent description","").option("--schedule <frequency>","manual, daily, weekdays, weekly, or monthly","weekly").option("--time <hh:mm>","Local run time","09:00").option("--timezone <zone>","IANA timezone","UTC").option("--output <adapter>","Output adapter","digest").option("--team-id <id>","Workspace ID").option("--yes","Approve saving the agent").action(async(n,t)=>{if(!t.yes)return c("Pass --yes to approve this operation");try{x(await $(e==="create"?"createAgent":"recommendAgent",{approvalReceipt:"cli:--yes",description:t.description,instructionsMarkdown:t.instructions,name:n,output:t.output,schedule:t.schedule,scheduleTime:t.time,teamId:t.teamId,timezone:t.timezone}))}catch(o){c(o instanceof Error?o.message:"Agent operation failed"),process.exit(d.GENERAL_ERROR)}})}var oi=new ni("agent").description("Scheduled agent commands").addCommand(ti("create")).addCommand(ti("recommend"));import{Command as Wt}from"commander";import mc from"ora";import{mkdir as dc,writeFile as ri}from"fs/promises";import{dirname as uc}from"path";async function Q(e,n){if(await dc(uc(n),{recursive:!0}),e.startsWith("data:")){let r=e.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");if(i.length===0)throw new Error("Downloaded media was empty");await ri(n,i);return}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download media: ${t.status}`);let o=Buffer.from(await t.arrayBuffer());if(o.length===0)throw new Error("Downloaded media was empty");await ri(n,o)}var pc=15e3,gc=40;function jn(e,n){if(n==="json"){x(e);return}if(n==="quiet"){console.log(e.videoUrl??e.requestId);return}u(`Request ID: ${e.requestId}`),u(`Status: ${e.status}`),e.durationSec!=null&&u(`Duration: ${e.durationSec}s`),e.videoUrl&&S(`Video URL: ${e.videoUrl}`),e.error&&c(`Error: ${e.error}`)}var fc=new Wt("options").description("List available presenter avatars and voices").option("--language <language>","Filter voices by language").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{try{let n=await Bo(e.language);if(e.format==="json"){x(n);return}let t=n.personal??[];if(e.format==="quiet"){for(let o of t)console.log(o.id);for(let o of n.avatars)console.log(o.id);for(let o of n.voices)console.log(o.id);return}if(t.length>0){u("Your presenters:");for(let o of t)console.log(` ${o.id} ${o.name}`)}u("Avatars:");for(let o of n.avatars){let r=o.renderTiers?.length?` [${o.renderTiers.join(", ")}]`:"";console.log(` ${o.id} ${o.name}${r}`)}u("Voices:");for(let o of n.voices)console.log(` ${o.id} ${o.name}${o.language?` (${o.language})`:""}`)}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),hc=new Wt("generate").description("Generate a reusable presenter clip").option("--avatar-id <id>","Avatar id from 'avatar options'; sandbox runs use the host presenter policy").option("--audio-url <url>","Public narration audio URL for avatar lip sync").option("--voice-id <id>","Voice id from 'avatar options'").option("--script <text>","Exact words for the presenter to speak").requiredOption("-o, --output <path>","Local output path").option("--aspect <aspect>","Aspect: 1:1, 9:16, 16:9","9:16").option("--duration <seconds>","Maximum requested duration (1-300)").option("--transparent","Render a transparent-background WebM presenter clip").option("--background-color <hex>","Solid presenter background color, for example #0F172A").option("--background-image-url <url>","Public image URL used as the presenter background").option("--fit <mode>","Background image fit: contain or cover").option("--output-format <container>","Container: mp4 (default) or webm \u2014 webm renders a transparent-background clip (single scene) for compositing").option("--render-tier <tier>","Render cost/quality: basic, standard, premium","basic").option("--title <title>","Clip title","Presenter clip").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.transparent?"webm":e.outputFormat;!!e.audioUrl==!!e.script&&(c("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(d.INVALID_INPUT)),["1:1","9:16","16:9"].includes(e.aspect)||(c("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(d.INVALID_INPUT)),e.outputFormat!==void 0&&!["mp4","webm"].includes(e.outputFormat)&&(c("Output format must be mp4 or webm"),process.exit(d.INVALID_INPUT)),e.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(e.backgroundColor)&&(c("Background color must be a six-digit hex value"),process.exit(d.INVALID_INPUT)),e.backgroundColor&&e.backgroundImageUrl&&(c("Provide only one presenter background"),process.exit(d.INVALID_INPUT)),e.fit!==void 0&&!["contain","cover"].includes(e.fit)&&(c("Fit must be contain or cover"),process.exit(d.INVALID_INPUT)),e.fit&&!e.backgroundImageUrl&&(c("Fit requires --background-image-url"),process.exit(d.INVALID_INPUT)),e.transparent&&e.outputFormat==="mp4"&&(c("--transparent cannot be combined with --output-format mp4"),process.exit(d.INVALID_INPUT)),n==="webm"&&(e.backgroundColor||e.backgroundImageUrl)&&(c("Transparent WebM output cannot be combined with a background"),process.exit(d.INVALID_INPUT)),["basic","standard","premium"].includes(e.renderTier)||(c("Render tier must be basic, standard, or premium"),process.exit(d.INVALID_INPUT));let t=e.duration?Number.parseInt(e.duration,10):void 0;t!==void 0&&(!Number.isFinite(t)||t<1||t>300)&&(c("Duration must be between 1 and 300 seconds"),process.exit(d.INVALID_INPUT));let o=e.format==="human"?mc("Generating presenter clip...").start():null;try{let r=e.audioUrl?{audioUrl:e.audioUrl}:{script:e.script??"",...e.voiceId?{voiceId:e.voiceId}:{}},i=await Go({...r,aspect:e.aspect,...e.avatarId?{avatarId:e.avatarId}:{},...e.backgroundColor?{backgroundHex:e.backgroundColor}:{},...e.backgroundImageUrl?{backgroundImageUrl:e.backgroundImageUrl}:{},...t!==void 0?{durationSec:t}:{},...e.fit?{fit:e.fit}:{},...n?{outputFormat:n}:{},renderTier:e.renderTier,title:e.title});if(!e.wait){o?.stop(),jn(i,e.format);return}let a=await K(()=>hn(i.requestId),gc,pc);if(a.status==="failed")throw new Error(a.error||"Presenter generation failed");if(!a.videoUrl)throw new Error("Presenter generation completed without a video URL");o&&(o.text="Downloading presenter clip..."),await Q(a.videoUrl,e.output),o?.stop(),jn(a,e.format),e.format==="human"&&S(`Saved to: ${e.output}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),yc=new Wt("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{jn(await hn(e),n.format)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ii=new Wt("avatar").description("Avatar/presenter media commands").addCommand(fc).addCommand(hc).addCommand(yc);import{writeFile as ai}from"fs/promises";import H from"chalk";import{Command as se}from"commander";import bc from"ora";var si=new se("branding").description("Manage brand profiles").addCommand(new se("list").description("List brand profiles").option("-f, --format <format>","Output format (table, json)","table").action(async e=>{await P();try{let n=await mn();if(n.brandings.length===0){e.format==="json"?console.log(JSON.stringify([])):(u("No brand profiles found"),console.log(),console.log(H.gray(`Create one with: ${g.commands[0]} branding extract <url>`)));return}e.format==="json"?console.log(JSON.stringify(n.brandings,null,2)):console.log(Qo(n.brandings))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new se("get").description("Get brand profile details").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)","summary").option("-o, --output <path>","Save JSON to file").action(async(e,n)=>{await P();try{let t=await Oo(e);if(n.output){await ai(n.output,JSON.stringify(t,null,2)),S(`Brand profile saved to ${n.output}`);return}if(n.format==="json")console.log(JSON.stringify(t,null,2));else{if(ge("Brand Profile"),console.log(),T("ID",t.id),T("Name",t.name),T("Source URL",t.sourceUrl??H.gray("None")),T("Default",t.isDefault?H.green("Yes"):"No"),t.createdAt&&T("Created",new Date(t.createdAt).toLocaleString()),console.log(),t.primaryColor||t.colors.length>0){if(console.log(H.bold(" Colors")),t.primaryColor){let r=H.bgHex(t.primaryColor)(" ");console.log(` Primary: ${r} ${t.primaryColor}`)}if(t.colors.length>0){console.log(" Palette:");for(let r of t.colors.slice(0,10)){let i=H.bgHex(r.hex)(" "),a=r.role?H.gray(` (${r.role})`):"";console.log(` ${i} ${r.hex}${a}`)}}console.log()}t.logoUrl&&(console.log(H.bold(" Logo")),console.log(` ${t.logoUrl}`),console.log());let o=t.typography;o&&Object.keys(o).length>0&&(console.log(H.bold(" Typography")),(o.primary||o.headings)&&console.log(` Headings: ${o.primary||o.headings||"-"}`),(o.secondary||o.body)&&console.log(` Body: ${o.secondary||o.body||"-"}`),console.log()),(t.confidence||t.extractionMethod)&&(console.log(H.bold(" Extraction")),t.confidence&&console.log(` Confidence: ${Math.round(t.confidence*100)}%`),t.extractionMethod&&console.log(` Method: ${t.extractionMethod}`),console.log()),console.log(H.gray(" Use --format json for full details")),console.log()}}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}})).addCommand(new se("find").description("Find existing brand profile by name or URL").argument("<query>","Brand name or website URL to search for").action(async e=>{await P();try{let n=await mn(),t=e.toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,""),o=n.brandings.filter(r=>{let i=(r.name||"").toLowerCase(),a=(r.sourceUrl||"").toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,"");return i.includes(t)||a.includes(t)||i.length>0&&t.includes(i)||a.length>0&&t.includes(a)});if(o.length===0){u(`No brand profiles matching "${e}"`),console.log(H.gray(` Extract one with: ${g.commands[0]} branding extract <url>`));return}console.log(`Found ${o.length} brand${o.length>1?"s":""}:
|
|
3773
|
-
`);for(let r of o){let i=r.primaryColor?`${H.bgHex(r.primaryColor)(" ")} ${r.primaryColor}`:"";console.log(` ${H.bold(r.name)} ${H.gray(r.id)}`),r.sourceUrl&&console.log(` ${H.gray(r.sourceUrl)}`),i&&console.log(` ${i}`),console.log()}console.log(H.gray(` Export with: ${g.commands[0]} branding get <id> -o branding.json`))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new se("extract").description("Extract brand profile from a website").argument("<url>","Website URL to extract branding from").option("--team-id <id>","Team ID").option("--yes","Confirm starting a paid/external extraction").option("--no-save","Extract without saving").option("-o, --output <path>","Save JSON to file").action(async(e,n)=>{await P(),n.yes||(c("Pass --yes to confirm brand extraction."),process.exit(d.INVALID_INPUT));try{new URL(e.startsWith("http")?e:`https://${e}`)}catch{c("Invalid URL format"),process.exit(6)}let t=e.startsWith("http")?e:`https://${e}`,o=n.teamId??ft(),r=bc({text:`Extracting branding from ${t}...`,stream:process.stdout}).start();try{let i=await Po(t,o,"cli:--yes");r.succeed("Brand extraction started");let a=JSON.stringify(i,null,2);n.output?(await ai(n.output,a),S(`Brand profile saved to ${n.output}`)):console.log(a),u(`Check progress with: ${g.commands[0]} branding status ${i.runId}`),console.log()}catch(i){r.fail("Extraction failed"),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}})).addCommand(new se("status").description("Check a brand extraction run").argument("<run-id>","Run ID returned by branding extract").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await D("extractBranding",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}})).addCommand(new se("set-default").description("Set a brand profile as default").argument("<id>","Brand profile ID").action(async e=>{await P(),u(`To set brand ${e} as default, use the web dashboard.`),console.log(),console.log(H.gray("API support for setting default brand is coming soon."))})).addCommand(new se("competitor").description("Brand competitor commands").addCommand(new se("list").description("List competitors for a brand").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").action(async e=>{try{console.log(JSON.stringify(await $("getBrandCompetitors",{brandingId:e.brandingId,teamId:e.teamId}),null,2))}catch(n){c(n instanceof Error?n.message:"Lookup failed"),process.exit(1)}})).addCommand(new se("add").description("Add or update a brand competitor").argument("<name>","Competitor name").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").option("--website <url>","Competitor website").option("--x-handle <handle>","Competitor X handle").option("--yes","Confirm writing brand data").action(async(e,n)=>{n.yes||(c("Pass --yes to confirm adding a competitor."),process.exit(d.INVALID_INPUT));try{x(await $("addCompetitor",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,name:e,teamId:n.teamId,website:n.website,xHandle:n.xHandle}))}catch(t){c(t instanceof Error?t.message:"Write failed"),process.exit(d.GENERAL_ERROR)}}))).addCommand(new se("social").description("Brand social handle commands").addCommand(new se("add").description("Add or update a brand social handle").argument("<platform>","Social platform").argument("<handle>","Account handle").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").option("--yes","Confirm writing brand data").action(async(e,n,t)=>{t.yes||(c("Pass --yes to confirm adding a social handle."),process.exit(d.INVALID_INPUT));try{x(await $("addBrandSocialHandle",{approvalReceipt:"cli:--yes",brandingId:t.brandingId,handle:n,platform:e,teamId:t.teamId}))}catch(o){c(o instanceof Error?o.message:"Write failed"),process.exit(d.GENERAL_ERROR)}})));import{readFile as wc}from"fs/promises";import{Command as ci}from"commander";var vc=new ci("extract").description("Extract normalized text from a URL or local file").argument("<source>","URL, encoded source, or local file path").option("--team-id <id>","Workspace ID").option("--mime-type <type>","Source MIME type").option("--max-length <count>","Maximum output characters","30000").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=e,o;e.includes("://")||(t=await wc(e,"utf8"),o=e);let r=await $("extractContent",{filename:o,maxLength:Number.parseInt(n.maxLength,10),mimeType:n.mimeType,source:t,teamId:n.teamId});n.format!=="quiet"&&x(r)}catch(t){c(t instanceof Error?t.message:"Extraction failed"),process.exit(d.GENERAL_ERROR)}}),li=new ci("content").description("Content extraction commands").addCommand(vc);import Y from"chalk";import{Command as xc}from"commander";import{existsSync as Sc,readFileSync as Cc}from"fs";import Ic,{resolve as di}from"path";var ui=new xc("create").description("Create a new presentation").argument("<topic>","The topic or title for the presentation").option("-n, --slides <count>","Number of slides (1-20)").option("-m, --mode <mode>","Generation quality (best, balanced, fast, ultrafast, instant, image-min, image, image-max) \u2014 default: fast. image-min/image/image-max render each slide as a full-bleed AI image (text not editable); slower + pricier, require image-mode access, and cap at 25 slides. image-min is cheapest (brand colors only, no exact fonts).").option("--image-tier <tier>","Embedded-image quality for HTML modes: smart (default, auto-routes per image), fast (cheapest, no extra credits), balanced (+50 credits/slide), best (premium, +200 credits/slide, slow). Ignored for image-*/instant modes.").option("-t, --tone <tone>","Tone (creative, professional, educational, formal, casual)").option("--amount <amount>","Content density (minimal, concise, detailed, extensive)").option("--audience <text>","Target audience description").option("-l, --language <lang>","Output language").option("--branding-id <id>","Branding ID (from `ccr branding list` or `ccr branding extract`)").option("--brand-domain <url>","Brand the deck by website/domain (e.g. https://www.pfizer.com). Errors if no matching saved brand exists.").option("--template <id>","Slide template ID to style the deck after (from `ccr templates`). A default template is applied automatically when omitted.").option("-c, --context <text>","Inline text context (research notes, key facts)").option("--context-file <path>","Path to a context file (text, markdown, JSON)").option("--stdin","Read context from stdin").option("-f, --file <paths...>","Files to upload (PDF, PPTX, DOCX, images)").option("-g, --goal <type>","Goal (inform, persuade, train, learn, entertain, report)").option("--styling <mode>","Styling mode (freeform, brand-only, brand-plus-style, style-only, no-styling)").option("--reference-url <url>","Image URL to use as visual style reference").option("--thinking-depth <depth>","AI thinking depth (quick, moderate, deep, profound)").option("--theme <preset>","[instant mode only] Color theme preset (blue, violet, rose, orange, green)").option("--primary-color <hex>","[instant mode only] Primary color (e.g., #0066CC)").option("--secondary-color <hex>","[instant mode only] Secondary color").option("--accent-color <hex>","[instant mode only] Accent color").option("--background-color <hex>","[instant mode only] Background color").option("--foreground-color <hex>","[instant mode only] Foreground/text color").option("--decorations <style>","[instant mode only] Background decoration (none, waves-bottom-left, waves-top-right, blob-corners, minimal)").option("--team-id <id>","Team ID (switch teams)").option("-o, --output <format>","Output format (human, json, quiet)").option("--no-stream","Wait for completion without streaming progress").option("--wait","Poll until generation completes").option("--debug","Enable debug logging").option("--open","Open in browser after creation").option("--id <uuid>","Use a specific UUID for the presentation").option("--studio","Studio mode: use current directory name as presentation ID (auto-links to Studio preview)").action(async(e,n)=>{await P();let t;n.slides!==void 0&&(t=parseInt(n.slides,10),(Number.isNaN(t)||t<1||t>20)&&(c("Slide count must be between 1 and 20"),process.exit(6)));let o=["best","balanced","fast","ultrafast","instant","image-min","image","image-max"];n.mode&&!o.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Valid: ${o.join(", ")}`),process.exit(6));let r=["smart","fast","balanced","best"];n.imageTier&&!r.includes(n.imageTier)&&(c(`Invalid image tier: ${n.imageTier}. Valid: ${r.join(", ")}`),process.exit(6));let i=["creative","professional","educational","formal","casual"];n.tone&&!i.includes(n.tone)&&(c(`Invalid tone: ${n.tone}. Valid: ${i.join(", ")}`),process.exit(6));let a=["minimal","concise","detailed","extensive"];n.amount&&!a.includes(n.amount)&&(c(`Invalid amount: ${n.amount}. Valid: ${a.join(", ")}`),process.exit(6));let s=["freeform","brand-only","brand-plus-style","style-only","no-styling"];n.styling&&!s.includes(n.styling)&&(c(`Invalid styling: ${n.styling}. Valid: ${s.join(", ")}`),process.exit(6));let l=["quick","moderate","deep","profound"];n.thinkingDepth&&!l.includes(n.thinkingDepth)&&(c(`Invalid thinking-depth: ${n.thinkingDepth}. Valid: ${l.join(", ")}`),process.exit(6));let m=["inform","persuade","train","learn","entertain","report"];n.goal&&!m.includes(n.goal)&&(c(`Invalid goal: ${n.goal}. Valid: ${m.join(", ")}`),process.exit(6));let p=["blue","violet","rose","orange","green"];n.theme&&!p.includes(n.theme)&&(c(`Invalid theme: ${n.theme}. Valid: ${p.join(", ")}`),process.exit(6));let w=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];n.decorations&&!w.includes(n.decorations)&&(c(`Invalid decorations: ${n.decorations}. Valid: ${w.join(", ")}`),process.exit(6));let I=n.theme||n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor||n.decorations;I&&n.mode&&n.mode!=="instant"&&(c("--theme, --primary-color, --decorations and other color options are only supported with --mode instant"),process.exit(6));let f=n.mode??(I?"instant":"fast"),R=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[C,M]of[["primary-color",n.primaryColor],["secondary-color",n.secondaryColor],["accent-color",n.accentColor],["background-color",n.backgroundColor],["foreground-color",n.foregroundColor]])M&&!R.test(M)&&(c(`Invalid ${C}: ${M}. Must be hex (e.g., #0066CC)`),process.exit(6));try{n.output!=="json"&&n.output!=="quiet"&&process.stdout.write(Y.gray("Checking generation limits... "));let C=await Do(f,t??10,n.teamId);if(n.output!=="json"&&n.output!=="quiet"){console.log(Y.green("\u2713"));let M=C.remaining[f],q=C.limits[f],ne=M===void 0||q===void 0?"":` | ${f}: ${M}/${q} remaining`;console.log(Y.gray(` Plan: ${C.planName}${ne}`))}}catch(C){n.output==="json"?console.log(JSON.stringify({success:!1,error:C instanceof Error?C.message:String(C)})):(console.log(Y.red("\u2717")),c(C instanceof Error?C.message:String(C))),process.exit(C.exitCode??1)}let b=[];if(n.file&&n.file.length>0){for(let C of n.file)Sc(di(C))||(c(`File not found: ${C}`),process.exit(6));n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(`
|
|
3774
|
-
Uploading ${n.file.length} file(s)...`));try{b=await Io(n.file.map(C=>di(C)),(C,M,q)=>{n.output!=="json"&&n.output!=="quiet"&&q&&process.stdout.write(`\r ${Y.cyan("\u2B06")} Uploading: ${q} (${C+1}/${M})`)}),n.output!=="json"&&n.output!=="quiet"&&console.log(`\r ${Y.green("\u2713")} Uploaded ${b.length} file(s) `)}catch(C){c(`Failed to upload files: ${C instanceof Error?C.message:String(C)}`),process.exit(1)}}let y;(n.stdin||!process.stdin.isTTY)&&(y=await Rc(),n.stdin&&!y&&(c("No content received from stdin"),process.exit(6)));let v=n.context;if(n.contextFile)try{v=Cc(n.contextFile,"utf-8"),v.trim()||(c(`Context file is empty: ${n.contextFile}`),process.exit(6))}catch{c(`Failed to read context file: ${n.contextFile}`),process.exit(6)}!y&&!v&&b.length===0&&(c("Context is required to create a presentation."),console.log(),console.log(Y.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(Y.gray(" -c, --context <text> Inline text context")),console.log(Y.gray(" --context-file <path> Read from a file")),console.log(Y.gray(` cat file | ${g.commands[0]} Pipe content`)),process.exit(6));let E=[...b];y&&E.push({id:`stdin-${Date.now()}`,content:y,title:"Piped Content",mime:"text/plain",selected:!0}),v&&E.push({id:`context-${Date.now()}`,content:v,title:"Context",mime:"text/plain",selected:!0});let A,N=n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor;(n.theme||N||n.decorations)&&(A={},n.theme&&(A.preset=n.theme),N&&(A.custom={},n.primaryColor&&(A.custom.primary=n.primaryColor),n.secondaryColor&&(A.custom.secondary=n.secondaryColor),n.accentColor&&(A.custom.accent=n.accentColor),n.backgroundColor&&(A.custom.background=n.backgroundColor),n.foregroundColor&&(A.custom.foreground=n.foregroundColor)),n.decorations&&(A.decorations=n.decorations));try{let C=await Ro({topic:e,...t!==void 0&&{slideCount:t},mode:f,...n.imageTier&&{imageTier:n.imageTier},...n.tone&&{tone:n.tone},...n.amount&&{amount:n.amount},...n.audience&&{audience:n.audience},...n.language&&{language:n.language},...n.brandingId&&{brandingId:n.brandingId},...n.brandDomain&&{brandDomain:n.brandDomain},...n.template&&{templateId:n.template},...n.styling&&{stylingMode:n.styling},...n.referenceUrl&&{referenceUrl:n.referenceUrl},...n.thinkingDepth&&{thinkingDepth:n.thinkingDepth},...n.goal&&{goal:n.goal},...n.teamId&&{teamId:n.teamId},...A&&{theme:A},...n.studio?{documentId:Ic.basename(process.cwd())}:n.id?{documentId:n.id}:{},...E.length>0&&{contentSources:{uploadedFiles:E,contextFiles:[]}}});if(!n.wait){n.output==="json"?console.log(JSON.stringify({success:!0,run:C},null,2)):n.output!=="quiet"&&(S("Presentation generation queued"),T("Run ID",C.runId),T("Status",C.status),console.log(Y.gray(` Check later with presentation status ${C.runId}`)));return}let M=await D("createSlides",C.runId,n.teamId);for(;!M.done;)n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(` ${M.message}`)),await new Promise(ne=>setTimeout(ne,(M.nextPollAfterSeconds??5)*1e3)),M=await D("createSlides",C.runId,n.teamId);if(M.error)throw new Error(M.error.message);let q=M.entity?await xe(M.entity.id):void 0;if(n.output==="json")console.log(JSON.stringify({success:!0,presentation:q,run:M,viewUrl:q?Le(q.slug,n.language??"en"):void 0},null,2));else{console.log(),S("Presentation created successfully"),console.log(),T("Title",q?.title??e),T("Slides",String(q?.numberOfSlides??t??"\u2014")),console.log();let ne=q?Le(q.slug,n.language??"en"):"N/A";ne!=="N/A"&&(console.log(Y.bold(" Open: ")+Y.cyan.underline(ne)),n.open&&await(await import("open")).default(ne)),console.log()}}catch(C){n.output==="json"?console.log(JSON.stringify({success:!1,error:C instanceof Error?C.message:String(C)})):c(C instanceof Error?C.message:String(C)),process.exit(C.exitCode??1)}});async function Rc(){return new Promise(e=>{let n="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){e("");return}process.stdin.on("data",t=>{n+=t}),process.stdin.on("end",()=>{e(n.trim())}),setTimeout(()=>{e(n.trim())},100)})}import{Command as Tc}from"commander";import Ht from"chalk";var mi=new Tc("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)","summary").option("--include <fields>","Fields to include (comma-separated: slides,styling)").option("-l, --language <lang>","Language for view URL","en").action(async(e,n)=>{await P();try{let t=await xe(e);if(n.format==="json"){console.log(JSON.stringify(t,null,2));return}let o=Le(t.slug,n.language);ge("Presentation Details"),console.log(),T("Slug",t.slug),T("Title",t.title||"Untitled"),T("Description",t.description||Ht.gray("None")),T("Slides",String(t.numberOfSlides||"-")),T("Mode",t.mode||"-"),T("Created",wn(t.createdAt)),t.updatedAt&&T("Updated",wn(t.updatedAt)),console.log(),o!=="N/A"&&console.log(Ht.bold(" Open: ")+Ht.cyan.underline(o)),console.log(),n.format==="full"&&n.include?.includes("slides")&&(console.log(Ht.gray("(Full slide content available in JSON format)")),console.log())}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as zt}from"commander";import kc from"ora";function de(e,n){let t=e instanceof Error?e.message:"Unknown error";return!n||t.includes(n)?t:`${t} Request ID: ${n}. Resume with the matching status command; do not start a duplicate run.`}function Ac(e){let n=e.assetType??"image";if(n!=="image"&&n!=="icon")throw new Error("Asset type must be image or icon");let t;if(e.maxResults&&(t=Number.parseInt(e.maxResults,10),Number.isNaN(t)||t<1))throw new Error("Max results must be a positive number");return{query:n==="icon"?`${e.query.trim()} transparent icon isolated symbol`:e.query.trim(),options:{maxResults:t||10,size:e.size,safeSearch:e.safeSearch,assetType:n,transparentBackground:n==="icon"}}}function $c(e){let n=e.url||e.imageUrl;if(!n)throw new Error("Image search returned a result without a URL");return n}function Ec(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function Oc(e,n){return e.data.results.flatMap(t=>t.results.map(o=>{let r=o,i=Ec(r);if(n==="icon"&&i!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...r,url:$c(r),provider:t.providerName,assetType:n,...i!==void 0?{transparent:i}:{}}}))}function Pc(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function Jt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Nc(e){return{requestId:e.runId,status:Pc(e),...e.entity?.url?{url:e.entity.url}:{},...e.error?.message?{error:e.error.message}:{},...Jt(e.output?.width)!==void 0?{width:Jt(e.output?.width)}:{},...Jt(e.output?.height)!==void 0?{height:Jt(e.output?.height)}:{}}}async function pi(e,n){return Nc(await D("createImage",e,n))}function qn(e,n){if(n==="json"){x(e);return}if(n==="quiet"){console.log(e.output??e.url??e.requestId);return}u(`Request ID: ${e.requestId}`),u(`Status: ${e.status}`),e.url&&S(`Image URL: ${e.url}`),e.output&&S(`Saved to: ${e.output}`),e.error&&c(`Error: ${e.error}`)}var Lc=new zt("search").description("Search for images").requiredOption("-q, --query <query>","Search query").option("-n, --max-results <number>","Maximum number of results (default: 10)").option("-s, --size <size>","Image size: small, medium, large, any","large").option("--asset-type <type>","Asset intent: image or transparent icon","image").option("--safe-search","Enable safe search (default: true)",!0).option("--no-safe-search","Disable safe search").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?kc("Searching for images...").start():null,o;try{o=Ac(e)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Invalid image search request"),process.exit(d.INVALID_INPUT);return}try{let r=await Rt(o);t?.stop(),r.success||(c("Search failed"),process.exit(d.GENERAL_ERROR));let i=o.options?.assetType??"image",a=Oc(r,i);if(n==="json"){x({success:!0,query:e.query,assetType:i,totalResults:a.length,images:a});return}if(n==="quiet"){for(let s of a)console.log(s.url);return}if(a.length===0){u("No images found");return}S(`Found ${a.length} images for "${e.query}"`),console.log();for(let s=0;s<a.length;s++){let l=a[s];console.log(`[${s+1}] ${l.title||"Untitled"}`),console.log(` URL: ${l.url}`),console.log(` Size: ${l.width}x${l.height}`),l.author&&console.log(` Author: ${l.author}`),console.log(` Provider: ${l.provider}`),console.log()}u(`Total cost: $${r.data.totalCost.toFixed(4)}`)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Dc=new zt("generate").description("Generate an image and optionally save it locally").argument("[prompt]","Image prompt").option("-p, --prompt <text>","Image prompt (named compatibility form)").option("--provider <provider>","Provider override").option("--model <model>","Model override").option("--width <pixels>","Width").option("--height <pixels>","Height").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Local output path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").option("--yes","Approve generation").action(async(e,n)=>{let t,o=e??n.prompt;o?.trim()||(c("Provide an image prompt as an argument or with --prompt"),process.exit(d.INVALID_INPUT)),n.yes||(c("Pass --yes to approve image generation"),process.exit(d.INVALID_INPUT)),!n.wait&&n.output&&(c("--output requires waiting for completion; remove --no-wait"),process.exit(d.INVALID_INPUT));try{let r=await $("createImage",{approvalReceipt:"cli:--yes",height:n.height?Number.parseInt(n.height,10):void 0,model:n.model,prompt:o.trim(),provider:n.provider,teamId:n.teamId,width:n.width?Number.parseInt(n.width,10):void 0});if(t=r.runId,!n.wait){qn({requestId:r.runId,status:"pending"},n.format);return}let i=await K(()=>pi(r.runId,n.teamId),180,2e3);if(i.status==="failed")throw new Error(i.error||"Image generation failed");if(!i.url)throw new Error("Image generation completed without an image URL");let a=n.output?{...i,output:n.output}:i;n.output&&await Q(i.url,n.output),qn(a,n.format)}catch(r){c(de(r,t),n.format),process.exit(d.GENERAL_ERROR)}}),Uc=new zt("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Download a completed image").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await pi(e,n.teamId);if(n.output){if(t.status!=="completed"||!t.url)throw new Error("Image generation is not complete");await Q(t.url,n.output),t.output=n.output}qn(t,n.format)}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),gi=new zt("image").description("Image search and generation commands").addCommand(Lc).addCommand(Dc).addCommand(Uc);import{Command as Bn}from"commander";var Fc=new Bn("search").description("Search the workspace Knowledge Hub").argument("[query]","Optional search query").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").option("--limit <count>","Maximum results","10").action(async(e,n)=>{try{x(await $("searchKnowledge",{kind:n.kind,limit:Number.parseInt(n.limit,10),query:e,teamId:n.teamId}))}catch(t){c(t instanceof Error?t.message:"Knowledge search failed"),process.exit(d.GENERAL_ERROR)}}),_c=new Bn("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async e=>{try{x(await $("getKnowledgeBundle",{kind:e.kind,teamId:e.teamId}))}catch(n){c(n instanceof Error?n.message:"Knowledge bundle failed"),process.exit(d.GENERAL_ERROR)}}),fi=new Bn("knowledge").description("Knowledge Hub commands").addCommand(Fc).addCommand(_c);import{Command as Gn}from"commander";var Vc=new Gn("create").description("Start background microsite generation").argument("<title>","Microsite title").requiredOption("--description <brief>","Microsite brief").option("--audience <audience>","Target audience").option("--tone <tone>","Tone").option("--language <language>","Content language","en").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await $("createMicrosite",{approvalReceipt:"cli:--yes",audience:n.audience,brandingId:n.brandingId,description:n.description,language:n.language,teamId:n.teamId,title:e,tone:n.tone}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),Mc=new Gn("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await D("createMicrosite",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),hi=new Gn("microsite").description("Microsite commands").addCommand(Vc).addCommand(Mc);import{Command as Jn}from"commander";import Wn from"ora";function Hn(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.outputUrl?console.log(e.outputUrl):console.log(e.requestId);return}u(`Request ID: ${e.requestId}`),u(`Status: ${e.status}`),e.duration&&u(`Duration: ${e.duration}s`),e.outputUrl&&S(`Output URL: ${e.outputUrl}`),e.cost!==void 0&&u(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var jc=new Jn("create").description("Mix audio tracks into a video (music will loop to match video duration)").requiredOption("--video <url>","Input video file/URL").option("--music <url>","Background music file/URL (will loop if shorter than video)").option("--voice <url>","Voiceover file/URL").option("--music-volume <percent>","Music volume 0-100 (default: 30, recommended for mix with voice)","30").option("--voice-volume <percent>","Voice volume 0-100","100").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{!e.music&&!e.voice&&(c("At least one of --music or --voice must be provided"),process.exit(d.INVALID_INPUT));let n=parseInt(e.musicVolume,10)/100,t=parseInt(e.voiceVolume,10)/100;(Number.isNaN(n)||n<0||n>1)&&(c("Music volume must be between 0 and 100"),process.exit(d.INVALID_INPUT)),(Number.isNaN(t)||t<0||t>2)&&(c("Voice volume must be between 0 and 200"),process.exit(d.INVALID_INPUT));let o=e.format,r=o==="human"?Wn("Mixing audio...").start():null,i=[{url:e.video,role:"video"}];e.music&&i.push({url:e.music,role:"background",volume:n*5}),e.voice&&i.push({url:e.voice,role:"voice",volume:t*2});try{let a=await Vo({operation:"add-to-video",inputs:i,options:{musicVolume:n,voiceVolume:t}});if(!e.wait){r?.stop(),Hn(a,o);return}r&&(r.text=`Processing (ID: ${a.requestId})...`);let s=await K(()=>pn(a.requestId),120,3e3);if(r?.stop(),s.status==="failed"&&(c(s.error||"Audio mixing failed"),process.exit(d.GENERAL_ERROR)),Hn(s,o),e.output){if(!s.outputUrl)throw new Error("Audio mix completed without an output URL");let l=o==="human"?Wn("Downloading...").start():null;await Q(s.outputUrl,e.output),l?.stop(),o==="human"&&S(`Saved to: ${e.output}`)}}catch(a){r?.stop(),c(a instanceof Error?a.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),qc=new Jn("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?Wn("Checking status...").start():null;try{let o=await pn(e);t?.stop(),Hn(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),yi=new Jn("mix").description("Audio mixing commands").addCommand(jc).addCommand(qc);import{Command as Yn}from"commander";import zn from"ora";function Xn(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.audioUrl?console.log(e.audioUrl):console.log(e.requestId);return}u(`Request ID: ${e.requestId}`),u(`Status: ${e.status}`),e.duration&&u(`Duration: ${e.duration}s`),e.audioUrl&&S(`Audio URL: ${e.audioUrl}`),e.cost!==void 0&&u(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var Bc=new Yn("generate").description("Generate music from a text prompt").requiredOption("-p, --prompt <text>","Music description").option("-d, --duration <seconds>","Duration in seconds (3-600)","30").option("-s, --style <style>","Style preset").option("--provider <provider>","Untrusted provider hint (host policy is authoritative)").option("--mode <mode>","Intent: auto, retrieve, or generate","auto").option("--no-instrumental","Allow vocals (background music is instrumental by default)").option("--tempo <bpm>","Tempo hint in BPM (60-180)").option("--audio-format <format>","Audio format: mp3, wav, flac, ogg","mp3").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=Number(e.duration);(!Number.isInteger(n)||n<3||n>600)&&(c("Duration must be between 3 and 600 seconds (10 minutes)"),process.exit(d.INVALID_INPUT)),!e.wait&&e.output&&(c("--output requires waiting for completion; remove --no-wait"),process.exit(d.INVALID_INPUT)),["auto","retrieve","generate"].includes(e.mode)||(c("Mode must be auto, retrieve, or generate"),process.exit(d.INVALID_INPUT)),["mp3","wav","flac","ogg"].includes(e.audioFormat)||(c("Audio format must be mp3, wav, flac, or ogg"),process.exit(d.INVALID_INPUT));let t=e.tempo?Number(e.tempo):void 0;t!==void 0&&(!Number.isInteger(t)||t<60||t>180)&&(c("Tempo must be between 60 and 180 BPM"),process.exit(d.INVALID_INPUT));let o=e.format,r=o==="human"?zn("Generating music...").start():null,i;try{let a=await It({prompt:e.prompt,duration:n,options:{provider:e.provider,mode:e.mode,instrumental:e.instrumental,style:e.style,tempo:t,format:e.audioFormat}});if(i=a.requestId,!e.wait){r?.stop(),Xn(a,o);return}let s=a;if(a.status!=="completed"&&a.status!=="failed"&&(r&&(r.text=`Processing (ID: ${a.requestId})...`),s=await K(()=>at(a.requestId),180,2e3)),r?.stop(),s.status==="failed"&&(c(s.error||"Music generation failed"),process.exit(d.GENERAL_ERROR)),e.output){if(!s.audioUrl)throw new Error("Music completed without an audio URL");let l=o==="human"?zn("Downloading...").start():null;await Q(s.audioUrl,e.output),l?.stop(),o==="human"&&S(`Saved to: ${e.output}`),s={...s,output:e.output}}Xn(s,o)}catch(a){r?.stop(),c(de(a,i),o),process.exit(d.GENERAL_ERROR)}}),Gc=new Yn("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?zn("Checking status...").start():null;try{let o=await at(e);t?.stop(),Xn(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),bi=new Yn("music").description("Music generation commands").addCommand(Bc).addCommand(Gc);import{Command as Kn}from"commander";function wi(e,n){return[...n,e]}var Wc=new Kn("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",wi,[]).option("--type <type>","single, multiple, or word-cloud","single").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve creation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve poll creation");try{x(await $("createPoll",{approvalReceipt:"cli:--yes",options:n.option.map(t=>({text:t})),pollType:n.type,question:e,teamId:n.teamId,title:n.title}))}catch(t){c(t instanceof Error?t.message:"Poll creation failed"),process.exit(d.GENERAL_ERROR)}}),Hc=new Kn("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",wi).option("--type <type>","single, multiple, or word-cloud").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve update").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve poll update");try{x(await $("editPoll",{approvalReceipt:"cli:--yes",options:n.option?.map(t=>({text:t})),pollId:e,pollType:n.type,question:n.question,teamId:n.teamId,title:n.title}))}catch(t){c(t instanceof Error?t.message:"Poll update failed"),process.exit(d.GENERAL_ERROR)}}),vi=new Kn("poll").description("Standalone poll commands").addCommand(Wc).addCommand(Hc);import{Command as xi}from"commander";var Jc=new xi("status").description("Check a presentation generation run").argument("<run-id>","Run ID returned by presentation generation").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await D("createSlides",e,n.teamId);if(n.format==="json"){x(t);return}if(n.format==="quiet"){console.log(t.status);return}u(`Status: ${t.status}`),u(t.message),t.progress!==null&&u(`Progress: ${t.progress}%`),t.error&&c(t.error.message)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Si=new xi("presentation").description("Presentation background-run commands").addCommand(Jc);import{writeFile as zc}from"fs/promises";import{Command as Xc}from"commander";import Yc from"ora";var Ci=new Xc("scrape").description("Extract content from a URL").argument("<url>","URL to scrape").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Save content to file").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format,o=t==="human"?Yc("Scraping URL...").start():null;try{let r=await jo(e,n.teamId);o?.stop(),(!r.success||!r.data)&&(c(r.error||"Failed to scrape URL"),process.exit(d.GENERAL_ERROR));let i=r.data;if(n.output&&(await zc(n.output,i.content,"utf-8"),t==="human"&&S(`Content saved to: ${n.output}`)),t==="json"){let{cost:a,...s}=i;x(s);return}if(t==="quiet"){console.log(i.content);return}i.title&&(console.log(),console.log(`Title: ${i.title}`)),i.metadata?.description&&console.log(`Description: ${i.metadata.description}`),console.log(`URL: ${i.url}`),console.log(`Tokens: ~${i.metadata?.tokenUsage?.toLocaleString()||"unknown"}`),i.warning&&_(i.warning),n.output||(console.log(),console.log("--- Content ---"),console.log(i.content)),i.cost&&i.cost>0&&u(`Cost: $${i.cost.toFixed(6)}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}});import{Command as dt}from"commander";function Xt(e,n){n!=="quiet"&&x(e)}var Kc=new dt("web").description("Search current public web sources").argument("<query>","Search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","5").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchInternet",{maxResults:Number.parseInt(n.maxResults,10),query:e,teamId:n.teamId});Xt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Search failed"),process.exit(d.GENERAL_ERROR)}}),Qc=new dt("news").description("Search recent news").argument("<topic>","News topic").option("--team-id <id>","Workspace ID").option("--timeframe <value>","Timeframe hint").option("--max-results <count>","Maximum results","6").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("getNews",{maxResults:Number.parseInt(n.maxResults,10),teamId:n.teamId,timeframe:n.timeframe,topic:e});Xt(t,n.format)}catch(t){c(t instanceof Error?t.message:"News search failed"),process.exit(d.GENERAL_ERROR)}}),Zc=new dt("images").description("Search licensed image providers").argument("<query>","Image search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","10").option("--aspect <aspect>","Aspect: any, square, wide, tall","any").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchImages",{aspect:n.aspect,maxResults:Number.parseInt(n.maxResults,10),query:e,teamId:n.teamId});Xt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Image search failed"),process.exit(d.GENERAL_ERROR)}}),el=new dt("video").description("Search licensed stock-video providers").argument("<query>","Stock-video search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","10").option("--orientation <value>","Orientation: landscape, portrait, square, any","any").option("--license <value>","License: free, premium, any","any").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchStockVideo",{license:n.license,maxResults:Number.parseInt(n.maxResults,10),orientation:n.orientation,query:e,teamId:n.teamId});Xt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Video search failed"),process.exit(d.GENERAL_ERROR)}}),Ii=new dt("search").description("Web, news, image, and stock-video search").addCommand(Kc).addCommand(Qc).addCommand(Zc).addCommand(el);import{Command as eo}from"commander";import Qn from"ora";function Zn(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.audioUrl?console.log(e.audioUrl):e.requestId?console.log(e.requestId):console.log(e.id);return}u(`Request ID: ${e.requestId||e.id}`),u(`Status: ${e.status}`),e.duration&&u(`Duration: ${e.duration}s`),e.audioUrl&&S(`Audio URL: ${e.audioUrl}`),e.cost!==void 0&&u(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var tl=new eo("generate").description("Generate sound effects from a text prompt").requiredOption("-t, --text <text>","Sound effect description (e.g., 'thunder rumbling, rain on window')").option("-d, --duration <seconds>","Duration in seconds (0.5-30)").option("-p, --provider <provider>","Untrusted provider hint (host policy is authoritative)").option("--prompt-influence <value>","How closely to follow prompt (0-1)","0.3").option("-l, --loop","Generate seamless looping audio",!1).option("--format <format>","Audio format: mp3, wav, ogg","mp3").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --output-format <format>","Output format: human, json, quiet","human").action(async e=>{let n;e.duration&&(n=parseFloat(e.duration),(isNaN(n)||n<.5||n>30)&&(c("Duration must be between 0.5 and 30 seconds"),process.exit(d.INVALID_INPUT)));let t;e.promptInfluence&&(t=parseFloat(e.promptInfluence),(isNaN(t)||t<0||t>1)&&(c("Prompt influence must be between 0 and 1"),process.exit(d.INVALID_INPUT)));let o=e.outputFormat,r=o==="human"?Qn("Generating sound effects...").start():null,i;try{let a=await qo({text:e.text,duration:n,options:{provider:e.provider,promptInfluence:t,loop:e.loop,format:e.format}});if(i=a.requestId||a.id,!e.wait){r?.stop(),Zn(a,o);return}let s=a;if(a.status!=="completed"&&a.status!=="failed"){let l=a.requestId||a.id;r&&(r.text=`Processing (ID: ${l})...`),s=await K(()=>fn(l),60,2e3)}if(r?.stop(),s.status==="failed"&&(c(s.error||"Sound effects generation failed"),process.exit(d.GENERAL_ERROR)),Zn(s,o),e.output){if(!s.audioUrl)throw new Error("Sound effect completed without an audio URL");let l=o==="human"?Qn("Downloading...").start():null;await Q(s.audioUrl,e.output),l?.stop(),o==="human"&&S(`Saved to: ${e.output}`)}}catch(a){r?.stop(),c(de(a,i),o),process.exit(d.GENERAL_ERROR)}}),nl=new eo("status").description("Check status of a sound effects generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?Qn("Checking status...").start():null;try{let o=await fn(e);t?.stop(),Zn(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Ri=new eo("sfx").description("Sound effects generation commands").addCommand(tl).addCommand(nl);import{mkdir as ol,writeFile as Ti}from"fs/promises";import{dirname as rl}from"path";import{Command as Yt}from"commander";import $i from"ora";var ki="en-US-Neural2-C",Ai="gemini",il=new Yt("generate").description("Generate speech from text").requiredOption("-t, --text <text>","Text to convert to speech").requiredOption("-o, --output <path>","Output file path").option("--voice-id <voiceId>","Voice ID (e.g., ElevenLabs: 21m00Tcm4TlvDq8ikWAM)").option("--voice <voice>",`Voice name (default: ${ki})`).option("-p, --provider <provider>",`Provider: gemini, elevenlabs, openai (default: ${Ai})`).option("-m, --model <model>","Model (provider-specific)").option("-s, --speed <speed>","Speech speed 0.1-4.0 (default: 1.0)").option("-l, --lang <lang>","Language or locale hint (for example en-US)").option("--speakers <json>",`Multi-speaker (Gemini, max 2): '[{"name":"Joe","voice":"Kore"},{"name":"Jane","voice":"Puck"}]'`).option("-i, --instructions <text>","Style prompt (OpenAI gpt-4o-mini-tts): tone, accent, speed, emotion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?$i("Generating speech...").start():null,o;e.speed&&(o=parseFloat(e.speed),(Number.isNaN(o)||o<.1||o>4)&&(t?.stop(),c("Speed must be between 0.1 and 4.0"),process.exit(d.INVALID_INPUT)));let r;if(e.speakers)try{r=JSON.parse(e.speakers),(!Array.isArray(r)||r.length===0||r.length>2||r.some(a=>!a||typeof a!="object"||typeof a.name!="string"||!a.name.trim()||typeof a.voice!="string"||!a.voice.trim()))&&(t?.stop(),c("Speakers must be an array with 1-2 name/voice items"),process.exit(d.INVALID_INPUT))}catch{t?.stop(),c(`Invalid --speakers JSON. Example: '[{"name":"Joe","voice":"Kore"}]'`),process.exit(d.INVALID_INPUT)}let i;try{let a=e.voiceId,s=e.voice||ki,l=e.provider||Ai,m={};r&&(m.gemini={speakers:r}),e.instructions&&(m.openai={instructions:e.instructions});let p=await Ct({text:e.text,options:{language:e.lang,provider:l,voiceId:a,voice:s,model:e.model,speed:o,providerOptions:Object.keys(m).length>0?m:void 0}});i=p.requestId,t?.stop();let w=e.output.endsWith(`.${p.format}`)?e.output:`${e.output}.${p.format}`;await ol(rl(w),{recursive:!0}),await Ti(w,p.audioData);let I=w.replace(/\.[^.]+$/,".txt");if(await Ti(I,e.text,"utf-8"),n==="json"){x({status:"completed",output:w,audioUrl:p.audioUrl,duration:p.duration,provider:p.provider,format:p.format,voice_id:p.voiceId??null,voice:p.voice??s,model:p.model??e.model??null,speed:p.speed??o??1,lang:p.language??e.lang??null,langApplied:p.langApplied??!1});return}if(n==="quiet"){console.log(w);return}S(`Saved to: ${w}`),u(`Duration: ${p.duration.toFixed(2)}s`),u(`Provider: ${p.provider}`),u(`Cost: $${p.cost.toFixed(6)}`)}catch(a){t?.stop(),c(de(a,i),n),process.exit(d.GENERAL_ERROR)}}),al=new Yt("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json","human").action(async e=>{let n=e.format==="human"?$i("Fetching voices...").start():null;try{let t=await _o(e.provider);if(n?.stop(),e.format==="json"){x(t.voices);return}if(Array.isArray(t.voices)){let o=e.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${o} Voices:`),console.log("-".repeat(50));for(let r of t.voices)console.log(` ${r.name} (${r.id})`),console.log(` ${r.description}`)}else for(let[o,r]of Object.entries(t.voices))if(!(!r||r.length===0)){console.log(),console.log(`${o.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let i of r)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}}catch(t){n?.stop(),c(t instanceof Error?t.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),sl=new Yt("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json","json").action(async(e,n)=>{try{x(await D("generateSpeech",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Ei=new Yt("tts").description("Text-to-speech commands").addCommand(il).addCommand(al).addCommand(sl);import{execSync as Ze,spawn as Ul,spawnSync as Fl}from"child_process";import{access as oo,mkdir as et,readFile as pt,rm as ro,writeFile as we}from"fs/promises";import{join as G,resolve as mt}from"path";import{Command as te}from"commander";import _l from"ffmpeg-static";import gt from"ora";import{homedir as cl}from"os";import{join as Oi}from"path";import{readdir as ll}from"fs/promises";var dl="conceptcraft";function Xe(){return Oi(cl(),`.${dl}`,"projects")}function Kt(e){return Oi(Xe(),e)}async function to(){try{let e=Xe();return(await ll(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}function Pi(e,n){let t=2,o=`${e}-${t}`;for(;n.includes(o);)t++,o=`${e}-${t}`;return o}import{Command as ul}from"commander";import ml from"ora";import{execSync as pl,spawnSync as Ye}from"child_process";import{mkdirSync as Ni,existsSync as Zt,readFileSync as Di,writeFileSync as Li}from"fs";import{join as $e,basename as gl}from"path";import{tmpdir as fl}from"os";function en(e,n){try{return pl(n,{stdio:"ignore"}),!0}catch{return!1}}function Qt(e){let n=Math.floor(e/60),t=Math.floor(e%60),o=Math.round(e%1*10);return`${n}:${String(t).padStart(2,"0")}.${o}`}function hl(e){let n=Ye("ffprobe",["-v","error","-show_entries","format=duration","-of","default=noprint_wrappers=1:nokey=1",e],{encoding:"utf-8"});return parseFloat(n.stdout.trim())}function yl(e,n){let t=Ye("ffmpeg",["-i",e,"-vf",`select='gt(scene,${n})',showinfo`,"-vsync","vfr","-f","null","-"],{encoding:"utf-8",timeout:12e4}),o=[0],r=(t.stderr||"").split(`
|
|
3775
|
-
`);for(let i of r){let a=i.match(/pts_time:([\d.]+)/);if(a){let s=parseFloat(a[1]);s-o[o.length-1]>=1.5&&o.push(s)}}return o}function
|
|
3776
|
-
`),b=$e(o,"analysis.md");
|
|
3777
|
-
Results saved to: ${o}`)}});import{mkdir as
|
|
3771
|
+
`);ze.command("install").description(`Install ${g.displayName} skills for AI coding assistants`).argument("[type]","Skill type: main, video, presentation, or omit for all").option("-d, --dir <path>","Install to specific directory").option("-g, --global","Install globally (to home directory)",!0).option("-l, --local","Install locally (to current directory)").option("-f, --force","Overwrite existing skill files").option("-m, --mode <mode>","Skill mode: standalone (render to file) or studio (Studio Preview)","standalone").action(async(e,n)=>{n.mode&&!Wt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Wt.join(", ")}`),process.exit(1));let t={...ei,mode:n.mode},o=[];e&&!dt.includes(e)&&(c(`Invalid skill type: ${e}. Must be one of: ${dt.join(", ")}`),process.exit(1));let r=[{name:"tts",content:_e(t)},{name:"music",content:Ve(t)},{name:"sfx",content:Me(t)},{name:"mix",content:je(t)},{name:"image",content:qe(t)},{name:"video-search",content:Be(t)},{name:"scrape",content:Ge(t)},{name:"branding",content:We(t)},{name:"config",content:He(t)}];(!e||e==="main")&&o.push({name:g.name,content:Ut(t),references:r});let i=[{name:"brief-guide",content:Dn.render(t)},{name:"website-assets",content:Nn.render(t)},{name:"source-scraping",content:Ln.render(t)}];(!e||e==="video")&&(o.push({name:`${g.name}-video`,content:Ft(t),references:i}),o.push({name:"remotion-scene-craft",content:Zr(t)})),(!e||e==="presentation")&&o.push({name:`${g.name}-presentation`,content:_t(t)}),(!e||e==="presentation-edit")&&o.push({name:`${g.name}-presentation-edit`,content:Vt(t)}),e==="tts"&&o.push({name:`${g.name}-tts`,content:_e(t)}),e==="music"&&o.push({name:`${g.name}-music`,content:Ve(t)}),e==="sfx"&&o.push({name:`${g.name}-sfx`,content:Me(t)}),e==="mix"&&o.push({name:`${g.name}-mix`,content:je(t)}),e==="image"&&o.push({name:`${g.name}-image`,content:qe(t)}),e==="video-search"&&o.push({name:`${g.name}-video-search`,content:Be(t)}),e==="scrape"&&o.push({name:`${g.name}-scrape`,content:Ge(t)}),e==="branding"&&o.push({name:`${g.name}-branding`,content:We(t)}),e==="config"&&o.push({name:`${g.name}-config`,content:He(t)}),console.log();for(let a of o){m(`Installing ${a.name}...`);let s=Bt(a.name,a.content,{dir:n.dir,local:n.local,force:n.force},a.references);if(s.installed.length>0&&(S(`${a.name} installed successfully`),R(" Installed to",s.installed.join(", "))),s.skipped.length>0&&(m(` Skipped (already exists): ${s.skipped.join(", ")}`),console.log(V.gray(" Use --force to overwrite"))),s.errors.length>0)for(let d of s.errors)c(` ${d}`);s.installed.length===0&&s.skipped.length===0&&s.errors.length===0&&(m(" No supported AI coding assistants detected"),console.log(V.gray(" Supported editors: "+Yr().join(", "))),console.log(V.gray(" Use --dir <path> to install to a specific directory"))),console.log()}if(!e||e==="video"){for(let a of[{name:"video-branding-director",generate:()=>Mn(t)},{name:"video-scene-builder",generate:Fn},{name:"video-scene-reviewer",generate:Un},{name:"video-audio-director",generate:()=>_n(t)},{name:"video-continuity-editor",generate:Vn}]){m(`Installing ${a.name} agent...`);let s=Kr(a.name,a.generate(),{force:n.force,dir:n.dir});if(s.installed.length>0){S(`${a.name} agent installed`);let d={"Claude Code":"~/.claude/agents/","GitHub Copilot":"~/.github/agents/"};R(" Installed to",s.installed.map(u=>n.dir?u:`${u} (${d[u]??"~/.<editor>/agents/"})`).join(", "))}s.skipped.length>0&&m(` Agent skipped (already exists): ${s.skipped.join(", ")}`)}console.log()}});ze.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action((e="main",n)=>{n.mode&&!Wt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Wt.join(", ")}`),process.exit(1));let t={...ei,mode:n.mode},r={main:()=>Ut(t),video:()=>Ft(t),presentation:()=>_t(t),"presentation-edit":()=>Vt(t),tts:()=>_e(t),music:()=>Ve(t),sfx:()=>Me(t),mix:()=>je(t),image:()=>qe(t),"video-search":()=>Be(t),scrape:()=>Ge(t),branding:()=>We(t),config:()=>He(t),"video-branding-director":()=>Mn(t),"video-scene-builder":()=>Fn(),"video-scene-reviewer":()=>Un(),"video-audio-director":()=>_n(t),"video-continuity-editor":()=>Vn()}[e];if(r)console.log(r());else{let i=[...dt,"video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"];c(`Invalid skill type: ${e}. Must be one of: ${i.join(", ")}`),process.exit(1)}});ze.command("uninstall").description(`Remove ${g.displayName} skills from AI coding assistants`).argument("[type]","Skill type: main, video, presentation, or omit for all").option("-g, --global","Uninstall globally (from home directory)",!0).option("-l, --local","Uninstall locally (from current directory)").action(async(e,n)=>{let t=[];e&&!dt.includes(e)&&(c(`Invalid skill type: ${e}. Must be one of: ${dt.join(", ")}`),process.exit(1)),(!e||e==="main")&&t.push(g.name),(!e||e==="video")&&(t.push(`${g.name}-video`),t.push("remotion-scene-craft")),(!e||e==="presentation")&&t.push(`${g.name}-presentation`),(!e||e==="presentation-edit")&&t.push(`${g.name}-presentation-edit`),(!e||e==="tts")&&t.push(`${g.name}-tts`),(!e||e==="music")&&t.push(`${g.name}-music`),(!e||e==="sfx")&&t.push(`${g.name}-sfx`),(!e||e==="mix")&&t.push(`${g.name}-mix`),(!e||e==="image")&&t.push(`${g.name}-image`),(!e||e==="video-search")&&t.push(`${g.name}-video-search`),(!e||e==="scrape")&&t.push(`${g.name}-scrape`),(!e||e==="branding")&&t.push(`${g.name}-branding`),(!e||e==="config")&&t.push(`${g.name}-config`),console.log();for(let o of t){let r=Gt(o,{local:n.local});if(r.removed.length>0?(S(`${o} uninstalled`),R(" Removed from",r.removed.join(", "))):m(` ${o} not found`),r.errors.length>0)for(let i of r.errors)_(` Failed to remove: ${i}`)}if(!e||e==="video")for(let o of["video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"])Qr(o).removed.length>0&&S(`${o} agent uninstalled`);console.log()});import{Command as wc}from"commander";import lt from"chalk";var ti=new wc("templates").description("List slide design templates (use with `create --template <id>`)").argument("[search]","Filter templates by name, description, or category").option("-f, --format <format>","Output format (table, json)","table").option("--limit <n>","Maximum templates to list","25").action(async(e,n)=>{await P();try{let t=Number.parseInt(n.limit??"25",10),{templates:o}=await Do(e,Number.isFinite(t)?t:25);if(o.length===0){n.format==="json"?console.log(JSON.stringify([])):m("No templates found");return}if(n.format==="json"){console.log(JSON.stringify(o,null,2));return}for(let r of o){let i=[r.isDefault?lt.green("default"):null,r.category??null,r.recommendedModes?.length?`modes: ${r.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${lt.bold(r.name)} ${lt.gray(r.id)}${i?`
|
|
3772
|
+
${lt.gray(i)}`:""}`)}console.log(),console.log(lt.gray(`Use one with: ${g.commands[0]} create "<topic>" --template <id>`))}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as vc}from"commander";import jn from"chalk";var ni=new vc("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)","human").action(async e=>{await P();try{let n=await we();if(Sn(),e.format==="json"){console.log(JSON.stringify(n,null,2));return}fe("User"),console.log(),R("Email",n.user.email),n.user.username&&R("Username",n.user.username),(n.user.firstName||n.user.lastName)&&R("Name",[n.user.firstName,n.user.lastName].filter(Boolean).join(" "));let t=n.authType==="apiKey"?"API Key":n.authType==="oauth"?"OAuth":"Session";if(R("Auth Type",t),n.currentTeam&&(console.log(),fe("Current Team"),console.log(),R("ID",n.currentTeam.id),R("Name",n.currentTeam.name),R("Plan",n.currentTeam.planName),R("Role",n.currentTeam.isOwner?"Owner":"Member")),n.teams.length>1){console.log(),fe("All Teams"),console.log();for(let o of n.teams){let r=o.isCurrent?jn.green(" (current)"):"";console.log(` ${jn.bold(o.name)}${r}`),console.log(jn.gray(` ID: ${o.id} | Plan: ${o.planName} | Role: ${o.role}`))}}console.log()}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}});function oi(e){return e[0]==="--"?e.slice(1):e}import{Command as qn}from"commander";function xc(e,n){return[...n,e]}var Sc=new qn("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",xc,[]).option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await $("createAdSet",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,brief:n.brief,hooks:n.hook.length?n.hook:[n.brief],style:n.style,teamId:n.teamId,title:e}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(l.GENERAL_ERROR)}}),Cc=new qn("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L("createAdSet",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),ri=new qn("ad-set").description("Ad set commands").addCommand(Sc).addCommand(Cc);import{Command as ai}from"commander";function ii(e){return new ai(e).description(e==="create"?"Create and activate a scheduled agent":"Create a reviewable agent recommendation").argument("<name>","Agent name").requiredOption("--instructions <markdown>","Agent instructions").option("--description <text>","Agent description","").option("--schedule <frequency>","manual, daily, weekdays, weekly, or monthly","weekly").option("--time <hh:mm>","Local run time","09:00").option("--timezone <zone>","IANA timezone","UTC").option("--output <adapter>","Output adapter","digest").option("--team-id <id>","Workspace ID").option("--yes","Approve saving the agent").action(async(n,t)=>{if(!t.yes)return c("Pass --yes to approve this operation");try{x(await $(e==="create"?"createAgent":"recommendAgent",{approvalReceipt:"cli:--yes",description:t.description,instructionsMarkdown:t.instructions,name:n,output:t.output,schedule:t.schedule,scheduleTime:t.time,teamId:t.teamId,timezone:t.timezone}))}catch(o){c(o instanceof Error?o.message:"Agent operation failed"),process.exit(l.GENERAL_ERROR)}})}var si=new ai("agent").description("Scheduled agent commands").addCommand(ii("create")).addCommand(ii("recommend"));import{Command as Ht}from"commander";import Rc from"ora";import{mkdir as Ic,writeFile as ci}from"fs/promises";import{dirname as Tc}from"path";async function Q(e,n){if(await Ic(Tc(n),{recursive:!0}),e.startsWith("data:")){let r=e.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");if(i.length===0)throw new Error("Downloaded media was empty");await ci(n,i);return}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download media: ${t.status}`);let o=Buffer.from(await t.arrayBuffer());if(o.length===0)throw new Error("Downloaded media was empty");await ci(n,o)}var kc=15e3,Ac=40;function Bn(e,n){if(n==="json"){x(e);return}if(n==="quiet"){console.log(e.videoUrl??e.requestId);return}m(`Request ID: ${e.requestId}`),m(`Status: ${e.status}`),e.durationSec!=null&&m(`Duration: ${e.durationSec}s`),e.videoUrl&&S(`Video URL: ${e.videoUrl}`),e.error&&c(`Error: ${e.error}`)}var $c=new Ht("options").description("List available presenter avatars and voices").option("--language <language>","Filter voices by language").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{try{let n=await Jo(e.language);if(e.format==="json"){x(n);return}let t=n.personal??[];if(e.format==="quiet"){for(let o of t)console.log(o.id);for(let o of n.avatars)console.log(o.id);for(let o of n.voices)console.log(o.id);return}if(t.length>0){m("Your presenters:");for(let o of t)console.log(` ${o.id} ${o.name}`)}m("Avatars:");for(let o of n.avatars){let r=o.renderTiers?.length?` [${o.renderTiers.join(", ")}]`:"";console.log(` ${o.id} ${o.name}${r}`)}m("Voices:");for(let o of n.voices)console.log(` ${o.id} ${o.name}${o.language?` (${o.language})`:""}`)}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Ec=new Ht("generate").description("Generate a reusable presenter clip").option("--avatar-id <id>","Avatar id from 'avatar options'; sandbox runs use the host presenter policy").option("--audio-url <url>","Public narration audio URL for avatar lip sync").option("--voice-id <id>","Voice id from 'avatar options'").option("--script <text>","Exact words for the presenter to speak").requiredOption("-o, --output <path>","Local output path").option("--aspect <aspect>","Aspect: 1:1, 9:16, 16:9","9:16").option("--duration <seconds>","Maximum requested duration (1-300)").option("--transparent","Render a transparent-background WebM presenter clip").option("--background-color <hex>","Solid presenter background color, for example #0F172A").option("--background-image-url <url>","Public image URL used as the presenter background").option("--fit <mode>","Background image fit: contain or cover").option("--output-format <container>","Container: mp4 (default) or webm \u2014 webm renders a transparent-background clip (single scene) for compositing").option("--render-tier <tier>","Render cost/quality: basic, standard, premium","basic").option("--title <title>","Clip title","Presenter clip").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.transparent?"webm":e.outputFormat;!!e.audioUrl==!!e.script&&(c("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(l.INVALID_INPUT)),["1:1","9:16","16:9"].includes(e.aspect)||(c("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(l.INVALID_INPUT)),e.outputFormat!==void 0&&!["mp4","webm"].includes(e.outputFormat)&&(c("Output format must be mp4 or webm"),process.exit(l.INVALID_INPUT)),e.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(e.backgroundColor)&&(c("Background color must be a six-digit hex value"),process.exit(l.INVALID_INPUT)),e.backgroundColor&&e.backgroundImageUrl&&(c("Provide only one presenter background"),process.exit(l.INVALID_INPUT)),e.fit!==void 0&&!["contain","cover"].includes(e.fit)&&(c("Fit must be contain or cover"),process.exit(l.INVALID_INPUT)),e.fit&&!e.backgroundImageUrl&&(c("Fit requires --background-image-url"),process.exit(l.INVALID_INPUT)),e.transparent&&e.outputFormat==="mp4"&&(c("--transparent cannot be combined with --output-format mp4"),process.exit(l.INVALID_INPUT)),n==="webm"&&(e.backgroundColor||e.backgroundImageUrl)&&(c("Transparent WebM output cannot be combined with a background"),process.exit(l.INVALID_INPUT)),["basic","standard","premium"].includes(e.renderTier)||(c("Render tier must be basic, standard, or premium"),process.exit(l.INVALID_INPUT));let t=e.duration?Number.parseInt(e.duration,10):void 0;t!==void 0&&(!Number.isFinite(t)||t<1||t>300)&&(c("Duration must be between 1 and 300 seconds"),process.exit(l.INVALID_INPUT));let o=e.format==="human"?Rc("Generating presenter clip...").start():null;try{let r=e.audioUrl?{audioUrl:e.audioUrl}:{script:e.script??"",...e.voiceId?{voiceId:e.voiceId}:{}},i=await zo({...r,aspect:e.aspect,...e.avatarId?{avatarId:e.avatarId}:{},...e.backgroundColor?{backgroundHex:e.backgroundColor}:{},...e.backgroundImageUrl?{backgroundImageUrl:e.backgroundImageUrl}:{},...t!==void 0?{durationSec:t}:{},...e.fit?{fit:e.fit}:{},...n?{outputFormat:n}:{},renderTier:e.renderTier,title:e.title});if(!e.wait){o?.stop(),Bn(i,e.format);return}let a=await K(()=>bn(i.requestId),Ac,kc);if(a.status==="failed")throw new Error(a.error||"Presenter generation failed");if(!a.videoUrl)throw new Error("Presenter generation completed without a video URL");o&&(o.text="Downloading presenter clip..."),await Q(a.videoUrl,e.output),o?.stop(),Bn(a,e.format),e.format==="human"&&S(`Saved to: ${e.output}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Oc=new Ht("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{Bn(await bn(e),n.format)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),di=new Ht("avatar").description("Avatar/presenter media commands").addCommand($c).addCommand(Ec).addCommand(Oc);import{writeFile as li}from"fs/promises";import H from"chalk";import{Command as se}from"commander";import Pc from"ora";var ui=new se("branding").description("Manage brand profiles").addCommand(new se("list").description("List brand profiles").option("-f, --format <format>","Output format (table, json)","table").action(async e=>{await P();try{let n=await gn();if(n.brandings.length===0){e.format==="json"?console.log(JSON.stringify([])):(m("No brand profiles found"),console.log(),console.log(H.gray(`Create one with: ${g.commands[0]} branding extract <url>`)));return}e.format==="json"?console.log(JSON.stringify(n.brandings,null,2)):console.log(nr(n.brandings))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new se("get").description("Get brand profile details").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)","summary").option("-o, --output <path>","Save JSON to file").action(async(e,n)=>{await P();try{let t=await Lo(e);if(n.output){await li(n.output,JSON.stringify(t,null,2)),S(`Brand profile saved to ${n.output}`);return}if(n.format==="json")console.log(JSON.stringify(t,null,2));else{if(fe("Brand Profile"),console.log(),R("ID",t.id),R("Name",t.name),R("Source URL",t.sourceUrl??H.gray("None")),R("Default",t.isDefault?H.green("Yes"):"No"),t.createdAt&&R("Created",new Date(t.createdAt).toLocaleString()),console.log(),t.primaryColor||t.colors.length>0){if(console.log(H.bold(" Colors")),t.primaryColor){let r=H.bgHex(t.primaryColor)(" ");console.log(` Primary: ${r} ${t.primaryColor}`)}if(t.colors.length>0){console.log(" Palette:");for(let r of t.colors.slice(0,10)){let i=H.bgHex(r.hex)(" "),a=r.role?H.gray(` (${r.role})`):"";console.log(` ${i} ${r.hex}${a}`)}}console.log()}t.logoUrl&&(console.log(H.bold(" Logo")),console.log(` ${t.logoUrl}`),console.log());let o=t.typography;o&&Object.keys(o).length>0&&(console.log(H.bold(" Typography")),(o.primary||o.headings)&&console.log(` Headings: ${o.primary||o.headings||"-"}`),(o.secondary||o.body)&&console.log(` Body: ${o.secondary||o.body||"-"}`),console.log()),(t.confidence||t.extractionMethod)&&(console.log(H.bold(" Extraction")),t.confidence&&console.log(` Confidence: ${Math.round(t.confidence*100)}%`),t.extractionMethod&&console.log(` Method: ${t.extractionMethod}`),console.log()),console.log(H.gray(" Use --format json for full details")),console.log()}}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}})).addCommand(new se("find").description("Find existing brand profile by name or URL").argument("<query>","Brand name or website URL to search for").action(async e=>{await P();try{let n=await gn(),t=e.toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,""),o=n.brandings.filter(r=>{let i=(r.name||"").toLowerCase(),a=(r.sourceUrl||"").toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,"");return i.includes(t)||a.includes(t)||i.length>0&&t.includes(i)||a.length>0&&t.includes(a)});if(o.length===0){m(`No brand profiles matching "${e}"`),console.log(H.gray(` Extract one with: ${g.commands[0]} branding extract <url>`));return}console.log(`Found ${o.length} brand${o.length>1?"s":""}:
|
|
3773
|
+
`);for(let r of o){let i=r.primaryColor?`${H.bgHex(r.primaryColor)(" ")} ${r.primaryColor}`:"";console.log(` ${H.bold(r.name)} ${H.gray(r.id)}`),r.sourceUrl&&console.log(` ${H.gray(r.sourceUrl)}`),i&&console.log(` ${i}`),console.log()}console.log(H.gray(` Export with: ${g.commands[0]} branding get <id> -o branding.json`))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new se("extract").description("Extract brand profile from a website").argument("<url>","Website URL to extract branding from").option("--team-id <id>","Team ID").option("--yes","Confirm starting a paid/external extraction").option("--no-save","Extract without saving").option("-o, --output <path>","Save JSON to file").action(async(e,n)=>{await P(),n.yes||(c("Pass --yes to confirm brand extraction."),process.exit(l.INVALID_INPUT));try{new URL(e.startsWith("http")?e:`https://${e}`)}catch{c("Invalid URL format"),process.exit(6)}let t=e.startsWith("http")?e:`https://${e}`,o=n.teamId??ht(),r=Pc({text:`Extracting branding from ${t}...`,stream:process.stdout}).start();try{let i=await Uo(t,o,"cli:--yes");r.succeed("Brand extraction started");let a=JSON.stringify(i,null,2);n.output?(await li(n.output,a),S(`Brand profile saved to ${n.output}`)):console.log(a),m(`Check progress with: ${g.commands[0]} branding status ${i.runId}`),console.log()}catch(i){r.fail("Extraction failed"),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}})).addCommand(new se("status").description("Check a brand extraction run").argument("<run-id>","Run ID returned by branding extract").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L("extractBranding",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}})).addCommand(new se("set-default").description("Set a brand profile as default").argument("<id>","Brand profile ID").action(async e=>{await P(),m(`To set brand ${e} as default, use the web dashboard.`),console.log(),console.log(H.gray("API support for setting default brand is coming soon."))})).addCommand(new se("competitor").description("Brand competitor commands").addCommand(new se("list").description("List competitors for a brand").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").action(async e=>{try{console.log(JSON.stringify(await $("getBrandCompetitors",{brandingId:e.brandingId,teamId:e.teamId}),null,2))}catch(n){c(n instanceof Error?n.message:"Lookup failed"),process.exit(1)}})).addCommand(new se("add").description("Add or update a brand competitor").argument("<name>","Competitor name").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").option("--website <url>","Competitor website").option("--x-handle <handle>","Competitor X handle").option("--yes","Confirm writing brand data").action(async(e,n)=>{n.yes||(c("Pass --yes to confirm adding a competitor."),process.exit(l.INVALID_INPUT));try{x(await $("addCompetitor",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,name:e,teamId:n.teamId,website:n.website,xHandle:n.xHandle}))}catch(t){c(t instanceof Error?t.message:"Write failed"),process.exit(l.GENERAL_ERROR)}}))).addCommand(new se("social").description("Brand social handle commands").addCommand(new se("add").description("Add or update a brand social handle").argument("<platform>","Social platform").argument("<handle>","Account handle").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").option("--yes","Confirm writing brand data").action(async(e,n,t)=>{t.yes||(c("Pass --yes to confirm adding a social handle."),process.exit(l.INVALID_INPUT));try{x(await $("addBrandSocialHandle",{approvalReceipt:"cli:--yes",brandingId:t.brandingId,handle:n,platform:e,teamId:t.teamId}))}catch(o){c(o instanceof Error?o.message:"Write failed"),process.exit(l.GENERAL_ERROR)}})));import{readFile as Nc}from"fs/promises";import{Command as mi}from"commander";var Dc=new mi("extract").description("Extract normalized text from a URL or local file").argument("<source>","URL, encoded source, or local file path").option("--team-id <id>","Workspace ID").option("--mime-type <type>","Source MIME type").option("--max-length <count>","Maximum output characters","30000").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=e,o;e.includes("://")||(t=await Nc(e,"utf8"),o=e);let r=await $("extractContent",{filename:o,maxLength:Number.parseInt(n.maxLength,10),mimeType:n.mimeType,source:t,teamId:n.teamId});n.format!=="quiet"&&x(r)}catch(t){c(t instanceof Error?t.message:"Extraction failed"),process.exit(l.GENERAL_ERROR)}}),pi=new mi("content").description("Content extraction commands").addCommand(Dc);import Y from"chalk";import{Command as Lc}from"commander";import{existsSync as Uc,readFileSync as Fc}from"fs";import _c,{resolve as gi}from"path";var fi=new Lc("create").description("Create a new presentation").argument("<topic>","The topic or title for the presentation").option("-n, --slides <count>","Number of slides (1-20)").option("-m, --mode <mode>","Generation quality (best, balanced, fast, ultrafast, instant, image-min, image, image-max) \u2014 default: fast. image-min/image/image-max render each slide as a full-bleed AI image (text not editable); slower + pricier, require image-mode access, and cap at 25 slides. image-min is cheapest (brand colors only, no exact fonts).").option("--image-tier <tier>","Embedded-image quality for HTML modes: smart (default, auto-routes per image), fast (cheapest, no extra credits), balanced (+50 credits/slide), best (premium, +200 credits/slide, slow). Ignored for image-*/instant modes.").option("-t, --tone <tone>","Tone (creative, professional, educational, formal, casual)").option("--amount <amount>","Content density (minimal, concise, detailed, extensive)").option("--audience <text>","Target audience description").option("-l, --language <lang>","Output language").option("--branding-id <id>","Branding ID (from `ccr branding list` or `ccr branding extract`)").option("--brand-domain <url>","Brand the deck by website/domain (e.g. https://www.pfizer.com). Errors if no matching saved brand exists.").option("--template <id>","Slide template ID to style the deck after (from `ccr templates`). A default template is applied automatically when omitted.").option("-c, --context <text>","Inline text context (research notes, key facts)").option("--context-file <path>","Path to a context file (text, markdown, JSON)").option("--stdin","Read context from stdin").option("-f, --file <paths...>","Files to upload (PDF, PPTX, DOCX, images)").option("-g, --goal <type>","Goal (inform, persuade, train, learn, entertain, report)").option("--styling <mode>","Styling mode (freeform, brand-only, brand-plus-style, style-only, no-styling)").option("--reference-url <url>","Image URL to use as visual style reference").option("--thinking-depth <depth>","AI thinking depth (quick, moderate, deep, profound)").option("--theme <preset>","[instant mode only] Color theme preset (blue, violet, rose, orange, green)").option("--primary-color <hex>","[instant mode only] Primary color (e.g., #0066CC)").option("--secondary-color <hex>","[instant mode only] Secondary color").option("--accent-color <hex>","[instant mode only] Accent color").option("--background-color <hex>","[instant mode only] Background color").option("--foreground-color <hex>","[instant mode only] Foreground/text color").option("--decorations <style>","[instant mode only] Background decoration (none, waves-bottom-left, waves-top-right, blob-corners, minimal)").option("--team-id <id>","Team ID (switch teams)").option("-o, --output <format>","Output format (human, json, quiet)").option("--no-stream","Wait for completion without streaming progress").option("--wait","Poll until generation completes").option("--debug","Enable debug logging").option("--open","Open in browser after creation").option("--id <uuid>","Use a specific UUID for the presentation").option("--studio","Studio mode: use current directory name as presentation ID (auto-links to Studio preview)").action(async(e,n)=>{await P();let t;n.slides!==void 0&&(t=parseInt(n.slides,10),(Number.isNaN(t)||t<1||t>20)&&(c("Slide count must be between 1 and 20"),process.exit(6)));let o=["best","balanced","fast","ultrafast","instant","image-min","image","image-max"];n.mode&&!o.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Valid: ${o.join(", ")}`),process.exit(6));let r=["smart","fast","balanced","best"];n.imageTier&&!r.includes(n.imageTier)&&(c(`Invalid image tier: ${n.imageTier}. Valid: ${r.join(", ")}`),process.exit(6));let i=["creative","professional","educational","formal","casual"];n.tone&&!i.includes(n.tone)&&(c(`Invalid tone: ${n.tone}. Valid: ${i.join(", ")}`),process.exit(6));let a=["minimal","concise","detailed","extensive"];n.amount&&!a.includes(n.amount)&&(c(`Invalid amount: ${n.amount}. Valid: ${a.join(", ")}`),process.exit(6));let s=["freeform","brand-only","brand-plus-style","style-only","no-styling"];n.styling&&!s.includes(n.styling)&&(c(`Invalid styling: ${n.styling}. Valid: ${s.join(", ")}`),process.exit(6));let d=["quick","moderate","deep","profound"];n.thinkingDepth&&!d.includes(n.thinkingDepth)&&(c(`Invalid thinking-depth: ${n.thinkingDepth}. Valid: ${d.join(", ")}`),process.exit(6));let u=["inform","persuade","train","learn","entertain","report"];n.goal&&!u.includes(n.goal)&&(c(`Invalid goal: ${n.goal}. Valid: ${u.join(", ")}`),process.exit(6));let p=["blue","violet","rose","orange","green"];n.theme&&!p.includes(n.theme)&&(c(`Invalid theme: ${n.theme}. Valid: ${p.join(", ")}`),process.exit(6));let w=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];n.decorations&&!w.includes(n.decorations)&&(c(`Invalid decorations: ${n.decorations}. Valid: ${w.join(", ")}`),process.exit(6));let I=n.theme||n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor||n.decorations;I&&n.mode&&n.mode!=="instant"&&(c("--theme, --primary-color, --decorations and other color options are only supported with --mode instant"),process.exit(6));let f=n.mode??(I?"instant":"fast"),T=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[C,M]of[["primary-color",n.primaryColor],["secondary-color",n.secondaryColor],["accent-color",n.accentColor],["background-color",n.backgroundColor],["foreground-color",n.foregroundColor]])M&&!T.test(M)&&(c(`Invalid ${C}: ${M}. Must be hex (e.g., #0066CC)`),process.exit(6));try{n.output!=="json"&&n.output!=="quiet"&&process.stdout.write(Y.gray("Checking generation limits... "));let C=await Vo(f,t??10,n.teamId);if(n.output!=="json"&&n.output!=="quiet"){console.log(Y.green("\u2713"));let M=C.remaining[f],q=C.limits[f],ne=M===void 0||q===void 0?"":` | ${f}: ${M}/${q} remaining`;console.log(Y.gray(` Plan: ${C.planName}${ne}`))}}catch(C){n.output==="json"?console.log(JSON.stringify({success:!1,error:C instanceof Error?C.message:String(C)})):(console.log(Y.red("\u2717")),c(C instanceof Error?C.message:String(C))),process.exit(C.exitCode??1)}let b=[];if(n.file&&n.file.length>0){for(let C of n.file)Uc(gi(C))||(c(`File not found: ${C}`),process.exit(6));n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(`
|
|
3774
|
+
Uploading ${n.file.length} file(s)...`));try{b=await Ao(n.file.map(C=>gi(C)),(C,M,q)=>{n.output!=="json"&&n.output!=="quiet"&&q&&process.stdout.write(`\r ${Y.cyan("\u2B06")} Uploading: ${q} (${C+1}/${M})`)}),n.output!=="json"&&n.output!=="quiet"&&console.log(`\r ${Y.green("\u2713")} Uploaded ${b.length} file(s) `)}catch(C){c(`Failed to upload files: ${C instanceof Error?C.message:String(C)}`),process.exit(1)}}let y;(n.stdin||!process.stdin.isTTY)&&(y=await Vc(),n.stdin&&!y&&(c("No content received from stdin"),process.exit(6)));let v=n.context;if(n.contextFile)try{v=Fc(n.contextFile,"utf-8"),v.trim()||(c(`Context file is empty: ${n.contextFile}`),process.exit(6))}catch{c(`Failed to read context file: ${n.contextFile}`),process.exit(6)}!y&&!v&&b.length===0&&(c("Context is required to create a presentation."),console.log(),console.log(Y.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(Y.gray(" -c, --context <text> Inline text context")),console.log(Y.gray(" --context-file <path> Read from a file")),console.log(Y.gray(` cat file | ${g.commands[0]} Pipe content`)),process.exit(6));let E=[...b];y&&E.push({id:`stdin-${Date.now()}`,content:y,title:"Piped Content",mime:"text/plain",selected:!0}),v&&E.push({id:`context-${Date.now()}`,content:v,title:"Context",mime:"text/plain",selected:!0});let A,N=n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor;(n.theme||N||n.decorations)&&(A={},n.theme&&(A.preset=n.theme),N&&(A.custom={},n.primaryColor&&(A.custom.primary=n.primaryColor),n.secondaryColor&&(A.custom.secondary=n.secondaryColor),n.accentColor&&(A.custom.accent=n.accentColor),n.backgroundColor&&(A.custom.background=n.backgroundColor),n.foregroundColor&&(A.custom.foreground=n.foregroundColor)),n.decorations&&(A.decorations=n.decorations));try{let C=await $o({topic:e,...t!==void 0&&{slideCount:t},mode:f,...n.imageTier&&{imageTier:n.imageTier},...n.tone&&{tone:n.tone},...n.amount&&{amount:n.amount},...n.audience&&{audience:n.audience},...n.language&&{language:n.language},...n.brandingId&&{brandingId:n.brandingId},...n.brandDomain&&{brandDomain:n.brandDomain},...n.template&&{templateId:n.template},...n.styling&&{stylingMode:n.styling},...n.referenceUrl&&{referenceUrl:n.referenceUrl},...n.thinkingDepth&&{thinkingDepth:n.thinkingDepth},...n.goal&&{goal:n.goal},...n.teamId&&{teamId:n.teamId},...A&&{theme:A},...n.studio?{documentId:_c.basename(process.cwd())}:n.id?{documentId:n.id}:{},...E.length>0&&{contentSources:{uploadedFiles:E,contextFiles:[]}}});if(!n.wait){n.output==="json"?console.log(JSON.stringify({success:!0,run:C},null,2)):n.output!=="quiet"&&(S("Presentation generation queued"),R("Run ID",C.runId),R("Status",C.status),console.log(Y.gray(` Check later with presentation status ${C.runId}`)));return}let M=await L("createSlides",C.runId,n.teamId);for(;!M.done;)n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(` ${M.message}`)),await new Promise(ne=>setTimeout(ne,(M.nextPollAfterSeconds??5)*1e3)),M=await L("createSlides",C.runId,n.teamId);if(M.error)throw new Error(M.error.message);let q=M.entity?await Se(M.entity.id):void 0;if(n.output==="json")console.log(JSON.stringify({success:!0,presentation:q,run:M,viewUrl:q?De(q.slug,n.language??"en"):void 0},null,2));else{console.log(),S("Presentation created successfully"),console.log(),R("Title",q?.title??e),R("Slides",String(q?.numberOfSlides??t??"\u2014")),console.log();let ne=q?De(q.slug,n.language??"en"):"N/A";ne!=="N/A"&&(console.log(Y.bold(" Open: ")+Y.cyan.underline(ne)),n.open&&await(await import("open")).default(ne)),console.log()}}catch(C){n.output==="json"?console.log(JSON.stringify({success:!1,error:C instanceof Error?C.message:String(C)})):c(C instanceof Error?C.message:String(C)),process.exit(C.exitCode??1)}});async function Vc(){return new Promise(e=>{let n="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){e("");return}process.stdin.on("data",t=>{n+=t}),process.stdin.on("end",()=>{e(n.trim())}),setTimeout(()=>{e(n.trim())},100)})}import{Command as Mc}from"commander";import Jt from"chalk";var hi=new Mc("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)","summary").option("--include <fields>","Fields to include (comma-separated: slides,styling)").option("-l, --language <lang>","Language for view URL","en").action(async(e,n)=>{await P();try{let t=await Se(e);if(n.format==="json"){console.log(JSON.stringify(t,null,2));return}let o=De(t.slug,n.language);fe("Presentation Details"),console.log(),R("Slug",t.slug),R("Title",t.title||"Untitled"),R("Description",t.description||Jt.gray("None")),R("Slides",String(t.numberOfSlides||"-")),R("Mode",t.mode||"-"),R("Created",xn(t.createdAt)),t.updatedAt&&R("Updated",xn(t.updatedAt)),console.log(),o!=="N/A"&&console.log(Jt.bold(" Open: ")+Jt.cyan.underline(o)),console.log(),n.format==="full"&&n.include?.includes("slides")&&(console.log(Jt.gray("(Full slide content available in JSON format)")),console.log())}catch(t){c(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}});import{Command as Xt}from"commander";import jc from"ora";function le(e,n){let t=e instanceof Error?e.message:"Unknown error";return!n||t.includes(n)?t:`${t} Request ID: ${n}. Resume with the matching status command; do not start a duplicate run.`}function qc(e){let n=e.assetType??"image";if(n!=="image"&&n!=="icon")throw new Error("Asset type must be image or icon");let t;if(e.maxResults&&(t=Number.parseInt(e.maxResults,10),Number.isNaN(t)||t<1))throw new Error("Max results must be a positive number");return{query:n==="icon"?`${e.query.trim()} transparent icon isolated symbol`:e.query.trim(),options:{maxResults:t||10,size:e.size,safeSearch:e.safeSearch,assetType:n,transparentBackground:n==="icon"}}}function Bc(e){let n=e.url||e.imageUrl;if(!n)throw new Error("Image search returned a result without a URL");return n}function Gc(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function Wc(e,n){return e.data.results.flatMap(t=>t.results.map(o=>{let r=o,i=Gc(r);if(n==="icon"&&i!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...r,url:Bc(r),provider:t.providerName,assetType:n,...i!==void 0?{transparent:i}:{}}}))}function Hc(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function zt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Jc(e){return{requestId:e.runId,status:Hc(e),...e.entity?.url?{url:e.entity.url}:{},...e.error?.message?{error:e.error.message}:{},...zt(e.output?.width)!==void 0?{width:zt(e.output?.width)}:{},...zt(e.output?.height)!==void 0?{height:zt(e.output?.height)}:{}}}async function yi(e,n){return Jc(await L("createImage",e,n))}function Gn(e,n){if(n==="json"){x(e);return}if(n==="quiet"){console.log(e.output??e.url??e.requestId);return}m(`Request ID: ${e.requestId}`),m(`Status: ${e.status}`),e.url&&S(`Image URL: ${e.url}`),e.output&&S(`Saved to: ${e.output}`),e.error&&c(`Error: ${e.error}`)}var zc=new Xt("search").description("Search for images").requiredOption("-q, --query <query>","Search query").option("-n, --max-results <number>","Maximum number of results (default: 10)").option("-s, --size <size>","Image size: small, medium, large, any","large").option("--asset-type <type>","Asset intent: image or transparent icon","image").option("--safe-search","Enable safe search (default: true)",!0).option("--no-safe-search","Disable safe search").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?jc("Searching for images...").start():null,o;try{o=qc(e)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Invalid image search request"),process.exit(l.INVALID_INPUT);return}try{let r=await Rt(o);t?.stop(),r.success||(c("Search failed"),process.exit(l.GENERAL_ERROR));let i=o.options?.assetType??"image",a=Wc(r,i);if(n==="json"){x({success:!0,query:e.query,assetType:i,totalResults:a.length,images:a});return}if(n==="quiet"){for(let s of a)console.log(s.url);return}if(a.length===0){m("No images found");return}S(`Found ${a.length} images for "${e.query}"`),console.log();for(let s=0;s<a.length;s++){let d=a[s];console.log(`[${s+1}] ${d.title||"Untitled"}`),console.log(` URL: ${d.url}`),console.log(` Size: ${d.width}x${d.height}`),d.author&&console.log(` Author: ${d.author}`),console.log(` Provider: ${d.provider}`),console.log()}m(`Total cost: $${r.data.totalCost.toFixed(4)}`)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Xc=new Xt("generate").description("Generate an image and optionally save it locally").argument("[prompt]","Image prompt").option("-p, --prompt <text>","Image prompt (named compatibility form)").option("--provider <provider>","Provider override").option("--model <model>","Model override").option("--width <pixels>","Width").option("--height <pixels>","Height").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Local output path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").option("--yes","Approve generation").action(async(e,n)=>{let t,o=e??n.prompt;o?.trim()||(c("Provide an image prompt as an argument or with --prompt"),process.exit(l.INVALID_INPUT)),n.yes||(c("Pass --yes to approve image generation"),process.exit(l.INVALID_INPUT)),!n.wait&&n.output&&(c("--output requires waiting for completion; remove --no-wait"),process.exit(l.INVALID_INPUT));try{let r=await $("createImage",{approvalReceipt:"cli:--yes",height:n.height?Number.parseInt(n.height,10):void 0,model:n.model,prompt:o.trim(),provider:n.provider,teamId:n.teamId,width:n.width?Number.parseInt(n.width,10):void 0});if(t=r.runId,!n.wait){Gn({requestId:r.runId,status:"pending"},n.format);return}let i=await K(()=>yi(r.runId,n.teamId),180,2e3);if(i.status==="failed")throw new Error(i.error||"Image generation failed");if(!i.url)throw new Error("Image generation completed without an image URL");let a=n.output?{...i,output:n.output}:i;n.output&&await Q(i.url,n.output),Gn(a,n.format)}catch(r){c(le(r,t),n.format),process.exit(l.GENERAL_ERROR)}}),Yc=new Xt("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Download a completed image").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await yi(e,n.teamId);if(n.output){if(t.status!=="completed"||!t.url)throw new Error("Image generation is not complete");await Q(t.url,n.output),t.output=n.output}Gn(t,n.format)}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),bi=new Xt("image").description("Image search and generation commands").addCommand(zc).addCommand(Xc).addCommand(Yc);import{Command as Wn}from"commander";var Kc=new Wn("search").description("Search the workspace Knowledge Hub").argument("[query]","Optional search query").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").option("--limit <count>","Maximum results","10").action(async(e,n)=>{try{x(await $("searchKnowledge",{kind:n.kind,limit:Number.parseInt(n.limit,10),query:e,teamId:n.teamId}))}catch(t){c(t instanceof Error?t.message:"Knowledge search failed"),process.exit(l.GENERAL_ERROR)}}),Qc=new Wn("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async e=>{try{x(await $("getKnowledgeBundle",{kind:e.kind,teamId:e.teamId}))}catch(n){c(n instanceof Error?n.message:"Knowledge bundle failed"),process.exit(l.GENERAL_ERROR)}}),wi=new Wn("knowledge").description("Knowledge Hub commands").addCommand(Kc).addCommand(Qc);import{Command as Hn}from"commander";var Zc=new Hn("create").description("Start background microsite generation").argument("<title>","Microsite title").requiredOption("--description <brief>","Microsite brief").option("--audience <audience>","Target audience").option("--tone <tone>","Tone").option("--language <language>","Content language","en").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await $("createMicrosite",{approvalReceipt:"cli:--yes",audience:n.audience,brandingId:n.brandingId,description:n.description,language:n.language,teamId:n.teamId,title:e,tone:n.tone}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(l.GENERAL_ERROR)}}),ed=new Hn("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L("createMicrosite",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),vi=new Hn("microsite").description("Microsite commands").addCommand(Zc).addCommand(ed);import{Command as Xn}from"commander";import Jn from"ora";function zn(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.outputUrl?console.log(e.outputUrl):console.log(e.requestId);return}m(`Request ID: ${e.requestId}`),m(`Status: ${e.status}`),e.duration&&m(`Duration: ${e.duration}s`),e.outputUrl&&S(`Output URL: ${e.outputUrl}`),e.cost!==void 0&&m(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var td=new Xn("create").description("Mix audio tracks into a video (music will loop to match video duration)").requiredOption("--video <url>","Input video file/URL").option("--music <url>","Background music file/URL (will loop if shorter than video)").option("--voice <url>","Voiceover file/URL").option("--music-volume <percent>","Music volume 0-100 (default: 30, recommended for mix with voice)","30").option("--voice-volume <percent>","Voice volume 0-100","100").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{!e.music&&!e.voice&&(c("At least one of --music or --voice must be provided"),process.exit(l.INVALID_INPUT));let n=parseInt(e.musicVolume,10)/100,t=parseInt(e.voiceVolume,10)/100;(Number.isNaN(n)||n<0||n>1)&&(c("Music volume must be between 0 and 100"),process.exit(l.INVALID_INPUT)),(Number.isNaN(t)||t<0||t>2)&&(c("Voice volume must be between 0 and 200"),process.exit(l.INVALID_INPUT));let o=e.format,r=o==="human"?Jn("Mixing audio...").start():null,i=[{url:e.video,role:"video"}];e.music&&i.push({url:e.music,role:"background",volume:n*5}),e.voice&&i.push({url:e.voice,role:"voice",volume:t*2});try{let a=await Bo({operation:"add-to-video",inputs:i,options:{musicVolume:n,voiceVolume:t}});if(!e.wait){r?.stop(),zn(a,o);return}r&&(r.text=`Processing (ID: ${a.requestId})...`);let s=await K(()=>fn(a.requestId),120,3e3);if(r?.stop(),s.status==="failed"&&(c(s.error||"Audio mixing failed"),process.exit(l.GENERAL_ERROR)),zn(s,o),e.output){if(!s.outputUrl)throw new Error("Audio mix completed without an output URL");let d=o==="human"?Jn("Downloading...").start():null;await Q(s.outputUrl,e.output),d?.stop(),o==="human"&&S(`Saved to: ${e.output}`)}}catch(a){r?.stop(),c(a instanceof Error?a.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),nd=new Xn("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?Jn("Checking status...").start():null;try{let o=await fn(e);t?.stop(),zn(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),xi=new Xn("mix").description("Audio mixing commands").addCommand(td).addCommand(nd);import{Command as Qn}from"commander";import Yn from"ora";function Kn(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.audioUrl?console.log(e.audioUrl):console.log(e.requestId);return}m(`Request ID: ${e.requestId}`),m(`Status: ${e.status}`),e.duration&&m(`Duration: ${e.duration}s`),e.audioUrl&&S(`Audio URL: ${e.audioUrl}`),e.cost!==void 0&&m(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var od=new Qn("generate").description("Generate music from a text prompt").requiredOption("-p, --prompt <text>","Music description").option("-d, --duration <seconds>","Duration in seconds (3-600)","30").option("-s, --style <style>","Style preset").option("--provider <provider>","Untrusted provider hint (host policy is authoritative)").option("--mode <mode>","Intent: auto, retrieve, or generate","auto").option("--no-instrumental","Allow vocals (background music is instrumental by default)").option("--tempo <bpm>","Tempo hint in BPM (60-180)").option("--audio-format <format>","Audio format: mp3, wav, flac, ogg","mp3").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=Number(e.duration);(!Number.isInteger(n)||n<3||n>600)&&(c("Duration must be between 3 and 600 seconds (10 minutes)"),process.exit(l.INVALID_INPUT)),!e.wait&&e.output&&(c("--output requires waiting for completion; remove --no-wait"),process.exit(l.INVALID_INPUT)),["auto","retrieve","generate"].includes(e.mode)||(c("Mode must be auto, retrieve, or generate"),process.exit(l.INVALID_INPUT)),["mp3","wav","flac","ogg"].includes(e.audioFormat)||(c("Audio format must be mp3, wav, flac, or ogg"),process.exit(l.INVALID_INPUT));let t=e.tempo?Number(e.tempo):void 0;t!==void 0&&(!Number.isInteger(t)||t<60||t>180)&&(c("Tempo must be between 60 and 180 BPM"),process.exit(l.INVALID_INPUT));let o=e.format,r=o==="human"?Yn("Generating music...").start():null,i;try{let a=await Tt({prompt:e.prompt,duration:n,options:{provider:e.provider,mode:e.mode,instrumental:e.instrumental,style:e.style,tempo:t,format:e.audioFormat}});if(i=a.requestId,!e.wait){r?.stop(),Kn(a,o);return}let s=a;if(a.status!=="completed"&&a.status!=="failed"&&(r&&(r.text=`Processing (ID: ${a.requestId})...`),s=await K(()=>st(a.requestId),180,2e3)),r?.stop(),s.status==="failed"&&(c(s.error||"Music generation failed"),process.exit(l.GENERAL_ERROR)),e.output){if(!s.audioUrl)throw new Error("Music completed without an audio URL");let d=o==="human"?Yn("Downloading...").start():null;await Q(s.audioUrl,e.output),d?.stop(),o==="human"&&S(`Saved to: ${e.output}`),s={...s,output:e.output}}Kn(s,o)}catch(a){r?.stop(),c(le(a,i),o),process.exit(l.GENERAL_ERROR)}}),rd=new Qn("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?Yn("Checking status...").start():null;try{let o=await st(e);t?.stop(),Kn(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Si=new Qn("music").description("Music generation commands").addCommand(od).addCommand(rd);import{Command as Zn}from"commander";function Ci(e,n){return[...n,e]}var id=new Zn("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",Ci,[]).option("--type <type>","single, multiple, or word-cloud","single").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve creation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve poll creation");try{x(await $("createPoll",{approvalReceipt:"cli:--yes",options:n.option.map(t=>({text:t})),pollType:n.type,question:e,teamId:n.teamId,title:n.title}))}catch(t){c(t instanceof Error?t.message:"Poll creation failed"),process.exit(l.GENERAL_ERROR)}}),ad=new Zn("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",Ci).option("--type <type>","single, multiple, or word-cloud").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve update").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve poll update");try{x(await $("editPoll",{approvalReceipt:"cli:--yes",options:n.option?.map(t=>({text:t})),pollId:e,pollType:n.type,question:n.question,teamId:n.teamId,title:n.title}))}catch(t){c(t instanceof Error?t.message:"Poll update failed"),process.exit(l.GENERAL_ERROR)}}),Ii=new Zn("poll").description("Standalone poll commands").addCommand(id).addCommand(ad);import{Command as Ti}from"commander";var sd=new Ti("status").description("Check a presentation generation run").argument("<run-id>","Run ID returned by presentation generation").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await L("createSlides",e,n.teamId);if(n.format==="json"){x(t);return}if(n.format==="quiet"){console.log(t.status);return}m(`Status: ${t.status}`),m(t.message),t.progress!==null&&m(`Progress: ${t.progress}%`),t.error&&c(t.error.message)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Ri=new Ti("presentation").description("Presentation background-run commands").addCommand(sd);import{writeFile as cd}from"fs/promises";import{Command as dd}from"commander";import ld from"ora";var ki=new dd("scrape").description("Extract content from a URL").argument("<url>","URL to scrape").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Save content to file").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format,o=t==="human"?ld("Scraping URL...").start():null;try{let r=await Wo(e,n.teamId);o?.stop(),(!r.success||!r.data)&&(c(r.error||"Failed to scrape URL"),process.exit(l.GENERAL_ERROR));let i=r.data;if(n.output&&(await cd(n.output,i.content,"utf-8"),t==="human"&&S(`Content saved to: ${n.output}`)),t==="json"){let{cost:a,...s}=i;x(s);return}if(t==="quiet"){console.log(i.content);return}i.title&&(console.log(),console.log(`Title: ${i.title}`)),i.metadata?.description&&console.log(`Description: ${i.metadata.description}`),console.log(`URL: ${i.url}`),console.log(`Tokens: ~${i.metadata?.tokenUsage?.toLocaleString()||"unknown"}`),i.warning&&_(i.warning),n.output||(console.log(),console.log("--- Content ---"),console.log(i.content)),i.cost&&i.cost>0&&m(`Cost: $${i.cost.toFixed(6)}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}});import{Command as ut}from"commander";function Yt(e,n){n!=="quiet"&&x(e)}var ud=new ut("web").description("Search current public web sources").argument("<query>","Search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","5").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchInternet",{maxResults:Number.parseInt(n.maxResults,10),query:e,teamId:n.teamId});Yt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Search failed"),process.exit(l.GENERAL_ERROR)}}),md=new ut("news").description("Search recent news").argument("<topic>","News topic").option("--team-id <id>","Workspace ID").option("--timeframe <value>","Timeframe hint").option("--max-results <count>","Maximum results","6").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("getNews",{maxResults:Number.parseInt(n.maxResults,10),teamId:n.teamId,timeframe:n.timeframe,topic:e});Yt(t,n.format)}catch(t){c(t instanceof Error?t.message:"News search failed"),process.exit(l.GENERAL_ERROR)}}),pd=new ut("images").description("Search licensed image providers").argument("<query>","Image search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","10").option("--aspect <aspect>","Aspect: any, square, wide, tall","any").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchImages",{aspect:n.aspect,maxResults:Number.parseInt(n.maxResults,10),query:e,teamId:n.teamId});Yt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Image search failed"),process.exit(l.GENERAL_ERROR)}}),gd=new ut("video").description("Search licensed stock-video providers").argument("<query>","Stock-video search query").option("--team-id <id>","Workspace ID").option("--max-results <count>","Maximum results","10").option("--orientation <value>","Orientation: landscape, portrait, square, any","any").option("--license <value>","License: free, premium, any","any").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{let t=await $("searchStockVideo",{license:n.license,maxResults:Number.parseInt(n.maxResults,10),orientation:n.orientation,query:e,teamId:n.teamId});Yt(t,n.format)}catch(t){c(t instanceof Error?t.message:"Video search failed"),process.exit(l.GENERAL_ERROR)}}),Ai=new ut("search").description("Web, news, image, and stock-video search").addCommand(ud).addCommand(md).addCommand(pd).addCommand(gd);import{Command as no}from"commander";import eo from"ora";function to(e,n){if(n==="json"){let{cost:t,...o}=e;x(o);return}if(n==="quiet"){e.audioUrl?console.log(e.audioUrl):e.requestId?console.log(e.requestId):console.log(e.id);return}m(`Request ID: ${e.requestId||e.id}`),m(`Status: ${e.status}`),e.duration&&m(`Duration: ${e.duration}s`),e.audioUrl&&S(`Audio URL: ${e.audioUrl}`),e.cost!==void 0&&m(`Cost: $${e.cost.toFixed(4)}`),e.error&&c(`Error: ${e.error}`)}var fd=new no("generate").description("Generate sound effects from a text prompt").requiredOption("-t, --text <text>","Sound effect description (e.g., 'thunder rumbling, rain on window')").option("-d, --duration <seconds>","Duration in seconds (0.5-30)").option("-p, --provider <provider>","Untrusted provider hint (host policy is authoritative)").option("--prompt-influence <value>","How closely to follow prompt (0-1)","0.3").option("-l, --loop","Generate seamless looping audio",!1).option("--format <format>","Audio format: mp3, wav, ogg","mp3").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --output-format <format>","Output format: human, json, quiet","human").action(async e=>{let n;e.duration&&(n=parseFloat(e.duration),(isNaN(n)||n<.5||n>30)&&(c("Duration must be between 0.5 and 30 seconds"),process.exit(l.INVALID_INPUT)));let t;e.promptInfluence&&(t=parseFloat(e.promptInfluence),(isNaN(t)||t<0||t>1)&&(c("Prompt influence must be between 0 and 1"),process.exit(l.INVALID_INPUT)));let o=e.outputFormat,r=o==="human"?eo("Generating sound effects...").start():null,i;try{let a=await Ho({text:e.text,duration:n,options:{provider:e.provider,promptInfluence:t,loop:e.loop,format:e.format}});if(i=a.requestId||a.id,!e.wait){r?.stop(),to(a,o);return}let s=a;if(a.status!=="completed"&&a.status!=="failed"){let d=a.requestId||a.id;r&&(r.text=`Processing (ID: ${d})...`),s=await K(()=>yn(d),60,2e3)}if(r?.stop(),s.status==="failed"&&(c(s.error||"Sound effects generation failed"),process.exit(l.GENERAL_ERROR)),to(s,o),e.output){if(!s.audioUrl)throw new Error("Sound effect completed without an audio URL");let d=o==="human"?eo("Downloading...").start():null;await Q(s.audioUrl,e.output),d?.stop(),o==="human"&&S(`Saved to: ${e.output}`)}}catch(a){r?.stop(),c(le(a,i),o),process.exit(l.GENERAL_ERROR)}}),hd=new no("status").description("Check status of a sound effects generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format==="human"?eo("Checking status...").start():null;try{let o=await yn(e);t?.stop(),to(o,n.format)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),$i=new no("sfx").description("Sound effects generation commands").addCommand(fd).addCommand(hd);import{mkdir as yd,writeFile as Ei}from"fs/promises";import{dirname as bd}from"path";import{Command as Kt}from"commander";import Ni from"ora";var Oi="en-US-Neural2-C",Pi="gemini",wd=new Kt("generate").description("Generate speech from text").requiredOption("-t, --text <text>","Text to convert to speech").requiredOption("-o, --output <path>","Output file path").option("--voice-id <voiceId>","Voice ID (e.g., ElevenLabs: 21m00Tcm4TlvDq8ikWAM)").option("--voice <voice>",`Voice name (default: ${Oi})`).option("-p, --provider <provider>",`Provider: gemini, elevenlabs, openai (default: ${Pi})`).option("-m, --model <model>","Model (provider-specific)").option("-s, --speed <speed>","Speech speed 0.1-4.0 (default: 1.0)").option("-l, --lang <lang>","Language or locale hint (for example en-US)").option("--speakers <json>",`Multi-speaker (Gemini, max 2): '[{"name":"Joe","voice":"Kore"},{"name":"Jane","voice":"Puck"}]'`).option("-i, --instructions <text>","Style prompt (OpenAI gpt-4o-mini-tts): tone, accent, speed, emotion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?Ni("Generating speech...").start():null,o;e.speed&&(o=parseFloat(e.speed),(Number.isNaN(o)||o<.1||o>4)&&(t?.stop(),c("Speed must be between 0.1 and 4.0"),process.exit(l.INVALID_INPUT)));let r;if(e.speakers)try{r=JSON.parse(e.speakers),(!Array.isArray(r)||r.length===0||r.length>2||r.some(a=>!a||typeof a!="object"||typeof a.name!="string"||!a.name.trim()||typeof a.voice!="string"||!a.voice.trim()))&&(t?.stop(),c("Speakers must be an array with 1-2 name/voice items"),process.exit(l.INVALID_INPUT))}catch{t?.stop(),c(`Invalid --speakers JSON. Example: '[{"name":"Joe","voice":"Kore"}]'`),process.exit(l.INVALID_INPUT)}let i;try{let a=e.voiceId,s=e.voice||Oi,d=e.provider||Pi,u={};r&&(u.gemini={speakers:r}),e.instructions&&(u.openai={instructions:e.instructions});let p=await It({text:e.text,options:{language:e.lang,provider:d,voiceId:a,voice:s,model:e.model,speed:o,providerOptions:Object.keys(u).length>0?u:void 0}});i=p.requestId,t?.stop();let w=e.output.endsWith(`.${p.format}`)?e.output:`${e.output}.${p.format}`;await yd(bd(w),{recursive:!0}),await Ei(w,p.audioData);let I=w.replace(/\.[^.]+$/,".txt");if(await Ei(I,e.text,"utf-8"),n==="json"){x({status:"completed",output:w,audioUrl:p.audioUrl,duration:p.duration,provider:p.provider,format:p.format,voice_id:p.voiceId??null,voice:p.voice??s,model:p.model??e.model??null,speed:p.speed??o??1,lang:p.language??e.lang??null,langApplied:p.langApplied??!1,timestamps:p.timestamps??null,words:p.wordTimings??null});return}if(n==="quiet"){console.log(w);return}S(`Saved to: ${w}`),m(`Duration: ${p.duration.toFixed(2)}s`),m(`Provider: ${p.provider}`),m(`Cost: $${p.cost.toFixed(6)}`)}catch(a){t?.stop(),c(le(a,i),n),process.exit(l.GENERAL_ERROR)}}),vd=new Kt("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json","human").action(async e=>{let n=e.format==="human"?Ni("Fetching voices...").start():null;try{let t=await qo(e.provider);if(n?.stop(),e.format==="json"){x(t.voices);return}if(Array.isArray(t.voices)){let o=e.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${o} Voices:`),console.log("-".repeat(50));for(let r of t.voices)console.log(` ${r.name} (${r.id})`),console.log(` ${r.description}`)}else for(let[o,r]of Object.entries(t.voices))if(!(!r||r.length===0)){console.log(),console.log(`${o.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let i of r)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}}catch(t){n?.stop(),c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),xd=new Kt("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json","json").action(async(e,n)=>{try{x(await L("generateSpeech",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),Di=new Kt("tts").description("Text-to-speech commands").addCommand(wd).addCommand(vd).addCommand(xd);import{execSync as Ze,spawn as Yd,spawnSync as Kd}from"child_process";import{access as io,mkdir as et,readFile as gt,rm as ao,writeFile as ve}from"fs/promises";import{join as G,resolve as pt}from"path";import{Command as te}from"commander";import Qd from"ffmpeg-static";import ft from"ora";import{homedir as Sd}from"os";import{join as Li}from"path";import{readdir as Cd}from"fs/promises";var Id="conceptcraft";function Xe(){return Li(Sd(),`.${Id}`,"projects")}function Qt(e){return Li(Xe(),e)}async function oo(){try{let e=Xe();return(await Cd(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}function Ui(e,n){let t=2,o=`${e}-${t}`;for(;n.includes(o);)t++,o=`${e}-${t}`;return o}import{Command as Td}from"commander";import Rd from"ora";import{execSync as kd,spawnSync as Ye}from"child_process";import{mkdirSync as Fi,existsSync as en,readFileSync as Vi,writeFileSync as _i}from"fs";import{join as $e,basename as Ad}from"path";import{tmpdir as $d}from"os";function tn(e,n){try{return kd(n,{stdio:"ignore"}),!0}catch{return!1}}function Zt(e){let n=Math.floor(e/60),t=Math.floor(e%60),o=Math.round(e%1*10);return`${n}:${String(t).padStart(2,"0")}.${o}`}function Ed(e){let n=Ye("ffprobe",["-v","error","-show_entries","format=duration","-of","default=noprint_wrappers=1:nokey=1",e],{encoding:"utf-8"});return parseFloat(n.stdout.trim())}function Od(e,n){let t=Ye("ffmpeg",["-i",e,"-vf",`select='gt(scene,${n})',showinfo`,"-vsync","vfr","-f","null","-"],{encoding:"utf-8",timeout:12e4}),o=[0],r=(t.stderr||"").split(`
|
|
3775
|
+
`);for(let i of r){let a=i.match(/pts_time:([\d.]+)/);if(a){let s=parseFloat(a[1]);s-o[o.length-1]>=1.5&&o.push(s)}}return o}function Pd(e,n,t){let o=[];for(let r=0;r<n.length;r++){let i=n[r]+.5,a=$e(t,`scene_${String(r+1).padStart(2,"0")}.jpg`);Ye("ffmpeg",["-ss",String(i),"-i",e,"-vframes","1","-q:v","2","-y",a],{stdio:"ignore",timeout:3e4}),o.push(a)}return o}function Nd(e,n){let t=$e(n,"audio.wav");if(Ye("ffmpeg",["-i",e,"-vn","-acodec","pcm_s16le","-ar","16000","-ac","1","-y",t],{stdio:"ignore",timeout:6e4}),!en(t)||!tn("whisper","which whisper")&&!tn("whisper-cpp","which whisper-cpp"))return null;let r=Ye("whisper",[t,"--model","base","--output_format","json","--output_dir",n,"--language","en"],{encoding:"utf-8",timeout:3e5}),i=$e(n,"audio.json");if(!en(i))return null;try{let a=JSON.parse(Vi(i,"utf-8"));return{text:a.text||"",segments:(a.segments||[]).map(s=>({start:s.start,end:s.end,text:s.text?.trim()||""}))}}catch{return null}}function Dd(e,n){let t=Vi(e).toString("base64"),o=JSON.stringify({model:n,prompt:"Describe this image in one short sentence (max 15 words). Focus on: what is shown, the setting, key objects or people.",images:[t],stream:!1}),r=Ye("curl",["-s","-X","POST","http://localhost:11434/api/generate","-H","Content-Type: application/json","-d",o],{encoding:"utf-8",timeout:6e4});try{return(JSON.parse(r.stdout).response||"").replace(/!!!IMAGE!!!/gi,"").replace(/\[image[^\]]*\]/gi,"").trim()||"Unable to describe frame"}catch{return"Unable to describe frame"}}var Mi=new Td("analyze").description("Analyze a video file: detect scenes, transcribe audio, describe frames").argument("<file>","Path to video file").option("-o, --output <path>","Output directory for analysis results").option("-t, --threshold <number>","Scene detection threshold (0-1, lower = more scenes)","0.3").option("-m, --model <name>","Ollama vision model","moondream").option("--no-vision","Skip frame description (faster)").option("--no-transcribe","Skip audio transcription").option("-f, --output-format <format>","Output format: human, json","human").action(async(e,n)=>{let t=Rd();en(e)||(console.error(`File not found: ${e}`),process.exit(1)),tn("ffmpeg","which ffmpeg")||(console.error("ffmpeg is required. Install: brew install ffmpeg"),process.exit(1)),n.vision!==!1&&!tn("ollama","which ollama")&&(console.error("ollama is required for vision. Install: brew install ollama"),process.exit(1));let o=n.output||$e($d(),`video-analyze-${Date.now()}`);Fi(o,{recursive:!0});let r=$e(o,"frames");Fi(r,{recursive:!0});let i=parseFloat(n.threshold),a=n.model;t.start("Reading video metadata...");let s=Ed(e);t.succeed(`Video: ${Zt(s)} (${s.toFixed(1)}s)`),t.start("Detecting scenes...");let d=Od(e,i);t.succeed(`Detected ${d.length} scenes`),t.start("Extracting key frames...");let u=Pd(e,d,r);t.succeed(`Extracted ${u.length} key frames`);let p=null;n.transcribe!==!1&&(t.start("Transcribing audio..."),p=Nd(e,o),p?t.succeed(`Transcribed: ${p.segments.length} segments`):t.warn("Transcription skipped (whisper not installed: pip install openai-whisper)"));let w=[];for(let f=0;f<d.length;f++){let T=d[f],b=f<d.length-1?d[f+1]:s,y="";n.vision!==!1&&en(u[f])&&(t.start(`Describing scene ${f+1}/${d.length}...`),y=Dd(u[f],a),t.succeed(`Scene ${f+1}: ${y}`)),w.push({id:f+1,startTime:T,endTime:b,duration:b-T,framePath:u[f],description:y})}let I={source:e,duration:s,scenes:w,transcript:p};if(n.outputFormat==="json"){let f=JSON.stringify(I,null,2),T=$e(o,"analysis.json");_i(T,f),console.log(f)}else{let f=["# Video Analysis","",`**Source:** ${Ad(e)}`,`**Duration:** ${Zt(s)} (${s.toFixed(1)}s)`,`**Scenes:** ${w.length}`,"","## Scenes",""];for(let y of w){if(f.push(`### Scene ${y.id} (${Zt(y.startTime)} - ${Zt(y.endTime)}) [${y.duration.toFixed(1)}s]`),y.description&&f.push(`**Visual:** ${y.description}`),p?.segments){let v=p.segments.filter(E=>E.end>y.startTime&&E.start<y.endTime);v.length>0&&f.push(`**Audio:** ${v.map(E=>E.text).join(" ").trim()}`)}f.push(`**Frame:** ${y.framePath}`),f.push("")}p?.text&&(f.push("## Full Transcript"),f.push(""),f.push(p.text.trim()),f.push(""));let T=f.join(`
|
|
3776
|
+
`),b=$e(o,"analysis.md");_i(b,T),console.log(T),console.log(`
|
|
3777
|
+
Results saved to: ${o}`)}});import{mkdir as Ld}from"fs/promises";import{join as Ud}from"path";import{Command as mt}from"commander";import qi from"ora";var Fd=5e3,_d=120,ji=5;function Vd(e,n){return[...n,e]}function Md(e,n){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw new Error;return t.toString()}catch{throw new Error(`${n} must be a public HTTP(S) URL`)}}function Bi(e){if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e))throw new Error("Source video id must be a UUID");return e}function jd(e){if(e.mode&&!["speed","precision"].includes(e.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:Md(e.audioUrl,"Audio URL"),...e.mode?{mode:e.mode}:{},sourceVideoId:Bi(e.sourceVideoId)}}function qd(e){let n=[],t=new Set;for(let r of e.targetLanguage){let i=r.trim(),a=i.toLocaleLowerCase("en-US");!i||t.has(a)||(t.add(a),n.push(i))}if(n.length===0)throw new Error("Provide at least one target language");if(n.length>ji)throw new Error(`Provide at most ${ji} target languages`);if(n.find(r=>r.length<2||r.length>40))throw new Error("Target languages must be between 2 and 40 characters");return{...e.captions?{captions:!0}:{},sourceVideoId:Bi(e.sourceVideoId),targetLanguages:n}}function Bd(e){return e.error||e.status==="failed"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"||e.status==="processing"?"processing":"pending"}function ro(e){return{requestId:e.runId,status:Bd(e),...e.entity?.url?{videoUrl:e.entity.url}:{},...e.output?{output:e.output}:{},...e.error?.message?{error:e.error.message}:{}}}function Gi(e){return{requestId:e.runId,status:"pending"}}async function Wi(e,n){return K(async()=>ro(await L(e,n)),_d,Fd)}function Ke(e,n){if(n==="json"){x(e);return}if(n==="quiet"){console.log(e.videoUrl??e.requestId);return}m(`Request ID: ${e.requestId}`),m(`Status: ${e.status}`),e.videoUrl&&S(`Video URL: ${e.videoUrl}`),e.error&&c(`Error: ${e.error}`)}function Gd(e){return Array.isArray(e?.languages)?e.languages.filter(n=>{if(!n||typeof n!="object"||Array.isArray(n))return!1;let t=n;return typeof t.language=="string"&&(t.status==="completed"||t.status==="failed")&&typeof t.videoId=="string"&&(t.videoUrl===null||typeof t.videoUrl=="string")}):[]}function Wd(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function Hd(e,n){let t=Wd(e);if(!n.has(t))return n.add(t),t;let o=t.slice(0,-4),r=2;for(;n.has(`${o}-${r}.mp4`);)r+=1;let i=`${o}-${r}.mp4`;return n.add(i),i}async function Jd(e,n){let t=Gd(e.output).filter(i=>i.status==="completed"&&!!i.videoUrl);if(t.length===0)throw new Error("Video translation completed without downloadable results");await Ld(n,{recursive:!0});let o=[],r=new Set;for(let i of t){let a=Ud(n,Hd(i.language,r));await Q(i.videoUrl,a),o.push({language:i.language,path:a})}return o}var zd=new mt("status").description("Check a video lip-sync request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{Ke(ro(await L("lipsyncVideo",e)),n.format)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Hi=new mt("lipsync").description("Re-voice a ready workspace video with a public audio URL").requiredOption("--source-video-id <uuid>","READY workspace video UUID").requiredOption("--audio-url <url>","Public replacement voice audio URL").option("--mode <mode>","Quality mode: speed or precision","speed").requiredOption("-o, --output <path>","Local output video path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format==="human"?qi("Starting video lip-sync...").start():null,t;try{let o=await Xo(jd(e));if(t=o.runId,!e.wait){n?.stop(),Ke(Gi(o),e.format);return}n&&(n.text="Waiting for video lip-sync...");let r=await Wi("lipsyncVideo",o.runId);if(r.status==="failed")throw new Error(r.error??"Video lip-sync failed");if(!r.videoUrl)throw new Error("Video lip-sync completed without a video URL");n&&(n.text="Downloading lip-synced video..."),await Q(r.videoUrl,e.output),n?.stop(),Ke(r,e.format),e.format==="human"&&S(`Saved to: ${e.output}`)}catch(o){n?.stop(),c(le(o,t),e.format),process.exit(l.GENERAL_ERROR)}}).addCommand(zd),Ji=new mt("translate-languages").description("List supported video translation target languages").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{try{let n=await Yo();if(e.format==="json")x({languages:n});else for(let t of n)console.log(t)}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),Xd=new mt("status").description("Check a video translation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{try{Ke(ro(await L("translateVideo",e)),n.format)}catch(t){c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),zi=new mt("translate").description("Translate a ready workspace video into one or more languages").requiredOption("--source-video-id <uuid>","READY workspace video UUID").option("--target-language <language>","Target language (repeatable)",Vd,[]).option("--captions","Burn provider-generated captions into translated videos").requiredOption("--output-dir <path>","Directory for translated videos").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format==="human"?qi("Starting video translation...").start():null,t;try{let o=await Ko(qd(e));if(t=o.runId,!e.wait){n?.stop(),Ke(Gi(o),e.format);return}n&&(n.text="Waiting for video translations...");let r=await Wi("translateVideo",o.runId);if(r.status==="failed")throw new Error(r.error??"Video translation failed");n&&(n.text="Downloading translated videos...");let i=await Jd(r,e.outputDir);if(n?.stop(),e.format==="json")x({...r,downloads:i});else if(e.format==="quiet")for(let a of i)console.log(a.path);else{Ke(r,e.format);for(let a of i)S(`${a.language}: ${a.path}`)}}catch(o){n?.stop(),c(le(o,t),e.format),process.exit(l.GENERAL_ERROR)}}).addCommand(Xd);var Zd="inizio-inc/remotion-video-template#main",Qe=30;async function el(e){let n=await gt(e,"utf-8");return JSON.parse(n)}async function tl(e){let n=G(e,"template.manifest.json");try{return await el(n)}catch{return{entry:"src/Root.tsx",compositions:[{id:"Main",type:"youtube",aspect:"16:9",default:!0}]}}}function Xi(){try{return Ze("bun --version",{stdio:"ignore"}),!0}catch{return!1}}function nl(e){if(e.includes("---")||e.includes("[Section")){let r=e.split(/---|\[Section \d+\]/i).filter(i=>i.trim());if(r.length>1)return r.map(i=>i.trim())}let n=e.split(/(?<=[.!?])\s+/).map(r=>r.trim()).filter(r=>r.length>0),t=[],o="";for(let r of n){let i=r.split(/\s+/).length;o?(t.push(`${o} ${r}`),o=""):i<5&&t.length<n.length-1?o=r:t.push(r)}return o&&(t.length>0?t[t.length-1]+=` ${o}`:t.push(o)),t}function ol(e,n,t=Qe,o){if(o&&o.characters.length>0)return rl(e,o,t);let r=e.reduce((a,s)=>a+s.split(/\s+/).length,0),i=0;return e.map((a,s)=>{let d=a.split(/\s+/).length,u=d/r,p=n*u,w=Math.round(p*t),I=a.split(""),f=p/I.length,T={characters:I,characterStartTimesSeconds:I.map((y,v)=>v*f),characterEndTimesSeconds:I.map((y,v)=>(v+1)*f)},b={id:s+1,text:a,wordCount:d,startTime:i,endTime:i+p,durationInSeconds:p,durationInFrames:w,timestamps:T};return i+=p,b})}function rl(e,n,t){let{characters:o,characterStartTimesSeconds:r,characterEndTimesSeconds:i}=n,a=o.join(""),s=[],d=0;for(let u=0;u<e.length;u++){let p=e[u],w=p.length;for(;d<o.length&&o[d].match(/^\s*$/);)d++;let I=d,f=r[I]||0;d+=w;let T=d-1;for(;T>I&&o[T]?.match(/^\s*$/);)T--;let b=i[Math.min(T,i.length-1)]||f+1,y=b-f,v=Math.round(y*t),E={characters:o.slice(I,T+1),characterStartTimesSeconds:r.slice(I,T+1).map(A=>A-f),characterEndTimesSeconds:i.slice(I,T+1).map(A=>A-f)};s.push({id:u+1,text:p,wordCount:p.split(/\s+/).length,startTime:f,endTime:b,durationInSeconds:y,durationInFrames:v,timestamps:E})}return s}function il(e){let n=e==="tiktok"?"vertical":e==="audiogram"?"square":"widescreen";return{scenes:[{name:"Hook",script:"Replace this with a bold opening line that grabs attention.",imageQuery:`cinematic ${n} intro visual, dramatic lighting`,videoQuery:`abstract ${n} motion background`},{name:"Proof",script:"Share the core insight, benefit, or product moment you want viewers to remember.",imageQuery:`people collaborating ${n} office, warm lighting`,videoQuery:`close-up hands using technology ${n}`},{name:"Close",script:"End with a crisp call to action and a confident closing line.",imageQuery:`bold typography ${n} background, high contrast`,videoQuery:`sunrise skyline ${n} timelapse`}],voice:"en-US-Neural2-C",voiceSettings:{speed:1,stability:.4,style:.6},musicPrompt:"uplifting cinematic background, modern and confident"}}async function al(e,n,t){let o=G(e,"public"),r=G(e,"scripts");await et(o,{recursive:!0}),await et(r,{recursive:!0});let i=G(o,"scenes.json");await ve(i,JSON.stringify(il(n),null,2),"utf-8");let a=`import { execSync } from "node:child_process";
|
|
3778
3778
|
|
|
3779
3779
|
execSync("${t} video generate plan --project .", { stdio: "inherit" });
|
|
3780
3780
|
`,s=`import { execSync } from "node:child_process";
|
|
3781
3781
|
|
|
3782
3782
|
const args = process.argv.slice(2).join(" ");
|
|
3783
3783
|
execSync("${t} video export --project . " + args, { stdio: "inherit" });
|
|
3784
|
-
`;await we(G(r,"plan.ts"),a,"utf-8"),await we(G(r,"export.ts"),s,"utf-8")}async function Hi(){return process.stdin.isTTY?null:new Promise(e=>{let n="",t=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",o=>{n+=o}),process.stdin.on("end",()=>{t||(t=!0,e(n.trim()||null))}),process.stdin.on("error",()=>{t||(t=!0,e(null))}),setTimeout(()=>{!t&&!n&&(t=!0,e(null))},500)})}function Jl(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function zl(e){let n={shortTitle:"Video",elements:[],audio:[],text:[],scenes:[]},t=!0;return e.forEach(o=>{let r=o.startTime*1e3,i=o.endTime*1e3,a=o.durationInSeconds*1e3;n.scenes.push({name:o.name||`Scene ${o.id}`,text:o.text,startMs:r,endMs:i}),o.imagePath?(n.elements.push({startMs:r,endMs:i,imageUrl:o.imagePath,enterTransition:"blur",exitTransition:"blur",animations:[{type:"scale",from:t?1.3:1,to:t?1:1.3,startMs:0,endMs:a}]}),t=!t):o.videoPath&&n.elements.push({startMs:r,endMs:i,videoUrl:o.videoPath,enterTransition:"blur",exitTransition:"blur",animations:[]}),o.audioPath&&n.audio.push({startMs:r,endMs:i,audioUrl:o.audioPath}),o.timestamps&&n.text.push({startMs:r,endMs:i,text:o.text,position:"bottom",animations:[],timestamps:o.timestamps})}),n}async function tn(e,n){if(e.startsWith("data:")){let r=e.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");await we(n,i);return}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download: ${t.status}`);let o=await t.arrayBuffer();await we(n,Buffer.from(o))}function Xl(e){try{let o=new URL(e).pathname.split(".").pop()?.toLowerCase();if(o&&["jpg","jpeg","png","gif","webp"].includes(o))return o}catch{}return"jpg"}var Yl=new te("assets").description("Generate assets (voiceover per scene, music, images, video)").option("-s, --script <text>","Narration script (legacy single-script mode)").option("--script-file <path>","Path to script file (legacy) or scenes JSON").option("--scenes <path>","Path to scenes.json (defaults to <project>/public/scenes.json)").option("-p, --project <dir>","Project directory (defaults to current directory; uses <dir>/public for output)").option("-t, --topic <text>","Topic for image search").option("-v, --voice <name>","TTS voice ID (ElevenLabs: Rachel, Josh, Adam; OpenAI: alloy, nova; Gemini: Kore, Puck)").option("-m, --music-prompt <text>","Music description").option("-n, --num-images <number>","Number of images to search/download","5").option("-o, --output <dir>","Output directory","./public").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?gt("Initializing...").start():null,o=e.project?mt(process.cwd(),e.project):null;try{let r=await Hi(),i=null;if(e.scenes&&!e.scriptFile&&(e.scriptFile=e.scenes),o&&(e.output=G(o,"public"),e.scriptFile?e.scriptFile=mt(o,e.scriptFile):!e.script&&!r&&(e.scriptFile=G(o,"public","scenes.json"))),r)try{let k=JSON.parse(r);k.scenes&&Array.isArray(k.scenes)&&(i=k)}catch{}if(!i&&e.scriptFile)try{let k=await pt(e.scriptFile,"utf-8"),J=JSON.parse(k);J.scenes&&Array.isArray(J.scenes)&&(i=J)}catch{}let a=i?.voice||e.voice,s=i?.voiceId,l=i?.provider,m=i?.model,p=i?.voiceInstructions,w=i?.musicPrompt||e.musicPrompt||"uplifting background music, positive energy",I=i?.musicDuration,f=G(e.output,"audio"),R=G(e.output,"images"),b=G(e.output,"videos");t&&(t.text="Creating directories..."),await et(f,{recursive:!0}),await et(R,{recursive:!0}),await et(b,{recursive:!0});let y=0,v=[],E=0,A=[],N=[];if(i&&i.scenes.length>0){n==="human"&&(t?.stop(),u(`Processing ${i.scenes.length} scenes...`),t?.start());let k=i.scenes.map((re,B)=>{let he=re.script;return re.voiceStyle&&(he=`${re.voiceStyle} ${he}`),{text:he,id:`scene-${B}`}});t&&(t.text="Generating speech for all scenes...");let J=await Fo({texts:k,options:{provider:l,voice:a,voiceId:s,model:m,voiceSettings:i.voiceSettings,instructions:p}});y+=J.totalCost;let oe=0;for(let re=0;re<i.scenes.length;re++){let B=i.scenes[re],he=Jl(B.name),me=J.results[re];t&&(t.text=`[${B.name}] Saving audio...`);let an=G(f,`${he}.${me.format}`);await we(an,me.audioData);let Oe=me.duration,ea=Math.round(Oe*Qe),nt={id:re+1,name:B.name,text:B.script,wordCount:B.script.split(/\s+/).length,startTime:oe,endTime:oe+Oe,durationInSeconds:Oe,durationInFrames:ea,audioPath:`audio/${he}.${me.format}`,timestamps:me.timestamps};if(B.imageQuery){t&&(t.text=`[${B.name}] Searching image...`);try{let Z=await Rt({query:B.imageQuery,options:{maxResults:1,size:"large",safeSearch:!0}}),ot=Z.data.results.flatMap(X=>X.results);if(y+=Z.data.totalCost,ot.length>0){let X=ot[0],rt=Xl(X.url),Ce=`${he}.${rt}`,sn=G(R,Ce);await tn(X.url,sn),nt.imagePath=`images/${Ce}`,A.push({path:`images/${Ce}`,url:X.url,width:X.width,height:X.height,query:B.imageQuery})}}catch(Z){n==="human"&&(t?.stop(),_(`[${B.name}] Image search failed: ${Z instanceof Error?Z.message:"Unknown"}`),t?.start())}}if(B.videoQuery){t&&(t.text=`[${B.name}] Searching video...`);try{let Z=await gn({query:B.videoQuery,options:{maxResults:1,license:"free"}}),ot=Z.data.results.flatMap(X=>X.results);if(y+=Z.data.totalCost,ot.length>0){let X=ot[0],rt=X.previewUrl||X.downloadUrl;if(rt){let Ce=`${he}.mp4`,sn=G(b,Ce);await tn(rt,sn),nt.videoPath=`videos/${Ce}`,N.push({path:`videos/${Ce}`,url:rt,width:X.width,height:X.height,duration:X.duration,query:B.videoQuery})}}}catch(Z){n==="human"&&(t?.stop(),_(`[${B.name}] Video search failed: ${Z instanceof Error?Z.message:"Unknown"}`),t?.start())}}if(v.push(nt),oe+=Oe,E+=Oe,n==="human"){t?.stop();let Z=[`audio: ${Oe.toFixed(1)}s`,nt.imagePath?"image":null,nt.videoPath?"video":null].filter(Boolean).join(", ");S(` ${B.name}: ${Z}`),t?.start()}}}else{let k=e.script;if(e.scriptFile)try{k=await pt(e.scriptFile,"utf-8")}catch(me){t?.stop(),c(`Failed to read script file: ${me instanceof Error?me.message:"Unknown error"}`),process.exit(d.INVALID_INPUT)}(!k||k.trim().length===0)&&(t?.stop(),c("Provide scenes via stdin JSON, --scenes/--script-file with scenes JSON, or --script for legacy mode"),process.exit(d.INVALID_INPUT)),k=k.trim();let J=e.topic||k.split(".")[0].slice(0,50);t&&(t.text="Generating voiceover...");let oe=await Ct({text:k,options:{voice:a}}),re=G(f,`voiceover.${oe.format}`);await we(re,oe.audioData),y+=oe.cost,E=oe.duration;let B=ql(k);v=Bl(B,oe.duration,Qe,oe.timestamps).map((me,an)=>({...me,name:`Section${an+1}`,audioPath:`audio/voiceover.${oe.format}`})),n==="human"&&(t?.stop(),S(`Voiceover: ${re} (${oe.duration.toFixed(1)}s)`),t?.start())}t&&(t.text="Creating timeline...");let C=zl(v),M=Math.max(C.audio.length>0?Math.max(...C.audio.map(k=>k.endMs)):0,C.text.length>0?Math.max(...C.text.map(k=>k.endMs)):0,C.elements.length>0?Math.max(...C.elements.map(k=>k.endMs)):0),q=M/1e3,ne=I?Math.min(300,Math.max(3,I)):Math.min(300,Math.ceil(q));console.log("[Music Generation] Requesting music:",{prompt:w,requestedDuration:ne,totalAudioDuration:E,actualVideoDuration:q,timelineDurationMs:M});let tt,nn;t&&(t.text="Generating music and thumbnail...");let Ki=`YouTube thumbnail style: BIG BOLD short headline text (like "$50K/MONTH"), dramatic engaging scene, arrows pointing to key elements, high contrast, vibrant colors, clean composition, 16:9. Video context: ${v.map(k=>k.text).join(" ")}`,on=[],Qi=(async()=>{if(ne<3)return n==="human"&&(t?.stop(),_(`Video duration (${q.toFixed(1)}s) is too short for music generation (minimum 3s).`),t?.start()),null;try{let k=await It({prompt:w,duration:ne});if(k.status!=="completed"&&k.status!=="failed"&&(k=await K(()=>at(k.requestId),60,2e3)),k.status==="failed")throw new Error(k.error||"Unknown error");let J=G(f,"music.mp3");return k.audioUrl&&await tn(k.audioUrl,J),{path:"audio/music.mp3",duration:k.duration||ne,prompt:w,cost:k.cost||0}}catch(k){return n==="human"&&(t?.stop(),_(`Music generation failed: ${k.message}`),t?.start()),null}})();on.push(Qi);let Zi=(async()=>{try{let k=await Mo({prompt:Ki,options:{width:1280,height:720}});if(k.success&&k.data.url){let J=G(e.output,"thumbnail.jpg");return await tn(k.data.url,J),y+=k.data.cost||0,J}return null}catch(k){return n==="human"&&(t?.stop(),_(`Thumbnail generation failed: ${k.message}`),t?.start()),null}})();on.push(Zi);let[Ee,so]=await Promise.all(on);Ee&&(tt=Ee,y+=Ee.cost||0,n==="human"&&(t?.stop(),S(`Music: ${G(f,"music.mp3")} (${Ee.duration}s)`),Ee.duration<q&&_(`Music duration (${Ee.duration.toFixed(1)}s) is shorter than video duration (${q.toFixed(1)}s).`),t?.start())),so&&(nn=so,n==="human"&&(t?.stop(),S(`Thumbnail: ${nn}`),t?.start())),t&&(t.text="Writing manifest...");let co=Math.round(q*Qe),lo={music:tt,thumbnail:nn?"thumbnail.jpg":void 0,images:A,videos:N,scenes:v,timeline:C,totalDurationInFrames:co,fps:Qe,totalCost:y,createdAt:new Date().toISOString()},rn=G(e.output,"video-manifest.json");if(await we(rn,JSON.stringify(lo,null,2)),t?.stop(),n==="json"){let{totalCost:k,...J}=lo;x(J);return}if(n==="quiet"){console.log(rn);return}console.log(),S("Video assets created successfully!"),console.log(),u(`Scenes: ${v.length} (${co} frames at ${Qe}fps)`);for(let k of v){let J=[k.audioPath?"audio":null,k.imagePath?"image":null,k.videoPath?"video":null].filter(Boolean).join(", ");u(` - ${k.name}: ${k.durationInSeconds.toFixed(1)}s [${J}]`)}u(`Music: ${tt?.path} (${tt?.duration}s)`),u(`Manifest: ${rn}`),console.log(),u(`Total cost: $${y.toFixed(4)}`)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Kl=new te("find").description("Find stock video clips (supporting)").argument("<query>","Search query").option("-n, --max-results <count>","Maximum number of results","10").option("-o, --orientation <type>","Video orientation: landscape, portrait, square, any","any").option("-l, --license <type>","License type: free, premium, any","free").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let{maxResults:t,orientation:o,license:r,format:i}=n,a=i==="human"?gt("Finding videos...").start():null;try{let s=await gn({query:e,options:{maxResults:parseInt(t,10),orientation:o,license:r}});a?.stop();let l=s.data.results.flatMap(m=>m.results);if(i==="json"){let{totalCost:m,...p}=s.data;x({...s,data:p});return}if(i==="quiet"){l.forEach(m=>{console.log(m.previewUrl||m.thumbnailUrl)});return}if(l.length===0){u("No videos found");return}S(`Found ${l.length} videos for "${e}"`),console.log(),l.forEach((m,p)=>{console.log(`[${p+1}] ${m.title}`),console.log(` URL: ${m.previewUrl||m.thumbnailUrl}`),console.log(` Duration: ${m.duration}s | Size: ${m.width}x${m.height}`),console.log(` Provider: ${m.provider}`),console.log()}),u(`Total cost: $${s.data.totalCost.toFixed(4)}`)}catch(s){a?.stop(),c(s instanceof Error?s.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Ql=new te("new").description("Create a new video project from a template").argument("<name>","Project directory name").option("-t, --template <repo>","GitHub repo (user/repo#commit)",Vl).option("--type <type>","Video type: youtube (16:9), tiktok (9:16), or audiogram (1:1)","youtube").option("--no-install","Skip dependency install").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format,o=t==="human"?gt("Initializing video project...").start():null;try{let r=Xe();await et(r,{recursive:!0});let i=Kt(e),a=n.type,s=await to();if(s.includes(e)){let f=Pi(e,s);o?.stop(),c(`Project "${e}" already exists at: ${i}`),u(`Try: ${g.commands[0]} video generate new ${f}`),process.exit(d.INVALID_INPUT)}/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+(#[a-zA-Z0-9_./-]+)?$/.test(n.template)||(o?.stop(),c(`Invalid template format: "${n.template}". Expected format: owner/repo or owner/repo#branch`),process.exit(d.INVALID_INPUT)),["youtube","tiktok","audiogram"].includes(a)||(o?.stop(),c(`Invalid type "${a}". Use youtube, tiktok, or audiogram.`),process.exit(d.INVALID_INPUT)),o&&(o.text=`Cloning template from ${n.template}...`);let[m,p]=n.template.split("#"),w=p?`-b ${p}`:"";try{Ze(`git clone ${w} --depth 1 https://github.com/${m}.git "${i}"`,{stdio:"pipe"}),await ro(G(i,".git"),{recursive:!0,force:!0})}catch(f){o?.stop(),c(`Failed to clone template: ${f instanceof Error?f.message:"Unknown error"}`),process.exit(d.GENERAL_ERROR)}t==="human"&&(o?.stop(),S(`Template downloaded to ${e}/`),o?.start());let I;try{I=await jl(i)}catch{o?.stop(),c("template.manifest.json not found or invalid in template repo"),process.exit(d.INVALID_INPUT)}if(I.propsSchema&&I.propsSchema!=="video-plan.v1"&&(o?.stop(),c(`Template propsSchema must be video-plan.v1 (found ${I.propsSchema})`),process.exit(d.INVALID_INPUT)),o&&(o.text="Writing scaffold files..."),await Hl(i,a,g.commands[0]),n.install){let f=Wi()?"bun":"npm";o&&(o.text=`Installing dependencies with ${f}...`),await new Promise((R,b)=>{let y=Ul(f,["install"],{cwd:i,stdio:"pipe",shell:!0});y.on("close",v=>{v===0?R():b(new Error(`${f} install failed with code ${v}`))}),y.on("error",b)}),t==="human"&&(o?.stop(),S("Dependencies installed"),o?.start())}if(o?.stop(),t==="json"){x({name:e,path:i,template:n.template,type:a,installed:n.install});return}if(t==="quiet"){console.log(i);return}console.log(),S(`Video project "${e}" created successfully!`),u(`Location: ${i}`),a==="tiktok"?u("Format: TikTok/Reels/Shorts (1080x1920 @ 30fps)"):a==="audiogram"?u("Format: Audiogram (1080x1080 @ 30fps)"):u("Format: YouTube (1920x1080 @ 30fps)"),console.log(),u("Next steps:"),u(` cd ${i}`),n.install||u(` ${Wi()?"bun":"npm"} install`),u(" bun run dev # Preview in Remotion Studio"),u(` ${g.commands[0]} video generate assets --scenes public/scenes.json`),u(` ${g.commands[0]} video generate plan`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Zl=new te("plan").description("Generate video plan from context (via stdin or --context)").option("-c, --context <text>","Context for plan generation").option("-o, --output <path>","Save plan to file").option("-b, --branding <path>","Branding JSON file to include").option("--render-target <target>","Plan target: hyperframes or remotion","hyperframes").option("--no-wait","Return the background run ID immediately").action(async e=>{let n=gt("Generating video plan...").start();try{let t=e.context;if(!t){let l=await Hi();l&&(t=l)}t||(n.stop(),c("Provide context via stdin or --context flag"),process.exit(d.INVALID_INPUT));let o;if(e.branding)try{o=await pt(e.branding,"utf-8")}catch{n.stop(),c(`Could not read branding file: ${e.branding}`),process.exit(d.INVALID_INPUT)}let r=e.renderTarget==="remotion"?"remotion":"hyperframes",i={context:t,branding:o,renderTarget:r};if(e.wait===!1){n.stop(),x(await yn(i));return}let a=await Xo(i);n.stop(),a.success||(c(a.error||"Failed to generate plan"),process.exit(d.GENERAL_ERROR));let s=a.data;e.output?(await we(e.output,s),S(`Plan saved to ${e.output}`)):console.log(s)}catch(t){n.stop(),c(t instanceof Error?t.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ed=new te("generate").description("Generate parts of a video project").addCommand(Ql).addCommand(Yl).addCommand(Zl),td=new te("create").description("Start background standalone video generation").argument("<title>","Video title").requiredOption("--brief <brief>","Video brief").option("--topic <topic>","Video topic").option("--duration <seconds>","Duration in seconds","30").option("--format <format>","tiktok, instagram_reel, or youtube_short","tiktok").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve video generation");try{x(await zo({brief:n.brief,durationSec:Number(n.duration),format:n.format,title:e,topic:n.topic}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),Ji=new te("plan").description("Start background video-plan generation").requiredOption("--context <brief>","Video brief (minimum 100 characters)").option("--branding <path>","Branding JSON file").option("--render-target <target>","hyperframes or remotion","hyperframes").option("--yes","Approve generation").action(async e=>{if(!e.yes)return c("Pass --yes to approve plan generation");try{let n=e.branding?await pt(e.branding,"utf-8"):void 0;x(await yn({branding:n,context:e.context,renderTarget:e.renderTarget==="remotion"?"remotion":"hyperframes"}))}catch(n){c(n instanceof Error?n.message:"Plan generation failed"),process.exit(d.GENERAL_ERROR)}}),nd=new te("status").description("Read video or video-plan background status").argument("<run-id>","Run ID").option("--plan","Read a video-plan run").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await D(n.plan?"generateVideoPlan":"createVideo",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),od=new te("status").description("Read video-plan background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await D("generateVideoPlan",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(d.GENERAL_ERROR)}});Ji.addCommand(od);var rd=new te("projects").description("List all video projects").option("-f, --format <format>","Output format: human, json","human").action(async e=>{let n=await to();if(e.format==="json"){x({projectsDir:Xe(),projects:n.map(t=>({name:t,path:Kt(t)}))});return}if(n.length===0){u("No video projects found"),u(`Projects are stored in: ${Xe()}`);return}console.log(`
|
|
3785
|
-
Video Projects:`),console.log("-".repeat(50));for(let t of n)console.log(` ${t}`),console.log(` ${
|
|
3784
|
+
`;await ve(G(r,"plan.ts"),a,"utf-8"),await ve(G(r,"export.ts"),s,"utf-8")}async function Yi(){return process.stdin.isTTY?null:new Promise(e=>{let n="",t=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",o=>{n+=o}),process.stdin.on("end",()=>{t||(t=!0,e(n.trim()||null))}),process.stdin.on("error",()=>{t||(t=!0,e(null))}),setTimeout(()=>{!t&&!n&&(t=!0,e(null))},500)})}function sl(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function cl(e){let n={shortTitle:"Video",elements:[],audio:[],text:[],scenes:[]},t=!0;return e.forEach(o=>{let r=o.startTime*1e3,i=o.endTime*1e3,a=o.durationInSeconds*1e3;n.scenes.push({name:o.name||`Scene ${o.id}`,text:o.text,startMs:r,endMs:i}),o.imagePath?(n.elements.push({startMs:r,endMs:i,imageUrl:o.imagePath,enterTransition:"blur",exitTransition:"blur",animations:[{type:"scale",from:t?1.3:1,to:t?1:1.3,startMs:0,endMs:a}]}),t=!t):o.videoPath&&n.elements.push({startMs:r,endMs:i,videoUrl:o.videoPath,enterTransition:"blur",exitTransition:"blur",animations:[]}),o.audioPath&&n.audio.push({startMs:r,endMs:i,audioUrl:o.audioPath}),o.timestamps&&n.text.push({startMs:r,endMs:i,text:o.text,position:"bottom",animations:[],timestamps:o.timestamps})}),n}async function nn(e,n){if(e.startsWith("data:")){let r=e.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");await ve(n,i);return}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download: ${t.status}`);let o=await t.arrayBuffer();await ve(n,Buffer.from(o))}function dl(e){try{let o=new URL(e).pathname.split(".").pop()?.toLowerCase();if(o&&["jpg","jpeg","png","gif","webp"].includes(o))return o}catch{}return"jpg"}var ll=new te("assets").description("Generate assets (voiceover per scene, music, images, video)").option("-s, --script <text>","Narration script (legacy single-script mode)").option("--script-file <path>","Path to script file (legacy) or scenes JSON").option("--scenes <path>","Path to scenes.json (defaults to <project>/public/scenes.json)").option("-p, --project <dir>","Project directory (defaults to current directory; uses <dir>/public for output)").option("-t, --topic <text>","Topic for image search").option("-v, --voice <name>","TTS voice ID (ElevenLabs: Rachel, Josh, Adam; OpenAI: alloy, nova; Gemini: Kore, Puck)").option("-m, --music-prompt <text>","Music description").option("-n, --num-images <number>","Number of images to search/download","5").option("-o, --output <dir>","Output directory","./public").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?ft("Initializing...").start():null,o=e.project?pt(process.cwd(),e.project):null;try{let r=await Yi(),i=null;if(e.scenes&&!e.scriptFile&&(e.scriptFile=e.scenes),o&&(e.output=G(o,"public"),e.scriptFile?e.scriptFile=pt(o,e.scriptFile):!e.script&&!r&&(e.scriptFile=G(o,"public","scenes.json"))),r)try{let k=JSON.parse(r);k.scenes&&Array.isArray(k.scenes)&&(i=k)}catch{}if(!i&&e.scriptFile)try{let k=await gt(e.scriptFile,"utf-8"),J=JSON.parse(k);J.scenes&&Array.isArray(J.scenes)&&(i=J)}catch{}let a=i?.voice||e.voice,s=i?.voiceId,d=i?.provider,u=i?.model,p=i?.voiceInstructions,w=i?.musicPrompt||e.musicPrompt||"uplifting background music, positive energy",I=i?.musicDuration,f=G(e.output,"audio"),T=G(e.output,"images"),b=G(e.output,"videos");t&&(t.text="Creating directories..."),await et(f,{recursive:!0}),await et(T,{recursive:!0}),await et(b,{recursive:!0});let y=0,v=[],E=0,A=[],N=[];if(i&&i.scenes.length>0){n==="human"&&(t?.stop(),m(`Processing ${i.scenes.length} scenes...`),t?.start());let k=i.scenes.map((re,B)=>{let ye=re.script;return re.voiceStyle&&(ye=`${re.voiceStyle} ${ye}`),{text:ye,id:`scene-${B}`}});t&&(t.text="Generating speech for all scenes...");let J=await jo({texts:k,options:{provider:d,voice:a,voiceId:s,model:u,voiceSettings:i.voiceSettings,instructions:p}});y+=J.totalCost;let oe=0;for(let re=0;re<i.scenes.length;re++){let B=i.scenes[re],ye=sl(B.name),me=J.results[re];t&&(t.text=`[${B.name}] Saving audio...`);let sn=G(f,`${ye}.${me.format}`);await ve(sn,me.audioData);let Oe=me.duration,ra=Math.round(Oe*Qe),nt={id:re+1,name:B.name,text:B.script,wordCount:B.script.split(/\s+/).length,startTime:oe,endTime:oe+Oe,durationInSeconds:Oe,durationInFrames:ra,audioPath:`audio/${ye}.${me.format}`,timestamps:me.timestamps};if(B.imageQuery){t&&(t.text=`[${B.name}] Searching image...`);try{let Z=await Rt({query:B.imageQuery,options:{maxResults:1,size:"large",safeSearch:!0}}),ot=Z.data.results.flatMap(X=>X.results);if(y+=Z.data.totalCost,ot.length>0){let X=ot[0],rt=dl(X.url),Ie=`${ye}.${rt}`,cn=G(T,Ie);await nn(X.url,cn),nt.imagePath=`images/${Ie}`,A.push({path:`images/${Ie}`,url:X.url,width:X.width,height:X.height,query:B.imageQuery})}}catch(Z){n==="human"&&(t?.stop(),_(`[${B.name}] Image search failed: ${Z instanceof Error?Z.message:"Unknown"}`),t?.start())}}if(B.videoQuery){t&&(t.text=`[${B.name}] Searching video...`);try{let Z=await hn({query:B.videoQuery,options:{maxResults:1,license:"free"}}),ot=Z.data.results.flatMap(X=>X.results);if(y+=Z.data.totalCost,ot.length>0){let X=ot[0],rt=X.previewUrl||X.downloadUrl;if(rt){let Ie=`${ye}.mp4`,cn=G(b,Ie);await nn(rt,cn),nt.videoPath=`videos/${Ie}`,N.push({path:`videos/${Ie}`,url:rt,width:X.width,height:X.height,duration:X.duration,query:B.videoQuery})}}}catch(Z){n==="human"&&(t?.stop(),_(`[${B.name}] Video search failed: ${Z instanceof Error?Z.message:"Unknown"}`),t?.start())}}if(v.push(nt),oe+=Oe,E+=Oe,n==="human"){t?.stop();let Z=[`audio: ${Oe.toFixed(1)}s`,nt.imagePath?"image":null,nt.videoPath?"video":null].filter(Boolean).join(", ");S(` ${B.name}: ${Z}`),t?.start()}}}else{let k=e.script;if(e.scriptFile)try{k=await gt(e.scriptFile,"utf-8")}catch(me){t?.stop(),c(`Failed to read script file: ${me instanceof Error?me.message:"Unknown error"}`),process.exit(l.INVALID_INPUT)}(!k||k.trim().length===0)&&(t?.stop(),c("Provide scenes via stdin JSON, --scenes/--script-file with scenes JSON, or --script for legacy mode"),process.exit(l.INVALID_INPUT)),k=k.trim();let J=e.topic||k.split(".")[0].slice(0,50);t&&(t.text="Generating voiceover...");let oe=await It({text:k,options:{voice:a}}),re=G(f,`voiceover.${oe.format}`);await ve(re,oe.audioData),y+=oe.cost,E=oe.duration;let B=nl(k);v=ol(B,oe.duration,Qe,oe.timestamps).map((me,sn)=>({...me,name:`Section${sn+1}`,audioPath:`audio/voiceover.${oe.format}`})),n==="human"&&(t?.stop(),S(`Voiceover: ${re} (${oe.duration.toFixed(1)}s)`),t?.start())}t&&(t.text="Creating timeline...");let C=cl(v),M=Math.max(C.audio.length>0?Math.max(...C.audio.map(k=>k.endMs)):0,C.text.length>0?Math.max(...C.text.map(k=>k.endMs)):0,C.elements.length>0?Math.max(...C.elements.map(k=>k.endMs)):0),q=M/1e3,ne=I?Math.min(300,Math.max(3,I)):Math.min(300,Math.ceil(q));console.log("[Music Generation] Requesting music:",{prompt:w,requestedDuration:ne,totalAudioDuration:E,actualVideoDuration:q,timelineDurationMs:M});let tt,on;t&&(t.text="Generating music and thumbnail...");let ta=`YouTube thumbnail style: BIG BOLD short headline text (like "$50K/MONTH"), dramatic engaging scene, arrows pointing to key elements, high contrast, vibrant colors, clean composition, 16:9. Video context: ${v.map(k=>k.text).join(" ")}`,rn=[],na=(async()=>{if(ne<3)return n==="human"&&(t?.stop(),_(`Video duration (${q.toFixed(1)}s) is too short for music generation (minimum 3s).`),t?.start()),null;try{let k=await Tt({prompt:w,duration:ne});if(k.status!=="completed"&&k.status!=="failed"&&(k=await K(()=>st(k.requestId),60,2e3)),k.status==="failed")throw new Error(k.error||"Unknown error");let J=G(f,"music.mp3");return k.audioUrl&&await nn(k.audioUrl,J),{path:"audio/music.mp3",duration:k.duration||ne,prompt:w,cost:k.cost||0}}catch(k){return n==="human"&&(t?.stop(),_(`Music generation failed: ${k.message}`),t?.start()),null}})();rn.push(na);let oa=(async()=>{try{let k=await Go({prompt:ta,options:{width:1280,height:720}});if(k.success&&k.data.url){let J=G(e.output,"thumbnail.jpg");return await nn(k.data.url,J),y+=k.data.cost||0,J}return null}catch(k){return n==="human"&&(t?.stop(),_(`Thumbnail generation failed: ${k.message}`),t?.start()),null}})();rn.push(oa);let[Ee,lo]=await Promise.all(rn);Ee&&(tt=Ee,y+=Ee.cost||0,n==="human"&&(t?.stop(),S(`Music: ${G(f,"music.mp3")} (${Ee.duration}s)`),Ee.duration<q&&_(`Music duration (${Ee.duration.toFixed(1)}s) is shorter than video duration (${q.toFixed(1)}s).`),t?.start())),lo&&(on=lo,n==="human"&&(t?.stop(),S(`Thumbnail: ${on}`),t?.start())),t&&(t.text="Writing manifest...");let uo=Math.round(q*Qe),mo={music:tt,thumbnail:on?"thumbnail.jpg":void 0,images:A,videos:N,scenes:v,timeline:C,totalDurationInFrames:uo,fps:Qe,totalCost:y,createdAt:new Date().toISOString()},an=G(e.output,"video-manifest.json");if(await ve(an,JSON.stringify(mo,null,2)),t?.stop(),n==="json"){let{totalCost:k,...J}=mo;x(J);return}if(n==="quiet"){console.log(an);return}console.log(),S("Video assets created successfully!"),console.log(),m(`Scenes: ${v.length} (${uo} frames at ${Qe}fps)`);for(let k of v){let J=[k.audioPath?"audio":null,k.imagePath?"image":null,k.videoPath?"video":null].filter(Boolean).join(", ");m(` - ${k.name}: ${k.durationInSeconds.toFixed(1)}s [${J}]`)}m(`Music: ${tt?.path} (${tt?.duration}s)`),m(`Manifest: ${an}`),console.log(),m(`Total cost: $${y.toFixed(4)}`)}catch(r){t?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),ul=new te("find").description("Find stock video clips (supporting)").argument("<query>","Search query").option("-n, --max-results <count>","Maximum number of results","10").option("-o, --orientation <type>","Video orientation: landscape, portrait, square, any","any").option("-l, --license <type>","License type: free, premium, any","free").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let{maxResults:t,orientation:o,license:r,format:i}=n,a=i==="human"?ft("Finding videos...").start():null;try{let s=await hn({query:e,options:{maxResults:parseInt(t,10),orientation:o,license:r}});a?.stop();let d=s.data.results.flatMap(u=>u.results);if(i==="json"){let{totalCost:u,...p}=s.data;x({...s,data:p});return}if(i==="quiet"){d.forEach(u=>{console.log(u.previewUrl||u.thumbnailUrl)});return}if(d.length===0){m("No videos found");return}S(`Found ${d.length} videos for "${e}"`),console.log(),d.forEach((u,p)=>{console.log(`[${p+1}] ${u.title}`),console.log(` URL: ${u.previewUrl||u.thumbnailUrl}`),console.log(` Duration: ${u.duration}s | Size: ${u.width}x${u.height}`),console.log(` Provider: ${u.provider}`),console.log()}),m(`Total cost: $${s.data.totalCost.toFixed(4)}`)}catch(s){a?.stop(),c(s instanceof Error?s.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),ml=new te("new").description("Create a new video project from a template").argument("<name>","Project directory name").option("-t, --template <repo>","GitHub repo (user/repo#commit)",Zd).option("--type <type>","Video type: youtube (16:9), tiktok (9:16), or audiogram (1:1)","youtube").option("--no-install","Skip dependency install").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(e,n)=>{let t=n.format,o=t==="human"?ft("Initializing video project...").start():null;try{let r=Xe();await et(r,{recursive:!0});let i=Qt(e),a=n.type,s=await oo();if(s.includes(e)){let f=Ui(e,s);o?.stop(),c(`Project "${e}" already exists at: ${i}`),m(`Try: ${g.commands[0]} video generate new ${f}`),process.exit(l.INVALID_INPUT)}/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+(#[a-zA-Z0-9_./-]+)?$/.test(n.template)||(o?.stop(),c(`Invalid template format: "${n.template}". Expected format: owner/repo or owner/repo#branch`),process.exit(l.INVALID_INPUT)),["youtube","tiktok","audiogram"].includes(a)||(o?.stop(),c(`Invalid type "${a}". Use youtube, tiktok, or audiogram.`),process.exit(l.INVALID_INPUT)),o&&(o.text=`Cloning template from ${n.template}...`);let[u,p]=n.template.split("#"),w=p?`-b ${p}`:"";try{Ze(`git clone ${w} --depth 1 https://github.com/${u}.git "${i}"`,{stdio:"pipe"}),await ao(G(i,".git"),{recursive:!0,force:!0})}catch(f){o?.stop(),c(`Failed to clone template: ${f instanceof Error?f.message:"Unknown error"}`),process.exit(l.GENERAL_ERROR)}t==="human"&&(o?.stop(),S(`Template downloaded to ${e}/`),o?.start());let I;try{I=await tl(i)}catch{o?.stop(),c("template.manifest.json not found or invalid in template repo"),process.exit(l.INVALID_INPUT)}if(I.propsSchema&&I.propsSchema!=="video-plan.v1"&&(o?.stop(),c(`Template propsSchema must be video-plan.v1 (found ${I.propsSchema})`),process.exit(l.INVALID_INPUT)),o&&(o.text="Writing scaffold files..."),await al(i,a,g.commands[0]),n.install){let f=Xi()?"bun":"npm";o&&(o.text=`Installing dependencies with ${f}...`),await new Promise((T,b)=>{let y=Yd(f,["install"],{cwd:i,stdio:"pipe",shell:!0});y.on("close",v=>{v===0?T():b(new Error(`${f} install failed with code ${v}`))}),y.on("error",b)}),t==="human"&&(o?.stop(),S("Dependencies installed"),o?.start())}if(o?.stop(),t==="json"){x({name:e,path:i,template:n.template,type:a,installed:n.install});return}if(t==="quiet"){console.log(i);return}console.log(),S(`Video project "${e}" created successfully!`),m(`Location: ${i}`),a==="tiktok"?m("Format: TikTok/Reels/Shorts (1080x1920 @ 30fps)"):a==="audiogram"?m("Format: Audiogram (1080x1080 @ 30fps)"):m("Format: YouTube (1920x1080 @ 30fps)"),console.log(),m("Next steps:"),m(` cd ${i}`),n.install||m(` ${Xi()?"bun":"npm"} install`),m(" bun run dev # Preview in Remotion Studio"),m(` ${g.commands[0]} video generate assets --scenes public/scenes.json`),m(` ${g.commands[0]} video generate plan`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),pl=new te("plan").description("Generate video plan from context (via stdin or --context)").option("-c, --context <text>","Context for plan generation").option("-o, --output <path>","Save plan to file").option("-b, --branding <path>","Branding JSON file to include").option("--render-target <target>","Plan target: hyperframes or remotion","hyperframes").option("--no-wait","Return the background run ID immediately").action(async e=>{let n=ft("Generating video plan...").start();try{let t=e.context;if(!t){let d=await Yi();d&&(t=d)}t||(n.stop(),c("Provide context via stdin or --context flag"),process.exit(l.INVALID_INPUT));let o;if(e.branding)try{o=await gt(e.branding,"utf-8")}catch{n.stop(),c(`Could not read branding file: ${e.branding}`),process.exit(l.INVALID_INPUT)}let r=e.renderTarget==="remotion"?"remotion":"hyperframes",i={context:t,branding:o,renderTarget:r};if(e.wait===!1){n.stop(),x(await wn(i));return}let a=await Zo(i);n.stop(),a.success||(c(a.error||"Failed to generate plan"),process.exit(l.GENERAL_ERROR));let s=a.data;e.output?(await ve(e.output,s),S(`Plan saved to ${e.output}`)):console.log(s)}catch(t){n.stop(),c(t instanceof Error?t.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),gl=new te("generate").description("Generate parts of a video project").addCommand(ml).addCommand(ll).addCommand(pl),fl=new te("create").description("Start background standalone video generation").argument("<title>","Video title").requiredOption("--brief <brief>","Video brief").option("--topic <topic>","Video topic").option("--duration <seconds>","Duration in seconds","30").option("--format <format>","tiktok, instagram_reel, or youtube_short","tiktok").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve video generation");try{x(await Qo({brief:n.brief,durationSec:Number(n.duration),format:n.format,title:e,topic:n.topic}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(l.GENERAL_ERROR)}}),Ki=new te("plan").description("Start background video-plan generation").requiredOption("--context <brief>","Video brief (minimum 100 characters)").option("--branding <path>","Branding JSON file").option("--render-target <target>","hyperframes or remotion","hyperframes").option("--yes","Approve generation").action(async e=>{if(!e.yes)return c("Pass --yes to approve plan generation");try{let n=e.branding?await gt(e.branding,"utf-8"):void 0;x(await wn({branding:n,context:e.context,renderTarget:e.renderTarget==="remotion"?"remotion":"hyperframes"}))}catch(n){c(n instanceof Error?n.message:"Plan generation failed"),process.exit(l.GENERAL_ERROR)}}),hl=new te("status").description("Read video or video-plan background status").argument("<run-id>","Run ID").option("--plan","Read a video-plan run").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L(n.plan?"generateVideoPlan":"createVideo",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),yl=new te("status").description("Read video-plan background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L("generateVideoPlan",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}});Ki.addCommand(yl);var bl=new te("projects").description("List all video projects").option("-f, --format <format>","Output format: human, json","human").action(async e=>{let n=await oo();if(e.format==="json"){x({projectsDir:Xe(),projects:n.map(t=>({name:t,path:Qt(t)}))});return}if(n.length===0){m("No video projects found"),m(`Projects are stored in: ${Xe()}`);return}console.log(`
|
|
3785
|
+
Video Projects:`),console.log("-".repeat(50));for(let t of n)console.log(` ${t}`),console.log(` ${Qt(t)}`);console.log()}),wl=new te("inject").description("Inject thumbnail into video (first frame + file icon)").requiredOption("-i, --video <path>","Input video file").requiredOption("-t, --thumbnail <path>","Thumbnail image").option("-o, --output <path>","Output video (default: video-with-thumb.mp4)").option("-f, --format <format>","Output format: human, json, quiet","human").action(async e=>{let n=e.format,t=n==="human"?ft("Injecting thumbnail...").start():null;try{let o=pt(e.video),r=pt(e.thumbnail),i=e.output?pt(e.output):o.replace(/\.mp4$/,"-with-thumb.mp4");await io(o),await io(r);let a=Qd;if(a)try{await io(a)}catch{a=null}if(!a)try{a=Ze("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let s=Kd(a,["-i",o],{encoding:"utf8"});if(s.error)throw new Error(`Failed to probe video: ${s.error.message}`);let d=(s.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!d)throw new Error("Could not detect video dimensions");let[,u,p]=d;t&&(t.text="Creating thumbnail frame...");let w="/tmp/cc-thumb-frame.mp4";Ze(`${a} -y -loop 1 -i "${r}" -vf "scale=${u}:${p}:force_original_aspect_ratio=decrease,pad=${u}:${p}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${w}"`,{stdio:"pipe"}),t&&(t.text="Concatenating with video...");let I="/tmp/cc-concat-video.mp4";if(Ze(`${a} -y -i "${w}" -i "${o}" -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0[v]" -map "[v]" -map 1:a -c:v libx264 -preset ultrafast -crf 18 -c:a copy "${I}"`,{stdio:"pipe"}),t&&(t.text="Adding file icon thumbnail..."),Ze(`${a} -y -i "${I}" -i "${r}" -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic "${i}"`,{stdio:"pipe"}),await ao(w,{force:!0}),await ao(I,{force:!0}),t?.stop(),n==="json"){x({success:!0,output:i});return}if(n==="quiet"){console.log(i);return}S(`Thumbnail injected: ${i}`)}catch(o){t?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(l.GENERAL_ERROR)}}),vl=new te("thumbnail").description("Thumbnail operations").addCommand(wl),so=new te("video").description("Video generation commands").addCommand(gl).addCommand(ul).addCommand(bl).addCommand(vl).addCommand(Hi).addCommand(Ji).addCommand(zi).addCommand(Mi);so.addCommand(fl).addCommand(Ki).addCommand(hl);import{Command as co}from"commander";var xl=new co("create").description("Start background visual-abstract generation").argument("<brief>","Dense source brief").option("--title <title>","Artifact title").option("--aspect <ratio>","1:1, 16:9, 9:16, 4:3, or 3:4","1:1").option("--quality <tier>","fast, balanced, or best","best").option("--preset <preset>","Output preset","executive-one-pager").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,n)=>{if(!n.yes)return c("Pass --yes to approve visual-abstract generation");try{x(await $("createVisualAbstract",{approvalReceipt:"cli:--yes",aspectRatio:n.aspect,brandingId:n.brandingId,brief:e,outputPreset:n.preset,qualityTier:n.quality,teamId:n.teamId,title:n.title}))}catch(t){c(t instanceof Error?t.message:"Generation failed"),process.exit(l.GENERAL_ERROR)}}),Sl=new co("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{x(await L("createVisualAbstract",e,n.teamId))}catch(t){c(t instanceof Error?t.message:"Status failed"),process.exit(l.GENERAL_ERROR)}}),Qi=new co("visual-abstract").description("Visual abstract commands").addCommand(xl).addCommand(Sl);var Cl=[fi,hi,ui,Di,Si,xi,bi,so,ki,$i,Ri,Ai,pi,wi,Ii,si,Qi,vi,ri,di];function Zi(e){for(let n of Cl)e.addCommand(n)}var Tl="0.3.13",W=new Il,xe=g.commands[0];W.name(xe).description(g.description).version(Tl,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output").configureOutput({outputError:(e,n)=>{n(ue.red(e))}});W.addCommand(Ir);W.addCommand(Tr);W.addCommand(dr);W.addCommand(wr);W.addCommand(lr);W.addCommand(fr);W.addCommand(br);W.addCommand(ti);W.addCommand(hr);W.addCommand(ni);W.addCommand(ze);W.addCommand(Lt);W.addCommand(or);Zi(W);var ea=pr();ea.commands.length>0&&W.addCommand(ea);W.on("command:*",e=>{console.error(ue.red(`Error: Unknown command '${e[0]}'`)),console.error(),console.error(`Run '${xe} --help' to see available commands.`),process.exit(1)});W.addHelpText("after",`
|
|
3786
3786
|
${ue.bold("Examples:")}
|
|
3787
3787
|
${ue.gray("# Log in (opens browser)")}
|
|
3788
|
-
$ ${
|
|
3788
|
+
$ ${xe} login
|
|
3789
3789
|
|
|
3790
3790
|
${ue.gray("# Create a presentation (recommended pattern)")}
|
|
3791
|
-
$ ${
|
|
3791
|
+
$ ${xe} create "Q4 Business Review" \\
|
|
3792
3792
|
-n 12 -m best \\
|
|
3793
3793
|
--audience "Executive leadership team" \\
|
|
3794
3794
|
--context "Revenue: $50M (+25% YoY), New customers: 150"
|
|
3795
3795
|
|
|
3796
3796
|
${ue.gray("# Create from a file")}
|
|
3797
|
-
$ ${
|
|
3797
|
+
$ ${xe} create "Product Launch" \\
|
|
3798
3798
|
-n 10 -m fast \\
|
|
3799
3799
|
--audience "Sales team and partners" \\
|
|
3800
3800
|
--context-file ./launch-brief.md
|
|
3801
3801
|
|
|
3802
3802
|
${ue.gray("# Create from URLs")}
|
|
3803
|
-
$ ${
|
|
3803
|
+
$ ${xe} create "Market Analysis" \\
|
|
3804
3804
|
-n 15 -m best \\
|
|
3805
3805
|
--audience "Strategy team" \\
|
|
3806
3806
|
--sources https://example.com/report.pdf
|
|
3807
3807
|
|
|
3808
3808
|
${ue.gray("# List and export")}
|
|
3809
|
-
$ ${
|
|
3810
|
-
$ ${
|
|
3809
|
+
$ ${xe} list --format table
|
|
3810
|
+
$ ${xe} export <slug> -o backup.zip
|
|
3811
3811
|
|
|
3812
3812
|
${ue.bold("Authentication:")}
|
|
3813
|
-
Run '${
|
|
3813
|
+
Run '${xe} login' to authenticate (recommended).
|
|
3814
3814
|
Or set CC_SLIDES_API_KEY environment variable for API key auth.
|
|
3815
3815
|
|
|
3816
3816
|
${ue.bold("More Info:")}
|
|
3817
3817
|
${ue.blue(g.docsUrl)}
|
|
3818
|
-
`);W.parse(
|
|
3818
|
+
`);W.parse(oi(process.argv.slice(2)),{from:"user"});
|