@conceptcraft/mindframes 0.3.8 → 0.3.10

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.
Files changed (2) hide show
  1. package/dist/index.js +60 -60
  2. 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"};import ce from"chalk";import{Command as xl}from"commander";import{Command as Wi}from"commander";import{randomUUID as rn}from"crypto";import{readFileSync as Di,statSync as Fi}from"fs";import{basename as mo}from"path";import yt from"chalk";import Ei from"conf";function no(t={}){let n=(s,l)=>{let u=t[s];return u&&u.trim().length>0?u.trim():l},e=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=e.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:r,name:i.replace(/^\./,""),displayName:e,description:`CLI tool for ${e} presentation generation`,commands:[o,r],apiUrl:n("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:n("NEXT_PUBLIC_DOCS_URL",`https://docs.${e.toLowerCase()}.ai`),packageName:n("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${a}_API_KEY`,apiUrlEnvVar:`${a}_API_URL`}}var p=typeof h<"u"&&h?h:no(process.env);var oo=p.apiUrl,Oi={apiKey:{type:"string"},apiUrl:{type:"string",default:oo},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}},O=new Ei({projectName:p.name,schema:Oi});function ro(){return{apiKey:fe(),apiUrl:j(),defaultTeamId:O.get("defaultTeamId"),accessToken:O.get("accessToken"),refreshToken:O.get("refreshToken"),tokenExpiresAt:O.get("tokenExpiresAt"),clientId:O.get("clientId"),clientSecret:O.get("clientSecret")}}function fe(){let t=process.env[p.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return t||O.get("apiKey")}function tn(t){O.set("apiKey",t)}function j(){let t=process.env[p.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return t||(O.get("apiUrl")??oo)}function nn(t){O.set("apiUrl",t)}function ut(){return O.get("defaultTeamId")}function Ee(t){O.set("defaultTeamId",t)}function mt(){O.clear()}function nt(){return O.path}function Oe(){return!!fe()}function io(){return O.get("accessToken")}function ao(){return O.get("refreshToken")}function pt(t,n,e){O.set("accessToken",t),O.set("refreshToken",n),O.set("tokenExpiresAt",Date.now()+(e-60)*1e3)}function gt(){O.delete("accessToken"),O.delete("refreshToken"),O.delete("tokenExpiresAt")}function so(){let t=O.get("tokenExpiresAt");return t?Date.now()>=t:!0}function Ce(){return!!O.get("accessToken")&&!!O.get("refreshToken")}function ft(){return O.get("clientId")}function ht(){return O.get("clientSecret")}function co(t,n){O.set("clientId",t),O.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 Pi(){let t=ao(),n=ft(),e=j();if(!t||!n)return null;try{let o=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!o.ok)return null;let r=await o.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:n}),a=ht();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 gt(),null;let l=await s.json();return pt(l.access_token,l.refresh_token,l.expires_in),l.access_token}catch{return null}}async function lo(){return Ce()?so()?Pi():io()||null:null}function ie(){return Ce()||Oe()}async function E(){if(!ie()){let t=p.commands[0],n=p.apiKeyEnvVar;console.error(yt.red("\u2717 Not authenticated.")),console.error(),console.error(yt.bold("To authenticate, run:")),console.error(yt.cyan(` ${t} login`)),console.error(),console.error(yt.gray(`Or set ${n} environment variable.`)),process.exit(d.AUTH_ERROR)}}function Ni(t){return t.length<=14?"****":`${t.slice(0,10)}...${t.slice(-4)}`}function uo(){let t=fe();if(t)return Ni(t)}function on(t){return["cc_slides_","mcp_","cc_sk_","sk_"].some(e=>t.startsWith(e))}async function de(){let t=await lo();if(t)return{Authorization:`Bearer ${t}`};let n=fe();return n?{"x-api-key":n}:{}}var D=class extends Error{constructor(e,o,r=1,i="operation_failed",a=!1){super(e);this.statusCode=o;this.exitCode=r;this.errorCode=i;this.retryable=a;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},po="Idempotency-Key";function Li(t){return t&&t!=="GET"?{[po]:rn()}:{}}async function z(t,n={}){let e=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let o=await de(),r=`${e}${t}`,i={...o,...Li(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 D(`Network error: ${u instanceof Error?u.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!s.ok){let u=await s.text().catch(()=>""),f=_i(u,s.status),v=1;switch(s.status){case 401:v=2;break;case 403:v=2;break;case 404:v=3;break;case 429:v=4;break;case 500:v=1;break}let I=`[${f.code}] ${f.message}`;throw new D(I,s.status,v,f.code,f.retryable)}return n.stream?s:s.headers.get("content-type")?.includes("application/json")?s.json():s.text()}function Ui(t){switch(t){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 _i(t,n){let e=Ui(n),o=t.trim()||`HTTP ${n}: The request could not be completed.`;try{let r=JSON.parse(t),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:e,message:typeof r.message=="string"?r.message:r.error,retryable:n===429||n>=500}}catch{}return{code:e,message:o,retryable:n===429||n>=500}}async function go(){return z("/api/cli/capabilities")}async function F(t,n,e){let o=e?`?teamId=${encodeURIComponent(e)}`:"";return z(`/api/cli/tool-runs/${encodeURIComponent(t)}/${encodeURIComponent(n)}${o}`)}async function A(t,n){return z(`/api/cli/tools/${encodeURIComponent(t)}`,{body:n,method:"POST"})}async function Mi(t,n,e=120){for(let o=0;o<e;o++){let r=await F(t,n);if(r.done){if(r.error)throw new D(`[${r.error.code??"operation_failed"}] ${r.error.message}`,500,1,r.error.code??"operation_failed",r.error.retryable);return r}await new Promise(i=>setTimeout(i,(r.nextPollAfterSeconds??2)*1e3))}throw new D("[operation_timed_out] The background operation timed out.",408,1,"operation_timed_out",!0)}function bt(t){return t.error||t.status==="failed"||t.status==="errored"||t.status==="cancelled"?"failed":t.done||t.status==="completed"?"completed":t.status==="in_progress"?"processing":"pending"}function Vi(t){try{let e=new URL(t).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return e&&/^[a-z0-9]+$/.test(e)?e:void 0}catch{return}}function ji(t){let n=t.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 qi(t){let n=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let e=await de(),o=Fi(t),r=mo(t),i=ji(t),a=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...e},body:JSON.stringify({fileMetadata:{name:r,type:i,size:o.size}})});if(!a.ok){let I=await a.text();throw new D(I||"Failed to get upload URL",a.status,1)}let s=await a.json(),l=Di(t),u=new FormData;for(let[I,g]of Object.entries(s.fields||{}))u.append(I,g);let f=new Blob([l],{type:i});u.append("file",f,r);let v=await fetch(s.url,{method:"POST",body:u});if(!v.ok)throw new D("Failed to upload file to storage",v.status,1);return{id:rn(),name:r,url:s.fileUrl,size:o.size,type:i,selected:!0}}async function fo(t,n){let e=[];for(let o=0;o<t.length;o++){let r=t[o],i=mo(r);n?.(o,t.length,i);let a=await qi(r);e.push(a)}return n?.(t.length,t.length,""),e}async function ho(t){let n={};for(let[o,r]of Object.entries(t))r!==void 0&&(n[o]=r);let e=n.designBrandReference??n.brandId??n.brandingId;return e!==void 0&&(n.designBrandReference=e,delete n.brandId,delete n.brandingId),A("createSlides",{...n,approvalReceipt:"cli:create"})}async function yo(t,n=20){let e=new URLSearchParams;return e.set("limit",String(n)),t&&e.set("teamId",t),(await z(`/api/cli/presentations?${e}`)).presentations}async function xe(t){return z(`/api/cli/presentation/${t}`)}async function bo(t){await z(`/api/cli/presentation/${t}`,{method:"DELETE"})}async function xo(t,n={}){let e=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let o=await de(),r=await fetch(`${e}/api/presentations/export`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({presentationId:t,options:{includeImages:n.includeImages??!0,includeBranding:n.includeBranding??!0,downloadExternalImages:n.includeExternal??!0}})});if(!r.ok)throw new D(await r.text(),r.status,r.status===404?3:1);return r.arrayBuffer()}async function vo(t,n,e={}){let o=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let r=await de(),i=new FormData,a=new Blob([t],{type:"application/zip"});i.append("file",a,n),i.append("options",JSON.stringify({dryRun:e.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 D(l.errors?.[0]?.message??"Import failed",s.status,1);return l}async function an(){return z("/api/cli/branding")}async function wo(t,n=25){let e=new URLSearchParams;return e.set("limit",String(n)),t&&e.set("search",t),z(`/api/cli/templates?${e}`)}async function So(t){return z(`/api/branding/${t}`)}async function Co(t,n,e){return A("extractBranding",{approvalReceipt:e,teamId:n,url:t})}async function he(){return z("/api/cli/whoami")}async function Io(){return z("/api/cli/features")}async function To(t,n,e={}){let o=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let r=await de(),i=await fetch(`${o}/api/presentations/${t}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({documentCreatedAt:n,targetWordCount:e.targetWordCount??300,tone:e.tone??"professional",language:e.language??"en",targetAudience:e.targetAudience??"General Audience",blogFormat:e.blogFormat??"narrative",customInstructions:e.customInstructions??"",includeImages:e.includeImages??!0,includeTableOfContents:e.includeTableOfContents??!1})});if(!i.ok)throw new D(await i.text(),i.status,i.status===404?3:1);return i}async function Bi(t){let n=new URLSearchParams;t&&n.set("teamId",t);let e=n.toString();return z(`/api/cli/limits${e?`?${e}`:""}`)}async function ko(t,n,e){let o=await Bi(e);if(!o.canGenerate[t]){let r=o.remaining[t]??0,i=o.limits[t]??0;throw i===0?new D(`The "${t}" mode is not available on your ${o.planName} plan. Available modes: ${o.availableModes.join(", ")||"none"}`,403,2):new D(`You have reached your ${t} generation limit for this billing cycle (${o.usage[t]??0}/${i} used). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,4)}if(o.maxSlidesPerPresentation!==-1&&n>o.maxSlidesPerPresentation)throw new D(`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 Ro(t){return t.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 xt(t){let n=await A("generateSpeech",{approvalReceipt:"cli:tts-generate",...t,text:Ro(t.text)}),o=(await Mi("generateSpeech",n.runId)).entity?.url;if(!o)throw new D("Speech completed without an audio URL",500);let r=await fetch(o);if(!r.ok)throw new D("Failed to download speech audio",502);return{audioData:Buffer.from(await r.arrayBuffer()),audioUrl:o,duration:0,cost:0,provider:t.options?.provider??"gemini",format:Vi(o)??"mp3",requestId:n.runId}}async function Ao(t){let n=j();if(!ie())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let e=await de(),o=rn(),r={...t,texts:t.texts.map(s=>({...s,text:Ro(s.text)}))},i;try{i=await fetch(`${n}/api/cli/tts/batch`,{method:"POST",headers:{"Content-Type":"application/json",[po]:o,...e},body:JSON.stringify(r)})}catch(s){throw new D(`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 u=JSON.parse(s);l=u.error||u.message||s}catch{l=s}throw new D(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(t){let n=t?`/api/cli/tts?provider=${t}`:"/api/cli/tts";return z(n)}async function vt(t){return{requestId:(await A("generateMusic",{...t,approvalReceipt:"cli:music-generate"})).runId,status:"pending"}}async function ot(t){let n=await F("generateMusic",t);return{requestId:t,status:bt(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Eo(t){return{requestId:(await A("mixAudio",{...t,approvalReceipt:"cli:mix-create"})).runId,status:"pending"}}async function sn(t){let n=await F("mixAudio",t);return{requestId:t,status:bt(n),outputUrl:n.entity?.url,error:n.error?.message}}async function wt(t){return z("/api/cli/images/search",{method:"POST",body:t})}async function Oo(t){return z("/api/cli/images/generate",{method:"POST",body:t})}async function cn(t){return z("/api/cli/videos/search",{method:"POST",body:t})}async function ue(t,n=60,e=2e3){for(let o=0;o<n;o++){let r=await t();if(r.status==="completed"||r.status==="failed")return r;await new Promise(i=>setTimeout(i,e))}throw new D("Operation timed out",408,1)}async function Po(t,n){let e=await A("scrape",{teamId:n,url:t});return{data:{content:e.content,cost:e.totalCost??0,metadata:{description:"",format:"markdown",tokenUsage:Math.ceil(e.content.length/4)},title:e.title??"",url:e.url},success:!0}}async function No(t){let n=await A("generateSfx",{...t,approvalReceipt:"cli:sfx-generate"});return{id:n.runId,requestId:n.runId,status:"pending"}}async function ln(t){let n=await F("generateSfx",t);return{id:n.entity?.id??t,requestId:t,status:bt(n),audioUrl:n.entity?.url,error:n.error?.message}}async function Do(t){return A("listPresenterOptions",{...t?{voiceLanguage:t}:{}})}async function Fo(t){return{requestId:(await A("generateAvatarVideo",{...t,approvalReceipt:"cli:avatar-generate"})).runId,status:"pending"}}async function dn(t){let n=await F("generateAvatarVideo",t);return{durationSec:typeof n.output?.durationSec=="number"?n.output.durationSec:null,error:n.error?.message,requestId:t,status:bt(n),videoUrl:n.entity?.url}}async function un(t){return A("generateVideoPlan",{...t,approvalReceipt:"cli:video-plan"})}async function Lo(t){return A("createVideo",{...t,approvalReceipt:"cli:video-create"})}async function Uo(t){return z("/api/cli/video/plan",{body:t,method:"POST"})}import P from"chalk";import mn from"cli-table3";function C(t,n="human"){n!=="quiet"&&n!=="json"&&console.log(P.green("\u2713"),t)}function c(t,n="human"){if(n!=="quiet"){if(n==="json"){console.error(JSON.stringify({error:t}));return}console.error(P.red("\u2717"),t)}}function L(t,n="human"){n!=="quiet"&&n!=="json"&&console.warn(P.yellow("\u26A0"),t)}function m(t,n="human"){n!=="quiet"&&n!=="json"&&console.log(P.blue("\u2139"),t)}function Pe(t,n="en"){return t?`${j()}/${n}/view/presentations/${t}`:"N/A"}function _o(t,n={}){let{showLinks:e=!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(e){let s=new mn({head:[P.cyan("Slug"),P.cyan("Title"),P.cyan("Slides"),P.cyan("Created"),P.cyan("URL")]});for(let l of t)s.push([r(l.slug||l.id.slice(0,8),30),r(l.title||"Untitled",22),String(l.numberOfSlides||"-"),i(l.createdAt),Pe(l.slug,o)]);return s.toString()}let a=new mn({head:[P.cyan("Slug"),P.cyan("Title"),P.cyan("Slides"),P.cyan("Mode"),P.cyan("Created")],colWidths:[32,28,8,11,18]});for(let s of t)a.push([s.slug||s.id.slice(0,8),s.title||"Untitled",String(s.numberOfSlides||"-"),s.mode||"-",i(s.createdAt)]);return a.toString()}function Mo(t){return t.map(n=>n.slug||n.id).join(`
4
- `)}function Vo(t){let n=[...t].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}),e=r=>{if(!r)return"-";try{return new URL(r).href}catch{return r.startsWith("http")?r:`https://${r}`}},o=new mn({head:[P.cyan("Name"),P.cyan("Source"),P.cyan("Color"),P.cyan("Logo"),P.cyan("Default"),P.cyan("ID")]});for(let r of n){let i=r.primaryColor?`${P.bgHex(r.primaryColor)(" ")} ${r.primaryColor}`:"-";o.push([r.name,e(r.sourceUrl),i,r.logoUrl?P.green("\u2713"):P.gray("\u2717"),r.isDefault?P.green("\u2605"):"",r.id])}return o.toString()}function pn(t){try{return new Date(t).toLocaleString()}catch{return t}}function me(t){console.log(),console.log(P.bold(t)),console.log(P.gray("\u2500".repeat(t.length)))}function T(t,n){console.log(` ${P.gray(t+":")} ${n??"-"}`)}function Gi(t){return JSON.stringify(t,null,2)}function x(t){console.log(Gi(t))}var jo=new Wi("capabilities").description("List callable capabilities and their parity state").option("-f, --format <format>","Output format: human, json, quiet","human").action(async t=>{try{let n=await go();if(t.format==="json"){x(n);return}for(let e of n.capabilities){if(t.format==="quiet"){console.log(e.name);continue}console.log(`${e.name} ${e.state} ${e.milestone}`)}}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}});import{mkdirSync as Yi,writeFileSync as Xi}from"fs";import{dirname as Wo,join as Ki}from"path";import{Command as ve}from"commander";import rt from"chalk";import{input as Qi,password as Zi,confirm as Ho,select as ea}from"@inquirer/prompts";import Ct from"ora";import Hi from"conf";var St=new Hi({projectName:"conceptcraft",configName:"feature-cache"}),Ji=3600*1e3,zi=1440*60*1e3;function qo(t){let n=0;for(let e=0;e<t.length;e++){let o=t.charCodeAt(e);n=(n<<5)-n+o,n=n&n}return n.toString(16)}function Bo(){if(!Oe())return null;let t=St.get("featureFlags");if(!t)return null;let n=qo(fe());if(t.apiKeyHash&&t.apiKeyHash!==n)return Te(),null;let e=Date.now()-t.fetchedAt;return e>zi?null:(e>Ji&&gn(),t.flags)}function gn(){Ie().catch(()=>{})}async function Ie(){let t=await Io(),n=fe();return St.set("featureFlags",{flags:t,fetchedAt:Date.now(),apiKeyHash:n?qo(n):void 0}),t}function Te(){St.delete("featureFlags")}function Go(){return St.path}var Jo=new ve("config").description("Manage CLI configuration").addCommand(new ve("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(rt.bold(`${p.displayName} CLI Configuration`)),console.log(rt.gray("\u2500".repeat(35))),console.log();try{let t=await Zi({message:"Enter your API key:",mask:"*",validate:o=>!o||o.trim().length===0?"API key is required":on(o.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(tn(t.trim()),await Ho({message:`Use a custom API URL? (default: ${p.apiUrl.replace("https://","")})`,default:!1})){let o=await Qi({message:"Enter API URL:",default:j(),validate:r=>{try{return new URL(r),!0}catch{return"Invalid URL format"}}});nn(o)}console.log();let e=Ct("Verifying API key...").start();try{let o=await he();if(e.succeed("API key verified!"),console.log(),m(`Logged in as: ${o.user.email}`),o.teams.length===0)L("No teams found for this user.");else if(o.teams.length===1){let r=o.teams[0];Ee(r.id),m(`Team: ${r.name} (${r.planName})`)}else{console.log(),m(`You have access to ${o.teams.length} teams.`);let r=await ea({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});Ee(r);let i=o.teams.find(a=>a.id===r);C(`Selected team: ${i?.name}`)}try{await Ie()}catch{}}catch(o){e.fail("Failed to verify API key"),L(`Could not verify API key: ${o instanceof Error?o.message:String(o)}`),L(`You may need to set the team ID manually: ${p.commands[0]} config set team-id <id>`)}console.log(),C("Configuration saved!"),m(`Config file: ${nt()}`),console.log()}catch(t){if(t.name==="ExitPromptError"){console.log(),m("Configuration cancelled.");return}throw t}})).addCommand(new ve("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async t=>{let n=ro();if(me("Current Configuration"),console.log(),T("API Key",uo()??rt.red("Not set")),T("API URL",n.apiUrl),T("Default Team ID",n.defaultTeamId??rt.gray("Not set")),console.log(),T("Config file",nt()),t.verify&&n.apiKey){console.log();let e=Ct("Verifying...").start();try{let o=await he();e.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){e.fail("Verification failed"),L(o instanceof Error?o.message:String(o))}}console.log()})).addCommand(new ve("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(t,n)=>{switch(t){case"api-key":on(n)||(c("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),tn(n),Te(),C("API key updated"),Ie().catch(()=>{});break;case"api-url":try{new URL(n),nn(n),C(`API URL set to: ${n}`)}catch{c("Invalid URL format"),process.exit(6)}break;case"team-id":Ee(n),C(`Default team ID set to: ${n}`);break;default:c(`Unknown config key: ${t}`),console.log(rt.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new ve("clear").description("Clear all configuration").action(async()=>{try{await Ho({message:"Are you sure you want to clear all configuration?",default:!1})?(mt(),Te(),C("Configuration cleared")):m("Cancelled")}catch{m("Cancelled")}})).addCommand(new ve("refresh").description("Refresh cached feature flags").action(async()=>{let t=Ct("Refreshing feature flags...").start();try{await Ie(),t.succeed("Feature flags refreshed"),m(`Run '${p.commands[0]} --help' to see updated commands`)}catch(n){t.fail("Failed to refresh"),c(n instanceof Error?n.message:String(n)),process.exit(1)}})).addCommand(new ve("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(t=>{t.cache?console.log(Go()):console.log(nt())})).addCommand(new ve("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let t=Ct("Pulling settings...").start();try{let n=await de(),e=await fetch(`${j()}/api/cli/settings`,{headers:n});if(!e.ok)throw new Error(`Request failed (HTTP ${e.status})`);let o=await e.text(),r=Ki(Wo(nt()),"settings.toml");Yi(Wo(r),{recursive:!0}),Xi(r,o,"utf8"),t.succeed("Settings pulled"),m(`Written to ${r}`)}catch(n){t.fail("Failed to pull settings"),c(n instanceof Error?n.message:String(n)),process.exit(1)}}));import{Command as ta}from"commander";import{confirm as na}from"@inquirer/prompts";var zo=new ta("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(t,n)=>{if(await E(),!n.force)try{if(!await na({message:`Are you sure you want to delete presentation "${t}"?`,default:!1})){n.quiet||L("Deletion cancelled");return}}catch{n.quiet||L("Deletion cancelled");return}try{await bo(t),n.quiet||C(`Presentation "${t}" deleted`)}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as Ne}from"commander";import Xo from"chalk";import oa from"ora";import{createParser as Vd}from"eventsource-parser";import qd from"chalk";import Gd from"ora";async function Yo(t,n={}){let e=t.body?.getReader();if(!e)throw new Error("Response body is not readable");let o=new TextDecoder,r="",i=!1;for(;!i;){let a=await e.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 ra(){return new Ne("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(t,n)=>{await E();let e=parseInt(n.words,10);(isNaN(e)||e<50||e>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=oa("Fetching presentation...").start();try{let i=await xe(t);r.text="Generating blog post...";let a=await To(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:e,tone:n.tone,targetAudience:n.audience??"General Audience",customInstructions:n.instructions??"",includeImages:!n.noImages,includeTableOfContents:n.toc??!1}),s=await Yo(a,{quiet:!0});r.succeed("Blog generated"),n.format==="json"?console.log(JSON.stringify({presentationId:t,title:i.title,wordCount:e,tone:n.tone,content:s},null,2)):n.format==="markdown"?console.log(s):(console.log(),console.log(Xo.bold(`Blog: ${i.title}`)),console.log(Xo.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 ia(){return new Ne("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(t,n)=>{await E(),m("Tweet generation coming soon.")})}function aa(){return new Ne("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)","human").action(async t=>{await E(),m("LinkedIn carousel generation coming soon.")})}function sa(){return new Ne("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(t,n)=>{await E(),m("Question generation coming soon.")})}function ca(){return new Ne("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(t,n)=>{await E(),m("Cheat sheet generation coming soon.")})}function Ko(){let t=new Ne("derive").description("Generate derivative content from a presentation"),n=Bo();return n&&(n.deckToBlog&&t.addCommand(ra()),n.deckToTweets&&t.addCommand(ia()),n.linkedInCarousel&&t.addCommand(aa()),n.redTeamQuestions&&t.addCommand(sa()),n.presenterCheatSheet&&t.addCommand(ca())),t}import{Command as la}from"commander";import{writeFile as da}from"fs/promises";import{resolve as Qo}from"path";import ua from"ora";var Zo=new la("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(t,n)=>{await E();let e=ua("Fetching presentation...").start();try{let o=await xe(t),r=o.title||t,i=o.id,a=t.replace(/[^a-z0-9-]/gi,"_").toLowerCase().substring(0,50),s=new Date().toISOString().split("T")[0],l=`${a}_${s}.zip`,u=n.output?Qo(n.output):Qo(process.cwd(),l);e.text=`Exporting "${r}"...`;let f=await xo(i,{includeImages:n.includeImages,includeBranding:n.includeBranding,includeExternal:!n.noExternal});e.text="Saving file...",await da(u,Buffer.from(f)),e.succeed("Export complete!"),console.log(),m(`File saved: ${u}`),m(`Size: ${ma(f.byteLength)}`),console.log()}catch(o){e.fail("Export failed"),c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});function ma(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}import{Command as pa}from"commander";import fn from"chalk";var er=new pa("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 t=>{await E(),m("Idea generation is available in the web dashboard."),console.log(),console.log(fn.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(fn.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(fn.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{Command as ga}from"commander";import{readFile as fa}from"fs/promises";import{resolve as ha,basename as ya}from"path";import ba from"ora";var tr=new ga("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");tr._hidden=!0;var nr=tr.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(t,n)=>{await E();try{(await he()).user.role!=="admin"&&(c("This command is only available to administrators"),process.exit(2))}catch{c("Failed to verify permissions"),process.exit(2)}let e=ha(t),o=ya(e);o.endsWith(".zip")||(c("File must be a ZIP archive"),process.exit(6));let r=ba("Reading file...").start();try{let i=await fa(e);n.dryRun?r.text="Validating...":r.text="Importing presentation...";let a=await vo(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(),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)L(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: ${e}`),process.exit(3)),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}});import{Command as xa}from"commander";var or=new xa("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 t=>{await E();let n=parseInt(t.limit,10);(isNaN(n)||n<1)&&(c("Invalid limit value"),process.exit(6));let e=t.teamId??ut();e||(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 yo(e,n);if(o.length===0){t.format==="json"?console.log(JSON.stringify([])):t.format!=="ids"&&m("No presentations found");return}switch(t.sort&&o.sort((r,i)=>{switch(t.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}}),t.format){case"json":console.log(JSON.stringify(o,null,2));break;case"ids":console.log(Mo(o));break;default:console.log(_o(o,{showLinks:t.detail,language:t.language}));break}}catch(o){c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});import{Command as va}from"commander";import rr from"chalk";import ir from"ora";import ar from"http";import{randomBytes as sr,createHash as wa}from"crypto";import Sa from"open";var Ca=`${p.displayName} CLI`,Ia=8765,Ta=8775;function ka(){return sr(32).toString("base64url")}function Ra(t){return wa("sha256").update(t).digest("base64url")}function Aa(){return sr(16).toString("hex")}async function $a(t,n){for(let e=t;e<=n;e++)try{return await new Promise((o,r)=>{let i=ar.createServer();i.listen(e,()=>{i.close(()=>o())}),i.on("error",r)}),e}catch{continue}throw new Error(`No available port found between ${t} and ${n}`)}async function Ea(t){let n=await fetch(`${t}/.well-known/oauth-authorization-server`);if(!n.ok)throw new Error(`Failed to fetch OAuth metadata: ${n.status}`);return n.json()}async function Oa(t,n){let e=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Ca,redirect_uris:[n],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:"presentations:read presentations:write"})});if(!e.ok){let o=await e.text();throw new Error(`Client registration failed: ${o}`)}return e.json()}async function Pa(t,n,e,o,r){let i=new URLSearchParams({grant_type:"authorization_code",code:n,redirect_uri:o,client_id:r,code_verifier:e}),a=await fetch(t,{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 Na(t,n){return new Promise((e,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=ar.createServer((u,f)=>{let v=new URL(u.url||"",`http://localhost:${t}`);if(v.pathname!=="/callback"){f.writeHead(404),f.end("Not found");return}let I=v.searchParams.get("code"),g=v.searchParams.get("state"),S=v.searchParams.get("error"),y=v.searchParams.get("error_description");if(f.writeHead(200,{"Content-Type":"text/html"}),S){f.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 ce from"chalk";import{Command as wl}from"commander";import{Command as Ji}from"commander";import{randomUUID as rn}from"crypto";import{readFileSync as Li,statSync as Ui}from"fs";import{basename as uo}from"path";import yt from"chalk";import Pi from"conf";function to(t={}){let n=(s,l)=>{let u=t[s];return u&&u.trim().length>0?u.trim():l},e=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=e.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:r,name:i.replace(/^\./,""),displayName:e,description:`CLI tool for ${e} presentation generation`,commands:[o,r],apiUrl:n("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:n("NEXT_PUBLIC_DOCS_URL",`https://docs.${e.toLowerCase()}.ai`),packageName:n("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${a}_API_KEY`,apiUrlEnvVar:`${a}_API_URL`,codexSelfConnectorAppId:t.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var p=typeof h<"u"&&h?h:to(process.env);var no=p.apiUrl,Ni={apiKey:{type:"string"},apiUrl:{type:"string",default:no},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}},O=new Pi({projectName:p.name,schema:Ni});function oo(){return{apiKey:fe(),apiUrl:j(),defaultTeamId:O.get("defaultTeamId"),accessToken:O.get("accessToken"),refreshToken:O.get("refreshToken"),tokenExpiresAt:O.get("tokenExpiresAt"),clientId:O.get("clientId"),clientSecret:O.get("clientSecret")}}function fe(){let t=process.env[p.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return t||O.get("apiKey")}function tn(t){O.set("apiKey",t)}function j(){let t=process.env[p.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return t||(O.get("apiUrl")??no)}function nn(t){O.set("apiUrl",t)}function ut(){return O.get("defaultTeamId")}function Ee(t){O.set("defaultTeamId",t)}function mt(){O.clear()}function nt(){return O.path}function Oe(){return!!fe()}function ro(){return O.get("accessToken")}function io(){return O.get("refreshToken")}function pt(t,n,e){O.set("accessToken",t),O.set("refreshToken",n),O.set("tokenExpiresAt",Date.now()+(e-60)*1e3)}function gt(){O.delete("accessToken"),O.delete("refreshToken"),O.delete("tokenExpiresAt")}function ao(){let t=O.get("tokenExpiresAt");return t?Date.now()>=t:!0}function Ce(){return!!O.get("accessToken")&&!!O.get("refreshToken")}function ft(){return O.get("clientId")}function ht(){return O.get("clientSecret")}function so(t,n){O.set("clientId",t),O.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 Di(){let t=io(),n=ft(),e=j();if(!t||!n)return null;try{let o=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!o.ok)return null;let r=await o.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:n}),a=ht();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 gt(),null;let l=await s.json();return pt(l.access_token,l.refresh_token,l.expires_in),l.access_token}catch{return null}}async function co(){return Ce()?ao()?Di():ro()||null:null}function ie(){return Ce()||Oe()}async function E(){if(!ie()){let t=p.commands[0],n=p.apiKeyEnvVar;console.error(yt.red("\u2717 Not authenticated.")),console.error(),console.error(yt.bold("To authenticate, run:")),console.error(yt.cyan(` ${t} login`)),console.error(),console.error(yt.gray(`Or set ${n} environment variable.`)),process.exit(d.AUTH_ERROR)}}function Fi(t){return t.length<=14?"****":`${t.slice(0,10)}...${t.slice(-4)}`}function lo(){let t=fe();if(t)return Fi(t)}function on(t){return["cc_slides_","mcp_","cc_sk_","sk_"].some(e=>t.startsWith(e))}async function de(){let t=await co();if(t)return{Authorization:`Bearer ${t}`};let n=fe();return n?{"x-api-key":n}:{}}var L=class extends Error{constructor(e,o,r=1,i="operation_failed",a=!1){super(e);this.statusCode=o;this.exitCode=r;this.errorCode=i;this.retryable=a;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},mo="Idempotency-Key";function _i(t){return t&&t!=="GET"?{[mo]:rn()}:{}}async function z(t,n={}){let e=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let o=await de(),r=`${e}${t}`,i={...o,..._i(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 L(`Network error: ${u instanceof Error?u.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!s.ok){let u=await s.text().catch(()=>""),f=Vi(u,s.status),v=1;switch(s.status){case 401:v=2;break;case 403:v=2;break;case 404:v=3;break;case 429:v=4;break;case 500:v=1;break}let I=`[${f.code}] ${f.message}`;throw new L(I,s.status,v,f.code,f.retryable)}return n.stream?s:s.headers.get("content-type")?.includes("application/json")?s.json():s.text()}function Mi(t){switch(t){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 Vi(t,n){let e=Mi(n),o=t.trim()||`HTTP ${n}: The request could not be completed.`;try{let r=JSON.parse(t),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:e,message:typeof r.message=="string"?r.message:r.error,retryable:n===429||n>=500}}catch{}return{code:e,message:o,retryable:n===429||n>=500}}async function po(){return z("/api/cli/capabilities")}async function U(t,n,e){let o=e?`?teamId=${encodeURIComponent(e)}`:"";return z(`/api/cli/tool-runs/${encodeURIComponent(t)}/${encodeURIComponent(n)}${o}`)}async function A(t,n){return z(`/api/cli/tools/${encodeURIComponent(t)}`,{body:n,method:"POST"})}async function ji(t,n,e=120){for(let o=0;o<e;o++){let r=await U(t,n);if(r.done){if(r.error)throw new L(`[${r.error.code??"operation_failed"}] ${r.error.message}`,500,1,r.error.code??"operation_failed",r.error.retryable);return r}await new Promise(i=>setTimeout(i,(r.nextPollAfterSeconds??2)*1e3))}throw new L("[operation_timed_out] The background operation timed out.",408,1,"operation_timed_out",!0)}function bt(t){return t.error||t.status==="failed"||t.status==="errored"||t.status==="cancelled"?"failed":t.done||t.status==="completed"?"completed":t.status==="in_progress"?"processing":"pending"}function qi(t){try{let e=new URL(t).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return e&&/^[a-z0-9]+$/.test(e)?e:void 0}catch{return}}function Bi(t){let n=t.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 Gi(t){let n=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let e=await de(),o=Ui(t),r=uo(t),i=Bi(t),a=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...e},body:JSON.stringify({fileMetadata:{name:r,type:i,size:o.size}})});if(!a.ok){let I=await a.text();throw new L(I||"Failed to get upload URL",a.status,1)}let s=await a.json(),l=Li(t),u=new FormData;for(let[I,g]of Object.entries(s.fields||{}))u.append(I,g);let f=new Blob([l],{type:i});u.append("file",f,r);let v=await fetch(s.url,{method:"POST",body:u});if(!v.ok)throw new L("Failed to upload file to storage",v.status,1);return{id:rn(),name:r,url:s.fileUrl,size:o.size,type:i,selected:!0}}async function go(t,n){let e=[];for(let o=0;o<t.length;o++){let r=t[o],i=uo(r);n?.(o,t.length,i);let a=await Gi(r);e.push(a)}return n?.(t.length,t.length,""),e}async function fo(t){let n={};for(let[o,r]of Object.entries(t))r!==void 0&&(n[o]=r);let e=n.designBrandReference??n.brandId??n.brandingId;return e!==void 0&&(n.designBrandReference=e,delete n.brandId,delete n.brandingId),A("createSlides",{...n,approvalReceipt:"cli:create"})}async function ho(t,n=20){let e=new URLSearchParams;return e.set("limit",String(n)),t&&e.set("teamId",t),(await z(`/api/cli/presentations?${e}`)).presentations}async function xe(t){return z(`/api/cli/presentation/${t}`)}async function yo(t){await z(`/api/cli/presentation/${t}`,{method:"DELETE"})}async function bo(t,n={}){let e=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let o=await de(),r=await fetch(`${e}/api/presentations/export`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({presentationId:t,options:{includeImages:n.includeImages??!0,includeBranding:n.includeBranding??!0,downloadExternalImages:n.includeExternal??!0}})});if(!r.ok)throw new L(await r.text(),r.status,r.status===404?3:1);return r.arrayBuffer()}async function xo(t,n,e={}){let o=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let r=await de(),i=new FormData,a=new Blob([t],{type:"application/zip"});i.append("file",a,n),i.append("options",JSON.stringify({dryRun:e.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 L(l.errors?.[0]?.message??"Import failed",s.status,1);return l}async function an(){return z("/api/cli/branding")}async function vo(t,n=25){let e=new URLSearchParams;return e.set("limit",String(n)),t&&e.set("search",t),z(`/api/cli/templates?${e}`)}async function wo(t){return z(`/api/branding/${t}`)}async function So(t,n,e){return A("extractBranding",{approvalReceipt:e,teamId:n,url:t})}async function he(){return z("/api/cli/whoami")}async function Co(){return z("/api/cli/features")}async function Io(t,n,e={}){let o=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let r=await de(),i=await fetch(`${o}/api/presentations/${t}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({documentCreatedAt:n,targetWordCount:e.targetWordCount??300,tone:e.tone??"professional",language:e.language??"en",targetAudience:e.targetAudience??"General Audience",blogFormat:e.blogFormat??"narrative",customInstructions:e.customInstructions??"",includeImages:e.includeImages??!0,includeTableOfContents:e.includeTableOfContents??!1})});if(!i.ok)throw new L(await i.text(),i.status,i.status===404?3:1);return i}async function Wi(t){let n=new URLSearchParams;t&&n.set("teamId",t);let e=n.toString();return z(`/api/cli/limits${e?`?${e}`:""}`)}async function To(t,n,e){let o=await Wi(e);if(!o.canGenerate[t]){let r=o.remaining[t]??0,i=o.limits[t]??0;throw i===0?new L(`The "${t}" mode is not available on your ${o.planName} plan. Available modes: ${o.availableModes.join(", ")||"none"}`,403,2):new L(`You have reached your ${t} generation limit for this billing cycle (${o.usage[t]??0}/${i} used). Try a different mode: ${o.availableModes.join(", ")||"none available"}`,403,4)}if(o.maxSlidesPerPresentation!==-1&&n>o.maxSlidesPerPresentation)throw new L(`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 ko(t){return t.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 xt(t){let n=await A("generateSpeech",{approvalReceipt:"cli:tts-generate",...t,text:ko(t.text)}),o=(await ji("generateSpeech",n.runId)).entity?.url;if(!o)throw new L("Speech completed without an audio URL",500);let r=await fetch(o);if(!r.ok)throw new L("Failed to download speech audio",502);return{audioData:Buffer.from(await r.arrayBuffer()),audioUrl:o,duration:0,cost:0,provider:t.options?.provider??"gemini",format:qi(o)??"mp3",requestId:n.runId}}async function Ro(t){let n=j();if(!ie())throw new L(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let e=await de(),o=rn(),r={...t,texts:t.texts.map(s=>({...s,text:ko(s.text)}))},i;try{i=await fetch(`${n}/api/cli/tts/batch`,{method:"POST",headers:{"Content-Type":"application/json",[mo]:o,...e},body:JSON.stringify(r)})}catch(s){throw new L(`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 u=JSON.parse(s);l=u.error||u.message||s}catch{l=s}throw new L(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 Ao(t){let n=t?`/api/cli/tts?provider=${t}`:"/api/cli/tts";return z(n)}async function vt(t){return{requestId:(await A("generateMusic",{...t,approvalReceipt:"cli:music-generate"})).runId,status:"pending"}}async function ot(t){let n=await U("generateMusic",t);return{requestId:t,status:bt(n),audioUrl:n.entity?.url,error:n.error?.message}}async function $o(t){return{requestId:(await A("mixAudio",{...t,approvalReceipt:"cli:mix-create"})).runId,status:"pending"}}async function sn(t){let n=await U("mixAudio",t);return{requestId:t,status:bt(n),outputUrl:n.entity?.url,error:n.error?.message}}async function wt(t){return z("/api/cli/images/search",{method:"POST",body:t})}async function Eo(t){return z("/api/cli/images/generate",{method:"POST",body:t})}async function cn(t){return z("/api/cli/videos/search",{method:"POST",body:t})}async function ue(t,n=60,e=2e3){for(let o=0;o<n;o++){let r=await t();if(r.status==="completed"||r.status==="failed")return r;await new Promise(i=>setTimeout(i,e))}throw new L("Operation timed out",408,1)}async function Oo(t,n){let e=await A("scrape",{teamId:n,url:t});return{data:{content:e.content,cost:e.totalCost??0,metadata:{description:"",format:"markdown",tokenUsage:Math.ceil(e.content.length/4)},title:e.title??"",url:e.url},success:!0}}async function Po(t){let n=await A("generateSfx",{...t,approvalReceipt:"cli:sfx-generate"});return{id:n.runId,requestId:n.runId,status:"pending"}}async function ln(t){let n=await U("generateSfx",t);return{id:n.entity?.id??t,requestId:t,status:bt(n),audioUrl:n.entity?.url,error:n.error?.message}}async function No(t){return A("listPresenterOptions",{...t?{voiceLanguage:t}:{}})}async function Do(t){return{requestId:(await A("generateAvatarVideo",{...t,approvalReceipt:"cli:avatar-generate"})).runId,status:"pending"}}async function dn(t){let n=await U("generateAvatarVideo",t);return{durationSec:typeof n.output?.durationSec=="number"?n.output.durationSec:null,error:n.error?.message,requestId:t,status:bt(n),videoUrl:n.entity?.url}}async function un(t){return A("generateVideoPlan",{...t,approvalReceipt:"cli:video-plan"})}async function Fo(t){return A("createVideo",{...t,approvalReceipt:"cli:video-create"})}async function Lo(t){return z("/api/cli/video/plan",{body:t,method:"POST"})}import F from"chalk";import mn from"cli-table3";function C(t,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.green("\u2713"),t)}function c(t,n="human"){if(n!=="quiet"){if(n==="json"){console.error(JSON.stringify({error:t}));return}console.error(F.red("\u2717"),t)}}function _(t,n="human"){n!=="quiet"&&n!=="json"&&console.warn(F.yellow("\u26A0"),t)}function m(t,n="human"){n!=="quiet"&&n!=="json"&&console.log(F.blue("\u2139"),t)}function Pe(t,n="en"){return t?`${j()}/${n}/view/presentations/${t}`:"N/A"}function Uo(t,n={}){let{showLinks:e=!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(e){let s=new mn({head:[F.cyan("Slug"),F.cyan("Title"),F.cyan("Slides"),F.cyan("Created"),F.cyan("URL")]});for(let l of t)s.push([r(l.slug||l.id.slice(0,8),30),r(l.title||"Untitled",22),String(l.numberOfSlides||"-"),i(l.createdAt),Pe(l.slug,o)]);return s.toString()}let a=new mn({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 t)a.push([s.slug||s.id.slice(0,8),s.title||"Untitled",String(s.numberOfSlides||"-"),s.mode||"-",i(s.createdAt)]);return a.toString()}function _o(t){return t.map(n=>n.slug||n.id).join(`
4
+ `)}function Mo(t){let n=[...t].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}),e=r=>{if(!r)return"-";try{return new URL(r).href}catch{return r.startsWith("http")?r:`https://${r}`}},o=new mn({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,e(r.sourceUrl),i,r.logoUrl?F.green("\u2713"):F.gray("\u2717"),r.isDefault?F.green("\u2605"):"",r.id])}return o.toString()}function pn(t){try{return new Date(t).toLocaleString()}catch{return t}}function me(t){console.log(),console.log(F.bold(t)),console.log(F.gray("\u2500".repeat(t.length)))}function k(t,n){console.log(` ${F.gray(t+":")} ${n??"-"}`)}function Hi(t){return JSON.stringify(t,null,2)}function x(t){console.log(Hi(t))}var Vo=new Ji("capabilities").description("List callable capabilities and their parity state").option("-f, --format <format>","Output format: human, json, quiet","human").action(async t=>{try{let n=await po();if(t.format==="json"){x(n);return}for(let e of n.capabilities){if(t.format==="quiet"){console.log(e.name);continue}console.log(`${e.name} ${e.state} ${e.milestone}`)}}catch(n){c(n instanceof Error?n.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}});import{mkdirSync as Ki,writeFileSync as Qi}from"fs";import{dirname as Go,join as Zi}from"path";import{Command as ve}from"commander";import rt from"chalk";import{input as ea,password as ta,confirm as Wo,select as na}from"@inquirer/prompts";import Ct from"ora";import zi from"conf";var St=new zi({projectName:"conceptcraft",configName:"feature-cache"}),Xi=3600*1e3,Yi=1440*60*1e3;function jo(t){let n=0;for(let e=0;e<t.length;e++){let o=t.charCodeAt(e);n=(n<<5)-n+o,n=n&n}return n.toString(16)}function qo(){if(!Oe())return null;let t=St.get("featureFlags");if(!t)return null;let n=jo(fe());if(t.apiKeyHash&&t.apiKeyHash!==n)return Te(),null;let e=Date.now()-t.fetchedAt;return e>Yi?null:(e>Xi&&gn(),t.flags)}function gn(){Ie().catch(()=>{})}async function Ie(){let t=await Co(),n=fe();return St.set("featureFlags",{flags:t,fetchedAt:Date.now(),apiKeyHash:n?jo(n):void 0}),t}function Te(){St.delete("featureFlags")}function Bo(){return St.path}var Ho=new ve("config").description("Manage CLI configuration").addCommand(new ve("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(rt.bold(`${p.displayName} CLI Configuration`)),console.log(rt.gray("\u2500".repeat(35))),console.log();try{let t=await ta({message:"Enter your API key:",mask:"*",validate:o=>!o||o.trim().length===0?"API key is required":on(o.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(tn(t.trim()),await Wo({message:`Use a custom API URL? (default: ${p.apiUrl.replace("https://","")})`,default:!1})){let o=await ea({message:"Enter API URL:",default:j(),validate:r=>{try{return new URL(r),!0}catch{return"Invalid URL format"}}});nn(o)}console.log();let e=Ct("Verifying API key...").start();try{let o=await he();if(e.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];Ee(r.id),m(`Team: ${r.name} (${r.planName})`)}else{console.log(),m(`You have access to ${o.teams.length} teams.`);let r=await na({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});Ee(r);let i=o.teams.find(a=>a.id===r);C(`Selected team: ${i?.name}`)}try{await Ie()}catch{}}catch(o){e.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: ${p.commands[0]} config set team-id <id>`)}console.log(),C("Configuration saved!"),m(`Config file: ${nt()}`),console.log()}catch(t){if(t.name==="ExitPromptError"){console.log(),m("Configuration cancelled.");return}throw t}})).addCommand(new ve("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async t=>{let n=oo();if(me("Current Configuration"),console.log(),k("API Key",lo()??rt.red("Not set")),k("API URL",n.apiUrl),k("Default Team ID",n.defaultTeamId??rt.gray("Not set")),console.log(),k("Config file",nt()),t.verify&&n.apiKey){console.log();let e=Ct("Verifying...").start();try{let o=await he();e.succeed("Verified"),console.log(),k("User",o.user.email),o.currentTeam&&k("Current Team",`${o.currentTeam.name} (${o.currentTeam.planName})`),o.teams.length>1&&k("Total Teams",String(o.teams.length))}catch(o){e.fail("Verification failed"),_(o instanceof Error?o.message:String(o))}}console.log()})).addCommand(new ve("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(t,n)=>{switch(t){case"api-key":on(n)||(c("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),tn(n),Te(),C("API key updated"),Ie().catch(()=>{});break;case"api-url":try{new URL(n),nn(n),C(`API URL set to: ${n}`)}catch{c("Invalid URL format"),process.exit(6)}break;case"team-id":Ee(n),C(`Default team ID set to: ${n}`);break;default:c(`Unknown config key: ${t}`),console.log(rt.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new ve("clear").description("Clear all configuration").action(async()=>{try{await Wo({message:"Are you sure you want to clear all configuration?",default:!1})?(mt(),Te(),C("Configuration cleared")):m("Cancelled")}catch{m("Cancelled")}})).addCommand(new ve("refresh").description("Refresh cached feature flags").action(async()=>{let t=Ct("Refreshing feature flags...").start();try{await Ie(),t.succeed("Feature flags refreshed"),m(`Run '${p.commands[0]} --help' to see updated commands`)}catch(n){t.fail("Failed to refresh"),c(n instanceof Error?n.message:String(n)),process.exit(1)}})).addCommand(new ve("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(t=>{t.cache?console.log(Bo()):console.log(nt())})).addCommand(new ve("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let t=Ct("Pulling settings...").start();try{let n=await de(),e=await fetch(`${j()}/api/cli/settings`,{headers:n});if(!e.ok)throw new Error(`Request failed (HTTP ${e.status})`);let o=await e.text(),r=Zi(Go(nt()),"settings.toml");Ki(Go(r),{recursive:!0}),Qi(r,o,"utf8"),t.succeed("Settings pulled"),m(`Written to ${r}`)}catch(n){t.fail("Failed to pull settings"),c(n instanceof Error?n.message:String(n)),process.exit(1)}}));import{Command as oa}from"commander";import{confirm as ra}from"@inquirer/prompts";var Jo=new oa("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(t,n)=>{if(await E(),!n.force)try{if(!await ra({message:`Are you sure you want to delete presentation "${t}"?`,default:!1})){n.quiet||_("Deletion cancelled");return}}catch{n.quiet||_("Deletion cancelled");return}try{await yo(t),n.quiet||C(`Presentation "${t}" deleted`)}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as Ne}from"commander";import Xo from"chalk";import ia from"ora";import{createParser as qd}from"eventsource-parser";import Gd from"chalk";import Hd from"ora";async function zo(t,n={}){let e=t.body?.getReader();if(!e)throw new Error("Response body is not readable");let o=new TextDecoder,r="",i=!1;for(;!i;){let a=await e.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 aa(){return new Ne("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(t,n)=>{await E();let e=parseInt(n.words,10);(isNaN(e)||e<50||e>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=ia("Fetching presentation...").start();try{let i=await xe(t);r.text="Generating blog post...";let a=await Io(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:e,tone:n.tone,targetAudience:n.audience??"General Audience",customInstructions:n.instructions??"",includeImages:!n.noImages,includeTableOfContents:n.toc??!1}),s=await zo(a,{quiet:!0});r.succeed("Blog generated"),n.format==="json"?console.log(JSON.stringify({presentationId:t,title:i.title,wordCount:e,tone:n.tone,content:s},null,2)):n.format==="markdown"?console.log(s):(console.log(),console.log(Xo.bold(`Blog: ${i.title}`)),console.log(Xo.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 sa(){return new Ne("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(t,n)=>{await E(),m("Tweet generation coming soon.")})}function ca(){return new Ne("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)","human").action(async t=>{await E(),m("LinkedIn carousel generation coming soon.")})}function la(){return new Ne("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(t,n)=>{await E(),m("Question generation coming soon.")})}function da(){return new Ne("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(t,n)=>{await E(),m("Cheat sheet generation coming soon.")})}function Yo(){let t=new Ne("derive").description("Generate derivative content from a presentation"),n=qo();return n&&(n.deckToBlog&&t.addCommand(aa()),n.deckToTweets&&t.addCommand(sa()),n.linkedInCarousel&&t.addCommand(ca()),n.redTeamQuestions&&t.addCommand(la()),n.presenterCheatSheet&&t.addCommand(da())),t}import{Command as ua}from"commander";import{writeFile as ma}from"fs/promises";import{resolve as Ko}from"path";import pa from"ora";var Qo=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(t,n)=>{await E();let e=pa("Fetching presentation...").start();try{let o=await xe(t),r=o.title||t,i=o.id,a=t.replace(/[^a-z0-9-]/gi,"_").toLowerCase().substring(0,50),s=new Date().toISOString().split("T")[0],l=`${a}_${s}.zip`,u=n.output?Ko(n.output):Ko(process.cwd(),l);e.text=`Exporting "${r}"...`;let f=await bo(i,{includeImages:n.includeImages,includeBranding:n.includeBranding,includeExternal:!n.noExternal});e.text="Saving file...",await ma(u,Buffer.from(f)),e.succeed("Export complete!"),console.log(),m(`File saved: ${u}`),m(`Size: ${ga(f.byteLength)}`),console.log()}catch(o){e.fail("Export failed"),c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});function ga(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}import{Command as fa}from"commander";import fn from"chalk";var Zo=new fa("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 t=>{await E(),m("Idea generation is available in the web dashboard."),console.log(),console.log(fn.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(fn.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(fn.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{Command as ha}from"commander";import{readFile as ya}from"fs/promises";import{resolve as ba,basename as xa}from"path";import va from"ora";var er=new ha("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");er._hidden=!0;var tr=er.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(t,n)=>{await E();try{(await he()).user.role!=="admin"&&(c("This command is only available to administrators"),process.exit(2))}catch{c("Failed to verify permissions"),process.exit(2)}let e=ba(t),o=xa(e);o.endsWith(".zip")||(c("File must be a ZIP archive"),process.exit(6));let r=va("Reading file...").start();try{let i=await ya(e);n.dryRun?r.text="Validating...":r.text="Importing presentation...";let a=await xo(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(),k("Slides",String(a.statistics.slidesImported)),k("Images",String(a.statistics.imagesUploaded)));else if(r.succeed("Import complete!"),console.log(),k("Presentation ID",a.presentationId??"N/A"),k("Document ID",a.documentId??"N/A"),a.statistics&&(k("Slides imported",String(a.statistics.slidesImported)),k("Images uploaded",String(a.statistics.imagesUploaded)),k("Time",`${a.statistics.totalTimeMs}ms`)),a.presentationId){let s=j();k("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: ${e}`),process.exit(3)),c(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}});import{Command as wa}from"commander";var nr=new wa("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 t=>{await E();let n=parseInt(t.limit,10);(isNaN(n)||n<1)&&(c("Invalid limit value"),process.exit(6));let e=t.teamId??ut();e||(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 ho(e,n);if(o.length===0){t.format==="json"?console.log(JSON.stringify([])):t.format!=="ids"&&m("No presentations found");return}switch(t.sort&&o.sort((r,i)=>{switch(t.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}}),t.format){case"json":console.log(JSON.stringify(o,null,2));break;case"ids":console.log(_o(o));break;default:console.log(Uo(o,{showLinks:t.detail,language:t.language}));break}}catch(o){c(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});import{Command as Sa}from"commander";import or from"chalk";import rr from"ora";import ir from"http";import{randomBytes as ar,createHash as Ca}from"crypto";import Ia from"open";var Ta=`${p.displayName} CLI`,ka=8765,Ra=8775;function Aa(){return ar(32).toString("base64url")}function $a(t){return Ca("sha256").update(t).digest("base64url")}function Ea(){return ar(16).toString("hex")}async function Oa(t,n){for(let e=t;e<=n;e++)try{return await new Promise((o,r)=>{let i=ir.createServer();i.listen(e,()=>{i.close(()=>o())}),i.on("error",r)}),e}catch{continue}throw new Error(`No available port found between ${t} and ${n}`)}async function Pa(t){let n=await fetch(`${t}/.well-known/oauth-authorization-server`);if(!n.ok)throw new Error(`Failed to fetch OAuth metadata: ${n.status}`);return n.json()}async function Na(t,n){let e=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Ta,redirect_uris:[n],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:"presentations:read presentations:write"})});if(!e.ok){let o=await e.text();throw new Error(`Client registration failed: ${o}`)}return e.json()}async function Da(t,n,e,o,r){let i=new URLSearchParams({grant_type:"authorization_code",code:n,redirect_uri:o,client_id:r,code_verifier:e}),a=await fetch(t,{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 Fa(t,n){return new Promise((e,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=ir.createServer((u,f)=>{let v=new URL(u.url||"",`http://localhost:${t}`);if(v.pathname!=="/callback"){f.writeHead(404),f.end("Not found");return}let I=v.searchParams.get("code"),g=v.searchParams.get("state"),T=v.searchParams.get("error"),y=v.searchParams.get("error_description");if(f.writeHead(200,{"Content-Type":"text/html"}),T){f.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>${y||S}</p>
10
+ <p>${y||T}</p>
11
11
  <p>You can close this window.</p>
12
12
  </body>
13
13
  </html>
14
- `),a(),o(new Error(y||S));return}if(!I||!g){f.end(`
14
+ `),a(),o(new Error(y||T));return}if(!I||!g){f.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(),e({code:I,state:g})});l.listen(t),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 Da(t,n){let e=await fetch(`${t}/api/cli/whoami`,{headers:{Authorization:`Bearer ${n}`}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.status}`);return e.json()}async function Fa(t){let n=j(),e=ir("Discovering OAuth server...").start();try{let o=await Ea(n);e.succeed("Connecting to "+n);let r=await $a(Ia,Ta),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=ft(),s=ht();if(!a){let R=await Oa(o.registration_endpoint,i);a=R.client_id,s=R.client_secret,co(a,s)}let l=ka(),u=Ra(l),f=Aa(),v=new URLSearchParams({client_id:a,redirect_uri:i,response_type:"code",scope:"presentations:read presentations:write",state:f,code_challenge:u,code_challenge_method:"S256"}),I=`${o.authorization_endpoint}?${v}`;console.log("Authorization URL: "+I),t.browser?(m("Opening browser..."),await Sa(I)):(console.log(rr.bold("Open this URL in your browser:")),console.log(rr.cyan(I)));let g=Na(r,f),{code:S}=await g;e=ir("Completing login...").start();let y=await Pa(o.token_endpoint,S,l,i,a);pt(y.access_token,y.refresh_token,y.expires_in);let b=await Da(n,y.access_token);e.succeed("Logged in!"),console.log(),T("Logged in as",b.user.email),b.currentTeam&&(Ee(b.currentTeam.id),T("Team",`${b.currentTeam.name} (${b.currentTeam.planName})`));try{await Ie()}catch{}console.log(),C("You're all set!"),console.log()}catch(o){throw e.fail("Login failed"),c(o instanceof Error?o.message:String(o)),o}}var cr=new va("login").description(`Authenticate with ${p.displayName} (opens browser)`).option("--no-browser","Print URL instead of opening browser").action(async t=>{console.log(),Ce()&&(L("You are already logged in."),m(`Run '${p.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await Fa(t),process.exit(0)}catch{process.exit(1)}});import{Command as La}from"commander";import{confirm as Ua}from"@inquirer/prompts";var lr=new La("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async t=>{console.log();let n=Ce(),e=Oe();if(!n&&!e){L("You are not logged in."),console.log();return}if(t.all)try{await Ua({message:"Clear all configuration including API key?",default:!1})?(mt(),Te(),C("All configuration cleared.")):m("Cancelled.")}catch{m("Cancelled.")}else gt(),Te(),C("Logged out successfully."),e&&m("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as Ts}from"os";import{join as ks}from"path";import se from"chalk";import{Command as Rs}from"commander";import{spawn as _a}from"child_process";import{existsSync as Ma,readdirSync as Va}from"fs";import{homedir as ur}from"os";import{delimiter as dr}from"path";import{query as ja}from"@anthropic-ai/claude-agent-sdk";function oe(t){if(t===void 0)return null;if(typeof t=="string")return t.length>12e3?`${t.slice(0,12e3)}\u2026`:t;try{let n=JSON.stringify(t);return n.length<=12e3?t:{preview:`${n.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(t).slice(0,12e3)}}function It(t){let n=typeof t=="string"?t:String(t??"");return n.length>12e3?`${n.slice(0,12e3)}\u2026`:n}function ae(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function N(t){return typeof t=="string"?t:""}function qa(t,n){let e=t.replace(/[/.]/g,"-");return`${ur()}/.claude/projects/${e}/${n}.jsonl`}function Ba(t){try{return Va(`${t}/.nvm/versions/node`).map(n=>`${t}/.nvm/versions/node/${n}/bin`).sort().reverse()}catch{return[]}}function Tt(){let t=ur(),n=[`${t}/.local/bin`,`${t}/.claude/local`,`${t}/.bun/bin`,`${t}/bin`,"/opt/homebrew/bin","/usr/local/bin",...Ba(t)],o=(process.env.PATH??"").split(dr);for(let r of n)o.includes(r)||o.push(r);return o.join(dr)}async function kt(t){let n=t??"claude";return new Promise(e=>{let o=_a(n,["--version"],{env:{...process.env,PATH:Tt()},stdio:["ignore","pipe","ignore"]}),r="";o.stdout.on("data",i=>{r+=i.toString("utf8")}),o.on("error",()=>e(null)),o.on("close",i=>{if(i!==0)return e(null);let a=r.trim().split(`
44
- `)[0]??"";e(a?{bin:n,version:a}:null)})})}var Ga=new Set(["","default","best"]);function hn(t){let n=t.filter(i=>i.text.trim());if(n.length===0)return"";let e=n[n.length-1],o=n.slice(0,-1);return o.length===0?e.text:`<conversation-history>
43
+ `),a(),e({code:I,state:g})});l.listen(t),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 La(t,n){let e=await fetch(`${t}/api/cli/whoami`,{headers:{Authorization:`Bearer ${n}`}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.status}`);return e.json()}async function Ua(t){let n=j(),e=rr("Discovering OAuth server...").start();try{let o=await Pa(n);e.succeed("Connecting to "+n);let r=await Oa(ka,Ra),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=ft(),s=ht();if(!a){let S=await Na(o.registration_endpoint,i);a=S.client_id,s=S.client_secret,so(a,s)}let l=Aa(),u=$a(l),f=Ea(),v=new URLSearchParams({client_id:a,redirect_uri:i,response_type:"code",scope:"presentations:read presentations:write",state:f,code_challenge:u,code_challenge_method:"S256"}),I=`${o.authorization_endpoint}?${v}`;console.log("Authorization URL: "+I),t.browser?(m("Opening browser..."),await Ia(I)):(console.log(or.bold("Open this URL in your browser:")),console.log(or.cyan(I)));let g=Fa(r,f),{code:T}=await g;e=rr("Completing login...").start();let y=await Da(o.token_endpoint,T,l,i,a);pt(y.access_token,y.refresh_token,y.expires_in);let b=await La(n,y.access_token);e.succeed("Logged in!"),console.log(),k("Logged in as",b.user.email),b.currentTeam&&(Ee(b.currentTeam.id),k("Team",`${b.currentTeam.name} (${b.currentTeam.planName})`));try{await Ie()}catch{}console.log(),C("You're all set!"),console.log()}catch(o){throw e.fail("Login failed"),c(o instanceof Error?o.message:String(o)),o}}var sr=new Sa("login").description(`Authenticate with ${p.displayName} (opens browser)`).option("--no-browser","Print URL instead of opening browser").action(async t=>{console.log(),Ce()&&(_("You are already logged in."),m(`Run '${p.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await Ua(t),process.exit(0)}catch{process.exit(1)}});import{Command as _a}from"commander";import{confirm as Ma}from"@inquirer/prompts";var cr=new _a("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async t=>{console.log();let n=Ce(),e=Oe();if(!n&&!e){_("You are not logged in."),console.log();return}if(t.all)try{await Ma({message:"Clear all configuration including API key?",default:!1})?(mt(),Te(),C("All configuration cleared.")):m("Cancelled.")}catch{m("Cancelled.")}else gt(),Te(),C("Logged out successfully."),e&&m("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as Rs}from"os";import{join as As}from"path";import se from"chalk";import{Command as $s}from"commander";import{spawn as Va}from"child_process";import{existsSync as ja,readdirSync as qa}from"fs";import{homedir as dr}from"os";import{delimiter as lr}from"path";import{query as Ba}from"@anthropic-ai/claude-agent-sdk";function oe(t){if(t===void 0)return null;if(typeof t=="string")return t.length>12e3?`${t.slice(0,12e3)}\u2026`:t;try{let n=JSON.stringify(t);return n.length<=12e3?t:{preview:`${n.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(t).slice(0,12e3)}}function It(t){let n=typeof t=="string"?t:String(t??"");return n.length>12e3?`${n.slice(0,12e3)}\u2026`:n}function ae(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function P(t){return typeof t=="string"?t:""}function Ga(t,n){let e=t.replace(/[/.]/g,"-");return`${dr()}/.claude/projects/${e}/${n}.jsonl`}function Wa(t){try{return qa(`${t}/.nvm/versions/node`).map(n=>`${t}/.nvm/versions/node/${n}/bin`).sort().reverse()}catch{return[]}}function Tt(){let t=dr(),n=[`${t}/.local/bin`,`${t}/.claude/local`,`${t}/.bun/bin`,`${t}/bin`,"/opt/homebrew/bin","/usr/local/bin",...Wa(t)],o=(process.env.PATH??"").split(lr);for(let r of n)o.includes(r)||o.push(r);return o.join(lr)}async function kt(t){let n=t??"claude";return new Promise(e=>{let o=Va(n,["--version"],{env:{...process.env,PATH:Tt()},stdio:["ignore","pipe","ignore"]}),r="";o.stdout.on("data",i=>{r+=i.toString("utf8")}),o.on("error",()=>e(null)),o.on("close",i=>{if(i!==0)return e(null);let a=r.trim().split(`
44
+ `)[0]??"";e(a?{bin:n,version:a}:null)})})}var Ha=new Set(["","default","best"]);function hn(t){let n=t.filter(i=>i.text.trim());if(n.length===0)return"";let e=n[n.length-1],o=n.slice(0,-1);return o.length===0?e.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
- ${e.text}`}function yn(t,n){return n?t.messages.filter(o=>o.text.trim()).at(-1)?.text??"":hn(t.messages)}function Wa({abortController:t,input:n,resumeSessionId:e,workspace:o}){let r=(n.modelId??"").trim(),i=n.thinking??null,a={abortController:t,allowedTools:["WebSearch","WebFetch"],cwd:o,env:{...process.env,PATH:Tt()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return Ga.has(r)||(a.model=r),n.effort&&(a.effort=n.effort),i&&i!=="disabled"&&(a.thinking={display:"summarized",type:i==="enabled"?"enabled":"adaptive"}),e?a.resume=e:n.system?.trim()&&(a.systemPrompt=n.system),a}async function mr(t){let n=yn(t.input,t.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let e=new AbortController,o=()=>e.abort();t.signal?.addEventListener("abort",o,{once:!0});let r=null,i=null,a=null,s=null,l=null,u=0,f=new Set;try{let g=ja({prompt:n,options:Wa({abortController:e,input:t.input,resumeSessionId:t.resumeSessionId,workspace:t.workspace})});for await(let S of g){let y=S;if(y.type==="system"&&y.subtype==="init"){typeof y.session_id=="string"&&(i=y.session_id),typeof y.model=="string"&&(r=y.model,t.onEvent({eventType:"chat.model",payload:{modelId:y.model}}));continue}if(y.type==="stream_event"){let b=y.event;if(b?.type!=="content_block_delta")continue;let R=b.delta;if(!R)continue;R.type==="text_delta"&&typeof R.text=="string"?(u+=R.text.length,t.onEvent({eventType:"chat.text.delta",payload:{text:R.text}})):R.type==="thinking_delta"&&typeof R.thinking=="string"&&t.onEvent({eventType:"chat.reasoning.delta",payload:{text:R.thinking}});continue}if(y.type==="assistant"){let b=ae(y.message),R=Array.isArray(b.content)?b.content:[];for(let M of R){let $=ae(M);if($.type!=="tool_use")continue;let _=N($.id),w=N($.name);!_||!w||f.has(_)||(f.add(_),t.onEvent({eventType:"chat.tool.started",payload:{input:oe($.input),toolCallId:_,toolName:w}}))}continue}if(y.type==="user"){let b=ae(y.message),R=Array.isArray(b.content)?b.content:[];for(let M of R){let $=ae(M);if($.type!=="tool_result")continue;let _=N($.tool_use_id);_&&t.onEvent({eventType:"chat.tool.completed",payload:{...$.is_error===!0?{errorText:typeof $.content=="string"?It($.content):"Claude tool call failed."}:{},output:oe($.content),toolCallId:_}})}continue}y.type==="result"&&(typeof y.result=="string"&&(s=y.result),y.usage&&typeof y.usage=="object"&&(a=y.usage),typeof y.session_id=="string"&&(i=y.session_id),(y.is_error===!0||y.subtype!=="success")&&(l=typeof y.result=="string"&&y.result||`Claude turn failed (${String(y.subtype)}).`,t.onEvent({eventType:"chat.error",message:l,payload:{message:l}})))}}finally{t.signal?.removeEventListener("abort",o)}if(t.signal?.aborted)throw new Error("Chat turn cancelled.");if(l)throw new Error(l);let v=s??"";u===0&&v&&t.onEvent({eventType:"chat.text.delta",payload:{text:v}});let I=i?qa(t.workspace,i):null;return{modelId:r,sessionId:i,sessionPath:I&&Ma(I)?I:null,text:v,usage:a}}import{spawn as Ha}from"child_process";import{closeSync as Ja,fstatSync as za,openSync as Ya,readSync as Xa,readdirSync as Ka}from"fs";import{homedir as Qa}from"os";import{join as pr}from"path";import{Codex as Za}from"@openai/codex-sdk";var es=["/Applications/Codex.app/Contents/Resources/codex"];async function Rt(t){let n=t?[t]:["codex",...es];for(let e of n){let o=await ts(e);if(o)return{bin:e,version:o}}return null}function ts(t){return new Promise(n=>{let e=Ha(t,["--version"],{env:{...process.env,PATH:Tt()},stdio:["ignore","pipe","ignore"]}),o="";e.stdout.on("data",r=>{o+=r.toString("utf8")}),e.on("error",()=>n(null)),e.on("close",r=>{if(r!==0)return n(null);let i=o.trim().split(`
51
- `)[0]??"";n(i||null)})})}var ns=24,os=4*1024*1024;function rs(t){let n;try{n=is(t).split(`
52
- `)}catch{return[]}let e=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 l=N(s.call_id),u=N(s.input);l&&s.name==="exec"&&/\btools\.web__run\s*\(/.test(u)&&(e.add(l),r=l);continue}if(a.type==="event_msg"&&s.type==="web_search_end"){let l=N(s.call_id);if(!l||!r)continue;let u=N(s.query),f=ae(s.action),I={action:{...f,...u&&!N(f.query)?{query:u}:{}},query:u,sources:[],toolCallId:l},g=o.get(r)??[];g.push(I),o.set(r,g);continue}if(a.type==="response_item"&&s.type==="custom_tool_call_output"){let l=N(s.call_id);if(!l||!e.has(l))continue;let u=as(s.output);for(let f of o.get(l)??[])f.sources=u;r===l&&(r=null)}}return Array.from(o.values()).flat()}function is(t){let n=Ya(t,"r");try{let e=za(n).size,o=Math.max(0,e-os),r=Buffer.alloc(e-o);Xa(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{Ja(n)}}function as(t){let e=bn(t).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],o=new Set,r=[];for(let i of e){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>=ns)break}catch{}}return r}function bn(t){return typeof t=="string"?t:Array.isArray(t)?t.map(bn).join(`
50
+ ${e.text}`}function yn(t,n){return n?t.messages.filter(o=>o.text.trim()).at(-1)?.text??"":hn(t.messages)}function Ja({abortController:t,input:n,resumeSessionId:e,workspace:o}){let r=(n.modelId??"").trim(),i=n.thinking??null,a={abortController:t,allowedTools:["WebSearch","WebFetch"],cwd:o,env:{...process.env,PATH:Tt()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return Ha.has(r)||(a.model=r),n.effort&&(a.effort=n.effort),i&&i!=="disabled"&&(a.thinking={display:"summarized",type:i==="enabled"?"enabled":"adaptive"}),e?a.resume=e:n.system?.trim()&&(a.systemPrompt=n.system),a}async function ur(t){let n=yn(t.input,t.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let e=new AbortController,o=()=>e.abort();t.signal?.addEventListener("abort",o,{once:!0});let r=null,i=null,a=null,s=null,l=null,u=0,f=new Set;try{let g=Ba({prompt:n,options:Ja({abortController:e,input:t.input,resumeSessionId:t.resumeSessionId,workspace:t.workspace})});for await(let T of g){let y=T;if(y.type==="system"&&y.subtype==="init"){typeof y.session_id=="string"&&(i=y.session_id),typeof y.model=="string"&&(r=y.model,t.onEvent({eventType:"chat.model",payload:{modelId:y.model}}));continue}if(y.type==="stream_event"){let b=y.event;if(b?.type!=="content_block_delta")continue;let S=b.delta;if(!S)continue;S.type==="text_delta"&&typeof S.text=="string"?(u+=S.text.length,t.onEvent({eventType:"chat.text.delta",payload:{text:S.text}})):S.type==="thinking_delta"&&typeof S.thinking=="string"&&t.onEvent({eventType:"chat.reasoning.delta",payload:{text:S.thinking}});continue}if(y.type==="assistant"){let b=ae(y.message),S=Array.isArray(b.content)?b.content:[];for(let D of S){let $=ae(D);if($.type!=="tool_use")continue;let N=P($.id),w=P($.name);!N||!w||f.has(N)||(f.add(N),t.onEvent({eventType:"chat.tool.started",payload:{input:oe($.input),toolCallId:N,toolName:w}}))}continue}if(y.type==="user"){let b=ae(y.message),S=Array.isArray(b.content)?b.content:[];for(let D of S){let $=ae(D);if($.type!=="tool_result")continue;let N=P($.tool_use_id);N&&t.onEvent({eventType:"chat.tool.completed",payload:{...$.is_error===!0?{errorText:typeof $.content=="string"?It($.content):"Claude tool call failed."}:{},output:oe($.content),toolCallId:N}})}continue}y.type==="result"&&(typeof y.result=="string"&&(s=y.result),y.usage&&typeof y.usage=="object"&&(a=y.usage),typeof y.session_id=="string"&&(i=y.session_id),(y.is_error===!0||y.subtype!=="success")&&(l=typeof y.result=="string"&&y.result||`Claude turn failed (${String(y.subtype)}).`,t.onEvent({eventType:"chat.error",message:l,payload:{message:l}})))}}finally{t.signal?.removeEventListener("abort",o)}if(t.signal?.aborted)throw new Error("Chat turn cancelled.");if(l)throw new Error(l);let v=s??"";u===0&&v&&t.onEvent({eventType:"chat.text.delta",payload:{text:v}});let I=i?Ga(t.workspace,i):null;return{modelId:r,sessionId:i,sessionPath:I&&ja(I)?I:null,text:v,usage:a}}import{spawn as za}from"child_process";import{closeSync as Xa,fstatSync as Ya,openSync as Ka,readdirSync as Qa,readSync as Za}from"fs";import{homedir as es}from"os";import{join as mr}from"path";import{Codex as ts}from"@openai/codex-sdk";var ns=["/Applications/Codex.app/Contents/Resources/codex"];async function Rt(t){let n=t?[t]:["codex",...ns];for(let e of n){let o=await os(e);if(o)return{bin:e,version:o}}return null}function os(t){return new Promise(n=>{let e=za(t,["--version"],{env:{...process.env,PATH:Tt()},stdio:["ignore","pipe","ignore"]}),o="";e.stdout.on("data",r=>{o+=r.toString("utf8")}),e.on("error",()=>n(null)),e.on("close",r=>{if(r!==0)return n(null);let i=o.trim().split(`
51
+ `)[0]??"";n(i||null)})})}var rs=24,is=4*1024*1024;function as(t){let n;try{n=ss(t).split(`
52
+ `)}catch{return[]}let e=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 l=P(s.call_id),u=P(s.input);l&&s.name==="exec"&&/\btools\.web__run\s*\(/.test(u)&&(e.add(l),r=l);continue}if(a.type==="event_msg"&&s.type==="web_search_end"){let l=P(s.call_id);if(!l||!r)continue;let u=P(s.query),f=ae(s.action),I={action:{...f,...u&&!P(f.query)?{query:u}:{}},query:u,sources:[],toolCallId:l},g=o.get(r)??[];g.push(I),o.set(r,g);continue}if(a.type==="response_item"&&s.type==="custom_tool_call_output"){let l=P(s.call_id);if(!l||!e.has(l))continue;let u=cs(s.output);for(let f of o.get(l)??[])f.sources=u;r===l&&(r=null)}}return Array.from(o.values()).flat()}function ss(t){let n=Ka(t,"r");try{let e=Ya(n).size,o=Math.max(0,e-is),r=Buffer.alloc(e-o);Za(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{Xa(n)}}function cs(t){let e=bn(t).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],o=new Set,r=[];for(let i of e){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>=rs)break}catch{}}return r}function bn(t){return typeof t=="string"?t:Array.isArray(t)?t.map(bn).join(`
54
54
  `):t&&typeof t=="object"?Object.values(t).map(bn).join(`
55
- `):""}function gr(t,n){let e=ae(t),o=N(e.type),r=N(e.id)||N(e.call_id)||N(e.tool_call_id);if(!r)return null;if(o==="command_execution"){let i=N(e.command),a=N(e.status),s={exitCode:typeof e.exit_code=="number"?e.exit_code:null,output:oe(e.aggregated_output)};return{...n&&a==="failed"?{errorText:It(e.aggregated_output)||"Command failed."}:{},input:{command:i},...n?{output:s}:{},toolCallId:r,toolName:"Bash"}}if(o==="mcp_tool_call"){let i=ae(e.error);return{...n&&N(i.message)?{errorText:N(i.message)}:{},input:oe(e.arguments),...n?{output:oe(e.result??{status:e.status??"completed"})}:{},toolCallId:r,toolName:N(e.tool)||N(e.name)||"Codex tool"}}if(o==="web_search"){let i=N(e.query);return{input:{query:i},...n?{output:{query:i}}:{},toolCallId:r,toolName:"web_search"}}if(o==="file_change"){let i=N(e.status);return{...n&&i==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:oe(e.changes)},...n?{output:{changes:oe(e.changes),status:i}}:{},toolCallId:r,toolName:"ApplyPatch"}}if(o==="custom_tool_call_output")return{input:{},...n?{output:oe(e.output)}:{},toolCallId:r,toolName:"Codex tool"};if(o==="custom_tool_call"||o==="dynamic_tool_call"||o==="function_call"){let i=N(e.name)||N(e.tool)||"Codex tool",a=e.input??e.arguments??{};return{input:i==="exec"&&typeof a=="string"?{command:a}:oe(a),...n?{output:oe(e.output??e.result??{status:e.status??"completed"})}:{},toolCallId:r,toolName:i}}return null}function ss(t,n=pr(Qa(),".codex","sessions")){try{let o=Ka(n,{recursive:!0}).find(r=>typeof r=="string"&&r.endsWith(`${t}.jsonl`));return o?pr(n,o):null}catch{return null}}function cs(t,n){return n?yn(t,n):hn(t.messages)}function ls(t,n){let e=n.system?.trim();return{codexPathOverride:t,...e?{config:{developer_instructions:e}}:{}}}var ds=new Set(["minimal","low","medium","high","xhigh"]);function us(t,n){let e={sandboxMode:"read-only",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:n},o=(t.modelId??"").trim();return o&&o!=="default"&&(e.model=o),t.effort&&ds.has(t.effort)&&(e.modelReasoningEffort=t.effort),e}async function fr(t){let n=cs(t.input,t.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let e=new Za(ls(t.bin,t.input)),o=us(t.input,t.workspace),r=t.resumeSessionId?e.resumeThread(t.resumeSessionId,o):e.startThread(o),i=t.resumeSessionId??null,a=null,s=null,l=[],u=[],{events:f}=await r.runStreamed(n);for await(let S of f){if(t.signal?.aborted)throw await f.return?.(void 0),new Error("Chat turn cancelled.");let y=S;if(y.type==="thread.started"){typeof y.thread_id=="string"&&(i=y.thread_id);continue}if(y.type==="item.started"){let b=gr(y.item,!1);b&&t.onEvent({eventType:"chat.tool.started",payload:b});continue}if(y.type==="item.completed"){let b=y.item;if(!b)continue;if(b.type==="agent_message"&&typeof b.text=="string")l.push(b.text),t.onEvent({eventType:"chat.text.delta",payload:{text:b.text}});else if(b.type==="reasoning"&&typeof b.text=="string")t.onEvent({eventType:"chat.reasoning.delta",payload:{text:b.text}});else{let R=gr(b,!0);R&&(b.type==="web_search"?u.push(R):t.onEvent({eventType:"chat.tool.completed",payload:R}))}continue}if(y.type==="turn.completed"){y.usage&&typeof y.usage=="object"&&(a=y.usage);continue}if(y.type==="turn.failed"){let b=y.error;s=typeof b?.message=="string"&&b.message||"Codex turn failed.",t.onEvent({eventType:"chat.error",message:s,payload:{message:s}})}}if(s)throw new Error(s);i=r.id??i;let v=i?ss(i):null,I=v?rs(v):[],g=new Map(I.map(S=>[S.toolCallId,S]));for(let S of u){let y=g.get(S.toolCallId);t.onEvent({eventType:"chat.tool.completed",payload:{...S,output:y?{action:y.action,query:y.query,sources:y.sources}:{action:{query:N(ae(S.input).query),type:"search"},sourceListUnavailable:!0,sources:[]}}})}return{modelId:t.input.modelId??null,sessionId:i,sessionPath:v,text:l.join(`
55
+ `):""}function pr(t,n){let e=ae(t),o=P(e.type),r=(o==="custom_tool_call"||o==="custom_tool_call_output"||o==="dynamic_tool_call"||o==="function_call"?P(e.call_id)||P(e.tool_call_id):P(e.id)||P(e.call_id)||P(e.tool_call_id))||P(e.id);if(!r)return null;if(o==="command_execution"){let i=P(e.command),a=P(e.status),s={exitCode:typeof e.exit_code=="number"?e.exit_code:null,output:oe(e.aggregated_output)};return{...n&&a==="failed"?{errorText:It(e.aggregated_output)||"Command failed."}:{},input:{command:i},...n?{output:s}:{},toolCallId:r,toolName:"Bash"}}if(o==="mcp_tool_call"){let i=ae(e.error);return{...n&&P(i.message)?{errorText:P(i.message)}:{},input:oe(e.arguments),...n?{output:oe(e.result??{status:e.status??"completed"})}:{},toolCallId:r,toolName:P(e.tool)||P(e.name)||"Codex tool"}}if(o==="web_search"){let i=P(e.query);return{input:{query:i},...n?{output:{query:i}}:{},toolCallId:r,toolName:"web_search"}}if(o==="file_change"){let i=P(e.status);return{...n&&i==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:oe(e.changes)},...n?{output:{changes:oe(e.changes),status:i}}:{},toolCallId:r,toolName:"ApplyPatch"}}if(o==="custom_tool_call_output")return{input:{},...n?{output:oe(e.output)}:{},toolCallId:r,toolName:"Codex tool"};if(o==="custom_tool_call"||o==="dynamic_tool_call"||o==="function_call"){let i=P(e.name)||P(e.tool)||"Codex tool",a=e.input??e.arguments??{};return{input:i==="exec"&&typeof a=="string"?{command:a}:oe(a),...n?{output:oe(e.output??e.result??{status:e.status??"completed"})}:{},toolCallId:r,toolName:i}}return null}function ls(t,n=mr(es(),".codex","sessions")){try{let o=Qa(n,{recursive:!0}).find(r=>typeof r=="string"&&r.endsWith(`${t}.jsonl`));return o?mr(n,o):null}catch{return null}}function ds(t,n){return n?yn(t,n):hn(t.messages)}function us(t,n,e=p.codexSelfConnectorAppId){let o=n.system?.trim(),r={...o?{developer_instructions:o}:{},...e?{apps:{[e]:{enabled:!1}}}:{}};return{codexPathOverride:t,...Object.keys(r).length>0?{config:r}:{}}}var ms=new Set(["minimal","low","medium","high","xhigh"]);function ps(t,n){let e={networkAccessEnabled:!0,sandboxMode:"workspace-write",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:n},o=(t.modelId??"").trim();return o&&o!=="default"&&(e.model=o),t.effort&&ms.has(t.effort)&&(e.modelReasoningEffort=t.effort),e}async function fr(t){let n=ds(t.input,t.resumeSessionId);if(!n)throw new Error("Chat turn has no user text to send.");let e=new ts(us(t.bin,t.input)),o=ps(t.input,t.workspace),r=t.resumeSessionId?e.resumeThread(t.resumeSessionId,o):e.startThread(o),i=t.resumeSessionId??null,a=null,s=null,l=[],u=[],{events:f}=await r.runStreamed(n);for await(let T of f){if(t.signal?.aborted)throw await f.return?.(void 0),new Error("Chat turn cancelled.");let y=T;if(y.type==="thread.started"){typeof y.thread_id=="string"&&(i=y.thread_id);continue}if(y.type==="item.started"){let b=pr(y.item,!1);b&&t.onEvent({eventType:"chat.tool.started",payload:b});continue}if(y.type==="item.completed"){let b=y.item;if(!b)continue;if(b.type==="agent_message"&&typeof b.text=="string")l.push(b.text),t.onEvent({eventType:"chat.text.delta",payload:{text:b.text}});else if(b.type==="reasoning"&&typeof b.text=="string")t.onEvent({eventType:"chat.reasoning.delta",payload:{text:b.text}});else{let S=pr(b,!0);S&&(b.type==="web_search"?u.push(S):t.onEvent({eventType:"chat.tool.completed",payload:S}))}continue}if(y.type==="turn.completed"){y.usage&&typeof y.usage=="object"&&(a=y.usage);continue}if(y.type==="turn.failed"){let b=y.error;s=typeof b?.message=="string"&&b.message||"Codex turn failed.",t.onEvent({eventType:"chat.error",message:s,payload:{message:s}})}}if(s)throw new Error(s);i=r.id??i;let v=i?ls(i,t.sessionsRoot):null,I=v?as(v):[],g=new Set(I.map((T,y)=>y));for(let T of u){let y=P(ae(T.input).query),b=gr(y),S=I.findIndex(($,N)=>g.has(N)&&gr($.query)===b);S<0&&(S=Array.from(g).sort(($,N)=>$-N)[0]??-1);let D=S>=0?I[S]:void 0;S>=0&&g.delete(S),t.onEvent({eventType:"chat.tool.completed",payload:{...T,output:D?{action:D.action,query:D.query,sources:D.sources}:{action:{query:y,type:"search"},sourceListUnavailable:!0,sources:[]}}})}return{modelId:t.input.modelId??null,sessionId:i,sessionPath:v,text:l.join(`
56
56
 
57
- `),usage:a}}import{randomUUID as hs}from"crypto";import{mkdir as ys}from"fs/promises";import{hostname as Cn,platform as bs}from"os";import{join as xs}from"path";var De=class extends Error{constructor(e,o,r=!1){super(e);this.statusCode=o;this.reRegister=r;this.name="RunnerApiError"}statusCode;reRegister};async function Fe(t,n={}){let e=await de();n.body!==void 0&&(e["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()}${t}`,{body:n.body!==void 0?JSON.stringify(n.body):void 0,headers:e,method:n.method??"GET",signal:o.signal}),s=await a.text(),l={};try{l=s?JSON.parse(s):{}}catch{l={error:s.slice(0,300)}}if(!a.ok)throw new De(typeof l.error=="string"?l.error:`Runner API returned ${a.status}`,a.status,l.reRegister===!0);return l}finally{clearTimeout(r),n.signal?.removeEventListener("abort",i)}}async function hr(t){await Fe("/api/runner/register",{body:t,method:"POST",timeoutMs:15e3})}async function yr(t,n){return(await Fe(`/api/runner/work?runnerId=${encodeURIComponent(t)}`,{signal:n,timeoutMs:28e3})).job??null}async function br(t){await Fe("/api/runner/heartbeat",{body:{runnerId:t},method:"POST",timeoutMs:1e4})}async function xr(t,n){return{cancelRequested:(await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/events`,{body:{events:n},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function xn(t,n,e){await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/complete`,{body:{result:e,runnerId:n},method:"POST",timeoutMs:15e3})}async function At(t,n,e,o=!0){await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/fail`,{body:{message:e,retryable:o,runnerId:n},method:"POST",timeoutMs:15e3})}import{mkdirSync as ms,readFileSync as ps,writeFileSync as vr}from"fs";import{dirname as gs,join as fs}from"path";function vn(t){return fs(t,"sessions.json")}function wn(t){try{let n=ps(vn(t),"utf8"),e=JSON.parse(n);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}function wr(t,n,e){return n?wn(t)[n]?.[e]??null:null}function Sr(t,n,e,o){if(!(!n||!o))try{let r=vn(t);ms(gs(r),{recursive:!0});let i=wn(t);i[n]={...i[n],[e]:o},vr(r,`${JSON.stringify(i,null," ")}
57
+ `),usage:a}}function gr(t){return t.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as bs}from"crypto";import{mkdir as xs}from"fs/promises";import{hostname as Cn,platform as vs}from"os";import{join as ws}from"path";var De=class extends Error{constructor(e,o,r=!1){super(e);this.statusCode=o;this.reRegister=r;this.name="RunnerApiError"}statusCode;reRegister};async function Fe(t,n={}){let e=await de();n.body!==void 0&&(e["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()}${t}`,{body:n.body!==void 0?JSON.stringify(n.body):void 0,headers:e,method:n.method??"GET",signal:o.signal}),s=await a.text(),l={};try{l=s?JSON.parse(s):{}}catch{l={error:s.slice(0,300)}}if(!a.ok)throw new De(typeof l.error=="string"?l.error:`Runner API returned ${a.status}`,a.status,l.reRegister===!0);return l}finally{clearTimeout(r),n.signal?.removeEventListener("abort",i)}}async function hr(t){await Fe("/api/runner/register",{body:t,method:"POST",timeoutMs:15e3})}async function yr(t,n){return(await Fe(`/api/runner/work?runnerId=${encodeURIComponent(t)}`,{signal:n,timeoutMs:28e3})).job??null}async function br(t){await Fe("/api/runner/heartbeat",{body:{runnerId:t},method:"POST",timeoutMs:1e4})}async function xr(t,n){return{cancelRequested:(await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/events`,{body:{events:n},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function xn(t,n,e){await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/complete`,{body:{result:e,runnerId:n},method:"POST",timeoutMs:15e3})}async function At(t,n,e,o=!0){await Fe(`/api/runner/jobs/${encodeURIComponent(t)}/fail`,{body:{message:e,retryable:o,runnerId:n},method:"POST",timeoutMs:15e3})}import{mkdirSync as gs,readFileSync as fs,writeFileSync as vr}from"fs";import{dirname as hs,join as ys}from"path";function vn(t){return ys(t,"sessions.json")}function wn(t){try{let n=fs(vn(t),"utf8"),e=JSON.parse(n);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}function wr(t,n,e){return n?wn(t)[n]?.[e]??null:null}function Sr(t,n,e,o){if(!(!n||!o))try{let r=vn(t);gs(hs(r),{recursive:!0});let i=wn(t);i[n]={...i[n],[e]:o},vr(r,`${JSON.stringify(i,null," ")}
58
58
  `,"utf8")}catch{}}function Cr(t,n,e){if(n)try{let o=wn(t);if(!o[n])return;delete o[n][e],vr(vn(t),`${JSON.stringify(o,null," ")}
59
- `,"utf8")}catch{}}var vs=300,ws=3e4;async function Ir(t){let[n,e]=await Promise.all([kt(t.claudeBin),Rt(t.codexBin)]);if(!n&&!e)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");n?t.log(`Claude Code detected: ${n.version} (${n.bin})`):t.log("Claude Code not found \u2014 Claude turns will be declined."),e?t.log(`Codex detected: ${e.version} (${e.bin})`):t.log("Codex not found \u2014 Codex turns will be declined.");let o=[...n?["claude-code"]:[],...e?["codex"]:[]],r=`${Cn().split(".")[0]}-${hs().slice(0,8)}`,i=()=>hr({capabilities:["chat_turn","proof"],claudeCodeVersion:n?.version??null,cliVersion:t.version,codexVersion:e?.version??null,hostname:Cn(),platform:bs(),runnerId:r,runtimes:o});for(await i(),t.log(`Registered as ${r} (runtimes: ${o.join(", ")}). Waiting for work\u2026`);!t.signal?.aborted;){let a=null;try{a=await yr(r,t.signal)}catch(s){if(t.signal?.aborted)break;if(s instanceof De&&s.reRegister){t.log("Server asked for re-registration."),await i().catch(()=>{});continue}t.log(`Work poll failed (${s instanceof Error?s.message:"unknown"}); retrying\u2026`),await Is(t.pollBackoffMs??5e3,t.signal);continue}if(!a){if(t.once)continue;continue}if(t.log(`Claimed ${a.jobType} job ${a.runId}.`),await Ss({claude:n,codex:e,job:a,options:t,runnerId:r}),t.once)break}}async function Ss({claude:t,codex:n,job:e,options:o,runnerId:r}){let i=new AbortController,a=()=>i.abort();o.signal?.addEventListener("abort",a,{once:!0});let s=setInterval(()=>{br(r).catch(()=>{})},ws),l=[],u=!1,f=async()=>{if(u||l.length===0)return;u=!0;let g=l.splice(0,100);try{let{cancelRequested:S}=await xr(e.runId,g);S&&i.abort()}catch(S){S instanceof De&&S.statusCode===409&&i.abort()}finally{u=!1}},v=setInterval(()=>{f()},vs),I=g=>{l.push(g)};try{if(e.jobType==="runner.proof"){let g=typeof e.input.message=="string"?e.input.message:"proof";I({eventType:"proof.echo",payload:{message:g}}),await Sn(f,l),await xn(e.runId,r,{echo:g}),o.log(`Proof job ${e.runId} completed.`);return}if(e.jobType==="runner.chat_turn"){let g=e.input.runtime==="codex"?"codex":"claude-code",S=g==="codex"?n&&{detection:n,run:fr}:t&&{detection:t,run:mr};if(!S){await At(e.runId,r,g==="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 y=typeof e.input.chatId=="string"&&e.input.chatId?e.input.chatId:null,b=xs(o.workspaceRoot,"chats",y??e.runId);await ys(b,{recursive:!0});let R=Cs(e.input),M=w=>I({eventType:w.eventType,message:w.message??null,payload:w.payload??{}}),$=wr(o.workspaceRoot,y,g),_;try{_=await S.run({bin:S.detection.bin,input:R,onEvent:M,resumeSessionId:$,signal:i.signal,workspace:b})}catch(w){if(!$||i.signal.aborted)throw w;o.log(`Resume of ${g} session failed (${w instanceof Error?w.message:"unknown"}); retrying fresh.`),Cr(o.workspaceRoot,y,g),_=await S.run({bin:S.detection.bin,input:R,onEvent:M,resumeSessionId:null,signal:i.signal,workspace:b})}Sr(o.workspaceRoot,y,g,_.sessionId),I({eventType:"chat.session",payload:{host:Cn(),runtime:g,runtimeVersion:S.detection.version,sessionId:_.sessionId,sessionPath:_.sessionPath}}),await Sn(f,l),await xn(e.runId,r,{modelId:_.modelId,runtime:g,runtimeVersion:S.detection.version,sessionId:_.sessionId,sessionPath:_.sessionPath,text:_.text,usage:_.usage??{}}),o.log(`Chat turn ${e.runId} (${g}) completed.`);return}await At(e.runId,r,`This runner does not support ${e.jobType} jobs. Update the desktop app / CLI.`,!1)}catch(g){let S=g instanceof Error?g.message:"Local runner job crashed.";o.log(`Job ${e.runId} failed: ${S}`),await Sn(f,l).catch(()=>{}),await At(e.runId,r,S).catch(()=>{})}finally{clearInterval(v),clearInterval(s),o.signal?.removeEventListener("abort",a)}}function Cs(t){let n=Array.isArray(t.messages)?t.messages.map(e=>{if(!e||typeof e!="object")return null;let o=e;return{role:typeof o.role=="string"?o.role:"user",text:typeof o.text=="string"?o.text:""}}).filter(e=>!!e):[];return{effort:typeof t.effort=="string"?t.effort:null,messages:n,modelId:typeof t.modelId=="string"?t.modelId:null,system:typeof t.system=="string"?t.system:null,thinking:typeof t.thinking=="string"?t.thinking:null}}async function Sn(t,n){for(;n.length>0;)await t(),n.length>0&&await new Promise(e=>setTimeout(e,25))}function Is(t,n){return t<=0||n?.aborted?Promise.resolve():new Promise(e=>{let o=setTimeout(r,t);function r(){clearTimeout(o),n?.removeEventListener("abort",r),e()}n?.addEventListener("abort",r,{once:!0})})}function As(){return ks(Ts(),`.${p.commands[0]}-runner`,"runs")}var $t=new Rs("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");$t.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[t,n]=await Promise.all([kt(),Rt()]);if(console.log(t?se.green(`\u2713 Claude Code ${t.version}`):se.red("\u2717 Claude Code not found on PATH")),console.log(n?se.green(`\u2713 Codex ${n.version} (${n.bin})`):se.red("\u2717 Codex not found (PATH or Codex.app)")),!ie()){console.log(se.red(`\u2717 Not logged in. Run '${p.commands[0]} login' first.`)),process.exitCode=2;return}try{let e=await he();console.log(se.green(`\u2713 Logged in as ${e.user.email}`))}catch(e){console.log(se.red(`\u2717 Auth check failed: ${e instanceof Error?e.message:"unknown"}`)),process.exitCode=2}});$t.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 t=>{ie()||(console.error(se.red(`Not authenticated. Run '${p.commands[0]} login' first.`)),process.exit(2));let n=new AbortController,e=()=>{console.log(se.gray(`
60
- Stopping runner\u2026`)),n.abort()};process.on("SIGINT",e),process.on("SIGTERM",e);try{await Ir({claudeBin:t.claudeBin,codexBin:t.codexBin,log:o=>console.log(se.gray(`[runner] ${o}`)),once:t.once,signal:n.signal,version:"0.3.8",workspaceRoot:t.workspace??As()})}catch(o){console.error(se.red(o instanceof Error?o.message:String(o))),process.exit(1)}});import{Command as Ds}from"commander";import U from"chalk";function Et(t){let{name:n,cmd:e}=t,o=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return`---
59
+ `,"utf8")}catch{}}var Ss=300,Cs=3e4;async function Ir(t){let[n,e]=await Promise.all([kt(t.claudeBin),Rt(t.codexBin)]);if(!n&&!e)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");n?t.log(`Claude Code detected: ${n.version} (${n.bin})`):t.log("Claude Code not found \u2014 Claude turns will be declined."),e?t.log(`Codex detected: ${e.version} (${e.bin})`):t.log("Codex not found \u2014 Codex turns will be declined.");let o=[...n?["claude-code"]:[],...e?["codex"]:[]],r=`${Cn().split(".")[0]}-${bs().slice(0,8)}`,i=()=>hr({capabilities:["chat_turn","proof"],claudeCodeVersion:n?.version??null,cliVersion:t.version,codexVersion:e?.version??null,hostname:Cn(),platform:vs(),runnerId:r,runtimes:o});for(await i(),t.log(`Registered as ${r} (runtimes: ${o.join(", ")}). Waiting for work\u2026`);!t.signal?.aborted;){let a=null;try{a=await yr(r,t.signal)}catch(s){if(t.signal?.aborted)break;if(s instanceof De&&s.reRegister){t.log("Server asked for re-registration."),await i().catch(()=>{});continue}t.log(`Work poll failed (${s instanceof Error?s.message:"unknown"}); retrying\u2026`),await ks(t.pollBackoffMs??5e3,t.signal);continue}if(!a){if(t.once)continue;continue}if(t.log(`Claimed ${a.jobType} job ${a.runId}.`),await Is({claude:n,codex:e,job:a,options:t,runnerId:r}),t.once)break}}async function Is({claude:t,codex:n,job:e,options:o,runnerId:r}){let i=new AbortController,a=()=>i.abort();o.signal?.addEventListener("abort",a,{once:!0});let s=setInterval(()=>{br(r).catch(()=>{})},Cs),l=[],u=!1,f=async()=>{if(u||l.length===0)return;u=!0;let g=l.splice(0,100);try{let{cancelRequested:T}=await xr(e.runId,g);T&&i.abort()}catch(T){T instanceof De&&T.statusCode===409&&i.abort()}finally{u=!1}},v=setInterval(()=>{f()},Ss),I=g=>{l.push(g)};try{if(e.jobType==="runner.proof"){let g=typeof e.input.message=="string"?e.input.message:"proof";I({eventType:"proof.echo",payload:{message:g}}),await Sn(f,l),await xn(e.runId,r,{echo:g}),o.log(`Proof job ${e.runId} completed.`);return}if(e.jobType==="runner.chat_turn"){let g=e.input.runtime==="codex"?"codex":"claude-code",T=g==="codex"?n&&{detection:n,run:fr}:t&&{detection:t,run:ur};if(!T){await At(e.runId,r,g==="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 y=typeof e.input.chatId=="string"&&e.input.chatId?e.input.chatId:null,b=ws(o.workspaceRoot,"chats",y??e.runId);await xs(b,{recursive:!0});let S=Ts(e.input),D=w=>I({eventType:w.eventType,message:w.message??null,payload:w.payload??{}}),$=wr(o.workspaceRoot,y,g),N;try{N=await T.run({bin:T.detection.bin,input:S,onEvent:D,resumeSessionId:$,signal:i.signal,workspace:b})}catch(w){if(!$||i.signal.aborted)throw w;o.log(`Resume of ${g} session failed (${w instanceof Error?w.message:"unknown"}); retrying fresh.`),Cr(o.workspaceRoot,y,g),N=await T.run({bin:T.detection.bin,input:S,onEvent:D,resumeSessionId:null,signal:i.signal,workspace:b})}Sr(o.workspaceRoot,y,g,N.sessionId),I({eventType:"chat.session",payload:{host:Cn(),runtime:g,runtimeVersion:T.detection.version,sessionId:N.sessionId,sessionPath:N.sessionPath}}),await Sn(f,l),await xn(e.runId,r,{modelId:N.modelId,runtime:g,runtimeVersion:T.detection.version,sessionId:N.sessionId,sessionPath:N.sessionPath,text:N.text,usage:N.usage??{}}),o.log(`Chat turn ${e.runId} (${g}) completed.`);return}await At(e.runId,r,`This runner does not support ${e.jobType} jobs. Update the desktop app / CLI.`,!1)}catch(g){let T=g instanceof Error?g.message:"Local runner job crashed.";o.log(`Job ${e.runId} failed: ${T}`),await Sn(f,l).catch(()=>{}),await At(e.runId,r,T).catch(()=>{})}finally{clearInterval(v),clearInterval(s),o.signal?.removeEventListener("abort",a)}}function Ts(t){let n=Array.isArray(t.messages)?t.messages.map(e=>{if(!e||typeof e!="object")return null;let o=e;return{role:typeof o.role=="string"?o.role:"user",text:typeof o.text=="string"?o.text:""}}).filter(e=>!!e):[];return{effort:typeof t.effort=="string"?t.effort:null,messages:n,modelId:typeof t.modelId=="string"?t.modelId:null,system:typeof t.system=="string"?t.system:null,thinking:typeof t.thinking=="string"?t.thinking:null}}async function Sn(t,n){for(;n.length>0;)await t(),n.length>0&&await new Promise(e=>setTimeout(e,25))}function ks(t,n){return t<=0||n?.aborted?Promise.resolve():new Promise(e=>{let o=setTimeout(r,t);function r(){clearTimeout(o),n?.removeEventListener("abort",r),e()}n?.addEventListener("abort",r,{once:!0})})}function Es(){return As(Rs(),`.${p.commands[0]}-runner`,"runs")}var $t=new $s("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");$t.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[t,n]=await Promise.all([kt(),Rt()]);if(console.log(t?se.green(`\u2713 Claude Code ${t.version}`):se.red("\u2717 Claude Code not found on PATH")),console.log(n?se.green(`\u2713 Codex ${n.version} (${n.bin})`):se.red("\u2717 Codex not found (PATH or Codex.app)")),!ie()){console.log(se.red(`\u2717 Not logged in. Run '${p.commands[0]} login' first.`)),process.exitCode=2;return}try{let e=await he();console.log(se.green(`\u2713 Logged in as ${e.user.email}`))}catch(e){console.log(se.red(`\u2717 Auth check failed: ${e instanceof Error?e.message:"unknown"}`)),process.exitCode=2}});$t.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 t=>{ie()||(console.error(se.red(`Not authenticated. Run '${p.commands[0]} login' first.`)),process.exit(2));let n=new AbortController,e=()=>{console.log(se.gray(`
60
+ Stopping runner\u2026`)),n.abort()};process.on("SIGINT",e),process.on("SIGTERM",e);try{await Ir({claudeBin:t.claudeBin,codexBin:t.codexBin,log:o=>console.log(se.gray(`[runner] ${o}`)),once:t.once,signal:n.signal,version:"0.3.10",workspaceRoot:t.workspace??Es()})}catch(o){console.error(se.red(o instanceof Error?o.message:String(o))),process.exit(1)}});import{Command as Ls}from"commander";import M from"chalk";function Et(t){let{name:n,cmd:e}=t,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
  ---
@@ -2770,19 +2770,19 @@ Extracts: tweet text, author info, media URLs
2770
2770
  ---
2771
2771
 
2772
2772
  All scraped content is returned in markdown format.
2773
- `};import{mkdirSync as Dt,writeFileSync as Ft,existsSync as We,rmSync as Rr}from"fs";import{join as Q,resolve as ke,relative as $s,basename as Ar}from"path";import{homedir as Lt}from"os";var pe=[{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 Es={sonnet:"claude-sonnet-4.6",haiku:"claude-haiku-4.5",opus:"claude-opus-4.6"},Os=["permissionMode","skills","subagentType"];function Ps(t){let n=t.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!n)return`developer_instructions = """
2773
+ `};import{existsSync as We,mkdirSync as Dt,rmSync as Ar,writeFileSync as Ft}from"fs";import{homedir as Lt}from"os";import{basename as $r,join as Q,relative as Os,resolve as ke}from"path";var pe=[{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 Ps={sonnet:"claude-sonnet-4.6",haiku:"claude-haiku-4.5",opus:"claude-opus-4.6"},Ns=["permissionMode","skills","subagentType"];function Ds(t){let n=t.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!n)return`developer_instructions = """
2774
2774
  ${t.replace(/"""/g,'\\"\\"\\"').trim()}
2775
2775
  """
2776
- `;let e=n[1],o=n[2].trim(),r=u=>e.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 = """
2776
+ `;let e=n[1],o=n[2].trim(),r=u=>e.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 = """
2777
2777
  ${s}
2778
2778
  """`].join(`
2779
- `)+`
2780
- `}function Rn(t,n){if(n==="codex")return Ps(t);if(n!=="copilot")return t;let e=t.match(/^---\n([\s\S]*?)\n---\n/);if(!e)return Tr(t);let o=e[1],r=t.slice(e.index+e[0].length);o=o.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(a,s,l,u)=>`${s}${Es[l]??l}${u}`);for(let a of Os)o=o.replace(new RegExp(`^${a}:[^
2779
+ `)}
2780
+ `}function Er(t,n){if(n!=="copilot")return t;let e=t.match(/^---\n([\s\S]*?)\n---\n/);if(!e)return kr(t);let o=e[1],r=t.slice((e.index??0)+e[0].length);o=o.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(a,s,l,u)=>`${s}${Ps[l]??l}${u}`);for(let a of Ns)o=o.replace(new RegExp(`^${a}:[^
2781
2781
  ]*
2782
- ?`,"m"),"");o=o.replace(/\n+$/,"");let i=Tr(r);return`---
2782
+ ?`,"m"),"");o=o.replace(/\n+$/,"");let i=kr(r);return`---
2783
2783
  ${o}
2784
2784
  ---
2785
- ${i}`}function Tr(t){return t.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 Ns(t,n){let e=ke(t),o=ke(t,n);if($s(e,o).startsWith("..")||ke(o)!==o.replace(/\.\./g,""))throw new Error(`Invalid path: "${n}" would escape base directory`);return o}function kr(t,n,e,o){let r=Q(t,"SKILL.md");if(Dt(t,{recursive:!0}),Ft(r,Rn(n,o),"utf-8"),e&&e.length>0){let i=Q(t,"references");Dt(i,{recursive:!0});for(let a of e){let s=Q(i,`${a.name}.md`);Ft(s,a.content,"utf-8")}}}function Ut(t,n,e={},o){let r={installed:[],skipped:[],errors:[]},i=e.local?process.cwd():Lt();if(e.dir){let a=Ar(ke(e.dir)),s=pe.find(l=>l.dir===a)?.provider;try{let l=ke(e.dir),u=Ns(l,Q("skills",t));kr(u,n,o,s),r.installed.push(e.dir)}catch(l){r.errors.push(`${e.dir}: ${l instanceof Error?l.message:String(l)}`)}}else for(let a of pe){let s=Q(i,a.dir),l=Q(s,"skills",t),u=Q(l,"SKILL.md");if(We(s)){if(We(u)&&!e.force){r.skipped.push(a.name);continue}try{kr(l,n,o,a.provider),r.installed.push(a.name)}catch(f){r.errors.push(`${a.name}: ${f instanceof Error?f.message:String(f)}`)}}}return r}function _t(t,n={}){let e={removed:[],errors:[]},o=n.local?process.cwd():Lt();for(let r of pe){let i=Q(o,r.dir,"skills",t);if(We(i))try{Rr(i,{recursive:!0}),e.removed.push(r.name)}catch(a){e.errors.push(`${r.name}: ${a instanceof Error?a.message:String(a)}`)}}return e}function $r(){return pe.map(t=>t.name)}function Er(t,n,e={}){let o={installed:[],skipped:[],errors:[]};if(e.dir){let a=Ar(ke(e.dir)),s=pe.find(v=>v.dir===a),l=s?.agentSuffix??".md",u=Q(ke(e.dir),"agents"),f=Q(u,`${t}${l}`);if(We(f)&&!e.force)o.skipped.push(e.dir);else try{Dt(u,{recursive:!0}),Ft(f,Rn(n,s?.provider),"utf-8"),o.installed.push(e.dir)}catch(v){o.errors.push(`${e.dir}: ${v instanceof Error?v.message:String(v)}`)}return o}let r=Lt(),i=pe.filter(a=>a.dir===".claude"||a.dir===".github"||a.dir===".codex");for(let a of i){let s=a.agentSuffix??".md",l=Q(r,a.dir,"agents"),u=Q(l,`${t}${s}`);if(We(u)&&!e.force){o.skipped.push(a.name);continue}try{Dt(l,{recursive:!0}),Ft(u,Rn(n,a.provider),"utf-8"),o.installed.push(a.name)}catch(f){o.errors.push(`${a.name}: ${f instanceof Error?f.message:String(f)}`)}}return o}function Or(t){let n={removed:[],errors:[]},e=Lt(),o=pe.filter(r=>r.dir===".claude"||r.dir===".github"||r.dir===".codex");for(let r of o){let i=r.agentSuffix??".md",a=Q(e,r.dir,"agents",`${t}${i}`);if(We(a))try{Rr(a),n.removed.push(r.name)}catch(s){n.errors.push(`${r.name}: ${s instanceof Error?s.message:String(s)}`)}}return n}function An(){return`---
2785
+ ${i}`}function Tr(t,n){return n==="codex"?Ds(t):Er(t,n)}function kr(t){return t.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 Fs(t,n){let e=ke(t),o=ke(t,n);if(Os(e,o).startsWith("..")||ke(o)!==o.replace(/\.\./g,""))throw new Error(`Invalid path: "${n}" would escape base directory`);return o}function Rr(t,n,e,o){let r=Q(t,"SKILL.md");if(Dt(t,{recursive:!0}),Ft(r,Er(n,o),"utf-8"),e&&e.length>0){let i=Q(t,"references");Dt(i,{recursive:!0});for(let a of e){let s=Q(i,`${a.name}.md`);Ft(s,a.content,"utf-8")}}}function Ut(t,n,e={},o){let r={installed:[],skipped:[],errors:[]},i=e.local?process.cwd():Lt();if(e.dir){let a=$r(ke(e.dir)),s=pe.find(l=>l.dir===a)?.provider;try{let l=ke(e.dir),u=Fs(l,Q("skills",t));Rr(u,n,o,s),r.installed.push(e.dir)}catch(l){r.errors.push(`${e.dir}: ${l instanceof Error?l.message:String(l)}`)}}else for(let a of pe){let s=Q(i,a.dir),l=Q(s,"skills",t),u=Q(l,"SKILL.md");if(We(s)){if(We(u)&&!e.force){r.skipped.push(a.name);continue}try{Rr(l,n,o,a.provider),r.installed.push(a.name)}catch(f){r.errors.push(`${a.name}: ${f instanceof Error?f.message:String(f)}`)}}}return r}function _t(t,n={}){let e={removed:[],errors:[]},o=n.local?process.cwd():Lt();for(let r of pe){let i=Q(o,r.dir,"skills",t);if(We(i))try{Ar(i,{recursive:!0}),e.removed.push(r.name)}catch(a){e.errors.push(`${r.name}: ${a instanceof Error?a.message:String(a)}`)}}return e}function Or(){return pe.map(t=>t.name)}function Pr(t,n,e={}){let o={installed:[],skipped:[],errors:[]};if(e.dir){let a=$r(ke(e.dir)),s=pe.find(v=>v.dir===a),l=s?.agentSuffix??".md",u=Q(ke(e.dir),"agents"),f=Q(u,`${t}${l}`);if(We(f)&&!e.force)o.skipped.push(e.dir);else try{Dt(u,{recursive:!0}),Ft(f,Tr(n,s?.provider),"utf-8"),o.installed.push(e.dir)}catch(v){o.errors.push(`${e.dir}: ${v instanceof Error?v.message:String(v)}`)}return o}let r=Lt(),i=pe.filter(a=>a.dir===".claude"||a.dir===".github"||a.dir===".codex");for(let a of i){let s=a.agentSuffix??".md",l=Q(r,a.dir,"agents"),u=Q(l,`${t}${s}`);if(We(u)&&!e.force){o.skipped.push(a.name);continue}try{Dt(l,{recursive:!0}),Ft(u,Tr(n,a.provider),"utf-8"),o.installed.push(a.name)}catch(f){o.errors.push(`${a.name}: ${f instanceof Error?f.message:String(f)}`)}}return o}function Nr(t){let n={removed:[],errors:[]},e=Lt(),o=pe.filter(r=>r.dir===".claude"||r.dir===".github"||r.dir===".codex");for(let r of o){let i=r.agentSuffix??".md",a=Q(e,r.dir,"agents",`${t}${i}`);if(We(a))try{Ar(a),n.removed.push(r.name)}catch(s){n.errors.push(`${r.name}: ${s instanceof Error?s.message:String(s)}`)}}return n}function Rn(){return`---
2786
2786
  name: video-scene-reviewer
2787
2787
  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.
2788
2788
  tools: Read, Glob
@@ -2879,7 +2879,7 @@ Priority fixes:
2879
2879
  - Scene under 80 lines with 5+ seconds duration = flag as too simple
2880
2880
  - Be specific in fixes: exact icon name, exact component, exact file
2881
2881
  - 85% pass rate minimum. Below = not ready for render
2882
- `}function $n(){return`---
2882
+ `}function An(){return`---
2883
2883
  name: video-scene-builder
2884
2884
  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.
2885
2885
  tools: Read, Write, Edit, Glob, Grep, Task, Bash
@@ -3062,7 +3062,7 @@ function AnimatedCamera() {
3062
3062
  - Don't download assets \u2014 the main AI already did that
3063
3063
  - Don't run render commands \u2014 the main AI handles that
3064
3064
  - Don't modify video-plan.md \u2014 it's read-only to you
3065
- `}function En(t){return`---
3065
+ `}function $n(t){return`---
3066
3066
  name: video-audio-director
3067
3067
  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.
3068
3068
  tools: Read, Bash, Write
@@ -3222,7 +3222,7 @@ This saves money and time \u2014 generation is expensive, downloading is free.
3222
3222
  - Don't choose voices \u2014 use the voice from your input
3223
3223
  - Don't skip the timing manifest \u2014 it's the critical handoff to scene builders
3224
3224
  - Don't re-generate audio if it was already generated successfully (see Error Handling above)
3225
- `}function On(){return`---
3225
+ `}function En(){return`---
3226
3226
  name: video-continuity-editor
3227
3227
  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.
3228
3228
  tools: Read, Glob, Grep
@@ -3333,7 +3333,7 @@ FIXES:
3333
3333
  - Focus on CROSS-SCENE issues. Per-scene quality is the reviewer's job.
3334
3334
  - Be specific in fixes: exact file, exact line, exact component.
3335
3335
  - 85% pass rate minimum.
3336
- `}function Pn(t){let n=t?.cmd??"mf";return`---
3336
+ `}function On(t){let n=t?.cmd??"mf";return`---
3337
3337
  name: video-branding-director
3338
3338
  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.
3339
3339
  tools: Read, Bash, Write
@@ -3436,7 +3436,7 @@ Query: <what was searched/extracted>
3436
3436
  - Download logos or images from websites directly (only from branding.json URLs after successful extraction)
3437
3437
  - Create or edit branding.json by hand
3438
3438
  - Ask the user questions \u2014 return failure to the orchestrator instead
3439
- `}function Pr(t){return`---
3439
+ `}function Dr(t){return`---
3440
3440
  name: remotion-scene-craft
3441
3441
  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.
3442
3442
  ---
@@ -3711,57 +3711,57 @@ const glow = interpolate(Math.sin(frame / fps * Math.PI * 2 / 2), [-1, 1], [0.1,
3711
3711
  - Static scenes with no visual change for 2+ seconds -> Every 2s needs a visual event.
3712
3712
  - Generic component substitution -> Plan says WhipPan, use WhipPan. Not slide() or wipe().
3713
3713
  - 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.
3714
- `}var it=["main","video","presentation","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","config"],Mt=["standalone","studio"],Nr={cmd:p.commands[0],pkg:p.packageName,url:p.apiUrl,name:p.name},He=new Ds("skill").description(`Manage ${p.displayName} skills for AI coding assistants`).addHelpText("after",`
3715
- ${U.bold("Skill Types:")}
3716
- ${U.cyan("main")} Main CLI skill with all capabilities overview
3717
- ${U.cyan("video")} Detailed video creation workflow with Remotion/R3F patterns
3718
- ${U.cyan("presentation")} Detailed presentation creation workflow
3719
- ${U.cyan("presentation-edit")} In-app presentation editing (Studio)
3720
-
3721
- ${U.bold("Reference Skills:")}
3722
- ${U.cyan("tts")} Text-to-speech generation (voices, providers, options)
3723
- ${U.cyan("music")} AI music generation (prompts, styles, duration)
3724
- ${U.cyan("sfx")} Sound effects generation (categories, looping, formats)
3725
- ${U.cyan("mix")} Audio mixing (video + voice + music)
3726
- ${U.cyan("image")} Image search and AI generation
3727
- ${U.cyan("video-search")} Stock video search
3728
- ${U.cyan("scrape")} URL content extraction
3729
- ${U.cyan("branding")} Brand profile management
3730
- ${U.cyan("config")} CLI configuration management
3731
-
3732
- ${U.bold("Examples:")}
3733
- ${U.gray("# Install main CLI skill (comprehensive overview)")}
3714
+ `}var it=["main","video","presentation","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","config"],Mt=["standalone","studio"],Fr={cmd:p.commands[0],pkg:p.packageName,url:p.apiUrl,name:p.name},He=new Ls("skill").description(`Manage ${p.displayName} skills for AI coding assistants`).addHelpText("after",`
3715
+ ${M.bold("Skill Types:")}
3716
+ ${M.cyan("main")} Main CLI skill with all capabilities overview
3717
+ ${M.cyan("video")} Detailed video creation workflow with Remotion/R3F patterns
3718
+ ${M.cyan("presentation")} Detailed presentation creation workflow
3719
+ ${M.cyan("presentation-edit")} In-app presentation editing (Studio)
3720
+
3721
+ ${M.bold("Reference Skills:")}
3722
+ ${M.cyan("tts")} Text-to-speech generation (voices, providers, options)
3723
+ ${M.cyan("music")} AI music generation (prompts, styles, duration)
3724
+ ${M.cyan("sfx")} Sound effects generation (categories, looping, formats)
3725
+ ${M.cyan("mix")} Audio mixing (video + voice + music)
3726
+ ${M.cyan("image")} Image search and AI generation
3727
+ ${M.cyan("video-search")} Stock video search
3728
+ ${M.cyan("scrape")} URL content extraction
3729
+ ${M.cyan("branding")} Brand profile management
3730
+ ${M.cyan("config")} CLI configuration management
3731
+
3732
+ ${M.bold("Examples:")}
3733
+ ${M.gray("# Install main CLI skill (comprehensive overview)")}
3734
3734
  $ ${p.commands[0]} skill install main
3735
3735
 
3736
- ${U.gray("# Install video skill")}
3736
+ ${M.gray("# Install video skill")}
3737
3737
  $ ${p.commands[0]} skill install video
3738
3738
 
3739
- ${U.gray("# Install presentation skill")}
3739
+ ${M.gray("# Install presentation skill")}
3740
3740
  $ ${p.commands[0]} skill install presentation
3741
3741
 
3742
- ${U.gray("# Install all skills")}
3742
+ ${M.gray("# Install all skills")}
3743
3743
  $ ${p.commands[0]} skill install
3744
3744
 
3745
- ${U.gray("# Install to specific directory")}
3745
+ ${M.gray("# Install to specific directory")}
3746
3746
  $ ${p.commands[0]} skill install main --dir ~/.claude
3747
3747
 
3748
- ${U.gray("# Show skill content")}
3748
+ ${M.gray("# Show skill content")}
3749
3749
  $ ${p.commands[0]} skill show main
3750
- `);He.command("install").description(`Install ${p.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(t,n)=>{n.mode&&!Mt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Mt.join(", ")}`),process.exit(1));let e={...Nr,mode:n.mode},o=[];t&&!it.includes(t)&&(c(`Invalid skill type: ${t}. Must be one of: ${it.join(", ")}`),process.exit(1));let r=[{name:"tts",content:Le(e)},{name:"music",content:Ue(e)},{name:"sfx",content:_e(e)},{name:"mix",content:Me(e)},{name:"image",content:Ve(e)},{name:"video-search",content:je(e)},{name:"scrape",content:qe(e)},{name:"branding",content:Be(e)},{name:"config",content:Ge(e)}];(!t||t==="main")&&o.push({name:p.name,content:Et(e),references:r});let i=[{name:"brief-guide",content:Tn.render(e)},{name:"website-assets",content:In.render(e)},{name:"source-scraping",content:kn.render(e)}];(!t||t==="video")&&(o.push({name:`${p.name}-video`,content:Ot(e),references:i}),o.push({name:"remotion-scene-craft",content:Pr(e)})),(!t||t==="presentation")&&o.push({name:`${p.name}-presentation`,content:Pt(e)}),(!t||t==="presentation-edit")&&o.push({name:`${p.name}-presentation-edit`,content:Nt(e)}),t==="tts"&&o.push({name:`${p.name}-tts`,content:Le(e)}),t==="music"&&o.push({name:`${p.name}-music`,content:Ue(e)}),t==="sfx"&&o.push({name:`${p.name}-sfx`,content:_e(e)}),t==="mix"&&o.push({name:`${p.name}-mix`,content:Me(e)}),t==="image"&&o.push({name:`${p.name}-image`,content:Ve(e)}),t==="video-search"&&o.push({name:`${p.name}-video-search`,content:je(e)}),t==="scrape"&&o.push({name:`${p.name}-scrape`,content:qe(e)}),t==="branding"&&o.push({name:`${p.name}-branding`,content:Be(e)}),t==="config"&&o.push({name:`${p.name}-config`,content:Ge(e)}),console.log();for(let a of o){m(`Installing ${a.name}...`);let s=Ut(a.name,a.content,{dir:n.dir,local:n.local,force:n.force},a.references);if(s.installed.length>0&&(C(`${a.name} installed successfully`),T(" Installed to",s.installed.join(", "))),s.skipped.length>0&&(m(` Skipped (already exists): ${s.skipped.join(", ")}`),console.log(U.gray(" Use --force to overwrite"))),s.errors.length>0)for(let l of s.errors)c(` ${l}`);s.installed.length===0&&s.skipped.length===0&&s.errors.length===0&&(m(" No supported AI coding assistants detected"),console.log(U.gray(" Supported editors: "+$r().join(", "))),console.log(U.gray(" Use --dir <path> to install to a specific directory"))),console.log()}if(!t||t==="video"){for(let a of[{name:"video-branding-director",generate:()=>Pn(e)},{name:"video-scene-builder",generate:$n},{name:"video-scene-reviewer",generate:An},{name:"video-audio-director",generate:()=>En(e)},{name:"video-continuity-editor",generate:On}]){m(`Installing ${a.name} agent...`);let s=Er(a.name,a.generate(),{force:n.force,dir:n.dir});if(s.installed.length>0){C(`${a.name} agent installed`);let l={"Claude Code":"~/.claude/agents/","GitHub Copilot":"~/.github/agents/"};T(" Installed to",s.installed.map(u=>n.dir?u:`${u} (${l[u]??"~/.<editor>/agents/"})`).join(", "))}s.skipped.length>0&&m(` Agent skipped (already exists): ${s.skipped.join(", ")}`)}console.log()}});He.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action((t="main",n)=>{n.mode&&!Mt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Mt.join(", ")}`),process.exit(1));let e={...Nr,mode:n.mode},r={main:()=>Et(e),video:()=>Ot(e),presentation:()=>Pt(e),"presentation-edit":()=>Nt(e),tts:()=>Le(e),music:()=>Ue(e),sfx:()=>_e(e),mix:()=>Me(e),image:()=>Ve(e),"video-search":()=>je(e),scrape:()=>qe(e),branding:()=>Be(e),config:()=>Ge(e),"video-branding-director":()=>Pn(e),"video-scene-builder":()=>$n(),"video-scene-reviewer":()=>An(),"video-audio-director":()=>En(e),"video-continuity-editor":()=>On()}[t];if(r)console.log(r());else{let i=[...it,"video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"];c(`Invalid skill type: ${t}. Must be one of: ${i.join(", ")}`),process.exit(1)}});He.command("uninstall").description(`Remove ${p.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(t,n)=>{let e=[];t&&!it.includes(t)&&(c(`Invalid skill type: ${t}. Must be one of: ${it.join(", ")}`),process.exit(1)),(!t||t==="main")&&e.push(p.name),(!t||t==="video")&&(e.push(`${p.name}-video`),e.push("remotion-scene-craft")),(!t||t==="presentation")&&e.push(`${p.name}-presentation`),(!t||t==="presentation-edit")&&e.push(`${p.name}-presentation-edit`),(!t||t==="tts")&&e.push(`${p.name}-tts`),(!t||t==="music")&&e.push(`${p.name}-music`),(!t||t==="sfx")&&e.push(`${p.name}-sfx`),(!t||t==="mix")&&e.push(`${p.name}-mix`),(!t||t==="image")&&e.push(`${p.name}-image`),(!t||t==="video-search")&&e.push(`${p.name}-video-search`),(!t||t==="scrape")&&e.push(`${p.name}-scrape`),(!t||t==="branding")&&e.push(`${p.name}-branding`),(!t||t==="config")&&e.push(`${p.name}-config`),console.log();for(let o of e){let r=_t(o,{local:n.local});if(r.removed.length>0?(C(`${o} uninstalled`),T(" Removed from",r.removed.join(", "))):m(` ${o} not found`),r.errors.length>0)for(let i of r.errors)L(` Failed to remove: ${i}`)}if(!t||t==="video")for(let o of["video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"])Or(o).removed.length>0&&C(`${o} agent uninstalled`);console.log()});import{Command as Fs}from"commander";import at from"chalk";var Dr=new Fs("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(t,n)=>{await E();try{let e=Number.parseInt(n.limit??"25",10),{templates:o}=await wo(t,Number.isFinite(e)?e: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?at.green("default"):null,r.category??null,r.recommendedModes?.length?`modes: ${r.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${at.bold(r.name)} ${at.gray(r.id)}${i?`
3751
- ${at.gray(i)}`:""}`)}console.log(),console.log(at.gray(`Use one with: ${p.commands[0]} create "<topic>" --template <id>`))}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as Ls}from"commander";import Nn from"chalk";var Fr=new Ls("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)","human").action(async t=>{await E();try{let n=await he();if(gn(),t.format==="json"){console.log(JSON.stringify(n,null,2));return}me("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 e=n.authType==="apiKey"?"API Key":n.authType==="oauth"?"OAuth":"Session";if(T("Auth Type",e),n.currentTeam&&(console.log(),me("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(),me("All Teams"),console.log();for(let o of n.teams){let r=o.isCurrent?Nn.green(" (current)"):"";console.log(` ${Nn.bold(o.name)}${r}`),console.log(Nn.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 Lr(t){return t[0]==="--"?t.slice(1):t}import{Command as Dn}from"commander";function Us(t,n){return[...n,t]}var _s=new Dn("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",Us,[]).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await A("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:t}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),Ms=new Dn("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("createAdSet",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Ur=new Dn("ad-set").description("Ad set commands").addCommand(_s).addCommand(Ms);import{Command as Mr}from"commander";function _r(t){return new Mr(t).description(t==="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,e)=>{if(!e.yes)return c("Pass --yes to approve this operation");try{x(await A(t==="create"?"createAgent":"recommendAgent",{approvalReceipt:"cli:--yes",description:e.description,instructionsMarkdown:e.instructions,name:n,output:e.output,schedule:e.schedule,scheduleTime:e.time,teamId:e.teamId,timezone:e.timezone}))}catch(o){c(o instanceof Error?o.message:"Agent operation failed"),process.exit(d.GENERAL_ERROR)}})}var Vr=new Mr("agent").description("Scheduled agent commands").addCommand(_r("create")).addCommand(_r("recommend"));import{Command as Vt}from"commander";import qs from"ora";import{mkdir as Vs,writeFile as jr}from"fs/promises";import{dirname as js}from"path";async function we(t,n){if(await Vs(js(n),{recursive:!0}),t.startsWith("data:")){let r=t.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 jr(n,i);return}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to download media: ${e.status}`);let o=Buffer.from(await e.arrayBuffer());if(o.length===0)throw new Error("Downloaded media was empty");await jr(n,o)}var Bs=15e3,Gs=40;function Fn(t,n){if(n==="json"){x(t);return}if(n==="quiet"){console.log(t.videoUrl??t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.durationSec!=null&&m(`Duration: ${t.durationSec}s`),t.videoUrl&&C(`Video URL: ${t.videoUrl}`),t.error&&c(`Error: ${t.error}`)}var Ws=new Vt("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 t=>{try{let n=await Do(t.language);if(t.format==="json"){x(n);return}let e=n.personal??[];if(t.format==="quiet"){for(let o of e)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(e.length>0){m("Your presenters:");for(let o of e)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(d.GENERAL_ERROR)}}),Hs=new Vt("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 t=>{let n=t.transparent?"webm":t.outputFormat;!!t.audioUrl==!!t.script&&(c("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(d.INVALID_INPUT)),["1:1","9:16","16:9"].includes(t.aspect)||(c("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(d.INVALID_INPUT)),t.outputFormat!==void 0&&!["mp4","webm"].includes(t.outputFormat)&&(c("Output format must be mp4 or webm"),process.exit(d.INVALID_INPUT)),t.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(t.backgroundColor)&&(c("Background color must be a six-digit hex value"),process.exit(d.INVALID_INPUT)),t.backgroundColor&&t.backgroundImageUrl&&(c("Provide only one presenter background"),process.exit(d.INVALID_INPUT)),t.fit!==void 0&&!["contain","cover"].includes(t.fit)&&(c("Fit must be contain or cover"),process.exit(d.INVALID_INPUT)),t.fit&&!t.backgroundImageUrl&&(c("Fit requires --background-image-url"),process.exit(d.INVALID_INPUT)),t.transparent&&t.outputFormat==="mp4"&&(c("--transparent cannot be combined with --output-format mp4"),process.exit(d.INVALID_INPUT)),n==="webm"&&(t.backgroundColor||t.backgroundImageUrl)&&(c("Transparent WebM output cannot be combined with a background"),process.exit(d.INVALID_INPUT)),["basic","standard","premium"].includes(t.renderTier)||(c("Render tier must be basic, standard, or premium"),process.exit(d.INVALID_INPUT));let e=t.duration?Number.parseInt(t.duration,10):void 0;e!==void 0&&(!Number.isFinite(e)||e<1||e>300)&&(c("Duration must be between 1 and 300 seconds"),process.exit(d.INVALID_INPUT));let o=t.format==="human"?qs("Generating presenter clip...").start():null;try{let r=t.audioUrl?{audioUrl:t.audioUrl}:{script:t.script??"",...t.voiceId?{voiceId:t.voiceId}:{}},i=await Fo({...r,aspect:t.aspect,...t.avatarId?{avatarId:t.avatarId}:{},...t.backgroundColor?{backgroundHex:t.backgroundColor}:{},...t.backgroundImageUrl?{backgroundImageUrl:t.backgroundImageUrl}:{},...e!==void 0?{durationSec:e}:{},...t.fit?{fit:t.fit}:{},...n?{outputFormat:n}:{},renderTier:t.renderTier,title:t.title});if(!t.wait){o?.stop(),Fn(i,t.format);return}let a=await ue(()=>dn(i.requestId),Gs,Bs);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 we(a.videoUrl,t.output),o?.stop(),Fn(a,t.format),t.format==="human"&&C(`Saved to: ${t.output}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Js=new Vt("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(t,n)=>{try{Fn(await dn(t),n.format)}catch(e){c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),qr=new Vt("avatar").description("Avatar/presenter media commands").addCommand(Ws).addCommand(Hs).addCommand(Js);import{writeFile as Br}from"fs/promises";import H from"chalk";import{Command as re}from"commander";import zs from"ora";var Gr=new re("branding").description("Manage brand profiles").addCommand(new re("list").description("List brand profiles").option("-f, --format <format>","Output format (table, json)","table").action(async t=>{await E();try{let n=await an();if(n.brandings.length===0){t.format==="json"?console.log(JSON.stringify([])):(m("No brand profiles found"),console.log(),console.log(H.gray(`Create one with: ${p.commands[0]} branding extract <url>`)));return}t.format==="json"?console.log(JSON.stringify(n.brandings,null,2)):console.log(Vo(n.brandings))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new re("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(t,n)=>{await E();try{let e=await So(t);if(n.output){await Br(n.output,JSON.stringify(e,null,2)),C(`Brand profile saved to ${n.output}`);return}if(n.format==="json")console.log(JSON.stringify(e,null,2));else{if(me("Brand Profile"),console.log(),T("ID",e.id),T("Name",e.name),T("Source URL",e.sourceUrl??H.gray("None")),T("Default",e.isDefault?H.green("Yes"):"No"),e.createdAt&&T("Created",new Date(e.createdAt).toLocaleString()),console.log(),e.primaryColor||e.colors.length>0){if(console.log(H.bold(" Colors")),e.primaryColor){let r=H.bgHex(e.primaryColor)(" ");console.log(` Primary: ${r} ${e.primaryColor}`)}if(e.colors.length>0){console.log(" Palette:");for(let r of e.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()}e.logoUrl&&(console.log(H.bold(" Logo")),console.log(` ${e.logoUrl}`),console.log());let o=e.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()),(e.confidence||e.extractionMethod)&&(console.log(H.bold(" Extraction")),e.confidence&&console.log(` Confidence: ${Math.round(e.confidence*100)}%`),e.extractionMethod&&console.log(` Method: ${e.extractionMethod}`),console.log()),console.log(H.gray(" Use --format json for full details")),console.log()}}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}})).addCommand(new re("find").description("Find existing brand profile by name or URL").argument("<query>","Brand name or website URL to search for").action(async t=>{await E();try{let n=await an(),e=t.toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,""),o=n.brandings.filter(r=>{let i=(r.name||"").toLowerCase(),a=(r.sourceUrl||"").toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,"");return i.includes(e)||a.includes(e)||i.length>0&&e.includes(i)||a.length>0&&e.includes(a)});if(o.length===0){m(`No brand profiles matching "${t}"`),console.log(H.gray(` Extract one with: ${p.commands[0]} branding extract <url>`));return}console.log(`Found ${o.length} brand${o.length>1?"s":""}:
3752
- `);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: ${p.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 re("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(t,n)=>{await E(),n.yes||(c("Pass --yes to confirm brand extraction."),process.exit(d.INVALID_INPUT));try{new URL(t.startsWith("http")?t:`https://${t}`)}catch{c("Invalid URL format"),process.exit(6)}let e=t.startsWith("http")?t:`https://${t}`,o=n.teamId??ut(),r=zs({text:`Extracting branding from ${e}...`,stream:process.stdout}).start();try{let i=await Co(e,o,"cli:--yes");r.succeed("Brand extraction started");let a=JSON.stringify(i,null,2);n.output?(await Br(n.output,a),C(`Brand profile saved to ${n.output}`)):console.log(a),m(`Check progress with: ${p.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 re("status").description("Check a brand extraction run").argument("<run-id>","Run ID returned by branding extract").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("extractBranding",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}})).addCommand(new re("set-default").description("Set a brand profile as default").argument("<id>","Brand profile ID").action(async t=>{await E(),m(`To set brand ${t} as default, use the web dashboard.`),console.log(),console.log(H.gray("API support for setting default brand is coming soon."))})).addCommand(new re("competitor").description("Brand competitor commands").addCommand(new re("list").description("List competitors for a brand").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").action(async t=>{try{console.log(JSON.stringify(await A("getBrandCompetitors",{brandingId:t.brandingId,teamId:t.teamId}),null,2))}catch(n){c(n instanceof Error?n.message:"Lookup failed"),process.exit(1)}})).addCommand(new re("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(t,n)=>{n.yes||(c("Pass --yes to confirm adding a competitor."),process.exit(d.INVALID_INPUT));try{x(await A("addCompetitor",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,name:t,teamId:n.teamId,website:n.website,xHandle:n.xHandle}))}catch(e){c(e instanceof Error?e.message:"Write failed"),process.exit(d.GENERAL_ERROR)}}))).addCommand(new re("social").description("Brand social handle commands").addCommand(new re("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(t,n,e)=>{e.yes||(c("Pass --yes to confirm adding a social handle."),process.exit(d.INVALID_INPUT));try{x(await A("addBrandSocialHandle",{approvalReceipt:"cli:--yes",brandingId:e.brandingId,handle:n,platform:t,teamId:e.teamId}))}catch(o){c(o instanceof Error?o.message:"Write failed"),process.exit(d.GENERAL_ERROR)}})));import{readFile as Ys}from"fs/promises";import{Command as Wr}from"commander";var Xs=new Wr("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(t,n)=>{try{let e=t,o;t.includes("://")||(e=await Ys(t,"utf8"),o=t);let r=await A("extractContent",{filename:o,maxLength:Number.parseInt(n.maxLength,10),mimeType:n.mimeType,source:e,teamId:n.teamId});n.format!=="quiet"&&x(r)}catch(e){c(e instanceof Error?e.message:"Extraction failed"),process.exit(d.GENERAL_ERROR)}}),Hr=new Wr("content").description("Content extraction commands").addCommand(Xs);import X from"chalk";import{Command as Ks}from"commander";import{existsSync as Qs,readFileSync as Zs}from"fs";import ec,{resolve as Jr}from"path";var zr=new Ks("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(t,n)=>{await E();let e;n.slides!==void 0&&(e=parseInt(n.slides,10),(Number.isNaN(e)||e<1||e>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 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 f=["blue","violet","rose","orange","green"];n.theme&&!f.includes(n.theme)&&(c(`Invalid theme: ${n.theme}. Valid: ${f.join(", ")}`),process.exit(6));let v=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];n.decorations&&!v.includes(n.decorations)&&(c(`Invalid decorations: ${n.decorations}. Valid: ${v.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 g=n.mode??(I?"instant":"fast"),S=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[w,V]of[["primary-color",n.primaryColor],["secondary-color",n.secondaryColor],["accent-color",n.accentColor],["background-color",n.backgroundColor],["foreground-color",n.foregroundColor]])V&&!S.test(V)&&(c(`Invalid ${w}: ${V}. Must be hex (e.g., #0066CC)`),process.exit(6));try{n.output!=="json"&&n.output!=="quiet"&&process.stdout.write(X.gray("Checking generation limits... "));let w=await ko(g,e??10,n.teamId);if(n.output!=="json"&&n.output!=="quiet"){console.log(X.green("\u2713"));let V=w.remaining[g],q=w.limits[g],ee=V===void 0||q===void 0?"":` | ${g}: ${V}/${q} remaining`;console.log(X.gray(` Plan: ${w.planName}${ee}`))}}catch(w){n.output==="json"?console.log(JSON.stringify({success:!1,error:w instanceof Error?w.message:String(w)})):(console.log(X.red("\u2717")),c(w instanceof Error?w.message:String(w))),process.exit(w.exitCode??1)}let y=[];if(n.file&&n.file.length>0){for(let w of n.file)Qs(Jr(w))||(c(`File not found: ${w}`),process.exit(6));n.output!=="json"&&n.output!=="quiet"&&console.log(X.gray(`
3753
- Uploading ${n.file.length} file(s)...`));try{y=await fo(n.file.map(w=>Jr(w)),(w,V,q)=>{n.output!=="json"&&n.output!=="quiet"&&q&&process.stdout.write(`\r ${X.cyan("\u2B06")} Uploading: ${q} (${w+1}/${V})`)}),n.output!=="json"&&n.output!=="quiet"&&console.log(`\r ${X.green("\u2713")} Uploaded ${y.length} file(s) `)}catch(w){c(`Failed to upload files: ${w instanceof Error?w.message:String(w)}`),process.exit(1)}}let b;(n.stdin||!process.stdin.isTTY)&&(b=await tc(),n.stdin&&!b&&(c("No content received from stdin"),process.exit(6)));let R=n.context;if(n.contextFile)try{R=Zs(n.contextFile,"utf-8"),R.trim()||(c(`Context file is empty: ${n.contextFile}`),process.exit(6))}catch{c(`Failed to read context file: ${n.contextFile}`),process.exit(6)}!b&&!R&&y.length===0&&(c("Context is required to create a presentation."),console.log(),console.log(X.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(X.gray(" -c, --context <text> Inline text context")),console.log(X.gray(" --context-file <path> Read from a file")),console.log(X.gray(` cat file | ${p.commands[0]} Pipe content`)),process.exit(6));let M=[...y];b&&M.push({id:`stdin-${Date.now()}`,content:b,title:"Piped Content",mime:"text/plain",selected:!0}),R&&M.push({id:`context-${Date.now()}`,content:R,title:"Context",mime:"text/plain",selected:!0});let $,_=n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor;(n.theme||_||n.decorations)&&($={},n.theme&&($.preset=n.theme),_&&($.custom={},n.primaryColor&&($.custom.primary=n.primaryColor),n.secondaryColor&&($.custom.secondary=n.secondaryColor),n.accentColor&&($.custom.accent=n.accentColor),n.backgroundColor&&($.custom.background=n.backgroundColor),n.foregroundColor&&($.custom.foreground=n.foregroundColor)),n.decorations&&($.decorations=n.decorations));try{let w=await ho({topic:t,...e!==void 0&&{slideCount:e},mode:g,...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},...$&&{theme:$},...n.studio?{documentId:ec.basename(process.cwd())}:n.id?{documentId:n.id}:{},...M.length>0&&{contentSources:{uploadedFiles:M,contextFiles:[]}}});if(!n.wait){n.output==="json"?console.log(JSON.stringify({success:!0,run:w},null,2)):n.output!=="quiet"&&(C("Presentation generation queued"),T("Run ID",w.runId),T("Status",w.status),console.log(X.gray(` Check later with presentation status ${w.runId}`)));return}let V=await F("createSlides",w.runId,n.teamId);for(;!V.done;)n.output!=="json"&&n.output!=="quiet"&&console.log(X.gray(` ${V.message}`)),await new Promise(ee=>setTimeout(ee,(V.nextPollAfterSeconds??5)*1e3)),V=await F("createSlides",w.runId,n.teamId);if(V.error)throw new Error(V.error.message);let q=V.entity?await xe(V.entity.id):void 0;if(n.output==="json")console.log(JSON.stringify({success:!0,presentation:q,run:V,viewUrl:q?Pe(q.slug,n.language??"en"):void 0},null,2));else{console.log(),C("Presentation created successfully"),console.log(),T("Title",q?.title??t),T("Slides",String(q?.numberOfSlides??e??"\u2014")),console.log();let ee=q?Pe(q.slug,n.language??"en"):"N/A";ee!=="N/A"&&(console.log(X.bold(" Open: ")+X.cyan.underline(ee)),n.open&&await(await import("open")).default(ee)),console.log()}}catch(w){n.output==="json"?console.log(JSON.stringify({success:!1,error:w instanceof Error?w.message:String(w)})):c(w instanceof Error?w.message:String(w)),process.exit(w.exitCode??1)}});async function tc(){return new Promise(t=>{let n="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){t("");return}process.stdin.on("data",e=>{n+=e}),process.stdin.on("end",()=>{t(n.trim())}),setTimeout(()=>{t(n.trim())},100)})}import{Command as nc}from"commander";import jt from"chalk";var Yr=new nc("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(t,n)=>{await E();try{let e=await xe(t);if(n.format==="json"){console.log(JSON.stringify(e,null,2));return}let o=Pe(e.slug,n.language);me("Presentation Details"),console.log(),T("Slug",e.slug),T("Title",e.title||"Untitled"),T("Description",e.description||jt.gray("None")),T("Slides",String(e.numberOfSlides||"-")),T("Mode",e.mode||"-"),T("Created",pn(e.createdAt)),e.updatedAt&&T("Updated",pn(e.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(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as qt}from"commander";import oc from"ora";var rc=new qt("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("--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 t=>{let n=t.format,e=n==="human"?oc("Searching for images...").start():null,o;t.maxResults&&(o=parseInt(t.maxResults,10),(Number.isNaN(o)||o<1)&&(e?.stop(),c("Max results must be a positive number"),process.exit(d.INVALID_INPUT)));try{let r=await wt({query:t.query,options:{maxResults:o||10,size:t.size,safeSearch:t.safeSearch}});e?.stop(),r.success||(c("Search failed"),process.exit(d.GENERAL_ERROR));let i=r.data.results.flatMap(a=>a.results.map(s=>({...s,provider:a.providerName})));if(n==="json"){x({success:!0,query:t.query,totalResults:i.length,images:i});return}if(n==="quiet"){for(let a of i)console.log(a.url);return}if(i.length===0){m("No images found");return}C(`Found ${i.length} images for "${t.query}"`),console.log();for(let a=0;a<i.length;a++){let s=i[a];console.log(`[${a+1}] ${s.title||"Untitled"}`),console.log(` URL: ${s.url}`),console.log(` Size: ${s.width}x${s.height}`),s.author&&console.log(` Author: ${s.author}`),console.log(` Provider: ${s.provider}`),console.log()}m(`Total cost: $${r.data.totalCost.toFixed(4)}`)}catch(r){e?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ic=new qt("generate").description("Start background image generation").argument("<prompt>","Image prompt").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("--yes","Approve generation").action(async(t,n)=>{if(!n.yes)return c("Pass --yes to approve image generation");try{x(await A("createImage",{approvalReceipt:"cli:--yes",height:n.height?Number.parseInt(n.height,10):void 0,model:n.model,prompt:t,provider:n.provider,teamId:n.teamId,width:n.width?Number.parseInt(n.width,10):void 0}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),ac=new qt("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("createImage",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Xr=new qt("image").description("Image search and generation commands").addCommand(rc).addCommand(ic).addCommand(ac);import{Command as Ln}from"commander";var sc=new Ln("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(t,n)=>{try{x(await A("searchKnowledge",{kind:n.kind,limit:Number.parseInt(n.limit,10),query:t,teamId:n.teamId}))}catch(e){c(e instanceof Error?e.message:"Knowledge search failed"),process.exit(d.GENERAL_ERROR)}}),cc=new Ln("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async t=>{try{x(await A("getKnowledgeBundle",{kind:t.kind,teamId:t.teamId}))}catch(n){c(n instanceof Error?n.message:"Knowledge bundle failed"),process.exit(d.GENERAL_ERROR)}}),Kr=new Ln("knowledge").description("Knowledge Hub commands").addCommand(sc).addCommand(cc);import{Command as Un}from"commander";var lc=new Un("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await A("createMicrosite",{approvalReceipt:"cli:--yes",audience:n.audience,brandingId:n.brandingId,description:n.description,language:n.language,teamId:n.teamId,title:t,tone:n.tone}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),dc=new Un("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("createMicrosite",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Qr=new Un("microsite").description("Microsite commands").addCommand(lc).addCommand(dc);import{Command as Vn}from"commander";import _n from"ora";function Mn(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.outputUrl?console.log(t.outputUrl):console.log(t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.outputUrl&&C(`Output URL: ${t.outputUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var uc=new Vn("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 t=>{!t.music&&!t.voice&&(c("At least one of --music or --voice must be provided"),process.exit(d.INVALID_INPUT));let n=parseInt(t.musicVolume,10)/100,e=parseInt(t.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(e)||e<0||e>2)&&(c("Voice volume must be between 0 and 200"),process.exit(d.INVALID_INPUT));let o=t.format,r=o==="human"?_n("Mixing audio...").start():null,i=[{url:t.video,role:"video"}];t.music&&i.push({url:t.music,role:"background",volume:n*5}),t.voice&&i.push({url:t.voice,role:"voice",volume:e*2});try{let a=await Eo({operation:"add-to-video",inputs:i,options:{musicVolume:n,voiceVolume:e}});if(!t.wait){r?.stop(),Mn(a,o);return}r&&(r.text=`Processing (ID: ${a.requestId})...`);let s=await ue(()=>sn(a.requestId),120,3e3);if(r?.stop(),s.status==="failed"&&(c(s.error||"Audio mixing failed"),process.exit(d.GENERAL_ERROR)),Mn(s,o),t.output){if(!s.outputUrl)throw new Error("Audio mix completed without an output URL");let l=o==="human"?_n("Downloading...").start():null;await we(s.outputUrl,t.output),l?.stop(),o==="human"&&C(`Saved to: ${t.output}`)}}catch(a){r?.stop(),c(a instanceof Error?a.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),mc=new Vn("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(t,n)=>{let e=n.format==="human"?_n("Checking status...").start():null;try{let o=await sn(t);e?.stop(),Mn(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Zr=new Vn("mix").description("Audio mixing commands").addCommand(uc).addCommand(mc);import{Command as Bn}from"commander";import jn from"ora";function qn(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.audioUrl?console.log(t.audioUrl):console.log(t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.audioUrl&&C(`Audio URL: ${t.audioUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var pc=new Bn("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>","Provider (elevenlabs, suno)").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 t=>{let n=parseInt(t.duration,10);(Number.isNaN(n)||n<3||n>600)&&(c("Duration must be between 3 and 600 seconds (10 minutes)"),process.exit(d.INVALID_INPUT));let e=t.format,o=e==="human"?jn("Generating music...").start():null;try{let r=await vt({prompt:t.prompt,duration:n,options:{provider:t.provider,style:t.style}});if(!t.wait){o?.stop(),qn(r,e);return}let i=r;if(r.status!=="completed"&&r.status!=="failed"&&(o&&(o.text=`Processing (ID: ${r.requestId})...`),i=await ue(()=>ot(r.requestId),60,2e3)),o?.stop(),i.status==="failed"&&(c(i.error||"Music generation failed"),process.exit(d.GENERAL_ERROR)),qn(i,e),t.output){if(!i.audioUrl)throw new Error("Music completed without an audio URL");let a=e==="human"?jn("Downloading...").start():null;await we(i.audioUrl,t.output),a?.stop(),e==="human"&&C(`Saved to: ${t.output}`)}}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),gc=new Bn("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(t,n)=>{let e=n.format==="human"?jn("Checking status...").start():null;try{let o=await ot(t);e?.stop(),qn(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ei=new Bn("music").description("Music generation commands").addCommand(pc).addCommand(gc);import{Command as Gn}from"commander";function ti(t,n){return[...n,t]}var fc=new Gn("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",ti,[]).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve poll creation");try{x(await A("createPoll",{approvalReceipt:"cli:--yes",options:n.option.map(e=>({text:e})),pollType:n.type,question:t,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Poll creation failed"),process.exit(d.GENERAL_ERROR)}}),hc=new Gn("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",ti).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve poll update");try{x(await A("editPoll",{approvalReceipt:"cli:--yes",options:n.option?.map(e=>({text:e})),pollId:t,pollType:n.type,question:n.question,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Poll update failed"),process.exit(d.GENERAL_ERROR)}}),ni=new Gn("poll").description("Standalone poll commands").addCommand(fc).addCommand(hc);import{Command as oi}from"commander";var yc=new oi("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(t,n)=>{try{let e=await F("createSlides",t,n.teamId);if(n.format==="json"){x(e);return}if(n.format==="quiet"){console.log(e.status);return}m(`Status: ${e.status}`),m(e.message),e.progress!==null&&m(`Progress: ${e.progress}%`),e.error&&c(e.error.message)}catch(e){c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ri=new oi("presentation").description("Presentation background-run commands").addCommand(yc);import{writeFile as bc}from"fs/promises";import{Command as xc}from"commander";import vc from"ora";var ii=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(t,n)=>{let e=n.format,o=e==="human"?vc("Scraping URL...").start():null;try{let r=await Po(t,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 bc(n.output,i.content,"utf-8"),e==="human"&&C(`Content saved to: ${n.output}`)),e==="json"){let{cost:a,...s}=i;x(s);return}if(e==="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&&L(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(d.GENERAL_ERROR)}});import{Command as st}from"commander";function Bt(t,n){n!=="quiet"&&x(t)}var wc=new st("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(t,n)=>{try{let e=await A("searchInternet",{maxResults:Number.parseInt(n.maxResults,10),query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Search failed"),process.exit(d.GENERAL_ERROR)}}),Sc=new st("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(t,n)=>{try{let e=await A("getNews",{maxResults:Number.parseInt(n.maxResults,10),teamId:n.teamId,timeframe:n.timeframe,topic:t});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"News search failed"),process.exit(d.GENERAL_ERROR)}}),Cc=new st("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(t,n)=>{try{let e=await A("searchImages",{aspect:n.aspect,maxResults:Number.parseInt(n.maxResults,10),query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Image search failed"),process.exit(d.GENERAL_ERROR)}}),Ic=new st("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(t,n)=>{try{let e=await A("searchStockVideo",{license:n.license,maxResults:Number.parseInt(n.maxResults,10),orientation:n.orientation,query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Video search failed"),process.exit(d.GENERAL_ERROR)}}),ai=new st("search").description("Web, news, image, and stock-video search").addCommand(wc).addCommand(Sc).addCommand(Cc).addCommand(Ic);import{Command as Jn}from"commander";import Wn from"ora";function Hn(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.audioUrl?console.log(t.audioUrl):t.requestId?console.log(t.requestId):console.log(t.id);return}m(`Request ID: ${t.requestId||t.id}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.audioUrl&&C(`Audio URL: ${t.audioUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var Tc=new Jn("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>","Provider (elevenlabs)","elevenlabs").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 t=>{let n;t.duration&&(n=parseFloat(t.duration),(isNaN(n)||n<.5||n>30)&&(c("Duration must be between 0.5 and 30 seconds"),process.exit(d.INVALID_INPUT)));let e;t.promptInfluence&&(e=parseFloat(t.promptInfluence),(isNaN(e)||e<0||e>1)&&(c("Prompt influence must be between 0 and 1"),process.exit(d.INVALID_INPUT)));let o=t.outputFormat,r=o==="human"?Wn("Generating sound effects...").start():null;try{let i=await No({text:t.text,duration:n,options:{provider:t.provider,promptInfluence:e,loop:t.loop,format:t.format}});if(!t.wait){r?.stop(),Hn(i,o);return}let a=i;if(i.status!=="completed"&&i.status!=="failed"){let s=i.requestId||i.id;r&&(r.text=`Processing (ID: ${s})...`),a=await ue(()=>ln(s),60,2e3)}if(r?.stop(),a.status==="failed"&&(c(a.error||"Sound effects generation failed"),process.exit(d.GENERAL_ERROR)),Hn(a,o),t.output){if(!a.audioUrl)throw new Error("Sound effect completed without an audio URL");let s=o==="human"?Wn("Downloading...").start():null;await we(a.audioUrl,t.output),s?.stop(),o==="human"&&C(`Saved to: ${t.output}`)}}catch(i){r?.stop(),c(i instanceof Error?i.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),kc=new Jn("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(t,n)=>{let e=n.format==="human"?Wn("Checking status...").start():null;try{let o=await ln(t);e?.stop(),Hn(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),si=new Jn("sfx").description("Sound effects generation commands").addCommand(Tc).addCommand(kc);import{Command as Gt}from"commander";import{mkdir as Rc,writeFile as ci}from"fs/promises";import ui from"ora";import{dirname as Ac}from"path";var li="en-US-Neural2-C",di="gemini",$c=new Gt("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: ${li})`).option("-p, --provider <provider>",`Provider: gemini, elevenlabs, openai (default: ${di})`).option("-m, --model <model>","Model (provider-specific)").option("-s, --speed <speed>","Speech speed 0.25-4.0 (default: 1.0)").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 t=>{let n=t.format,e=n==="human"?ui("Generating speech...").start():null,o;t.speed&&(o=parseFloat(t.speed),(isNaN(o)||o<.25||o>4)&&(e?.stop(),c("Speed must be between 0.25 and 4.0"),process.exit(d.INVALID_INPUT)));let r;if(t.speakers)try{r=JSON.parse(t.speakers),(!Array.isArray(r)||r.length>2)&&(e?.stop(),c("Speakers must be an array with max 2 items"),process.exit(d.INVALID_INPUT))}catch{e?.stop(),c(`Invalid --speakers JSON. Example: '[{"name":"Joe","voice":"Kore"}]'`),process.exit(d.INVALID_INPUT)}try{let i=t.voiceId,a=t.voice||li,s=t.provider||di,l={};r&&(l.gemini={speakers:r}),t.instructions&&(l.openai={instructions:t.instructions});let u=await xt({text:t.text,options:{provider:s,voiceId:i,voice:a,model:t.model,speed:o,providerOptions:Object.keys(l).length>0?l:void 0}});e?.stop();let f=t.output.endsWith(`.${u.format}`)?t.output:`${t.output}.${u.format}`;await Rc(Ac(f),{recursive:!0}),await ci(f,u.audioData);let v=f.replace(/\.[^.]+$/,".txt");if(await ci(v,t.text,"utf-8"),n==="json"){x({status:"completed",output:f,audioUrl:u.audioUrl,duration:u.duration,provider:u.provider,format:u.format});return}if(n==="quiet"){console.log(f);return}C(`Saved to: ${f}`),m(`Duration: ${u.duration.toFixed(2)}s`),m(`Provider: ${u.provider}`),m(`Cost: $${u.cost.toFixed(6)}`)}catch(i){e?.stop(),c(i instanceof Error?i.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Ec=new Gt("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 t=>{let n=t.format==="human"?ui("Fetching voices...").start():null;try{let e=await $o(t.provider);if(n?.stop(),t.format==="json"){x(e.voices);return}if(Array.isArray(e.voices)){let o=t.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${o} Voices:`),console.log("-".repeat(50));for(let r of e.voices)console.log(` ${r.name} (${r.id})`),console.log(` ${r.description}`)}else for(let[o,r]of Object.entries(e.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(e){n?.stop(),c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Oc=new Gt("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(t,n)=>{try{x(await F("generateSpeech",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),mi=new Gt("tts").description("Text-to-speech commands").addCommand($c).addCommand(Ec).addCommand(Oc);import{execSync as Xe,spawn as Wc,spawnSync as Hc}from"child_process";import{access as Yn,mkdir as Ke,readFile as lt,rm as Xn,writeFile as ye}from"fs/promises";import{join as G,resolve as ct}from"path";import{Command as Z}from"commander";import Jc from"ffmpeg-static";import dt from"ora";import{homedir as Pc}from"os";import{join as pi}from"path";import{readdir as Nc}from"fs/promises";var Dc="conceptcraft";function Je(){return pi(Pc(),`.${Dc}`,"projects")}function Wt(t){return pi(Je(),t)}async function zn(){try{let t=Je();return(await Nc(t,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function gi(t,n){let e=2,o=`${t}-${e}`;for(;n.includes(o);)e++,o=`${t}-${e}`;return o}import{Command as Fc}from"commander";import Lc from"ora";import{execSync as Uc,spawnSync as ze}from"child_process";import{mkdirSync as fi,existsSync as Jt,readFileSync as yi,writeFileSync as hi}from"fs";import{join as Re,basename as _c}from"path";import{tmpdir as Mc}from"os";function zt(t,n){try{return Uc(n,{stdio:"ignore"}),!0}catch{return!1}}function Ht(t){let n=Math.floor(t/60),e=Math.floor(t%60),o=Math.round(t%1*10);return`${n}:${String(e).padStart(2,"0")}.${o}`}function Vc(t){let n=ze("ffprobe",["-v","error","-show_entries","format=duration","-of","default=noprint_wrappers=1:nokey=1",t],{encoding:"utf-8"});return parseFloat(n.stdout.trim())}function jc(t,n){let e=ze("ffmpeg",["-i",t,"-vf",`select='gt(scene,${n})',showinfo`,"-vsync","vfr","-f","null","-"],{encoding:"utf-8",timeout:12e4}),o=[0],r=(e.stderr||"").split(`
3754
- `);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 qc(t,n,e){let o=[];for(let r=0;r<n.length;r++){let i=n[r]+.5,a=Re(e,`scene_${String(r+1).padStart(2,"0")}.jpg`);ze("ffmpeg",["-ss",String(i),"-i",t,"-vframes","1","-q:v","2","-y",a],{stdio:"ignore",timeout:3e4}),o.push(a)}return o}function Bc(t,n){let e=Re(n,"audio.wav");if(ze("ffmpeg",["-i",t,"-vn","-acodec","pcm_s16le","-ar","16000","-ac","1","-y",e],{stdio:"ignore",timeout:6e4}),!Jt(e)||!zt("whisper","which whisper")&&!zt("whisper-cpp","which whisper-cpp"))return null;let r=ze("whisper",[e,"--model","base","--output_format","json","--output_dir",n,"--language","en"],{encoding:"utf-8",timeout:3e5}),i=Re(n,"audio.json");if(!Jt(i))return null;try{let a=JSON.parse(yi(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 Gc(t,n){let e=yi(t).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:[e],stream:!1}),r=ze("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 bi=new Fc("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(t,n)=>{let e=Lc();Jt(t)||(console.error(`File not found: ${t}`),process.exit(1)),zt("ffmpeg","which ffmpeg")||(console.error("ffmpeg is required. Install: brew install ffmpeg"),process.exit(1)),n.vision!==!1&&!zt("ollama","which ollama")&&(console.error("ollama is required for vision. Install: brew install ollama"),process.exit(1));let o=n.output||Re(Mc(),`video-analyze-${Date.now()}`);fi(o,{recursive:!0});let r=Re(o,"frames");fi(r,{recursive:!0});let i=parseFloat(n.threshold),a=n.model;e.start("Reading video metadata...");let s=Vc(t);e.succeed(`Video: ${Ht(s)} (${s.toFixed(1)}s)`),e.start("Detecting scenes...");let l=jc(t,i);e.succeed(`Detected ${l.length} scenes`),e.start("Extracting key frames...");let u=qc(t,l,r);e.succeed(`Extracted ${u.length} key frames`);let f=null;n.transcribe!==!1&&(e.start("Transcribing audio..."),f=Bc(t,o),f?e.succeed(`Transcribed: ${f.segments.length} segments`):e.warn("Transcription skipped (whisper not installed: pip install openai-whisper)"));let v=[];for(let g=0;g<l.length;g++){let S=l[g],y=g<l.length-1?l[g+1]:s,b="";n.vision!==!1&&Jt(u[g])&&(e.start(`Describing scene ${g+1}/${l.length}...`),b=Gc(u[g],a),e.succeed(`Scene ${g+1}: ${b}`)),v.push({id:g+1,startTime:S,endTime:y,duration:y-S,framePath:u[g],description:b})}let I={source:t,duration:s,scenes:v,transcript:f};if(n.outputFormat==="json"){let g=JSON.stringify(I,null,2),S=Re(o,"analysis.json");hi(S,g),console.log(g)}else{let g=["# Video Analysis","",`**Source:** ${_c(t)}`,`**Duration:** ${Ht(s)} (${s.toFixed(1)}s)`,`**Scenes:** ${v.length}`,"","## Scenes",""];for(let b of v){if(g.push(`### Scene ${b.id} (${Ht(b.startTime)} - ${Ht(b.endTime)}) [${b.duration.toFixed(1)}s]`),b.description&&g.push(`**Visual:** ${b.description}`),f?.segments){let R=f.segments.filter(M=>M.end>b.startTime&&M.start<b.endTime);R.length>0&&g.push(`**Audio:** ${R.map(M=>M.text).join(" ").trim()}`)}g.push(`**Frame:** ${b.framePath}`),g.push("")}f?.text&&(g.push("## Full Transcript"),g.push(""),g.push(f.text.trim()),g.push(""));let S=g.join(`
3755
- `),y=Re(o,"analysis.md");hi(y,S),console.log(S),console.log(`
3756
- Results saved to: ${o}`)}});var zc="inizio-inc/remotion-video-template#main",Ye=30;async function Yc(t){let n=await lt(t,"utf-8");return JSON.parse(n)}async function Xc(t){let n=G(t,"template.manifest.json");try{return await Yc(n)}catch{return{entry:"src/Root.tsx",compositions:[{id:"Main",type:"youtube",aspect:"16:9",default:!0}]}}}function xi(){try{return Xe("bun --version",{stdio:"ignore"}),!0}catch{return!1}}function Kc(t){if(t.includes("---")||t.includes("[Section")){let r=t.split(/---|\[Section \d+\]/i).filter(i=>i.trim());if(r.length>1)return r.map(i=>i.trim())}let n=t.split(/(?<=[.!?])\s+/).map(r=>r.trim()).filter(r=>r.length>0),e=[],o="";for(let r of n){let i=r.split(/\s+/).length;o?(e.push(`${o} ${r}`),o=""):i<5&&e.length<n.length-1?o=r:e.push(r)}return o&&(e.length>0?e[e.length-1]+=` ${o}`:e.push(o)),e}function Qc(t,n,e=Ye,o){if(o&&o.characters.length>0)return Zc(t,o,e);let r=t.reduce((a,s)=>a+s.split(/\s+/).length,0),i=0;return t.map((a,s)=>{let l=a.split(/\s+/).length,u=l/r,f=n*u,v=Math.round(f*e),I=a.split(""),g=f/I.length,S={characters:I,characterStartTimesSeconds:I.map((b,R)=>R*g),characterEndTimesSeconds:I.map((b,R)=>(R+1)*g)},y={id:s+1,text:a,wordCount:l,startTime:i,endTime:i+f,durationInSeconds:f,durationInFrames:v,timestamps:S};return i+=f,y})}function Zc(t,n,e){let{characters:o,characterStartTimesSeconds:r,characterEndTimesSeconds:i}=n,a=o.join(""),s=[],l=0;for(let u=0;u<t.length;u++){let f=t[u],v=f.length;for(;l<o.length&&o[l].match(/^\s*$/);)l++;let I=l,g=r[I]||0;l+=v;let S=l-1;for(;S>I&&o[S]?.match(/^\s*$/);)S--;let y=i[Math.min(S,i.length-1)]||g+1,b=y-g,R=Math.round(b*e),M={characters:o.slice(I,S+1),characterStartTimesSeconds:r.slice(I,S+1).map($=>$-g),characterEndTimesSeconds:i.slice(I,S+1).map($=>$-g)};s.push({id:u+1,text:f,wordCount:f.split(/\s+/).length,startTime:g,endTime:y,durationInSeconds:b,durationInFrames:R,timestamps:M})}return s}function el(t){let n=t==="tiktok"?"vertical":t==="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 tl(t,n,e){let o=G(t,"public"),r=G(t,"scripts");await Ke(o,{recursive:!0}),await Ke(r,{recursive:!0});let i=G(o,"scenes.json");await ye(i,JSON.stringify(el(n),null,2),"utf-8");let a=`import { execSync } from "node:child_process";
3750
+ `);He.command("install").description(`Install ${p.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(t,n)=>{n.mode&&!Mt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Mt.join(", ")}`),process.exit(1));let e={...Fr,mode:n.mode},o=[];t&&!it.includes(t)&&(c(`Invalid skill type: ${t}. Must be one of: ${it.join(", ")}`),process.exit(1));let r=[{name:"tts",content:Le(e)},{name:"music",content:Ue(e)},{name:"sfx",content:_e(e)},{name:"mix",content:Me(e)},{name:"image",content:Ve(e)},{name:"video-search",content:je(e)},{name:"scrape",content:qe(e)},{name:"branding",content:Be(e)},{name:"config",content:Ge(e)}];(!t||t==="main")&&o.push({name:p.name,content:Et(e),references:r});let i=[{name:"brief-guide",content:Tn.render(e)},{name:"website-assets",content:In.render(e)},{name:"source-scraping",content:kn.render(e)}];(!t||t==="video")&&(o.push({name:`${p.name}-video`,content:Ot(e),references:i}),o.push({name:"remotion-scene-craft",content:Dr(e)})),(!t||t==="presentation")&&o.push({name:`${p.name}-presentation`,content:Pt(e)}),(!t||t==="presentation-edit")&&o.push({name:`${p.name}-presentation-edit`,content:Nt(e)}),t==="tts"&&o.push({name:`${p.name}-tts`,content:Le(e)}),t==="music"&&o.push({name:`${p.name}-music`,content:Ue(e)}),t==="sfx"&&o.push({name:`${p.name}-sfx`,content:_e(e)}),t==="mix"&&o.push({name:`${p.name}-mix`,content:Me(e)}),t==="image"&&o.push({name:`${p.name}-image`,content:Ve(e)}),t==="video-search"&&o.push({name:`${p.name}-video-search`,content:je(e)}),t==="scrape"&&o.push({name:`${p.name}-scrape`,content:qe(e)}),t==="branding"&&o.push({name:`${p.name}-branding`,content:Be(e)}),t==="config"&&o.push({name:`${p.name}-config`,content:Ge(e)}),console.log();for(let a of o){m(`Installing ${a.name}...`);let s=Ut(a.name,a.content,{dir:n.dir,local:n.local,force:n.force},a.references);if(s.installed.length>0&&(C(`${a.name} installed successfully`),k(" Installed to",s.installed.join(", "))),s.skipped.length>0&&(m(` Skipped (already exists): ${s.skipped.join(", ")}`),console.log(M.gray(" Use --force to overwrite"))),s.errors.length>0)for(let l of s.errors)c(` ${l}`);s.installed.length===0&&s.skipped.length===0&&s.errors.length===0&&(m(" No supported AI coding assistants detected"),console.log(M.gray(" Supported editors: "+Or().join(", "))),console.log(M.gray(" Use --dir <path> to install to a specific directory"))),console.log()}if(!t||t==="video"){for(let a of[{name:"video-branding-director",generate:()=>On(e)},{name:"video-scene-builder",generate:An},{name:"video-scene-reviewer",generate:Rn},{name:"video-audio-director",generate:()=>$n(e)},{name:"video-continuity-editor",generate:En}]){m(`Installing ${a.name} agent...`);let s=Pr(a.name,a.generate(),{force:n.force,dir:n.dir});if(s.installed.length>0){C(`${a.name} agent installed`);let l={"Claude Code":"~/.claude/agents/","GitHub Copilot":"~/.github/agents/"};k(" Installed to",s.installed.map(u=>n.dir?u:`${u} (${l[u]??"~/.<editor>/agents/"})`).join(", "))}s.skipped.length>0&&m(` Agent skipped (already exists): ${s.skipped.join(", ")}`)}console.log()}});He.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action((t="main",n)=>{n.mode&&!Mt.includes(n.mode)&&(c(`Invalid mode: ${n.mode}. Must be one of: ${Mt.join(", ")}`),process.exit(1));let e={...Fr,mode:n.mode},r={main:()=>Et(e),video:()=>Ot(e),presentation:()=>Pt(e),"presentation-edit":()=>Nt(e),tts:()=>Le(e),music:()=>Ue(e),sfx:()=>_e(e),mix:()=>Me(e),image:()=>Ve(e),"video-search":()=>je(e),scrape:()=>qe(e),branding:()=>Be(e),config:()=>Ge(e),"video-branding-director":()=>On(e),"video-scene-builder":()=>An(),"video-scene-reviewer":()=>Rn(),"video-audio-director":()=>$n(e),"video-continuity-editor":()=>En()}[t];if(r)console.log(r());else{let i=[...it,"video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"];c(`Invalid skill type: ${t}. Must be one of: ${i.join(", ")}`),process.exit(1)}});He.command("uninstall").description(`Remove ${p.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(t,n)=>{let e=[];t&&!it.includes(t)&&(c(`Invalid skill type: ${t}. Must be one of: ${it.join(", ")}`),process.exit(1)),(!t||t==="main")&&e.push(p.name),(!t||t==="video")&&(e.push(`${p.name}-video`),e.push("remotion-scene-craft")),(!t||t==="presentation")&&e.push(`${p.name}-presentation`),(!t||t==="presentation-edit")&&e.push(`${p.name}-presentation-edit`),(!t||t==="tts")&&e.push(`${p.name}-tts`),(!t||t==="music")&&e.push(`${p.name}-music`),(!t||t==="sfx")&&e.push(`${p.name}-sfx`),(!t||t==="mix")&&e.push(`${p.name}-mix`),(!t||t==="image")&&e.push(`${p.name}-image`),(!t||t==="video-search")&&e.push(`${p.name}-video-search`),(!t||t==="scrape")&&e.push(`${p.name}-scrape`),(!t||t==="branding")&&e.push(`${p.name}-branding`),(!t||t==="config")&&e.push(`${p.name}-config`),console.log();for(let o of e){let r=_t(o,{local:n.local});if(r.removed.length>0?(C(`${o} uninstalled`),k(" Removed from",r.removed.join(", "))):m(` ${o} not found`),r.errors.length>0)for(let i of r.errors)_(` Failed to remove: ${i}`)}if(!t||t==="video")for(let o of["video-branding-director","video-scene-builder","video-scene-reviewer","video-audio-director","video-continuity-editor"])Nr(o).removed.length>0&&C(`${o} agent uninstalled`);console.log()});import{Command as Us}from"commander";import at from"chalk";var Lr=new Us("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(t,n)=>{await E();try{let e=Number.parseInt(n.limit??"25",10),{templates:o}=await vo(t,Number.isFinite(e)?e: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?at.green("default"):null,r.category??null,r.recommendedModes?.length?`modes: ${r.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${at.bold(r.name)} ${at.gray(r.id)}${i?`
3751
+ ${at.gray(i)}`:""}`)}console.log(),console.log(at.gray(`Use one with: ${p.commands[0]} create "<topic>" --template <id>`))}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as _s}from"commander";import Pn from"chalk";var Ur=new _s("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)","human").action(async t=>{await E();try{let n=await he();if(gn(),t.format==="json"){console.log(JSON.stringify(n,null,2));return}me("User"),console.log(),k("Email",n.user.email),n.user.username&&k("Username",n.user.username),(n.user.firstName||n.user.lastName)&&k("Name",[n.user.firstName,n.user.lastName].filter(Boolean).join(" "));let e=n.authType==="apiKey"?"API Key":n.authType==="oauth"?"OAuth":"Session";if(k("Auth Type",e),n.currentTeam&&(console.log(),me("Current Team"),console.log(),k("ID",n.currentTeam.id),k("Name",n.currentTeam.name),k("Plan",n.currentTeam.planName),k("Role",n.currentTeam.isOwner?"Owner":"Member")),n.teams.length>1){console.log(),me("All Teams"),console.log();for(let o of n.teams){let r=o.isCurrent?Pn.green(" (current)"):"";console.log(` ${Pn.bold(o.name)}${r}`),console.log(Pn.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 _r(t){return t[0]==="--"?t.slice(1):t}import{Command as Nn}from"commander";function Ms(t,n){return[...n,t]}var Vs=new Nn("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",Ms,[]).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await A("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:t}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),js=new Nn("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("createAdSet",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Mr=new Nn("ad-set").description("Ad set commands").addCommand(Vs).addCommand(js);import{Command as jr}from"commander";function Vr(t){return new jr(t).description(t==="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,e)=>{if(!e.yes)return c("Pass --yes to approve this operation");try{x(await A(t==="create"?"createAgent":"recommendAgent",{approvalReceipt:"cli:--yes",description:e.description,instructionsMarkdown:e.instructions,name:n,output:e.output,schedule:e.schedule,scheduleTime:e.time,teamId:e.teamId,timezone:e.timezone}))}catch(o){c(o instanceof Error?o.message:"Agent operation failed"),process.exit(d.GENERAL_ERROR)}})}var qr=new jr("agent").description("Scheduled agent commands").addCommand(Vr("create")).addCommand(Vr("recommend"));import{Command as Vt}from"commander";import Gs from"ora";import{mkdir as qs,writeFile as Br}from"fs/promises";import{dirname as Bs}from"path";async function we(t,n){if(await qs(Bs(n),{recursive:!0}),t.startsWith("data:")){let r=t.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 Br(n,i);return}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to download media: ${e.status}`);let o=Buffer.from(await e.arrayBuffer());if(o.length===0)throw new Error("Downloaded media was empty");await Br(n,o)}var Ws=15e3,Hs=40;function Dn(t,n){if(n==="json"){x(t);return}if(n==="quiet"){console.log(t.videoUrl??t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.durationSec!=null&&m(`Duration: ${t.durationSec}s`),t.videoUrl&&C(`Video URL: ${t.videoUrl}`),t.error&&c(`Error: ${t.error}`)}var Js=new Vt("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 t=>{try{let n=await No(t.language);if(t.format==="json"){x(n);return}let e=n.personal??[];if(t.format==="quiet"){for(let o of e)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(e.length>0){m("Your presenters:");for(let o of e)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(d.GENERAL_ERROR)}}),zs=new Vt("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 t=>{let n=t.transparent?"webm":t.outputFormat;!!t.audioUrl==!!t.script&&(c("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(d.INVALID_INPUT)),["1:1","9:16","16:9"].includes(t.aspect)||(c("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(d.INVALID_INPUT)),t.outputFormat!==void 0&&!["mp4","webm"].includes(t.outputFormat)&&(c("Output format must be mp4 or webm"),process.exit(d.INVALID_INPUT)),t.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(t.backgroundColor)&&(c("Background color must be a six-digit hex value"),process.exit(d.INVALID_INPUT)),t.backgroundColor&&t.backgroundImageUrl&&(c("Provide only one presenter background"),process.exit(d.INVALID_INPUT)),t.fit!==void 0&&!["contain","cover"].includes(t.fit)&&(c("Fit must be contain or cover"),process.exit(d.INVALID_INPUT)),t.fit&&!t.backgroundImageUrl&&(c("Fit requires --background-image-url"),process.exit(d.INVALID_INPUT)),t.transparent&&t.outputFormat==="mp4"&&(c("--transparent cannot be combined with --output-format mp4"),process.exit(d.INVALID_INPUT)),n==="webm"&&(t.backgroundColor||t.backgroundImageUrl)&&(c("Transparent WebM output cannot be combined with a background"),process.exit(d.INVALID_INPUT)),["basic","standard","premium"].includes(t.renderTier)||(c("Render tier must be basic, standard, or premium"),process.exit(d.INVALID_INPUT));let e=t.duration?Number.parseInt(t.duration,10):void 0;e!==void 0&&(!Number.isFinite(e)||e<1||e>300)&&(c("Duration must be between 1 and 300 seconds"),process.exit(d.INVALID_INPUT));let o=t.format==="human"?Gs("Generating presenter clip...").start():null;try{let r=t.audioUrl?{audioUrl:t.audioUrl}:{script:t.script??"",...t.voiceId?{voiceId:t.voiceId}:{}},i=await Do({...r,aspect:t.aspect,...t.avatarId?{avatarId:t.avatarId}:{},...t.backgroundColor?{backgroundHex:t.backgroundColor}:{},...t.backgroundImageUrl?{backgroundImageUrl:t.backgroundImageUrl}:{},...e!==void 0?{durationSec:e}:{},...t.fit?{fit:t.fit}:{},...n?{outputFormat:n}:{},renderTier:t.renderTier,title:t.title});if(!t.wait){o?.stop(),Dn(i,t.format);return}let a=await ue(()=>dn(i.requestId),Hs,Ws);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 we(a.videoUrl,t.output),o?.stop(),Dn(a,t.format),t.format==="human"&&C(`Saved to: ${t.output}`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Xs=new Vt("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet","human").action(async(t,n)=>{try{Dn(await dn(t),n.format)}catch(e){c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Gr=new Vt("avatar").description("Avatar/presenter media commands").addCommand(Js).addCommand(zs).addCommand(Xs);import{writeFile as Wr}from"fs/promises";import H from"chalk";import{Command as re}from"commander";import Ys from"ora";var Hr=new re("branding").description("Manage brand profiles").addCommand(new re("list").description("List brand profiles").option("-f, --format <format>","Output format (table, json)","table").action(async t=>{await E();try{let n=await an();if(n.brandings.length===0){t.format==="json"?console.log(JSON.stringify([])):(m("No brand profiles found"),console.log(),console.log(H.gray(`Create one with: ${p.commands[0]} branding extract <url>`)));return}t.format==="json"?console.log(JSON.stringify(n.brandings,null,2)):console.log(Mo(n.brandings))}catch(n){c(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new re("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(t,n)=>{await E();try{let e=await wo(t);if(n.output){await Wr(n.output,JSON.stringify(e,null,2)),C(`Brand profile saved to ${n.output}`);return}if(n.format==="json")console.log(JSON.stringify(e,null,2));else{if(me("Brand Profile"),console.log(),k("ID",e.id),k("Name",e.name),k("Source URL",e.sourceUrl??H.gray("None")),k("Default",e.isDefault?H.green("Yes"):"No"),e.createdAt&&k("Created",new Date(e.createdAt).toLocaleString()),console.log(),e.primaryColor||e.colors.length>0){if(console.log(H.bold(" Colors")),e.primaryColor){let r=H.bgHex(e.primaryColor)(" ");console.log(` Primary: ${r} ${e.primaryColor}`)}if(e.colors.length>0){console.log(" Palette:");for(let r of e.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()}e.logoUrl&&(console.log(H.bold(" Logo")),console.log(` ${e.logoUrl}`),console.log());let o=e.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()),(e.confidence||e.extractionMethod)&&(console.log(H.bold(" Extraction")),e.confidence&&console.log(` Confidence: ${Math.round(e.confidence*100)}%`),e.extractionMethod&&console.log(` Method: ${e.extractionMethod}`),console.log()),console.log(H.gray(" Use --format json for full details")),console.log()}}catch(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}})).addCommand(new re("find").description("Find existing brand profile by name or URL").argument("<query>","Brand name or website URL to search for").action(async t=>{await E();try{let n=await an(),e=t.toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,""),o=n.brandings.filter(r=>{let i=(r.name||"").toLowerCase(),a=(r.sourceUrl||"").toLowerCase().replace(/^https?:\/\//,"").replace(/\/$/,"");return i.includes(e)||a.includes(e)||i.length>0&&e.includes(i)||a.length>0&&e.includes(a)});if(o.length===0){m(`No brand profiles matching "${t}"`),console.log(H.gray(` Extract one with: ${p.commands[0]} branding extract <url>`));return}console.log(`Found ${o.length} brand${o.length>1?"s":""}:
3752
+ `);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: ${p.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 re("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(t,n)=>{await E(),n.yes||(c("Pass --yes to confirm brand extraction."),process.exit(d.INVALID_INPUT));try{new URL(t.startsWith("http")?t:`https://${t}`)}catch{c("Invalid URL format"),process.exit(6)}let e=t.startsWith("http")?t:`https://${t}`,o=n.teamId??ut(),r=Ys({text:`Extracting branding from ${e}...`,stream:process.stdout}).start();try{let i=await So(e,o,"cli:--yes");r.succeed("Brand extraction started");let a=JSON.stringify(i,null,2);n.output?(await Wr(n.output,a),C(`Brand profile saved to ${n.output}`)):console.log(a),m(`Check progress with: ${p.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 re("status").description("Check a brand extraction run").argument("<run-id>","Run ID returned by branding extract").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("extractBranding",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}})).addCommand(new re("set-default").description("Set a brand profile as default").argument("<id>","Brand profile ID").action(async t=>{await E(),m(`To set brand ${t} as default, use the web dashboard.`),console.log(),console.log(H.gray("API support for setting default brand is coming soon."))})).addCommand(new re("competitor").description("Brand competitor commands").addCommand(new re("list").description("List competitors for a brand").option("--branding-id <id>","Brand ID").option("--team-id <id>","Workspace ID").action(async t=>{try{console.log(JSON.stringify(await A("getBrandCompetitors",{brandingId:t.brandingId,teamId:t.teamId}),null,2))}catch(n){c(n instanceof Error?n.message:"Lookup failed"),process.exit(1)}})).addCommand(new re("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(t,n)=>{n.yes||(c("Pass --yes to confirm adding a competitor."),process.exit(d.INVALID_INPUT));try{x(await A("addCompetitor",{approvalReceipt:"cli:--yes",brandingId:n.brandingId,name:t,teamId:n.teamId,website:n.website,xHandle:n.xHandle}))}catch(e){c(e instanceof Error?e.message:"Write failed"),process.exit(d.GENERAL_ERROR)}}))).addCommand(new re("social").description("Brand social handle commands").addCommand(new re("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(t,n,e)=>{e.yes||(c("Pass --yes to confirm adding a social handle."),process.exit(d.INVALID_INPUT));try{x(await A("addBrandSocialHandle",{approvalReceipt:"cli:--yes",brandingId:e.brandingId,handle:n,platform:t,teamId:e.teamId}))}catch(o){c(o instanceof Error?o.message:"Write failed"),process.exit(d.GENERAL_ERROR)}})));import{readFile as Ks}from"fs/promises";import{Command as Jr}from"commander";var Qs=new Jr("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(t,n)=>{try{let e=t,o;t.includes("://")||(e=await Ks(t,"utf8"),o=t);let r=await A("extractContent",{filename:o,maxLength:Number.parseInt(n.maxLength,10),mimeType:n.mimeType,source:e,teamId:n.teamId});n.format!=="quiet"&&x(r)}catch(e){c(e instanceof Error?e.message:"Extraction failed"),process.exit(d.GENERAL_ERROR)}}),zr=new Jr("content").description("Content extraction commands").addCommand(Qs);import Y from"chalk";import{Command as Zs}from"commander";import{existsSync as ec,readFileSync as tc}from"fs";import nc,{resolve as Xr}from"path";var Yr=new Zs("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(t,n)=>{await E();let e;n.slides!==void 0&&(e=parseInt(n.slides,10),(Number.isNaN(e)||e<1||e>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 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 f=["blue","violet","rose","orange","green"];n.theme&&!f.includes(n.theme)&&(c(`Invalid theme: ${n.theme}. Valid: ${f.join(", ")}`),process.exit(6));let v=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];n.decorations&&!v.includes(n.decorations)&&(c(`Invalid decorations: ${n.decorations}. Valid: ${v.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 g=n.mode??(I?"instant":"fast"),T=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[w,V]of[["primary-color",n.primaryColor],["secondary-color",n.secondaryColor],["accent-color",n.accentColor],["background-color",n.backgroundColor],["foreground-color",n.foregroundColor]])V&&!T.test(V)&&(c(`Invalid ${w}: ${V}. 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 w=await To(g,e??10,n.teamId);if(n.output!=="json"&&n.output!=="quiet"){console.log(Y.green("\u2713"));let V=w.remaining[g],q=w.limits[g],ee=V===void 0||q===void 0?"":` | ${g}: ${V}/${q} remaining`;console.log(Y.gray(` Plan: ${w.planName}${ee}`))}}catch(w){n.output==="json"?console.log(JSON.stringify({success:!1,error:w instanceof Error?w.message:String(w)})):(console.log(Y.red("\u2717")),c(w instanceof Error?w.message:String(w))),process.exit(w.exitCode??1)}let y=[];if(n.file&&n.file.length>0){for(let w of n.file)ec(Xr(w))||(c(`File not found: ${w}`),process.exit(6));n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(`
3753
+ Uploading ${n.file.length} file(s)...`));try{y=await go(n.file.map(w=>Xr(w)),(w,V,q)=>{n.output!=="json"&&n.output!=="quiet"&&q&&process.stdout.write(`\r ${Y.cyan("\u2B06")} Uploading: ${q} (${w+1}/${V})`)}),n.output!=="json"&&n.output!=="quiet"&&console.log(`\r ${Y.green("\u2713")} Uploaded ${y.length} file(s) `)}catch(w){c(`Failed to upload files: ${w instanceof Error?w.message:String(w)}`),process.exit(1)}}let b;(n.stdin||!process.stdin.isTTY)&&(b=await oc(),n.stdin&&!b&&(c("No content received from stdin"),process.exit(6)));let S=n.context;if(n.contextFile)try{S=tc(n.contextFile,"utf-8"),S.trim()||(c(`Context file is empty: ${n.contextFile}`),process.exit(6))}catch{c(`Failed to read context file: ${n.contextFile}`),process.exit(6)}!b&&!S&&y.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 | ${p.commands[0]} Pipe content`)),process.exit(6));let D=[...y];b&&D.push({id:`stdin-${Date.now()}`,content:b,title:"Piped Content",mime:"text/plain",selected:!0}),S&&D.push({id:`context-${Date.now()}`,content:S,title:"Context",mime:"text/plain",selected:!0});let $,N=n.primaryColor||n.secondaryColor||n.accentColor||n.backgroundColor||n.foregroundColor;(n.theme||N||n.decorations)&&($={},n.theme&&($.preset=n.theme),N&&($.custom={},n.primaryColor&&($.custom.primary=n.primaryColor),n.secondaryColor&&($.custom.secondary=n.secondaryColor),n.accentColor&&($.custom.accent=n.accentColor),n.backgroundColor&&($.custom.background=n.backgroundColor),n.foregroundColor&&($.custom.foreground=n.foregroundColor)),n.decorations&&($.decorations=n.decorations));try{let w=await fo({topic:t,...e!==void 0&&{slideCount:e},mode:g,...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},...$&&{theme:$},...n.studio?{documentId:nc.basename(process.cwd())}:n.id?{documentId:n.id}:{},...D.length>0&&{contentSources:{uploadedFiles:D,contextFiles:[]}}});if(!n.wait){n.output==="json"?console.log(JSON.stringify({success:!0,run:w},null,2)):n.output!=="quiet"&&(C("Presentation generation queued"),k("Run ID",w.runId),k("Status",w.status),console.log(Y.gray(` Check later with presentation status ${w.runId}`)));return}let V=await U("createSlides",w.runId,n.teamId);for(;!V.done;)n.output!=="json"&&n.output!=="quiet"&&console.log(Y.gray(` ${V.message}`)),await new Promise(ee=>setTimeout(ee,(V.nextPollAfterSeconds??5)*1e3)),V=await U("createSlides",w.runId,n.teamId);if(V.error)throw new Error(V.error.message);let q=V.entity?await xe(V.entity.id):void 0;if(n.output==="json")console.log(JSON.stringify({success:!0,presentation:q,run:V,viewUrl:q?Pe(q.slug,n.language??"en"):void 0},null,2));else{console.log(),C("Presentation created successfully"),console.log(),k("Title",q?.title??t),k("Slides",String(q?.numberOfSlides??e??"\u2014")),console.log();let ee=q?Pe(q.slug,n.language??"en"):"N/A";ee!=="N/A"&&(console.log(Y.bold(" Open: ")+Y.cyan.underline(ee)),n.open&&await(await import("open")).default(ee)),console.log()}}catch(w){n.output==="json"?console.log(JSON.stringify({success:!1,error:w instanceof Error?w.message:String(w)})):c(w instanceof Error?w.message:String(w)),process.exit(w.exitCode??1)}});async function oc(){return new Promise(t=>{let n="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){t("");return}process.stdin.on("data",e=>{n+=e}),process.stdin.on("end",()=>{t(n.trim())}),setTimeout(()=>{t(n.trim())},100)})}import{Command as rc}from"commander";import jt from"chalk";var Kr=new rc("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(t,n)=>{await E();try{let e=await xe(t);if(n.format==="json"){console.log(JSON.stringify(e,null,2));return}let o=Pe(e.slug,n.language);me("Presentation Details"),console.log(),k("Slug",e.slug),k("Title",e.title||"Untitled"),k("Description",e.description||jt.gray("None")),k("Slides",String(e.numberOfSlides||"-")),k("Mode",e.mode||"-"),k("Created",pn(e.createdAt)),e.updatedAt&&k("Updated",pn(e.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(e){c(e instanceof Error?e.message:String(e)),process.exit(e.exitCode??1)}});import{Command as qt}from"commander";import ic from"ora";var ac=new qt("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("--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 t=>{let n=t.format,e=n==="human"?ic("Searching for images...").start():null,o;t.maxResults&&(o=parseInt(t.maxResults,10),(Number.isNaN(o)||o<1)&&(e?.stop(),c("Max results must be a positive number"),process.exit(d.INVALID_INPUT)));try{let r=await wt({query:t.query,options:{maxResults:o||10,size:t.size,safeSearch:t.safeSearch}});e?.stop(),r.success||(c("Search failed"),process.exit(d.GENERAL_ERROR));let i=r.data.results.flatMap(a=>a.results.map(s=>({...s,provider:a.providerName})));if(n==="json"){x({success:!0,query:t.query,totalResults:i.length,images:i});return}if(n==="quiet"){for(let a of i)console.log(a.url);return}if(i.length===0){m("No images found");return}C(`Found ${i.length} images for "${t.query}"`),console.log();for(let a=0;a<i.length;a++){let s=i[a];console.log(`[${a+1}] ${s.title||"Untitled"}`),console.log(` URL: ${s.url}`),console.log(` Size: ${s.width}x${s.height}`),s.author&&console.log(` Author: ${s.author}`),console.log(` Provider: ${s.provider}`),console.log()}m(`Total cost: $${r.data.totalCost.toFixed(4)}`)}catch(r){e?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),sc=new qt("generate").description("Start background image generation").argument("<prompt>","Image prompt").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("--yes","Approve generation").action(async(t,n)=>{if(!n.yes)return c("Pass --yes to approve image generation");try{x(await A("createImage",{approvalReceipt:"cli:--yes",height:n.height?Number.parseInt(n.height,10):void 0,model:n.model,prompt:t,provider:n.provider,teamId:n.teamId,width:n.width?Number.parseInt(n.width,10):void 0}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),cc=new qt("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("createImage",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Qr=new qt("image").description("Image search and generation commands").addCommand(ac).addCommand(sc).addCommand(cc);import{Command as Fn}from"commander";var lc=new Fn("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(t,n)=>{try{x(await A("searchKnowledge",{kind:n.kind,limit:Number.parseInt(n.limit,10),query:t,teamId:n.teamId}))}catch(e){c(e instanceof Error?e.message:"Knowledge search failed"),process.exit(d.GENERAL_ERROR)}}),dc=new Fn("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async t=>{try{x(await A("getKnowledgeBundle",{kind:t.kind,teamId:t.teamId}))}catch(n){c(n instanceof Error?n.message:"Knowledge bundle failed"),process.exit(d.GENERAL_ERROR)}}),Zr=new Fn("knowledge").description("Knowledge Hub commands").addCommand(lc).addCommand(dc);import{Command as Ln}from"commander";var uc=new Ln("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve generation");try{x(await A("createMicrosite",{approvalReceipt:"cli:--yes",audience:n.audience,brandingId:n.brandingId,description:n.description,language:n.language,teamId:n.teamId,title:t,tone:n.tone}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),mc=new Ln("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("createMicrosite",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),ei=new Ln("microsite").description("Microsite commands").addCommand(uc).addCommand(mc);import{Command as Mn}from"commander";import Un from"ora";function _n(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.outputUrl?console.log(t.outputUrl):console.log(t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.outputUrl&&C(`Output URL: ${t.outputUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var pc=new Mn("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 t=>{!t.music&&!t.voice&&(c("At least one of --music or --voice must be provided"),process.exit(d.INVALID_INPUT));let n=parseInt(t.musicVolume,10)/100,e=parseInt(t.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(e)||e<0||e>2)&&(c("Voice volume must be between 0 and 200"),process.exit(d.INVALID_INPUT));let o=t.format,r=o==="human"?Un("Mixing audio...").start():null,i=[{url:t.video,role:"video"}];t.music&&i.push({url:t.music,role:"background",volume:n*5}),t.voice&&i.push({url:t.voice,role:"voice",volume:e*2});try{let a=await $o({operation:"add-to-video",inputs:i,options:{musicVolume:n,voiceVolume:e}});if(!t.wait){r?.stop(),_n(a,o);return}r&&(r.text=`Processing (ID: ${a.requestId})...`);let s=await ue(()=>sn(a.requestId),120,3e3);if(r?.stop(),s.status==="failed"&&(c(s.error||"Audio mixing failed"),process.exit(d.GENERAL_ERROR)),_n(s,o),t.output){if(!s.outputUrl)throw new Error("Audio mix completed without an output URL");let l=o==="human"?Un("Downloading...").start():null;await we(s.outputUrl,t.output),l?.stop(),o==="human"&&C(`Saved to: ${t.output}`)}}catch(a){r?.stop(),c(a instanceof Error?a.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),gc=new Mn("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(t,n)=>{let e=n.format==="human"?Un("Checking status...").start():null;try{let o=await sn(t);e?.stop(),_n(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ti=new Mn("mix").description("Audio mixing commands").addCommand(pc).addCommand(gc);import{Command as qn}from"commander";import Vn from"ora";function jn(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.audioUrl?console.log(t.audioUrl):console.log(t.requestId);return}m(`Request ID: ${t.requestId}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.audioUrl&&C(`Audio URL: ${t.audioUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var fc=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>","Provider (elevenlabs, suno)").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 t=>{let n=parseInt(t.duration,10);(Number.isNaN(n)||n<3||n>600)&&(c("Duration must be between 3 and 600 seconds (10 minutes)"),process.exit(d.INVALID_INPUT));let e=t.format,o=e==="human"?Vn("Generating music...").start():null;try{let r=await vt({prompt:t.prompt,duration:n,options:{provider:t.provider,style:t.style}});if(!t.wait){o?.stop(),jn(r,e);return}let i=r;if(r.status!=="completed"&&r.status!=="failed"&&(o&&(o.text=`Processing (ID: ${r.requestId})...`),i=await ue(()=>ot(r.requestId),60,2e3)),o?.stop(),i.status==="failed"&&(c(i.error||"Music generation failed"),process.exit(d.GENERAL_ERROR)),jn(i,e),t.output){if(!i.audioUrl)throw new Error("Music completed without an audio URL");let a=e==="human"?Vn("Downloading...").start():null;await we(i.audioUrl,t.output),a?.stop(),e==="human"&&C(`Saved to: ${t.output}`)}}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),hc=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(t,n)=>{let e=n.format==="human"?Vn("Checking status...").start():null;try{let o=await ot(t);e?.stop(),jn(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ni=new qn("music").description("Music generation commands").addCommand(fc).addCommand(hc);import{Command as Bn}from"commander";function oi(t,n){return[...n,t]}var yc=new Bn("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",oi,[]).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve poll creation");try{x(await A("createPoll",{approvalReceipt:"cli:--yes",options:n.option.map(e=>({text:e})),pollType:n.type,question:t,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Poll creation failed"),process.exit(d.GENERAL_ERROR)}}),bc=new Bn("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",oi).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(t,n)=>{if(!n.yes)return c("Pass --yes to approve poll update");try{x(await A("editPoll",{approvalReceipt:"cli:--yes",options:n.option?.map(e=>({text:e})),pollId:t,pollType:n.type,question:n.question,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Poll update failed"),process.exit(d.GENERAL_ERROR)}}),ri=new Bn("poll").description("Standalone poll commands").addCommand(yc).addCommand(bc);import{Command as ii}from"commander";var xc=new ii("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(t,n)=>{try{let e=await U("createSlides",t,n.teamId);if(n.format==="json"){x(e);return}if(n.format==="quiet"){console.log(e.status);return}m(`Status: ${e.status}`),m(e.message),e.progress!==null&&m(`Progress: ${e.progress}%`),e.error&&c(e.error.message)}catch(e){c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ai=new ii("presentation").description("Presentation background-run commands").addCommand(xc);import{writeFile as vc}from"fs/promises";import{Command as wc}from"commander";import Sc from"ora";var si=new wc("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(t,n)=>{let e=n.format,o=e==="human"?Sc("Scraping URL...").start():null;try{let r=await Oo(t,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 vc(n.output,i.content,"utf-8"),e==="human"&&C(`Content saved to: ${n.output}`)),e==="json"){let{cost:a,...s}=i;x(s);return}if(e==="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(d.GENERAL_ERROR)}});import{Command as st}from"commander";function Bt(t,n){n!=="quiet"&&x(t)}var Cc=new st("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(t,n)=>{try{let e=await A("searchInternet",{maxResults:Number.parseInt(n.maxResults,10),query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Search failed"),process.exit(d.GENERAL_ERROR)}}),Ic=new st("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(t,n)=>{try{let e=await A("getNews",{maxResults:Number.parseInt(n.maxResults,10),teamId:n.teamId,timeframe:n.timeframe,topic:t});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"News search failed"),process.exit(d.GENERAL_ERROR)}}),Tc=new st("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(t,n)=>{try{let e=await A("searchImages",{aspect:n.aspect,maxResults:Number.parseInt(n.maxResults,10),query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Image search failed"),process.exit(d.GENERAL_ERROR)}}),kc=new st("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(t,n)=>{try{let e=await A("searchStockVideo",{license:n.license,maxResults:Number.parseInt(n.maxResults,10),orientation:n.orientation,query:t,teamId:n.teamId});Bt(e,n.format)}catch(e){c(e instanceof Error?e.message:"Video search failed"),process.exit(d.GENERAL_ERROR)}}),ci=new st("search").description("Web, news, image, and stock-video search").addCommand(Cc).addCommand(Ic).addCommand(Tc).addCommand(kc);import{Command as Hn}from"commander";import Gn from"ora";function Wn(t,n){if(n==="json"){let{cost:e,...o}=t;x(o);return}if(n==="quiet"){t.audioUrl?console.log(t.audioUrl):t.requestId?console.log(t.requestId):console.log(t.id);return}m(`Request ID: ${t.requestId||t.id}`),m(`Status: ${t.status}`),t.duration&&m(`Duration: ${t.duration}s`),t.audioUrl&&C(`Audio URL: ${t.audioUrl}`),t.cost!==void 0&&m(`Cost: $${t.cost.toFixed(4)}`),t.error&&c(`Error: ${t.error}`)}var Rc=new Hn("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>","Provider (elevenlabs)","elevenlabs").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 t=>{let n;t.duration&&(n=parseFloat(t.duration),(isNaN(n)||n<.5||n>30)&&(c("Duration must be between 0.5 and 30 seconds"),process.exit(d.INVALID_INPUT)));let e;t.promptInfluence&&(e=parseFloat(t.promptInfluence),(isNaN(e)||e<0||e>1)&&(c("Prompt influence must be between 0 and 1"),process.exit(d.INVALID_INPUT)));let o=t.outputFormat,r=o==="human"?Gn("Generating sound effects...").start():null;try{let i=await Po({text:t.text,duration:n,options:{provider:t.provider,promptInfluence:e,loop:t.loop,format:t.format}});if(!t.wait){r?.stop(),Wn(i,o);return}let a=i;if(i.status!=="completed"&&i.status!=="failed"){let s=i.requestId||i.id;r&&(r.text=`Processing (ID: ${s})...`),a=await ue(()=>ln(s),60,2e3)}if(r?.stop(),a.status==="failed"&&(c(a.error||"Sound effects generation failed"),process.exit(d.GENERAL_ERROR)),Wn(a,o),t.output){if(!a.audioUrl)throw new Error("Sound effect completed without an audio URL");let s=o==="human"?Gn("Downloading...").start():null;await we(a.audioUrl,t.output),s?.stop(),o==="human"&&C(`Saved to: ${t.output}`)}}catch(i){r?.stop(),c(i instanceof Error?i.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Ac=new Hn("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(t,n)=>{let e=n.format==="human"?Gn("Checking status...").start():null;try{let o=await ln(t);e?.stop(),Wn(o,n.format)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),li=new Hn("sfx").description("Sound effects generation commands").addCommand(Rc).addCommand(Ac);import{Command as Gt}from"commander";import{mkdir as $c,writeFile as di}from"fs/promises";import pi from"ora";import{dirname as Ec}from"path";var ui="en-US-Neural2-C",mi="gemini",Oc=new Gt("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: ${ui})`).option("-p, --provider <provider>",`Provider: gemini, elevenlabs, openai (default: ${mi})`).option("-m, --model <model>","Model (provider-specific)").option("-s, --speed <speed>","Speech speed 0.25-4.0 (default: 1.0)").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 t=>{let n=t.format,e=n==="human"?pi("Generating speech...").start():null,o;t.speed&&(o=parseFloat(t.speed),(isNaN(o)||o<.25||o>4)&&(e?.stop(),c("Speed must be between 0.25 and 4.0"),process.exit(d.INVALID_INPUT)));let r;if(t.speakers)try{r=JSON.parse(t.speakers),(!Array.isArray(r)||r.length>2)&&(e?.stop(),c("Speakers must be an array with max 2 items"),process.exit(d.INVALID_INPUT))}catch{e?.stop(),c(`Invalid --speakers JSON. Example: '[{"name":"Joe","voice":"Kore"}]'`),process.exit(d.INVALID_INPUT)}try{let i=t.voiceId,a=t.voice||ui,s=t.provider||mi,l={};r&&(l.gemini={speakers:r}),t.instructions&&(l.openai={instructions:t.instructions});let u=await xt({text:t.text,options:{provider:s,voiceId:i,voice:a,model:t.model,speed:o,providerOptions:Object.keys(l).length>0?l:void 0}});e?.stop();let f=t.output.endsWith(`.${u.format}`)?t.output:`${t.output}.${u.format}`;await $c(Ec(f),{recursive:!0}),await di(f,u.audioData);let v=f.replace(/\.[^.]+$/,".txt");if(await di(v,t.text,"utf-8"),n==="json"){x({status:"completed",output:f,audioUrl:u.audioUrl,duration:u.duration,provider:u.provider,format:u.format});return}if(n==="quiet"){console.log(f);return}C(`Saved to: ${f}`),m(`Duration: ${u.duration.toFixed(2)}s`),m(`Provider: ${u.provider}`),m(`Cost: $${u.cost.toFixed(6)}`)}catch(i){e?.stop(),c(i instanceof Error?i.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Pc=new Gt("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 t=>{let n=t.format==="human"?pi("Fetching voices...").start():null;try{let e=await Ao(t.provider);if(n?.stop(),t.format==="json"){x(e.voices);return}if(Array.isArray(e.voices)){let o=t.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${o} Voices:`),console.log("-".repeat(50));for(let r of e.voices)console.log(` ${r.name} (${r.id})`),console.log(` ${r.description}`)}else for(let[o,r]of Object.entries(e.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(e){n?.stop(),c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),Nc=new Gt("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(t,n)=>{try{x(await U("generateSpeech",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),gi=new Gt("tts").description("Text-to-speech commands").addCommand(Oc).addCommand(Pc).addCommand(Nc);import{execSync as Ye,spawn as Jc,spawnSync as zc}from"child_process";import{access as zn,mkdir as Ke,readFile as lt,rm as Xn,writeFile as ye}from"fs/promises";import{join as G,resolve as ct}from"path";import{Command as Z}from"commander";import Xc from"ffmpeg-static";import dt from"ora";import{homedir as Dc}from"os";import{join as fi}from"path";import{readdir as Fc}from"fs/promises";var Lc="conceptcraft";function Je(){return fi(Dc(),`.${Lc}`,"projects")}function Wt(t){return fi(Je(),t)}async function Jn(){try{let t=Je();return(await Fc(t,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function hi(t,n){let e=2,o=`${t}-${e}`;for(;n.includes(o);)e++,o=`${t}-${e}`;return o}import{Command as Uc}from"commander";import _c from"ora";import{execSync as Mc,spawnSync as ze}from"child_process";import{mkdirSync as yi,existsSync as Jt,readFileSync as xi,writeFileSync as bi}from"fs";import{join as Re,basename as Vc}from"path";import{tmpdir as jc}from"os";function zt(t,n){try{return Mc(n,{stdio:"ignore"}),!0}catch{return!1}}function Ht(t){let n=Math.floor(t/60),e=Math.floor(t%60),o=Math.round(t%1*10);return`${n}:${String(e).padStart(2,"0")}.${o}`}function qc(t){let n=ze("ffprobe",["-v","error","-show_entries","format=duration","-of","default=noprint_wrappers=1:nokey=1",t],{encoding:"utf-8"});return parseFloat(n.stdout.trim())}function Bc(t,n){let e=ze("ffmpeg",["-i",t,"-vf",`select='gt(scene,${n})',showinfo`,"-vsync","vfr","-f","null","-"],{encoding:"utf-8",timeout:12e4}),o=[0],r=(e.stderr||"").split(`
3754
+ `);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 Gc(t,n,e){let o=[];for(let r=0;r<n.length;r++){let i=n[r]+.5,a=Re(e,`scene_${String(r+1).padStart(2,"0")}.jpg`);ze("ffmpeg",["-ss",String(i),"-i",t,"-vframes","1","-q:v","2","-y",a],{stdio:"ignore",timeout:3e4}),o.push(a)}return o}function Wc(t,n){let e=Re(n,"audio.wav");if(ze("ffmpeg",["-i",t,"-vn","-acodec","pcm_s16le","-ar","16000","-ac","1","-y",e],{stdio:"ignore",timeout:6e4}),!Jt(e)||!zt("whisper","which whisper")&&!zt("whisper-cpp","which whisper-cpp"))return null;let r=ze("whisper",[e,"--model","base","--output_format","json","--output_dir",n,"--language","en"],{encoding:"utf-8",timeout:3e5}),i=Re(n,"audio.json");if(!Jt(i))return null;try{let a=JSON.parse(xi(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 Hc(t,n){let e=xi(t).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:[e],stream:!1}),r=ze("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 vi=new Uc("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(t,n)=>{let e=_c();Jt(t)||(console.error(`File not found: ${t}`),process.exit(1)),zt("ffmpeg","which ffmpeg")||(console.error("ffmpeg is required. Install: brew install ffmpeg"),process.exit(1)),n.vision!==!1&&!zt("ollama","which ollama")&&(console.error("ollama is required for vision. Install: brew install ollama"),process.exit(1));let o=n.output||Re(jc(),`video-analyze-${Date.now()}`);yi(o,{recursive:!0});let r=Re(o,"frames");yi(r,{recursive:!0});let i=parseFloat(n.threshold),a=n.model;e.start("Reading video metadata...");let s=qc(t);e.succeed(`Video: ${Ht(s)} (${s.toFixed(1)}s)`),e.start("Detecting scenes...");let l=Bc(t,i);e.succeed(`Detected ${l.length} scenes`),e.start("Extracting key frames...");let u=Gc(t,l,r);e.succeed(`Extracted ${u.length} key frames`);let f=null;n.transcribe!==!1&&(e.start("Transcribing audio..."),f=Wc(t,o),f?e.succeed(`Transcribed: ${f.segments.length} segments`):e.warn("Transcription skipped (whisper not installed: pip install openai-whisper)"));let v=[];for(let g=0;g<l.length;g++){let T=l[g],y=g<l.length-1?l[g+1]:s,b="";n.vision!==!1&&Jt(u[g])&&(e.start(`Describing scene ${g+1}/${l.length}...`),b=Hc(u[g],a),e.succeed(`Scene ${g+1}: ${b}`)),v.push({id:g+1,startTime:T,endTime:y,duration:y-T,framePath:u[g],description:b})}let I={source:t,duration:s,scenes:v,transcript:f};if(n.outputFormat==="json"){let g=JSON.stringify(I,null,2),T=Re(o,"analysis.json");bi(T,g),console.log(g)}else{let g=["# Video Analysis","",`**Source:** ${Vc(t)}`,`**Duration:** ${Ht(s)} (${s.toFixed(1)}s)`,`**Scenes:** ${v.length}`,"","## Scenes",""];for(let b of v){if(g.push(`### Scene ${b.id} (${Ht(b.startTime)} - ${Ht(b.endTime)}) [${b.duration.toFixed(1)}s]`),b.description&&g.push(`**Visual:** ${b.description}`),f?.segments){let S=f.segments.filter(D=>D.end>b.startTime&&D.start<b.endTime);S.length>0&&g.push(`**Audio:** ${S.map(D=>D.text).join(" ").trim()}`)}g.push(`**Frame:** ${b.framePath}`),g.push("")}f?.text&&(g.push("## Full Transcript"),g.push(""),g.push(f.text.trim()),g.push(""));let T=g.join(`
3755
+ `),y=Re(o,"analysis.md");bi(y,T),console.log(T),console.log(`
3756
+ Results saved to: ${o}`)}});var Yc="inizio-inc/remotion-video-template#main",Xe=30;async function Kc(t){let n=await lt(t,"utf-8");return JSON.parse(n)}async function Qc(t){let n=G(t,"template.manifest.json");try{return await Kc(n)}catch{return{entry:"src/Root.tsx",compositions:[{id:"Main",type:"youtube",aspect:"16:9",default:!0}]}}}function wi(){try{return Ye("bun --version",{stdio:"ignore"}),!0}catch{return!1}}function Zc(t){if(t.includes("---")||t.includes("[Section")){let r=t.split(/---|\[Section \d+\]/i).filter(i=>i.trim());if(r.length>1)return r.map(i=>i.trim())}let n=t.split(/(?<=[.!?])\s+/).map(r=>r.trim()).filter(r=>r.length>0),e=[],o="";for(let r of n){let i=r.split(/\s+/).length;o?(e.push(`${o} ${r}`),o=""):i<5&&e.length<n.length-1?o=r:e.push(r)}return o&&(e.length>0?e[e.length-1]+=` ${o}`:e.push(o)),e}function el(t,n,e=Xe,o){if(o&&o.characters.length>0)return tl(t,o,e);let r=t.reduce((a,s)=>a+s.split(/\s+/).length,0),i=0;return t.map((a,s)=>{let l=a.split(/\s+/).length,u=l/r,f=n*u,v=Math.round(f*e),I=a.split(""),g=f/I.length,T={characters:I,characterStartTimesSeconds:I.map((b,S)=>S*g),characterEndTimesSeconds:I.map((b,S)=>(S+1)*g)},y={id:s+1,text:a,wordCount:l,startTime:i,endTime:i+f,durationInSeconds:f,durationInFrames:v,timestamps:T};return i+=f,y})}function tl(t,n,e){let{characters:o,characterStartTimesSeconds:r,characterEndTimesSeconds:i}=n,a=o.join(""),s=[],l=0;for(let u=0;u<t.length;u++){let f=t[u],v=f.length;for(;l<o.length&&o[l].match(/^\s*$/);)l++;let I=l,g=r[I]||0;l+=v;let T=l-1;for(;T>I&&o[T]?.match(/^\s*$/);)T--;let y=i[Math.min(T,i.length-1)]||g+1,b=y-g,S=Math.round(b*e),D={characters:o.slice(I,T+1),characterStartTimesSeconds:r.slice(I,T+1).map($=>$-g),characterEndTimesSeconds:i.slice(I,T+1).map($=>$-g)};s.push({id:u+1,text:f,wordCount:f.split(/\s+/).length,startTime:g,endTime:y,durationInSeconds:b,durationInFrames:S,timestamps:D})}return s}function nl(t){let n=t==="tiktok"?"vertical":t==="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 ol(t,n,e){let o=G(t,"public"),r=G(t,"scripts");await Ke(o,{recursive:!0}),await Ke(r,{recursive:!0});let i=G(o,"scenes.json");await ye(i,JSON.stringify(nl(n),null,2),"utf-8");let a=`import { execSync } from "node:child_process";
3757
3757
 
3758
3758
  execSync("${e} video generate plan --project .", { stdio: "inherit" });
3759
3759
  `,s=`import { execSync } from "node:child_process";
3760
3760
 
3761
3761
  const args = process.argv.slice(2).join(" ");
3762
3762
  execSync("${e} video export --project . " + args, { stdio: "inherit" });
3763
- `;await ye(G(r,"plan.ts"),a,"utf-8"),await ye(G(r,"export.ts"),s,"utf-8")}async function vi(){return process.stdin.isTTY?null:new Promise(t=>{let n="",e=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",o=>{n+=o}),process.stdin.on("end",()=>{e||(e=!0,t(n.trim()||null))}),process.stdin.on("error",()=>{e||(e=!0,t(null))}),setTimeout(()=>{!e&&!n&&(e=!0,t(null))},500)})}function nl(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function ol(t){let n={shortTitle:"Video",elements:[],audio:[],text:[],scenes:[]},e=!0;return t.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:e?1.3:1,to:e?1:1.3,startMs:0,endMs:a}]}),e=!e):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 Yt(t,n){if(t.startsWith("data:")){let r=t.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");await ye(n,i);return}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to download: ${e.status}`);let o=await e.arrayBuffer();await ye(n,Buffer.from(o))}function rl(t){try{let o=new URL(t).pathname.split(".").pop()?.toLowerCase();if(o&&["jpg","jpeg","png","gif","webp"].includes(o))return o}catch{}return"jpg"}var il=new Z("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 t=>{let n=t.format,e=n==="human"?dt("Initializing...").start():null,o=t.project?ct(process.cwd(),t.project):null;try{let r=await vi(),i=null;if(t.scenes&&!t.scriptFile&&(t.scriptFile=t.scenes),o&&(t.output=G(o,"public"),t.scriptFile?t.scriptFile=ct(o,t.scriptFile):!t.script&&!r&&(t.scriptFile=G(o,"public","scenes.json"))),r)try{let k=JSON.parse(r);k.scenes&&Array.isArray(k.scenes)&&(i=k)}catch{}if(!i&&t.scriptFile)try{let k=await lt(t.scriptFile,"utf-8"),J=JSON.parse(k);J.scenes&&Array.isArray(J.scenes)&&(i=J)}catch{}let a=i?.voice||t.voice,s=i?.voiceId,l=i?.provider,u=i?.model,f=i?.voiceInstructions,v=i?.musicPrompt||t.musicPrompt||"uplifting background music, positive energy",I=i?.musicDuration,g=G(t.output,"audio"),S=G(t.output,"images"),y=G(t.output,"videos");e&&(e.text="Creating directories..."),await Ke(g,{recursive:!0}),await Ke(S,{recursive:!0}),await Ke(y,{recursive:!0});let b=0,R=[],M=0,$=[],_=[];if(i&&i.scenes.length>0){n==="human"&&(e?.stop(),m(`Processing ${i.scenes.length} scenes...`),e?.start());let k=i.scenes.map((ne,B)=>{let ge=ne.script;return ne.voiceStyle&&(ge=`${ne.voiceStyle} ${ge}`),{text:ge,id:`scene-${B}`}});e&&(e.text="Generating speech for all scenes...");let J=await Ao({texts:k,options:{provider:l,voice:a,voiceId:s,model:u,voiceSettings:i.voiceSettings,instructions:f}});b+=J.totalCost;let te=0;for(let ne=0;ne<i.scenes.length;ne++){let B=i.scenes[ne],ge=nl(B.name),le=J.results[ne];e&&(e.text=`[${B.name}] Saving audio...`);let Zt=G(g,`${ge}.${le.format}`);await ye(Zt,le.audioData);let $e=le.duration,Ai=Math.round($e*Ye),Ze={id:ne+1,name:B.name,text:B.script,wordCount:B.script.split(/\s+/).length,startTime:te,endTime:te+$e,durationInSeconds:$e,durationInFrames:Ai,audioPath:`audio/${ge}.${le.format}`,timestamps:le.timestamps};if(B.imageQuery){e&&(e.text=`[${B.name}] Searching image...`);try{let K=await wt({query:B.imageQuery,options:{maxResults:1,size:"large",safeSearch:!0}}),et=K.data.results.flatMap(Y=>Y.results);if(b+=K.data.totalCost,et.length>0){let Y=et[0],tt=rl(Y.url),Se=`${ge}.${tt}`,en=G(S,Se);await Yt(Y.url,en),Ze.imagePath=`images/${Se}`,$.push({path:`images/${Se}`,url:Y.url,width:Y.width,height:Y.height,query:B.imageQuery})}}catch(K){n==="human"&&(e?.stop(),L(`[${B.name}] Image search failed: ${K instanceof Error?K.message:"Unknown"}`),e?.start())}}if(B.videoQuery){e&&(e.text=`[${B.name}] Searching video...`);try{let K=await cn({query:B.videoQuery,options:{maxResults:1,license:"free"}}),et=K.data.results.flatMap(Y=>Y.results);if(b+=K.data.totalCost,et.length>0){let Y=et[0],tt=Y.previewUrl||Y.downloadUrl;if(tt){let Se=`${ge}.mp4`,en=G(y,Se);await Yt(tt,en),Ze.videoPath=`videos/${Se}`,_.push({path:`videos/${Se}`,url:tt,width:Y.width,height:Y.height,duration:Y.duration,query:B.videoQuery})}}}catch(K){n==="human"&&(e?.stop(),L(`[${B.name}] Video search failed: ${K instanceof Error?K.message:"Unknown"}`),e?.start())}}if(R.push(Ze),te+=$e,M+=$e,n==="human"){e?.stop();let K=[`audio: ${$e.toFixed(1)}s`,Ze.imagePath?"image":null,Ze.videoPath?"video":null].filter(Boolean).join(", ");C(` ${B.name}: ${K}`),e?.start()}}}else{let k=t.script;if(t.scriptFile)try{k=await lt(t.scriptFile,"utf-8")}catch(le){e?.stop(),c(`Failed to read script file: ${le instanceof Error?le.message:"Unknown error"}`),process.exit(d.INVALID_INPUT)}(!k||k.trim().length===0)&&(e?.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=t.topic||k.split(".")[0].slice(0,50);e&&(e.text="Generating voiceover...");let te=await xt({text:k,options:{voice:a}}),ne=G(g,`voiceover.${te.format}`);await ye(ne,te.audioData),b+=te.cost,M=te.duration;let B=Kc(k);R=Qc(B,te.duration,Ye,te.timestamps).map((le,Zt)=>({...le,name:`Section${Zt+1}`,audioPath:`audio/voiceover.${te.format}`})),n==="human"&&(e?.stop(),C(`Voiceover: ${ne} (${te.duration.toFixed(1)}s)`),e?.start())}e&&(e.text="Creating timeline...");let w=ol(R),V=Math.max(w.audio.length>0?Math.max(...w.audio.map(k=>k.endMs)):0,w.text.length>0?Math.max(...w.text.map(k=>k.endMs)):0,w.elements.length>0?Math.max(...w.elements.map(k=>k.endMs)):0),q=V/1e3,ee=I?Math.min(300,Math.max(3,I)):Math.min(300,Math.ceil(q));console.log("[Music Generation] Requesting music:",{prompt:v,requestedDuration:ee,totalAudioDuration:M,actualVideoDuration:q,timelineDurationMs:V});let Qe,Xt;e&&(e.text="Generating music and thumbnail...");let Ti=`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: ${R.map(k=>k.text).join(" ")}`,Kt=[],ki=(async()=>{if(ee<3)return n==="human"&&(e?.stop(),L(`Video duration (${q.toFixed(1)}s) is too short for music generation (minimum 3s).`),e?.start()),null;try{let k=await vt({prompt:v,duration:ee});if(k.status!=="completed"&&k.status!=="failed"&&(k=await ue(()=>ot(k.requestId),60,2e3)),k.status==="failed")throw new Error(k.error||"Unknown error");let J=G(g,"music.mp3");return k.audioUrl&&await Yt(k.audioUrl,J),{path:"audio/music.mp3",duration:k.duration||ee,prompt:v,cost:k.cost||0}}catch(k){return n==="human"&&(e?.stop(),L(`Music generation failed: ${k.message}`),e?.start()),null}})();Kt.push(ki);let Ri=(async()=>{try{let k=await Oo({prompt:Ti,options:{width:1280,height:720}});if(k.success&&k.data.url){let J=G(t.output,"thumbnail.jpg");return await Yt(k.data.url,J),b+=k.data.cost||0,J}return null}catch(k){return n==="human"&&(e?.stop(),L(`Thumbnail generation failed: ${k.message}`),e?.start()),null}})();Kt.push(Ri);let[Ae,Zn]=await Promise.all(Kt);Ae&&(Qe=Ae,b+=Ae.cost||0,n==="human"&&(e?.stop(),C(`Music: ${G(g,"music.mp3")} (${Ae.duration}s)`),Ae.duration<q&&L(`Music duration (${Ae.duration.toFixed(1)}s) is shorter than video duration (${q.toFixed(1)}s).`),e?.start())),Zn&&(Xt=Zn,n==="human"&&(e?.stop(),C(`Thumbnail: ${Xt}`),e?.start())),e&&(e.text="Writing manifest...");let eo=Math.round(q*Ye),to={music:Qe,thumbnail:Xt?"thumbnail.jpg":void 0,images:$,videos:_,scenes:R,timeline:w,totalDurationInFrames:eo,fps:Ye,totalCost:b,createdAt:new Date().toISOString()},Qt=G(t.output,"video-manifest.json");if(await ye(Qt,JSON.stringify(to,null,2)),e?.stop(),n==="json"){let{totalCost:k,...J}=to;x(J);return}if(n==="quiet"){console.log(Qt);return}console.log(),C("Video assets created successfully!"),console.log(),m(`Scenes: ${R.length} (${eo} frames at ${Ye}fps)`);for(let k of R){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: ${Qe?.path} (${Qe?.duration}s)`),m(`Manifest: ${Qt}`),console.log(),m(`Total cost: $${b.toFixed(4)}`)}catch(r){e?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),al=new Z("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(t,n)=>{let{maxResults:e,orientation:o,license:r,format:i}=n,a=i==="human"?dt("Finding videos...").start():null;try{let s=await cn({query:t,options:{maxResults:parseInt(e,10),orientation:o,license:r}});a?.stop();let l=s.data.results.flatMap(u=>u.results);if(i==="json"){let{totalCost:u,...f}=s.data;x({...s,data:f});return}if(i==="quiet"){l.forEach(u=>{console.log(u.previewUrl||u.thumbnailUrl)});return}if(l.length===0){m("No videos found");return}C(`Found ${l.length} videos for "${t}"`),console.log(),l.forEach((u,f)=>{console.log(`[${f+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(d.GENERAL_ERROR)}}),sl=new Z("new").description("Create a new video project from a template").argument("<name>","Project directory name").option("-t, --template <repo>","GitHub repo (user/repo#commit)",zc).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(t,n)=>{let e=n.format,o=e==="human"?dt("Initializing video project...").start():null;try{let r=Je();await Ke(r,{recursive:!0});let i=Wt(t),a=n.type,s=await zn();if(s.includes(t)){let g=gi(t,s);o?.stop(),c(`Project "${t}" already exists at: ${i}`),m(`Try: ${p.commands[0]} video generate new ${g}`),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[u,f]=n.template.split("#"),v=f?`-b ${f}`:"";try{Xe(`git clone ${v} --depth 1 https://github.com/${u}.git "${i}"`,{stdio:"pipe"}),await Xn(G(i,".git"),{recursive:!0,force:!0})}catch(g){o?.stop(),c(`Failed to clone template: ${g instanceof Error?g.message:"Unknown error"}`),process.exit(d.GENERAL_ERROR)}e==="human"&&(o?.stop(),C(`Template downloaded to ${t}/`),o?.start());let I;try{I=await Xc(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 tl(i,a,p.commands[0]),n.install){let g=xi()?"bun":"npm";o&&(o.text=`Installing dependencies with ${g}...`),await new Promise((S,y)=>{let b=Wc(g,["install"],{cwd:i,stdio:"pipe",shell:!0});b.on("close",R=>{R===0?S():y(new Error(`${g} install failed with code ${R}`))}),b.on("error",y)}),e==="human"&&(o?.stop(),C("Dependencies installed"),o?.start())}if(o?.stop(),e==="json"){x({name:t,path:i,template:n.template,type:a,installed:n.install});return}if(e==="quiet"){console.log(i);return}console.log(),C(`Video project "${t}" 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(` ${p.commands[0]} video generate assets --scenes public/scenes.json`),m(` ${p.commands[0]} video generate plan`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),cl=new Z("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 t=>{let n=dt("Generating video plan...").start();try{let e=t.context;if(!e){let l=await vi();l&&(e=l)}e||(n.stop(),c("Provide context via stdin or --context flag"),process.exit(d.INVALID_INPUT));let o;if(t.branding)try{o=await lt(t.branding,"utf-8")}catch{n.stop(),c(`Could not read branding file: ${t.branding}`),process.exit(d.INVALID_INPUT)}let r=t.renderTarget==="remotion"?"remotion":"hyperframes",i={context:e,branding:o,renderTarget:r};if(t.wait===!1){n.stop(),x(await un(i));return}let a=await Uo(i);n.stop(),a.success||(c(a.error||"Failed to generate plan"),process.exit(d.GENERAL_ERROR));let s=a.data;t.output?(await ye(t.output,s),C(`Plan saved to ${t.output}`)):console.log(s)}catch(e){n.stop(),c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ll=new Z("generate").description("Generate parts of a video project").addCommand(sl).addCommand(il).addCommand(cl),dl=new Z("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve video generation");try{x(await Lo({brief:n.brief,durationSec:Number(n.duration),format:n.format,title:t,topic:n.topic}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),wi=new Z("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 t=>{if(!t.yes)return c("Pass --yes to approve plan generation");try{let n=t.branding?await lt(t.branding,"utf-8"):void 0;x(await un({branding:n,context:t.context,renderTarget:t.renderTarget==="remotion"?"remotion":"hyperframes"}))}catch(n){c(n instanceof Error?n.message:"Plan generation failed"),process.exit(d.GENERAL_ERROR)}}),ul=new Z("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(t,n)=>{try{x(await F(n.plan?"generateVideoPlan":"createVideo",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),ml=new Z("status").description("Read video-plan background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("generateVideoPlan",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}});wi.addCommand(ml);var pl=new Z("projects").description("List all video projects").option("-f, --format <format>","Output format: human, json","human").action(async t=>{let n=await zn();if(t.format==="json"){x({projectsDir:Je(),projects:n.map(e=>({name:e,path:Wt(e)}))});return}if(n.length===0){m("No video projects found"),m(`Projects are stored in: ${Je()}`);return}console.log(`
3764
- Video Projects:`),console.log("-".repeat(50));for(let e of n)console.log(` ${e}`),console.log(` ${Wt(e)}`);console.log()}),gl=new Z("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 t=>{let n=t.format,e=n==="human"?dt("Injecting thumbnail...").start():null;try{let o=ct(t.video),r=ct(t.thumbnail),i=t.output?ct(t.output):o.replace(/\.mp4$/,"-with-thumb.mp4");await Yn(o),await Yn(r);let a=Jc;if(a)try{await Yn(a)}catch{a=null}if(!a)try{a=Xe("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let s=Hc(a,["-i",o],{encoding:"utf8"});if(s.error)throw new Error(`Failed to probe video: ${s.error.message}`);let l=(s.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!l)throw new Error("Could not detect video dimensions");let[,u,f]=l;e&&(e.text="Creating thumbnail frame...");let v="/tmp/cc-thumb-frame.mp4";Xe(`${a} -y -loop 1 -i "${r}" -vf "scale=${u}:${f}:force_original_aspect_ratio=decrease,pad=${u}:${f}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${v}"`,{stdio:"pipe"}),e&&(e.text="Concatenating with video...");let I="/tmp/cc-concat-video.mp4";if(Xe(`${a} -y -i "${v}" -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"}),e&&(e.text="Adding file icon thumbnail..."),Xe(`${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 Xn(v,{force:!0}),await Xn(I,{force:!0}),e?.stop(),n==="json"){x({success:!0,output:i});return}if(n==="quiet"){console.log(i);return}C(`Thumbnail injected: ${i}`)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),fl=new Z("thumbnail").description("Thumbnail operations").addCommand(gl),Kn=new Z("video").description("Video generation commands").addCommand(ll).addCommand(al).addCommand(pl).addCommand(fl).addCommand(bi);Kn.addCommand(dl).addCommand(wi).addCommand(ul);import{Command as Qn}from"commander";var hl=new Qn("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve visual-abstract generation");try{x(await A("createVisualAbstract",{approvalReceipt:"cli:--yes",aspectRatio:n.aspect,brandingId:n.brandingId,brief:t,outputPreset:n.preset,qualityTier:n.quality,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),yl=new Qn("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await F("createVisualAbstract",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Si=new Qn("visual-abstract").description("Visual abstract commands").addCommand(hl).addCommand(yl);var bl=[zr,Yr,Gr,mi,ei,Zr,Xr,Kn,ii,si,ri,ai,Hr,Kr,ni,Vr,Si,Qr,Ur,qr];function Ci(t){for(let n of bl)t.addCommand(n)}var vl="0.3.8",W=new xl,be=p.commands[0];W.name(be).description(p.description).version(vl,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output").configureOutput({outputError:(t,n)=>{n(ce.red(t))}});W.addCommand(cr);W.addCommand(lr);W.addCommand(Jo);W.addCommand(or);W.addCommand(zo);W.addCommand(Zo);W.addCommand(nr);W.addCommand(Dr);W.addCommand(er);W.addCommand(Fr);W.addCommand(He);W.addCommand($t);W.addCommand(jo);Ci(W);var Ii=Ko();Ii.commands.length>0&&W.addCommand(Ii);W.on("command:*",t=>{console.error(ce.red(`Error: Unknown command '${t[0]}'`)),console.error(),console.error(`Run '${be} --help' to see available commands.`),process.exit(1)});W.addHelpText("after",`
3763
+ `;await ye(G(r,"plan.ts"),a,"utf-8"),await ye(G(r,"export.ts"),s,"utf-8")}async function Si(){return process.stdin.isTTY?null:new Promise(t=>{let n="",e=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",o=>{n+=o}),process.stdin.on("end",()=>{e||(e=!0,t(n.trim()||null))}),process.stdin.on("error",()=>{e||(e=!0,t(null))}),setTimeout(()=>{!e&&!n&&(e=!0,t(null))},500)})}function rl(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function il(t){let n={shortTitle:"Video",elements:[],audio:[],text:[],scenes:[]},e=!0;return t.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:e?1.3:1,to:e?1:1.3,startMs:0,endMs:a}]}),e=!e):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 Xt(t,n){if(t.startsWith("data:")){let r=t.match(/^data:[^;]+;base64,(.+)$/);if(!r)throw new Error("Invalid data URL format");let i=Buffer.from(r[1],"base64");await ye(n,i);return}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to download: ${e.status}`);let o=await e.arrayBuffer();await ye(n,Buffer.from(o))}function al(t){try{let o=new URL(t).pathname.split(".").pop()?.toLowerCase();if(o&&["jpg","jpeg","png","gif","webp"].includes(o))return o}catch{}return"jpg"}var sl=new Z("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 t=>{let n=t.format,e=n==="human"?dt("Initializing...").start():null,o=t.project?ct(process.cwd(),t.project):null;try{let r=await Si(),i=null;if(t.scenes&&!t.scriptFile&&(t.scriptFile=t.scenes),o&&(t.output=G(o,"public"),t.scriptFile?t.scriptFile=ct(o,t.scriptFile):!t.script&&!r&&(t.scriptFile=G(o,"public","scenes.json"))),r)try{let R=JSON.parse(r);R.scenes&&Array.isArray(R.scenes)&&(i=R)}catch{}if(!i&&t.scriptFile)try{let R=await lt(t.scriptFile,"utf-8"),J=JSON.parse(R);J.scenes&&Array.isArray(J.scenes)&&(i=J)}catch{}let a=i?.voice||t.voice,s=i?.voiceId,l=i?.provider,u=i?.model,f=i?.voiceInstructions,v=i?.musicPrompt||t.musicPrompt||"uplifting background music, positive energy",I=i?.musicDuration,g=G(t.output,"audio"),T=G(t.output,"images"),y=G(t.output,"videos");e&&(e.text="Creating directories..."),await Ke(g,{recursive:!0}),await Ke(T,{recursive:!0}),await Ke(y,{recursive:!0});let b=0,S=[],D=0,$=[],N=[];if(i&&i.scenes.length>0){n==="human"&&(e?.stop(),m(`Processing ${i.scenes.length} scenes...`),e?.start());let R=i.scenes.map((ne,B)=>{let ge=ne.script;return ne.voiceStyle&&(ge=`${ne.voiceStyle} ${ge}`),{text:ge,id:`scene-${B}`}});e&&(e.text="Generating speech for all scenes...");let J=await Ro({texts:R,options:{provider:l,voice:a,voiceId:s,model:u,voiceSettings:i.voiceSettings,instructions:f}});b+=J.totalCost;let te=0;for(let ne=0;ne<i.scenes.length;ne++){let B=i.scenes[ne],ge=rl(B.name),le=J.results[ne];e&&(e.text=`[${B.name}] Saving audio...`);let Zt=G(g,`${ge}.${le.format}`);await ye(Zt,le.audioData);let $e=le.duration,Ei=Math.round($e*Xe),Ze={id:ne+1,name:B.name,text:B.script,wordCount:B.script.split(/\s+/).length,startTime:te,endTime:te+$e,durationInSeconds:$e,durationInFrames:Ei,audioPath:`audio/${ge}.${le.format}`,timestamps:le.timestamps};if(B.imageQuery){e&&(e.text=`[${B.name}] Searching image...`);try{let K=await wt({query:B.imageQuery,options:{maxResults:1,size:"large",safeSearch:!0}}),et=K.data.results.flatMap(X=>X.results);if(b+=K.data.totalCost,et.length>0){let X=et[0],tt=al(X.url),Se=`${ge}.${tt}`,en=G(T,Se);await Xt(X.url,en),Ze.imagePath=`images/${Se}`,$.push({path:`images/${Se}`,url:X.url,width:X.width,height:X.height,query:B.imageQuery})}}catch(K){n==="human"&&(e?.stop(),_(`[${B.name}] Image search failed: ${K instanceof Error?K.message:"Unknown"}`),e?.start())}}if(B.videoQuery){e&&(e.text=`[${B.name}] Searching video...`);try{let K=await cn({query:B.videoQuery,options:{maxResults:1,license:"free"}}),et=K.data.results.flatMap(X=>X.results);if(b+=K.data.totalCost,et.length>0){let X=et[0],tt=X.previewUrl||X.downloadUrl;if(tt){let Se=`${ge}.mp4`,en=G(y,Se);await Xt(tt,en),Ze.videoPath=`videos/${Se}`,N.push({path:`videos/${Se}`,url:tt,width:X.width,height:X.height,duration:X.duration,query:B.videoQuery})}}}catch(K){n==="human"&&(e?.stop(),_(`[${B.name}] Video search failed: ${K instanceof Error?K.message:"Unknown"}`),e?.start())}}if(S.push(Ze),te+=$e,D+=$e,n==="human"){e?.stop();let K=[`audio: ${$e.toFixed(1)}s`,Ze.imagePath?"image":null,Ze.videoPath?"video":null].filter(Boolean).join(", ");C(` ${B.name}: ${K}`),e?.start()}}}else{let R=t.script;if(t.scriptFile)try{R=await lt(t.scriptFile,"utf-8")}catch(le){e?.stop(),c(`Failed to read script file: ${le instanceof Error?le.message:"Unknown error"}`),process.exit(d.INVALID_INPUT)}(!R||R.trim().length===0)&&(e?.stop(),c("Provide scenes via stdin JSON, --scenes/--script-file with scenes JSON, or --script for legacy mode"),process.exit(d.INVALID_INPUT)),R=R.trim();let J=t.topic||R.split(".")[0].slice(0,50);e&&(e.text="Generating voiceover...");let te=await xt({text:R,options:{voice:a}}),ne=G(g,`voiceover.${te.format}`);await ye(ne,te.audioData),b+=te.cost,D=te.duration;let B=Zc(R);S=el(B,te.duration,Xe,te.timestamps).map((le,Zt)=>({...le,name:`Section${Zt+1}`,audioPath:`audio/voiceover.${te.format}`})),n==="human"&&(e?.stop(),C(`Voiceover: ${ne} (${te.duration.toFixed(1)}s)`),e?.start())}e&&(e.text="Creating timeline...");let w=il(S),V=Math.max(w.audio.length>0?Math.max(...w.audio.map(R=>R.endMs)):0,w.text.length>0?Math.max(...w.text.map(R=>R.endMs)):0,w.elements.length>0?Math.max(...w.elements.map(R=>R.endMs)):0),q=V/1e3,ee=I?Math.min(300,Math.max(3,I)):Math.min(300,Math.ceil(q));console.log("[Music Generation] Requesting music:",{prompt:v,requestedDuration:ee,totalAudioDuration:D,actualVideoDuration:q,timelineDurationMs:V});let Qe,Yt;e&&(e.text="Generating music and thumbnail...");let Ri=`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: ${S.map(R=>R.text).join(" ")}`,Kt=[],Ai=(async()=>{if(ee<3)return n==="human"&&(e?.stop(),_(`Video duration (${q.toFixed(1)}s) is too short for music generation (minimum 3s).`),e?.start()),null;try{let R=await vt({prompt:v,duration:ee});if(R.status!=="completed"&&R.status!=="failed"&&(R=await ue(()=>ot(R.requestId),60,2e3)),R.status==="failed")throw new Error(R.error||"Unknown error");let J=G(g,"music.mp3");return R.audioUrl&&await Xt(R.audioUrl,J),{path:"audio/music.mp3",duration:R.duration||ee,prompt:v,cost:R.cost||0}}catch(R){return n==="human"&&(e?.stop(),_(`Music generation failed: ${R.message}`),e?.start()),null}})();Kt.push(Ai);let $i=(async()=>{try{let R=await Eo({prompt:Ri,options:{width:1280,height:720}});if(R.success&&R.data.url){let J=G(t.output,"thumbnail.jpg");return await Xt(R.data.url,J),b+=R.data.cost||0,J}return null}catch(R){return n==="human"&&(e?.stop(),_(`Thumbnail generation failed: ${R.message}`),e?.start()),null}})();Kt.push($i);let[Ae,Qn]=await Promise.all(Kt);Ae&&(Qe=Ae,b+=Ae.cost||0,n==="human"&&(e?.stop(),C(`Music: ${G(g,"music.mp3")} (${Ae.duration}s)`),Ae.duration<q&&_(`Music duration (${Ae.duration.toFixed(1)}s) is shorter than video duration (${q.toFixed(1)}s).`),e?.start())),Qn&&(Yt=Qn,n==="human"&&(e?.stop(),C(`Thumbnail: ${Yt}`),e?.start())),e&&(e.text="Writing manifest...");let Zn=Math.round(q*Xe),eo={music:Qe,thumbnail:Yt?"thumbnail.jpg":void 0,images:$,videos:N,scenes:S,timeline:w,totalDurationInFrames:Zn,fps:Xe,totalCost:b,createdAt:new Date().toISOString()},Qt=G(t.output,"video-manifest.json");if(await ye(Qt,JSON.stringify(eo,null,2)),e?.stop(),n==="json"){let{totalCost:R,...J}=eo;x(J);return}if(n==="quiet"){console.log(Qt);return}console.log(),C("Video assets created successfully!"),console.log(),m(`Scenes: ${S.length} (${Zn} frames at ${Xe}fps)`);for(let R of S){let J=[R.audioPath?"audio":null,R.imagePath?"image":null,R.videoPath?"video":null].filter(Boolean).join(", ");m(` - ${R.name}: ${R.durationInSeconds.toFixed(1)}s [${J}]`)}m(`Music: ${Qe?.path} (${Qe?.duration}s)`),m(`Manifest: ${Qt}`),console.log(),m(`Total cost: $${b.toFixed(4)}`)}catch(r){e?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),cl=new Z("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(t,n)=>{let{maxResults:e,orientation:o,license:r,format:i}=n,a=i==="human"?dt("Finding videos...").start():null;try{let s=await cn({query:t,options:{maxResults:parseInt(e,10),orientation:o,license:r}});a?.stop();let l=s.data.results.flatMap(u=>u.results);if(i==="json"){let{totalCost:u,...f}=s.data;x({...s,data:f});return}if(i==="quiet"){l.forEach(u=>{console.log(u.previewUrl||u.thumbnailUrl)});return}if(l.length===0){m("No videos found");return}C(`Found ${l.length} videos for "${t}"`),console.log(),l.forEach((u,f)=>{console.log(`[${f+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(d.GENERAL_ERROR)}}),ll=new Z("new").description("Create a new video project from a template").argument("<name>","Project directory name").option("-t, --template <repo>","GitHub repo (user/repo#commit)",Yc).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(t,n)=>{let e=n.format,o=e==="human"?dt("Initializing video project...").start():null;try{let r=Je();await Ke(r,{recursive:!0});let i=Wt(t),a=n.type,s=await Jn();if(s.includes(t)){let g=hi(t,s);o?.stop(),c(`Project "${t}" already exists at: ${i}`),m(`Try: ${p.commands[0]} video generate new ${g}`),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[u,f]=n.template.split("#"),v=f?`-b ${f}`:"";try{Ye(`git clone ${v} --depth 1 https://github.com/${u}.git "${i}"`,{stdio:"pipe"}),await Xn(G(i,".git"),{recursive:!0,force:!0})}catch(g){o?.stop(),c(`Failed to clone template: ${g instanceof Error?g.message:"Unknown error"}`),process.exit(d.GENERAL_ERROR)}e==="human"&&(o?.stop(),C(`Template downloaded to ${t}/`),o?.start());let I;try{I=await Qc(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 ol(i,a,p.commands[0]),n.install){let g=wi()?"bun":"npm";o&&(o.text=`Installing dependencies with ${g}...`),await new Promise((T,y)=>{let b=Jc(g,["install"],{cwd:i,stdio:"pipe",shell:!0});b.on("close",S=>{S===0?T():y(new Error(`${g} install failed with code ${S}`))}),b.on("error",y)}),e==="human"&&(o?.stop(),C("Dependencies installed"),o?.start())}if(o?.stop(),e==="json"){x({name:t,path:i,template:n.template,type:a,installed:n.install});return}if(e==="quiet"){console.log(i);return}console.log(),C(`Video project "${t}" 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(` ${wi()?"bun":"npm"} install`),m(" bun run dev # Preview in Remotion Studio"),m(` ${p.commands[0]} video generate assets --scenes public/scenes.json`),m(` ${p.commands[0]} video generate plan`)}catch(r){o?.stop(),c(r instanceof Error?r.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),dl=new Z("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 t=>{let n=dt("Generating video plan...").start();try{let e=t.context;if(!e){let l=await Si();l&&(e=l)}e||(n.stop(),c("Provide context via stdin or --context flag"),process.exit(d.INVALID_INPUT));let o;if(t.branding)try{o=await lt(t.branding,"utf-8")}catch{n.stop(),c(`Could not read branding file: ${t.branding}`),process.exit(d.INVALID_INPUT)}let r=t.renderTarget==="remotion"?"remotion":"hyperframes",i={context:e,branding:o,renderTarget:r};if(t.wait===!1){n.stop(),x(await un(i));return}let a=await Lo(i);n.stop(),a.success||(c(a.error||"Failed to generate plan"),process.exit(d.GENERAL_ERROR));let s=a.data;t.output?(await ye(t.output,s),C(`Plan saved to ${t.output}`)):console.log(s)}catch(e){n.stop(),c(e instanceof Error?e.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),ul=new Z("generate").description("Generate parts of a video project").addCommand(ll).addCommand(sl).addCommand(dl),ml=new Z("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve video generation");try{x(await Fo({brief:n.brief,durationSec:Number(n.duration),format:n.format,title:t,topic:n.topic}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),Ci=new Z("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 t=>{if(!t.yes)return c("Pass --yes to approve plan generation");try{let n=t.branding?await lt(t.branding,"utf-8"):void 0;x(await un({branding:n,context:t.context,renderTarget:t.renderTarget==="remotion"?"remotion":"hyperframes"}))}catch(n){c(n instanceof Error?n.message:"Plan generation failed"),process.exit(d.GENERAL_ERROR)}}),pl=new Z("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(t,n)=>{try{x(await U(n.plan?"generateVideoPlan":"createVideo",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),gl=new Z("status").description("Read video-plan background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("generateVideoPlan",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}});Ci.addCommand(gl);var fl=new Z("projects").description("List all video projects").option("-f, --format <format>","Output format: human, json","human").action(async t=>{let n=await Jn();if(t.format==="json"){x({projectsDir:Je(),projects:n.map(e=>({name:e,path:Wt(e)}))});return}if(n.length===0){m("No video projects found"),m(`Projects are stored in: ${Je()}`);return}console.log(`
3764
+ Video Projects:`),console.log("-".repeat(50));for(let e of n)console.log(` ${e}`),console.log(` ${Wt(e)}`);console.log()}),hl=new Z("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 t=>{let n=t.format,e=n==="human"?dt("Injecting thumbnail...").start():null;try{let o=ct(t.video),r=ct(t.thumbnail),i=t.output?ct(t.output):o.replace(/\.mp4$/,"-with-thumb.mp4");await zn(o),await zn(r);let a=Xc;if(a)try{await zn(a)}catch{a=null}if(!a)try{a=Ye("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let s=zc(a,["-i",o],{encoding:"utf8"});if(s.error)throw new Error(`Failed to probe video: ${s.error.message}`);let l=(s.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!l)throw new Error("Could not detect video dimensions");let[,u,f]=l;e&&(e.text="Creating thumbnail frame...");let v="/tmp/cc-thumb-frame.mp4";Ye(`${a} -y -loop 1 -i "${r}" -vf "scale=${u}:${f}:force_original_aspect_ratio=decrease,pad=${u}:${f}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${v}"`,{stdio:"pipe"}),e&&(e.text="Concatenating with video...");let I="/tmp/cc-concat-video.mp4";if(Ye(`${a} -y -i "${v}" -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"}),e&&(e.text="Adding file icon thumbnail..."),Ye(`${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 Xn(v,{force:!0}),await Xn(I,{force:!0}),e?.stop(),n==="json"){x({success:!0,output:i});return}if(n==="quiet"){console.log(i);return}C(`Thumbnail injected: ${i}`)}catch(o){e?.stop(),c(o instanceof Error?o.message:"Unknown error"),process.exit(d.GENERAL_ERROR)}}),yl=new Z("thumbnail").description("Thumbnail operations").addCommand(hl),Yn=new Z("video").description("Video generation commands").addCommand(ul).addCommand(cl).addCommand(fl).addCommand(yl).addCommand(vi);Yn.addCommand(ml).addCommand(Ci).addCommand(pl);import{Command as Kn}from"commander";var bl=new Kn("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(t,n)=>{if(!n.yes)return c("Pass --yes to approve visual-abstract generation");try{x(await A("createVisualAbstract",{approvalReceipt:"cli:--yes",aspectRatio:n.aspect,brandingId:n.brandingId,brief:t,outputPreset:n.preset,qualityTier:n.quality,teamId:n.teamId,title:n.title}))}catch(e){c(e instanceof Error?e.message:"Generation failed"),process.exit(d.GENERAL_ERROR)}}),xl=new Kn("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{x(await U("createVisualAbstract",t,n.teamId))}catch(e){c(e instanceof Error?e.message:"Status failed"),process.exit(d.GENERAL_ERROR)}}),Ii=new Kn("visual-abstract").description("Visual abstract commands").addCommand(bl).addCommand(xl);var vl=[Yr,Kr,Hr,gi,ni,ti,Qr,Yn,si,li,ai,ci,zr,Zr,ri,qr,Ii,ei,Mr,Gr];function Ti(t){for(let n of vl)t.addCommand(n)}var Sl="0.3.10",W=new wl,be=p.commands[0];W.name(be).description(p.description).version(Sl,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output").configureOutput({outputError:(t,n)=>{n(ce.red(t))}});W.addCommand(sr);W.addCommand(cr);W.addCommand(Ho);W.addCommand(nr);W.addCommand(Jo);W.addCommand(Qo);W.addCommand(tr);W.addCommand(Lr);W.addCommand(Zo);W.addCommand(Ur);W.addCommand(He);W.addCommand($t);W.addCommand(Vo);Ti(W);var ki=Yo();ki.commands.length>0&&W.addCommand(ki);W.on("command:*",t=>{console.error(ce.red(`Error: Unknown command '${t[0]}'`)),console.error(),console.error(`Run '${be} --help' to see available commands.`),process.exit(1)});W.addHelpText("after",`
3765
3765
  ${ce.bold("Examples:")}
3766
3766
  ${ce.gray("# Log in (opens browser)")}
3767
3767
  $ ${be} login
@@ -3794,4 +3794,4 @@ ${ce.bold("Authentication:")}
3794
3794
 
3795
3795
  ${ce.bold("More Info:")}
3796
3796
  ${ce.blue(p.docsUrl)}
3797
- `);W.parse(Lr(process.argv.slice(2)),{from:"user"});
3797
+ `);W.parse(_r(process.argv.slice(2)),{from:"user"});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conceptcraft/mindframes",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "CLI tool for creating AI-powered presentations with ConceptCraft",
5
5
  "type": "module",
6
6
  "bin": {