@conceptcraft/mindframes 0.3.25 → 0.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +382 -362
- 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 f={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 G from"chalk";import{Command as bR}from"commander";import tn from"chalk";import{Command as ep}from"commander";function la(e={}){let t=(d,u)=>{let g=e[d];return g&&g.trim().length>0?g.trim():u},n=t("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),r=t("NEXT_PUBLIC_CLI_COMMAND","ccr"),o=t("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),i=t("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${o}`),c=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:o,name:i.replace(/^\./,""),displayName:n,description:`CLI tool for ${n} presentation generation`,commands:[r,o],apiUrl:t("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:t("NEXT_PUBLIC_DOCS_URL",`https://docs.${n.toLowerCase()}.ai`),packageName:t("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${c}_API_KEY`,apiUrlEnvVar:`${c}_API_URL`,codexSelfConnectorAppId:e.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var p=typeof f<"u"&&f?f:la(process.env);import _ from"chalk";import Zr from"cli-table3";import Iu from"conf";import ma from"path";var pa=p.apiUrl,ku={apiKey:{type:"string"},apiUrl:{type:"string",default:pa},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}};function xu(e=p.apiKeyEnvVar){return e.endsWith("_API_KEY")?`${e.slice(0,-8)}_CONFIG_DIR`:`${e}_CONFIG_DIR`}function Ru(e=process.env){let t=xu(),n=e[t]?.trim()||e.CC_SLIDES_CONFIG_DIR?.trim();if(n){if(!ma.isAbsolute(n))throw new Error(`${t} must be an absolute directory path`);return ma.normalize(n)}}var ua=Ru(),U=new Iu({projectName:p.name,schema:ku,...ua?{configFileMode:384,cwd:ua}:{}});function ga(){return{apiKey:Pe(),apiUrl:B(),defaultTeamId:U.get("defaultTeamId"),accessToken:U.get("accessToken"),refreshToken:U.get("refreshToken"),tokenExpiresAt:U.get("tokenExpiresAt"),clientId:U.get("clientId"),clientSecret:U.get("clientSecret")}}function Pe(){let e=process.env[p.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return e||U.get("apiKey")}function Yr(e){U.set("apiKey",e)}function B(){let e=process.env[p.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return e||(U.get("apiUrl")??pa)}function Qr(e){U.set("apiUrl",e)}function te(){return U.get("defaultTeamId")}function gt(e){U.set("defaultTeamId",e)}function On(){U.clear()}function Zt(){return U.path}function ft(){return!!Pe()}function fa(){return U.get("accessToken")}function ha(){return U.get("refreshToken")}function Dn(e,t,n){U.set("accessToken",e),U.set("refreshToken",t),U.set("tokenExpiresAt",Date.now()+(n-60)*1e3)}function Nn(){U.delete("accessToken"),U.delete("refreshToken"),U.delete("tokenExpiresAt")}function ya(){let e=U.get("tokenExpiresAt");return e?Date.now()>=e:!0}function Qe(){return!!U.get("accessToken")&&!!U.get("refreshToken")}function ba(){return U.get("clientId")}function wa(){return U.get("clientSecret")}function va(e,t){U.set("clientId",e),U.set("clientSecret",t)}function k(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(_.green("\u2713"),e)}function a(e,t="human"){if(t!=="quiet"){if(t==="json"){console.error(JSON.stringify({error:e}));return}console.error(_.red("\u2717"),e)}}function L(e,t="human"){t!=="quiet"&&t!=="json"&&console.warn(_.yellow("\u26A0"),e)}function Ia(e,t="human"){t==="quiet"||t==="json"||console.error(_.cyan("\u2192"),e)}function b(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(_.blue("\u2139"),e)}function ht(e,t="en"){return e?`${B()}/${t}/view/presentations/${e}`:"N/A"}function ka(e,t={}){let{showLinks:n=!1,language:r="en"}=t,o=(d,u)=>d.length>u?`${d.slice(0,u-1)}\u2026`:d,i=d=>{if(!d)return"-";try{return new Date(d).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(n){let d=new Zr({head:[_.cyan("Slug"),_.cyan("Title"),_.cyan("Slides"),_.cyan("Created"),_.cyan("URL")]});for(let u of e)d.push([o(u.slug||u.id.slice(0,8),30),o(u.title||"Untitled",22),String(u.numberOfSlides||"-"),i(u.createdAt),ht(u.slug,r)]);return d.toString()}let c=new Zr({head:[_.cyan("Slug"),_.cyan("Title"),_.cyan("Slides"),_.cyan("Mode"),_.cyan("Created")],colWidths:[32,28,8,11,18]});for(let d of e)c.push([d.slug||d.id.slice(0,8),d.title||"Untitled",String(d.numberOfSlides||"-"),d.mode||"-",i(d.createdAt)]);return c.toString()}function xa(e){let t=[...e].sort((o,i)=>{if(o.isDefault&&!i.isDefault)return-1;if(!o.isDefault&&i.isDefault)return 1;let c=o.createdAt?new Date(o.createdAt).getTime():0;return(i.createdAt?new Date(i.createdAt).getTime():0)-c}),n=o=>{if(!o)return"-";try{return new URL(o).href}catch{return o.startsWith("http")?o:`https://${o}`}},r=new Zr({head:[_.cyan("Name"),_.cyan("Source"),_.cyan("Color"),_.cyan("Logo"),_.cyan("Default"),_.cyan("ID")]});for(let o of t){let i=o.primaryColor?`${_.bgHex(o.primaryColor)(" ")} ${o.primaryColor}`:"-";r.push([o.name,n(o.sourceUrl),i,o.logoUrl?_.green("\u2713"):_.gray("\u2717"),o.isDefault?_.green("\u2605"):"",o.id])}return r.toString()}function eo(e){try{return new Date(e).toLocaleString()}catch{return e}}function ve(e){console.log(),console.log(_.bold(e)),console.log(_.gray("\u2500".repeat(e.length)))}function C(e,t){console.log(` ${_.gray(`${e}:`)} ${t??"-"}`)}function Cu(e){return JSON.stringify(e,null,2)}function l(e){console.log(Cu(e))}import{createHash as io,randomUUID as re}from"crypto";import{readFileSync as Na,statSync as La}from"fs";import{basename as so}from"path";import{spawnSync as Su}from"child_process";import{existsSync as Eu,mkdtempSync as Tu,rmSync as $u,writeFileSync as Au}from"fs";import{tmpdir as Pu}from"os";import{join as Ra}from"path";import to from"ffmpeg-static";var Ou=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function Du(e){let t=Ou.exec(e);if(!t)return;let n=Number(t[1])*3600+Number(t[2])*60+Number(t[3]);return Number.isFinite(n)&&n>0?n:void 0}function Ca(e,t="audio"){if(e.length===0)return;let n=to&&Eu(to)?to:"ffmpeg",r=/^[a-z0-9]+$/i.test(t)?t:"audio",o=Tu(Ra(Pu(),"mf-tts-duration-")),i=Ra(o,`speech.${r}`);try{Au(i,e);let c=Su(n,["-hide_banner","-i",i],{encoding:"utf8"});return c.error?void 0:Du(c.stderr??"")}finally{$u(o,{force:!0,recursive:!0})}}import Ln from"chalk";var s={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function Nu(){let e=ha(),t=ba(),n=B();if(!e||!t)return null;try{let r=await fetch(`${n}/.well-known/oauth-authorization-server`);if(!r.ok)return null;let o=await r.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:t}),c=wa();c&&i.set("client_secret",c);let d=await fetch(o.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!d.ok)return Nn(),null;let u=await d.json();return Dn(u.access_token,u.refresh_token,u.expires_in),u.access_token}catch{return null}}async function Sa(){return Qe()?ya()?Nu():fa()||null:null}function Oe(){return Qe()||ft()}async function h(){if(!Oe()){let e=p.commands[0],t=p.apiKeyEnvVar;console.error(Ln.red("\u2717 Not authenticated.")),console.error(),console.error(Ln.bold("To authenticate, run:")),console.error(Ln.cyan(` ${e} login`)),console.error(),console.error(Ln.gray(`Or set ${t} environment variable.`)),process.exit(s.AUTH_ERROR)}}function Lu(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function Ea(){let e=Pe();if(e)return Lu(e)}function no(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(n=>e.startsWith(n))}import{mkdirSync as Uu,readFileSync as _u,writeFileSync as qu}from"fs";import{homedir as ju}from"os";import{join as Ta}from"path";import Vu from"ajv/dist/2020.js";var ro=new Map;function $a(){return Ta(ju(),".conceptcraft","schemas")}function Aa(e){return Ta($a(),`${e}.json`)}function Mu(e){try{let t=JSON.parse(_u(Aa(e),"utf8"));return typeof t?.catalogVersion=="number"&&t.schema?t:null}catch{return null}}function Bu(e,t){try{Uu($a(),{recursive:!0}),qu(Aa(e),JSON.stringify(t))}catch{}}async function Fu(e){let t=ro.get(e);if(t!==void 0)return t;try{let n=await Pa(e),r={catalogVersion:n.catalogVersion,schema:n.operationSchema??n.schema};return Bu(e,r),ro.set(e,r),r}catch{let n=Mu(e);return ro.set(e,n),n}}function Gu(e){let t=e.instancePath.replace(/^\//,"").replace(/\//g,"."),n=t.length>0?t:"(root)",r=e.keyword==="additionalProperties"?`: unknown field "${e.params.additionalProperty}"`:`: ${e.message??"invalid value"}`;return`${n}${r}`}async function Un(e,t){let n=await Fu(e);if(!n)return;let r;try{r=new Vu({allErrors:!0,strict:!1}).compile(n.schema)}catch{return}if(r(t))return;let o=(r.errors??[]).slice(0,10).map(Gu);throw new Error(`Request does not match the ${e} contract \u2014 ${o.join("; ")}`)}function ne(e,t){let n=e instanceof Error?e.message:"Unknown error";return!t||n.includes(t)?n:`${n} Request ID: ${t}. Resume with the matching status command; do not start a duplicate run.`}function ue(e,t={}){let n=e?.code?.trim()||t.defaultCode?.trim()||"",r=e?.message?.trim()||"The run failed without a reported reason.";return n?`[${n}] ${r}`:r}function oo(e){let t=e.status?.trim().toLowerCase()??"";return!!e.error||t==="failed"||t==="errored"||t==="cancelled"?`${e.runId?.trim()?`Run ${e.runId.trim()}`:"Run"} ${t||"failed"}: ${ue(e.error)}`:null}function Oa(e){let t=e.projectId??"<project-id>";return/Narration is still missing for \d+ slides?\./.test(e.message)?["Narration is captured from speaker notes when the video project is prepared, so 'presentation video refresh' will not backfill it.",`Fill each empty scene with: ${e.binary} presentation video-narration ${t} --slide-id <slide-id> (scene ids: ${e.binary} presentation video inspect ${t})`].join(`
|
|
4
|
-
`):/Every scene is excluded from the video\./.test(e.message)?`Include a scene again with: ${e.binary} presentation video edit ${t} --edit '{"type":"patch_scene","scene":1,"excluded":false}'`:null}async function Ie(){let e=await Sa();if(e)return{Authorization:`Bearer ${e}`};let t=Pe();return t?{"x-api-key":t}:{}}var D=class extends Error{constructor(n,r,o=1,i="operation_failed",c=!1){super(n);this.statusCode=r;this.exitCode=o;this.errorCode=i;this.retryable=c;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},Ua="Idempotency-Key";function Ku(e){return e&&e!=="GET"?{[Ua]:re()}:{}}async function Se(e,t={}){let n=B();if(!Oe()&&!t.allowUnauthenticated)throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let r=await Ie(),o=`${n}${e}`,i={...r,...Ku(t.method),...t.headers};t.body&&!t.stream&&(i["Content-Type"]="application/json");let c={method:t.method??"GET",headers:i};t.body&&(c.body=JSON.stringify(t.body));let d;try{d=await fetch(o,c)}catch(g){throw new D(`Network error: ${g instanceof Error?g.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!d.ok){let g=await d.text().catch(()=>""),w=Ju(g,d.status),v=1;switch(d.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 x=`[${w.code}] ${w.message}`;throw new D(x,d.status,v,w.code,w.retryable)}return t.stream?d:d.headers.get("content-type")?.includes("application/json")?d.json():d.text()}function Wu(e){switch(e){case 400:return"invalid_input";case 401:return"authentication_required";case 402:return"insufficient_credits";case 403:return"access_denied";case 404:return"not_found";case 429:return"rate_limited";case 503:return"service_unavailable";default:return"operation_failed"}}function Ju(e,t){let n=Wu(t),r=e.trim()||`HTTP ${t}: The request could not be completed.`;try{let o=JSON.parse(e),i=typeof o.error=="object"&&o.error!==null?o.error:void 0;if(o.ok===!1&&typeof i?.code=="string"&&typeof i.message=="string")return{code:i.code,message:i.message,retryable:i.retryable===!0};if(typeof o.error=="string")return{code:/^[a-z][a-z0-9_]+$/.test(o.error)?o.error:n,message:typeof o.message=="string"?o.message:o.error,retryable:t===429||t>=500}}catch{}return{code:n,message:r,retryable:t===429||t>=500}}async function Pa(e){return Se(`/api/cli/tools/${encodeURIComponent(e)}/schema`)}async function _a(){return Se("/api/cli/capabilities",{allowUnauthenticated:!0})}async function I(e,t,n){let r=await co(n),o=`?teamId=${encodeURIComponent(r)}`;return Se(`/api/cli/tool-runs/${encodeURIComponent(e)}/${encodeURIComponent(t)}${o}`)}async function m(e,t,n){let r=await co(t.teamId);return Se(`/api/cli/tools/${encodeURIComponent(e)}`,{body:{...t,teamId:r},headers:n?{[Ua]:n}:void 0,method:"POST"})}function W(e){return co(e)}async function co(e){let t=typeof e=="string"&&e.trim()?e.trim():te()?.trim();if(t)return t;let n=await Ee();if(n.currentTeam?.id)return n.currentTeam.id;throw new D("Team ID required. Select a workspace with `mf config set team-id <id>` or pass --team-id.",400,void 0,"invalid_input")}async function qa(e){return Se("/api/llm-connections/profiles",{body:e,method:"POST"})}async function de(e,t,n,r=120){let o=0;for(let i=0;r===null||i<r;i++){let c;try{c=await I(e,t,n),o=0}catch(d){if(d instanceof D&&d.retryable&&o<2){o+=1,await new Promise(u=>setTimeout(u,2e3));continue}throw d instanceof D?new D(`${d.message} Request ID: ${t}.`,d.statusCode,d.exitCode,d.errorCode,d.retryable):new D(`${d instanceof Error?d.message:"Unknown error"} Request ID: ${t}.`,0,5,"poll_failed",!0)}if(c.done){if(c.error)throw new D(`${ue(c.error,{defaultCode:"operation_failed"})} Request ID: ${t}.`,500,1,c.error.code??"operation_failed",c.error.retryable);return c}await new Promise(d=>setTimeout(d,(c.nextPollAfterSeconds??2)*1e3))}throw new D(`[operation_timed_out] The background operation timed out. Request ID: ${t}.`,408,1,"operation_timed_out",!0)}function _n(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function zu(e){try{let n=new URL(e).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return n&&/^[a-z0-9]+$/.test(n)?n:void 0}catch{return}}function yt(e){let t=e.toLowerCase().split(".").pop();return{pdf:"application/pdf",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",mp4:"video/mp4",mov:"video/quicktime",mpeg:"video/mpeg",mpg:"video/mpeg",webm:"video/webm",aac:"audio/aac",m4a:"audio/mp4",mp3:"audio/mpeg",oga:"audio/ogg",ogg:"audio/ogg",wav:"audio/wav",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"}[t||""]||"application/octet-stream"}function Ze(e){let t=La(e);return{fileName:so(e),fileSize:t.size,fileType:yt(e)}}async function et(e,t){let n=Ze(e),r=Na(e),o=new FormData;for(let[c,d]of Object.entries(t.fields))o.append(c,d);o.append("file",new Blob([r],{type:n.fileType}),n.fileName);let i=await fetch(t.uploadUrl,{method:"POST",body:o});if(!i.ok)throw new D("Failed to upload file to storage",i.status,1);return{id:t.fileId??re(),name:n.fileName,s3Key:t.s3Key,url:t.fileUrl,size:n.fileSize,type:n.fileType,selected:!0}}async function Q(e,t={}){let n=B();if(!Oe())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let r=await Ie(),o=La(e),i=so(e),c=yt(e),d=Na(e),u=io("sha256").update(d).digest("hex"),g=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({fileMetadata:{lastModified:o.mtimeMs,name:i,type:c,size:o.size},...t.storagePrefix?{storagePrefix:t.storagePrefix}:{},...t.idempotencyKey?{uploadIdentity:{contentSha256:u,idempotencyKey:t.idempotencyKey}}:{}})});if(!g.ok){let v=await g.text();throw new D(v||"Failed to get upload URL",g.status,1)}let w=await g.json();return et(e,{...t.idempotencyKey?{fileId:`file-${io("sha256").update(JSON.stringify({contentSha256:u,fileName:i,idempotencyKey:t.idempotencyKey})).digest("hex")}`}:{},fields:w.fields||{},fileUrl:w.fileUrl,s3Key:w.uploadKey,uploadUrl:w.url})}async function ja(e,t,n={}){let r=[];for(let o=0;o<e.length;o++){let i=e[o],c=so(i);t?.(o,e.length,c);let d=await Q(i,{idempotencyKey:n.idempotencyKey});r.push(d)}return t?.(e.length,e.length,""),r}async function Va(e,t,n){let r={};for(let[o,i]of Object.entries(e))i!==void 0&&(r[o]=i);return r.brandingId===void 0&&typeof r.brandId=="string"&&(r.brandingId=r.brandId),delete r.brandId,m("createSlides",{...r,...n?{approvalReceipt:n}:{}},t)}async function Ma(e,t=20,n=0,r="updated"){return(await m("listPresentations",{limit:t,offset:n,sort:r,teamId:e})).presentations}async function bt(e,t){let n=t?.includeSlides!==!1,r=await m("getPresentation",{includeSlides:n,presentationId:e,teamId:t?.teamId});return n?{...r.presentation,slides:r.slides}:r.presentation}async function Ba(e,t,n,r){return m("generateSpeakerNotes",{...t,presentationId:e,teamId:r},n)}async function qn(e){let t=B(),n=await fetch(`${t}/api/durable-runs/${encodeURIComponent(e)}/events`,{headers:await Ie()});if(!n.ok)throw new D(await n.text(),n.status);return n}async function Fa(e,t={}){await m("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},t.idempotencyKey??`cli:presentation:delete:${io("sha256").update(JSON.stringify({slugOrId:e,teamId:t.teamId??null})).digest("hex")}`)}async function Ga(e,t){return m("updatePresentationVisibility",{presentationId:e,teamId:t.teamId,visibility:t.visibility},t.idempotencyKey??`cli:presentation:visibility:${re()}`)}async function Ka(e,t,n){return m("exportPresentation",{format:t,presentationId:e,teamId:n?.teamId})}async function Wa(e){let t;try{t=await fetch(e)}catch(n){throw new D(`Network error while downloading the export: ${n instanceof Error?n.message:"Unknown error"}`,0,5,"service_unavailable",!0)}if(!t.ok)throw new D(`[fetch_failed] The export download link returned ${t.status}. Signed links expire after one hour \u2014 re-run the export.`,t.status,1,"fetch_failed",!0);return t.arrayBuffer()}async function Ja(e,t,n={}){let r=B();if(!Oe())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let o=await Ie(),i=new FormData,c=new Blob([e],{type:"application/zip"});i.append("file",c,t),i.append("options",JSON.stringify({dryRun:n.dryRun??!1,remapIds:!0}));let d=await fetch(`${r}/api/presentations/import`,{method:"POST",headers:o,body:i}),u=await d.json();if(!d.ok)throw new D(u.errors?.[0]?.message??"Import failed",d.status,1);return u}async function za(e,t=25){return m("listSlideTemplates",{limit:t,search:e})}async function Ha(e,t,n,r,o){return m("extractBranding",{approvalReceipt:n,skipExistingBrandingLookup:r,teamId:t,url:e},o)}async function Ee(){return Se("/api/cli/whoami")}async function Xa(){return Se("/api/cli/features")}async function Ya(e,t,n={}){let r=B();if(!Oe())throw new D(`Not authenticated. Run '${p.commands[0]} login' or set ${p.apiKeyEnvVar} environment variable.`,401,2);let o=await Ie(),i=await fetch(`${r}/api/presentations/${e}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({documentCreatedAt:t,targetWordCount:n.targetWordCount??300,tone:n.tone??"professional",language:n.language??"en",targetAudience:n.targetAudience??"General Audience",blogFormat:n.blogFormat??"narrative",customInstructions:n.customInstructions??"",includeImages:n.includeImages??!0,includeTableOfContents:n.includeTableOfContents??!1})});if(!i.ok)throw new D(await i.text(),i.status,i.status===404?3:1);return i}async function lo(e){return m("getGenerationLimits",{teamId:e})}async function Qa(e,t,n){let r=await lo(n);if(!r.canGenerate[e]){let o=r.remaining[e]??0,i=r.limits[e]??0;throw i===0?new D(`The "${e}" mode is not available on your ${r.planName} plan. Available modes: ${r.availableModes.join(", ")||"none"}`,403,2):new D(`You have reached your ${e} generation limit for this billing cycle (${r.usage[e]??0}/${i} used). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,4)}if(r.maxSlidesPerPresentation!==-1&&t>r.maxSlidesPerPresentation)throw new D(`Maximum ${r.maxSlidesPerPresentation} slides allowed on your ${r.planName} plan (requested: ${t}). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,6);return r}function Hu(e){return e.replace(/[\u2014\u2013]/g,"-").replace(/[\u201C\u201D]/g,'"').replace(/[\u2018\u2019]/g,"'").replace(/\u2026/g,"...").replace(/\u00A0/g," ").replace(/[\u2010-\u2015]/g,"-").replace(/[\u2032\u2033]/g,"'")}async function Za(e,t){let n={...e,text:Hu(e.text)};await Un("generateSpeech",n);let r=await m("generateSpeech",{approvalReceipt:t?.approvalReceipt,...n},t?.idempotencyKey),o=await de("generateSpeech",r.runId),i=o.entity?.url;if(!i)throw new D(`Speech completed without an audio URL. Request ID: ${r.runId}.`,500);let c;try{c=await fetch(i)}catch(x){throw new D(`${x instanceof Error?x.message:"Failed to download speech audio"} Request ID: ${r.runId}.`,0,5,"download_failed",!0)}if(!c.ok)throw new D(`Failed to download speech audio. Request ID: ${r.runId}.`,c.status,5,"download_failed",c.status===429||c.status>=500);let d=o.output??{},u=e.options??{},g=Ce(d.format)??zu(i)??"mp3",w=Buffer.from(await c.arrayBuffer()),v=es(d.durationSec,d.duration,d.duration_s)??Ca(w,g);if(v===void 0)throw new D(`Speech completed without a measurable duration. Request ID: ${r.runId}.`,500,1,"invalid_audio_metadata");return{audioData:w,audioUrl:i,duration:v,provider:Ce(d.provider)??u.provider??"gemini",format:g,requestId:r.runId,voiceId:Ce(d.voice_id)??Ce(d.voiceId),voice:Ce(d.voice),model:Ce(d.model),speed:ao(d.speed)??u.speed,language:Ce(d.lang)??Ce(d.language)??u.language,langApplied:Da(d.langApplied)??Da(d.lang_applied),timestamps:Xu(d.timestamps),wordTimings:Yu(d.timestamps??d.timings)}}function es(...e){for(let t of e){let n=typeof t=="number"?t:typeof t=="string"&&t.trim()?Number(t):Number.NaN;if(Number.isFinite(n)&&n>0)return n}}function Xu(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=t.characters,r=t.characterStartTimesSeconds??t.character_start_times_seconds,o=t.characterEndTimesSeconds??t.character_end_times_seconds;if(!(!Array.isArray(n)||!Array.isArray(r)||!Array.isArray(o))&&!(n.length===0||n.length!==r.length||n.length!==o.length||!n.every(i=>typeof i=="string")||!r.every(i=>typeof i=="number"&&Number.isFinite(i))||!o.every(i=>typeof i=="number"&&Number.isFinite(i))))return{characters:n,characterStartTimesSeconds:r,characterEndTimesSeconds:o}}function Yu(e){if(!Array.isArray(e))return;let t=e.flatMap(n=>{if(!n||typeof n!="object"||Array.isArray(n))return[];let r=n,o=Ce(r.text)??Ce(r.word),i=ao(r.start),c=ao(r.end);return o&&i!==void 0&&c!==void 0&&c>=i?[{text:o,start:i,end:c}]:[]});return t.length>0?t:void 0}function Ce(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function ao(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Da(e){return typeof e=="boolean"?e:void 0}async function ts(e){let t=e?`/api/cli/tts?provider=${e}`:"/api/cli/tts";return Se(t)}async function ns(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);return delete n.idempotency_key,await Un("generateMusic",n),{requestId:(await m("generateMusic",{...n,approvalReceipt:t?.approvalReceipt},r)).runId,status:"pending"}}async function mo(e){let t=await I("generateMusic",e);return{requestId:e,status:_n(t),audioUrl:t.entity?.url,duration:es(t.output?.durationSec,t.output?.duration,t.output?.duration_s),error:t.error?.message}}async function rs(e,t){return{requestId:(await m("mixAudio",{...e,approvalReceipt:t?.approvalReceipt},t?.idempotencyKey)).runId,status:"pending"}}async function uo(e){let t=await I("mixAudio",e);return{requestId:e,status:_n(t),outputUrl:t.entity?.url,error:t.error?.message}}async function os(e){return Se("/api/cli/images/search",{method:"POST",body:e})}async function is(e){return Se("/api/cli/videos/search",{method:"POST",body:e})}async function pe(e,t=60,n=2e3){let r=0;for(let o=0;o<t;o++){let i;try{i=await e(),r=0}catch(c){if(c instanceof D&&c.retryable&&r<2){r+=1,await new Promise(d=>setTimeout(d,n));continue}throw c}if(i.status==="completed"||i.status==="failed")return i;await new Promise(c=>setTimeout(c,n))}throw new D("Operation timed out",408,1)}async function as(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);delete n.idempotency_key,await Un("generateSfx",n);let o=await m("generateSfx",{...n,approvalReceipt:t?.approvalReceipt},r);return{id:o.runId,requestId:o.runId,status:"pending"}}async function po(e){let t=await I("generateSfx",e);return{id:t.entity?.id??e,requestId:e,status:_n(t),audioUrl:t.entity?.url,error:t.error?.message}}async function ss(e,t){return m("listPresenterOptions",{...e?{voiceLanguage:e}:{},...t?{teamId:t}:{}})}async function ds(e,t){return{requestId:(await m("generateAvatarVideo",e,t)).runId,status:"pending"}}async function go(e){let t=await I("generateAvatarVideo",e);return{durationSec:typeof t.output?.durationSec=="number"?t.output.durationSec:null,error:t.error?.message,requestId:e,status:_n(t),videoUrl:t.entity?.url}}async function cs(e,t){return m("lipsyncVideo",e,t??re())}async function ls(e,t){return m("clipVideo",e,t??re())}async function ms(){return(await m("listTranslationLanguages",{})).languages}async function us(e,t){return m("translateVideo",e,t??re())}async function ps(e,t,n){return m("createVideo",{...e,approvalReceipt:t},n)}async function gs(e){let{idempotencyKey:t,...n}=e;return m("analyzeVideoReference",n,t)}async function fs(e,t){return de("analyzeVideoReference",e,t)}async function hs(e,t){return de("selectPresentationVideoStockMusic",e,t)}async function ys(e,t){return de("preparePresentationVideoPreviews",e,t,null)}async function bs(e,t){return de("generateBrandVariations",e,t)}async function ws(e,t){return de("extractBrandProducts",e,t)}async function vs(e,t){return de("buildBrandVoice",e,t)}async function Is(e,t){return de("generateBrandGuardrails",e,t)}async function ks(e,t){return de("repairBrandQuality",e,t)}async function xs(e,t){return de("syncBrandToPresentations",e,t)}async function Rs(e,t){return de("syncBrandFoundation",e,t)}async function Cs(e){return m("listVoices",e)}async function Ss(e){return m("adoptLibraryVoice",e,re())}async function Es(e){return m("setVoiceFavorite",e,re())}async function Ts(e){return m("designVoice",e,re())}async function $s(e){return m("saveDesignedVoice",e,re())}async function As(e){return m("retireVoice",e,re())}async function Ps(e){return m("listCastPresets",e)}async function Os(e){return m("createCastPreset",e,re())}async function Ds(e){return m("updateCastPreset",e,re())}async function Ns(e,t){return m("deleteCastPreset",{presetId:e,...t?{teamId:t}:{}},re())}var Ls=[{billing:"free",category:"branding",description:"Attach a social handle to an accessible brand profile.",id:"addBrandSocialHandle",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social add",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Add a competitor to an accessible brand profile.",id:"addCompetitor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding competitor add",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"File an uploaded file on this workspace's Library shelf; a .zip is expanded into the files it holds.",id:"addLibraryFile",lifecycle:{mode:"bounded"},milestone:"M8",name:"file save",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Add a voice from the shared library to this workspace, so it can be used like one of your own.",id:"adoptLibraryVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice add",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"media",description:"Transcribe an uploaded recording and publish the transcript for generation.",id:"analyzeMediaAsset",lifecycle:{mode:"background",status:{cliCommand:"media analyze status",pollAfterSeconds:10}},milestone:"M8",name:"media analyze",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Analyze an uploaded video before using it as a source, motion, blocking, or pacing reference in a video storyboard. The completed status output includes the analysisId required by the storyboard's source-video binding.",id:"analyzeVideoReference",lifecycle:{mode:"background",status:{cliCommand:"video reference status",pollAfterSeconds:10}},milestone:"M8",name:"video reference analyze",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Version a presentation with changes from its already-linked brand.",id:"applyPresentationBrandChanges",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation apply-changes",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Approve a private or team brand for use.",id:"approveBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding approve",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Branch an immutable footage version into a new project.",id:"branchFootageProjectVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage branch",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Draft a brand's Voice and Context document from source material.",id:"buildBrandVoice",lifecycle:{mode:"background",status:{cliCommand:"branding voice build-status",pollAfterSeconds:3}},milestone:"M2",name:"branding voice build",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Cancel an active linked-presentation brand sync.",id:"cancelBrandPresentationSync",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding sync-cancel",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Request cancellation of an in-flight presentation MP4 render.",id:"cancelPresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video cancel",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Turn a ready video into short clips with virality scores (one clip-set artifact).",id:"clipVideo",lifecycle:{mode:"background",status:{cliCommand:"video clips status",pollAfterSeconds:20}},milestone:"M8",name:"video clips",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Mark a brand's onboarding review complete.",id:"completeBrandOnboarding",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding onboarding complete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"delegated",category:"artifacts",description:"Generate and persist an ad variation set.",id:"createAdSet",lifecycle:{mode:"background",status:{cliCommand:"ad-set status",pollAfterSeconds:10}},milestone:"M6",name:"ad-set create",operation:"generation",scopes:["ad-sets:write"],state:"available"},{billing:"free",category:"agents",description:"Activate an exact reviewed scheduled-agent draft.",id:"createAgent",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent create",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"quota",category:"branding",description:"Create an empty brand in the workspace.",id:"createBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding create",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Mint a brand- and actor-scoped storage upload target for one private or team brand.",id:"createBrandAssetUploadUrl",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset upload-url",operation:"query",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Save one way a cast member appears: a personal presenter (pp_* id), a backdrop, and optionally a voice, under a name unique to that person.",id:"createCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Save a markdown, CSV or plain-text document into the Library.",id:"createDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Create a transcript-native, versioned footage edit project.",id:"createFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"media",description:"Generate and persist an image.",id:"createImage",lifecycle:{mode:"background",status:{cliCommand:"image status",pollAfterSeconds:10}},milestone:"M5",name:"image generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Mint an upload target for a file this caller will file in the Library.",id:"createLibraryFileUploadUrl",lifecycle:{mode:"bounded"},milestone:"M8",name:"file upload-url",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Create a Library folder, optionally inside another folder.",id:"createLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"dynamic",category:"artifacts",description:"Generate and persist a microsite.",id:"createMicrosite",lifecycle:{mode:"background",status:{cliCommand:"microsite status",pollAfterSeconds:10}},milestone:"M6",name:"microsite create",operation:"generation",scopes:["microsites:write"],state:"available"},{billing:"free",category:"artifacts",description:"Create a standalone poll.",id:"createPoll",lifecycle:{mode:"bounded"},milestone:"M3",name:"poll create",operation:"mutation",scopes:["polls:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Create an MP4 video from a finished presentation, or render an existing presentation-video project.",id:"createPresentationVideo",lifecycle:{mode:"background",status:{cliCommand:"presentation video status",pollAfterSeconds:10}},milestone:"M4",name:"presentation video",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a deterministic, owned-project-scoped upload target for custom presentation-video music.",id:"createPresentationVideoMusicUploadUrl",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video music upload-url",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Create a reusable personal presenter from approved footage, a headshot, or a synthetic-persona prompt.",id:"createPresenter",lifecycle:{mode:"background",status:{cliCommand:"avatar presenter status",pollAfterSeconds:10}},milestone:"M8",name:"avatar presenter create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"presentations",description:"Generate a presentation and persist the resulting deck.",id:"createSlides",lifecycle:{mode:"background",status:{cliCommand:"presentation status",pollAfterSeconds:20}},milestone:"M4",name:"create",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate one video from the opaque text and explicit metadata stored in a pinned storyboard revision.",id:"createVideo",lifecycle:{mode:"background",status:{cliCommand:"video status",pollAfterSeconds:20}},milestone:"M8",name:"video create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Create a versioned Markdown video storyboard.",id:"createVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"artifacts",description:"Generate a persisted standalone visual abstract.",id:"createVisualAbstract",lifecycle:{mode:"background",status:{cliCommand:"visual-abstract status",pollAfterSeconds:10}},milestone:"M5",name:"visual-abstract create",operation:"generation",scopes:["visual-abstracts:write"],state:"available"},{billing:"free",category:"branding",description:"Remove a brand from the library.",id:"deleteBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one asset record from a private or team brand's visible library.",id:"deleteBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one competitor from an accessible brand.",id:"deleteBrandCompetitor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding competitor delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one custom Foundation colour role.",id:"deleteBrandCustomColor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding foundation color delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one of a brand's guardrail rules.",id:"deleteBrandGuardrail",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one product from a brand.",id:"deleteBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one social account from an accessible brand.",id:"deleteBrandSocialHandle",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one per-channel brand design variant.",id:"deleteBrandVariant",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Retire a saved cast preset. Existing videos keep working; the preset stops being offered.",id:"deleteCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset delete",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Remove a document from the Library.",id:"deleteDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document delete",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Delete a Library folder and its descendants while returning their items to Unfiled.",id:"deleteLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders delete",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"presentations",description:"Permanently delete an owned presentation, all of its versions, and its publications.",id:"deletePresentation",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation delete",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"fixed",category:"media",description:"Generate candidate voices from a written description, or vary one you already heard.",id:"designVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice design",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Compare two points in a brand's version history.",id:"diffBrandVersions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version diff",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Create a replay-safe draft copy of one brand product with its assets and provenance.",id:"duplicateBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product duplicate",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"artifacts",description:"Edit a standalone poll.",id:"editPoll",lifecycle:{mode:"bounded"},milestone:"M3",name:"poll edit",operation:"mutation",scopes:["polls:write"],state:"available"},{billing:"free",category:"presentations",description:"Apply one atomic edit to a presentation-video draft. add_scene inserts an empty title scene after the reference; duplicate_scene inserts an independent copy of its visual, narration, voice, presenter and scene settings; replace_video_scene swaps the addressed scene for an owned reusable video while preserving its timeline identity. patch_scene with excluded toggles inclusion without deleting the scene.",id:"editPresentationVideoDraft",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video edit",operation:"mutation",scopes:["presentations:write","media:read"],state:"available"},{billing:"dynamic",category:"presentations",description:"Generate narration for the planned or explicitly selected presentation-video slides.",id:"ensurePresentationVideoNarration",lifecycle:{mode:"background",status:{cliCommand:"presentation video narrate status",pollAfterSeconds:5}},milestone:"M4",name:"presentation video narrate",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Render a presentation you can edit to HTML/PDF/PPTX and return a short-lived signed download URL.",id:"exportPresentation",lifecycle:{mode:"bounded"},milestone:"M1",name:"export",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"quota",category:"branding",description:"Extract and persist a reusable brand profile from a URL.",id:"extractBranding",lifecycle:{mode:"background",status:{cliCommand:"branding status",pollAfterSeconds:10}},milestone:"M2",name:"branding extract",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Discover a brand's products by crawling its site.",id:"extractBrandProducts",lifecycle:{mode:"background",status:{cliCommand:"branding product extract-status",pollAfterSeconds:3}},milestone:"M2",name:"branding product extract",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"dynamic",category:"research",description:"Extract bounded text and metadata from a source.",id:"extractContent",lifecycle:{mode:"bounded"},milestone:"M1",name:"content extract",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"knowledge",description:"File an artifact into a Library folder, or return it to Unfiled.",id:"fileArtifactIntoFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library file",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Permanently erase every stored version of a scheduled Agent memory.",id:"forgetAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory forget",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate one reusable avatar/presenter clip for composition into a video. Accepts a stock avatar id or a personal presenter's pp_* id as avatarId.",id:"generateAvatarVideo",lifecycle:{mode:"background",status:{cliCommand:"avatar status",pollAfterSeconds:10}},milestone:"M8",name:"avatar generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Draft guardrail rule proposals for a brand.",id:"generateBrandGuardrails",lifecycle:{mode:"background",status:{cliCommand:"branding guardrails generate-status",pollAfterSeconds:3}},milestone:"M2",name:"branding guardrails generate",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Generate a brand's per-channel design variants and gradients.",id:"generateBrandVariations",lifecycle:{mode:"background",status:{cliCommand:"branding variations status",pollAfterSeconds:3}},milestone:"M2",name:"branding variations generate",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate music from a direct brief or final video facts as an approved, recoverable run.",id:"generateMusic",lifecycle:{mode:"background",status:{cliCommand:"music status",pollAfterSeconds:10}},milestone:"M7",name:"music generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Generate a right-way or wrong-way scene clip from a picture and attach it as a layer to one or more scenes of a presentation video.",id:"generatePresentationVideoSceneClip",lifecycle:{mode:"background",status:{cliCommand:"presentation video scene-clip status",pollAfterSeconds:10}},milestone:"M8",name:"presentation video scene-clip generate",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate an additional look for an existing personal presenter while preserving the same Cast identity.",id:"generatePresenterLook",lifecycle:{mode:"background",status:{cliCommand:"avatar look status",pollAfterSeconds:10}},milestone:"M8",name:"avatar look generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate one sound-effect cue from a direct brief or final video facts as an approved, recoverable run.",id:"generateSfx",lifecycle:{mode:"background",status:{cliCommand:"sfx status",pollAfterSeconds:10}},milestone:"M7",name:"sfx generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Generate persisted speaker notes for a presentation version.",id:"generateSpeakerNotes",lifecycle:{mode:"background",status:{cliCommand:"presentation speaker-notes-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation speaker-notes",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate speech audio from text as an approved, recoverable run.",id:"generateSpeech",lifecycle:{mode:"background",status:{cliCommand:"tts status",pollAfterSeconds:10}},milestone:"M7",name:"tts generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"Read one owned Agent and its complete configuration.",id:"getAgent",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent get",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"Read what a scheduled Agent remembers. Memory is context recorded from its runs; it grants no permission and overrides no instruction.",id:"getAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory show",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"branding",description:"List competitors saved for an accessible brand profile.",id:"getBrandCompetitors",lifecycle:{mode:"bounded"},milestone:"M1",name:"branding competitor list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read the complete current brand footer settings.",id:"getBrandFooter",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding footer get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's guardrail rules.",id:"getBrandGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's design tokens, the keys it is missing, or its design.md document.",id:"getBrandProfile",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding profile",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read which decks have drifted from a brand.",id:"getBrandQuality",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding quality get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's Voice and Context document.",id:"getBrandVoice",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding voice get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"billing",description:"List every credit charge inside one activity group, with the run that made it.",id:"getCreditActivityGroup",lifecycle:{mode:"bounded"},milestone:"M8",name:"credits trace",operation:"query",scopes:["billing:read"],state:"available"},{billing:"free",category:"media",description:"Read an owned footage project and its append-only versions.",id:"getFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"presentations",description:"Read the workspace's per-mode generation limits, usage, remaining quota, plan and storage allowance.",id:"getGenerationLimits",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation limits",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"knowledge",description:"Return a bounded Open Knowledge Format workspace bundle.",id:"getKnowledgeBundle",lifecycle:{mode:"bounded"},milestone:"M1",name:"knowledge bundle",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search recent news sources.",id:"getNews",lifecycle:{mode:"bounded"},milestone:"M1",name:"search news",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"presentations",description:"Read an owned presentation and optionally its ordered slides.",id:"getPresentation",lifecycle:{mode:"bounded"},milestone:"M1",name:"get",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"branding",description:"Read changes in a presentation's already-linked brand.",id:"getPresentationBrandDrift",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation drift",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"presentations",description:"Read presentation ownership, access, and eligible team members.",id:"getPresentationSharing",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation sharing get",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one owned presentation-video Studio chat with safe attachment and scene-marker context.",id:"getPresentationVideoChatThread",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video chat",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read whether a presentation-video draft is behind its source deck without changing it.",id:"getPresentationVideoFreshness",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video freshness",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read preview run status and prepared image metadata for every video scene.",id:"getPresentationVideoPreviews",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video previews inspect",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read an owned presentation-video project and its ordered scene timeline.",id:"getPresentationVideoProject",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video inspect",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one MP4 render attempt with its exact snapshot and download metadata.",id:"getPresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video render",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one saved presentation-video draft snapshot without restoring it.",id:"getPresentationVideoVersion",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video version",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"agents",description:"Read one roster-visible Agent without exposing its private configuration.",id:"getRosterAgent",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent roster get",operation:"query",scopes:["agents:read"],state:"available"},{billing:"dynamic",category:"research",description:"Fetch a YouTube video's timestamped transcript, title, channel, and duration.",id:"getYoutubeTranscript",lifecycle:{mode:"bounded"},milestone:"M1",name:"transcript",operation:"query",scopes:["research:read"],state:"available"},{billing:"quota",category:"branding",description:"Import a reusable brand from DESIGN.md and optionally merge URL evidence.",id:"importBrandDesignMd",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding import",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Import a recording from a connected account into the media library.",id:"importConnectorRecording",lifecycle:{mode:"background",status:{cliCommand:"media import status",pollAfterSeconds:5}},milestone:"M8",name:"media import",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Import every completed provider-assisted take, preserving explicit source traceability when proven.",id:"importFootageProviderTakes",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage import-takes",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Import an attached PowerPoint as an auditable, review-gated Mindframes presentation.",id:"importPowerPoint",lifecycle:{mode:"background",status:{cliCommand:"presentation import status",pollAfterSeconds:5}},milestone:"M4",name:"presentation import",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Create proxy, filmstrip, and waveform evidence for one footage range.",id:"inspectFootageRange",lifecycle:{mode:"background",status:{cliCommand:"footage inspection-status",pollAfterSeconds:2}},milestone:"M8",name:"footage inspect",operation:"generation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"media",description:"Re-voice a ready video with new audio via provider lip-sync (one sibling re-voiced video artifact).",id:"lipsyncVideo",lifecycle:{mode:"background",status:{cliCommand:"video lipsync status",pollAfterSeconds:20}},milestone:"M8",name:"video lipsync",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"List the caller's roster: owned Agents plus same-workspace Agents shared with the team.",id:"listAgentRoster",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent roster list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"List the caller's scheduled Agents with stable cursor pagination.",id:"listAgents",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"List the user's secret-free Claude Code or Codex connection profiles and current selection.",id:"listAiConnectionProfiles",lifecycle:{mode:"bounded"},milestone:"M8",name:"ai-connections list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"branding",description:"Read a filtered, cursor-paginated activity feed for one brand.",id:"listBrandActivity",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding activity",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List uploaded assets attached to one private or team brand, optionally by kind.",id:"listBrandAssets",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List available workspace brand profiles, optionally filtered by name or domain.",id:"listBrandings",lifecycle:{mode:"bounded"},milestone:"M1",name:"branding list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the safe, owned job history for one brand.",id:"listBrandJobs",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding jobs list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List stable logo candidates and identify the active one.",id:"listBrandLogos",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List workspace members that a brand permission administrator can address.",id:"listBrandPermissionCandidates",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission candidates",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List explicit member access overrides for one team brand.",id:"listBrandPermissions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List presentations already linked to a brand.",id:"listBrandPresentations",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentations list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the products a brand sells.",id:"listBrandProducts",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the social accounts recorded as belonging to one accessible brand.",id:"listBrandSocialHandles",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's per-channel design variants.",id:"listBrandVariants",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's published versions.",id:"listBrandVersions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"media",description:"List saved ways a cast member appears \u2014 a trained presenter, a backdrop, and optionally a voice, under one name. Filtered to what the caller may actually use.",id:"listCastPresets",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset list",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"billing",description:"List a workspace's credit spend grouped by the artifact it was spent on.",id:"listCreditActivity",lifecycle:{mode:"bounded"},milestone:"M8",name:"credits activity",operation:"query",scopes:["billing:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the workspace's documents, newest first.",id:"listDocuments",lifecycle:{mode:"bounded"},milestone:"M8",name:"document list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"List a document's append-only version history.",id:"listDocumentVersions",lifecycle:{mode:"bounded"},milestone:"M8",name:"document versions",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the files this workspace filed in its Library.",id:"listLibraryFiles",lifecycle:{mode:"bounded"},milestone:"M8",name:"file list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the workspace Library folder tree in display order, optionally with item counts.",id:"listLibraryFolders",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"List presentations visible to the caller in one explicitly selected workspace.",id:"listPresentations",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the owned Studio chat threads for a presentation video.",id:"listPresentationVideoChatThreads",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video chats",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List every presentation-video draft for a source deck with stage and staleness.",id:"listPresentationVideoProjects",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video drafts",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List every MP4 render attempt for a presentation-video project.",id:"listPresentationVideoRenders",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video renders",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List saved presentation-video draft versions.",id:"listPresentationVideoVersions",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video versions",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"media",description:"List the personal-presenter engines, supported source kinds, customer-credit prices, and exact localized consent statement available to this workspace.",id:"listPresenterCreationOptions",lifecycle:{mode:"bounded"},milestone:"M8",name:"avatar presenter options",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List provider-neutral presenter avatars, voices, and voice languages, plus the workspace's trained personal presenters (`personal` roster group, pp_* ids).",id:"listPresenterOptions",lifecycle:{mode:"bounded"},milestone:"M8",name:"avatar options",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List ready generated clips and uploaded MediaAssets while excluding final presentation-to-MP4 renders.",id:"listReusableVideoClips",lifecycle:{mode:"bounded"},milestone:"M8",name:"video library list",operation:"query",scopes:["media:read","presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the slide design templates available to the workspace, plus system templates.",id:"listSlideTemplates",lifecycle:{mode:"bounded"},milestone:"M1",name:"templates",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"support",description:"List this workspace's support requests and their status; --mine narrows to the reports you filed.",id:"listSupportRequests",lifecycle:{mode:"bounded"},milestone:"M8",name:"support list",operation:"query",scopes:["support:read"],state:"available"},{billing:"free",category:"media",description:"List provider-neutral target languages for video translation.",id:"listTranslationLanguages",lifecycle:{mode:"bounded"},milestone:"M8",name:"video translate-languages",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List the voices this workspace can narrate with, filtered by the labels the provider states.",id:"listVoices",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice list",operation:"query",scopes:["media:read"],state:"available"},{billing:"dynamic",category:"media",description:"Mix voice, music, and sound-effect tracks as an approved, recoverable run.",id:"mixAudio",lifecycle:{mode:"background",status:{cliCommand:"mix status",pollAfterSeconds:10}},milestone:"M7",name:"mix create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Move a Library folder under a new parent or to the top level.",id:"moveLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders move",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Pause an owned Agent's schedule without changing its configuration.",id:"pauseAgentSchedule",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent pause",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"presentations",description:"Create or reuse a presentation-video project for a finished presentation.",id:"preparePresentationVideo",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video prepare",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Start or resume slide-preview preparation for a presentation-video draft.",id:"preparePresentationVideoPreviews",lifecycle:{mode:"background",status:{cliCommand:"presentation video previews status",pollAfterSeconds:2}},milestone:"M4",name:"presentation video previews prepare",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Publish the brand's working draft as a new live version.",id:"publishBrandVersion",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version publish",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Read the full content of an artifact this workspace owns: a presentation's slides, a video's request, narration and scenes, a narrated-video project's scene timeline, a microsite's or article's blocks, or a Library document.",id:"readArtifact",lifecycle:{mode:"bounded"},milestone:"M1",name:"artifact read",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"Read one document's full body and metadata.",id:"readDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document read",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"media",description:"Read a video storyboard and its immutable revision history.",id:"readVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Set or clear a Library folder's colour.",id:"recolorLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders recolor",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Create a private inactive scheduled-agent draft for review.",id:"recommendAgent",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent recommend",operation:"generation",scopes:["agents:write"],state:"available"},{billing:"free",category:"presentations",description:"Refresh deck-backed video scenes from the latest presentation version.",id:"refreshPresentationVideoSlides",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video refresh",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Regenerate one narration override in a presentation-video draft.",id:"regeneratePresentationVideoNarration",lifecycle:{mode:"background",status:{cliCommand:"presentation video-narration-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation video-narration",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Register an already-uploaded file in one private or team brand's asset library.",id:"registerBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset register",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove an exact logo candidate and select its deterministic fallback when active.",id:"removeBrandLogo",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo remove",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one member's explicit access override from a team brand.",id:"removeBrandPermission",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission remove",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Take a file off this workspace's Library shelf and delete its stored bytes.",id:"removeLibraryFile",lifecycle:{mode:"bounded"},milestone:"M8",name:"file remove",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"branding",description:"Rename one asset in a private or team brand's library.",id:"renameBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset rename",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Rename a Library folder.",id:"renameLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders rename",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"delegated",category:"media",description:"Render selected outputs from one exact, strategy-approved footage draft version.",id:"renderFootageProject",lifecycle:{mode:"background",status:{cliCommand:"footage render-status",pollAfterSeconds:5}},milestone:"M8",name:"footage render",operation:"generation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Render one scene of a presentation video to its own reusable MP4 segment and cache it for the final render.",id:"renderPresentationVideoScene",lifecycle:{mode:"background",status:{cliCommand:"presentation video scene status",pollAfterSeconds:10}},milestone:"M8",name:"presentation video scene render",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Repair decks that have visually drifted from a brand.",id:"repairBrandQuality",lifecycle:{mode:"background",status:{cliCommand:"branding quality repair-status",pollAfterSeconds:5}},milestone:"M2",name:"branding quality repair",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Resolve a brand's current draft design for an artifact context, including ordered node trace and conflicts.",id:"resolveBrandDesign",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding design resolve",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"knowledge",description:"Restore an earlier version by appending it as the current one.",id:"restoreDocumentVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"document restore",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Restore an immutable footage version as a new project head.",id:"restoreFootageProjectVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage restore",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Restore a saved presentation-video draft version as a new version, optionally only when both the current version and non-coalescing project revision still match expected values.",id:"restorePresentationVideoVersion",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video restore",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"agents",description:"Resume an owned Agent's saved schedule without changing its configuration.",id:"resumeAgentSchedule",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent resume",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"media",description:"Remove one of your own workspace voices and release the slot it holds.",id:"retireVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice remove",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Retry the failed or cancelled slide-preview run attached to a video draft.",id:"retryPresentationVideoPreviews",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video previews retry",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Append a semantic revision to a footage edit project.",id:"reviseFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage revise",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"media",description:"Create a new presenter Look by editing an existing Look without changing its source.",id:"revisePresenterLook",lifecycle:{mode:"background",status:{cliCommand:"avatar look revision-status",pollAfterSeconds:10}},milestone:"M8",name:"avatar look revise",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Create a new immutable revision of a Markdown video storyboard.",id:"reviseVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard revise",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one of a brand's products.",id:"saveBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Keep one of the candidates from designVoice as a reusable workspace voice.",id:"saveDesignedVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice save",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"research",description:"Read and normalize bounded content from a public URL.",id:"scrape",lifecycle:{mode:"bounded"},milestone:"M1",name:"scrape",operation:"query",scopes:["research:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search licensed image catalogs.",id:"searchImages",lifecycle:{mode:"bounded"},milestone:"M1",name:"search images",operation:"query",scopes:["research:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search current public web sources.",id:"searchInternet",lifecycle:{mode:"bounded"},milestone:"M1",name:"search web",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"knowledge",description:"Search the workspace Knowledge Hub across presentations, artifacts, context, and agents.",id:"searchKnowledge",lifecycle:{mode:"bounded"},milestone:"M1",name:"knowledge search",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"Search the presentation-video stock-music catalog and return preview metadata plus opaque selection tokens.",id:"searchPresentationVideoStockMusic",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video music stock search",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"dynamic",category:"media",description:"Search web and licensed stock-video catalogs with provider-neutral attribution.",id:"searchStockVideo",lifecycle:{mode:"bounded"},milestone:"M1",name:"search video",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"agents",description:"Select a Claude Code or Codex connection profile, or restore the native provider route.",id:"selectAiConnectionProfile",lifecycle:{mode:"bounded"},milestone:"M8",name:"ai-connections select",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Materialize a searched stock track, or auto-select from saved deck context, and persist it on a presentation-video project.",id:"selectPresentationVideoStockMusic",lifecycle:{mode:"background",status:{cliCommand:"presentation video music stock status",pollAfterSeconds:3}},milestone:"M4",name:"presentation video music stock select",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"agents",description:"Share an owned Agent with the workspace or return it to private visibility.",id:"setAgentVisibility",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent visibility set",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one custom Foundation colour role atomically.",id:"setBrandCustomColor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding foundation color set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Change one or more brand footer settings without guessing the rest.",id:"setBrandFooter",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding footer set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's gradient library and its role pointers.",id:"setBrandGradients",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding gradient set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one of a brand's guardrail rules.",id:"setBrandGuardrail",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Point a brand at an already-uploaded logo, dark-background logo variant, or favicon.",id:"setBrandLogo",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Set one team member's explicit access role for a team brand.",id:"setBrandPermission",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Atomically set approved and draft state for a bounded set of brand products.",id:"setBrandProductSelection",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product select",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Star or unstar a brand in your own library.",id:"setBrandStar",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding star",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one per-channel brand design variant.",id:"setBrandVariant",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Write a brand's Voice and Context document.",id:"setBrandVoice",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding voice set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Make one brand the default for this workspace or for you.",id:"setDefaultBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding set-default",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Set a presentation-video scene, or an exact slideIds batch atomically, to a specific avatar/look or saved preset, including the preset voice by default, or restore inheritance from the project default. A batch creates one saved version and does not render media.",id:"setPresentationVideoScenePresenter",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video presenter",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Set the poster image of a finished video.",id:"setVideoThumbnail",lifecycle:{mode:"bounded"},milestone:"M8",name:"video thumbnail set",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Star a voice so it stays at the top of your list, or remove the star. A star is a shortcut, never a permission.",id:"setVoiceFavorite",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice star",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"support",description:"File a bug, question, feature request or billing issue against Mindframes.",id:"submitSupportRequest",lifecycle:{mode:"bounded"},milestone:"M8",name:"support report",operation:"mutation",scopes:["support:write"],state:"available"},{billing:"free",category:"branding",description:"Mirror a brand's current flat data into its resolved DAG and active snapshot.",id:"syncBrandFoundation",lifecycle:{mode:"background",status:{cliCommand:"branding foundation sync-status",pollAfterSeconds:3}},milestone:"M2",name:"branding foundation sync",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Apply a brand to every presentation linked to it.",id:"syncBrandToPresentations",lifecycle:{mode:"background",status:{cliCommand:"branding sync-status",pollAfterSeconds:5}},milestone:"M2",name:"branding sync",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Evaluate a brand's guardrail rules against content.",id:"testBrandGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails test",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"presentations",description:"Transfer a complete presentation and all saved versions to an active team editor or admin.",id:"transferPresentationOwnership",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation transfer",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Transform an uploaded PowerPoint source into an auditable presentation review.",id:"transformPresentationImport",lifecycle:{mode:"background",status:{cliCommand:"presentation import transform-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation import transform",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Translate a ready video into sibling language versions (one video per target language).",id:"translateVideo",lifecycle:{mode:"background",status:{cliCommand:"video translate status",pollAfterSeconds:20}},milestone:"M8",name:"video translate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"Update an owned Agent's schedule, sources, outputs, delivery, review, runtime, or blueprint configuration.",id:"updateAgentConfiguration",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent configure",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"agents",description:"Add to or remove from what a scheduled Agent remembers.",id:"updateAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory set",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"branding",description:"Rename a brand or change which brand it sits under.",id:"updateBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding update",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Write a brand's design tokens from a key patch or a whole design.md document.",id:"updateBrandTokens",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Change a saved cast preset's name, presenter, backdrop, or voice. Sends the complete preset, not a patch.",id:"updateCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset update",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Edit a document's body, title or summary under an optimistic lock.",id:"updateDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document update",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"presentations",description:"Manage presentation collaborators and team access.",id:"updatePresentationSharing",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation sharing update",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Update avatar, presenter layout/background/scene visibility, voice, music, captions, format, and renderer settings for a presentation-video project. settings.sceneVoiceIds atomically merges exact scene voice overrides without changing omitted scenes or the default voice; settings changes do not render media.",id:"updatePresentationVideoSettings",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video settings",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Set who can open a presentation: public, team, or private.",id:"updatePresentationVisibility",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation visibility",operation:"mutation",scopes:["presentations:write"],state:"available"}];function jn(e){return{capabilities:Ls,catalogVersion:1,reason:e,source:"snapshot"}}async function en(e=_a){try{let{capabilities:t,catalogVersion:n}=await e();return!Array.isArray(t)||t.length===0?jn("the live catalog returned no capabilities"):{capabilities:t,catalogVersion:n,source:"live"}}catch(t){let n=t instanceof Error?t.message:String(t);return jn(n)}}import{InvalidArgumentError as Zu}from"commander";function y(e,t){return n=>{if(t.includes(n))return n;throw new Zu(`Expected one of: ${t.join(", ")}. Run the command with --help to see what ${e} accepts.`)}}var Us=["presentations","media","branding","knowledge","research","artifacts","agents","support"],tp=80,np=30;function rp(e){return e.billing!==void 0&&e.billing!=="free"&&e.billing!=="quota"}function op(e){return e.lifecycle?.mode==="background"}function ip(e,t){if(t<=0)return[e];let n=[],r="";for(let o of e.split(/\s+/).filter(Boolean))r===""?r=o:r.length+1+o.length<=t?r=`${r} ${o}`:(n.push(r),r=o);return r!==""&&n.push(r),n.length>0?n:[""]}function _s(e){let t=Us.indexOf(e);return t===-1?Us.length:t}function ap(e,t){let n=t.search?.trim().toLowerCase(),r=t.category?.trim().toLowerCase();return e.filter(o=>r&&(o.category??"").toLowerCase()!==r?!1:n?`${o.name} ${o.description??""}`.toLowerCase().includes(n):!0)}function sp(e){let t=new Map;for(let i of e){let c=i.category??"other",d=t.get(c);d?d.push(i):t.set(c,[i])}let n=[...t.entries()].sort(([i],[c])=>{let d=_s(i)-_s(c);return d!==0?d:i.localeCompare(c)}),r=Math.min(np,Math.max(...e.map(i=>i.name.length))),o=[];for(let[i,c]of n){c.sort((d,u)=>d.name.localeCompare(u.name)),o.length>0&&o.push(""),o.push(tn.bold(`${i} (${c.length})`));for(let d of c){let u=`${rp(d)?"$":" "}${op(d)?"*":" "}`,g=d.name.padEnd(r),w=2+r+1+u.length+1,v=Math.max(24,tp-w),x=ip(d.description??"",v);o.push(` ${tn.cyan(g)} ${tn.yellow(u)} ${x[0]??""}`.trimEnd());for(let T of x.slice(1))o.push(`${" ".repeat(w)}${T}`)}}return o}function dp(e){return e.map(t=>`${t.name} ${t.state} ${t.milestone}`)}function cp(e,t={filtered:!1}){if(e.length===0)return[t.filtered?"No capabilities match that filter.":"No capabilities available."];if(!e.some(i=>i.description||i.category))return dp(e);let r=p.commands[0],o=sp(e);return o.push(""),o.push(tn.dim(`${e.length} capabilities \xB7 $ = paid \xB7 * = background (returns a run id)`)),o.push(tn.dim(`Filter with: ${r} capabilities --search <query>`)),o}var qs=new ep("capabilities").description("Index of everything this CLI can do \u2014 every command, grouped and described").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").option("-s, --search <query>","Only show capabilities matching a query").option("--category <name>","Only show one category").action(async e=>{try{let t=await en(),n=ap(t.capabilities,e),r=!!(e.search||e.category);if(e.format==="json"){l({capabilities:n,catalogVersion:t.catalogVersion,source:t.source,...t.reason?{sourceReason:t.reason}:{}});return}if(e.format==="quiet"){for(let o of n)console.log(o.name);return}t.source==="snapshot"&&L(`Showing the capability list baked into this CLI build (${t.reason}); the deployed catalog may have moved on.`);for(let o of cp(n,{filtered:r}))console.log(o)}catch(t){a(t instanceof Error?t.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}});import{mkdirSync as pp,writeFileSync as gp}from"fs";import{dirname as Bs,join as fp}from"path";import{Command as qe}from"commander";import nn from"chalk";import{input as hp,password as yp,confirm as Fs,select as bp}from"@inquirer/prompts";import Mn from"ora";import lp from"conf";var Vn=new lp({projectName:"conceptcraft",configName:"feature-cache"}),mp=3600*1e3,up=1440*60*1e3;function js(e){let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);t=(t<<5)-t+r,t=t&t}return t.toString(16)}function Vs(){if(!ft())return null;let e=Vn.get("featureFlags");if(!e)return null;let t=js(Pe());if(e.apiKeyHash&&e.apiKeyHash!==t)return nt(),null;let n=Date.now()-e.fetchedAt;return n>up?null:(n>mp&&fo(),e.flags)}function fo(){tt().catch(()=>{})}async function tt(){let e=await Xa(),t=Pe();return Vn.set("featureFlags",{flags:e,fetchedAt:Date.now(),apiKeyHash:t?js(t):void 0}),e}function nt(){Vn.delete("featureFlags")}function Ms(){return Vn.path}var Gs=new qe("config").description("Manage CLI configuration: account settings, and the cached feature flags that decide which commands appear").addCommand(new qe("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(nn.bold(`${p.displayName} CLI Configuration`)),console.log(nn.gray("\u2500".repeat(35))),console.log();try{let e=await yp({message:"Enter your API key:",mask:"*",validate:r=>!r||r.trim().length===0?"API key is required":no(r.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(Yr(e.trim()),await Fs({message:`Use a custom API URL? (default: ${p.apiUrl.replace("https://","")})`,default:!1})){let r=await hp({message:"Enter API URL:",default:B(),validate:o=>{try{return new URL(o),!0}catch{return"Invalid URL format"}}});Qr(r)}console.log();let n=Mn("Verifying API key...").start();try{let r=await Ee();if(n.succeed("API key verified!"),console.log(),b(`Logged in as: ${r.user.email}`),r.teams.length===0)L("No teams found for this user.");else if(r.teams.length===1){let o=r.teams[0];gt(o.id),b(`Team: ${o.name} (${o.planName})`)}else{console.log(),b(`You have access to ${r.teams.length} teams.`);let o=await bp({message:"Select your default team:",choices:r.teams.map(c=>({name:`${c.name} (${c.planName}) - ${c.role}${c.isCurrent?" [current]":""}`,value:c.id})),default:r.currentTeam?.id});gt(o);let i=r.teams.find(c=>c.id===o);k(`Selected team: ${i?.name}`)}try{await tt()}catch{}}catch(r){n.fail("Failed to verify API key"),L(`Could not verify API key: ${r instanceof Error?r.message:String(r)}`),L(`You may need to set the team ID manually: ${p.commands[0]} config set team-id <id>`)}console.log(),k("Configuration saved!"),b(`Config file: ${Zt()}`),console.log()}catch(e){if(e.name==="ExitPromptError"){console.log(),b("Configuration cancelled.");return}throw e}})).addCommand(new qe("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async e=>{let t=ga();if(ve("Current Configuration"),console.log(),C("API Key",Ea()??nn.red("Not set")),C("API URL",t.apiUrl),C("Default Team ID",t.defaultTeamId??nn.gray("Not set")),console.log(),C("Config file",Zt()),e.verify&&t.apiKey){console.log();let n=Mn("Verifying...").start();try{let r=await Ee();n.succeed("Verified"),console.log(),C("User",r.user.email),r.currentTeam&&C("Current Team",`${r.currentTeam.name} (${r.currentTeam.planName})`),r.teams.length>1&&C("Total Teams",String(r.teams.length))}catch(r){n.fail("Verification failed"),L(r instanceof Error?r.message:String(r))}}console.log()})).addCommand(new qe("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(e,t)=>{switch(e){case"api-key":no(t)||(a("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),Yr(t),nt(),k("API key updated"),tt().catch(()=>{});break;case"api-url":try{new URL(t),Qr(t),k(`API URL set to: ${t}`)}catch{a("Invalid URL format"),process.exit(6)}break;case"team-id":gt(t),k(`Default team ID set to: ${t}`);break;default:a(`Unknown config key: ${e}`),console.log(nn.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new qe("clear").description("Clear all configuration").action(async()=>{try{await Fs({message:"Are you sure you want to clear all configuration?",default:!1})?(On(),nt(),k("Configuration cleared")):b("Cancelled")}catch{b("Cancelled")}})).addCommand(new qe("refresh").description("Refresh cached feature flags").action(async()=>{let e=Mn("Refreshing feature flags...").start();try{await tt(),e.succeed("Feature flags refreshed"),b(`Run '${p.commands[0]} --help' to see updated commands`)}catch(t){e.fail("Failed to refresh"),a(t instanceof Error?t.message:String(t)),process.exit(1)}})).addCommand(new qe("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(e=>{e.cache?console.log(Ms()):console.log(Zt())})).addCommand(new qe("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let e=Mn("Pulling settings...").start();try{let t=await Ie(),n=await fetch(`${B()}/api/cli/settings`,{headers:t});if(!n.ok)throw new Error(`Request failed (HTTP ${n.status})`);let r=await n.text(),o=fp(Bs(Zt()),"settings.toml");pp(Bs(o),{recursive:!0}),gp(o,r,"utf8"),e.succeed("Settings pulled"),b(`Written to ${o}`)}catch(t){e.fail("Failed to pull settings"),a(t instanceof Error?t.message:String(t)),process.exit(1)}}));import{Command as vp}from"commander";import{confirm as Ip}from"@inquirer/prompts";import{createHash as wp}from"crypto";function z(e){let t=wp("sha256").update(JSON.stringify({command:e.command,payload:ho(e.payload),workspaceId:e.workspaceId})).digest("hex");return`cli:${e.command.trim().toLowerCase().replace(/[^a-z0-9._:-]+/g,"-").replace(/^-+|-+$/g,"")||"command"}:${t}`}function ho(e){return Array.isArray(e)?e.map(ho):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,ho(n)]))}var Ks=new vp("delete").description("Delete a presentation").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-y, --yes","Confirm permanent deletion without prompting").option("-f, --force","Deprecated alias for --yes").option("--team-id <id>","Workspace ID (uses configured default)").option("--idempotency-key <key>","Stable key to safely retry this deletion").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("-q, --quiet","Suppress output").action(async(e,t)=>{if(await h(),!t.yes&&!t.force)try{if(!await Ip({message:`Are you sure you want to delete presentation "${e}"?`,default:!1})){t.quiet||L("Deletion cancelled");return}}catch{t.quiet||L("Deletion cancelled");return}let n=t.teamId??te(),r=t.idempotencyKey??z({command:"presentation:delete",payload:{slug:e},workspaceId:n??"configured-default"});try{await Fa(e,{approvalReceipt:t.approvalReceipt,idempotencyKey:r,teamId:n}),t.quiet||k(`Presentation "${e}" deleted`)}catch(o){o.errorCode==="approval_required"&&L(`Retry with --idempotency-key ${r}`),a(o instanceof Error?o.message:String(o)),process.exit(o.exitCode??1)}});import{Command as wt}from"commander";import Js from"chalk";import kp from"ora";import{createParser as wS}from"eventsource-parser";import IS from"chalk";import xS from"ora";async function Ws(e,t={}){let n=e.body?.getReader();if(!n)throw new Error("Response body is not readable");let r=new TextDecoder,o="",i=!1;for(;!i;){let c=await n.read();if(i=c.done,c.value){let d=r.decode(c.value,{stream:!0});o+=d,t.quiet||process.stdout.write(d)}}return t.quiet||console.log(),o}function xp(){return new wt("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)",y("--format",["human","json","markdown"]),"human").option("--instructions <text>","Custom instructions for the blog").option("--no-images","Exclude image references").option("--toc","Include table of contents").action(async(e,t)=>{await h();let n=parseInt(t.words,10);(Number.isNaN(n)||n<50||n>2e3)&&(a("Word count must be between 50 and 2000"),process.exit(6));let r=["professional","casual","educational"];r.includes(t.tone)||(a(`Invalid tone. Valid options: ${r.join(", ")}`),process.exit(6));let o=kp("Fetching presentation...").start();try{let i=await bt(e);o.text="Generating blog post...";let c=await Ya(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:n,tone:t.tone,targetAudience:t.audience??"General Audience",customInstructions:t.instructions??"",includeImages:!t.noImages,includeTableOfContents:t.toc??!1}),d=await Ws(c,{quiet:!0});o.succeed("Blog generated"),t.format==="json"?console.log(JSON.stringify({presentationId:e,title:i.title,wordCount:n,tone:t.tone,content:d},null,2)):t.format==="markdown"?console.log(d):(console.log(),console.log(Js.bold(`Blog: ${i.title}`)),console.log(Js.gray("\u2500".repeat(40))),console.log(),console.log(d),console.log())}catch(i){o.fail("Generation failed"),a(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}})}function Rp(){return new wt("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)",y("--format",["human","json"]),"human").action(async(e,t)=>{await h(),b("Tweet generation coming soon.")})}function Cp(){return new wt("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)",y("--format",["human","json"]),"human").action(async e=>{await h(),b("LinkedIn carousel generation coming soon.")})}function Sp(){return new wt("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)",y("--format",["human","json"]),"human").action(async(e,t)=>{await h(),b("Question generation coming soon.")})}function Ep(){return new wt("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)",y("--format",["human","json","markdown"]),"human").action(async(e,t)=>{await h(),b("Cheat sheet generation coming soon.")})}function zs(){let e=new wt("derive").description("Generate derivative content from a presentation"),t=Vs();return t&&(t.deckToBlog&&e.addCommand(xp()),t.deckToTweets&&e.addCommand(Rp()),t.linkedInCarousel&&e.addCommand(Cp()),t.redTeamQuestions&&e.addCommand(Sp()),t.presenterCheatSheet&&e.addCommand(Ep())),e}import{Command as Tp}from"commander";import yo from"chalk";var Hs=new Tp("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)",y("--format",["human","json"]),"human").action(async e=>{await h(),b("Idea generation is available in the web dashboard."),console.log(),console.log(yo.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(yo.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(yo.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{Command as $p}from"commander";import{readFile as Ap}from"fs/promises";import{resolve as Pp,basename as Op}from"path";import Dp from"ora";var Xs=new $p("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");Xs._hidden=!0;var Ys=Xs.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(e,t)=>{await h();try{(await Ee()).user.role!=="admin"&&(a("This command is only available to administrators"),process.exit(2))}catch{a("Failed to verify permissions"),process.exit(2)}let n=Pp(e),r=Op(n);r.endsWith(".zip")||(a("File must be a ZIP archive"),process.exit(6));let o=Dp("Reading file...").start();try{let i=await Ap(n);t.dryRun?o.text="Validating...":o.text="Importing presentation...";let c=await Ja(i,r,{dryRun:t.dryRun});if(c.success){if(t.dryRun)o.succeed("Validation passed!"),console.log(),b("The file is valid and can be imported."),c.statistics&&(console.log(),C("Slides",String(c.statistics.slidesImported)),C("Images",String(c.statistics.imagesUploaded)));else if(o.succeed("Import complete!"),console.log(),C("Presentation ID",c.presentationId??"N/A"),C("Document ID",c.documentId??"N/A"),c.statistics&&(C("Slides imported",String(c.statistics.slidesImported)),C("Images uploaded",String(c.statistics.imagesUploaded)),C("Time",`${c.statistics.totalTimeMs}ms`)),c.presentationId){let d=B();C("View URL",`${d}/p/${c.presentationId}`)}if(c.warnings&&c.warnings.length>0){console.log();for(let d of c.warnings)L(d)}console.log()}else{if(o.fail("Import failed"),console.log(),c.errors)for(let d of c.errors)a(`${d.type}: ${d.message}`);process.exit(1)}}catch(i){o.fail("Import failed"),i.code==="ENOENT"&&(a(`File not found: ${n}`),process.exit(3)),a(i instanceof Error?i.message:String(i)),process.exit(i.exitCode??1)}});import{Command as Np}from"commander";function bo(){return new Np("list").description("List presentations").option("-n, --limit <count>","Number of results to return","20").option("--offset <count>","Zero-based result offset","0").option("--sort <field>","Sort by field (updated, created, title)",y("--sort",["updated","created","title"]),"updated").option("--team-id <id>","Team ID (uses default if not specified)").option("--json","Output machine-readable JSON").action(async e=>{await h();let t=parseInt(e.limit,10);(Number.isNaN(t)||t<1||t>50)&&(a("Invalid limit value (expected 1-50)"),process.exit(6));let n=parseInt(e.offset,10);(Number.isNaN(n)||n<0||n>1e4)&&(a("Invalid offset value (expected 0-10000)"),process.exit(6));let r=e.teamId??te();r||(a("Team ID required. Set a default with 'mf config set team-id <id>' or use --team-id"),process.exit(6));try{let o=await Ma(r,t,n,e.sort);if(o.length===0){e.json?console.log(JSON.stringify([])):b("No presentations found");return}console.log(e.json?JSON.stringify(o,null,2):ka(o))}catch(o){a(o instanceof Error?o.message:String(o));let i=typeof o=="object"&&o!==null&&"exitCode"in o&&typeof o.exitCode=="number"?o.exitCode:1;process.exit(i)}})}var Qs=bo();import{createHash as Lp,randomBytes as td}from"crypto";import nd from"http";import Zs from"chalk";import{Command as Up}from"commander";import _p from"open";import ed from"ora";var qp=`${p.displayName} CLI`,jp=8765,Vp=8775,Mp=["presentations:read","presentations:write","brands:read","brands:write","media:read","media:write"];function Bp(){return td(32).toString("base64url")}function Fp(e){return Lp("sha256").update(e).digest("base64url")}function Gp(){return td(16).toString("hex")}async function Kp(e,t){for(let n=e;n<=t;n++)try{return await new Promise((r,o)=>{let i=nd.createServer();i.listen(n,()=>{i.close(()=>r())}),i.on("error",o)}),n}catch{}throw new Error(`No available port found between ${e} and ${t}`)}async function Wp(e){let t=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!t.ok)throw new Error(`Failed to fetch OAuth metadata: ${t.status}`);return t.json()}function Jp(e){let t=e.scopes_supported?.filter(n=>typeof n=="string"&&n.trim().length>0);return(t?.length?t:Mp).join(" ")}function zp(e,t){if(!t?.trim())return Jp(e);let n=t.split(",").map(o=>o.trim()).filter(Boolean);if(n.length===0)throw new Error("--scopes must include at least one OAuth scope");let r=e.scopes_supported?.filter(o=>typeof o=="string"&&o.trim().length>0);if(r?.length){let o=n.filter(i=>!r.includes(i));if(o.length>0)throw new Error(`Unsupported OAuth scope${o.length===1?"":"s"}: ${o.join(", ")}`)}return n.join(" ")}async function Hp(e,t,n){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:qp,redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:n})});if(!r.ok){let o=await r.text();throw new Error(`Client registration failed: ${o}`)}return r.json()}async function Xp(e,t,n,r,o){let i=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:r,client_id:o,code_verifier:n}),c=await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!c.ok){let d=await c.text();throw new Error(`Token exchange failed: ${d}`)}return c.json()}function Yp(e,t){return new Promise((n,r)=>{let o,i=!1,c=()=>{i||(i=!0,clearTimeout(o),process.off("SIGINT",d),process.off("SIGTERM",d),u.close())},d=()=>{c(),r(new Error("Login cancelled"))},u=nd.createServer((g,w)=>{let v=new URL(g.url||"",`http://localhost:${e}`);if(v.pathname!=="/callback"){w.writeHead(404),w.end("Not found");return}let x=v.searchParams.get("code"),T=v.searchParams.get("state"),A=v.searchParams.get("error"),S=v.searchParams.get("error_description");if(w.writeHead(200,{"Content-Type":"text/html"}),A){w.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 X from"chalk";import{Command as IS}from"commander";import fn from"chalk";import{Command as gg}from"commander";function _a(t={}){let e=(c,u)=>{let f=t[c];return f&&f.trim().length>0?f.trim():u},n=e("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),r=e("NEXT_PUBLIC_CLI_COMMAND","ccr"),o=e("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),i=e("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${o}`),d=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:o,name:i.replace(/^\./,""),displayName:n,description:`CLI tool for ${n} presentation generation`,commands:[r,o],apiUrl:e("NEXT_PUBLIC_API_URL","http://localhost:3000"),docsUrl:e("NEXT_PUBLIC_DOCS_URL",`https://docs.${n.toLowerCase()}.ai`),packageName:e("NEXT_PUBLIC_CLI_PACKAGE_NAME","@conceptcraft/cli"),configDir:i,apiKeyEnvVar:`${d}_API_KEY`,apiUrlEnvVar:`${d}_API_URL`,codexSelfConnectorAppId:t.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var g=typeof h<"u"&&h?h:_a(process.env);import{createHash as Io,randomUUID as J}from"crypto";import{readFileSync as os,statSync as is}from"fs";import{basename as xo}from"path";import{spawnSync as Nu}from"child_process";import{existsSync as Lu,mkdtempSync as Uu,rmSync as _u,writeFileSync as ju}from"fs";import{tmpdir as Vu}from"os";import{join as ja}from"path";import ho from"ffmpeg-static";var qu=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function Mu(t){let e=qu.exec(t);if(!e)return;let n=Number(e[1])*3600+Number(e[2])*60+Number(e[3]);return Number.isFinite(n)&&n>0?n:void 0}function Va(t,e="audio"){if(t.length===0)return;let n=ho&&Lu(ho)?ho:"ffmpeg",r=/^[a-z0-9]+$/i.test(e)?e:"audio",o=Uu(ja(Vu(),"mf-tts-duration-")),i=ja(o,`speech.${r}`);try{ju(i,t);let d=Nu(n,["-hide_banner","-i",i],{encoding:"utf8"});return d.error?void 0:Mu(d.stderr??"")}finally{_u(o,{force:!0,recursive:!0})}}import Yn from"chalk";import Bu from"conf";import qa from"path";var Ba=g.apiUrl,Fu={apiKey:{type:"string"},apiUrl:{type:"string",default:Ba},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}};function Gu(t=g.apiKeyEnvVar){return t.endsWith("_API_KEY")?`${t.slice(0,-8)}_CONFIG_DIR`:`${t}_CONFIG_DIR`}function Ku(t=process.env){let e=Gu(),n=t[e]?.trim()||t.CC_SLIDES_CONFIG_DIR?.trim();if(n){if(!qa.isAbsolute(n))throw new Error(`${e} must be an absolute directory path`);return qa.normalize(n)}}var Ma=Ku(),U=new Bu({projectName:g.name,schema:Fu,...Ma?{configFileMode:384,cwd:Ma}:{}});function Fa(){return{apiKey:Ue(),apiUrl:F(),defaultTeamId:U.get("defaultTeamId"),accessToken:U.get("accessToken"),refreshToken:U.get("refreshToken"),tokenExpiresAt:U.get("tokenExpiresAt"),clientId:U.get("clientId"),clientSecret:U.get("clientSecret")}}function Ue(){let t=process.env[g.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return t||U.get("apiKey")}function yo(t){U.set("apiKey",t)}function F(){let t=process.env[g.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return t||(U.get("apiUrl")??Ba)}function bo(t){U.set("apiUrl",t)}function se(){return U.get("defaultTeamId")}function kt(t){U.set("defaultTeamId",t)}function zn(){U.clear()}function pn(){return U.path}function xt(){return!!Ue()}function Ga(){return U.get("accessToken")}function Ka(){return U.get("refreshToken")}function Hn(t,e,n){U.set("accessToken",t),U.set("refreshToken",e),U.set("tokenExpiresAt",Date.now()+(n-60)*1e3)}function Xn(){U.delete("accessToken"),U.delete("refreshToken"),U.delete("tokenExpiresAt")}function Wa(){let t=U.get("tokenExpiresAt");return t?Date.now()>=t:!0}function it(){return!!U.get("accessToken")&&!!U.get("refreshToken")}function Ja(){return U.get("clientId")}function za(){return U.get("clientSecret")}function Ha(t,e){U.set("clientId",t),U.set("clientSecret",e)}var s={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function Wu(){let t=Ka(),e=Ja(),n=F();if(!t||!e)return null;try{let r=await fetch(`${n}/.well-known/oauth-authorization-server`);if(!r.ok)return null;let o=await r.json(),i=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:e}),d=za();d&&i.set("client_secret",d);let c=await fetch(o.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!c.ok)return Xn(),null;let u=await c.json();return Hn(u.access_token,u.refresh_token,u.expires_in),u.access_token}catch{return null}}async function Xa(){return it()?Wa()?Wu():Ga()||null:null}function _e(){return it()||xt()}async function b(){if(!_e()){let t=g.commands[0],e=g.apiKeyEnvVar;console.error(Yn.red("\u2717 Not authenticated.")),console.error(),console.error(Yn.bold("To authenticate, run:")),console.error(Yn.cyan(` ${t} login`)),console.error(),console.error(Yn.gray(`Or set ${e} environment variable.`)),process.exit(s.AUTH_ERROR)}}function Ju(t){return t.length<=14?"****":`${t.slice(0,10)}...${t.slice(-4)}`}function Ya(){let t=Ue();if(t)return Ju(t)}function wo(t){return["cc_slides_","mcp_","cc_sk_","sk_"].some(n=>t.startsWith(n))}import{mkdirSync as zu,readFileSync as Hu,writeFileSync as Xu}from"fs";import{homedir as Yu}from"os";import{join as Qa}from"path";import Qu from"ajv/dist/2020.js";var vo=new Map;function Za(){return Qa(Yu(),".conceptcraft","schemas")}function es(t){return Qa(Za(),`${t}.json`)}function Zu(t){try{let e=JSON.parse(Hu(es(t),"utf8"));return typeof e?.catalogVersion=="number"&&e.schema?e:null}catch{return null}}function eg(t,e){try{zu(Za(),{recursive:!0}),Xu(es(t),JSON.stringify(e))}catch{}}async function tg(t){let e=vo.get(t);if(e!==void 0)return e;try{let n=await ts(t),r={catalogVersion:n.catalogVersion,schema:n.operationSchema??n.schema};return eg(t,r),vo.set(t,r),r}catch{let n=Zu(t);return vo.set(t,n),n}}function ng(t){let e=t.instancePath.replace(/^\//,"").replace(/\//g,"."),n=e.length>0?e:"(root)",r=t.keyword==="additionalProperties"?`: unknown field "${t.params.additionalProperty}"`:`: ${t.message??"invalid value"}`;return`${n}${r}`}async function Qn(t,e){let n=await tg(t);if(!n)return;let r;try{r=new Qu({allErrors:!0,strict:!1}).compile(n.schema)}catch{return}if(r(e))return;let o=(r.errors??[]).slice(0,10).map(ng);throw new Error(`Request does not match the ${t} contract \u2014 ${o.join("; ")}`)}function rg(t){if(!t||typeof t!="object")return null;let e=t.errorCode,n=t.message;return e!=="approval_required"?null:typeof n=="string"&&n.trim()?n:null}function te(t,e){let n=e?null:rg(t);if(n)return n;let r="The run failed. Check its status for recovery details.";return!e||r.includes(e)?r:`${r} Request ID: ${e}. Resume with the matching status command; do not start a duplicate run.`}function re(t,e={}){let n=t?.code?.trim()||e.defaultCode?.trim()||"",r=t?.message?.trim()||"The run failed without a reported reason.";return n?`[${n}] ${r}`:r}function un(t){let e=t.status?.trim().toLowerCase()??"";return!!t.error||e==="failed"||e==="errored"||e==="cancelled"?`${t.runId?.trim()?`Run ${t.runId.trim()}`:"Run"} ${e||"failed"}: ${re(t.error)}`:null}function ns(t){let e=t.projectId??"<project-id>";return/Narration is still missing for \d+ slides?\./.test(t.message)?["Narration is captured from speaker notes when the video project is prepared, so 'presentation video refresh' will not backfill it.",`Fill each empty scene with: ${t.binary} presentation video-narration ${e} --slide-id <slide-id> (scene ids: ${t.binary} presentation video inspect ${e})`].join(`
|
|
4
|
+
`):/Every scene is excluded from the video\./.test(t.message)?`Include a scene again with: ${t.binary} presentation video edit ${e} --edit '{"type":"patch_scene","scene":1,"excluded":false}'`:null}async function ge(){let t=await Xa();if(t)return{Authorization:`Bearer ${t}`};let e=Ue();return e?{"x-api-key":e}:{}}var C=class extends Error{constructor(n,r,o=1,i="operation_failed",d=!1){super(n);this.statusCode=r;this.exitCode=o;this.errorCode=i;this.retryable=d;this.name="ApiError"}statusCode;exitCode;errorCode;retryable},as="Idempotency-Key";function og(t){return t&&t!=="GET"?{[as]:J()}:{}}async function Pe(t,e={}){let n=F();if(!_e()&&!e.allowUnauthenticated)throw new C(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let r=await ge(),o=`${n}${t}`,i={...r,...og(e.method),...e.headers};e.body&&!e.stream&&(i["Content-Type"]="application/json");let d={method:e.method??"GET",headers:i};e.body&&(d.body=JSON.stringify(e.body));let c;try{c=await fetch(o,d)}catch{throw new C("Network error while contacting Mindframes. Please try again.",0,5,"service_unavailable",!0)}if(!c.ok){let f=await c.text().catch(()=>""),v=Ge(f,c.status),I=1;switch(c.status){case 401:I=2;break;case 403:I=2;break;case 404:I=3;break;case 429:I=4;break;case 500:I=1;break}let S=`[${v.code}] ${v.message}`;throw new C(S,c.status,I,v.code,v.retryable)}return e.stream?c:c.headers.get("content-type")?.includes("application/json")?c.json():c.text()}function ig(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 Ro(t){return t===401||t===403?2:t===404?3:t===429?4:1}function Ge(t,e){let n=ig(e),r=`HTTP ${e}: The request could not be completed.`;try{let o=JSON.parse(t),i=typeof o.error=="object"&&o.error!==null?o.error:void 0;if(o.ok===!1&&typeof i?.code=="string"&&typeof i.message=="string")return{code:i.code,message:i.message,retryable:i.retryable===!0}}catch{}return{code:n,message:r,retryable:e===429||e>=500}}async function ts(t){return Pe(`/api/cli/tools/${encodeURIComponent(t)}/schema`)}async function ss(){return Pe("/api/cli/capabilities",{allowUnauthenticated:!0})}async function x(t,e,n){let r=await Co(n),o=`?teamId=${encodeURIComponent(r)}`;return Pe(`/api/cli/tool-runs/${encodeURIComponent(t)}/${encodeURIComponent(e)}${o}`)}async function p(t,e,n){let r=await Co(e.teamId);return Pe(`/api/cli/tools/${encodeURIComponent(t)}`,{body:{...e,teamId:r},headers:n?{[as]:n}:void 0,method:"POST"})}function B(t){return Co(t)}async function Co(t){let e=typeof t=="string"&&t.trim()?t.trim():se()?.trim();if(e)return e;let n=await Oe();if(n.currentTeam?.id)return n.currentTeam.id;throw new C("Team ID required. Select a workspace with `mf config set team-id <id>` or pass --team-id.",400,void 0,"invalid_input")}async function ds(t){return Pe("/api/llm-connections/profiles",{body:t,method:"POST"})}async function Y(t,e,n,r=120){let o=0;for(let i=0;r===null||i<r;i++){let d;try{d=await x(t,e,n),o=0}catch(c){if(c instanceof C&&c.retryable&&o<2){o+=1,await new Promise(u=>setTimeout(u,2e3));continue}throw c instanceof C?new C(`${c.message} Request ID: ${e}.`,c.statusCode,c.exitCode,c.errorCode,c.retryable):new C(`The background operation could not be checked. Request ID: ${e}.`,0,5,"poll_failed",!0)}if(d.done){if(d.error)throw new C(`${re(d.error,{defaultCode:"operation_failed"})} Request ID: ${e}.`,500,1,d.error.code??"operation_failed",d.error.retryable);return d}await new Promise(c=>setTimeout(c,(d.nextPollAfterSeconds??2)*1e3))}throw new C(`[operation_timed_out] The background operation timed out. Request ID: ${e}.`,408,1,"operation_timed_out",!0)}function Zn(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 ag(t){try{let n=new URL(t).pathname.split("/").pop()?.split(".").pop()?.toLowerCase();return n&&/^[a-z0-9]+$/.test(n)?n:void 0}catch{return}}function Rt(t){let e=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",mp4:"video/mp4",mov:"video/quicktime",mpeg:"video/mpeg",mpg:"video/mpeg",webm:"video/webm",aac:"audio/aac",m4a:"audio/mp4",mp3:"audio/mpeg",oga:"audio/ogg",ogg:"audio/ogg",wav:"audio/wav",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"}[e||""]||"application/octet-stream"}function at(t){let e=is(t);return{fileName:xo(t),fileSize:e.size,fileType:Rt(t)}}async function st(t,e){let n=at(t),r=os(t),o=new FormData;for(let[d,c]of Object.entries(e.fields))o.append(d,c);o.append("file",new Blob([r],{type:n.fileType}),n.fileName);let i=await fetch(e.uploadUrl,{method:"POST",body:o});if(!i.ok)throw new C("Failed to upload file to storage",i.status,1);return{id:e.fileId??J(),name:n.fileName,s3Key:e.s3Key,url:e.fileUrl,size:n.fileSize,type:n.fileType,selected:!0}}async function ee(t,e={}){let n=F();if(!_e())throw new C(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let r=await ge(),o=is(t),i=xo(t),d=Rt(t),c=os(t),u=Io("sha256").update(c).digest("hex"),f=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({fileMetadata:{lastModified:o.mtimeMs,name:i,type:d,size:o.size},...e.storagePrefix?{storagePrefix:e.storagePrefix}:{},...e.idempotencyKey?{uploadIdentity:{contentSha256:u,idempotencyKey:e.idempotencyKey}}:{}})});if(!f.ok){let I=await f.text(),S=Ge(I,f.status);throw new C(`[${S.code}] ${S.message}`,f.status,Ro(f.status),S.code,S.retryable)}let v=await f.json();return st(t,{...e.idempotencyKey?{fileId:`file-${Io("sha256").update(JSON.stringify({contentSha256:u,fileName:i,idempotencyKey:e.idempotencyKey})).digest("hex")}`}:{},fields:v.fields||{},fileUrl:v.fileUrl,s3Key:v.uploadKey,uploadUrl:v.url})}async function cs(t,e,n={}){let r=[];for(let o=0;o<t.length;o++){let i=t[o],d=xo(i);e?.(o,t.length,d);let c=await ee(i,{idempotencyKey:n.idempotencyKey});r.push(c)}return e?.(t.length,t.length,""),r}async function ls(t,e,n){let r={};for(let[o,i]of Object.entries(t))i!==void 0&&(r[o]=i);return r.brandingId===void 0&&typeof r.brandId=="string"&&(r.brandingId=r.brandId),delete r.brandId,p("createSlides",{...r,...n?{approvalReceipt:n}:{}},e)}async function ms(t,e=20,n=0,r="updated"){return(await p("listPresentations",{limit:e,offset:n,sort:r,teamId:t})).presentations}async function Ct(t,e){let n=e?.includeSlides!==!1,r=await p("getPresentation",{includeSlides:n,presentationId:t,teamId:e?.teamId});return n?{...r.presentation,slides:r.slides}:r.presentation}async function ps(t,e,n,r){return p("generateSpeakerNotes",{...e,presentationId:t,teamId:r},n)}async function us(t,e,n,r){return p("setSpeakerNotes",{notes:e,presentationId:t,teamId:r},n)}async function er(t){let e=F(),n=await fetch(`${e}/api/durable-runs/${encodeURIComponent(t)}/events`,{headers:await ge()});if(!n.ok){let r=Ge(await n.text().catch(()=>""),n.status);throw new C(`[${r.code}] ${r.message}`,n.status,Ro(n.status),r.code,r.retryable)}return n}async function gs(t,e={}){await p("deletePresentation",{approvalReceipt:e.approvalReceipt,presentationId:t,teamId:e.teamId},e.idempotencyKey??`cli:presentation:delete:${Io("sha256").update(JSON.stringify({slugOrId:t,teamId:e.teamId??null})).digest("hex")}`)}async function fs(t,e){return p("updatePresentationVisibility",{presentationId:t,teamId:e.teamId,visibility:e.visibility},e.idempotencyKey??`cli:presentation:visibility:${J()}`)}async function hs(t,e,n){return p("exportPresentation",{format:e,presentationId:t,teamId:n?.teamId})}async function ys(t){let e;try{e=await fetch(t)}catch{throw new C("Network error while downloading the export. Please try again.",0,5,"service_unavailable",!0)}if(!e.ok)throw new C(`[fetch_failed] The export download link returned ${e.status}. Signed links expire after one hour \u2014 re-run the export.`,e.status,1,"fetch_failed",!0);return e.arrayBuffer()}async function bs(t,e,n={}){let r=F();if(!_e())throw new C(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let o=await ge(),i=new FormData,d=new Blob([new Uint8Array(t)],{type:"application/zip"});i.append("file",d,e),i.append("options",JSON.stringify({dryRun:n.dryRun??!1,remapIds:!0}));let c=await fetch(`${r}/api/presentations/import`,{method:"POST",headers:o,body:i}),u=await c.json();if(!c.ok)throw new C("Import failed. The server rejected the presentation.",c.status,1);return u}async function ws(t,e=25){return p("listSlideTemplates",{limit:e,search:t})}async function vs(t,e,n,r,o){return p("extractBranding",{approvalReceipt:n,skipExistingBrandingLookup:r,teamId:e,url:t},o)}async function Oe(){return Pe("/api/cli/whoami")}async function Is(){return Pe("/api/cli/features")}async function ks(t,e,n={}){let r=F();if(!_e())throw new C(`Not authenticated. Run '${g.commands[0]} login' or set ${g.apiKeyEnvVar} environment variable.`,401,2);let o=await ge(),i=await fetch(`${r}/api/presentations/${t}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify({documentCreatedAt:e,targetWordCount:n.targetWordCount??300,tone:n.tone??"professional",language:n.language??"en",targetAudience:n.targetAudience??"General Audience",blogFormat:n.blogFormat??"narrative",customInstructions:n.customInstructions??"",includeImages:n.includeImages??!0,includeTableOfContents:n.includeTableOfContents??!1})});if(!i.ok){let d=Ge(await i.text().catch(()=>""),i.status);throw new C(`[${d.code}] ${d.message}`,i.status,Ro(i.status),d.code,d.retryable)}return i}async function So(t){return p("getGenerationLimits",{teamId:t})}async function xs(t,e,n){let r=await So(n);if(!r.canGenerate[t]){let o=r.remaining[t]??0,i=r.limits[t]??0;throw i===0?new C(`The "${t}" mode is not available on your ${r.planName} plan. Available modes: ${r.availableModes.join(", ")||"none"}`,403,2):new C(`You have reached your ${t} generation limit for this billing cycle (${r.usage[t]??0}/${i} used). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,4)}if(r.maxSlidesPerPresentation!==-1&&e>r.maxSlidesPerPresentation)throw new C(`Maximum ${r.maxSlidesPerPresentation} slides allowed on your ${r.planName} plan (requested: ${e}). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,6);return r}function sg(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 Rs(t,e){let n={...t,text:sg(t.text)};await Qn("generateSpeech",n);let r=await p("generateSpeech",{approvalReceipt:e?.approvalReceipt,...n},e?.idempotencyKey),o=await Y("generateSpeech",r.runId),i=o.entity?.url;if(!i)throw new C(`Speech completed without an audio URL. Request ID: ${r.runId}.`,500);let d;try{d=await fetch(i)}catch{throw new C(`Failed to download speech audio. Request ID: ${r.runId}.`,0,5,"download_failed",!0)}if(!d.ok)throw new C(`Failed to download speech audio. Request ID: ${r.runId}.`,d.status,5,"download_failed",d.status===429||d.status>=500);let c=o.output??{},u=t.options??{},f=$e(c.format)??ag(i)??"mp3",v=Buffer.from(await d.arrayBuffer()),I=Cs(c.durationSec,c.duration,c.duration_s)??Va(v,f);if(I===void 0)throw new C(`Speech completed without a measurable duration. Request ID: ${r.runId}.`,500,1,"invalid_audio_metadata");return{audioData:v,audioUrl:i,duration:I,provider:$e(c.provider)??u.provider??"gemini",format:f,requestId:r.runId,voiceId:$e(c.voice_id)??$e(c.voiceId),voice:$e(c.voice),model:$e(c.model),speed:ko(c.speed)??u.speed,language:$e(c.lang)??$e(c.language)??u.language,langApplied:rs(c.langApplied)??rs(c.lang_applied),timestamps:dg(c.timestamps),wordTimings:cg(c.timestamps??c.timings)}}function Cs(...t){for(let e of t){let n=typeof e=="number"?e:typeof e=="string"&&e.trim()?Number(e):Number.NaN;if(Number.isFinite(n)&&n>0)return n}}function dg(t){if(!t||typeof t!="object"||Array.isArray(t))return;let e=t,n=e.characters,r=e.characterStartTimesSeconds??e.character_start_times_seconds,o=e.characterEndTimesSeconds??e.character_end_times_seconds;if(!(!Array.isArray(n)||!Array.isArray(r)||!Array.isArray(o))&&!(n.length===0||n.length!==r.length||n.length!==o.length||!n.every(i=>typeof i=="string")||!r.every(i=>typeof i=="number"&&Number.isFinite(i))||!o.every(i=>typeof i=="number"&&Number.isFinite(i))))return{characters:n,characterStartTimesSeconds:r,characterEndTimesSeconds:o}}function cg(t){if(!Array.isArray(t))return;let e=t.flatMap(n=>{if(!n||typeof n!="object"||Array.isArray(n))return[];let r=n,o=$e(r.text)??$e(r.word),i=ko(r.start),d=ko(r.end);return o&&i!==void 0&&d!==void 0&&d>=i?[{text:o,start:i,end:d}]:[]});return e.length>0?e:void 0}function $e(t){return typeof t=="string"&&t.trim()?t.trim():void 0}function ko(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function rs(t){return typeof t=="boolean"?t:void 0}async function Ss(t){let e=t?`/api/cli/tts?provider=${t}`:"/api/cli/tts";return Pe(e)}async function Es(t,e){let n={...t},r=e?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);return delete n.idempotency_key,await Qn("generateMusic",n),{requestId:(await p("generateMusic",{...n,approvalReceipt:e?.approvalReceipt},r)).runId,status:"pending"}}async function Eo(t){let e=await x("generateMusic",t);return{requestId:t,status:Zn(e),audioUrl:e.entity?.url,duration:Cs(e.output?.durationSec,e.output?.duration,e.output?.duration_s),error:e.error?.message}}async function Ts(t,e){return{requestId:(await p("mixAudio",{...t,approvalReceipt:e?.approvalReceipt},e?.idempotencyKey)).runId,status:"pending"}}async function To(t){let e=await x("mixAudio",t);return{requestId:t,status:Zn(e),outputUrl:e.entity?.url,error:e.error?.message}}async function As(t){return Pe("/api/cli/images/search",{method:"POST",body:t})}async function $s(t){return Pe("/api/cli/videos/search",{method:"POST",body:t})}async function be(t,e=60,n=2e3){let r=0;for(let o=0;o<e;o++){let i;try{i=await t(),r=0}catch(d){if(d instanceof C&&d.retryable&&r<2){r+=1,await new Promise(c=>setTimeout(c,n));continue}throw d}if(i.status==="completed"||i.status==="failed")return i;await new Promise(d=>setTimeout(d,n))}throw new C("Operation timed out",408,1)}async function Ps(t,e){let n={...t},r=e?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);delete n.idempotency_key,await Qn("generateSfx",n);let o=await p("generateSfx",{...n,approvalReceipt:e?.approvalReceipt},r);return{id:o.runId,requestId:o.runId,status:"pending"}}async function Ao(t){let e=await x("generateSfx",t);return{id:e.entity?.id??t,requestId:t,status:Zn(e),audioUrl:e.entity?.url,error:e.error?.message}}async function Os(t,e){return p("listPresenterOptions",{...t?{voiceLanguage:t}:{},...e?{teamId:e}:{}})}async function Ds(t,e){return{requestId:(await p("generateAvatarVideo",t,e)).runId,status:"pending"}}async function $o(t){let e=await x("generateAvatarVideo",t);return{durationSec:typeof e.output?.durationSec=="number"?e.output.durationSec:null,error:e.error?.message,requestId:t,status:Zn(e),videoUrl:e.entity?.url}}async function Ns(t,e,n){return p("lipsyncVideo",{...t,approvalReceipt:n},e??J())}async function Ls(t,e,n){return p("clipVideo",{...t,approvalReceipt:n},e??J())}async function Us(){return(await p("listTranslationLanguages",{})).languages}async function _s(t,e,n){return p("translateVideo",{...t,approvalReceipt:n},e??J())}async function js(t,e,n){return p("createVideo",{...t,approvalReceipt:e},n)}async function Vs(t){let{idempotencyKey:e,...n}=t;return p("analyzeVideoReference",n,e)}async function qs(t,e){return Y("analyzeVideoReference",t,e)}async function Ms(t,e){return Y("selectPresentationVideoStockMusic",t,e)}async function Bs(t,e){return Y("preparePresentationVideoPreviews",t,e,null)}async function Fs(t,e){return Y("generateBrandVariations",t,e)}async function Gs(t,e){return Y("extractBrandProducts",t,e)}async function Ks(t,e){return Y("buildBrandVoice",t,e)}async function Ws(t,e){return Y("generateBrandGuardrails",t,e)}async function Js(t,e){return Y("repairBrandQuality",t,e)}async function zs(t,e){return Y("syncBrandToPresentations",t,e)}async function Hs(t,e){return Y("syncBrandFoundation",t,e)}async function Xs(t){return p("listVoices",t)}async function Ys(t){return p("adoptLibraryVoice",t,J())}async function Qs(t){return p("setVoiceFavorite",t,J())}async function Zs(t){return p("setVoicePolicy",t,J())}async function ed(t){return p("requestVoiceApproval",t,J())}async function td(t){return p("listVoiceApprovalRequests",t,J())}async function nd(t){return p("decideVoiceApprovalRequest",t,J())}async function rd(t){return p("setVoiceTone",t,J())}async function od(t){return p("setVoiceVisibility",t,J())}async function id(t){return p("setVoiceApproval",t,J())}async function ad(t){return p("listVoiceApprovals",t,J())}async function sd(t){return p("designVoice",t,J())}async function dd(t){return p("saveDesignedVoice",t,J())}async function cd(t){return p("retireVoice",t,J())}async function ld(t){return p("listCastPresets",t)}async function md(t){return p("createCastPreset",t,J())}async function pd(t){return p("updateCastPreset",t,J())}async function ud(t,e){return p("deleteCastPreset",{presetId:t,...e?{teamId:e}:{}},J())}var lg="The command failed. Please try again.";function m(t,e=lg){return t instanceof C&&t.message.trim()?t.message:e}import{InvalidArgumentError as mg}from"commander";function y(t,e){return n=>{if(e.includes(n))return n;throw new mg(`Expected one of: ${e.join(", ")}. Run the command with --help to see what ${t} accepts.`)}}import j from"chalk";import Po from"cli-table3";function k(t,e="human"){e!=="quiet"&&e!=="json"&&console.log(j.green("\u2713"),t)}function a(t,e="human"){if(e!=="quiet"){if(e==="json"){console.error(JSON.stringify({error:t}));return}console.error(j.red("\u2717"),t)}}function L(t,e="human"){e!=="quiet"&&e!=="json"&&console.warn(j.yellow("\u26A0"),t)}function gd(t,e="human"){e==="quiet"||e==="json"||console.error(j.cyan("\u2192"),t)}function w(t,e="human"){e!=="quiet"&&e!=="json"&&console.log(j.blue("\u2139"),t)}function St(t,e="en"){return t?`${F()}/${e}/view/presentations/${t}`:"N/A"}function fd(t,e={}){let{showLinks:n=!1,language:r="en"}=e,o=(c,u)=>c.length>u?`${c.slice(0,u-1)}\u2026`:c,i=c=>{if(!c)return"-";try{return new Date(c).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(n){let c=new Po({head:[j.cyan("Slug"),j.cyan("Title"),j.cyan("Slides"),j.cyan("Created"),j.cyan("URL")]});for(let u of t)c.push([o(u.slug||u.id.slice(0,8),30),o(u.title||"Untitled",22),String(u.numberOfSlides||"-"),i(u.createdAt),St(u.slug,r)]);return c.toString()}let d=new Po({head:[j.cyan("Slug"),j.cyan("Title"),j.cyan("Slides"),j.cyan("Mode"),j.cyan("Created")],colWidths:[32,28,8,11,18]});for(let c of t)d.push([c.slug||c.id.slice(0,8),c.title||"Untitled",String(c.numberOfSlides||"-"),c.mode||"-",i(c.createdAt)]);return d.toString()}function hd(t){let e=[...t].sort((o,i)=>{if(o.isDefault&&!i.isDefault)return-1;if(!o.isDefault&&i.isDefault)return 1;let d=o.createdAt?new Date(o.createdAt).getTime():0;return(i.createdAt?new Date(i.createdAt).getTime():0)-d}),n=o=>{if(!o)return"-";try{return new URL(o).href}catch{return o.startsWith("http")?o:`https://${o}`}},r=new Po({head:[j.cyan("Name"),j.cyan("Source"),j.cyan("Color"),j.cyan("Logo"),j.cyan("Default"),j.cyan("ID")]});for(let o of e){let i=o.primaryColor?`${j.bgHex(o.primaryColor)(" ")} ${o.primaryColor}`:"-";r.push([o.name,n(o.sourceUrl),i,o.logoUrl?j.green("\u2713"):j.gray("\u2717"),o.isDefault?j.green("\u2605"):"",o.id])}return r.toString()}function Oo(t){try{return new Date(t).toLocaleString()}catch{return t}}function Se(t){console.log(),console.log(j.bold(t)),console.log(j.gray("\u2500".repeat(t.length)))}function E(t,e){console.log(` ${j.gray(`${t}:`)} ${e??"-"}`)}function pg(t){return JSON.stringify(t,null,2)}function l(t){console.log(pg(t))}var yd=[{billing:"free",category:"branding",description:"Attach a social handle to an accessible brand profile.",id:"addBrandSocialHandle",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social add",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Add a competitor to an accessible brand profile.",id:"addCompetitor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding competitor add",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"File an uploaded file on this workspace's Library shelf. A ZIP expands all members by default; exact archiveMemberPaths select members and preserve the original ZIP.",id:"addLibraryFile",lifecycle:{mode:"bounded"},milestone:"M8",name:"file save",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Add a voice from the shared library to this workspace, so it can be used like one of your own.",id:"adoptLibraryVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice add",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"media",description:"Transcribe an uploaded recording and publish the transcript for generation.",id:"analyzeMediaAsset",lifecycle:{mode:"background",status:{cliCommand:"media analyze status",pollAfterSeconds:10}},milestone:"M8",name:"media analyze",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Analyze an uploaded video before using it as a source, motion, blocking, or pacing reference in a video storyboard. The completed status output includes the analysisId required by the storyboard's source-video binding.",id:"analyzeVideoReference",lifecycle:{mode:"background",status:{cliCommand:"video reference status",pollAfterSeconds:10}},milestone:"M8",name:"video reference analyze",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Version a presentation with changes from its already-linked brand.",id:"applyPresentationBrandChanges",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation apply-changes",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Copy the deck's speaker notes into scene narration verbatim for the given scenes.",id:"applyPresentationVideoSpeakerNotes",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video apply-notes",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Approve a private or team brand for use.",id:"approveBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding approve",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Branch an immutable footage version into a new project.",id:"branchFootageProjectVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage branch",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Draft a brand's Voice and Context document from source material.",id:"buildBrandVoice",lifecycle:{mode:"background",status:{cliCommand:"branding voice build-status",pollAfterSeconds:3}},milestone:"M2",name:"branding voice build",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Cancel an active linked-presentation brand sync.",id:"cancelBrandPresentationSync",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding sync-cancel",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Request cancellation of an in-flight presentation MP4 render.",id:"cancelPresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video cancel",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Turn a ready video into short clips with virality scores (one clip-set artifact).",id:"clipVideo",lifecycle:{mode:"background",status:{cliCommand:"video clips status",pollAfterSeconds:20}},milestone:"M8",name:"video clips",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Mark a brand's onboarding review complete.",id:"completeBrandOnboarding",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding onboarding complete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"delegated",category:"artifacts",description:"Generate and persist an ad variation set.",id:"createAdSet",lifecycle:{mode:"background",status:{cliCommand:"ad-set status",pollAfterSeconds:10}},milestone:"M6",name:"ad-set create",operation:"generation",scopes:["ad-sets:write"],state:"available"},{billing:"free",category:"agents",description:"Activate an exact reviewed scheduled-agent draft.",id:"createAgent",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent create",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"quota",category:"branding",description:"Create an empty brand in the workspace.",id:"createBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding create",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Mint a brand- and actor-scoped storage upload target for one private or team brand.",id:"createBrandAssetUploadUrl",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset upload-url",operation:"query",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Save one way a cast member appears: a personal presenter (pp_* id), a backdrop, and optionally a voice, under a name unique to that person.",id:"createCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Save a markdown, CSV or plain-text document into the Library.",id:"createDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Create a transcript-native, versioned footage edit project.",id:"createFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"media",description:"Generate and persist an image.",id:"createImage",lifecycle:{mode:"background",status:{cliCommand:"image status",pollAfterSeconds:10}},milestone:"M5",name:"image generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Mint an upload target for a file this caller will file in the Library.",id:"createLibraryFileUploadUrl",lifecycle:{mode:"bounded"},milestone:"M8",name:"file upload-url",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Create a Library folder, optionally inside another folder.",id:"createLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"dynamic",category:"artifacts",description:"Generate and persist a microsite.",id:"createMicrosite",lifecycle:{mode:"background",status:{cliCommand:"microsite status",pollAfterSeconds:10}},milestone:"M6",name:"microsite create",operation:"generation",scopes:["microsites:write"],state:"available"},{billing:"free",category:"artifacts",description:"Create a standalone poll.",id:"createPoll",lifecycle:{mode:"bounded"},milestone:"M3",name:"poll create",operation:"mutation",scopes:["polls:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Create an MP4 video from a finished presentation, or render an existing presentation-video project.",id:"createPresentationVideo",lifecycle:{mode:"background",status:{cliCommand:"presentation video status",pollAfterSeconds:10}},milestone:"M4",name:"presentation video",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a deterministic, owned-project-scoped upload target for custom presentation-video music.",id:"createPresentationVideoMusicUploadUrl",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video music upload-url",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Create a reusable personal presenter from approved footage, a headshot, or a synthetic-persona prompt.",id:"createPresenter",lifecycle:{mode:"background",status:{cliCommand:"avatar presenter status",pollAfterSeconds:10}},milestone:"M8",name:"avatar presenter create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"presentations",description:"Generate a presentation and persist the resulting deck.",id:"createSlides",lifecycle:{mode:"background",status:{cliCommand:"presentation status",pollAfterSeconds:20}},milestone:"M4",name:"create",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"artifacts",description:"Mint a presigned S3 upload for a file, with the final proxied file URL.",id:"createUploadUrl",lifecycle:{mode:"bounded"},milestone:"M1",name:"artifact upload-url",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate one video from the opaque text and explicit metadata stored in a pinned storyboard revision.",id:"createVideo",lifecycle:{mode:"background",status:{cliCommand:"video status",pollAfterSeconds:20}},milestone:"M8",name:"video create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Create a versioned Markdown video storyboard.",id:"createVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard create",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"fixed",category:"artifacts",description:"Generate a persisted standalone visual abstract.",id:"createVisualAbstract",lifecycle:{mode:"background",status:{cliCommand:"visual-abstract status",pollAfterSeconds:10}},milestone:"M5",name:"visual-abstract create",operation:"generation",scopes:["visual-abstracts:write"],state:"available"},{billing:"delegated",category:"media",description:"Create a narrated walkthrough draft from a hosted screen recording: the narration run analyzes the source, writes narration moments, and leaves a draft ready to edit or render.",id:"createWalkthrough",lifecycle:{mode:"background",status:{cliCommand:"walkthrough status",pollAfterSeconds:10}},milestone:"M8",name:"walkthrough create",operation:"generation",scopes:["walkthroughs:write"],state:"available"},{billing:"free",category:"media",description:"Mint a short-lived presigned POST for a walkthrough source recording (up to 1 GiB). Upload the exact bytes to uploadUrl, then pass fileUrl as sourceVideoUrl to create_walkthrough.",id:"createWalkthroughUploadUrl",lifecycle:{mode:"bounded"},milestone:"M8",name:"walkthrough upload-url",operation:"mutation",scopes:["walkthroughs:write"],state:"available"},{billing:"free",category:"media",description:"Approve, decline or withdraw a request to admit a voice.",id:"decideVoiceApprovalRequest",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice decide",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Remove a brand from the library.",id:"deleteBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one asset record from a private or team brand's visible library.",id:"deleteBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one competitor from an accessible brand.",id:"deleteBrandCompetitor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding competitor delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one custom Foundation colour role.",id:"deleteBrandCustomColor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding foundation color delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one of a brand's guardrail rules.",id:"deleteBrandGuardrail",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one product from a brand.",id:"deleteBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one word from a brand pronunciation dictionary while retaining its version history. Free reversible brand configuration.",id:"deleteBrandPronunciation",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding pronunciation delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one social account from an accessible brand.",id:"deleteBrandSocialHandle",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one per-channel brand design variant.",id:"deleteBrandVariant",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant delete",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Retire a saved cast preset. Existing videos keep working; the preset stops being offered.",id:"deleteCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset delete",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Remove a document from the Library.",id:"deleteDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document delete",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Delete a Library folder and its descendants while returning their items to Unfiled.",id:"deleteLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders delete",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"presentations",description:"Permanently delete an owned presentation, all of its versions, and its publications.",id:"deletePresentation",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation delete",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"fixed",category:"media",description:"Generate candidate voices from a written description, or vary one you already heard.",id:"designVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice design",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Compare two points in a brand's version history.",id:"diffBrandVersions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version diff",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Create a replay-safe draft copy of one brand product with its assets and provenance.",id:"duplicateBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product duplicate",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"artifacts",description:"Edit a standalone poll.",id:"editPoll",lifecycle:{mode:"bounded"},milestone:"M3",name:"poll edit",operation:"mutation",scopes:["polls:write"],state:"available"},{billing:"free",category:"presentations",description:"Apply one atomic edit to a presentation-video draft. Provide basedOnVersionNumber, branchId and expectedHeadVersionNumber together to edit an immutable saved version; selecting or saving an unchanged snapshot creates no version. save_draft submits a full composition/settings proposal; unlisted narration stays on the selected branch baseline. add_scene_layer accepts owned media or a stockVideoToken issued by searchStockVideo, without importing stock footage into Library. add_scene inserts an empty title scene after the reference; duplicate_scene inserts an independent copy of its visual, narration, voice, presenter and scene settings; replace_video_scene swaps the addressed scene for an owned reusable video while preserving its timeline identity. patch_scene with excluded toggles inclusion without deleting the scene.",id:"editPresentationVideoDraft",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video edit",operation:"mutation",scopes:["presentations:write","media:read"],state:"available"},{billing:"dynamic",category:"presentations",description:"Generate narration for the planned or explicitly selected presentation-video slides.",id:"ensurePresentationVideoNarration",lifecycle:{mode:"background",status:{cliCommand:"presentation video narrate status",pollAfterSeconds:5}},milestone:"M4",name:"presentation video narrate",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Render a presentation you can edit to HTML/PDF/PPTX and return a short-lived signed download URL.",id:"exportPresentation",lifecycle:{mode:"bounded"},milestone:"M1",name:"export",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"quota",category:"branding",description:"Extract and persist a reusable brand profile from a URL.",id:"extractBranding",lifecycle:{mode:"background",status:{cliCommand:"branding status",pollAfterSeconds:10}},milestone:"M2",name:"branding extract",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Discover a brand's products by crawling its site.",id:"extractBrandProducts",lifecycle:{mode:"background",status:{cliCommand:"branding product extract-status",pollAfterSeconds:3}},milestone:"M2",name:"branding product extract",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"dynamic",category:"research",description:"Extract bounded text and metadata from a source.",id:"extractContent",lifecycle:{mode:"bounded"},milestone:"M1",name:"content extract",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"knowledge",description:"File an artifact into a Library folder, or return it to Unfiled.",id:"fileArtifactIntoFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library file",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Permanently erase every stored version of a scheduled Agent memory.",id:"forgetAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory forget",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate one reusable avatar/presenter clip for composition into a video. Accepts a stock avatar id or a personal presenter's pp_* id as avatarId.",id:"generateAvatarVideo",lifecycle:{mode:"background",status:{cliCommand:"avatar status",pollAfterSeconds:10}},milestone:"M8",name:"avatar generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Draft guardrail rule proposals for a brand.",id:"generateBrandGuardrails",lifecycle:{mode:"background",status:{cliCommand:"branding guardrails generate-status",pollAfterSeconds:3}},milestone:"M2",name:"branding guardrails generate",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Generate a brand's per-channel design variants and gradients.",id:"generateBrandVariations",lifecycle:{mode:"background",status:{cliCommand:"branding variations status",pollAfterSeconds:3}},milestone:"M2",name:"branding variations generate",operation:"generation",scopes:["brands:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate music from a direct brief or final video facts as an approved, recoverable run.",id:"generateMusic",lifecycle:{mode:"background",status:{cliCommand:"music status",pollAfterSeconds:10}},milestone:"M7",name:"music generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Generate a right-way or wrong-way scene clip from a picture and attach it as a layer to one or more scenes of a presentation video.",id:"generatePresentationVideoSceneClip",lifecycle:{mode:"background",status:{cliCommand:"presentation video scene-clip status",pollAfterSeconds:10}},milestone:"M8",name:"presentation video scene-clip generate",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Generate an additional look for an existing personal presenter while preserving the same Cast identity.",id:"generatePresenterLook",lifecycle:{mode:"background",status:{cliCommand:"avatar look status",pollAfterSeconds:10}},milestone:"M8",name:"avatar look generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate one sound-effect cue from a direct brief or final video facts as an approved, recoverable run.",id:"generateSfx",lifecycle:{mode:"background",status:{cliCommand:"sfx status",pollAfterSeconds:10}},milestone:"M7",name:"sfx generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Generate persisted speaker notes for a presentation version.",id:"generateSpeakerNotes",lifecycle:{mode:"background",status:{cliCommand:"presentation speaker-notes-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation speaker-notes",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"dynamic",category:"media",description:"Generate speech from text with an optional brand pronunciation dictionary and the selected narration voice, as an approved, recoverable run.",id:"generateSpeech",lifecycle:{mode:"background",status:{cliCommand:"tts status",pollAfterSeconds:10}},milestone:"M7",name:"tts generate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"Read one owned Agent and its complete configuration.",id:"getAgent",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent get",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"Read what a scheduled Agent remembers. Memory is context recorded from its runs; it grants no permission and overrides no instruction.",id:"getAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory show",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"branding",description:"List competitors saved for an accessible brand profile.",id:"getBrandCompetitors",lifecycle:{mode:"bounded"},milestone:"M1",name:"branding competitor list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read the complete current brand footer settings.",id:"getBrandFooter",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding footer get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's guardrail rules.",id:"getBrandGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's design tokens, the keys it is missing, or its design.md document.",id:"getBrandProfile",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding profile",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read the pronunciation rule for one word saved in a brand.",id:"getBrandPronunciation",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding pronunciation get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read which decks have drifted from a brand.",id:"getBrandQuality",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding quality get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"Read a brand's Voice and Context document.",id:"getBrandVoice",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding voice get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"billing",description:"List every credit charge inside one activity group, with the run that made it.",id:"getCreditActivityGroup",lifecycle:{mode:"bounded"},milestone:"M8",name:"credits trace",operation:"query",scopes:["billing:read"],state:"available"},{billing:"free",category:"media",description:"Read an owned footage project and its append-only versions.",id:"getFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"presentations",description:"Read the workspace's per-mode generation limits, usage, remaining quota, plan and storage allowance.",id:"getGenerationLimits",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation limits",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"knowledge",description:"Return a bounded Open Knowledge Format workspace bundle.",id:"getKnowledgeBundle",lifecycle:{mode:"bounded"},milestone:"M1",name:"knowledge bundle",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search recent news sources.",id:"getNews",lifecycle:{mode:"bounded"},milestone:"M1",name:"search news",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"presentations",description:"Read an owned presentation and optionally its ordered slides.",id:"getPresentation",lifecycle:{mode:"bounded"},milestone:"M1",name:"get",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"branding",description:"Read changes in a presentation's already-linked brand.",id:"getPresentationBrandDrift",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation drift",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"presentations",description:"Read presentation ownership, access, and eligible team members.",id:"getPresentationSharing",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation sharing get",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one owned presentation-video Studio chat with safe attachment and scene-marker context.",id:"getPresentationVideoChatThread",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video chat",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read whether a presentation-video draft is behind its source deck without changing it.",id:"getPresentationVideoFreshness",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video freshness",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read preview run status and prepared image metadata for every video scene.",id:"getPresentationVideoPreviews",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video previews inspect",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read an owned presentation-video project and its ordered scene timeline.",id:"getPresentationVideoProject",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video inspect",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one MP4 render attempt with its exact snapshot and download metadata.",id:"getPresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video render",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read one saved presentation-video draft snapshot without restoring it.",id:"getPresentationVideoVersion",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video version",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"agents",description:"Read one roster-visible Agent without exposing its private configuration.",id:"getRosterAgent",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent roster get",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"media",description:"Read how many people watched a shared video and how far they got.",id:"getVideoViewAnalytics",lifecycle:{mode:"bounded"},milestone:"M8",name:"video views",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"Read one walkthrough with its narration moments, presenter status, and render results.",id:"getWalkthrough",lifecycle:{mode:"bounded"},milestone:"M8",name:"walkthrough get",operation:"query",scopes:["walkthroughs:read"],state:"available"},{billing:"dynamic",category:"research",description:"Fetch a YouTube video's timestamped transcript, title, channel, and duration.",id:"getYoutubeTranscript",lifecycle:{mode:"bounded"},milestone:"M1",name:"transcript",operation:"query",scopes:["research:read"],state:"available"},{billing:"quota",category:"branding",description:"Import a reusable brand from DESIGN.md and optionally merge URL evidence.",id:"importBrandDesignMd",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding import",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Import a recording from a connected account into the media library.",id:"importConnectorRecording",lifecycle:{mode:"background",status:{cliCommand:"media import status",pollAfterSeconds:5}},milestone:"M8",name:"media import",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Import every completed provider-assisted take, preserving explicit source traceability when proven.",id:"importFootageProviderTakes",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage import-takes",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Import an attached PowerPoint as an auditable, review-gated Mindframes presentation.",id:"importPowerPoint",lifecycle:{mode:"background",status:{cliCommand:"presentation import status",pollAfterSeconds:5}},milestone:"M4",name:"presentation import",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Split an uploaded script across existing video scenes without rewriting the source text.",id:"importPresentationVideoScript",lifecycle:{mode:"background",status:{cliCommand:"presentation video-script-import-status",pollAfterSeconds:10}},milestone:"M4",name:"presentation video-script-import",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Create proxy, filmstrip, and waveform evidence for one footage range.",id:"inspectFootageRange",lifecycle:{mode:"background",status:{cliCommand:"footage inspection-status",pollAfterSeconds:2}},milestone:"M8",name:"footage inspect",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Inspect an owned ZIP upload and list exact member paths and metadata without decompressing members.",id:"inspectLibraryArchive",lifecycle:{mode:"bounded"},milestone:"M8",name:"file inspect-archive",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"delegated",category:"media",description:"Re-voice a ready video with new audio via provider lip-sync (one sibling re-voiced video artifact).",id:"lipsyncVideo",lifecycle:{mode:"background",status:{cliCommand:"video lipsync status",pollAfterSeconds:20}},milestone:"M8",name:"video lipsync",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"List the caller's roster: owned Agents plus same-workspace Agents shared with the team.",id:"listAgentRoster",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent roster list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"List the caller's scheduled Agents with stable cursor pagination.",id:"listAgents",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"agents",description:"List the user's secret-free Claude Code or Codex connection profiles and current selection.",id:"listAiConnectionProfiles",lifecycle:{mode:"bounded"},milestone:"M8",name:"ai-connections list",operation:"query",scopes:["agents:read"],state:"available"},{billing:"free",category:"branding",description:"Read a filtered, cursor-paginated activity feed for one brand.",id:"listBrandActivity",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding activity",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List uploaded assets attached to one private or team brand, optionally by kind.",id:"listBrandAssets",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List available workspace brand profiles, optionally filtered by name or domain.",id:"listBrandings",lifecycle:{mode:"bounded"},milestone:"M1",name:"branding list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the safe, owned job history for one brand.",id:"listBrandJobs",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding jobs list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List stable logo candidates and identify the active one.",id:"listBrandLogos",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List workspace members that a brand permission administrator can address.",id:"listBrandPermissionCandidates",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission candidates",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List explicit member access overrides for one team brand.",id:"listBrandPermissions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List presentations already linked to a brand.",id:"listBrandPresentations",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentations list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the products a brand sells.",id:"listBrandProducts",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the word-to-pronunciation rules saved in a brand dictionary.",id:"listBrandPronunciations",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding pronunciation list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List the social accounts recorded as belonging to one accessible brand.",id:"listBrandSocialHandles",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding social list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's per-channel design variants.",id:"listBrandVariants",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's published versions.",id:"listBrandVersions",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version list",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"media",description:"List saved ways a cast member appears \u2014 a trained presenter, a backdrop, and optionally a voice, under one name. Filtered to what the caller may actually use.",id:"listCastPresets",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset list",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"billing",description:"List a workspace's credit spend grouped by the artifact it was spent on.",id:"listCreditActivity",lifecycle:{mode:"bounded"},milestone:"M8",name:"credits activity",operation:"query",scopes:["billing:read"],state:"available"},{billing:"free",category:"presentations",description:"List Discussion Grants for private deck collaboration without model execution.",id:"listDiscussionGrants",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion grant list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List Discussion Threads for private deck collaboration without model execution.",id:"listDiscussionThreads",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the workspace's documents, newest first.",id:"listDocuments",lifecycle:{mode:"bounded"},milestone:"M8",name:"document list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"List a document's append-only version history.",id:"listDocumentVersions",lifecycle:{mode:"bounded"},milestone:"M8",name:"document versions",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"dynamic",category:"branding",description:"Listen to saved brand pronunciations, reusing unchanged audio and returning Mindframes asset URLs.",id:"listenBrandPronunciations",lifecycle:{mode:"background",status:{cliCommand:"branding pronunciation listen status",pollAfterSeconds:10}},milestone:"M2",name:"branding pronunciation listen",operation:"generation",scopes:["brands:read","media:write"],state:"available"},{billing:"free",category:"knowledge",description:"List the files this workspace filed in its Library.",id:"listLibraryFiles",lifecycle:{mode:"bounded"},milestone:"M8",name:"file list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the workspace Library folder tree in display order, optionally with item counts.",id:"listLibraryFolders",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"List presentations visible to the caller in one explicitly selected workspace.",id:"listPresentations",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the owned Studio chat threads for a presentation video.",id:"listPresentationVideoChatThreads",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video chats",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List every presentation-video draft for a source deck with stage and staleness.",id:"listPresentationVideoProjects",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video drafts",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List every MP4 render attempt for a presentation-video project.",id:"listPresentationVideoRenders",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video renders",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List saved presentation-video draft versions.",id:"listPresentationVideoVersions",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video versions",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"media",description:"List the personal-presenter engines, supported source kinds, customer-credit prices, and exact localized consent statement available to this workspace.",id:"listPresenterCreationOptions",lifecycle:{mode:"bounded"},milestone:"M8",name:"avatar presenter options",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List provider-neutral presenter avatars, voices, and voice languages, plus the workspace's trained personal presenters (`personal` roster group, pp_* ids).",id:"listPresenterOptions",lifecycle:{mode:"bounded"},milestone:"M8",name:"avatar options",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List ready generated clips and uploaded MediaAssets while excluding final presentation-to-MP4 renders.",id:"listReusableVideoClips",lifecycle:{mode:"bounded"},milestone:"M8",name:"video library list",operation:"query",scopes:["media:read","presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the slide design templates available to the workspace, plus system templates.",id:"listSlideTemplates",lifecycle:{mode:"bounded"},milestone:"M1",name:"templates",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"support",description:"List this workspace's support requests and their status; --mine narrows to the reports you filed.",id:"listSupportRequests",lifecycle:{mode:"bounded"},milestone:"M8",name:"support list",operation:"query",scopes:["support:read"],state:"available"},{billing:"free",category:"media",description:"List provider-neutral target languages for video translation.",id:"listTranslationLanguages",lifecycle:{mode:"bounded"},milestone:"M8",name:"video translate-languages",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"The voices people have asked to have admitted, and whether you can decide.",id:"listVoiceApprovalRequests",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice requests",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"Which voices this workspace's material may be spoken in, and whether that is binding.",id:"listVoiceApprovals",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice approvals",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List the voices this workspace can narrate with, filtered by the labels the provider states.",id:"listVoices",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice list",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"media",description:"List the workspace's walkthroughs, newest first, with narration and render status.",id:"listWalkthroughs",lifecycle:{mode:"bounded"},milestone:"M8",name:"walkthrough list",operation:"query",scopes:["walkthroughs:read"],state:"available"},{billing:"free",category:"knowledge",description:"List the workspace's in-flight, draft, failed, and finished work across every artifact kind, with lifecycle state and a resume target for each.",id:"listWorkItems",lifecycle:{mode:"bounded"},milestone:"M1",name:"work list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"dynamic",category:"media",description:"Mix voice, music, and sound-effect tracks as an approved, recoverable run.",id:"mixAudio",lifecycle:{mode:"background",status:{cliCommand:"mix status",pollAfterSeconds:10}},milestone:"M7",name:"mix create",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Move a Library folder under a new parent or to the top level.",id:"moveLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders move",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Pause an owned Agent's schedule without changing its configuration.",id:"pauseAgentSchedule",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent pause",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"presentations",description:"Post Discussion Message for private deck collaboration without model execution.",id:"postDiscussionMessage",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion post",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Create or reuse a presentation-video project for a finished presentation.",id:"preparePresentationVideo",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video prepare",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Start or resume slide-preview preparation for a presentation-video draft.",id:"preparePresentationVideoPreviews",lifecycle:{mode:"background",status:{cliCommand:"presentation video previews status",pollAfterSeconds:2}},milestone:"M4",name:"presentation video previews prepare",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Publish the brand's working draft as a new live version.",id:"publishBrandVersion",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding version publish",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Read the full content of an artifact this workspace owns: a presentation's slides, a video's request, narration and scenes, a narrated-video project's scene timeline, a microsite's or article's blocks, or a Library document.",id:"readArtifact",lifecycle:{mode:"bounded"},milestone:"M1",name:"artifact read",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"Read Discussion Events for private deck collaboration without model execution.",id:"readDiscussionEvents",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion events",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"Read Discussion Thread for private deck collaboration without model execution.",id:"readDiscussionThread",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion read",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"knowledge",description:"Read one document's full body and metadata.",id:"readDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document read",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"media",description:"Read a video storyboard and its immutable revision history.",id:"readVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Set or clear a Library folder's colour.",id:"recolorLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders recolor",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Create a private inactive scheduled-agent draft for review.",id:"recommendAgent",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent recommend",operation:"generation",scopes:["agents:write"],state:"available"},{billing:"free",category:"presentations",description:"Refresh deck-backed video scenes from the latest presentation version.",id:"refreshPresentationVideoSlides",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video refresh",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Regenerate one narration override in a presentation-video draft.",id:"regeneratePresentationVideoNarration",lifecycle:{mode:"background",status:{cliCommand:"presentation video-narration-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation video-narration",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Register an already-uploaded file in one private or team brand's asset library.",id:"registerBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset register",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Register Discussion Actor for private deck collaboration without model execution.",id:"registerDiscussionActor",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion actor register",operation:"mutation",scopes:["presentations:read"],state:"available"},{billing:"free",category:"branding",description:"Remove an exact logo candidate and select its deterministic fallback when active.",id:"removeBrandLogo",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo remove",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Remove one member's explicit access override from a team brand.",id:"removeBrandPermission",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission remove",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Take a file off this workspace's Library shelf and delete its stored bytes.",id:"removeLibraryFile",lifecycle:{mode:"bounded"},milestone:"M8",name:"file remove",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"branding",description:"Rename one asset in a private or team brand's library.",id:"renameBrandAsset",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding asset rename",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Rename a Library folder.",id:"renameLibraryFolder",lifecycle:{mode:"bounded"},milestone:"M1",name:"library folders rename",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"delegated",category:"media",description:"Render selected outputs from one exact, strategy-approved footage draft version.",id:"renderFootageProject",lifecycle:{mode:"background",status:{cliCommand:"footage render-status",pollAfterSeconds:5}},milestone:"M8",name:"footage render",operation:"generation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Render one scene of a presentation video to its own reusable MP4 segment and cache it for the final render.",id:"renderPresentationVideoScene",lifecycle:{mode:"background",status:{cliCommand:"presentation video scene status",pollAfterSeconds:10}},milestone:"M8",name:"presentation video scene render",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Render a narrated walkthrough draft to MP4. Billed by the draft's saved cost mode (quick or premium) when the render completes.",id:"renderWalkthrough",lifecycle:{mode:"background",status:{cliCommand:"walkthrough status",pollAfterSeconds:10}},milestone:"M8",name:"walkthrough render",operation:"generation",scopes:["walkthroughs:write"],state:"available"},{billing:"free",category:"branding",description:"Repair decks that have visually drifted from a brand.",id:"repairBrandQuality",lifecycle:{mode:"background",status:{cliCommand:"branding quality repair-status",pollAfterSeconds:5}},milestone:"M2",name:"branding quality repair",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Ask for a voice to be admitted for this workspace's material.",id:"requestVoiceApproval",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice request",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Resolve a brand's current draft design for an artifact context, including ordered node trace and conflicts.",id:"resolveBrandDesign",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding design resolve",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"knowledge",description:"Restore an earlier version by appending it as the current one.",id:"restoreDocumentVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"document restore",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"media",description:"Restore an immutable footage version as a new project head.",id:"restoreFootageProjectVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage restore",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Restore a saved presentation-video draft version as a new version, optionally only when both the current version and non-coalescing project revision still match expected values.",id:"restorePresentationVideoVersion",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video restore",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"agents",description:"Resume an owned Agent's saved schedule without changing its configuration.",id:"resumeAgentSchedule",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent resume",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"media",description:"Remove one of your own workspace voices and release the slot it holds.",id:"retireVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice remove",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"presentations",description:"Retry the failed or cancelled slide-preview run attached to a video draft.",id:"retryPresentationVideoPreviews",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video previews retry",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Append a semantic revision to a footage edit project.",id:"reviseFootageProject",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage revise",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"delegated",category:"media",description:"Create a new presenter Look by editing an existing Look without changing its source.",id:"revisePresenterLook",lifecycle:{mode:"background",status:{cliCommand:"avatar look revision-status",pollAfterSeconds:10}},milestone:"M8",name:"avatar look revise",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Create a new immutable revision of a Markdown video storyboard.",id:"reviseVideoStoryboard",lifecycle:{mode:"bounded"},milestone:"M8",name:"video storyboard revise",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one of a brand's products.",id:"saveBrandProduct",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Keep one of the candidates from designVoice as a reusable workspace voice.",id:"saveDesignedVoice",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice save",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"dynamic",category:"research",description:"Read and normalize bounded content from a public URL.",id:"scrape",lifecycle:{mode:"bounded"},milestone:"M1",name:"scrape",operation:"query",scopes:["research:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search licensed image catalogs.",id:"searchImages",lifecycle:{mode:"bounded"},milestone:"M1",name:"search images",operation:"query",scopes:["research:read"],state:"available"},{billing:"dynamic",category:"research",description:"Search current public web sources.",id:"searchInternet",lifecycle:{mode:"bounded"},milestone:"M1",name:"search web",operation:"query",scopes:["research:read"],state:"available"},{billing:"free",category:"knowledge",description:"Search the workspace Knowledge Hub across presentations, artifacts, context, and agents.",id:"searchKnowledge",lifecycle:{mode:"bounded"},milestone:"M1",name:"knowledge search",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"Search the presentation-video stock-music catalog and return preview metadata plus opaque selection tokens.",id:"searchPresentationVideoStockMusic",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video music stock search",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"dynamic",category:"media",description:"Search web and licensed stock-video catalogs. Playable stock files include a workspace-bound selectionToken for add_scene_layer with stockVideoToken; selection does not import footage into Library.",id:"searchStockVideo",lifecycle:{mode:"bounded"},milestone:"M1",name:"search video",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"agents",description:"Select a Claude Code or Codex connection profile, or restore the native provider route.",id:"selectAiConnectionProfile",lifecycle:{mode:"bounded"},milestone:"M8",name:"ai-connections select",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Materialize a searched stock track, or auto-select from saved deck context, and persist it on a presentation-video project.",id:"selectPresentationVideoStockMusic",lifecycle:{mode:"background",status:{cliCommand:"presentation video music stock status",pollAfterSeconds:3}},milestone:"M4",name:"presentation video music stock select",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"agents",description:"Share an owned Agent with the workspace or return it to private visibility.",id:"setAgentVisibility",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent visibility set",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one custom Foundation colour role atomically.",id:"setBrandCustomColor",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding foundation color set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Change one or more brand footer settings without guessing the rest.",id:"setBrandFooter",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding footer set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's gradient library and its role pointers.",id:"setBrandGradients",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding gradient set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one of a brand's guardrail rules.",id:"setBrandGuardrail",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Point a brand at an already-uploaded logo, dark-background logo variant, or favicon.",id:"setBrandLogo",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding logo set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Set one team member's explicit access role for a team brand.",id:"setBrandPermission",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding permission set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Atomically set approved and draft state for a bounded set of brand products.",id:"setBrandProductSelection",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding product select",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or replace one word-to-pronunciation rule in a brand dictionary. Free reversible brand configuration; no provider is called.",id:"setBrandPronunciation",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding pronunciation set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or replace a batch of brand pronunciation rules together. Free reversible brand configuration; unchanged rules retain their identity and version.",id:"setBrandPronunciations",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding pronunciation set-batch",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Star or unstar a brand in your own library.",id:"setBrandStar",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding star",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Create or update one per-channel brand design variant.",id:"setBrandVariant",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding variant set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Write a brand's Voice and Context document.",id:"setBrandVoice",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding voice set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Make one brand the default for this workspace or for you.",id:"setDefaultBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding set-default",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"presentations",description:"Set Discussion Grant for private deck collaboration without model execution.",id:"setDiscussionGrant",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion grant set",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Set Discussion State for private deck collaboration without model execution.",id:"setDiscussionState",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion state set",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Set a presentation-video scene, or an exact slideIds batch atomically, to a specific avatar/look or saved preset, including the preset voice by default, or restore inheritance from the project default. A batch creates one saved version and does not render media.",id:"setPresentationVideoScenePresenter",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video presenter",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Write exact speaker notes onto slides of a presentation, or clear them, without generation.",id:"setSpeakerNotes",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation speaker-notes-set",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"media",description:"Set the poster image of a finished video.",id:"setVideoThumbnail",lifecycle:{mode:"bounded"},milestone:"M8",name:"video thumbnail set",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Set who may open a video's /v link: private (owner), team (workspace), or public (anyone with the link). Returns the canonical share URL.",id:"setVideoVisibility",lifecycle:{mode:"bounded"},milestone:"M8",name:"video share",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Admit a voice for this workspace's material, or withdraw it.",id:"setVoiceApproval",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice approve",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Star a voice so it stays at the top of your list, or remove the star. A star is a shortcut, never a permission.",id:"setVoiceFavorite",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice star",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Decide whether this workspace's material may be spoken in any voice, or only in approved ones.",id:"setVoicePolicy",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice policy",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Save how a workspace voice reads by default \u2014 professional, conversational or energetic, or exact stability, expressiveness and speed \u2014 or clear it. Recorded clones keep the delivery of their recording.",id:"setVoiceTone",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice tone",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"media",description:"Share a voice you made with the workspace, or keep it to yourself.",id:"setVoiceVisibility",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice share",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"support",description:"File a bug, question, feature request or billing issue against Mindframes.",id:"submitSupportRequest",lifecycle:{mode:"bounded"},milestone:"M8",name:"support report",operation:"mutation",scopes:["support:write"],state:"available"},{billing:"free",category:"branding",description:"Mirror a brand's current flat data into its resolved DAG and active snapshot.",id:"syncBrandFoundation",lifecycle:{mode:"background",status:{cliCommand:"branding foundation sync-status",pollAfterSeconds:3}},milestone:"M2",name:"branding foundation sync",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Apply a brand to every presentation linked to it.",id:"syncBrandToPresentations",lifecycle:{mode:"background",status:{cliCommand:"branding sync-status",pollAfterSeconds:5}},milestone:"M2",name:"branding sync",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Evaluate a brand's guardrail rules against content.",id:"testBrandGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding guardrails test",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"presentations",description:"Transfer a complete presentation and all saved versions to an active team editor or admin.",id:"transferPresentationOwnership",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation transfer",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Transform an uploaded PowerPoint source into an auditable presentation review.",id:"transformPresentationImport",lifecycle:{mode:"background",status:{cliCommand:"presentation import transform-status",pollAfterSeconds:5}},milestone:"M4",name:"presentation import transform",operation:"generation",scopes:["presentations:write"],state:"available"},{billing:"delegated",category:"media",description:"Translate a ready video into sibling language versions (one video per target language).",id:"translateVideo",lifecycle:{mode:"background",status:{cliCommand:"video translate status",pollAfterSeconds:20}},milestone:"M8",name:"video translate",operation:"generation",scopes:["media:write"],state:"available"},{billing:"free",category:"agents",description:"Update an owned Agent's schedule, sources, outputs, delivery, review, runtime, or blueprint configuration.",id:"updateAgentConfiguration",lifecycle:{mode:"bounded"},milestone:"M8",name:"agent configure",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"agents",description:"Add to or remove from what a scheduled Agent remembers.",id:"updateAgentMemory",lifecycle:{mode:"bounded"},milestone:"M3",name:"agent memory set",operation:"mutation",scopes:["agents:write"],state:"available"},{billing:"free",category:"branding",description:"Rename a brand or change which brand it sits under.",id:"updateBrand",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding update",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Write a brand's design tokens from a key patch or a whole design.md document.",id:"updateBrandTokens",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"media",description:"Change a saved cast preset's name, presenter, backdrop, or voice. Sends the complete preset, not a patch.",id:"updateCastPreset",lifecycle:{mode:"bounded"},milestone:"M8",name:"cast preset update",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"knowledge",description:"Edit a document's body, title or summary under an optimistic lock.",id:"updateDocument",lifecycle:{mode:"bounded"},milestone:"M8",name:"document update",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"presentations",description:"Manage presentation collaborators and team access.",id:"updatePresentationSharing",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation sharing update",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Update avatar, presenter layout/background/scene visibility, voice, music, captions, format, and renderer settings for a presentation-video project. settings.sceneVoiceIds atomically merges exact scene voice overrides without changing omitted scenes or the default voice; settings.sceneVoiceEnabled turns one scene's narration off (silent, text kept, no default-voice fallback) or back on; settings.voiceTone and settings.sceneVoiceTones set how narration reads (professional, conversational, energetic or exact values); settings changes do not render media.",id:"updatePresentationVideoSettings",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video settings",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Set who can open a presentation: public, team, or private.",id:"updatePresentationVisibility",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation visibility",operation:"mutation",scopes:["presentations:write"],state:"available"}];function tr(t){return{capabilities:yd,catalogVersion:1,reason:t,source:"snapshot"}}async function gn(t=ss){try{let{capabilities:e,catalogVersion:n}=await t();return!Array.isArray(e)||e.length===0?tr("the live catalog returned no capabilities"):{capabilities:e,catalogVersion:n,source:"live"}}catch(e){let n=e instanceof Error?e.message:String(e);return tr(n)}}var bd=["presentations","media","branding","knowledge","research","artifacts","agents","support"],fg=80,hg=30;function yg(t){return t.billing!==void 0&&t.billing!=="free"&&t.billing!=="quota"}function bg(t){return t.lifecycle?.mode==="background"}function wg(t,e){if(e<=0)return[t];let n=[],r="";for(let o of t.split(/\s+/).filter(Boolean))r===""?r=o:r.length+1+o.length<=e?r=`${r} ${o}`:(n.push(r),r=o);return r!==""&&n.push(r),n.length>0?n:[""]}function wd(t){let e=bd.indexOf(t);return e===-1?bd.length:e}function vg(t,e){let n=e.search?.trim().toLowerCase(),r=e.category?.trim().toLowerCase();return t.filter(o=>r&&(o.category??"").toLowerCase()!==r?!1:n?`${o.name} ${o.description??""}`.toLowerCase().includes(n):!0)}function Ig(t){let e=new Map;for(let i of t){let d=i.category??"other",c=e.get(d);c?c.push(i):e.set(d,[i])}let n=[...e.entries()].sort(([i],[d])=>{let c=wd(i)-wd(d);return c!==0?c:i.localeCompare(d)}),r=Math.min(hg,Math.max(...t.map(i=>i.name.length))),o=[];for(let[i,d]of n){d.sort((c,u)=>c.name.localeCompare(u.name)),o.length>0&&o.push(""),o.push(fn.bold(`${i} (${d.length})`));for(let c of d){let u=`${yg(c)?"$":" "}${bg(c)?"*":" "}`,f=c.name.padEnd(r),v=2+r+1+u.length+1,I=Math.max(24,fg-v),S=wg(c.description??"",I);o.push(` ${fn.cyan(f)} ${fn.yellow(u)} ${S[0]??""}`.trimEnd());for(let $ of S.slice(1))o.push(`${" ".repeat(v)}${$}`)}}return o}function kg(t){return t.map(e=>`${e.name} ${e.state} ${e.milestone}`)}function xg(t,e={filtered:!1}){if(t.length===0)return[e.filtered?"No capabilities match that filter.":"No capabilities available."];if(!t.some(i=>i.description||i.category))return kg(t);let r=g.commands[0],o=Ig(t);return o.push(""),o.push(fn.dim(`${t.length} capabilities \xB7 $ = paid \xB7 * = background (returns a run id)`)),o.push(fn.dim(`Filter with: ${r} capabilities --search <query>`)),o}var vd=new gg("capabilities").description("Index of everything this CLI can do \u2014 every command, grouped and described").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").option("-s, --search <query>","Only show capabilities matching a query").option("--category <name>","Only show one category").action(async t=>{try{let e=await gn(),n=vg(e.capabilities,t),r=!!(t.search||t.category);if(t.format==="json"){l({capabilities:n,catalogVersion:e.catalogVersion,source:e.source,...e.reason?{sourceReason:e.reason}:{}});return}if(t.format==="quiet"){for(let o of n)console.log(o.name);return}e.source==="snapshot"&&L(`Showing the capability list baked into this CLI build (${e.reason}); the deployed catalog may have moved on.`);for(let o of xg(n,{filtered:r}))console.log(o)}catch(e){a(m(e,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{mkdirSync as Eg,writeFileSync as Tg}from"fs";import{dirname as Rd,join as Ag}from"path";import{confirm as Cd,input as $g,password as Pg,select as Og}from"@inquirer/prompts";import hn from"chalk";import{Command as Ke}from"commander";import rr from"ora";import Rg from"conf";var nr=new Rg({projectName:"conceptcraft",configName:"feature-cache"}),Cg=3600*1e3,Sg=1440*60*1e3;function Id(t){let e=0;for(let n=0;n<t.length;n++){let r=t.charCodeAt(n);e=(e<<5)-e+r,e=e&e}return e.toString(16)}function kd(){if(!xt())return null;let t=nr.get("featureFlags");if(!t)return null;let e=Id(Ue());if(t.apiKeyHash&&t.apiKeyHash!==e)return ct(),null;let n=Date.now()-t.fetchedAt;return n>Sg?null:(n>Cg&&Do(),t.flags)}function Do(){dt().catch(()=>{})}async function dt(){let t=await Is(),e=Ue();return nr.set("featureFlags",{flags:t,fetchedAt:Date.now(),apiKeyHash:e?Id(e):void 0}),t}function ct(){nr.delete("featureFlags")}function xd(){return nr.path}var Sd=new Ke("config").description("Manage CLI configuration: account settings, and the cached feature flags that decide which commands appear").addCommand(new Ke("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(hn.bold(`${g.displayName} CLI Configuration`)),console.log(hn.gray("\u2500".repeat(35))),console.log();try{let t=await Pg({message:"Enter your API key:",mask:"*",validate:r=>!r||r.trim().length===0?"API key is required":wo(r.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(yo(t.trim()),await Cd({message:`Use a custom API URL? (default: ${g.apiUrl.replace("https://","")})`,default:!1})){let r=await $g({message:"Enter API URL:",default:F(),validate:o=>{try{return new URL(o),!0}catch{return"Invalid URL format"}}});bo(r)}console.log();let n=rr("Verifying API key...").start();try{let r=await Oe();if(n.succeed("API key verified!"),console.log(),w(`Logged in as: ${r.user.email}`),r.teams.length===0)L("No teams found for this user.");else if(r.teams.length===1){let o=r.teams[0];kt(o.id),w(`Team: ${o.name} (${o.planName})`)}else{console.log(),w(`You have access to ${r.teams.length} teams.`);let o=await Og({message:"Select your default team:",choices:r.teams.map(d=>({name:`${d.name} (${d.planName}) - ${d.role}${d.isCurrent?" [current]":""}`,value:d.id})),default:r.currentTeam?.id});kt(o);let i=r.teams.find(d=>d.id===o);k(`Selected team: ${i?.name}`)}try{await dt()}catch{}}catch(r){n.fail("Failed to verify API key"),L(`Could not verify API key: ${m(r,"The operation could not be completed.")}`),L(`You may need to set the team ID manually: ${g.commands[0]} config set team-id <id>`)}console.log(),k("Configuration saved!"),w(`Config file: ${pn()}`),console.log()}catch(t){if(t.name==="ExitPromptError"){console.log(),w("Configuration cancelled.");return}throw t}})).addCommand(new Ke("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async t=>{let e=Fa();if(Se("Current Configuration"),console.log(),E("API Key",Ya()??hn.red("Not set")),E("API URL",e.apiUrl),E("Default Team ID",e.defaultTeamId??hn.gray("Not set")),console.log(),E("Config file",pn()),t.verify&&e.apiKey){console.log();let n=rr("Verifying...").start();try{let r=await Oe();n.succeed("Verified"),console.log(),E("User",r.user.email),r.currentTeam&&E("Current Team",`${r.currentTeam.name} (${r.currentTeam.planName})`),r.teams.length>1&&E("Total Teams",String(r.teams.length))}catch{n.fail("Verification failed"),L("The operation could not be completed.")}}console.log()})).addCommand(new Ke("set").description("Set a configuration value").argument("<key>","Configuration key (api-key, api-url, team-id)").argument("<value>","Value to set").action(async(t,e)=>{switch(t){case"api-key":wo(e)||(a("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),yo(e),ct(),k("API key updated"),dt().catch(()=>{});break;case"api-url":try{new URL(e),bo(e),k(`API URL set to: ${e}`)}catch{a("Invalid URL format"),process.exit(6)}break;case"team-id":kt(e),k(`Default team ID set to: ${e}`);break;default:a(`Unknown config key: ${t}`),console.log(hn.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new Ke("clear").description("Clear all configuration").action(async()=>{try{await Cd({message:"Are you sure you want to clear all configuration?",default:!1})?(zn(),ct(),k("Configuration cleared")):w("Cancelled")}catch{w("Cancelled")}})).addCommand(new Ke("refresh").description("Refresh cached feature flags").action(async()=>{let t=rr("Refreshing feature flags...").start();try{await dt(),t.succeed("Feature flags refreshed"),w(`Run '${g.commands[0]} --help' to see updated commands`)}catch{t.fail("Failed to refresh"),a("The command failed. Please try again."),process.exit(1)}})).addCommand(new Ke("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(t=>{t.cache?console.log(xd()):console.log(pn())})).addCommand(new Ke("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let t=rr("Pulling settings...").start();try{let e=await ge(),n=await fetch(`${F()}/api/cli/settings`,{headers:e});if(!n.ok)throw new Error(`Request failed (HTTP ${n.status})`);let r=await n.text(),o=Ag(Rd(pn()),"settings.toml");Eg(Rd(o),{recursive:!0}),Tg(o,r,"utf8"),t.succeed("Settings pulled"),w(`Written to ${o}`)}catch{t.fail("Failed to pull settings"),a("The command failed. Please try again."),process.exit(1)}}));import{confirm as Ng}from"@inquirer/prompts";import{Command as Lg}from"commander";import{createHash as Dg}from"crypto";function Z(t){let e=Dg("sha256").update(JSON.stringify({command:t.command,payload:No(t.payload),workspaceId:t.workspaceId})).digest("hex");return`cli:${t.command.trim().toLowerCase().replace(/[^a-z0-9._:-]+/g,"-").replace(/^-+|-+$/g,"")||"command"}:${e}`}function No(t){return Array.isArray(t)?t.map(No):!t||typeof t!="object"?t:Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,No(n)]))}var Ed=new Lg("delete").description("Delete a presentation").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-y, --yes","Confirm permanent deletion without prompting").option("-f, --force","Deprecated alias for --yes").option("--team-id <id>","Workspace ID (uses configured default)").option("--idempotency-key <key>","Stable key to safely retry this deletion").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("-q, --quiet","Suppress output").action(async(t,e)=>{if(await b(),!e.yes&&!e.force)try{if(!await Ng({message:`Are you sure you want to delete presentation "${t}"?`,default:!1})){e.quiet||L("Deletion cancelled");return}}catch{e.quiet||L("Deletion cancelled");return}let n=e.teamId??se(),r=e.idempotencyKey??Z({command:"presentation:delete",payload:{slug:t},workspaceId:n??"configured-default"});try{await gs(t,{approvalReceipt:e.approvalReceipt,idempotencyKey:r,teamId:n}),e.quiet||k(`Presentation "${t}" deleted`)}catch(o){o.errorCode==="approval_required"&&L(`Retry with --idempotency-key ${r}`),a("The command failed. Please try again."),process.exit(o.exitCode??1)}});import Ad from"chalk";import{Command as Et}from"commander";import Ug from"ora";import{createParser as ET}from"eventsource-parser";import AT from"chalk";import PT from"ora";async function Td(t,e={}){let n=t.body?.getReader();if(!n)throw new Error("Response body is not readable");let r=new TextDecoder,o="",i=!1;for(;!i;){let d=await n.read();if(i=d.done,d.value){let c=r.decode(d.value,{stream:!0});o+=c,e.quiet||process.stdout.write(c)}}return e.quiet||console.log(),o}function _g(){return new Et("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)",y("--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,e)=>{await b();let n=parseInt(e.words,10);(Number.isNaN(n)||n<50||n>2e3)&&(a("Word count must be between 50 and 2000"),process.exit(6));let r=["professional","casual","educational"];r.includes(e.tone)||(a(`Invalid tone. Valid options: ${r.join(", ")}`),process.exit(6));let o=Ug("Fetching presentation...").start();try{let i=await Ct(t);o.text="Generating blog post...";let d=await ks(i.id,i.documentCreatedAt||i.createdAt,{targetWordCount:n,tone:e.tone,targetAudience:e.audience??"General Audience",customInstructions:e.instructions??"",includeImages:!e.noImages,includeTableOfContents:e.toc??!1}),c=await Td(d,{quiet:!0});o.succeed("Blog generated"),e.format==="json"?console.log(JSON.stringify({presentationId:t,title:i.title,wordCount:n,tone:e.tone,content:c},null,2)):e.format==="markdown"?console.log(c):(console.log(),console.log(Ad.bold(`Blog: ${i.title}`)),console.log(Ad.gray("\u2500".repeat(40))),console.log(),console.log(c),console.log())}catch(i){o.fail("Generation failed"),a("The command failed. Please try again."),process.exit(i.exitCode??1)}})}function jg(){return new Et("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)",y("--format",["human","json"]),"human").action(async(t,e)=>{await b(),w("Tweet generation coming soon.")})}function Vg(){return new Et("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)",y("--format",["human","json"]),"human").action(async t=>{await b(),w("LinkedIn carousel generation coming soon.")})}function qg(){return new Et("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)",y("--format",["human","json"]),"human").action(async(t,e)=>{await b(),w("Question generation coming soon.")})}function Mg(){return new Et("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)",y("--format",["human","json","markdown"]),"human").action(async(t,e)=>{await b(),w("Cheat sheet generation coming soon.")})}function $d(){let t=new Et("derive").description("Generate derivative content from a presentation"),e=kd();return e&&(e.deckToBlog&&t.addCommand(_g()),e.deckToTweets&&t.addCommand(jg()),e.linkedInCarousel&&t.addCommand(Vg()),e.redTeamQuestions&&t.addCommand(qg()),e.presenterCheatSheet&&t.addCommand(Mg())),t}import{Command as Bg}from"commander";import Lo from"chalk";var Pd=new Bg("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)",y("--format",["human","json"]),"human").action(async t=>{await b(),w("Idea generation is available in the web dashboard."),console.log(),console.log(Lo.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(Lo.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(Lo.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{readFile as Fg}from"fs/promises";import{basename as Gg,resolve as Kg}from"path";import{Command as Wg}from"commander";import Jg from"ora";var Od=new Wg("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");Od._hidden=!0;var Dd=Od.option("--dry-run","Validate without importing").option("--overwrite","Overwrite existing presentations").option("--remap-ids","Generate new IDs (default: true)",!0).action(async(t,e)=>{await b();try{(await Oe()).user.role!=="admin"&&(a("This command is only available to administrators"),process.exit(2))}catch{a("Failed to verify permissions"),process.exit(2)}let n=Kg(t),r=Gg(n);r.endsWith(".zip")||(a("File must be a ZIP archive"),process.exit(6));let o=Jg("Reading file...").start();try{let i=await Fg(n);e.dryRun?o.text="Validating...":o.text="Importing presentation...";let d=await bs(i,r,{dryRun:e.dryRun});if(d.success){if(e.dryRun)o.succeed("Validation passed!"),console.log(),w("The file is valid and can be imported."),d.statistics&&(console.log(),E("Slides",String(d.statistics.slidesImported)),E("Images",String(d.statistics.imagesUploaded)));else if(o.succeed("Import complete!"),console.log(),E("Presentation ID",d.presentationId??"N/A"),E("Document ID",d.documentId??"N/A"),d.statistics&&(E("Slides imported",String(d.statistics.slidesImported)),E("Images uploaded",String(d.statistics.imagesUploaded)),E("Time",`${d.statistics.totalTimeMs}ms`)),d.presentationId){let c=F();E("View URL",`${c}/p/${d.presentationId}`)}if(d.warnings&&d.warnings.length>0){console.log();for(let c of d.warnings)L(c)}console.log()}else o.fail("Import failed"),console.log(),d.errors?.length&&a("Import failed. The server rejected the presentation."),process.exit(1)}catch(i){o.fail("Import failed"),i.code==="ENOENT"&&(a(`File not found: ${n}`),process.exit(3)),a("The command failed. Please try again."),process.exit(i.exitCode??1)}});import{Command as zg}from"commander";function Uo(){return new zg("list").description("List presentations").option("-n, --limit <count>","Number of results to return","20").option("--offset <count>","Zero-based result offset","0").option("--sort <field>","Sort by field (updated, created, title)",y("--sort",["updated","created","title"]),"updated").option("--team-id <id>","Team ID (uses default if not specified)").option("--json","Output machine-readable JSON").action(async t=>{await b();let e=parseInt(t.limit,10);(Number.isNaN(e)||e<1||e>50)&&(a("Invalid limit value (expected 1-50)"),process.exit(6));let n=parseInt(t.offset,10);(Number.isNaN(n)||n<0||n>1e4)&&(a("Invalid offset value (expected 0-10000)"),process.exit(6));let r=t.teamId??se();r||(a("Team ID required. Set a default with 'mf config set team-id <id>' or use --team-id"),process.exit(6));try{let o=await ms(r,e,n,t.sort);if(o.length===0){t.json?console.log(JSON.stringify([])):w("No presentations found");return}console.log(t.json?JSON.stringify(o,null,2):fd(o))}catch(o){a("The command failed. Please try again.");let i=typeof o=="object"&&o!==null&&"exitCode"in o&&typeof o.exitCode=="number"?o.exitCode:1;process.exit(i)}})}var Nd=Uo();import{createHash as Hg,randomBytes as _d}from"crypto";import jd from"http";import Ld from"chalk";import{Command as Xg}from"commander";import Yg from"open";import Ud from"ora";var Qg=`${g.displayName} CLI`,Zg=8765,ef=8775,tf=["presentations:read","presentations:write","brands:read","brands:write","media:read","media:write"];function nf(){return _d(32).toString("base64url")}function rf(t){return Hg("sha256").update(t).digest("base64url")}function of(){return _d(16).toString("hex")}async function af(t,e){for(let n=t;n<=e;n++)try{return await new Promise((r,o)=>{let i=jd.createServer();i.listen(n,()=>{i.close(()=>r())}),i.on("error",o)}),n}catch{}throw new Error(`No available port found between ${t} and ${e}`)}async function sf(t){let e=await fetch(`${t}/.well-known/oauth-authorization-server`);if(!e.ok)throw new Error(`Failed to fetch OAuth metadata: ${e.status}`);return e.json()}function df(t){let e=t.scopes_supported?.filter(n=>typeof n=="string"&&n.trim().length>0);return(e?.length?e:tf).join(" ")}function cf(t,e){if(!e?.trim())return df(t);let n=e.split(",").map(o=>o.trim()).filter(Boolean);if(n.length===0)throw new Error("--scopes must include at least one OAuth scope");let r=t.scopes_supported?.filter(o=>typeof o=="string"&&o.trim().length>0);if(r?.length){let o=n.filter(i=>!r.includes(i));if(o.length>0)throw new Error(`Unsupported OAuth scope${o.length===1?"":"s"}: ${o.join(", ")}`)}return n.join(" ")}async function lf(t,e,n){let r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Qg,redirect_uris:[e],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none",scope:n})});if(!r.ok)throw new Error("Client registration failed. Please try again.");return r.json()}async function mf(t,e,n,r,o){let i=new URLSearchParams({grant_type:"authorization_code",code:e,redirect_uri:r,client_id:o,code_verifier:n}),d=await fetch(t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!d.ok)throw new Error("Token exchange failed. Please try again.");return d.json()}function pf(t,e){return new Promise((n,r)=>{let o,i=!1,d=()=>{i||(i=!0,clearTimeout(o),process.off("SIGINT",c),process.off("SIGTERM",c),u.close())},c=()=>{d(),r(new Error("Login cancelled"))},u=jd.createServer((f,v)=>{let I=new URL(f.url||"",`http://localhost:${t}`);if(I.pathname!=="/callback"){v.writeHead(404),v.end("Not found");return}let S=I.searchParams.get("code"),$=I.searchParams.get("state"),O=I.searchParams.get("error"),T=I.searchParams.get("error_description");if(v.writeHead(200,{"Content-Type":"text/html"}),O){v.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>${
|
|
10
|
+
<p>${T||O}</p>
|
|
11
11
|
<p>You can close this window.</p>
|
|
12
12
|
</body>
|
|
13
13
|
</html>
|
|
14
|
-
`),
|
|
14
|
+
`),d(),r(new Error(T||O));return}if(!S||!$){v.end(`
|
|
15
15
|
<!DOCTYPE html>
|
|
16
16
|
<html>
|
|
17
17
|
<head><title>Login Failed</title></head>
|
|
@@ -21,7 +21,7 @@ var f={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"C
|
|
|
21
21
|
<p>You can close this window.</p>
|
|
22
22
|
</body>
|
|
23
23
|
</html>
|
|
24
|
-
`),
|
|
24
|
+
`),d(),r(new Error("Missing authorization code or state"));return}if($!==e){v.end(`
|
|
25
25
|
<!DOCTYPE html>
|
|
26
26
|
<html>
|
|
27
27
|
<head><title>Login Failed</title></head>
|
|
@@ -31,7 +31,7 @@ var f={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"C
|
|
|
31
31
|
<p>You can close this window.</p>
|
|
32
32
|
</body>
|
|
33
33
|
</html>
|
|
34
|
-
`),
|
|
34
|
+
`),d(),r(new Error("State mismatch"));return}v.end(`
|
|
35
35
|
<!DOCTYPE html>
|
|
36
36
|
<html>
|
|
37
37
|
<head><title>Login Successful</title></head>
|
|
@@ -40,266 +40,285 @@ var f={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
|
-
`),
|
|
44
|
-
`)[0]??"";n(
|
|
43
|
+
`),d(),n({code:S,state:$})});u.listen(t),process.once("SIGINT",c),process.once("SIGTERM",c),o=setTimeout(()=>{d(),r(new Error("Login timed out - no callback received within 5 minutes"))},300*1e3)})}async function uf(t,e){let n=await fetch(`${t}/api/cli/whoami`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new Error(`Failed to fetch user info: ${n.status}`);return n.json()}async function gf(t){let e=F(),n=Ud("Discovering OAuth server...").start();try{let r=await sf(e),o=cf(r,t.scopes);n.succeed(`Connecting to ${e}`);let i=await af(Zg,ef),d=`http://localhost:${i}/callback`;console.log(`Redirect URI: ${d}`),console.log(`Authorization endpoint: ${r.authorization_endpoint}`),console.log(`Token endpoint: ${r.token_endpoint}`),console.log(`Registration endpoint: ${r.registration_endpoint}`);let c=await lf(r.registration_endpoint,d,o),u=c.client_id;Ha(u,c.client_secret);let f=nf(),v=rf(f),I=of(),S=new URLSearchParams({client_id:u,redirect_uri:d,response_type:"code",scope:o,state:I,code_challenge:v,code_challenge_method:"S256"}),$=`${r.authorization_endpoint}?${S}`;console.log(`Authorization URL: ${$}`),t.browser?(w("Opening browser..."),await Yg($)):(console.log(Ld.bold("Open this URL in your browser:")),console.log(Ld.cyan($)));let O=pf(i,I),{code:T}=await O;n=Ud("Completing login...").start();let P=await mf(r.token_endpoint,T,f,d,u);Hn(P.access_token,P.refresh_token,P.expires_in);let A=await uf(e,P.access_token);n.succeed("Logged in!"),console.log(),E("Logged in as",A.user.email),A.currentTeam&&(kt(A.currentTeam.id),E("Team",`${A.currentTeam.name} (${A.currentTeam.planName})`));try{await dt()}catch{}console.log(),k("You're all set!"),console.log()}catch(r){throw n.fail("Login failed"),a("The command failed. Please try again."),r}}var Vd=new Xg("login").description(`Authenticate with ${g.displayName} (opens browser)`).option("--no-browser","Print URL instead of opening browser").option("--scopes <scopes>","Comma-separated OAuth scopes to request (defaults to all server-supported scopes)").action(async t=>{console.log(),it()&&(L("You are already logged in."),w(`Run '${g.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await gf(t),process.exit(0)}catch{process.exit(1)}});import{Command as ff}from"commander";import{confirm as hf}from"@inquirer/prompts";var qd=new ff("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async t=>{console.log();let e=it(),n=xt();if(!e&&!n){L("You are not logged in."),console.log();return}if(t.all)try{await hf({message:"Clear all configuration including API key?",default:!1})?(zn(),ct(),k("All configuration cleared.")):w("Cancelled.")}catch{w("Cancelled.")}else Xn(),ct(),k("Logged out successfully."),n&&w("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as th}from"os";import{join as nh}from"path";import Ee from"chalk";import{Command as rh}from"commander";import{spawn as yf}from"child_process";import{existsSync as bf,readdirSync as wf}from"fs";import{homedir as Fd}from"os";import{delimiter as Md}from"path";import{query as vf}from"@anthropic-ai/claude-agent-sdk";function we(t){if(t===void 0)return null;if(typeof t=="string")return t.length>12e3?`${t.slice(0,12e3)}\u2026`:t;try{let e=JSON.stringify(t);return e.length<=12e3?t:{preview:`${e.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(t).slice(0,12e3)}}function or(t){let e=typeof t=="string"?t:String(t??"");return e.length>12e3?`${e.slice(0,12e3)}\u2026`:e}function ve(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function V(t){return typeof t=="string"?t:""}function Bd(t,e){let n=t.replace(/[/.]/g,"-");return`${Fd()}/.claude/projects/${n}/${e}.jsonl`}function If(t){try{return wf(`${t}/.nvm/versions/node`).map(e=>`${t}/.nvm/versions/node/${e}/bin`).sort().reverse()}catch{return[]}}function ir(){let t=Fd(),e=[`${t}/.local/bin`,`${t}/.claude/local`,`${t}/.bun/bin`,`${t}/bin`,"/opt/homebrew/bin","/usr/local/bin",...If(t)],r=(process.env.PATH??"").split(Md);for(let o of e)r.includes(o)||r.push(o);return r.join(Md)}async function ar(t){let e=t??"claude";return new Promise(n=>{let r=yf(e,["--version"],{env:{...process.env,PATH:ir()},stdio:["ignore","pipe","ignore"]}),o="";r.stdout.on("data",i=>{o+=i.toString("utf8")}),r.on("error",()=>n(null)),r.on("close",i=>{if(i!==0)return n(null);let d=o.trim().split(`
|
|
44
|
+
`)[0]??"";n(d?{bin:e,version:d}:null)})})}var kf=new Set(["","default","best"]);function _o(t){let e=t.filter(i=>i.text.trim());if(e.length===0)return"";let n=e[e.length-1],r=e.slice(0,-1);return r.length===0?n.text:`<conversation-history>
|
|
45
45
|
${r.map(i=>`${i.role==="assistant"?"Assistant":"User"}: ${i.text}`).join(`
|
|
46
46
|
|
|
47
47
|
`)}
|
|
48
48
|
</conversation-history>
|
|
49
49
|
|
|
50
|
-
${n.text}`}function
|
|
51
|
-
`)[0]??"";
|
|
52
|
-
`)}catch{return[]}let n=new Set,r=new Map,o=null;for(let i of
|
|
53
|
-
`);return
|
|
54
|
-
`):
|
|
55
|
-
`):""}function
|
|
56
|
-
|
|
57
|
-
`),usage:
|
|
58
|
-
`,"utf8")}catch{}}function
|
|
59
|
-
`,"utf8")}catch{}}var
|
|
60
|
-
Stopping runner\u2026`)),t.abort()};process.on("SIGINT",n),process.on("SIGTERM",n);try{await kd({claudeBin:e.claudeBin,codexBin:e.codexBin,log:r=>console.log(ke.gray(`[runner] ${r}`)),once:e.once,signal:t.signal,version:"0.3.25",workspaceRoot:e.workspace??Fg()})}catch(r){console.error(ke.red(r instanceof Error?r.message:String(r))),process.exit(1)}});import ee from"chalk";import{Command as gR}from"commander";import{Command as To}from"commander";function Gg(e,t){return[...t,e]}var Kg=new To("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",Gg,[]).option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{l(await m("createAdSet",{approvalReceipt:"cli:--yes",brandingId:t.brandingId,brief:t.brief,hooks:t.hook.length?t.hook:[t.brief],style:t.style,teamId:t.teamId,title:e}))}catch(n){a(n instanceof Error?n.message:"Generation failed"),process.exit(s.GENERAL_ERROR)}}),Wg=new To("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await I("createAdSet",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),xd=new To("ad-set").description("Generate a set of ad creatives (hooks, copy, visuals) from a campaign brief").addCommand(Kg).addCommand(Wg);import{randomUUID as Ed}from"crypto";import{readFileSync as Td}from"fs";import{readFile as Qg}from"fs/promises";import{Command as xe}from"commander";import{readFileSync as Jg}from"fs";function he(e,t=()=>Jg(0,"utf8")){if(e.approvalReceipt&&e.approvalReceiptStdin)throw new Error("Pass only one approval receipt input mode.");let n=e.approvalReceiptStdin?t().trim():e.approvalReceipt;if(e.approvalReceiptStdin&&!n)throw new Error("No approval receipt was provided on stdin.");return n}import{randomUUID as zg}from"crypto";function De(e,t){a(e instanceof Error?e.message:t),process.exit(e instanceof D?e.exitCode:s.GENERAL_ERROR)}function rn(e){return`cli:agent-management:${e}:${zg()}`}function kt(e,t){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw new Error(`${t} must be a positive integer`);return n}import{Command as on}from"commander";var Hg=new on("list").description("List one roster page: your Agents plus teammates' team-visible Agents").option("--cursor <cursor>","Continue from a previous nextCursor").option("--page-size <n>","Roster rows to return (1-100)","50").option("--team-id <id>","Workspace ID").action(async e=>{try{l(await m("listAgentRoster",{cursor:e.cursor,pageSize:kt(e.pageSize,"--page-size"),teamId:e.teamId}))}catch(t){De(t,"Could not list the Agent roster")}}),Xg=new on("get").description("Read one roster-visible Agent card without private configuration").argument("<agent-id>","Roster-visible Agent UUID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("getRosterAgent",{agentId:e,teamId:t.teamId}))}catch(n){De(n,"Could not read the roster Agent")}}),Rd=new on("roster").description("Discover Agents shared inside the current workspace; never cross-workspace").addCommand(Hg).addCommand(Xg),Yg=new on("set").description("Share an owned Agent with the workspace or make it private").argument("<agent-id>","Owned scheduled Agent UUID").argument("<visibility>","Desired visibility: private or team",y("visibility",["private","team"])).requiredOption("--expected-visibility <visibility>","Current value from agent roster get: private, team, or legacy public",y("--expected-visibility",["private","team","public"])).option("--idempotency-key <key>","Reuse only for an exact retry of this visibility change").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{try{l(await m("setAgentVisibility",{agentId:e,expectedVisibility:n.expectedVisibility,teamId:n.teamId,visibility:t},n.idempotencyKey?.trim()||rn("visibility")))}catch(r){De(r,"Could not change Agent visibility")}}),Cd=new on("visibility").description("Control whether an owned Agent is private or team-visible").addCommand(Yg);function xt(e,t){return[...t,e]}function Zg(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new Error("Expected a positive integer.");return t}async function Hn(e,t){let n=t.trim(),r=n.startsWith("{")?n:await Qg(n,"utf8"),o=JSON.parse(r);if(!o||typeof o!="object"||Array.isArray(o))throw new Error(`${e} must contain one JSON object.`);return o}var ef=new xe("create").description("Activate a reviewed Agent draft; get browser approval, then retry with the same key and receipt.").argument("<draft-id>","Reviewed agent draft UUID").requiredOption("--expected-version <number>","Exact draft version shown during review",Zg).requiredOption("--idempotency-key <key>","Stable key bound into the approval receipt and reused on retry").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--yes","Confirm activation intent; this never substitutes for the approval receipt").option("--team-id <id>","Workspace ID").action(async(e,t)=>{t.yes||(a("Pass --yes to request activation. A server-issued approval receipt is still required."),process.exit(s.INVALID_INPUT)),await $d("Agent activation failed",()=>m("createAgent",{approvalReceipt:t.approvalReceipt,draftId:e,expectedVersion:t.expectedVersion,teamId:t.teamId},t.idempotencyKey))}),tf=new xe("recommend").description("Save a private inactive scheduled-agent draft for review; this command never activates or runs it.").argument("<name>","Agent name").requiredOption("--instructions <markdown>","Standing agent instructions").option("--description <text>","Agent description","").option("--goal <text>","User-visible recurring objective").option("--rationale <text>","Why this draft is being recommended").option("--schedule <frequency>","manual, daily, weekdays, weekly, or monthly").option("--schedule-r-rule <rrule>","Precise recurrence rule").option("--schedule-time <hh:mm>","Local run time").option("--timezone <zone>","IANA timezone").option("--schedule-config <json-or-path>","Full schedule configuration as inline JSON or a JSON file").option("--source <connector>","Source connector (repeatable)",xt,[]).option("--x-handle-target <handle>","Target for the x_handle source").option("--x-search-target <query>","Query for the x_search source").option("--primary-output <adapter>","Legacy primary output fallback").option("--output <adapter>","Output adapter (repeatable)",xt,[]).option("--output-config <json-or-path>","Full output slot configuration (repeatable)",xt,[]).option("--delivery-adapter <adapter>","Delivery adapter").option("--delivery-config <json-or-path>","Full delivery configuration as inline JSON or a JSON file").option("--review-policy <policy>","manual_review, auto_send, or draft_only","manual_review").option("--runtime <json-or-path>","Scheduled runtime configuration as inline JSON or a JSON file").option("--sandbox-blueprint-id <id>","Sandbox blueprint UUID").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await $d("Agent recommendation failed",async()=>m("recommendAgent",{deliveryAdapter:t.deliveryAdapter,deliveryConfig:t.deliveryConfig?await Hn("--delivery-config",t.deliveryConfig):void 0,description:t.description,goal:t.goal,instructionsMarkdown:t.instructions,name:e,outputAdapter:t.primaryOutput,outputAdapters:t.output.length?t.output:void 0,outputConfigs:t.outputConfig.length?await Promise.all(t.outputConfig.map(n=>Hn("--output-config",n))):void 0,rationale:t.rationale,reviewPolicy:t.reviewPolicy,runtime:t.runtime?await Hn("--runtime",t.runtime):void 0,sandboxBlueprintId:t.sandboxBlueprintId,schedule:t.schedule,scheduleConfig:t.scheduleConfig?await Hn("--schedule-config",t.scheduleConfig):void 0,scheduleRRule:t.scheduleRRule,scheduleTime:t.scheduleTime,sourceConnectors:t.source.length?t.source:void 0,teamId:t.teamId,timezone:t.timezone,xHandleTarget:t.xHandleTarget,xSearchTarget:t.xSearchTarget},t.idempotencyKey??Ed()))});async function $d(e,t){try{l(await t())}catch(n){if(n instanceof D){let r=`[${n.errorCode}] `;console.error(JSON.stringify({error:{code:n.errorCode,message:n.message.startsWith(r)?n.message.slice(r.length):n.message,retryable:n.retryable},ok:!1})),process.exit(n.exitCode)}console.error(JSON.stringify({error:{code:"operation_failed",message:n instanceof Error?n.message:e,retryable:!1},ok:!1})),process.exit(s.GENERAL_ERROR)}}function nf(e,t){return e==="none"?null:kt(e,t)}function rf(e){return e==="none"?null:e}function rt(e,t){let n;try{n=Td(e,"utf8")}catch(r){throw new Error(`${t} could not read ${e}: ${r instanceof Error?r.message:"unknown file error"}`)}try{return JSON.parse(n)}catch(r){throw new Error(`${t} must point to valid JSON: ${r instanceof Error?r.message:"invalid JSON"}`)}}function of(e,t){try{return Td(e,"utf8")}catch(n){throw new Error(`${t} could not read ${e}: ${n instanceof Error?n.message:"unknown file error"}`)}}var af=new xe("list").description("List all owned Agents, following cursor pages to closure").option("--cursor <cursor>","Resume from a previous nextCursor").option("--page-size <n>","Rows fetched per page","50").option("--team-id <id>","Workspace ID").action(async e=>{try{let t=[],n=e.cursor;for(;;){let r=await m("listAgents",{cursor:n,pageSize:kt(e.pageSize,"--page-size"),teamId:e.teamId});if(t.push(...r.agents),!r.hasMore||!r.nextCursor)break;n=r.nextCursor}l({agents:t,total:t.length})}catch(t){De(t,"Could not list Agents")}}),sf=new xe("get").description("Read one owned Agent and its complete configuration").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("getAgent",{agentId:e,teamId:t.teamId}))}catch(n){De(n,"Could not read the Agent")}}),df=new xe("configure").description("Update Agent configuration; enable automatic external delivery in the browser").argument("<agent-id>","Scheduled Agent UUID").requiredOption("--expected-version <n>","Version returned by agent get").option("--name <text>","Agent name").option("--description <text>","Agent description").option("--goal <text>","Recurring objective").option("--instructions-file <path>","UTF-8 Markdown instructions").option("--schedule-file <path>","Typed schedule JSON document").option("--sources-file <path>","Typed source array JSON document").option("--output-file <path>","Typed primary output JSON document").option("--outputs-file <path>","Typed output array JSON document").option("--delivery-file <path>","Typed delivery JSON document").option("--review-policy <policy>","manual_review, auto_send, or draft_only").option("--runtime-file <path>","Typed runtime JSON document").option("--sandbox-blueprint-id <id|none>","Subscription sandbox blueprint, or none").option("--per-run-credit-cap <credits|none>","Positive credit ceiling, or none").option("--files-file <path>","Typed attached-file array JSON document").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("updateAgentConfiguration",{additionalFiles:t.filesFile?rt(t.filesFile,"--files-file"):void 0,agentId:e,delivery:t.deliveryFile?rt(t.deliveryFile,"--delivery-file"):void 0,description:t.description,expectedVersion:kt(t.expectedVersion,"--expected-version"),goal:t.goal,instructionsMarkdown:t.instructionsFile?of(t.instructionsFile,"--instructions-file"):void 0,name:t.name,output:t.outputFile?rt(t.outputFile,"--output-file"):void 0,outputs:t.outputsFile?rt(t.outputsFile,"--outputs-file"):void 0,perRunCreditCap:t.perRunCreditCap===void 0?void 0:nf(t.perRunCreditCap,"--per-run-credit-cap"),reviewPolicy:t.reviewPolicy,runtime:t.runtimeFile?rt(t.runtimeFile,"--runtime-file"):void 0,sandboxBlueprintId:t.sandboxBlueprintId===void 0?void 0:rf(t.sandboxBlueprintId),schedule:t.scheduleFile?rt(t.scheduleFile,"--schedule-file"):void 0,sources:t.sourcesFile?rt(t.sourcesFile,"--sources-file"):void 0,teamId:t.teamId},t.idempotencyKey??rn("configure")))}catch(n){De(n,"Could not update the Agent")}});function Sd(e){return new xe(e).description(`${e==="pause"?"Pause":"Resume"} an Agent schedule`).argument("<agent-id>","Scheduled Agent UUID").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(t,n)=>{try{l(await m(e==="pause"?"pauseAgentSchedule":"resumeAgentSchedule",{agentId:t,teamId:n.teamId},n.idempotencyKey??rn(e)))}catch(r){De(r,`Could not ${e} the Agent schedule`)}})}function $o(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}function cf(e){return`cli:agent-memory:${e}:${Ed()}`}function lf(e,t){let n=e.indexOf("="),r=n===-1?e:e.slice(0,n),o=n===-1?"":e.slice(n+1);return[...t,{name:r.trim(),note:o.trim()}]}var mf=new xe("show").description("Show what a scheduled agent remembers").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("getAgentMemory",{agentId:e,teamId:t.teamId}))}catch(n){$o(n,"Could not read the agent's memory")}}),uf=new xe("set").description("Add to or remove from what an agent remembers. Owner or workspace admin only.").argument("<agent-id>","Scheduled Agent UUID").option("--learned <text>","Durable fact to add (repeatable)",xt,[]).option("--always <text>","Standing instruction to add (repeatable)",xt,[]).option("--never <text>","Thing it must not do, to add (repeatable)",xt,[]).option("--track <name=note>","Entity to track, as name=note (repeatable)",lf,[]).option("--notes <text>","Replace the freeform notes").option("--operation <operation>","Mutation operation: add or remove","add").option("--remove-field <field>","Field to remove from: learned, recurringInstructions, negativePreferences, entities, or notes").option("--remove-value <text>","Item to remove; not needed when removing notes").option("--remove <field>","Deprecated alias for --remove-field").option("--value <text>","Deprecated alias for --remove-value").option("--expected-version <n>","Refuse the write unless the stored memory is still at this version").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{let n=t.removeField??t.remove,r=t.removeValue??t.value,o=t.operation==="remove"||!!n;try{l(await m("updateAgentMemory",{agentId:e,entities:t.track.length?t.track:void 0,expectedVersion:t.expectedVersion===void 0?void 0:Number.parseInt(t.expectedVersion,10),learned:t.learned.length?t.learned:void 0,negativePreferences:t.never.length?t.never:void 0,notes:t.notes,operation:o?"remove":"add",recurringInstructions:t.always.length?t.always:void 0,removeField:n,removeValue:r,teamId:t.teamId},t.idempotencyKey??cf(o?"remove":"add")))}catch(i){$o(i,"Could not update the agent's memory")}}),pf=new xe("forget").description("Erase every stored version of an agent's memory. This cannot be undone.").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable key bound into the approval receipt and reused on retry").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--yes","Confirm erasure intent; this never substitutes for an approval receipt").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to request erasure. A browser-issued approval receipt is still required.");try{let n=he(t);l(await m("forgetAgentMemory",{approvalReceipt:n,agentId:e,teamId:t.teamId},t.idempotencyKey))}catch(n){$o(n,"Could not erase the agent's memory")}}),gf=new xe("memory").description("Read, edit, and erase what a scheduled agent remembers").addCommand(mf).addCommand(uf).addCommand(pf),Ad=new xe("agent").description("Recommend, activate, configure, and manage scheduled Agents").addCommand(af).addCommand(sf).addCommand(Rd).addCommand(Cd).addCommand(df).addCommand(Sd("pause")).addCommand(Sd("resume")).addCommand(ef).addCommand(tf).addCommand(gf);import{Command as Pd}from"commander";var Ao=["article","document","microsite","presentation","presentationVideo","video"];function ff(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}function hf(e){if(e===void 0)return;let t=/^\s*(\d+)\s*(?:-\s*(\d+)\s*)?$/.exec(e);t||(a(`--slides expects N or N-M, got "${e}"`),process.exit(s.GENERAL_ERROR));let n=Number(t[1]),r=t[2]===void 0?n:Number(t[2]);return(n<1||r<n)&&(a(`--slides range must start at 1 and end no earlier than it starts, got "${e}"`),process.exit(s.GENERAL_ERROR)),{from:n,to:r}}var yf=new Pd("read").description("Read an owned artifact's full content").argument("<kind>",`Artifact kind: ${Ao.join(", ")}`).argument("<artifact-id>","Artifact id, or slug where the kind has one").option("--slides <range>","Presentations only: N or N-M. Omit to read every slide.").option("--team-id <id>","Workspace to read from").action(async(e,t,n)=>{Ao.includes(e)||(a(`Unknown artifact kind "${e}". Expected one of: ${Ao.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await m("readArtifact",{artifactId:t,kind:e,slides:hf(n.slides),teamId:n.teamId});l(r)}catch(r){ff(r,"Could not read the artifact")}}),Od=new Pd("artifact").description("Read artifacts this workspace owns").addCommand(yf);import{randomUUID as bf}from"crypto";import{password as wf}from"@inquirer/prompts";import{Command as Xn}from"commander";function Po(e){if(e==="claude-code"||e==="codex")return e;throw new Error("--runtime must be claude-code or codex")}function vf(e,t){let n=e;if(t==="claude-code"&&(n==="zai-claude"||n==="anthropic-compatible")||t==="codex"&&n==="openai-responses-compatible")return n;throw new Error(t==="claude-code"?"--provider must be zai-claude or anthropic-compatible for Claude":"--provider must be openai-responses-compatible for Codex")}async function If(){let e="";for await(let t of process.stdin)if(e+=String(t),e.length>65536)throw new Error("Credential input is too large");return e.trim()}var kf=new Xn("add").description("Enroll a provider credential without exposing it in arguments").requiredOption("--runtime <runtime>","claude-code or codex").requiredOption("--provider <provider>","zai-claude, anthropic-compatible, or openai-responses-compatible").requiredOption("--label <name>","Profile name shown in Mindframes").requiredOption("--model <model-id>","Provider model id").option("--base-url <url>","Public HTTPS provider base URL").option("--api-key-stdin","Read the provider key from stdin instead of a hidden prompt").option("--use","Select the new profile immediately").action(async e=>{try{let t=Po(e.runtime),n=vf(e.provider,t);if(!e.apiKeyStdin&&!process.stdin.isTTY)throw new Error("Non-interactive enrollment requires --api-key-stdin. Never pass provider keys as command arguments.");let r=e.apiKeyStdin?await If():(await wf({mask:"*",message:"Provider API key:"})).trim();if(!r)throw new Error("Provider API key is required");let o=await qa({apiKey:r,...e.baseUrl?{baseUrl:e.baseUrl}:{},label:e.label,makeDefault:e.use??!1,modelId:e.model,provider:n,runtime:t});k(`Saved connection profile ${o.label} (${o.id})`)}catch(t){a(t instanceof Error?t.message:"Profile enrollment failed"),process.exit(s.GENERAL_ERROR)}}),xf=new Xn("list").description("List secret-free Claude Code or Codex connection profiles").requiredOption("--runtime <runtime>","claude-code or codex").action(async e=>{try{let t=Po(e.runtime);l(await m("listAiConnectionProfiles",{runtime:t}))}catch(t){a(t instanceof Error?t.message:"Profile list failed"),process.exit(s.GENERAL_ERROR)}}),Rf=new Xn("select").description("Select a profile UUID, or 'native' for the first-party route").requiredOption("--runtime <runtime>","claude-code or codex").requiredOption("--profile-id <id>","Profile UUID or native").option("--idempotency-key <key>","Reuse only for an exact retry of this profile selection").option("--yes","Confirm changing the active inference route").action(async e=>{e.yes||(a("Pass --yes to confirm changing the active connection profile."),process.exit(s.INVALID_INPUT));try{let t=Po(e.runtime),n=await m("selectAiConnectionProfile",{profileId:e.profileId,runtime:t},e.idempotencyKey?.trim()||bf());k(n.selectedProfileId?`Selected connection profile ${n.selectedProfileId}`:"Selected the native provider route")}catch(t){a(t instanceof Error?t.message:"Profile selection failed"),process.exit(s.GENERAL_ERROR)}}),Dd=new Xn("ai-connections").description("Manage Claude Code and Codex inference routes").addCommand(kf).addCommand(xf).addCommand(Rf);import{randomUUID as Qn}from"crypto";import{readFileSync as Of}from"fs";import{readFile as Df}from"fs/promises";import ot from"chalk";import{Command as ce}from"commander";import Nf from"ora";import{mkdir as Cf,writeFile as Nd}from"fs/promises";import{dirname as Sf}from"path";async function oe(e,t){if(await Cf(Sf(t),{recursive:!0}),e.startsWith("data:")){let o=e.match(/^data:[^;]+;base64,(.+)$/);if(!o)throw new Error("Invalid data URL format");let i=Buffer.from(o[1],"base64");if(i.length===0)throw new Error("Downloaded media was empty");await Nd(t,i);return}let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download media: ${n.status}`);let r=Buffer.from(await n.arrayBuffer());if(r.length===0)throw new Error("Downloaded media was empty");await Nd(t,r)}import{existsSync as Ld}from"fs";import{resolve as Ef}from"path";var Tf=/^([A-Za-z][A-Za-z0-9_-]*)=(.+)$/;function $f(e){let t=e.trim();if(!t)throw new Error("A reference image value cannot be empty.");if(Ld(t))return{source:t};let n=Tf.exec(t);return n?{label:n[1],source:n[2]}:{source:t}}function Af(e,t,n){if(!e.startsWith("image/")&&e!=="application/octet-stream")throw new Error(`Reference image ${t} (${n}) is ${e}, not an image. A reference must be an image; pass an image file or a public image URL.`)}function Pf(e,t){let n;try{n=new URL(e)}catch(r){throw new Error(`Reference image ${t} (${e}) must be an existing local file or an HTTP(S) URL.`,{cause:r})}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`Reference image ${t} (${e}) must use an HTTP(S) URL.`);return n}async function Yn(e,t){if(e?.length){if(t.maxCount!==void 0&&e.length>t.maxCount)throw new Error(`${t.maxCountSubject??"This command"} accepts at most ${t.maxCount} reference images; ${e.length} were provided.`);return Promise.all(e.map(async(n,r)=>{let o=r+1,{label:i,source:c}=$f(n);if(Ld(c)){let u=Ef(c),g=yt(u);t.rejectNonImageFiles&&Af(g,o,c);let w=await Q(u,{idempotencyKey:`${t.idempotencyKey}:reference:${o}`}),v=w.type||g;return{...i?{label:i}:{},...v.startsWith("image/")?{mediaType:v}:{},url:w.url}}let d=Pf(c,o);return{...i?{label:i}:{},url:d.toString()}}))}}var Lf=15e3,Uf=40,_f=3;function qf(e,t){return[...t,e]}async function jf(e){let t=e.trim(),n=t.startsWith("[")?t:await Df(t,"utf8"),r=JSON.parse(n);if(!Array.isArray(r)||r.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new Error("--starter-looks-json must contain one JSON array of objects.");return r}async function Ud(e,t){return(await Yn(e,{idempotencyKey:t,maxCount:_f,maxCountSubject:"A presenter Look"}))?.map(r=>({url:r.url}))}function Oo(e,t){if(t==="json"){l(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}b(`Request ID: ${e.requestId}`),b(`Status: ${e.status}`),e.durationSec!=null&&b(`Duration: ${e.durationSec}s`),e.videoUrl&&k(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}var Vf=new ce("options").description("List available presenter avatars and voices").option("--language <language>","Filter voices by language").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await ss(e.language,e.teamId);if(e.format==="json"){l(t);return}let n=t.personal??[];if(e.format==="quiet"){for(let r of n)console.log(r.id);for(let r of t.avatars)console.log(r.id);for(let r of t.voices)console.log(r.id);return}if(n.length>0){b("Your presenters:");for(let r of n)console.log(` ${r.id} ${r.name}`)}b("Avatars:");for(let r of t.avatars){let o=r.renderTiers?.length?` [${r.renderTiers.join(", ")}]`:"";console.log(` ${r.id} ${r.name}${o}`)}b("Voices:");for(let r of t.voices)console.log(` ${r.id} ${r.name}${r.language?` (${r.language})`:""}`)}catch(t){a(t instanceof Error?t.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Mf=new ce("options").description("List personal-presenter engines, prices, supported sources, and exact consent wording").option("--locale <locale>","Consent locale: en, es, hi, ru, or zh","en").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await m("listPresenterCreationOptions",{locale:e.locale,teamId:e.teamId});if(e.format==="json")return l(t);if(e.format==="quiet"){for(let n of t.options)console.log(n.id);return}b(t.canCreate?"Presenter creation is enabled.":"Presenter creation is not enabled for this account.");for(let n of t.options)console.log(`
|
|
61
|
-
${ot.bold(n.label)} ${ot.gray(n.id)}`),console.log(` ${n.description}`),console.log(` Sources: ${n.supportedKinds.join(", ")}`),console.log(` Credits: ${Object.entries(n.creationCredits).map(([r,o])=>`${r}=${o}`).join(", ")}`),console.log(` Consent: ${n.consentCopyText}`)}catch(t){a(t instanceof Error?t.message:"Options failed"),process.exit(s.GENERAL_ERROR)}}),Bf=new ce("create").description("Create a personal presenter after browser-confirmed likeness consent").requiredOption("--name <name>","Presenter name").requiredOption("--engine <id>","Engine id from 'avatar presenter options'").requiredOption("--kind <kind>","Source kind: footage, photo, or prompt").requiredOption("--consent-statement <text>","Exact consent text from 'avatar presenter options'").option("--locale <locale>","Consent locale","en").option("--source <path>","Local footage or headshot file").option("--prompt <text>","Synthetic-persona description").option("--reference-image <path...>","Up to three local prompt reference images",qf,[]).option("--starter-looks-json <json-or-path>","Optional starter-look array as inline JSON or a JSON file").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key bound into the approval receipt and upload retries").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--yes","Confirm creation intent; this never substitutes for likeness consent").option("--no-wait","Return after the presenter creation run is accepted").action(async e=>{e.yes||(a("Pass --yes to confirm presenter creation intent. Browser-issued likeness approval is still required."),process.exit(s.INVALID_INPUT)),["footage","photo","prompt"].includes(e.kind)||(a("--kind must be footage, photo, or prompt."),process.exit(s.INVALID_INPUT)),e.approvalReceipt&&e.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let t=e.approvalReceiptStdin?Of(0,"utf8").trim():e.approvalReceipt;e.approvalReceiptStdin&&!t&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let n=e.idempotencyKey??Qn();try{if(e.kind==="prompt"&&!e.prompt?.trim())throw new Error("--prompt is required for prompt presenters.");if(e.kind!=="prompt"&&!e.source)throw new Error("--source is required for footage and photo presenters.");if(e.referenceImage.length>3)throw new Error("At most three --reference-image values are allowed.");let r=e.source?await Q(e.source,{idempotencyKey:`${n}:source`,storagePrefix:"presenters"}):void 0,o=await Promise.all(e.referenceImage.map((d,u)=>Q(d,{idempotencyKey:`${n}:reference:${u}`,storagePrefix:"presenters"}))),i=e.starterLooksJson?await jf(e.starterLooksJson):[],c=await m("createPresenter",{approvalReceipt:t,consentCopyLocale:e.locale,consentCopyText:e.consentStatement,engineId:e.engine,kind:e.kind,name:e.name,...e.prompt?{prompt:e.prompt}:{},...o.length?{referenceImageS3Keys:o.map(d=>d.s3Key)}:{},...r?{s3Key:r.s3Key}:{},starterLooks:i,teamId:e.teamId},n);if(!e.wait){l(c),b(`Check progress with: ${p.commands[0]} avatar presenter status ${c.runId}`);return}l(await de("createPresenter",c.runId,e.teamId,null))}catch(r){let o=r instanceof Error?r.message:String(r);a(o),o.includes("approval")&&b(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${n}`),process.exit(s.GENERAL_ERROR)}}),Ff=new ce("status").description("Read personal-presenter creation status").argument("<run-id>","Durable run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await I("createPresenter",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Gf=new ce("presenter").description("Discover and create reusable personal presenters").addCommand(Mf).addCommand(Bf).addCommand(Ff),Kf=new ce("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("--branding-id <id>","Workspace brand applied to the presenter clip").option("--cast-preset-id <id>","Saved cast preset supplying presenter, backdrop, and voice").option("--captions","Burn provider-generated captions into the clip").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; defaults to the presenter's lowest supported tier").option("--title <title>","Clip title","Presenter clip").option("--strict-branding","Fail when the selected brand cannot be applied completely").option("--idempotency-key <key>","Stable retry key for this presenter clip").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.transparent?"webm":e.outputFormat;!!e.audioUrl==!!e.script&&(a("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(s.INVALID_INPUT)),["1:1","9:16","16:9"].includes(e.aspect)||(a("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(s.INVALID_INPUT)),e.outputFormat!==void 0&&!["mp4","webm"].includes(e.outputFormat)&&(a("Output format must be mp4 or webm"),process.exit(s.INVALID_INPUT)),e.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(e.backgroundColor)&&(a("Background color must be a six-digit hex value"),process.exit(s.INVALID_INPUT)),e.backgroundColor&&e.backgroundImageUrl&&(a("Provide only one presenter background"),process.exit(s.INVALID_INPUT)),e.fit!==void 0&&!["contain","cover"].includes(e.fit)&&(a("Fit must be contain or cover"),process.exit(s.INVALID_INPUT)),e.fit&&!e.backgroundImageUrl&&(a("Fit requires --background-image-url"),process.exit(s.INVALID_INPUT)),e.transparent&&e.outputFormat==="mp4"&&(a("--transparent cannot be combined with --output-format mp4"),process.exit(s.INVALID_INPUT)),t==="webm"&&(e.backgroundColor||e.backgroundImageUrl)&&(a("Transparent WebM output cannot be combined with a background"),process.exit(s.INVALID_INPUT)),e.renderTier!==void 0&&!["basic","standard","premium"].includes(e.renderTier)&&(a("Render tier must be basic, standard, or premium"),process.exit(s.INVALID_INPUT));let n=e.duration?Number.parseInt(e.duration,10):void 0;n!==void 0&&(!Number.isFinite(n)||n<1||n>300)&&(a("Duration must be between 1 and 300 seconds"),process.exit(s.INVALID_INPUT));let r=e.format==="human"?Nf("Generating presenter clip...").start():null;try{let o=e.idempotencyKey??Qn(),i=e.audioUrl?{audioUrl:e.audioUrl}:{script:e.script??"",...e.voiceId?{voiceId:e.voiceId}:{}},c=await ds({...i,aspect:e.aspect,...e.avatarId?{avatarId:e.avatarId}:{},...e.backgroundColor?{backgroundHex:e.backgroundColor}:{},...e.backgroundImageUrl?{backgroundImageUrl:e.backgroundImageUrl}:{},...e.brandingId?{brandingId:e.brandingId}:{},...e.castPresetId?{castPresetId:e.castPresetId}:{},...e.captions?{captions:!0}:{},...n!==void 0?{durationSec:n}:{},...e.fit?{fit:e.fit}:{},...t?{outputFormat:t}:{},...e.renderTier?{renderTier:e.renderTier}:{},...e.strictBranding?{strictBranding:!0}:{},title:e.title},o);if(!e.wait){r?.stop(),Oo(c,e.format);return}let d=await pe(()=>go(c.requestId),Uf,Lf);if(d.status==="failed")throw new Error(d.error||"Presenter generation failed");if(!d.videoUrl)throw new Error("Presenter generation completed without a video URL");r&&(r.text="Downloading presenter clip..."),await oe(d.videoUrl,e.output),r?.stop(),Oo(d,e.format),e.format==="human"&&k(`Saved to: ${e.output}`)}catch(o){r?.stop(),a(o instanceof Error?o.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Wf=new ce("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{Oo(await go(e),t.format)}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Jf=new ce("generate").description("Generate another look for an existing personal presenter").argument("<base-profile-id>","Base personal presenter id (pp_*)").requiredOption("--name <name>","Look name").requiredOption("--description <description>","Short look description").requiredOption("--prompt <prompt>","Exact appearance generation prompt").requiredOption("--look-id <id>","Stable template/look id").option("--reference-image <path-or-url...>","Up to three local images or URLs for location, outfit, or style guidance").option("--idempotency-key <key>","Stable retry key for this look request").action(async(e,t)=>{try{let n=t.idempotencyKey??Qn(),r=await Ud(t.referenceImage,n),o=await m("generatePresenterLook",{baseProfileId:e,description:t.description,id:t.lookId,prompt:t.prompt,...r?{referenceImages:r}:{},title:t.name},n);l(o)}catch(n){a(n instanceof Error?n.message:"Look generation failed"),process.exit(s.GENERAL_ERROR)}}),zf=new ce("status").description("Read presenter look generation status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await I("generatePresenterLook",e);if(t.format==="json")return l(n);if(t.format==="quiet")return console.log(n.status);b(`Run ID: ${e}`),b(`Status: ${n.status}`),n.error?.message&&a(n.error.message)}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Hf=new ce("revise").description("Create a new Look by editing an existing presenter Look").argument("<look-id>","Ready presenter Look id (pp_*)").requiredOption("--instruction <instruction>","What to add, remove, or change").option("--reference-image <path-or-url...>","Up to three local images or URLs for location, outfit, or style guidance").option("--idempotency-key <key>","Stable retry key for this revision").action(async(e,t)=>{try{let n=t.idempotencyKey??Qn(),r=await Ud(t.referenceImage,n),o=await m("revisePresenterLook",{instruction:t.instruction,...r?{referenceImages:r}:{},sourceLookId:e},n);l(o)}catch(n){a(n instanceof Error?n.message:"Look revision failed"),process.exit(s.GENERAL_ERROR)}}),Xf=new ce("revision-status").description("Read presenter Look revision status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await I("revisePresenterLook",e);if(t.format==="json")return l(n);if(t.format==="quiet")return console.log(n.status);b(`Run ID: ${e}`),b(`Status: ${n.status}`),n.error?.message&&a(n.error.message)}catch(n){a(n instanceof Error?n.message:"Revision status failed"),process.exit(s.GENERAL_ERROR)}}),Yf=new ce("look").description("Manage looks under an existing personal presenter").addCommand(Jf).addCommand(Hf).addCommand(Xf).addCommand(zf),Do=new ce("avatar").description("Generate presenter clips and looks; avatar options lists the voices and looks used by presentation video presenter and cast preset").addCommand(Vf).addCommand(Gf).addCommand(Kf).addCommand(Yf).addCommand(Wf);Do.addHelpText("after",`
|
|
62
|
-
${
|
|
63
|
-
${
|
|
64
|
-
$ ${
|
|
65
|
-
|
|
66
|
-
${
|
|
67
|
-
${
|
|
68
|
-
$ ${
|
|
69
|
-
|
|
70
|
-
${
|
|
71
|
-
$ ${
|
|
72
|
-
`);import{randomUUID as Vb}from"crypto";import{readFileSync as Mb}from"fs";import{writeFile as Bb}from"fs/promises";import F from"chalk";import{Command as Pt,InvalidArgumentError as Wc}from"commander";import Fb from"ora";import{createHash as gh}from"crypto";import{Command as cn,InvalidArgumentError as dn}from"commander";import{createHash as rh}from"crypto";import{existsSync as oh,readFileSync as ih}from"fs";import{basename as ah}from"path";import{Command as sh,InvalidArgumentError as an}from"commander";import dh from"ora";import{createHash as Qf}from"crypto";import{Command as Zf,InvalidArgumentError as _d}from"commander";var eh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function th(e){if(!eh.test(e))throw new _d("brand-id expects a UUID from `mf branding list`.");return e}function nh(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new _d("--file-size expects the exact positive whole-number byte size.");return t}async function Lo(e){let{idempotencyKey:t,...n}=e;return m("createBrandAssetUploadUrl",n,t)}function No(e){if(e===void 0)return"";if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(No).join(",")}]`;let t=e;return`{${Object.keys(t).filter(n=>t[n]!==void 0).sort().map(n=>`${JSON.stringify(n)}:${No(t[n])}`).join(",")}}`}function Uo(e){return Qf("sha256").update(`createBrandAssetUploadUrl:${No(e)}`).digest("hex").slice(0,32)}var qd=new Zf("upload-url").description("Mint a short-lived brand-scoped storage POST; this does not upload bytes").argument("<brand-id>","Brand UUID you may manage",th).requiredOption("--file-name <name>","Original filename used in storage content disposition").requiredOption("--file-type <mime>","Exact MIME type that the storage POST will send").requiredOption("--file-size <bytes>","Exact byte size, 1-104857600",nh).option("--idempotency-key <key>","Stable retry key; defaults to a hash of brand and complete file metadata").option("--team-id <id>","Workspace ID; defaults to the selected workspace").addHelpText("after","\nNext: POST every returned field plus the file to uploadUrl, then run `mf branding asset register` with fileUrl, MIME type, and size.\n").action(async(e,t)=>{await h();try{l(await Lo({brandId:e,...t,idempotencyKey:t.idempotencyKey??Uo({brandId:e,fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType})}))}catch(n){a(n instanceof Error?n.message:"Brand asset upload URL creation failed"),process.exit(s.GENERAL_ERROR)}});var ch=["footage","image","before_after","logo","audio"],lh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function mh(e){if(!lh.test(e))throw new an("brand-id expects a UUID from `mf branding list`.");return e}function jd(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new an(`${e} expects a whole number of 0 or more.`);return n}}function uh(e){let t=Number(e);if(!Number.isFinite(t)||t<0)throw new an("--duration-sec expects a number of 0 or more.");return t}function ph(e){let t;try{t=JSON.parse(e)}catch{throw new an("--metadata expects valid JSON.")}if(!t||typeof t!="object"||Array.isArray(t))throw new an("--metadata expects a JSON object.");return t}var Vd=new sh("upload").description("Upload one local file, register it on a brand, and print the asset JSON").argument("<brand-id>","Brand UUID",mh).requiredOption("--file <path>","Local file to upload through Mindframes storage").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",y("--kind",ch)).option("--label <text>","Display label; defaults to the local filename").option("--width <px>","Image or video width in pixels",jd("--width")).option("--height <px>","Image or video height in pixels",jd("--height")).option("--duration-sec <n>","Audio or video duration in seconds",uh).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",y("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',ph).option("--idempotency-key <key>","Retry key; defaults to a hash of file bytes and complete registration input").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h(),oh(t.file)||(a(`File not found: ${t.file}`),process.exit(s.INVALID_INPUT)),t.kind==="before_after"&&(!t.role||!t.setKey)&&(a("--kind before_after requires both --role and --set-key."),process.exit(s.INVALID_INPUT)),t.kind!=="before_after"&&(t.role||t.setKey)&&(a("--role and --set-key are only valid with --kind before_after."),process.exit(s.INVALID_INPUT));let n=rh("sha256").update(ih(t.file)).digest("hex"),r=Ze(t.file),o={brandId:e,contentHash:n,durationSec:t.durationSec,fileName:r.fileName,fileSize:r.fileSize,fileType:r.fileType,height:t.height,kind:t.kind,label:t.label===void 0?r.fileName:t.label.trim(),metadata:t.metadata,role:t.role,setKey:t.setKey,width:t.width},i=t.idempotencyKey??Uo(o),c=dh({text:`Uploading ${ah(t.file)}...`,stream:process.stderr}).start();try{let d=await Lo({brandId:e,...r,idempotencyKey:i,teamId:t.teamId}),u=await et(t.file,d);c.succeed("Uploaded"),l(await m("registerBrandAsset",{brandId:e,durationSec:t.durationSec,height:t.height,kind:t.kind,label:o.label,metadata:t.metadata,mimeType:u.type,role:t.role,s3Key:u.s3Key,setKey:t.setKey,sizeBytes:u.size,teamId:t.teamId,url:u.url,width:t.width},i))}catch(d){c.fail("Asset upload failed"),a(d instanceof Error?d.message:"Asset upload failed"),process.exit(s.GENERAL_ERROR)}});var Md=["footage","image","before_after","logo","audio"],fh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Rt(e){return t=>{if(!fh.test(t))throw new dn(`${e} expects a UUID from \`mf branding list\` or \`mf branding asset list\`.`);return t}}function sn(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t)throw new dn(`${e} expects a whole number from ${t} upward.`);return r}}function hh(e){return t=>{let n=Number(t);if(!Number.isFinite(n)||n<0)throw new dn(`${e} expects a number of 0 or more.`);return n}}function yh(e){let t;try{t=JSON.parse(e)}catch(n){throw new dn(`--metadata expects JSON: ${n instanceof Error?n.message:String(n)}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new dn("--metadata expects a JSON object.");return t}function _o(e){return gh("sha256").update(e).digest("hex").slice(0,32)}function Zn(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}var bh=new cn("list").description("List one brand's uploaded assets and print stable asset IDs").argument("<brand-id>","Brand UUID",Rt("brand-id")).option("--kind <kind>","Filter: footage | image | before_after | logo | audio",y("--kind",Md)).option("--limit <count>","Caller-selected page size; omit to return every matching asset",sn("--limit",1)).option("--offset <count>","Matching assets to skip before returning results (default: 0)",sn("--offset",0)).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandAssets",{brandId:e,...t.kind?{kind:t.kind}:{},...t.limit?{limit:t.limit}:{},...t.offset!==void 0?{offset:t.offset}:{},teamId:t.teamId}))}catch(n){Zn(n,"Asset list failed")}}),wh=new cn("register").description("Register one app-owned upload from its exact URL, key, MIME, and metadata").argument("<brand-id>","Brand UUID",Rt("brand-id")).requiredOption("--url <url>","Final app-owned file URL returned by the upload step").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",y("--kind",Md)).option("--label <text>","Optional display label, up to 160 characters").requiredOption("--mime-type <type>","Exact MIME type returned by the upload step; verified against storage").option("--s3-key <key>","Optional storage key; when set it must match the URL and upload owner").option("--size-bytes <n>","Expected byte size; when set it must match storage",sn("--size-bytes",0)).option("--width <px>","Image or video width in pixels",sn("--width",0)).option("--height <px>","Image or video height in pixels",sn("--height",0)).option("--duration-sec <n>","Audio or video duration in seconds",hh("--duration-sec")).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",y("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',yh).option("--idempotency-key <key>","Retry key; defaults to a hash of the complete registration input").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h(),t.kind==="before_after"&&(!t.role||!t.setKey)&&(a("--kind before_after requires both --role and --set-key."),process.exit(s.INVALID_INPUT)),t.kind!=="before_after"&&(t.role||t.setKey)&&(a("--role and --set-key are only valid with --kind before_after."),process.exit(s.INVALID_INPUT));let n={brandId:e,durationSec:t.durationSec,height:t.height,kind:t.kind,label:t.label,metadata:t.metadata,mimeType:t.mimeType,role:t.role,s3Key:t.s3Key,setKey:t.setKey,sizeBytes:t.sizeBytes,teamId:t.teamId,url:t.url,width:t.width},r=t.idempotencyKey??_o(`registerBrandAsset:${JSON.stringify(n)}`);try{l(await m("registerBrandAsset",n,r))}catch(o){Zn(o,"Asset registration failed")}}),vh=new cn("rename").description("Rename one asset, then print its stored label and metadata").argument("<asset-id>","Asset UUID from `mf branding asset list`",Rt("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Rt("--brand")).requiredOption("--label <text>","New non-empty label, up to 160 characters").option("--idempotency-key <key>","Retry key; defaults to a hash of asset ID and label").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();let n=t.label.trim();n||(a("--label cannot be empty."),process.exit(s.INVALID_INPUT));try{l(await m("renameBrandAsset",{assetId:e,brandId:t.brand,label:n,teamId:t.teamId},t.idempotencyKey??_o(`renameBrandAsset:${e}:${n}`)))}catch(r){Zn(r,"Asset rename failed")}}),Ih=new cn("delete").description("Remove one asset record from the brand while keeping its uploaded file").argument("<asset-id>","Asset UUID from `mf branding asset list`",Rt("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Rt("--brand")).option("--yes","Confirm removal from the brand library without an interactive prompt").option("--idempotency-key <key>","Retry key; defaults to a stable hash of the asset ID").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h(),t.yes||(a("Refusing removal from the brand library without --yes."),process.exit(s.INVALID_INPUT));try{l(await m("deleteBrandAsset",{assetId:e,brandId:t.brand,teamId:t.teamId},t.idempotencyKey??_o(`deleteBrandAsset:${e}`)))}catch(n){Zn(n,"Asset deletion failed")}}),Bd=new cn("asset").description("List, upload, rename, and remove a brand's private asset library").addCommand(bh).addCommand(wh).addCommand(qd).addCommand(Vd).addCommand(vh).addCommand(Ih);import{Command as Fd,InvalidArgumentError as kh}from"commander";var xh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Rh=["presentation","reel","story","video","walkthrough","slide","microsite","article"];function Ch(e){if(!xh.test(e))throw new kh("Expected a brand UUID from `mf branding list`.");return e}var Sh=new Fd("resolve").description("Resolve design tokens, node trace, rules, and conflicts").argument("<brand-id>","Brand UUID",Ch).requiredOption("--artifact <type>","Artifact type",y("--artifact",[...Rh])).option("--channel <name>","Channel condition").option("--audience <name>","Audience condition").option("--product <name>","Product condition").option("--locale <name>","Locale condition").option("--market <name>","Market condition").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();let n={artifactType:t.artifact,brandId:e,teamId:t.teamId};for(let r of["audience","channel","locale","market","product"])t[r]!==void 0&&(n[r]=t[r]);try{l(await m("resolveBrandDesign",n))}catch(r){a(r instanceof Error?r.message:"Brand design resolve failed"),process.exit(s.GENERAL_ERROR)}}),Gd=new Fd("design").description("Inspect resolved brand design state").addCommand(Sh);import{createHash as Eh,randomUUID as Th}from"crypto";import{Command as Ne,InvalidArgumentError as Kd}from"commander";var $h=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ln(e){if(!$h.test(e))throw new Kd("Expected a brand UUID from `mf branding list`.");return e}function Ah(e){if(e==="true")return!0;if(e==="false")return!1;throw new Kd("--show expects true or false.")}function er(e,t){return Eh("sha256").update(JSON.stringify([e,t])).digest("hex").slice(0,32)}function Ct(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}var Ph=new Ne("set").description("Create or update one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",ln).argument("<role>","Custom role without the color. prefix").argument("<hex>","Three- or six-digit hex colour, for example #114b97").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from the complete change when omitted").action(async(e,t,n,r)=>{await h();let o={brandId:e,hex:n,role:t,teamId:r.teamId};try{l(await m("setBrandCustomColor",o,r.idempotencyKey??er("setBrandCustomColor",o)))}catch(i){Ct(i,"Custom colour update failed")}}),Oh=new Ne("delete").description("Remove one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",ln).argument("<role>","Custom role without the color. prefix").option("--yes","Confirm removal without an interactive prompt").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from brand and role when omitted").action(async(e,t,n)=>{await h(),n.yes||(a("Refusing to remove a custom colour without --yes."),process.exit(s.INVALID_INPUT));let r={brandId:e,role:t,teamId:n.teamId};try{l(await m("deleteBrandCustomColor",r,n.idempotencyKey??er("deleteBrandCustomColor",r)))}catch(o){Ct(o,"Custom colour removal failed")}}),Dh=new Ne("sync").description("Synchronize current brand data into the canonical brand graph").argument("<brand-id>","Brand UUID",ln).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; a new one is minted when omitted").action(async(e,t)=>{await h();let n={brandId:e,teamId:t.teamId};try{let r=await m("syncBrandFoundation",n,t.idempotencyKey??er("syncBrandFoundation",[n,Th()]));l(t.wait===!1?r:await Rs(r.runId,t.teamId))}catch(r){Ct(r,"Brand foundation sync failed")}}),Nh=new Ne("sync-status").description("Read a brand foundation sync run").argument("<run-id>","Run ID from `branding foundation sync --no-wait`").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await I("syncBrandFoundation",e,t.teamId))}catch(n){Ct(n,"Brand foundation sync status failed")}}),Wd=new Ne("foundation").description("Manage atomic Foundation settings backed by the brand DAG").addCommand(new Ne("color").description("Manage custom colour roles").addCommand(Ph).addCommand(Oh)).addCommand(Dh).addCommand(Nh),Lh=new Ne("get").description("Read the complete current footer and its source").argument("<brand-id>","Brand UUID",ln).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("getBrandFooter",{brandId:e,teamId:t.teamId}))}catch(n){Ct(n,"Footer read failed")}}),Uh=new Ne("set").description("Patch footer text, visibility, or alignment atomically").argument("<brand-id>","Brand UUID",ln).option("--text <text>","Complete footer text; pass an empty string to clear it").option("--show <boolean>","Whether artifacts show the footer: true | false",Ah).option("--alignment <value>","Footer alignment: left | center | right",y("--alignment",["left","center","right"])).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from the complete patch when omitted").action(async(e,t)=>{await h(),t.alignment===void 0&&t.show===void 0&&t.text===void 0&&(a("Pass at least one of --text, --show, or --alignment."),process.exit(s.INVALID_INPUT));let n={alignment:t.alignment,brandId:e,show:t.show,teamId:t.teamId,text:t.text};try{l(await m("setBrandFooter",n,t.idempotencyKey??er("setBrandFooter",n)))}catch(r){Ct(r,"Footer update failed")}}),Jd=new Ne("footer").description("Read or update the brand footer").addCommand(Lh).addCommand(Uh);import{createHash as _h}from"crypto";import{Command as zd}from"commander";var qh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function jh(e){qh.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Vh(e){return _h("sha256").update(e).digest("hex").slice(0,32)}function Hd(e,t){try{return JSON.parse(t)}catch(n){a(`${e} is not valid JSON: ${n instanceof Error?n.message:String(n)}`),process.exit(s.INVALID_INPUT)}}function Mh(e,t){let n=Hd(e,t);return Array.isArray(n)||(a(`${e} must be a JSON array of gradients, e.g. '[{"id":"dawn","type":"linear","stops":[{"color":"#155DAC","position":0},{"color":"#0B2C52","position":100}]}]'.`),process.exit(s.INVALID_INPUT)),n}function Bh(e,t){let n=Hd(e,t);return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${e} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}var Fh=new zd("set").description("Replace a brand's gradient library (whole-set: omitted gradients are deleted)").argument("<brand-id>","Brand profile ID").requiredOption("--gradients <json>",`The complete gradient list as JSON, e.g. '[{"id":"dawn","name":"Dawn","type":"linear","angle":135,"stops":[{"color":"#155DAC","position":0},{"color":"#0B2C52","position":100}]}]'. Gradients you omit are DELETED.`).option("--roles <json>",`Role pointers by gradient id, e.g. '{"primary":"dawn"}'. Omit to leave the brand's current roles alone.`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),jh(e);let n={brandId:e,gradients:Mh("--gradients",t.gradients),teamId:t.teamId};t.roles!==void 0&&(n.gradientRoles=Bh("--roles",t.roles));try{l(await m("setBrandGradients",n,Vh(`setBrandGradients:${e}:${JSON.stringify(n)}`)))}catch(r){a(r instanceof Error?r.message:"Set failed"),process.exit(s.GENERAL_ERROR)}}),Xd=new zd("gradient").description("Brand gradient library commands").addCommand(Fh);import{createHash as Gh}from"crypto";import{Command as it}from"commander";var Kh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function mn(e){Kh.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Wh(e,t=[]){return[...t,e]}function jo(e){return Gh("sha256").update(e).digest("hex").slice(0,32)}function qo(e,t){if(t==="true")return!0;if(t==="false")return!1;a(`${e} must be true or false; got "${t}".`),process.exit(s.INVALID_INPUT)}function Yd(e,t){try{return JSON.parse(t)}catch{a(`${e} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}var Jh=new it("get").description("Read a brand's guardrail rules").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),mn(e);try{l(await m("getBrandGuardrails",{brandId:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Read failed"),process.exit(s.GENERAL_ERROR)}}),zh=new it("test").description("Check content against a brand's guardrail rules").argument("<brand-id>","Brand profile ID").option("--content <text>","The content to check").option("--channel <channel>","Channel the content is for, e.g. deck-16-9").option("--market <market>","Market the content is for, e.g. US").option("--artifact-type <type>","Artifact type, e.g. presentation").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),mn(e),t.content===void 0&&(a("Pass --content with the text to check."),process.exit(s.INVALID_INPUT));let n={brandId:e,content:t.content,teamId:t.teamId};t.channel!==void 0&&(n.channel=t.channel),t.market!==void 0&&(n.market=t.market),t.artifactType!==void 0&&(n.artifactType=t.artifactType);try{let r=await m("testBrandGuardrails",n);l(r),r.passed===!1&&process.exit(s.GENERAL_ERROR)}catch(r){a(r instanceof Error?r.message:"Test failed"),process.exit(s.GENERAL_ERROR)}}),Hh=new it("set").description("Create or update one of a brand's guardrail rules").argument("<brand-id>","Brand profile ID").option("--name <text>","Human-readable name for the rule").option("--category <category>","language | compliance | channel-requirements | accessibility | asset-usage").option("--severity <severity>","shadow | warn | block").option("--require <json>",`What the rule demands, as JSON, e.g. '{"component":"banned-phrase","text":"cheap"}'`).option("--conditions <json>",`When the rule applies, as JSON, e.g. '{"op":"AND","clauses":[{"field":"channel","op":"is","values":["deck-16-9"]}]}'`).option("--enabled <bool>","true or false; defaults to true").option("--node-key <key>","Key of an existing rule to UPDATE, as `guardrails get` lists it. Omit to create.").option("--notes <text>","Notes about the rule").option("--slug <slug>","Explicit kebab-case slug for a new rule").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),mn(e),(!t.name||!t.category||!t.severity)&&(a("Pass --name, --category and --severity."),process.exit(s.INVALID_INPUT)),t.require===void 0&&(a(`Pass --require, e.g. '{"component":"banned-phrase"}'.`),process.exit(s.INVALID_INPUT));let n={brandId:e,category:t.category,name:t.name,require:Yd("--require",t.require),severity:t.severity,teamId:t.teamId};t.conditions!==void 0&&(n.conditions=Yd("--conditions",t.conditions)),t.enabled!==void 0&&(n.enabled=qo("--enabled",t.enabled)),t.nodeKey!==void 0&&(n.nodeKey=t.nodeKey),t.notes!==void 0&&(n.notes=t.notes),t.slug!==void 0&&(n.slug=t.slug),t.publish!==void 0&&(n.publish=qo("--publish",t.publish));try{l(await m("setBrandGuardrail",n,jo(`setBrandGuardrail:${e}:${JSON.stringify(n)}`)))}catch(r){a(r instanceof Error?r.message:"Write failed"),process.exit(s.GENERAL_ERROR)}}),Xh=new it("delete").description("Remove one of a brand's guardrail rules").argument("<brand-id>","Brand profile ID").argument("<node-key>","Key of the rule, as `guardrails get` lists it").option("--publish <bool>","Publish a brand snapshot after the removal; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await h(),mn(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.publish!==void 0&&(r.publish=qo("--publish",n.publish));try{l(await m("deleteBrandGuardrail",r,jo(`deleteBrandGuardrail:${e}:${t}`)))}catch(o){a(o instanceof Error?o.message:"Delete failed"),process.exit(s.GENERAL_ERROR)}}),Yh=new it("generate").description("Draft guardrail rule proposals for a brand").argument("<brand-id>","Brand profile ID").option("--brand-name <name>","Brand name to draft rules for").option("--channel <channel>","Channel the brand publishes to; repeat for several. At least one is required.",Wh).option("--brand-description <text>","What the brand does").option("--brand-voice <text>","How the brand sounds").option("--industry <text>","Industry the brand operates in").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),mn(e),t.brandName||(a("Pass --brand-name."),process.exit(s.INVALID_INPUT)),t.channel?.length||(a("Pass at least one --channel to scope the proposed rules."),process.exit(s.INVALID_INPUT));let n={activeChannels:t.channel,brandId:e,brandName:t.brandName,teamId:t.teamId};t.brandDescription!==void 0&&(n.brandDescription=t.brandDescription),t.brandVoice!==void 0&&(n.brandVoice=t.brandVoice),t.industry!==void 0&&(n.industry=t.industry);try{let r=await m("generateBrandGuardrails",n,jo(`generateBrandGuardrails:${JSON.stringify(n)}`));if(t.wait===!1){l(r);return}l(await Is(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Generate failed"),process.exit(s.GENERAL_ERROR)}}),Qh=new it("generate-status").description("Read a brand guardrails generation run").argument("<run-id>","Run ID from `branding guardrails generate --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("generateBrandGuardrails",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Qd=new it("guardrails").description("Brand guardrail rule commands").addCommand(Jh).addCommand(zh).addCommand(Hh).addCommand(Xh).addCommand(Yh).addCommand(Qh);import{randomUUID as Zh}from"crypto";import{readFile as Zd}from"fs/promises";import{Command as ey}from"commander";var ec=new ey("import").description("Import a workspace brand from a DESIGN.md file").argument("<design-md-file>","Path to the DESIGN.md file").option("--name <name>","Override the brand name in the document").option("--url <url>","Associate a source URL with the imported brand").option("--url-evidence <json-file>","Merge a saved raw URL-extraction JSON response").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key for retrying the same import without creating another brand").action(async(e,t)=>{await h();try{let n=await Zd(e,"utf8"),r=t.urlEvidence?JSON.parse(await Zd(t.urlEvidence,"utf8")):void 0,o=t.idempotencyKey??Zh();l(await m("importBrandDesignMd",{designMd:n,name:t.name,teamId:t.teamId,url:t.url,urlExtractedRaw:r},o))}catch(n){a(n instanceof Error?n.message:"Import failed"),process.exit(s.GENERAL_ERROR)}});import{Command as tc,InvalidArgumentError as nc}from"commander";var ty=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ny(e){if(!ty.test(e))throw new nc("Expected a brand UUID from `mf branding list`.");return e}function ry(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>50)throw new nc("--limit expects a whole number from 1 to 50.");return t}var oy=new tc("list").description("List recent safe job summaries for one brand").argument("<brand-id>","Brand UUID",ny).option("--limit <count>","Newest jobs to return, 1-50 (default: 20)",ry).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandJobs",{brandId:e,limit:t.limit,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Brand job history failed"),process.exit(s.GENERAL_ERROR)}}),rc=new tc("jobs").description("Inspect brand background activity").addCommand(oy);import{createHash as iy}from"crypto";import{Command as je}from"commander";var ay=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ve(e){ay.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function St(e){return iy("sha256").update(e).digest("hex").slice(0,32)}var oc=new je("create").description("Create an empty workspace brand and print its JSON").argument("<name>","Name for the new brand").option("--parent <brand-id>","File the new brand under this parent").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),t.parent&&Ve(t.parent);try{l(await m("createBrand",{name:e,parentBrandingId:t.parent,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Create failed"),process.exit(s.GENERAL_ERROR)}}),ic=new je("star").description("Add a library star, or remove it with --off, and print the result").argument("<brand-id>","Brand profile ID").option("--off","Remove the star instead of adding it").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ve(e);let n=!t.off;try{l(await m("setBrandStar",{brandId:e,starred:n,teamId:t.teamId},St(`setBrandStar:${e}:${n}`)))}catch(r){a(r instanceof Error?r.message:"Star failed"),process.exit(s.GENERAL_ERROR)}});async function sy(e,t){let n=await m("getBrandProfile",{brandId:e,teamId:t.teamId});return typeof n.name=="string"?n.name:e}var ac=new je("delete").description("Soft-delete a brand after confirmation and print the result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").option("--yes","Confirm soft deletion without an interactive prompt").action(async(e,t)=>{if(await h(),Ve(e),!t.yes&&process.stdin.isTTY){let n;try{n=await sy(e,t)}catch(r){a(r instanceof Error?r.message:"Could not read the brand"),process.exit(s.GENERAL_ERROR)}a(`Refusing to delete "${n}" (${e}) without confirmation. Re-run with --yes to remove this brand from the library.`),process.exit(s.GENERAL_ERROR)}try{l(await m("deleteBrand",{brandId:e,teamId:t.teamId},St(`deleteBrand:${e}`)))}catch(n){a(n instanceof Error?n.message:"Delete failed"),process.exit(s.GENERAL_ERROR)}}),Vo="none",sc=new je("update").description("Rename with --name or move with --parent; print the updated JSON").argument("<brand-id>","Brand profile ID").option("--name <name>","New name for the brand").option("--parent <brand-id>",`File the brand under this parent, or "${Vo}" to detach it`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ve(e);let n=t.parent?.toLowerCase()===Vo;t.parent!==void 0&&!n&&Ve(t.parent),t.name===void 0&&t.parent===void 0&&(a(`Nothing to update. Pass --name to rename this brand, or --parent <brand-id> to move it (--parent ${Vo} detaches it).`),process.exit(s.INVALID_INPUT));let r={brandId:e,teamId:t.teamId};t.name!==void 0&&(r.name=t.name),t.parent!==void 0&&(r.parentBrandingId=n?null:t.parent);try{l(await m("updateBrand",r,St(`updateBrand:${e}:${t.name??""}:${t.parent??""}`)))}catch(o){a(o instanceof Error?o.message:"Update failed"),process.exit(s.GENERAL_ERROR)}}),dc=new je("set-default").description("Use this brand by default for new artifacts and print the result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ve(e);try{l(await m("setDefaultBrand",{brandId:e,teamId:t.teamId},St(`setDefaultBrand:${e}`)))}catch(n){a(n instanceof Error?n.message:"Set default failed"),process.exit(s.GENERAL_ERROR)}}),cc=new je("approve").description("Approve a reviewed brand for use and print the persisted result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ve(e);try{let n=await W(t.teamId);l(await m("approveBrand",{brandId:e,teamId:n},St(`approveBrand:${n}:${e}`)))}catch(n){a(n instanceof Error?n.message:"Approve failed"),process.exit(s.GENERAL_ERROR)}}),lc=new je("onboarding").description("Manage the brand onboarding review state").addCommand(new je("complete").description("Mark onboarding review complete without approving the brand").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ve(e);try{let n=await W(t.teamId);l(await m("completeBrandOnboarding",{brandId:e,teamId:n},St(`completeBrandOnboarding:${n}:${e}`)))}catch(n){a(n instanceof Error?n.message:"Complete onboarding failed"),process.exit(s.GENERAL_ERROR)}}));import{createHash as Mo}from"crypto";import{existsSync as dy,readFileSync as cy}from"fs";import{basename as ly}from"path";import{Command as tr}from"commander";import my from"ora";function uy(e,t,n){return Mo("sha256").update(JSON.stringify([e,t,n??null])).digest("hex").slice(0,32)}var mc=new tr("logo").description("Upload primary, dark-background, and favicon logo files").addCommand(new tr("list").description("List exact logo candidates and identify the active one").argument("<brand-id>","Brand UUID from `mf branding list`").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandLogos",{brandId:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Logo list failed"),process.exit(s.GENERAL_ERROR)}})).addCommand(new tr("remove").description("Remove one exact candidate URL and select its deterministic fallback").argument("<brand-id>","Brand UUID from `mf branding list`").argument("<logo-url>","Exact URL returned by `mf branding logo list`").option("--yes","Confirm exact candidate removal without an interactive prompt").option("--idempotency-key <key>","Stable retry key; derived from brand and URL when omitted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t,n)=>{await h(),n.yes||(a("Refusing to remove a logo candidate without --yes."),process.exit(s.INVALID_INPUT));try{l(await m("removeBrandLogo",{brandId:e,logoUrl:t,teamId:n.teamId},n.idempotencyKey??uy("removeBrandLogo",e,t)))}catch(r){a(r instanceof Error?r.message:"Logo removal failed"),process.exit(s.GENERAL_ERROR)}})).addCommand(new tr("set").description("Upload one logo variant and print the updated brand JSON").argument("[brand-id]","Brand ID (defaults to this workspace's default brand)").requiredOption("--file <path>","Local image file to upload and use").option("--variant <variant>","primary | dark | favicon. 'dark' is the reversed lock-up for dark backgrounds","primary").option("--idempotency-key <key>","Stable retry key; deterministically derived from workspace, brand, variant, and file bytes when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();let n=t.variant??"primary";["primary","dark","favicon"].includes(n)||(a(`--variant must be primary, dark, or favicon (got "${n}")`),process.exit(s.INVALID_INPUT)),dy(t.file)||(a(`File not found: ${t.file}`),process.exit(s.INVALID_INPUT));let r=Mo("sha256").update(cy(t.file)).digest("hex"),o=t.idempotencyKey??Mo("sha256").update(`setBrandLogo:${t.teamId??"current"}:${e??"default"}:${n}:${r}`).digest("hex").slice(0,32),i=my({text:`Uploading ${ly(t.file)}...`,stream:process.stderr}).start(),c;try{c=(await Q(t.file,{idempotencyKey:`${o}:upload`,storagePrefix:"brand-logos"})).url,i.succeed("Uploaded")}catch(d){i.fail("Upload failed"),a(d instanceof Error?d.message:String(d)),process.exit(s.GENERAL_ERROR)}try{l(await m("setBrandLogo",{brandId:e,fileUrl:c,teamId:t.teamId,variant:n},o))}catch(d){a(d instanceof Error?d.message:"Write failed"),process.exit(s.GENERAL_ERROR)}}));import{createHash as py,randomUUID as gy}from"crypto";import{Command as Et,InvalidArgumentError as nr}from"commander";var fy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,hy=["admin","editor","viewer"],uc=["cancelled","completed","failed","info","queued","running"],pc=["activity","brand-extraction-request","brand-resolution","brand-sync-job"];function at(e){return t=>{if(!fy.test(t))throw new nr(`${e} expects a UUID from \`mf branding list\` or the workspace member list.`);return t}}function fc(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>200)throw new nr("--limit expects a whole number from 1 to 200.");return t}function gc(e,t){return n=>{let r=n.split(",").map(i=>i.trim()).filter(Boolean);if(r.find(i=>!t.includes(i))||r.length===0)throw new nr(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function hc(e,t){return py("sha256").update(JSON.stringify([e,t,gy()])).digest("hex").slice(0,32)}function un(e,t){a(e instanceof Error?e.message:t),process.exit(typeof e=="object"&&e!==null&&"exitCode"in e&&typeof e.exitCode=="number"?e.exitCode:s.GENERAL_ERROR)}var yy=new Et("list").description("List explicit member access overrides for one team brand").argument("<brand-id>","Team brand UUID",at("brand-id")).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandPermissions",{brandId:e,teamId:t.teamId}))}catch(n){un(n,"Brand permission list failed")}}),by=new Et("candidates").description("List member IDs eligible for one team brand's access overrides").argument("<brand-id>","Team brand UUID",at("brand-id")).option("--query <text>","Search member name, username, or email").option("--limit <count>","Maximum members, 1-200 (default: 50)",fc).option("--offset <count>","Members to skip (default: 0)",e=>{let t=Number(e);if(!Number.isInteger(t)||t<0)throw new nr("--offset expects a whole number of 0 or more.");return t}).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandPermissionCandidates",{brandId:e,limit:t.limit,offset:t.offset,query:t.query,teamId:t.teamId}))}catch(n){un(n,"Brand permission candidate list failed")}}),wy=new Et("set").description("Set one team member's explicit role for a team brand").argument("<brand-id>","Team brand UUID",at("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",at("--user")).requiredOption("--role <role>","Desired override: admin | editor | viewer",y("--role",hy)).option("--idempotency-key <key>","Explicit retry identity; otherwise a new payload-bound key is minted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId,userId:t.user},t.idempotencyKey??hc("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId??null,userId:t.user})))}catch(n){un(n,"Brand permission update failed")}}),vy=new Et("remove").description("Remove one member override so the team role applies again").argument("<brand-id>","Team brand UUID",at("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",at("--user")).option("--yes","Confirm this access change without an interactive prompt").option("--idempotency-key <key>","Explicit retry identity; otherwise a new payload-bound key is minted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h(),t.yes||(a("Refusing to remove a brand access override without --yes."),process.exit(s.INVALID_INPUT));try{l(await m("removeBrandPermission",{brandId:e,teamId:t.teamId,userId:t.user},t.idempotencyKey??hc("removeBrandPermission",{brandId:e,teamId:t.teamId??null,userId:t.user})))}catch(n){un(n,"Brand permission removal failed")}}),yc=new Et("permission").description("Administer explicit member access overrides for a team brand").addCommand(by).addCommand(yy).addCommand(wy).addCommand(vy),bc=new Et("activity").description("Read a brand's filtered, cursor-paginated activity feed").argument("<brand-id>","Brand UUID",at("brand-id")).option("--query <text>","Search action, summary, detail, entity, and metadata").option("--status <statuses>",`Comma-separated statuses: ${uc.join(" | ")}`,gc("--status",uc)).option("--source-type <types>",`Comma-separated sources: ${pc.join(" | ")}`,gc("--source-type",pc)).option("--from <iso-time>","Inclusive ISO-8601 lower time bound").option("--to <iso-time>","Inclusive ISO-8601 upper time bound").option("--limit <count>","Maximum rows, 1-200 (default: 80)",fc).option("--cursor <cursor>","Opaque nextCursor from the preceding page").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await h();try{l(await m("listBrandActivity",{brandId:e,cursor:t.cursor,from:t.from,limit:t.limit,query:t.query,sourceTypes:t.sourceType,statuses:t.status,teamId:t.teamId,to:t.to}))}catch(n){un(n,"Brand activity read failed")}});import{createHash as Iy}from"crypto";import{Command as Tt,InvalidArgumentError as Fo}from"commander";var ky=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Bo(e,t){if(ky.test(e))return e;throw new Fo(`${t} must be a UUID.`)}function xy(e){let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=50)return t;throw new Fo("limit must be a whole number from 1 to 50.")}function Ry(e){let t=Number(e);if(Number.isInteger(t)&&t>=0)return t;throw new Fo("offset must be a whole number of 0 or more.")}function Cy(e){return Iy("sha256").update(e).digest("hex").slice(0,32)}async function rr(e,t){await h();try{l(await e())}catch(n){a(n instanceof Error?n.message:t),process.exit(s.GENERAL_ERROR)}}var wc=new Tt("presentations").description("Inspect presentations already linked to a brand").addCommand(new Tt("list").description("List linked decks with preview, version, stale, and last-sync state").argument("<brand-id>","Brand UUID from `branding list`").option("--limit <n>","Rows to return (1-50; default 50)",xy,50).option("--offset <n>","Zero-based offset (default 0)",Ry,0).option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{let n=Bo(e,"brand-id");await rr(()=>m("listBrandPresentations",{brandId:n,limit:t.limit,offset:t.offset,teamId:t.teamId}),"Could not list linked presentations")})),vc=new Tt("presentation").description("Inspect or update one deck from its already-linked brand").addCommand(new Tt("drift").description("Read current, drifted, unknown, or not-linked status and exact changes").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{await rr(()=>m("getPresentationBrandDrift",{presentationId:e,teamId:t.teamId}),"Could not read presentation brand drift")})).addCommand(new Tt("apply-changes").description("Create a new deck version using its linked brand's current colors, fonts, and logo").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").requiredOption("--idempotency-key <key>","Stable key; reuse it for an exact retry, change it for a later brand update").action(async(e,t)=>{await rr(()=>m("applyPresentationBrandChanges",{presentationId:e,teamId:t.teamId},t.idempotencyKey),"Could not apply linked-brand changes")})),Ic=new Tt("sync-cancel").description("Cancel an active bulk linked-deck sync through its durable run; retries are safe").argument("<brand-id>","Brand UUID used to start the sync").argument("<run-id>","Active run UUID from `branding sync --no-wait`").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t,n)=>{let r=Bo(e,"brand-id"),o=Bo(t,"run-id");await rr(()=>m("cancelBrandPresentationSync",{brandId:r,runId:o,teamId:n.teamId},Cy(`cancelBrandPresentationSync:${r}:${o}`)),"Could not cancel brand sync")});import{createHash as Sy,randomUUID as Cc}from"crypto";import{Command as Me}from"commander";var Ey=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,kc=["product","service","platform","solution"],or=["candidate","draft","approved"],xc=["brand-site","brand-site-scan","brand-site-extract","product-url"];function $t(e){Ey.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ir(e,t,n){if(n.includes(t))return t;a(`${e} must be one of: ${n.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Ty(e,t){let n=Number(t);if(Number.isInteger(n)&&n>0)return n;a(`${e} must be a whole number greater than zero.`),process.exit(s.INVALID_INPUT)}function Go(e){return Sy("sha256").update(e).digest("hex").slice(0,32)}var $y=new Me("list").description("List the products a brand sells").argument("<brand-id>","Brand profile ID").option("--status <status>",`Only products in this state. One of: ${or.join(", ")}. Omit for the saved catalogue.`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),$t(e),t.status!==void 0&&ir("--status",t.status,or);let n={brandId:e,teamId:t.teamId};t.status!==void 0&&(n.status=t.status);try{l(await m("listBrandProducts",n))}catch(r){a(r instanceof Error?r.message:"List failed"),process.exit(s.GENERAL_ERROR)}}),Ay=new Me("set").description("Create or update one of a brand's products").argument("<brand-id>","Brand profile ID").option("--product <id>","Existing product to update. Omit to create, or to update the product this brand already has at the same --url.").option("--name <name>","Product name (required when creating)").option("--type <type>",`One of: ${kc.join(", ")}`).option("--description <text>","What the product is, in full").option("--summary <text>","Short form of the description").option("--url <url>","The product's page. Also its identity: a url this brand already has updates that product.").option("--status <status>",`One of: ${or.join(", ")}`).option("--logo-url <url>","Product logo URL").option("--inherits-brand <true|false>","Whether the product presents in the parent brand's design").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),$t(e),t.type!==void 0&&ir("--type",t.type,kc),t.status!==void 0&&ir("--status",t.status,or),t.inheritsBrand!==void 0&&t.inheritsBrand!=="true"&&t.inheritsBrand!=="false"&&(a("--inherits-brand must be true or false."),process.exit(s.INVALID_INPUT));let n={brandId:e,teamId:t.teamId};t.product!==void 0&&(n.productId=t.product),t.name!==void 0&&(n.name=t.name),t.type!==void 0&&(n.type=t.type),t.description!==void 0&&(n.description=t.description),t.summary!==void 0&&(n.summary=t.summary),t.url!==void 0&&(n.url=t.url),t.status!==void 0&&(n.status=t.status),t.logoUrl!==void 0&&(n.logoUrl=t.logoUrl),t.inheritsBrand!==void 0&&(n.inheritsBrand=t.inheritsBrand==="true");try{l(await m("saveBrandProduct",n,Go(`saveBrandProduct:${e}:${t.product??t.url??t.name??"new"}`)))}catch(r){a(r instanceof Error?r.message:"Save failed"),process.exit(s.GENERAL_ERROR)}}),Rc=(e,t=[])=>[...t,e],Py=new Me("select").description("Atomically set approved products in a bounded product set").argument("<brand-id>","Brand profile ID").option("--product <id>","Product whose state to set; repeat for every product in the bounded set.",Rc).option("--approve <id>","Product from --product that should finish approved; repeat as needed. Others finish draft.",Rc).option("--idempotency-key <key>","Stable retry key for this selection").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),$t(e),t.product?.length||(a("Pass at least one --product <id> to set product approval."),process.exit(s.INVALID_INPUT));let n={approvedProductIds:t.approve??[],brandId:e,productIds:t.product,teamId:t.teamId};try{l(await m("setBrandProductSelection",n,t.idempotencyKey??Cc()))}catch(r){a(r instanceof Error?r.message:"Selection failed"),process.exit(s.GENERAL_ERROR)}}),Oy=new Me("duplicate").description("Create an independent draft copy of one product").argument("<brand-id>","Brand profile ID").requiredOption("--product <id>","Product ID to duplicate").option("--name <name>","Name for the copy").option("--idempotency-key <key>","Stable retry key for this duplication").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),$t(e);let n={brandId:e,productId:t.product,teamId:t.teamId};t.name!==void 0&&(n.name=t.name);try{l(await m("duplicateBrandProduct",n,t.idempotencyKey??Cc()))}catch(r){a(r instanceof Error?r.message:"Duplicate failed"),process.exit(s.GENERAL_ERROR)}}),Dy=new Me("delete").description("Remove one product from a brand").argument("<brand-id>","Brand profile ID").option("--product <id>","Product ID to remove").option("--team-id <id>","Workspace ID").option("--yes","Skip the confirmation prompt").action(async(e,t)=>{await h(),$t(e),t.product===void 0&&(a("Pass --product <id> to name the product to remove. `branding product list <brand-id>` prints the ids."),process.exit(s.INVALID_INPUT)),!t.yes&&process.stdin.isTTY&&(a(`Refusing to delete product "${t.product}" without confirmation. Re-run with --yes.`),process.exit(s.GENERAL_ERROR));try{l(await m("deleteBrandProduct",{brandId:e,productId:t.product,teamId:t.teamId},Go(`deleteBrandProduct:${e}:${t.product}`)))}catch(n){a(n instanceof Error?n.message:"Delete failed"),process.exit(s.GENERAL_ERROR)}}),Ny=new Me("extract").description("Discover a brand's products by crawling its site").argument("<brand-id>","Brand profile ID").option("--mode <mode>",`One of: ${xc.join(", ")}`).option("--url <url>","Page to extract (product-url), or the site to scan instead of the brand's own recorded URL").option("--max-products <count>","How many pages to take from the scan (max 30)").option("--product <id>","Candidate product to extract; repeat for several. Required for brand-site-extract.",(e,t=[])=>[...t,e]).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),$t(e),t.mode!==void 0&&ir("--mode",t.mode,xc);let n={brandId:e,teamId:t.teamId};t.mode!==void 0&&(n.mode=t.mode),t.url!==void 0&&(n.url=t.url),t.maxProducts!==void 0&&(n.maxProducts=Ty("--max-products",t.maxProducts)),t.product?.length&&(n.productIds=t.product);try{let r=await m("extractBrandProducts",n,Go(`extractBrandProducts:${JSON.stringify(n)}`));if(t.wait===!1){l(r);return}l(await ws(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Extract failed"),process.exit(s.GENERAL_ERROR)}}),Ly=new Me("extract-status").description("Read a brand product extraction run").argument("<run-id>","Run ID from `branding product extract --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("extractBrandProducts",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Sc=new Me("product").description("Brand product catalogue commands").addCommand($y).addCommand(Ay).addCommand(Py).addCommand(Oy).addCommand(Dy).addCommand(Ny).addCommand(Ly);import{createHash as Uy}from"crypto";import{Command as ar}from"commander";var _y=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ec(e){_y.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function qy(e,t=[]){return[...t,e]}function jy(e){return Uy("sha256").update(e).digest("hex").slice(0,32)}var Vy=new ar("get").description("Read which decks have drifted from a brand").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ec(e);try{l(await m("getBrandQuality",{brandId:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Read failed"),process.exit(s.GENERAL_ERROR)}}),My=new ar("repair").description("Repair decks that have visually drifted from a brand").argument("<brand-id>","Brand profile ID").option("--scope <scope>","selected (repair only --deck ids) or all_eligible (repair every drifted deck). Required.").option("--deck <presentation-id>","Deck to repair; repeat for several. Only used with --scope selected.",qy).option("--confirm-partial","Also repair decks whose guidance changed too; they stay flagged as guidance-outdated afterwards.").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ec(e),t.scope!=="selected"&&t.scope!=="all_eligible"&&(a("Pass --scope selected or --scope all_eligible. There is no default: 'selected' repairs only the decks you name, 'all_eligible' repairs every drifted deck on the brand."),process.exit(s.INVALID_INPUT)),t.scope==="selected"&&!t.deck?.length&&(a("--scope selected needs at least one --deck."),process.exit(s.INVALID_INPUT));let n={brandId:e,scope:t.scope,teamId:t.teamId};t.deck?.length&&(n.presentationIds=t.deck),t.confirmPartial===!0&&(n.confirmedPartialRepair=!0);try{let r=await m("repairBrandQuality",n,jy(`repairBrandQuality:${JSON.stringify(n)}`));if(t.wait===!1){l(r);return}l(await ks(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Repair failed"),process.exit(s.GENERAL_ERROR)}}),By=new ar("repair-status").description("Read a brand quality repair run").argument("<run-id>","Run ID from `branding quality repair --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("repairBrandQuality",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Tc=new ar("quality").description("Brand deck quality commands").addCommand(Vy).addCommand(My).addCommand(By);function Ko(e){return Array.isArray(e.items)}function Le(e){return typeof e=="string"&&e.length>0?e:void 0}function Wo(e){return Le(e.resolvedTokens?.logoUrl)??Le(e.brandData?.assets?.logo)??Le(e.brandData?.assets?.logoUrl)??Le(e.brandData?.logoUrl)}function Jo(e){return Le(e.resolvedTokens?.colors?.primary)??Le(e.brandData?.colors?.primary)??Le(e.brandData?.enhancedColors?.palette?.[0]?.hex)}function $c(e){let t=e.brandData?.enhancedColors?.palette??e.brandData?.colors?.palette;if(!Array.isArray(t))return[];let n=[];for(let r of t){if(typeof r=="string"){n.push({hex:r});continue}if(r&&typeof r=="object"&&"hex"in r){let{hex:o,role:i}=r;typeof o=="string"&&n.push({hex:o,...typeof i=="string"?{role:i}:{}})}}return n}function Fy(e){return{id:e.id,isDefault:e.isDefault,name:e.name,...e.domain?{sourceUrl:e.domain}:{},...e.logoUrl?{logoUrl:e.logoUrl}:{},...e.primaryColor?{primaryColor:e.primaryColor}:{}}}function Gy(e){let t=Le(e.extractedFrom)??Le(e.normalizedUrl),n=Wo(e),r=Jo(e);return{id:e.id,isDefault:e.isDefault,name:e.name,...t?{sourceUrl:t}:{},...n?{logoUrl:n}:{},...r?{primaryColor:r}:{},...e.createdAt?{createdAt:e.createdAt}:{}}}function Ac(e){return Ko(e)?e.items.map(Gy):e.brandings.map(Fy)}import{createHash as Ky}from"crypto";import{Command as Fe,InvalidArgumentError as Wy}from"commander";var Jy=["x","instagram","facebook","linkedin","tiktok","youtube"],zy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Be(e){if(!zy.test(e))throw new Wy("Expected a UUID returned by the corresponding list command.");return e}function sr(e,t){return Ky("sha256").update(JSON.stringify([e,...t])).digest("hex")}function At(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}var Hy=new Fe("list").description("List one brand's competitors with stable IDs, websites, X accounts, and avatars").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await h();try{l(await m("getBrandCompetitors",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){At(t,"Competitor list failed")}}),Xy=new Fe("add").description("Add or update one competitor by name and print its stable saved row").argument("<name>","Competitor company or product name").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--website <url>","Competitor website as a full URL").option("--x-handle <handle>","Competitor X handle, with or without @").option("--x-avatar-url <url>","Avatar URL for the selected X account").option("--no-resolve-handle","Do not search X when --x-handle is omitted").action(async(e,t)=>{await h();let n={brandingId:t.brandingId,name:e,resolveHandle:t.resolveHandle,teamId:t.teamId,website:t.website,xAvatarUrl:t.xAvatarUrl,xHandle:t.xHandle};try{l(await m("addCompetitor",n,sr("addCompetitor",[t.brandingId??"default",e.trim(),t.website??null,t.xHandle??null,t.xAvatarUrl??null,t.resolveHandle])))}catch(r){At(r,"Competitor write failed")}}),Yy=new Fe("delete").description("Remove one competitor by the stable ID from competitor list").argument("<competitor-id>","Competitor UUID",Be).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await h(),t.yes||(a("Refusing to remove a competitor without --yes."),process.exit(s.INVALID_INPUT));try{l(await m("deleteBrandCompetitor",{brandingId:t.brandingId,competitorId:e,teamId:t.teamId},sr("deleteBrandCompetitor",[t.brandingId??"default",e])))}catch(n){At(n,"Competitor removal failed")}}),Pc=new Fe("competitor").description("List, add, update, or remove a brand's competitor watch rows").addCommand(Hy).addCommand(Xy).addCommand(Yy),Qy=new Fe("list").description("List one brand's social accounts with stable IDs, platforms, sources, and URLs").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await h();try{l(await m("listBrandSocialHandles",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){At(t,"Social-account list failed")}}),Zy=new Fe("add").description("Record one social account and print its stable saved row").argument("<platform>","Social network: x | instagram | facebook | linkedin | tiktok | youtube",y("platform",Jy)).argument("<handle>","Account handle on that social network").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t,n)=>{await h();try{l(await m("addBrandSocialHandle",{brandingId:n.brandingId,handle:t,platform:e,teamId:n.teamId},sr("addBrandSocialHandle",[n.brandingId??"default",e,t.replace(/^@/,"")])))}catch(r){At(r,"Social-account write failed")}}),eb=new Fe("delete").description("Remove one social account by the stable ID from social list").argument("<handle-id>","Social-handle UUID",Be).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",Be).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await h(),t.yes||(a("Refusing to remove a social account without --yes."),process.exit(s.INVALID_INPUT));try{l(await m("deleteBrandSocialHandle",{brandingId:t.brandingId,handleId:e,teamId:t.teamId},sr("deleteBrandSocialHandle",[t.brandingId??"default",e])))}catch(n){At(n,"Social-account removal failed")}}),Oc=new Fe("social").description("List, record, or remove the social accounts owned by a brand").addCommand(Qy).addCommand(Zy).addCommand(eb);import{createHash as tb}from"crypto";import{Command as Dc}from"commander";var nb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function rb(e){nb.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ob(e){return tb("sha256").update(e).digest("hex").slice(0,32)}var Nc=new Dc("sync").description("Update linked decks from their brand; waits by default, versions decks, and prints JSON").argument("<brand-id>","Brand profile ID").option("--no-wait","Return a run ID; resume with `branding sync-status <run-id>`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),rb(e);let n={brandId:e,teamId:t.teamId};try{let r=await m("syncBrandToPresentations",n,ob(`syncBrandToPresentations:${e}`));if(t.wait===!1){l(r);return}l(await xs(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Sync failed"),process.exit(s.GENERAL_ERROR)}}),Lc=new Dc("sync-status").description("Print linked-deck sync progress, terminal result, or error").argument("<run-id>","Run ID from `branding sync --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("syncBrandToPresentations",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}});import{readFile as ib}from"fs/promises";import{randomUUID as ab}from"crypto";import{Command as Uc}from"commander";var sb=["color.primary","color.background","color.text","color.secondary","color.accent","color.surface","color.link","typography.primary","typography.secondary","typography.h1","typography.h2","typography.h3","typography.h4","typography.h5","typography.h6","typography.paragraph","typography.button","typography.small","typography.label","typography.caption","asset.logo","asset.logo.dark","asset.favicon"];function db(e){let t=e.split(".").filter(Boolean);for(let n=t.length;n>=2;n--){let r=t.slice(0,n).join(".");if(sb.includes(r))return{fieldPath:t.slice(n),nodeKey:r}}return{fieldPath:t.slice(2),nodeKey:t.slice(0,2).join(".")}}function cb(e){let t={};for(let n of e){let r=n.indexOf("=");if(r<=0)throw new Error(`"${n}" is not a token assignment. Use key=value, e.g. color.primary=#114b97`);let o=n.slice(0,r).trim(),i=n.slice(r+1);if(o.split(".").filter(Boolean).length<2)throw new Error(`"${o}" is not a brand token key. Expected something like color.primary or typography.h1.size`);let{fieldPath:d,nodeKey:u}=db(o),g=lb(i);if(d.length===0){t[u]=g;continue}let w=t[u],v=w&&typeof w=="object"&&!Array.isArray(w)?w:{},x=v;for(let T of d.slice(0,-1)){let A=x[T],S=A&&typeof A=="object"&&!Array.isArray(A)?A:{};x[T]=S,x=S}x[d[d.length-1]]=g,t[u]=v}return t}function lb(e){return e==="true"?!0:e==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(e)?Number(e):e}function mb(e,t){return e===void 0?{assignments:[...t]}:e.includes("=")?{assignments:[e,...t]}:{assignments:[...t],brandId:e}}var _c=new Uc("profile").description("Read a brand's design tokens, the keys it is missing, or its design.md").argument("[brand-id]","Brand ID (defaults to this workspace's brand)").option("--format <format>","tokens (default) or md").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await m("getBrandProfile",{brandId:e,format:t.format,teamId:t.teamId});if(t.format==="md"&&typeof n.designMd=="string"){console.log(n.designMd);return}l(n)}catch(n){a(n instanceof Error?n.message:"Profile read failed"),process.exit(s.GENERAL_ERROR)}}),qc=new Uc("set").description("Write brand design tokens (key=value pairs or a design.md)").argument("[brand-id]","Brand ID (defaults to this workspace's brand)").argument("[tokens...]","Token assignments, e.g. color.primary=#114b97 typography.h1.size=32px").option("--design-md <path>","Apply a whole design.md file instead").option("--no-publish","Stage the change without publishing a new active brand version").option("--team-id <id>","Workspace ID").option("--yes","Confirm writing brand data").action(async(e,t,n)=>{n.yes||(a("Pass --yes to confirm writing brand tokens."),process.exit(s.INVALID_INPUT));let{assignments:r,brandId:o}=mb(e,t),i;try{i=r.length>0?cb(r):void 0}catch(d){a(d instanceof Error?d.message:"Invalid token pair"),process.exit(s.INVALID_INPUT)}let c;if(n.designMd)try{c=await ib(n.designMd,"utf8")}catch(d){a(`Could not read ${n.designMd}: ${d instanceof Error?d.message:String(d)}`),process.exit(s.INVALID_INPUT)}!i&&!c&&(a("Nothing to write. Pass token assignments (color.primary=#114b97) or --design-md <file>."),process.exit(s.INVALID_INPUT));try{l(await m("updateBrandTokens",{brandId:o,designMd:c,publish:n.publish===!1?!1:void 0,teamId:n.teamId,tokens:i},ab()))}catch(d){a(d instanceof Error?d.message:"Write failed"),process.exit(s.GENERAL_ERROR)}});import{createHash as ub}from"crypto";import{Command as lr}from"commander";var pb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,cr=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Ho(e){pb.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function jc(e){return ub("sha256").update(e).digest("hex").slice(0,32)}function Vc(e){if(cr.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${cr.join(", ")}.`),process.exit(s.INVALID_INPUT)}function dr(e){return e===""?null:e}function zo(e,t){if(t==="")return null;let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${r instanceof Error?r.message:String(r)}`),process.exit(s.INVALID_INPUT)}return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${e} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}function gb(e,t){if(t==="true")return!0;if(t==="false")return!1;a(`${e} takes "true" or "false", not "${t}".`),process.exit(s.INVALID_INPUT)}function fb(e){if(e==="")return null;let t=Number(e);return Number.isInteger(t)||(a(`--max-seconds takes a whole number of seconds, not "${e}".`),process.exit(s.INVALID_INPUT)),t}var hb=new lr("list").description("List a brand's per-channel design variants").argument("<brand-id>","Brand profile ID").option("--channel <key>",`One of: ${cr.join(", ")}`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ho(e),t.channel!==void 0&&Vc(t.channel);try{l(await m("listBrandVariants",{brandId:e,channelKey:t.channel,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"List failed"),process.exit(s.GENERAL_ERROR)}}),yb=new lr("set").description("Create or update one per-channel brand design variant").argument("<brand-id>","Brand profile ID").option("--variant <slug>","Variant slug; omit to create one with a new slug").option("--channel <key>",`One of: ${cr.join(", ")}`).option("--name <name>","Display name for the variant").option("--default <true|false>","Make this the channel's default, or drop the role").option("--colors <json>",`Palette as JSON, e.g. '{"primary":"#155DAC","background":"#FFFFFF","text":"#111111"}'`).option("--logo-treatment <json>",'Logo backdrop as JSON; pass "" to clear').option("--background-gradient <json>",'Gradient document as JSON; pass "" to clear').option("--aspect <ratio>",'Aspect ratio, e.g. 16:9; pass "" to clear').option("--max-seconds <seconds>",'Longest runtime in seconds; pass "" to clear').option("--voice-tone <tone>",'Voice tone override; pass "" to clear').option("--opening-style <style>",'Opening style; pass "" to clear').option("--logo-position <position>",'Logo position; pass "" to clear').option("--constraints <text>",'Generator constraints; pass "" to clear').option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Ho(e),t.channel!==void 0&&Vc(t.channel);let n={brandId:e,teamId:t.teamId};t.variant!==void 0&&(n.variantId=t.variant),t.channel!==void 0&&(n.channelKey=t.channel),t.name!==void 0&&(n.name=t.name),t.default!==void 0&&(n.isDefault=gb("--default",t.default)),t.colors!==void 0&&(n.colors=zo("--colors",t.colors)),t.logoTreatment!==void 0&&(n.logoTreatment=zo("--logo-treatment",t.logoTreatment)),t.backgroundGradient!==void 0&&(n.backgroundGradient=zo("--background-gradient",t.backgroundGradient)),t.aspect!==void 0&&(n.aspect=dr(t.aspect)),t.maxSeconds!==void 0&&(n.maxSeconds=fb(t.maxSeconds)),t.voiceTone!==void 0&&(n.voiceOverride=t.voiceTone===""?null:{tone:t.voiceTone}),t.openingStyle!==void 0&&(n.openingStyle=dr(t.openingStyle)),t.logoPosition!==void 0&&(n.logoPosition=dr(t.logoPosition)),t.constraints!==void 0&&(n.constraints=dr(t.constraints));try{l(await m("setBrandVariant",n,t.variant===void 0?void 0:jc(`setBrandVariant:${e}:${t.variant}:${JSON.stringify(n)}`)))}catch(r){a(r instanceof Error?r.message:"Set failed"),process.exit(s.GENERAL_ERROR)}}),bb=new lr("delete").description("Remove one per-channel brand design variant").argument("<brand-id>","Brand profile ID").option("--variant <slug>","Variant slug to remove").option("--team-id <id>","Workspace ID").option("--yes","Skip the confirmation prompt").action(async(e,t)=>{await h(),Ho(e),t.variant===void 0&&(a("Pass --variant <slug> to name the variant to remove. `branding variant list <brand-id>` prints the slugs."),process.exit(s.INVALID_INPUT)),!t.yes&&process.stdin.isTTY&&(a(`Refusing to delete variant "${t.variant}" without confirmation. This delete is permanent \u2014 re-run with --yes.`),process.exit(s.GENERAL_ERROR));try{l(await m("deleteBrandVariant",{brandId:e,teamId:t.teamId,variantId:t.variant},jc(`deleteBrandVariant:${e}:${t.variant}`)))}catch(n){a(n instanceof Error?n.message:"Delete failed"),process.exit(s.GENERAL_ERROR)}}),Mc=new lr("variant").description("Per-channel brand design variant commands").addCommand(hb).addCommand(yb).addCommand(bb);import{createHash as wb}from"crypto";import{Command as Yo}from"commander";var vb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Xo=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Ib(e){vb.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function kb(e){if(Xo.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${Xo.join(", ")}.`),process.exit(s.INVALID_INPUT)}function xb(e,t){let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${r instanceof Error?r.message:String(r)}`),process.exit(s.INVALID_INPUT)}return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${e} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}function Rb(e){return wb("sha256").update(e).digest("hex").slice(0,32)}var Cb=new Yo("generate").description("Generate a brand's per-channel design variants and gradients, replacing the channel's previous set").argument("[brand-id]","Brand profile ID; omit to generate a preview that is not saved").option("--channel <key>",`One of: ${Xo.join(", ")}`).option("--name <name>","Brand name to generate against").option("--description <text>","What the brand is, as generator context").option("--tone <tone>","Tone hint, e.g. 'warm, confident'").option("--style <style>","Visual style hint, e.g. 'editorial, high contrast'").option("--colors <json>",`Palette as JSON, e.g. '{"primary":"#155DAC","background":"#FFFFFF","text":"#111111"}'. Required when no brand id is given.`).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),e!==void 0&&Ib(e),t.channel!==void 0&&kb(t.channel);let n={teamId:t.teamId};e!==void 0&&(n.brandId=e),t.channel!==void 0&&(n.channelKey=t.channel),t.name!==void 0&&(n.brandName=t.name),t.description!==void 0&&(n.brandDescription=t.description),t.tone!==void 0&&(n.brandTone=t.tone),t.style!==void 0&&(n.brandStyle=t.style),t.colors!==void 0&&(n.sourceColors=xb("--colors",t.colors));try{let r=await m("generateBrandVariations",n,Rb(`generateBrandVariations:${e??"preview"}:${t.channel??"deck-16-9"}`));if(t.wait===!1){l(r);return}l(await bs(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Generate failed"),process.exit(s.GENERAL_ERROR)}}),Sb=new Yo("status").description("Read a brand variations generation run").argument("<run-id>","Run ID from `branding variations generate --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("generateBrandVariations",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Bc=new Yo("variations").description("Generated brand design variations").addCommand(Cb).addCommand(Sb);import{createHash as Eb}from"crypto";import{Command as mr}from"commander";var Qo=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Zo(e){Qo.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Tb(e,t){if(t==="head"||Qo.test(t))return t;a(`${e} must be a version id or "head".`),process.exit(s.INVALID_INPUT)}function $b(e,t){if(Qo.test(t))return t;a(`${e} must be a version id from \`branding version list\`.`),process.exit(s.INVALID_INPUT)}function Ab(e){return Eb("sha256").update(e).digest("hex").slice(0,32)}var Pb=new mr("list").description("List a brand's published versions, newest first").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Zo(e);try{l(await m("listBrandVersions",{brandId:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"List failed"),process.exit(s.GENERAL_ERROR)}}),Ob=new mr("diff").description("Compare two points in a brand's version history").argument("<brand-id>","Brand profile ID").option("--from <version-id>","Baseline version to compare against. Defaults to the brand's live version.").option("--to <version-id|head>","Version to compare. Defaults to head, the unpublished working draft.").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Zo(e);let n={brandId:e,teamId:t.teamId};t.from!==void 0&&(n.from=$b("--from",t.from)),t.to!==void 0&&(n.to=Tb("--to",t.to));try{l(await m("diffBrandVersions",n))}catch(r){a(r instanceof Error?r.message:"Diff failed"),process.exit(s.GENERAL_ERROR)}}),Db=new mr("publish").description("Publish the brand's working draft as a new live version").argument("<brand-id>","Brand profile ID").option("--label <text>","Short name for this version, unique within the brand (max 64 characters)").option("--notes <text>","What changed. Defaults to a changelog derived from the diff.").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Zo(e);let n={brandId:e,teamId:t.teamId};t.label!==void 0&&(n.label=t.label),t.notes!==void 0&&(n.notes=t.notes);try{l(await m("publishBrandVersion",n,Ab(`publishBrandVersion:${e}:${t.label??"auto"}`)))}catch(r){a(r instanceof Error?r.message:"Publish failed"),process.exit(s.GENERAL_ERROR)}}),Fc=new mr("version").description("Brand version history commands").addCommand(Pb).addCommand(Ob).addCommand(Db);import{createHash as Nb}from"crypto";import{Command as pn}from"commander";var Lb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ti(e){Lb.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ei(e,t=[]){return[...t,e]}function Gc(e){return Nb("sha256").update(e).digest("hex").slice(0,32)}var Ub=new pn("get").description("Read a brand's Voice & Context document").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),ti(e);try{l(await m("getBrandVoice",{brandId:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Read failed"),process.exit(s.GENERAL_ERROR)}}),_b=new pn("set").description("Write a brand's Voice & Context document").argument("<brand-id>","Brand profile ID").option("--positioning <text>","Positioning and promise").option("--voice-tone <text>","How the brand sounds").option("--authoritative-facts <text>","Facts generated content must never contradict").option("--approved-language <text>","Wording the brand endorses").option("--guardrails <text>","What the brand must never say or do").option("--sources <json>",`Provenance as JSON, e.g. '[{"kind":"url","name":"About page"}]'. Omitting this clears the recorded provenance.`).option("--replace","Acknowledge that this replaces the WHOLE document: sections you omit are removed. Required when the payload would drop a section the brand has.").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),ti(e);let n={brandId:e,teamId:t.teamId};if(t.positioning!==void 0&&(n.positioning=t.positioning),t.voiceTone!==void 0&&(n.voiceTone=t.voiceTone),t.authoritativeFacts!==void 0&&(n.authoritativeFacts=t.authoritativeFacts),t.approvedLanguage!==void 0&&(n.approvedLanguage=t.approvedLanguage),t.guardrails!==void 0&&(n.guardrails=t.guardrails),t.replace===!0&&(n.replace=!0),t.sources!==void 0)try{n.sources=JSON.parse(t.sources)}catch{a("--sources must be valid JSON (an array of source objects)."),process.exit(s.INVALID_INPUT)}try{l(await m("setBrandVoice",n,Gc(`setBrandVoice:${e}:${JSON.stringify(n)}`)))}catch(r){a(r instanceof Error?r.message:"Write failed"),process.exit(s.GENERAL_ERROR)}}),qb=new pn("build").description("Draft a brand's Voice & Context document from source material").argument("<brand-id>","Brand profile ID").option("--url <url>","Page to read; repeat for several",ei).option("--text <text>","Pasted source material; repeat for several",ei).option("--file <name:source>","Document to read, as name:source; repeat for several",ei).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),ti(e);let n={brandId:e,teamId:t.teamId};t.url?.length&&(n.urls=t.url),t.text?.length&&(n.text=t.text),t.file?.length&&(n.files=t.file.map(r=>{let o=r.indexOf(":");return(o<=0||o===r.length-1)&&(a(`--file must be name:source; got "${r}".`),process.exit(s.INVALID_INPUT)),{name:r.slice(0,o),source:r.slice(o+1)}})),!t.url?.length&&!t.text?.length&&!t.file?.length&&(a("Pass at least one --url, --text or --file to draft from."),process.exit(s.INVALID_INPUT));try{let r=await m("buildBrandVoice",n,Gc(`buildBrandVoice:${JSON.stringify(n)}`));if(t.wait===!1){l(r);return}l(await vs(r.runId,t.teamId))}catch(r){a(r instanceof Error?r.message:"Build failed"),process.exit(s.GENERAL_ERROR)}}),jb=new pn("build-status").description("Read a brand voice build run").argument("<run-id>","Run ID from `branding voice build --no-wait`").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await I("buildBrandVoice",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),Kc=new pn("voice").description("Brand voice and context commands").addCommand(Ub).addCommand(_b).addCommand(qb).addCommand(jb);function Gb(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new Wc(`${e} expects a whole number of 0 or more.`);return n}}function Kb(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new Wc(`${e} expects a whole number of 1+.`);return n}}var Wb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Jb=50;function zb(e){let t=e.extractedFrom??e.normalizedUrl??null,n=Jo(e),r=$c(e),o=Wo(e);if(ve("Brand Profile"),console.log(),C("ID",e.id),C("Name",e.name),C("Source URL",t??F.gray("None")),C("Default",e.isDefault?F.green("Yes"):"No"),e.createdAt&&C("Created",new Date(e.createdAt).toLocaleString()),console.log(),n||r.length>0){if(console.log(F.bold(" Colors")),n&&console.log(` Primary: ${F.bgHex(n)(" ")} ${n}`),r.length>0){console.log(" Palette:");for(let w of r.slice(0,10)){let v=w.role?F.gray(` (${w.role})`):"";console.log(` ${F.bgHex(w.hex)(" ")} ${w.hex}${v}`)}}console.log()}o&&(console.log(F.bold(" Logo")),console.log(` ${o}`),console.log());let i=e.brandData?.typography,c=e.resolvedTokens?.headingFont??i?.primary??i?.headings,d=e.resolvedTokens?.bodyFont??i?.secondary??i?.body;(c||d)&&(console.log(F.bold(" Typography")),console.log(` Headings: ${c??"-"}`),console.log(` Body: ${d??"-"}`),console.log());let u=e.brandData?.confidence,g=e.brandData?.extractionMethod;(typeof u=="number"||typeof g=="string")&&(console.log(F.bold(" Extraction")),typeof u=="number"&&console.log(` Confidence: ${Math.round(u*100)}%`),typeof g=="string"&&console.log(` Method: ${g}`),console.log()),console.log(F.gray(" Use --format json for full details")),console.log()}var Jc=new Pt("branding").description("Read and manage workspace brands, design rules, assets, permissions, and social presence").addCommand(_c).addCommand(qc).addCommand(Bd).addCommand(Gd).addCommand(yc).addCommand(bc).addCommand(rc).addCommand(new Pt("list").description("List accessible brands as a table or paged JSON").option("--search <text>","Filter by brand name or website/domain; an exact brand id also matches").option("--filter <filter>","Which slice to return (all, mine, team)",y("--filter",["all","mine","team"])).option("--sort <sort>","Sort key (created, name, updated)",y("--sort",["created","name","updated"])).option("--shape <shape>","Result shape: list (paged rows, default) or chat (compact matches)",y("--shape",["chat","list"])).option("--limit <n>","Page size (server default: 12 for the list shape, 50 for chat)",Kb("--limit")).option("--offset <n>","Brands to skip before the page",Gb("--offset")).option("--team-id <id>","Workspace ID").option("--json","Print the complete JSON response instead of a table").action(async e=>{await h();try{let t=e.shape??"list",n=await m("listBrandings",{filter:e.filter,limit:e.limit,offset:e.offset,search:e.search,shape:t,sort:e.sort,teamId:e.teamId});if(e.json){l(n);return}let r=Ac(n);if(r.length===0){b("No brand profiles found"),console.log(),console.log(F.gray(`Create one with: ${p.commands[0]} branding extract <url>`));return}console.log(xa(r));let o=e.offset??0;Ko(n)?n.hasMore&&console.log(F.gray(` ${o+r.length} of ${n.total}. Next page: --offset ${o+r.length}`)):r.length>=(e.limit??Jb)&&console.log(F.gray(` Showing ${r.length} from --offset ${o}; there may be more. Next page: --offset ${o+r.length}`))}catch(t){a(t instanceof Error?t.message:String(t)),process.exit(t.exitCode??1)}})).addCommand(new Pt("get").description("Read one brand as a summary or complete JSON").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)",y("--format",["summary","json"]),"summary").option("-o, --output <path>","Save JSON to file").option("--team-id <id>","Workspace ID").action(async(e,t)=>{if(await h(),!Wb.test(e)){a(`"${e}" is not a brand id. Pass the UUID from \`${p.commands[0]} branding list\`, or search by name with \`${p.commands[0]} branding find <query>\`.`),process.exit(s.INVALID_INPUT);return}try{let r=(await m("listBrandings",{limit:1,search:e,shape:"list",teamId:t.teamId})).items?.[0];if(!r){a(`No brand profile with id ${e} is accessible.`),process.exit(s.NOT_FOUND);return}if(t.output){await Bb(t.output,JSON.stringify(r,null,2)),k(`Brand profile saved to ${t.output}`);return}if(t.format==="json"){console.log(JSON.stringify(r,null,2));return}zb(r)}catch(n){a(n instanceof Error?n.message:String(n)),process.exit(n.exitCode??1)}})).addCommand(new Pt("find").description("Print matching brand IDs for an exact name, domain, or website URL").argument("<query>","Brand name or website URL to search for").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{let r=(await m("listBrandings",{search:e,shape:"chat",teamId:t.teamId})).brandings;if(r.length===0){b(`No brand profiles matching "${e}"`),console.log(F.gray(` Extract one with: ${p.commands[0]} branding extract <url>`));return}console.log(`Found ${r.length} brand${r.length>1?"s":""}:
|
|
73
|
-
`);for(let o of r){let i=o.primaryColor?`${
|
|
74
|
-
${
|
|
75
|
-
${
|
|
76
|
-
$ ${
|
|
77
|
-
|
|
78
|
-
${
|
|
79
|
-
${
|
|
80
|
-
$ ${
|
|
81
|
-
|
|
82
|
-
${
|
|
83
|
-
$ ${
|
|
84
|
-
`);import
|
|
85
|
-
|
|
86
|
-
${
|
|
87
|
-
${
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
${
|
|
91
|
-
$ ${
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
${
|
|
95
|
-
|
|
96
|
-
$ ${p.commands[0]} presentation video narration <project-id>
|
|
97
|
-
`)
|
|
98
|
-
${
|
|
99
|
-
${
|
|
100
|
-
$ ${
|
|
101
|
-
|
|
102
|
-
${
|
|
103
|
-
${
|
|
104
|
-
$ ${
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
$
|
|
108
|
-
|
|
109
|
-
Uploading ${t.file.length} file(s)...`));try{$=await ja(t.file.map(P=>Zc(P)),(P,be,me)=>{t.output!=="json"&&t.output!=="quiet"&&me&&process.stdout.write(`\r ${Z.cyan("\u2B06")} Uploading: ${me} (${P+1}/${be})`)},{idempotencyKey:n}),t.output!=="json"&&t.output!=="quiet"&&console.log(`\r ${Z.green("\u2713")} Uploaded ${$.length} file(s) `)}catch(P){a(`Failed to upload files: ${P instanceof Error?P.message:String(P)}`),process.exit(1)}}let E;(t.stdin||!process.stdin.isTTY)&&(E=await hw(),t.stdin&&!E&&(a("No content received from stdin"),process.exit(6)));let M=t.context;if(t.contextFile)try{M=pw(t.contextFile,"utf-8"),M.trim()||(a(`Context file is empty: ${t.contextFile}`),process.exit(6))}catch{a(`Failed to read context file: ${t.contextFile}`),process.exit(6)}!E&&!M&&!t.additionalContext&&!t.contentSources&&!t.sourcePresentation&&$.length===0&&(a("Context is required to create a presentation."),console.log(),console.log(Z.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(Z.gray(" -c, --context <text> Inline text context")),console.log(Z.gray(" --context-file <path> Read from a file")),console.log(Z.gray(` cat file | ${p.commands[0]} Pipe content`)),process.exit(6));let N=[...$];E&&N.push({id:`stdin-${n}`,content:E,title:"Piped Content",mime:"text/plain",selected:!0}),M&&N.push({id:`context-${n}`,content:M,title:"Context",mime:"text/plain",selected:!0});let O,Y=t.primaryColor||t.secondaryColor||t.accentColor||t.backgroundColor||t.foregroundColor;(t.theme||Y||t.decorations)&&(O={},t.theme&&(O.preset=t.theme),Y&&(O.custom={},t.primaryColor&&(O.custom.primary=t.primaryColor),t.secondaryColor&&(O.custom.secondary=t.secondaryColor),t.accentColor&&(O.custom.accent=t.accentColor),t.backgroundColor&&(O.custom.background=t.backgroundColor),t.foregroundColor&&(O.custom.foreground=t.foregroundColor)),t.decorations&&(O.decorations=t.decorations));try{let P=ai("--content-sources",t.contentSources),be=fw(t.sourceMode,ai("--source-presentation",t.sourcePresentation),$),me=await Va({topic:e,...t.additionalContext&&{additionalContext:t.additionalContext},...r!==void 0&&{slideCount:r},mode:A,...t.imageTier&&{imageTier:t.imageTier},...t.tone&&{tone:t.tone},...t.amount&&{amount:t.amount},...t.audience&&{audience:t.audience},...t.language&&{language:t.language},...t.brandingId&&{brandingId:t.brandingId},...t.brandDomain&&{brandDomain:t.brandDomain},...t.brandEnforcement&&{brandEnforcement:ai("--brand-enforcement",t.brandEnforcement)},...t.brandVariantId&&{brandVariantId:t.brandVariantId},...t.conversationContext&&{conversationContext:t.conversationContext},...t.designBrandReference&&{designBrandReference:t.designBrandReference},...t.family&&{family:t.family},...t.generationRequestId&&{generationRequestId:t.generationRequestId},...t.imagePolicy&&{imagePolicy:t.imagePolicy},...t.template&&{templateId:t.template},...t.styling&&{stylingMode:t.styling},...t.referenceUrl&&{referenceUrl:t.referenceUrl},...t.thinkingDepth&&{thinkingDepth:t.thinkingDepth},...t.goal&&{goal:t.goal},...t.teamId&&{teamId:t.teamId},...t.sourceMode&&{sourceMode:t.sourceMode},...be&&{sourcePresentation:be},...t.widgetSessionId&&{widgetSessionId:t.widgetSessionId},...O&&{theme:O},...t.studio?{documentId:gw.basename(process.cwd())}:t.id?{documentId:t.id}:{},...P?{contentSources:P}:N.length>0&&{contentSources:{uploadedFiles:N,contextFiles:[]}}},n,t.approvalReceipt);if(!t.wait){t.output==="json"?console.log(JSON.stringify({success:!0,run:me},null,2)):t.output!=="quiet"&&(k("Presentation generation queued"),C("Run ID",me.runId),C("Status",me.status),console.log(Z.gray(` Check later with presentation status ${me.runId}`)));return}let we=await I("createSlides",me.runId,t.teamId);for(;!we.done;)t.output!=="json"&&t.output!=="quiet"&&console.log(Z.gray(` ${we.message}`)),await new Promise(Qt=>setTimeout(Qt,(we.nextPollAfterSeconds??5)*1e3)),we=await I("createSlides",me.runId,t.teamId);if(we.error)throw new Error(ue(we.error));let Ye=we.entity?await bt(we.entity.id):void 0;if(t.output==="json")console.log(JSON.stringify({success:!0,presentation:Ye,run:we,viewUrl:Ye?ht(Ye.slug,t.language??"en"):void 0},null,2));else{console.log(),k("Presentation created successfully"),console.log(),C("Title",Ye?.title??e),C("Slides",String(Ye?.numberOfSlides??r??"\u2014")),console.log();let Qt=Ye?ht(Ye.slug,t.language??"en"):"N/A";Qt!=="N/A"&&(console.log(Z.bold(" Open: ")+Z.cyan.underline(Qt)),t.open&&await(await import("open")).default(Qt)),console.log()}}catch(P){t.output==="json"?console.log(JSON.stringify({success:!1,error:P instanceof Error?P.message:String(P),...P.errorCode==="approval_required"?{idempotencyKey:n}:{}})):(P.errorCode==="approval_required"&&C("Idempotency key",n),a(P instanceof Error?P.message:String(P))),process.exit(P.exitCode??1)}});async function hw(){return new Promise(e=>{let t="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){e("");return}process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t.trim())}),setTimeout(()=>{e(t.trim())},100)})}import{Command as di}from"commander";function si(e,t){let n=Number(e);return(!Number.isInteger(n)||n<0)&&(a(`${t} must be a whole number`),process.exit(s.GENERAL_ERROR)),n}var yw=new di("activity").description("List credit spend grouped by the artifact it was spent on").option("--limit <count>","How many groups to return (default 20)").option("--offset <count>","How many groups to skip").option("--team-id <id>","Workspace ID").action(async e=>{try{l(await m("listCreditActivity",{limit:e.limit===void 0?void 0:si(e.limit,"--limit"),offset:e.offset===void 0?void 0:si(e.offset,"--offset"),teamId:e.teamId}))}catch(t){a(t instanceof Error?t.message:"Reading credit activity failed"),process.exit(s.GENERAL_ERROR)}}),bw=new di("trace").description("List every credit charge inside one activity group").argument("[group-id]","Artifact or chat ID the group is keyed on; omit only with --group-type ungrouped").option("--group-type <type>","artifact (default), chat, or ungrouped").option("--limit <count>","How many charges to return (default 100)").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("getCreditActivityGroup",{groupId:e,groupType:t.groupType,limit:t.limit===void 0?void 0:si(t.limit,"--limit"),teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Reading the credit activity group failed"),process.exit(s.GENERAL_ERROR)}}),tl=new di("credits").description("Credit spend reporting").addCommand(yw).addCommand(bw);import{randomUUID as ww}from"crypto";import{readFile as vw}from"fs/promises";import{Command as Ge}from"commander";var ci=["text/markdown","text/csv","text/plain"];async function nl(e){let t=e.content;if(t!==void 0&&t!=="-"&&!t.startsWith("@"))return t;if(t?.startsWith("@"))return vw(t.slice(1),"utf8");if(t==="-"||!process.stdin.isTTY)return Iw();a("No document body. Pass --content <text>, --content @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function Iw(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function pr(e){return`cli:document:${e}:${ww()}`}function dt(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}function kw(e){if(!e)return;let t=e.split(".").pop()?.toLowerCase();if(t==="md"||t==="markdown")return"text/markdown";if(t==="csv")return"text/csv";if(t==="txt")return"text/plain"}var xw=new Ge("create").description("Save a document into the Library").argument("<title>","Document title").option("--team-id <id>","Workspace ID").option("--content <text>","Document body: literal text, @<path> to read a file, or '-' for stdin").option("--media-type <type>",`One of ${ci.join(", ")}; inferred from an @<path> body when omitted`).option("--summary <text>","One line for the Library card").action(async(e,t)=>{try{let n=t.mediaType??kw(t.content?.startsWith("@")?t.content.slice(1):void 0);n||(a(`Cannot tell what this document is. Pass --media-type (${ci.join(", ")}).`),process.exit(s.GENERAL_ERROR)),l(await m("createDocument",{content:await nl(t),mediaType:n,summary:t.summary,teamId:t.teamId,title:e},pr("create")))}catch(n){dt(n,"Could not save the document")}}),Rw=new Ge("list").description("List the workspace's documents, newest first").option("--team-id <id>","Workspace ID").option("--media-type <type>",`Filter to one of ${ci.join(", ")}`).option("--limit <n>","Maximum documents to return (default 50)").action(async e=>{try{l(await m("listDocuments",{limit:e.limit?Number(e.limit):void 0,mediaType:e.mediaType,teamId:e.teamId}))}catch(t){dt(t,"Could not list documents")}}),Cw=new Ge("read").description("Print a document's body").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await m("readDocument",{documentId:e,teamId:t.teamId}),{document:r}=n;process.stderr.write(`${r.title} \xB7 ${r.mediaType} \xB7 v${r.version} \xB7 ${r.byteLength} bytes
|
|
110
|
-
`)
|
|
111
|
-
${hn.bold("Examples:")}
|
|
112
|
-
|
|
113
|
-
$
|
|
114
|
-
|
|
115
|
-
${
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
${
|
|
120
|
-
${hn.gray("# For an MP4 instead")}
|
|
121
|
-
|
|
122
|
-
`);import{randomUUID as Lw}from"crypto";import{existsSync as Uw}from"fs";import{Command as Dt,InvalidArgumentError as il}from"commander";var _w=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function qw(e){if(!_w.test(e))throw new il("file-id expects a UUID from `mf file list`.");return e}function mi(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new il(`${e} expects a whole number above 0.`);return n}}function gr(e){return`cli:file:${e}:${Lw()}`}function yn(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}var jw=new Dt("add").description("Put a local file on the Library shelf; a .zip is expanded into the files it holds").argument("<path>","Path to the local file").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h(),Uw(e)||(a(`File not found: ${e}`),process.exit(s.INVALID_INPUT));try{let n=Ze(e),r=gr("add"),o=await m("createLibraryFileUploadUrl",{...n,teamId:t.teamId},`${r}:upload`),i=await et(e,o);l(await m("addLibraryFile",{mediaType:i.type,name:i.name,size:i.size,teamId:t.teamId,uploadKey:i.s3Key,url:i.url},r))}catch(n){yn(n,"Could not add that file to the Library")}}),Vw=new Dt("upload-url").description("Mint an upload target for a file you will add to the Library").requiredOption("--file-name <name>","Name of the file being uploaded").requiredOption("--file-size <bytes>","Exact byte size of the file",mi("--file-size")).requiredOption("--file-type <mime>","Media type of the file").option("--team-id <id>","Workspace ID").action(async e=>{await h();try{l(await m("createLibraryFileUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},gr("upload-url")))}catch(t){yn(t,"Could not mint an upload target")}}),Mw=new Dt("list").description("List the workspace's Library files, newest first").option("--team-id <id>","Workspace ID").option("--limit <n>","Maximum files to return (default 50)",mi("--limit")).action(async e=>{await h();try{l(await m("listLibraryFiles",{limit:e.limit,teamId:e.teamId}))}catch(t){yn(t,"Could not list Library files")}}),Bw=new Dt("remove").description("Take a file off the shelf and delete its stored bytes").argument("<file-id>","File id from `mf file list`",qw).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await h();try{l(await m("removeLibraryFile",{fileId:e,teamId:t.teamId},gr("remove")))}catch(n){yn(n,"Could not remove that file")}}),Fw=new Dt("save").description("File an object you already uploaded onto the Library shelf").requiredOption("--media-type <type>","Media type of the uploaded object").requiredOption("--name <name>","File name to show on the shelf").requiredOption("--size <bytes>","Byte size of the uploaded object",mi("--size")).requiredOption("--upload-key <key>","Storage key from `mf file upload-url`").requiredOption("--url <url>","App-owned file URL from `mf file upload-url`").option("--team-id <id>","Workspace ID").action(async e=>{await h();try{l(await m("addLibraryFile",{mediaType:e.mediaType,name:e.name,size:e.size,teamId:e.teamId,uploadKey:e.uploadKey,url:e.url},gr("save")))}catch(t){yn(t,"Could not file that object")}}),al=new Dt("file").description("Library files you can mention in chat with @").addCommand(jw).addCommand(Fw).addCommand(Mw).addCommand(Bw).addCommand(Vw);import{Command as Re}from"commander";var Gw=new Re("create").description("Create a transcript-native footage edit project").requiredOption("--title <title>","Project title").requiredOption("--source <asset-ids...>","Analyzed source recording IDs").requiredOption("--strategy <json>","Editorial strategy JSON object").requiredOption("--ranges <json>","Selected ranges JSON array").requiredOption("--outputs <json>","Output variants JSON array").option("--overlays <json>","Overlay JSON array","[]").option("--music-asset-id <id>","Music media asset ID").option("--source-chat-id <id>","Source chat ID").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async e=>{await Ke("createFootageProject",{input:{musicAssetId:e.musicAssetId??null,outputs:bn(e.outputs,"outputs"),overlays:bn(e.overlays,"overlays"),ranges:bn(e.ranges,"ranges"),sourceAssetIds:e.source,sourceChatId:e.sourceChatId,strategy:bn(e.strategy,"strategy"),teamId:e.teamId,title:e.title},idempotencyKey:e.idempotencyKey})}),Kw=new Re("show").description("Read a footage project and its append-only versions").argument("<project-id>","Project ID or slug").option("--version-id <id>","Historical version ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await Ke("getFootageProject",{input:{projectId:e,teamId:t.teamId,versionId:t.versionId}})}),Ww=new Re("revise").description("Append a semantic footage draft revision").argument("<project-id>","Project ID or slug").requiredOption("--base-version-id <id>","Current version ID").requiredOption("--change-summary <text>","Human-readable change summary").option("--title <title>","Replacement title").option("--strategy <json>","Replacement strategy JSON object").option("--ranges <json>","Replacement ranges JSON array").option("--outputs <json>","Replacement outputs JSON array").option("--overlays <json>","Replacement overlays JSON array").option("--music-asset-id <id-or-null>","Replacement music asset ID or null").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await Ke("reviseFootageProject",{input:cl({baseVersionId:t.baseVersionId,changeSummary:t.changeSummary,musicAssetId:t.musicAssetId==="null"?null:t.musicAssetId,outputs:fr(t.outputs,"outputs"),overlays:fr(t.overlays,"overlays"),projectId:e,ranges:fr(t.ranges,"ranges"),strategy:fr(t.strategy,"strategy"),teamId:t.teamId,title:t.title}),idempotencyKey:t.idempotencyKey})}),Jw=new Re("restore").description("Restore a historical footage version as a new head").argument("<project-id>","Project ID or slug").argument("<version-id>","Historical version ID").option("--change-summary <text>","Change summary","Restored version").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await Ke("restoreFootageProjectVersion",{input:{changeSummary:n.changeSummary,projectId:e,teamId:n.teamId,versionId:t},idempotencyKey:n.idempotencyKey})}),zw=new Re("branch").description("Branch a historical footage version into a new project").argument("<project-id>","Source project ID or slug").argument("<version-id>","Historical version ID").requiredOption("--title <title>","New project title").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await Ke("branchFootageProjectVersion",{input:{projectId:e,teamId:n.teamId,title:n.title,versionId:t},idempotencyKey:n.idempotencyKey})}),Hw=new Re("inspect").description("Create proxy, filmstrip, and waveform evidence for one range").argument("<project-id>","Project ID or slug").argument("<range-id>","Stable range ID").requiredOption("--version-id <id>","Exact version ID").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await Ke("inspectFootageRange",{input:{projectId:e,rangeId:t,teamId:n.teamId,versionId:n.versionId},idempotencyKey:n.idempotencyKey})}),Xw=new Re("inspection-status").description("Read a footage range inspection run").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await dl("inspectFootageRange",e,t.teamId)}),Yw=new Re("render").description("Render an exact approved footage draft version").argument("<project-id>","Project ID or slug").requiredOption("--version-id <id>","Exact version ID").option("--output <ids...>","Output IDs; omit to render every output").option("--approval-receipt <receipt>","Browser-issued approval receipt; omit on the first call to get the confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").requiredOption("--idempotency-key <key>","Key bound into the receipt").option("--team-id <id>","Workspace ID").action(async(e,t)=>{let n=he(t);await Ke("renderFootageProject",{input:cl({approvalReceipt:n,outputIds:t.output,projectId:e,teamId:t.teamId,versionId:t.versionId}),idempotencyKey:t.idempotencyKey})}),Qw=new Re("render-status").description("Read a Footage Studio render run").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await dl("renderFootageProject",e,t.teamId)}),Zw=new Re("import-takes").description("Import all completed takes from a clipping invocation").argument("<project-id>","Project ID or slug").requiredOption("--invocation-id <id>","cc-services clipping invocation ID").requiredOption("--idempotency-key <key>","Stable import retry key").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await Ke("importFootageProviderTakes",{input:{invocationId:t.invocationId,projectId:e,teamId:t.teamId},idempotencyKey:t.idempotencyKey})}),sl=new Re("footage").description("Create, inspect, revise, and render transcript-native footage edits").addCommand(Gw).addCommand(Kw).addCommand(Ww).addCommand(Jw).addCommand(zw).addCommand(Hw).addCommand(Xw).addCommand(Yw).addCommand(Qw).addCommand(Zw);async function Ke(e,t){try{l(await m(e,t.input,t.idempotencyKey))}catch(n){a(n instanceof Error?n.message:"Footage operation failed"),process.exit(s.GENERAL_ERROR)}}async function dl(e,t,n){try{l(await I(e,t,n))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}function bn(e,t){try{return JSON.parse(e)}catch{throw new Error(`${t} must be valid JSON.`)}}function fr(e,t){return typeof e=="string"?bn(e,t):void 0}function cl(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}import{Command as ev}from"commander";import ct from"chalk";function tv(e){return new Set((e??"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean))}function nv(e){if(!e)throw new Error("Slides were requested but the server returned none. Retry, or read the deck in the browser.");ve("Slides"),console.log();for(let t of e){console.log(ct.bold(` ${t.number}. ${t.title||"Untitled"}`));let n=t.text?.trim();console.log(n?ll(n):ct.gray(" (no text on this slide \u2014 image or empty)"));let r=t.speakerNotes?.trim();r&&(console.log(ct.gray(" Narration/notes:")),console.log(ct.gray(ll(r)))),console.log()}}function ll(e){return e.split(`
|
|
123
|
-
|
|
124
|
-
`)}var ml=new ev("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)",y("--format",["summary","full","json"]),"summary").option("--include <fields>","Legacy fields list (comma-separated: slides,styling)").option("--include-slides","Include ordered slide content",!0).option("--no-include-slides","Omit slide content for a smaller response").option("-l, --language <lang>","Language for view URL","en").option("--team-id <id>","Workspace ID (uses configured default)").action(async function(e,t){await h();try{let n=this.getOptionValueSource("includeSlides")==="cli"?t.includeSlides:this.getOptionValueSource("include")==="cli"?tv(t.include).has("slides"):!0,r=t.teamId??te();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let o=await bt(e,{includeSlides:n,teamId:r});if(t.format==="json"){console.log(JSON.stringify(o,null,2));return}let i=ht(o.slug,t.language);ve("Presentation Details"),console.log(),C("Slug",o.slug),C("Title",o.title||"Untitled"),C("Description",o.description||ct.gray("None")),C("Slides",String(o.numberOfSlides||"-")),C("Mode",o.mode||"-"),C("Created",eo(o.createdAt)),o.updatedAt&&C("Updated",eo(o.updatedAt)),console.log(),i!=="N/A"&&console.log(ct.bold(" Open: ")+ct.cyan.underline(i)),console.log(),n&&nv(o.slides)}catch(n){a(n instanceof Error?n.message:String(n));let r=n&&typeof n=="object"&&"exitCode"in n&&typeof n.exitCode=="number"?n.exitCode:1;process.exit(r)}});import{randomUUID as rv}from"crypto";import{Command as yr}from"commander";import ov from"ora";function iv(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function av(e){let t=e.assetType??"image";if(t!=="image"&&t!=="icon")throw new Error("Asset type must be image or icon");let n;if(e.maxResults&&(n=Number.parseInt(e.maxResults,10),Number.isNaN(n)||n<1))throw new Error("Max results must be a positive number");return{query:t==="icon"?`${e.query.trim()} transparent icon isolated symbol`:e.query.trim(),options:{maxResults:n||10,size:e.size,safeSearch:e.safeSearch,assetType:t,sources:iv(e.source),transparentBackground:t==="icon"}}}function sv(e){let t=e.url||e.imageUrl;if(!t)throw new Error("Image search returned a result without a URL");return t}function dv(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function cv(e){let t=[],n=e.reduce((r,o)=>Math.max(r,o.length),0);for(let r=0;r<n;r+=1)for(let o of e){let i=o[r];i!==void 0&&t.push(i)}return t}function lv(e,t){let n=e.data.results.map(r=>r.results.map(o=>{let i=o,c=dv(i);if(t==="icon"&&c!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...i,url:sv(i),provider:r.providerName,assetType:t,...c!==void 0?{transparent:c}:{}}}));return cv(n)}function mv(e){return e.error||e.status==="failed"||e.status==="errored"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"?"processing":"pending"}function hr(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function uv(e){return{requestId:e.runId,status:mv(e),...e.entity?.url?{url:e.entity.url}:{},...e.error?{error:ue(e.error)}:{},...hr(e.output?.width)!==void 0?{width:hr(e.output?.width)}:{},...hr(e.output?.height)!==void 0?{height:hr(e.output?.height)}:{}}}async function ul(e,t){return uv(await I("createImage",e,t))}function ui(e,t){if(t==="json"){l(e);return}if(t==="quiet"){console.log(e.output??e.url??e.requestId);return}b(`Request ID: ${e.requestId}`),b(`Status: ${e.status}`),e.url&&k(`Image URL: ${e.url}`),e.output&&k(`Saved to: ${e.output}`),e.error&&a(`Error: ${e.error}`)}var pv=new yr("search").description("Search images across the web and licensed stock").requiredOption("-q, --query <query>","Search query").option("-n, --max-results <number>","Maximum number of results (default: 10)").option("-s, --size <size>","Image size: small, medium, large, any","large").option("--asset-type <type>","Asset intent: image or transparent icon","image").option("--source <source>","Catalog: web, stock, or any (default: any)","any").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",y("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format,n=t==="human"?ov("Searching for images...").start():null,r;try{r=av(e)}catch(o){n?.stop(),a(o instanceof Error?o.message:"Invalid image search request"),process.exit(s.INVALID_INPUT);return}try{let o=await os(r);n?.stop(),o.success||(a("Search failed"),process.exit(s.GENERAL_ERROR));let i=r.options?.assetType??"image",c=lv(o,i);if(t==="json"){l({success:!0,query:e.query,assetType:i,totalResults:c.length,images:c});return}if(t==="quiet"){for(let d of c)console.log(d.url);return}if(c.length===0){b("No images found");return}k(`Found ${c.length} images for "${e.query}"`),console.log();for(let d=0;d<c.length;d++){let u=c[d];console.log(`[${d+1}] ${u.title||"Untitled"}`),console.log(` URL: ${u.url}`),console.log(` Size: ${u.width}x${u.height}`),u.author&&console.log(` Author: ${u.author}`),console.log(` Provider: ${u.provider}`),console.log()}}catch(o){n?.stop(),a(o instanceof Error?o.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),gv=new yr("generate").description("Generate an image and optionally save it locally").argument("[prompt]","Image prompt").option("-p, --prompt <text>","Image prompt (named compatibility form)").option("--provider <provider>","Provider override").option("--model <model>","Model override").option("--aspect-ratio <ratio>","Output aspect ratio: square, wide, or tall",y("--aspect-ratio",["square","wide","tall"])).option("--number-of-images <count>","Number of images (1-4)").option("--purpose <purpose>","Explicit image intent: general, draft, infographic, brand-max, or vector; omitted means general",y("--purpose",["general","draft","infographic","brand-max","vector"])).option("--width <pixels>","Width").option("--height <pixels>","Height").option("--reason <text>","Optional generation reason").option("--team-id <id>","Workspace ID").option("--reference-image <label=path-or-url...>","Image the generation must follow: a local file (uploaded for you, never resized) or a public HTTP(S) URL. Repeatable. Prefix an optional label, e.g. identity=./face.jpg, style=https://\u2026/mood.png. Fidelity depends on the routed model: the auto-routed one returns a similar-looking subject, while --provider google-ai --model gemini-3-pro-image returns the same person \u2014 but that pin takes effect only on workspaces holding the internal image-model-override flag").option("--idempotency-key <key>","Stable retry key for this generation and its reference uploads").option("-o, --output <path>","Local output path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").option("--yes","Approve generation").action(async(e,t)=>{let n,r=e??t.prompt;r?.trim()||(a("Provide an image prompt as an argument or with --prompt"),process.exit(s.INVALID_INPUT)),t.yes||(a("Pass --yes to approve image generation"),process.exit(s.INVALID_INPUT)),!t.wait&&t.output&&(a("--output requires waiting for completion; remove --no-wait"),process.exit(s.INVALID_INPUT)),(t.provider||t.model)&&L("--provider/--model are honoured only for workspaces holding the internal image-model-override flag. Without it the server drops them and routes the request itself.",t.format),t.referenceImage?.length&&!t.model&&L("Reference images without --model route to a light model that returns a similar-looking, not identical, subject. A recognisable likeness needs --provider google-ai --model gemini-3-pro-image on a workspace with the image-model-override flag.",t.format);let o=t.idempotencyKey??rv();try{let i=await Yn(t.referenceImage,{idempotencyKey:o,rejectNonImageFiles:!0}),c=await m("createImage",{aspectRatio:t.aspectRatio,confirmed:!0,height:t.height?Number.parseInt(t.height,10):void 0,model:t.model,numberOfImages:t.numberOfImages?Number.parseInt(t.numberOfImages,10):void 0,prompt:r.trim(),provider:t.provider,...t.purpose?{purpose:t.purpose}:{},...i?{referenceImages:i}:{},reason:t.reason,teamId:t.teamId,width:t.width?Number.parseInt(t.width,10):void 0},o);if(n=c.runId,!t.wait){ui({requestId:c.runId,status:"pending"},t.format);return}let d=await pe(()=>ul(c.runId,t.teamId),180,2e3);if(d.status==="failed")throw new Error(d.error||"Image generation failed");if(!d.url)throw new Error("Image generation completed without an image URL");let u=t.output?{...d,output:t.output}:d;t.output&&await oe(d.url,t.output),ui(u,t.format)}catch(i){a(ne(i,n),t.format),process.exit(s.GENERAL_ERROR)}}),fv=new yr("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Download a completed image").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await ul(e,t.teamId);if(t.output){if(n.status!=="completed"||!n.url)throw new Error("Image generation is not complete");await oe(n.url,t.output),n.output=t.output}ui(n,t.format)}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),pl=new yr("image").description("Image search and generation commands").addCommand(pv).addCommand(gv).addCommand(fv);import{Command as pi}from"commander";var hv=new pi("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").option("--provenance <source>","Filter by human or agent provenance").action(async(e,t)=>{try{l(await m("searchKnowledge",{kind:t.kind,limit:Number.parseInt(t.limit,10),provenance:t.provenance,query:e,teamId:t.teamId}))}catch(n){a(n instanceof Error?n.message:"Knowledge search failed"),process.exit(s.GENERAL_ERROR)}}),yv=new pi("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async e=>{try{l(await m("getKnowledgeBundle",{kind:e.kind,teamId:e.teamId}))}catch(t){a(t instanceof Error?t.message:"Knowledge bundle failed"),process.exit(s.GENERAL_ERROR)}}),gl=new pi("knowledge").description("Search the workspace Knowledge Hub and read bounded knowledge bundles").addCommand(hv).addCommand(yv);import{randomUUID as bv}from"crypto";import br from"chalk";import{Command as Ue}from"commander";function gi(e){if(e!==void 0)return e==="root"?null:e}function Nt(e){return`cli:library:${e}:${bv()}`}function lt(e,t){a(e instanceof Error?e.message:t),process.exit(s.GENERAL_ERROR)}var wv=new Ue("list").description("List the Library folder tree").option("--team-id <id>","Workspace ID").option("--counts","Include how many items are in each folder").action(async e=>{try{l(await m("listLibraryFolders",{includeEntryCounts:!!e.counts,teamId:e.teamId}))}catch(t){lt(t,"Could not list folders")}}),vv=new Ue("create").description("Create a Library folder").argument("<name>","Folder name").option("--team-id <id>","Workspace ID").option("--parent <id>","Parent folder id; omit for a top-level folder").option("--color <color>","Colour token (slate, blue, green, amber, red, violet)").action(async(e,t)=>{try{l(await m("createLibraryFolder",{color:t.color,name:e,parentId:gi(t.parent),teamId:t.teamId},Nt("create")))}catch(n){lt(n,"Could not create the folder")}}),Iv=new Ue("rename").description("Rename a Library folder").argument("<folder-id>","Folder id").argument("<name>","New name").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{try{l(await m("renameLibraryFolder",{folderId:e,name:t,teamId:n.teamId},Nt("rename")))}catch(r){lt(r,"Could not rename the folder")}}),kv=new Ue("recolor").description("Set or clear a Library folder's colour").argument("<folder-id>","Folder id").requiredOption("--color <color>","Colour token (slate, blue, green, amber, red, violet), or 'none' to clear").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("recolorLibraryFolder",{color:t.color==="none"?null:t.color,folderId:e,teamId:t.teamId},Nt("recolor")))}catch(n){lt(n,"Could not recolour the folder")}}),xv=new Ue("move").description("Move a Library folder under a new parent").argument("<folder-id>","Folder id").requiredOption("--to <id>","New parent folder id, or 'root' for top level").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("moveLibraryFolder",{folderId:e,newParentId:gi(t.to),teamId:t.teamId},Nt("move")))}catch(n){lt(n,"Could not move the folder")}}),Rv=new Ue("delete").description("Delete a folder and its subfolders; items inside are unfiled").argument("<folder-id>","Folder id").requiredOption("--yes","Confirm deletion").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("deleteLibraryFolder",{folderId:e,teamId:t.teamId},Nt("delete")))}catch(n){lt(n,"Could not delete the folder")}}),Cv=new Ue("folders").description("Manage Library folders").addCommand(wv).addCommand(vv).addCommand(Iv).addCommand(kv).addCommand(xv).addCommand(Rv),Sv=new Ue("file").description("File an artifact into a Library folder").argument("<kind>","Artifact kind, e.g. presentation or microsite").argument("<target-id>","Id of the artifact itself").requiredOption("--folder <id>","Destination folder id, or 'root' to unfile the artifact").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{try{l(await m("fileArtifactIntoFolder",{folderId:gi(n.folder),kind:e,targetId:t,teamId:n.teamId},Nt("file")))}catch(r){lt(r,"Could not file that item")}}),fi=new Ue("library").description("Library folders and filing").addCommand(Cv).addCommand(Sv);fi.addHelpText("after",`
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
`);import{randomUUID as Ev}from"crypto";import{Command as wn}from"commander";function R(e,t){let n={...t},r=e.parent,o=!1;for(;r;){let i=r.opts?.();if(i){o=!0;for(let[c,d]of Object.entries(i))n[c]===void 0&&d!==void 0&&(n[c]=d)}r=r.parent}return o?n:t}var fl=new wn("analyze").description("Transcribe an uploaded recording and publish it for generation").argument("<asset-id>","Recording ID").option("--language <code>","BCP-47 language hint for the spoken audio").option("--no-diarize","Skip speaker attribution (cheaper, but a multi-speaker recording becomes much weaker as generation input)").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable recovery key").option("--yes","Confirm the charge \u2014 billed per source-minute").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to confirm. Analysis is billed per minute of source audio.");let n=t.idempotencyKey??Ev();try{l(await m("analyzeMediaAsset",{assetId:e,diarize:t.diarize,language:t.language,teamId:t.teamId},n))}catch(r){a(`${r instanceof Error?r.message:"Analysis failed"} Retry with --idempotency-key ${n}.`),process.exit(s.GENERAL_ERROR)}}),Tv=new wn("status").description("Read an analysis run's status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async function(e,t){let n=R(this,t);try{l(await I("analyzeMediaAsset",e,n.teamId))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}});fl.addCommand(Tv);var hl=new wn("import").description("Import a recording from a connected account").argument("<remote-file-id>","The provider's own ID for the recording").requiredOption("--provider <id>","Provider id of the connected account, e.g. google").requiredOption("--connector <id>","Connected account ID to read from").option("--title <title>","Name for the imported recording").option("--chat <id>","Chat this import was requested from").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("importConnectorRecording",{connectorId:t.connector,providerId:t.provider,remoteFileId:e,sourceChatId:t.chat,teamId:t.teamId,title:t.title}))}catch(n){a(n instanceof Error?n.message:"Import failed"),process.exit(s.GENERAL_ERROR)}}),$v=new wn("status").description("Read an import run's status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async function(e,t){let n=R(this,t);try{l(await I("importConnectorRecording",e,n.teamId))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}});hl.addCommand($v);var yl=new wn("media").description("Ingest and transcribe recordings you already own").addCommand(fl).addCommand(hl);import{Command as hi}from"commander";var Av=new hi("create").description("Start background microsite generation").argument("<title>","Microsite title").requiredOption("--description <brief>","Microsite brief").option("--audience <audience>","Target audience").option("--tone <tone>","Tone").option("--language <language>","Content language","en").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").option("--yes","Approve generation").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{l(await m("createMicrosite",{approvalReceipt:"cli:--yes",audience:t.audience,brandingId:t.brandingId,description:t.description,language:t.language,teamId:t.teamId,title:e,tone:t.tone}))}catch(n){a(n instanceof Error?n.message:"Generation failed"),process.exit(s.GENERAL_ERROR)}}),Pv=new hi("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await I("createMicrosite",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),bl=new hi("microsite").description("Generate a shareable multi-section web microsite from a brief").addCommand(Av).addCommand(Pv);import{randomUUID as Ov}from"crypto";import{Command as wi}from"commander";import yi from"ora";function bi(e,t){if(t==="json"){l(e);return}if(t==="quiet"){e.outputUrl?console.log(e.outputUrl):console.log(e.requestId);return}b(`Request ID: ${e.requestId}`),b(`Status: ${e.status}`),e.duration&&b(`Duration: ${e.duration}s`),e.outputUrl&&k(`Output URL: ${e.outputUrl}`),e.error&&a(`Error: ${e.error}`)}var Dv=new wi("create").description("Mix audio tracks into a video (music will loop to match video duration)").option("--video <url>","Input video file/URL").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--inputs-json <json>","Canonical audio input array").option("--operation <operation>","Canonical mix operation","add-to-video").option("--options-json <json>","Canonical mix options JSON").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",y("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=he(e)}catch(g){a(g instanceof Error?g.message:String(g)),process.exit(s.INVALID_INPUT)}!e.inputsJson&&(!e.video||!e.music&&!e.voice)&&(a("At least one of --music or --voice must be provided"),process.exit(s.INVALID_INPUT));let n=parseInt(e.musicVolume,10)/100,r=parseInt(e.voiceVolume,10)/100;(Number.isNaN(n)||n<0||n>1)&&(a("Music volume must be between 0 and 100"),process.exit(s.INVALID_INPUT)),(Number.isNaN(r)||r<0||r>2)&&(a("Voice volume must be between 0 and 200"),process.exit(s.INVALID_INPUT));let o=e.format,i=o==="human"?yi("Mixing audio...").start():null,c=e.inputsJson?Nv("--inputs-json",e.inputsJson):[{url:e.video,role:"video"}];!e.inputsJson&&e.music&&c.push({url:e.music,role:"background",volume:n*5}),!e.inputsJson&&e.voice&&c.push({url:e.voice,role:"voice",volume:r*2});let d,u=e.idempotencyKey??Ov();try{let g=e.optionsJson?Lv("--options-json",e.optionsJson):{},w=await rs({operation:e.operation,inputs:c,options:e.inputsJson?g:{...g,musicVolume:n,voiceVolume:r}},{approvalReceipt:t,idempotencyKey:u});if(d=w.requestId,!e.wait){i?.stop(),bi(w,o);return}i&&(i.text=`Processing (ID: ${w.requestId})...`);let v=await pe(()=>uo(w.requestId),120,3e3);if(i?.stop(),v.status==="failed"&&(a(v.error||"Audio mixing failed"),process.exit(s.GENERAL_ERROR)),bi(v,o),e.output){if(!v.outputUrl)throw new Error("Audio mix completed without an output URL");let x=o==="human"?yi("Downloading...").start():null;await oe(v.outputUrl,e.output),x?.stop(),o==="human"&&k(`Saved to: ${e.output}`)}}catch(g){i?.stop(),a(`${ne(g,d)} Retry with --idempotency-key ${u}.`,o),process.exit(s.GENERAL_ERROR)}});function Nv(e,t){try{let n=JSON.parse(t);if(!Array.isArray(n))throw new Error;return n}catch{throw new Error(`${e} must be a JSON array`)}}function Lv(e,t){try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error;return n}catch{throw new Error(`${e} must be a JSON object`)}}var Uv=new wi("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format==="human"?yi("Checking status...").start():null;try{let r=await uo(e);n?.stop(),bi(r,t.format)}catch(r){n?.stop(),a(r instanceof Error?r.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),wl=new wi("mix").description("Audio mixing commands").addCommand(Dv).addCommand(Uv);import{randomUUID as Fv}from"crypto";import{Command as Ii}from"commander";import Gv from"ora";import{readFileSync as _v}from"fs";var vl=500,Il=1e4,wr=100,kl=1e4,xl=1e3,Cl=["duration_s","idempotency_key","narration","schema_version","video_description"],qv=["end_s","id","start_s","text","words"],jv=["end","id","start","text"],Vv=["description","end_s","id","start_s"];function Sl(e){let t=Tl(e);if($l(t),vn(t,Cl,""),t.duration_s<3)throw new Error("Music request duration_s must be between 3 and 600");return t}function El(e){let t=Tl(e);$l(t),vn(t,[...Cl,"visual_event"],"");let n=t.visual_event;if(!vr(n))throw new Error("SFX request visual_event is required");if(vn(n,Vv,"visual_event"),!We(n.description))throw new Error("SFX request visual_event.description is required");if(!We(n.id)||!Je(n.start_s))throw new Error("SFX request visual_event requires id and start_s");if(n.end_s!==void 0&&(!Je(n.end_s)||n.end_s<n.start_s))throw new Error("SFX request visual_event.end_s must be after start_s");return t}function Tl(e){try{let t=JSON.parse(_v(e,"utf8"));if(!vr(t))throw new Error("request must be a JSON object");return t}catch(t){throw new Error(`Cannot read audio request ${e}: ${t instanceof Error?t.message:String(t)}`)}}function $l(e){if(e.schema_version!==1)throw new Error("Audio request schema_version must be 1");if(!We(e.video_description))throw new Error("Audio request video_description is required");if(!Je(e.duration_s)||e.duration_s<.5||e.duration_s>600)throw new Error("Audio request duration_s must be between 0.5 and 600");if(!Array.isArray(e.narration))throw new Error("Audio request narration must be an array");if(e.narration.length>vl)throw new Error(`Audio request narration holds at most ${vl} lines`);if(e.narration.forEach(Mv),e.idempotency_key!==void 0&&!We(e.idempotency_key))throw new Error("Audio request idempotency_key must be a non-empty string")}function Mv(e,t){let n=`narration.${t}`;if(!vr(e))throw new Error(`Audio request ${n} must be an object`);if(vn(e,qv,n),!We(e.id)||e.id.length>wr)throw new Error(`Audio request ${n}.id is required (1-${wr} characters)`);if(!We(e.text)||e.text.trim().length>kl)throw new Error(`Audio request ${n}.text is required (1-${kl} characters)`);if(Rl(e.start_s,`${n}.start_s`),Rl(e.end_s,`${n}.end_s`),Je(e.start_s)&&Je(e.end_s)&&e.end_s<e.start_s)throw new Error(`Audio request ${n}.end_s must be greater than or equal to ${n}.start_s`);if(e.words!==void 0){if(!Array.isArray(e.words)||e.words.length>Il)throw new Error(`Audio request ${n}.words must be an array of at most ${Il} entries`);e.words.forEach((r,o)=>{Bv(r,`${n}.words.${o}`)})}}function Bv(e,t){if(!vr(e))throw new Error(`Audio request ${t} must be an object`);if(vn(e,jv,t),!We(e.text)||e.text.trim().length>xl)throw new Error(`Audio request ${t}.text is required (1-${xl} characters)`);if(!Je(e.start)||!Je(e.end))throw new Error(`Audio request ${t} requires numeric start and end seconds`);if(e.end<e.start)throw new Error(`Audio request ${t}.end must be greater than or equal to ${t}.start`);if(e.id!==void 0&&(!We(e.id)||e.id.length>wr))throw new Error(`Audio request ${t}.id must be 1-${wr} characters`)}function Rl(e,t){if(e!==void 0&&!Je(e))throw new Error(`Audio request ${t} must be a non-negative number`)}function vn(e,t,n){let r=Object.keys(e).filter(i=>!t.includes(i));if(r.length===0)return;let o=n?`${n} `:"";throw new Error(`Audio request ${o}has unknown field(s): ${r.join(", ")}. Allowed: ${t.join(", ")}`)}function vr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function We(e){return typeof e=="string"&&e.trim().length>0}function Je(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0}function vi(e,t){if(t==="json"){l(e);return}if(t==="quiet"){console.log(e.audioUrl??e.requestId);return}b(`Request ID: ${e.requestId}`),b(`Status: ${e.status}`),e.duration&&b(`Duration: ${e.duration}s`),e.audioUrl&&k(`Audio URL: ${e.audioUrl}`),e.error&&a(`Error: ${e.error}`)}var Kv=new Ii("generate").description("Generate music that follows a video's narration and final timing").option("--request <path>","JSON file with video description, narration, and final timing").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--duration <seconds>","Direct music duration").option("--duration-seconds <seconds>","Final video duration").option("--narration-json <json>","Final narration timing array").option("--options-json <json>","Canonical music options JSON").option("--prompt <text>","Direct music brief").option("--schema-version <version>","Video facts schema version").option("--video-description <text>","Final video description").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=he(e)}catch(d){a(d instanceof Error?d.message:String(d)),process.exit(s.INVALID_INPUT)}!e.wait&&e.output&&(a("--output requires waiting for completion; remove --no-wait"),process.exit(s.INVALID_INPUT));let n;try{n=e.request?Sl(e.request):{...e.duration?{duration:Number(e.duration)}:{},...e.durationSeconds?{duration_s:Number(e.durationSeconds)}:{},...e.narrationJson?{narration:Al("--narration-json",e.narrationJson)}:{},...e.optionsJson?{options:Al("--options-json",e.optionsJson)}:{},...e.prompt?{prompt:e.prompt}:{},...e.schemaVersion?{schema_version:Number(e.schemaVersion)}:{},...e.videoDescription?{video_description:e.videoDescription}:{}}}catch(d){a(d instanceof Error?d.message:String(d)),process.exit(s.INVALID_INPUT)}let r=e.format,o=r==="human"?Gv("Generating music for video...").start():null,i,c=e.idempotencyKey??n.idempotency_key??Fv();try{let d=await ns(n,{approvalReceipt:t,idempotencyKey:c});if(i=d.requestId,!e.wait){o?.stop(),vi(d,r);return}o&&(o.text=`Processing (ID: ${d.requestId})...`);let u=d.status==="completed"||d.status==="failed"?d:await pe(()=>mo(d.requestId),180,2e3);if(o?.stop(),u.status==="failed"&&(a(u.error||"Music generation failed"),process.exit(s.GENERAL_ERROR)),e.output){if(!u.audioUrl)throw new Error("Music completed without an audio URL");await oe(u.audioUrl,e.output),r==="human"&&k(`Saved to: ${e.output}`),u.output=e.output}vi(u,r)}catch(d){o?.stop(),a(`${ne(d,i)} Retry with --idempotency-key ${c}.`,r),process.exit(s.GENERAL_ERROR)}});function Al(e,t){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON`)}}var Wv=new Ii("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{vi(await mo(e),t.format)}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Pl=new Ii("music").description("Video-aware music generation commands").addCommand(Kv).addCommand(Wv);import{Command as ki}from"commander";function Ol(e,t){return[...t,e]}var Jv=new ki("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",Ol,[]).option("--type <type>","single, multiple, or word-cloud","single").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve creation").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll creation");try{l(await m("createPoll",{approvalReceipt:"cli:--yes",options:t.option.map(n=>({text:n})),pollType:t.type,question:e,teamId:t.teamId,title:t.title}))}catch(n){a(n instanceof Error?n.message:"Poll creation failed"),process.exit(s.GENERAL_ERROR)}}),zv=new ki("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",Ol).option("--type <type>","single, multiple, or word-cloud").option("--title <title>","Poll title").option("--team-id <id>","Workspace ID").option("--yes","Approve update").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll update");try{l(await m("editPoll",{approvalReceipt:"cli:--yes",options:t.option?.map(n=>({text:n})),pollId:e,pollType:t.type,question:t.question,teamId:t.teamId,title:t.title}))}catch(n){a(n instanceof Error?n.message:"Poll update failed"),process.exit(s.GENERAL_ERROR)}}),Dl=new ki("poll").description("Standalone poll commands").addCommand(Jv).addCommand(zv);import{randomUUID as Ar}from"crypto";import{readFile as Im}from"fs/promises";import V from"chalk";import{Command as K,InvalidArgumentError as Ni}from"commander";import{Command as Nl,InvalidArgumentError as Hv}from"commander";var Ll=new Nl("chats").description("List Studio chat threads for an owned presentation video").argument("<project-id>","Presentation-video project UUID or editor slug").option("--limit <number>","Maximum threads (1-100)",_l(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await ql("Chat thread list failed",()=>m("listPresentationVideoChatThreads",{limit:n.limit,projectId:e,teamId:n.teamId}))}),Ul=new Nl("chat").description("Read one Studio chat with safe attachment and scene-marker context").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<chat-id>","Thread UUID from presentation video chats").option("--before <timestamp>","Return messages older than this ISO timestamp").option("--limit <number>","Maximum messages (1-50)",_l(1,50)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=R(this,n);await ql("Chat thread read failed",()=>m("getPresentationVideoChatThread",{before:r.before,chatId:t,limit:r.limit,projectId:e,teamId:r.teamId}))});function _l(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new Hv(`Expected an integer between ${e} and ${t}.`);return r}}async function ql(e,t){try{l(await t())}catch(n){a(n instanceof Error?n.message:e),process.exit(s.GENERAL_ERROR)}}import{randomUUID as xi}from"crypto";import{readFile as Xv}from"fs/promises";import{Command as kr}from"commander";var jl=new kr("edit").description("Apply one atomic draft edit: narration, scene patch/move/remove, composition, or intro/outro card").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--edit <json-or-path>","Edit object as inline JSON or a JSON file path").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=R(this,t);await xr("Draft edit failed",async()=>m("editPresentationVideoDraft",{edit:await Yv(n.edit),projectId:e,teamId:n.teamId},n.idempotencyKey??xi()))}),Vl=new kr("versions").description("List saved presentation-video draft versions").argument("<project-id>","Presentation-video project UUID or editor slug").option("--before-version <number>","Continue below this version number",Ir(1)).option("--limit <number>","Maximum versions",Ir(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await xr("Version list failed",()=>m("listPresentationVideoVersions",{beforeVersion:n.beforeVersion,limit:n.limit,projectId:e,teamId:n.teamId}))}),Ml=new kr("restore").description("Restore a saved draft version as a new version").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<version-number>","Version number",Ir(1)).option("--expected-current-version <number>","Refuse to restore if a newer draft version exists",Ir(1)).option("--expected-project-updated-at <timestamp>","Non-coalescing project revision paired with --expected-current-version").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n){let r=R(this,n);await xr("Version restore failed",()=>m("restorePresentationVideoVersion",{expectedCurrentVersion:r.expectedCurrentVersion,expectedProjectUpdatedAt:r.expectedProjectUpdatedAt,projectId:e,teamId:r.teamId,versionNumber:t},r.idempotencyKey??xi()))}),Bl=new kr("refresh").description("Refresh deck-backed scenes from the latest presentation version").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=R(this,t);await xr("Slide refresh failed",()=>m("refreshPresentationVideoSlides",{projectId:e,teamId:n.teamId},n.idempotencyKey??xi()))});async function Yv(e){let t=e.trim(),n=t.startsWith("{")?t:await Xv(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("--edit must contain one JSON object.");return r}function Ir(e,t=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new Error(`Expected an integer between ${e} and ${t}.`);return r}}async function xr(e,t){try{l(await t())}catch(n){a(n instanceof Error?n.message:e),process.exit(s.GENERAL_ERROR)}}import{createHash as Qv}from"crypto";import{Command as Lt,InvalidArgumentError as Zv}from"commander";var Fl=new Lt("drafts").description("List every video draft for one presentation with stage and staleness").argument("<presentation-id>","Source presentation ID, document ID, or slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await Ut("Draft list failed",()=>m("listPresentationVideoProjects",{presentationId:e,teamId:n.teamId}))}),Gl=new Lt("freshness").description("Check whether a video draft is behind its source deck without changing it").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await Ut("Freshness read failed",()=>m("getPresentationVideoFreshness",{projectId:e,teamId:n.teamId}))}),Kl=new Lt("version").description("Read one saved draft snapshot without restoring it").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<version-number>","Saved version number",Hl(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=R(this,n);await Ut("Version read failed",()=>m("getPresentationVideoVersion",{projectId:e,teamId:r.teamId,versionNumber:t}))}),Wl=new Lt("renders").description("List MP4 render attempts newest first, including failures").argument("<project-id>","Presentation-video project UUID or editor slug").option("--limit <number>","Maximum render attempts; omit to return the complete history",Hl(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await Ut("Render history failed",()=>m("listPresentationVideoRenders",{limit:n.limit,projectId:e,teamId:n.teamId}))}),Jl=new Lt("render").description("Read one render's exact snapshot, asset progress, ordered events, and MP4 URL").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","Render attempt UUID from `presentation video renders`").option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=R(this,n);await Ut("Render read failed",()=>m("getPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId}))}),zl=new Lt("cancel").description("Request cancellation of one in-flight MP4 DurableRun").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","In-flight render attempt UUID").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; deterministically derived from both IDs when omitted").action(async function(e,t,n){let r=R(this,n);await Ut("Render cancellation failed",()=>m("cancelPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId},r.idempotencyKey??eI(e,t)))});function Hl(e,t=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new Zv(`Expected an integer between ${e} and ${t}.`);return r}}function eI(e,t){return`presentation-video-cancel:${Qv("sha256").update(`${e}\0${t}`).digest("hex")}`}async function Ut(e,t){try{l(await t())}catch(n){a(n instanceof Error?n.message:e),process.exit(s.GENERAL_ERROR)}}import{randomUUID as nI}from"crypto";import{Command as kn}from"commander";import{existsSync as tI}from"fs";var Xl=["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full"];function _t(e){let[t,n]=e.split(":");if(t==="background")return{kind:"background"};if(t==="full")return{kind:"full"};if(t==="split"){if(n!=="left"&&n!=="right")throw new Error("--placement split needs a side: split:left or split:right.");return{kind:"split",side:n}}if(t==="box"){if(!n||!Xl.includes(n))throw new Error(`--placement box needs an anchor: box:${Xl.join(" | box:")}.`);return{kind:"box",placement:{anchor:n}}}throw new Error("--placement must be background, split:left, split:right, full, or box:<anchor>.")}function Rr(e){if(e.wholeScene&&e.duration!==void 0)throw new Error("--whole-scene and --duration ask for opposite things; pass only one.");let t=e.duration!==void 0||e.start!==void 0||e.wholeScene===!0;if(e.startWord!==void 0){if(t)throw new Error("--start-word replaces --start, --duration and --whole-scene; pass words or seconds, not both.");if(e.clearAnchor)throw new Error("--start-word and --clear-anchor ask for opposites.");if(e.endWord!==void 0&&e.endWord<e.startWord)throw new Error("--end-word must not come before --start-word.");return{anchor:{...e.endWord!==void 0?{endWord:e.endWord}:{},startWord:e.startWord}}}if(e.endWord!==void 0)throw new Error("--end-word needs --start-word.");if(!(!t&&!e.clearAnchor))return{...e.clearAnchor?{anchor:null}:{},...e.wholeScene?{durationSec:null}:e.duration!==void 0?{durationSec:e.duration}:{},...e.start!==void 0?{startSec:e.start}:{}}}function mt(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new Error(`${e} must be a 0-based narration word index (0, 1, 2, \u2026).`);return n}}function In(e){let t=e.split(",").map(n=>n.trim()).filter(Boolean);if(t.length===0)throw new Error("Provide at least one scene id.");return t}function Te(e){return t=>{let n=Number(t);if(!Number.isFinite(n)||n<0)throw new Error(`${e} must be a number of seconds.`);return n}}async function Cr(e,t={}){if(e.startsWith("https://"))return{url:e};if(e.startsWith("http://"))throw new Error("A layer image URL must use https.");if(tI(e))return{uploadKey:(await Q(e,{idempotencyKey:t.idempotencyKey,storagePrefix:"scene-layers"})).s3Key};if(em(e))return{mediaAssetId:e};throw new Error("--image must be a local file path, an https image URL, or a media-library asset UUID.")}var Sr=["brand","alert"],Ri="::",Yl=";;";function Ei(e){if([e.textTitle,e.textCallout,e.textList].filter(r=>r!==void 0).length>1)throw new Error("Pass only one of --text-title, --text-callout or --text-list; each one is a whole card.");let n=Si(e.tone);if(e.textTitle!==void 0)return{heading:Ci(e.textTitle,"--text-title"),tone:n,variant:"title"};if(e.textCallout!==void 0){let[r,o]=Ql(e.textCallout,Ri);return{...o?.trim()?{body:o.trim()}:{},heading:Ci(r,"--text-callout"),tone:n,variant:"callout"}}if(e.textList!==void 0){let[r,o]=Ql(e.textList,Ri),i=(o??"").split(Yl).map(c=>c.trim()).filter(Boolean);if(i.length===0)throw new Error(`--text-list needs a heading and its points: --text-list "Heading${Ri}first${Yl}second".`);return{heading:Ci(r,"--text-list"),items:i,tone:n,variant:"list"}}if(e.tone!==void 0)throw new Error("--tone describes a text layer; pass it with --text-title, --text-callout or --text-list.")}function Zl(e){let t=Ei({...e,tone:void 0});return t?{body:t.body??null,heading:t.heading,items:t.items??null,...e.tone!==void 0?{tone:Si(e.tone)}:{},variant:t.variant}:e.tone===void 0?void 0:{tone:Si(e.tone)}}function Si(e){if(e===void 0)return"brand";if(e!=="alert"&&e!=="brand")throw new Error(`--tone must be ${Sr.join(" or ")}.`);return e}function Ci(e,t){let n=(e??"").trim();if(!n)throw new Error(`${t} needs the text to show.`);return n}function Ql(e,t){let n=e.indexOf(t);return n<0?[e,void 0]:[e.slice(0,n),e.slice(n+t.length)]}function em(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}function Ti(e){try{return Rr(e)}catch(t){a(t instanceof Error?t.message:"Invalid layer timing."),process.exit(s.INVALID_INPUT)}}function tm(e){try{return e()}catch(t){a(t instanceof Error?t.message:"Invalid layer text."),process.exit(s.INVALID_INPUT)}}async function Er(e,t){try{l(await t())}catch(n){a(n instanceof Error?n.message:e),process.exit(s.GENERAL_ERROR)}}function Tr(e,t,n){return m("editPresentationVideoDraft",{edit:n,projectId:e,teamId:t.teamId},t.idempotencyKey??nI())}var rI=new kn("add").description("Add one timed layer to one or more scenes").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--scenes <ids>","Comma-separated composition scene ids").option("--video <id>","Reusable library video id").option("--media <id>","Media-library asset id (image or video)").option("--image <file-or-url>","Local image file to upload, or an https image URL").option("--slide <scene-id>","Reuse the image already on that deck scene").option("--text-title <line>","Words on a brand card: one loud line").option("--text-callout <heading::body>",'Words on a brand card: a heading over a paragraph, e.g. "Lockout first::Isolate the source."').option("--text-list <heading::a;;b;;c>","Words on a brand card: a heading over up to three points").option("--tone <tone>",`Text card colour: ${Sr.join(" | ")}`).option("--placement <placement>","background | split:left | split:right | full | box:<anchor> (default background; required for a text layer, which cannot use background)").option("--start <seconds>","Seconds from the scene's first frame",Te("--start")).option("--duration <seconds>","Seconds shown; omit for the whole scene",Te("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces --start/--duration",mt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive); omit for the whole scene",mt("--end-word")).option("--label <text>",'Studio label, e.g. "Right way"').option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=R(this,t),r=tm(()=>Ei(n));[n.video,n.media,n.image,n.slide,r].filter(c=>c!==void 0).length!==1&&(a("Pass exactly one of --video, --media, --image, --slide, --text-title, --text-callout or --text-list."),process.exit(s.INVALID_INPUT)),r&&n.placement===void 0&&(a("A text layer needs --placement: split:left, split:right, full, or box:<anchor>. It cannot use background, where words paint under the scrim."),process.exit(s.INVALID_INPUT));let i=Ti(n);await Er("Layer add failed",async()=>{let c=r?{text:r}:n.video?{videoId:n.video}:n.media?{mediaAssetId:n.media}:n.slide?{slideId:n.slide}:await Cr(n.image,{idempotencyKey:n.idempotencyKey});return Tr(e,n,{...n.label?{label:n.label}:{},placement:_t(n.placement??"background"),sceneIds:In(n.scenes),source:c,...i?{timing:i}:{},type:"add_scene_layer"})})}),oI=new kn("update").description("Move, retime, relabel or retype one layer. A picture or a clip is not editable \u2014 add a new layer instead \u2014 but a text layer's words are, because nothing was resolved to produce them").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id").argument("<layer-id>","Layer id from the project read").option("--placement <placement>","background | split:left | split:right | full | box:<anchor>").option("--start <seconds>","Seconds from the scene's first frame",Te("--start")).option("--duration <seconds>","Seconds shown",Te("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces the seconds flags",mt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive)",mt("--end-word")).option("--clear-anchor","Drop the word anchor and put the layer back on seconds").option("--whole-scene","Clear the length so the layer shows until the scene ends").option("--text-title <line>","Retype a text layer as one loud line").option("--text-callout <heading::body>","Retype a text layer as a heading over a paragraph").option("--text-list <heading::a;;b;;c>","Retype a text layer as a heading over up to three points").option("--tone <tone>",`Text card colour: ${Sr.join(" | ")}`).option("--label <text>","Studio label").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n,r){let o=R(this,r),i=Ti(o),c=tm(()=>Zl(o));o.placement===void 0&&i===void 0&&c===void 0&&o.label===void 0&&(a("Provide at least one of --placement, --start, --duration, --whole-scene, --start-word, --clear-anchor, --text-title, --text-callout, --text-list, --tone or --label."),process.exit(s.INVALID_INPUT)),await Er("Layer update failed",()=>Tr(e,o,{...o.label!==void 0?{label:o.label}:{},layerId:n,...o.placement!==void 0?{placement:_t(o.placement)}:{},sceneId:t,...c?{text:c}:{},...i?{timing:i}:{},type:"update_scene_layer"}))}),iI=new kn("remove").description("Remove one layer from one scene").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id").argument("<layer-id>","Layer id from the project read").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n,r){let o=R(this,r);await Er("Layer remove failed",()=>Tr(e,o,{layerId:n,sceneId:t,type:"remove_scene_layer"}))}),aI=new kn("copy").description("Copy one layer onto other scenes, optionally with a different placement").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id the layer sits on").argument("<layer-id>","Layer id from the project read").requiredOption("--to <ids>","Comma-separated target scene ids").option("--placement <placement>","background | split:left | split:right | full | box:<anchor>").option("--start <seconds>","Retime the copies: seconds from each scene's first frame",Te("--start")).option("--duration <seconds>","Retime the copies: seconds shown",Te("--duration")).option("--start-word <index>","Retime the copies on each TARGET scene's narration words (0-based)",mt("--start-word")).option("--end-word <index>","Last narration word shown on each target (inclusive)",mt("--end-word")).option("--clear-anchor","Drop the source layer's word anchor on the copies").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n,r){let o=R(this,r),i=Ti(o);await Er("Layer copy failed",()=>Tr(e,o,{layerId:n,...o.placement!==void 0?{placement:_t(o.placement)}:{},sceneId:t,...i?{timing:i}:{},toSceneIds:In(o.to),type:"copy_scene_layer"}))}),nm=new kn("layer").description("Add, move, remove or copy the timed layers on a scene").addCommand(rI).addCommand(oI).addCommand(iI).addCommand(aI).addHelpText("after",`
|
|
50
|
+
${n.text}`}function jo(t,e){return e?t.messages.filter(r=>r.text.trim()).at(-1)?.text??"":_o(t.messages)}function xf({abortController:t,input:e,resumeSessionId:n,workspace:r}){let o=(e.modelId??"").trim(),i=e.thinking??null,d={abortController:t,allowedTools:["WebSearch","WebFetch"],cwd:r,env:{...process.env,PATH:ir()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return kf.has(o)||(d.model=o),e.effort&&(d.effort=e.effort),i&&i!=="disabled"&&(d.thinking={display:"summarized",type:i==="enabled"?"enabled":"adaptive"}),n?d.resume=n:e.system?.trim()&&(d.systemPrompt=e.system),d}async function Gd(t){let e=jo(t.input,t.resumeSessionId);if(!e)throw new Error("Chat turn has no user text to send.");let n=new AbortController,r=()=>n.abort();t.signal?.addEventListener("abort",r,{once:!0});let o=null,i=null,d=null,c=null,u=null,f=0,v=new Set;try{let $=vf({prompt:e,options:xf({abortController:n,input:t.input,resumeSessionId:t.resumeSessionId,workspace:t.workspace})});for await(let O of $){let T=O;if(T.type==="system"&&T.subtype==="init"){typeof T.session_id=="string"&&(i=T.session_id,t.onEvent({eventType:"chat.session",payload:{sessionId:i,sessionPath:Bd(t.workspace,i)}})),typeof T.model=="string"&&(o=T.model,t.onEvent({eventType:"chat.model",payload:{modelId:T.model}}));continue}if(T.type==="stream_event"){let P=T.event;if(P?.type!=="content_block_delta")continue;let A=P.delta;if(!A)continue;A.type==="text_delta"&&typeof A.text=="string"?(f+=A.text.length,t.onEvent({eventType:"chat.text.delta",payload:{text:A.text}})):A.type==="thinking_delta"&&typeof A.thinking=="string"&&t.onEvent({eventType:"chat.reasoning.delta",payload:{text:A.thinking}});continue}if(T.type==="assistant"){let P=ve(T.message),A=Array.isArray(P.content)?P.content:[];for(let G of A){let N=ve(G);if(N.type!=="tool_use")continue;let D=V(N.id),ue=V(N.name);!D||!ue||v.has(D)||(v.add(D),t.onEvent({eventType:"chat.tool.started",payload:{input:we(N.input),toolCallId:D,toolName:ue}}))}continue}if(T.type==="user"){let P=ve(T.message),A=Array.isArray(P.content)?P.content:[];for(let G of A){let N=ve(G);if(N.type!=="tool_result")continue;let D=V(N.tool_use_id);D&&t.onEvent({eventType:"chat.tool.completed",payload:{...N.is_error===!0?{errorText:typeof N.content=="string"?or(N.content):"Claude tool call failed."}:{},output:we(N.content),toolCallId:D}})}continue}T.type==="result"&&(typeof T.result=="string"&&(c=T.result),T.usage&&typeof T.usage=="object"&&(d=T.usage),typeof T.session_id=="string"&&(i=T.session_id),(T.is_error===!0||T.subtype!=="success")&&(u=typeof T.result=="string"&&T.result||`Claude turn failed (${String(T.subtype)}).`,t.onEvent({eventType:"chat.error",message:u,payload:{message:u}})))}}finally{t.signal?.removeEventListener("abort",r)}if(t.signal?.aborted)throw new Error("Chat turn cancelled.");if(u)throw new Error(u);let I=c??"";f===0&&I&&t.onEvent({eventType:"chat.text.delta",payload:{text:I}});let S=i?Bd(t.workspace,i):null;return{modelId:o,sessionId:i,sessionPath:S&&bf(S)?S:null,text:I,usage:d}}import{spawn as Rf}from"child_process";import{closeSync as Cf,fstatSync as Sf,openSync as Ef,readdirSync as Tf,readSync as Af}from"fs";import{homedir as $f}from"os";import{join as Kd}from"path";import{Codex as Pf}from"@openai/codex-sdk";var Of=["/Applications/Codex.app/Contents/Resources/codex"];async function sr(t){let e=t?[t]:["codex",...Of];for(let n of e){let r=await Df(n);if(r)return{bin:n,version:r}}return null}function Df(t){return new Promise(e=>{let n=Rf(t,["--version"],{env:{...process.env,PATH:ir()},stdio:["ignore","pipe","ignore"]}),r="";n.stdout.on("data",o=>{r+=o.toString("utf8")}),n.on("error",()=>e(null)),n.on("close",o=>{if(o!==0)return e(null);let i=r.trim().split(`
|
|
51
|
+
`)[0]??"";e(i||null)})})}var Nf=24,Lf=4*1024*1024,zd=new Set(["custom_tool_call","custom_tool_call_output","dynamic_tool_call","function_call"]);function Uf(t){let e;try{e=_f(t).split(`
|
|
52
|
+
`)}catch{return[]}let n=new Set,r=new Map,o=null;for(let i of e){if(!i.trim())continue;let d;try{d=JSON.parse(i)}catch{continue}let c=ve(d.payload);if(d.type==="response_item"&&c.type==="custom_tool_call"){let u=V(c.call_id),f=V(c.input);u&&c.name==="exec"&&/\btools\.web__run\s*\(/.test(f)&&(n.add(u),o=u);continue}if(d.type==="event_msg"&&c.type==="web_search_end"){let u=V(c.call_id);if(!u||!o)continue;let f=V(c.query),v=ve(c.action),S={action:{...v,...f&&!V(v.query)?{query:f}:{}},query:f,sources:Wd(c.results),toolCallId:u},$=r.get(o)??[];$.push(S),r.set(o,$);continue}if(d.type==="response_item"&&c.type==="custom_tool_call_output"){let u=V(c.call_id);if(!u||!n.has(u))continue;let f=Wd(c.output);for(let v of r.get(u)??[])v.sources.length===0&&(v.sources=f);o===u&&(o=null)}}return Array.from(r.values()).flat()}function _f(t){let e=Ef(t,"r");try{let n=Sf(e).size,r=Math.max(0,n-Lf),o=Buffer.alloc(n-r);Af(e,o,0,o.length,r);let i=o.toString("utf8");if(r===0)return i;let d=i.indexOf(`
|
|
53
|
+
`);return d===-1?"":i.slice(d+1)}finally{Cf(e)}}function Wd(t){let n=Mo(t).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],r=new Set,o=[];for(let i of n){let d=i.replace(/[.,;:!?]+$/,"");try{let c=new URL(d);if(c.protocol!=="http:"&&c.protocol!=="https:"||r.has(c.href))continue;if(r.add(c.href),o.push({type:"url",url:c.href}),o.length>=Nf)break}catch{}}return o}function Mo(t){return typeof t=="string"?t:Array.isArray(t)?t.map(Mo).join(`
|
|
54
|
+
`):t&&typeof t=="object"?Object.values(t).map(Mo).join(`
|
|
55
|
+
`):""}function Vo(t,e){let n=ve(t),r=V(n.type),o=V(n.id),i=V(n.call_id)||V(n.tool_call_id),d=zd.has(r)?i||o:o||i;if(!d)return null;if(r==="command_execution"){let c=V(n.command),u=V(n.status),f={exitCode:typeof n.exit_code=="number"?n.exit_code:null,output:we(n.aggregated_output)};return{...e&&u==="failed"?{errorText:or(n.aggregated_output)||"Command failed."}:{},input:{command:c},...e?{output:f}:{},toolCallId:d,toolName:"Bash"}}if(r==="mcp_tool_call"){let c=ve(n.error);return{...e&&V(c.message)?{errorText:V(c.message)}:{},input:we(n.arguments),...e?{output:we(n.result??{status:n.status??"completed"})}:{},toolCallId:d,toolName:V(n.tool)||V(n.name)||"Codex tool"}}if(r==="web_search"){let c=V(n.query);return{input:{query:c},...e?{output:{query:c}}:{},toolCallId:d,toolName:"web_search"}}if(r==="file_change"){let c=V(n.status);return{...e&&c==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:we(n.changes)},...e?{output:{changes:we(n.changes),status:c}}:{},toolCallId:d,toolName:"ApplyPatch"}}if(r==="custom_tool_call_output")return{input:{},...e?{output:we(n.output)}:{},toolCallId:d,toolName:"Codex tool"};if(r==="custom_tool_call"||r==="dynamic_tool_call"||r==="function_call"){let c=V(n.name)||V(n.tool)||"Codex tool",u=n.input??n.arguments??{};return{input:c==="exec"&&typeof u=="string"?{command:u}:we(u),...e?{output:we(n.output??n.result??{status:n.status??"completed"})}:{},toolCallId:d,toolName:c}}return null}function qo(t,e=Kd($f(),".codex","sessions")){try{let r=Tf(e,{recursive:!0}).find(o=>typeof o=="string"&&o.endsWith(`${t}.jsonl`));return r?Kd(e,r):null}catch{return null}}function jf(t,e){return e?jo(t,e):_o(t.messages)}function Vf(t,e,n=g.codexSelfConnectorAppId){let r=e.system?.trim(),o={...r?{developer_instructions:r}:{},...n?{apps:{[n]:{enabled:!1}}}:{}};return{codexPathOverride:t,...Object.keys(o).length>0?{config:o}:{}}}var qf=new Set(["minimal","low","medium","high","xhigh"]);function Mf(t,e){let n={networkAccessEnabled:!0,sandboxMode:"workspace-write",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:e},r=(t.modelId??"").trim();return r&&r!=="default"&&(n.model=r),t.effort&&qf.has(t.effort)&&(n.modelReasoningEffort=t.effort),n}async function Hd(t){let e=jf(t.input,t.resumeSessionId);if(!e)throw new Error("Chat turn has no user text to send.");let n=new Pf(Vf(t.bin,t.input)),r=Mf(t.input,t.workspace),o=t.resumeSessionId?n.resumeThread(t.resumeSessionId,r):n.startThread(r),i=t.resumeSessionId??null,d=null,c=null,u=[],f=new Set,v=new Set,I=null,S=T=>{I??=qo(T,t.sessionsRoot),t.onEvent({eventType:"chat.session",payload:{sessionId:T,sessionPath:I}})},$=T=>{i&&(I??=qo(i,t.sessionsRoot));let P=I?Uf(I):[],A=V(ve(T.input).query),G=Jd(A),N=P.find(D=>!f.has(D.toolCallId)&&Jd(D.query)===G)??P.find(D=>!f.has(D.toolCallId));N&&f.add(N.toolCallId),t.onEvent({eventType:"chat.tool.completed",payload:{...T,output:N?{action:N.action,query:N.query,sources:N.sources}:{action:{query:A,type:"search"},sourceListUnavailable:!0,sources:[]}}})},{events:O}=await o.runStreamed(e);i&&S(i);for await(let T of O){if(t.signal?.aborted)throw await O.return?.(void 0),new Error("Chat turn cancelled.");let P=T;if(P.type==="thread.started"){typeof P.thread_id=="string"&&(i=P.thread_id,S(P.thread_id));continue}if(P.type==="item.started"){let A=Vo(P.item,!1);if(A){t.onEvent({eventType:"chat.tool.started",payload:A});let G=ve(P.item);if(zd.has(V(G.type))&&V(G.status)==="completed"){let N=Vo(G,!0);N&&(v.add(N.toolCallId),t.onEvent({eventType:"chat.tool.completed",payload:N}))}}continue}if(P.type==="item.completed"){let A=P.item;if(!A)continue;if(A.type==="agent_message"&&typeof A.text=="string")u.push(A.text),t.onEvent({eventType:"chat.text.delta",payload:{text:A.text}});else if(A.type==="reasoning"&&typeof A.text=="string")t.onEvent({eventType:"chat.reasoning.delta",payload:{text:A.text}});else{let G=Vo(A,!0);G&&(A.type==="web_search"?$(G):A.type==="custom_tool_call"&&v.has(G.toolCallId)||t.onEvent({eventType:"chat.tool.completed",payload:G}))}continue}if(P.type==="turn.completed"){P.usage&&typeof P.usage=="object"&&(d=P.usage);continue}if(P.type==="turn.failed"){let A=P.error;c=typeof A?.message=="string"&&A.message||"Codex turn failed.",t.onEvent({eventType:"chat.error",message:c,payload:{message:c}})}}if(c)throw new Error(c);return i=o.id??i,i&&(I??=qo(i,t.sessionsRoot)),{modelId:t.input.modelId??null,sessionId:i,sessionPath:I,text:u.join(`
|
|
56
|
+
|
|
57
|
+
`),usage:d}}function Jd(t){return t.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as Wf}from"crypto";import{mkdir as Jf}from"fs/promises";import{hostname as cr,platform as zf}from"os";import{join as Hf}from"path";var Tt=class extends Error{constructor(n,r,o=!1){super(n);this.statusCode=r;this.reRegister=o;this.name="RunnerApiError"}statusCode;reRegister};async function At(t,e={}){let n=await ge();e.body!==void 0&&(n["Content-Type"]="application/json");let r=new AbortController,o=setTimeout(()=>r.abort(),e.timeoutMs??3e4),i=()=>r.abort();e.signal?.addEventListener("abort",i,{once:!0});try{let d=await fetch(`${F()}${t}`,{body:e.body!==void 0?JSON.stringify(e.body):void 0,headers:n,method:e.method??"GET",signal:r.signal}),c=await d.text(),u={};try{u=c?JSON.parse(c):{}}catch{u={}}if(!d.ok){let f=Ge(c,d.status);throw new Tt(`[${f.code}] ${f.message}`,d.status,u.reRegister===!0)}return u}finally{clearTimeout(o),e.signal?.removeEventListener("abort",i)}}async function Xd(t){await At("/api/runner/register",{body:t,method:"POST",timeoutMs:15e3})}async function Yd(t,e){return(await At(`/api/runner/work?runnerId=${encodeURIComponent(t)}`,{signal:e,timeoutMs:28e3})).job??null}async function Qd(t){await At("/api/runner/heartbeat",{body:{runnerId:t},method:"POST",timeoutMs:1e4})}async function Zd(t,e){return{cancelRequested:(await At(`/api/runner/jobs/${encodeURIComponent(t)}/events`,{body:{events:e},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function Bo(t,e,n){await At(`/api/runner/jobs/${encodeURIComponent(t)}/complete`,{body:{result:n,runnerId:e},method:"POST",timeoutMs:15e3})}async function dr(t,e,n,r=!0){await At(`/api/runner/jobs/${encodeURIComponent(t)}/fail`,{body:{message:n,retryable:r,runnerId:e},method:"POST",timeoutMs:15e3})}import{mkdirSync as Bf,readFileSync as Ff,writeFileSync as ec}from"fs";import{dirname as Gf,join as Kf}from"path";function Fo(t){return Kf(t,"sessions.json")}function Go(t){try{let e=Ff(Fo(t),"utf8"),n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}return{}}function tc(t,e,n){return e?Go(t)[e]?.[n]??null:null}function nc(t,e,n,r){if(!(!e||!r))try{let o=Fo(t);Bf(Gf(o),{recursive:!0});let i=Go(t);i[e]={...i[e],[n]:r},ec(o,`${JSON.stringify(i,null," ")}
|
|
58
|
+
`,"utf8")}catch{}}function rc(t,e,n){if(e)try{let r=Go(t);if(!r[e])return;delete r[e][n],ec(Fo(t),`${JSON.stringify(r,null," ")}
|
|
59
|
+
`,"utf8")}catch{}}var Xf=300,Yf=3e4;async function oc(t){let[e,n]=await Promise.all([ar(t.claudeBin),sr(t.codexBin)]);if(!e&&!n)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");e?t.log(`Claude Code detected: ${e.version} (${e.bin})`):t.log("Claude Code not found \u2014 Claude turns will be declined."),n?t.log(`Codex detected: ${n.version} (${n.bin})`):t.log("Codex not found \u2014 Codex turns will be declined.");let r=[...e?["claude-code"]:[],...n?["codex"]:[]],o=`${cr().split(".")[0]}-${Wf().slice(0,8)}`,i=()=>Xd({capabilities:["chat_turn","proof"],claudeCodeVersion:e?.version??null,cliVersion:t.version,codexVersion:n?.version??null,hostname:cr(),platform:zf(),runnerId:o,runtimes:r});for(await i(),t.log(`Registered as ${o} (runtimes: ${r.join(", ")}). Waiting for work\u2026`);!t.signal?.aborted;){let d=null;try{d=await Yd(o,t.signal)}catch(c){if(t.signal?.aborted)break;if(c instanceof Tt&&c.reRegister){t.log("Server asked for re-registration."),await i().catch(()=>{});continue}t.log("Work poll failed; retrying\u2026"),await eh(t.pollBackoffMs??5e3,t.signal);continue}if(!d){if(t.once)continue;continue}if(t.log(`Claimed ${d.jobType} job ${d.runId}.`),await Qf({claude:e,codex:n,job:d,options:t,runnerId:o}),t.once)break}}async function Qf({claude:t,codex:e,job:n,options:r,runnerId:o}){let i=new AbortController,d=()=>i.abort();r.signal?.addEventListener("abort",d,{once:!0});let c=setInterval(()=>{Qd(o).catch(()=>{})},Yf),u=[],f=!1,v=async()=>{if(f||u.length===0)return;f=!0;let $=u.splice(0,100);try{let{cancelRequested:O}=await Zd(n.runId,$);O&&i.abort()}catch(O){O instanceof Tt&&O.statusCode===409&&i.abort()}finally{f=!1}},I=setInterval(()=>{v()},Xf),S=$=>{u.push($)};try{if(n.jobType==="runner.proof"){let $=typeof n.input.message=="string"?n.input.message:"proof";S({eventType:"proof.echo",payload:{message:$}}),await Ko(v,u),await Bo(n.runId,o,{echo:$}),r.log(`Proof job ${n.runId} completed.`);return}if(n.jobType==="runner.chat_turn"){let $=n.input.runtime==="codex"?"codex":"claude-code",O=$==="codex"?e&&{detection:e,run:Hd}:t&&{detection:t,run:Gd};if(!O){await dr(n.runId,o,$==="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 T=typeof n.input.chatId=="string"&&n.input.chatId?n.input.chatId:null,P=Hf(r.workspaceRoot,"chats",T??n.runId);await Jf(P,{recursive:!0});let A=Zf(n.input),G=ue=>S({eventType:ue.eventType,message:ue.message??null,payload:ue.eventType==="chat.session"?{host:cr(),runtime:$,runtimeVersion:O.detection.version,...ue.payload??{}}:ue.payload??{}}),N=tc(r.workspaceRoot,T,$),D;try{D=await O.run({bin:O.detection.bin,input:A,onEvent:G,resumeSessionId:N,signal:i.signal,workspace:P})}catch(ue){if(!N||i.signal.aborted)throw ue;r.log(`Resume of ${$} session failed; retrying fresh.`),rc(r.workspaceRoot,T,$),D=await O.run({bin:O.detection.bin,input:A,onEvent:G,resumeSessionId:null,signal:i.signal,workspace:P})}nc(r.workspaceRoot,T,$,D.sessionId),S({eventType:"chat.session",payload:{host:cr(),runtime:$,runtimeVersion:O.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath}}),await Ko(v,u),await Bo(n.runId,o,{modelId:D.modelId,runtime:$,runtimeVersion:O.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath,text:D.text,usage:D.usage??{}}),r.log(`Chat turn ${n.runId} (${$}) completed.`);return}await dr(n.runId,o,`This runner does not support ${n.jobType} jobs. Update the desktop app / CLI.`,!1)}catch{let O="Local runner job crashed.";r.log(`Job ${n.runId} failed: ${O}`),await Ko(v,u).catch(()=>{}),await dr(n.runId,o,O).catch(()=>{})}finally{clearInterval(I),clearInterval(c),r.signal?.removeEventListener("abort",d)}}function Zf(t){let e=Array.isArray(t.messages)?t.messages.map(n=>{if(!n||typeof n!="object")return null;let r=n;return{role:typeof r.role=="string"?r.role:"user",text:typeof r.text=="string"?r.text:""}}).filter(n=>!!n):[];return{effort:typeof t.effort=="string"?t.effort:null,messages:e,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 Ko(t,e){for(;e.length>0;)await t(),e.length>0&&await new Promise(n=>setTimeout(n,25))}function eh(t,e){return t<=0||e?.aborted?Promise.resolve():new Promise(n=>{let r=setTimeout(o,t);function o(){clearTimeout(r),e?.removeEventListener("abort",o),n()}e?.addEventListener("abort",o,{once:!0})})}function oh(){return nh(th(),`.${g.commands[0]}-runner`,"runs")}var lr=new rh("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");lr.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[t,e]=await Promise.all([ar(),sr()]);if(console.log(t?Ee.green(`\u2713 Claude Code ${t.version}`):Ee.red("\u2717 Claude Code not found on PATH")),console.log(e?Ee.green(`\u2713 Codex ${e.version} (${e.bin})`):Ee.red("\u2717 Codex not found (PATH or Codex.app)")),!_e()){console.log(Ee.red(`\u2717 Not logged in. Run '${g.commands[0]} login' first.`)),process.exitCode=2;return}try{let n=await Oe();console.log(Ee.green(`\u2713 Logged in as ${n.user.email}`))}catch{console.log(Ee.red("\u2717 Auth check failed. Please sign in again and retry.")),process.exitCode=2}});lr.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=>{_e()||(console.error(Ee.red(`Not authenticated. Run '${g.commands[0]} login' first.`)),process.exit(2));let e=new AbortController,n=()=>{console.log(Ee.gray(`
|
|
60
|
+
Stopping runner\u2026`)),e.abort()};process.on("SIGINT",n),process.on("SIGTERM",n);try{await oc({claudeBin:t.claudeBin,codexBin:t.codexBin,log:r=>console.log(Ee.gray(`[runner] ${r}`)),once:t.once,signal:e.signal,version:"0.3.26",workspaceRoot:t.workspace??oh()})}catch{console.error(Ee.red("The local runner failed. Check the runner logs and try again.")),process.exit(1)}});import ae from"chalk";import{Command as yS}from"commander";import{Command as Wo}from"commander";import{readFileSync as ih}from"fs";function _(t,e=()=>ih(0,"utf8")){if(t.approvalReceipt&&t.approvalReceiptStdin)throw new C("Pass only one approval receipt input mode.",400);let n=t.approvalReceiptStdin?e().trim():t.approvalReceipt;if(t.approvalReceiptStdin&&!n)throw new C("No approval receipt was provided on stdin.",400);return n}function yn(t,e){return[...e,t]}var ah=new Wo("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",yn,[]).option("--angle <text>","Creative angle (repeat)",yn,[]).option("--cta <text>","Call to action (repeat)",yn,[]).option("--voice <text>","Voice or persona (repeat)",yn,[]).option("--aspect <ratio>","9:16, 1:1, or 16:9 (repeat)",yn,[]).option("--duration <seconds>","Creative duration in seconds",t=>Number.parseInt(t,10)).option("--max-variations <count>","Maximum generated variations",t=>Number.parseInt(t,10)).option("--review-policy <policy>","review or auto_save").option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--branding-id <id>","Branding ID").option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--yes","Approve generation").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to approve generation");try{l(await p("createAdSet",{angles:e.angle.length?e.angle:void 0,approvalReceipt:_(e),aspects:e.aspect.length?e.aspect:void 0,brandingId:e.brandingId,brief:e.brief,ctas:e.cta.length?e.cta:void 0,durationSec:e.duration,hooks:e.hook.length?e.hook:[e.brief],maxVariations:e.maxVariations,reviewPolicy:e.reviewPolicy,style:e.style,teamId:e.teamId,title:t,voices:e.voice.length?e.voice:void 0},e.idempotencyKey))}catch(n){a(m(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),sh=new Wo("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("createAdSet",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),ic=new Wo("ad-set").description("Generate a set of ad creatives (hooks, copy, visuals) from a campaign brief").addCommand(ah).addCommand(sh);import{randomUUID as cc}from"crypto";import{readFileSync as lc}from"fs";import{readFile as ph}from"fs/promises";import{Command as Te}from"commander";import{randomUUID as dh}from"crypto";function je(t,e){a(m(t,e)),process.exit(t instanceof C?t.exitCode:s.GENERAL_ERROR)}function bn(t){return`cli:agent-management:${t}:${dh()}`}function $t(t,e){let n=Number(t);if(!Number.isInteger(n)||n<=0)throw new Error(`${e} must be a positive integer`);return n}import{Command as wn}from"commander";var ch=new wn("list").description("List one roster page: your Agents plus teammates' team-visible Agents").option("--cursor <cursor>","Continue from a previous nextCursor").option("--page-size <n>","Roster rows to return (1-100)","50").option("--team-id <id>","Workspace ID").action(async t=>{try{l(await p("listAgentRoster",{cursor:t.cursor,pageSize:$t(t.pageSize,"--page-size"),teamId:t.teamId}))}catch(e){je(e,"Could not list the Agent roster")}}),lh=new wn("get").description("Read one roster-visible Agent card without private configuration").argument("<agent-id>","Roster-visible Agent UUID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("getRosterAgent",{agentId:t,teamId:e.teamId}))}catch(n){je(n,"Could not read the roster Agent")}}),ac=new wn("roster").description("Discover Agents shared inside the current workspace; never cross-workspace").addCommand(ch).addCommand(lh),mh=new wn("set").description("Share an owned Agent with the workspace or make it private").argument("<agent-id>","Owned scheduled Agent UUID").argument("<visibility>","Desired visibility: private or team",y("visibility",["private","team"])).requiredOption("--expected-visibility <visibility>","Current value from agent roster get: private, team, or legacy public",y("--expected-visibility",["private","team","public"])).option("--idempotency-key <key>","Reuse only for an exact retry of this visibility change").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{try{l(await p("setAgentVisibility",{agentId:t,expectedVisibility:n.expectedVisibility,teamId:n.teamId,visibility:e},n.idempotencyKey?.trim()||bn("visibility")))}catch(r){je(r,"Could not change Agent visibility")}}),sc=new wn("visibility").description("Control whether an owned Agent is private or team-visible").addCommand(mh);function Pt(t,e){return[...e,t]}function uh(t){let e=Number(t);if(!Number.isInteger(e)||e<1)throw new Error("Expected a positive integer.");return e}async function mr(t,e){let n=e.trim(),r=n.startsWith("{")?n:await ph(n,"utf8"),o=JSON.parse(r);if(!o||typeof o!="object"||Array.isArray(o))throw new Error(`${t} must contain one JSON object.`);return o}var gh=new Te("create").description("Activate a reviewed Agent draft; get browser approval, then retry with the same key and receipt.").argument("<draft-id>","Reviewed agent draft UUID").requiredOption("--expected-version <number>","Exact draft version shown during review",uh).requiredOption("--idempotency-key <key>","Stable key bound into the approval receipt and reused on retry").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--yes","Confirm activation intent; this never substitutes for the approval receipt").option("--team-id <id>","Workspace ID").action(async(t,e)=>{e.yes||(a("Pass --yes to request activation. A server-issued approval receipt is still required."),process.exit(s.INVALID_INPUT)),await mc("Agent activation failed",()=>p("createAgent",{approvalReceipt:e.approvalReceipt,draftId:t,expectedVersion:e.expectedVersion,teamId:e.teamId},e.idempotencyKey))}),fh=new Te("recommend").description("Save a private inactive scheduled-agent draft for review; this command never activates or runs it.").argument("<name>","Agent name").requiredOption("--instructions <markdown>","Standing agent instructions").option("--description <text>","Agent description","").option("--goal <text>","User-visible recurring objective").option("--rationale <text>","Why this draft is being recommended").option("--schedule <frequency>","manual, daily, weekdays, weekly, or monthly").option("--schedule-r-rule <rrule>","Precise recurrence rule").option("--schedule-time <hh:mm>","Local run time").option("--timezone <zone>","IANA timezone").option("--schedule-config <json-or-path>","Full schedule configuration as inline JSON or a JSON file").option("--source <connector>","Source connector (repeatable)",Pt,[]).option("--x-handle-target <handle>","Target for the x_handle source").option("--x-search-target <query>","Query for the x_search source").option("--primary-output <adapter>","Legacy primary output fallback").option("--output <adapter>","Output adapter (repeatable)",Pt,[]).option("--output-config <json-or-path>","Full output slot configuration (repeatable)",Pt,[]).option("--delivery-adapter <adapter>","Delivery adapter").option("--delivery-config <json-or-path>","Full delivery configuration as inline JSON or a JSON file").option("--review-policy <policy>","manual_review, auto_send, or draft_only","manual_review").option("--runtime <json-or-path>","Scheduled runtime configuration as inline JSON or a JSON file").option("--sandbox-blueprint-id <id>","Sandbox blueprint UUID").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await mc("Agent recommendation failed",async()=>p("recommendAgent",{deliveryAdapter:e.deliveryAdapter,deliveryConfig:e.deliveryConfig?await mr("--delivery-config",e.deliveryConfig):void 0,description:e.description,goal:e.goal,instructionsMarkdown:e.instructions,name:t,outputAdapter:e.primaryOutput,outputAdapters:e.output.length?e.output:void 0,outputConfigs:e.outputConfig.length?await Promise.all(e.outputConfig.map(n=>mr("--output-config",n))):void 0,rationale:e.rationale,reviewPolicy:e.reviewPolicy,runtime:e.runtime?await mr("--runtime",e.runtime):void 0,sandboxBlueprintId:e.sandboxBlueprintId,schedule:e.schedule,scheduleConfig:e.scheduleConfig?await mr("--schedule-config",e.scheduleConfig):void 0,scheduleRRule:e.scheduleRRule,scheduleTime:e.scheduleTime,sourceConnectors:e.source.length?e.source:void 0,teamId:e.teamId,timezone:e.timezone,xHandleTarget:e.xHandleTarget,xSearchTarget:e.xSearchTarget},e.idempotencyKey??cc()))});async function mc(t,e){try{l(await e())}catch(n){if(n instanceof C){let r=`[${n.errorCode}] `;console.error(JSON.stringify({error:{code:n.errorCode,message:n.message.startsWith(r)?n.message.slice(r.length):n.message,retryable:n.retryable},ok:!1})),process.exit(n.exitCode)}console.error(JSON.stringify({error:{code:"operation_failed",message:m(n,t),retryable:!1},ok:!1})),process.exit(s.GENERAL_ERROR)}}function hh(t,e){return t==="none"?null:$t(t,e)}function yh(t){return t==="none"?null:t}function lt(t,e){let n;try{n=lc(t,"utf8")}catch(r){throw new Error(`${e} could not read ${t}: ${m(r,"unknown file error")}`)}try{return JSON.parse(n)}catch(r){throw new Error(`${e} must point to valid JSON: ${m(r,"invalid JSON")}`)}}function bh(t,e){try{return lc(t,"utf8")}catch(n){throw new Error(`${e} could not read ${t}: ${m(n,"unknown file error")}`)}}var wh=new Te("list").description("List all owned Agents, following cursor pages to closure").option("--cursor <cursor>","Resume from a previous nextCursor").option("--page-size <n>","Rows fetched per page","50").option("--team-id <id>","Workspace ID").action(async t=>{try{let e=[],n=t.cursor;for(;;){let r=await p("listAgents",{cursor:n,pageSize:$t(t.pageSize,"--page-size"),teamId:t.teamId});if(e.push(...r.agents),!r.hasMore||!r.nextCursor)break;n=r.nextCursor}l({agents:e,total:e.length})}catch(e){je(e,"Could not list Agents")}}),vh=new Te("get").description("Read one owned Agent and its complete configuration").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("getAgent",{agentId:t,teamId:e.teamId}))}catch(n){je(n,"Could not read the Agent")}}),Ih=new Te("configure").description("Update Agent configuration; enable automatic external delivery in the browser").argument("<agent-id>","Scheduled Agent UUID").requiredOption("--expected-version <n>","Version returned by agent get").option("--name <text>","Agent name").option("--description <text>","Agent description").option("--goal <text>","Recurring objective").option("--instructions-file <path>","UTF-8 Markdown instructions").option("--schedule-file <path>","Typed schedule JSON document").option("--sources-file <path>","Typed source array JSON document").option("--output-file <path>","Typed primary output JSON document").option("--outputs-file <path>","Typed output array JSON document").option("--delivery-file <path>","Typed delivery JSON document").option("--review-policy <policy>","manual_review, auto_send, or draft_only").option("--runtime-file <path>","Typed runtime JSON document").option("--sandbox-blueprint-id <id|none>","Subscription sandbox blueprint, or none").option("--per-run-credit-cap <credits|none>","Positive credit ceiling, or none").option("--files-file <path>","Typed attached-file array JSON document").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("updateAgentConfiguration",{additionalFiles:e.filesFile?lt(e.filesFile,"--files-file"):void 0,agentId:t,delivery:e.deliveryFile?lt(e.deliveryFile,"--delivery-file"):void 0,description:e.description,expectedVersion:$t(e.expectedVersion,"--expected-version"),goal:e.goal,instructionsMarkdown:e.instructionsFile?bh(e.instructionsFile,"--instructions-file"):void 0,name:e.name,output:e.outputFile?lt(e.outputFile,"--output-file"):void 0,outputs:e.outputsFile?lt(e.outputsFile,"--outputs-file"):void 0,perRunCreditCap:e.perRunCreditCap===void 0?void 0:hh(e.perRunCreditCap,"--per-run-credit-cap"),reviewPolicy:e.reviewPolicy,runtime:e.runtimeFile?lt(e.runtimeFile,"--runtime-file"):void 0,sandboxBlueprintId:e.sandboxBlueprintId===void 0?void 0:yh(e.sandboxBlueprintId),schedule:e.scheduleFile?lt(e.scheduleFile,"--schedule-file"):void 0,sources:e.sourcesFile?lt(e.sourcesFile,"--sources-file"):void 0,teamId:e.teamId},e.idempotencyKey??bn("configure")))}catch(n){je(n,"Could not update the Agent")}});function dc(t){return new Te(t).description(`${t==="pause"?"Pause":"Resume"} an Agent schedule`).argument("<agent-id>","Scheduled Agent UUID").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,n)=>{try{l(await p(t==="pause"?"pauseAgentSchedule":"resumeAgentSchedule",{agentId:e,teamId:n.teamId},n.idempotencyKey??bn(t)))}catch(r){je(r,`Could not ${t} the Agent schedule`)}})}function Jo(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}function kh(t){return`cli:agent-memory:${t}:${cc()}`}function xh(t,e){let n=t.indexOf("="),r=n===-1?t:t.slice(0,n),o=n===-1?"":t.slice(n+1);return[...e,{name:r.trim(),note:o.trim()}]}var Rh=new Te("show").description("Show what a scheduled agent remembers").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("getAgentMemory",{agentId:t,teamId:e.teamId}))}catch(n){Jo(n,"Could not read the agent's memory")}}),Ch=new Te("set").description("Add to or remove from what an agent remembers. Owner or workspace admin only.").argument("<agent-id>","Scheduled Agent UUID").option("--learned <text>","Durable fact to add (repeatable)",Pt,[]).option("--always <text>","Standing instruction to add (repeatable)",Pt,[]).option("--never <text>","Thing it must not do, to add (repeatable)",Pt,[]).option("--track <name=note>","Entity to track, as name=note (repeatable)",xh,[]).option("--notes <text>","Replace the freeform notes").option("--operation <operation>","Mutation operation: add or remove","add").option("--remove-field <field>","Field to remove from: learned, recurringInstructions, negativePreferences, entities, or notes").option("--remove-value <text>","Item to remove; not needed when removing notes").option("--remove <field>","Deprecated alias for --remove-field").option("--value <text>","Deprecated alias for --remove-value").option("--expected-version <n>","Refuse the write unless the stored memory is still at this version").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(t,e)=>{let n=e.removeField??e.remove,r=e.removeValue??e.value,o=e.operation==="remove"||!!n;try{l(await p("updateAgentMemory",{agentId:t,entities:e.track.length?e.track:void 0,expectedVersion:e.expectedVersion===void 0?void 0:Number.parseInt(e.expectedVersion,10),learned:e.learned.length?e.learned:void 0,negativePreferences:e.never.length?e.never:void 0,notes:e.notes,operation:o?"remove":"add",recurringInstructions:e.always.length?e.always:void 0,removeField:n,removeValue:r,teamId:e.teamId},e.idempotencyKey??kh(o?"remove":"add")))}catch(i){Jo(i,"Could not update the agent's memory")}}),Sh=new Te("forget").description("Erase every stored version of an agent's memory. This cannot be undone.").argument("<agent-id>","Scheduled Agent UUID").option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable key bound into the approval receipt and reused on retry").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--yes","Confirm erasure intent; this never substitutes for an approval receipt").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to request erasure. A browser-issued approval receipt is still required.");try{let n=_(e);l(await p("forgetAgentMemory",{approvalReceipt:n,agentId:t,teamId:e.teamId},e.idempotencyKey))}catch(n){Jo(n,"Could not erase the agent's memory")}}),Eh=new Te("memory").description("Read, edit, and erase what a scheduled agent remembers").addCommand(Rh).addCommand(Ch).addCommand(Sh),pc=new Te("agent").description("Recommend, activate, configure, and manage scheduled Agents").addCommand(wh).addCommand(vh).addCommand(ac).addCommand(sc).addCommand(Ih).addCommand(dc("pause")).addCommand(dc("resume")).addCommand(gh).addCommand(fh).addCommand(Eh);import{randomUUID as Th}from"crypto";import{password as Ah}from"@inquirer/prompts";import{Command as pr}from"commander";function zo(t){if(t==="claude-code"||t==="codex")return t;throw new Error("--runtime must be claude-code or codex")}function $h(t,e){let n=t;if(e==="claude-code"&&(n==="zai-claude"||n==="anthropic-compatible")||e==="codex"&&n==="openai-responses-compatible")return n;throw new Error(e==="claude-code"?"--provider must be zai-claude or anthropic-compatible for Claude":"--provider must be openai-responses-compatible for Codex")}async function Ph(){let t="";for await(let e of process.stdin)if(t+=String(e),t.length>65536)throw new Error("Credential input is too large");return t.trim()}var Oh=new pr("add").description("Enroll a provider credential without exposing it in arguments").requiredOption("--runtime <runtime>","claude-code or codex").requiredOption("--provider <provider>","zai-claude, anthropic-compatible, or openai-responses-compatible").requiredOption("--label <name>","Profile name shown in Mindframes").requiredOption("--model <model-id>","Provider model id").option("--base-url <url>","Public HTTPS provider base URL").option("--api-key-stdin","Read the provider key from stdin instead of a hidden prompt").option("--use","Select the new profile immediately").action(async t=>{try{let e=zo(t.runtime),n=$h(t.provider,e);if(!t.apiKeyStdin&&!process.stdin.isTTY)throw new Error("Non-interactive enrollment requires --api-key-stdin. Never pass provider keys as command arguments.");let r=t.apiKeyStdin?await Ph():(await Ah({mask:"*",message:"Provider API key:"})).trim();if(!r)throw new Error("Provider API key is required");let o=await ds({apiKey:r,...t.baseUrl?{baseUrl:t.baseUrl}:{},label:t.label,makeDefault:t.use??!1,modelId:t.model,provider:n,runtime:e});k(`Saved connection profile ${o.label} (${o.id})`)}catch(e){a(m(e,"Profile enrollment failed")),process.exit(s.GENERAL_ERROR)}}),Dh=new pr("list").description("List secret-free Claude Code or Codex connection profiles").requiredOption("--runtime <runtime>","claude-code or codex").action(async t=>{try{let e=zo(t.runtime);l(await p("listAiConnectionProfiles",{runtime:e}))}catch(e){a(m(e,"Profile list failed")),process.exit(s.GENERAL_ERROR)}}),Nh=new pr("select").description("Select a profile UUID, or 'native' for the first-party route").requiredOption("--runtime <runtime>","claude-code or codex").requiredOption("--profile-id <id>","Profile UUID or native").option("--idempotency-key <key>","Reuse only for an exact retry of this profile selection").option("--yes","Confirm changing the active inference route").action(async t=>{t.yes||(a("Pass --yes to confirm changing the active connection profile."),process.exit(s.INVALID_INPUT));try{let e=zo(t.runtime),n=await p("selectAiConnectionProfile",{profileId:t.profileId,runtime:e},t.idempotencyKey?.trim()||Th());k(n.selectedProfileId?`Selected connection profile ${n.selectedProfileId}`:"Selected the native provider route")}catch(e){a(m(e,"Profile selection failed")),process.exit(s.GENERAL_ERROR)}}),uc=new pr("ai-connections").description("Manage Claude Code and Codex inference routes").addCommand(Oh).addCommand(Dh).addCommand(Nh);import{Command as Xo}from"commander";var Ho=["article","document","microsite","presentation","presentationVideo","video"];function gc(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}function Lh(t){if(t===void 0)return;let e=/^\s*(\d+)\s*(?:-\s*(\d+)\s*)?$/.exec(t);e||(a(`--slides expects N or N-M, got "${t}"`),process.exit(s.GENERAL_ERROR));let n=Number(e[1]),r=e[2]===void 0?n:Number(e[2]);return(n<1||r<n)&&(a(`--slides range must start at 1 and end no earlier than it starts, got "${t}"`),process.exit(s.GENERAL_ERROR)),{from:n,to:r}}var Uh=new Xo("read").description("Read an owned artifact's full content").argument("<kind>",`Artifact kind: ${Ho.join(", ")}`).argument("<artifact-id>","Artifact id, or slug where the kind has one").option("--slides <range>","Presentations only: N or N-M. Omit to read every slide.").option("--team-id <id>","Workspace to read from").action(async(t,e,n)=>{Ho.includes(t)||(a(`Unknown artifact kind "${t}". Expected one of: ${Ho.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("readArtifact",{artifactId:e,kind:t,slides:Lh(n.slides),teamId:n.teamId});l(r)}catch(r){gc(r,"Could not read the artifact")}}),_h=new Xo("upload-url").description("Mint a presigned upload target for a file").requiredOption("--file-name <name>","Name of the file to upload").requiredOption("--file-type <type>","MIME type of the file").requiredOption("--file-size <bytes>","Exact size in bytes",t=>{let e=Number(t);return(!Number.isInteger(e)||e<0)&&(a("--file-size expects the exact whole-number byte size."),process.exit(s.GENERAL_ERROR)),e}).requiredOption("--idempotency-key <key>","Stable invocation key; a retry under it re-mints a POST for the same object").option("--team-id <id>","Workspace to mint the upload in").action(async t=>{try{l(await p("createUploadUrl",{fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType,teamId:t.teamId},t.idempotencyKey))}catch(e){gc(e,"Could not mint the upload URL")}}),fc=new Xo("artifact").description("Read artifacts this workspace owns").addCommand(Uh).addCommand(_h);import{randomUUID as gr}from"crypto";import{readFileSync as Kh}from"fs";import{readFile as Wh}from"fs/promises";import mt from"chalk";import{Command as fe}from"commander";import Jh from"ora";import{mkdir as jh,writeFile as hc}from"fs/promises";import{dirname as Vh}from"path";async function de(t,e){if(await jh(Vh(e),{recursive:!0}),t.startsWith("data:")){let o=t.match(/^data:[^;]+;base64,(.+)$/);if(!o)throw new Error("Invalid data URL format");let i=Buffer.from(o[1],"base64");if(i.length===0)throw new Error("Downloaded media was empty");await hc(e,i);return}let n=await fetch(t);if(!n.ok)throw new Error(`Failed to download media: ${n.status}`);let r=Buffer.from(await n.arrayBuffer());if(r.length===0)throw new Error("Downloaded media was empty");await hc(e,r)}import{existsSync as yc}from"fs";import{resolve as qh}from"path";var Mh=/^([A-Za-z][A-Za-z0-9_-]*)=(.+)$/;function Bh(t){let e=t.trim();if(!e)throw new C("A reference image value cannot be empty.",400);if(yc(e))return{source:e};let n=Mh.exec(e);return n?{label:n[1],source:n[2]}:{source:e}}function Fh(t,e,n){if(!t.startsWith("image/")&&t!=="application/octet-stream")throw new C(`Reference image ${e} (${n}) is ${t}, not an image. A reference must be an image; pass an image file or a public image URL.`,400)}function Gh(t,e){let n;try{n=new URL(t)}catch{throw new C(`Reference image ${e} (${t}) must be an existing local file or an HTTP(S) URL.`,400)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new C(`Reference image ${e} (${t}) must use an HTTP(S) URL.`,400);return n}async function ur(t,e){if(t?.length){if(e.maxCount!==void 0&&t.length>e.maxCount)throw new C(`${e.maxCountSubject??"This command"} accepts at most ${e.maxCount} reference images; ${t.length} were provided.`,400);return Promise.all(t.map(async(n,r)=>{let o=r+1,{label:i,source:d}=Bh(n);if(yc(d)){let u=qh(d),f=Rt(u);e.rejectNonImageFiles&&Fh(f,o,d);let v=await ee(u,{idempotencyKey:`${e.idempotencyKey}:reference:${o}`}),I=v.type||f;return{...i?{label:i}:{},...I.startsWith("image/")?{mediaType:I}:{},url:v.url}}let c=Gh(d,o);return{...i?{label:i}:{},url:c.toString()}}))}}var zh=15e3,Hh=40,Xh=3;function Yh(t,e){return[...e,t]}async function Qh(t){let e=t.trim(),n=e.startsWith("[")?e:await Wh(e,"utf8"),r=JSON.parse(n);if(!Array.isArray(r)||r.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new Error("--starter-looks-json must contain one JSON array of objects.");return r}async function bc(t,e){return(await ur(t,{idempotencyKey:e,maxCount:Xh,maxCountSubject:"A presenter Look"}))?.map(r=>({url:r.url}))}function Yo(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.videoUrl??t.requestId);return}w(`Request ID: ${t.requestId}`),w(`Status: ${t.status}`),t.durationSec!=null&&w(`Duration: ${t.durationSec}s`),t.videoUrl&&k(`Video URL: ${t.videoUrl}`),t.error&&a(`Error: ${t.error}`)}var Zh=new fe("options").description("List available presenter avatars and voices").option("--language <language>","Filter voices by language").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{try{let e=await Os(t.language,t.teamId);if(t.format==="json"){l(e);return}let n=e.personal??[];if(t.format==="quiet"){for(let r of n)console.log(r.id);for(let r of e.avatars)console.log(r.id);for(let r of e.voices)console.log(r.id);return}if(n.length>0){w("Your presenters:");for(let r of n)console.log(` ${r.id} ${r.name}`)}w("Avatars:");for(let r of e.avatars){let o=r.renderTiers?.length?` [${r.renderTiers.join(", ")}]`:"";console.log(` ${r.id} ${r.name}${o}`)}w("Voices:");for(let r of e.voices)console.log(` ${r.id} ${r.name}${r.language?` (${r.language})`:""}`)}catch(e){a(m(e,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),ey=new fe("options").description("List personal-presenter engines, prices, supported sources, and exact consent wording").option("--locale <locale>","Consent locale: en, es, hi, ru, or zh","en").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{try{let e=await p("listPresenterCreationOptions",{locale:t.locale,teamId:t.teamId});if(t.format==="json")return l(e);if(t.format==="quiet"){for(let n of e.options)console.log(n.id);return}w(e.canCreate?"Presenter creation is enabled.":"Presenter creation is not enabled for this account.");for(let n of e.options)console.log(`
|
|
61
|
+
${mt.bold(n.label)} ${mt.gray(n.id)}`),console.log(` ${n.description}`),console.log(` Sources: ${n.supportedKinds.join(", ")}`),console.log(` Credits: ${Object.entries(n.creationCredits).map(([r,o])=>`${r}=${o}`).join(", ")}`),console.log(` Consent: ${n.consentCopyText}`)}catch(e){a(m(e,"Options failed")),process.exit(s.GENERAL_ERROR)}}),ty=new fe("create").description("Create a personal presenter after browser-confirmed likeness consent").requiredOption("--name <name>","Presenter name").requiredOption("--engine <id>","Engine id from 'avatar presenter options'").requiredOption("--kind <kind>","Source kind: footage, photo, or prompt").requiredOption("--consent-statement <text>","Exact consent text from 'avatar presenter options'").option("--locale <locale>","Consent locale","en").option("--source <path>","Local footage or headshot file").option("--prompt <text>","Synthetic-persona description").option("--reference-image <path...>","Up to three local prompt reference images",Yh,[]).option("--starter-looks-json <json-or-path>","Optional starter-look array as inline JSON or a JSON file").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key bound into the approval receipt and upload retries").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--yes","Confirm creation intent; this never substitutes for likeness consent").option("--no-wait","Return after the presenter creation run is accepted").action(async t=>{t.yes||(a("Pass --yes to confirm presenter creation intent. Browser-issued likeness approval is still required."),process.exit(s.INVALID_INPUT)),["footage","photo","prompt"].includes(t.kind)||(a("--kind must be footage, photo, or prompt."),process.exit(s.INVALID_INPUT)),t.approvalReceipt&&t.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let e=t.approvalReceiptStdin?Kh(0,"utf8").trim():t.approvalReceipt;t.approvalReceiptStdin&&!e&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let n=t.idempotencyKey??gr();try{if(t.kind==="prompt"&&!t.prompt?.trim())throw new Error("--prompt is required for prompt presenters.");if(t.kind!=="prompt"&&!t.source)throw new Error("--source is required for footage and photo presenters.");if(t.referenceImage.length>3)throw new Error("At most three --reference-image values are allowed.");let r=t.source?await ee(t.source,{idempotencyKey:`${n}:source`,storagePrefix:"presenters"}):void 0,o=await Promise.all(t.referenceImage.map((c,u)=>ee(c,{idempotencyKey:`${n}:reference:${u}`,storagePrefix:"presenters"}))),i=t.starterLooksJson?await Qh(t.starterLooksJson):[],d=await p("createPresenter",{approvalReceipt:e,consentCopyLocale:t.locale,consentCopyText:t.consentStatement,engineId:t.engine,kind:t.kind,name:t.name,...t.prompt?{prompt:t.prompt}:{},...o.length?{referenceImageS3Keys:o.map(c=>c.s3Key)}:{},...r?{s3Key:r.s3Key}:{},starterLooks:i,teamId:t.teamId},n);if(!t.wait){l(d),w(`Check progress with: ${g.commands[0]} avatar presenter status ${d.runId}`);return}l(await Y("createPresenter",d.runId,t.teamId,null))}catch(r){let o=m(r);a(o),o.includes("approval")&&w(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${n}`),process.exit(s.GENERAL_ERROR)}}),ny=new fe("status").description("Read personal-presenter creation status").argument("<run-id>","Durable run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("createPresenter",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),ry=new fe("presenter").description("Discover and create reusable personal presenters").addCommand(ey).addCommand(ty).addCommand(ny),oy=new fe("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("--branding-id <id>","Workspace brand applied to the presenter clip").option("--cast-preset-id <id>","Saved cast preset supplying presenter, backdrop, and voice").option("--captions","Burn provider-generated captions into the clip").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; defaults to the presenter's lowest supported tier").option("--title <title>","Clip title","Presenter clip").option("--strict-branding","Fail when the selected brand cannot be applied completely").option("--idempotency-key <key>","Stable retry key for this presenter clip").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.transparent?"webm":t.outputFormat;!!t.audioUrl==!!t.script&&(a("Provide exactly one avatar speech input: --audio-url or --script"),process.exit(s.INVALID_INPUT)),["1:1","9:16","16:9"].includes(t.aspect)||(a("Aspect must be one of 1:1, 9:16, or 16:9"),process.exit(s.INVALID_INPUT)),t.outputFormat!==void 0&&!["mp4","webm"].includes(t.outputFormat)&&(a("Output format must be mp4 or webm"),process.exit(s.INVALID_INPUT)),t.backgroundColor!==void 0&&!/^#[0-9a-fA-F]{6}$/.test(t.backgroundColor)&&(a("Background color must be a six-digit hex value"),process.exit(s.INVALID_INPUT)),t.backgroundColor&&t.backgroundImageUrl&&(a("Provide only one presenter background"),process.exit(s.INVALID_INPUT)),t.fit!==void 0&&!["contain","cover"].includes(t.fit)&&(a("Fit must be contain or cover"),process.exit(s.INVALID_INPUT)),t.fit&&!t.backgroundImageUrl&&(a("Fit requires --background-image-url"),process.exit(s.INVALID_INPUT)),t.transparent&&t.outputFormat==="mp4"&&(a("--transparent cannot be combined with --output-format mp4"),process.exit(s.INVALID_INPUT)),e==="webm"&&(t.backgroundColor||t.backgroundImageUrl)&&(a("Transparent WebM output cannot be combined with a background"),process.exit(s.INVALID_INPUT)),t.renderTier!==void 0&&!["basic","standard","premium"].includes(t.renderTier)&&(a("Render tier must be basic, standard, or premium"),process.exit(s.INVALID_INPUT));let n=t.duration?Number.parseInt(t.duration,10):void 0;n!==void 0&&(!Number.isFinite(n)||n<1||n>300)&&(a("Duration must be between 1 and 300 seconds"),process.exit(s.INVALID_INPUT));let r=t.format==="human"?Jh("Generating presenter clip...").start():null;try{let o=t.idempotencyKey??gr(),i=t.audioUrl?{audioUrl:t.audioUrl}:{script:t.script??"",...t.voiceId?{voiceId:t.voiceId}:{}},d=await Ds({...i,aspect:t.aspect,...t.avatarId?{avatarId:t.avatarId}:{},...t.backgroundColor?{backgroundHex:t.backgroundColor}:{},...t.backgroundImageUrl?{backgroundImageUrl:t.backgroundImageUrl}:{},...t.brandingId?{brandingId:t.brandingId}:{},...t.castPresetId?{castPresetId:t.castPresetId}:{},...t.captions?{captions:!0}:{},...n!==void 0?{durationSec:n}:{},...t.fit?{fit:t.fit}:{},...e?{outputFormat:e}:{},...t.renderTier?{renderTier:t.renderTier}:{},...t.strictBranding?{strictBranding:!0}:{},title:t.title},o);if(!t.wait){r?.stop(),Yo(d,t.format);return}let c=await be(()=>$o(d.requestId),Hh,zh);if(c.status==="failed")throw new Error(c.error||"Presenter generation failed");if(!c.videoUrl)throw new Error("Presenter generation completed without a video URL");r&&(r.text="Downloading presenter clip..."),await de(c.videoUrl,t.output),r?.stop(),Yo(c,t.format),t.format==="human"&&k(`Saved to: ${t.output}`)}catch(o){r?.stop(),a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),iy=new fe("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{Yo(await $o(t),e.format)}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),ay=new fe("generate").description("Generate another look for an existing personal presenter").argument("<base-profile-id>","Base personal presenter id (pp_*)").requiredOption("--name <name>","Look name").requiredOption("--description <description>","Short look description").requiredOption("--prompt <prompt>","Exact appearance generation prompt").requiredOption("--look-id <id>","Stable template/look id").option("--reference-image <path-or-url...>","Up to three local images or URLs for location, outfit, or style guidance").option("--idempotency-key <key>","Stable retry key for this look request").action(async(t,e)=>{try{let n=e.idempotencyKey??gr(),r=await bc(e.referenceImage,n),o=await p("generatePresenterLook",{baseProfileId:t,description:e.description,id:e.lookId,prompt:e.prompt,...r?{referenceImages:r}:{},title:e.name},n);l(o)}catch(n){a(m(n,"Look generation failed")),process.exit(s.GENERAL_ERROR)}}),sy=new fe("status").description("Read presenter look generation status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await x("generatePresenterLook",t);if(e.format==="json")return l(n);if(e.format==="quiet")return console.log(n.status);w(`Run ID: ${t}`),w(`Status: ${n.status}`),n.error&&a(re(n.error))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),dy=new fe("revise").description("Create a new Look by editing an existing presenter Look").argument("<look-id>","Ready presenter Look id (pp_*)").requiredOption("--instruction <instruction>","What to add, remove, or change").option("--reference-image <path-or-url...>","Up to three local images or URLs for location, outfit, or style guidance").option("--idempotency-key <key>","Stable retry key for this revision").action(async(t,e)=>{try{let n=e.idempotencyKey??gr(),r=await bc(e.referenceImage,n),o=await p("revisePresenterLook",{instruction:e.instruction,...r?{referenceImages:r}:{},sourceLookId:t},n);l(o)}catch(n){a(m(n,"Look revision failed")),process.exit(s.GENERAL_ERROR)}}),cy=new fe("revision-status").description("Read presenter Look revision status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await x("revisePresenterLook",t);if(e.format==="json")return l(n);if(e.format==="quiet")return console.log(n.status);w(`Run ID: ${t}`),w(`Status: ${n.status}`),n.error&&a(re(n.error))}catch(n){a(m(n,"Revision status failed")),process.exit(s.GENERAL_ERROR)}}),ly=new fe("look").description("Manage looks under an existing personal presenter").addCommand(ay).addCommand(dy).addCommand(cy).addCommand(sy),Qo=new fe("avatar").description("Generate presenter clips and looks; avatar options lists the voices and looks used by presentation video presenter and cast preset").addCommand(Zh).addCommand(ry).addCommand(oy).addCommand(ly).addCommand(iy);Qo.addHelpText("after",`
|
|
62
|
+
${mt.bold("Examples:")}
|
|
63
|
+
${mt.gray("# Discover the presenter avatars and voices you can use")}
|
|
64
|
+
$ ${g.commands[0]} avatar options
|
|
65
|
+
|
|
66
|
+
${mt.bold("See also:")}
|
|
67
|
+
${mt.gray("# Save a presenter + backdrop + voice combination under a name")}
|
|
68
|
+
$ ${g.commands[0]} cast preset --help
|
|
69
|
+
|
|
70
|
+
${mt.gray("# Apply an avatar, look, or preset to one presentation-video scene")}
|
|
71
|
+
$ ${g.commands[0]} presentation video presenter <project-id>
|
|
72
|
+
`);import{randomUUID as av}from"crypto";import{readFileSync as sv}from"fs";import{writeFile as dv}from"fs/promises";import z from"chalk";import{Command as Mt,InvalidArgumentError as Dl}from"commander";import cv from"ora";import{createHash as Ey}from"crypto";import{Command as xn,InvalidArgumentError as kn}from"commander";import{createHash as hy}from"crypto";import{existsSync as yy,readFileSync as by}from"fs";import{basename as wy}from"path";import{Command as vy,InvalidArgumentError as vn}from"commander";import Iy from"ora";import{createHash as my}from"crypto";import{Command as py,InvalidArgumentError as wc}from"commander";var uy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gy(t){if(!uy.test(t))throw new wc("brand-id expects a UUID from `mf branding list`.");return t}function fy(t){let e=Number(t);if(!Number.isInteger(e)||e<1)throw new wc("--file-size expects the exact positive whole-number byte size.");return e}async function ei(t){let{idempotencyKey:e,...n}=t;return p("createBrandAssetUploadUrl",n,e)}function Zo(t){if(t===void 0)return"";if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(Zo).join(",")}]`;let e=t;return`{${Object.keys(e).filter(n=>e[n]!==void 0).sort().map(n=>`${JSON.stringify(n)}:${Zo(e[n])}`).join(",")}}`}function ti(t){return my("sha256").update(`createBrandAssetUploadUrl:${Zo(t)}`).digest("hex").slice(0,32)}var vc=new py("upload-url").description("Mint a short-lived brand-scoped storage POST; this does not upload bytes").argument("<brand-id>","Brand UUID you may manage",gy).requiredOption("--file-name <name>","Original filename used in storage content disposition").requiredOption("--file-type <mime>","Exact MIME type that the storage POST will send").requiredOption("--file-size <bytes>","Exact byte size, 1-104857600",fy).option("--idempotency-key <key>","Stable retry key; defaults to a hash of brand and complete file metadata").option("--team-id <id>","Workspace ID; defaults to the selected workspace").addHelpText("after","\nNext: POST every returned field plus the file to uploadUrl, then run `mf branding asset register` with fileUrl, MIME type, and size.\n").action(async(t,e)=>{await b();try{l(await ei({brandId:t,...e,idempotencyKey:e.idempotencyKey??ti({brandId:t,fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType})}))}catch(n){a(m(n,"Brand asset upload URL creation failed")),process.exit(s.GENERAL_ERROR)}});var ky=["footage","image","before_after","logo","audio"],xy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ry(t){if(!xy.test(t))throw new vn("brand-id expects a UUID from `mf branding list`.");return t}function Ic(t){return e=>{let n=Number(e);if(!Number.isInteger(n)||n<0)throw new vn(`${t} expects a whole number of 0 or more.`);return n}}function Cy(t){let e=Number(t);if(!Number.isFinite(e)||e<0)throw new vn("--duration-sec expects a number of 0 or more.");return e}function Sy(t){let e;try{e=JSON.parse(t)}catch{throw new vn("--metadata expects valid JSON.")}if(!e||typeof e!="object"||Array.isArray(e))throw new vn("--metadata expects a JSON object.");return e}var kc=new vy("upload").description("Upload one local file, register it on a brand, and print the asset JSON").argument("<brand-id>","Brand UUID",Ry).requiredOption("--file <path>","Local file to upload through Mindframes storage").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",y("--kind",ky)).option("--label <text>","Display label; defaults to the local filename").option("--width <px>","Image or video width in pixels",Ic("--width")).option("--height <px>","Image or video height in pixels",Ic("--height")).option("--duration-sec <n>","Audio or video duration in seconds",Cy).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",y("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',Sy).option("--idempotency-key <key>","Retry key; defaults to a hash of file bytes and complete registration input").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b(),yy(e.file)||(a(`File not found: ${e.file}`),process.exit(s.INVALID_INPUT)),e.kind==="before_after"&&(!e.role||!e.setKey)&&(a("--kind before_after requires both --role and --set-key."),process.exit(s.INVALID_INPUT)),e.kind!=="before_after"&&(e.role||e.setKey)&&(a("--role and --set-key are only valid with --kind before_after."),process.exit(s.INVALID_INPUT));let n=hy("sha256").update(by(e.file)).digest("hex"),r=at(e.file),o={brandId:t,contentHash:n,durationSec:e.durationSec,fileName:r.fileName,fileSize:r.fileSize,fileType:r.fileType,height:e.height,kind:e.kind,label:e.label===void 0?r.fileName:e.label.trim(),metadata:e.metadata,role:e.role,setKey:e.setKey,width:e.width},i=e.idempotencyKey??ti(o),d=Iy({text:`Uploading ${wy(e.file)}...`,stream:process.stderr}).start();try{let c=await ei({brandId:t,...r,idempotencyKey:i,teamId:e.teamId}),u=await st(e.file,c);d.succeed("Uploaded"),l(await p("registerBrandAsset",{brandId:t,durationSec:e.durationSec,height:e.height,kind:e.kind,label:o.label,metadata:e.metadata,mimeType:u.type,role:e.role,s3Key:u.s3Key,setKey:e.setKey,sizeBytes:u.size,teamId:e.teamId,url:u.url,width:e.width},i))}catch(c){d.fail("Asset upload failed"),a(m(c,"Asset upload failed")),process.exit(s.GENERAL_ERROR)}});var xc=["footage","image","before_after","logo","audio"],Ty=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ot(t){return e=>{if(!Ty.test(e))throw new kn(`${t} expects a UUID from \`mf branding list\` or \`mf branding asset list\`.`);return e}}function In(t,e){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e)throw new kn(`${t} expects a whole number from ${e} upward.`);return r}}function Ay(t){return e=>{let n=Number(e);if(!Number.isFinite(n)||n<0)throw new kn(`${t} expects a number of 0 or more.`);return n}}function $y(t){let e;try{e=JSON.parse(t)}catch(n){throw new kn(`--metadata expects JSON: ${m(n)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new kn("--metadata expects a JSON object.");return e}function ni(t){return Ey("sha256").update(t).digest("hex").slice(0,32)}function fr(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var Py=new xn("list").description("List one brand's uploaded assets and print stable asset IDs").argument("<brand-id>","Brand UUID",Ot("brand-id")).option("--kind <kind>","Filter: footage | image | before_after | logo | audio",y("--kind",xc)).option("--limit <count>","Caller-selected page size; omit to return every matching asset",In("--limit",1)).option("--offset <count>","Matching assets to skip before returning results (default: 0)",In("--offset",0)).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandAssets",{brandId:t,...e.kind?{kind:e.kind}:{},...e.limit?{limit:e.limit}:{},...e.offset!==void 0?{offset:e.offset}:{},teamId:e.teamId}))}catch(n){fr(n,"Asset list failed")}}),Oy=new xn("register").description("Register one app-owned upload from its exact URL, key, MIME, and metadata").argument("<brand-id>","Brand UUID",Ot("brand-id")).requiredOption("--url <url>","Final app-owned file URL returned by the upload step").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",y("--kind",xc)).option("--label <text>","Optional display label, up to 160 characters").requiredOption("--mime-type <type>","Exact MIME type returned by the upload step; verified against storage").option("--s3-key <key>","Optional storage key; when set it must match the URL and upload owner").option("--size-bytes <n>","Expected byte size; when set it must match storage",In("--size-bytes",0)).option("--width <px>","Image or video width in pixels",In("--width",0)).option("--height <px>","Image or video height in pixels",In("--height",0)).option("--duration-sec <n>","Audio or video duration in seconds",Ay("--duration-sec")).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",y("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',$y).option("--idempotency-key <key>","Retry key; defaults to a hash of the complete registration input").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b(),e.kind==="before_after"&&(!e.role||!e.setKey)&&(a("--kind before_after requires both --role and --set-key."),process.exit(s.INVALID_INPUT)),e.kind!=="before_after"&&(e.role||e.setKey)&&(a("--role and --set-key are only valid with --kind before_after."),process.exit(s.INVALID_INPUT));let n={brandId:t,durationSec:e.durationSec,height:e.height,kind:e.kind,label:e.label,metadata:e.metadata,mimeType:e.mimeType,role:e.role,s3Key:e.s3Key,setKey:e.setKey,sizeBytes:e.sizeBytes,teamId:e.teamId,url:e.url,width:e.width},r=e.idempotencyKey??ni(`registerBrandAsset:${JSON.stringify(n)}`);try{l(await p("registerBrandAsset",n,r))}catch(o){fr(o,"Asset registration failed")}}),Dy=new xn("rename").description("Rename one asset, then print its stored label and metadata").argument("<asset-id>","Asset UUID from `mf branding asset list`",Ot("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Ot("--brand")).requiredOption("--label <text>","New non-empty label, up to 160 characters").option("--idempotency-key <key>","Retry key; defaults to a hash of asset ID and label").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();let n=e.label.trim();n||(a("--label cannot be empty."),process.exit(s.INVALID_INPUT));try{l(await p("renameBrandAsset",{assetId:t,brandId:e.brand,label:n,teamId:e.teamId},e.idempotencyKey??ni(`renameBrandAsset:${t}:${n}`)))}catch(r){fr(r,"Asset rename failed")}}),Ny=new xn("delete").description("Remove one asset record from the brand while keeping its uploaded file").argument("<asset-id>","Asset UUID from `mf branding asset list`",Ot("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Ot("--brand")).option("--yes","Confirm removal from the brand library without an interactive prompt").option("--idempotency-key <key>","Retry key; defaults to a stable hash of the asset ID").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b(),e.yes||(a("Refusing removal from the brand library without --yes."),process.exit(s.INVALID_INPUT));try{l(await p("deleteBrandAsset",{assetId:t,brandId:e.brand,teamId:e.teamId},e.idempotencyKey??ni(`deleteBrandAsset:${t}`)))}catch(n){fr(n,"Asset deletion failed")}}),Rc=new xn("asset").description("List, upload, rename, and remove a brand's private asset library").addCommand(Py).addCommand(Oy).addCommand(vc).addCommand(kc).addCommand(Dy).addCommand(Ny);import{Command as Cc,InvalidArgumentError as Ly}from"commander";var Uy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,_y=["presentation","reel","story","video","walkthrough","slide","microsite","article"];function jy(t){if(!Uy.test(t))throw new Ly("Expected a brand UUID from `mf branding list`.");return t}var Vy=new Cc("resolve").description("Resolve design tokens, node trace, rules, and conflicts").argument("<brand-id>","Brand UUID",jy).requiredOption("--artifact <type>","Artifact type",y("--artifact",[..._y])).option("--channel <name>","Channel condition").option("--audience <name>","Audience condition").option("--product <name>","Product condition").option("--locale <name>","Locale condition").option("--market <name>","Market condition").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();let n={artifactType:e.artifact,brandId:t,teamId:e.teamId};for(let r of["audience","channel","locale","market","product"])e[r]!==void 0&&(n[r]=e[r]);try{l(await p("resolveBrandDesign",n))}catch(r){a(m(r,"Brand design resolve failed")),process.exit(s.GENERAL_ERROR)}}),Sc=new Cc("design").description("Inspect resolved brand design state").addCommand(Vy);import{createHash as qy,randomUUID as My}from"crypto";import{Command as Ve,InvalidArgumentError as Ec}from"commander";var By=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Rn(t){if(!By.test(t))throw new Ec("Expected a brand UUID from `mf branding list`.");return t}function Fy(t){if(t==="true")return!0;if(t==="false")return!1;throw new Ec("--show expects true or false.")}function hr(t,e){return qy("sha256").update(JSON.stringify([t,e])).digest("hex").slice(0,32)}function Dt(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var Gy=new Ve("set").description("Create or update one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",Rn).argument("<role>","Custom role without the color. prefix").argument("<hex>","Three- or six-digit hex colour, for example #114b97").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from the complete change when omitted").action(async(t,e,n,r)=>{await b();let o={brandId:t,hex:n,role:e,teamId:r.teamId};try{l(await p("setBrandCustomColor",o,r.idempotencyKey??hr("setBrandCustomColor",o)))}catch(i){Dt(i,"Custom colour update failed")}}),Ky=new Ve("delete").description("Remove one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",Rn).argument("<role>","Custom role without the color. prefix").option("--yes","Confirm removal without an interactive prompt").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from brand and role when omitted").action(async(t,e,n)=>{await b(),n.yes||(a("Refusing to remove a custom colour without --yes."),process.exit(s.INVALID_INPUT));let r={brandId:t,role:e,teamId:n.teamId};try{l(await p("deleteBrandCustomColor",r,n.idempotencyKey??hr("deleteBrandCustomColor",r)))}catch(o){Dt(o,"Custom colour removal failed")}}),Wy=new Ve("sync").description("Synchronize current brand data into the canonical brand graph").argument("<brand-id>","Brand UUID",Rn).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; a new one is minted when omitted").action(async(t,e)=>{await b();let n={brandId:t,teamId:e.teamId};try{let r=await p("syncBrandFoundation",n,e.idempotencyKey??hr("syncBrandFoundation",[n,My()]));l(e.wait===!1?r:await Hs(r.runId,e.teamId))}catch(r){Dt(r,"Brand foundation sync failed")}}),Jy=new Ve("sync-status").description("Read a brand foundation sync run").argument("<run-id>","Run ID from `branding foundation sync --no-wait`").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await x("syncBrandFoundation",t,e.teamId))}catch(n){Dt(n,"Brand foundation sync status failed")}}),Tc=new Ve("foundation").description("Manage atomic Foundation settings backed by the brand DAG").addCommand(new Ve("color").description("Manage custom colour roles").addCommand(Gy).addCommand(Ky)).addCommand(Wy).addCommand(Jy),zy=new Ve("get").description("Read the complete current footer and its source").argument("<brand-id>","Brand UUID",Rn).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("getBrandFooter",{brandId:t,teamId:e.teamId}))}catch(n){Dt(n,"Footer read failed")}}),Hy=new Ve("set").description("Patch footer text, visibility, or alignment atomically").argument("<brand-id>","Brand UUID",Rn).option("--text <text>","Complete footer text; pass an empty string to clear it").option("--show <boolean>","Whether artifacts show the footer: true | false",Fy).option("--alignment <value>","Footer alignment: left | center | right",y("--alignment",["left","center","right"])).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--idempotency-key <key>","Stable retry key; derived from the complete patch when omitted").action(async(t,e)=>{await b(),e.alignment===void 0&&e.show===void 0&&e.text===void 0&&(a("Pass at least one of --text, --show, or --alignment."),process.exit(s.INVALID_INPUT));let n={alignment:e.alignment,brandId:t,show:e.show,teamId:e.teamId,text:e.text};try{l(await p("setBrandFooter",n,e.idempotencyKey??hr("setBrandFooter",n)))}catch(r){Dt(r,"Footer update failed")}}),Ac=new Ve("footer").description("Read or update the brand footer").addCommand(zy).addCommand(Hy);import{createHash as Xy}from"crypto";import{Command as $c}from"commander";var Yy=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Qy(t){Yy.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Zy(t){return Xy("sha256").update(t).digest("hex").slice(0,32)}function Pc(t,e){try{return JSON.parse(e)}catch(n){a(`${t} is not valid JSON: ${m(n)}`),process.exit(s.INVALID_INPUT)}}function eb(t,e){let n=Pc(t,e);return Array.isArray(n)||(a(`${t} must be a JSON array of gradients, e.g. '[{"id":"dawn","type":"linear","stops":[{"color":"#155DAC","position":0},{"color":"#0B2C52","position":100}]}]'.`),process.exit(s.INVALID_INPUT)),n}function tb(t,e){let n=Pc(t,e);return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${t} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}var nb=new $c("set").description("Replace a brand's gradient library (whole-set: omitted gradients are deleted)").argument("<brand-id>","Brand profile ID").requiredOption("--gradients <json>",`The complete gradient list as JSON, e.g. '[{"id":"dawn","name":"Dawn","type":"linear","angle":135,"stops":[{"color":"#155DAC","position":0},{"color":"#0B2C52","position":100}]}]'. Gradients you omit are DELETED.`).option("--roles <json>",`Role pointers by gradient id, e.g. '{"primary":"dawn"}'. Omit to leave the brand's current roles alone.`).option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Qy(t);let n={brandId:t,gradients:eb("--gradients",e.gradients),teamId:e.teamId};e.roles!==void 0&&(n.gradientRoles=tb("--roles",e.roles));try{l(await p("setBrandGradients",n,Zy(`setBrandGradients:${t}:${JSON.stringify(n)}`)))}catch(r){a(m(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),Oc=new $c("gradient").description("Brand gradient library commands").addCommand(nb);import{createHash as rb}from"crypto";import{Command as pt}from"commander";var ob=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cn(t){ob.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ib(t,e=[]){return[...e,t]}function oi(t){return rb("sha256").update(t).digest("hex").slice(0,32)}function ri(t,e){if(e==="true")return!0;if(e==="false")return!1;a(`${t} must be true or false; got "${e}".`),process.exit(s.INVALID_INPUT)}function Dc(t,e){try{return JSON.parse(e)}catch{a(`${t} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}var ab=new pt("get").description("Read a brand's guardrail rules").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Cn(t);try{l(await p("getBrandGuardrails",{brandId:t,teamId:e.teamId}))}catch(n){a(m(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),sb=new pt("test").description("Report brand rule violations; exits non-zero when the report is blocked").argument("<brand-id>","Brand profile ID").option("--content <text>","The content to check").option("--channel <channel>","Channel the content is for, e.g. deck-16-9").option("--market <market>","Market the content is for, e.g. US").option("--artifact-type <type>","Artifact type, e.g. presentation").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Cn(t),e.content===void 0&&(a("Pass --content with the text to check."),process.exit(s.INVALID_INPUT));let n={brandId:t,content:e.content,teamId:e.teamId};e.channel!==void 0&&(n.channel=e.channel),e.market!==void 0&&(n.market=e.market),e.artifactType!==void 0&&(n.artifactType=e.artifactType);try{let r=await p("testBrandGuardrails",n);l(r),r.passed===!1&&process.exit(s.GENERAL_ERROR)}catch(r){a(m(r,"Test failed")),process.exit(s.GENERAL_ERROR)}}),db=new pt("set").description("Create or update one of a brand's guardrail rules").argument("<brand-id>","Brand profile ID").option("--name <text>","Human-readable name for the rule").option("--category <category>","language | compliance | channel-requirements | accessibility | asset-usage").option("--severity <severity>","shadow | warn | block (report severity; does not prevent artifact generation)").option("--require <json>",`What the rule demands, as JSON, e.g. '{"component":"banned-phrase","text":"cheap"}'`).option("--conditions <json>",`When the rule applies, as JSON, e.g. '{"op":"AND","clauses":[{"field":"channel","op":"is","values":["deck-16-9"]}]}'`).option("--enabled <bool>","true or false; defaults to true").option("--node-key <key>","Key of an existing rule to UPDATE, as `guardrails get` lists it. Omit to create.").option("--notes <text>","Notes about the rule").option("--slug <slug>","Explicit kebab-case slug for a new rule").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Cn(t),(!e.name||!e.category||!e.severity)&&(a("Pass --name, --category and --severity."),process.exit(s.INVALID_INPUT)),e.require===void 0&&(a(`Pass --require, e.g. '{"component":"banned-phrase"}'.`),process.exit(s.INVALID_INPUT));let n={brandId:t,category:e.category,name:e.name,require:Dc("--require",e.require),severity:e.severity,teamId:e.teamId};e.conditions!==void 0&&(n.conditions=Dc("--conditions",e.conditions)),e.enabled!==void 0&&(n.enabled=ri("--enabled",e.enabled)),e.nodeKey!==void 0&&(n.nodeKey=e.nodeKey),e.notes!==void 0&&(n.notes=e.notes),e.slug!==void 0&&(n.slug=e.slug),e.publish!==void 0&&(n.publish=ri("--publish",e.publish));try{l(await p("setBrandGuardrail",n,oi(`setBrandGuardrail:${t}:${JSON.stringify(n)}`)))}catch(r){a(m(r,"Write failed")),process.exit(s.GENERAL_ERROR)}}),cb=new pt("delete").description("Remove one of a brand's guardrail rules").argument("<brand-id>","Brand profile ID").argument("<node-key>","Key of the rule, as `guardrails get` lists it").option("--publish <bool>","Publish a brand snapshot after the removal; defaults to true").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{await b(),Cn(t);let r={brandId:t,nodeKey:e,teamId:n.teamId};n.publish!==void 0&&(r.publish=ri("--publish",n.publish));try{l(await p("deleteBrandGuardrail",r,oi(`deleteBrandGuardrail:${t}:${e}`)))}catch(o){a(m(o,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),lb=new pt("generate").description("Draft guardrail rule proposals for a brand").argument("<brand-id>","Brand profile ID").option("--brand-name <name>","Brand name to draft rules for").option("--channel <channel>","Channel the brand publishes to; repeat for several. At least one is required.",ib).option("--brand-description <text>","What the brand does").option("--brand-voice <text>","How the brand sounds").option("--industry <text>","Industry the brand operates in").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Cn(t),e.brandName||(a("Pass --brand-name."),process.exit(s.INVALID_INPUT)),e.channel?.length||(a("Pass at least one --channel to scope the proposed rules."),process.exit(s.INVALID_INPUT));let n={activeChannels:e.channel,brandId:t,brandName:e.brandName,teamId:e.teamId};e.brandDescription!==void 0&&(n.brandDescription=e.brandDescription),e.brandVoice!==void 0&&(n.brandVoice=e.brandVoice),e.industry!==void 0&&(n.industry=e.industry);try{let r=await p("generateBrandGuardrails",n,oi(`generateBrandGuardrails:${JSON.stringify(n)}`));if(e.wait===!1){l(r);return}l(await Ws(r.runId,e.teamId))}catch(r){a(m(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),mb=new pt("generate-status").description("Read a brand guardrails generation run").argument("<run-id>","Run ID from `branding guardrails generate --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("generateBrandGuardrails",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Nc=new pt("guardrails").description("Brand guardrail rule commands").addCommand(ab).addCommand(sb).addCommand(db).addCommand(cb).addCommand(lb).addCommand(mb);import{randomUUID as pb}from"crypto";import{readFile as Lc}from"fs/promises";import{Command as ub}from"commander";var Uc=new ub("import").description("Import a workspace brand from a DESIGN.md file").argument("<design-md-file>","Path to the DESIGN.md file").option("--name <name>","Override the brand name in the document").option("--url <url>","Associate a source URL with the imported brand").option("--url-evidence <json-file>","Merge a saved raw URL-extraction JSON response").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key for retrying the same import without creating another brand").action(async(t,e)=>{await b();try{let n=await Lc(t,"utf8"),r=e.urlEvidence?JSON.parse(await Lc(e.urlEvidence,"utf8")):void 0,o=e.idempotencyKey??pb();l(await p("importBrandDesignMd",{designMd:n,name:e.name,teamId:e.teamId,url:e.url,urlExtractedRaw:r},o))}catch(n){a(m(n,"Import failed")),process.exit(s.GENERAL_ERROR)}});import{Command as _c,InvalidArgumentError as jc}from"commander";var gb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function fb(t){if(!gb.test(t))throw new jc("Expected a brand UUID from `mf branding list`.");return t}function hb(t){let e=Number(t);if(!Number.isInteger(e)||e<1||e>50)throw new jc("--limit expects a whole number from 1 to 50.");return e}var yb=new _c("list").description("List recent safe job summaries for one brand").argument("<brand-id>","Brand UUID",fb).option("--limit <count>","Newest jobs to return, 1-50 (default: 20)",hb).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandJobs",{brandId:t,limit:e.limit,teamId:e.teamId}))}catch(n){a(m(n,"Brand job history failed")),process.exit(s.GENERAL_ERROR)}}),Vc=new _c("jobs").description("Inspect brand background activity").addCommand(yb);import{createHash as bb}from"crypto";import{Command as We}from"commander";var wb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Je(t){wb.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Nt(t){return bb("sha256").update(t).digest("hex").slice(0,32)}var qc=new We("create").description("Create an empty workspace brand and print its JSON").argument("<name>","Name for the new brand").option("--parent <brand-id>","File the new brand under this parent").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),e.parent&&Je(e.parent);try{l(await p("createBrand",{name:t,parentBrandingId:e.parent,teamId:e.teamId}))}catch(n){a(m(n,"Create failed")),process.exit(s.GENERAL_ERROR)}}),Mc=new We("star").description("Add a library star, or remove it with --off, and print the result").argument("<brand-id>","Brand profile ID").option("--off","Remove the star instead of adding it").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Je(t);let n=!e.off;try{l(await p("setBrandStar",{brandId:t,starred:n,teamId:e.teamId},Nt(`setBrandStar:${t}:${n}`)))}catch(r){a(m(r,"Star failed")),process.exit(s.GENERAL_ERROR)}});async function vb(t,e){let n=await p("getBrandProfile",{brandId:t,teamId:e.teamId});return typeof n.name=="string"?n.name:t}var Bc=new We("delete").description("Soft-delete a brand after confirmation and print the result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").option("--yes","Confirm soft deletion without an interactive prompt").action(async(t,e)=>{if(await b(),Je(t),!e.yes&&process.stdin.isTTY){let n;try{n=await vb(t,e)}catch(r){a(m(r,"Could not read the brand")),process.exit(s.GENERAL_ERROR)}a(`Refusing to delete "${n}" (${t}) without confirmation. Re-run with --yes to remove this brand from the library.`),process.exit(s.GENERAL_ERROR)}try{l(await p("deleteBrand",{brandId:t,teamId:e.teamId},Nt(`deleteBrand:${t}`)))}catch(n){a(m(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),ii="none",Fc=new We("update").description("Rename with --name or move with --parent; print the updated JSON").argument("<brand-id>","Brand profile ID").option("--name <name>","New name for the brand").option("--parent <brand-id>",`File the brand under this parent, or "${ii}" to detach it`).option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Je(t);let n=e.parent?.toLowerCase()===ii;e.parent!==void 0&&!n&&Je(e.parent),e.name===void 0&&e.parent===void 0&&(a(`Nothing to update. Pass --name to rename this brand, or --parent <brand-id> to move it (--parent ${ii} detaches it).`),process.exit(s.INVALID_INPUT));let r={brandId:t,teamId:e.teamId};e.name!==void 0&&(r.name=e.name),e.parent!==void 0&&(r.parentBrandingId=n?null:e.parent);try{l(await p("updateBrand",r,Nt(`updateBrand:${t}:${e.name??""}:${e.parent??""}`)))}catch(o){a(m(o,"Update failed")),process.exit(s.GENERAL_ERROR)}}),Gc=new We("set-default").description("Use this brand by default for new artifacts and print the result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Je(t);try{l(await p("setDefaultBrand",{brandId:t,teamId:e.teamId},Nt(`setDefaultBrand:${t}`)))}catch(n){a(m(n,"Set default failed")),process.exit(s.GENERAL_ERROR)}}),Kc=new We("approve").description("Approve a reviewed brand for use and print the persisted result").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Je(t);try{let n=await B(e.teamId);l(await p("approveBrand",{brandId:t,teamId:n},Nt(`approveBrand:${n}:${t}`)))}catch(n){a(m(n,"Approve failed")),process.exit(s.GENERAL_ERROR)}}),Wc=new We("onboarding").description("Manage the brand onboarding review state").addCommand(new We("complete").description("Mark onboarding review complete without approving the brand").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),Je(t);try{let n=await B(e.teamId);l(await p("completeBrandOnboarding",{brandId:t,teamId:n},Nt(`completeBrandOnboarding:${n}:${t}`)))}catch(n){a(m(n,"Complete onboarding failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as ai}from"crypto";import{existsSync as Ib,readFileSync as kb}from"fs";import{basename as xb}from"path";import{Command as yr}from"commander";import Rb from"ora";function Cb(t,e,n){return ai("sha256").update(JSON.stringify([t,e,n??null])).digest("hex").slice(0,32)}var Jc=new yr("logo").description("Upload primary, dark-background, and favicon logo files").addCommand(new yr("list").description("List exact logo candidates and identify the active one").argument("<brand-id>","Brand UUID from `mf branding list`").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandLogos",{brandId:t,teamId:e.teamId}))}catch(n){a(m(n,"Logo list failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new yr("remove").description("Remove one exact candidate URL and select its deterministic fallback").argument("<brand-id>","Brand UUID from `mf branding list`").argument("<logo-url>","Exact URL returned by `mf branding logo list`").option("--yes","Confirm exact candidate removal without an interactive prompt").option("--idempotency-key <key>","Stable retry key; derived from brand and URL when omitted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e,n)=>{await b(),n.yes||(a("Refusing to remove a logo candidate without --yes."),process.exit(s.INVALID_INPUT));try{l(await p("removeBrandLogo",{brandId:t,logoUrl:e,teamId:n.teamId},n.idempotencyKey??Cb("removeBrandLogo",t,e)))}catch(r){a(m(r,"Logo removal failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new yr("set").description("Upload one logo variant and print the updated brand JSON").argument("[brand-id]","Brand ID (defaults to this workspace's default brand)").requiredOption("--file <path>","Local image file to upload and use").option("--variant <variant>","primary | dark | favicon. 'dark' is the reversed lock-up for dark backgrounds","primary").option("--idempotency-key <key>","Stable retry key; deterministically derived from workspace, brand, variant, and file bytes when omitted").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();let n=e.variant??"primary";["primary","dark","favicon"].includes(n)||(a(`--variant must be primary, dark, or favicon (got "${n}")`),process.exit(s.INVALID_INPUT)),Ib(e.file)||(a(`File not found: ${e.file}`),process.exit(s.INVALID_INPUT));let r=ai("sha256").update(kb(e.file)).digest("hex"),o=e.idempotencyKey??ai("sha256").update(`setBrandLogo:${e.teamId??"current"}:${t??"default"}:${n}:${r}`).digest("hex").slice(0,32),i=Rb({text:`Uploading ${xb(e.file)}...`,stream:process.stderr}).start(),d;try{d=(await ee(e.file,{idempotencyKey:`${o}:upload`,storagePrefix:"brand-logos"})).url,i.succeed("Uploaded")}catch(c){i.fail("Upload failed"),a(m(c)),process.exit(s.GENERAL_ERROR)}try{l(await p("setBrandLogo",{brandId:t,fileUrl:d,teamId:e.teamId,variant:n},o))}catch(c){a(m(c,"Write failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as Sb,randomUUID as Eb}from"crypto";import{Command as Lt,InvalidArgumentError as br}from"commander";var Tb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Ab=["admin","editor","viewer"],zc=["cancelled","completed","failed","info","queued","running"],Hc=["activity","brand-extraction-request","brand-resolution","brand-sync-job"];function ut(t){return e=>{if(!Tb.test(e))throw new br(`${t} expects a UUID from \`mf branding list\` or the workspace member list.`);return e}}function Yc(t){let e=Number(t);if(!Number.isInteger(e)||e<1||e>200)throw new br("--limit expects a whole number from 1 to 200.");return e}function Xc(t,e){return n=>{let r=n.split(",").map(i=>i.trim()).filter(Boolean);if(r.find(i=>!e.includes(i))||r.length===0)throw new br(`${t} expects comma-separated values from: ${e.join(", ")}.`);return r}}function Qc(t,e){return Sb("sha256").update(JSON.stringify([t,e,Eb()])).digest("hex").slice(0,32)}function Sn(t,e){a(m(t,e)),process.exit(typeof t=="object"&&t!==null&&"exitCode"in t&&typeof t.exitCode=="number"?t.exitCode:s.GENERAL_ERROR)}var $b=new Lt("list").description("List explicit member access overrides for one team brand").argument("<brand-id>","Team brand UUID",ut("brand-id")).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandPermissions",{brandId:t,teamId:e.teamId}))}catch(n){Sn(n,"Brand permission list failed")}}),Pb=new Lt("candidates").description("List member IDs eligible for one team brand's access overrides").argument("<brand-id>","Team brand UUID",ut("brand-id")).option("--query <text>","Search member name, username, or email").option("--limit <count>","Maximum members, 1-200 (default: 50)",Yc).option("--offset <count>","Members to skip (default: 0)",t=>{let e=Number(t);if(!Number.isInteger(e)||e<0)throw new br("--offset expects a whole number of 0 or more.");return e}).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandPermissionCandidates",{brandId:t,limit:e.limit,offset:e.offset,query:e.query,teamId:e.teamId}))}catch(n){Sn(n,"Brand permission candidate list failed")}}),Ob=new Lt("set").description("Set one team member's explicit role for a team brand").argument("<brand-id>","Team brand UUID",ut("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",ut("--user")).requiredOption("--role <role>","Desired override: admin | editor | viewer",y("--role",Ab)).option("--idempotency-key <key>","Explicit retry identity; otherwise a new payload-bound key is minted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("setBrandPermission",{brandId:t,role:e.role,teamId:e.teamId,userId:e.user},e.idempotencyKey??Qc("setBrandPermission",{brandId:t,role:e.role,teamId:e.teamId??null,userId:e.user})))}catch(n){Sn(n,"Brand permission update failed")}}),Db=new Lt("remove").description("Remove one member override so the team role applies again").argument("<brand-id>","Team brand UUID",ut("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",ut("--user")).option("--yes","Confirm this access change without an interactive prompt").option("--idempotency-key <key>","Explicit retry identity; otherwise a new payload-bound key is minted").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b(),e.yes||(a("Refusing to remove a brand access override without --yes."),process.exit(s.INVALID_INPUT));try{l(await p("removeBrandPermission",{brandId:t,teamId:e.teamId,userId:e.user},e.idempotencyKey??Qc("removeBrandPermission",{brandId:t,teamId:e.teamId??null,userId:e.user})))}catch(n){Sn(n,"Brand permission removal failed")}}),Zc=new Lt("permission").description("Administer explicit member access overrides for a team brand").addCommand(Pb).addCommand($b).addCommand(Ob).addCommand(Db),el=new Lt("activity").description("Read a brand's filtered, cursor-paginated activity feed").argument("<brand-id>","Brand UUID",ut("brand-id")).option("--query <text>","Search action, summary, detail, entity, and metadata").option("--status <statuses>",`Comma-separated statuses: ${zc.join(" | ")}`,Xc("--status",zc)).option("--source-type <types>",`Comma-separated sources: ${Hc.join(" | ")}`,Xc("--source-type",Hc)).option("--from <iso-time>","Inclusive ISO-8601 lower time bound").option("--to <iso-time>","Inclusive ISO-8601 upper time bound").option("--limit <count>","Maximum rows, 1-200 (default: 80)",Yc).option("--cursor <cursor>","Opaque nextCursor from the preceding page").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e)=>{await b();try{l(await p("listBrandActivity",{brandId:t,cursor:e.cursor,from:e.from,limit:e.limit,query:e.query,sourceTypes:e.sourceType,statuses:e.status,teamId:e.teamId,to:e.to}))}catch(n){Sn(n,"Brand activity read failed")}});import{createHash as Nb}from"crypto";import{Command as Ut,InvalidArgumentError as di}from"commander";var Lb=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function si(t,e){if(Lb.test(t))return t;throw new di(`${e} must be a UUID.`)}function Ub(t){let e=Number(t);if(Number.isInteger(e)&&e>=1&&e<=50)return e;throw new di("limit must be a whole number from 1 to 50.")}function _b(t){let e=Number(t);if(Number.isInteger(e)&&e>=0)return e;throw new di("offset must be a whole number of 0 or more.")}function jb(t){return Nb("sha256").update(t).digest("hex").slice(0,32)}async function wr(t,e){await b();try{l(await t())}catch(n){a(m(n,e)),process.exit(s.GENERAL_ERROR)}}var tl=new Ut("presentations").description("Inspect presentations already linked to a brand").addCommand(new Ut("list").description("List linked decks with preview, version, stale, and last-sync state").argument("<brand-id>","Brand UUID from `branding list`").option("--limit <n>","Rows to return (1-50; default 50)",Ub,50).option("--offset <n>","Zero-based offset (default 0)",_b,0).option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(t,e)=>{let n=si(t,"brand-id");await wr(()=>p("listBrandPresentations",{brandId:n,limit:e.limit,offset:e.offset,teamId:e.teamId}),"Could not list linked presentations")})),nl=new Ut("presentation").description("Inspect or update one deck from its already-linked brand").addCommand(new Ut("drift").description("Read current, drifted, unknown, or not-linked status and exact changes").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(t,e)=>{await wr(()=>p("getPresentationBrandDrift",{presentationId:t,teamId:e.teamId}),"Could not read presentation brand drift")})).addCommand(new Ut("apply-changes").description("Create a new deck version using its linked brand's current colors, fonts, and logo").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").requiredOption("--idempotency-key <key>","Stable key; reuse it for an exact retry, change it for a later brand update").action(async(t,e)=>{await wr(()=>p("applyPresentationBrandChanges",{presentationId:t,teamId:e.teamId},e.idempotencyKey),"Could not apply linked-brand changes")})),rl=new Ut("sync-cancel").description("Cancel an active bulk linked-deck sync through its durable run; retries are safe").argument("<brand-id>","Brand UUID used to start the sync").argument("<run-id>","Active run UUID from `branding sync --no-wait`").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(t,e,n)=>{let r=si(t,"brand-id"),o=si(e,"run-id");await wr(()=>p("cancelBrandPresentationSync",{brandId:r,runId:o,teamId:n.teamId},jb(`cancelBrandPresentationSync:${r}:${o}`)),"Could not cancel brand sync")});import{createHash as Vb,randomUUID as sl}from"crypto";import{Command as ze}from"commander";var qb=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ol=["product","service","platform","solution"],vr=["candidate","draft","approved"],il=["brand-site","brand-site-scan","brand-site-extract","product-url"];function _t(t){qb.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Ir(t,e,n){if(n.includes(e))return e;a(`${t} must be one of: ${n.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Mb(t,e){let n=Number(e);if(Number.isInteger(n)&&n>0)return n;a(`${t} must be a whole number greater than zero.`),process.exit(s.INVALID_INPUT)}function ci(t){return Vb("sha256").update(t).digest("hex").slice(0,32)}var Bb=new ze("list").description("List the products a brand sells").argument("<brand-id>","Brand profile ID").option("--status <status>",`Only products in this state. One of: ${vr.join(", ")}. Omit for the saved catalogue.`).option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),_t(t),e.status!==void 0&&Ir("--status",e.status,vr);let n={brandId:t,teamId:e.teamId};e.status!==void 0&&(n.status=e.status);try{l(await p("listBrandProducts",n))}catch(r){a(m(r,"List failed")),process.exit(s.GENERAL_ERROR)}}),Fb=new ze("set").description("Create or update one of a brand's products").argument("<brand-id>","Brand profile ID").option("--product <id>","Existing product to update. Omit to create, or to update the product this brand already has at the same --url.").option("--name <name>","Product name (required when creating)").option("--type <type>",`One of: ${ol.join(", ")}`).option("--description <text>","What the product is, in full").option("--summary <text>","Short form of the description").option("--url <url>","The product's page. Also its identity: a url this brand already has updates that product.").option("--status <status>",`One of: ${vr.join(", ")}`).option("--logo-url <url>","Product logo URL").option("--inherits-brand <true|false>","Whether the product presents in the parent brand's design").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),_t(t),e.type!==void 0&&Ir("--type",e.type,ol),e.status!==void 0&&Ir("--status",e.status,vr),e.inheritsBrand!==void 0&&e.inheritsBrand!=="true"&&e.inheritsBrand!=="false"&&(a("--inherits-brand must be true or false."),process.exit(s.INVALID_INPUT));let n={brandId:t,teamId:e.teamId};e.product!==void 0&&(n.productId=e.product),e.name!==void 0&&(n.name=e.name),e.type!==void 0&&(n.type=e.type),e.description!==void 0&&(n.description=e.description),e.summary!==void 0&&(n.summary=e.summary),e.url!==void 0&&(n.url=e.url),e.status!==void 0&&(n.status=e.status),e.logoUrl!==void 0&&(n.logoUrl=e.logoUrl),e.inheritsBrand!==void 0&&(n.inheritsBrand=e.inheritsBrand==="true");try{l(await p("saveBrandProduct",n,ci(`saveBrandProduct:${t}:${e.product??e.url??e.name??"new"}`)))}catch(r){a(m(r,"Save failed")),process.exit(s.GENERAL_ERROR)}}),al=(t,e=[])=>[...e,t],Gb=new ze("select").description("Atomically set approved products in a bounded product set").argument("<brand-id>","Brand profile ID").option("--product <id>","Product whose state to set; repeat for every product in the bounded set.",al).option("--approve <id>","Product from --product that should finish approved; repeat as needed. Others finish draft.",al).option("--idempotency-key <key>","Stable retry key for this selection").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),_t(t),e.product?.length||(a("Pass at least one --product <id> to set product approval."),process.exit(s.INVALID_INPUT));let n={approvedProductIds:e.approve??[],brandId:t,productIds:e.product,teamId:e.teamId};try{l(await p("setBrandProductSelection",n,e.idempotencyKey??sl()))}catch(r){a(m(r,"Selection failed")),process.exit(s.GENERAL_ERROR)}}),Kb=new ze("duplicate").description("Create an independent draft copy of one product").argument("<brand-id>","Brand profile ID").requiredOption("--product <id>","Product ID to duplicate").option("--name <name>","Name for the copy").option("--idempotency-key <key>","Stable retry key for this duplication").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),_t(t);let n={brandId:t,productId:e.product,teamId:e.teamId};e.name!==void 0&&(n.name=e.name);try{l(await p("duplicateBrandProduct",n,e.idempotencyKey??sl()))}catch(r){a(m(r,"Duplicate failed")),process.exit(s.GENERAL_ERROR)}}),Wb=new ze("delete").description("Remove one product from a brand").argument("<brand-id>","Brand profile ID").option("--product <id>","Product ID to remove").option("--team-id <id>","Workspace ID").option("--yes","Skip the confirmation prompt").action(async(t,e)=>{await b(),_t(t),e.product===void 0&&(a("Pass --product <id> to name the product to remove. `branding product list <brand-id>` prints the ids."),process.exit(s.INVALID_INPUT)),!e.yes&&process.stdin.isTTY&&(a(`Refusing to delete product "${e.product}" without confirmation. Re-run with --yes.`),process.exit(s.GENERAL_ERROR));try{l(await p("deleteBrandProduct",{brandId:t,productId:e.product,teamId:e.teamId},ci(`deleteBrandProduct:${t}:${e.product}`)))}catch(n){a(m(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Jb=new ze("extract").description("Discover a brand's products by crawling its site").argument("<brand-id>","Brand profile ID").option("--mode <mode>",`One of: ${il.join(", ")}`).option("--url <url>","Page to extract (product-url), or the site to scan instead of the brand's own recorded URL").option("--max-products <count>","How many pages to take from the scan (max 30)").option("--product <id>","Candidate product to extract; repeat for several. Required for brand-site-extract.",(t,e=[])=>[...e,t]).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),_t(t),e.mode!==void 0&&Ir("--mode",e.mode,il);let n={brandId:t,teamId:e.teamId};e.mode!==void 0&&(n.mode=e.mode),e.url!==void 0&&(n.url=e.url),e.maxProducts!==void 0&&(n.maxProducts=Mb("--max-products",e.maxProducts)),e.product?.length&&(n.productIds=e.product);try{let r=await p("extractBrandProducts",n,ci(`extractBrandProducts:${JSON.stringify(n)}`));if(e.wait===!1){l(r);return}l(await Gs(r.runId,e.teamId))}catch(r){a(m(r,"Extract failed")),process.exit(s.GENERAL_ERROR)}}),zb=new ze("extract-status").description("Read a brand product extraction run").argument("<run-id>","Run ID from `branding product extract --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("extractBrandProducts",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),dl=new ze("product").description("Brand product catalogue commands").addCommand(Bb).addCommand(Fb).addCommand(Gb).addCommand(Kb).addCommand(Wb).addCommand(Jb).addCommand(zb);import{randomUUID as mi}from"crypto";import{Command as Vt}from"commander";import{randomUUID as Hb}from"crypto";import{Command as cl}from"commander";function R(t,e){let n={...e},r=t.parent,o=!1;for(;r;){let i=r.opts?.();if(i){o=!0;for(let[d,c]of Object.entries(i))n[d]===void 0&&c!==void 0&&(n[d]=c)}r=r.parent}return o?n:e}function jt(t){return t._checkForMissingMandatoryOptions=function(){for(let e of this.options)e.mandatory&&this.getOptionValue(e.attributeName())===void 0&&this.missingMandatoryOptionValue(e)},t}var li="listenBrandPronunciations";function ll(t){let e=un(t);if(e)throw new C(e,500);let n=t.output;if(typeof n?.brandId!="string"||!Array.isArray(n.items))throw new C("Pronunciation listening completed without its audio list.",500);let r=n.items.map(o=>{if(!o||typeof o!="object"||!("word"in o)||typeof o.word!="string"||!("audioUrl"in o)||typeof o.audioUrl!="string")throw new C("Pronunciation listening returned an invalid audio entry.",500);return{word:o.word,audioUrl:o.audioUrl}});l({brandId:n.brandId,items:r})}function ml(t,e=""){a(`${m(t,"Pronunciation listening failed")}${e}`);let n=t&&typeof t=="object"&&"exitCode"in t?t.exitCode:void 0;process.exit(typeof n=="number"?n:s.GENERAL_ERROR)}var Xb=new cl("status").description("Read pronunciation listening status and recover its audio URLs").argument("<run-id>","Pronunciation listening run ID").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{let r=R(n,e);await b();try{let o=await x(li,t,r.teamId);o.done?ll(o):l(o)}catch(o){ml(o)}}),pl=new cl("listen").enablePositionalOptions().description("Get audio URLs for all or selected words saved in a brand").argument("<brand-id>","Brand profile ID").option("--words <json>","JSON array of exact dictionary words; omit for all").option("--voice-id <id>","Opaque Mindframes narration voice ID; omit for the workspace default").option("--no-wait","Return the accepted run without waiting for audio").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Reuse a request key to recover this listening").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").addCommand(Xb).action(async(t,e)=>{let n,r;try{if(!t)throw new C("Brand ID is required to start listening.",400,s.INVALID_INPUT);if(e.words!==void 0)try{n=JSON.parse(e.words)}catch{throw new C("--words must be valid JSON.",400,s.INVALID_INPUT)}r=_(e)}catch(d){a(m(d,"Invalid pronunciation listening input.")),process.exit(s.INVALID_INPUT);return}await b();let o=e.idempotencyKey??Hb(),i;try{let d=await p(li,{brandId:t,...e.words!==void 0?{words:n}:{},...e.voiceId!==void 0?{voiceId:e.voiceId}:{},teamId:e.teamId,approvalReceipt:r},o);if(i=d.runId,e.wait===!1){l(d);return}ll(await Y(li,i,e.teamId))}catch(d){ml(Object.assign(new C(te(d,i),500),{exitCode:d&&typeof d=="object"&&"exitCode"in d?d.exitCode:void 0}),` Retry with --idempotency-key ${o}.${i?` Recover with branding pronunciation listen status ${i}.`:""}`)}});async function En(t,e,n){await b();try{l(await p(t,e,n))}catch(r){a(m(r,"Pronunciation command failed"));let o=r&&typeof r=="object"&&"exitCode"in r?r.exitCode:void 0;process.exit(typeof o=="number"?o:s.GENERAL_ERROR)}}var Yb=new Vt("list").description("List the pronunciation rules saved in a brand as JSON").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await En("listBrandPronunciations",{brandId:t,teamId:e.teamId})}),Qb=new Vt("get").description("Read a brand pronunciation rule by its exact, case-sensitive word").argument("<brand-id>","Brand profile ID").argument("<word>","Word or phrase saved in the dictionary (case-sensitive)").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{await En("getBrandPronunciation",{brandId:t,word:e,teamId:n.teamId})}),Zb=new Vt("set").description("Create or replace a brand's pronunciation rule for an exact word").argument("<brand-id>","Brand profile ID").argument("<word>","Word or phrase to pronounce (case-sensitive)").requiredOption("--pronunciation <text>","Desired spoken form of the word").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Reuse a request key to retry this same write").action(async(t,e,n)=>{await En("setBrandPronunciation",{brandId:t,word:e,pronunciation:n.pronunciation,teamId:n.teamId},n.idempotencyKey??mi())}),ew=new Vt("delete").description("Remove a pronunciation rule from a brand by its exact word").argument("<brand-id>","Brand profile ID").argument("<word>","Word or phrase to remove (case-sensitive)").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Reuse a request key to retry this same removal").action(async(t,e,n)=>{await En("deleteBrandPronunciation",{brandId:t,word:e,teamId:n.teamId},n.idempotencyKey??mi())}),tw=new Vt("set-batch").description("Create or replace multiple pronunciation rules in one atomic brand write").argument("<brand-id>","Brand profile ID").requiredOption("--rules <json>","JSON array of word and pronunciation objects").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Reuse a request key to retry this same batch").action(async(t,e)=>{let n;try{n=JSON.parse(e.rules??"")}catch{a("--rules must be valid JSON."),process.exit(s.INVALID_INPUT);return}await En("setBrandPronunciations",{brandId:t,rules:n,teamId:e.teamId},e.idempotencyKey??mi())}),ul=new Vt("pronunciation").description("Manage the words and spoken forms in a brand's pronunciation dictionary").addCommand(Yb).addCommand(Qb).addCommand(Zb).addCommand(tw).addCommand(ew).addCommand(pl);import{createHash as nw}from"crypto";import{Command as kr}from"commander";var rw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gl(t){rw.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ow(t,e=[]){return[...e,t]}function iw(t){return nw("sha256").update(t).digest("hex").slice(0,32)}var aw=new kr("get").description("Read which decks have drifted from a brand").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),gl(t);try{l(await p("getBrandQuality",{brandId:t,teamId:e.teamId}))}catch(n){a(m(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),sw=new kr("repair").description("Repair decks that have visually drifted from a brand").argument("<brand-id>","Brand profile ID").option("--scope <scope>","selected (repair only --deck ids) or all_eligible (repair every drifted deck). Required.").option("--deck <presentation-id>","Deck to repair; repeat for several. Only used with --scope selected.",ow).option("--confirm-partial","Also repair decks whose guidance changed too; they stay flagged as guidance-outdated afterwards.").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),gl(t),e.scope!=="selected"&&e.scope!=="all_eligible"&&(a("Pass --scope selected or --scope all_eligible. There is no default: 'selected' repairs only the decks you name, 'all_eligible' repairs every drifted deck on the brand."),process.exit(s.INVALID_INPUT)),e.scope==="selected"&&!e.deck?.length&&(a("--scope selected needs at least one --deck."),process.exit(s.INVALID_INPUT));let n={brandId:t,scope:e.scope,teamId:e.teamId};e.deck?.length&&(n.presentationIds=e.deck),e.confirmPartial===!0&&(n.confirmedPartialRepair=!0);try{let r=await p("repairBrandQuality",n,iw(`repairBrandQuality:${JSON.stringify(n)}`));if(e.wait===!1){l(r);return}l(await Js(r.runId,e.teamId))}catch(r){a(m(r,"Repair failed")),process.exit(s.GENERAL_ERROR)}}),dw=new kr("repair-status").description("Read a brand quality repair run").argument("<run-id>","Run ID from `branding quality repair --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("repairBrandQuality",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),fl=new kr("quality").description("Brand deck quality commands").addCommand(aw).addCommand(sw).addCommand(dw);function pi(t){return Array.isArray(t.items)}function qe(t){return typeof t=="string"&&t.length>0?t:void 0}function ui(t){return qe(t.resolvedTokens?.logoUrl)??qe(t.brandData?.assets?.logo)??qe(t.brandData?.assets?.logoUrl)??qe(t.brandData?.logoUrl)}function gi(t){return qe(t.resolvedTokens?.colors?.primary)??qe(t.brandData?.colors?.primary)??qe(t.brandData?.enhancedColors?.palette?.[0]?.hex)}function hl(t){let e=t.brandData?.enhancedColors?.palette??t.brandData?.colors?.palette;if(!Array.isArray(e))return[];let n=[];for(let r of e){if(typeof r=="string"){n.push({hex:r});continue}if(r&&typeof r=="object"&&"hex"in r){let{hex:o,role:i}=r;typeof o=="string"&&n.push({hex:o,...typeof i=="string"?{role:i}:{}})}}return n}function cw(t){return{id:t.id,isDefault:t.isDefault,name:t.name,...t.domain?{sourceUrl:t.domain}:{},...t.logoUrl?{logoUrl:t.logoUrl}:{},...t.primaryColor?{primaryColor:t.primaryColor}:{}}}function lw(t){let e=qe(t.extractedFrom)??qe(t.normalizedUrl),n=ui(t),r=gi(t);return{id:t.id,isDefault:t.isDefault,name:t.name,...e?{sourceUrl:e}:{},...n?{logoUrl:n}:{},...r?{primaryColor:r}:{},...t.createdAt?{createdAt:t.createdAt}:{}}}function yl(t){return pi(t)?t.items.map(lw):t.brandings.map(cw)}import{createHash as mw}from"crypto";import{Command as Xe,InvalidArgumentError as pw}from"commander";var uw=["x","instagram","facebook","linkedin","tiktok","youtube"],gw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function He(t){if(!gw.test(t))throw new pw("Expected a UUID returned by the corresponding list command.");return t}function xr(t,e){return mw("sha256").update(JSON.stringify([t,...e])).digest("hex")}function qt(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var fw=new Xe("list").description("List one brand's competitors with stable IDs, websites, X accounts, and avatars").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async t=>{await b();try{l(await p("getBrandCompetitors",{brandingId:t.brandingId,teamId:t.teamId}))}catch(e){qt(e,"Competitor list failed")}}),hw=new Xe("add").description("Add or update one competitor by name and print its stable saved row").argument("<name>","Competitor company or product name").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--website <url>","Competitor website as a full URL").option("--x-handle <handle>","Competitor X handle, with or without @").option("--x-avatar-url <url>","Avatar URL for the selected X account").option("--no-resolve-handle","Do not search X when --x-handle is omitted").action(async(t,e)=>{await b();let n={brandingId:e.brandingId,name:t,resolveHandle:e.resolveHandle,teamId:e.teamId,website:e.website,xAvatarUrl:e.xAvatarUrl,xHandle:e.xHandle};try{l(await p("addCompetitor",n,xr("addCompetitor",[e.brandingId??"default",t.trim(),e.website??null,e.xHandle??null,e.xAvatarUrl??null,e.resolveHandle])))}catch(r){qt(r,"Competitor write failed")}}),yw=new Xe("delete").description("Remove one competitor by the stable ID from competitor list").argument("<competitor-id>","Competitor UUID",He).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(t,e)=>{await b(),e.yes||(a("Refusing to remove a competitor without --yes."),process.exit(s.INVALID_INPUT));try{l(await p("deleteBrandCompetitor",{brandingId:e.brandingId,competitorId:t,teamId:e.teamId},xr("deleteBrandCompetitor",[e.brandingId??"default",t])))}catch(n){qt(n,"Competitor removal failed")}}),bl=new Xe("competitor").description("List, add, update, or remove a brand's competitor watch rows").addCommand(fw).addCommand(hw).addCommand(yw),bw=new Xe("list").description("List one brand's social accounts with stable IDs, platforms, sources, and URLs").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async t=>{await b();try{l(await p("listBrandSocialHandles",{brandingId:t.brandingId,teamId:t.teamId}))}catch(e){qt(e,"Social-account list failed")}}),ww=new Xe("add").description("Record one social account and print its stable saved row").argument("<platform>","Social network: x | instagram | facebook | linkedin | tiktok | youtube",y("platform",uw)).argument("<handle>","Account handle on that social network").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(t,e,n)=>{await b();try{l(await p("addBrandSocialHandle",{brandingId:n.brandingId,handle:e,platform:t,teamId:n.teamId},xr("addBrandSocialHandle",[n.brandingId??"default",t,e.replace(/^@/,"")])))}catch(r){qt(r,"Social-account write failed")}}),vw=new Xe("delete").description("Remove one social account by the stable ID from social list").argument("<handle-id>","Social-handle UUID",He).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",He).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(t,e)=>{await b(),e.yes||(a("Refusing to remove a social account without --yes."),process.exit(s.INVALID_INPUT));try{l(await p("deleteBrandSocialHandle",{brandingId:e.brandingId,handleId:t,teamId:e.teamId},xr("deleteBrandSocialHandle",[e.brandingId??"default",t])))}catch(n){qt(n,"Social-account removal failed")}}),wl=new Xe("social").description("List, record, or remove the social accounts owned by a brand").addCommand(bw).addCommand(ww).addCommand(vw);import{createHash as Iw}from"crypto";import{Command as vl}from"commander";var kw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function xw(t){kw.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Rw(t){return Iw("sha256").update(t).digest("hex").slice(0,32)}var Il=new vl("sync").description("Update linked decks from their brand; waits by default, versions decks, and prints JSON").argument("<brand-id>","Brand profile ID").option("--no-wait","Return a run ID; resume with `branding sync-status <run-id>`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),xw(t);let n={brandId:t,teamId:e.teamId};try{let r=await p("syncBrandToPresentations",n,Rw(`syncBrandToPresentations:${t}`));if(e.wait===!1){l(r);return}l(await zs(r.runId,e.teamId))}catch(r){a(m(r,"Sync failed")),process.exit(s.GENERAL_ERROR)}}),kl=new vl("sync-status").description("Print linked-deck sync progress, terminal result, or error").argument("<run-id>","Run ID from `branding sync --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("syncBrandToPresentations",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Cw}from"crypto";import{readFile as Sw}from"fs/promises";import{Command as xl}from"commander";var Ew=["color.primary","color.background","color.text","color.secondary","color.accent","color.surface","color.link","typography.primary","typography.secondary","typography.h1","typography.h2","typography.h3","typography.h4","typography.h5","typography.h6","typography.paragraph","typography.button","typography.small","typography.label","typography.caption","asset.logo","asset.logo.dark","asset.favicon"];function Tw(t){let e=t.split(".").filter(Boolean);for(let n=e.length;n>=2;n--){let r=e.slice(0,n).join(".");if(Ew.includes(r))return{fieldPath:e.slice(n),nodeKey:r}}return{fieldPath:e.slice(2),nodeKey:e.slice(0,2).join(".")}}function Aw(t){let e={};for(let n of t){let r=n.indexOf("=");if(r<=0)throw new Error(`"${n}" is not a token assignment. Use key=value, e.g. color.primary=#114b97`);let o=n.slice(0,r).trim(),i=n.slice(r+1);if(o.split(".").filter(Boolean).length<2)throw new Error(`"${o}" is not a brand token key. Expected something like color.primary or typography.h1.size`);let{fieldPath:c,nodeKey:u}=Tw(o),f=$w(i);if(c.length===0){e[u]=f;continue}let v=e[u],I=v&&typeof v=="object"&&!Array.isArray(v)?v:{},S=I;for(let $ of c.slice(0,-1)){let O=S[$],T=O&&typeof O=="object"&&!Array.isArray(O)?O:{};S[$]=T,S=T}S[c[c.length-1]]=f,e[u]=I}return e}function $w(t){return t==="true"?!0:t==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(t)?Number(t):t}function Pw(t,e){return t===void 0?{assignments:[...e]}:t.includes("=")?{assignments:[t,...e]}:{assignments:[...e],brandId:t}}var Rl=new xl("profile").description("Read a brand's design tokens, the keys it is missing, or its design.md").argument("[brand-id]","Brand ID (defaults to this workspace's brand)").option("--format <format>","tokens (default) or md").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{let n=await p("getBrandProfile",{brandId:t,format:e.format,teamId:e.teamId});if(e.format==="md"&&typeof n.designMd=="string"){console.log(n.designMd);return}l(n)}catch(n){a(m(n,"Profile read failed")),process.exit(s.GENERAL_ERROR)}}),Cl=new xl("set").description("Write brand design tokens (key=value pairs or a design.md)").argument("[brand-id]","Brand ID (defaults to this workspace's brand)").argument("[tokens...]","Token assignments, e.g. color.primary=#114b97 typography.h1.size=32px").option("--design-md <path>","Apply a whole design.md file instead").option("--no-publish","Stage the change without publishing a new active brand version").option("--team-id <id>","Workspace ID").option("--yes","Confirm writing brand data").action(async(t,e,n)=>{n.yes||(a("Pass --yes to confirm writing brand tokens."),process.exit(s.INVALID_INPUT));let{assignments:r,brandId:o}=Pw(t,e),i;try{i=r.length>0?Aw(r):void 0}catch(c){a(m(c,"Invalid token pair")),process.exit(s.INVALID_INPUT)}let d;if(n.designMd)try{d=await Sw(n.designMd,"utf8")}catch(c){a(`Could not read ${n.designMd}: ${m(c)}`),process.exit(s.INVALID_INPUT)}!i&&!d&&(a("Nothing to write. Pass token assignments (color.primary=#114b97) or --design-md <file>."),process.exit(s.INVALID_INPUT));try{l(await p("updateBrandTokens",{brandId:o,designMd:d,publish:n.publish===!1?!1:void 0,teamId:n.teamId,tokens:i},Cw()))}catch(c){a(m(c,"Write failed")),process.exit(s.GENERAL_ERROR)}});import{createHash as Ow}from"crypto";import{Command as Sr}from"commander";var Dw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Cr=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function hi(t){Dw.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Sl(t){return Ow("sha256").update(t).digest("hex").slice(0,32)}function El(t){if(Cr.includes(t))return t;a(`"${t}" is not a channel. Pass one of: ${Cr.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Rr(t){return t===""?null:t}function fi(t,e){if(e==="")return null;let n;try{n=JSON.parse(e)}catch(r){a(`${t} is not valid JSON: ${m(r)}`),process.exit(s.INVALID_INPUT)}return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${t} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}function Nw(t,e){if(e==="true")return!0;if(e==="false")return!1;a(`${t} takes "true" or "false", not "${e}".`),process.exit(s.INVALID_INPUT)}function Lw(t){if(t==="")return null;let e=Number(t);return Number.isInteger(e)||(a(`--max-seconds takes a whole number of seconds, not "${t}".`),process.exit(s.INVALID_INPUT)),e}var Uw=new Sr("list").description("List a brand's per-channel design variants").argument("<brand-id>","Brand profile ID").option("--channel <key>",`One of: ${Cr.join(", ")}`).option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),hi(t),e.channel!==void 0&&El(e.channel);try{l(await p("listBrandVariants",{brandId:t,channelKey:e.channel,teamId:e.teamId}))}catch(n){a(m(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),_w=new Sr("set").description("Create or update one per-channel brand design variant").argument("<brand-id>","Brand profile ID").option("--variant <slug>","Variant slug; omit to create one with a new slug").option("--channel <key>",`One of: ${Cr.join(", ")}`).option("--name <name>","Display name for the variant").option("--default <true|false>","Make this the channel's default, or drop the role").option("--colors <json>",`Palette as JSON, e.g. '{"primary":"#155DAC","background":"#FFFFFF","text":"#111111"}'`).option("--logo-treatment <json>",'Logo backdrop as JSON; pass "" to clear').option("--background-gradient <json>",'Gradient document as JSON; pass "" to clear').option("--aspect <ratio>",'Aspect ratio, e.g. 16:9; pass "" to clear').option("--max-seconds <seconds>",'Longest runtime in seconds; pass "" to clear').option("--voice-tone <tone>",'Voice tone override; pass "" to clear').option("--opening-style <style>",'Opening style; pass "" to clear').option("--logo-position <position>",'Logo position; pass "" to clear').option("--constraints <text>",'Generator constraints; pass "" to clear').option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),hi(t),e.channel!==void 0&&El(e.channel);let n={brandId:t,teamId:e.teamId};e.variant!==void 0&&(n.variantId=e.variant),e.channel!==void 0&&(n.channelKey=e.channel),e.name!==void 0&&(n.name=e.name),e.default!==void 0&&(n.isDefault=Nw("--default",e.default)),e.colors!==void 0&&(n.colors=fi("--colors",e.colors)),e.logoTreatment!==void 0&&(n.logoTreatment=fi("--logo-treatment",e.logoTreatment)),e.backgroundGradient!==void 0&&(n.backgroundGradient=fi("--background-gradient",e.backgroundGradient)),e.aspect!==void 0&&(n.aspect=Rr(e.aspect)),e.maxSeconds!==void 0&&(n.maxSeconds=Lw(e.maxSeconds)),e.voiceTone!==void 0&&(n.voiceOverride=e.voiceTone===""?null:{tone:e.voiceTone}),e.openingStyle!==void 0&&(n.openingStyle=Rr(e.openingStyle)),e.logoPosition!==void 0&&(n.logoPosition=Rr(e.logoPosition)),e.constraints!==void 0&&(n.constraints=Rr(e.constraints));try{l(await p("setBrandVariant",n,e.variant===void 0?void 0:Sl(`setBrandVariant:${t}:${e.variant}:${JSON.stringify(n)}`)))}catch(r){a(m(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),jw=new Sr("delete").description("Remove one per-channel brand design variant").argument("<brand-id>","Brand profile ID").option("--variant <slug>","Variant slug to remove").option("--team-id <id>","Workspace ID").option("--yes","Skip the confirmation prompt").action(async(t,e)=>{await b(),hi(t),e.variant===void 0&&(a("Pass --variant <slug> to name the variant to remove. `branding variant list <brand-id>` prints the slugs."),process.exit(s.INVALID_INPUT)),!e.yes&&process.stdin.isTTY&&(a(`Refusing to delete variant "${e.variant}" without confirmation. This delete is permanent \u2014 re-run with --yes.`),process.exit(s.GENERAL_ERROR));try{l(await p("deleteBrandVariant",{brandId:t,teamId:e.teamId,variantId:e.variant},Sl(`deleteBrandVariant:${t}:${e.variant}`)))}catch(n){a(m(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Tl=new Sr("variant").description("Per-channel brand design variant commands").addCommand(Uw).addCommand(_w).addCommand(jw);import{createHash as Vw}from"crypto";import{Command as bi}from"commander";var qw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,yi=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Mw(t){qw.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Bw(t){if(yi.includes(t))return t;a(`"${t}" is not a channel. Pass one of: ${yi.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Fw(t,e){let n;try{n=JSON.parse(e)}catch(r){a(`${t} is not valid JSON: ${m(r)}`),process.exit(s.INVALID_INPUT)}return(typeof n!="object"||n===null||Array.isArray(n))&&(a(`${t} must be a JSON object.`),process.exit(s.INVALID_INPUT)),n}function Gw(t){return Vw("sha256").update(t).digest("hex").slice(0,32)}var Kw=new bi("generate").description("Generate a brand's per-channel design variants and gradients, replacing the channel's previous set").argument("[brand-id]","Brand profile ID; omit to generate a preview that is not saved").option("--channel <key>",`One of: ${yi.join(", ")}`).option("--name <name>","Brand name to generate against").option("--description <text>","What the brand is, as generator context").option("--tone <tone>","Tone hint, e.g. 'warm, confident'").option("--style <style>","Visual style hint, e.g. 'editorial, high contrast'").option("--colors <json>",`Palette as JSON, e.g. '{"primary":"#155DAC","background":"#FFFFFF","text":"#111111"}'. Required when no brand id is given.`).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),t!==void 0&&Mw(t),e.channel!==void 0&&Bw(e.channel);let n={teamId:e.teamId};t!==void 0&&(n.brandId=t),e.channel!==void 0&&(n.channelKey=e.channel),e.name!==void 0&&(n.brandName=e.name),e.description!==void 0&&(n.brandDescription=e.description),e.tone!==void 0&&(n.brandTone=e.tone),e.style!==void 0&&(n.brandStyle=e.style),e.colors!==void 0&&(n.sourceColors=Fw("--colors",e.colors));try{let r=await p("generateBrandVariations",n,Gw(`generateBrandVariations:${t??"preview"}:${e.channel??"deck-16-9"}`));if(e.wait===!1){l(r);return}l(await Fs(r.runId,e.teamId))}catch(r){a(m(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),Ww=new bi("status").description("Read a brand variations generation run").argument("<run-id>","Run ID from `branding variations generate --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("generateBrandVariations",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Al=new bi("variations").description("Generated brand design variations").addCommand(Kw).addCommand(Ww);import{createHash as Jw}from"crypto";import{Command as Er}from"commander";var wi=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function vi(t){wi.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function zw(t,e){if(e==="head"||wi.test(e))return e;a(`${t} must be a version id or "head".`),process.exit(s.INVALID_INPUT)}function Hw(t,e){if(wi.test(e))return e;a(`${t} must be a version id from \`branding version list\`.`),process.exit(s.INVALID_INPUT)}function Xw(t){return Jw("sha256").update(t).digest("hex").slice(0,32)}var Yw=new Er("list").description("List a brand's published versions, newest first").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),vi(t);try{l(await p("listBrandVersions",{brandId:t,teamId:e.teamId}))}catch(n){a(m(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),Qw=new Er("diff").description("Compare two points in a brand's version history").argument("<brand-id>","Brand profile ID").option("--from <version-id>","Baseline version to compare against. Defaults to the brand's live version.").option("--to <version-id|head>","Version to compare. Defaults to head, the unpublished working draft.").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),vi(t);let n={brandId:t,teamId:e.teamId};e.from!==void 0&&(n.from=Hw("--from",e.from)),e.to!==void 0&&(n.to=zw("--to",e.to));try{l(await p("diffBrandVersions",n))}catch(r){a(m(r,"Diff failed")),process.exit(s.GENERAL_ERROR)}}),Zw=new Er("publish").description("Publish the brand's working draft as a new live version").argument("<brand-id>","Brand profile ID").option("--label <text>","Short name for this version, unique within the brand (max 64 characters)").option("--notes <text>","What changed. Defaults to a changelog derived from the diff.").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),vi(t);let n={brandId:t,teamId:e.teamId};e.label!==void 0&&(n.label=e.label),e.notes!==void 0&&(n.notes=e.notes);try{l(await p("publishBrandVersion",n,Xw(`publishBrandVersion:${t}:${e.label??"auto"}`)))}catch(r){a(m(r,"Publish failed")),process.exit(s.GENERAL_ERROR)}}),$l=new Er("version").description("Brand version history commands").addCommand(Yw).addCommand(Qw).addCommand(Zw);import{createHash as ev}from"crypto";import{Command as Tn}from"commander";var tv=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ki(t){tv.test(t)||(a(`"${t}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Ii(t,e=[]){return[...e,t]}function Pl(t){return ev("sha256").update(t).digest("hex").slice(0,32)}var nv=new Tn("get").description("Read a brand's Voice & Context document").argument("<brand-id>","Brand profile ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),ki(t);try{l(await p("getBrandVoice",{brandId:t,teamId:e.teamId}))}catch(n){a(m(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),rv=new Tn("set").description("Write a brand's Voice & Context document").argument("<brand-id>","Brand profile ID").option("--positioning <text>","Positioning and promise").option("--voice-tone <text>","How the brand sounds").option("--authoritative-facts <text>","Facts generated content must never contradict").option("--approved-language <text>","Wording the brand endorses").option("--guardrails <text>","What the brand must never say or do").option("--sources <json>",`Provenance as JSON, e.g. '[{"kind":"url","name":"About page"}]'. Omitting this clears the recorded provenance.`).option("--replace","Acknowledge that this replaces the WHOLE document: sections you omit are removed. Required when the payload would drop a section the brand has.").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),ki(t);let n={brandId:t,teamId:e.teamId};if(e.positioning!==void 0&&(n.positioning=e.positioning),e.voiceTone!==void 0&&(n.voiceTone=e.voiceTone),e.authoritativeFacts!==void 0&&(n.authoritativeFacts=e.authoritativeFacts),e.approvedLanguage!==void 0&&(n.approvedLanguage=e.approvedLanguage),e.guardrails!==void 0&&(n.guardrails=e.guardrails),e.replace===!0&&(n.replace=!0),e.sources!==void 0)try{n.sources=JSON.parse(e.sources)}catch{a("--sources must be valid JSON (an array of source objects)."),process.exit(s.INVALID_INPUT)}try{l(await p("setBrandVoice",n,Pl(`setBrandVoice:${t}:${JSON.stringify(n)}`)))}catch(r){a(m(r,"Write failed")),process.exit(s.GENERAL_ERROR)}}),ov=new Tn("build").description("Draft a brand's Voice & Context document from source material").argument("<brand-id>","Brand profile ID").option("--url <url>","Page to read; repeat for several",Ii).option("--text <text>","Pasted source material; repeat for several",Ii).option("--file <name:source>","Document to read, as name:source; repeat for several",Ii).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b(),ki(t);let n={brandId:t,teamId:e.teamId};e.url?.length&&(n.urls=e.url),e.text?.length&&(n.text=e.text),e.file?.length&&(n.files=e.file.map(r=>{let o=r.indexOf(":");return(o<=0||o===r.length-1)&&(a(`--file must be name:source; got "${r}".`),process.exit(s.INVALID_INPUT)),{name:r.slice(0,o),source:r.slice(o+1)}})),!e.url?.length&&!e.text?.length&&!e.file?.length&&(a("Pass at least one --url, --text or --file to draft from."),process.exit(s.INVALID_INPUT));try{let r=await p("buildBrandVoice",n,Pl(`buildBrandVoice:${JSON.stringify(n)}`));if(e.wait===!1){l(r);return}l(await Ks(r.runId,e.teamId))}catch(r){a(m(r,"Build failed")),process.exit(s.GENERAL_ERROR)}}),iv=new Tn("build-status").description("Read a brand voice build run").argument("<run-id>","Run ID from `branding voice build --no-wait`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await x("buildBrandVoice",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Ol=new Tn("voice").description("Brand voice and context commands").addCommand(nv).addCommand(rv).addCommand(ov).addCommand(iv);function lv(t){return e=>{let n=Number(e);if(!Number.isInteger(n)||n<0)throw new Dl(`${t} expects a whole number of 0 or more.`);return n}}function mv(t){return e=>{let n=Number(e);if(!Number.isInteger(n)||n<1)throw new Dl(`${t} expects a whole number of 1+.`);return n}}var pv=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,uv=50;function gv(t){let e=t.extractedFrom??t.normalizedUrl??null,n=gi(t),r=hl(t),o=ui(t);if(Se("Brand Profile"),console.log(),E("ID",t.id),E("Name",t.name),E("Source URL",e??z.gray("None")),E("Default",t.isDefault?z.green("Yes"):"No"),t.createdAt&&E("Created",new Date(t.createdAt).toLocaleString()),console.log(),n||r.length>0){if(console.log(z.bold(" Colors")),n&&console.log(` Primary: ${z.bgHex(n)(" ")} ${n}`),r.length>0){console.log(" Palette:");for(let v of r.slice(0,10)){let I=v.role?z.gray(` (${v.role})`):"";console.log(` ${z.bgHex(v.hex)(" ")} ${v.hex}${I}`)}}console.log()}o&&(console.log(z.bold(" Logo")),console.log(` ${o}`),console.log());let i=t.brandData?.typography,d=t.resolvedTokens?.headingFont??i?.primary??i?.headings,c=t.resolvedTokens?.bodyFont??i?.secondary??i?.body;(d||c)&&(console.log(z.bold(" Typography")),console.log(` Headings: ${d??"-"}`),console.log(` Body: ${c??"-"}`),console.log());let u=t.brandData?.confidence,f=t.brandData?.extractionMethod;(typeof u=="number"||typeof f=="string")&&(console.log(z.bold(" Extraction")),typeof u=="number"&&console.log(` Confidence: ${Math.round(u*100)}%`),typeof f=="string"&&console.log(` Method: ${f}`),console.log()),console.log(z.gray(" Use --format json for full details")),console.log()}var Nl=new Mt("branding").description("Read and manage workspace brands, design rules, assets, permissions, and social presence").addCommand(Rl).addCommand(Cl).addCommand(Rc).addCommand(Sc).addCommand(Zc).addCommand(el).addCommand(Vc).addCommand(new Mt("list").description("List accessible brands as a table or paged JSON").option("--search <text>","Filter by brand name or website/domain; an exact brand id also matches").option("--filter <filter>","Which slice to return (all, mine, team)",y("--filter",["all","mine","team"])).option("--sort <sort>","Sort key (created, name, updated)",y("--sort",["created","name","updated"])).option("--shape <shape>","Result shape: list (paged rows, default) or chat (compact matches)",y("--shape",["chat","list"])).option("--limit <n>","Page size (server default: 12 for the list shape, 50 for chat)",mv("--limit")).option("--offset <n>","Brands to skip before the page",lv("--offset")).option("--team-id <id>","Workspace ID").option("--json","Print the complete JSON response instead of a table").action(async t=>{await b();try{let e=t.shape??"list",n=await p("listBrandings",{filter:t.filter,limit:t.limit,offset:t.offset,search:t.search,shape:e,sort:t.sort,teamId:t.teamId});if(t.json){l(n);return}let r=yl(n);if(r.length===0){w("No brand profiles found"),console.log(),console.log(z.gray(`Create one with: ${g.commands[0]} branding extract <url>`));return}console.log(hd(r));let o=t.offset??0;pi(n)?n.hasMore&&console.log(z.gray(` ${o+r.length} of ${n.total}. Next page: --offset ${o+r.length}`)):r.length>=(t.limit??uv)&&console.log(z.gray(` Showing ${r.length} from --offset ${o}; there may be more. Next page: --offset ${o+r.length}`))}catch(e){a("The command failed. Please try again."),process.exit(e.exitCode??1)}})).addCommand(new Mt("get").description("Read one brand as a summary or complete JSON").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)",y("--format",["summary","json"]),"summary").option("-o, --output <path>","Save JSON to file").option("--team-id <id>","Workspace ID").action(async(t,e)=>{if(await b(),!pv.test(t)){a(`"${t}" is not a brand id. Pass the UUID from \`${g.commands[0]} branding list\`, or search by name with \`${g.commands[0]} branding find <query>\`.`),process.exit(s.INVALID_INPUT);return}try{let r=(await p("listBrandings",{limit:1,search:t,shape:"list",teamId:e.teamId})).items?.[0];if(!r){a(`No brand profile with id ${t} is accessible.`),process.exit(s.NOT_FOUND);return}if(e.output){await dv(e.output,JSON.stringify(r,null,2)),k(`Brand profile saved to ${e.output}`);return}if(e.format==="json"){console.log(JSON.stringify(r,null,2));return}gv(r)}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Mt("find").description("Print matching brand IDs for an exact name, domain, or website URL").argument("<query>","Brand name or website URL to search for").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{let r=(await p("listBrandings",{search:t,shape:"chat",teamId:e.teamId})).brandings;if(r.length===0){w(`No brand profiles matching "${t}"`),console.log(z.gray(` Extract one with: ${g.commands[0]} branding extract <url>`));return}console.log(`Found ${r.length} brand${r.length>1?"s":""}:
|
|
73
|
+
`);for(let o of r){let i=o.primaryColor?`${z.bgHex(o.primaryColor)(" ")} ${o.primaryColor}`:"";console.log(` ${z.bold(o.name)} ${z.gray(o.id)}`),o.domain&&console.log(` ${z.gray(o.domain)}`),i&&console.log(` ${i}`),console.log()}console.log(z.gray(` Export with: ${g.commands[0]} branding get <id> -o branding.json`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Mt("extract").description("Start paid website extraction and print a run ID for `branding status`").argument("<url>","Website URL to extract branding from").option("--team-id <id>","Workspace ID; defaults to your configured workspace").option("--yes","Confirm you intend to start a paid extraction. Intent only: approval still requires --approval-receipt").option("--approval-receipt <receipt>","Receipt from the browser confirmation URL; omit on the first call to be given that URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin so it is not exposed in process arguments").option("--idempotency-key <key>","Stable key bound into the approval receipt; pass the same one when retrying with the receipt").option("--skip-existing-lookup","Extract this exact URL even when the workspace already has related brands").action(async(t,e)=>{await b(),e.yes||(a("Pass --yes to confirm brand extraction."),process.exit(s.INVALID_INPUT));try{new URL(t.startsWith("http")?t:`https://${t}`)}catch{a("Invalid URL format"),process.exit(6)}let n=t.startsWith("http")?t:`https://${t}`,r=e.teamId??se(),o=e.idempotencyKey??av();e.approvalReceipt&&e.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let i=e.approvalReceiptStdin?sv(0,"utf8").trim():e.approvalReceipt;e.approvalReceiptStdin&&!i&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let d=cv({text:`Extracting branding from ${n}...`,stream:process.stdout}).start(),c;try{let u=await vs(n,r,i,e.skipExistingLookup,o);if(u.status==="needs_choice"){d.stop(),w(`This workspace already has ${u.matches.length} related brand${u.matches.length===1?"":"s"} for ${n}. Nothing was extracted and nothing was charged.`),console.log();for(let f of u.matches)console.log(` ${z.bold(f.name??"Untitled")}`),console.log(` ${z.gray(f.id)}`),f.extractedFrom&&console.log(` ${z.gray(f.extractedFrom)}`);console.log(),w(`Use one of the above, or re-run with --skip-existing-lookup to extract ${n} anyway.`),c=s.INVALID_INPUT}else d.succeed("Brand extraction started"),console.log(JSON.stringify(u,null,2)),w(`Check progress with: ${g.commands[0]} branding status ${u.runId}`),console.log()}catch(u){let f=m(u);f.includes("approval")&&(d.stop(),a(f),console.log(),w(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${o}`),process.exit(s.INVALID_INPUT)),d.fail("Extraction failed"),a(f),process.exit(u.exitCode??1)}c!==void 0&&process.exit(c)})).addCommand(new Mt("status").description("Print a brand extraction run's current state, error, or result").argument("<run-id>","Run ID returned by branding extract").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("extractBranding",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(qc).addCommand(Uc).addCommand(Fc).addCommand(Mc).addCommand(Gc).addCommand(Kc).addCommand(Wc).addCommand(Bc).addCommand(bl).addCommand(Jc).addCommand(Tc).addCommand(Ac).addCommand(Oc).addCommand(dl).addCommand(Tl).addCommand(Al).addCommand($l).addCommand(Ol).addCommand(Nc).addCommand(ul).addCommand(fl).addCommand(tl).addCommand(nl).addCommand(Il).addCommand(kl).addCommand(rl).addCommand(wl);import An from"chalk";import{Command as Bt}from"commander";function fv(t){switch(t.background){case"color":{if(!t.backgroundColor)throw new Error("--background color needs --background-color <hex>, e.g. #1d4ed8");return{hex:t.backgroundColor,kind:"color"}}case"image":{if(!t.backgroundImage)throw new Error("--background image needs --background-image <url>");return{fit:t.fit,kind:"image",url:t.backgroundImage}}default:return{kind:t.background}}}function Ll(t,e){return{background:fv(e),name:t,presenterProfileId:e.presenter,...e.voiceId?{voiceId:e.voiceId}:{}}}function Tr(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.id);return}k(`${t.name} (${t.id})`),w(` Presenter: ${t.presenterProfileId}`),w(` Backdrop: ${hv(t.background)}`),t.voiceId&&w(` Voice: ${t.voiceId}`)}function hv(t){switch(t.kind){case"color":return`color ${t.hex}`;case"image":return`image ${t.url} (${t.fit})`;default:return t.kind}}function Ul(t){return t.requiredOption("--presenter <profileId>",`Trained personal presenter id (pp_*), from \`${g.commands[0]} avatar options\``).option("--background <kind>","Backdrop: original, transparent, color, or image","original").option("--background-color <hex>","Backdrop color, e.g. #1d4ed8").option("--background-image <url>","Backdrop image URL").option("--fit <fit>","How an image backdrop fills the frame","cover").option("--voice-id <voiceId>","Workspace voice to save with this preset").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human")}var yv=new Bt("list").description("List saved cast presets you can use").option("--cast-member-id <castMemberId>","Only this person's presets").option("--branding-id <brandingId>","Narrow to one brand").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{try{let e=await ld({...t.brandingId?{brandingId:t.brandingId}:{},...t.castMemberId?{castMemberId:t.castMemberId}:{},...t.teamId?{teamId:t.teamId}:{}});if(t.format==="json"){l(e);return}if(t.format==="quiet"){for(let n of e.presets)console.log(n.id);return}if(e.presets.length===0){w("No presets saved yet.");return}for(let n of e.presets)Tr(n,"human")}catch(e){a(m(e)),process.exit(s.API_ERROR)}}),bv=Ul(new Bt("create").description("Save one way a cast member appears").argument("<name>",'What to call this preset, e.g. "In the cafe"').requiredOption("--cast-member-id <castMemberId>","The person this preset is a way of showing")).action(async(t,e)=>{try{let n=await md({castMemberId:e.castMemberId,...Ll(t,e),...e.teamId?{teamId:e.teamId}:{}});Tr(n.preset,e.format)}catch(n){a(m(n)),process.exit(s.API_ERROR)}}),wv=Ul(new Bt("update").description("Change a saved preset (sends the complete preset)").argument("<preset-id>","The preset to change").requiredOption("--name <name>","What to call it")).action(async(t,e)=>{try{let n=await pd({presetId:t,...Ll(e.name,e),...e.teamId?{teamId:e.teamId}:{}});Tr(n.preset,e.format)}catch(n){a(m(n)),process.exit(s.API_ERROR)}}),vv=new Bt("delete").description("Retire a saved preset. Existing videos keep working.").argument("<preset-id>","The preset to retire").option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await ud(t,e.teamId);if(e.format==="human"){k(`Retired "${n.preset.name}".`);return}Tr(n.preset,e.format)}catch(n){a(m(n)),process.exit(s.API_ERROR)}}),Iv=new Bt("preset").description("Saved ways a cast member appears").addCommand(yv).addCommand(bv).addCommand(wv).addCommand(vv),xi=new Bt("cast").description("The faces and voices your videos can use").addCommand(Iv);xi.addHelpText("after",`
|
|
74
|
+
${An.bold("Examples:")}
|
|
75
|
+
${An.gray("# List the saved presenter/backdrop/voice combinations")}
|
|
76
|
+
$ ${g.commands[0]} cast preset list
|
|
77
|
+
|
|
78
|
+
${An.bold("See also:")}
|
|
79
|
+
${An.gray("# The presenter avatars, looks, and voices a preset is built from")}
|
|
80
|
+
$ ${g.commands[0]} avatar options
|
|
81
|
+
|
|
82
|
+
${An.gray("# Use a preset on one presentation-video scene")}
|
|
83
|
+
$ ${g.commands[0]} presentation video presenter <project-id>
|
|
84
|
+
`);import{randomUUID as kv}from"crypto";import{readFile as xv}from"fs/promises";import $n from"chalk";import{Command as _l}from"commander";var Rv=new _l("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("--idempotency-key <key>","Stable retry key").option("--filename <name>","Source filename metadata").option("--mime-type <type>","Source MIME type").option("--max-length <count>","Maximum output characters","30000").option("--reason <text>","Reason for this extraction").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=t,r;t.includes("://")||(n=await xv(t,"utf8"),r=t);let o=await p("extractContent",{filename:e.filename??r,maxLength:Number.parseInt(e.maxLength,10),mimeType:e.mimeType,reason:e.reason,source:n,teamId:e.teamId},e.idempotencyKey??kv());e.format!=="quiet"&&l(o)}catch(n){a(m(n,"Extraction failed")),process.exit(s.GENERAL_ERROR)}}),Ri=new _l("content").description("Extract normalized text from a URL, a local file, or an encoded document").addCommand(Rv);Ri.addHelpText("after",`
|
|
85
|
+
${$n.bold("Examples:")}
|
|
86
|
+
${$n.gray("# Normalized text from a local document")}
|
|
87
|
+
$ ${g.commands[0]} content extract ./paper.pdf
|
|
88
|
+
|
|
89
|
+
${$n.bold("See also:")}
|
|
90
|
+
${$n.gray("# Web pages, with page metadata and cost reporting")}
|
|
91
|
+
$ ${g.commands[0]} scrape https://example.com/post
|
|
92
|
+
|
|
93
|
+
${$n.gray("# Spoken words out of audio or video")}
|
|
94
|
+
$ ${g.commands[0]} transcript --help
|
|
95
|
+
`);import{existsSync as Cv,readFileSync as Sv}from"fs";import Ev,{resolve as jl}from"path";import oe from"chalk";import{Command as Tv}from"commander";function Ci(t,e){if(e)try{let n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("expected an object");return n}catch(n){throw new Error(`${t} must be a valid JSON object.`,{cause:n})}}function Av(t,e,n){if(t!=="as-is"||e)return e;let r=n.filter(o=>o.name.toLowerCase().endsWith(".pptx"));if(r.length!==1)throw new Error("--source-mode as-is requires exactly one uploaded .pptx file (or --source-presentation JSON).");return{filename:r[0].name,sourceUrl:r[0].url}}var Vl=new Tv("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. Each tier is a per-image credit ceiling as well as its price: quick (+20/slide), smart (default, +60/slide), balanced (+250/slide), best (+500/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("--additional-context <text>","Additional generation instructions").option("--conversation-context <text>","Prior conversation context").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("--brand-enforcement <json>","Brand enforcement JSON object").option("--brand-variant-id <id>","Saved brand variant ID").option("--design-brand-reference <text>","Design brand reference").option("--family <family>","Layout family (minimal, editorial, bold, dashboard)",y("--family",["minimal","editorial","bold","dashboard"])).option("--generation-request-id <id>","Generation funnel correlation ID").option("--image-policy <policy>","Image policy (auto, none)",y("--image-policy",["auto","none"])).option("--content-sources <json>","Canonical content-sources JSON object").option("--source-mode <mode>","Attached deck mode (reference, as-is)",y("--source-mode",["reference","as-is"])).option("--source-presentation <json>","Attached PowerPoint JSON object with filename and sourceUrl").option("--widget-session-id <id>","Stable widget session ID").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("--format <format>","Output format (human, json, quiet)",y("--format",["human","json","quiet"])).option("-o, --output <format>","Output format (human, json, quiet) \u2014 short form of --format",y("--output",["human","json","quiet"])).option("--no-stream","Wait for completion without streaming progress").option("--wait","Poll until generation completes").option("--idempotency-key <key>","Stable retry key").option("--approval-receipt <receipt>","Server-issued approval receipt for this exact generation request").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,e)=>{e.output=e.format??e.output,await b();let n=e.idempotencyKey??Z({command:"presentation:create",payload:{...e,approvalReceipt:void 0,idempotencyKey:void 0,topic:t},workspaceId:e.teamId??"configured-default"}),r;e.slides!==void 0&&(r=parseInt(e.slides,10),(Number.isNaN(r)||r<1||r>20)&&(a("Slide count must be between 1 and 20"),process.exit(6)));let o=["best","balanced","fast","ultrafast","instant","image-min","image","image-max"];e.mode&&!o.includes(e.mode)&&(a(`Invalid mode: ${e.mode}. Valid: ${o.join(", ")}`),process.exit(6));let i=["smart","fast","balanced","best"];e.imageTier&&!i.includes(e.imageTier)&&(a(`Invalid image tier: ${e.imageTier}. Valid: ${i.join(", ")}`),process.exit(6));let d=["creative","professional","educational","formal","casual"];e.tone&&!d.includes(e.tone)&&(a(`Invalid tone: ${e.tone}. Valid: ${d.join(", ")}`),process.exit(6));let c=["minimal","concise","detailed","extensive"];e.amount&&!c.includes(e.amount)&&(a(`Invalid amount: ${e.amount}. Valid: ${c.join(", ")}`),process.exit(6));let u=["freeform","brand-only","brand-plus-style","style-only","no-styling"];e.styling&&!u.includes(e.styling)&&(a(`Invalid styling: ${e.styling}. Valid: ${u.join(", ")}`),process.exit(6));let f=["quick","moderate","deep","profound"];e.thinkingDepth&&!f.includes(e.thinkingDepth)&&(a(`Invalid thinking-depth: ${e.thinkingDepth}. Valid: ${f.join(", ")}`),process.exit(6));let v=["inform","persuade","train","learn","entertain","report"];e.goal&&!v.includes(e.goal)&&(a(`Invalid goal: ${e.goal}. Valid: ${v.join(", ")}`),process.exit(6));let I=["blue","violet","rose","orange","green"];e.theme&&!I.includes(e.theme)&&(a(`Invalid theme: ${e.theme}. Valid: ${I.join(", ")}`),process.exit(6));let S=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];e.decorations&&!S.includes(e.decorations)&&(a(`Invalid decorations: ${e.decorations}. Valid: ${S.join(", ")}`),process.exit(6));let $=e.theme||e.primaryColor||e.secondaryColor||e.accentColor||e.backgroundColor||e.foregroundColor||e.decorations;$&&e.mode&&e.mode!=="instant"&&(a("--theme, --primary-color, --decorations and other color options are only supported with --mode instant"),process.exit(6));let O=e.mode??($?"instant":"fast"),T=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[W,Re]of[["primary-color",e.primaryColor],["secondary-color",e.secondaryColor],["accent-color",e.accentColor],["background-color",e.backgroundColor],["foreground-color",e.foregroundColor]])Re&&!T.test(Re)&&(a(`Invalid ${W}: ${Re}. Must be hex (e.g., #0066CC)`),process.exit(6));try{e.output!=="json"&&e.output!=="quiet"&&process.stdout.write(oe.gray("Checking generation limits... "));let W=await xs(O,r??10,e.teamId);if(e.output!=="json"&&e.output!=="quiet"){console.log(oe.green("\u2713"));let Re=W.remaining[O],ye=W.limits[O],Ce=Re===void 0||ye===void 0?"":` | ${O}: ${Re}/${ye} remaining`;console.log(oe.gray(` Plan: ${W.planName}${Ce}`))}}catch(W){e.output==="json"?console.log(JSON.stringify({success:!1,error:"The operation could not be completed."})):(console.log(oe.red("\u2717")),a("The command failed. Please try again.")),process.exit(W.exitCode??1)}let P=[];if(e.file&&e.file.length>0){for(let W of e.file)Cv(jl(W))||(a(`File not found: ${W}`),process.exit(6));e.output!=="json"&&e.output!=="quiet"&&console.log(oe.gray(`
|
|
96
|
+
Uploading ${e.file.length} file(s)...`));try{P=await cs(e.file.map(W=>jl(W)),(W,Re,ye)=>{e.output!=="json"&&e.output!=="quiet"&&ye&&process.stdout.write(`\r ${oe.cyan("\u2B06")} Uploading: ${ye} (${W+1}/${Re})`)},{idempotencyKey:n}),e.output!=="json"&&e.output!=="quiet"&&console.log(`\r ${oe.green("\u2713")} Uploaded ${P.length} file(s) `)}catch{a("Failed to upload files. Please try again."),process.exit(1)}}let A;(e.stdin||!process.stdin.isTTY)&&(A=await $v(),e.stdin&&!A&&(a("No content received from stdin"),process.exit(6)));let G=e.context;if(e.contextFile)try{G=Sv(e.contextFile,"utf-8"),G.trim()||(a(`Context file is empty: ${e.contextFile}`),process.exit(6))}catch{a(`Failed to read context file: ${e.contextFile}`),process.exit(6)}!A&&!G&&!e.additionalContext&&!e.contentSources&&!e.sourcePresentation&&P.length===0&&(a("Context is required to create a presentation."),console.log(),console.log(oe.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(oe.gray(" -c, --context <text> Inline text context")),console.log(oe.gray(" --context-file <path> Read from a file")),console.log(oe.gray(` cat file | ${g.commands[0]} Pipe content`)),process.exit(6));let N=[...P];A&&N.push({id:`stdin-${n}`,content:A,title:"Piped Content",mime:"text/plain",selected:!0}),G&&N.push({id:`context-${n}`,content:G,title:"Context",mime:"text/plain",selected:!0});let D,ue=e.primaryColor||e.secondaryColor||e.accentColor||e.backgroundColor||e.foregroundColor;(e.theme||ue||e.decorations)&&(D={},e.theme&&(D.preset=e.theme),ue&&(D.custom={},e.primaryColor&&(D.custom.primary=e.primaryColor),e.secondaryColor&&(D.custom.secondary=e.secondaryColor),e.accentColor&&(D.custom.accent=e.accentColor),e.backgroundColor&&(D.custom.background=e.backgroundColor),e.foregroundColor&&(D.custom.foreground=e.foregroundColor)),e.decorations&&(D.decorations=e.decorations));try{let W=Ci("--content-sources",e.contentSources),Re=Av(e.sourceMode,Ci("--source-presentation",e.sourcePresentation),P),ye=await ls({topic:t,...e.additionalContext&&{additionalContext:e.additionalContext},...r!==void 0&&{slideCount:r},mode:O,...e.imageTier&&{imageTier:e.imageTier},...e.tone&&{tone:e.tone},...e.amount&&{amount:e.amount},...e.audience&&{audience:e.audience},...e.language&&{language:e.language},...e.brandingId&&{brandingId:e.brandingId},...e.brandDomain&&{brandDomain:e.brandDomain},...e.brandEnforcement&&{brandEnforcement:Ci("--brand-enforcement",e.brandEnforcement)},...e.brandVariantId&&{brandVariantId:e.brandVariantId},...e.conversationContext&&{conversationContext:e.conversationContext},...e.designBrandReference&&{designBrandReference:e.designBrandReference},...e.family&&{family:e.family},...e.generationRequestId&&{generationRequestId:e.generationRequestId},...e.imagePolicy&&{imagePolicy:e.imagePolicy},...e.template&&{templateId:e.template},...e.styling&&{stylingMode:e.styling},...e.referenceUrl&&{referenceUrl:e.referenceUrl},...e.thinkingDepth&&{thinkingDepth:e.thinkingDepth},...e.goal&&{goal:e.goal},...e.teamId&&{teamId:e.teamId},...e.sourceMode&&{sourceMode:e.sourceMode},...Re&&{sourcePresentation:Re},...e.widgetSessionId&&{widgetSessionId:e.widgetSessionId},...D&&{theme:D},...e.studio?{documentId:Ev.basename(process.cwd())}:e.id?{documentId:e.id}:{},...W?{contentSources:W}:N.length>0&&{contentSources:{uploadedFiles:N,contextFiles:[]}}},n,e.approvalReceipt);if(!e.wait){e.output==="json"?console.log(JSON.stringify({success:!0,run:ye},null,2)):e.output!=="quiet"&&(k("Presentation generation queued"),E("Run ID",ye.runId),E("Status",ye.status),console.log(oe.gray(` Check later with presentation status ${ye.runId}`)));return}let Ce=await x("createSlides",ye.runId,e.teamId);for(;!Ce.done;)e.output!=="json"&&e.output!=="quiet"&&console.log(oe.gray(` ${Ce.message}`)),await new Promise(mn=>setTimeout(mn,(Ce.nextPollAfterSeconds??5)*1e3)),Ce=await x("createSlides",ye.runId,e.teamId);if(Ce.error)throw new Error(re(Ce.error));let ot=Ce.entity?await Ct(Ce.entity.id):void 0;if(e.output==="json")console.log(JSON.stringify({success:!0,presentation:ot,run:Ce,viewUrl:ot?St(ot.slug,e.language??"en"):void 0},null,2));else{console.log(),k("Presentation created successfully"),console.log(),E("Title",ot?.title??t),E("Slides",String(ot?.numberOfSlides??r??"\u2014")),console.log();let mn=ot?St(ot.slug,e.language??"en"):"N/A";mn!=="N/A"&&(console.log(oe.bold(" Open: ")+oe.cyan.underline(mn)),e.open&&await(await import("open")).default(mn)),console.log()}}catch(W){e.output==="json"?console.log(JSON.stringify({success:!1,error:"The operation could not be completed.",...W.errorCode==="approval_required"?{idempotencyKey:n}:{}})):(W.errorCode==="approval_required"&&E("Idempotency key",n),a("The command failed. Please try again.")),process.exit(W.exitCode??1)}});async function $v(){return new Promise(t=>{let e="";if(process.stdin.setEncoding("utf8"),process.stdin.isTTY){t("");return}process.stdin.on("data",n=>{e+=n}),process.stdin.on("end",()=>{t(e.trim())}),setTimeout(()=>{t(e.trim())},100)})}import{Command as Ei}from"commander";function Si(t,e){let n=Number(t);return(!Number.isInteger(n)||n<0)&&(a(`${e} must be a whole number`),process.exit(s.GENERAL_ERROR)),n}var Pv=new Ei("activity").description("List credit spend grouped by the artifact it was spent on").option("--limit <count>","How many groups to return (default 20)").option("--offset <count>","How many groups to skip").option("--team-id <id>","Workspace ID").action(async t=>{try{l(await p("listCreditActivity",{limit:t.limit===void 0?void 0:Si(t.limit,"--limit"),offset:t.offset===void 0?void 0:Si(t.offset,"--offset"),teamId:t.teamId}))}catch(e){a(m(e,"Reading credit activity failed")),process.exit(s.GENERAL_ERROR)}}),Ov=new Ei("trace").description("List every credit charge inside one activity group").argument("[group-id]","Artifact or chat ID the group is keyed on; omit only with --group-type ungrouped").option("--group-type <type>","artifact (default), chat, or ungrouped").option("--limit <count>","How many charges to return (default 100)").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("getCreditActivityGroup",{groupId:t,groupType:e.groupType,limit:e.limit===void 0?void 0:Si(e.limit,"--limit"),teamId:e.teamId}))}catch(n){a(m(n,"Reading the credit activity group failed")),process.exit(s.GENERAL_ERROR)}}),ql=new Ei("credits").description("Credit spend reporting").addCommand(Pv).addCommand(Ov);import{randomUUID as Dv}from"crypto";import{readFile as Nv}from"fs/promises";import{Command as Ie,InvalidArgumentError as Ml}from"commander";function Pn(t){return e=>{if(!e.trim())throw new Ml(`${t} must not be blank.`);return e}}function Ti(t,e){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<e)throw new Ml(`${t} must be a whole number of ${e} or more.`);return r}}function Bl(t){return t.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}function Ar(t){return Bl(t).option("--idempotency-key <key>","Exact retry key; a new key is generated when omitted",Pn("--idempotency-key"))}function $r(t){return Bl(t).option("--cursor <cursor>","Continue from the previous nextCursor").option("--page-size <n>","Rows per page; follow nextCursor for all rows",Ti("--page-size",1),50)}function Pr(t,e){return{documentId:t,cursor:e.cursor,pageSize:e.pageSize}}async function Lv(t){if(t.startsWith("@file:"))return Nv(t.slice(6),"utf8");if(t!=="-")return t;let e=[];for await(let n of process.stdin)e.push(Buffer.from(n));return Buffer.concat(e).toString("utf8")}async function Ye(t,e,n,r=!1){let o=r?e.idempotencyKey??`cli:discussion:${Dv()}`:void 0;try{l(await p(t,{...await n(),teamId:e.teamId},o))}catch(i){let d=m(i,"Discussion request failed.");a(`${d}${o?` For an exact retry, reuse --idempotency-key ${o}.`:""}`),process.exit(i instanceof C?i.exitCode:s.GENERAL_ERROR)}}function Uv(){let t=Ar(new Ie("register").description("Register this authenticated credential as an external discussion agent").argument("<display-name>","Declared agent name; does not attest the executable",Pn("display-name"))).action(async(u,f)=>Ye("registerDiscussionActor",f,()=>({displayName:u}),!0)),e=Ar(new Ie("set").description("Set or revoke one external agent's access to a private deck discussion").argument("<document-id>","Presentation document family UUID").argument("<actor-id>","Registered discussion actor UUID").argument("<permission>","Access: none, read, or comment",y("permission",["none","read","comment"])).requiredOption("--expected-revision <revision>","Current grant revision; use 0 when no grant exists",Ti("--expected-revision",0))).action(async(u,f,v,I)=>Ye("setDiscussionGrant",I,()=>({documentId:u,actorId:f,permission:v,expectedRevision:I.expectedRevision}),!0)),n=$r(new Ie("list").description("Read one page of external-agent grants for a private deck").argument("<document-id>","Presentation document family UUID")).action(async(u,f)=>Ye("listDiscussionGrants",f,()=>Pr(u,f))),r=Ar(new Ie("post").description("Post a message or reply; mentions do not invoke agents").argument("<document-id>","Presentation document family UUID").argument("<body>","Full message: literal text, @file:<path> for a UTF-8 file, or '-' for stdin").option("--thread-id <id>","Reply to this thread; omit to open a thread").option("--anchor-slide-id <id>","Anchor the new thread to this slide id; not valid with --thread-id",Pn("--anchor-slide-id"))).action(async(u,f,v)=>Ye("postDiscussionMessage",v,async()=>({documentId:u,threadId:v.threadId,anchorSlideId:v.anchorSlideId,body:Pn("body")(await Lv(f))}),!0)),o=Ar(new Ie("set").description("Resolve or reopen a discussion thread using its current revision").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<state>","Desired state: open or resolved",y("state",["open","resolved"])).requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Ti("--expected-revision",1))).action(async(u,f,v,I)=>Ye("setDiscussionState",I,()=>({documentId:u,threadId:f,state:v,expectedRevision:I.expectedRevision}),!0)),i=$r(new Ie("list").description("Read one page of durable threads for a private deck").argument("<document-id>","Presentation document family UUID").option("--anchor-slide-id <id>","Only threads anchored to this slide id",Pn("--anchor-slide-id"))).action(async(u,f)=>Ye("listDiscussionThreads",f,()=>({...Pr(u,f),anchorSlideId:f.anchorSlideId}))),d=$r(new Ie("read").description("Read a thread and one page of its fully attributed messages").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID")).action(async(u,f,v)=>Ye("readDiscussionThread",v,()=>({...Pr(u,v),threadId:f}))),c=$r(new Ie("events").description("Read one ordered page of durable discussion events; resume with nextCursor").argument("<document-id>","Presentation document family UUID")).action(async(u,f)=>Ye("readDiscussionEvents",f,()=>Pr(u,f)));return new Ie("discussion").description("Collaborate on private decks with attributed human and external-agent messages").addCommand(new Ie("actor").description("Register the current external-agent credential").addCommand(t)).addCommand(new Ie("grant").description("Manage external-agent discussion access").addCommand(e).addCommand(n)).addCommand(r).addCommand(new Ie("state").description("Resolve or reopen discussion threads").addCommand(o)).addCommand(i).addCommand(d).addCommand(c)}var Fl=Uv();import{randomUUID as _v}from"crypto";import{readFile as jv}from"fs/promises";import{Command as Qe}from"commander";var Ai=["text/markdown","text/csv","text/plain"];async function Gl(t){let e=t.content;if(e!==void 0&&e!=="-"&&!e.startsWith("@"))return e;if(e?.startsWith("@"))return jv(e.slice(1),"utf8");if(e==="-"||!process.stdin.isTTY)return Vv();a("No document body. Pass --content <text>, --content @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function Vv(){let t=[];for await(let e of process.stdin)t.push(Buffer.from(e));return Buffer.concat(t).toString("utf8")}function Or(t){return`cli:document:${t}:${_v()}`}function gt(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}function qv(t){if(!t)return;let e=t.split(".").pop()?.toLowerCase();if(e==="md"||e==="markdown")return"text/markdown";if(e==="csv")return"text/csv";if(e==="txt")return"text/plain"}var Mv=new Qe("create").description("Save a document into the Library").argument("<title>","Document title").option("--team-id <id>","Workspace ID").option("--content <text>","Document body: literal text, @<path> to read a file, or '-' for stdin").option("--media-type <type>",`One of ${Ai.join(", ")}; inferred from an @<path> body when omitted`).option("--summary <text>","One line for the Library card").action(async(t,e)=>{try{let n=e.mediaType??qv(e.content?.startsWith("@")?e.content.slice(1):void 0);n||(a(`Cannot tell what this document is. Pass --media-type (${Ai.join(", ")}).`),process.exit(s.GENERAL_ERROR)),l(await p("createDocument",{content:await Gl(e),mediaType:n,summary:e.summary,teamId:e.teamId,title:t},Or("create")))}catch(n){gt(n,"Could not save the document")}}),Bv=new Qe("list").description("List the workspace's documents, newest first").option("--team-id <id>","Workspace ID").option("--media-type <type>",`Filter to one of ${Ai.join(", ")}`).option("--limit <n>","Maximum documents to return (default 50)").action(async t=>{try{l(await p("listDocuments",{limit:t.limit?Number(t.limit):void 0,mediaType:t.mediaType,teamId:t.teamId}))}catch(e){gt(e,"Could not list documents")}}),Fv=new Qe("read").description("Print a document's body").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{let n=await p("readDocument",{documentId:t,teamId:e.teamId}),{document:r}=n;process.stderr.write(`${r.title} \xB7 ${r.mediaType} \xB7 v${r.version} \xB7 ${r.byteLength} bytes
|
|
97
|
+
`),process.stdout.write(r.content)}catch(n){gt(n,"Could not read the document")}}),Gv=new Qe("update").description("Edit a document under an optimistic lock").argument("<document-id>","Document id").requiredOption("--expected-version <n>","The version you last read; the edit is rejected if it has moved on").option("--team-id <id>","Workspace ID").option("--content <text>","New body: literal text, @<path> to read a file, or '-' for stdin").option("--title <text>","New title").option("--summary <text>","New Library-card summary").option("--change-summary <text>","What changed, recorded on the version").action(async(t,e)=>{try{let n=e.content!==void 0;l(await p("updateDocument",{changeSummary:e.changeSummary,content:n?await Gl(e):void 0,documentId:t,expectedVersion:Number(e.expectedVersion),summary:e.summary,teamId:e.teamId,title:e.title},Or("update")))}catch(n){gt(n,"Could not update the document")}}),Kv=new Qe("delete").description("Remove a document from the Library").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").option("--yes","Skip the confirmation prompt").action(async(t,e)=>{try{!e.yes&&process.stdin.isTTY&&(a("Refusing to delete without confirmation. Re-run with --yes to remove this document."),process.exit(s.GENERAL_ERROR)),l(await p("deleteDocument",{documentId:t,teamId:e.teamId},Or("delete")))}catch(n){gt(n,"Could not delete the document")}}),Wv=new Qe("versions").description("List a document's version history").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("listDocumentVersions",{documentId:t,teamId:e.teamId}))}catch(n){gt(n,"Could not list versions")}}),Jv=new Qe("restore").description("Restore an earlier version by appending it as the current one").argument("<document-id>","Document id").requiredOption("--version-number <n>","The historical version to restore").requiredOption("--expected-version <n>","The version you last read; the restore is rejected if it has moved on").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("restoreDocumentVersion",{documentId:t,expectedVersion:Number(e.expectedVersion),teamId:e.teamId,versionNumber:Number(e.versionNumber)},Or("restore")))}catch(n){gt(n,"Could not restore the version")}}),Kl=new Qe("document").description("Create, read and edit Library documents").addCommand(Mv).addCommand(Bv).addCommand(Fv).addCommand(Gv).addCommand(Kv).addCommand(Wv).addCommand(Jv);import{writeFile as zv}from"fs/promises";import{resolve as Wl}from"path";import On from"chalk";import{Command as Hv}from"commander";import Xv from"ora";var Yv=["html","pdf","pptx"],$i=new Hv("export").description("Export a presentation to a local HTML, PDF or PPTX file").argument("<id-or-slug>","Presentation slug, presentation ID or document ID").option("-o, --output <path>","Output file path").option("-f, --format <format>","Export format: html, pdf, pptx",y("--format",Yv),"html").option("--team-id <id>","Workspace ID (uses configured default)").action(async(t,e)=>{await b();let n=Xv("Exporting presentation...").start();try{let r=e.teamId??se();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let o=await hs(t,e.format,{teamId:r}),i=e.output?Wl(e.output):Wl(process.cwd(),o.fileName);n.text="Downloading...";let d=await ys(o.downloadUrl);await zv(i,Buffer.from(d)),n.succeed("Export complete!"),console.log(),w(`File saved: ${i}`),w(`Format: ${o.format}`),w(`Slides: ${o.slideCount}`),w(`Size: ${Qv(d.byteLength)}`),console.log()}catch(r){n.fail("Export failed"),a("The command failed. Please try again."),process.exit(r.exitCode??1)}});function Qv(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}$i.addHelpText("after",`
|
|
98
|
+
${On.bold("Examples:")}
|
|
99
|
+
${On.gray("# Self-contained interactive HTML (default)")}
|
|
100
|
+
$ ${g.commands[0]} export <id-or-slug> -o deck.html
|
|
101
|
+
|
|
102
|
+
${On.gray("# PDF or PowerPoint")}
|
|
103
|
+
$ ${g.commands[0]} export <id-or-slug> -f pdf -o deck.pdf
|
|
104
|
+
$ ${g.commands[0]} export <id-or-slug> -f pptx -o deck.pptx
|
|
105
|
+
|
|
106
|
+
${On.bold("See also:")}
|
|
107
|
+
${On.gray("# For an MP4 instead")}
|
|
108
|
+
$ ${g.commands[0]} presentation video <id-or-slug>
|
|
109
|
+
`);import{randomUUID as Zv}from"crypto";import{existsSync as eI}from"fs";import{Command as ft,InvalidArgumentError as Jl}from"commander";var tI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function nI(t){if(!tI.test(t))throw new Jl("file-id expects a UUID from `mf file list`.");return t}function Pi(t){return e=>{let n=Number(e);if(!Number.isInteger(n)||n<1)throw new Jl(`${t} expects a whole number above 0.`);return n}}function Dr(t){return`cli:file:${t}:${Zv()}`}function Ft(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var rI=new ft("add").description("Put a local file on the Library shelf; a .zip is expanded into the files it holds").argument("<path>","Path to the local file").option("--team-id <id>","Workspace ID").option("--archive-member-paths <paths...>","Exact ZIP member paths to save; preserves the source ZIP").action(async(t,e)=>{await b(),eI(t)||(a(`File not found: ${t}`),process.exit(s.INVALID_INPUT));try{let n=at(t),r=Dr("add"),o=await p("createLibraryFileUploadUrl",{...n,teamId:e.teamId},`${r}:upload`),i=await st(t,o);l(await p("addLibraryFile",{archiveMemberPaths:e.archiveMemberPaths,mediaType:i.type,name:i.name,size:i.size,teamId:e.teamId,uploadKey:i.s3Key,url:i.url},r))}catch(n){Ft(n,"Could not add that file to the Library")}}),oI=new ft("upload-url").description("Mint an upload target for a file you will add to the Library").requiredOption("--file-name <name>","Name of the file being uploaded").requiredOption("--file-size <bytes>","Exact byte size of the file",Pi("--file-size")).requiredOption("--file-type <mime>","Media type of the file").option("--team-id <id>","Workspace ID").action(async t=>{await b();try{l(await p("createLibraryFileUploadUrl",{fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType,teamId:t.teamId},Dr("upload-url")))}catch(e){Ft(e,"Could not mint an upload target")}}),iI=new ft("list").description("List the workspace's Library files, newest first").option("--team-id <id>","Workspace ID").option("--limit <n>","Maximum files to return (default 50)",Pi("--limit")).action(async t=>{await b();try{l(await p("listLibraryFiles",{limit:t.limit,teamId:t.teamId}))}catch(e){Ft(e,"Could not list Library files")}}),aI=new ft("remove").description("Take a file off the shelf and delete its stored bytes").argument("<file-id>","File id from `mf file list`",nI).option("--team-id <id>","Workspace ID").action(async(t,e)=>{await b();try{l(await p("removeLibraryFile",{fileId:t,teamId:e.teamId},Dr("remove")))}catch(n){Ft(n,"Could not remove that file")}}),sI=new ft("inspect-archive").description("List exact member paths and metadata from an owned ZIP upload").requiredOption("--upload-key <key>","Storage key from `mf file upload-url`").requiredOption("--url <url>","App-owned file URL from `mf file upload-url`").option("--team-id <id>","Workspace ID").action(async t=>{await b();try{l(await p("inspectLibraryArchive",t))}catch(e){Ft(e,"Could not inspect that ZIP upload")}}),dI=new ft("save").description("File an object you already uploaded onto the Library shelf").option("--archive-member-paths <paths...>","Exact ZIP member paths to save; preserves the source ZIP").requiredOption("--media-type <type>","Media type of the uploaded object").requiredOption("--name <name>","File name to show on the shelf").requiredOption("--size <bytes>","Byte size of the uploaded object",Pi("--size")).requiredOption("--upload-key <key>","Storage key from `mf file upload-url`").requiredOption("--url <url>","App-owned file URL from `mf file upload-url`").option("--team-id <id>","Workspace ID").action(async t=>{await b();try{l(await p("addLibraryFile",{archiveMemberPaths:t.archiveMemberPaths,mediaType:t.mediaType,name:t.name,size:t.size,teamId:t.teamId,uploadKey:t.uploadKey,url:t.url},Dr("save")))}catch(e){Ft(e,"Could not file that object")}}),zl=new ft("file").description("Library files you can mention in chat with @").addCommand(rI).addCommand(dI).addCommand(sI).addCommand(iI).addCommand(aI).addCommand(oI);import{Command as Ae}from"commander";var cI=new Ae("create").description("Create a transcript-native footage edit project").requiredOption("--title <title>","Project title").requiredOption("--source <asset-ids...>","Analyzed source recording IDs").requiredOption("--strategy <json>","Editorial strategy JSON object").requiredOption("--ranges <json>","Selected ranges JSON array").requiredOption("--outputs <json>","Output variants JSON array").option("--overlays <json>","Overlay JSON array","[]").option("--music-asset-id <id>","Music media asset ID").option("--source-chat-id <id>","Source chat ID").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async t=>{await Ze("createFootageProject",{input:{musicAssetId:t.musicAssetId??null,outputs:Dn(t.outputs,"outputs"),overlays:Dn(t.overlays,"overlays"),ranges:Dn(t.ranges,"ranges"),sourceAssetIds:t.source,sourceChatId:t.sourceChatId,strategy:Dn(t.strategy,"strategy"),teamId:t.teamId,title:t.title},idempotencyKey:t.idempotencyKey})}),lI=new Ae("show").description("Read a footage project and its append-only versions").argument("<project-id>","Project ID or slug").option("--version-id <id>","Historical version ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await Ze("getFootageProject",{input:{projectId:t,teamId:e.teamId,versionId:e.versionId}})}),mI=new Ae("revise").description("Append a semantic footage draft revision").argument("<project-id>","Project ID or slug").requiredOption("--base-version-id <id>","Current version ID").requiredOption("--change-summary <text>","Human-readable change summary").option("--title <title>","Replacement title").option("--strategy <json>","Replacement strategy JSON object").option("--ranges <json>","Replacement ranges JSON array").option("--outputs <json>","Replacement outputs JSON array").option("--overlays <json>","Replacement overlays JSON array").option("--music-asset-id <id-or-null>","Replacement music asset ID or null").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await Ze("reviseFootageProject",{input:Yl({baseVersionId:e.baseVersionId,changeSummary:e.changeSummary,musicAssetId:e.musicAssetId==="null"?null:e.musicAssetId,outputs:Nr(e.outputs,"outputs"),overlays:Nr(e.overlays,"overlays"),projectId:t,ranges:Nr(e.ranges,"ranges"),strategy:Nr(e.strategy,"strategy"),teamId:e.teamId,title:e.title}),idempotencyKey:e.idempotencyKey})}),pI=new Ae("restore").description("Restore a historical footage version as a new head").argument("<project-id>","Project ID or slug").argument("<version-id>","Historical version ID").option("--change-summary <text>","Change summary","Restored version").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{await Ze("restoreFootageProjectVersion",{input:{changeSummary:n.changeSummary,projectId:t,teamId:n.teamId,versionId:e},idempotencyKey:n.idempotencyKey})}),uI=new Ae("branch").description("Branch a historical footage version into a new project").argument("<project-id>","Source project ID or slug").argument("<version-id>","Historical version ID").requiredOption("--title <title>","New project title").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{await Ze("branchFootageProjectVersion",{input:{projectId:t,teamId:n.teamId,title:n.title,versionId:e},idempotencyKey:n.idempotencyKey})}),gI=new Ae("inspect").description("Create proxy, filmstrip, and waveform evidence for one range").argument("<project-id>","Project ID or slug").argument("<range-id>","Stable range ID").requiredOption("--version-id <id>","Exact version ID").requiredOption("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{await Ze("inspectFootageRange",{input:{projectId:t,rangeId:e,teamId:n.teamId,versionId:n.versionId},idempotencyKey:n.idempotencyKey})}),fI=new Ae("inspection-status").description("Read a footage range inspection run").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await Xl("inspectFootageRange",t,e.teamId)}),hI=new Ae("render").description("Render an exact approved footage draft version").argument("<project-id>","Project ID or slug").requiredOption("--version-id <id>","Exact version ID").option("--output <ids...>","Output IDs; omit to render every output").option("--approval-receipt <receipt>","Browser-issued approval receipt; omit on the first call to get the confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").requiredOption("--idempotency-key <key>","Key bound into the receipt").option("--team-id <id>","Workspace ID").action(async(t,e)=>{let n=_(e);await Ze("renderFootageProject",{input:Yl({approvalReceipt:n,outputIds:e.output,projectId:t,teamId:e.teamId,versionId:e.versionId}),idempotencyKey:e.idempotencyKey})}),yI=new Ae("render-status").description("Read a Footage Studio render run").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await Xl("renderFootageProject",t,e.teamId)}),bI=new Ae("import-takes").description("Import all completed takes from a clipping invocation").argument("<project-id>","Project ID or slug").requiredOption("--invocation-id <id>","cc-services clipping invocation ID").requiredOption("--idempotency-key <key>","Stable import retry key").option("--team-id <id>","Workspace ID").action(async(t,e)=>{await Ze("importFootageProviderTakes",{input:{invocationId:e.invocationId,projectId:t,teamId:e.teamId},idempotencyKey:e.idempotencyKey})}),Hl=new Ae("footage").description("Create, inspect, revise, and render transcript-native footage edits").addCommand(cI).addCommand(lI).addCommand(mI).addCommand(pI).addCommand(uI).addCommand(gI).addCommand(fI).addCommand(hI).addCommand(yI).addCommand(bI);async function Ze(t,e){try{l(await p(t,e.input,e.idempotencyKey))}catch(n){a(m(n,"Footage operation failed")),process.exit(s.GENERAL_ERROR)}}async function Xl(t,e,n){try{l(await x(t,e,n))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}function Dn(t,e){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON.`)}}function Nr(t,e){return typeof t=="string"?Dn(t,e):void 0}function Yl(t){return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}import ht from"chalk";import{Command as wI}from"commander";function vI(t){return new Set((t??"").split(",").map(e=>e.trim().toLowerCase()).filter(Boolean))}function II(t){if(!t)throw new Error("Slides were requested but the server returned none. Retry, or read the deck in the browser.");Se("Slides"),console.log();for(let e of t){console.log(ht.bold(` ${e.number}. ${e.title||"Untitled"}`));let n=e.text?.trim();console.log(n?Ql(n):ht.gray(" (no text on this slide \u2014 image or empty)"));let r=e.speakerNotes?.trim();r&&(console.log(ht.gray(" Narration/notes:")),console.log(ht.gray(Ql(r)))),console.log()}}function Ql(t){return t.split(`
|
|
110
|
+
`).map(e=>` ${e}`).join(`
|
|
111
|
+
`)}var Zl=new wI("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)",y("--format",["summary","full","json"]),"summary").option("--include <fields>","Legacy fields list (comma-separated: slides,styling)").option("--include-slides","Include ordered slide content",!0).option("--no-include-slides","Omit slide content for a smaller response").option("-l, --language <lang>","Language for view URL","en").option("--team-id <id>","Workspace ID (uses configured default)").action(async function(t,e){await b();try{let n=this.getOptionValueSource("includeSlides")==="cli"?e.includeSlides:this.getOptionValueSource("include")==="cli"?vI(e.include).has("slides"):!0,r=e.teamId??se();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let o=await Ct(t,{includeSlides:n,teamId:r});if(e.format==="json"){console.log(JSON.stringify(o,null,2));return}let i=St(o.slug,e.language);Se("Presentation Details"),console.log(),E("Slug",o.slug),E("Title",o.title||"Untitled"),E("Description",o.description||ht.gray("None")),E("Slides",String(o.numberOfSlides||"-")),E("Mode",o.mode||"-"),E("Created",Oo(o.createdAt)),o.updatedAt&&E("Updated",Oo(o.updatedAt)),console.log(),i!=="N/A"&&console.log(ht.bold(" Open: ")+ht.cyan.underline(i)),console.log(),n&&II(o.slides)}catch(n){a("The command failed. Please try again.");let r=n&&typeof n=="object"&&"exitCode"in n&&typeof n.exitCode=="number"?n.exitCode:1;process.exit(r)}});import{randomUUID as kI}from"crypto";import{Command as Ur}from"commander";import xI from"ora";function RI(t){let e=t?.trim().toLowerCase();if(!(!e||e==="any"||e==="all"))return e==="web"||e==="stock"?[e]:void 0}function CI(t){let e=t.assetType??"image";if(e!=="image"&&e!=="icon")throw new Error("Asset type must be image or icon");let n;if(t.maxResults&&(n=Number.parseInt(t.maxResults,10),Number.isNaN(n)||n<1))throw new Error("Max results must be a positive number");return{query:e==="icon"?`${t.query.trim()} transparent icon isolated symbol`:t.query.trim(),options:{maxResults:n||10,size:t.size,safeSearch:t.safeSearch,assetType:e,sources:RI(t.source),transparentBackground:e==="icon"}}}function SI(t){let e=t.url||t.imageUrl;if(!e)throw new Error("Image search returned a result without a URL");return e}function EI(t){return t.transparent??t.isTransparent??t.metadata?.transparent??t.metadata?.isTransparent}function TI(t){let e=[],n=t.reduce((r,o)=>Math.max(r,o.length),0);for(let r=0;r<n;r+=1)for(let o of t){let i=o[r];i!==void 0&&e.push(i)}return e}function AI(t,e){let n=t.data.results.map(r=>r.results.map(o=>{let i=o,d=EI(i);if(e==="icon"&&d!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...i,url:SI(i),provider:r.providerName,assetType:e,...d!==void 0?{transparent:d}:{}}}));return TI(n)}function $I(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 Lr(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function PI(t){return{requestId:t.runId,status:$I(t),...t.entity?.url?{url:t.entity.url}:{},...t.error?{error:re(t.error)}:{},...Lr(t.output?.width)!==void 0?{width:Lr(t.output?.width)}:{},...Lr(t.output?.height)!==void 0?{height:Lr(t.output?.height)}:{}}}async function em(t,e){return PI(await x("createImage",t,e))}function Oi(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.output??t.url??t.requestId);return}w(`Request ID: ${t.requestId}`),w(`Status: ${t.status}`),t.url&&k(`Image URL: ${t.url}`),t.output&&k(`Saved to: ${t.output}`),t.error&&a(`Error: ${t.error}`)}var OI=new Ur("search").description("Search images across the web and licensed stock").requiredOption("-q, --query <query>","Search query").option("-n, --max-results <number>","Maximum number of results (default: 10)").option("-s, --size <size>","Image size: small, medium, large, any","large").option("--asset-type <type>","Asset intent: image or transparent icon","image").option("--source <source>","Catalog: web, stock, or any (default: any)","any").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",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.format,n=e==="human"?xI("Searching for images...").start():null,r;try{r=CI(t)}catch(o){n?.stop(),a(m(o,"Invalid image search request")),process.exit(s.INVALID_INPUT);return}try{let o=await As(r);n?.stop(),o.success||(a("Search failed"),process.exit(s.GENERAL_ERROR));let i=r.options?.assetType??"image",d=AI(o,i);if(e==="json"){l({success:!0,query:t.query,assetType:i,totalResults:d.length,images:d});return}if(e==="quiet"){for(let c of d)console.log(c.url);return}if(d.length===0){w("No images found");return}k(`Found ${d.length} images for "${t.query}"`),console.log();for(let c=0;c<d.length;c++){let u=d[c];console.log(`[${c+1}] ${u.title||"Untitled"}`),console.log(` URL: ${u.url}`),console.log(` Size: ${u.width}x${u.height}`),u.author&&console.log(` Author: ${u.author}`),console.log(` Provider: ${u.provider}`),console.log()}}catch(o){n?.stop(),a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),DI=new Ur("generate").description("Generate an image and optionally save it locally").argument("[prompt]","Image prompt").option("-p, --prompt <text>","Image prompt (named compatibility form)").option("--provider <provider>","Provider override").option("--model <model>","Model override").option("--aspect-ratio <ratio>","Output aspect ratio: square, wide, or tall",y("--aspect-ratio",["square","wide","tall"])).option("--number-of-images <count>","Number of images (1-4)").option("--purpose <purpose>","Explicit image intent: general, draft, infographic, brand-max, or vector; omitted means general",y("--purpose",["general","draft","infographic","brand-max","vector"])).option("--width <pixels>","Width").option("--height <pixels>","Height").option("--reason <text>","Optional generation reason").option("--team-id <id>","Workspace ID").option("--reference-image <label=path-or-url...>","Image the generation must follow: a local file (uploaded for you, never resized) or a public HTTP(S) URL. Repeatable. Prefix an optional label, e.g. identity=./face.jpg, style=https://\u2026/mood.png. Fidelity depends on the routed model: the auto-routed one returns a similar-looking subject, while --provider google-ai --model gemini-3-pro-image returns the same person \u2014 but that pin takes effect only on workspaces holding the internal image-model-override flag").option("--idempotency-key <key>","Stable retry key for this generation and its reference uploads").option("-o, --output <path>","Local output path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").option("--yes","Approve generation").action(async(t,e)=>{let n,r=t??e.prompt;r?.trim()||(a("Provide an image prompt as an argument or with --prompt"),process.exit(s.INVALID_INPUT)),e.yes||(a("Pass --yes to approve image generation"),process.exit(s.INVALID_INPUT)),!e.wait&&e.output&&(a("--output requires waiting for completion; remove --no-wait"),process.exit(s.INVALID_INPUT)),(e.provider||e.model)&&L("--provider/--model are honoured only for workspaces holding the internal image-model-override flag. Without it the server drops them and routes the request itself.",e.format),e.referenceImage?.length&&!e.model&&L("Reference images without --model route to a light model that returns a similar-looking, not identical, subject. A recognisable likeness needs --provider google-ai --model gemini-3-pro-image on a workspace with the image-model-override flag.",e.format);let o=e.idempotencyKey??kI(),i;try{i=await ur(e.referenceImage,{idempotencyKey:o,rejectNonImageFiles:!0})}catch(d){a(m(d,"Could not resolve --reference-image"),e.format),process.exit(s.INVALID_INPUT)}try{let d=await p("createImage",{aspectRatio:e.aspectRatio,confirmed:!0,height:e.height?Number.parseInt(e.height,10):void 0,model:e.model,numberOfImages:e.numberOfImages?Number.parseInt(e.numberOfImages,10):void 0,prompt:r.trim(),provider:e.provider,...e.purpose?{purpose:e.purpose}:{},...i?{referenceImages:i}:{},reason:e.reason,teamId:e.teamId,width:e.width?Number.parseInt(e.width,10):void 0},o);if(n=d.runId,!e.wait){Oi({requestId:d.runId,status:"pending"},e.format);return}let c=await be(()=>em(d.runId,e.teamId),180,2e3);if(c.status==="failed")throw new Error(c.error||"Image generation failed");if(!c.url)throw new Error("Image generation completed without an image URL");let u=e.output?{...c,output:e.output}:c;e.output&&await de(c.url,e.output),Oi(u,e.format)}catch(d){a(te(d,n),e.format),process.exit(s.GENERAL_ERROR)}}),NI=new Ur("status").description("Read image generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-o, --output <path>","Download a completed image").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await em(t,e.teamId);if(e.output){if(n.status!=="completed"||!n.url)throw new Error("Image generation is not complete");await de(n.url,e.output),n.output=e.output}Oi(n,e.format)}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),tm=new Ur("image").description("Image search and generation commands").addCommand(OI).addCommand(DI).addCommand(NI);import{Command as Di}from"commander";var LI=new Di("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").option("--provenance <source>","Filter by human or agent provenance").action(async(t,e)=>{try{l(await p("searchKnowledge",{kind:e.kind,limit:Number.parseInt(e.limit,10),provenance:e.provenance,query:t,teamId:e.teamId}))}catch(n){a(m(n,"Knowledge search failed")),process.exit(s.GENERAL_ERROR)}}),UI=new Di("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async t=>{try{l(await p("getKnowledgeBundle",{kind:t.kind,teamId:t.teamId}))}catch(e){a(m(e,"Knowledge bundle failed")),process.exit(s.GENERAL_ERROR)}}),nm=new Di("knowledge").description("Search the workspace Knowledge Hub and read bounded knowledge bundles").addCommand(LI).addCommand(UI);import{randomUUID as _I}from"crypto";import _r from"chalk";import{Command as Me}from"commander";function Ni(t){if(t!==void 0)return t==="root"?null:t}function Gt(t){return`cli:library:${t}:${_I()}`}function yt(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var jI=new Me("list").description("List the Library folder tree").option("--team-id <id>","Workspace ID").option("--counts","Include how many items are in each folder").action(async t=>{try{l(await p("listLibraryFolders",{includeEntryCounts:!!t.counts,teamId:t.teamId}))}catch(e){yt(e,"Could not list folders")}}),VI=new Me("create").description("Create a Library folder").argument("<name>","Folder name").option("--team-id <id>","Workspace ID").option("--parent <id>","Parent folder id; omit for a top-level folder").option("--color <color>","Colour token (slate, blue, green, amber, red, violet)").action(async(t,e)=>{try{l(await p("createLibraryFolder",{color:e.color,name:t,parentId:Ni(e.parent),teamId:e.teamId},Gt("create")))}catch(n){yt(n,"Could not create the folder")}}),qI=new Me("rename").description("Rename a Library folder").argument("<folder-id>","Folder id").argument("<name>","New name").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{try{l(await p("renameLibraryFolder",{folderId:t,name:e,teamId:n.teamId},Gt("rename")))}catch(r){yt(r,"Could not rename the folder")}}),MI=new Me("recolor").description("Set or clear a Library folder's colour").argument("<folder-id>","Folder id").requiredOption("--color <color>","Colour token (slate, blue, green, amber, red, violet), or 'none' to clear").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("recolorLibraryFolder",{color:e.color==="none"?null:e.color,folderId:t,teamId:e.teamId},Gt("recolor")))}catch(n){yt(n,"Could not recolour the folder")}}),BI=new Me("move").description("Move a Library folder under a new parent").argument("<folder-id>","Folder id").requiredOption("--to <id>","New parent folder id, or 'root' for top level").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("moveLibraryFolder",{folderId:t,newParentId:Ni(e.to),teamId:e.teamId},Gt("move")))}catch(n){yt(n,"Could not move the folder")}}),FI=new Me("delete").description("Delete a folder and its subfolders; items inside are unfiled").argument("<folder-id>","Folder id").requiredOption("--yes","Confirm deletion").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("deleteLibraryFolder",{folderId:t,teamId:e.teamId},Gt("delete")))}catch(n){yt(n,"Could not delete the folder")}}),GI=new Me("folders").description("Manage Library folders").addCommand(jI).addCommand(VI).addCommand(qI).addCommand(MI).addCommand(BI).addCommand(FI),KI=new Me("file").description("File an artifact into a Library folder").argument("<kind>","Artifact kind, e.g. presentation or microsite").argument("<target-id>","Id of the artifact itself").requiredOption("--folder <id>","Destination folder id, or 'root' to unfile the artifact").option("--team-id <id>","Workspace ID").action(async(t,e,n)=>{try{l(await p("fileArtifactIntoFolder",{folderId:Ni(n.folder),kind:t,targetId:e,teamId:n.teamId},Gt("file")))}catch(r){yt(r,"Could not file that item")}}),Li=new Me("library").description("Library folders and filing").addCommand(GI).addCommand(KI);Li.addHelpText("after",`
|
|
112
|
+
${_r.bold("Examples:")}
|
|
113
|
+
${_r.gray("# Browse the folder tree and file an artifact into a folder")}
|
|
114
|
+
$ ${g.commands[0]} library folders list
|
|
115
|
+
$ ${g.commands[0]} library file presentation <id> --folder <folder-id>
|
|
116
|
+
|
|
117
|
+
${_r.bold("See also:")}
|
|
118
|
+
${_r.gray("# A different thing: reusable video clips, not Library folders")}
|
|
119
|
+
$ ${g.commands[0]} video library --help
|
|
120
|
+
`);import{randomUUID as rm}from"crypto";import{Command as Nn}from"commander";var om=new Nn("analyze").description("Transcribe an uploaded recording and publish it for generation").argument("<asset-id>","Recording ID").option("--language <code>","BCP-47 language hint for the spoken audio").option("--no-diarize","Skip speaker attribution (cheaper, but a multi-speaker recording becomes much weaker as generation input)").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable recovery key").option("--yes","Confirm the charge \u2014 billed per source-minute").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to confirm. Analysis is billed per minute of source audio.");let n=e.idempotencyKey??rm();try{l(await p("analyzeMediaAsset",{assetId:t,diarize:e.diarize,language:e.language,teamId:e.teamId},n))}catch(r){a(`${m(r,"Analysis failed")} Retry with --idempotency-key ${n}.`),process.exit(s.GENERAL_ERROR)}}),WI=new Nn("status").description("Read an analysis run's status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async function(t,e){let n=R(this,e);try{l(await x("analyzeMediaAsset",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});om.addCommand(WI);var im=new Nn("import").description("Import a recording from a connected account").argument("<remote-file-id>","The provider's own ID for the recording").requiredOption("--provider <id>","Provider id of the connected account, e.g. google").requiredOption("--connector <id>","Connected account ID to read from").option("--title <title>","Name for the imported recording").option("--chat <id>","Chat this import was requested from").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").action(async(t,e)=>{try{l(await p("importConnectorRecording",{connectorId:e.connector,providerId:e.provider,remoteFileId:t,sourceChatId:e.chat,teamId:e.teamId,title:e.title},e.idempotencyKey??rm()))}catch(n){a(m(n,"Import failed")),process.exit(s.GENERAL_ERROR)}}),JI=new Nn("status").description("Read an import run's status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async function(t,e){let n=R(this,e);try{l(await x("importConnectorRecording",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});im.addCommand(jt(JI));var am=new Nn("media").description("Ingest and transcribe recordings you already own").addCommand(om).addCommand(im);import{Command as Ui}from"commander";function zI(t,e){let n=t.indexOf("=");return n<=0&&(a("Pass --additional-page as /path=Title"),process.exit(s.INVALID_INPUT)),[...e,{path:t.slice(0,n),title:t.slice(n+1)}]}var HI=new Ui("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("--design-brand-reference <text>","Free-text design or brand reference").option("--additional-page <page>","Extra page as /path=Title (repeat)",zI,[]).option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--yes","Approve generation").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to approve generation");try{l(await p("createMicrosite",{additionalPages:e.additionalPage.length?e.additionalPage:void 0,approvalReceipt:_(e),audience:e.audience,brandingId:e.brandingId,description:e.description,designBrandReference:e.designBrandReference,language:e.language,teamId:e.teamId,title:t,tone:e.tone},e.idempotencyKey))}catch(n){a(m(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),XI=new Ui("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("createMicrosite",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),sm=new Ui("microsite").description("Generate a shareable multi-section web microsite from a brief").addCommand(HI).addCommand(XI);import{randomUUID as YI}from"crypto";import{Command as Vi}from"commander";import _i from"ora";function ji(t,e){if(e==="json"){l(t);return}if(e==="quiet"){t.outputUrl?console.log(t.outputUrl):console.log(t.requestId);return}w(`Request ID: ${t.requestId}`),w(`Status: ${t.status}`),t.duration&&w(`Duration: ${t.duration}s`),t.outputUrl&&k(`Output URL: ${t.outputUrl}`),t.error&&a(`Error: ${t.error}`)}var QI=new Vi("create").description("Mix audio tracks into a video (music will loop to match video duration)").option("--video <url>","Input video file/URL").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--inputs-json <json>","Canonical audio input array").option("--operation <operation>","Canonical mix operation","add-to-video").option("--options-json <json>","Canonical mix options JSON").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",y("--format",["human","json","quiet"]),"human").action(async t=>{let e;try{e=_(t)}catch(f){a(m(f)),process.exit(s.INVALID_INPUT)}!t.inputsJson&&(!t.video||!t.music&&!t.voice)&&(a("At least one of --music or --voice must be provided"),process.exit(s.INVALID_INPUT));let n=parseInt(t.musicVolume,10)/100,r=parseInt(t.voiceVolume,10)/100;(Number.isNaN(n)||n<0||n>1)&&(a("Music volume must be between 0 and 100"),process.exit(s.INVALID_INPUT)),(Number.isNaN(r)||r<0||r>2)&&(a("Voice volume must be between 0 and 200"),process.exit(s.INVALID_INPUT));let o=t.format,i=o==="human"?_i("Mixing audio...").start():null,d=t.inputsJson?ZI("--inputs-json",t.inputsJson):[{url:t.video,role:"video"}];!t.inputsJson&&t.music&&d.push({url:t.music,role:"background",volume:n*5}),!t.inputsJson&&t.voice&&d.push({url:t.voice,role:"voice",volume:r*2});let c,u=t.idempotencyKey??YI();try{let f=t.optionsJson?ek("--options-json",t.optionsJson):{},v=await Ts({operation:t.operation,inputs:d,options:t.inputsJson?f:{...f,musicVolume:n,voiceVolume:r}},{approvalReceipt:e,idempotencyKey:u});if(c=v.requestId,!t.wait){i?.stop(),ji(v,o);return}i&&(i.text=`Processing (ID: ${v.requestId})...`);let I=await be(()=>To(v.requestId),120,3e3);if(i?.stop(),I.status==="failed"&&(a(I.error||"Audio mixing failed"),process.exit(s.GENERAL_ERROR)),ji(I,o),t.output){if(!I.outputUrl)throw new Error("Audio mix completed without an output URL");let S=o==="human"?_i("Downloading...").start():null;await de(I.outputUrl,t.output),S?.stop(),o==="human"&&k(`Saved to: ${t.output}`)}}catch(f){i?.stop(),a(`${te(f,c)} Retry with --idempotency-key ${u}.`,o),process.exit(s.GENERAL_ERROR)}});function ZI(t,e){try{let n=JSON.parse(e);if(!Array.isArray(n))throw new Error;return n}catch{throw new Error(`${t} must be a JSON array`)}}function ek(t,e){try{let n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))throw new Error;return n}catch{throw new Error(`${t} must be a JSON object`)}}var tk=new Vi("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{let n=e.format==="human"?_i("Checking status...").start():null;try{let r=await To(t);n?.stop(),ji(r,e.format)}catch(r){n?.stop(),a(m(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),dm=new Vi("mix").description("Audio mixing commands").addCommand(QI).addCommand(tk);import{randomUUID as dk}from"crypto";import{Command as Mi}from"commander";import ck from"ora";import{readFileSync as nk}from"fs";var cm=500,lm=1e4,jr=100,mm=1e4,pm=1e3,gm=["duration_s","idempotency_key","narration","schema_version","video_description"],rk=["end_s","id","start_s","text","words"],ok=["end","id","start","text"],ik=["description","end_s","id","start_s"];function fm(t){let e=ym(t);if(bm(e),Ln(e,gm,""),e.duration_s<3)throw new Error("Music request duration_s must be between 3 and 600");return e}function hm(t){let e=ym(t);bm(e),Ln(e,[...gm,"visual_event"],"");let n=e.visual_event;if(!Vr(n))throw new Error("SFX request visual_event is required");if(Ln(n,ik,"visual_event"),!et(n.description))throw new Error("SFX request visual_event.description is required");if(!et(n.id)||!tt(n.start_s))throw new Error("SFX request visual_event requires id and start_s");if(n.end_s!==void 0&&(!tt(n.end_s)||n.end_s<n.start_s))throw new Error("SFX request visual_event.end_s must be after start_s");return e}function ym(t){try{let e=JSON.parse(nk(t,"utf8"));if(!Vr(e))throw new Error("request must be a JSON object");return e}catch(e){throw new Error(`Cannot read audio request ${t}: ${e instanceof Error?e.message:String(e)}`)}}function bm(t){if(t.schema_version!==1)throw new Error("Audio request schema_version must be 1");if(!et(t.video_description))throw new Error("Audio request video_description is required");if(!tt(t.duration_s)||t.duration_s<.5||t.duration_s>600)throw new Error("Audio request duration_s must be between 0.5 and 600");if(!Array.isArray(t.narration))throw new Error("Audio request narration must be an array");if(t.narration.length>cm)throw new Error(`Audio request narration holds at most ${cm} lines`);if(t.narration.forEach(ak),t.idempotency_key!==void 0&&!et(t.idempotency_key))throw new Error("Audio request idempotency_key must be a non-empty string")}function ak(t,e){let n=`narration.${e}`;if(!Vr(t))throw new Error(`Audio request ${n} must be an object`);if(Ln(t,rk,n),!et(t.id)||t.id.length>jr)throw new Error(`Audio request ${n}.id is required (1-${jr} characters)`);if(!et(t.text)||t.text.trim().length>mm)throw new Error(`Audio request ${n}.text is required (1-${mm} characters)`);if(um(t.start_s,`${n}.start_s`),um(t.end_s,`${n}.end_s`),tt(t.start_s)&&tt(t.end_s)&&t.end_s<t.start_s)throw new Error(`Audio request ${n}.end_s must be greater than or equal to ${n}.start_s`);if(t.words!==void 0){if(!Array.isArray(t.words)||t.words.length>lm)throw new Error(`Audio request ${n}.words must be an array of at most ${lm} entries`);t.words.forEach((r,o)=>{sk(r,`${n}.words.${o}`)})}}function sk(t,e){if(!Vr(t))throw new Error(`Audio request ${e} must be an object`);if(Ln(t,ok,e),!et(t.text)||t.text.trim().length>pm)throw new Error(`Audio request ${e}.text is required (1-${pm} characters)`);if(!tt(t.start)||!tt(t.end))throw new Error(`Audio request ${e} requires numeric start and end seconds`);if(t.end<t.start)throw new Error(`Audio request ${e}.end must be greater than or equal to ${e}.start`);if(t.id!==void 0&&(!et(t.id)||t.id.length>jr))throw new Error(`Audio request ${e}.id must be 1-${jr} characters`)}function um(t,e){if(t!==void 0&&!tt(t))throw new Error(`Audio request ${e} must be a non-negative number`)}function Ln(t,e,n){let r=Object.keys(t).filter(i=>!e.includes(i));if(r.length===0)return;let o=n?`${n} `:"";throw new Error(`Audio request ${o}has unknown field(s): ${r.join(", ")}. Allowed: ${e.join(", ")}`)}function Vr(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function et(t){return typeof t=="string"&&t.trim().length>0}function tt(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0}function qi(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.audioUrl??t.requestId);return}w(`Request ID: ${t.requestId}`),w(`Status: ${t.status}`),t.duration&&w(`Duration: ${t.duration}s`),t.audioUrl&&k(`Audio URL: ${t.audioUrl}`),t.error&&a(`Error: ${t.error}`)}var lk=new Mi("generate").description("Generate music that follows a video's narration and final timing").option("--request <path>","JSON file with video description, narration, and final timing").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--duration <seconds>","Direct music duration").option("--duration-seconds <seconds>","Final video duration").option("--narration-json <json>","Final narration timing array").option("--options-json <json>","Canonical music options JSON").option("--prompt <text>","Direct music brief").option("--schema-version <version>","Video facts schema version").option("--video-description <text>","Final video description").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e;try{e=_(t)}catch(c){a(m(c)),process.exit(s.INVALID_INPUT)}!t.wait&&t.output&&(a("--output requires waiting for completion; remove --no-wait"),process.exit(s.INVALID_INPUT));let n;try{n=t.request?fm(t.request):{...t.duration?{duration:Number(t.duration)}:{},...t.durationSeconds?{duration_s:Number(t.durationSeconds)}:{},...t.narrationJson?{narration:wm("--narration-json",t.narrationJson)}:{},...t.optionsJson?{options:wm("--options-json",t.optionsJson)}:{},...t.prompt?{prompt:t.prompt}:{},...t.schemaVersion?{schema_version:Number(t.schemaVersion)}:{},...t.videoDescription?{video_description:t.videoDescription}:{}}}catch(c){a(m(c)),process.exit(s.INVALID_INPUT)}let r=t.format,o=r==="human"?ck("Generating music for video...").start():null,i,d=t.idempotencyKey??n.idempotency_key??dk();try{let c=await Es(n,{approvalReceipt:e,idempotencyKey:d});if(i=c.requestId,!t.wait){o?.stop(),qi(c,r);return}o&&(o.text=`Processing (ID: ${c.requestId})...`);let u=c.status==="completed"||c.status==="failed"?c:await be(()=>Eo(c.requestId),180,2e3);if(o?.stop(),u.status==="failed"&&(a(u.error||"Music generation failed"),process.exit(s.GENERAL_ERROR)),t.output){if(!u.audioUrl)throw new Error("Music completed without an audio URL");await de(u.audioUrl,t.output),r==="human"&&k(`Saved to: ${t.output}`),u.output=t.output}qi(u,r)}catch(c){o?.stop(),a(`${te(c,i)} Retry with --idempotency-key ${d}.`,r),process.exit(s.GENERAL_ERROR)}});function wm(t,e){try{return JSON.parse(e)}catch{throw new Error(`${t} must be valid JSON`)}}var mk=new Mi("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{qi(await Eo(t),e.format)}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),vm=new Mi("music").description("Video-aware music generation commands").addCommand(lk).addCommand(mk);import{Command as Bi,InvalidArgumentError as pk}from"commander";function Im(t,e){return[...e,t]}function km(t){return e=>{if(e==="true")return!0;if(e==="false")return!1;throw new pk(`Expected one of: true, false. Run the command with --help to see what ${t} accepts.`)}}function xm(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var uk=new Bi("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",Im,[]).option("--type <type>","single, multiple, or word-cloud",y("--type",["single","multiple","word-cloud"]),"single").option("--title <title>","Poll title").option("--description <text>","Poll description").option("--closes-at <iso>","ISO 8601 close time").option("--respondent-policy <policy>","anonymous, name, or email",y("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",km("--show-results-to-participants")).option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--yes","Approve poll creation").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to approve poll creation");try{l(await p("createPoll",{approvalReceipt:_(e),closesAt:e.closesAt,description:e.description,options:e.option.map(n=>({text:n})),pollType:e.type,question:t,respondentPolicy:e.respondentPolicy,showResultsToParticipants:e.showResultsToParticipants,teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(n){xm(n,"Poll creation failed")}}),gk=new Bi("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",Im).option("--type <type>","single, multiple, or word-cloud",y("--type",["single","multiple","word-cloud"])).option("--chart-type <type>","Chart type valid for the poll type").option("--title <title>","Poll title").option("--description <text>","Poll description").option("--closes-at <iso>","ISO 8601 close time").option("--respondent-policy <policy>","anonymous, name, or email",y("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",km("--show-results-to-participants")).option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--yes","Approve poll update").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to approve poll update");try{l(await p("editPoll",{approvalReceipt:_(e),chartType:e.chartType,closesAt:e.closesAt,description:e.description,options:e.option?.map(n=>({text:n})),pollId:t,pollType:e.type,question:e.question,respondentPolicy:e.respondentPolicy,showResultsToParticipants:e.showResultsToParticipants,teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(n){xm(n,"Poll update failed")}}),Rm=new Bi("poll").description("Standalone poll commands").addCommand(uk).addCommand(gk);import{randomUUID as zt}from"crypto";import{readFile as wp}from"fs/promises";import M from"chalk";import{Command as K,InvalidArgumentError as Hr}from"commander";import{Command as Fi}from"commander";function fk(t,e){return[...e,t]}function Cm(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var hk=new Fi("request").description("Run a bounded specialist review of a frozen presentation revision; waits by default").requiredOption("--document-id <id>","Presentation document family UUID").requiredOption("--agent-id <id>","Roster specialist agent UUID").option("--slide-id <id>","Limit the review to this slide; repeat for several",fk,[]).option("--instructions <text>","Additional review guidance").option("--prior-review-run-id <id>","Re-review: verify an earlier run's open findings against the newer revision").option("--max-credits <credits>","Caller ceiling for this run; the server clamps it to the per-run cap (500)").option("--team-id <id>","Workspace ID override").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--no-wait","Return the run ID; recover with presentation review status <run-id>").action(async function(t){let e=R(this,t);try{let n=await B(e.teamId),r=await p("requestPresentationReview",{agentId:e.agentId,approvalReceipt:_(e),documentId:e.documentId,instructions:e.instructions,maxCredits:e.maxCredits?Number.parseInt(e.maxCredits,10):void 0,priorReviewRunId:e.priorReviewRunId,slideIds:e.slideId.length?e.slideId:void 0,teamId:n},e.idempotencyKey);if(e.wait===!1)return l(r);l(await Y("requestPresentationReview",r.runId,n))}catch(n){Cm(n,"Review request failed")}}).addHelpText("after",`
|
|
121
|
+
What happens:
|
|
122
|
+
Freezes the deck's newest immutable version, runs the named roster specialist in one
|
|
123
|
+
bounded pass, and posts each finding into the deck's private discussion as an
|
|
124
|
+
agent-authored, slide-anchored thread.
|
|
125
|
+
|
|
126
|
+
Billing:
|
|
127
|
+
The run is metered and hard-capped at 500 customer credits ($5). The first call
|
|
128
|
+
without --approval-receipt returns a browser confirmation URL; approve it there,
|
|
129
|
+
then retry this exact command with the returned receipt and the same
|
|
130
|
+
--idempotency-key. A retried key replays the same run \u2014 it never pays twice.
|
|
131
|
+
|
|
132
|
+
Re-review:
|
|
133
|
+
$ ${g.commands[0]} presentation review request --document-id <id> --agent-id <id> \\
|
|
134
|
+
--prior-review-run-id <run-id> --idempotency-key <new-key>
|
|
135
|
+
Confirms which earlier findings the newer revision addressed and resolves those threads.
|
|
136
|
+
|
|
137
|
+
Recovery:
|
|
138
|
+
$ ${g.commands[0]} presentation review status <run-id>
|
|
139
|
+
`),yk=new Fi("status").description("Read one presentation review run's progress, result, or typed error").argument("<run-id>","Run ID returned by presentation review request").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await x("requestPresentationReview",t,n.teamId))}catch(r){Cm(r,"Review run status failed")}}),Sm=new Fi("review").description("Bounded specialist reviews of a frozen presentation revision").addCommand(hk).addCommand(yk);import{Command as Em,InvalidArgumentError as bk}from"commander";var Tm=new Em("chats").description("List Studio chat threads for an owned presentation video").argument("<project-id>","Presentation-video project UUID or editor slug").option("--limit <number>","Maximum threads (1-100)",$m(1,100)).option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await Pm("Chat thread list failed",()=>p("listPresentationVideoChatThreads",{limit:n.limit,projectId:t,teamId:n.teamId}))}),Am=new Em("chat").description("Read one Studio chat with safe attachment and scene-marker context").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<chat-id>","Thread UUID from presentation video chats").option("--before <timestamp>","Return messages older than this ISO timestamp").option("--limit <number>","Maximum messages (1-50)",$m(1,50)).option("--team-id <id>","Workspace ID override").action(async function(t,e,n){let r=R(this,n);await Pm("Chat thread read failed",()=>p("getPresentationVideoChatThread",{before:r.before,chatId:e,limit:r.limit,projectId:t,teamId:r.teamId}))});function $m(t,e){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t||r>e)throw new bk(`Expected an integer between ${t} and ${e}.`);return r}}async function Pm(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as Gi}from"crypto";import{readFile as wk}from"fs/promises";import{Command as Mr}from"commander";function Om(t){let e=Number(t);if(!Number.isSafeInteger(e)||e<1)throw new Error("Draft version numbers must be positive integers.");return e}function ke(t){return t.option("--based-on-version-number <number>","Immutable selected draft baseline",Om).option("--branch-id <id>","Selected draft editor branch UUID").option("--expected-head-version-number <number>","Expected current draft history head",Om)}function xe(t){let{basedOnVersionNumber:e,branchId:n,expectedHeadVersionNumber:r}=t,o=[e,n,r].filter(i=>i!==void 0).length;if(o===0)return{};if(o!==3||!n||!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(n))throw new Error("Selected draft edits require base version, branch UUID, and expected head together.");return{basedOnVersionNumber:e,branchId:n,expectedHeadVersionNumber:r}}var Dm=ke(new Mr("edit")).description("Apply one atomic draft edit: narration, scene patch/move/remove, composition, or intro/outro card").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--edit <json-or-path>","Edit object as inline JSON or a JSON file path").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e){let n=R(this,e);await Br("Draft edit failed",async()=>p("editPresentationVideoDraft",{edit:await vk(n.edit),...xe(n),projectId:t,teamId:n.teamId},n.idempotencyKey??Gi()))}),Nm=new Mr("versions").description("List saved presentation-video draft versions").argument("<project-id>","Presentation-video project UUID or editor slug").option("--before-version <number>","Continue below this version number",qr(1)).option("--limit <number>","Maximum versions",qr(1,100)).option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await Br("Version list failed",()=>p("listPresentationVideoVersions",{beforeVersion:n.beforeVersion,limit:n.limit,projectId:t,teamId:n.teamId}))}),Lm=new Mr("restore").description("Restore a saved draft version as a new version").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<version-number>","Version number",qr(1)).option("--expected-current-version <number>","Refuse to restore if a newer draft version exists",qr(1)).option("--expected-project-updated-at <timestamp>","Non-coalescing project revision paired with --expected-current-version").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e,n){let r=R(this,n);await Br("Version restore failed",()=>p("restorePresentationVideoVersion",{expectedCurrentVersion:r.expectedCurrentVersion,expectedProjectUpdatedAt:r.expectedProjectUpdatedAt,projectId:t,teamId:r.teamId,versionNumber:e},r.idempotencyKey??Gi()))}),Um=new Mr("refresh").description("Refresh deck-backed scenes from the latest presentation version").argument("<project-id>","Presentation-video project UUID or editor slug").option("--expected-version-id <id>","Reviewed source version").option("--visual-slide-ids <ids...>","Exact visuals to refresh; other scenes retain their sources").option("--keep-narration","Record the decision to retain narration in the refreshed version").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e){let n=R(this,e);await Br("Slide refresh failed",()=>p("refreshPresentationVideoSlides",{projectId:t,teamId:n.teamId,keepNarration:e.keepNarration,expectedVersionId:n.expectedVersionId,visualSlideIds:n.visualSlideIds},n.idempotencyKey??Gi()))});async function vk(t){let e=t.trim(),n=e.startsWith("{")?e:await wk(e,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("--edit must contain one JSON object.");return r}function qr(t,e=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t||r>e)throw new Error(`Expected an integer between ${t} and ${e}.`);return r}}async function Br(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}import{createHash as Ik}from"crypto";import{Command as Kt,InvalidArgumentError as kk}from"commander";var _m=new Kt("drafts").description("List every video draft for one presentation with stage and staleness").argument("<presentation-id>","Source presentation ID, document ID, or slug").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await Wt("Draft list failed",()=>p("listPresentationVideoProjects",{presentationId:t,teamId:n.teamId}))}),jm=new Kt("freshness").description("Check whether a video draft is behind its source deck without changing it").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await Wt("Freshness read failed",()=>p("getPresentationVideoFreshness",{projectId:t,teamId:n.teamId}))}),Vm=new Kt("version").description("Read one saved draft snapshot without restoring it").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<version-number>","Saved version number",Fm(1)).option("--team-id <id>","Workspace ID override").action(async function(t,e,n){let r=R(this,n);await Wt("Version read failed",()=>p("getPresentationVideoVersion",{projectId:t,teamId:r.teamId,versionNumber:e}))}),qm=new Kt("renders").description("List MP4 render attempts newest first, including failures").argument("<project-id>","Presentation-video project UUID or editor slug").option("--limit <number>","Maximum render attempts; omit to return the complete history",Fm(1)).option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await Wt("Render history failed",()=>p("listPresentationVideoRenders",{limit:n.limit,projectId:t,teamId:n.teamId}))}),Mm=new Kt("render").description("Read one render's exact snapshot, asset progress, ordered events, and MP4 URL").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","Render attempt UUID from `presentation video renders`").option("--team-id <id>","Workspace ID override").action(async function(t,e,n){let r=R(this,n);await Wt("Render read failed",()=>p("getPresentationVideoRender",{projectId:t,renderId:e,teamId:r.teamId}))}),Bm=new Kt("cancel").description("Request cancellation of one in-flight MP4 DurableRun").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","In-flight render attempt UUID").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; deterministically derived from both IDs when omitted").action(async function(t,e,n){let r=R(this,n);await Wt("Render cancellation failed",()=>p("cancelPresentationVideoRender",{projectId:t,renderId:e,teamId:r.teamId},r.idempotencyKey??xk(t,e)))});function Fm(t,e=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t||r>e)throw new kk(`Expected an integer between ${t} and ${e}.`);return r}}function xk(t,e){return`presentation-video-cancel:${Ik("sha256").update(`${t}\0${e}`).digest("hex")}`}async function Wt(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as Ck}from"crypto";import{Command as _n}from"commander";import{existsSync as Rk}from"fs";var Gm=["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full"];function Jt(t){let[e,n]=t.split(":");if(e==="background")return{kind:"background"};if(e==="full")return{kind:"full"};if(e==="split"){if(n!=="left"&&n!=="right")throw new Error("--placement split needs a side: split:left or split:right.");return{kind:"split",side:n}}if(e==="box"){if(!n||!Gm.includes(n))throw new Error(`--placement box needs an anchor: box:${Gm.join(" | box:")}.`);return{kind:"box",placement:{anchor:n}}}throw new Error("--placement must be background, split:left, split:right, full, or box:<anchor>.")}function Fr(t){if(t.wholeScene&&t.duration!==void 0)throw new Error("--whole-scene and --duration ask for opposite things; pass only one.");let e=t.duration!==void 0||t.start!==void 0||t.wholeScene===!0;if(t.startWord!==void 0){if(e)throw new Error("--start-word replaces --start, --duration and --whole-scene; pass words or seconds, not both.");if(t.clearAnchor)throw new Error("--start-word and --clear-anchor ask for opposites.");if(t.endWord!==void 0&&t.endWord<t.startWord)throw new Error("--end-word must not come before --start-word.");return{anchor:{...t.endWord!==void 0?{endWord:t.endWord}:{},startWord:t.startWord}}}if(t.endWord!==void 0)throw new Error("--end-word needs --start-word.");if(!(!e&&!t.clearAnchor))return{...t.clearAnchor?{anchor:null}:{},...t.wholeScene?{durationSec:null}:t.duration!==void 0?{durationSec:t.duration}:{},...t.start!==void 0?{startSec:t.start}:{}}}function bt(t){return e=>{let n=Number(e);if(!Number.isInteger(n)||n<0)throw new Error(`${t} must be a 0-based narration word index (0, 1, 2, \u2026).`);return n}}function Un(t){let e=t.split(",").map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new Error("Provide at least one scene id.");return e}function De(t){return e=>{let n=Number(e);if(!Number.isFinite(n)||n<0)throw new Error(`${t} must be a number of seconds.`);return n}}async function Gr(t,e={}){if(t.startsWith("https://"))return{url:t};if(t.startsWith("http://"))throw new Error("A layer image URL must use https.");if(Rk(t))return{uploadKey:(await ee(t,{idempotencyKey:e.idempotencyKey,storagePrefix:"scene-layers"})).s3Key};if(zm(t))return{mediaAssetId:t};throw new Error("--image must be a local file path, an https image URL, or a media-library asset UUID.")}var Kr=["brand","alert"],Ki="::",Km=";;";function zi(t){if([t.textTitle,t.textCallout,t.textList].filter(r=>r!==void 0).length>1)throw new Error("Pass only one of --text-title, --text-callout or --text-list; each one is a whole card.");let n=Ji(t.tone);if(t.textTitle!==void 0)return{heading:Wi(t.textTitle,"--text-title"),tone:n,variant:"title"};if(t.textCallout!==void 0){let[r,o]=Wm(t.textCallout,Ki);return{...o?.trim()?{body:o.trim()}:{},heading:Wi(r,"--text-callout"),tone:n,variant:"callout"}}if(t.textList!==void 0){let[r,o]=Wm(t.textList,Ki),i=(o??"").split(Km).map(d=>d.trim()).filter(Boolean);if(i.length===0)throw new Error(`--text-list needs a heading and its points: --text-list "Heading${Ki}first${Km}second".`);return{heading:Wi(r,"--text-list"),items:i,tone:n,variant:"list"}}if(t.tone!==void 0)throw new Error("--tone describes a text layer; pass it with --text-title, --text-callout or --text-list.")}function Jm(t){let e=zi({...t,tone:void 0});return e?{body:e.body??null,heading:e.heading,items:e.items??null,...t.tone!==void 0?{tone:Ji(t.tone)}:{},variant:e.variant}:t.tone===void 0?void 0:{tone:Ji(t.tone)}}function Ji(t){if(t===void 0)return"brand";if(t!=="alert"&&t!=="brand")throw new Error(`--tone must be ${Kr.join(" or ")}.`);return t}function Wi(t,e){let n=(t??"").trim();if(!n)throw new Error(`${e} needs the text to show.`);return n}function Wm(t,e){let n=t.indexOf(e);return n<0?[t,void 0]:[t.slice(0,n),t.slice(n+e.length)]}function zm(t){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)}function Hi(t){try{return Fr(t)}catch(e){a(m(e,"Invalid layer timing.")),process.exit(s.INVALID_INPUT)}}function Hm(t){try{return t()}catch(e){a(m(e,"Invalid layer text.")),process.exit(s.INVALID_INPUT)}}async function Wr(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}function Jr(t,e,n){return p("editPresentationVideoDraft",{edit:n,projectId:t,teamId:e.teamId},e.idempotencyKey??Ck())}var Sk=new _n("add").description("Add one timed layer to one or more scenes").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--scenes <ids>","Comma-separated composition scene ids").option("--video <id>","Reusable library video id").option("--stock-video-token <token>","Playable selectionToken returned by search video (no Library import)").option("--media <id>","Media-library asset id (image or video)").option("--image <file-or-url>","Local image file to upload, or an https image URL").option("--slide <scene-id>","Reuse the image already on that deck scene").option("--text-title <line>","Words on a brand card: one loud line").option("--text-callout <heading::body>",'Words on a brand card: a heading over a paragraph, e.g. "Lockout first::Isolate the source."').option("--text-list <heading::a;;b;;c>","Words on a brand card: a heading over up to three points").option("--tone <tone>",`Text card colour: ${Kr.join(" | ")}`).option("--placement <placement>","background | split:left | split:right | full | box:<anchor> (default background; required for a text layer, which cannot use background)").option("--start <seconds>","Seconds from the scene's first frame",De("--start")).option("--duration <seconds>","Seconds shown; omit for the whole scene",De("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces --start/--duration",bt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive); omit for the whole scene",bt("--end-word")).option("--label <text>",'Studio label, e.g. "Right way"').option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e){let n=R(this,e),r=Hm(()=>zi(n));[n.video,n.media,n.image,n.slide,n.stockVideoToken,r].filter(d=>d!==void 0).length!==1&&(a("Pass exactly one of --video, --media, --stock-video-token, --image, --slide, --text-title, --text-callout or --text-list."),process.exit(s.INVALID_INPUT)),r&&n.placement===void 0&&(a("A text layer needs --placement: split:left, split:right, full, or box:<anchor>. It cannot use background, where words paint under the scrim."),process.exit(s.INVALID_INPUT));let i=Hi(n);await Wr("Layer add failed",async()=>{let d=r?{text:r}:n.stockVideoToken?{stockVideoToken:n.stockVideoToken}:n.video?{videoId:n.video}:n.media?{mediaAssetId:n.media}:n.slide?{slideId:n.slide}:await Gr(n.image,{idempotencyKey:n.idempotencyKey});return Jr(t,n,{...n.label?{label:n.label}:{},placement:Jt(n.placement??"background"),sceneIds:Un(n.scenes),source:d,...i?{timing:i}:{},type:"add_scene_layer"})})}),Ek=new _n("update").description("Move, retime, relabel or retype one layer. A picture or a clip is not editable \u2014 add a new layer instead \u2014 but a text layer's words are, because nothing was resolved to produce them").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id").argument("<layer-id>","Layer id from the project read").option("--placement <placement>","background | split:left | split:right | full | box:<anchor>").option("--start <seconds>","Seconds from the scene's first frame",De("--start")).option("--duration <seconds>","Seconds shown",De("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces the seconds flags",bt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive)",bt("--end-word")).option("--clear-anchor","Drop the word anchor and put the layer back on seconds").option("--whole-scene","Clear the length so the layer shows until the scene ends").option("--text-title <line>","Retype a text layer as one loud line").option("--text-callout <heading::body>","Retype a text layer as a heading over a paragraph").option("--text-list <heading::a;;b;;c>","Retype a text layer as a heading over up to three points").option("--tone <tone>",`Text card colour: ${Kr.join(" | ")}`).option("--label <text>","Studio label").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e,n,r){let o=R(this,r),i=Hi(o),d=Hm(()=>Jm(o));o.placement===void 0&&i===void 0&&d===void 0&&o.label===void 0&&(a("Provide at least one of --placement, --start, --duration, --whole-scene, --start-word, --clear-anchor, --text-title, --text-callout, --text-list, --tone or --label."),process.exit(s.INVALID_INPUT)),await Wr("Layer update failed",()=>Jr(t,o,{...o.label!==void 0?{label:o.label}:{},layerId:n,...o.placement!==void 0?{placement:Jt(o.placement)}:{},sceneId:e,...d?{text:d}:{},...i?{timing:i}:{},type:"update_scene_layer"}))}),Tk=new _n("remove").description("Remove one layer from one scene").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id").argument("<layer-id>","Layer id from the project read").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e,n,r){let o=R(this,r);await Wr("Layer remove failed",()=>Jr(t,o,{layerId:n,sceneId:e,type:"remove_scene_layer"}))}),Ak=new _n("copy").description("Copy one layer onto other scenes, optionally with a different placement").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<scene-id>","Composition scene id the layer sits on").argument("<layer-id>","Layer id from the project read").requiredOption("--to <ids>","Comma-separated target scene ids").option("--placement <placement>","background | split:left | split:right | full | box:<anchor>").option("--start <seconds>","Retime the copies: seconds from each scene's first frame",De("--start")).option("--duration <seconds>","Retime the copies: seconds shown",De("--duration")).option("--start-word <index>","Retime the copies on each TARGET scene's narration words (0-based)",bt("--start-word")).option("--end-word <index>","Last narration word shown on each target (inclusive)",bt("--end-word")).option("--clear-anchor","Drop the source layer's word anchor on the copies").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(t,e,n,r){let o=R(this,r),i=Hi(o);await Wr("Layer copy failed",()=>Jr(t,o,{layerId:n,...o.placement!==void 0?{placement:Jt(o.placement)}:{},sceneId:e,...i?{timing:i}:{},toSceneIds:Un(o.to),type:"copy_scene_layer"}))}),Xm=new _n("layer").description("Add, move, remove or copy the timed layers on a scene").addCommand(Sk).addCommand(Ek).addCommand(Tk).addCommand(Ak).addHelpText("after",`
|
|
134
140
|
Examples:
|
|
135
|
-
${
|
|
136
|
-
${
|
|
137
|
-
${
|
|
138
|
-
${
|
|
139
|
-
${
|
|
140
|
-
${
|
|
141
|
-
${
|
|
142
|
-
${
|
|
143
|
-
${
|
|
144
|
-
${
|
|
145
|
-
${
|
|
146
|
-
${
|
|
147
|
-
`);import{randomUUID as
|
|
141
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-1,slide-3 --image ./floor.jpg --placement background --label "Right way"
|
|
142
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-2 --video <video-id> --placement split:left --start 2 --duration 5
|
|
143
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-2 --video <video-id> --placement box:top-right --start-word 12 --end-word 18
|
|
144
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-3 --text-title "Lockout before you service it" --tone alert --placement full
|
|
145
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-2 --text-callout "Lockout/tagout::Isolate the energy source, apply your own lock, and keep the key on you." --placement split:right
|
|
146
|
+
${g.commands[0]} presentation video layer add <project-id> --scenes slide-4 --text-list "Before you start::Isolate;;Lock;;Verify" --placement box:top-right --start-word 4 --end-word 11
|
|
147
|
+
${g.commands[0]} presentation video layer update <project-id> slide-2 layer-abc --text-callout "Lockout/tagout::Isolate, lock, and verify before any service." --tone alert
|
|
148
|
+
${g.commands[0]} presentation video layer update <project-id> slide-1 layer-abc --placement box:top-right
|
|
149
|
+
${g.commands[0]} presentation video layer update <project-id> slide-1 layer-abc --whole-scene
|
|
150
|
+
${g.commands[0]} presentation video layer update <project-id> slide-1 layer-abc --clear-anchor --start 2 --duration 5
|
|
151
|
+
${g.commands[0]} presentation video layer copy <project-id> slide-1 layer-abc --to slide-4,slide-5 --placement full
|
|
152
|
+
${g.commands[0]} presentation video layer remove <project-id> slide-1 layer-abc
|
|
153
|
+
`);import{randomUUID as $k}from"crypto";import{Command as Pk}from"commander";var Ok=["basic","standard","premium"],Xi=new Pk("presenter").description("Set one scene to a different avatar/look or preset, or restore the project default").argument("<project-id>","Presentation video project ID").argument("<slide-id>","Slide or intro/outro scene ID").option("--avatar-id <id>","Exact avatar/look ID from presenter list").option("--slide-ids <ids...>","Exact scene IDs to apply atomically; include the slide-id argument").option("--cast-preset-id <id>","Saved cast preset ID").option("--no-apply-preset-voice","Preserve this scene's current voice instead of applying the preset voice").option("--inherit","Remove the override and inherit the project default").option("--render-tier <tier>","Avatar render tier: basic, standard, or premium").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this update").action(async function(t,e,n){let r=R(this,n);try{if(+!!r.avatarId+ +!!r.castPresetId+ +(r.inherit===!0)!==1)throw new Error("Pass exactly one of --avatar-id, --cast-preset-id, or --inherit.");if(r.renderTier&&!r.avatarId)throw new Error("--render-tier can only be used with --avatar-id.");if(r.renderTier&&!Ok.includes(r.renderTier))throw new Error("--render-tier must be basic, standard, or premium.");l(await p("setPresentationVideoScenePresenter",{...xe(r),applyPresetVoice:r.castPresetId?r.applyPresetVoice:void 0,avatarId:r.avatarId,castPresetId:r.castPresetId,inherit:r.inherit,projectId:t,renderTier:r.renderTier,slideId:e,slideIds:r.slideIds,teamId:r.teamId},Dk(r.idempotencyKey)))}catch(o){a(m(o,"Scene presenter update failed")),process.exit(s.GENERAL_ERROR)}});function Dk(t){return t||$k()}ke(Xi);import{createHash as Nk}from"crypto";import{Command as jn}from"commander";var Lk=new jn("prepare").description("Start or resume free slide-preview preparation; waits by default for completion").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--no-wait","Return the run ID; recover with presentation video previews status <run-id>").action(async function(t,e){let n=R(this,e);await zr("Preview preparation failed",async()=>{let r=await B(n.teamId),o=await p("preparePresentationVideoPreviews",{projectId:t,teamId:r},n.idempotencyKey??Qm("prepare",t,r));return n.wait===!1?o:Bs(o.runId,r)})}).addHelpText("after",`
|
|
148
154
|
What happens:
|
|
149
155
|
Reuses the draft's checkpointed preview run and prepares only missing deck-slide images.
|
|
150
156
|
Card and reusable-video scenes report not_required. This command is free and does not render MP4.
|
|
151
157
|
|
|
152
158
|
Recovery:
|
|
153
|
-
$ ${
|
|
154
|
-
$ ${
|
|
155
|
-
$ ${
|
|
156
|
-
`),
|
|
159
|
+
$ ${g.commands[0]} presentation video previews status <run-id>
|
|
160
|
+
$ ${g.commands[0]} presentation video previews inspect <project-id>
|
|
161
|
+
$ ${g.commands[0]} presentation video previews retry <project-id> # only after failed/cancelled
|
|
162
|
+
`),Uk=new jn("inspect").description("Read preview run progress and horizontal/vertical image metadata for every scene").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await zr("Preview status read failed",()=>p("getPresentationVideoPreviews",{projectId:t,teamId:n.teamId}))}).addHelpText("after",`
|
|
157
163
|
Output:
|
|
158
164
|
summary.status is idle, preparing, ready, failed, or not_required.
|
|
159
165
|
scenes[] reports ready, missing, or not_required plus stored horizontalUrl/verticalUrl.
|
|
160
166
|
run contains the durable run ID, phase, progress, status, and typed public error.
|
|
161
|
-
`),
|
|
167
|
+
`),_k=new jn("retry").description("Retry the attached failed or cancelled preview run from its saved checkpoints").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; generated when omitted").action(async function(t,e){let n=R(this,e);await zr("Preview retry failed",async()=>{let r=await B(n.teamId);return p("retryPresentationVideoPreviews",{projectId:t,teamId:r},n.idempotencyKey??Qm("retry",t,r))})}).addHelpText("after",`
|
|
162
168
|
Rules:
|
|
163
169
|
Only failed or cancelled preview runs can be retried. Active and completed runs are refused.
|
|
164
170
|
Retry resumes unfinished scenes; it does not rebuild images already stored on the draft.
|
|
165
171
|
|
|
166
172
|
Next:
|
|
167
|
-
$ ${
|
|
168
|
-
`),
|
|
173
|
+
$ ${g.commands[0]} presentation video previews inspect <project-id>
|
|
174
|
+
`),jk=new jn("status").description("Read one preview DurableRun's progress, result, or typed error").argument("<run-id>","Run ID returned by presentation video previews prepare").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await zr("Preview run status failed",()=>x("preparePresentationVideoPreviews",t,n.teamId))}),Ym=new jn("previews").description("Prepare, inspect, or retry the slide images used by presentation-to-MP4").addCommand(Lk).addCommand(Uk).addCommand(_k).addCommand(jk);function Qm(t,e,n){return`presentation-video-previews:${t}:${Nk("sha256").update(`${n}\0${e}`).digest("hex")}`}async function zr(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}import{Command as Yi}from"commander";var Zm=new Yi("inspect").description("Read a presentation-video project and its ordered scene timeline").argument("<project-id>","Presentation-video project UUID or editor slug").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await p("getPresentationVideoProject",{projectId:t,teamId:n.teamId}))}catch(r){a(m(r,"Project read failed")),process.exit(s.GENERAL_ERROR)}}),Vk=new Yi("list").description("List generated clips and uploaded recordings usable in a presentation video").argument("<project-id>","Target presentation-video project UUID or slug").option("--cursor <cursor>","Opaque cursor from the previous page").option("--limit <number>","Maximum clips to return",qk).option("--query <text>","Filter clips by title").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await p("listReusableVideoClips",{cursor:n.cursor,limit:n.limit,projectId:t,query:n.query,teamId:n.teamId}))}catch(r){a(m(r,"Clip list failed")),process.exit(s.GENERAL_ERROR)}}),ep=new Yi("library").description("Reusable generated clips and uploaded recordings").addCommand(Vk);function qk(t){let e=Number(t);if(!Number.isInteger(e)||e<1||e>100)throw new Error("--limit must be an integer between 1 and 100.");return e}import{randomUUID as Gk}from"crypto";import{Command as Qi}from"commander";import{readFile as Mk}from"fs/promises";import{InvalidArgumentError as tp}from"commander";async function Bk(t){let e=t.trim(),n=e.startsWith("{")?e:await Mk(e,"utf-8"),r=JSON.parse(n);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("--settings must be a JSON object.");return r}async function np(t){let e=t.settings?await Bk(t.settings):{},n=[t.captionHeight,t.captionWidth,t.captionX,t.captionY].some(i=>i!==void 0),r=[t.captionBackgroundColor,t.captionFontFamily,t.captionFontSize,t.captionHighlightColor,t.captionTextColor].some(i=>i!==void 0),o=[t.presenterAnchor,t.presenterApplyToAll,t.presenterBackground,t.presenterBackgroundFit,t.presenterBackgroundHex,t.presenterBackgroundUrl,t.presenterBorderRadius,t.presenterFramingX,t.presenterFramingY,t.presenterFramingZoom,t.presenterHeight,t.presenterOffsetX,t.presenterOffsetY,t.presenterSize,t.presenterUseDefault,t.presenterVisible,t.presenterX,t.presenterY].some(i=>i!==void 0);if(n&&e.captionPlacement!==void 0)throw new Error("Pass caption placement either as typed flags or inside --settings, not both.");if(r&&e.captionStyle!==void 0)throw new Error("Pass caption style either as typed flags or inside --settings, not both.");if(o&&e.presenter!==void 0)throw new Error("Pass presenter layout either as typed flags or as settings.presenter, not both.");return Fk({captionBackgroundColor:t.captionBackgroundColor,captionFontFamily:t.captionFontFamily,captionFontSize:t.captionFontSize,captionHeight:t.captionHeight,captionHighlightColor:t.captionHighlightColor,captionTextColor:t.captionTextColor,captionWidth:t.captionWidth,captionX:t.captionX,captionY:t.captionY,presenterAnchor:t.presenterAnchor,presenterApplyToAll:t.presenterApplyToAll||void 0,presenterBackgroundFit:t.presenterBackgroundFit,presenterBackgroundHex:t.presenterBackgroundHex,presenterBackgroundKind:t.presenterBackground,presenterBackgroundUrl:t.presenterBackgroundUrl,presenterBorderRadius:t.presenterBorderRadius,presenterFramingX:t.presenterFramingX,presenterFramingY:t.presenterFramingY,presenterFramingZoom:t.presenterFramingZoom,presenterHeight:t.presenterHeight,presenterOffsetX:t.presenterOffsetX,presenterOffsetY:t.presenterOffsetY,presenterSize:t.presenterSize,presenterSlideId:t.presenterSlideId,presenterUseDefault:t.presenterUseDefault||void 0,presenterVisible:t.presenterVisible,presenterX:t.presenterX,presenterY:t.presenterY,settings:t.settings?e:void 0})}function H(t,e,n,r=!1){return o=>{let i=Number(o);if(!Number.isFinite(i)||i<e||i>n||r&&!Number.isInteger(i))throw new tp(`${t} must be ${r?"an integer":"a number"} from ${e} to ${n}.`);return i}}function rp(t){return e=>{if(e==="true")return!0;if(e==="false")return!1;throw new tp(`${t} must be true or false.`)}}function Fk(t){return Object.fromEntries(Object.entries(t).filter(e=>e[1]!==void 0))}var Kk=["right-way","wrong-way"],Wk=new Qi("status").description("Read a presentation-video scene clip run").argument("<run-id>","Run ID returned by presentation video scene-clip generate").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await x("generatePresentationVideoSceneClip",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),op=new Qi("generate").description("Generate a right-way or wrong-way scene clip from a picture and attach it as a layer").argument("<project-id>","Presentation video project ID or slug").requiredOption("--image <file-or-url-or-id>","Local image file to upload, an https image URL, or a media-library asset UUID").requiredOption("--scenes <ids>","Comma-separated composition scene ids the finished clip is attached to").option("--preset <preset>","right-way (correct procedure) or wrong-way (unsafe act, needs --no-real-person). Default right-way").option("--no-real-person","Declare that no real, identifiable person appears in the picture. Required by --preset wrong-way").option("--placement <placement>","background | split:left | split:right | full | box:<anchor> (default background)").option("--start <seconds>","Seconds from the scene's first frame",De("--start")).option("--layer-duration <seconds>","Seconds the layer is on screen; omit for the whole scene",De("--layer-duration")).option("--label <text>",'Studio label, e.g. "Right way"').option("--duration-seconds <n>","Clip length, 5 to 15 seconds (default 6)",H("--duration-seconds",5,15,!0)).option("--prompt <text>","Replace the derived scene description").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this clip request").option("--yes","Confirm the scene-clip charge").action(async function(t,e){let n=R(this,e);if(!n.yes)return a("Pass --yes to confirm generating a paid scene clip.");let r=n.preset??"right-way";Kk.includes(r)||(a("--preset must be right-way or wrong-way."),process.exit(s.INVALID_INPUT));let o=n.realPerson===!1;r==="wrong-way"&&!o&&(a("A wrong-way clip stages an unsafe act on whoever is in the picture, so it must never be a real person. Pass --no-real-person to declare the picture people-free."),process.exit(s.INVALID_INPUT)),r!=="wrong-way"&&o&&(a("--no-real-person only applies to --preset wrong-way."),process.exit(s.INVALID_INPUT)),n.durationSeconds!==void 0&&!Number.isInteger(n.durationSeconds)&&(a("--duration-seconds must be a whole number of seconds."),process.exit(s.INVALID_INPUT));try{let i=xe(n),d=await Gr(n.image,{idempotencyKey:n.idempotencyKey}),c=Fr({duration:n.layerDuration,start:n.start});l(await p("generatePresentationVideoSceneClip",{...i,destination:{...n.label?{label:n.label}:{},placement:Jt(n.placement??"background"),sceneIds:Un(n.scenes),...c?{timing:c}:{}},durationSeconds:n.durationSeconds,image:d,preset:r,projectId:t,prompt:n.prompt,teamId:n.teamId,...o?{wrongWay:{noRealPersonInImage:!0}}:{}},n.idempotencyKey??Gk()))}catch(i){a(m(i,"Scene clip failed")),process.exit(s.GENERAL_ERROR)}});ke(op);var ip=new Qi("scene-clip").description("Generate scene-clip footage and attach it as a scene layer").addCommand(op).addCommand(Wk).addHelpText("after",`
|
|
169
175
|
A wrong-way clip is refused unless you declare the picture people-free with
|
|
170
176
|
--no-real-person. Layers already in the project are managed with
|
|
171
|
-
${
|
|
177
|
+
${g.commands[0]} presentation video layer.
|
|
172
178
|
|
|
173
179
|
Examples:
|
|
174
|
-
${
|
|
175
|
-
${
|
|
176
|
-
${
|
|
177
|
-
`);import{randomUUID as
|
|
180
|
+
${g.commands[0]} presentation video scene-clip generate <project-id> --image ./lathe.jpg --scenes slide-3 --yes
|
|
181
|
+
${g.commands[0]} presentation video scene-clip generate <project-id> --image ./machine.jpg --scenes slide-3,slide-4 --preset wrong-way --no-real-person --placement split:right --yes
|
|
182
|
+
${g.commands[0]} presentation video scene-clip status <run-id>
|
|
183
|
+
`);import{randomUUID as Jk}from"crypto";import{Command as Zi}from"commander";var zk=new Zi("render").description("Render one scene of a presentation video to its own MP4").argument("<project-id>","Presentation video project ID or slug").argument("<scene-id>","Composition scene ID to render").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this scene render request").option("--yes","Confirm the scene render charge").action(async function(t,e,n){let r=R(this,n);if(!r.yes)return a("Pass --yes to confirm rendering a paid scene preview. A scene already cached at its current state is free and still needs --yes only when it must be rendered.");try{l(await p("renderPresentationVideoScene",{projectId:t,sceneId:e,teamId:r.teamId},r.idempotencyKey??Jk()))}catch(o){a(m(o,"Scene render failed")),process.exit(s.GENERAL_ERROR)}}),Hk=new Zi("status").description("Read a presentation-video scene render run").argument("<run-id>","Run ID returned by presentation video scene render").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await x("renderPresentationVideoScene",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),ap=new Zi("scene").description("Render and inspect one scene of a presentation video").addCommand(zk).addCommand(Hk).addHelpText("after",`
|
|
178
184
|
A scene render produces the same frames the final video uses, so rendering the
|
|
179
185
|
whole video afterwards is not charged for the scenes it reuses. Editing a scene
|
|
180
186
|
invalidates its segment; render it again to see the change.
|
|
181
187
|
|
|
182
188
|
Examples:
|
|
183
|
-
${
|
|
184
|
-
${
|
|
185
|
-
`);import{
|
|
189
|
+
${g.commands[0]} presentation video scene render <project-id> slide-3 --yes
|
|
190
|
+
${g.commands[0]} presentation video scene status <run-id>
|
|
191
|
+
`);import{createHash as Xk,randomUUID as Yk}from"crypto";import{Command as sp}from"commander";var dp="importPresentationVideoScript",cp=new sp("video-script-import").description("Import an uploaded script into existing scenes without rewriting its text (uses credits)").argument("<project-id>","Presentation-video project UUID or editor slug").option("--file <path>","Upload a local PDF, Word, PowerPoint or text document").option("--file-url <url>","An already-uploaded document URL; not an arbitrary website URL").option("--instructions <text>","Optional guidance for splitting the script across existing scenes").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--no-follow","Return immediately with the durable run ID").action(async function(t,e){try{let n=R(this,e);if(!!n.file==!!n.fileUrl)throw new Error("Provide exactly one of --file or --file-url.");let r=n.idempotencyKey??Yk(),o=await B(n.teamId),i=n.file?(await ee(n.file,{idempotencyKey:`script:${Xk("sha256").update(r).digest("hex")}`})).url:n.fileUrl,d=await p(dp,{projectId:t,fileUrl:i,instructions:n.instructions,teamId:o},r);if(l(d),!n.follow||d.status==="completed")return;w(`Script import run: ${d.runId}`),await Vn(d.runId,"presentation video-script-import-status",()=>Qk(d.runId,o))}catch(n){a(m(n,"Script import failed")),process.exit(s.GENERAL_ERROR)}}),lp=new sp("video-script-import-status").description("Read the terminal state and recovery information for a script import").argument("<run-id>","Run ID returned by video-script-import").option("--team-id <id>","Workspace ID override").action(async function(t,e){try{let n=R(this,e);l(await x(dp,t,n.teamId))}catch(n){a(m(n,"Script import status failed")),process.exit(s.GENERAL_ERROR)}});async function Qk(t,e){let n=new URL(`/api/v1/presentation-videos/script-imports/runs/${encodeURIComponent(t)}/events`,F());n.searchParams.set("teamId",e);let r=await fetch(n,{headers:await ge()});if(!r.ok)throw new C("Script import event stream is unavailable; use the status command to recover.",r.status);return r}import{Command as Zk}from"commander";var ea=new Zk("settings").description("Update saved presentation-video voice, presenter, caption, format, or renderer settings").argument("<project-id>","Presentation video project ID").option("--settings <json-or-path>","Advanced settings patch as JSON or a path to a JSON file").option("--caption-x <ratio>","Caption box center on the horizontal axis, from 0 to 1",H("--caption-x",0,1)).option("--caption-y <ratio>","Caption box center on the vertical axis, from 0 to 1",H("--caption-y",0,1)).option("--caption-width <ratio>","Caption box width as a frame fraction, from 0.18 to 0.95",H("--caption-width",.18,.95)).option("--caption-height <ratio>","Caption box height as a frame fraction, from 0.05 to 0.5",H("--caption-height",.05,.5)).option("--caption-font-family <css-list>","Caption CSS font-family list").option("--caption-font-size <pixels>","Caption font size in pixels, from 20 to 96",H("--caption-font-size",20,96,!0)).option("--caption-text-color <color>","Caption text color: hex, rgb, hsl, transparent, or var()").option("--caption-highlight-color <color>","Current-word highlight color: hex, rgb, hsl, transparent, or var()").option("--caption-background-color <color>","Caption box color: hex, rgb, hsl, transparent, or var()").option("--presenter-slide-id <id>","Target one scene; omit to update the project presenter default").option("--presenter-anchor <anchor>","Presenter anchor: bottom-left, bottom-right, top-left, top-right, left-half, right-half, left-overlay, right-overlay, full, or free",y("--presenter-anchor",["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full","free"])).option("--presenter-size <ratio>","Presenter box width as a frame fraction, from 0.08 to 0.9",H("--presenter-size",.08,.9)).option("--presenter-height <ratio>","Explicit presenter box height as a frame fraction, from 0.05 to 1",H("--presenter-height",.05,1)).option("--presenter-x <ratio>","Horizontal center from 0 to 1; use with --presenter-anchor free",H("--presenter-x",0,1)).option("--presenter-y <ratio>","Vertical center from 0 to 1; use with --presenter-anchor free",H("--presenter-y",0,1)).option("--presenter-offset-x <ratio>","Horizontal edge offset for anchored placement, from 0 to 0.35",H("--presenter-offset-x",0,.35)).option("--presenter-offset-y <ratio>","Vertical edge offset for anchored placement, from 0 to 0.35",H("--presenter-offset-y",0,.35)).option("--presenter-border-radius <ratio>","Corner radius from 0 (square) to 0.5 (circle or pill)",H("--presenter-border-radius",0,.5)).option("--presenter-framing-x <ratio>","Horizontal crop focus inside the presenter box, from 0 to 1",H("--presenter-framing-x",0,1)).option("--presenter-framing-y <ratio>","Vertical crop focus inside the presenter box, from 0 to 1",H("--presenter-framing-y",0,1)).option("--presenter-framing-zoom <ratio>","Crop zoom inside the presenter box, from 1 to 2",H("--presenter-framing-zoom",1,2)).option("--presenter-background <kind>","Background: original, transparent, color, or image",y("--presenter-background",["original","transparent","color","image"])).option("--presenter-background-hex <hex>","Six-digit #RRGGBB value required with --presenter-background color").option("--presenter-background-url <url>","HTTP(S) image required with --presenter-background image").option("--presenter-background-fit <fit>","Image background fit: cover or contain",y("--presenter-background-fit",["cover","contain"])).option("--presenter-visible <true|false>","Show or hide the presenter on --presenter-slide-id",rp("--presenter-visible")).option("--presenter-apply-to-all","Make the targeted scene placement the project default and clear placement overrides").option("--presenter-use-default","Remove the targeted scene placement override and use the project default").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this settings update").option("--yes","Confirm updating presentation video settings").action(async function(t,e){let n=R(this,e),r;try{r=await np(n)}catch(o){a(m(o,"Invalid settings patch")),process.exit(s.INVALID_INPUT)}if(Object.keys(r).length===0&&(a("Pass a caption or presenter flag, or --settings <json-or-path>, with the patch to apply."),process.exit(s.INVALID_INPUT)),!n.yes)return a("Pass --yes to confirm updating presentation video settings.");try{let o=await B(n.teamId),i={projectId:t,...r,...xe(n),teamId:o};l(await p("updatePresentationVideoSettings",i,n.idempotencyKey??Z({command:"presentation video settings",payload:i,workspaceId:o})))}catch(o){a(m(o,"Settings update failed")),process.exit(s.GENERAL_ERROR)}}).addHelpText("after",`
|
|
186
192
|
Caption geometry uses frame-relative values. x/y are the box center; width/height are its size.
|
|
187
193
|
Omitted caption fields keep their saved values. Run presentation video inspect <project-id> to verify them.
|
|
188
194
|
Presenter geometry also uses frame-relative values. Omit --presenter-slide-id to edit the default; pass it for one scene.
|
|
189
195
|
Free placement requires --presenter-anchor free plus both --presenter-x and --presenter-y.
|
|
190
196
|
|
|
191
197
|
Examples:
|
|
192
|
-
${
|
|
193
|
-
${
|
|
194
|
-
${
|
|
195
|
-
${
|
|
196
|
-
${
|
|
197
|
-
`);import{Command as
|
|
198
|
+
${g.commands[0]} presentation video settings <project-id> --caption-y 0.82 --caption-width 0.72 --yes
|
|
199
|
+
${g.commands[0]} presentation video settings <project-id> --caption-font-size 44 --caption-highlight-color '#14c8ff' --yes
|
|
200
|
+
${g.commands[0]} presentation video settings <project-id> --presenter-slide-id <slide-id> --presenter-anchor free --presenter-x 0.7 --presenter-y 0.4 --presenter-size 0.28 --yes
|
|
201
|
+
${g.commands[0]} presentation video settings <project-id> --presenter-slide-id <slide-id> --presenter-apply-to-all --yes
|
|
202
|
+
${g.commands[0]} presentation video settings <project-id> --presenter-background color --presenter-background-hex '#14213d' --yes
|
|
203
|
+
`);ke(ea);import{Command as qn,InvalidArgumentError as ix}from"commander";import{createHash as ex}from"crypto";import{existsSync as tx,readFileSync as nx}from"fs";import{Command as mp,InvalidArgumentError as pp}from"commander";function rx(t){let e=Number(t);if(!Number.isFinite(e)||e<0||e>1)throw new pp("--volume must be a number from 0 to 1.");return e}function ox(t){let e=Number(t);if(!Number.isInteger(e)||e<1)throw new pp("--file-size must be a positive whole number.");return e}async function up(t){let{idempotencyKey:e,teamId:n,...r}=t;return p("createPresentationVideoMusicUploadUrl",{...r,teamId:n},e)}var gp=new mp("upload-url").description("Mint a project-scoped audio storage POST; this does not upload bytes or change settings").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--file-name <name>","Original audio filename").requiredOption("--file-type <mime>","Exact audio MIME type").requiredOption("--file-size <bytes>","Exact positive byte size; maximum 104857600",ox).option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; derived from workspace, project, and exact file metadata when omitted").action(async function(t,e){let n=R(this,e);await b();try{let r=await B(n.teamId),o={fileName:n.fileName,fileSize:n.fileSize,fileType:n.fileType,projectId:t};l(await up({...o,idempotencyKey:n.idempotencyKey??Z({command:"presentation video music upload-url",payload:o,workspaceId:r}),teamId:r}))}catch(r){a(m(r,"Custom music upload URL creation failed")),process.exit(s.GENERAL_ERROR)}}),ta=new mp("upload").description("Upload local audio, save it as this video's custom music, and verify the draft").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--file <path>","Local audio file to upload").option("--volume <level>","Saved mix level from 0 to 1; default 0.12",rx,.12).option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; derived from workspace, project, exact bytes, MIME, and level when omitted").addHelpText("after",`
|
|
198
204
|
Postcondition: mode=upload, filename, and volume are read back from the saved project. This command never downloads an arbitrary URL.
|
|
199
|
-
`).action(async function(e
|
|
205
|
+
`).action(async function(t,e){let n=R(this,e);await b(),tx(n.file)||(a(`File not found: ${n.file}`),process.exit(s.INVALID_INPUT));try{let r=await B(n.teamId),o=xe(n),i=at(n.file),d=ex("sha256").update(nx(n.file)).digest("hex"),c={...o,contentSha256:d,...i,projectId:t,volume:n.volume},u=n.idempotencyKey??Z({command:"presentation video music upload",payload:c,workspaceId:r}),f=await up({...i,idempotencyKey:`${u}:upload`,projectId:t,teamId:r}),v=await st(n.file,f),I=await p("updatePresentationVideoSettings",{projectId:f.projectId,...o,settings:{music:{audioUrl:v.url,fileName:v.name,mode:"upload",volume:n.volume}},teamId:r},`${u}:settings`),$=(await p("getPresentationVideoProject",{projectId:f.projectId,teamId:r})).renderSettings.music;if($.mode!=="upload"||$.uploadedFileName!==i.fileName||$.volume!==n.volume)throw new Error("Custom music upload completed but the saved project did not match it.");l({contentSha256:d,fileName:i.fileName,fileSize:i.fileSize,fileType:i.fileType,music:$,projectId:I.projectId,s3Key:f.s3Key,settings:I.settings.music})}catch(r){a(m(r,"Custom music upload failed")),process.exit(s.GENERAL_ERROR)}});ke(ta);function ax(t){let e=Number(t);if(!Number.isInteger(e)||e<1||e>24)throw new ix("--limit must be an integer from 1 to 24.");return e}var sx=new qn("search").description("Search stock music and return preview URLs plus opaque selection tokens").argument("<query>","Mood, genre, instrument, or other search terms").option("--limit <count>","Return 1 to 24 tracks; default 12",ax).option("--token <token>","Opaque nextToken from the previous page").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await ra("Stock-music search failed",()=>p("searchPresentationVideoStockMusic",{limit:n.limit,query:t,teamId:n.teamId,token:n.token}))}).addHelpText("after",`
|
|
200
206
|
Output:
|
|
201
207
|
tracks[].previewUrl is for audition only. tracks[].selectionToken is opaque and short-lived.
|
|
202
208
|
To save one result, pass its id, name, and selectionToken to stock select.
|
|
203
209
|
|
|
204
210
|
Example:
|
|
205
|
-
$ ${
|
|
206
|
-
`),
|
|
211
|
+
$ ${g.commands[0]} presentation video music stock search "calm ambient" --limit 8
|
|
212
|
+
`),fp=new qn("select").description("Select one paid stock track; waits by default, saves it, and returns a recovery run ID").argument("<project-id>","Presentation-video project UUID or editor slug").option("--mode <mode>","Selection mode: manual or auto","manual").option("--selection-token <token>","Opaque selectionToken from stock search; manual mode only").option("--track-id <id>","Track id from stock search; manual mode only").option("--track-name <name>","Track name from stock search; manual mode only").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; deterministically derived from workspace and exact selection when omitted").option("--no-wait","Return the run ID; recover with presentation video music stock status <run-id>").action(async function(t,e){let n=R(this,e);if(n.mode!=="manual"&&n.mode!=="auto")return na("--mode must be manual or auto.");if(n.mode==="manual"&&(!n.selectionToken||!n.trackId||!n.trackName))return na("Manual mode requires --selection-token, --track-id, and --track-name from stock search.");if(n.mode==="auto"&&(n.selectionToken||n.trackId||n.trackName))return na("Auto mode derives the choice from the saved deck; omit manual track flags.");await ra("Stock-music selection failed",async()=>{let r=await B(n.teamId),o={...xe(n),mode:n.mode,projectId:t,selectionToken:n.selectionToken,teamId:r,trackId:n.trackId,trackName:n.trackName},i=await p("selectPresentationVideoStockMusic",o,n.idempotencyKey??Z({command:"presentation-video-stock-music-select",payload:o,workspaceId:r}));return n.wait===!1?i:Ms(i.runId,r)})}).addHelpText("after",`
|
|
207
213
|
Postcondition:
|
|
208
214
|
The completed run persists mode=stock, the durable audio URL, duration, track identity,
|
|
209
215
|
and a new project draft version. It does not render an MP4.
|
|
210
216
|
|
|
211
217
|
Manual:
|
|
212
|
-
$ ${
|
|
218
|
+
$ ${g.commands[0]} presentation video music stock select <project-id> --selection-token <token> --track-id <id> --track-name "Warm Horizon"
|
|
213
219
|
|
|
214
220
|
Auto from saved slide titles and narration:
|
|
215
|
-
$ ${
|
|
216
|
-
`),qI=new Rn("status").description("Read stock-music run status/progress, billing, persisted result, or typed failure").argument("<run-id>","Run ID returned by stock select --no-wait").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);await Di("Stock-music status failed",()=>I("selectPresentationVideoStockMusic",e,n.teamId))}),wm=new Rn("music").description("Search and select music sources for an existing video project").addCommand(bm).addCommand(ym).addCommand(new Rn("stock").description("Preview catalog tracks and save a manual or deck-aware automatic selection").addCommand(UI).addCommand(_I).addCommand(qI));async function Di(e,t){try{l(await t())}catch(n){a(n instanceof Error?n.message:e),process.exit(s.GENERAL_ERROR)}}function Oi(e){a(e),process.exit(s.INVALID_INPUT)}import{readFile as jI}from"fs/promises";async function vm(e){if(!e)return;let t=e.trim().startsWith("{")?e:await jI(e,"utf8"),n=JSON.parse(t);if(!n||Array.isArray(n)||typeof n!="object")throw new Error("--slide-instructions must be a JSON object or file path");let r={};for(let[o,i]of Object.entries(n)){if(!o.trim()||typeof i!="string")throw new Error("--slide-instructions must map non-empty slide IDs to text");r[o]=i}return r}var VI=new K("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",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await I("createSlides",e,t.teamId);if(t.format==="json"){l(n);return}if(t.format==="quiet"){console.log(n.status);return}b(`Status: ${n.status}`),b(n.message),n.progress!==null&&b(`Progress: ${n.progress}%`),n.error&&a(ue(n.error))}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),MI=new K("delete").description("Permanently delete an owned presentation and its publications").argument("<presentation-id>","Presentation id or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--yes","Confirm permanent deletion").action(async(e,t)=>{t.yes||(a("Refusing to permanently delete without confirmation. Re-run with --yes."),process.exit(s.GENERAL_ERROR));let n=t.idempotencyKey??z({command:"presentation:delete",payload:{presentationId:e},workspaceId:t.teamId??"configured-default"});try{l(await m("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},n))}catch(r){r.errorCode==="approval_required"&&L(`Retry with --idempotency-key ${n}`),a(r instanceof Error?r.message:"Could not delete the presentation"),process.exit(s.GENERAL_ERROR)}}),BI=new K("limits").description("Show the selected workspace's presentation generation limits").option("--team-id <id>","Workspace ID (uses configured default)").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{await h();let t=e.teamId??te();t||(a("Team ID required. Set one with `mf config set team-id <id>` or pass --team-id."),process.exit(s.GENERAL_ERROR));try{let n=await lo(t);if(e.format==="json")return l(n);if(e.format==="quiet")return console.log(n.planName);b(`Plan: ${n.planName}`),b(`Available modes: ${n.availableModes.join(", ")||"none"}`),b(`Maximum slides: ${n.maxSlidesPerPresentation}`)}catch(n){a(n instanceof Error?n.message:"Could not read generation limits"),process.exit(s.GENERAL_ERROR)}}),FI=new K("visibility").description("Set an owned presentation's visibility to private, team, or public").argument("<presentation-id>","Presentation ID or slug").argument("<visibility>","private, team, or public",y("visibility",["private","team","public"])).option("--team-id <id>","Workspace ID (uses configured default)").option("--idempotency-key <key>","Stable retry key").action(async(e,t,n)=>{await h();try{l(await Ga(e,{idempotencyKey:n.idempotencyKey,teamId:n.teamId,visibility:t}))}catch(r){a(r instanceof Error?r.message:"Could not update presentation visibility"),process.exit(s.GENERAL_ERROR)}});function km(e){let t=Number(e);if(!Number.isInteger(t)||t<0)throw new Ni("Expected a non-negative integer.");return t}async function GI(e){let t=e.trim(),n=t.startsWith("[")?t:await Im(t,"utf-8"),r=JSON.parse(n);if(!Array.isArray(r))throw new Ni("--grants must be a JSON array.");for(let o of r)if(!o||typeof o!="object"||typeof o.userId!="string"||!["view","edit"].includes(o.permission))throw new Ni('Every grant must be {"userId":"\u2026","permission":"view|edit"}.');return r}var KI=new K("get").description("Read presentation ownership and team access").requiredOption("--document-id <id>","Presentation document ID").option("--team-id <id>","Workspace ID override").action(async e=>{try{l(await m("getPresentationSharing",{documentId:e.documentId,teamId:e.teamId}))}catch(t){a(t instanceof Error?t.message:"Could not read presentation sharing"),process.exit(s.GENERAL_ERROR)}}),WI=new K("update").description("Replace presentation collaborators and team access").requiredOption("--document-id <id>","Presentation document ID").requiredOption("--expected-revision <number>","Revision returned by presentation sharing get",km).requiredOption("--team-access <access>","restricted, view, or edit",y("--team-access",["restricted","view","edit"])).requiredOption("--grants <json-or-path>","Complete JSON grant array; use [] to remove all collaborators").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID override").action(async e=>{try{let t=await W(e.teamId),n=await GI(e.grants),r=e.idempotencyKey??z({command:"presentation:sharing:update",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess},workspaceId:t});l(await m("updatePresentationSharing",{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess,teamId:t},r))}catch(t){a(t instanceof Error?t.message:"Could not update presentation sharing"),process.exit(s.GENERAL_ERROR)}}),JI=new K("sharing").description("Read or update presentation team access").addCommand(KI).addCommand(WI),zI=new K("transfer").description("Transfer a presentation and every saved version").requiredOption("--document-id <id>","Presentation document ID").requiredOption("--to-user-id <id>","Active team editor or admin").requiredOption("--expected-revision <number>","Revision returned by presentation sharing get",km).option("--previous-owner-access <access>","Keep edit access or remove access",y("--previous-owner-access",["edit","remove"]),"edit").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID override").action(async e=>{try{let t=await W(e.teamId),n=e.idempotencyKey??z({command:"presentation:transfer",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,toUserId:e.toUserId},workspaceId:t});l(await m("transferPresentationOwnership",{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,teamId:t,toUserId:e.toUserId},n))}catch(t){a(t instanceof Error?t.message:"Could not transfer presentation ownership"),process.exit(s.GENERAL_ERROR)}}),HI=new K("transform").description("Transform an uploaded PowerPoint import for review").argument("<import-id>","PowerPoint import ID returned by Mindframes").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=R(this,t);try{let r=await m("transformPresentationImport",{importId:e},n.idempotencyKey);l(r)}catch(r){a(r instanceof Error?r.message:"Transform failed"),process.exit(s.GENERAL_ERROR)}});function xm(e){return new K(e.name).description(e.description).argument("<run-id>","Run ID returned by PowerPoint import").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,n)=>{try{let r=await I(e.capabilityId,t,n.teamId);n.format==="json"?l(r):n.format==="quiet"?console.log(r.status):(b(`Status: ${r.status}`),b(r.message),r.error&&a(ue(r.error)))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}})}var XI=xm({capabilityId:"importPowerPoint",description:"Read a PowerPoint import run",name:"status"}),YI=xm({capabilityId:"transformPresentationImport",description:"Read a PowerPoint transform run",name:"transform-status"}),Rm=new K("import").description("Import a PowerPoint through the review-gated reconstruction pipeline").option("--file <path>","Path to the .pptx to import").option("--filename <name>","Override the uploaded filename").option("--mode <mode>","Import mode: preserve or rebrand","preserve").option("--branding-id <id>","Saved brand ID (required for rebrand mode)").option("--source-chat-id <id>","Associate the import with an existing chat").option("--title <title>","Presentation title").option("--idempotency-key <key>","Stable retry key").action(async e=>{if(!e.file){Rm.help();return}e.file.toLowerCase().endsWith(".pptx")||(a("PowerPoint import requires a .pptx file."),process.exit(s.INVALID_INPUT));try{let t=await Q(e.file,{idempotencyKey:e.idempotencyKey}),n=await m("importPowerPoint",{brandingId:e.brandingId,filename:e.filename??t.name,mode:e.mode,sourceChatId:e.sourceChatId,sourceUrl:t.url,title:e.title},e.idempotencyKey??Ar());l(n)}catch(t){a(t instanceof Error?t.message:"Import failed"),process.exit(s.GENERAL_ERROR)}}).addCommand(HI).addCommand(XI).addCommand(YI),QI=new K("speaker-notes-status").description("Check a speaker-notes generation run").argument("<run-id>","Run ID returned by speaker-notes generation").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await I("generateSpeakerNotes",e,t.teamId);t.format==="json"?l(n):t.format==="quiet"?console.log(n.status):(b(`Status: ${n.status}`),b(n.message))}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),ZI=new K("video-narration-status").description("Check a presentation-video narration regeneration run").argument("<run-id>","Run ID returned by video-narration").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await I("regeneratePresentationVideoNarration",e,t.teamId);t.format==="json"?l(n):t.format==="quiet"?console.log(n.status):(b(`Status: ${n.status}`),b(n.message))}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),ek=new K("status").description("Read a presentation-video MP4 render run").argument("<run-id>","Run ID returned by presentation video").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);try{l(await I("createPresentationVideo",e,n.teamId))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),tk=new K("prepare").description("Create or reuse a presentation-video project for a presentation").argument("<presentation-id>","Presentation ID, document ID, or slug").option("--force-new","Create a fresh video project even if the current presentation version already has one").option("--narrate","Also generate the narration the project is missing (costs credits; requires --yes)").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this prepare request").option("--yes","Confirm the narration charge when --narrate is used").action(async function(e,t){let n=R(this,t);if(n.narrate&&!n.yes)return a("Pass --yes to confirm. --narrate generates speaker notes and costs credits.");try{l(await m("preparePresentationVideo",{forceNew:n.forceNew,narrate:n.narrate,presentationId:e,teamId:n.teamId},n.idempotencyKey??Ar()))}catch(r){a(r instanceof Error?r.message:"Prepare failed"),process.exit(s.GENERAL_ERROR)}}),nk=new K("status").description("Read a presentation-video narration run").argument("<run-id>","Run ID returned by presentation video narrate").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=R(this,t);try{l(await I("ensurePresentationVideoNarration",e,n.teamId))}catch(r){a(r instanceof Error?r.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),rk=new K("narrate").description("Generate the narration a presentation-video project is still missing").argument("<project-id>","Presentation video project ID").option("--no-wait","Return immediately with the durable run ID").option("--slide-id <id>","Regenerate one changed or new slide; repeat for more",Cm,[]).option("--keep-current","Keep all current narration and generate no slide text").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this narration request").option("--yes","Confirm the narration charge").action(async function(e,t){let n=R(this,t);if(n.keepCurrent&&n.slideId?.length)return a("Use either --keep-current or --slide-id, not both.");if(!n.yes&&!n.keepCurrent)return a("Pass --yes to confirm. Generating narration costs credits.");try{let r=await m("ensurePresentationVideoNarration",{projectId:e,...n.keepCurrent?{slideIds:[]}:n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??Ar());if(n.wait===!1||r.runStatus==="completed"){l(r);return}l(r),await Li(r.runId,"presentation video narrate status",()=>qn(r.runId))}catch(r){a(r instanceof Error?r.message:"Narration failed"),process.exit(s.GENERAL_ERROR)}}).addCommand(nk),ok=new K("video").description("Create an MP4 video from a presentation").argument("[presentation-id]","Presentation ID, document ID, or slug").option("--project-id <id>","Advanced: render an already-configured presentation video project").option("--settings <json-or-path>","Settings patch as JSON or a path to a JSON file; only valid with presentation-id").option("--force-new","Create a fresh video project even if the current presentation version already has one").option("--force-rerender","Start a new MP4 render even when the current project fingerprint has a completed render").option("--render-engine <engine>","Renderer for this MP4 only: remotion (Standard) or hyperframes (Premium)").option("--no-slide-animations","Premium renderer only: render every slide fully composed from its first frame instead of building it in as it is narrated").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this render request").option("--yes","Confirm starting the MP4 render").action(async(e,t)=>{if(!t.yes)return a("Pass --yes to confirm presentation video rendering.");try{if(!e&&!t.projectId)throw new Error("Pass a presentation id or --project-id.");if(e&&t.projectId)throw new Error("Pass either presentation id or --project-id, not both.");if(t.projectId&&(t.settings||t.forceNew))throw new Error("--settings and --force-new require a presentation id, not --project-id.");if(t.renderEngine&&t.renderEngine!=="remotion"&&t.renderEngine!=="hyperframes")throw new Error("--render-engine must be remotion or hyperframes.");l(await m("createPresentationVideo",{forceNew:t.forceNew,forceRerender:t.forceRerender,presentationId:e,projectId:t.projectId,renderEngine:t.renderEngine,settings:t.settings?await ik(t.settings):void 0,slideAnimations:t.slideAnimations===!1?!1:void 0,teamId:t.teamId},t.idempotencyKey))}catch(n){let r=n instanceof Error?n.message:"Render failed";a(r);let o=Oa({binary:p.commands[0],message:r,projectId:t.projectId});o&&Ia(o),process.exit(s.GENERAL_ERROR)}}).addCommand(tk).addCommand(rk).addCommand(am).addCommand(jl).addCommand(wm).addCommand(Ll).addCommand(Ul).addCommand(Fl).addCommand(Gl).addCommand(rm).addCommand(om).addCommand(Bl).addCommand(Ml).addCommand(pm).addCommand(nm).addCommand(dm).addCommand(cm).addCommand(ek).addCommand(Jl).addCommand(Wl).addCommand(zl).addCommand(Kl).addCommand(Vl);async function ik(e){let t=e.trim(),n=t.startsWith("{")?t:await Im(t,"utf-8"),r=JSON.parse(n);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("--settings must be a JSON object.");return r}function Cm(e,t){return[...t,e]}var ak=new K("speaker-notes").description("Generate paid speaker notes; waits by default and requires --yes").argument("<presentation-id>","Presentation ID or slug").option("--mode <mode>","ensure or regenerate","ensure").option("--style <style>","concise or detailed","concise").option("--density <density>","Narration density: brief, balanced, or deep").option("--instructions <text>","Instructions for every selected slide").option("--language <language>","Output language").option("--slide-id <id>","Target one slide (repeatable)",Cm,[]).option("--slide-instructions <json-or-path>","Per-slide instructions as a JSON object or JSON file path").option("--no-follow","Return the run ID; recover with presentation speaker-notes-status <run-id>").option("--yes","Confirm the speaker-notes generation charge").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes request").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{if(!t.yes)throw new Error("Pass --yes to confirm. Generating speaker notes costs credits.");if(!["ensure","regenerate"].includes(t.mode))throw new Error("--mode must be ensure or regenerate");if(!["concise","detailed"].includes(t.style))throw new Error("--style must be concise or detailed");if(t.density&&!["brief","balanced","deep"].includes(t.density))throw new Error("--density must be brief, balanced, or deep");let n=await W(t.teamId),r={density:t.density??(t.style==="detailed"?"deep":"balanced"),instructions:t.instructions,language:t.language,mode:t.mode,slideIds:t.slideId.length?t.slideId:void 0,slideInstructions:await vm(t.slideInstructions)},o=await Ba(e,r,t.idempotencyKey??z({command:"presentation speaker-notes",payload:r,workspaceId:n}),n);if(t.format==="json"||!t.follow){l(o);return}b(`Speaker notes run: ${o.runId}`),await Li(o.runId,"presentation speaker-notes-status",()=>qn(o.runId))}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),sk=new K("video-narration").description("Regenerate one scene or an exact scene batch in a presentation video draft").argument("<project-id>","Presentation video project ID").option("--slide-id <id>","One slide ID in the video draft").option("--slide-ids <ids...>","Exact scene IDs for one durable batch").option("--instructions <text>","Optional regeneration instructions").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--no-follow","Return immediately with the durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async function(e,t){try{let n=R(this,t),r=await W(n.teamId),o={instructions:t.instructions,projectId:e,slideId:t.slideId,slideIds:t.slideIds,teamId:r},i=await m("regeneratePresentationVideoNarration",o,n.idempotencyKey??Ar());if(t.format==="json"||!t.follow){l(i);return}b(`Narration run: ${i.runId}`),await Li(i.runId,"presentation video-narration-status",()=>qn(i.runId))}catch(n){a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}});async function Li(e,t,n){let r=null;try{r=await ck(await n())}catch(o){let i=o instanceof Error&&o.message.trim()?o.message.trim():"the event stream ended unexpectedly";L(`Stopped following run ${e}: ${i}. The run is unaffected \u2014 check it with '${p.commands[0]} ${t} ${e}'.`);return}if(r)throw new Error(`Run ${e} ${r.status}: ${r.message} Inspect it with '${p.commands[0]} ${t} ${e}'.`)}function dk(e){let t=e.eventType;if(t==="run.completed"||t==="durable_run.completed")return"completed";let n=t==="run.failed"||t==="durable_run.failed"?"failed":t==="run.cancelled"||t==="durable_run.cancelled"?"cancelled":null;return n?{message:e.payload?.message?.trim()||e.message?.trim()||"the run reported no error message",status:n}:null}async function ck(e){let t=e.body?.getReader();if(!t)throw new Error("Speaker notes event stream is unavailable");let n=new TextDecoder,r="",o=null;for(;;){let{done:i,value:c}=await t.read();r+=n.decode(c,{stream:!i});let d=r.split(`
|
|
217
|
-
|
|
218
|
-
`);r=
|
|
219
|
-
`).find(
|
|
220
|
-
${
|
|
221
|
-
$ ${
|
|
222
|
-
$ ${
|
|
223
|
-
$ ${
|
|
224
|
-
$ ${
|
|
225
|
-
$ ${
|
|
226
|
-
|
|
227
|
-
${
|
|
228
|
-
${
|
|
229
|
-
${
|
|
230
|
-
${
|
|
231
|
-
${
|
|
232
|
-
${
|
|
233
|
-
${
|
|
234
|
-
${
|
|
235
|
-
${
|
|
236
|
-
$ ${
|
|
237
|
-
$ ${
|
|
238
|
-
$ ${
|
|
239
|
-
|
|
240
|
-
${
|
|
241
|
-
${
|
|
242
|
-
${
|
|
243
|
-
${
|
|
244
|
-
${
|
|
245
|
-
${
|
|
246
|
-
${
|
|
247
|
-
$ ${
|
|
248
|
-
$ ${
|
|
249
|
-
|
|
250
|
-
${
|
|
251
|
-
${
|
|
252
|
-
$ ${
|
|
253
|
-
`);import{randomUUID as
|
|
254
|
-
${
|
|
255
|
-
${
|
|
256
|
-
$ ${
|
|
257
|
-
|
|
258
|
-
${
|
|
259
|
-
${
|
|
260
|
-
$ ${
|
|
261
|
-
|
|
262
|
-
${
|
|
263
|
-
$ ${
|
|
264
|
-
`);import{randomUUID as
|
|
265
|
-
${
|
|
266
|
-
$ ${
|
|
267
|
-
$ ${
|
|
268
|
-
|
|
269
|
-
${
|
|
270
|
-
${
|
|
271
|
-
$ ${
|
|
272
|
-
$ ${
|
|
273
|
-
`);import{randomUUID as
|
|
274
|
-
${
|
|
275
|
-
`):o.cues.map(
|
|
276
|
-
`);if(t.output&&(await qk(t.output,i,"utf-8"),n==="human"&&k(`Transcript saved to: ${t.output}`)),n==="json"){l(o);return}if(n==="quiet"){console.log(i);return}console.log(),console.log(`Title: ${o.title}`),o.channelName&&console.log(`Channel: ${o.channelName}`),o.durationFormatted&&console.log(`Duration: ${o.durationFormatted}`),console.log(`Language: ${o.language??"unknown"}${o.isAutoGenerated?" (auto-generated)":""}`),console.log(`Words: ${o.wordCount.toLocaleString()}`),console.log(`URL: ${o.url}`),o.truncated&&L("Transcript was truncated to fit the response budget."),t.output||(console.log(),console.log("--- Transcript ---"),console.log(i))}catch(o){r?.stop(),a(o instanceof Error?o.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Mk}from"crypto";import{mkdir as Bk,writeFile as Lm}from"fs/promises";import{dirname as Fk}from"path";import{Command as Dr}from"commander";import Um from"ora";var Gk=new Dr("generate").description("Generate speech from text").requiredOption("-t, --text <text>","Text to convert to speech").requiredOption("-o, --output <path>","Output file path").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--options-json <json>","Canonical speech options JSON").option("--voice-id <voiceId>","Opaque Mindframes voice ID").option("-s, --speed <speed>","Speech speed 0.1-4.0 (default: 1.0)").option("-l, --lang <lang>","Language or locale hint (for example en-US)").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.idempotencyKey??Mk(),n;try{n=he(e)}catch(d){a(d instanceof Error?d.message:String(d)),process.exit(s.INVALID_INPUT)}let r=e.format,o=r==="human"?Um("Generating speech...").start():null,i;e.speed&&(i=parseFloat(e.speed),(Number.isNaN(i)||i<.1||i>4)&&(o?.stop(),a("Speed must be between 0.1 and 4.0"),process.exit(s.INVALID_INPUT)));let c;try{let d=e.optionsJson?Kk("--options-json",e.optionsJson):{},u=await Za({text:e.text,options:{...d,language:e.lang,voiceId:e.voiceId,speed:i}},{approvalReceipt:n,idempotencyKey:t});c=u.requestId,o?.stop();let g=e.output.endsWith(`.${u.format}`)?e.output:`${e.output}.${u.format}`;await Bk(Fk(g),{recursive:!0}),await Lm(g,u.audioData);let w=g.replace(/\.[^.]+$/,".txt");if(await Lm(w,e.text,"utf-8"),r==="json"){l({status:"completed",requestId:u.requestId,output:g,audioUrl:u.audioUrl,duration:u.duration,format:u.format,speed:u.speed??i??1,lang:u.language??e.lang??null,langApplied:u.langApplied??!1,timestamps:u.timestamps??null,words:u.wordTimings??null});return}if(r==="quiet"){console.log(g);return}k(`Saved to: ${g}`),b(`Duration: ${u.duration.toFixed(2)}s`)}catch(d){o?.stop(),a(`${ne(d,c)} Retry with --idempotency-key ${t}.`,r),process.exit(s.GENERAL_ERROR)}});function Kk(e,t){try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error;return n}catch{throw new Error(`${e} must be a JSON object`)}}var Wk=new Dr("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json",y("--format",["human","json"]),"human").action(async e=>{let t=e.format==="human"?Um("Fetching voices...").start():null;try{let n=await ts(e.provider);if(t?.stop(),e.format==="json"){l(n.voices);return}if(Array.isArray(n.voices)){let r=e.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${r} Voices:`),console.log("-".repeat(50));for(let o of n.voices)console.log(` ${o.name} (${o.id})`),console.log(` ${o.description}`)}else for(let[r,o]of Object.entries(n.voices))if(!(!o||o.length===0)){console.log(),console.log(`${r.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let i of o)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}}catch(n){t?.stop(),a(n instanceof Error?n.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Jk=new Dr("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json",y("--format",["json"]),"json").action(async(e,t)=>{try{l(await I("generateSpeech",e,t.teamId))}catch(n){a(n instanceof Error?n.message:"Status failed"),process.exit(s.GENERAL_ERROR)}}),_m=new Dr("tts").description("Text-to-speech commands").addCommand(Gk).addCommand(Wk).addCommand(Jk);import{execSync as Ur,spawnSync as mx}from"child_process";import{access as Ji,readFile as ux,rm as Wm}from"fs/promises";import{resolve as Tn}from"path";import ie from"chalk";import{Command as le}from"commander";import px from"ffmpeg-static";import Jm from"ora";import{Command as zk}from"commander";var qm=new zk("set").description("Set the poster of a finished video").argument("<video-id>","Finished video whose poster is being set").option("--at-seconds <seconds>","Moment of the video to cut the poster from").option("--image-url <url>","Existing https image to use as the poster").option("--upload-key <key>","Key of an image you uploaded").option("--team-id <id>","Workspace to act in").action(async(e,t)=>{[t.atSeconds,t.imageUrl,t.uploadKey].filter(o=>o!==void 0).length>1&&(a("Name at most one poster source: --at-seconds, --image-url or --upload-key. Name none to restore the automatic one."),process.exit(s.INVALID_INPUT));let r={videoId:e};if(t.atSeconds!==void 0){let o=Number(t.atSeconds);(!Number.isFinite(o)||o<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),r.atSeconds=o}t.imageUrl!==void 0&&(r.imageUrl=t.imageUrl),t.uploadKey!==void 0&&(r.uploadKey=t.uploadKey),t.teamId!==void 0&&(r.teamId=t.teamId);try{let o=await W(t.teamId),i=await m("setVideoThumbnail",r,z({command:"video thumbnail set",payload:r,workspaceId:o}));l(i),k(`Poster set from ${i.source}.`)}catch(o){a(o instanceof Error?o.message:"Setting the poster failed"),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Gi}from"crypto";import{mkdir as Hk}from"fs/promises";import{join as Xk}from"path";import{Command as ut}from"commander";import Vm from"ora";var Yk=5e3,Qk=120,jm=5;function Mm(e,t){return[...t,e]}function Zk(e,t){try{let n=new URL(e);if(n.protocol!=="https:"&&n.protocol!=="http:")throw new Error;return n.toString()}catch{throw new Error(`${t} must be a public HTTP(S) URL`)}}function Nr(e){if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e))throw new Error("Source video id must be a UUID");return e}function ex(e){if(e.mode&&!["speed","precision"].includes(e.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:Zk(e.audioUrl,"Audio URL"),...e.mode?{mode:e.mode}:{},sourceVideoId:Nr(e.sourceVideoId)}}function tx(e){let t=[],n=new Set;for(let o of e.targetLanguage){let i=o.trim(),c=i.toLocaleLowerCase("en-US");!i||n.has(c)||(n.add(c),t.push(i))}if(t.length===0)throw new Error("Provide at least one target language");if(t.length>jm)throw new Error(`Provide at most ${jm} target languages`);if(t.find(o=>o.length<2||o.length>40))throw new Error("Target languages must be between 2 and 40 characters");return{...e.captions?{captions:!0}:{},sourceVideoId:Nr(e.sourceVideoId),targetLanguages:t}}function nx(e){if(e.aspect&&!["9:16","16:9","1:1"].includes(e.aspect))throw new Error("Clip aspect must be 9:16, 16:9, or 1:1");let t=e.duration.filter(r=>["30","60","180","long"].includes(r));if(t.length!==e.duration.length)throw new Error("Clip duration must be 30, 60, 180, or long");let n=e.maxClips?Number.parseInt(e.maxClips,10):void 0;if(n!==void 0&&(!Number.isInteger(n)||n<1||n>10))throw new Error("Max clips must be between 1 and 10");return{...e.aspect?{aspect:e.aspect}:{},...e.brandingId?{brandingId:Nr(e.brandingId)}:{},...e.captionStyle?{captionStyle:e.captionStyle}:{},...e.captions?{captions:!0}:{},...t.length?{durationTypes:t}:{},...e.inputLanguage?{inputLanguage:e.inputLanguage}:{},...n!==void 0?{maxClips:n}:{},...e.prompt?{prompt:e.prompt}:{},sourceVideoId:Nr(e.sourceVideoId),...e.title?{title:e.title}:{}}}function rx(e){return e.error||e.status==="failed"||e.status==="cancelled"?"failed":e.done||e.status==="completed"?"completed":e.status==="in_progress"||e.status==="processing"?"processing":"pending"}function Lr(e){return{requestId:e.runId,status:rx(e),...e.entity?.url?{videoUrl:e.entity.url}:{},...e.output?{output:e.output}:{},...e.error?{error:ue(e.error)}:{}}}function Ki(e){return{requestId:e.runId,status:"pending"}}async function Wi(e,t){return pe(async()=>Lr(await I(e,t)),Qk,Yk)}function _e(e,t){if(t==="json"){l(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}b(`Request ID: ${e.requestId}`),b(`Status: ${e.status}`),e.videoUrl&&k(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}function ox(e){return Array.isArray(e?.languages)?e.languages.filter(t=>{if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t;return typeof n.language=="string"&&(n.status==="completed"||n.status==="failed")&&typeof n.videoId=="string"&&(n.videoUrl===null||typeof n.videoUrl=="string")}):[]}function ix(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function ax(e,t){let n=ix(e);if(!t.has(n))return t.add(n),n;let r=n.slice(0,-4),o=2;for(;t.has(`${r}-${o}.mp4`);)o+=1;let i=`${r}-${o}.mp4`;return t.add(i),i}async function sx(e,t){let n=ox(e.output).filter(i=>i.status==="completed"&&!!i.videoUrl);if(n.length===0)throw new Error("Video translation completed without downloadable results");await Hk(t,{recursive:!0});let r=[],o=new Set;for(let i of n){let c=Xk(t,ax(i.language,o));await oe(i.videoUrl,c),r.push({language:i.language,path:c})}return r}var dx=new ut("status").description("Check a video lip-sync request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(e,t){let r=R(this,t).format??"human";try{_e(Lr(await I("lipsyncVideo",e)),r)}catch(o){a(o instanceof Error?o.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Bm=new ut("lipsync").description("Re-voice a ready workspace video with a public audio URL").requiredOption("--source-video-id <uuid>","READY workspace video UUID").requiredOption("--audio-url <url>","Public replacement voice audio URL").option("--mode <mode>","Quality mode: speed or precision","speed").requiredOption("-o, --output <path>","Local output video path").option("--idempotency-key <key>","Stable retry key").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Vm("Starting video lip-sync...").start():null,n;try{let r=await cs(ex(e),e.idempotencyKey??Gi());if(n=r.runId,!e.wait){t?.stop(),_e(Ki(r),e.format);return}t&&(t.text="Waiting for video lip-sync...");let o=await Wi("lipsyncVideo",r.runId);if(o.status==="failed")throw new Error(o.error??"Video lip-sync failed");if(!o.videoUrl)throw new Error("Video lip-sync completed without a video URL");t&&(t.text="Downloading lip-synced video..."),await oe(o.videoUrl,e.output),t?.stop(),_e(o,e.format),e.format==="human"&&k(`Saved to: ${e.output}`)}catch(r){t?.stop(),a(ne(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(dx),Fm=new ut("translate-languages").description("List supported video translation target languages").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await ms();if(e.format==="json")l({languages:t});else for(let n of t)console.log(n)}catch(t){a(t instanceof Error?t.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),cx=new ut("status").description("Check a video translation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(e,t){let r=R(this,t).format??"human";try{_e(Lr(await I("translateVideo",e)),r)}catch(o){a(o instanceof Error?o.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Gm=new ut("translate").description("Translate a ready workspace video into one or more languages").requiredOption("--source-video-id <uuid>","READY workspace video UUID").option("--target-language <language>","Target language (repeatable)",Mm,[]).option("--captions","Burn provider-generated captions into translated videos").requiredOption("--output-dir <path>","Directory for translated videos").option("--idempotency-key <key>","Stable retry key").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Vm("Starting video translation...").start():null,n;try{let r=await us(tx(e),e.idempotencyKey??Gi());if(n=r.runId,!e.wait){t?.stop(),_e(Ki(r),e.format);return}t&&(t.text="Waiting for video translations...");let o=await Wi("translateVideo",r.runId);if(o.status==="failed")throw new Error(o.error??"Video translation failed");t&&(t.text="Downloading translated videos...");let i=await sx(o,e.outputDir);if(t?.stop(),e.format==="json")l({...o,downloads:i});else if(e.format==="quiet")for(let c of i)console.log(c.path);else{_e(o,e.format);for(let c of i)k(`${c.language}: ${c.path}`)}}catch(r){t?.stop(),a(ne(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(cx),lx=new ut("status").description("Check a video clipping request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(e,t){let n=R(this,t);try{_e(Lr(await I("clipVideo",e)),n.format??"human")}catch(r){a(r instanceof Error?r.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),Km=new ut("clips").description("Turn a ready workspace video into short clips").requiredOption("--source-video-id <uuid>","READY workspace video UUID").option("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--branding-id <uuid>","Workspace brand UUID").option("--caption-style <style>","Provider caption style").option("--captions","Burn provider-generated captions into clips").option("--duration <bucket>","Duration bucket: 30, 60, 180, or long",Mm,[]).option("--input-language <language>","Source language").option("--max-clips <count>","Maximum displayed clips (1-10)").option("--prompt <text>","Editorial clipping guidance").option("--title <text>","Provider job title").option("--idempotency-key <key>","Stable retry key").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{let n=await ls(nx(e),e.idempotencyKey??Gi());if(t=n.runId,!e.wait)return _e(Ki(n),e.format);let r=await Wi("clipVideo",n.runId);if(r.status==="failed")throw new Error(r.error??"Video clipping failed");_e(r,e.format)}catch(n){a(ne(n,t),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(lx);async function gx(){return process.stdin.isTTY?null:new Promise(e=>{let t="",n=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",r=>{t+=r}),process.stdin.on("end",()=>{n||(n=!0,e(t.trim()?t:null))}),process.stdin.on("error",()=>{n||(n=!0,e(null))}),setTimeout(()=>{!n&&!t&&(n=!0,e(null))},500)})}function fx(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}var hx=new le("find").description("Find video clips across the web and licensed stock").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("--source <source>","Catalog: web, stock, or any (default: any)","any").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let{maxResults:n,orientation:r,license:o,format:i}=t,c=i==="human"?Jm("Finding videos...").start():null;try{let d=await is({query:e,options:{maxResults:parseInt(n,10),orientation:r,license:o,sources:fx(t.source)}});c?.stop();let u=d.data.results.flatMap(g=>g.results);if(i==="json"){l(d);return}if(i==="quiet"){u.forEach(g=>{console.log(g.embedUrl||g.previewUrl||g.thumbnailUrl)});return}if(u.length===0){b("No videos found");return}k(`Found ${u.length} videos for "${e}"`),console.log(),u.forEach((g,w)=>{let v=g.kind==="embed";console.log(`[${w+1}] ${g.title}`),console.log(` ${v?"Embed":"URL"}: ${g.embedUrl||g.previewUrl||g.thumbnailUrl}`),console.log(v?` Duration: ${g.duration}s | Embed only \u2014 plays in the host player, do not download`:` Duration: ${g.duration}s | Size: ${g.width}x${g.height}`),console.log(` Provider: ${g.provider}`),console.log()})}catch(d){c?.stop(),a(d instanceof Error?d.message:"Unknown error"),process.exit(s.GENERAL_ERROR)}}),yx=new le("create").description("Generate one video from a pinned storyboard revision").requiredOption("--storyboard-revision <id>","Immutable storyboard revision UUID").option("--source-video <id>","Ready video from an earlier create call to use as base footage").option("--release","Render at 720p for release. Costs more; drafts are 480p by default").option("--team-id <id>","Workspace ID").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--yes","Approve paid video generation").action(async e=>{if(!e.yes)return a("Pass --yes to approve video generation");try{l(await ps({quality:e.release?"release":void 0,sourceVideoId:e.sourceVideo,storyboardRevisionId:e.storyboardRevision,teamId:e.teamId},e.approvalReceipt,e.idempotencyKey))}catch(t){a(t instanceof Error?t.message:"Generation failed"),process.exit(s.GENERAL_ERROR)}});async function zm(e){let t=e==="-"?await gx():await ux(e,"utf-8");if(!t?.trim())throw new Error(e==="-"?"No storyboard Markdown was received on stdin":`Storyboard file is empty: ${e}`);return t}async function Hm(e,t={}){if(e)return e.length===1&&e[0]==="none"?[]:Promise.all(e.map(async n=>{let r;try{let x=JSON.parse(n);if(!x||typeof x!="object"||Array.isArray(x))throw new Error("Media binding must be a JSON object");r=x}catch(x){throw new Error(`Invalid --media binding. Pass one JSON object per binding, for example '{"handle":"actress-photo","path":"./actress.jpg","purpose":"identity"}'.`,{cause:x})}let o=$e(r.handle),i=$e(r.path),c=$e(r.fileUrl)??$e(r.url),d=$e(r.purpose),u=$e(r.videoRole),g=$e(r.analysisId)??$e(r.analysis);if(!o||!i&&!c||!d)throw new Error("Invalid --media binding. handle, purpose, and either path or url are required strings.");if(i&&c)throw new Error("A media binding cannot contain both path and url.");if(i&&d==="source"&&g)throw new Error("A source analysis is bound to the original uploaded URL. Reuse the url/name/mime/size binding printed by 'video reference analyze' instead of uploading path again.");if(i&&!t.uploadIdempotencyKey)throw new Error("Local storyboard media requires the command idempotency key.");let w=i?await Q(Tn(i),{idempotencyKey:`${t.uploadIdempotencyKey}:media:${o}`}):{name:$e(r.name),size:Number(r.size),type:$e(r.mime),url:c};if(!w.name||!w.type||!w.url||!Number.isSafeInteger(w.size)||w.size<=0)throw new Error(`URL media binding "${n}" requires name, mime, and positive integer size.`);let v=w.type.startsWith("video/")?"video":w.type.startsWith("audio/")?"audio":w.type.startsWith("image/")?"image":null;if(!v)throw new Error(`Unsupported media type for ${i??c}: ${w.type}`);if(!["source","style","identity","required"].includes(d))throw new Error(`Invalid media purpose: ${d}`);if(u&&!["reference","first-frame","last-frame"].includes(u))throw new Error(`Invalid videoRole: ${u}`);if(u&&v!=="image")throw new Error("videoRole is supported only for image bindings.");return{...g?{analysisId:g}:{},fileUrl:w.url,handle:o,kind:v,mime:w.type,name:w.name,purpose:d,size:w.size,...u?{videoRole:u}:{}}}))}function $e(e){return typeof e=="string"&&e.length>0?e:void 0}var bx=new le("create").description("Create a versioned Markdown video storyboard").requiredOption("--file <path>","Markdown file path, or - for stdin").requiredOption("--duration <seconds>","Exact total duration in seconds").requiredOption("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--title <text>","Artifact label").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact create").option("--media <binding...>",'One JSON binding per asset: {"handle":"actress-photo","path":"./actress.jpg","purpose":"identity"}').option("--team-id <id>","Workspace ID").action(async e=>{try{l(await m("createVideoStoryboard",{aspectRatio:e.aspect,durationSec:Number(e.duration),mediaBindings:await Hm(e.media,{uploadIdempotencyKey:e.idempotencyKey}),storyboardMarkdown:await zm(e.file),teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(t){a(t instanceof Error?t.message:"Storyboard creation failed"),process.exit(s.GENERAL_ERROR)}}),wx=new le("revise").description("Append an immutable revision to a video storyboard").argument("<storyboard-id>","Storyboard UUID").requiredOption("--base-revision <id>","Revision UUID that was edited").requiredOption("--file <path>","Complete Markdown file path, or - for stdin").requiredOption("--duration <seconds>","Exact total duration in seconds").requiredOption("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--title <text>","Replacement artifact label").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact revision").option("--change-summary <text>","Short description of this revision").option("--media <binding...>",'Replace media bindings with one JSON object per asset; use the JSON printed by "video reference analyze" for analyzed source video').option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{l(await m("reviseVideoStoryboard",{aspectRatio:t.aspect,baseRevisionId:t.baseRevision,changeSummary:t.changeSummary,durationSec:Number(t.duration),mediaBindings:await Hm(t.media,{uploadIdempotencyKey:t.idempotencyKey}),storyboardId:e,storyboardMarkdown:await zm(t.file),teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(n instanceof Error?n.message:"Storyboard revision failed"),process.exit(s.GENERAL_ERROR)}}),vx=new le("show").description("Read a storyboard; print Markdown unless --json is used").argument("<storyboard-id>","Storyboard UUID").option("--revision <id>","Read one immutable revision UUID").option("--team-id <id>","Workspace ID").option("--json","Print the complete structured response").action(async(e,t)=>{try{let n=await m("readVideoStoryboard",{revisionId:t.revision,storyboardId:e,teamId:t.teamId});if(t.json){l(n);return}console.error(`${n.storyboard.title} \xB7 revision ${n.storyboard.revision.versionNumber} (${n.storyboard.revision.id})`),console.log(n.storyboard.revision.storyboardMarkdown)}catch(n){a(n instanceof Error?n.message:"Storyboard read failed"),process.exit(s.GENERAL_ERROR)}}),Ix=new le("storyboard").description("Create, revise, and read Markdown video storyboards").addCommand(bx).addCommand(wx).addCommand(vx),Xm=new le("analyze").description("Upload and analyze a reference video; its analysisId is the only analysis video generation consumes").requiredOption("--file <path>","Local reference video").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact analysis").option("--user-request <text>","What the analysis should focus on").option("--team-id <id>","Workspace ID").option("--no-wait","Return the durable run immediately").option("--json","Print the complete structured result").action(async e=>{try{let t=await Q(Tn(e.file),{idempotencyKey:`video-reference-analysis:${e.idempotencyKey}:source`});if(!t.type.startsWith("video/"))throw new Error(`Reference analysis requires a video, got ${t.type}`);let n=await gs({idempotencyKey:e.idempotencyKey,sourceUrl:t.url,teamId:e.teamId,userRequest:e.userRequest}),r={analysisId:n.runId,fileUrl:t.url,handle:"source-video",kind:"video",mime:t.type,name:t.name,purpose:"source",size:t.size};if(e.wait===!1){l({...n,binding:r,source:t});return}let o=await fs(n.runId,e.teamId);if(e.json){l({...o,binding:r,source:t});return}let i=o.output?.analysis??{};console.log(typeof i.promptContext=="string"?i.promptContext:JSON.stringify(o.output,null,2)),console.error(`Analysis run: ${n.runId}`),console.error(`Storyboard media JSON: ${JSON.stringify(r)}`)}catch(t){a(t instanceof Error?t.message:"Reference analysis failed"),process.exit(s.GENERAL_ERROR)}});Xm.addHelpText("after",`
|
|
277
|
-
${
|
|
278
|
-
${
|
|
279
|
-
${
|
|
280
|
-
`);var
|
|
281
|
-
${
|
|
282
|
-
${
|
|
283
|
-
$ ${
|
|
284
|
-
|
|
285
|
-
${
|
|
286
|
-
$ ${
|
|
287
|
-
|
|
288
|
-
${
|
|
289
|
-
${
|
|
290
|
-
${
|
|
291
|
-
${
|
|
292
|
-
${
|
|
293
|
-
${
|
|
294
|
-
$ ${
|
|
295
|
-
$ ${
|
|
296
|
-
|
|
297
|
-
${
|
|
298
|
-
${
|
|
299
|
-
$ ${
|
|
300
|
-
`);import{Command as
|
|
301
|
-
`)}function ae(e,t){if(e.source==="live")return`<!-- Generated from the live ${t.name} capability catalog (v${e.catalogVersion}, ${e.capabilities.length} capabilities) at install time. Re-run \`${t.cmd} skill install\` to refresh. -->`;let n=e.reason?` Reason: ${jr(e.reason).replace(/\.+$/,"")}.`:"";return`<!-- STALE-RISK: the live catalog could not be read at install time, so this was rendered from the snapshot baked into the installed CLI (v${e.catalogVersion}, ${e.capabilities.length} capabilities).${n} Run \`${t.cmd} login\` then \`${t.cmd} skill install --force\` to regenerate from the live catalog, and treat \`${t.cmd} capabilities\` as authoritative over this file. -->`}function ru(e){return e.map(t=>`- [${t}](#${t.toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/ /g,"-")})`).join(`
|
|
302
|
-
|
|
221
|
+
$ ${g.commands[0]} presentation video music stock select <project-id> --mode auto
|
|
222
|
+
`),dx=new qn("status").description("Read stock-music run status/progress, billing, persisted result, or typed failure").argument("<run-id>","Run ID returned by stock select --no-wait").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);await ra("Stock-music status failed",()=>x("selectPresentationVideoStockMusic",t,n.teamId))});ke(fp);var hp=new qn("music").description("Search and select music sources for an existing video project").addCommand(ta).addCommand(gp).addCommand(new qn("stock").description("Preview catalog tracks and save a manual or deck-aware automatic selection").addCommand(sx).addCommand(fp).addCommand(dx));async function ra(t,e){try{l(await e())}catch(n){a(m(n,t)),process.exit(s.GENERAL_ERROR)}}function na(t){a(t),process.exit(s.INVALID_INPUT)}import{readFile as oa}from"fs/promises";async function yp(t){if(!t)return;let e=t.trim().startsWith("{")?t:await oa(t,"utf8"),n=JSON.parse(e);if(!n||Array.isArray(n)||typeof n!="object")throw new C("--slide-instructions must be a JSON object or file path",400);let r={};for(let[o,i]of Object.entries(n)){if(!o.trim()||typeof i!="string")throw new C("--slide-instructions must map non-empty slide IDs to text",400);r[o]=i}return r}async function bp(t){let e=t.slideId!==void 0||t.text!==void 0||t.textFile!==void 0;if(t.notes!==void 0){if(e)throw new C("Use either --notes or --slide-id with --text/--text-file, not both",400);let r=t.notes.trim().startsWith("[")?t.notes:await oa(t.notes,"utf8"),o=JSON.parse(r);if(!Array.isArray(o)||o.length===0||!o.every(i=>i&&typeof i=="object"&&typeof i.slideId=="string"&&typeof i.text=="string"))throw new C('--notes must be a non-empty JSON array of {"slideId","text"} or a path to one',400);return o.map(({slideId:i,text:d})=>({slideId:i,text:d}))}if(!t.slideId)throw new C("Pass --slide-id with --text or --text-file, or --notes",400);if(t.text===void 0==(t.textFile===void 0))throw new C("Pass exactly one of --text or --text-file (an empty --text clears the note)",400);let n=t.text??await oa(t.textFile,"utf8");return[{slideId:t.slideId,text:n}]}var cx=new K("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",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await x("createSlides",t,e.teamId);if(e.format==="json"){l(n);return}if(e.format==="quiet"){console.log(n.status);return}w(`Status: ${n.status}`),w(n.message),n.progress!==null&&w(`Progress: ${n.progress}%`),n.error&&a(re(n.error))}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),lx=new K("delete").description("Permanently delete an owned presentation and its publications").argument("<presentation-id>","Presentation id or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--yes","Confirm permanent deletion").action(async(t,e)=>{e.yes||(a("Refusing to permanently delete without confirmation. Re-run with --yes."),process.exit(s.GENERAL_ERROR));let n=e.idempotencyKey??Z({command:"presentation:delete",payload:{presentationId:t},workspaceId:e.teamId??"configured-default"});try{l(await p("deletePresentation",{approvalReceipt:e.approvalReceipt,presentationId:t,teamId:e.teamId},n))}catch(r){r.errorCode==="approval_required"&&L(`Retry with --idempotency-key ${n}`),a(m(r,"Could not delete the presentation")),process.exit(s.GENERAL_ERROR)}}),mx=new K("limits").description("Show the selected workspace's presentation generation limits").option("--team-id <id>","Workspace ID (uses configured default)").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{await b();let e=t.teamId??se();e||(a("Team ID required. Set one with `mf config set team-id <id>` or pass --team-id."),process.exit(s.GENERAL_ERROR));try{let n=await So(e);if(t.format==="json")return l(n);if(t.format==="quiet")return console.log(n.planName);w(`Plan: ${n.planName}`),w(`Available modes: ${n.availableModes.join(", ")||"none"}`),w(`Maximum slides: ${n.maxSlidesPerPresentation}`)}catch(n){a(m(n,"Could not read generation limits")),process.exit(s.GENERAL_ERROR)}}),px=new K("visibility").description("Set an owned presentation's visibility to private, team, or public").argument("<presentation-id>","Presentation ID or slug").argument("<visibility>","private, team, or public",y("visibility",["private","team","public"])).option("--team-id <id>","Workspace ID (uses configured default)").option("--idempotency-key <key>","Stable retry key").action(async(t,e,n)=>{await b();try{l(await fs(t,{idempotencyKey:n.idempotencyKey,teamId:n.teamId,visibility:e}))}catch(r){a(m(r,"Could not update presentation visibility")),process.exit(s.GENERAL_ERROR)}});function vp(t){let e=Number(t);if(!Number.isInteger(e)||e<0)throw new Hr("Expected a non-negative integer.");return e}async function ux(t){let e=t.trim(),n=e.startsWith("[")?e:await wp(e,"utf-8"),r=JSON.parse(n);if(!Array.isArray(r))throw new Hr("--grants must be a JSON array.");for(let o of r)if(!o||typeof o!="object"||typeof o.userId!="string"||!["view","edit"].includes(o.permission))throw new Hr('Every grant must be {"userId":"\u2026","permission":"view|edit"}.');return r}var gx=new K("get").description("Read presentation ownership and team access").requiredOption("--document-id <id>","Presentation document ID").option("--team-id <id>","Workspace ID override").action(async t=>{try{l(await p("getPresentationSharing",{documentId:t.documentId,teamId:t.teamId}))}catch(e){a(m(e,"Could not read presentation sharing")),process.exit(s.GENERAL_ERROR)}}),fx=new K("update").description("Replace presentation collaborators and team access").requiredOption("--document-id <id>","Presentation document ID").requiredOption("--expected-revision <number>","Revision returned by presentation sharing get",vp).requiredOption("--team-access <access>","restricted, view, or edit",y("--team-access",["restricted","view","edit"])).requiredOption("--grants <json-or-path>","Complete JSON grant array; use [] to remove all collaborators").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID override").action(async t=>{try{let e=await B(t.teamId),n=await ux(t.grants),r=t.idempotencyKey??Z({command:"presentation:sharing:update",payload:{documentId:t.documentId,expectedRevision:t.expectedRevision,grants:n,teamAccess:t.teamAccess},workspaceId:e});l(await p("updatePresentationSharing",{documentId:t.documentId,expectedRevision:t.expectedRevision,grants:n,teamAccess:t.teamAccess,teamId:e},r))}catch(e){a(m(e,"Could not update presentation sharing")),process.exit(s.GENERAL_ERROR)}}),hx=new K("sharing").description("Read or update presentation team access").addCommand(gx).addCommand(fx),yx=new K("transfer").description("Transfer a presentation and every saved version").requiredOption("--document-id <id>","Presentation document ID").requiredOption("--to-user-id <id>","Active team editor or admin").requiredOption("--expected-revision <number>","Revision returned by presentation sharing get",vp).option("--previous-owner-access <access>","Keep edit access or remove access",y("--previous-owner-access",["edit","remove"]),"edit").option("--idempotency-key <key>","Stable retry key").option("--team-id <id>","Workspace ID override").action(async t=>{try{let e=await B(t.teamId),n=t.idempotencyKey??Z({command:"presentation:transfer",payload:{documentId:t.documentId,expectedRevision:t.expectedRevision,previousOwnerAccess:t.previousOwnerAccess,toUserId:t.toUserId},workspaceId:e});l(await p("transferPresentationOwnership",{documentId:t.documentId,expectedRevision:t.expectedRevision,previousOwnerAccess:t.previousOwnerAccess,teamId:e,toUserId:t.toUserId},n))}catch(e){a(m(e,"Could not transfer presentation ownership")),process.exit(s.GENERAL_ERROR)}}),bx=new K("transform").description("Transform an uploaded PowerPoint import for review").argument("<import-id>","PowerPoint import ID returned by Mindframes").option("--idempotency-key <key>","Stable retry key").action(async function(t,e){let n=R(this,e);try{let r=await p("transformPresentationImport",{importId:t},n.idempotencyKey);l(r)}catch(r){a(m(r,"Transform failed")),process.exit(s.GENERAL_ERROR)}});function Ip(t){return new K(t.name).description(t.description).argument("<run-id>","Run ID returned by PowerPoint import").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(e,n)=>{try{let r=await x(t.capabilityId,e,n.teamId);n.format==="json"?l(r):n.format==="quiet"?console.log(r.status):(w(`Status: ${r.status}`),w(r.message),r.error&&a(re(r.error)))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}})}var wx=Ip({capabilityId:"importPowerPoint",description:"Read a PowerPoint import run",name:"status"}),vx=Ip({capabilityId:"transformPresentationImport",description:"Read a PowerPoint transform run",name:"transform-status"}),kp=new K("import").description("Import a PowerPoint through the review-gated reconstruction pipeline").option("--file <path>","Path to the .pptx to import").option("--filename <name>","Override the uploaded filename").option("--mode <mode>","Import mode: preserve or rebrand","preserve").option("--branding-id <id>","Saved brand ID (required for rebrand mode)").option("--source-chat-id <id>","Associate the import with an existing chat").option("--title <title>","Presentation title").option("--idempotency-key <key>","Stable retry key").action(async t=>{if(!t.file){kp.help();return}t.file.toLowerCase().endsWith(".pptx")||(a("PowerPoint import requires a .pptx file."),process.exit(s.INVALID_INPUT));try{let e=await ee(t.file,{idempotencyKey:t.idempotencyKey}),n=await p("importPowerPoint",{brandingId:t.brandingId,filename:t.filename??e.name,mode:t.mode,sourceChatId:t.sourceChatId,sourceUrl:e.url,title:t.title},t.idempotencyKey??zt());l(n)}catch(e){a(m(e,"Import failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(bx).addCommand(wx).addCommand(vx),Ix=new K("speaker-notes-status").description("Check a speaker-notes generation run").argument("<run-id>","Run ID returned by speaker-notes generation").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await x("generateSpeakerNotes",t,e.teamId);e.format==="json"?l(n):e.format==="quiet"?console.log(n.status):(w(`Status: ${n.status}`),w(n.message))}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),kx=new K("video-narration-status").description("Check a presentation-video narration regeneration run").argument("<run-id>","Run ID returned by video-narration").option("--team-id <id>","Workspace ID override").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await x("regeneratePresentationVideoNarration",t,e.teamId);e.format==="json"?l(n):e.format==="quiet"?console.log(n.status):(w(`Status: ${n.status}`),w(n.message))}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),xx=new K("status").description("Read a presentation-video MP4 render run").argument("<run-id>","Run ID returned by presentation video").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await x("createPresentationVideo",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Rx=new K("prepare").description("Create or reuse a presentation-video project for a presentation").argument("<presentation-id>","Presentation ID, document ID, or slug").option("--force-new","Create a fresh video project even if the current presentation version already has one").option("--narrate","Also generate the narration the project is missing (costs credits; requires --yes)").option("--seed-from <draft>",'Create the project from an existing video draft: its id or slug for a full duplicate, or a JSON object like {"projectId":"<id>","carry":["narration","scenes","settings"]}').option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this prepare request").option("--yes","Confirm the narration charge when --narrate is used").action(async function(t,e){let n=R(this,e);if(n.narrate&&!n.yes)return a("Pass --yes to confirm. --narrate generates speaker notes and costs credits.");try{l(await p("preparePresentationVideo",{forceNew:n.forceNew,narrate:n.narrate,presentationId:t,seedFrom:$x(n.seedFrom),teamId:n.teamId},n.idempotencyKey??zt()))}catch(r){a(m(r,"Prepare failed")),process.exit(s.GENERAL_ERROR)}}),Cx=new K("status").description("Read a presentation-video narration run").argument("<run-id>","Run ID returned by presentation video narrate").option("--team-id <id>","Workspace ID override").action(async function(t,e){let n=R(this,e);try{l(await x("ensurePresentationVideoNarration",t,n.teamId))}catch(r){a(m(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Sx=new K("narrate").description("Generate the narration a presentation-video project is still missing").argument("<project-id>","Presentation video project ID").option("--no-wait","Return immediately with the durable run ID").option("--slide-id <id>","Regenerate one changed or new slide; repeat for more",ia,[]).option("--keep-current","Keep all current narration and generate no slide text").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this narration request").option("--yes","Confirm the narration charge").action(async function(t,e){let n=R(this,e);if(n.keepCurrent&&n.slideId?.length)return a("Use either --keep-current or --slide-id, not both.");if(!n.yes&&!n.keepCurrent)return a("Pass --yes to confirm. Generating narration costs credits.");try{let r=await p("ensurePresentationVideoNarration",{projectId:t,...n.keepCurrent?{slideIds:[]}:n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??zt());if(n.wait===!1||r.runStatus==="completed"){l(r);return}l(r),await Vn(r.runId,"presentation video narrate status",()=>er(r.runId))}catch(r){a(m(r,"Narration failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(Cx),Ex=new K("apply-notes").description("Copy speaker notes into scene narration verbatim (free, no generation)").argument("<project-id>","Presentation video project ID").option("--slide-id <id>","Apply notes to one scene; repeat for more (default: every scene with a note)",ia,[]).option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes apply").action(async function(t,e){let n=R(this,e);try{l(await p("applyPresentationVideoSpeakerNotes",{projectId:t,...n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??zt()))}catch(r){a(m(r,"Speaker-notes apply failed")),process.exit(s.GENERAL_ERROR)}}),Tx=new K("video").description("Create an MP4 video from a presentation").argument("[presentation-id]","Presentation ID, document ID, or slug").option("--project-id <id>","Advanced: render an already-configured presentation video project").option("--draft-version-number <number>","Render this immutable draft history version; requires --project-id").option("--settings <json-or-path>","Settings patch as JSON or a path to a JSON file; only valid with presentation-id").option("--force-new","Create a fresh video project even if the current presentation version already has one").option("--force-rerender","Start a new MP4 render even when the current project fingerprint has a completed render").option("--render-engine <engine>","Renderer for this MP4 only: remotion (Standard) or hyperframes (Premium)").option("--no-slide-animations","Premium renderer only: render every slide fully composed from its first frame instead of building it in as it is narrated").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this render request").option("--yes","Confirm starting the MP4 render").action(async(t,e)=>{if(!e.yes)return a("Pass --yes to confirm presentation video rendering.");try{if(!t&&!e.projectId)throw new Error("Pass a presentation id or --project-id.");if(t&&e.projectId)throw new Error("Pass either presentation id or --project-id, not both.");if(e.projectId&&(e.settings||e.forceNew))throw new Error("--settings and --force-new require a presentation id, not --project-id.");if(e.renderEngine&&e.renderEngine!=="remotion"&&e.renderEngine!=="hyperframes")throw new Error("--render-engine must be remotion or hyperframes.");let n=e.draftVersionNumber===void 0?void 0:Number(e.draftVersionNumber);if(n!==void 0&&(!Number.isInteger(n)||n<1||!e.projectId))throw new Error("--draft-version-number requires a positive integer and --project-id.");l(await p("createPresentationVideo",{draftVersionNumber:n,forceNew:e.forceNew,forceRerender:e.forceRerender,presentationId:t,projectId:e.projectId,renderEngine:e.renderEngine,settings:e.settings?await Ax(e.settings):void 0,slideAnimations:e.slideAnimations===!1?!1:void 0,teamId:e.teamId},e.idempotencyKey))}catch(n){let r=m(n,"Render failed");a(r);let o=ns({binary:g.commands[0],message:r,projectId:e.projectId});o&&gd(o),process.exit(s.GENERAL_ERROR)}}).addCommand(Ex).addCommand(Rx).addCommand(Sx).addCommand(Zm).addCommand(Dm).addCommand(hp).addCommand(Tm).addCommand(Am).addCommand(_m).addCommand(jm).addCommand(Xi).addCommand(Ym).addCommand(Um).addCommand(Lm).addCommand(ea).addCommand(Xm).addCommand(ip).addCommand(ap).addCommand(xx).addCommand(Mm).addCommand(qm).addCommand(Bm).addCommand(Vm).addCommand(Nm);async function Ax(t){let e=t.trim(),n=e.startsWith("{")?e:await wp(e,"utf-8"),r=JSON.parse(n);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("--settings must be a JSON object.");return r}function $x(t){if(!t)return;let e=t.trim();if(!e.startsWith("{"))return{projectId:e};try{let n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{throw new Hr('--seed-from must be a draft id or a JSON object like {"projectId":"<id>","carry":["narration","scenes","settings"]}.')}}function ia(t,e){return[...e,t]}var Px=new K("speaker-notes").description("Generate paid speaker notes; waits by default and requires --yes").argument("<presentation-id>","Presentation ID or slug").option("--mode <mode>","ensure or regenerate","ensure").option("--style <style>","concise or detailed","concise").option("--density <density>","Narration density: brief, balanced, or deep").option("--instructions <text>","Instructions for every selected slide").option("--rewrite-existing","With --mode regenerate, improve each slide's existing notes instead of writing new ones").option("--language <language>","Output language").option("--slide-id <id>","Target one slide (repeatable)",ia,[]).option("--slide-instructions <json-or-path>","Per-slide instructions as a JSON object or JSON file path").option("--no-follow","Return the run ID; recover with presentation speaker-notes-status <run-id>").option("--yes","Confirm the speaker-notes generation charge").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes request").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{if(!e.yes)throw new Error("Pass --yes to confirm. Generating speaker notes costs credits.");if(!["ensure","regenerate"].includes(e.mode))throw new Error("--mode must be ensure or regenerate");if(!["concise","detailed"].includes(e.style))throw new Error("--style must be concise or detailed");if(e.density&&!["brief","balanced","deep"].includes(e.density))throw new Error("--density must be brief, balanced, or deep");let n=await B(e.teamId),r={density:e.density??(e.style==="detailed"?"deep":"balanced"),instructions:e.instructions,language:e.language,mode:e.mode,rewriteExisting:e.rewriteExisting||void 0,slideIds:e.slideId.length?e.slideId:void 0,slideInstructions:await yp(e.slideInstructions)},o=await ps(t,r,e.idempotencyKey??Z({command:"presentation speaker-notes",payload:r,workspaceId:n}),n);if(e.format==="json"||!e.follow){l(o);return}w(`Speaker notes run: ${o.runId}`),await Vn(o.runId,"presentation speaker-notes-status",()=>er(o.runId))}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Ox=new K("speaker-notes-set").description("Write exact speaker notes onto slides, or clear them (free, no generation)").argument("<presentation-id>","Presentation ID or slug").option("--slide-id <id>","The one slide to write").option("--text <text>","The note for --slide-id; an empty string clears it").option("--text-file <path>","Read the note for --slide-id from a file").option("--notes <json-or-path>",'Several slides at once: a JSON array of {"slideId","text"} or a file path').option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes write").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await bp(e),r=await B(e.teamId),o=await us(t,n,e.idempotencyKey??zt(),r);if(e.format==="json"){l(o);return}if(e.format==="quiet"){console.log(o.slides.length);return}for(let i of o.slides)w(i.status==="intentionally_empty"?`Slide ${i.slideNumber}: notes cleared`:`Slide ${i.slideNumber}: notes saved`)}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Dx=new K("video-narration").description("Regenerate one scene or an exact scene batch in a presentation video draft").argument("<project-id>","Presentation video project ID").option("--slide-id <id>","One slide ID in the video draft").option("--slide-ids <ids...>","Exact scene IDs for one durable batch").option("--visual-slide-ids <ids...>","Exact offered visuals to refresh with narration").option("--no-refresh-visuals","Regenerate narration while retaining every scene visual").option("--expected-version-id <id>","Reviewed presentation version to update together with narration").option("--based-on-version-number <number>","Immutable video draft baseline").option("--branch-id <id>","Selected draft editor branch UUID").option("--expected-head-version-number <number>","Expected current draft history head").option("--instructions <text>","Optional regeneration instructions").option("--no-speaker-notes","Generate from the visible slide only, without speaker notes as reference").option("--density <density>","Narration density for this batch only: brief, balanced, or deep").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--no-follow","Return immediately with the durable run ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async function(t,e){try{let n=R(this,e),r=await B(n.teamId),o={basedOnVersionNumber:e.basedOnVersionNumber===void 0?void 0:Number(e.basedOnVersionNumber),branchId:e.branchId,expectedHeadVersionNumber:e.expectedHeadVersionNumber===void 0?void 0:Number(e.expectedHeadVersionNumber)},i=Object.values(o).filter(u=>u!==void 0).length;if(i&&(i!==3||!Number.isInteger(o.basedOnVersionNumber)||Number(o.basedOnVersionNumber)<1||!Number.isInteger(o.expectedHeadVersionNumber)||Number(o.expectedHeadVersionNumber)<1))throw new Error("Selected narration edits require a positive base/head version and branch ID together.");if(e.density&&!["brief","balanced","deep"].includes(e.density))throw new Error("--density must be brief, balanced, or deep");let d={...o,density:e.density,visualSlideIds:e.refreshVisuals===!1?[]:e.visualSlideIds,expectedVersionId:e.expectedVersionId,instructions:e.instructions,projectId:t,slideId:e.slideId,slideIds:e.slideIds,teamId:r,useSpeakerNotes:e.speakerNotes===!1?!1:void 0},c=await p("regeneratePresentationVideoNarration",d,n.idempotencyKey??zt());if(e.format==="json"||!e.follow){l(c);return}w(`Narration run: ${c.runId}`),await Vn(c.runId,"presentation video-narration-status",()=>er(c.runId))}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}});async function Vn(t,e,n){let r=null;try{r=await Lx(await n())}catch(o){let i=m(o,"the event stream ended unexpectedly");L(`Stopped following run ${t}: ${i}. The run is unaffected \u2014 check it with '${g.commands[0]} ${e} ${t}'.`);return}if(r)throw new Error(`Run ${t} ${r.status}: ${r.message} Inspect it with '${g.commands[0]} ${e} ${t}'.`)}function Nx(t){let e=t.eventType;if(e==="run.completed"||e==="durable_run.completed")return"completed";let n=e==="run.failed"||e==="durable_run.failed"?"failed":e==="run.cancelled"||e==="durable_run.cancelled"?"cancelled":null;return n?{message:t.payload?.message?.trim()||t.message?.trim()||"the run reported no error message",status:n}:null}async function Lx(t){let e=t.body?.getReader();if(!e)throw new Error("Speaker notes event stream is unavailable");let n=new TextDecoder,r="",o=null;for(;;){let{done:i,value:d}=await e.read();r+=n.decode(d,{stream:!i});let c=r.split(`
|
|
223
|
+
|
|
224
|
+
`);r=c.pop()??"";for(let u of c){let f=u.split(`
|
|
225
|
+
`).find(S=>S.startsWith("data:"))?.slice(5).trim();if(!f)continue;let v=JSON.parse(f);v.eventType?.startsWith("slide.")&&w(`${v.eventType}${v.payload?.slideId?` \xB7 ${v.payload.slideId}`:""}`);let I=Nx(v);I==="completed"?o=null:I&&(o=I)}if(i)return o}}var aa=new K("presentation").description("Create an MP4 video from a finished presentation, plus speaker notes, PowerPoint import, and run status").addCommand(cx).addCommand(Uo()).addCommand(mx).addCommand(px).addCommand(hx).addCommand(yx).addCommand(lx).addCommand(kp).addCommand(Px).addCommand(Ox).addCommand(Ix).addCommand(Tx).addCommand(Dx).addCommand(kx).addCommand(cp).addCommand(lp).addCommand(Sm);aa.addHelpText("after",`
|
|
226
|
+
${M.bold("Deck to MP4:")}
|
|
227
|
+
$ ${g.commands[0]} presentation video prepare <slug> ${M.gray("# create/reuse the video project (free)")}
|
|
228
|
+
$ ${g.commands[0]} presentation video narrate <project-id> --yes ${M.gray("# fill in missing narration")}
|
|
229
|
+
$ ${g.commands[0]} presentation video inspect <project-id> ${M.gray("# review the scene timeline")}
|
|
230
|
+
$ ${g.commands[0]} presentation video <slug> --yes ${M.gray("# start the MP4 render")}
|
|
231
|
+
$ ${g.commands[0]} presentation video status <run-id> ${M.gray("# follow the render")}
|
|
232
|
+
|
|
233
|
+
${M.bold("Voice and avatar defaults:")}
|
|
234
|
+
${M.gray("# prepare picks the narration voice for you \u2014 the one this user last")}
|
|
235
|
+
${M.gray("# chose if it is still ready, otherwise the first ready voice \u2014 and")}
|
|
236
|
+
${M.gray("# reports it. Show which voice was selected and offer to change it")}
|
|
237
|
+
${M.gray("# instead of interviewing the user about voices. Every voice in")}
|
|
238
|
+
${M.gray("# avatar options carries a previewUrl audio sample they can hear.")}
|
|
239
|
+
${M.gray('# No avatar is chosen, on purpose: "slides with a voiceover" is the')}
|
|
240
|
+
${M.gray("# normal outcome, so presenter: null is finished, not misconfigured.")}
|
|
241
|
+
${M.gray("# Ask whether they want a presenter; do not assume either way.")}
|
|
242
|
+
$ ${g.commands[0]} avatar options ${M.gray("# real voice and avatar ids + previews")}
|
|
243
|
+
$ ${g.commands[0]} presentation video settings <project-id> --yes --settings '{"voiceId":"<id>"}'
|
|
244
|
+
$ ${g.commands[0]} presentation video settings <project-id> --yes --settings '{"avatarId":"<id>"}'
|
|
245
|
+
|
|
246
|
+
${M.bold("Before rendering:")}
|
|
247
|
+
${M.gray("# Approve the content, then approve the spend \u2014 two questions. Read the")}
|
|
248
|
+
${M.gray("# narration back scene by scene from inspect (scenes[].narration.text)")}
|
|
249
|
+
${M.gray("# and get a yes on the script itself, plus the voice, the presenter (or")}
|
|
250
|
+
${M.gray("# none), music, format and captions, before the render. Reworking one")}
|
|
251
|
+
${M.gray("# scene is the cheap loop; the MP4 is not. --yes is your intent, not")}
|
|
252
|
+
${M.gray("# the user's consent.")}
|
|
253
|
+
$ ${g.commands[0]} presentation video inspect <project-id> ${M.gray("# narration text + settings to show")}
|
|
254
|
+
$ ${g.commands[0]} presentation video-narration <project-id> --slide-id <id> --instructions "shorter, warmer"
|
|
255
|
+
|
|
256
|
+
${M.bold("See also:")}
|
|
257
|
+
${M.gray("# Building a video from scratch instead of from a deck")}
|
|
258
|
+
$ ${g.commands[0]} video --help
|
|
259
|
+
`);import{randomUUID as Ux}from"crypto";import{writeFile as _x}from"fs/promises";import Mn from"chalk";import{Command as jx}from"commander";import Vx from"ora";var sa=new jx("scrape").description("Extract content from a URL").argument("<url>","URL to scrape").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--provider <name>","Scraping provider preference").option("--reason <text>","Reason for scraping this URL").option("--response-format <format>","Response format: markdown, html, text, content").option("-o, --output <path>","Save content to file").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{let n=e.format,r=n==="human"?Vx("Scraping URL...").start():null;try{let o=await p("scrape",{provider:e.provider,reason:e.reason,responseFormat:e.responseFormat,teamId:e.teamId,url:t},e.idempotencyKey??Ux());r?.stop();let i={content:o.content,metadata:{description:"",format:o.format??"unknown",tokenUsage:Math.ceil(o.content.length/4)},title:o.title??"",mode:o.mode,url:o.url};if(e.output&&(await _x(e.output,i.content,"utf-8"),n==="human"&&k(`Content saved to: ${e.output}`)),n==="json"){l(i);return}if(n==="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),e.output||(console.log(),console.log("--- Content ---"),console.log(i.content))}catch(o){r?.stop(),a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}});sa.addHelpText("after",`
|
|
260
|
+
${Mn.bold("Examples:")}
|
|
261
|
+
${Mn.gray("# Pull the readable content of a web page")}
|
|
262
|
+
$ ${g.commands[0]} scrape https://example.com/post
|
|
263
|
+
|
|
264
|
+
${Mn.bold("See also:")}
|
|
265
|
+
${Mn.gray("# Local files and documents, not just URLs")}
|
|
266
|
+
$ ${g.commands[0]} content extract ./paper.pdf
|
|
267
|
+
|
|
268
|
+
${Mn.gray("# Spoken words out of audio or video")}
|
|
269
|
+
$ ${g.commands[0]} transcript --help
|
|
270
|
+
`);import{randomUUID as Xr}from"crypto";import da from"chalk";import{Command as Bn}from"commander";function Yr(t,e){e!=="quiet"&&l(t)}var qx=new Bn("web").description("Search current public web sources").argument("<query>","Search query").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--max-results <count>","Maximum results","5").option("--country <code>","Two-letter search country code").option("--language <code>","Search language code").option("--queries <queries...>","Additional search queries").option("--reason <text>","Reason for this search").option("--recency <value>","Recency: all, h, d, w, m, y").option("--timeframe <value>","Timeframe: all, hour, day, week, month, year").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=[t,...e.queries??[]],r=await p("searchInternet",{gl:e.country,hl:e.language,maxResults:Number.parseInt(e.maxResults,10),queries:n,reason:e.reason,teamId:e.teamId,tbs:e.recency,timeframe:e.timeframe},e.idempotencyKey??Xr());Yr(r,e.format)}catch(n){a(m(n,"Search failed")),process.exit(s.GENERAL_ERROR)}}),Mx=new Bn("news").description("Search recent news").argument("<topic>","News topic").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--timeframe <value>","Timeframe hint").option("--max-results <count>","Maximum results","6").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await p("getNews",{maxResults:Number.parseInt(e.maxResults,10),teamId:e.teamId,timeframe:e.timeframe,topic:t},e.idempotencyKey??Xr());Yr(n,e.format)}catch(n){a(m(n,"News search failed")),process.exit(s.GENERAL_ERROR)}});function xp(t){let e=t?.trim().toLowerCase();if(!(!e||e==="any"||e==="all"))return e==="web"||e==="stock"?[e]:void 0}function Bx(t){if(!t?.length)return;let e=[...new Set(t.map(n=>n.toLowerCase()))];if(e.some(n=>n!=="embed"&&n!=="file"))throw new Error("Video kind must be embed or file");return e}var Fx=new Bn("images").description("Search images across the web and licensed stock").argument("<query>","Image search query").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--max-results <count>","Maximum results","10").option("--aspect <aspect>","Aspect: any, square, wide, tall","any").option("--queries <queries...>","Additional image queries").option("--reason <text>","Reason for this search").option("--source <source>","Catalog: web, stock, or any (default: any)","any").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=[t,...e.queries??[]],r=await p("searchImages",{aspect:e.aspect,maxResults:Number.parseInt(e.maxResults,10),queries:n,reason:e.reason,sources:xp(e.source),teamId:e.teamId},e.idempotencyKey??Xr());Yr(r,e.format)}catch(n){a(m(n,"Image search failed")),process.exit(s.GENERAL_ERROR)}}),Gx=new Bn("video").description("Search video across the web and licensed stock").argument("<query>","Video search query").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--max-results <count>","Maximum results","10").option("--kind <kind...>","Usable result kind: embed, file, or both (default: both)").option("--source <source>","Catalog: web, stock, or any (default: any)","any").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",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{let n=await p("searchStockVideo",{kinds:Bx(e.kind),license:e.license,maxResults:Number.parseInt(e.maxResults,10),orientation:e.orientation,query:t,sources:xp(e.source),teamId:e.teamId},e.idempotencyKey??Xr());Yr(n,e.format)}catch(n){a(m(n,"Video search failed")),process.exit(s.GENERAL_ERROR)}}),ca=new Bn("search").description("Web, news, image, and stock-video search").addCommand(qx).addCommand(Mx).addCommand(Fx).addCommand(Gx);ca.addHelpText("after",`
|
|
271
|
+
${da.bold("Examples:")}
|
|
272
|
+
$ ${g.commands[0]} search web "state of AI video 2026"
|
|
273
|
+
$ ${g.commands[0]} search news "vaccine approvals"
|
|
274
|
+
|
|
275
|
+
${da.bold("See also:")}
|
|
276
|
+
${da.gray("# `search images` and `search video` overlap with these")}
|
|
277
|
+
$ ${g.commands[0]} image search --help
|
|
278
|
+
$ ${g.commands[0]} video find --help
|
|
279
|
+
`);import{randomUUID as Kx}from"crypto";import{Command as pa}from"commander";import Wx from"ora";function ma(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.audioUrl??t.requestId??t.id);return}w(`Request ID: ${t.requestId||t.id}`),w(`Status: ${t.status}`),t.duration&&w(`Duration: ${t.duration}s`),t.audioUrl&&k(`Audio URL: ${t.audioUrl}`),t.error&&a(`Error: ${t.error}`)}var Jx=new pa("generate").description("Generate one SFX cue from a video's final facts and visual event").option("--request <path>","JSON file with video description, narration timings, and visual_event").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--duration <seconds>","Direct cue duration").option("--duration-seconds <seconds>","Final video duration").option("--narration-json <json>","Final narration timing array").option("--options-json <json>","Canonical sound-effect options JSON").option("--schema-version <version>","Video facts schema version").option("--text <text>","Direct sound-effect brief").option("--video-description <text>","Final video description").option("--visual-event-json <json>","Final visual event JSON").option("-o, --output <path>","Output file path").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e;try{e=_(t)}catch(c){a(m(c)),process.exit(s.INVALID_INPUT)}!t.wait&&t.output&&(a("--output requires waiting for completion; remove --no-wait"),process.exit(s.INVALID_INPUT));let n;try{n=t.request?hm(t.request):{...t.duration?{duration:Number(t.duration)}:{},...t.durationSeconds?{duration_s:Number(t.durationSeconds)}:{},...t.narrationJson?{narration:la("--narration-json",t.narrationJson)}:{},...t.optionsJson?{options:la("--options-json",t.optionsJson)}:{},...t.schemaVersion?{schema_version:Number(t.schemaVersion)}:{},...t.text?{text:t.text}:{},...t.videoDescription?{video_description:t.videoDescription}:{},...t.visualEventJson?{visual_event:la("--visual-event-json",t.visualEventJson)}:{}}}catch(c){a(m(c)),process.exit(s.INVALID_INPUT)}let r=t.format,o=r==="human"?Wx("Generating sound effect for video...").start():null,i,d=t.idempotencyKey??n.idempotency_key??Kx();try{let c=await Ps(n,{approvalReceipt:e,idempotencyKey:d});if(i=c.requestId||c.id,!t.wait){o?.stop(),ma(c,r);return}let u=c.requestId||c.id;o&&(o.text=`Processing (ID: ${u})...`);let f=c.status==="completed"||c.status==="failed"?c:await be(()=>Ao(u),60,2e3);if(o?.stop(),f.status==="failed"&&(a(f.error||"Sound effects generation failed"),process.exit(s.GENERAL_ERROR)),t.output){if(!f.audioUrl)throw new Error("Sound effect completed without an audio URL");await de(f.audioUrl,t.output),r==="human"&&k(`Saved to: ${t.output}`)}ma(f,r)}catch(c){o?.stop(),a(`${te(c,i)} Retry with --idempotency-key ${d}.`,r),process.exit(s.GENERAL_ERROR)}});function la(t,e){try{return JSON.parse(e)}catch{throw new Error(`${t} must be valid JSON`)}}var zx=new pa("status").description("Check status of a sound effects generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{try{ma(await Ao(t),e.format)}catch(n){a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Rp=new pa("sfx").description("Video-aware sound effects generation commands").addCommand(Jx).addCommand(zx);import{randomUUID as Ep}from"crypto";import{readFile as Zx}from"fs/promises";import{Command as ua}from"commander";import{existsSync as Hx,readFileSync as Xx,statSync as Yx}from"fs";import{basename as Qx}from"path";var Be=class extends Error{constructor(n,r){super(n);this.code=r;this.name="SupportAttachmentError"}code};async function Cp(t,e){let n=await fetch(`${F()}${t}`,{body:JSON.stringify(e),headers:{"Content-Type":"application/json",...await ge()},method:"POST"}),r=await n.text().catch(()=>"");if(!n.ok){let o=Ge(r,n.status);throw new Be(o.message,o.code)}try{return r?JSON.parse(r):null}catch{throw new Be("The attachment request returned an invalid response.","support_attachment_invalid_response")}}async function Sp(t,e){if(!Hx(t))throw new Be(`No such file: ${t}`,"support_attachment_missing_file");let n=Yx(t);if(!n.isFile()||n.size<=0)throw new Be(`Not a readable file with content: ${t}`,"support_attachment_missing_file");let r=Qx(t),o=await Cp("/api/support/attachments/presign",{fileName:r,mediaType:Rt(t),requestUuid:e.requestUuid,size:n.size,...e.teamId?{teamId:e.teamId}:{}}),i=new FormData;for(let[u,f]of Object.entries(o.upload.fields))i.append(u,f);i.append("file",new Blob([Xx(t)],{type:o.mediaType}),r);let d=await fetch(o.upload.url,{body:i,method:"POST"});if(!d.ok)throw new Be(`Storage refused the upload of ${r} (${d.status}).`,"support_attachment_upload_failed");let c=await Cp("/api/support/attachments/confirm",{key:o.attachmentKey,originalName:r,...e.teamId?{teamId:e.teamId}:{}});return{bytes:c.attachment.bytes,key:c.attachmentKey,mediaType:c.attachment.mediaType,name:c.attachment.name}}var eR=["received","looking_into_it","planned","in_progress","fixed_awaiting_release","shipped","not_planned","needs_input","resolved"];async function tR(t){if(t!==void 0&&t!=="-"&&!t.startsWith("@"))return t;if(t?.startsWith("@"))return Zx(t.slice(1),"utf8");if(t==="-"||!process.stdin.isTTY)return nR();a("Nothing to report. Pass the text as an argument, @<path> to read a file, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function nR(){let t=[];for await(let e of process.stdin)t.push(Buffer.from(e));return Buffer.concat(t).toString("utf8")}function rR(t){if(t===void 0)return{};let e;try{e=JSON.parse(t)}catch(n){a(`--context must be a JSON object: ${m(n)}`),process.exit(s.GENERAL_ERROR)}return(e===null||typeof e!="object"||Array.isArray(e))&&(a("--context must be a JSON object."),process.exit(s.GENERAL_ERROR)),e}function oR(t,e){return[...e,t]}async function iR(t,e){let n=[];for(let r of t)try{let o=await Sp(r,e);n.push(o.key)}catch(o){throw o instanceof Be&&(a(`${r}: ${o.message}`),process.exit(s.GENERAL_ERROR)),o}return n}function Tp(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var aR=new ua("report").description("File a bug, question, feature request or billing issue").argument("[text]","What happened, in your own words: literal text, @<path> to read a file, or '-' for stdin").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--attach <file>","Attach a local file to the report; repeatable, up to 5 files (25 MiB each, 200 MiB for video)",oR,[]).option("--screenshot-url <key>","Object key returned by the support screenshot upload (support-requests/<teamId>/<uuid>/screenshot.<ext>)").option("--source <source>","Where the report comes from; defaults to cli").option("--context <json>",`JSON object of extra context, e.g. '{"kind":"bug"}' for your own guess at bug | confusing | feature | billing | other (triage decides), route, errorReference, chatId, artifactId`).action(async(t,e)=>{try{let n=rR(e.context),r=Ep(),o=await iR(e.attach??[],{requestUuid:r,teamId:e.teamId});l(await p("submitSupportRequest",{attachmentKeys:o.length>0?o:void 0,context:Object.keys(n).length>0?n:void 0,screenshotUrl:e.screenshotUrl,source:e.source,teamId:e.teamId,text:await tR(t)},e.idempotencyKey??`cli:support:report:${Ep()}`))}catch(n){Tp(n,"Could not file the report")}}),sR=new ua("list").description("List the workspace's support requests and their status, newest first").option("--team-id <id>","Workspace ID").option("--mine","Only the reports you filed yourself").option("--status <status>",`Only items in one of ${eR.join(", ")}`).option("--limit <n>","Maximum items to return (default 50)").action(async t=>{try{l(await p("listSupportRequests",{limit:t.limit?Number(t.limit):void 0,mine:t.mine?!0:void 0,status:t.status,teamId:t.teamId}))}catch(e){Tp(e,"Could not list support requests")}}),Ap=new ua("support").description("File a report and follow what became of it").addCommand(aR).addCommand(sR);import Fn from"chalk";import{Command as dR}from"commander";var $p=new dR("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)",y("--format",["table","json"]),"table").option("--limit <n>","Maximum templates to list","25").action(async(t,e)=>{await b();try{let n=Number.parseInt(e.limit??"25",10),{templates:r}=await ws(t,Number.isFinite(n)?n:25);if(r.length===0){e.format==="json"?console.log(JSON.stringify([])):w("No templates found");return}if(e.format==="json"){console.log(JSON.stringify(r,null,2));return}for(let o of r){let i=[o.isDefault?Fn.green("default"):null,o.category??null,o.recommendedModes?.length?`modes: ${o.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${Fn.bold(o.name)} ${Fn.gray(o.id)}${i?`
|
|
280
|
+
${Fn.gray(i)}`:""}`)}console.log(),console.log(Fn.gray(`Use one with: ${g.commands[0]} create "<topic>" --template <id>`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}});import{randomUUID as cR}from"crypto";import{writeFile as lR}from"fs/promises";import{Command as mR}from"commander";import pR from"ora";var Pp=new mR("transcript").description("Fetch a YouTube video's transcript").argument("<url>","YouTube URL or 11-character video id").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key").option("--language <codes>","Comma-separated language priority list, e.g. 'en,de' or 'asr-en'").option("--reason <text>","Reason for retrieving the transcript").option("--no-timestamps","Print plain text without [m:ss] prefixes").option("-o, --output <path>","Save the transcript to a file").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{let n=e.format,r=n==="human"?pR("Fetching transcript...").start():null;try{let o=await p("getYoutubeTranscript",{language:e.language,reason:e.reason,teamId:e.teamId,url:t},e.idempotencyKey??cR());r?.stop();let i=e.timestamps?o.cues.map(d=>`[${d.timestamp}] ${d.text}`).join(`
|
|
281
|
+
`):o.cues.map(d=>d.text).join(`
|
|
282
|
+
`);if(e.output&&(await lR(e.output,i,"utf-8"),n==="human"&&k(`Transcript saved to: ${e.output}`)),n==="json"){l(o);return}if(n==="quiet"){console.log(i);return}console.log(),console.log(`Title: ${o.title}`),o.channelName&&console.log(`Channel: ${o.channelName}`),o.durationFormatted&&console.log(`Duration: ${o.durationFormatted}`),console.log(`Language: ${o.language??"unknown"}${o.isAutoGenerated?" (auto-generated)":""}`),console.log(`Words: ${o.wordCount.toLocaleString()}`),console.log(`URL: ${o.url}`),o.truncated&&L("Transcript was truncated to fit the response budget."),e.output||(console.log(),console.log("--- Transcript ---"),console.log(i))}catch(o){r?.stop(),a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as uR}from"crypto";import{mkdir as gR,writeFile as Op}from"fs/promises";import{dirname as fR}from"path";import{Command as Qr}from"commander";import Dp from"ora";var hR=new Qr("generate").description("Generate speech from text").requiredOption("-t, --text <text>","Text to convert to speech").requiredOption("-o, --output <path>","Output file path").option("--approval-receipt <receipt>","Browser-issued approval receipt").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--idempotency-key <key>","Stable recovery key").option("--options-json <json>","Canonical speech options JSON").option("--brand-id <id>","Apply this brand's pronunciation dictionary").option("--voice-id <voiceId>","Opaque Mindframes voice ID").option("-s, --speed <speed>","Speech speed 0.1-4.0 (default: 1.0)").option("-l, --lang <lang>","Language or locale hint (for example en-US)").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.idempotencyKey??uR(),n;try{n=_(t)}catch(c){a(m(c)),process.exit(s.INVALID_INPUT)}let r=t.format,o=r==="human"?Dp("Generating speech...").start():null,i;t.speed&&(i=parseFloat(t.speed),(Number.isNaN(i)||i<.1||i>4)&&(o?.stop(),a("Speed must be between 0.1 and 4.0"),process.exit(s.INVALID_INPUT)));let d;try{let c=t.optionsJson?yR("--options-json",t.optionsJson):{},u=await Rs({text:t.text,...t.brandId!==void 0?{brandId:t.brandId}:{},options:{...c,language:t.lang,voiceId:t.voiceId,speed:i}},{approvalReceipt:n,idempotencyKey:e});d=u.requestId,o?.stop();let f=t.output.endsWith(`.${u.format}`)?t.output:`${t.output}.${u.format}`;await gR(fR(f),{recursive:!0}),await Op(f,u.audioData);let v=f.replace(/\.[^.]+$/,".txt");if(await Op(v,t.text,"utf-8"),r==="json"){l({status:"completed",requestId:u.requestId,output:f,audioUrl:u.audioUrl,duration:u.duration,format:u.format,speed:u.speed??i??1,lang:u.language??t.lang??null,langApplied:u.langApplied??!1,timestamps:u.timestamps??null,words:u.wordTimings??null});return}if(r==="quiet"){console.log(f);return}k(`Saved to: ${f}`),w(`Duration: ${u.duration.toFixed(2)}s`)}catch(c){o?.stop(),a(`${te(c,d)} Retry with --idempotency-key ${e}.`,r),process.exit(s.GENERAL_ERROR)}});function yR(t,e){try{let n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))throw new Error;return n}catch{throw new Error(`${t} must be a JSON object`)}}var bR=new Qr("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json",y("--format",["human","json"]),"human").action(async t=>{let e=t.format==="human"?Dp("Fetching voices...").start():null;try{let n=await Ss(t.provider);if(e?.stop(),t.format==="json"){l(n.voices);return}if(Array.isArray(n.voices)){let r=t.provider?.toUpperCase()||"VOICES";console.log(),console.log(`${r} Voices:`),console.log("-".repeat(50));for(let o of n.voices)console.log(` ${o.name} (${o.id})`),console.log(` ${o.description}`)}else for(let[r,o]of Object.entries(n.voices))if(!(!o||o.length===0)){console.log(),console.log(`${r.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let i of o)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}}catch(n){e?.stop(),a(m(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),wR=new Qr("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json",y("--format",["json"]),"json").action(async(t,e)=>{try{l(await x("generateSpeech",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Np=new Qr("tts").description("Text-to-speech commands").addCommand(hR).addCommand(bR).addCommand(wR);import{execSync as to,spawnSync as BR}from"child_process";import{createHash as FR}from"crypto";import{access as ya,readFile as GR,rm as Wp}from"fs/promises";import{resolve as Gn}from"path";import ce from"chalk";import{Command as le}from"commander";import KR from"ffmpeg-static";import Jp from"ora";import{randomUUID as vR}from"crypto";import{Command as IR}from"commander";var ga=["private","team","public"],Lp=new IR("share").description("Set who may open a video's /v link \u2014 private, team, or public \u2014 and print the canonical share URL").argument("<video-id>","Video UUID").argument("<visibility>",`One of: ${ga.join(", ")}`).option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key so retries never apply the visibility change twice").option("--json","Print the complete structured response").action(async(t,e,n)=>{ga.includes(e)||(a(`Invalid visibility "${e}". Expected one of: ${ga.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("setVideoVisibility",{teamId:n.teamId,videoId:t,visibility:e},n.idempotencyKey??vR());if(n.json){l(r);return}r.shareUrl?k(`Video is now ${r.visibility}: ${r.shareUrl}`):k(`Video is now ${r.visibility} (no public link).`)}catch(r){a(m(r,"Visibility update failed")),process.exit(s.GENERAL_ERROR)}});import{Command as kR}from"commander";var Up=new kR("set").description("Set the poster of a finished video").argument("<video-id>","Finished video whose poster is being set").option("--at-seconds <seconds>","Moment of the video to cut the poster from").option("--image-url <url>","Existing https image to use as the poster").option("--upload-key <key>","Key of an image you uploaded").option("--team-id <id>","Workspace to act in").action(async(t,e)=>{[e.atSeconds,e.imageUrl,e.uploadKey].filter(o=>o!==void 0).length>1&&(a("Name at most one poster source: --at-seconds, --image-url or --upload-key. Name none to restore the automatic one."),process.exit(s.INVALID_INPUT));let r={videoId:t};if(e.atSeconds!==void 0){let o=Number(e.atSeconds);(!Number.isFinite(o)||o<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),r.atSeconds=o}e.imageUrl!==void 0&&(r.imageUrl=e.imageUrl),e.uploadKey!==void 0&&(r.uploadKey=e.uploadKey),e.teamId!==void 0&&(r.teamId=e.teamId);try{let o=await B(e.teamId),i=await p("setVideoThumbnail",r,Z({command:"video thumbnail set",payload:r,workspaceId:o}));l(i),k(`Poster set from ${i.source}.`)}catch(o){a(m(o,"Setting the poster failed")),process.exit(s.GENERAL_ERROR)}});import{mkdir as xR}from"fs/promises";import{join as RR}from"path";import{Command as wt}from"commander";import jp from"ora";var CR=5e3,SR=120,_p=5;function Vp(t,e){return[...e,t]}function ER(t,e){try{let n=new URL(t);if(n.protocol!=="https:"&&n.protocol!=="http:")throw new Error;return n.toString()}catch{throw new Error(`${e} must be a public HTTP(S) URL`)}}function Zr(t){if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t))throw new Error("Source video id must be a UUID");return t}function TR(t){if(t.mode&&!["speed","precision"].includes(t.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:ER(t.audioUrl,"Audio URL"),...t.mode?{mode:t.mode}:{},sourceVideoId:Zr(t.sourceVideoId)}}function AR(t){let e=[],n=new Set;for(let o of t.targetLanguage){let i=o.trim(),d=i.toLocaleLowerCase("en-US");!i||n.has(d)||(n.add(d),e.push(i))}if(e.length===0)throw new Error("Provide at least one target language");if(e.length>_p)throw new Error(`Provide at most ${_p} target languages`);if(e.find(o=>o.length<2||o.length>40))throw new Error("Target languages must be between 2 and 40 characters");return{...t.captions?{captions:!0}:{},sourceVideoId:Zr(t.sourceVideoId),targetLanguages:e}}function $R(t){if(t.aspect&&!["9:16","16:9","1:1"].includes(t.aspect))throw new Error("Clip aspect must be 9:16, 16:9, or 1:1");let e=t.duration.filter(r=>["30","60","180","long"].includes(r));if(e.length!==t.duration.length)throw new Error("Clip duration must be 30, 60, 180, or long");let n=t.maxClips?Number.parseInt(t.maxClips,10):void 0;if(n!==void 0&&(!Number.isInteger(n)||n<1||n>10))throw new Error("Max clips must be between 1 and 10");return{...t.aspect?{aspect:t.aspect}:{},...t.brandingId?{brandingId:Zr(t.brandingId)}:{},...t.captionStyle?{captionStyle:t.captionStyle}:{},...t.captions?{captions:!0}:{},...e.length?{durationTypes:e}:{},...t.inputLanguage?{inputLanguage:t.inputLanguage}:{},...n!==void 0?{maxClips:n}:{},...t.prompt?{prompt:t.prompt}:{},sourceVideoId:Zr(t.sourceVideoId),...t.title?{title:t.title}:{}}}function PR(t){return t.error||t.status==="failed"||t.status==="cancelled"?"failed":t.done||t.status==="completed"?"completed":t.status==="in_progress"||t.status==="processing"?"processing":"pending"}function eo(t){return{requestId:t.runId,status:PR(t),...t.entity?.url?{videoUrl:t.entity.url}:{},...t.output?{output:t.output}:{},...t.error?{error:re(t.error)}:{}}}function fa(t){return{requestId:t.runId,status:"pending"}}async function ha(t,e){return be(async()=>eo(await x(t,e)),SR,CR)}function Fe(t,e){if(e==="json"){l(t);return}if(e==="quiet"){console.log(t.videoUrl??t.requestId);return}w(`Request ID: ${t.requestId}`),w(`Status: ${t.status}`),t.videoUrl&&k(`Video URL: ${t.videoUrl}`),t.error&&a(`Error: ${t.error}`)}function OR(t){return Array.isArray(t?.languages)?t.languages.filter(e=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e;return typeof n.language=="string"&&(n.status==="completed"||n.status==="failed")&&typeof n.videoId=="string"&&(n.videoUrl===null||typeof n.videoUrl=="string")}):[]}function DR(t){return`${t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function NR(t,e){let n=DR(t);if(!e.has(n))return e.add(n),n;let r=n.slice(0,-4),o=2;for(;e.has(`${r}-${o}.mp4`);)o+=1;let i=`${r}-${o}.mp4`;return e.add(i),i}async function LR(t,e){let n=OR(t.output).filter(i=>i.status==="completed"&&!!i.videoUrl);if(n.length===0)throw new Error("Video translation completed without downloadable results");await xR(e,{recursive:!0});let r=[],o=new Set;for(let i of n){let d=RR(e,NR(i.language,o));await de(i.videoUrl,d),r.push({language:i.language,path:d})}return r}var UR=new wt("status").description("Check a video lip-sync request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(t,e){let r=R(this,e).format??"human";try{Fe(eo(await x("lipsyncVideo",t)),r)}catch(o){a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),qp=new wt("lipsync").description("Re-voice a ready workspace video with a public audio URL").requiredOption("--source-video-id <uuid>","Workspace GeneratedVideo UUID from a completed video status result (not a run, project, media-library id, or URL)").requiredOption("--audio-url <url>","Public replacement voice audio URL").option("--mode <mode>","Quality mode: speed or precision","speed").requiredOption("-o, --output <path>","Local output video path").requiredOption("--idempotency-key <key>","Stable retry key bound into the approval receipt").option("--approval-receipt <receipt>","Browser-issued approval receipt; omit on the first call to get the confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.format==="human"?jp("Starting video lip-sync...").start():null,n;try{let r=await Ns(TR(t),t.idempotencyKey,_(t));if(n=r.runId,!t.wait){e?.stop(),Fe(fa(r),t.format);return}e&&(e.text="Waiting for video lip-sync...");let o=await ha("lipsyncVideo",r.runId);if(o.status==="failed")throw new Error(o.error??"Video lip-sync failed");if(!o.videoUrl)throw new Error("Video lip-sync completed without a video URL");e&&(e.text="Downloading lip-synced video..."),await de(o.videoUrl,t.output),e?.stop(),Fe(o,t.format),t.format==="human"&&k(`Saved to: ${t.output}`)}catch(r){e?.stop(),a(te(r,n),t.format),process.exit(s.GENERAL_ERROR)}}).addCommand(jt(UR)),Mp=new wt("translate-languages").description("List supported video translation target languages").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{try{let e=await Us();if(t.format==="json")l({languages:e});else for(let n of e)console.log(n)}catch(e){a(m(e,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),_R=new wt("status").description("Check a video translation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(t,e){let r=R(this,e).format??"human";try{Fe(eo(await x("translateVideo",t)),r)}catch(o){a(m(o,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Bp=new wt("translate").description("Translate a ready workspace video into one or more languages").requiredOption("--source-video-id <uuid>","Workspace GeneratedVideo UUID from a completed video status result (not a run, project, media-library id, or URL)").option("--target-language <language>","Target language (repeatable)",Vp,[]).option("--captions","Burn provider-generated captions into translated videos").requiredOption("--output-dir <path>","Directory for translated videos").requiredOption("--idempotency-key <key>","Stable retry key bound into the approval receipt").option("--approval-receipt <receipt>","Browser-issued approval receipt; omit on the first call to get the confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.format==="human"?jp("Starting video translation...").start():null,n;try{let r=await _s(AR(t),t.idempotencyKey,_(t));if(n=r.runId,!t.wait){e?.stop(),Fe(fa(r),t.format);return}e&&(e.text="Waiting for video translations...");let o=await ha("translateVideo",r.runId);if(o.status==="failed")throw new Error(o.error??"Video translation failed");e&&(e.text="Downloading translated videos...");let i=await LR(o,t.outputDir);if(e?.stop(),t.format==="json")l({...o,downloads:i});else if(t.format==="quiet")for(let d of i)console.log(d.path);else{Fe(o,t.format);for(let d of i)k(`${d.language}: ${d.path}`)}}catch(r){e?.stop(),a(te(r,n),t.format),process.exit(s.GENERAL_ERROR)}}).addCommand(jt(_R)),jR=new wt("status").description("Check a video clipping request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"])).action(async function(t,e){let n=R(this,e);try{Fe(eo(await x("clipVideo",t)),n.format??"human")}catch(r){a(m(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Fp=new wt("clips").description("Turn a ready workspace video into short clips").requiredOption("--source-video-id <uuid>","Workspace GeneratedVideo UUID from a completed video status result (not a run, project, media-library id, or URL)").option("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--branding-id <uuid>","Workspace brand UUID").option("--caption-style <style>","Provider caption style").option("--captions","Burn provider-generated captions into clips").option("--duration <bucket>","Duration bucket: 30, 60, 180, or long",Vp,[]).option("--input-language <language>","Source language").option("--max-clips <count>","Maximum displayed clips (1-10)").option("--prompt <text>","Editorial clipping guidance").option("--title <text>","Provider job title").requiredOption("--idempotency-key <key>","Stable retry key bound into the approval receipt").option("--approval-receipt <receipt>","Browser-issued approval receipt; omit on the first call to get the confirmation URL").option("--approval-receipt-stdin","Read the browser-issued approval receipt from stdin").option("--no-wait","Do not wait for completion").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async t=>{let e;try{let n=await Ls($R(t),t.idempotencyKey,_(t));if(e=n.runId,!t.wait)return Fe(fa(n),t.format);let r=await ha("clipVideo",n.runId);if(r.status==="failed")throw new Error(r.error??"Video clipping failed");Fe(r,t.format)}catch(n){a(te(n,e),t.format),process.exit(s.GENERAL_ERROR)}}).addCommand(jt(jR));import{Command as VR}from"commander";function qR(t){return t===null?"\u2014":`${Math.round(t*100)}%`}function Gp(t){return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function MR(t){return t.viewer?t.viewer.name??t.viewer.email??t.viewer.id:"Anonymous"}var Kp=new VR("views").description("Who watched a shared video, and how far they got").argument("<video-id>","Video UUID").option("--team-id <id>","Workspace ID").option("--cursor <cursor>","Page cursor from a previous response").option("--json","Print the complete structured response").action(async(t,e)=>{try{let n=await p("getVideoViewAnalytics",{cursor:e.cursor,teamId:e.teamId,videoId:t});if(e.json){l(n);return}console.log(`${n.views} view${n.views===1?"":"s"} \xB7 ${n.completions} watched to the end \xB7 ${qR(n.averageCompletionRate)} average depth`),console.log(`${n.signedInViewers} signed-in viewer${n.signedInViewers===1?"":"s"} \xB7 ${Gp(n.averageWatchedSeconds)} average watch time`);for(let r of n.sessions)console.log(` ${r.completed?"\u2713":"\xB7"} ${MR(r)} \u2014 ${Gp(r.furthestSeconds)} reached, last seen ${r.lastViewedAt}`);n.nextCursor&&console.log(`More sittings \u2014 rerun with --cursor ${n.nextCursor}`)}catch(n){a(m(n,"View analytics read failed")),process.exit(s.GENERAL_ERROR)}});async function WR(){return process.stdin.isTTY?null:new Promise(t=>{let e="",n=!1;process.stdin.setEncoding("utf-8"),process.stdin.on("data",r=>{e+=r}),process.stdin.on("end",()=>{n||(n=!0,t(e.trim()?e:null))}),process.stdin.on("error",()=>{n||(n=!0,t(null))}),setTimeout(()=>{!n&&!e&&(n=!0,t(null))},500)})}function JR(t){let e=t?.trim().toLowerCase();if(!(!e||e==="any"||e==="all"))return e==="web"||e==="stock"?[e]:void 0}var zR=new le("find").description("Find video clips across the web and licensed stock").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("--source <source>","Catalog: web, stock, or any (default: any)","any").option("-f, --format <format>","Output format: human, json, quiet",y("--format",["human","json","quiet"]),"human").action(async(t,e)=>{let{maxResults:n,orientation:r,license:o,format:i}=e,d=i==="human"?Jp("Finding videos...").start():null;try{let c=await $s({query:t,options:{maxResults:parseInt(n,10),orientation:r,license:o,sources:JR(e.source)}});d?.stop();let u=c.data.results.flatMap(f=>f.results);if(i==="json"){l(c);return}if(i==="quiet"){u.forEach(f=>{console.log(f.embedUrl||f.previewUrl||f.thumbnailUrl)});return}if(u.length===0){w("No videos found");return}k(`Found ${u.length} videos for "${t}"`),console.log(),u.forEach((f,v)=>{let I=f.kind==="embed";console.log(`[${v+1}] ${f.title}`),console.log(` ${I?"Embed":"URL"}: ${f.embedUrl||f.previewUrl||f.thumbnailUrl}`),console.log(I?` Duration: ${f.duration}s | Embed only \u2014 plays in the host player, do not download`:` Duration: ${f.duration}s | Size: ${f.width}x${f.height}`),console.log(` Provider: ${f.provider}`),console.log()})}catch(c){d?.stop(),a(m(c,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),HR=new le("create").description("Generate one video from a pinned storyboard revision").requiredOption("--storyboard-revision <id>","Immutable storyboard revision UUID").option("--source-video <id>","Ready video from an earlier create call to use as base footage").option("--release","Render at 720p for release. Costs more; drafts are 480p by default").option("--team-id <id>","Workspace ID").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--yes","Approve paid video generation").action(async t=>{if(!t.yes)return a("Pass --yes to approve video generation");try{l(await js({quality:t.release?"release":void 0,sourceVideoId:t.sourceVideo,storyboardRevisionId:t.storyboardRevision,teamId:t.teamId},t.approvalReceipt,t.idempotencyKey))}catch(e){a(m(e,"Generation failed")),process.exit(s.GENERAL_ERROR)}});async function zp(t){let e=t==="-"?await WR():await GR(t,"utf-8");if(!e?.trim())throw new Error(t==="-"?"No storyboard Markdown was received on stdin":`Storyboard file is empty: ${t}`);return e}async function Hp(t,e={}){if(t)return t.length===1&&t[0]==="none"?[]:Promise.all(t.map(async n=>{let r;try{let S=JSON.parse(n);if(!S||typeof S!="object"||Array.isArray(S))throw new Error("Media binding must be a JSON object");r=S}catch(S){throw new Error(`Invalid --media binding. Pass one JSON object per binding, for example '{"handle":"actress-photo","path":"./actress.jpg","purpose":"identity"}'.`,{cause:S})}let o=Ne(r.handle),i=Ne(r.path),d=Ne(r.fileUrl)??Ne(r.url),c=Ne(r.purpose),u=Ne(r.videoRole),f=Ne(r.analysisId)??Ne(r.analysis);if(!o||!i&&!d||!c)throw new Error("Invalid --media binding. handle, purpose, and either path or url are required strings.");if(i&&d)throw new Error("A media binding cannot contain both path and url.");if(i&&c==="source"&&f)throw new Error("A source analysis is bound to the original uploaded URL. Reuse the url/name/mime/size binding printed by 'video reference analyze' instead of uploading path again.");if(i&&!e.uploadIdempotencyKey)throw new Error("Local storyboard media requires the command idempotency key.");let v=i?await ee(Gn(i),{idempotencyKey:`${e.uploadIdempotencyKey}:media:${o}`}):{name:Ne(r.name),size:Number(r.size),type:Ne(r.mime),url:d};if(!v.name||!v.type||!v.url||!Number.isSafeInteger(v.size)||v.size<=0)throw new Error(`URL media binding "${n}" requires name, mime, and positive integer size.`);let I=v.type.startsWith("video/")?"video":v.type.startsWith("audio/")?"audio":v.type.startsWith("image/")?"image":null;if(!I)throw new Error(`Unsupported media type for ${i??d}: ${v.type}`);if(!["source","style","identity","required"].includes(c))throw new Error(`Invalid media purpose: ${c}`);if(u&&!["reference","first-frame","last-frame"].includes(u))throw new Error(`Invalid videoRole: ${u}`);if(u&&I!=="image")throw new Error("videoRole is supported only for image bindings.");return{...f?{analysisId:f}:{},fileUrl:v.url,handle:o,kind:I,mime:v.type,name:v.name,purpose:c,size:v.size,...u?{videoRole:u}:{}}}))}function Ne(t){return typeof t=="string"&&t.length>0?t:void 0}var XR=new le("create").description("Create a versioned Markdown video storyboard").requiredOption("--file <path>","Markdown file path, or - for stdin").requiredOption("--duration <seconds>","Exact total duration in seconds").requiredOption("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--title <text>","Artifact label").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact create").option("--media <binding...>",'One JSON binding per asset: {"handle":"actress-photo","path":"./actress.jpg","purpose":"identity"}').option("--team-id <id>","Workspace ID").action(async t=>{try{l(await p("createVideoStoryboard",{aspectRatio:t.aspect,durationSec:Number(t.duration),mediaBindings:await Hp(t.media,{uploadIdempotencyKey:t.idempotencyKey}),storyboardMarkdown:await zp(t.file),teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(e){a(m(e,"Storyboard creation failed")),process.exit(s.GENERAL_ERROR)}}),YR=new le("revise").description("Append an immutable revision to a video storyboard").argument("<storyboard-id>","Storyboard UUID").requiredOption("--base-revision <id>","Revision UUID that was edited").requiredOption("--file <path>","Complete Markdown file path, or - for stdin").requiredOption("--duration <seconds>","Exact total duration in seconds").requiredOption("--aspect <ratio>","Output aspect: 9:16, 16:9, or 1:1").option("--title <text>","Replacement artifact label").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact revision").option("--change-summary <text>","Short description of this revision").option("--media <binding...>",'Replace media bindings with one JSON object per asset; use the JSON printed by "video reference analyze" for analyzed source video').option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("reviseVideoStoryboard",{aspectRatio:e.aspect,baseRevisionId:e.baseRevision,changeSummary:e.changeSummary,durationSec:Number(e.duration),mediaBindings:await Hp(e.media,{uploadIdempotencyKey:e.idempotencyKey}),storyboardId:t,storyboardMarkdown:await zp(e.file),teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(n){a(m(n,"Storyboard revision failed")),process.exit(s.GENERAL_ERROR)}}),QR=new le("show").description("Read a storyboard; print Markdown unless --json is used").argument("<storyboard-id>","Storyboard UUID").option("--revision <id>","Read one immutable revision UUID").option("--team-id <id>","Workspace ID").option("--json","Print the complete structured response").action(async(t,e)=>{try{let n=await p("readVideoStoryboard",{revisionId:e.revision,storyboardId:t,teamId:e.teamId});if(e.json){l(n);return}console.error(`${n.storyboard.title} \xB7 revision ${n.storyboard.revision.versionNumber} (${n.storyboard.revision.id})`),console.log(n.storyboard.revision.storyboardMarkdown)}catch(n){a(m(n,"Storyboard read failed")),process.exit(s.GENERAL_ERROR)}}),ZR=new le("storyboard").description("Create, revise, and read Markdown video storyboards").addCommand(XR).addCommand(YR).addCommand(QR),Xp=new le("analyze").description("Upload and analyze a reference video; its analysisId is the only analysis video generation consumes").requiredOption("--file <path>","Local reference video").requiredOption("--idempotency-key <key>","Stable key to reuse when retrying this exact analysis").option("--user-request <text>","What the analysis should focus on").option("--team-id <id>","Workspace ID").option("--no-wait","Return the durable run immediately").option("--json","Print the complete structured result").action(async t=>{try{let e=await ee(Gn(t.file),{idempotencyKey:`video-reference-analysis:${t.idempotencyKey}:source`});if(!e.type.startsWith("video/"))throw new Error(`Reference analysis requires a video, got ${e.type}`);let n=await Vs({idempotencyKey:t.idempotencyKey,sourceUrl:e.url,teamId:t.teamId,userRequest:t.userRequest}),r={analysisId:n.runId,fileUrl:e.url,handle:"source-video",kind:"video",mime:e.type,name:e.name,purpose:"source",size:e.size};if(t.wait===!1){l({...n,binding:r,source:e});return}let o=await qs(n.runId,t.teamId);if(t.json){l({...o,binding:r,source:e});return}let i=o.output?.analysis??{};console.log(typeof i.promptContext=="string"?i.promptContext:JSON.stringify(o.output,null,2)),console.error(`Analysis run: ${n.runId}`),console.error(`Storyboard media JSON: ${JSON.stringify(r)}`)}catch(e){a(m(e,"Reference analysis failed")),process.exit(s.GENERAL_ERROR)}});Xp.addHelpText("after",`
|
|
283
|
+
${ce.gray("# Prints an analysisId plus a ready storyboard media binding. Pass that")}
|
|
284
|
+
${ce.gray("# binding to video storyboard create/revise --media; generation reads the")}
|
|
285
|
+
${ce.gray("# analysis from the analysisId, never from local files.")}
|
|
286
|
+
`);var eC=new le("status").description("Read a video-reference analysis run").argument("<run-id>","Analysis run UUID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{let n=await x("analyzeVideoReference",t,e.teamId);l(n);let r=un(n);if(r)throw new Error(r)}catch(n){a(m(n,"Status read failed")),process.exit(s.GENERAL_ERROR)}}),tC=new le("reference").description("Upload and inspect reusable video references").addCommand(Xp).addCommand(eC),nC=new le("cancel").description("Cancel one in-flight video run (the cancelRunId `work list` reports)").argument("<run-id>","Durable run ID of the in-flight video work").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key; deterministically derived from the run ID when omitted").action(async function(t,e){try{l(await p("cancelVideoRun",{runId:t,teamId:e.teamId},e.idempotencyKey??`video-cancel:${FR("sha256").update(t).digest("hex")}`))}catch(n){a(m(n,"Video cancellation failed")),process.exit(s.GENERAL_ERROR)}}),rC=new le("status").description("Read video background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{let n=await x("createVideo",t,e.teamId);l(n);let r=un(n);if(r)throw new Error(r)}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),oC=new le("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",y("--format",["human","json","quiet"]),"human").action(async t=>{let e=t.format,n=e==="human"?Jp("Injecting thumbnail...").start():null;try{let r=Gn(t.video),o=Gn(t.thumbnail),i=t.output?Gn(t.output):r.replace(/\.mp4$/,"-with-thumb.mp4");await ya(r),await ya(o);let d=KR;if(d)try{await ya(d)}catch{d=null}if(!d)try{d=to("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let c=BR(d,["-i",r],{encoding:"utf8"});if(c.error)throw new Error(`Failed to probe video: ${c.error.message}`);let u=(c.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!u)throw new Error("Could not detect video dimensions");let[,f,v]=u;n&&(n.text="Creating thumbnail frame...");let I="/tmp/cc-thumb-frame.mp4";to(`${d} -y -loop 1 -i "${o}" -vf "scale=${f}:${v}:force_original_aspect_ratio=decrease,pad=${f}:${v}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${I}"`,{stdio:"pipe"}),n&&(n.text="Concatenating with video...");let S="/tmp/cc-concat-video.mp4";if(to(`${d} -y -i "${I}" -i "${r}" -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 "${S}"`,{stdio:"pipe"}),n&&(n.text="Adding file icon thumbnail..."),to(`${d} -y -i "${S}" -i "${o}" -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic "${i}"`,{stdio:"pipe"}),await Wp(I,{force:!0}),await Wp(S,{force:!0}),n?.stop(),e==="json"){l({success:!0,output:i});return}if(e==="quiet"){console.log(i);return}k(`Thumbnail injected: ${i}`)}catch(r){n?.stop(),a(m(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),iC=new le("thumbnail").description("Thumbnail operations").addCommand(oC).addCommand(Up),no=new le("video").description("Build a video from scratch \u2014 brief or storyboard to stock and generated footage, translation, lipsync, analysis (for a finished deck, use presentation video)").addCommand(zR).addCommand(iC).addCommand(Fp).addCommand(qp).addCommand(Mp).addCommand(Bp).addCommand(ep).addCommand(Lp).addCommand(Kp);no.addCommand(HR).addCommand(ZR).addCommand(tC).addCommand(nC).addCommand(rC);no.addHelpText("after",`
|
|
287
|
+
${ce.bold("Examples:")}
|
|
288
|
+
${ce.gray("# Storyboard-first video from a brief")}
|
|
289
|
+
$ ${g.commands[0]} video storyboard create --file brief.md --duration 15 --aspect 16:9 --idempotency-key launch-1
|
|
290
|
+
|
|
291
|
+
${ce.gray("# Find licensed stock footage")}
|
|
292
|
+
$ ${g.commands[0]} video find "city timelapse"
|
|
293
|
+
|
|
294
|
+
${ce.bold("Before generating:")}
|
|
295
|
+
${ce.gray("# Approve the content, then approve the spend \u2014 two questions. Paste the")}
|
|
296
|
+
${ce.gray("# storyboard text into your reply and get a yes on it BEFORE pinning a")}
|
|
297
|
+
${ce.gray("# revision; revising is free and append-only, a pinned revision is not.")}
|
|
298
|
+
${ce.gray("# The browser confirmation video create requires is about cost and")}
|
|
299
|
+
${ce.gray("# destination, not the user reading the script. --yes is neither.")}
|
|
300
|
+
$ ${g.commands[0]} video storyboard show <storyboard-id>
|
|
301
|
+
$ ${g.commands[0]} video storyboard revise <storyboard-id> --base-revision <revision-id> --file brief-v2.md --idempotency-key launch-2
|
|
302
|
+
|
|
303
|
+
${ce.bold("See also:")}
|
|
304
|
+
${ce.gray("# Already have a deck? Render it to MP4 (narration, avatar, captions)")}
|
|
305
|
+
$ ${g.commands[0]} presentation video <slug>
|
|
306
|
+
`);import{Command as ba}from"commander";var aC=new ba("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, best, or enterprise","best").option("--preset <preset>","Output preset","executive-one-pager").option("--output <type>","raster or vector","raster").option("--branding-id <id>","Branding ID").option("--brand-name <name>","Brand name rendered on the artifact").option("--context <text>","Additional generation context").option("--custom-instructions <text>","Custom rendering instructions").option("--reference-url <url...>","Up to three image URLs to use as visual references").option("--team-id <id>","Workspace ID").requiredOption("--idempotency-key <key>","Stable invocation key bound into the approval receipt").option("--approval-receipt <receipt>","Receipt returned by the browser confirmation URL; omit on the first call to get that URL").option("--approval-receipt-stdin","Read the approval receipt from stdin instead of argv").option("--yes","Confirm generation using workspace credits").action(async(t,e)=>{e.yes||(a("Pass --yes to confirm visual-abstract generation"),process.exit(s.INVALID_INPUT));try{let n=Array.isArray(e.referenceUrl)?e.referenceUrl.map((r,o)=>({label:`visual-reference-${o+1}`,url:r})):void 0;l(await p("createVisualAbstract",{approvalReceipt:_(e),aspectRatio:e.aspect,brandingId:e.brandingId,brandName:e.brandName,brief:t,context:e.context,customInstructions:e.customInstructions,outputPreset:e.preset,outputType:e.output,qualityTier:e.quality,referenceImages:n,teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(n){a(m(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),sC=new ba("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("createVisualAbstract",t,e.teamId))}catch(n){a(m(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Yp=new ba("visual-abstract").description("Generate a one-page visual abstract graphic (raster or vector) from a dense brief").addCommand(aC).addCommand(sC);import he from"chalk";import{Command as me}from"commander";import{Command as dC}from"commander";var Qp=new dC("tone").description("Set how a voice you made reads by default, or clear it").argument("<voice-id>","A voice this workspace made, from voice list").option("--preset <preset>","professional (steady), conversational (natural) or energetic (lively)",y("--preset",["professional","conversational","energetic"])).option("--stability <0-1>","Higher reads more evenly; lower widens the emotional range",H("--stability",0,1)).option("--expressiveness <0-1>","How much the read exaggerates emphasis; 0 is neutral",H("--expressiveness",0,1)).option("--speed <0.7-1.2>","Speaking pace; 1 is normal",H("--speed",.7,1.2)).option("--clear","Remove the saved tone").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await rd({...e.clear?{clear:!0}:{},...e.expressiveness===void 0?{}:{expressiveness:e.expressiveness},...e.preset?{preset:e.preset}:{},...e.speed===void 0?{}:{speed:e.speed},...e.stability===void 0?{}:{stability:e.stability},voiceId:t});if(e.format==="json"){l(n);return}if(!n.voice.tone){k(`${n.voice.name} reads with its natural delivery again.`);return}k(`${n.voice.name} now reads ${cC(n.voice.tone)}.`),w("Videos already narrated keep their audio until their next render re-voices them.")}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}});function cC(t){let e=[t.stability===void 0?null:`stability ${t.stability}`,t.expressiveness===void 0?null:`expressiveness ${t.expressiveness}`,t.speed===void 0?null:`speed ${t.speed}`].filter(Boolean),n=t.preset?`in a ${t.preset} tone`:"in a custom tone";return e.length>0?`${n} (${e.join(", ")})`:n}var Zp=["male","female"],eu=["young","middle_aged","old"];function wa(t){let e=[t.gender,t.age,t.accent,t.useCase].filter(Boolean).join(" \xB7 "),n=t.description?he.gray(` \u2014 ${t.description}`):"",r=t.ready?"":he.yellow(" (not ready)"),o=t.sharedBy?.name?.trim()||t.sharedBy?.email?.trim(),i=o?he.gray(` shared by ${o}`):"";return`${he.bold(t.name)}${r} ${he.gray(t.id)}${i}
|
|
307
|
+
${e||he.gray("no stated labels")}${n}`}var lC=new me("list").description("The voices this workspace can narrate with").option("--gender <gender>","male or female",y("--gender",Zp)).option("--age <age>","young, middle_aged or old",y("--age",eu)).option("--accent <accent>",'Stated accent, e.g. "american"').option("--use-case <useCase>",'Stated use case, e.g. "conversational"').option("--query <text>","Match the name or the character note").option("--language <language>",'Language code, e.g. "en" or "hi"').option("--page <n>","Which page of the shared library to read").option("--page-size <n>","How many library voices per page (max 100)").option("--format <format>","text or json","text").action(async t=>{try{let e=await Xs({...t.accent?{accent:t.accent}:{},...t.age?{age:t.age}:{},...t.gender?{gender:t.gender}:{},...t.language?{language:t.language}:{},...t.page?{page:Number(t.page)}:{},...t.pageSize?{pageSize:Number(t.pageSize)}:{},...t.query?{query:t.query}:{},...t.useCase?{useCase:t.useCase}:{}});if(t.format==="json"){l(e);return}if(e.catalogUnavailable&&w("Built-in voices are temporarily unavailable; showing yours only."),e.voices.length===0){w("No voices match those filters.");return}for(let n of e.voices)console.log(wa(n));if(e.library.length>0){w(e.curated?`From the shared library \u2014 ${e.totalMatching} more behind these:`:`From the shared library \u2014 ${e.totalMatching} match:`);for(let n of e.library)console.log(wa(n));w(`Add one with ${g.commands[0]} voice add <voice-id>`)}e.libraryUnavailable&&w("The shared library could not be searched; showing yours only."),e.canDesignVoice&&w(`Nothing fits? ${g.commands[0]} voice design "<description>"`)}catch(e){a(m(e)),process.exit(s.GENERAL_ERROR)}}),mC=new me("design").description("Generate candidate voices from a written description").argument("<description>","The voice in words").option("--text <text>","What the candidates should say (100-1000 chars)").option("--include-audio","Return the candidate audio inline; large, so off by default").option("--remix-of <candidateId>","Vary a candidate from an earlier round").option("--round-id <id>","Your own id, so retrying it is not charged twice").option("--seed <n>","Make the round reproducible").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await sd({description:t,...e.includeAudio?{includeAudio:!0}:{},...e.remixOf?{remixOf:e.remixOf}:{},...e.roundId?{roundId:e.roundId}:{},...e.seed?{seed:Number(e.seed)}:{},...e.text?{text:e.text}:{}});if(e.format==="json"){l(n);return}k(`${n.candidates.length} candidates \xB7 ${n.creditsCharged} credits`);for(let r of n.candidates){let o=r.durationSeconds?` (${r.durationSeconds.toFixed(1)}s)`:"";console.log(` ${he.gray(r.id)}${o}`)}w(e.includeAudio?"Audio is in --format json. Keep one with:":"Add --include-audio --format json to hear them. Keep one with:"),w(` ${g.commands[0]} voice save <candidate-id> --name "<name>" --description "${t.slice(0,40)}\u2026"`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),pC=new me("save").description("Keep a candidate as a reusable workspace voice").argument("<candidate-id>","A candidate handle from voice design").requiredOption("--name <name>","What the workspace will call it").requiredOption("--description <text>","The description that produced it").option("--gender <gender>","male or female",y("--gender",Zp)).option("--age <age>","young, middle_aged or old",y("--age",eu)).option("--accent <accent>",'e.g. "american"').option("--use-case <useCase>",'e.g. "conversational"').option("--passed-over <ids>","Comma-separated candidates you auditioned and did not keep").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n={...e.accent?{accent:e.accent}:{},...e.age?{age:e.age}:{},...e.gender?{gender:e.gender}:{},...e.useCase?{useCase:e.useCase}:{}},r=await dd({candidateId:t,description:e.description,...n,name:e.name,...e.passedOver?{passedOver:e.passedOver.split(",").map(o=>o.trim()).filter(Boolean)}:{}});if(e.format==="json"){l(r);return}k(`Saved ${r.voice.name}`),console.log(wa(r.voice)),Object.keys(n).length||w("No labels given, so this voice matches no gender/age/accent filter.")}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),uC=new me("remove").description("Remove one of your own voices and release the slot it holds").argument("<voice-id>","A workspace voice id from voice list").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await cd({voiceId:t});if(e.format==="json"){l(n);return}k("Voice removed."),n.heldProviderSlot&&!n.providerSlotReleased&&w("The voice slot was not released and is still held.")}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),gC=new me("add").description("Add a voice from the shared library to this workspace").argument("<voice-id>","A library voice handle from voice list").option("--name <name>","What this workspace will call it").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await Ys({...e.name?{name:e.name}:{},voiceId:t});if(e.format==="json"){l(n);return}k(`${n.voice.name} is now one of your voices.`),w(` ${he.gray(n.voice.id)}`),w(`Use it with ${g.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),fC=new me("star").description("Keep a voice at the top of your list, or remove the star").argument("<voice-id>","A workspace voice id, or a library handle").option("--favorite <favorite>","true to star, false to unstar",y("--favorite",["true","false"]),"true").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=e.favorite==="true",r=await Qs({favorite:n,voiceId:t});if(e.format==="json"){l(r);return}k(n?`${r.voice.name} is starred.`:`${r.voice.name} is no longer starred.`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),hC=new me("share").description("Share a voice you made with the workspace, or keep it private").argument("<voice-id>","A voice this workspace made, from voice list").option("--visibility <visibility>","team to share it, private to keep it to yourself",y("--visibility",["team","private"]),"team").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await od({visibility:e.visibility,voiceId:t});if(e.format==="json"){l(n);return}k(e.visibility==="team"?`${n.voice.name} is shared with the workspace.`:`${n.voice.name} is private to you again.`),e.visibility==="team"&&w("Sharing does not approve it. Where a workspace restricts which voices its material may use, a team admin still has to approve this one.")}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),yC=new me("policy").description("Whether approved voices are the only ones material may use").argument("<mode>","open, or enforced",y("<mode>",["open","enforced"])).option("--brand <brand-id>","Scope the rule to one brand").option("--format <format>","text or json","text").option("--yes","Required to turn enforcement on").action(async(t,e)=>{try{if(t==="enforced"&&!e.yes){a("Enforcing restricts every member of this workspace to the approved voices. Re-run with --yes to confirm."),process.exit(s.GENERAL_ERROR);return}let n=await Zs({...e.brand?{brandId:e.brand}:{},mode:t});if(e.format==="json"){l(n);return}let r=e.brand?"this brand":"this workspace";k(t==="enforced"?`Only approved voices may be used in ${r}'s material.`:`Any voice may be used in ${r}'s material.`),t==="enforced"&&w(`Videos that already exist are unaffected. Approve voices with ${g.commands[0]} voice approve <voice-id>`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),bC=new me("approve").description("Admit a voice for this workspace's material, or withdraw it").argument("<voice-id>","A workspace voice id, from voice list").option("--approved <approved>","true to admit it, false to withdraw it",y("--approved",["true","false"]),"true").option("--brand <brand-id>","Scope the approval to one brand").option("--note <note>","Why it was admitted, kept with who admitted it").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=e.approved==="true",r=await id({approved:n,...e.brand?{brandId:e.brand}:{},...e.note?{note:e.note}:{},voiceId:t});if(e.format==="json"){l(r);return}let o=r.voice?.name??t;k(n?`${o} is approved for this workspace's material.`:`${o} is no longer approved.`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),wC=new me("approvals").description("Which voices are approved, and whether that is binding").option("--brand <brand-id>","Read one brand's rule").option("--format <format>","text or json","text").action(async t=>{try{let e=await ad(t.brand?{brandId:t.brand}:{});if(t.format==="json"){l(e);return}w(e.enforced?"Only the voices below may be used.":"Any voice may be used. The voices below are approved, which is a recommendation until enforcement is on."),e.catalogUnavailable&&w("Voice names could not be read just now, so some rows below say the voice no longer exists when it may simply be unreachable.");for(let n of e.policies.filter(r=>r.mode==="enforced"))w(n.brandId?`Enforced for brand ${n.brandId}`:"Enforced for the whole team");if(e.voices.length===0){w("No voices are approved yet.");return}for(let n of e.voices){let r=n.voice?.name??"(voice no longer exists)",o=n.brandId?" [brand]":"",i=n.note?` \u2014 ${n.note}`:"";w(`${r}${o} ${n.voiceId}${i}`)}}catch(e){a(m(e)),process.exit(s.GENERAL_ERROR)}}),vC=new me("request").description("Ask a team admin to admit a voice for this workspace").argument("<voice-id>","A voice this workspace can use, from voice list").option("--brand <brand-id>","Ask for one brand rather than the team").option("--note <note>","Why it is worth admitting, for whoever decides").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await ed({...e.brand?{brandId:e.brand}:{},...e.note?{note:e.note}:{},voiceId:t});if(e.format==="json"){l(n);return}k(n.created?`A team admin has been asked to admit ${n.voice.name}.`:`${n.voice.name} is already waiting on a decision.`)}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),IC=new me("requests").description("Voices people have asked to have admitted").option("--mine","Only your own requests").option("--state <state>","pending, approved, declined or withdrawn",y("--state",["pending","approved","declined","withdrawn"])).option("--format <format>","text or json","text").action(async t=>{try{let e=await td({...t.mine?{mine:!0}:{},...t.state?{state:t.state}:{}});if(t.format==="json"){l(e);return}if(e.requests.length===0){w("Nothing is waiting on a decision.");return}for(let n of e.requests){let r=n.requestedByViewer?"you":"a teammate",o=n.note?` \u2014 ${n.note}`:"";w(`${n.id} ${n.state.padEnd(9)} ${n.voiceId} (asked by ${r})${o}`)}e.canDecide&&w(`Settle one with ${g.commands[0]} voice decide <request-id> --state approved`)}catch(e){a(m(e)),process.exit(s.GENERAL_ERROR)}}),kC=new me("decide").description("Approve, decline, or withdraw a request to admit a voice").argument("<request-id>","From voice requests").requiredOption("--state <state>","approved, declined, or withdrawn to take back your own",y("--state",["approved","declined","withdrawn"])).option("--approve-voice <approve>","true to admit the voice as well; ignored unless approving",y("--approve-voice",["true","false"]),"true").option("--format <format>","text or json","text").action(async(t,e)=>{try{let n=await nd({approveVoice:e.approveVoice==="true",requestId:t,state:e.state});if(e.format==="json"){l(n);return}k(`That request is ${n.request.state}.`),n.admittedVoice&&w("The voice is now approved for this workspace's material.")}catch(n){a(m(n)),process.exit(s.GENERAL_ERROR)}}),va=new me("voice").description("The voices your narration can use").addCommand(lC).addCommand(mC).addCommand(pC).addCommand(gC).addCommand(fC).addCommand(hC).addCommand(Qp).addCommand(yC).addCommand(bC).addCommand(wC).addCommand(vC).addCommand(IC).addCommand(kC).addCommand(uC);va.addHelpText("after",`
|
|
308
|
+
${he.bold("Examples:")}
|
|
309
|
+
${he.gray("# The request a fixed catalog cannot answer")}
|
|
310
|
+
$ ${g.commands[0]} voice list --gender male --age middle_aged --accent american --use-case conversational
|
|
311
|
+
|
|
312
|
+
${he.gray("# Or describe one that does not exist yet, then keep it")}
|
|
313
|
+
$ ${g.commands[0]} voice design "Native American English. Male, early thirties. Calm, confident, conversational; medium-low pitch, moderate pace."
|
|
314
|
+
$ ${g.commands[0]} voice save <candidate-id> --name "Floor lead" --description "\u2026" --gender male --age middle_aged
|
|
315
|
+
|
|
316
|
+
${he.bold("See also:")}
|
|
317
|
+
${he.gray("# Narrate a presentation video with the voice you chose")}
|
|
318
|
+
$ ${g.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes
|
|
319
|
+
`);import{randomUUID as Ia}from"crypto";import{Command as vt}from"commander";function tu(t,e){try{let n=JSON.parse(e);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{a(`${t} must be a JSON object, e.g. --${t} '{"mode":"stock"}'`),process.exit(s.GENERAL_ERROR)}}async function nu(t,e,n){if(n.wait===!1){l(e);return}w(`Run ${e.runId} accepted (${e.status}). Waiting\u2026`);let r=await Y(t,e.runId,n.teamId,n.maxAttempts);l(r)}var xC=new vt("upload-url").description("Mint a presigned POST for a walkthrough source recording (up to 1 GiB)").requiredOption("--file-name <name>","Name of the recording file").requiredOption("--file-size <bytes>","Exact file size in bytes",Number).requiredOption("--file-type <type>","MIME type: video/mp4, video/webm or video/quicktime").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ia()).action(async t=>{try{l(await p("createWalkthroughUploadUrl",{fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType,teamId:t.teamId},t.idempotencyKey))}catch(e){a(m(e,"Upload URL failed")),process.exit(s.GENERAL_ERROR)}}),RC=new vt("create").description("Turn a hosted recording into a narrated walkthrough").argument("<source-video-url>","Hosted recording URL (see `mf walkthrough upload-url`)").requiredOption("--yes","Confirm the narration-plan charge (billed)").option("--title <title>","Walkthrough title").option("--source-media-type <type>","video/mp4 or video/webm").option("--source-duration <seconds>","Source duration in seconds",Number).option("--source-width <px>","Source width in pixels",Number).option("--source-height <px>","Source height in pixels",Number).option("--source-audio-volume <0..1>","Original audio mix level",Number).option("--source-chat-id <id>","Chat this walkthrough belongs to").option("--audience <text>","Intended audience").option("--tone <text>","Narration tone").option("--target-length <text>","Desired walkthrough length").option("--cost-mode <mode>","quick or premium").option("--no-captions","Render without captions").option("--voice-id <id>","Narration voice catalog ID").option("--music-config <json>","Music configuration as a JSON object").option("--presenter-config <json>","Presenter configuration as a JSON object").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ia()).option("--no-wait","Return the run ID instead of waiting for narration").action(async(t,e)=>{try{let n=await p("createWalkthrough",{audience:e.audience,captions:e.captions,costMode:e.costMode,musicConfig:e.musicConfig?tu("music-config",e.musicConfig):void 0,presenterConfig:e.presenterConfig?tu("presenter-config",e.presenterConfig):void 0,sourceAudioVolume:e.sourceAudioVolume,sourceChatId:e.sourceChatId,sourceDurationSec:e.sourceDuration,sourceHeight:e.sourceHeight,sourceMediaType:e.sourceMediaType,sourceVideoUrl:t,sourceWidth:e.sourceWidth,targetLength:e.targetLength,teamId:e.teamId,title:e.title,tone:e.tone,voiceId:e.voiceId},e.idempotencyKey);await nu("createWalkthrough",n,{...e,maxAttempts:180})}catch(n){a(m(n,"Creation failed")),process.exit(s.GENERAL_ERROR)}}),CC=new vt("render").description("Render a walkthrough draft to a finished MP4").argument("<walkthrough-id>","Walkthrough ID").requiredOption("--yes","Confirm the render charge (billed per tier)").option("--cost-mode <mode>","quick or premium").option("--source-audio-volume <0..1>","Original audio mix level",Number).option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ia()).option("--no-wait","Return the run ID instead of waiting for the render").action(async(t,e)=>{try{let n=await p("renderWalkthrough",{costMode:e.costMode,sourceAudioVolume:e.sourceAudioVolume,teamId:e.teamId,walkthroughId:t},e.idempotencyKey);await nu("renderWalkthrough",n,{...e,maxAttempts:300})}catch(n){a(m(n,"Render failed")),process.exit(s.GENERAL_ERROR)}}),SC=new vt("status").description("Check a create or render run").argument("<run-id>","Run ID returned by `walkthrough create` or `walkthrough render`").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await x("createWalkthrough",t,e.teamId));return}catch(n){n instanceof C&&n.statusCode===404||(a(m(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR))}try{l(await x("renderWalkthrough",t,e.teamId))}catch(n){a(m(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR)}}),EC=new vt("get").description("Read one walkthrough").argument("<walkthrough-id>","Walkthrough ID").option("--team-id <id>","Workspace ID").action(async(t,e)=>{try{l(await p("getWalkthrough",{teamId:e.teamId,walkthroughId:t}))}catch(n){a(m(n,"Lookup failed")),process.exit(s.GENERAL_ERROR)}}),TC=new vt("list").description("List walkthroughs in the workspace").option("--limit <count>","Maximum rows to return",Number).option("--team-id <id>","Workspace ID").action(async t=>{try{l(await p("listWalkthroughs",{limit:t.limit,teamId:t.teamId}))}catch(e){a(m(e,"List failed")),process.exit(s.GENERAL_ERROR)}}),ru=new vt("walkthrough").description("Recorded walkthroughs: narrated videos from screen captures").addCommand(xC).addCommand(RC).addCommand(CC).addCommand(SC).addCommand(EC).addCommand(TC);import{Command as du,InvalidArgumentError as cu}from"commander";var ou=["article","cheat-sheet","flashcards","microsite","presentation","quiz","survey","video"],iu=["cancelled","draft","failed","in-progress","published","ready","setup"],au=["mine","workspace"];function AC(t,e){return n=>{if(!e.includes(n))throw new cu(`${t} expects one of: ${e.join(", ")}.`);return n}}function su(t,e){return n=>{let r=n.split(",").map(i=>i.trim()).filter(Boolean);if(r.find(i=>!e.includes(i))||r.length===0)throw new cu(`${t} expects comma-separated values from: ${e.join(", ")}.`);return r}}function $C(t,e){a(m(t,e)),process.exit(s.GENERAL_ERROR)}var PC=new du("list").description("List the workspace's in-flight, draft, failed, and finished work \u2014 continuation-first").option("--kinds <kinds>",`Filter to artifact kinds: ${ou.join(", ")}`,su("--kinds",ou)).option("--lifecycle <states>",`Filter to lifecycle states: ${iu.join(", ")}`,su("--lifecycle",iu)).option("--limit <n>","Maximum items to return (default 20, max 50)").option("--scope <scope>",`Whose work to list: ${au.join(", ")}`,AC("--scope",au)).option("--offset <n>","Zero-based result offset").option("--team-id <id>","Workspace ID").action(async t=>{try{l(await p("listWorkItems",{kinds:t.kinds,lifecycle:t.lifecycle,limit:t.limit?Number(t.limit):void 0,offset:t.offset?Number(t.offset):void 0,scope:t.scope,teamId:t.teamId}))}catch(e){$C(e,"Could not list work items")}}),lu=new du("work").description("Inspect the workspace's recent and in-flight work").addCommand(PC);var ka=[Vl,Zl,fc,Nl,Np,vm,dm,tm,no,sa,Pp,Rp,aa,ca,Ri,nm,Li,Rm,pc,uc,Yp,sm,ic,Qo,am,xi,va,Kl,Fl,zl,Hl,$i,ql,Ap,$p,ru,lu];function mu(t){for(let e of ka)t.addCommand(e)}function pu(t,e,n){let r=e?`${e} ${t.name()}`:t.name();n.set(r,{arguments:t.registeredArguments.filter(o=>o.required).map(o=>`<${o.name()}>`),requiredOptions:t.options.filter(o=>o.mandatory).map(o=>o.long).filter(o=>!!o)});for(let o of t.commands)pu(o,r,n)}var ro;function OC(){if(!ro){ro=new Map;for(let t of ka)pu(t,"",ro)}return ro}function uu(t){let e=OC().get(t);return e?[...e.arguments,...e.requiredOptions.map(n=>`${n} \u2026`)].join(" "):""}var gu=["presentations","media","branding","knowledge","research","artifacts","agents","support"],xa={agents:"Scheduled agents and agent memory",artifacts:"Polls, microsites, ad sets and visual abstracts",branding:"Brand profiles, tokens, logos and competitors",knowledge:"Library documents, folders and the Knowledge Hub",media:"Voiceover, music, SFX, images, stock footage, avatars and video",presentations:"Decks, PowerPoint import, speaker notes and deck\u2192MP4",research:"Scraping, transcripts, web/news/image search and extraction",support:"Filing and following bug reports, questions and feature requests"},DC="other";function NC(t){let e=t.category?.trim();return e&&e.length>0?e:DC}function fu(t){let e=gu.indexOf(t);return e===-1?gu.length:e}function Kn(t){let e=new Map;for(let n of t){let r=NC(n),o=e.get(r);o?o.push(n):e.set(r,[n])}return[...e.entries()].sort(([n],[r])=>fu(n)-fu(r)||n.localeCompare(r)).map(([n,r])=>({capabilities:[...r].sort((o,i)=>o.name.localeCompare(i.name)),category:n}))}function Ra(t){return t.lifecycle?.mode==="background"}function Ca(t,e){let n=t.lifecycle?.status?.cliCommand?.trim();if(!(!Ra(t)||!n))return`${e} ${n} <run-id>`}function LC(t){switch(t.billing){case"free":return"free";case"quota":return"plan quota";case"fixed":return"credits (fixed)";case"dynamic":return"credits (usage-based)";case"delegated":return"credits (on completion)";default:return"unknown \u2014 check `capabilities`"}}function oo(t){return t.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function UC(t,e){let n=Ca(t,e);return n?`run id \u2014 poll \`${n}\``:`immediate (${t.operation??"call"})`}function nt(t,e){let n=["| Command | What it does | Takes | Returns | Cost | Scopes |","|---|---|---|---|---|---|"],r=t.map(o=>{let i=uu(o.name),d=o.scopes?.length?o.scopes.map(c=>`\`${c}\``).join(", "):"\u2014";return`| \`${e} ${oo(o.name)}\` | ${oo(o.description??"")} | ${i?`\`${oo(i)}\``:"\u2014"} | ${UC(o,e)} | ${LC(o)} | ${d} |`});return[...n,...r].join(`
|
|
320
|
+
`)}function pe(t,e){if(t.source==="live")return`<!-- Generated from the live ${e.name} capability catalog (v${t.catalogVersion}, ${t.capabilities.length} capabilities) at install time. Re-run \`${e.cmd} skill install\` to refresh. -->`;let n=t.reason?` Reason: ${oo(t.reason).replace(/\.+$/,"")}.`:"";return`<!-- STALE-RISK: the live catalog could not be read at install time, so this was rendered from the snapshot baked into the installed CLI (v${t.catalogVersion}, ${t.capabilities.length} capabilities).${n} Run \`${e.cmd} login\` then \`${e.cmd} skill install --force\` to regenerate from the live catalog, and treat \`${e.cmd} capabilities\` as authoritative over this file. -->`}function hu(t){return t.map(e=>`- [${e}](#${e.toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/ /g,"-")})`).join(`
|
|
321
|
+
`)}var _C=["get","presentation video prepare","presentation video inspect","presentation video settings","presentation video edit","presentation video presenter","presentation video","presentation video versions","presentation video restore","presentation video refresh","presentation video-narration","presentation speaker-notes","video library list","avatar options"];function jC(t){let e=new Map(t.map(n=>[n.name,n]));return _C.map(n=>e.get(n)).filter(n=>n!==void 0)}function Ht(t,e){let{cmd:n}=t,r=jC(e.capabilities),o=e.capabilities.find(d=>d.name==="presentation video"),i=o?Ca(o,n)??`${n} presentation video status <run-id>`:`${n} presentation video status <run-id>`;return`${pe(e,t)}
|
|
303
322
|
|
|
304
323
|
# Deck \u2192 MP4 (\`${n} presentation video\`)
|
|
305
324
|
|
|
@@ -534,11 +553,11 @@ not maintain a second copy.
|
|
|
534
553
|
|
|
535
554
|
## Every capability in this flow
|
|
536
555
|
|
|
537
|
-
${
|
|
556
|
+
${nt(r,n)}
|
|
538
557
|
|
|
539
558
|
If something you need is not in this table, do not conclude it is missing \u2014
|
|
540
559
|
run \`${n} capabilities --search video\`.
|
|
541
|
-
`}var
|
|
560
|
+
`}var VC=["video reference analyze","video storyboard create","video storyboard revise","video storyboard show","video create","search video","video translate-languages","video translate","video lipsync","media analyze","media import","video library list"];function Sa(t){let e=new Map(t.map(n=>[n.name,n]));return VC.map(n=>e.get(n)).filter(n=>n!==void 0)}function io(t,e){let{cmd:n}=t,r=Sa(e.capabilities);return`${pe(e,t)}
|
|
542
561
|
|
|
543
562
|
# Video from scratch (\`${n} video\`)
|
|
544
563
|
|
|
@@ -708,63 +727,63 @@ ${n} video library list <project-id> # reusable clips and rec
|
|
|
708
727
|
|
|
709
728
|
## Every capability in this flow
|
|
710
729
|
|
|
711
|
-
${
|
|
730
|
+
${nt(r,n)}
|
|
712
731
|
|
|
713
732
|
If something you need is not in this table, do not conclude it is missing \u2014
|
|
714
733
|
run \`${n} capabilities --search video\`.
|
|
715
|
-
`}var
|
|
734
|
+
`}var qC=12,MC={media:"video.md",presentations:"deck-to-video.md"};function BC(t,e,n,r){let{cmd:o}=t,i=xa[n]??n,d=r.filter(Ra),c=r.filter(v=>v.billing!==void 0&&v.billing!=="free"),u=MC[n],f=["Every capability",...d.length>0?["Background operations"]:[]];return`${pe(e,t)}
|
|
716
735
|
|
|
717
736
|
# ${n} \u2014 ${i}
|
|
718
737
|
|
|
719
|
-
${r.length} capabilit${r.length===1?"y":"ies"} in this category${
|
|
738
|
+
${r.length} capabilit${r.length===1?"y":"ies"} in this category${c.length>0?`, ${c.length} of which ${c.length===1?"costs":"cost"} credits or ${c.length===1?"counts":"count"} against a plan quota`:", all free"}.${u?`
|
|
720
739
|
|
|
721
740
|
Step-by-step flow: [${u}](${u}).`:""}
|
|
722
|
-
${r.length>
|
|
741
|
+
${r.length>qC?`
|
|
723
742
|
## Contents
|
|
724
743
|
|
|
725
|
-
${
|
|
744
|
+
${hu(f)}
|
|
726
745
|
`:""}
|
|
727
746
|
## Every capability
|
|
728
747
|
|
|
729
|
-
${
|
|
730
|
-
${
|
|
748
|
+
${nt(r,o)}
|
|
749
|
+
${d.length>0?`
|
|
731
750
|
## Background operations
|
|
732
751
|
|
|
733
752
|
These return a run id immediately and keep working. Poll the status command
|
|
734
753
|
until it reports done \u2014 do not assume success from the accept response.
|
|
735
754
|
|
|
736
|
-
${
|
|
755
|
+
${d.map(v=>`- \`${o} ${v.name}\` \u2192 \`${o} ${v.lifecycle?.status?.cliCommand??""} <run-id>\`${v.lifecycle?.status?.pollAfterSeconds?` (first poll after ~${v.lifecycle.status.pollAfterSeconds}s)`:""}`).join(`
|
|
737
756
|
`)}
|
|
738
757
|
`:""}
|
|
739
758
|
Anything missing here? Run \`${o} capabilities --category ${n}\` \u2014 the
|
|
740
759
|
catalog is authoritative and always current; this file is a snapshot of it.
|
|
741
|
-
`}function
|
|
760
|
+
`}function yu(t,e,n={}){let r=[{content:Ht(t,e),name:"deck-to-video"},{content:io(t,e),name:"video"}];for(let{capabilities:o,category:i}of Kn(e.capabilities)){let d=n[i];r.push({content:BC(t,e,i,o)+(d?`
|
|
742
761
|
---
|
|
743
762
|
|
|
744
|
-
${
|
|
763
|
+
${d}`:""),name:i})}return r}function bu(t){let e=[{file:"deck-to-video.md",when:"An existing deck must become an MP4 \u2014 narration, voice, avatar, music, captions."},{file:"video.md",when:"A video is being built from a brief or storyboard, with no deck involved."}];for(let{capabilities:n,category:r}of Kn(t.capabilities))e.push({file:`${r}.md`,when:`${xa[r]??r} (${n.length} commands).`});return e}function Wn(t){return[...new Set(t.flatMap(e=>[e.name,...e.lifecycle.status?.cliCommand?[e.lifecycle.status.cliCommand]:[]]))]}function ie(t,e,n,r="direct-operation-smoke"){let o=r==="ui-e2e"?"Browser/product E2E only; it does not execute the built CLI through the HTTP adapter.":"Canonical-operation smoke with adapter assertions; it does not execute a built CLI through the HTTP adapter.";return{level:"partial",boundary:r,kind:"smoke",source:`scripts/lib/deployment-smoke-catalog.ts#${e}`,case:e,run:`pnpm smoke -- run ${t} --url <non-production-deployment>`,claim:`${o} ${n}`}}function Xt(t,e,n){return{level:"partial",boundary:"mocked-adapter-integration",kind:"integration",source:t,case:e,run:`pnpm exec vitest run ${t}`,claim:`In-memory adapter integration with mocked canonical operations; no real HTTP operation or fixture postcondition is reached. ${n}`}}function Ea(t,e,n){return{level:"full",boundary:"real-cli-http-journey",kind:"smoke",source:`scripts/lib/deployment-smoke-catalog.ts#${e}`,case:e,run:`pnpm smoke:${t} -- --url http://localhost:3000`,claim:`Built CLI subprocess through the real HTTP adapter, governance, and canonical operation, with a controlled fixture and independently verified postcondition. ${n}`}}var wu="tests/integration/tool-surface/presentations.integration.test.ts",FC="tests/integration/tool-surface/branding.integration.test.ts";function vu(t){switch(t){case"create":return[Xt(wu,"normalizes MCP and CLI starts into the same durable job input","MCP and CLI normalize the same generation input."),ie("presentation","presentation.create","A real deck is generated and persisted.","ui-e2e")];case"export":return[ie("presentation","presentation.export","Real PDF, PPTX, HTML, and PNG exports are validated.","ui-e2e")];case"presentation import":case"presentation import transform":return[ie("presentation-import","presentation.import-powerpoint","A PowerPoint is imported, reviewed, and reopened.","ui-e2e")];case"presentation speaker-notes":case"presentation speaker-notes-status":return[ie("presentation","presentation.speaker-notes","Persisted speaker notes are ready after reload.","ui-e2e")];default:return[]}}function GC(t){return["presentation video inspect","video library list"].includes(t)?[ie("presentation-video-agent-reads","video.presentation.agent-read-surfaces","Canonical agent surfaces share one owned project/source result.")]:["presentation video edit","presentation video refresh","presentation video restore","presentation video versions","presentation video-narration","presentation video-narration-status"].includes(t)?[ie("presentation-video-agent-edits","video.presentation.agent-edit-surfaces","Draft edits and restores persist through canonical agent operations.")]:t==="presentation video presenter"?[ie("presentation-video-scene-presenter","video.presentation.scene-presenter-agent-surfaces","A per-scene presenter override persists across agent surfaces.")]:["presentation video prepare","presentation video settings","presentation video status"].includes(t)?[Xt(wu,`generated MCP and CLI ${t}`,"The integration suite compares matching MCP and CLI adapter results.")]:t==="get"||t.startsWith("presentation speaker-notes")?vu(t):[]}function KC(t){if(["branding pronunciation listen","branding pronunciation listen status"].includes(t))return[{...ie("branding-pronunciation-listening","branding.pronunciation-listening-core-contracts","Pronunciation listening adapter contracts use controlled fixtures."),claim:"Local fixture smoke exercises generated API/CLI gateway/MCP start contracts and worker output contracts. Canonical start, provider synthesis and persistence are mocked at their respective test boundaries; natural CLI status recovery has unit checks only. No built CLI HTTP journey or retained Preview proof is claimed."}];if(t==="branding pronunciation set-batch")return[{...Xt("tests/integration/tool-surface/brand-pronunciation-batch.integration.test.ts","preserves identical atomic batch results and unrelated rules across API, CLI and MCP",""),claim:"Pronunciation dictionary batch results agree across API, governed CLI and standard MCP adapter contracts with an in-memory mocked store. No built CLI HTTP journey, live speech or retained Preview journey is proven."}];if(["branding pronunciation list","branding pronunciation get","branding pronunciation set","branding pronunciation delete"].includes(t))return[{...Xt("tests/integration/tool-surface/brand-pronunciation.integration.test.ts","keeps add, list, get, update and delete results identical across API, CLI and MCP",""),claim:"Pronunciation dictionary CRUD results agree across API, governed CLI and standard MCP adapter contracts with an in-memory mocked store. No built CLI HTTP journey, live speech or retained Preview journey is proven."}];if(["branding list","branding profile","branding competitor list"].includes(t))return[ie("branding","branding.agent-read-surfaces","Brand reads resolve the same controlled brand across agent surfaces.")];if(t==="branding extract")return[ie("branding","branding.extraction-approval-refusal","Only the approval refusal and no-charge boundary is proven.")];if(t==="branding create")return[ie("branding","branding.create","Creation, idempotency, and plan-limit refusal reach the canonical operation.")];let e=[["branding product","branding.products","Product lifecycle behavior is exercised."],["branding variant","branding.variants","Variant lifecycle behavior is exercised."],["branding version","branding.versions","Version lifecycle behavior is exercised."],["branding voice","branding.voice","Voice document behavior is exercised."],["branding gradient","branding.gradients","Gradient replacement behavior is exercised."],["branding variations","branding.gradients","Variation generation is declared; provider-backed CLI success is not proven."],["branding guardrail","branding.guardrails","Guardrail lifecycle behavior is exercised."],["branding quality","branding.quality","Quality reads and repair refusal are exercised."],["branding sync","branding.sync","A durable linked-deck sync completes."]];for(let[n,r,o]of e)if(t.startsWith(n))return[ie("branding",r,o)];return["branding star","branding default","branding delete"].some(n=>t.startsWith(n))?[ie("branding","branding.lifecycle-pointers","Star, default, and deletion pointers reach canonical operations.")]:t==="branding update"?[ie("branding","branding.record-fields","Rename and parent moves reach updateBrand.")]:t==="branding set"?[Xt(FC,"runs the free brand write on both lanes without an approval receipt","MCP and CLI invoke the same free brand write in memory.")]:[]}function WC(t){return["agent roster list","agent roster get","agent visibility set"].includes(t)?[Ea("agent-roster-visibility","agent.roster-visibility","Owner and teammate roster projections, visibility CAS, replay, conflicts, and database postconditions are verified.")]:["agent list","agent get","agent configure","agent pause","agent resume"].includes(t)?[Ea("agent-management","agent.management-primitives","Owned-Agent reads, configuration CAS, schedule transitions, replay, conflicts, and database postconditions are verified.")]:[]}function JC(t,e){return t==="presentation"?vu(e):t==="presentation-video"?GC(e):t==="agents"?WC(e):KC(e)}function Ta(t,e){return Wn(e).map(n=>{let r=JC(t,n),o=r.length===0?"missing":r.some(i=>i.level==="full")?"full":"partial";return{command:n,evidence:r,level:o}})}function Iu(t){return t==="presentation video"||t.startsWith("presentation video ")||t.startsWith("presentation video-")}function Aa(t,e){let n=new Set(e.capabilities.map(r=>r.name));return t.flow.filter(r=>n.has(r))}function zC(t,e){let n=new Set(e.capabilities.map(o=>o.name)),r=(o,i)=>n.has(o)?`- \`${t.cmd} ${o}\` \u2014 ${i}`:void 0;return`# Presentation workflow
|
|
745
764
|
|
|
746
765
|
Use this flow for decks, not MP4 production or brand-library maintenance.
|
|
747
766
|
|
|
748
767
|
1. Run \`../scripts/check-auth.sh\`, then \`../scripts/check-flow.sh\`.
|
|
749
|
-
2. Inspect exact flags with \`${
|
|
768
|
+
2. Inspect exact flags with \`${t.cmd} <command> --help\`; never infer a flag from another surface.
|
|
750
769
|
3. Gather source material before generation and pass only user-provided or verified context.
|
|
751
770
|
4. If the user chose a saved brand, pass its id during creation. Do not claim a brand can be attached to an arbitrary existing deck.
|
|
752
771
|
5. Retain a background run id and poll the catalog-named status command.
|
|
753
|
-
6. Resolve the final deck with \`${
|
|
772
|
+
6. Resolve the final deck with \`${t.cmd} get\`; export only when requested.
|
|
754
773
|
|
|
755
774
|
## Useful operations present in this catalog
|
|
756
775
|
|
|
757
776
|
${[r("create","create a deck from a topic and context"),r("presentation import","import a PowerPoint into a new deck"),r("get","read the resulting presentation"),r("export","export a deck to a supported format"),r("presentation delete","delete only after explicit user intent")].filter(Boolean).join(`
|
|
758
777
|
`)}
|
|
759
778
|
|
|
760
|
-
For narration, scenes, presenters, captions, or MP4 output, load \`${
|
|
761
|
-
`}function
|
|
779
|
+
For narration, scenes, presenters, captions, or MP4 output, load \`${t.name}-presentation-video\`.
|
|
780
|
+
`}function HC(t,e){let n=Aa(Yt.branding,e).map(r=>`- \`${t.cmd} ${r}\``).join(`
|
|
762
781
|
`);return`# Branding workflow
|
|
763
782
|
|
|
764
783
|
Branding owns saved private and team brand profiles. It does not edit arbitrary deck HTML.
|
|
765
784
|
|
|
766
785
|
1. Run \`../scripts/check-auth.sh\`, then discover the live surface with \`../scripts/discover-capabilities.sh\`.
|
|
767
|
-
For least privilege, authenticate with \`${
|
|
786
|
+
For least privilege, authenticate with \`${t.cmd} login --scopes brands:read,brands:write\`.
|
|
768
787
|
2. Resolve the workspace or team explicitly when requested.
|
|
769
788
|
3. List or inspect before mutating. Use the returned brand id; never guess from a name or URL.
|
|
770
789
|
4. Select a brand during presentation creation. A later sync may propagate changed tokens only to decks already linked to that brand.
|
|
@@ -775,13 +794,13 @@ Branding owns saved private and team brand profiles. It does not edit arbitrary
|
|
|
775
794
|
${n||"No common anchors are present in this snapshot; run discovery before acting."}
|
|
776
795
|
|
|
777
796
|
Read [commands.md](commands.md) for every available brand operation and its scopes.
|
|
778
|
-
`}function
|
|
797
|
+
`}function XC(t,e){let n=Aa(Yt.agents,e).map(r=>`- \`${t.cmd} ${r}\``).join(`
|
|
779
798
|
`);return`# Agents workflow
|
|
780
799
|
|
|
781
800
|
This skill owns scheduled Mindframes Agents. It is not a guide for software-development agents.
|
|
782
801
|
|
|
783
802
|
1. Run \`../scripts/check-auth.sh\`, then discover the deployed Agents surface with \`../scripts/discover-capabilities.sh\`.
|
|
784
|
-
Use \`${
|
|
803
|
+
Use \`${t.cmd} login --scopes agents:read,agents:write\` only when a visibility mutation is required.
|
|
785
804
|
2. Use \`agent list\` and \`agent get\` for Agents owned by the caller. Use \`agent roster list\` and \`agent roster get\` for the safe team-visible roster projection.
|
|
786
805
|
3. Never infer global or cross-team discovery. Legacy \`public\` visibility is readable only under the existing same-team roster policy and cannot be newly selected.
|
|
787
806
|
4. Before changing visibility, read the owned Agent's current visibility. Pass it as \`--expected-visibility\` to \`agent visibility set\`; choose only \`private\` or \`team\`.
|
|
@@ -792,25 +811,25 @@ This skill owns scheduled Mindframes Agents. It is not a guide for software-deve
|
|
|
792
811
|
${n||"No common anchors are present in this snapshot; run discovery before acting."}
|
|
793
812
|
|
|
794
813
|
Read [commands.md](commands.md) for current inputs, outputs, scopes, and exact CLI help.
|
|
795
|
-
`}var
|
|
814
|
+
`}var YC=[{id:1,prompt:"Create a ten-slide investor presentation from my supplied metrics using team brand br_42, then give me the final deck link.",expected_output:"A create-and-verify plan that applies the saved brand only during deck creation.",expectations:["Runs the auth and flow checks before a product operation.","Inspects create help instead of inventing flags.","Passes the chosen brand id during presentation creation.","Polls a background run and resolves the final deck with get."]},{id:2,prompt:"Import ./board-update.pptx and export the resulting presentation as PDF.",expected_output:"An import, verification, and export flow using only real presentation commands.",expectations:["Uses presentation import and reads its help.","Does not route through standalone video or presentation-video commands.","Verifies the imported presentation before export."]},{id:3,prompt:"Turn presentation pr_123 into a narrated vertical MP4 with captions.",expected_output:"A handoff to the presentation-video skill rather than deck creation.",expectations:["Routes to the presentation-video skill.","Does not use the from-scratch video pipeline."]}],QC=[{id:1,prompt:"Make presentation pr_123 a 9:16 MP4 with concise narration and captions, and let me approve before rendering.",expected_output:"A prepare, inspect, settings, render, and status flow with a human spend gate.",expectations:["Runs auth and flow checks before product work.","Prepares and inspects before rendering.","Separates editable preparation from paid render approval.","Polls the exact render status command and verifies the MP4 result."]},{id:2,prompt:"For presentation-video project pv_9, rewrite only slide s_4 narration to be warmer and shorter, then show me the updated draft.",expected_output:"A targeted narration edit and project inspection without starting a render.",expectations:["Uses the named slide narration operation.","Does not start a paid render without a separate request and approval.","Reads the updated project after the edit completes."]},{id:3,prompt:"Create a 30-second product promo from this script; there is no presentation.",expected_output:"A handoff to the standalone video skill.",expectations:["Routes to the standalone video skill because no deck exists.","Does not create a presentation-video project."]}],ZC=[{id:1,prompt:"Our team brand logo and fonts changed. Update br_42 and propagate the changes to presentations already linked to it.",expected_output:"A read, update, verify, and linked-deck sync flow over the existing brand.",expectations:["Reads br_42 before mutation.","Verifies the saved brand profile.","Uses sync semantics only for already-linked presentations.","Does not invent arbitrary brand attachment."]},{id:2,prompt:"Find our saved Acme team brand, then create a new quarterly deck using it.",expected_output:"A brand lookup followed by presentation creation with the resolved id.",expectations:["Lists or gets the brand instead of guessing an id.","Hands deck creation to the presentation skill.","Uses the brand id during deck creation."]},{id:3,prompt:"Move slide 4 after slide 7 and replace its hero image.",expected_output:"A handoff to presentation editing, not a branding mutation.",expectations:["Does not trigger brand profile writes.","Routes to presentation editing capabilities."]}],eS=[{id:1,prompt:"Share my private Agent ag_42 with this workspace, but do not make it globally public.",expected_output:"An owner read, compare-and-set visibility mutation to team, and owner plus roster verification flow.",expectations:["Reads the owned Agent before mutation and uses its returned visibility as expectedVisibility.","Selects team rather than inventing public exposure.","Verifies the owner record and team roster after the mutation."]},{id:2,prompt:"Show me the Agents my teammates have shared with our workspace.",expected_output:"A paginated roster list followed by safe roster detail reads when needed.",expectations:["Uses agent roster list rather than owner-only agent list.","Does not claim cross-team or global public search.","Does not expose instructions, credentials, or private configuration."]},{id:3,prompt:"Turn presentation pr_123 into a narrated MP4.",expected_output:"A handoff to the presentation-video skill.",expectations:["Routes to the presentation-video skill, not scheduled Agents.","Does not create or configure an Agent."]}],Yt={presentation:{type:"presentation",title:"Presentation",description:t=>`Use whenever the user wants to create, import, inspect, export, organize, share, delete, or edit a ${t} presentation, deck, slides, pitch deck, or PowerPoint. Do not use for turning an existing deck into an MP4 (use ${t}-presentation-video), video from scratch (use ${t}-video), or maintaining saved brands (use ${t}-branding).`,discoveryQuery:"presentation",select:t=>t.category==="presentations"&&!Iu(t.name),flow:["create","presentation status","get","export"],workflow:zC,evals:YC},"presentation-video":{type:"presentation-video",title:"Presentation to MP4",description:t=>`Use whenever an existing ${t} presentation or deck must become a narrated video or MP4, or when its narration, scenes, presenter, music, captions, draft versions, or render status must be managed. Do not use for video from a brief with no deck (use ${t}-video), ordinary slide editing (use ${t}-presentation), or brand maintenance (use ${t}-branding).`,discoveryQuery:"presentation video",select:t=>Iu(t.name)||t.name==="presentation speaker-notes"||t.name==="get"||t.name==="avatar options"||t.name==="video library list",flow:["presentation video prepare","presentation video inspect","presentation video settings","presentation video","presentation video status"],workflow:Ht,evals:QC},branding:{type:"branding",title:"Branding",description:t=>`Use whenever the user wants to discover, create, inspect, or maintain private or team ${t} brand profiles, tokens, logos, fonts, voice, guardrails, products, versions, quality, or linked-presentation updates. Trigger for "use our brand" when a saved brand must first be resolved. Do not use for arbitrary slide edits or presentation-to-MP4 work.`,discoveryQuery:"branding",select:t=>t.category==="branding",flow:["branding list","branding profile","branding set","branding sync"],workflow:HC,evals:ZC},agents:{type:"agents",title:"Agents",description:t=>`Use for scheduled ${t} Agents: owned-Agent management, workspace roster discovery, and owner-authorized private/team visibility changes. Do not trigger for generic coding agents, presentation-to-MP4 work, or global/public Agent search.`,discoveryQuery:"agent",select:t=>t.category==="agents",flow:["agent list","agent roster list","agent roster get","agent visibility set"],workflow:XC,evals:eS}};function ao(t,e){return e.capabilities.filter(Yt[t].select).sort((n,r)=>n.name.localeCompare(r.name))}function tS(t,e,n){let r=ao(n.type,e),o=new Set(r.map(d=>d.name)),i=Wn(r).filter(d=>!o.has(d));return`${pe(e,t)}
|
|
796
815
|
|
|
797
816
|
# ${n.title} commands
|
|
798
817
|
|
|
799
|
-
Generated from the capability catalog. It describes ${r.length} callable operations; run \`${
|
|
818
|
+
Generated from the capability catalog. It describes ${r.length} callable operations; run \`${t.cmd} capabilities --search "${n.discoveryQuery}"\` for the deployed surface.
|
|
800
819
|
|
|
801
|
-
${
|
|
820
|
+
${nt(r,t.cmd)}
|
|
802
821
|
${i.length?`## Recovery commands
|
|
803
822
|
|
|
804
|
-
${i.map(
|
|
823
|
+
${i.map(d=>`- \`${t.cmd} ${d}\``).join(`
|
|
805
824
|
`)}
|
|
806
825
|
`:""}
|
|
807
|
-
`}function
|
|
826
|
+
`}function nS(t,e,n){let r=Ta(n.type,ao(n.type,e)),o=r.map(f=>{let v=f.evidence.length?f.evidence.map(S=>`**${S.kind}** ${S.source} \u2014 ${S.case}`).join("<br>"):"No non-unit evidence registered.",I=f.evidence.length?f.evidence.map(S=>S.claim).join(" "):"Do not claim integration or smoke coverage for this command.";return`| \`${t.cmd} ${f.command}\` | **${f.level.toUpperCase()}** | ${v} | ${I} |`}),i=[...new Set(r.flatMap(f=>f.evidence.map(v=>v.run)))],d=r.filter(f=>f.level==="full").length,c=r.filter(f=>f.level==="partial").length,u=r.length-d-c;return`${pe(e,t)}
|
|
808
827
|
|
|
809
828
|
# ${n.title} non-unit evidence
|
|
810
829
|
|
|
811
830
|
Capability registration and unit tests are not command parity evidence. **FULL** requires built CLI \u2192 real HTTP adapter \u2192 governance \u2192 canonical operation \u2192 controlled fixture/provider \u2192 independently verified postcondition. **PARTIAL** names a narrower boundary. **MISSING** has no registered non-unit evidence.
|
|
812
831
|
|
|
813
|
-
Summary: ${
|
|
832
|
+
Summary: ${d} full, ${c} partial, ${u} missing.
|
|
814
833
|
|
|
815
834
|
| Command | Coverage | Executable evidence | Proven claim |
|
|
816
835
|
|---|---|---|---|
|
|
@@ -825,9 +844,9 @@ Smoke runs require an approved non-production target and their catalog prerequis
|
|
|
825
844
|
${i.length?i.join(`
|
|
826
845
|
`):"# No non-unit evidence registered."}
|
|
827
846
|
\`\`\`
|
|
828
|
-
`}function
|
|
829
|
-
`),
|
|
830
|
-
`),u=
|
|
847
|
+
`}function ku(t){return`'${t.replace(/'/g,`'"'"'`)}'`}function rS(t,e,n){let r=ao(n.type,e),o=Wn(r),i=Ta(n.type,r),d=i.filter(f=>f.level==="missing").map(f=>f.command).join(`
|
|
848
|
+
`),c=i.filter(f=>f.level==="partial").map(f=>f.command).join(`
|
|
849
|
+
`),u=ku(t.cmd);return[{path:"scripts/check-auth.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
831
850
|
set -eu
|
|
832
851
|
CLI=${u}
|
|
833
852
|
command -v "$CLI" >/dev/null 2>&1 || { echo "$CLI is not installed" >&2; exit 127; }
|
|
@@ -837,7 +856,7 @@ printf '%s\\n' "Authentication and feature catalog are ready."
|
|
|
837
856
|
`},{path:"scripts/discover-capabilities.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
838
857
|
set -eu
|
|
839
858
|
CLI=${u}
|
|
840
|
-
QUERY=\${1:-${
|
|
859
|
+
QUERY=\${1:-${ku(n.discoveryQuery)}}
|
|
841
860
|
"$CLI" capabilities --search "$QUERY" --format json
|
|
842
861
|
`},{path:"scripts/verify-help.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
843
862
|
set -eu
|
|
@@ -859,18 +878,18 @@ while IFS= read -r REQUIRED; do
|
|
|
859
878
|
[ -z "$REQUIRED" ] && continue
|
|
860
879
|
printf '%s\\n' "$AVAILABLE" | grep -Fqx "$REQUIRED" || { echo "Missing required capability: $REQUIRED" >&2; exit 1; }
|
|
861
880
|
done <<'COMMANDS'
|
|
862
|
-
${
|
|
881
|
+
${Aa(n,e).join(`
|
|
863
882
|
`)}
|
|
864
883
|
COMMANDS
|
|
865
884
|
printf '%s\\n' "${n.title} flow anchors are available."
|
|
866
885
|
`},{path:"scripts/check-coverage.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
867
886
|
set -eu
|
|
868
887
|
PARTIAL=$(cat <<'COMMANDS'
|
|
869
|
-
${
|
|
888
|
+
${c}
|
|
870
889
|
COMMANDS
|
|
871
890
|
)
|
|
872
891
|
MISSING=$(cat <<'COMMANDS'
|
|
873
|
-
${
|
|
892
|
+
${d}
|
|
874
893
|
COMMANDS
|
|
875
894
|
)
|
|
876
895
|
[ -z "$PARTIAL" ] || printf 'PARTIAL command evidence (not parity):\\n%s\\n' "$PARTIAL" >&2
|
|
@@ -880,14 +899,14 @@ if [ -n "$PARTIAL" ] || [ -n "$MISSING" ]; then
|
|
|
880
899
|
exit 1
|
|
881
900
|
fi
|
|
882
901
|
printf '%s\\n' 'Every documented command has full real-CLI journey evidence.'
|
|
883
|
-
`}]}function
|
|
884
|
-
`}}function
|
|
902
|
+
`}]}function oS(t,e){return{path:"evals/evals.json",content:`${JSON.stringify({skill_name:t,evals:e.map(n=>({...n,files:[],expectations:[...n.expectations,"Consults references/coverage.md and never reports PARTIAL or MISSING as full command parity."]}))},null,2)}
|
|
903
|
+
`}}function Le(t,e,n){let r=Yt[n],o=`${t.name}-${n}`,i=ao(n,e).length;return`---
|
|
885
904
|
name: ${o}
|
|
886
905
|
description: >-
|
|
887
|
-
${r.description(
|
|
906
|
+
${r.description(t.name)}
|
|
888
907
|
---
|
|
889
908
|
|
|
890
|
-
${
|
|
909
|
+
${pe(e,t)}
|
|
891
910
|
|
|
892
911
|
# ${r.title}
|
|
893
912
|
|
|
@@ -899,7 +918,7 @@ Use this narrow workflow. Do not infer command names or reuse flags from UI, API
|
|
|
899
918
|
2. Run \`scripts/check-flow.sh\` or \`scripts/discover-capabilities.sh [query]\`.
|
|
900
919
|
3. Read [references/coverage.md](references/coverage.md); MISSING is not covered.
|
|
901
920
|
4. Read [references/workflow.md](references/workflow.md).
|
|
902
|
-
5. Read [references/commands.md](references/commands.md) only for the needed operation, then run \`${
|
|
921
|
+
5. Read [references/commands.md](references/commands.md) only for the needed operation, then run \`${t.cmd} <command> --help\`.
|
|
903
922
|
6. Verify returned state; an accepted background run is not completion.
|
|
904
923
|
|
|
905
924
|
## Bundled resources
|
|
@@ -913,18 +932,19 @@ Use this narrow workflow. Do not infer command names or reuse flags from UI, API
|
|
|
913
932
|
- \`scripts/check-flow.sh\` \u2014 verify minimum flow anchors exist.
|
|
914
933
|
- \`scripts/check-coverage.sh\` \u2014 fail unless every documented command has full real-CLI evidence.
|
|
915
934
|
- \`evals/evals.json\` \u2014 realistic trigger and workflow evaluations.
|
|
916
|
-
`}function
|
|
917
|
-
`),u
|
|
918
|
-
`),
|
|
935
|
+
`}function Qt(t,e,n){let r=Yt[n];return[{name:"commands",content:tS(t,e,r)},{name:"coverage",content:nS(t,e,r)},{name:"workflow",content:r.workflow(t,e)}]}function Zt(t,e,n){let r=Yt[n];return[...rS(t,e,r),oS(`${t.name}-${n}`,r.evals)]}var iS=[{capability:"create",intent:'"Make me a presentation / deck / slides about X"',reference:"presentations.md",suffix:' "Topic" --context "\u2026"'},{capability:"presentation video prepare",intent:'"Turn my deck into a video / MP4 / narrated video"',reference:"deck-to-video.md",suffix:" <presentation-id> --yes"},{capability:"video storyboard create",intent:'"Make me a video about X" (no deck exists)',reference:"video.md",suffix:" --file ./storyboard.md \u2026"},{capability:"presentation import",intent:'"Import this PowerPoint / .pptx"',reference:"presentations.md",suffix:" --file deck.pptx --mode preserve"},{capability:"discussion list",intent:'"Read comments / review threads on a private deck"',reference:"presentations.md",suffix:" <document-id>"},{capability:"presentation speaker-notes",intent:'"Write speaker notes for this deck"',reference:"deck-to-video.md",suffix:" <presentation-id>"},{capability:"presentation video-narration",intent:'"Rewrite the narration on one slide"',reference:"deck-to-video.md",suffix:" <project-id> --slide-id <id>"},{capability:"tts generate",intent:'"Voiceover / narration / read this aloud / TTS"',reference:"media.md",suffix:' -t "Text" -o out.mp3'},{capability:"music generate",intent:'"Background music / a soundtrack"',reference:"media.md"},{capability:"sfx generate",intent:'"Sound effects"',reference:"media.md"},{capability:"mix create",intent:'"Mix this voiceover and music into the video"',reference:"media.md"},{capability:"image generate",intent:'"Generate an image"',reference:"media.md"},{capability:"image generate",intent:'"An image of this person / product / logo" (keep a real likeness)',reference:"image.md",suffix:' -p "\u2026" --reference-image identity=./photo.jpg --yes'},{capability:"search images",intent:'"Find a stock photo"',reference:"research.md",suffix:' -q "\u2026"'},{capability:"search video",intent:'"Find stock footage / b-roll"',reference:"video.md",suffix:' "ocean waves"'},{capability:"avatar options",intent:'"Which avatars / presenters / voices can I use?"',reference:"media.md"},{capability:"avatar generate",intent:'"Make a talking-head / avatar clip"',reference:"media.md"},{capability:"video translate",intent:'"Dub / translate this video"',reference:"video.md"},{capability:"video lipsync",intent:'"Re-sync the lips to this new audio"',reference:"video.md"},{capability:"branding extract",intent:'"Match my brand" / "pull branding from this site"',reference:"branding.md",suffix:" <url>"},{capability:"scrape",intent:'"Read this web page"',reference:"research.md",suffix:" https://example.com"},{capability:"transcript",intent:'"Get the transcript of this YouTube video"',reference:"research.md",suffix:" <url>"},{capability:"search web",intent:'"Search the web / find news about X"',reference:"research.md",suffix:' "query"'},{capability:"knowledge search",intent:'"What do we already have on X?"',reference:"knowledge.md"},{capability:"document create",intent:'"Save this as a document" / library filing',reference:"knowledge.md"},{capability:"file add",intent:'"Put this deck/PDF in the Library so I can @ it in chat"',reference:"knowledge.md"},{capability:"microsite create",intent:'"Build a landing page / microsite"',reference:"artifacts.md"},{capability:"poll create",intent:'"Make a poll"',reference:"artifacts.md"},{capability:"visual-abstract create",intent:'"One-page visual summary"',reference:"artifacts.md"},{capability:"ad-set create",intent:'"Ad creatives for this campaign"',reference:"artifacts.md"},{capability:"agent create",intent:'"Schedule this to run every week"',reference:"agents.md"},{capability:"support report",intent:'"Something broke / how do I / I wish it could" \u2014 file it, then `support list`',reference:"support.md"}],aS=["ai-connections","capabilities","config","delete","derive","export","footage","ideas","import","list","login","logout","runner","skill","templates","whoami"];function so(t,e=tr("rendered without a catalog fetch")){let{name:n,cmd:r,pkg:o}=t,i=new Map(e.capabilities.map(I=>[I.name,I])),d=iS.filter(I=>i.has(I.capability)).map(I=>`| ${I.intent} | \`${r} ${I.capability}${I.suffix??""}\` | [${I.reference}](references/${I.reference}) |`).join(`
|
|
936
|
+
`),u=Kn(e.capabilities).map(({capabilities:I,category:S})=>`${S} (${I.length})`).join(", "),f=bu(e).map(({file:I,when:S})=>`| [references/${I}](references/${I}) | ${S} |`).join(`
|
|
937
|
+
`),v=[...new Set([...e.capabilities.map(I=>I.name.split(" ")[0]),...aS])].sort().map(I=>`\`${I}\``).join(", ");return`---
|
|
919
938
|
name: ${n}
|
|
920
939
|
description: >-
|
|
921
940
|
Route any ${n} CLI task to the smallest installed domain skill. Trigger for
|
|
922
941
|
presentations, decks, presentation-to-MP4, video, branding, media generation,
|
|
923
|
-
research, knowledge, artifacts, or scheduled agents.
|
|
924
|
-
detailed workflows live in domain skills and
|
|
942
|
+
research, knowledge, artifacts, private deck discussions, or scheduled agents.
|
|
943
|
+
This is an intent router; detailed workflows live in domain skills and
|
|
944
|
+
catalog-generated references.
|
|
925
945
|
---
|
|
926
946
|
|
|
927
|
-
${
|
|
947
|
+
${pe(e,t)}
|
|
928
948
|
|
|
929
949
|
# ${n} CLI router
|
|
930
950
|
|
|
@@ -951,7 +971,7 @@ Something broke, a question, or a feature request \u2192 the \`support\` group:
|
|
|
951
971
|
|
|
952
972
|
| The user asks for\u2026 | Start here | Catalog detail |
|
|
953
973
|
|---|---|---|
|
|
954
|
-
${
|
|
974
|
+
${d}
|
|
955
975
|
|
|
956
976
|
## Composing commands
|
|
957
977
|
|
|
@@ -973,21 +993,21 @@ ${u}.
|
|
|
973
993
|
|
|
974
994
|
| File | Read it when |
|
|
975
995
|
|---|---|
|
|
976
|
-
${
|
|
996
|
+
${f}
|
|
977
997
|
|
|
978
998
|
## Every command group
|
|
979
999
|
|
|
980
1000
|
Run \`${r} <group> --help\` for any of these:
|
|
981
1001
|
|
|
982
|
-
${
|
|
983
|
-
`}function
|
|
984
|
-
name: ${
|
|
1002
|
+
${v}
|
|
1003
|
+
`}function co(t){let{name:e,cmd:n}=t;return`---
|
|
1004
|
+
name: ${e}-presentation-edit
|
|
985
1005
|
description: >
|
|
986
1006
|
Use ONLY when editing an already-created presentation that has real slides:
|
|
987
1007
|
changing slide text, colors, fonts, images, charts, layout, or adding/removing slides.
|
|
988
1008
|
Triggers: "change", "edit", "update", "fix", "modify", "add a slide", "make it X".
|
|
989
1009
|
Do NOT load for creation requests \u2014 "create a presentation", "make slides",
|
|
990
|
-
"build a deck", "3-slide pitch", "new presentation" \u2192 use ${
|
|
1010
|
+
"build a deck", "3-slide pitch", "new presentation" \u2192 use ${e}-presentation.
|
|
991
1011
|
---
|
|
992
1012
|
|
|
993
1013
|
# Presentation Editor \u2014 In-App Guide
|
|
@@ -1265,8 +1285,8 @@ Do NOT render or export the presentation \u2014 that's handled by the app.
|
|
|
1265
1285
|
| Create brand-new presentation (5+ slides, new topic) | \`${n} create ...\` via CLI |
|
|
1266
1286
|
| Redesign the whole deck | \`${n} create ...\` via CLI, then sync |
|
|
1267
1287
|
| User provides a URL to base the presentation on | \`${n} scrape <url>\` \u2192 \`${n} create ...\` |
|
|
1268
|
-
`}function
|
|
1269
|
-
`),
|
|
1288
|
+
`}function lo(t,e){return Le(t,e,"presentation")}var sS=[{capability:"video reference analyze",when:"Optional \u2014 match the style of a reference video."},{capability:"video storyboard create",when:"Write the storyboard. Markdown in, immutable revision out."},{capability:"video storyboard revise",when:"Iterate. Each revision is appended, never rewritten."},{capability:"video create",when:"Render a pinned revision. Paid, approval-gated, background."}];function mo(t,e){let{cmd:n,name:r,pkg:o}=t,i=new Set(e.capabilities.map(u=>u.name)),d=sS.filter(u=>i.has(u.capability)).map((u,f)=>`${f+1}. \`${n} ${u.capability}\` \u2014 ${u.when}`).join(`
|
|
1289
|
+
`),c=Sa(e.capabilities).length;return`---
|
|
1270
1290
|
name: ${r}-video
|
|
1271
1291
|
description: >-
|
|
1272
1292
|
Use when a video must be built from scratch \u2014 a brief, a script, a storyboard,
|
|
@@ -1274,10 +1294,10 @@ description: >-
|
|
|
1274
1294
|
involved. Trigger it even when the user never names the product: "make me a
|
|
1275
1295
|
video about X", "turn this script into a video", "I need a 30s promo".
|
|
1276
1296
|
For turning an EXISTING presentation into an MP4, use the ${r} skill's
|
|
1277
|
-
deck\u2192MP4 flow instead. ${
|
|
1297
|
+
deck\u2192MP4 flow instead. ${c} CLI capabilities, listed in references/video.md.
|
|
1278
1298
|
---
|
|
1279
1299
|
|
|
1280
|
-
${
|
|
1300
|
+
${pe(e,t)}
|
|
1281
1301
|
|
|
1282
1302
|
# ${r} video
|
|
1283
1303
|
|
|
@@ -1291,7 +1311,7 @@ one wastes a paid render. There is no \`video export\` subcommand.
|
|
|
1291
1311
|
|
|
1292
1312
|
## The flow
|
|
1293
1313
|
|
|
1294
|
-
${
|
|
1314
|
+
${d}
|
|
1295
1315
|
|
|
1296
1316
|
Then poll \`${n} video status <run-id>\` until it reports done.
|
|
1297
1317
|
|
|
@@ -1331,17 +1351,17 @@ ${n} video <sub> --help
|
|
|
1331
1351
|
\`\`\`
|
|
1332
1352
|
|
|
1333
1353
|
The catalog is authoritative and always current; this file is a snapshot of it.
|
|
1334
|
-
`}function
|
|
1354
|
+
`}function xu(t,e){return[{content:io(t,e),name:"video"},{content:Ht(t,e),name:"deck-to-video"}]}import{chmodSync as dS,existsSync as Oa,mkdirSync as $a,rmSync as cS,writeFileSync as Pa}from"fs";import{homedir as Su}from"os";import{basename as lS,dirname as mS,join as rt,relative as pS,resolve as Jn}from"path";var It=[{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 uS={sonnet:"claude-sonnet-4.6",haiku:"claude-haiku-4.5",opus:"claude-opus-4.6"},gS=["permissionMode","skills","subagentType"];function fS(t,e){if(e!=="copilot")return t;let n=t.match(/^---\n([\s\S]*?)\n---\n/);if(!n)return Ru(t);let r=n[1],o=t.slice((n.index??0)+n[0].length);r=r.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(d,c,u,f)=>`${c}${uS[u]??u}${f}`);for(let d of gS)r=r.replace(new RegExp(`^${d}:[^
|
|
1335
1355
|
]*
|
|
1336
|
-
?`,"m"),"");r=r.replace(/\n+$/,"");let i=
|
|
1356
|
+
?`,"m"),"");r=r.replace(/\n+$/,"");let i=Ru(o);return`---
|
|
1337
1357
|
${r}
|
|
1338
1358
|
---
|
|
1339
|
-
${i}`}function
|
|
1340
|
-
name: ${
|
|
1359
|
+
${i}`}function Ru(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 Eu(t,e){let n=Jn(t),r=Jn(t,e);if(pS(n,r).startsWith("..")||Jn(r)!==r.replace(/\.\./g,""))throw new Error(`Invalid path: "${e}" would escape base directory`);return r}function Cu(t,e,n,r,o){let i=rt(t,"SKILL.md");if($a(t,{recursive:!0}),Pa(i,fS(e,r),"utf-8"),n&&n.length>0){let d=rt(t,"references");$a(d,{recursive:!0});for(let c of n){let u=rt(d,`${c.name}.md`);Pa(u,c.content,"utf-8")}}for(let d of o??[]){let c=Eu(t,d.path);$a(mS(c),{recursive:!0}),Pa(c,d.content,"utf-8"),d.executable&&dS(c,493)}}function po(t,e,n={},r,o){let i={installed:[],skipped:[],errors:[]},d=n.local?process.cwd():Su();if(n.dir){let c=lS(Jn(n.dir)),u=It.find(f=>f.dir===c)?.provider;try{let f=Jn(n.dir),v=Eu(f,rt("skills",t));Cu(v,e,r,u,o),i.installed.push(n.dir)}catch(f){i.errors.push(`${n.dir}: ${m(f)}`)}}else for(let c of It){let u=rt(d,c.dir),f=rt(u,"skills",t),v=rt(f,"SKILL.md");if(Oa(u)){if(Oa(v)&&!n.force){i.skipped.push(c.name);continue}try{Cu(f,e,r,c.provider,o),i.installed.push(c.name)}catch(I){i.errors.push(`${c.name}: ${m(I)}`)}}}return i}function uo(t,e={}){let n={removed:[],errors:[]},r=e.local?process.cwd():Su();for(let o of It){let i=rt(r,o.dir,"skills",t);if(Oa(i))try{cS(i,{recursive:!0}),n.removed.push(o.name)}catch(d){n.errors.push(`${o.name}: ${m(d)}`)}}return n}function Tu(){return It.map(t=>t.name)}function en(t){let{name:e,cmd:n}=t;return`---
|
|
1360
|
+
name: ${e}-tts
|
|
1341
1361
|
description: Text-to-speech generation. Convert text to natural speech with multiple providers (Gemini, ElevenLabs, OpenAI) and voices. Use for voiceovers, narration, accessibility.
|
|
1342
1362
|
---
|
|
1343
1363
|
|
|
1344
|
-
# ${
|
|
1364
|
+
# ${e} TTS (Text-to-Speech)
|
|
1345
1365
|
|
|
1346
1366
|
Convert text to natural speech with multiple providers and voices.
|
|
1347
1367
|
|
|
@@ -1536,12 +1556,12 @@ ${n} tts generate \\
|
|
|
1536
1556
|
2. **Voice matching** - Match voice style to content: Puck for upbeat, Charon for serious
|
|
1537
1557
|
3. **Speed adjustment** - Use 0.9-0.95 for narration, 1.0-1.1 for casual
|
|
1538
1558
|
4. **Multiple voiceovers** - Run \`${n} tts generate\` once per line and poll each run with \`${n} tts status <run-id>\`
|
|
1539
|
-
`}function
|
|
1540
|
-
name: ${
|
|
1559
|
+
`}function tn(t){let{name:e,cmd:n}=t;return`---
|
|
1560
|
+
name: ${e}-music
|
|
1541
1561
|
description: Generate music that follows a video's narration and final timing. Gemini plans the provider prompt on the backend.
|
|
1542
1562
|
---
|
|
1543
1563
|
|
|
1544
|
-
# ${
|
|
1564
|
+
# ${e} Video Music
|
|
1545
1565
|
|
|
1546
1566
|
Generate TTS first and finalize the storyboard/timeline. Then write a factual request; do not write a music prompt, music plan, style list, or provider options.
|
|
1547
1567
|
|
|
@@ -1562,12 +1582,12 @@ ${n} music status <request-id>
|
|
|
1562
1582
|
\`\`\`
|
|
1563
1583
|
|
|
1564
1584
|
The backend sends these facts to Gemini, receives the provider-ready musical direction, and makes the paid music-provider request. Retrying the same unchanged request is idempotent.
|
|
1565
|
-
`}function
|
|
1566
|
-
name: ${
|
|
1585
|
+
`}function nn(t){let{name:e,cmd:n}=t;return`---
|
|
1586
|
+
name: ${e}-sfx
|
|
1567
1587
|
description: Generate one sound effect aligned with a final visual event and narration. Gemini plans the provider prompt on the backend.
|
|
1568
1588
|
---
|
|
1569
1589
|
|
|
1570
|
-
# ${
|
|
1590
|
+
# ${e} Video Sound Effects
|
|
1571
1591
|
|
|
1572
1592
|
Generate TTS first and finalize timing. For each meaningful sound cue, send the video's facts plus exactly one factual \`visual_event\`. Include word timings when TTS provides them. Do not author an SFX prompt or provider settings.
|
|
1573
1593
|
|
|
@@ -1600,12 +1620,12 @@ ${n} sfx status <request-id>
|
|
|
1600
1620
|
\`\`\`
|
|
1601
1621
|
|
|
1602
1622
|
The backend sends these facts to Gemini, receives one provider-ready SFX description, and makes the paid SFX-provider request. Retrying the same unchanged request is idempotent.
|
|
1603
|
-
`}function
|
|
1604
|
-
name: ${
|
|
1623
|
+
`}function rn(t){let{name:e,cmd:n}=t;return`---
|
|
1624
|
+
name: ${e}-mix
|
|
1605
1625
|
description: Audio mixing for video production. Combine video with voiceover and background music. Supports volume control, fade effects, and multiple audio tracks.
|
|
1606
1626
|
---
|
|
1607
1627
|
|
|
1608
|
-
# ${
|
|
1628
|
+
# ${e} Audio Mixing
|
|
1609
1629
|
|
|
1610
1630
|
Mix video with voiceover and background music.
|
|
1611
1631
|
|
|
@@ -1750,12 +1770,12 @@ ${n} mix status <request-id>
|
|
|
1750
1770
|
2. **Music selection** - Choose music that doesn't compete with voice frequency.
|
|
1751
1771
|
3. **Consistent levels** - Keep voice at 100%, adjust music only.
|
|
1752
1772
|
4. **File sizes** - Use \`--no-wait\` for large files to avoid timeout.
|
|
1753
|
-
`}function
|
|
1754
|
-
name: ${
|
|
1773
|
+
`}function on(t){let{name:e,cmd:n}=t;return`---
|
|
1774
|
+
name: ${e}-image
|
|
1755
1775
|
description: Image search across the web and licensed stock, plus AI image generation with reference images. Find licensed photos to publish, web images for specific real-world subjects, generate a custom image, or generate one that keeps a real person's face, a product or a logo by passing a local photo or URL as a reference. For videos, presentations, marketing.
|
|
1756
1776
|
---
|
|
1757
1777
|
|
|
1758
|
-
# ${
|
|
1778
|
+
# ${e} Image Commands
|
|
1759
1779
|
|
|
1760
1780
|
Search images (web + licensed stock) and generate AI images.
|
|
1761
1781
|
|
|
@@ -2143,12 +2163,12 @@ things you wrote on their behalf.
|
|
|
2143
2163
|
likeness additionally needs \`--provider google-ai --model gemini-3-pro-image\`
|
|
2144
2164
|
**and** the \`image-model-override\` flag on the workspace; without the flag
|
|
2145
2165
|
the server drops the pin and the likeness is close, not exact.
|
|
2146
|
-
`}function
|
|
2147
|
-
name: ${
|
|
2166
|
+
`}function an(t){let{name:e,cmd:n}=t;return`---
|
|
2167
|
+
name: ${e}-video-search
|
|
2148
2168
|
description: Video search across the web and licensed stock. Find downloadable stock clips for b-roll and backgrounds, or web videos (YouTube, Vimeo) to embed in a slide or microsite.
|
|
2149
2169
|
---
|
|
2150
2170
|
|
|
2151
|
-
# ${
|
|
2171
|
+
# ${e} Video Search
|
|
2152
2172
|
|
|
2153
2173
|
Find video: licensed clips you can download, or web videos you can embed.
|
|
2154
2174
|
|
|
@@ -2340,12 +2360,12 @@ ${n} video find "city timelapse" --orientation landscape -n 10
|
|
|
2340
2360
|
3. **Preview first** - Use preview URLs to check quality
|
|
2341
2361
|
4. **License** - Verify license for commercial use
|
|
2342
2362
|
5. **JSON export** - Save searches for batch processing
|
|
2343
|
-
`}function
|
|
2344
|
-
name: ${
|
|
2363
|
+
`}function sn(t){let{name:e,cmd:n}=t;return`---
|
|
2364
|
+
name: ${e}-scrape
|
|
2345
2365
|
description: Scrape any URL the user provides. Use when user says "check this site", "look at this URL", "use this website", "here's the link", or shares any URL for context. Supports websites, YouTube, Twitter/X.
|
|
2346
2366
|
---
|
|
2347
2367
|
|
|
2348
|
-
# ${
|
|
2368
|
+
# ${e} URL Scraping
|
|
2349
2369
|
|
|
2350
2370
|
Extract content from URLs for analysis and context.
|
|
2351
2371
|
|
|
@@ -2530,12 +2550,12 @@ ${n} scrape https://blog.example.com -f quiet | ${n} create "Blog Summary"
|
|
|
2530
2550
|
3. **Use JSON** - For programmatic processing of results
|
|
2531
2551
|
4. **Combine sources** - Scrape multiple URLs for comprehensive context
|
|
2532
2552
|
5. **Token count** - Check token usage for large documents
|
|
2533
|
-
`}function
|
|
2534
|
-
name: ${
|
|
2553
|
+
`}function go(t){let{name:e,cmd:n}=t;return`---
|
|
2554
|
+
name: ${e}-branding
|
|
2535
2555
|
description: Brand profile management. Extract branding from websites, manage saved brands, apply consistent styling to presentations.
|
|
2536
2556
|
---
|
|
2537
2557
|
|
|
2538
|
-
# ${
|
|
2558
|
+
# ${e} Branding Management
|
|
2539
2559
|
|
|
2540
2560
|
Manage brand profiles for consistent styling across presentations.
|
|
2541
2561
|
|
|
@@ -2640,12 +2660,12 @@ ${n} branding set-default abc123
|
|
|
2640
2660
|
2. **If extraction fails** \u2014 Proceed without branding. Do not manually create brand assets.
|
|
2641
2661
|
3. **Set default** \u2014 If you mostly work with one brand, set it as default.
|
|
2642
2662
|
4. **Override** \u2014 Use \`--brand\` flag to override default for specific presentations.
|
|
2643
|
-
`}function
|
|
2644
|
-
name: ${
|
|
2663
|
+
`}function dn(t){let{name:e,cmd:n}=t,r=e.toUpperCase().replace(/[^A-Z0-9]/g,"_");return`---
|
|
2664
|
+
name: ${e}-config
|
|
2645
2665
|
description: CLI configuration management. Set API keys, team IDs, custom API URLs. Verify authentication status.
|
|
2646
2666
|
---
|
|
2647
2667
|
|
|
2648
|
-
# ${
|
|
2668
|
+
# ${e} Configuration
|
|
2649
2669
|
|
|
2650
2670
|
Manage CLI settings and authentication.
|
|
2651
2671
|
|
|
@@ -2801,70 +2821,70 @@ ${n} config show --verify # Test API key
|
|
|
2801
2821
|
\`\`\`bash
|
|
2802
2822
|
${n} config set team-id <correct-team-id>
|
|
2803
2823
|
\`\`\`
|
|
2804
|
-
`}var
|
|
2805
|
-
${
|
|
2806
|
-
${
|
|
2807
|
-
${
|
|
2808
|
-
${
|
|
2809
|
-
${
|
|
2810
|
-
${
|
|
2811
|
-
${
|
|
2812
|
-
${
|
|
2813
|
-
|
|
2814
|
-
${
|
|
2815
|
-
|
|
2816
|
-
${
|
|
2817
|
-
$ ${
|
|
2818
|
-
$ ${
|
|
2819
|
-
$ ${
|
|
2820
|
-
$ ${
|
|
2821
|
-
$ ${
|
|
2822
|
-
`);
|
|
2823
|
-
`)),n(
|
|
2824
|
-
`))}});for(let
|
|
2825
|
-
${
|
|
2826
|
-
$ ${
|
|
2827
|
-
$ ${
|
|
2828
|
-
|
|
2829
|
-
${
|
|
2830
|
-
${
|
|
2831
|
-
$ ${
|
|
2832
|
-
${
|
|
2833
|
-
$ ${
|
|
2834
|
-
${
|
|
2835
|
-
$ ${
|
|
2836
|
-
${
|
|
2837
|
-
$ ${
|
|
2838
|
-
${
|
|
2839
|
-
$ ${
|
|
2840
|
-
${
|
|
2841
|
-
$ ${
|
|
2842
|
-
${
|
|
2843
|
-
$ ${
|
|
2844
|
-
${
|
|
2845
|
-
$ ${
|
|
2846
|
-
${
|
|
2847
|
-
$ ${
|
|
2848
|
-
${
|
|
2849
|
-
$ ${
|
|
2850
|
-
${
|
|
2851
|
-
$ ${
|
|
2852
|
-
|
|
2853
|
-
${
|
|
2854
|
-
'${
|
|
2855
|
-
'${
|
|
2824
|
+
`}var hS=["main","video","presentation","presentation-video","presentation-edit","branding","agents"];function ne(t,e){return t===void 0||t==="main"?hS.some(n=>n===e):t===e}var cn=["main","video","presentation","presentation-video","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","agents","config"],fo=["standalone","studio"],Au={cmd:g.commands[0],pkg:g.packageName,url:g.apiUrl,name:g.name},ln=new yS("skill").description(`Manage ${g.displayName} skills for AI coding assistants`).addHelpText("after",`
|
|
2825
|
+
${ae.bold("Skill Types:")}
|
|
2826
|
+
${ae.cyan("main")} Intent router and capability index
|
|
2827
|
+
${ae.cyan("presentation")} Create, import, inspect, and export decks
|
|
2828
|
+
${ae.cyan("presentation-video")} Turn an existing deck into an MP4
|
|
2829
|
+
${ae.cyan("branding")} Manage private and team brand profiles
|
|
2830
|
+
${ae.cyan("agents")} Manage scheduled Agents and team roster visibility
|
|
2831
|
+
${ae.cyan("video")} Build a video from scratch (no deck)
|
|
2832
|
+
${ae.cyan("presentation-edit")} Legacy Studio editing guide
|
|
2833
|
+
|
|
2834
|
+
${ae.bold("Reference-only types:")} tts, music, sfx, mix, image, video-search, scrape, config
|
|
2835
|
+
|
|
2836
|
+
${ae.bold("Examples:")}
|
|
2837
|
+
$ ${g.commands[0]} skill install ${ae.gray("# core suite")}
|
|
2838
|
+
$ ${g.commands[0]} skill install presentation-video
|
|
2839
|
+
$ ${g.commands[0]} skill install branding --dir ~/.claude
|
|
2840
|
+
$ ${g.commands[0]} skill install agents
|
|
2841
|
+
$ ${g.commands[0]} skill show presentation
|
|
2842
|
+
`);ln.command("install").description(`Install ${g.displayName} skills for AI coding assistants`).argument("[type]","Skill type, or omit to install the core skill suite").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,e)=>{e.mode&&!fo.includes(e.mode)&&(a(`Invalid mode: ${e.mode}. Must be one of: ${fo.join(", ")}`),process.exit(1));let n={...Au,mode:e.mode},r=[];t&&!cn.includes(t)&&(a(`Invalid skill type: ${t}. Must be one of: ${cn.join(", ")}`),process.exit(1));let o=await gn();o.source==="snapshot"&&(L(`Live capability catalog unavailable (${o.reason??"unknown reason"}) \u2014 generating from the snapshot baked into this CLI.`),console.log(ae.gray(` Run \`${g.commands[0]} login\` then re-run with --force to regenerate from the live catalog.`)));let i=[...yu(n,o,{branding:go(n)}),{name:"tts",content:en(n)},{name:"music",content:tn(n)},{name:"sfx",content:nn(n)},{name:"mix",content:rn(n)},{name:"image",content:on(n)},{name:"video-search",content:an(n)},{name:"scrape",content:sn(n)},{name:"config",content:dn(n)}];ne(t,"main")&&r.push({name:g.name,content:so(n,o),references:i}),ne(t,"video")&&r.push({content:mo(n,o),name:`${g.name}-video`,references:xu(n,o)}),ne(t,"presentation")&&r.push({name:`${g.name}-presentation`,content:lo(n,o),references:Qt(n,o,"presentation"),files:Zt(n,o,"presentation")}),ne(t,"presentation-video")&&r.push({name:`${g.name}-presentation-video`,content:Le(n,o,"presentation-video"),references:Qt(n,o,"presentation-video"),files:Zt(n,o,"presentation-video")}),ne(t,"presentation-edit")&&r.push({name:`${g.name}-presentation-edit`,content:co(n)}),ne(t,"branding")&&r.push({name:`${g.name}-branding`,content:Le(n,o,"branding"),references:Qt(n,o,"branding"),files:Zt(n,o,"branding")}),ne(t,"agents")&&r.push({name:`${g.name}-agents`,content:Le(n,o,"agents"),references:Qt(n,o,"agents"),files:Zt(n,o,"agents")}),ne(t,"tts")&&r.push({name:`${g.name}-tts`,content:en(n)}),ne(t,"music")&&r.push({name:`${g.name}-music`,content:tn(n)}),ne(t,"sfx")&&r.push({name:`${g.name}-sfx`,content:nn(n)}),ne(t,"mix")&&r.push({name:`${g.name}-mix`,content:rn(n)}),ne(t,"image")&&r.push({name:`${g.name}-image`,content:on(n)}),ne(t,"video-search")&&r.push({name:`${g.name}-video-search`,content:an(n)}),ne(t,"scrape")&&r.push({name:`${g.name}-scrape`,content:sn(n)}),ne(t,"config")&&r.push({name:`${g.name}-config`,content:dn(n)}),console.log();for(let d of r){w(`Installing ${d.name}...`);let c=po(d.name,d.content,{dir:e.dir,local:e.local,force:e.force},d.references,d.files);if(c.installed.length>0&&(k(`${d.name} installed successfully`),E(" Installed to",c.installed.join(", "))),c.skipped.length>0&&(w(` Skipped (already exists): ${c.skipped.join(", ")}`),console.log(ae.gray(" Use --force to overwrite"))),c.errors.length>0)for(let u of c.errors)a(` ${u}`);c.installed.length===0&&c.skipped.length===0&&c.errors.length===0&&(w(" No supported AI coding assistants detected"),console.log(ae.gray(` Supported editors: ${Tu().join(", ")}`)),console.log(ae.gray(" Use --dir <path> to install to a specific directory"))),console.log()}});ln.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action(async(t="main",e)=>{e.mode&&!fo.includes(e.mode)&&(a(`Invalid mode: ${e.mode}. Must be one of: ${fo.join(", ")}`),process.exit(1));let n={...Au,mode:e.mode},r=await gn(),i={main:()=>so(n,r),video:()=>mo(n,r),presentation:()=>lo(n,r),"presentation-video":()=>Le(n,r,"presentation-video"),"presentation-edit":()=>co(n),tts:()=>en(n),music:()=>tn(n),sfx:()=>nn(n),mix:()=>rn(n),image:()=>on(n),"video-search":()=>an(n),scrape:()=>sn(n),branding:()=>Le(n,r,"branding"),agents:()=>Le(n,r,"agents"),config:()=>dn(n)}[t];i?console.log(i()):(a(`Invalid skill type: ${t}. Must be one of: ${cn.join(", ")}`),process.exit(1))});ln.command("uninstall").description(`Remove ${g.displayName} skills from AI coding assistants`).argument("[type]","Skill type, or omit to remove installed skills").option("-g, --global","Uninstall globally (from home directory)",!0).option("-l, --local","Uninstall locally (from current directory)").action(async(t,e)=>{let n=[];t&&!cn.includes(t)&&(a(`Invalid skill type: ${t}. Must be one of: ${cn.join(", ")}`),process.exit(1)),(!t||t==="main")&&n.push(g.name),(!t||t==="video")&&n.push(`${g.name}-video`),(!t||t==="presentation")&&n.push(`${g.name}-presentation`),(!t||t==="presentation-video")&&n.push(`${g.name}-presentation-video`),(!t||t==="presentation-edit")&&n.push(`${g.name}-presentation-edit`),(!t||t==="tts")&&n.push(`${g.name}-tts`),(!t||t==="music")&&n.push(`${g.name}-music`),(!t||t==="sfx")&&n.push(`${g.name}-sfx`),(!t||t==="mix")&&n.push(`${g.name}-mix`),(!t||t==="image")&&n.push(`${g.name}-image`),(!t||t==="video-search")&&n.push(`${g.name}-video-search`),(!t||t==="scrape")&&n.push(`${g.name}-scrape`),(!t||t==="branding")&&n.push(`${g.name}-branding`),(!t||t==="agents")&&n.push(`${g.name}-agents`),(!t||t==="config")&&n.push(`${g.name}-config`),console.log();for(let r of n){let o=uo(r,{local:e.local});if(o.removed.length>0?(k(`${r} uninstalled`),E(" Removed from",o.removed.join(", "))):w(` ${r} not found`),o.errors.length>0)for(let i of o.errors)L(` Failed to remove: ${i}`)}console.log()});import Da from"chalk";import{Command as bS}from"commander";var $u=new bS("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)",y("--format",["human","json"]),"human").action(async t=>{await b();try{let e=await Oe();if(Do(),t.format==="json"){console.log(JSON.stringify(e,null,2));return}Se("User"),console.log(),E("Email",e.user.email),e.user.username&&E("Username",e.user.username),(e.user.firstName||e.user.lastName)&&E("Name",[e.user.firstName,e.user.lastName].filter(Boolean).join(" "));let n=e.authType==="apiKey"?"API Key":e.authType==="oauth"?"OAuth":"Session";if(E("Auth Type",n),e.currentTeam&&(console.log(),Se("Current Team"),console.log(),E("ID",e.currentTeam.id),E("Name",e.currentTeam.name),E("Plan",e.currentTeam.planName),E("Role",e.currentTeam.isOwner?"Owner":"Member")),e.teams.length>1){console.log(),Se("All Teams"),console.log();for(let r of e.teams){let o=r.isCurrent?Da.green(" (current)"):"";console.log(` ${Da.bold(r.name)}${o}`),console.log(Da.gray(` ID: ${r.id} | Plan: ${r.planName} | Role: ${r.role}`))}}console.log()}catch(e){a("The command failed. Please try again."),process.exit(e.exitCode??1)}});function Pu(t){return t[0]==="--"?t.slice(1):t}import Na from"chalk";function La(t){t.configureOutput({outputError:(e,n)=>{n(Na.red(e));let r=/unknown option '(-{1,2}[^'\s=]+)/.exec(e);if(!r)return;let o=vS(t,r[1]);o&&n(Na.yellow(`Did you mean '${o}'?
|
|
2843
|
+
`)),n(Na.gray(`Run '${wS(t)} --help' to see the accepted options.
|
|
2844
|
+
`))}});for(let e of t.commands)La(e)}function wS(t){let e=[],n=t;for(;n;)e.unshift(n.name()),n=n.parent;return e.join(" ")}function vS(t,e){let n,r=Number.POSITIVE_INFINITY;for(let i of t.options)if(!i.hidden)for(let d of[i.short,i.long]){if(!d)continue;let c=Ua(e,d);c<r&&(r=c,n=i.flags)}let o=e.startsWith("--")?2:1;return n!==void 0&&r<=o?n:void 0}function Ua(t,e){if(t===e)return 0;if(t.length===0)return e.length;if(e.length===0)return t.length;let n=Array.from({length:e.length+1},(r,o)=>o);for(let r=1;r<=t.length;r++){let o=[r];for(let i=1;i<=e.length;i++){let d=t[r-1]===e[i-1]?0:1;o[i]=Math.min(o[i-1]+1,n[i]+1,n[i-1]+d)}n=o}return n[e.length]}var kS="0.3.26",Q=new IS,q=g.commands[0];Q.name(q).description(`${g.displayName} CLI \u2014 presentations, videos, avatars, audio, branding, media and research`).version(kS,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output");Q.addCommand(vd);mu(Q);Q.addCommand(Nd);Q.addCommand(Dd);Q.addCommand(Pd);Q.addCommand(Ed);Q.addCommand($u);Q.addCommand(Vd);Q.addCommand(qd);Q.addCommand(Sd);Q.addCommand(ln);Q.addCommand(lr);var Ou=$d();Ou.commands.length>0&&Q.addCommand(Ou);function xS(t){let e=t.toLowerCase(),n=e.length<=4?1:2,r,o=Number.POSITIVE_INFINITY;for(let i of Q.commands)for(let d of[i.name(),...i.aliases()]){let c=Ua(e,d.toLowerCase());c<o&&(o=c,r=i.name())}return r!==void 0&&o<=n?r:void 0}Q.on("command:*",t=>{let e=String(t[0]);console.error(X.red(`Error: Unknown command '${e}'`)),console.error();let n=xS(e);n&&console.error(`Did you mean '${n}'?`),console.error(`Run '${q} --help' to see available commands.`),console.error(`Run '${q} capabilities' for the full list of callable capabilities.`),process.exit(1)});Q.addHelpText("after",`
|
|
2845
|
+
${X.bold("Start here:")}
|
|
2846
|
+
$ ${q} capabilities ${X.gray("# every capability + its exact command path")}
|
|
2847
|
+
$ ${q} <group> --help ${X.gray("# drill into any command group above")}
|
|
2848
|
+
|
|
2849
|
+
${X.bold("Common tasks:")}
|
|
2850
|
+
${X.gray("Make a presentation")}
|
|
2851
|
+
$ ${q} create "<topic>" --context "..."
|
|
2852
|
+
${X.gray("Turn a finished presentation into an MP4 (narration + avatar)")}
|
|
2853
|
+
$ ${q} presentation video <slug>
|
|
2854
|
+
${X.gray("Export a presentation to HTML, PDF or PPTX")}
|
|
2855
|
+
$ ${q} export <id-or-slug> -o deck.html
|
|
2856
|
+
${X.gray("Make a video from scratch (no deck)")}
|
|
2857
|
+
$ ${q} video storyboard create ${X.gray("then")} $ ${q} video create
|
|
2858
|
+
${X.gray("Regenerate one slide's narration in a video draft")}
|
|
2859
|
+
$ ${q} presentation video-narration <project-id>
|
|
2860
|
+
${X.gray("Generate speaker notes")}
|
|
2861
|
+
$ ${q} presentation speaker-notes <presentation-id>
|
|
2862
|
+
${X.gray("Import a PowerPoint")}
|
|
2863
|
+
$ ${q} presentation import
|
|
2864
|
+
${X.gray("Extract a brand identity from a URL")}
|
|
2865
|
+
$ ${q} branding extract <url>
|
|
2866
|
+
${X.gray("Voiceover, music, sound effects")}
|
|
2867
|
+
$ ${q} tts generate | ${q} music generate | ${q} sfx generate
|
|
2868
|
+
${X.gray("Find stock footage / images")}
|
|
2869
|
+
$ ${q} video find | ${q} image search
|
|
2870
|
+
${X.gray("Read a web page or a YouTube transcript")}
|
|
2871
|
+
$ ${q} scrape <url> | ${q} transcript <url>
|
|
2872
|
+
|
|
2873
|
+
${X.bold("Two different video pipelines:")}
|
|
2874
|
+
'${q} presentation video ...' renders an EXISTING deck to MP4.
|
|
2875
|
+
'${q} video ...' builds a video from a storyboard or brief with stock
|
|
2856
2876
|
and generated footage \u2014 no deck involved.
|
|
2857
2877
|
|
|
2858
|
-
${
|
|
2859
|
-
Run '${
|
|
2878
|
+
${X.bold("Authentication:")}
|
|
2879
|
+
Run '${q} login' to authenticate (recommended).
|
|
2860
2880
|
Or set CC_SLIDES_API_KEY environment variable for API key auth.
|
|
2861
2881
|
|
|
2862
|
-
${
|
|
2882
|
+
${X.bold("Note:")}
|
|
2863
2883
|
The command list above is not always complete: feature-flag-gated commands
|
|
2864
|
-
(the '${
|
|
2865
|
-
and '${
|
|
2866
|
-
'${
|
|
2884
|
+
(the '${q} derive' subcommands) appear only after '${q} login'
|
|
2885
|
+
and '${q} config refresh' have cached your feature access. Run
|
|
2886
|
+
'${q} capabilities' for the authoritative list.
|
|
2867
2887
|
|
|
2868
|
-
${
|
|
2869
|
-
${
|
|
2870
|
-
`);
|
|
2888
|
+
${X.bold("More Info:")}
|
|
2889
|
+
${X.blue(g.docsUrl)}
|
|
2890
|
+
`);La(Q);Q.parse(Pu(process.argv.slice(2)),{from:"user"});
|