@conceptcraft/mindframes 0.3.27 → 0.3.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +175 -135
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module'; const require = createRequire(import.meta.url);
3
- var h={id:"mindframes",name:"mindframes",displayName:"Mindframes",description:"CLI tool for Mindframes presentation generation",commands:["mf","mindframes"],apiUrl:"https://www.mindframes.app",docsUrl:"https://docs.mindframes.ai",packageName:"@conceptcraft/mindframes",configDir:".mindframes",apiKeyEnvVar:"MINDFRAMES_API_KEY",apiUrlEnvVar:"MINDFRAMES_API_URL",codexSelfConnectorAppId:"asdk_app_6a2b9629c1608191970dcb3ab374ac55"};import te from"chalk";import{Command as S$}from"commander";import Hn from"chalk";import{Command as My}from"commander";function kd(e={}){let t=(l,d)=>{let g=e[l];return g&&g.trim().length>0?g.trim():d},n=t("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),r=t("NEXT_PUBLIC_CLI_COMMAND","ccr"),i=t("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),o=t("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${i}`),c=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:i,name:o.replace(/^\./,""),displayName:n,description:`CLI tool for ${n} presentation generation`,commands:[r,i],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:o,apiKeyEnvVar:`${c}_API_KEY`,apiUrlEnvVar:`${c}_API_URL`,codexSelfConnectorAppId:e.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var f=typeof h<"u"&&h?h:kd(process.env);import{createHash as Ao,randomUUID as J}from"crypto";import{readFileSync as Gd,statSync as Kd}from"fs";import{basename as Oo}from"path";import ty from"readline";async function xd(e){process.stderr.write(`${JSON.stringify({event:"approval_required",...e.approvalUrl?{approvalUrl:e.approvalUrl}:{}})}
4
- `);let t=ty.createInterface({input:process.stdin,terminal:process.stdin.isTTY===!0});try{return(await new Promise(i=>{if(process.stdin.isTTY){t.question(`Approve this exact request in your browser: ${e.approvalUrl??e.message}
5
- Then paste the approval receipt: `,i);return}let o=!1,c=l=>{o||(o=!0,i(l))};t.on("line",c),t.on("close",()=>c(""))})).trim()||void 0}finally{t.close()}}import{spawnSync as ny}from"child_process";import{existsSync as ry,mkdtempSync as iy,rmSync as oy,writeFileSync as ay}from"fs";import{tmpdir as sy}from"os";import{join as Rd}from"path";import xo from"ffmpeg-static";var dy=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function cy(e){let t=dy.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 Cd(e,t="audio"){if(e.length===0)return;let n=xo&&ry(xo)?xo:"ffmpeg",r=/^[a-z0-9]+$/i.test(t)?t:"audio",i=iy(Rd(sy(),"mf-tts-duration-")),o=Rd(i,`speech.${r}`);try{ay(o,e);let c=ny(n,["-hide_banner","-i",o],{encoding:"utf8"});return c.error?void 0:cy(c.stderr??"")}finally{oy(i,{force:!0,recursive:!0})}}import jr from"chalk";import ly from"conf";import Sd from"path";var Pd=f.apiUrl,my={apiKey:{type:"string"},apiUrl:{type:"string",default:Pd},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}};function py(e=f.apiKeyEnvVar){return e.endsWith("_API_KEY")?`${e.slice(0,-8)}_CONFIG_DIR`:`${e}_CONFIG_DIR`}function uy(e=process.env){let t=py(),n=e[t]?.trim()||e.CC_SLIDES_CONFIG_DIR?.trim();if(n){if(!Sd.isAbsolute(n))throw new Error(`${t} must be an absolute directory path`);return Sd.normalize(n)}}var Ed=uy(),M=new ly({projectName:f.name,schema:my,...Ed?{configFileMode:384,cwd:Ed}:{}});function Ad(){return{apiKey:Qe(),apiUrl:K(),defaultTeamId:M.get("defaultTeamId"),accessToken:M.get("accessToken"),refreshToken:M.get("refreshToken"),tokenExpiresAt:M.get("tokenExpiresAt"),clientId:M.get("clientId"),clientSecret:M.get("clientSecret")}}function Qe(){let e=process.env[f.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return e||M.get("apiKey")}function Ro(e){M.set("apiKey",e)}function K(){let e=process.env[f.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return e||(M.get("apiUrl")??Pd)}function Co(e){M.set("apiUrl",e)}function ve(){return M.get("defaultTeamId")}function ln(e){M.set("defaultTeamId",e)}function Lr(){M.clear()}function Jn(){return M.path}function mn(){return!!Qe()}function Td(){return M.get("accessToken")}function Od(){return M.get("refreshToken")}function Ur(e,t,n){M.set("accessToken",e),M.set("refreshToken",t),M.set("tokenExpiresAt",Date.now()+(n-60)*1e3)}function _r(){M.delete("accessToken"),M.delete("refreshToken"),M.delete("tokenExpiresAt")}function $d(){let e=M.get("tokenExpiresAt");return e?Date.now()>=e:!0}function Pt(){return!!M.get("accessToken")&&!!M.get("refreshToken")}function Dd(){return M.get("clientId")}function Nd(){return M.get("clientSecret")}function Ld(e,t){M.set("clientId",e),M.set("clientSecret",t)}var s={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function gy(){let e=Od(),t=Dd(),n=K();if(!e||!t)return null;try{let r=await fetch(`${n}/.well-known/oauth-authorization-server`);if(!r.ok)return null;let i=await r.json(),o=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:t}),c=Nd();c&&o.set("client_secret",c);let l=await fetch(i.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()});if(!l.ok)return _r(),null;let d=await l.json();return Ur(d.access_token,d.refresh_token,d.expires_in),d.access_token}catch{return null}}async function Ud(){return Pt()?$d()?gy():Td()||null:null}function Ze(){return Pt()||mn()}async function w(){if(!Ze()){let e=f.commands[0],t=f.apiKeyEnvVar;console.error(jr.red("\u2717 Not authenticated.")),console.error(),console.error(jr.bold("To authenticate, run:")),console.error(jr.cyan(` ${e} login`)),console.error(),console.error(jr.gray(`Or set ${t} environment variable.`)),process.exit(s.AUTH_ERROR)}}function fy(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function _d(){let e=Qe();if(e)return fy(e)}function So(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(n=>e.startsWith(n))}import{mkdirSync as hy,readFileSync as yy,writeFileSync as by}from"fs";import{homedir as wy}from"os";import{join as jd}from"path";import vy from"ajv/dist/2020.js";var Eo=new Map;function qd(){return jd(wy(),".conceptcraft","schemas")}function Md(e){return jd(qd(),`${e}.json`)}function Iy(e){try{let t=JSON.parse(yy(Md(e),"utf8"));return typeof t?.catalogVersion=="number"&&t.schema?t:null}catch{return null}}function ky(e,t){try{hy(qd(),{recursive:!0}),by(Md(e),JSON.stringify(t))}catch{}}async function xy(e){let t=Eo.get(e);if(t!==void 0)return t;try{let n=await Vd(e),r={catalogVersion:n.catalogVersion,schema:n.operationSchema??n.schema};return ky(e,r),Eo.set(e,r),r}catch{let n=Iy(e);return Eo.set(e,n),n}}function Ry(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 qr(e,t){let n=await xy(e);if(!n)return;let r;try{r=new vy({allErrors:!0,strict:!1}).compile(n.schema)}catch{return}if(r(t))return;let i=(r.errors??[]).slice(0,10).map(Ry);throw new Error(`Request does not match the ${e} contract \u2014 ${i.join("; ")}`)}function Cy(e){if(!e||typeof e!="object")return null;let t=e.errorCode,n=e.message,r=typeof n=="string"&&n.trim()?n:null;if(t==="approval_required")return r;if(t!=="invalid_input")return null;let i=e.details,o=[...r?[r]:[],...Array.isArray(i)?Po(i):[]];return o.length>0?o.join(`
6
- `):null}var pn="terminalRunFailure",de=class extends Error{[pn]=!0};function un(e){return!!e&&typeof e=="object"&&e[pn]===!0}function oe(e,t){let n=t?null:Cy(e);if(n)return n;if(un(e)){let i=e instanceof Error&&e.message.trim()?e.message.trim():"The run failed.";return`${/[.!?]$/.test(i)?i:`${i}.`}${t?` Request ID: ${t}.`:""} The run is finished and cannot be resumed \u2014 retry with a new request, a new idempotency key, and a fresh approval receipt where one is required.`}let r="The run failed. Check its status for recovery details.";return!t||r.includes(t)?r:`${r} Request ID: ${t}. Resume with the matching status command; do not start a duplicate run.`}function Ee(e,t){return un(e)?"":` Retry with --idempotency-key ${t}.`}function ge(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 zn(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"}: ${ge(e.error)}`:null}function Fd(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(`
7
- `):/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 fe(){let e=await Ud();if(e)return{Authorization:`Bearer ${e}`};let t=Qe();return t?{"x-api-key":t}:{}}var P=class extends Error{constructor(n,r,i=1,o="operation_failed",c=!1,l,d){super(n);this.statusCode=r;this.exitCode=i;this.errorCode=o;this.retryable=c;this.approvalUrl=l;this.details=d;this.name="ApiError"}statusCode;exitCode;errorCode;retryable;approvalUrl;details},Wd="Idempotency-Key",Jd=!1;function zd(e){Jd=e}function Sy(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!(e instanceof FormData)}function Ey(e){return e&&e!=="GET"?{[Wd]:J()}:{}}async function Oe(e,t={}){let n=K();if(!Ze()&&!t.allowUnauthenticated)throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let r=await fe(),i=`${n}${e}`,o={...r,...Ey(t.method),...t.headers};t.body&&!t.stream&&(o["Content-Type"]="application/json");let c={method:t.method??"GET",headers:o};t.body&&(c.body=JSON.stringify(t.body));let l;try{l=await fetch(i,c)}catch{throw new P("Network error while contacting Mindframes. Please try again.",0,5,"service_unavailable",!0)}if(!l.ok){let g=await l.text().catch(()=>""),y=mt(g,l.status);if(y.code==="approval_required"&&Jd&&!t.approvalRetried&&Sy(t.body)&&!t.body.approvalReceipt){let T=await xd({approvalUrl:y.approvalUrl,message:y.message});if(T)return Oe(e,{...t,approvalRetried:!0,body:{...t.body,approvalReceipt:T}})}let v=1;switch(l.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=`[${y.code}] ${y.message}`;throw new P(x,l.status,v,y.code,y.retryable,y.approvalUrl,y.details)}return t.stream?l:l.headers.get("content-type")?.includes("application/json")?l.json():l.text()}function Py(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 Ay(e){let t=e.match(/https?:\/\/\S*\/approvals\/\S+/);return t?t[0].replace(/[.,;]+$/,""):void 0}function $o(e){return e===401||e===403?2:e===404?3:e===429?4:1}function Ty(e){if(!Array.isArray(e))return;let t=e.flatMap(n=>{if(!n||typeof n!="object")return[];let r=n;return typeof r.message!="string"||!r.message.trim()?[]:[{...typeof r.code=="string"?{code:r.code}:{},message:r.message,...typeof r.path=="string"?{path:r.path}:{}}]});return t.length>0?t:void 0}function mt(e,t){let n=Py(t),r=`HTTP ${t}: The request could not be completed.`;try{let i=JSON.parse(e),o=typeof i.error=="object"&&i.error!==null?i.error:void 0;if(i.ok===!1&&typeof o?.code=="string"&&typeof o.message=="string")return{approvalUrl:typeof o.approval?.approvalUrl=="string"?o.approval.approvalUrl:typeof o.approvalUrl=="string"?o.approvalUrl:Ay(o.message),code:o.code,details:Ty(o.details),message:o.message,retryable:o.retryable===!0}}catch{}return{code:n,message:r,retryable:t===429||t>=500}}async function Vd(e){return Oe(`/api/cli/tools/${encodeURIComponent(e)}/schema`)}async function Hd(){return Oe("/api/cli/capabilities",{allowUnauthenticated:!0})}async function R(e,t,n){let r=await Mr(n),i=`?teamId=${encodeURIComponent(r)}`;return Oe(`/api/cli/tool-runs/${encodeURIComponent(e)}/${encodeURIComponent(t)}${i}`)}async function Xd(e,t,n){let r=await Mr(t);return Oe(`/api/v1/presentations/edits/runs/${encodeURIComponent(e)}/events?teamId=${encodeURIComponent(r)}`,{stream:!0,headers:n?{"Last-Event-ID":n}:void 0})}async function p(e,t,n){let r=await Mr(t.teamId);return Oe(`/api/cli/tools/${encodeURIComponent(e)}`,{body:{...t,teamId:r},headers:n?{[Wd]:n}:void 0,method:"POST"})}function U(e){return Mr(e)}async function Mr(e){let t=typeof e=="string"&&e.trim()?e.trim():ve()?.trim();if(t)return t;let n=await Je();if(n.currentTeam?.id)return n.currentTeam.id;throw new P("Team ID required. Select a workspace with `mf config set team-id <id>` or pass --team-id.",400,void 0,"invalid_input")}async function Yd(e){return Oe("/api/llm-connections/profiles",{body:e,method:"POST"})}var Oy=1800*1e3;async function z(e,t,n,r=120,i){let o=Date.now()+(i?.maxWaitMs??Oy),c=0;for(let d=0;(r===null||d<r)&&Date.now()<o;d++){let g;try{g=await R(e,t,n),c=0}catch(v){if(v instanceof P&&v.retryable&&c<2){c+=1,await new Promise(x=>setTimeout(x,2e3));continue}throw v instanceof P?new P(`${v.message} Request ID: ${t}.`,v.statusCode,v.exitCode,v.errorCode,v.retryable):new P(`The background operation could not be checked. Request ID: ${t}.`,0,5,"poll_failed",!0)}if(g.done){if(g.error)throw Object.assign(new P(`${ge(g.error,{defaultCode:"operation_failed"})} Request ID: ${t}.`,500,1,g.error.code??"operation_failed",g.error.retryable),{[pn]:!0});return g}let y=Math.min((g.nextPollAfterSeconds??2)*1e3,Math.max(0,o-Date.now()));await new Promise(v=>setTimeout(v,y))}let l=i?.statusCommand?` Check it with '${f.commands[0]} ${i.statusCommand} ${t}'.`:"";throw new P(`Stopped following run ${t}: timed out. The run is unaffected \u2014 it may still be running.${l}`,408,1,"operation_timed_out",!0)}function Vr(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 $y(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 gn(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 et(e){let t=Kd(e);return{fileName:Oo(e),fileSize:t.size,fileType:gn(e)}}async function tt(e,t){let n=et(e),r=Gd(e),i=new FormData;for(let[c,l]of Object.entries(t.fields))i.append(c,l);i.append("file",new Blob([r],{type:n.fileType}),n.fileName);let o=await fetch(t.uploadUrl,{method:"POST",body:i});if(!o.ok)throw new P("Failed to upload file to storage",o.status,1);return{id:t.fileId??J(),name:n.fileName,s3Key:t.s3Key,url:t.fileUrl,size:n.fileSize,type:n.fileType,selected:!0}}async function ie(e,t={}){let n=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let r=await fe(),i=Kd(e),o=Oo(e),c=gn(e),l=Gd(e),d=Ao("sha256").update(l).digest("hex"),g=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({fileMetadata:{lastModified:i.mtimeMs,name:o,type:c,size:i.size},...t.storagePrefix?{storagePrefix:t.storagePrefix}:{},...t.idempotencyKey?{uploadIdentity:{contentSha256:d,idempotencyKey:t.idempotencyKey}}:{}})});if(!g.ok){let v=await g.text(),x=mt(v,g.status);throw new P(`[${x.code}] ${x.message}`,g.status,$o(g.status),x.code,x.retryable)}let y=await g.json();return tt(e,{...t.idempotencyKey?{fileId:`file-${Ao("sha256").update(JSON.stringify({contentSha256:d,fileName:o,idempotencyKey:t.idempotencyKey})).digest("hex")}`}:{},fields:y.fields||{},fileUrl:y.fileUrl,s3Key:y.uploadKey,uploadUrl:y.url})}async function Qd(e,t,n={}){let r=[];for(let i=0;i<e.length;i++){let o=e[i],c=Oo(o);t?.(i,e.length,c);let l=await ie(o,{idempotencyKey:n.idempotencyKey});r.push(l)}return t?.(e.length,e.length,""),r}async function Zd(e,t,n){let r={};for(let[i,o]of Object.entries(e))o!==void 0&&(r[i]=o);return r.brandingId===void 0&&typeof r.brandId=="string"&&(r.brandingId=r.brandId),delete r.brandId,p("createSlides",{...r,...n?{approvalReceipt:n}:{}},t)}async function ec(e,t=20,n=0,r="updated",i){return(await p("listPresentations",{limit:t,offset:n,sort:r,teamId:e,search:i})).presentations}async function fn(e,t){let n=t?.includeSlides!==!1,r=await p("getPresentation",{includeSlides:n,presentationId:e,teamId:t?.teamId});if("done"in r){if(t?.includeGenerating)return r;throw new Error(r.instructions,{cause:r})}return n?{...r.presentation,slides:r.slides,...Object.hasOwn(r,"speakerNotes")?{speakerNotes:r.speakerNotes}:{}}:r.presentation}async function tc(e,t,n,r){return p("generateSpeakerNotes",{...t,presentationId:e,teamId:r},n)}async function nc(e,t,n,r){return p("setSpeakerNotes",{notes:t,presentationId:e,teamId:r},n)}async function Fr(e,t){let n=K(),r=await fetch(`${n}/api/durable-runs/${encodeURIComponent(e)}/events`,{headers:{...await fe(),...t?{"Last-Event-ID":t}:{}}});if(!r.ok){let i=mt(await r.text().catch(()=>""),r.status);throw new P(`[${i.code}] ${i.message}`,r.status,$o(r.status),i.code,i.retryable)}return r}async function rc(e,t={}){await p("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},t.idempotencyKey??`cli:presentation:delete:${Ao("sha256").update(JSON.stringify({slugOrId:e,teamId:t.teamId??null})).digest("hex")}`)}async function ic(e,t){return p("updatePresentationVisibility",{presentationId:e,teamId:t.teamId,visibility:t.visibility},t.idempotencyKey??`cli:presentation:visibility:${J()}`)}async function oc(e,t,n){return p("exportPresentation",{format:t,presentationId:e,teamId:n?.teamId})}async function hn(e){let t;try{t=await fetch(e)}catch{throw new P("Network error while downloading the export. Please try again.",0,5,"service_unavailable",!0)}if(!t.ok)throw new P(`[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 ac(e,t,n={}){let r=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let i=await fe(),o=new FormData,c=new Blob([new Uint8Array(e)],{type:"application/zip"});o.append("file",c,t),o.append("options",JSON.stringify({dryRun:n.dryRun??!1,remapIds:!0}));let l=await fetch(`${r}/api/presentations/import`,{method:"POST",headers:i,body:o}),d=await l.json();if(!l.ok)throw new P("Import failed. The server rejected the presentation.",l.status,1);return d}async function sc(e,t=25){return p("listSlideTemplates",{limit:t,search:e})}async function dc(e,t,n,r,i){return p("extractBranding",{approvalReceipt:n,skipExistingBrandingLookup:r,teamId:t,url:e},i)}async function Je(){return Oe("/api/cli/whoami")}async function cc(){return Oe("/api/cli/features")}async function lc(e,t,n={}){let r=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let i=await fe(),o=await fetch(`${r}/api/presentations/${e}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...i},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(!o.ok){let c=mt(await o.text().catch(()=>""),o.status);throw new P(`[${c.code}] ${c.message}`,o.status,$o(o.status),c.code,c.retryable)}return o}async function Do(e){return p("getGenerationLimits",{teamId:e})}async function mc(e,t,n){let r=await Do(n);if(!r.canGenerate[e]){let i=r.remaining[e]??0,o=r.limits[e]??0;throw o===0?new P(`The "${e}" mode is not available on your ${r.planName} plan. Available modes: ${r.availableModes.join(", ")||"none"}`,403,2):new P(`You have reached your ${e} generation limit for this billing cycle (${r.usage[e]??0}/${o} used). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,4)}if(r.maxSlidesPerPresentation!==-1&&t>r.maxSlidesPerPresentation)throw new P(`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 Dy(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 pc(e,t){let n={...e,text:Dy(e.text)};await qr("generateSpeech",n);let r=await p("generateSpeech",{approvalReceipt:t?.approvalReceipt,...n},t?.idempotencyKey),i=await z("generateSpeech",r.runId),o=i.entity?.url;if(!o)throw new P(`Speech completed without an audio URL. Request ID: ${r.runId}.`,500);let c;try{c=await fetch(o)}catch{throw new P(`Failed to download speech audio. Request ID: ${r.runId}.`,0,5,"download_failed",!0)}if(!c.ok)throw new P(`Failed to download speech audio. Request ID: ${r.runId}.`,c.status,5,"download_failed",c.status===429||c.status>=500);let l=i.output??{},d=e.options??{},g=We(l.format)??$y(o)??"mp3",y=Buffer.from(await c.arrayBuffer()),v=uc(l.durationSec,l.duration,l.duration_s)??Cd(y,g);if(v===void 0)throw new P(`Speech completed without a measurable duration. Request ID: ${r.runId}.`,500,1,"invalid_audio_metadata");return{audioData:y,audioUrl:o,duration:v,provider:We(l.provider)??d.provider??"gemini",format:g,requestId:r.runId,voiceId:We(l.voice_id)??We(l.voiceId),voice:We(l.voice),model:We(l.model),speed:To(l.speed)??d.speed,language:We(l.lang)??We(l.language)??d.language,langApplied:Bd(l.langApplied)??Bd(l.lang_applied),timestamps:Ny(l.timestamps),wordTimings:Ly(l.timestamps??l.timings)}}function uc(...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 Ny(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=t.characters,r=t.characterStartTimesSeconds??t.character_start_times_seconds,i=t.characterEndTimesSeconds??t.character_end_times_seconds;if(!(!Array.isArray(n)||!Array.isArray(r)||!Array.isArray(i))&&!(n.length===0||n.length!==r.length||n.length!==i.length||!n.every(o=>typeof o=="string")||!r.every(o=>typeof o=="number"&&Number.isFinite(o))||!i.every(o=>typeof o=="number"&&Number.isFinite(o))))return{characters:n,characterStartTimesSeconds:r,characterEndTimesSeconds:i}}function Ly(e){if(!Array.isArray(e))return;let t=e.flatMap(n=>{if(!n||typeof n!="object"||Array.isArray(n))return[];let r=n,i=We(r.text)??We(r.word),o=To(r.start),c=To(r.end);return i&&o!==void 0&&c!==void 0&&c>=o?[{text:i,start:o,end:c}]:[]});return t.length>0?t:void 0}function We(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function To(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Bd(e){return typeof e=="boolean"?e:void 0}async function gc(e){let t=e?`/api/cli/tts?provider=${e}`:"/api/cli/tts";return Oe(t)}async function fc(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);return delete n.idempotency_key,await qr("generateMusic",n),{requestId:(await p("generateMusic",{...n,approvalReceipt:t?.approvalReceipt},r)).runId,status:"pending"}}async function No(e){let t=await R("generateMusic",e);return{requestId:e,status:Vr(t),audioUrl:t.entity?.url,duration:uc(t.output?.durationSec,t.output?.duration,t.output?.duration_s),error:t.error?.message}}async function hc(e,t){return{requestId:(await p("mixAudio",{...e,approvalReceipt:t?.approvalReceipt},t?.idempotencyKey)).runId,status:"pending"}}async function Lo(e){let t=await R("mixAudio",e);return{requestId:e,status:Vr(t),outputUrl:t.entity?.url,error:t.error?.message}}async function yc(e){return Oe("/api/cli/images/search",{method:"POST",body:e})}async function bc(e){return Oe("/api/cli/videos/search",{method:"POST",body:e})}async function $e(e,t=60,n=2e3){let r=0;for(let i=0;i<t;i++){let o;try{o=await e(),r=0}catch(c){if(c instanceof P&&c.retryable&&r<2){r+=1,await new Promise(l=>setTimeout(l,n));continue}throw c}if(o.status==="completed"||o.status==="failed")return o;await new Promise(c=>setTimeout(c,n))}throw new P("Operation timed out",408,1)}async function wc(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);delete n.idempotency_key,await qr("generateSfx",n);let i=await p("generateSfx",{...n,approvalReceipt:t?.approvalReceipt},r);return{id:i.runId,requestId:i.runId,status:"pending"}}async function Uo(e){let t=await R("generateSfx",e);return{id:t.entity?.id??e,requestId:e,status:Vr(t),audioUrl:t.entity?.url,error:t.error?.message}}async function vc(e,t){return p("listPresenterOptions",{...e?{voiceLanguage:e}:{},...t?{teamId:t}:{}})}async function Ic(e,t){return{requestId:(await p("generateAvatarVideo",e,t)).runId,status:"pending"}}async function _o(e){let t=await R("generateAvatarVideo",e);return{durationSec:typeof t.output?.durationSec=="number"?t.output.durationSec:null,error:t.error?.message,requestId:e,status:Vr(t),videoUrl:t.entity?.url}}async function kc(e,t,n){return p("lipsyncVideo",{...e,approvalReceipt:n},t??J())}async function xc(e,t,n){return p("clipVideo",{...e,approvalReceipt:n},t??J())}async function Rc(){return(await p("listTranslationLanguages",{})).languages}async function Cc(e,t,n){return p("translateVideo",{...e,approvalReceipt:n},t??J())}async function Sc(e,t,n){return p("createVideo",{...e,approvalReceipt:t},n)}async function Ec(e){let{idempotencyKey:t,...n}=e;return p("analyzeVideoReference",n,t)}async function Pc(e,t){return z("analyzeVideoReference",e,t)}async function Ac(e,t){return z("selectPresentationVideoStockMusic",e,t)}async function Tc(e,t){return z("preparePresentationVideoMediaSuggestions",e,t,null,{statusCommand:"presentation video suggestions status"})}async function Oc(e,t){return z("preparePresentationVideoSuggestionAction",e,t,null,{statusCommand:"presentation video suggestions action prepare status"})}async function $c(e,t){return z("preparePresentationVideoPreviews",e,t,null,{statusCommand:"presentation video previews status"})}async function Dc(e,t){return z("generateBrandVariations",e,t)}async function Nc(e,t){return z("extractBrandProducts",e,t)}async function Lc(e,t){return z("buildBrandVoice",e,t)}async function Uc(e,t){return z("generateBrandGuardrails",e,t)}async function _c(e,t){return z("repairBrandQuality",e,t)}async function jc(e,t){return z("syncBrandToPresentations",e,t)}async function qc(e,t){return z("syncBrandFoundation",e,t)}async function Mc(e){return p("listVoices",e)}async function Vc(e){return p("adoptLibraryVoice",e,J())}async function Fc(e){return p("setVoiceFavorite",e,J())}async function Bc(e){return p("setVoiceShortlisted",e,J())}async function Gc(e){return p("setVoicePolicy",e,J())}async function Kc(e){return p("requestVoiceApproval",e,J())}async function Wc(e){return p("listVoiceApprovalRequests",e,J())}async function Jc(e){return p("decideVoiceApprovalRequest",e,J())}async function zc(e){return p("setVoiceTone",e,J())}async function Hc(e){return p("setVoiceVisibility",e,J())}async function Xc(e){return p("setVoiceApproval",e,J())}async function Yc(e){return p("listVoiceApprovals",e,J())}async function Qc(e){return p("designVoice",e,J())}async function Zc(e){return p("saveDesignedVoice",e,J())}async function el(e){return p("retireVoice",e,J())}async function tl(e){return p("listCastPresets",e)}async function nl(e){return p("createCastPreset",e,J())}async function rl(e){return p("updateCastPreset",e,J())}async function il(e,t){return p("deleteCastPreset",{presetId:e,...t?{teamId:t}:{}},J())}var Uy="The command failed. Please try again.";function ol(e){return e.replace(/[\u0000-\u001f\u007f-\u009f]/g," ").trim()}function Po(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||typeof n.message!="string"||!n.message.trim())continue;let r=typeof n.path=="string"&&n.path.trim()?`${ol(n.path)}: `:"";t.push(` ${r}${ol(n.message)}`)}return t}function u(e,t=Uy){return e instanceof P&&e.message.trim()?[e.message,...Po(e.details)].join(`
8
- `):t}import{InvalidArgumentError as _y}from"commander";function b(e,t){return n=>{if(t.includes(n))return n;throw new _y(`Expected one of: ${t.join(", ")}. Run the command with --help to see what ${e} accepts.`)}}import V from"chalk";import jo from"cli-table3";function C(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(V.green("\u2713"),e)}function a(e,t="human"){if(t!=="quiet"){if(t==="json"){console.error(JSON.stringify({error:e}));return}console.error(V.red("\u2717"),e)}}function q(e,t="human"){t!=="quiet"&&t!=="json"&&console.warn(V.yellow("\u26A0"),e)}function al(e,t="human"){t==="quiet"||t==="json"||console.error(V.cyan("\u2192"),e)}function I(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(V.blue("\u2139"),e)}function yn(e,t="en"){return e?`${K()}/${t}/view/presentations/${e}`:"N/A"}function sl(e,t={}){let{showLinks:n=!1,language:r="en"}=t,i=(l,d)=>l.length>d?`${l.slice(0,d-1)}\u2026`:l,o=l=>{if(!l)return"-";try{return new Date(l).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(n){let l=new jo({head:[V.cyan("Slug"),V.cyan("Title"),V.cyan("Slides"),V.cyan("Created"),V.cyan("URL")]});for(let d of e)l.push([i(d.slug||d.id.slice(0,8),30),i(d.title||"Untitled",22),String(d.numberOfSlides||"-"),o(d.createdAt),yn(d.slug,r)]);return l.toString()}let c=new jo({head:[V.cyan("Slug"),V.cyan("Title"),V.cyan("Slides"),V.cyan("Mode"),V.cyan("Created")],colWidths:[32,28,8,11,18]});for(let l of e)c.push([l.slug||l.id.slice(0,8),l.title||"Untitled",String(l.numberOfSlides||"-"),l.mode||"-",o(l.createdAt)]);return c.toString()}function dl(e){let t=[...e].sort((i,o)=>{if(i.isDefault&&!o.isDefault)return-1;if(!i.isDefault&&o.isDefault)return 1;let c=i.createdAt?new Date(i.createdAt).getTime():0;return(o.createdAt?new Date(o.createdAt).getTime():0)-c}),n=i=>{if(!i)return"-";try{return new URL(i).href}catch{return i.startsWith("http")?i:`https://${i}`}},r=new jo({head:[V.cyan("Name"),V.cyan("Source"),V.cyan("Color"),V.cyan("Logo"),V.cyan("Default"),V.cyan("ID")]});for(let i of t){let o=i.primaryColor?`${V.bgHex(i.primaryColor)(" ")} ${i.primaryColor}`:"-";r.push([i.name,n(i.sourceUrl),o,i.logoUrl?V.green("\u2713"):V.gray("\u2717"),i.isDefault?V.green("\u2605"):"",i.id])}return r.toString()}function qo(e){try{return new Date(e).toLocaleString()}catch{return e}}function De(e){console.log(),console.log(V.bold(e)),console.log(V.gray("\u2500".repeat(e.length)))}function O(e,t){console.log(` ${V.gray(`${e}:`)} ${t??"-"}`)}function jy(e){return JSON.stringify(e,null,2)}function m(e){console.log(jy(e))}var Br=[{billing:"free",category:"knowledge",description:"Select an exact completed video as accepted while preserving prior outputs.",id:"acceptMissionOutput",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output accept",operation:"mutation",scopes:["knowledge:write","presentations:read","media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Accept the artifact that fills one of a mission item's outputs, bound to its exact version and what it was made from.",id:"acceptMissionOutputSlot",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output accept-slot",operation:"mutation",scopes:["knowledge:write","presentations:read"],state:"available"},{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:"free",category:"knowledge",description:"Adopt an artifact into a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"adoptMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission adopt",operation:"mutation",scopes:["knowledge: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:"presentations",description:"Apply Reviewed Scene Change without generating new content.",id:"applyPresentationVideoSuggestionAction",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action apply",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:"knowledge",description:"Record receipt-bound human approval of the exact narration checkpoint without starting rendering.",id:"approveMissionNarration",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission review approve",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations: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:"free",category:"media",description:"Cancel one in-flight video generation, translation, clip, lipsync, avatar, or narrated-video render run in this workspace.",id:"cancelVideoRun",lifecycle:{mode:"bounded"},milestone:"M8",name:"video cancel",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Check a deck version against its linked brand's guardrail rules.",id:"checkPresentationGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation guardrails",operation:"query",scopes:["brands:read","presentations:read"],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:"free",category:"presentations",description:"Copy a scene's effective avatar \u2014 presenter identity plus its placement box \u2014 into a portable clipboard string that paste_presentation_video_presenter applies to scenes in any presentation video.",id:"copyPresentationVideoPresenter",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video copy-presenter",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"delegated",category:"artifacts",description:"Generate and persist an ad variation set: short-form video ads from hooks, or governed static ads from approved templates filled only with the brand's approved claims.",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:"artifacts",description:"Create a governed ad template as a lint-checked draft (version 1).",id:"createAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template create",operation:"mutation",scopes:["brands: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:"presentations",description:"Create a guest review link for a pinned presentation revision, choosing an isolated or shared guest room and an optional verified-only posting policy.",id:"createDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link create",operation:"mutation",scopes:["presentations: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:"free",category:"presentations",description:"Build a governed HCP deck from a brand's approved claims library, with locked ISI and References slides.",id:"createGovernedDeck",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed create",operation:"generation",scopes:["presentations: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:"knowledge",description:"Create a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"createMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission create",operation:"mutation",scopes:["knowledge: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:"free",category:"presentations",description:"Prepare scoped read-only Studio access for an authorized presentation, workspace catalog, owned creation/edit/speaker-notes run progress, or private request-bound approval delivery.",id:"createPresentationStudioLaunch",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation studio-launch",operation:"query",scopes:["presentations:read"],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:"knowledge",description:"Create a quiz, flashcard set or cheat sheet from explicit caller-supplied items.",id:"createStudySet",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"delegated",category:"agents",description:"Spawn one or more child chat threads that each run as their own durable chat turn under a parent chat.",id:"createThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread create",operation:"mutation",scopes:["chat-threads: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:"Copy a pinned stock video template into a separate editable Studio draft. No speech, avatar or render is generated.",id:"createVideoFromTemplate",lifecycle:{mode:"bounded"},milestone:"M8",name:"video templates create",operation:"mutation",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:"knowledge",description:"Permanently delete a mission and its machinery; optionally destroy the decks and narrated videos it produced.",id:"deleteMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission delete",operation:"mutation",scopes:["knowledge:write","presentations: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:"free",category:"presentations",description:"Delete a finished, failed, or cancelled presentation render attempt, optionally with the video it produced.",id:"deletePresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video delete-render",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"knowledge",description:"Delete a workspace- or member-owned skill. Removes its body and assets.",id:"deleteTeamSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills delete",operation:"mutation",scopes:["skills:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Design new or existing video scenes using presentation style, brand and uploaded sources.",id:"designPresentationVideoScenes",lifecycle:{mode:"background",status:{cliCommand:"presentation video-scene-design status",pollAfterSeconds:10}},milestone:"M4",name:"presentation video-scene-design",operation:"generation",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:"delegated",category:"presentations",description:"Apply a metered edit to an authorized current presentation version and save the result.",id:"editPresentation",lifecycle:{mode:"background",status:{cliCommand:"presentation edit status",pollAfterSeconds:10}},milestone:"M8",name:"presentation edit",operation:"mutation",scopes:["presentations: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. add_interaction, update_interaction and remove_interaction manage the interactive overlays a player honours around the rendered video \u2014 buttons, choices, quiz questions and scene-end actions; adding or updating one requires the workspace's interactive-video capability and a Team or Enterprise plan, while removal stays open to every plan. Interactions never move the draft's render fingerprint. update_card changes a card scene's background (a hex colour, an image or deck-slide backdrop resolved like add_scene_layer sources, or the brand default), its visible text via textHidden \u2014 never an empty title \u2014 and its subtitle.",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:"branding",description:"Export an approved governed static set or deck version as a PromoMats-ready package.",id:"exportForPromoMats",lifecycle:{mode:"bounded"},milestone:"M2",name:"promomats export",operation:"query",scopes:["brands:read","presentations:read"],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:"free",category:"presentations",description:"Package a finished presentation video as a downloadable SCORM zip whose launcher embeds a revocable video link and reports watch completion and quiz results to the LMS. Bounded synchronous work: one share row, a small zip, one private upload - no provider call. passMarkPercent requires the latest published interaction manifest to contain a question.",id:"exportPresentationVideoScorm",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm export",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"workspace",description:"Export who did what in a workspace (admins only) as JSON or CSV.",id:"exportWorkspaceAuditLog",lifecycle:{mode:"bounded"},milestone:"M8",name:"audit-log export",operation:"query",scopes:["audit: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:"Create a right-way or wrong-way clip from a picture or prompt and attach it to video scenes.",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:"artifacts",description:"Read one governed ad template version with its HTML, slots, sizes and lint report.",id:"getAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template get",operation:"query",scopes:["brands:read"],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 saved video voices and presenters.",id:"getBrandVideoDefaults",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults 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:"branding",description:"Read one governed claim at a version, with its references and version history.",id:"getClaim",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"presentations",description:"Read a governed deck version's claim map and a fresh pre-submission check report.",id:"getGovernedDeck",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed get",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:"free",category:"branding",description:"Read one ISI or legal block at a version, with its version history.",id:"getLegalBlock",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"media",description:"Read safe recording metadata and a bounded page of its transcript or precise stored word evidence before choosing cuts.",id:"getMediaAsset",lifecycle:{mode:"bounded"},milestone:"M8",name:"media show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Get a mission\u2019s status using durable intended outcomes and permission-checked native artifact links. No generation or acceptance. Every item and output carries one status vocabulary (not_started, in_progress, waiting_for_you, ready, final, changed_since_final). historyItemId also returns that item's version history: each output's versions, what each was made from, and which were accepted. waitForSourceImportMs (max 15000) is only for a free PowerPoint source import: it holds the read while the mission's import is still running so one reply can report the outcome, and is ignored when no source import is running (never use it for billed stages such as notes, narration, render or deck generation); it changes nothing.",id:"getMissionStatus",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission status",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 saved scene critiques and media ideas, version history and whether they match the current draft.",id:"getPresentationVideoMediaSuggestions",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions inspect",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:"Inspect Scene Changes without generating new content.",id:"getPresentationVideoSuggestionActions",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action inspect",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:"knowledge",description:"Read one skill's metadata and SKILL.md body.",id:"getSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills show",operation:"query",scopes:["skills:read"],state:"available"},{billing:"free",category:"knowledge",description:"Read a study set with its full items and their stable ids.",id:"getStudySet",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set get",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"agents",description:"Read one child chat thread's status, run id, and settled result.",id:"getThread",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread get",operation:"query",scopes:["chat-threads:read"],state:"available"},{billing:"free",category:"agents",description:"Read a child chat thread's transcript, newest page first.",id:"getThreadMessages",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread messages",operation:"query",scopes:["chat-threads:read"],state:"available"},{billing:"free",category:"media",description:"Read how many people watched a shared video, how far they got, and how they answered its published interactions.",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:"branding",description:"Import a brand's claims library from a PromoMats export: preview, then commit; never approves.",id:"importClaims",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"free",category:"knowledge",description:"Fill one of a mission item's manual outputs with an existing presentation or finished video, replacing any earlier link.",id:"linkMissionOutput",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output link",operation:"mutation",scopes:["knowledge:write","presentations: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:"artifacts",description:"List a brand's governed ad templates.",id:"listAdTemplates",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template list",operation:"query",scopes:["brands:read"],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:"branding",description:"List a brand's governed claims with status, scope and references.",id:"listClaims",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims list",operation:"query",scopes:["brands: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 the members and roster agents a caller may mention on a document.",id:"listDiscussionMentionables",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion mentionables",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the guest review links on a presentation with their pinned revision, room, posting policy, expiry and revocation state.",id:"listDiscussionReviewLinks",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link list",operation:"query",scopes:["presentations:write"],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:"media",description:"Discover six immutable footage caption treatment versions with bounded concrete defaults. Requires footage-caption-treatments and effective Footage Studio access.",id:"listFootageCaptionTreatments",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage caption-treatments",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"presentations",description:"List the caller's durable collaboration inbox items (mentions, assignments, review requests).",id:"listInboxItems",lifecycle:{mode:"bounded"},milestone:"M4",name:"inbox list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's ISI and legal blocks with variant, placement and status.",id:"listLegalBlocks",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks list",operation:"query",scopes:["brands: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:"knowledge",description:"List missions using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"listMissions",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"List deck embed shares without bearer tokens. Write access required; recovery stays available on any plan.",id:"listPresentationDeckEmbedShares",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List or search 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 standalone embed shares without bearer tokens. Write access required; recovery remains available on any plan.",id:"listPresentationVideoEmbedShares",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed list",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 every SCORM export minted for a presentation video project with its settings and revocation state; export tokens are never returned. Available on any plan so a downgraded workspace can still take links down.",id:"listPresentationVideoScormExports",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm list",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:"knowledge",description:"List the skills available to the workspace, including the team's own disabled skills.",id:"listSkills",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills list",operation:"query",scopes:["skills: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:"knowledge",description:"List the workspace's study sets, newest first, optionally filtered by kind.",id:"listStudySets",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set list",operation:"query",scopes:["knowledge: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:"agents",description:"List the child chat threads spawned under a parent chat, with status, run id, and settled result.",id:"listThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread list",operation:"query",scopes:["chat-threads: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 immutable video templates available to this workspace.",id:"listVideoTemplates",lifecycle:{mode:"bounded"},milestone:"M8",name:"video templates list",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. Pass scope 'mine' for only the caller's own work. Kinds whose domains carry their own read scope (presentations, videos) are only included when the caller's grant covers them.",id:"listWorkItems",lifecycle:{mode:"bounded"},milestone:"M1",name:"work list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"Mark the caller's collaboration inbox items as read.",id:"markInboxItemsRead",lifecycle:{mode:"bounded"},milestone:"M4",name:"inbox mark-read",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a free revocable embed link for a public deck. Team plan and embed-links required. Bounded insert; duplicate keys reject and tokens are returned once. No separate approval for an explicitly requested reversible link.",id:"mintPresentationDeckEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed mint",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a free revocable embed link for a finished presentation video. Team plan and embed-links flag required. Bounded single insert; duplicate keys reject and tokens are returned once. No separate approval for this reversible, explicitly requested link.",id:"mintPresentationVideoEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed mint",operation:"mutation",scopes:["presentations:write"],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:"presentations",description:"Apply a copied avatar \u2014 presenter identity plus its placement box \u2014 from a mindframes/presenter@1 clipboard string to one scene or an exact slideIds batch in any presentation video, adapting the box to the target format.",id:"pastePresentationVideoPresenter",lifecycle:{mode:"bounded"},milestone:"M5",name:"presentation video paste-presenter",operation:"mutation",scopes:["presentations: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:"delegated",category:"knowledge",description:'Prepare selected mission items for narration review: each item imports its source (PowerPoint) or generates a deck from a document source, creates its draft, optionally writes speaker notes (`notes`) and generates narration (`narrate`) \u2014 both billed and opt-in \u2014 and requests the human review \u2014 independently and durably. A draft that ends with zero narration is never frozen for review: the item routes back to `narrate` when the request authorized it, or stops `narration_missing` (`narrate_not_authorized` when the request never authorized `narrate` \u2014 a pending yes, not a failure). `review` reads narration that already exists: for a freshly imported deck whose narration the user has not approved, send `stages: ["import", "draft"]` and add `narrate` and `review` only after the user says yes to billed narration. Approving a free import never starts billed work or needs that yes; an item whose request reviews narration it never generated stops `narrate_not_authorized` until the user consents. Document sources spend billed deck generation inside the import stage; the request must set allowDeckGeneration: true to admit them. The `post` stage writes a billed LinkedIn post from the item\'s deck for items whose output plan has one, the `reel` stage renders a billed 15-second vertical reel from it, and the `agent` stage runs the team agent an output names (fulfilment agent) and saves its answer as the output\'s document; naming each stage is its consent. reviewPolicy sets where this request stops for a person (overriding the mission\'s; frozen at admission). creditCeiling caps the credits the request may commit: each billed step reserves a conservative estimate before it starts, and one that would pass the ceiling does not start (its item stops credit_ceiling_reached).',id:"prepareMission",lifecycle:{mode:"background",status:{cliCommand:"mission prepare status",pollAfterSeconds:10}},milestone:"M1",name:"mission prepare",operation:"generation",scopes:["knowledge:write","presentations:read","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:"Review one narrated-video scene in the full draft context and propose concrete improvements; retain useful suggestions across minor edits.",id:"preparePresentationVideoMediaSuggestions",lifecycle:{mode:"background",status:{cliCommand:"presentation video suggestions status",pollAfterSeconds:2}},milestone:"M8",name:"presentation video suggestions 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:"dynamic",category:"presentations",description:"Prepare and retain an isolated narration or editable text-layer change for review.",id:"preparePresentationVideoSuggestionAction",lifecycle:{mode:"background",status:{cliCommand:"presentation video suggestions action prepare status",pollAfterSeconds:2}},milestone:"M8",name:"presentation video suggestions action prepare",operation:"generation",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:"presentations",description:"Freeze the draft's interactions onto the finished video as an immutable, versioned manifest resolved against the render's persisted scene timeline. Omitting renderId publishes onto the project's current video; an unchanged republish returns the latest manifest with created:false, and publishing an empty interactions list unpublishes.",id:"publishPresentationVideoInteractions",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video interaction publish",operation:"mutation",scopes:["presentations: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 saved Footage project and version history, 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:"knowledge",description:"Read a bounded window of a Library file's extracted text (for example its chapter list) before planning work from it.",id:"readLibraryFileExcerpt",lifecycle:{mode:"bounded"},milestone:"M1",name:"file excerpt",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:"knowledge",description:"Reconcile a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"reconcileMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission reconcile",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"delegated",category:"knowledge",description:"Finish an interrupted render start from its recorded intent identity, or report the recovery state for another principal without granting their spend or retry authority.",id:"recoverMissionRenderIntent",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output render recover",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations: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:"delegated",category:"knowledge",description:"Regenerate one of a mission item's automated outputs: the deck from its source (a PowerPoint re-imports free; a document source needs allowDeckGeneration), the narrated video from the current deck (new narration needs allowNarration), the LinkedIn post from the current deck (billed; needs allowTextGeneration), the reel from the current deck (a billed render; needs allowReelRender), or an output a team agent delivers (a billed agent run; needs allowAgentRuns). The current output stays until the new one is ready.",id:"regenerateMissionOutput",lifecycle:{mode:"background",status:{cliCommand:"mission output regenerate status",pollAfterSeconds:10}},milestone:"M1",name:"mission output regenerate",operation:"generation",scopes:["knowledge:write","presentations:read","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:"knowledge",description:"Start or safely resume rendering the exact human-approved narration checkpoint for one mission item.",id:"renderMissionOutput",lifecycle:{mode:"background",status:{cliCommand:"mission output render status",pollAfterSeconds:10}},milestone:"M1",name:"mission output render",operation:"generation",scopes:["knowledge:write","presentations:read","presentations: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:"knowledge",description:"Replace a mission's complete order: phases and every live item, including moves between phases, without touching running preparation.",id:"reorderMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission reorder",operation:"mutation",scopes:["knowledge: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:"knowledge",description:"Replace a mission item source with a Library PowerPoint and resume its free blocked import without widening preparation consent.",id:"replaceMissionItemSource",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission source replace",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Freeze a narration draft for human review; rendering remains manual.",id:"requestMissionNarrationReview",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission review request",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Run a bounded specialist review of a frozen presentation revision; findings land in the deck's discussion.",id:"requestPresentationReview",lifecycle:{mode:"background",status:{cliCommand:"presentation review status",pollAfterSeconds:3}},milestone:"M4",name:"presentation review request",operation:"mutation",scopes:["presentations: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 Applied Scene Change without generating new content.",id:"restorePresentationVideoSuggestionAction",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action restore",operation:"mutation",scopes:["presentations: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:"presentations",description:"Revoke a guest review link. Every guest session it admitted is fenced on the next read or write.",id:"revokeDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a deck embed share with no separate approval for explicitly requested access removal. Write access required. CAS preserves the original timestamp; recovery stays available on any plan.",id:"revokePresentationDeckEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a standalone video embed share. Free reversible access removal with no separate approval; repeated calls preserve the revocation timestamp. Write access required; recovery remains available on any plan.",id:"revokePresentationVideoEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a SCORM export's embed link so it stops resolving for LMS learners. Idempotent: a second call returns the same revokedAt. Available on any plan.",id:"revokePresentationVideoScormExport",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm revoke",operation:"mutation",scopes:["presentations: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. missionId narrows to a mission's deliverables and missionStatus to deliverables at those statuses (not_started, in_progress, waiting_for_you, ready, final, changed_since_final); a result that is a mission deliverable carries fromMission.",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:"free",category:"presentations",description:"Select a saved version of scene suggestions without applying changes, generating media or changing the scene.",id:"selectPresentationVideoMediaSuggestionsVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions select",operation:"mutation",scopes:["presentations: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:"delegated",category:"agents",description:"Send a message into an existing child chat thread: delivered live into a running turn, queued when the turn cannot take guidance, or starts a new durable turn.",id:"sendThreadMessage",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread send",operation:"mutation",scopes:["chat-threads: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:"artifacts",description:"Set the poster image an artifact shows on cards and share surfaces, or reset it to the automatic preview.",id:"setArtifactPoster",lifecycle:{mode:"bounded"},milestone:"M8",name:"artifact poster set",operation:"mutation",scopes:["knowledge: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:"Set or clear a brand's default opening and closing card scenes for narrated presentation videos. Free reversible brand configuration.",id:"setBrandVideoBookends",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-bookends",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's saved video presenter defaults.",id:"setBrandVideoPresenters",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-presenters",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's saved video voice defaults.",id:"setBrandVideoVoices",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-voices",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:"Create or edit a draft claim, or restrict or retire one; never approves.",id:"setClaim",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"Assign an accountable team member to a discussion thread; notifies the assignee.",id:"setDiscussionAssignee",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion assign",operation:"mutation",scopes:["presentations: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:"Hide or restore a discussion message. Authors moderate their own messages; members moderate guest review activity. Hidden rows are excluded from guest reads.",id:"setDiscussionMessageVisibility",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion message visibility",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Replace the requested reviewers on a discussion thread; newly added reviewers are notified.",id:"setDiscussionReviewers",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion reviewers",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:"Switch one claim slot of a governed deck to another approved claim; references are renumbered.",id:"setGovernedDeckClaim",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed set-claim",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Create or edit a draft ISI or legal block, or restrict or retire one; never approves.",id:"setLegalBlock",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Archive a mission so finished work leaves the active list, or restore it. Archiving is housekeeping: all history stays addressable and nothing in the pipeline stops.",id:"setMissionArchived",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission archive",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Star a mission so it stays at the top of your list, or remove the star. A star is a personal shortcut, never a permission.",id:"setMissionFavorite",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission favorite",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Pin a mission for the whole workspace, or lift the pin. The pin is the workspace's shared mark, visible to every member.",id:"setMissionPin",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission pin",operation:"mutation",scopes:["knowledge: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:"Add a voice to your team's shortlist, or remove it. A shortlist is shared by the whole workspace and grants no permission.",id:"setVoiceShortlisted",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice shortlist",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:"knowledge",description:"Start or explicitly retry an independent PowerPoint import for one mission item and its current Library source.",id:"startMissionSourceImport",lifecycle:{mode:"background",status:{cliCommand:"mission source import status",pollAfterSeconds:10}},milestone:"M1",name:"mission source import",operation:"generation",scopes:["knowledge:write","presentations:write"],state:"available"},{billing:"free",category:"knowledge",description:"Stop in-flight mission preparation: the named live items (or every live item when omitted) stop typed cancelled, their in-flight child generation, import, and narration runs are cancelled, and the coordinator run settles cancelled. Completed work is not un-billed or undone.",id:"stopMissionPreparation",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission prepare stop",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Stop a running child chat thread by requesting cancellation of its durable run and live worker.",id:"stopThread",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread stop",operation:"mutation",scopes:["chat-threads: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:"artifacts",description:"Save a new draft version of a governed ad template; earlier versions stay unchanged.",id:"updateAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template update",operation:"mutation",scopes:["brands: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:"presentations",description:"Edit a discussion message's body. Only the attributed author may edit; sets editedAt.",id:"updateDiscussionMessage",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion message update",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Update a guest review link's label, posting policy, expiry or pinned revision under optimistic concurrency.",id:"updateDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link update",operation:"mutation",scopes:["presentations: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:"knowledge",description:"Append intended items or update goals and sources while retaining previously accepted outputs.",id:"updateMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission 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"},{billing:"free",category:"knowledge",description:"Create or update a workspace- or member-owned skill from a SKILL.md document plus optional bundled files.",id:"upsertTeamSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills create",operation:"mutation",scopes:["skills:write"],state:"available"},{billing:"free",category:"agents",description:"Wait until child chat threads reach a terminal state and return their final status and results.",id:"waitThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread wait",operation:"query",scopes:["chat-threads:read"],state:"available"}],Mo={updatePresentationVideoSettings:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{basedOnVersionNumber:{type:"integer",minimum:1,maximum:9007199254740991},branchId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},expectedHeadVersionNumber:{type:"integer",minimum:1,maximum:9007199254740991},captionBackgroundColor:{description:"Caption box color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionFontFamily:{description:"Caption CSS font-family list.",type:"string",minLength:1,maxLength:180},captionFontSize:{description:"Caption font size in pixels, from 20 to 96.",type:"integer",minimum:20,maximum:96},captionHeight:{description:"Caption box height as a frame fraction, from 0.05 to 0.5.",type:"number",minimum:.05,maximum:.5},captionHighlightColor:{description:"Current-word highlight color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionTextColor:{description:"Caption text color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionWidth:{description:"Caption box width as a frame fraction, from 0.18 to 0.95.",type:"number",minimum:.18,maximum:.95},captionX:{description:"Caption box center on the horizontal axis, from 0 to 1.",type:"number",minimum:0,maximum:1},captionY:{description:"Caption box center on the vertical axis, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterAnchor:{description:"Presenter box preset, or free for explicit x/y placement.",type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},presenterApplyToAll:{description:"Promote the targeted scene's resulting placement to the project default and clear every per-scene placement override. Requires presenterSlideId.",type:"boolean",const:!0},presenterBackgroundFit:{description:"How a presenter background image fills the frame.",type:"string",enum:["cover","contain"]},presenterBackgroundHex:{description:"Presenter background color, required for kind=color.",type:"string",pattern:"^#[0-9a-fA-F]{6}$"},presenterBackgroundKind:{description:"Presenter background type. color requires presenterBackgroundHex; image requires presenterBackgroundUrl.",type:"string",enum:["original","transparent","color","image"]},presenterBackgroundUrl:{description:"Hosted presenter background image URL, required for kind=image.",type:"string",maxLength:2048,format:"uri"},presenterBorderRadius:{description:"Presenter corner radius from 0 (square) to 0.5 (circle or pill).",type:"number",minimum:0,maximum:.5},presenterFramingX:{description:"Horizontal crop focus inside the presenter box, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterFramingY:{description:"Vertical crop focus inside the presenter box, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterFramingZoom:{description:"Presenter media crop zoom, from 1 to 2.",type:"number",minimum:1,maximum:2},presenterHeight:{description:"Explicit presenter box height as a frame fraction, from 0.05 to 1.",type:"number",minimum:.05,maximum:1},presenterOffsetX:{description:"Horizontal edge offset for anchored placement, from 0 to 0.35.",type:"number",minimum:0,maximum:.35},presenterOffsetY:{description:"Vertical edge offset for anchored placement, from 0 to 0.35.",type:"number",minimum:0,maximum:.35},presenterSize:{description:"Presenter box width as a frame fraction, from 0.08 to 0.9.",type:"number",minimum:.08,maximum:.9},presenterSlideId:{description:"Scene whose presenter placement, visibility, or scene-specific background should change. Omit to edit the project default placement/background.",type:"string",minLength:1,maxLength:240},presenterUseDefault:{description:"Remove this scene's placement override so it uses the project default. Requires presenterSlideId.",type:"boolean",const:!0},presenterVisible:{description:"Show or hide the presenter on one scene. Requires presenterSlideId. Showing restores project-default inheritance, matching the editor.",type:"boolean"},presenterX:{description:"Presenter box horizontal center, from 0 to 1; valid only for a free placement.",type:"number",minimum:0,maximum:1},presenterY:{description:"Presenter box vertical center, from 0 to 1; valid only for a free placement.",type:"number",minimum:0,maximum:1},projectId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",description:"Presentation video project whose saved setup should be updated."},settings:{description:"Advanced partial settings profile to merge into the saved project. Use the typed caption fields for caption placement and style.",type:"object",properties:{avatarId:{description:"Avatar or look id from `avatar options` to present the whole video. The server resolves the presenter identity and render tier. Alternative to `presenter`; to remove the presenter pass presenter: null.",type:"string",minLength:1,maxLength:240},captions:{description:"Render word-level captions when narration timings exist.",type:"boolean"},captionPlacement:{description:"Move or resize the caption box with normalized x, y, width, and height values. Omitted fields keep their saved values.",type:"object",properties:{height:{type:"number",minimum:.05,maximum:.5,description:"Caption box height as a frame fraction, from 0.05 to 0.5."},width:{type:"number",minimum:.18,maximum:.95,description:"Caption box width as a frame fraction, from 0.18 to 0.95."},x:{type:"number",minimum:0,maximum:1,description:"Caption box center on the horizontal axis, from 0 to 1."},y:{type:"number",minimum:0,maximum:1,description:"Caption box center on the vertical axis, from 0 to 1."}}},captionStyle:{description:"Change caption font, size, text, highlight, or background colors. Omitted fields keep their saved values.",type:"object",properties:{backgroundColor:{description:"Caption box color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},fontFamily:{description:"Caption CSS font-family list.",type:"string",minLength:1,maxLength:180},fontSizePx:{description:"Caption font size in pixels, from 20 to 96.",type:"integer",minimum:20,maximum:96},highlightColor:{description:"Current-word highlight color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},textColor:{description:"Caption text color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180}}},format:{description:"Output aspect ratio for the MP4.",type:"string",enum:["16:9","9:16","1:1"]},music:{description:"Background music settings to merge into the saved project.",type:"object",properties:{audioUrl:{type:"string",format:"uri"},fileName:{type:"string",maxLength:240},matchDeckStyle:{type:"boolean"},mode:{default:"basic",type:"string",enum:["basic","standard","stock","upload","off"]},prompt:{type:"string",minLength:1,maxLength:8e3},regenerateToken:{type:"string",minLength:1,maxLength:64},stockDurationSec:{type:"number",exclusiveMinimum:0,maximum:86400},stockSelection:{type:"string",enum:["auto","manual"]},stockTrackId:{type:"string",minLength:1,maxLength:500},volume:{default:.12,type:"number",minimum:0,maximum:1}}},narrationAudioTags:{description:"Use audio tags such as [short pause] or [excited] in the narration: written in when narration is generated, and performed by voices that support them. false keeps any tags in the text but removes them before speech. Has an effect only where audio tags are enabled for the workspace.",type:"boolean"},narrationDensity:{description:"How much narration to generate per slide.",type:"string",enum:["brief","balanced","deep"]},presenter:{description:"Selected avatar/presenter, or null to remove it.",anyOf:[{type:"object",properties:{assetClass:{type:"string",enum:["digital_twin","photo_avatar","studio_avatar"]},background:{oneOf:[{type:"object",properties:{kind:{type:"string",const:"original"}},required:["kind"]},{type:"object",properties:{kind:{type:"string",const:"transparent"}},required:["kind"]},{type:"object",properties:{hex:{type:"string",pattern:"^#[0-9a-fA-F]{6}$"},kind:{type:"string",const:"color"}},required:["hex","kind"]},{type:"object",properties:{fit:{default:"cover",type:"string",enum:["cover","contain"]},kind:{type:"string",const:"image"},url:{type:"string",maxLength:2048,format:"uri"}},required:["kind","url"]}]},defaultPlacement:{type:"object",properties:{anchor:{type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},framing:{default:{x:.5,y:.1,zoom:1},type:"object",properties:{x:{default:.5,type:"number",minimum:0,maximum:1},y:{default:.1,type:"number",minimum:0,maximum:1},zoom:{default:1,type:"number",minimum:1,maximum:2}}},borderRadius:{default:0,type:"number",minimum:0,maximum:.5},offsetX:{default:.04,type:"number",minimum:0,maximum:.35},offsetY:{default:.05,type:"number",minimum:0,maximum:.35},size:{default:.24,type:"number",minimum:.08,maximum:.9},height:{type:"number",minimum:.05,maximum:1},x:{type:"number",minimum:0,maximum:1},y:{type:"number",minimum:0,maximum:1}},required:["anchor"]},delivery:{type:"object",properties:{expressiveness:{type:"string",enum:["low","medium","high"]},motionPrompt:{type:"string",minLength:1,maxLength:600},resolution:{type:"string",enum:["720p","1080p","4k"]}}},lookId:{type:"string",minLength:1},name:{type:"string",minLength:1,maxLength:160},presenterId:{type:"string",minLength:1},previewImageUrl:{type:"string",format:"uri"},renderTier:{type:"string",enum:["basic","standard","premium"]},source:{type:"object",properties:{height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},orientation:{type:"string",enum:["landscape","portrait","square"]},width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["height","orientation","width"]},perSlideEnabled:{default:{},type:"object",propertyNames:{type:"string"},additionalProperties:{type:"boolean"}},perSlidePlacements:{default:{},type:"object",propertyNames:{type:"string"},additionalProperties:{type:"object",properties:{anchor:{type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},framing:{default:{x:.5,y:.1,zoom:1},type:"object",properties:{x:{default:.5,type:"number",minimum:0,maximum:1},y:{default:.1,type:"number",minimum:0,maximum:1},zoom:{default:1,type:"number",minimum:1,maximum:2}}},borderRadius:{default:0,type:"number",minimum:0,maximum:.5},offsetX:{default:.04,type:"number",minimum:0,maximum:.35},offsetY:{default:.05,type:"number",minimum:0,maximum:.35},size:{default:.24,type:"number",minimum:.08,maximum:.9},height:{type:"number",minimum:.05,maximum:1},x:{type:"number",minimum:0,maximum:1},y:{type:"number",minimum:0,maximum:1}},required:["anchor"]}}},required:["defaultPlacement","lookId","name","presenterId","renderTier"]},{type:"null"}]},speakerNotesMode:{description:"How narration treats the deck's speaker notes: `as_is` copies each applicable note into its scene verbatim with no generation, `as_reference` hands notes to the model as source material. `ignored` skips the note entirely: it never reaches the model and the scene is narrated from the slide alone.",type:"string",enum:["as_is","as_reference","ignored"]},speakerNotesModeBySlide:{description:"Per-scene exceptions to speakerNotesMode, keyed by scene id. Replaces the saved exceptions; an empty object clears them.",type:"object",propertyNames:{type:"string"},additionalProperties:{type:"string",enum:["as_is","as_reference","ignored"]}},renderEngine:{description:"Terminal renderer for the MP4.",type:"string",enum:["remotion","hyperframes"]},renderTier:{description:"Render tier for `avatarId`. Only valid together with avatarId; defaults to the look's standard tier.",type:"string",enum:["basic","standard","premium"]},voice:{description:"Selected narration voice, or null to clear it.",anyOf:[{type:"object",properties:{description:{anyOf:[{type:"string"},{type:"null"}]},id:{type:"string",minLength:1},label:{type:"string",minLength:1,maxLength:160}},required:["id","label"]},{type:"null"}]},sceneVoiceIds:{description:"Merge narration voice overrides by exact composition scene ID. Omitted scenes and the default voice stay unchanged. Use all desired scene IDs to apply to multiple scenes. Giving a voice-disabled scene a voice turns its narration back on.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{type:"string",minLength:1}},sceneVoiceEnabled:{description:"Turn narration off (false) or back on (true) by exact composition scene ID. A disabled scene keeps its narration text, voice override and tone, renders silent for its current duration, and generates no voiceover or presenter clip; it does not fall back to the default voice. Omitted scenes stay unchanged.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{type:"boolean"}},voiceId:{description:"Narration voice id from `avatar options`. The server resolves its label. Alternative to `voice`; to clear the voice pass voice: null.",type:"string",minLength:1,maxLength:240},voiceTone:{description:"How every narrated scene is performed: a preset and/or stability, expressiveness and speed. Replaces the saved tone; null clears it so each voice uses its own default. Recorded clones keep the delivery of their recording. Changes re-voice affected scenes on the next render.",anyOf:[{type:"object",properties:{preset:{description:"Named tone: professional (steady and neutral \u2014 the default for narration), conversational (the speech provider's balanced defaults) or energetic (lively, animated). Individual values override it.",type:"string",enum:["professional","conversational","energetic"]},stability:{description:"0-1. Higher reads more evenly and consistently; lower widens the emotional range.",type:"number",minimum:0,maximum:1},expressiveness:{description:"0-1. How much the read exaggerates emphasis and emotion. 0 is neutral.",type:"number",minimum:0,maximum:1},speed:{description:"0.7-1.2 speaking pace, 1 is normal.",type:"number",minimum:.7,maximum:1.2}},additionalProperties:!1},{type:"null"}]},sceneVoiceTones:{description:"Merge per-scene tone overrides by exact composition scene ID; null removes a scene's override. Omitted scenes stay unchanged.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{anyOf:[{type:"object",properties:{preset:{description:"Named tone: professional (steady and neutral \u2014 the default for narration), conversational (the speech provider's balanced defaults) or energetic (lively, animated). Individual values override it.",type:"string",enum:["professional","conversational","energetic"]},stability:{description:"0-1. Higher reads more evenly and consistently; lower widens the emotional range.",type:"number",minimum:0,maximum:1},expressiveness:{description:"0-1. How much the read exaggerates emphasis and emotion. 0 is neutral.",type:"number",minimum:0,maximum:1},speed:{description:"0.7-1.2 speaking pace, 1 is normal.",type:"number",minimum:.7,maximum:1.2}},additionalProperties:!1},{type:"null"}]}}},additionalProperties:!1}},required:["projectId"],additionalProperties:!1}};function Gr(e){return{capabilities:Br,catalogVersion:1,reason:e,settingsSchemas:Mo,source:"snapshot"}}async function bn(e=Hd){try{let{capabilities:t,catalogVersion:n,settingsSchemas:r}=await e();return!Array.isArray(t)||t.length===0?Gr("the live catalog returned no capabilities"):{capabilities:t,catalogVersion:n,settingsSchemas:r??Mo,source:"live"}}catch(t){let n=t instanceof Error?t.message:String(t);return Gr(n)}}var cl=["presentations","media","branding","knowledge","research","artifacts","agents","support"],Vy=80,Fy=30;function By(e){return e.billing!==void 0&&e.billing!=="free"&&e.billing!=="quota"}function Gy(e){return e.lifecycle?.mode==="background"}function Ky(e,t){if(t<=0)return[e];let n=[],r="";for(let i of e.split(/\s+/).filter(Boolean))r===""?r=i:r.length+1+i.length<=t?r=`${r} ${i}`:(n.push(r),r=i);return r!==""&&n.push(r),n.length>0?n:[""]}function ll(e){let t=cl.indexOf(e);return t===-1?cl.length:t}function Wy(e,t){let n=t.search?.trim().toLowerCase(),r=t.category?.trim().toLowerCase();return e.filter(i=>r&&(i.category??"").toLowerCase()!==r?!1:n?`${i.name} ${i.description??""}`.toLowerCase().includes(n):!0)}function Jy(e){let t=new Map;for(let o of e){let c=o.category??"other",l=t.get(c);l?l.push(o):t.set(c,[o])}let n=[...t.entries()].sort(([o],[c])=>{let l=ll(o)-ll(c);return l!==0?l:o.localeCompare(c)}),r=Math.min(Fy,Math.max(...e.map(o=>o.name.length))),i=[];for(let[o,c]of n){c.sort((l,d)=>l.name.localeCompare(d.name)),i.length>0&&i.push(""),i.push(Hn.bold(`${o} (${c.length})`));for(let l of c){let d=`${By(l)?"$":" "}${Gy(l)?"*":" "}`,g=l.name.padEnd(r),y=2+r+1+d.length+1,v=Math.max(24,Vy-y),x=Ky(l.description??"",v);i.push(` ${Hn.cyan(g)} ${Hn.yellow(d)} ${x[0]??""}`.trimEnd());for(let T of x.slice(1))i.push(`${" ".repeat(y)}${T}`)}}return i}function zy(e){return e.map(t=>`${t.name} ${t.state} ${t.milestone}`)}function Hy(e,t={filtered:!1}){if(e.length===0)return[t.filtered?"No capabilities match that filter.":"No capabilities available."];if(!e.some(o=>o.description||o.category))return zy(e);let r=f.commands[0],i=Jy(e);return i.push(""),i.push(Hn.dim(`${e.length} capabilities \xB7 $ = paid \xB7 * = background (returns a run id)`)),i.push(Hn.dim(`Filter with: ${r} capabilities --search <query>`)),i}var ml=new My("capabilities").description("Index of everything this CLI can do \u2014 every command, grouped and described").option("-f, --format <format>","Output format: human, json, quiet",b("--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 bn(),n=Wy(t.capabilities,e),r=!!(e.search||e.category);if(e.format==="json"){m({capabilities:n,catalogVersion:t.catalogVersion,source:t.source,...t.reason?{sourceReason:t.reason}:{}});return}if(e.format==="quiet"){for(let i of n)console.log(i.name);return}t.source==="snapshot"&&q(`Showing the capability list baked into this CLI build (${t.reason}); the deployed catalog may have moved on.`);for(let i of Hy(n,{filtered:r}))console.log(i)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{mkdirSync as Zy,writeFileSync as eb}from"fs";import{dirname as fl,join as tb}from"path";import{confirm as hl,input as nb,password as rb,select as ib}from"@inquirer/prompts";import Xn from"chalk";import{Command as pt}from"commander";import Wr from"ora";import Xy from"conf";var Kr=new Xy({projectName:"conceptcraft",configName:"feature-cache"}),Yy=3600*1e3,Qy=1440*60*1e3;function pl(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 ul(){if(!mn())return null;let e=Kr.get("featureFlags");if(!e)return null;let t=pl(Qe());if(e.apiKeyHash&&e.apiKeyHash!==t)return Tt(),null;let n=Date.now()-e.fetchedAt;return n>Qy?null:(n>Yy&&Vo(),e.flags)}function Vo(){At().catch(()=>{})}async function At(){let e=await cc(),t=Qe();return Kr.set("featureFlags",{flags:e,fetchedAt:Date.now(),apiKeyHash:t?pl(t):void 0}),e}function Tt(){Kr.delete("featureFlags")}function gl(){return Kr.path}var yl=new pt("config").description("Manage CLI configuration: account settings, and the cached feature flags that decide which commands appear").addCommand(new pt("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(Xn.bold(`${f.displayName} CLI Configuration`)),console.log(Xn.gray("\u2500".repeat(35))),console.log();try{let e=await rb({message:"Enter your API key:",mask:"*",validate:r=>!r||r.trim().length===0?"API key is required":So(r.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(Ro(e.trim()),await hl({message:`Use a custom API URL? (default: ${f.apiUrl.replace("https://","")})`,default:!1})){let r=await nb({message:"Enter API URL:",default:K(),validate:i=>{try{return new URL(i),!0}catch{return"Invalid URL format"}}});Co(r)}console.log();let n=Wr("Verifying API key...").start();try{let r=await Je();if(n.succeed("API key verified!"),console.log(),I(`Logged in as: ${r.user.email}`),r.teams.length===0)q("No teams found for this user.");else if(r.teams.length===1){let i=r.teams[0];ln(i.id),I(`Team: ${i.name} (${i.planName})`)}else{console.log(),I(`You have access to ${r.teams.length} teams.`);let i=await ib({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});ln(i);let o=r.teams.find(c=>c.id===i);C(`Selected team: ${o?.name}`)}try{await At()}catch{}}catch(r){n.fail("Failed to verify API key"),q(`Could not verify API key: ${u(r,"The operation could not be completed.")}`),q(`You may need to set the team ID manually: ${f.commands[0]} config set team-id <id>`)}console.log(),C("Configuration saved!"),I(`Config file: ${Jn()}`),console.log()}catch(e){if(e.name==="ExitPromptError"){console.log(),I("Configuration cancelled.");return}throw e}})).addCommand(new pt("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async e=>{let t=Ad();if(De("Current Configuration"),console.log(),O("API Key",_d()??Xn.red("Not set")),O("API URL",t.apiUrl),O("Default Team ID",t.defaultTeamId??Xn.gray("Not set")),console.log(),O("Config file",Jn()),e.verify&&t.apiKey){console.log();let n=Wr("Verifying...").start();try{let r=await Je();n.succeed("Verified"),console.log(),O("User",r.user.email),r.currentTeam&&O("Current Team",`${r.currentTeam.name} (${r.currentTeam.planName})`),r.teams.length>1&&O("Total Teams",String(r.teams.length))}catch{n.fail("Verification failed"),q("The operation could not be completed.")}}console.log()})).addCommand(new pt("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":So(t)||(a("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),Ro(t),Tt(),C("API key updated"),At().catch(()=>{});break;case"api-url":try{new URL(t),Co(t),C(`API URL set to: ${t}`)}catch{a("Invalid URL format"),process.exit(6)}break;case"team-id":ln(t),C(`Default team ID set to: ${t}`);break;default:a(`Unknown config key: ${e}`),console.log(Xn.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new pt("clear").description("Clear all configuration").action(async()=>{try{await hl({message:"Are you sure you want to clear all configuration?",default:!1})?(Lr(),Tt(),C("Configuration cleared")):I("Cancelled")}catch{I("Cancelled")}})).addCommand(new pt("refresh").description("Refresh cached feature flags").action(async()=>{let e=Wr("Refreshing feature flags...").start();try{await At(),e.succeed("Feature flags refreshed"),I(`Run '${f.commands[0]} --help' to see updated commands`)}catch{e.fail("Failed to refresh"),a("The command failed. Please try again."),process.exit(1)}})).addCommand(new pt("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(e=>{e.cache?console.log(gl()):console.log(Jn())})).addCommand(new pt("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let e=Wr("Pulling settings...").start();try{let t=await fe(),n=await fetch(`${K()}/api/cli/settings`,{headers:t});if(!n.ok)throw new Error(`Request failed (HTTP ${n.status})`);let r=await n.text(),i=tb(fl(Jn()),"settings.toml");Zy(fl(i),{recursive:!0}),eb(i,r,"utf8"),e.succeed("Settings pulled"),I(`Written to ${i}`)}catch{e.fail("Failed to pull settings"),a("The command failed. Please try again."),process.exit(1)}}));import{confirm as ab}from"@inquirer/prompts";import{Command as sb}from"commander";function Ot(e){return e instanceof P&&e.errorCode==="approval_required"}function bl(e){return`Retry this exact request with --approval-receipt <receipt> --idempotency-key ${e}, or re-run it with the root --wait-for-approval flag to wait for the approval here.`}function Jr(e,t){return`This request needs approval before it can run.${e.approvalUrl?` Open ${e.approvalUrl}.`:""} ${bl(t)}`}function zr(e){return{success:!1,error:e.error,errorCode:"approval_required",...e.caught.approvalUrl?{approvalUrl:e.caught.approvalUrl}:{},idempotencyKey:e.idempotencyKey,retry:bl(e.idempotencyKey)}}import{createHash as ob}from"crypto";function Q(e){let t=ob("sha256").update(JSON.stringify({command:e.command,payload:Fo(e.payload),workspaceId:e.workspaceId})).digest("hex");return`cli:${e.command.trim().toLowerCase().replace(/[^a-z0-9._:-]+/g,"-").replace(/^-+|-+$/g,"")||"command"}:${t}`}function Fo(e){return Array.isArray(e)?e.map(Fo):!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,Fo(n)]))}var wl=new sb("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 w(),!t.yes&&!t.force)try{if(!await ab({message:`Are you sure you want to delete presentation "${e}"?`,default:!1})){t.quiet||q("Deletion cancelled");return}}catch{t.quiet||q("Deletion cancelled");return}let n=t.teamId??ve(),r=t.idempotencyKey??Q({command:"presentation:delete",payload:{slug:e},workspaceId:n??"configured-default"});try{await rc(e,{approvalReceipt:t.approvalReceipt,idempotencyKey:r,teamId:n}),t.quiet||C(`Presentation "${e}" deleted`)}catch(i){Ot(i)?a(Jr(i,r)):a("The command failed. Please try again."),process.exit(i.exitCode??1)}});import Il from"chalk";import{Command as wn}from"commander";import db from"ora";import{createParser as VN}from"eventsource-parser";import BN from"chalk";import KN from"ora";async function vl(e,t={}){let n=e.body?.getReader();if(!n)throw new Error("Response body is not readable");let r=new TextDecoder,i="",o=!1;for(;!o;){let c=await n.read();if(o=c.done,c.value){let l=r.decode(c.value,{stream:!0});i+=l,t.quiet||process.stdout.write(l)}}return t.quiet||console.log(),i}function cb(){return new wn("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)",b("--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 w();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 i=db("Fetching presentation...").start();try{let o=await fn(e);i.text="Generating blog post...";let c=await lc(o.id,o.documentCreatedAt||o.createdAt,{targetWordCount:n,tone:t.tone,targetAudience:t.audience??"General Audience",customInstructions:t.instructions??"",includeImages:!t.noImages,includeTableOfContents:t.toc??!1}),l=await vl(c,{quiet:!0});i.succeed("Blog generated"),t.format==="json"?console.log(JSON.stringify({presentationId:e,title:o.title,wordCount:n,tone:t.tone,content:l},null,2)):t.format==="markdown"?console.log(l):(console.log(),console.log(Il.bold(`Blog: ${o.title}`)),console.log(Il.gray("\u2500".repeat(40))),console.log(),console.log(l),console.log())}catch(o){i.fail("Generation failed"),a("The command failed. Please try again."),process.exit(o.exitCode??1)}})}function lb(){return new wn("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)",b("--format",["human","json"]),"human").action(async(e,t)=>{await w(),I("Tweet generation coming soon.")})}function mb(){return new wn("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)",b("--format",["human","json"]),"human").action(async e=>{await w(),I("LinkedIn carousel generation coming soon.")})}function pb(){return new wn("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)",b("--format",["human","json"]),"human").action(async(e,t)=>{await w(),I("Question generation coming soon.")})}function ub(){return new wn("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)",b("--format",["human","json","markdown"]),"human").action(async(e,t)=>{await w(),I("Cheat sheet generation coming soon.")})}function kl(e=ul()){let t=new wn("derive").description("Generate derivative content from a presentation");return e&&(e.deckToBlog&&t.addCommand(cb()),e.deckToTweets&&t.addCommand(lb()),e.linkedInCarousel&&t.addCommand(mb()),e.redTeamQuestions&&t.addCommand(pb()),e.presenterCheatSheet&&t.addCommand(ub())),t}import{Command as gb}from"commander";import Bo from"chalk";var xl=new gb("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)",b("--format",["human","json"]),"human").action(async e=>{await w(),I("Idea generation is available in the web dashboard."),console.log(),console.log(Bo.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(Bo.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(Bo.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{readFile as fb}from"fs/promises";import{basename as hb,resolve as yb}from"path";import{Command as bb}from"commander";import wb from"ora";var Rl=new bb("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");Rl._hidden=!0;var Cl=Rl.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 w();try{(await Je()).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=yb(e),r=hb(n);r.endsWith(".zip")||(a("File must be a ZIP archive"),process.exit(6));let i=wb("Reading file...").start();try{let o=await fb(n);t.dryRun?i.text="Validating...":i.text="Importing presentation...";let c=await ac(o,r,{dryRun:t.dryRun});if(c.success){if(t.dryRun)i.succeed("Validation passed!"),console.log(),I("The file is valid and can be imported."),c.statistics&&(console.log(),O("Slides",String(c.statistics.slidesImported)),O("Images",String(c.statistics.imagesUploaded)));else if(i.succeed("Import complete!"),console.log(),O("Presentation ID",c.presentationId??"N/A"),O("Document ID",c.documentId??"N/A"),c.statistics&&(O("Slides imported",String(c.statistics.slidesImported)),O("Images uploaded",String(c.statistics.imagesUploaded)),O("Time",`${c.statistics.totalTimeMs}ms`)),c.presentationId){let l=K();O("View URL",`${l}/p/${c.presentationId}`)}if(c.warnings&&c.warnings.length>0){console.log();for(let l of c.warnings)q(l)}console.log()}else i.fail("Import failed"),console.log(),c.errors?.length&&a("Import failed. The server rejected the presentation."),process.exit(1)}catch(o){i.fail("Import failed"),o.code==="ENOENT"&&(a(`File not found: ${n}`),process.exit(3)),a("The command failed. Please try again."),process.exit(o.exitCode??1)}});import{Command as vb}from"commander";function Go(){return new vb("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)",b("--sort",["updated","created","title"]),"updated").option("--search <text>","Search presentation titles").option("--team-id <id>","Team ID (uses default if not specified)").option("--json","Output machine-readable JSON").action(async e=>{await w();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??ve();r||(a("Team ID required. Set a default with 'mf config set team-id <id>' or use --team-id"),process.exit(6));try{let i=await ec(r,t,n,e.sort,e.search);if(i.length===0){e.json?console.log(JSON.stringify([])):I("No presentations found");return}console.log(e.json?JSON.stringify(i,null,2):sl(i))}catch(i){a("The command failed. Please try again.");let o=typeof i=="object"&&i!==null&&"exitCode"in i&&typeof i.exitCode=="number"?i.exitCode:1;process.exit(o)}})}var Sl=Go();import{createHash as Ib,randomBytes as Al}from"crypto";import Tl from"http";import El from"chalk";import{Command as kb}from"commander";import xb from"open";import Pl from"ora";var Rb=`${f.displayName} CLI`,Cb=8765,Sb=8775,Eb=["presentations:read","presentations:write","brands:read","brands:write","media:read","media:write"];function Pb(){return Al(32).toString("base64url")}function Ab(e){return Ib("sha256").update(e).digest("base64url")}function Tb(){return Al(16).toString("hex")}async function Ob(e,t){for(let n=e;n<=t;n++)try{return await new Promise((r,i)=>{let o=Tl.createServer();o.listen(n,()=>{o.close(()=>r())}),o.on("error",i)}),n}catch{}throw new Error(`No available port found between ${e} and ${t}`)}async function $b(e){let t=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!t.ok)throw new Error(`Failed to fetch OAuth metadata: ${t.status}`);let n=await t.json();if(!n||typeof n!="object"||Array.isArray(n)||!("authorization_endpoint"in n)||typeof n.authorization_endpoint!="string"||!("token_endpoint"in n)||typeof n.token_endpoint!="string"||!("registration_endpoint"in n)||typeof n.registration_endpoint!="string")throw new Error("The selected server returned invalid OAuth metadata");let r="issuer"in n?n.issuer:void 0,i="scopes_supported"in n?n.scopes_supported:void 0;if(r!==void 0&&typeof r!="string"||i!==void 0&&(!Array.isArray(i)||!i.every(o=>typeof o=="string")))throw new Error("The selected server returned invalid OAuth metadata");return{authorization_endpoint:n.authorization_endpoint,token_endpoint:n.token_endpoint,registration_endpoint:n.registration_endpoint,issuer:r,scopes_supported:i}}function Db(e){let t=e.scopes_supported?.filter(n=>typeof n=="string"&&n.trim().length>0);return(t?.length?t:Eb).join(" ")}function Nb(e,t){if(!t?.trim())return Db(e);let n=t.split(",").map(i=>i.trim()).filter(Boolean);if(n.length===0)throw new Error("--scopes must include at least one OAuth scope");let r=e.scopes_supported?.filter(i=>typeof i=="string"&&i.trim().length>0);if(r?.length){let i=n.filter(o=>!r.includes(o));if(i.length>0)throw new Error(`Unsupported OAuth scope${i.length===1?"":"s"}: ${i.join(", ")}`)}return n.join(" ")}async function Lb(e,t,n){if(t===void 0)return;let r=new URL(e),i;try{i=new URL(t)}catch{throw new Error("--resource must be an absolute advertised OAuth resource URL")}if(t!==t.trim()||i.origin!==r.origin||i.username||i.password||i.search||i.hash||i.toString()!==t||!["https:","http:"].includes(i.protocol))throw new Error("--resource must identify an exact resource on the selected server");let o=new URL(`/.well-known/oauth-protected-resource${i.pathname==="/"?"":i.pathname}`,r.origin),c=await fetch(o,{redirect:"error"});if(!c.ok)throw new Error("The selected server does not advertise this OAuth resource");let l=await c.json();if(!l||typeof l!="object"||Array.isArray(l)||!("resource"in l)||l.resource!==t||!n||!("authorization_servers"in l)||!Array.isArray(l.authorization_servers)||!l.authorization_servers.every(d=>typeof d=="string")||!l.authorization_servers.includes(n))throw new Error("OAuth resource metadata does not match the selected authorization server");return t}function Ub(e){return new URLSearchParams({...e,response_type:"code",code_challenge_method:"S256"})}async function _b(e,t,n){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Rb,redirect_uris:[t],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 jb(e,t,n,r,i,o){let c=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:r,client_id:i,code_verifier:n});o&&c.set("resource",o);let l=await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:c.toString()});if(!l.ok)throw new Error("Token exchange failed. Please try again.");return l.json()}function qb(e,t){return new Promise((n,r)=>{let i,o=!1,c=()=>{o||(o=!0,clearTimeout(i),process.off("SIGINT",l),process.off("SIGTERM",l),d.close())},l=()=>{c(),r(new Error("Login cancelled"))},d=Tl.createServer((g,y)=>{let v=new URL(g.url||"",`http://localhost:${e}`);if(v.pathname!=="/callback"){y.writeHead(404),y.end("Not found");return}let x=v.searchParams.get("code"),T=v.searchParams.get("state"),L=v.searchParams.get("error"),$=v.searchParams.get("error_description");if(y.writeHead(200,{"Content-Type":"text/html"}),L){y.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 te from"chalk";import{Command as $$}from"commander";import Xn from"chalk";import{Command as By}from"commander";function Rd(e={}){let t=(l,d)=>{let g=e[l];return g&&g.trim().length>0?g.trim():d},n=t("NEXT_PUBLIC_PRODUCT_SHORT_NAME","ConceptCraft"),r=t("NEXT_PUBLIC_CLI_COMMAND","ccr"),i=t("NEXT_PUBLIC_CLI_COMMAND_FULL","conceptcraft"),o=t("NEXT_PUBLIC_CLI_CONFIG_DIR",`.${i}`),c=n.toUpperCase().replace(/[^A-Z0-9]/g,"_");return{id:i,name:o.replace(/^\./,""),displayName:n,description:`CLI tool for ${n} presentation generation`,commands:[r,i],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:o,apiKeyEnvVar:`${c}_API_KEY`,apiUrlEnvVar:`${c}_API_URL`,codexSelfConnectorAppId:e.NEXT_PUBLIC_CODEX_SELF_CONNECTOR_APP_ID?.trim()||void 0}}var f=typeof h<"u"&&h?h:Rd(process.env);import{createHash as Oo,randomUUID as J}from"crypto";import{readFileSync as Wd,statSync as Jd}from"fs";import{basename as Do}from"path";import iy from"readline";async function Cd(e){process.stderr.write(`${JSON.stringify({event:"approval_required",...e.approvalUrl?{approvalUrl:e.approvalUrl}:{}})}
4
+ `);let t=iy.createInterface({input:process.stdin,terminal:process.stdin.isTTY===!0});try{return(await new Promise(i=>{if(process.stdin.isTTY){t.question(`Approve this exact request in your browser: ${e.approvalUrl??e.message}
5
+ Then paste the approval receipt: `,i);return}let o=!1,c=l=>{o||(o=!0,i(l))};t.on("line",c),t.on("close",()=>c(""))})).trim()||void 0}finally{t.close()}}import{spawnSync as oy}from"child_process";import{existsSync as ay,mkdtempSync as sy,rmSync as dy,writeFileSync as cy}from"fs";import{tmpdir as ly}from"os";import{join as Sd}from"path";import Co from"ffmpeg-static";var my=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function py(e){let t=my.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 Ed(e,t="audio"){if(e.length===0)return;let n=Co&&ay(Co)?Co:"ffmpeg",r=/^[a-z0-9]+$/i.test(t)?t:"audio",i=sy(Sd(ly(),"mf-tts-duration-")),o=Sd(i,`speech.${r}`);try{cy(o,e);let c=oy(n,["-hide_banner","-i",o],{encoding:"utf8"});return c.error?void 0:py(c.stderr??"")}finally{dy(i,{force:!0,recursive:!0})}}import qr from"chalk";import uy from"conf";import Pd from"path";var Td=f.apiUrl,gy={apiKey:{type:"string"},apiUrl:{type:"string",default:Td},defaultTeamId:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},tokenExpiresAt:{type:"number"},clientId:{type:"string"},clientSecret:{type:"string"}};function fy(e=f.apiKeyEnvVar){return e.endsWith("_API_KEY")?`${e.slice(0,-8)}_CONFIG_DIR`:`${e}_CONFIG_DIR`}function hy(e=process.env){let t=fy(),n=e[t]?.trim()||e.CC_SLIDES_CONFIG_DIR?.trim();if(n){if(!Pd.isAbsolute(n))throw new Error(`${t} must be an absolute directory path`);return Pd.normalize(n)}}var Ad=hy(),M=new uy({projectName:f.name,schema:gy,...Ad?{configFileMode:384,cwd:Ad}:{}});function Od(){return{apiKey:Qe(),apiUrl:K(),defaultTeamId:M.get("defaultTeamId"),accessToken:M.get("accessToken"),refreshToken:M.get("refreshToken"),tokenExpiresAt:M.get("tokenExpiresAt"),clientId:M.get("clientId"),clientSecret:M.get("clientSecret")}}function Qe(){let e=process.env[f.apiKeyEnvVar]??process.env.CC_SLIDES_API_KEY;return e||M.get("apiKey")}function So(e){M.set("apiKey",e)}function K(){let e=process.env[f.apiUrlEnvVar]??process.env.CC_SLIDES_API_URL;return e||(M.get("apiUrl")??Td)}function Eo(e){M.set("apiUrl",e)}function ve(){return M.get("defaultTeamId")}function ln(e){M.set("defaultTeamId",e)}function Ur(){M.clear()}function zn(){return M.path}function mn(){return!!Qe()}function $d(){return M.get("accessToken")}function Dd(){return M.get("refreshToken")}function _r(e,t,n){M.set("accessToken",e),M.set("refreshToken",t),M.set("tokenExpiresAt",Date.now()+(n-60)*1e3)}function jr(){M.delete("accessToken"),M.delete("refreshToken"),M.delete("tokenExpiresAt")}function Nd(){let e=M.get("tokenExpiresAt");return e?Date.now()>=e:!0}function Pt(){return!!M.get("accessToken")&&!!M.get("refreshToken")}function Ld(){return M.get("clientId")}function Ud(){return M.get("clientSecret")}function _d(e,t){M.set("clientId",e),M.set("clientSecret",t)}var s={SUCCESS:0,GENERAL_ERROR:1,AUTH_ERROR:2,NOT_FOUND:3,RATE_LIMIT:4,NETWORK_ERROR:5,INVALID_INPUT:6};async function yy(){let e=Dd(),t=Ld(),n=K();if(!e||!t)return null;try{let r=await fetch(`${n}/.well-known/oauth-authorization-server`);if(!r.ok)return null;let i=await r.json(),o=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:t}),c=Ud();c&&o.set("client_secret",c);let l=await fetch(i.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()});if(!l.ok)return jr(),null;let d=await l.json();return _r(d.access_token,d.refresh_token,d.expires_in),d.access_token}catch{return null}}async function jd(){return Pt()?Nd()?yy():$d()||null:null}function Ze(){return Pt()||mn()}async function w(){if(!Ze()){let e=f.commands[0],t=f.apiKeyEnvVar;console.error(qr.red("\u2717 Not authenticated.")),console.error(),console.error(qr.bold("To authenticate, run:")),console.error(qr.cyan(` ${e} login`)),console.error(),console.error(qr.gray(`Or set ${t} environment variable.`)),process.exit(s.AUTH_ERROR)}}function by(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function qd(){let e=Qe();if(e)return by(e)}function Po(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(n=>e.startsWith(n))}import{mkdirSync as wy,readFileSync as vy,writeFileSync as Iy}from"fs";import{homedir as ky}from"os";import{join as Md}from"path";import xy from"ajv/dist/2020.js";var Ao=new Map;function Vd(){return Md(ky(),".conceptcraft","schemas")}function Fd(e){return Md(Vd(),`${e}.json`)}function Ry(e){try{let t=JSON.parse(vy(Fd(e),"utf8"));return typeof t?.catalogVersion=="number"&&t.schema?t:null}catch{return null}}function Cy(e,t){try{wy(Vd(),{recursive:!0}),Iy(Fd(e),JSON.stringify(t))}catch{}}async function Sy(e){let t=Ao.get(e);if(t!==void 0)return t;try{let n=await Bd(e),r={catalogVersion:n.catalogVersion,schema:n.operationSchema??n.schema};return Cy(e,r),Ao.set(e,r),r}catch{let n=Ry(e);return Ao.set(e,n),n}}function Ey(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 Mr(e,t){let n=await Sy(e);if(!n)return;let r;try{r=new xy({allErrors:!0,strict:!1}).compile(n.schema)}catch{return}if(r(t))return;let i=(r.errors??[]).slice(0,10).map(Ey);throw new Error(`Request does not match the ${e} contract \u2014 ${i.join("; ")}`)}function Py(e){if(!e||typeof e!="object")return null;let t=e.errorCode,n=e.message,r=typeof n=="string"&&n.trim()?n:null;if(t==="approval_required")return r;if(t!=="invalid_input")return null;let i=e.details,o=[...r?[r]:[],...Array.isArray(i)?To(i):[]];return o.length>0?o.join(`
6
+ `):null}var pn="terminalRunFailure",de=class extends Error{[pn]=!0};function un(e){return!!e&&typeof e=="object"&&e[pn]===!0}function oe(e,t){let n=t?null:Py(e);if(n)return n;if(un(e)){let i=e instanceof Error&&e.message.trim()?e.message.trim():"The run failed.";return`${/[.!?]$/.test(i)?i:`${i}.`}${t?` Request ID: ${t}.`:""} The run is finished and cannot be resumed \u2014 retry with a new request, a new idempotency key, and a fresh approval receipt where one is required.`}let r="The run failed. Check its status for recovery details.";return!t||r.includes(t)?r:`${r} Request ID: ${t}. Resume with the matching status command; do not start a duplicate run.`}function Ee(e,t){return un(e)?"":` Retry with --idempotency-key ${t}.`}function ge(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 Hn(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"}: ${ge(e.error)}`:null}function Gd(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(`
7
+ `):/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 fe(){let e=await jd();if(e)return{Authorization:`Bearer ${e}`};let t=Qe();return t?{"x-api-key":t}:{}}var P=class extends Error{constructor(n,r,i=1,o="operation_failed",c=!1,l,d){super(n);this.statusCode=r;this.exitCode=i;this.errorCode=o;this.retryable=c;this.approvalUrl=l;this.details=d;this.name="ApiError"}statusCode;exitCode;errorCode;retryable;approvalUrl;details},zd="Idempotency-Key",Hd=!1;function Xd(e){Hd=e}function Ay(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!(e instanceof FormData)}function Ty(e){return e&&e!=="GET"?{[zd]:J()}:{}}async function Oe(e,t={}){let n=K();if(!Ze()&&!t.allowUnauthenticated)throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2,"authentication_required");let r=await fe(),i=`${n}${e}`,o={...r,...Ty(t.method),...t.headers};t.body&&!t.stream&&(o["Content-Type"]="application/json");let c={method:t.method??"GET",headers:o};t.body&&(c.body=JSON.stringify(t.body));let l;try{l=await fetch(i,c)}catch{throw new P("Network error while contacting Mindframes. Please try again.",0,5,"service_unavailable",!0)}if(!l.ok){let g=await l.text().catch(()=>""),y=mt(g,l.status);if(y.code==="approval_required"&&Hd&&!t.approvalRetried&&Ay(t.body)&&!t.body.approvalReceipt){let T=await Cd({approvalUrl:y.approvalUrl,message:y.message});if(T)return Oe(e,{...t,approvalRetried:!0,body:{...t.body,approvalReceipt:T}})}let v=1;switch(l.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=`[${y.code}] ${y.message}`;throw new P(x,l.status,v,y.code,y.retryable,y.approvalUrl,y.details)}return t.stream?l:l.headers.get("content-type")?.includes("application/json")?l.json():l.text()}function Oy(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 $y(e){let t=e.match(/https?:\/\/\S*\/approvals\/\S+/);return t?t[0].replace(/[.,;]+$/,""):void 0}function No(e){return e===401||e===403?2:e===404?3:e===429?4:1}function Dy(e){if(!Array.isArray(e))return;let t=e.flatMap(n=>{if(!n||typeof n!="object")return[];let r=n;return typeof r.message!="string"||!r.message.trim()?[]:[{...typeof r.code=="string"?{code:r.code}:{},message:r.message,...typeof r.path=="string"?{path:r.path}:{}}]});return t.length>0?t:void 0}function mt(e,t){let n=Oy(t),r=`HTTP ${t}: The request could not be completed.`;try{let i=JSON.parse(e),o=typeof i.error=="object"&&i.error!==null?i.error:void 0;if(i.ok===!1&&typeof o?.code=="string"&&typeof o.message=="string")return{approvalUrl:typeof o.approval?.approvalUrl=="string"?o.approval.approvalUrl:typeof o.approvalUrl=="string"?o.approvalUrl:$y(o.message),code:o.code,details:Dy(o.details),message:o.message,retryable:o.retryable===!0}}catch{}return{code:n,message:r,retryable:t===429||t>=500}}async function Bd(e){return Oe(`/api/cli/tools/${encodeURIComponent(e)}/schema`)}async function Yd(){return Oe("/api/cli/capabilities",{allowUnauthenticated:!0})}async function R(e,t,n){let r=await Vr(n),i=`?teamId=${encodeURIComponent(r)}`;return Oe(`/api/cli/tool-runs/${encodeURIComponent(e)}/${encodeURIComponent(t)}${i}`)}async function Qd(e,t,n){let r=await Vr(t);return Oe(`/api/v1/presentations/edits/runs/${encodeURIComponent(e)}/events?teamId=${encodeURIComponent(r)}`,{stream:!0,headers:n?{"Last-Event-ID":n}:void 0})}async function p(e,t,n){let r=await Vr(t.teamId);return Oe(`/api/cli/tools/${encodeURIComponent(e)}`,{body:{...t,teamId:r},headers:n?{[zd]:n}:void 0,method:"POST"})}function U(e){return Vr(e)}async function Vr(e){let t=typeof e=="string"&&e.trim()?e.trim():ve()?.trim();if(t)return t;let n=await Je();if(n.currentTeam?.id)return n.currentTeam.id;throw new P("Team ID required. Select a workspace with `mf config set team-id <id>` or pass --team-id.",400,void 0,"invalid_input")}async function Zd(e){return Oe("/api/llm-connections/profiles",{body:e,method:"POST"})}var Ny=1800*1e3;async function z(e,t,n,r=120,i){let o=Date.now()+(i?.maxWaitMs??Ny),c=0;for(let d=0;(r===null||d<r)&&Date.now()<o;d++){let g;try{g=await R(e,t,n),c=0}catch(v){if(v instanceof P&&v.retryable&&c<2){c+=1,await new Promise(x=>setTimeout(x,2e3));continue}throw v instanceof P?new P(`${v.message} Request ID: ${t}.`,v.statusCode,v.exitCode,v.errorCode,v.retryable):new P(`The background operation could not be checked. Request ID: ${t}.`,0,5,"poll_failed",!0)}if(g.done){if(g.error)throw Object.assign(new P(`${ge(g.error,{defaultCode:"operation_failed"})} Request ID: ${t}.`,500,1,g.error.code??"operation_failed",g.error.retryable),{[pn]:!0});return g}let y=Math.min((g.nextPollAfterSeconds??2)*1e3,Math.max(0,o-Date.now()));await new Promise(v=>setTimeout(v,y))}let l=i?.statusCommand?` Check it with '${f.commands[0]} ${i.statusCommand} ${t}'.`:"";throw new P(`Stopped following run ${t}: timed out. The run is unaffected \u2014 it may still be running.${l}`,408,1,"operation_timed_out",!0)}function Fr(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 Ly(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 gn(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 et(e){let t=Jd(e);return{fileName:Do(e),fileSize:t.size,fileType:gn(e)}}async function tt(e,t){let n=et(e),r=Wd(e),i=new FormData;for(let[c,l]of Object.entries(t.fields))i.append(c,l);i.append("file",new Blob([r],{type:n.fileType}),n.fileName);let o=await fetch(t.uploadUrl,{method:"POST",body:i});if(!o.ok)throw new P("Failed to upload file to storage",o.status,1);return{id:t.fileId??J(),name:n.fileName,s3Key:t.s3Key,url:t.fileUrl,size:n.fileSize,type:n.fileType,selected:!0}}async function ie(e,t={}){let n=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let r=await fe(),i=Jd(e),o=Do(e),c=gn(e),l=Wd(e),d=Oo("sha256").update(l).digest("hex"),g=await fetch(`${n}/api/cli/files/upload`,{method:"POST",headers:{"Content-Type":"application/json",...r},body:JSON.stringify({fileMetadata:{lastModified:i.mtimeMs,name:o,type:c,size:i.size},...t.storagePrefix?{storagePrefix:t.storagePrefix}:{},...t.idempotencyKey?{uploadIdentity:{contentSha256:d,idempotencyKey:t.idempotencyKey}}:{}})});if(!g.ok){let v=await g.text(),x=mt(v,g.status);throw new P(`[${x.code}] ${x.message}`,g.status,No(g.status),x.code,x.retryable)}let y=await g.json();return tt(e,{...t.idempotencyKey?{fileId:`file-${Oo("sha256").update(JSON.stringify({contentSha256:d,fileName:o,idempotencyKey:t.idempotencyKey})).digest("hex")}`}:{},fields:y.fields||{},fileUrl:y.fileUrl,s3Key:y.uploadKey,uploadUrl:y.url})}async function ec(e,t,n={}){let r=[];for(let i=0;i<e.length;i++){let o=e[i],c=Do(o);t?.(i,e.length,c);let l=await ie(o,{idempotencyKey:n.idempotencyKey});r.push(l)}return t?.(e.length,e.length,""),r}async function tc(e,t,n){let r={};for(let[i,o]of Object.entries(e))o!==void 0&&(r[i]=o);return r.brandingId===void 0&&typeof r.brandId=="string"&&(r.brandingId=r.brandId),delete r.brandId,p("createSlides",{...r,...n?{approvalReceipt:n}:{}},t)}async function nc(e,t=20,n=0,r="updated",i){return(await p("listPresentations",{limit:t,offset:n,sort:r,teamId:e,search:i})).presentations}async function fn(e,t){let n=t?.includeSlides!==!1,r=await p("getPresentation",{includeSlides:n,presentationId:e,teamId:t?.teamId});if("done"in r){if(t?.includeGenerating)return r;throw new Error(r.instructions,{cause:r})}return n?{...r.presentation,slides:r.slides,...Object.hasOwn(r,"speakerNotes")?{speakerNotes:r.speakerNotes}:{}}:r.presentation}async function rc(e,t,n,r){return p("generateSpeakerNotes",{...t,presentationId:e,teamId:r},n)}async function ic(e,t,n,r){return p("setSpeakerNotes",{notes:t,presentationId:e,teamId:r},n)}async function Br(e,t){let n=K(),r=await fetch(`${n}/api/durable-runs/${encodeURIComponent(e)}/events`,{headers:{...await fe(),...t?{"Last-Event-ID":t}:{}}});if(!r.ok){let i=mt(await r.text().catch(()=>""),r.status);throw new P(`[${i.code}] ${i.message}`,r.status,No(r.status),i.code,i.retryable)}return r}async function oc(e,t={}){await p("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},t.idempotencyKey??`cli:presentation:delete:${Oo("sha256").update(JSON.stringify({slugOrId:e,teamId:t.teamId??null})).digest("hex")}`)}async function ac(e,t){return p("updatePresentationVisibility",{presentationId:e,teamId:t.teamId,visibility:t.visibility},t.idempotencyKey??`cli:presentation:visibility:${J()}`)}async function sc(e,t,n){return p("exportPresentation",{format:t,presentationId:e,teamId:n?.teamId})}async function hn(e){let t;try{t=await fetch(e)}catch{throw new P("Network error while downloading the export. Please try again.",0,5,"service_unavailable",!0)}if(!t.ok)throw new P(`[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 dc(e,t,n={}){let r=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let i=await fe(),o=new FormData,c=new Blob([new Uint8Array(e)],{type:"application/zip"});o.append("file",c,t),o.append("options",JSON.stringify({dryRun:n.dryRun??!1,remapIds:!0}));let l=await fetch(`${r}/api/presentations/import`,{method:"POST",headers:i,body:o}),d=await l.json();if(!l.ok)throw new P("Import failed. The server rejected the presentation.",l.status,1);return d}async function cc(e,t=25){return p("listSlideTemplates",{limit:t,search:e})}async function lc(e,t,n,r,i){return p("extractBranding",{approvalReceipt:n,skipExistingBrandingLookup:r,teamId:t,url:e},i)}async function Je(){return Oe("/api/cli/whoami")}async function mc(){return Oe("/api/cli/features")}async function pc(e,t,n={}){let r=K();if(!Ze())throw new P(`Not authenticated. Run '${f.commands[0]} login' or set ${f.apiKeyEnvVar} environment variable.`,401,2);let i=await fe(),o=await fetch(`${r}/api/presentations/${e}/generate-blog`,{method:"POST",headers:{"Content-Type":"application/json",...i},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(!o.ok){let c=mt(await o.text().catch(()=>""),o.status);throw new P(`[${c.code}] ${c.message}`,o.status,No(o.status),c.code,c.retryable)}return o}async function Lo(e){return p("getGenerationLimits",{teamId:e})}async function uc(e,t,n){let r=await Lo(n);if(!r.canGenerate[e]){let i=r.remaining[e]??0,o=r.limits[e]??0;throw o===0?new P(`The "${e}" mode is not available on your ${r.planName} plan. Available modes: ${r.availableModes.join(", ")||"none"}`,403,2):new P(`You have reached your ${e} generation limit for this billing cycle (${r.usage[e]??0}/${o} used). Try a different mode: ${r.availableModes.join(", ")||"none available"}`,403,4)}if(r.maxSlidesPerPresentation!==-1&&t>r.maxSlidesPerPresentation)throw new P(`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 Uy(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 gc(e,t){let n={...e,text:Uy(e.text)};await Mr("generateSpeech",n);let r=await p("generateSpeech",{approvalReceipt:t?.approvalReceipt,...n},t?.idempotencyKey),i=await z("generateSpeech",r.runId),o=i.entity?.url;if(!o)throw new P(`Speech completed without an audio URL. Request ID: ${r.runId}.`,500);let c;try{c=await fetch(o)}catch{throw new P(`Failed to download speech audio. Request ID: ${r.runId}.`,0,5,"download_failed",!0)}if(!c.ok)throw new P(`Failed to download speech audio. Request ID: ${r.runId}.`,c.status,5,"download_failed",c.status===429||c.status>=500);let l=i.output??{},d=e.options??{},g=We(l.format)??Ly(o)??"mp3",y=Buffer.from(await c.arrayBuffer()),v=fc(l.durationSec,l.duration,l.duration_s)??Ed(y,g);if(v===void 0)throw new P(`Speech completed without a measurable duration. Request ID: ${r.runId}.`,500,1,"invalid_audio_metadata");return{audioData:y,audioUrl:o,duration:v,provider:We(l.provider)??d.provider??"gemini",format:g,requestId:r.runId,voiceId:We(l.voice_id)??We(l.voiceId),voice:We(l.voice),model:We(l.model),speed:$o(l.speed)??d.speed,language:We(l.lang)??We(l.language)??d.language,langApplied:Kd(l.langApplied)??Kd(l.lang_applied),timestamps:_y(l.timestamps),wordTimings:jy(l.timestamps??l.timings)}}function fc(...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 _y(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=t.characters,r=t.characterStartTimesSeconds??t.character_start_times_seconds,i=t.characterEndTimesSeconds??t.character_end_times_seconds;if(!(!Array.isArray(n)||!Array.isArray(r)||!Array.isArray(i))&&!(n.length===0||n.length!==r.length||n.length!==i.length||!n.every(o=>typeof o=="string")||!r.every(o=>typeof o=="number"&&Number.isFinite(o))||!i.every(o=>typeof o=="number"&&Number.isFinite(o))))return{characters:n,characterStartTimesSeconds:r,characterEndTimesSeconds:i}}function jy(e){if(!Array.isArray(e))return;let t=e.flatMap(n=>{if(!n||typeof n!="object"||Array.isArray(n))return[];let r=n,i=We(r.text)??We(r.word),o=$o(r.start),c=$o(r.end);return i&&o!==void 0&&c!==void 0&&c>=o?[{text:i,start:o,end:c}]:[]});return t.length>0?t:void 0}function We(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function $o(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Kd(e){return typeof e=="boolean"?e:void 0}async function hc(e){let t=e?`/api/cli/tts?provider=${e}`:"/api/cli/tts";return Oe(t)}async function yc(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);return delete n.idempotency_key,await Mr("generateMusic",n),{requestId:(await p("generateMusic",{...n,approvalReceipt:t?.approvalReceipt},r)).runId,status:"pending"}}async function Uo(e){let t=await R("generateMusic",e);return{requestId:e,status:Fr(t),audioUrl:t.entity?.url,duration:fc(t.output?.durationSec,t.output?.duration,t.output?.duration_s),error:t.error?.message}}async function bc(e,t){return{requestId:(await p("mixAudio",{...e,approvalReceipt:t?.approvalReceipt},t?.idempotencyKey)).runId,status:"pending"}}async function _o(e){let t=await R("mixAudio",e);return{requestId:e,status:Fr(t),outputUrl:t.entity?.url,error:t.error?.message}}async function wc(e){return Oe("/api/cli/images/search",{method:"POST",body:e})}async function vc(e){return Oe("/api/cli/videos/search",{method:"POST",body:e})}async function $e(e,t=60,n=2e3){let r=0;for(let i=0;i<t;i++){let o;try{o=await e(),r=0}catch(c){if(c instanceof P&&c.retryable&&r<2){r+=1,await new Promise(l=>setTimeout(l,n));continue}throw c}if(o.status==="completed"||o.status==="failed")return o;await new Promise(c=>setTimeout(c,n))}throw new P("Operation timed out",408,1)}async function Ic(e,t){let n={...e},r=t?.idempotencyKey??(typeof n.idempotency_key=="string"?n.idempotency_key:void 0);delete n.idempotency_key,await Mr("generateSfx",n);let i=await p("generateSfx",{...n,approvalReceipt:t?.approvalReceipt},r);return{id:i.runId,requestId:i.runId,status:"pending"}}async function jo(e){let t=await R("generateSfx",e);return{id:t.entity?.id??e,requestId:e,status:Fr(t),audioUrl:t.entity?.url,error:t.error?.message}}async function kc(e,t){return p("listPresenterOptions",{...e?{voiceLanguage:e}:{},...t?{teamId:t}:{}})}async function xc(e,t){return{requestId:(await p("generateAvatarVideo",e,t)).runId,status:"pending"}}async function qo(e){let t=await R("generateAvatarVideo",e);return{durationSec:typeof t.output?.durationSec=="number"?t.output.durationSec:null,error:t.error?.message,requestId:e,status:Fr(t),videoUrl:t.entity?.url}}async function Rc(e,t,n){return p("lipsyncVideo",{...e,approvalReceipt:n},t??J())}async function Cc(e,t,n){return p("clipVideo",{...e,approvalReceipt:n},t??J())}async function Sc(){return(await p("listTranslationLanguages",{})).languages}async function Ec(e,t,n){return p("translateVideo",{...e,approvalReceipt:n},t??J())}async function Pc(e,t,n){return p("createVideo",{...e,approvalReceipt:t},n)}async function Ac(e){let{idempotencyKey:t,...n}=e;return p("analyzeVideoReference",n,t)}async function Tc(e,t){return z("analyzeVideoReference",e,t)}async function Oc(e,t){return z("selectPresentationVideoStockMusic",e,t)}async function $c(e,t){return z("preparePresentationVideoMediaSuggestions",e,t,null,{statusCommand:"presentation video suggestions status"})}async function Dc(e,t){return z("preparePresentationVideoSuggestionAction",e,t,null,{statusCommand:"presentation video suggestions action prepare status"})}async function Nc(e,t){return z("preparePresentationVideoPreviews",e,t,null,{statusCommand:"presentation video previews status"})}async function Lc(e,t){return z("generateBrandVariations",e,t)}async function Uc(e,t){return z("extractBrandProducts",e,t)}async function _c(e,t){return z("buildBrandVoice",e,t)}async function jc(e,t){return z("generateBrandGuardrails",e,t)}async function qc(e,t){return z("repairBrandQuality",e,t)}async function Mc(e,t){return z("syncBrandToPresentations",e,t)}async function Vc(e,t){return z("syncBrandFoundation",e,t)}async function Fc(e){return p("listVoices",e)}async function Bc(e){return p("adoptLibraryVoice",e,J())}async function Gc(e){return p("setVoiceFavorite",e,J())}async function Kc(e){return p("setVoiceShortlisted",e,J())}async function Wc(e){return p("setVoicePolicy",e,J())}async function Jc(e){return p("requestVoiceApproval",e,J())}async function zc(e){return p("listVoiceApprovalRequests",e,J())}async function Hc(e){return p("decideVoiceApprovalRequest",e,J())}async function Xc(e){return p("setVoiceTone",e,J())}async function Yc(e){return p("setVoiceVisibility",e,J())}async function Qc(e){return p("setVoiceApproval",e,J())}async function Zc(e){return p("listVoiceApprovals",e,J())}async function el(e){return p("designVoice",e,J())}async function tl(e){return p("saveDesignedVoice",e,J())}async function nl(e){return p("retireVoice",e,J())}async function rl(e){return p("listCastPresets",e)}async function il(e){return p("createCastPreset",e,J())}async function ol(e){return p("updateCastPreset",e,J())}async function al(e,t){return p("deleteCastPreset",{presetId:e,...t?{teamId:t}:{}},J())}var qy="The command failed. Please try again.";function sl(e){return e.replace(/[\u0000-\u001f\u007f-\u009f]/g," ").trim()}function To(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||typeof n.message!="string"||!n.message.trim())continue;let r=typeof n.path=="string"&&n.path.trim()?`${sl(n.path)}: `:"";t.push(` ${r}${sl(n.message)}`)}return t}function u(e,t=qy){return e instanceof P&&e.message.trim()?[e.message,...To(e.details)].join(`
8
+ `):t}import{InvalidArgumentError as My}from"commander";function b(e,t){return n=>{if(t.includes(n))return n;throw new My(`Expected one of: ${t.join(", ")}. Run the command with --help to see what ${e} accepts.`)}}import V from"chalk";import Mo from"cli-table3";function C(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(V.green("\u2713"),e)}function a(e,t="human"){if(t!=="quiet"){if(t==="json"){console.error(JSON.stringify({error:e}));return}console.error(V.red("\u2717"),e)}}function q(e,t="human"){t!=="quiet"&&t!=="json"&&console.warn(V.yellow("\u26A0"),e)}function dl(e,t="human"){t==="quiet"||t==="json"||console.error(V.cyan("\u2192"),e)}function I(e,t="human"){t!=="quiet"&&t!=="json"&&console.log(V.blue("\u2139"),e)}function yn(e,t="en"){return e?`${K()}/${t}/view/presentations/${e}`:"N/A"}function cl(e,t={}){let{showLinks:n=!1,language:r="en"}=t,i=(l,d)=>l.length>d?`${l.slice(0,d-1)}\u2026`:l,o=l=>{if(!l)return"-";try{return new Date(l).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).replace(" at ",", ")}catch{return"-"}};if(n){let l=new Mo({head:[V.cyan("Slug"),V.cyan("Title"),V.cyan("Slides"),V.cyan("Created"),V.cyan("URL")]});for(let d of e)l.push([i(d.slug||d.id.slice(0,8),30),i(d.title||"Untitled",22),String(d.numberOfSlides||"-"),o(d.createdAt),yn(d.slug,r)]);return l.toString()}let c=new Mo({head:[V.cyan("Slug"),V.cyan("Title"),V.cyan("Slides"),V.cyan("Mode"),V.cyan("Created")],colWidths:[32,28,8,11,18]});for(let l of e)c.push([l.slug||l.id.slice(0,8),l.title||"Untitled",String(l.numberOfSlides||"-"),l.mode||"-",o(l.createdAt)]);return c.toString()}function ll(e){let t=[...e].sort((i,o)=>{if(i.isDefault&&!o.isDefault)return-1;if(!i.isDefault&&o.isDefault)return 1;let c=i.createdAt?new Date(i.createdAt).getTime():0;return(o.createdAt?new Date(o.createdAt).getTime():0)-c}),n=i=>{if(!i)return"-";try{return new URL(i).href}catch{return i.startsWith("http")?i:`https://${i}`}},r=new Mo({head:[V.cyan("Name"),V.cyan("Source"),V.cyan("Color"),V.cyan("Logo"),V.cyan("Default"),V.cyan("ID")]});for(let i of t){let o=i.primaryColor?`${V.bgHex(i.primaryColor)(" ")} ${i.primaryColor}`:"-";r.push([i.name,n(i.sourceUrl),o,i.logoUrl?V.green("\u2713"):V.gray("\u2717"),i.isDefault?V.green("\u2605"):"",i.id])}return r.toString()}function Vo(e){try{return new Date(e).toLocaleString()}catch{return e}}function De(e){console.log(),console.log(V.bold(e)),console.log(V.gray("\u2500".repeat(e.length)))}function O(e,t){console.log(` ${V.gray(`${e}:`)} ${t??"-"}`)}function Vy(e){return JSON.stringify(e,null,2)}function m(e){console.log(Vy(e))}var Gr=[{billing:"free",category:"knowledge",description:"Select an exact completed video as accepted while preserving prior outputs.",id:"acceptMissionOutput",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output accept",operation:"mutation",scopes:["knowledge:write","presentations:read","media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Accept the artifact that fills one of a mission item's outputs, bound to its exact version and what it was made from.",id:"acceptMissionOutputSlot",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output accept-slot",operation:"mutation",scopes:["knowledge:write","presentations:read"],state:"available"},{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:"free",category:"knowledge",description:"Adopt an artifact into a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"adoptMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission adopt",operation:"mutation",scopes:["knowledge: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:"presentations",description:"Apply Reviewed Scene Change without generating new content.",id:"applyPresentationVideoSuggestionAction",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action apply",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:"knowledge",description:"Record receipt-bound human approval of the exact narration checkpoint without starting rendering.",id:"approveMissionNarration",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission review approve",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations: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:"free",category:"media",description:"Cancel one in-flight video generation, translation, clip, lipsync, avatar, or narrated-video render run in this workspace.",id:"cancelVideoRun",lifecycle:{mode:"bounded"},milestone:"M8",name:"video cancel",operation:"mutation",scopes:["media:write"],state:"available"},{billing:"free",category:"branding",description:"Check a deck version against its linked brand's guardrail rules.",id:"checkPresentationGuardrails",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding presentation guardrails",operation:"query",scopes:["brands:read","presentations:read"],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:"free",category:"presentations",description:"Copy a scene's effective avatar \u2014 presenter identity plus its placement box \u2014 into a portable clipboard string that paste_presentation_video_presenter applies to scenes in any presentation video.",id:"copyPresentationVideoPresenter",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video copy-presenter",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"delegated",category:"artifacts",description:"Generate and persist an ad variation set: short-form video ads from hooks, or governed static ads from approved templates filled only with the brand's approved claims.",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:"artifacts",description:"Create a governed ad template as a lint-checked draft (version 1).",id:"createAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template create",operation:"mutation",scopes:["brands: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:"presentations",description:"Create a guest review link for a pinned presentation revision, choosing an isolated or shared guest room and an optional verified-only posting policy.",id:"createDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link create",operation:"mutation",scopes:["presentations: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:"free",category:"presentations",description:"Build a governed HCP deck from a brand's approved claims library, with locked ISI and References slides.",id:"createGovernedDeck",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed create",operation:"generation",scopes:["presentations: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:"knowledge",description:"Create a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"createMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission create",operation:"mutation",scopes:["knowledge: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:"free",category:"presentations",description:"Prepare scoped read-only Studio access for an authorized presentation, workspace catalog, owned creation/edit/speaker-notes run progress, or private request-bound approval delivery.",id:"createPresentationStudioLaunch",lifecycle:{mode:"bounded"},milestone:"M1",name:"presentation studio-launch",operation:"query",scopes:["presentations:read"],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:"knowledge",description:"Create a quiz, flashcard set or cheat sheet from explicit caller-supplied items.",id:"createStudySet",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set create",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"delegated",category:"agents",description:"Spawn one or more child chat threads that each run as their own durable chat turn under a parent chat.",id:"createThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread create",operation:"mutation",scopes:["chat-threads: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:"Copy a pinned stock video template into a separate editable Studio draft. No speech, avatar or render is generated.",id:"createVideoFromTemplate",lifecycle:{mode:"bounded"},milestone:"M8",name:"video templates create",operation:"mutation",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:"knowledge",description:"Permanently delete a mission and its machinery; optionally destroy the decks and narrated videos it produced.",id:"deleteMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission delete",operation:"mutation",scopes:["knowledge:write","presentations: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:"free",category:"presentations",description:"Delete a finished, failed, or cancelled presentation render attempt, optionally with the video it produced.",id:"deletePresentationVideoRender",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video delete-render",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"knowledge",description:"Delete a workspace- or member-owned skill. Removes its body and assets.",id:"deleteTeamSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills delete",operation:"mutation",scopes:["skills:write"],state:"available"},{billing:"delegated",category:"presentations",description:"Design new or existing video scenes using presentation style, brand and uploaded sources.",id:"designPresentationVideoScenes",lifecycle:{mode:"background",status:{cliCommand:"presentation video-scene-design status",pollAfterSeconds:10}},milestone:"M4",name:"presentation video-scene-design",operation:"generation",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:"delegated",category:"presentations",description:"Apply a metered edit to an authorized current presentation version and save the result.",id:"editPresentation",lifecycle:{mode:"background",status:{cliCommand:"presentation edit status",pollAfterSeconds:10}},milestone:"M8",name:"presentation edit",operation:"mutation",scopes:["presentations: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. add_interaction, update_interaction and remove_interaction manage the interactive overlays a player honours around the rendered video \u2014 buttons, choices, quiz questions and scene-end actions; adding or updating one requires the workspace's interactive-video capability and a Team or Enterprise plan, while removal stays open to every plan. Interactions never move the draft's render fingerprint. update_card changes a card scene's background (a hex colour, an image or deck-slide backdrop resolved like add_scene_layer sources, or the brand default), its visible text via textHidden \u2014 never an empty title \u2014 and its subtitle.",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:"branding",description:"Export an approved governed static set or deck version as a PromoMats-ready package.",id:"exportForPromoMats",lifecycle:{mode:"bounded"},milestone:"M2",name:"promomats export",operation:"query",scopes:["brands:read","presentations:read"],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:"free",category:"presentations",description:"Package a finished presentation video as a downloadable SCORM zip whose launcher embeds a revocable video link and reports watch completion and quiz results to the LMS. Bounded synchronous work: one share row, a small zip, one private upload - no provider call. passMarkPercent requires the latest published interaction manifest to contain a question.",id:"exportPresentationVideoScorm",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm export",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"workspace",description:"Export who did what in a workspace (admins only) as JSON or CSV.",id:"exportWorkspaceAuditLog",lifecycle:{mode:"bounded"},milestone:"M8",name:"audit-log export",operation:"query",scopes:["audit: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:"Create a right-way or wrong-way clip from a picture or prompt and attach it to video scenes.",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:"artifacts",description:"Read one governed ad template version with its HTML, slots, sizes and lint report.",id:"getAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template get",operation:"query",scopes:["brands:read"],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 saved video voices and presenters.",id:"getBrandVideoDefaults",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults 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:"branding",description:"Read one governed claim at a version, with its references and version history.",id:"getClaim",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"presentations",description:"Read a governed deck version's claim map and a fresh pre-submission check report.",id:"getGovernedDeck",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed get",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:"free",category:"branding",description:"Read one ISI or legal block at a version, with its version history.",id:"getLegalBlock",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks get",operation:"query",scopes:["brands:read"],state:"available"},{billing:"free",category:"media",description:"Read safe recording metadata and a bounded page of its transcript or precise stored word evidence before choosing cuts.",id:"getMediaAsset",lifecycle:{mode:"bounded"},milestone:"M8",name:"media show",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"knowledge",description:"Get a mission\u2019s status using durable intended outcomes and permission-checked native artifact links. No generation or acceptance. Every item and output carries one status vocabulary (not_started, in_progress, waiting_for_you, ready, final, changed_since_final). historyItemId also returns that item's version history: each output's versions, what each was made from, and which were accepted. waitForSourceImportMs (max 15000) is only for a free PowerPoint source import: it holds the read while the mission's import is still running so one reply can report the outcome, and is ignored when no source import is running (never use it for billed stages such as notes, narration, render or deck generation); it changes nothing.",id:"getMissionStatus",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission status",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 saved scene critiques and media ideas, version history and whether they match the current draft.",id:"getPresentationVideoMediaSuggestions",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions inspect",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:"Inspect Scene Changes without generating new content.",id:"getPresentationVideoSuggestionActions",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action inspect",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:"knowledge",description:"Read one skill's metadata and SKILL.md body.",id:"getSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills show",operation:"query",scopes:["skills:read"],state:"available"},{billing:"free",category:"knowledge",description:"Read a study set with its full items and their stable ids.",id:"getStudySet",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set get",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"agents",description:"Read one child chat thread's status, run id, and settled result.",id:"getThread",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread get",operation:"query",scopes:["chat-threads:read"],state:"available"},{billing:"free",category:"agents",description:"Read a child chat thread's transcript, newest page first.",id:"getThreadMessages",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread messages",operation:"query",scopes:["chat-threads:read"],state:"available"},{billing:"free",category:"media",description:"Read how many people watched a shared video, how far they got, and how they answered its published interactions.",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:"branding",description:"Import a brand's claims library from a PromoMats export: preview, then commit; never approves.",id:"importClaims",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"free",category:"knowledge",description:"Fill one of a mission item's manual outputs with an existing presentation or finished video, replacing any earlier link.",id:"linkMissionOutput",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output link",operation:"mutation",scopes:["knowledge:write","presentations: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:"artifacts",description:"List a brand's governed ad templates.",id:"listAdTemplates",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template list",operation:"query",scopes:["brands:read"],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:"branding",description:"List a brand's governed claims with status, scope and references.",id:"listClaims",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims list",operation:"query",scopes:["brands: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 the members and roster agents a caller may mention on a document.",id:"listDiscussionMentionables",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion mentionables",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List the guest review links on a presentation with their pinned revision, room, posting policy, expiry and revocation state.",id:"listDiscussionReviewLinks",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link list",operation:"query",scopes:["presentations:write"],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:"media",description:"Discover six immutable footage caption treatment versions with bounded concrete defaults. Requires footage-caption-treatments and effective Footage Studio access.",id:"listFootageCaptionTreatments",lifecycle:{mode:"bounded"},milestone:"M8",name:"footage caption-treatments",operation:"query",scopes:["media:read"],state:"available"},{billing:"free",category:"presentations",description:"List the caller's durable collaboration inbox items (mentions, assignments, review requests).",id:"listInboxItems",lifecycle:{mode:"bounded"},milestone:"M4",name:"inbox list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"branding",description:"List a brand's ISI and legal blocks with variant, placement and status.",id:"listLegalBlocks",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks list",operation:"query",scopes:["brands: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:"knowledge",description:"List missions using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"listMissions",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"List deck embed shares without bearer tokens. Write access required; recovery stays available on any plan.",id:"listPresentationDeckEmbedShares",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed list",operation:"query",scopes:["presentations:read"],state:"available"},{billing:"free",category:"presentations",description:"List or search 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 standalone embed shares without bearer tokens. Write access required; recovery remains available on any plan.",id:"listPresentationVideoEmbedShares",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed list",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 every SCORM export minted for a presentation video project with its settings and revocation state; export tokens are never returned. Available on any plan so a downgraded workspace can still take links down.",id:"listPresentationVideoScormExports",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm list",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:"knowledge",description:"List the skills available to the workspace, including the team's own disabled skills.",id:"listSkills",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills list",operation:"query",scopes:["skills: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:"knowledge",description:"List the workspace's study sets, newest first, optionally filtered by kind.",id:"listStudySets",lifecycle:{mode:"bounded"},milestone:"M8",name:"study-set list",operation:"query",scopes:["knowledge: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:"agents",description:"List the child chat threads spawned under a parent chat, with status, run id, and settled result.",id:"listThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread list",operation:"query",scopes:["chat-threads: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 immutable video templates available to this workspace.",id:"listVideoTemplates",lifecycle:{mode:"bounded"},milestone:"M8",name:"video templates list",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. Pass scope 'mine' for only the caller's own work. Kinds whose domains carry their own read scope (presentations, videos) are only included when the caller's grant covers them.",id:"listWorkItems",lifecycle:{mode:"bounded"},milestone:"M1",name:"work list",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"free",category:"presentations",description:"Mark the caller's collaboration inbox items as read.",id:"markInboxItemsRead",lifecycle:{mode:"bounded"},milestone:"M4",name:"inbox mark-read",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a free revocable embed link for a public deck. Team plan and embed-links required. Bounded insert; duplicate keys reject and tokens are returned once. No separate approval for an explicitly requested reversible link.",id:"mintPresentationDeckEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed mint",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Mint a free revocable embed link for a finished presentation video. Team plan and embed-links flag required. Bounded single insert; duplicate keys reject and tokens are returned once. No separate approval for this reversible, explicitly requested link.",id:"mintPresentationVideoEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed mint",operation:"mutation",scopes:["presentations:write"],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:"presentations",description:"Apply a copied avatar \u2014 presenter identity plus its placement box \u2014 from a mindframes/presenter@1 clipboard string to one scene or an exact slideIds batch in any presentation video, adapting the box to the target format.",id:"pastePresentationVideoPresenter",lifecycle:{mode:"bounded"},milestone:"M5",name:"presentation video paste-presenter",operation:"mutation",scopes:["presentations: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:"delegated",category:"knowledge",description:'Prepare selected mission items for narration review: each item imports its source (PowerPoint) or generates a deck from a document source, creates its draft, optionally writes speaker notes (`notes`) and generates narration (`narrate`) \u2014 both billed and opt-in \u2014 and requests the human review \u2014 independently and durably. A draft that ends with zero narration is never frozen for review: the item routes back to `narrate` when the request authorized it, or stops `narration_missing` (`narrate_not_authorized` when the request never authorized `narrate` \u2014 a pending yes, not a failure). `review` reads narration that already exists: for a freshly imported deck whose narration the user has not approved, send `stages: ["import", "draft"]` and add `narrate` and `review` only after the user says yes to billed narration. Approving a free import never starts billed work or needs that yes; an item whose request reviews narration it never generated stops `narrate_not_authorized` until the user consents. Document sources spend billed deck generation inside the import stage; the request must set allowDeckGeneration: true to admit them. The `post` stage writes a billed LinkedIn post from the item\'s deck for items whose output plan has one, the `reel` stage renders a billed 15-second vertical reel from it, and the `agent` stage runs the team agent an output names (fulfilment agent) and saves its answer as the output\'s document; naming each stage is its consent. reviewPolicy sets where this request stops for a person (overriding the mission\'s; frozen at admission). creditCeiling caps the credits the request may commit: each billed step reserves a conservative estimate before it starts, and one that would pass the ceiling does not start (its item stops credit_ceiling_reached).',id:"prepareMission",lifecycle:{mode:"background",status:{cliCommand:"mission prepare status",pollAfterSeconds:10}},milestone:"M1",name:"mission prepare",operation:"generation",scopes:["knowledge:write","presentations:read","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:"Review one narrated-video scene in the full draft context and propose concrete improvements; retain useful suggestions across minor edits.",id:"preparePresentationVideoMediaSuggestions",lifecycle:{mode:"background",status:{cliCommand:"presentation video suggestions status",pollAfterSeconds:2}},milestone:"M8",name:"presentation video suggestions 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:"dynamic",category:"presentations",description:"Prepare and retain an isolated narration or editable text-layer change for review.",id:"preparePresentationVideoSuggestionAction",lifecycle:{mode:"background",status:{cliCommand:"presentation video suggestions action prepare status",pollAfterSeconds:2}},milestone:"M8",name:"presentation video suggestions action prepare",operation:"generation",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:"presentations",description:"Freeze the draft's interactions onto the finished video as an immutable, versioned manifest resolved against the render's persisted scene timeline. Omitting renderId publishes onto the project's current video; an unchanged republish returns the latest manifest with created:false, and publishing an empty interactions list unpublishes.",id:"publishPresentationVideoInteractions",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video interaction publish",operation:"mutation",scopes:["presentations: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 saved Footage project and version history, 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:"knowledge",description:"Read a bounded window of a Library file's extracted text (for example its chapter list) before planning work from it.",id:"readLibraryFileExcerpt",lifecycle:{mode:"bounded"},milestone:"M1",name:"file excerpt",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:"knowledge",description:"Reconcile a mission using durable intended outcomes and permission-checked native artifact links. No generation or acceptance.",id:"reconcileMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission reconcile",operation:"query",scopes:["knowledge:read"],state:"available"},{billing:"delegated",category:"knowledge",description:"Finish an interrupted render start from its recorded intent identity, or report the recovery state for another principal without granting their spend or retry authority.",id:"recoverMissionRenderIntent",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission output render recover",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations: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:"delegated",category:"knowledge",description:"Regenerate one of a mission item's automated outputs: the deck from its source (a PowerPoint re-imports free; a document source needs allowDeckGeneration), the narrated video from the current deck (new narration needs allowNarration), the LinkedIn post from the current deck (billed; needs allowTextGeneration), the reel from the current deck (a billed render; needs allowReelRender), or an output a team agent delivers (a billed agent run; needs allowAgentRuns). The current output stays until the new one is ready.",id:"regenerateMissionOutput",lifecycle:{mode:"background",status:{cliCommand:"mission output regenerate status",pollAfterSeconds:10}},milestone:"M1",name:"mission output regenerate",operation:"generation",scopes:["knowledge:write","presentations:read","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:"knowledge",description:"Start or safely resume rendering the exact human-approved narration checkpoint for one mission item.",id:"renderMissionOutput",lifecycle:{mode:"background",status:{cliCommand:"mission output render status",pollAfterSeconds:10}},milestone:"M1",name:"mission output render",operation:"generation",scopes:["knowledge:write","presentations:read","presentations: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:"knowledge",description:"Replace a mission's complete order: phases and every live item, including moves between phases, without touching running preparation.",id:"reorderMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission reorder",operation:"mutation",scopes:["knowledge: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:"knowledge",description:"Replace a mission item source with a Library PowerPoint and resume its free blocked import without widening preparation consent.",id:"replaceMissionItemSource",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission source replace",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Freeze a narration draft for human review; rendering remains manual.",id:"requestMissionNarrationReview",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission review request",operation:"mutation",scopes:["knowledge:write","presentations:read","presentations:write"],state:"available"},{billing:"dynamic",category:"presentations",description:"Run a bounded specialist review of a frozen presentation revision; findings land in the deck's discussion.",id:"requestPresentationReview",lifecycle:{mode:"background",status:{cliCommand:"presentation review status",pollAfterSeconds:3}},milestone:"M4",name:"presentation review request",operation:"mutation",scopes:["presentations: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 Applied Scene Change without generating new content.",id:"restorePresentationVideoSuggestionAction",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions action restore",operation:"mutation",scopes:["presentations: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:"presentations",description:"Revoke a guest review link. Every guest session it admitted is fenced on the next read or write.",id:"revokeDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a deck embed share with no separate approval for explicitly requested access removal. Write access required. CAS preserves the original timestamp; recovery stays available on any plan.",id:"revokePresentationDeckEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation embed revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a standalone video embed share. Free reversible access removal with no separate approval; repeated calls preserve the revocation timestamp. Write access required; recovery remains available on any plan.",id:"revokePresentationVideoEmbedShare",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video embed revoke",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Revoke a SCORM export's embed link so it stops resolving for LMS learners. Idempotent: a second call returns the same revokedAt. Available on any plan.",id:"revokePresentationVideoScormExport",lifecycle:{mode:"bounded"},milestone:"M4",name:"presentation video scorm revoke",operation:"mutation",scopes:["presentations: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. missionId narrows to a mission's deliverables and missionStatus to deliverables at those statuses (not_started, in_progress, waiting_for_you, ready, final, changed_since_final); a result that is a mission deliverable carries fromMission.",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:"free",category:"presentations",description:"Select a saved version of scene suggestions without applying changes, generating media or changing the scene.",id:"selectPresentationVideoMediaSuggestionsVersion",lifecycle:{mode:"bounded"},milestone:"M8",name:"presentation video suggestions select",operation:"mutation",scopes:["presentations: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:"delegated",category:"agents",description:"Send a message into an existing child chat thread: delivered live into a running turn, queued when the turn cannot take guidance, or starts a new durable turn.",id:"sendThreadMessage",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread send",operation:"mutation",scopes:["chat-threads: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:"artifacts",description:"Set the poster image an artifact shows on cards and share surfaces, or reset it to the automatic preview.",id:"setArtifactPoster",lifecycle:{mode:"bounded"},milestone:"M8",name:"artifact poster set",operation:"mutation",scopes:["knowledge: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:"Set or clear a brand's default opening and closing card scenes for narrated presentation videos. Free reversible brand configuration.",id:"setBrandVideoBookends",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-bookends",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's saved video presenter defaults.",id:"setBrandVideoPresenters",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-presenters",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"branding",description:"Replace a brand's saved video voice defaults.",id:"setBrandVideoVoices",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding video-defaults set-voices",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:"Create or edit a draft claim, or restrict or retire one; never approves.",id:"setClaim",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding claims 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:"Assign an accountable team member to a discussion thread; notifies the assignee.",id:"setDiscussionAssignee",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion assign",operation:"mutation",scopes:["presentations: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:"Hide or restore a discussion message. Authors moderate their own messages; members moderate guest review activity. Hidden rows are excluded from guest reads.",id:"setDiscussionMessageVisibility",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion message visibility",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Replace the requested reviewers on a discussion thread; newly added reviewers are notified.",id:"setDiscussionReviewers",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion reviewers",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:"Switch one claim slot of a governed deck to another approved claim; references are renumbered.",id:"setGovernedDeckClaim",lifecycle:{mode:"bounded"},milestone:"M6",name:"presentation governed set-claim",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"branding",description:"Create or edit a draft ISI or legal block, or restrict or retire one; never approves.",id:"setLegalBlock",lifecycle:{mode:"bounded"},milestone:"M2",name:"branding legal-blocks set",operation:"mutation",scopes:["brands:write"],state:"available"},{billing:"free",category:"knowledge",description:"Archive a mission so finished work leaves the active list, or restore it. Archiving is housekeeping: all history stays addressable and nothing in the pipeline stops.",id:"setMissionArchived",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission archive",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Star a mission so it stays at the top of your list, or remove the star. A star is a personal shortcut, never a permission.",id:"setMissionFavorite",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission favorite",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"knowledge",description:"Pin a mission for the whole workspace, or lift the pin. The pin is the workspace's shared mark, visible to every member.",id:"setMissionPin",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission pin",operation:"mutation",scopes:["knowledge: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:"Add a voice to your team's shortlist, or remove it. A shortlist is shared by the whole workspace and grants no permission.",id:"setVoiceShortlisted",lifecycle:{mode:"bounded"},milestone:"M8",name:"voice shortlist",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:"knowledge",description:"Start or explicitly retry an independent PowerPoint import for one mission item and its current Library source.",id:"startMissionSourceImport",lifecycle:{mode:"background",status:{cliCommand:"mission source import status",pollAfterSeconds:10}},milestone:"M1",name:"mission source import",operation:"generation",scopes:["knowledge:write","presentations:write"],state:"available"},{billing:"free",category:"knowledge",description:"Stop in-flight mission preparation: the named live items (or every live item when omitted) stop typed cancelled, their in-flight child generation, import, and narration runs are cancelled, and the coordinator run settles cancelled. Completed work is not un-billed or undone.",id:"stopMissionPreparation",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission prepare stop",operation:"mutation",scopes:["knowledge:write"],state:"available"},{billing:"free",category:"agents",description:"Stop a running child chat thread by requesting cancellation of its durable run and live worker.",id:"stopThread",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread stop",operation:"mutation",scopes:["chat-threads: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:"artifacts",description:"Save a new draft version of a governed ad template; earlier versions stay unchanged.",id:"updateAdTemplate",lifecycle:{mode:"bounded"},milestone:"M6",name:"ad-template update",operation:"mutation",scopes:["brands: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:"presentations",description:"Edit a discussion message's body. Only the attributed author may edit; sets editedAt.",id:"updateDiscussionMessage",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion message update",operation:"mutation",scopes:["presentations:write"],state:"available"},{billing:"free",category:"presentations",description:"Update a guest review link's label, posting policy, expiry or pinned revision under optimistic concurrency.",id:"updateDiscussionReviewLink",lifecycle:{mode:"bounded"},milestone:"M4",name:"discussion review-link update",operation:"mutation",scopes:["presentations: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:"knowledge",description:"Append intended items or update goals and sources while retaining previously accepted outputs.",id:"updateMission",lifecycle:{mode:"bounded"},milestone:"M1",name:"mission 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"},{billing:"free",category:"knowledge",description:"Create or update a workspace- or member-owned skill from a SKILL.md document plus optional bundled files.",id:"upsertTeamSkill",lifecycle:{mode:"bounded"},milestone:"M3",name:"skills create",operation:"mutation",scopes:["skills:write"],state:"available"},{billing:"free",category:"agents",description:"Wait until child chat threads reach a terminal state and return their final status and results.",id:"waitThreads",lifecycle:{mode:"bounded"},milestone:"M10",name:"thread wait",operation:"query",scopes:["chat-threads:read"],state:"available"}],Fo={updatePresentationVideoSettings:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{basedOnVersionNumber:{type:"integer",minimum:1,maximum:9007199254740991},branchId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},expectedHeadVersionNumber:{type:"integer",minimum:1,maximum:9007199254740991},captionBackgroundColor:{description:"Caption box color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionFontFamily:{description:"Caption CSS font-family list.",type:"string",minLength:1,maxLength:180},captionFontSize:{description:"Caption font size in pixels, from 20 to 96.",type:"integer",minimum:20,maximum:96},captionHeight:{description:"Caption box height as a frame fraction, from 0.05 to 0.5.",type:"number",minimum:.05,maximum:.5},captionHighlightColor:{description:"Current-word highlight color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionTextColor:{description:"Caption text color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},captionWidth:{description:"Caption box width as a frame fraction, from 0.18 to 0.95.",type:"number",minimum:.18,maximum:.95},captionX:{description:"Caption box center on the horizontal axis, from 0 to 1.",type:"number",minimum:0,maximum:1},captionY:{description:"Caption box center on the vertical axis, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterAnchor:{description:"Presenter box preset, or free for explicit x/y placement.",type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},presenterApplyToAll:{description:"Promote the targeted scene's resulting placement to the project default and clear every per-scene placement override. Requires presenterSlideId.",type:"boolean",const:!0},presenterBackgroundFit:{description:"How a presenter background image fills the frame.",type:"string",enum:["cover","contain"]},presenterBackgroundHex:{description:"Presenter background color, required for kind=color.",type:"string",pattern:"^#[0-9a-fA-F]{6}$"},presenterBackgroundKind:{description:"Presenter background type. color requires presenterBackgroundHex; image requires presenterBackgroundUrl.",type:"string",enum:["original","transparent","color","image"]},presenterBackgroundUrl:{description:"Hosted presenter background image URL, required for kind=image.",type:"string",maxLength:2048,format:"uri"},presenterBorderRadius:{description:"Presenter corner radius from 0 (square) to 0.5 (circle or pill).",type:"number",minimum:0,maximum:.5},presenterFramingX:{description:"Horizontal crop focus inside the presenter box, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterFramingY:{description:"Vertical crop focus inside the presenter box, from 0 to 1.",type:"number",minimum:0,maximum:1},presenterFramingZoom:{description:"Presenter media crop zoom, from 1 to 2.",type:"number",minimum:1,maximum:2},presenterHeight:{description:"Explicit presenter box height as a frame fraction, from 0.05 to 1.",type:"number",minimum:.05,maximum:1},presenterOffsetX:{description:"Horizontal edge offset for anchored placement, from 0 to 0.35.",type:"number",minimum:0,maximum:.35},presenterOffsetY:{description:"Vertical edge offset for anchored placement, from 0 to 0.35.",type:"number",minimum:0,maximum:.35},presenterSize:{description:"Presenter box width as a frame fraction, from 0.08 to 0.9.",type:"number",minimum:.08,maximum:.9},presenterSlideId:{description:"Scene whose presenter placement, visibility, or scene-specific background should change. Omit to edit the project default placement/background.",type:"string",minLength:1,maxLength:240},presenterUseDefault:{description:"Remove this scene's placement override so it uses the project default. Requires presenterSlideId.",type:"boolean",const:!0},presenterVisible:{description:"Show or hide the presenter on one scene. Requires presenterSlideId. Showing restores project-default inheritance, matching the editor.",type:"boolean"},presenterX:{description:"Presenter box horizontal center, from 0 to 1; valid only for a free placement.",type:"number",minimum:0,maximum:1},presenterY:{description:"Presenter box vertical center, from 0 to 1; valid only for a free placement.",type:"number",minimum:0,maximum:1},projectId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",description:"Presentation video project whose saved setup should be updated."},settings:{description:"Advanced partial settings profile to merge into the saved project. Use the typed caption fields for caption placement and style.",type:"object",properties:{avatarId:{description:"Avatar or look id from `avatar options` to present the whole video. The server resolves the presenter identity and render tier. Alternative to `presenter`; to remove the presenter pass presenter: null.",type:"string",minLength:1,maxLength:240},captions:{description:"Render word-level captions when narration timings exist.",type:"boolean"},captionPlacement:{description:"Move or resize the caption box with normalized x, y, width, and height values. Omitted fields keep their saved values.",type:"object",properties:{height:{type:"number",minimum:.05,maximum:.5,description:"Caption box height as a frame fraction, from 0.05 to 0.5."},width:{type:"number",minimum:.18,maximum:.95,description:"Caption box width as a frame fraction, from 0.18 to 0.95."},x:{type:"number",minimum:0,maximum:1,description:"Caption box center on the horizontal axis, from 0 to 1."},y:{type:"number",minimum:0,maximum:1,description:"Caption box center on the vertical axis, from 0 to 1."}}},captionStyle:{description:"Change caption font, size, text, highlight, or background colors. Omitted fields keep their saved values.",type:"object",properties:{backgroundColor:{description:"Caption box color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},fontFamily:{description:"Caption CSS font-family list.",type:"string",minLength:1,maxLength:180},fontSizePx:{description:"Caption font size in pixels, from 20 to 96.",type:"integer",minimum:20,maximum:96},highlightColor:{description:"Current-word highlight color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180},textColor:{description:"Caption text color as hex, rgb, hsl, transparent, or var().",type:"string",minLength:1,maxLength:180}}},format:{description:"Output aspect ratio for the MP4.",type:"string",enum:["16:9","9:16","1:1"]},music:{description:"Background music settings to merge into the saved project.",type:"object",properties:{audioUrl:{type:"string",format:"uri"},fileName:{type:"string",maxLength:240},matchDeckStyle:{type:"boolean"},mode:{default:"basic",type:"string",enum:["basic","standard","stock","upload","off"]},prompt:{type:"string",minLength:1,maxLength:8e3},regenerateToken:{type:"string",minLength:1,maxLength:64},stockDurationSec:{type:"number",exclusiveMinimum:0,maximum:86400},stockSelection:{type:"string",enum:["auto","manual"]},stockTrackId:{type:"string",minLength:1,maxLength:500},volume:{default:.12,type:"number",minimum:0,maximum:1}}},narrationAudioTags:{description:"Use audio tags such as [short pause] or [excited] in the narration: written in when narration is generated, and performed by voices that support them. false keeps any tags in the text but removes them before speech. Has an effect only where audio tags are enabled for the workspace.",type:"boolean"},narrationDensity:{description:"How much narration to generate per slide.",type:"string",enum:["brief","balanced","deep"]},presenter:{description:"Selected avatar/presenter, or null to remove it.",anyOf:[{type:"object",properties:{assetClass:{type:"string",enum:["digital_twin","photo_avatar","studio_avatar"]},background:{oneOf:[{type:"object",properties:{kind:{type:"string",const:"original"}},required:["kind"]},{type:"object",properties:{kind:{type:"string",const:"transparent"}},required:["kind"]},{type:"object",properties:{hex:{type:"string",pattern:"^#[0-9a-fA-F]{6}$"},kind:{type:"string",const:"color"}},required:["hex","kind"]},{type:"object",properties:{fit:{default:"cover",type:"string",enum:["cover","contain"]},kind:{type:"string",const:"image"},url:{type:"string",maxLength:2048,format:"uri"}},required:["kind","url"]}]},defaultPlacement:{type:"object",properties:{anchor:{type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},framing:{default:{x:.5,y:.1,zoom:1},type:"object",properties:{x:{default:.5,type:"number",minimum:0,maximum:1},y:{default:.1,type:"number",minimum:0,maximum:1},zoom:{default:1,type:"number",minimum:1,maximum:2}}},borderRadius:{default:0,type:"number",minimum:0,maximum:.5},offsetX:{default:.04,type:"number",minimum:0,maximum:.35},offsetY:{default:.05,type:"number",minimum:0,maximum:.35},size:{default:.24,type:"number",minimum:.08,maximum:.9},height:{type:"number",minimum:.05,maximum:1},x:{type:"number",minimum:0,maximum:1},y:{type:"number",minimum:0,maximum:1}},required:["anchor"]},delivery:{type:"object",properties:{expressiveness:{type:"string",enum:["low","medium","high"]},motionPrompt:{type:"string",minLength:1,maxLength:600},resolution:{type:"string",enum:["720p","1080p","4k"]}}},lookId:{type:"string",minLength:1},name:{type:"string",minLength:1,maxLength:160},presenterId:{type:"string",minLength:1},previewImageUrl:{type:"string",format:"uri"},renderTier:{type:"string",enum:["basic","standard","premium"]},source:{type:"object",properties:{height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},orientation:{type:"string",enum:["landscape","portrait","square"]},width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["height","orientation","width"]},perSlideEnabled:{default:{},type:"object",propertyNames:{type:"string"},additionalProperties:{type:"boolean"}},perSlidePlacements:{default:{},type:"object",propertyNames:{type:"string"},additionalProperties:{type:"object",properties:{anchor:{type:"string",enum:["bottom-left","bottom-right","top-left","top-right","left-half","right-half","full","left-overlay","right-overlay","free"]},framing:{default:{x:.5,y:.1,zoom:1},type:"object",properties:{x:{default:.5,type:"number",minimum:0,maximum:1},y:{default:.1,type:"number",minimum:0,maximum:1},zoom:{default:1,type:"number",minimum:1,maximum:2}}},borderRadius:{default:0,type:"number",minimum:0,maximum:.5},offsetX:{default:.04,type:"number",minimum:0,maximum:.35},offsetY:{default:.05,type:"number",minimum:0,maximum:.35},size:{default:.24,type:"number",minimum:.08,maximum:.9},height:{type:"number",minimum:.05,maximum:1},x:{type:"number",minimum:0,maximum:1},y:{type:"number",minimum:0,maximum:1}},required:["anchor"]}}},required:["defaultPlacement","lookId","name","presenterId","renderTier"]},{type:"null"}]},speakerNotesMode:{description:"How narration treats the deck's speaker notes: `as_is` copies each applicable note into its scene verbatim with no generation, `as_reference` hands notes to the model as source material. `ignored` skips the note entirely: it never reaches the model and the scene is narrated from the slide alone.",type:"string",enum:["as_is","as_reference","ignored"]},speakerNotesModeBySlide:{description:"Per-scene exceptions to speakerNotesMode, keyed by scene id. Replaces the saved exceptions; an empty object clears them.",type:"object",propertyNames:{type:"string"},additionalProperties:{type:"string",enum:["as_is","as_reference","ignored"]}},renderEngine:{description:"Terminal renderer for the MP4.",type:"string",enum:["remotion","hyperframes"]},renderTier:{description:"Render tier for `avatarId`. Only valid together with avatarId; defaults to the look's standard tier.",type:"string",enum:["basic","standard","premium"]},voice:{description:"Selected narration voice, or null to clear it.",anyOf:[{type:"object",properties:{description:{anyOf:[{type:"string"},{type:"null"}]},id:{type:"string",minLength:1},label:{type:"string",minLength:1,maxLength:160}},required:["id","label"]},{type:"null"}]},sceneVoiceIds:{description:"Merge narration voice overrides by exact composition scene ID. Omitted scenes and the default voice stay unchanged. Use all desired scene IDs to apply to multiple scenes. Giving a voice-disabled scene a voice turns its narration back on.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{type:"string",minLength:1}},sceneVoiceEnabled:{description:"Turn narration off (false) or back on (true) by exact composition scene ID. A disabled scene keeps its narration text, voice override and tone, renders silent for its current duration, and generates no voiceover or presenter clip; it does not fall back to the default voice. Omitted scenes stay unchanged.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{type:"boolean"}},voiceId:{description:"Narration voice id from `avatar options`. The server resolves its label. Alternative to `voice`; to clear the voice pass voice: null.",type:"string",minLength:1,maxLength:240},voiceTone:{description:"How every narrated scene is performed: a preset and/or stability, expressiveness and speed. Replaces the saved tone; null clears it so each voice uses its own default. Recorded clones keep the delivery of their recording. Changes re-voice affected scenes on the next render.",anyOf:[{type:"object",properties:{preset:{description:"Named tone: professional (steady and neutral \u2014 the default for narration), conversational (the speech provider's balanced defaults) or energetic (lively, animated). Individual values override it.",type:"string",enum:["professional","conversational","energetic"]},stability:{description:"0-1. Higher reads more evenly and consistently; lower widens the emotional range.",type:"number",minimum:0,maximum:1},expressiveness:{description:"0-1. How much the read exaggerates emphasis and emotion. 0 is neutral.",type:"number",minimum:0,maximum:1},speed:{description:"0.7-1.2 speaking pace, 1 is normal.",type:"number",minimum:.7,maximum:1.2}},additionalProperties:!1},{type:"null"}]},sceneVoiceTones:{description:"Merge per-scene tone overrides by exact composition scene ID; null removes a scene's override. Omitted scenes stay unchanged.",type:"object",propertyNames:{type:"string",minLength:1},additionalProperties:{anyOf:[{type:"object",properties:{preset:{description:"Named tone: professional (steady and neutral \u2014 the default for narration), conversational (the speech provider's balanced defaults) or energetic (lively, animated). Individual values override it.",type:"string",enum:["professional","conversational","energetic"]},stability:{description:"0-1. Higher reads more evenly and consistently; lower widens the emotional range.",type:"number",minimum:0,maximum:1},expressiveness:{description:"0-1. How much the read exaggerates emphasis and emotion. 0 is neutral.",type:"number",minimum:0,maximum:1},speed:{description:"0.7-1.2 speaking pace, 1 is normal.",type:"number",minimum:.7,maximum:1.2}},additionalProperties:!1},{type:"null"}]}}},additionalProperties:!1}},required:["projectId"],additionalProperties:!1}};function Kr(e){return{capabilities:Gr,catalogVersion:1,reason:e,settingsSchemas:Fo,source:"snapshot"}}async function bn(e=Yd){try{let{capabilities:t,catalogVersion:n,settingsSchemas:r}=await e();return!Array.isArray(t)||t.length===0?Kr("the live catalog returned no capabilities"):{capabilities:t,catalogVersion:n,settingsSchemas:r??Fo,source:"live"}}catch(t){let n=t instanceof Error?t.message:String(t);return Kr(n)}}var ml=["presentations","media","branding","knowledge","research","artifacts","agents","support"],Gy=80,Ky=30;function Wy(e){return e.billing!==void 0&&e.billing!=="free"&&e.billing!=="quota"}function Jy(e){return e.lifecycle?.mode==="background"}function zy(e,t){if(t<=0)return[e];let n=[],r="";for(let i of e.split(/\s+/).filter(Boolean))r===""?r=i:r.length+1+i.length<=t?r=`${r} ${i}`:(n.push(r),r=i);return r!==""&&n.push(r),n.length>0?n:[""]}function pl(e){let t=ml.indexOf(e);return t===-1?ml.length:t}function Hy(e,t){let n=t.search?.trim().toLowerCase(),r=t.category?.trim().toLowerCase();return e.filter(i=>r&&(i.category??"").toLowerCase()!==r?!1:n?`${i.name} ${i.description??""}`.toLowerCase().includes(n):!0)}function Xy(e){let t=new Map;for(let o of e){let c=o.category??"other",l=t.get(c);l?l.push(o):t.set(c,[o])}let n=[...t.entries()].sort(([o],[c])=>{let l=pl(o)-pl(c);return l!==0?l:o.localeCompare(c)}),r=Math.min(Ky,Math.max(...e.map(o=>o.name.length))),i=[];for(let[o,c]of n){c.sort((l,d)=>l.name.localeCompare(d.name)),i.length>0&&i.push(""),i.push(Xn.bold(`${o} (${c.length})`));for(let l of c){let d=`${Wy(l)?"$":" "}${Jy(l)?"*":" "}`,g=l.name.padEnd(r),y=2+r+1+d.length+1,v=Math.max(24,Gy-y),x=zy(l.description??"",v);i.push(` ${Xn.cyan(g)} ${Xn.yellow(d)} ${x[0]??""}`.trimEnd());for(let T of x.slice(1))i.push(`${" ".repeat(y)}${T}`)}}return i}function Yy(e){return e.map(t=>`${t.name} ${t.state} ${t.milestone}`)}function Qy(e,t={filtered:!1}){if(e.length===0)return[t.filtered?"No capabilities match that filter.":"No capabilities available."];if(!e.some(o=>o.description||o.category))return Yy(e);let r=f.commands[0],i=Xy(e);return i.push(""),i.push(Xn.dim(`${e.length} capabilities \xB7 $ = paid \xB7 * = background (returns a run id)`)),i.push(Xn.dim(`Filter with: ${r} capabilities --search <query>`)),i}var ul=new By("capabilities").description("Index of everything this CLI can do \u2014 every command, grouped and described").option("-f, --format <format>","Output format: human, json, quiet",b("--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 bn(),n=Hy(t.capabilities,e),r=!!(e.search||e.category);if(e.format==="json"){m({capabilities:n,catalogVersion:t.catalogVersion,source:t.source,...t.reason?{sourceReason:t.reason}:{}});return}if(e.format==="quiet"){for(let i of n)console.log(i.name);return}t.source==="snapshot"&&q(`Showing the capability list baked into this CLI build (${t.reason}); the deployed catalog may have moved on.`);for(let i of Qy(n,{filtered:r}))console.log(i)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{mkdirSync as nb,writeFileSync as rb}from"fs";import{dirname as yl,join as ib}from"path";import{confirm as bl,input as ob,password as ab,select as sb}from"@inquirer/prompts";import Yn from"chalk";import{Command as pt}from"commander";import Jr from"ora";import Zy from"conf";var Wr=new Zy({projectName:"conceptcraft",configName:"feature-cache"}),eb=3600*1e3,tb=1440*60*1e3;function gl(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 fl(){if(!mn())return null;let e=Wr.get("featureFlags");if(!e)return null;let t=gl(Qe());if(e.apiKeyHash&&e.apiKeyHash!==t)return Tt(),null;let n=Date.now()-e.fetchedAt;return n>tb?null:(n>eb&&Bo(),e.flags)}function Bo(){At().catch(()=>{})}async function At(){let e=await mc(),t=Qe();return Wr.set("featureFlags",{flags:e,fetchedAt:Date.now(),apiKeyHash:t?gl(t):void 0}),e}function Tt(){Wr.delete("featureFlags")}function hl(){return Wr.path}var wl=new pt("config").description("Manage CLI configuration: account settings, and the cached feature flags that decide which commands appear").addCommand(new pt("init").description("Initialize configuration interactively").action(async()=>{console.log(),console.log(Yn.bold(`${f.displayName} CLI Configuration`)),console.log(Yn.gray("\u2500".repeat(35))),console.log();try{let e=await ab({message:"Enter your API key:",mask:"*",validate:r=>!r||r.trim().length===0?"API key is required":Po(r.trim())?!0:"Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"});if(So(e.trim()),await bl({message:`Use a custom API URL? (default: ${f.apiUrl.replace("https://","")})`,default:!1})){let r=await ob({message:"Enter API URL:",default:K(),validate:i=>{try{return new URL(i),!0}catch{return"Invalid URL format"}}});Eo(r)}console.log();let n=Jr("Verifying API key...").start();try{let r=await Je();if(n.succeed("API key verified!"),console.log(),I(`Logged in as: ${r.user.email}`),r.teams.length===0)q("No teams found for this user.");else if(r.teams.length===1){let i=r.teams[0];ln(i.id),I(`Team: ${i.name} (${i.planName})`)}else{console.log(),I(`You have access to ${r.teams.length} teams.`);let i=await sb({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});ln(i);let o=r.teams.find(c=>c.id===i);C(`Selected team: ${o?.name}`)}try{await At()}catch{}}catch(r){n.fail("Failed to verify API key"),q(`Could not verify API key: ${u(r,"The operation could not be completed.")}`),q(`You may need to set the team ID manually: ${f.commands[0]} config set team-id <id>`)}console.log(),C("Configuration saved!"),I(`Config file: ${zn()}`),console.log()}catch(e){if(e.name==="ExitPromptError"){console.log(),I("Configuration cancelled.");return}throw e}})).addCommand(new pt("show").description("Show current configuration").option("--verify","Verify API key and show team details").action(async e=>{let t=Od();if(De("Current Configuration"),console.log(),O("API Key",qd()??Yn.red("Not set")),O("API URL",t.apiUrl),O("Default Team ID",t.defaultTeamId??Yn.gray("Not set")),console.log(),O("Config file",zn()),e.verify&&t.apiKey){console.log();let n=Jr("Verifying...").start();try{let r=await Je();n.succeed("Verified"),console.log(),O("User",r.user.email),r.currentTeam&&O("Current Team",`${r.currentTeam.name} (${r.currentTeam.planName})`),r.teams.length>1&&O("Total Teams",String(r.teams.length))}catch{n.fail("Verification failed"),q("The operation could not be completed.")}}console.log()})).addCommand(new pt("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":Po(t)||(a("Invalid API key format. Keys should start with 'cc_slides_' or 'mcp_'"),process.exit(6)),So(t),Tt(),C("API key updated"),At().catch(()=>{});break;case"api-url":try{new URL(t),Eo(t),C(`API URL set to: ${t}`)}catch{a("Invalid URL format"),process.exit(6)}break;case"team-id":ln(t),C(`Default team ID set to: ${t}`);break;default:a(`Unknown config key: ${e}`),console.log(Yn.gray("Valid keys: api-key, api-url, team-id")),process.exit(6)}})).addCommand(new pt("clear").description("Clear all configuration").action(async()=>{try{await bl({message:"Are you sure you want to clear all configuration?",default:!1})?(Ur(),Tt(),C("Configuration cleared")):I("Cancelled")}catch{I("Cancelled")}})).addCommand(new pt("refresh").description("Refresh cached feature flags").action(async()=>{let e=Jr("Refreshing feature flags...").start();try{await At(),e.succeed("Feature flags refreshed"),I(`Run '${f.commands[0]} --help' to see updated commands`)}catch{e.fail("Failed to refresh"),a("The command failed. Please try again."),process.exit(1)}})).addCommand(new pt("path").description("Show configuration file path").option("--cache","Show feature cache file path").action(e=>{e.cache?console.log(hl()):console.log(zn())})).addCommand(new pt("pull").description("Pull your account settings (memory, brand, prefs) into a local config.toml").action(async()=>{let e=Jr("Pulling settings...").start();try{let t=await fe(),n=await fetch(`${K()}/api/cli/settings`,{headers:t});if(!n.ok)throw new Error(`Request failed (HTTP ${n.status})`);let r=await n.text(),i=ib(yl(zn()),"settings.toml");nb(yl(i),{recursive:!0}),rb(i,r,"utf8"),e.succeed("Settings pulled"),I(`Written to ${i}`)}catch{e.fail("Failed to pull settings"),a("The command failed. Please try again."),process.exit(1)}}));import{confirm as cb}from"@inquirer/prompts";import{Command as lb}from"commander";function Ot(e){return e instanceof P&&e.errorCode==="approval_required"}function vl(e){return`Retry this exact request with --approval-receipt <receipt> --idempotency-key ${e}, or re-run it with the root --wait-for-approval flag to wait for the approval here.`}function zr(e,t){return`This request needs approval before it can run.${e.approvalUrl?` Open ${e.approvalUrl}.`:""} ${vl(t)}`}function Hr(e){return{success:!1,error:e.error,errorCode:"approval_required",...e.caught.approvalUrl?{approvalUrl:e.caught.approvalUrl}:{},idempotencyKey:e.idempotencyKey,retry:vl(e.idempotencyKey)}}import{createHash as db}from"crypto";function Q(e){let t=db("sha256").update(JSON.stringify({command:e.command,payload:Go(e.payload),workspaceId:e.workspaceId})).digest("hex");return`cli:${e.command.trim().toLowerCase().replace(/[^a-z0-9._:-]+/g,"-").replace(/^-+|-+$/g,"")||"command"}:${t}`}function Go(e){return Array.isArray(e)?e.map(Go):!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,Go(n)]))}var Il=new lb("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 w(),!t.yes&&!t.force)try{if(!await cb({message:`Are you sure you want to delete presentation "${e}"?`,default:!1})){t.quiet||q("Deletion cancelled");return}}catch{t.quiet||q("Deletion cancelled");return}let n=t.teamId??ve(),r=t.idempotencyKey??Q({command:"presentation:delete",payload:{slug:e},workspaceId:n??"configured-default"});try{await oc(e,{approvalReceipt:t.approvalReceipt,idempotencyKey:r,teamId:n}),t.quiet||C(`Presentation "${e}" deleted`)}catch(i){Ot(i)?a(zr(i,r)):a("The command failed. Please try again."),process.exit(i.exitCode??1)}});import xl from"chalk";import{Command as wn}from"commander";import mb from"ora";import{createParser as JN}from"eventsource-parser";import HN from"chalk";import YN from"ora";async function kl(e,t={}){let n=e.body?.getReader();if(!n)throw new Error("Response body is not readable");let r=new TextDecoder,i="",o=!1;for(;!o;){let c=await n.read();if(o=c.done,c.value){let l=r.decode(c.value,{stream:!0});i+=l,t.quiet||process.stdout.write(l)}}return t.quiet||console.log(),i}function pb(){return new wn("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)",b("--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 w();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 i=mb("Fetching presentation...").start();try{let o=await fn(e);i.text="Generating blog post...";let c=await pc(o.id,o.documentCreatedAt||o.createdAt,{targetWordCount:n,tone:t.tone,targetAudience:t.audience??"General Audience",customInstructions:t.instructions??"",includeImages:!t.noImages,includeTableOfContents:t.toc??!1}),l=await kl(c,{quiet:!0});i.succeed("Blog generated"),t.format==="json"?console.log(JSON.stringify({presentationId:e,title:o.title,wordCount:n,tone:t.tone,content:l},null,2)):t.format==="markdown"?console.log(l):(console.log(),console.log(xl.bold(`Blog: ${o.title}`)),console.log(xl.gray("\u2500".repeat(40))),console.log(),console.log(l),console.log())}catch(o){i.fail("Generation failed"),a("The command failed. Please try again."),process.exit(o.exitCode??1)}})}function ub(){return new wn("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)",b("--format",["human","json"]),"human").action(async(e,t)=>{await w(),I("Tweet generation coming soon.")})}function gb(){return new wn("linkedin").description("Generate a LinkedIn carousel from a presentation").argument("<slug>","Presentation slug").option("-f, --format <format>","Output format (human, json)",b("--format",["human","json"]),"human").action(async e=>{await w(),I("LinkedIn carousel generation coming soon.")})}function fb(){return new wn("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)",b("--format",["human","json"]),"human").action(async(e,t)=>{await w(),I("Question generation coming soon.")})}function hb(){return new wn("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)",b("--format",["human","json","markdown"]),"human").action(async(e,t)=>{await w(),I("Cheat sheet generation coming soon.")})}function Rl(e=fl()){let t=new wn("derive").description("Generate derivative content from a presentation");return e&&(e.deckToBlog&&t.addCommand(pb()),e.deckToTweets&&t.addCommand(ub()),e.linkedInCarousel&&t.addCommand(gb()),e.redTeamQuestions&&t.addCommand(fb()),e.presenterCheatSheet&&t.addCommand(hb())),t}import{Command as yb}from"commander";import Ko from"chalk";var Cl=new yb("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)",b("--format",["human","json"]),"human").action(async e=>{await w(),I("Idea generation is available in the web dashboard."),console.log(),console.log(Ko.gray("The CLI will support idea generation in a future release.")),console.log(),console.log("For now, try these approaches:"),console.log(Ko.gray("` 1. Visit the ${brand.displayName} dashboard and use the idea generator`")),console.log(Ko.gray(" 2. Create a presentation with a broad topic and refine it")),console.log()});import{readFile as bb}from"fs/promises";import{basename as wb,resolve as vb}from"path";import{Command as Ib}from"commander";import kb from"ora";var Sl=new Ib("import").description("Import a presentation from ZIP (admin only)").argument("<file>","Path to ZIP file");Sl._hidden=!0;var El=Sl.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 w();try{(await Je()).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=vb(e),r=wb(n);r.endsWith(".zip")||(a("File must be a ZIP archive"),process.exit(6));let i=kb("Reading file...").start();try{let o=await bb(n);t.dryRun?i.text="Validating...":i.text="Importing presentation...";let c=await dc(o,r,{dryRun:t.dryRun});if(c.success){if(t.dryRun)i.succeed("Validation passed!"),console.log(),I("The file is valid and can be imported."),c.statistics&&(console.log(),O("Slides",String(c.statistics.slidesImported)),O("Images",String(c.statistics.imagesUploaded)));else if(i.succeed("Import complete!"),console.log(),O("Presentation ID",c.presentationId??"N/A"),O("Document ID",c.documentId??"N/A"),c.statistics&&(O("Slides imported",String(c.statistics.slidesImported)),O("Images uploaded",String(c.statistics.imagesUploaded)),O("Time",`${c.statistics.totalTimeMs}ms`)),c.presentationId){let l=K();O("View URL",`${l}/p/${c.presentationId}`)}if(c.warnings&&c.warnings.length>0){console.log();for(let l of c.warnings)q(l)}console.log()}else i.fail("Import failed"),console.log(),c.errors?.length&&a("Import failed. The server rejected the presentation."),process.exit(1)}catch(o){i.fail("Import failed"),o.code==="ENOENT"&&(a(`File not found: ${n}`),process.exit(3)),a("The command failed. Please try again."),process.exit(o.exitCode??1)}});import{Command as xb}from"commander";function Wo(){return new xb("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)",b("--sort",["updated","created","title"]),"updated").option("--search <text>","Search presentation titles").option("--team-id <id>","Team ID (uses default if not specified)").option("--json","Output machine-readable JSON").action(async e=>{await w();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??ve();r||(a("Team ID required. Set a default with 'mf config set team-id <id>' or use --team-id"),process.exit(6));try{let i=await nc(r,t,n,e.sort,e.search);if(i.length===0){e.json?console.log(JSON.stringify([])):I("No presentations found");return}console.log(e.json?JSON.stringify(i,null,2):cl(i))}catch(i){a("The command failed. Please try again.");let o=typeof i=="object"&&i!==null&&"exitCode"in i&&typeof i.exitCode=="number"?i.exitCode:1;process.exit(o)}})}var Pl=Wo();import{createHash as Rb,randomBytes as Ol}from"crypto";import $l from"http";import Al from"chalk";import{Command as Cb}from"commander";import Sb from"open";import Tl from"ora";var Eb=`${f.displayName} CLI`,Pb=8765,Ab=8775,Tb=["presentations:read","presentations:write","brands:read","brands:write","media:read","media:write"];function Ob(){return Ol(32).toString("base64url")}function $b(e){return Rb("sha256").update(e).digest("base64url")}function Db(){return Ol(16).toString("hex")}async function Nb(e,t){for(let n=e;n<=t;n++)try{return await new Promise((r,i)=>{let o=$l.createServer();o.listen(n,()=>{o.close(()=>r())}),o.on("error",i)}),n}catch{}throw new Error(`No available port found between ${e} and ${t}`)}async function Lb(e){let t=await fetch(`${e}/.well-known/oauth-authorization-server`);if(!t.ok)throw new Error(`Failed to fetch OAuth metadata: ${t.status}`);let n=await t.json();if(!n||typeof n!="object"||Array.isArray(n)||!("authorization_endpoint"in n)||typeof n.authorization_endpoint!="string"||!("token_endpoint"in n)||typeof n.token_endpoint!="string"||!("registration_endpoint"in n)||typeof n.registration_endpoint!="string")throw new Error("The selected server returned invalid OAuth metadata");let r="issuer"in n?n.issuer:void 0,i="scopes_supported"in n?n.scopes_supported:void 0;if(r!==void 0&&typeof r!="string"||i!==void 0&&(!Array.isArray(i)||!i.every(o=>typeof o=="string")))throw new Error("The selected server returned invalid OAuth metadata");return{authorization_endpoint:n.authorization_endpoint,token_endpoint:n.token_endpoint,registration_endpoint:n.registration_endpoint,issuer:r,scopes_supported:i}}function Ub(e){let t=e.scopes_supported?.filter(n=>typeof n=="string"&&n.trim().length>0);return(t?.length?t:Tb).join(" ")}function _b(e,t){if(!t?.trim())return Ub(e);let n=t.split(",").map(i=>i.trim()).filter(Boolean);if(n.length===0)throw new Error("--scopes must include at least one OAuth scope");let r=e.scopes_supported?.filter(i=>typeof i=="string"&&i.trim().length>0);if(r?.length){let i=n.filter(o=>!r.includes(o));if(i.length>0)throw new Error(`Unsupported OAuth scope${i.length===1?"":"s"}: ${i.join(", ")}`)}return n.join(" ")}async function jb(e,t,n){if(t===void 0)return;let r=new URL(e),i;try{i=new URL(t)}catch{throw new Error("--resource must be an absolute advertised OAuth resource URL")}if(t!==t.trim()||i.origin!==r.origin||i.username||i.password||i.search||i.hash||i.toString()!==t||!["https:","http:"].includes(i.protocol))throw new Error("--resource must identify an exact resource on the selected server");let o=new URL(`/.well-known/oauth-protected-resource${i.pathname==="/"?"":i.pathname}`,r.origin),c=await fetch(o,{redirect:"error"});if(!c.ok)throw new Error("The selected server does not advertise this OAuth resource");let l=await c.json();if(!l||typeof l!="object"||Array.isArray(l)||!("resource"in l)||l.resource!==t||!n||!("authorization_servers"in l)||!Array.isArray(l.authorization_servers)||!l.authorization_servers.every(d=>typeof d=="string")||!l.authorization_servers.includes(n))throw new Error("OAuth resource metadata does not match the selected authorization server");return t}function qb(e){return new URLSearchParams({...e,response_type:"code",code_challenge_method:"S256"})}async function Mb(e,t,n){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Eb,redirect_uris:[t],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 Vb(e,t,n,r,i,o){let c=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:r,client_id:i,code_verifier:n});o&&c.set("resource",o);let l=await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:c.toString()});if(!l.ok)throw new Error("Token exchange failed. Please try again.");return l.json()}function Fb(e,t){return new Promise((n,r)=>{let i,o=!1,c=()=>{o||(o=!0,clearTimeout(i),process.off("SIGINT",l),process.off("SIGTERM",l),d.close())},l=()=>{c(),r(new Error("Login cancelled"))},d=$l.createServer((g,y)=>{let v=new URL(g.url||"",`http://localhost:${e}`);if(v.pathname!=="/callback"){y.writeHead(404),y.end("Not found");return}let x=v.searchParams.get("code"),T=v.searchParams.get("state"),L=v.searchParams.get("error"),$=v.searchParams.get("error_description");if(y.writeHead(200,{"Content-Type":"text/html"}),L){y.end(`
9
9
  <!DOCTYPE html>
10
10
  <html>
11
11
  <head><title>Login Failed</title></head>
@@ -44,26 +44,26 @@ Then paste the approval receipt: `,i);return}let o=!1,c=l=>{o||(o=!0,i(l))};t.on
44
44
  <p>You can close this window and return to the terminal.</p>
45
45
  </body>
46
46
  </html>
47
- `),c(),n({code:x,state:T})});d.listen(e),process.once("SIGINT",l),process.once("SIGTERM",l),i=setTimeout(()=>{c(),r(new Error("Login timed out - no callback received within 5 minutes"))},300*1e3)})}async function Mb(e,t){let n=await fetch(`${e}/api/cli/whoami`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw new Error(`Failed to fetch user info: ${n.status}`);return n.json()}async function Vb(e){let t=K(),n=Pl("Discovering OAuth server...").start();try{let r=await $b(t),i=Nb(r,e.scopes),o=await Lb(t,e.resource,r.issuer);n.succeed(`Connecting to ${t}`);let c=await Ob(Cb,Sb),l=`http://localhost:${c}/callback`;console.log(`Redirect URI: ${l}`),console.log(`Authorization endpoint: ${r.authorization_endpoint}`),console.log(`Token endpoint: ${r.token_endpoint}`),console.log(`Registration endpoint: ${r.registration_endpoint}`);let d=await _b(r.registration_endpoint,l,i),g=d.client_id;Ld(g,d.client_secret);let y=Pb(),v=Ab(y),x=Tb(),T=Ub({client_id:g,redirect_uri:l,scope:i,state:x,code_challenge:v,...o?{resource:o}:{}}),L=`${r.authorization_endpoint}?${T}`;console.log(`Authorization URL: ${L}`),e.browser?(I("Opening browser..."),await xb(L)):(console.log(El.bold("Open this URL in your browser:")),console.log(El.cyan(L)));let $=qb(c,x),{code:N}=await $;n=Pl("Completing login...").start();let S=await jb(r.token_endpoint,N,y,l,g,o);Ur(S.access_token,S.refresh_token,S.expires_in);let E=await Mb(t,S.access_token);n.succeed("Logged in!"),console.log(),O("Logged in as",E.user.email),E.currentTeam&&(ln(E.currentTeam.id),O("Team",`${E.currentTeam.name} (${E.currentTeam.planName})`));try{await At()}catch{}console.log(),C("You're all set!"),console.log()}catch(r){throw n.fail("Login failed"),a("The command failed. Please try again."),r}}var Ol=new kb("login").description(`Authenticate with ${f.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)").option("--resource <url>","Exact OAuth resource advertised by the selected server").action(async e=>{console.log(),Pt()&&(q("You are already logged in."),I(`Run '${f.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await Vb(e),process.exit(0)}catch{process.exit(1)}});import{Command as Fb}from"commander";import{confirm as Bb}from"@inquirer/prompts";var $l=new Fb("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async e=>{console.log();let t=Pt(),n=mn();if(!t&&!n){q("You are not logged in."),console.log();return}if(e.all)try{await Bb({message:"Clear all configuration including API key?",default:!1})?(Lr(),Tt(),C("All configuration cleared.")):I("Cancelled.")}catch{I("Cancelled.")}else _r(),Tt(),C("Logged out successfully."),n&&I("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as Pw}from"os";import{join as Aw}from"path";import qe from"chalk";import{Command as Tw}from"commander";import{spawn as Gb}from"child_process";import{existsSync as Kb,readdirSync as Wb}from"fs";import{homedir as Ll}from"os";import{delimiter as Dl}from"path";import{query as Jb}from"@anthropic-ai/claude-agent-sdk";function Ne(e){if(e===void 0)return null;if(typeof e=="string")return e.length>12e3?`${e.slice(0,12e3)}\u2026`:e;try{let t=JSON.stringify(e);return t.length<=12e3?e:{preview:`${t.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(e).slice(0,12e3)}}function Hr(e){let t=typeof e=="string"?e:String(e??"");return t.length>12e3?`${t.slice(0,12e3)}\u2026`:t}function Le(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function F(e){return typeof e=="string"?e:""}function Nl(e,t){let n=e.replace(/[/.]/g,"-");return`${Ll()}/.claude/projects/${n}/${t}.jsonl`}function zb(e){try{return Wb(`${e}/.nvm/versions/node`).map(t=>`${e}/.nvm/versions/node/${t}/bin`).sort().reverse()}catch{return[]}}function Xr(){let e=Ll(),t=[`${e}/.local/bin`,`${e}/.claude/local`,`${e}/.bun/bin`,`${e}/bin`,"/opt/homebrew/bin","/usr/local/bin",...zb(e)],r=(process.env.PATH??"").split(Dl);for(let i of t)r.includes(i)||r.push(i);return r.join(Dl)}async function Yr(e){let t=e??"claude";return new Promise(n=>{let r=Gb(t,["--version"],{env:{...process.env,PATH:Xr()},stdio:["ignore","pipe","ignore"]}),i="";r.stdout.on("data",o=>{i+=o.toString("utf8")}),r.on("error",()=>n(null)),r.on("close",o=>{if(o!==0)return n(null);let c=i.trim().split(`
48
- `)[0]??"";n(c?{bin:t,version:c}:null)})})}var Hb=new Set(["","default","best"]);function Ko(e){let t=e.filter(o=>o.text.trim());if(t.length===0)return"";let n=t[t.length-1],r=t.slice(0,-1);return r.length===0?n.text:`<conversation-history>
47
+ `),c(),n({code:x,state:T})});d.listen(e),process.once("SIGINT",l),process.once("SIGTERM",l),i=setTimeout(()=>{c(),r(new Error("Login timed out - no callback received within 5 minutes"))},300*1e3)})}async function Bb(e,t){let n=await fetch(`${e}/api/cli/whoami`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw new Error(`Failed to fetch user info: ${n.status}`);return n.json()}async function Gb(e){let t=K(),n=Tl("Discovering OAuth server...").start();try{let r=await Lb(t),i=_b(r,e.scopes),o=await jb(t,e.resource,r.issuer);n.succeed(`Connecting to ${t}`);let c=await Nb(Pb,Ab),l=`http://localhost:${c}/callback`;console.log(`Redirect URI: ${l}`),console.log(`Authorization endpoint: ${r.authorization_endpoint}`),console.log(`Token endpoint: ${r.token_endpoint}`),console.log(`Registration endpoint: ${r.registration_endpoint}`);let d=await Mb(r.registration_endpoint,l,i),g=d.client_id;_d(g,d.client_secret);let y=Ob(),v=$b(y),x=Db(),T=qb({client_id:g,redirect_uri:l,scope:i,state:x,code_challenge:v,...o?{resource:o}:{}}),L=`${r.authorization_endpoint}?${T}`;console.log(`Authorization URL: ${L}`),e.browser?(I("Opening browser..."),await Sb(L)):(console.log(Al.bold("Open this URL in your browser:")),console.log(Al.cyan(L)));let $=Fb(c,x),{code:N}=await $;n=Tl("Completing login...").start();let S=await Vb(r.token_endpoint,N,y,l,g,o);_r(S.access_token,S.refresh_token,S.expires_in);let E=await Bb(t,S.access_token);n.succeed("Logged in!"),console.log(),O("Logged in as",E.user.email),E.currentTeam&&(ln(E.currentTeam.id),O("Team",`${E.currentTeam.name} (${E.currentTeam.planName})`));try{await At()}catch{}console.log(),C("You're all set!"),console.log()}catch(r){throw n.fail("Login failed"),a("The command failed. Please try again."),r}}var Dl=new Cb("login").description(`Authenticate with ${f.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)").option("--resource <url>","Exact OAuth resource advertised by the selected server").action(async e=>{console.log(),Pt()&&(q("You are already logged in."),I(`Run '${f.commands[0]} logout' to log out first, or continue to re-authenticate.`),console.log());try{await Gb(e),process.exit(0)}catch{process.exit(1)}});import{Command as Kb}from"commander";import{confirm as Wb}from"@inquirer/prompts";var Nl=new Kb("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async e=>{console.log();let t=Pt(),n=mn();if(!t&&!n){q("You are not logged in."),console.log();return}if(e.all)try{await Wb({message:"Clear all configuration including API key?",default:!1})?(Ur(),Tt(),C("All configuration cleared.")):I("Cancelled.")}catch{I("Cancelled.")}else jr(),Tt(),C("Logged out successfully."),n&&I("Note: Your API key is still configured. Use --all to clear everything.");console.log()});import{homedir as Ow}from"os";import{join as $w}from"path";import qe from"chalk";import{Command as Dw}from"commander";import{spawn as Jb}from"child_process";import{existsSync as zb,readdirSync as Hb}from"fs";import{homedir as _l}from"os";import{delimiter as Ll}from"path";import{query as Xb}from"@anthropic-ai/claude-agent-sdk";function Ne(e){if(e===void 0)return null;if(typeof e=="string")return e.length>12e3?`${e.slice(0,12e3)}\u2026`:e;try{let t=JSON.stringify(e);return t.length<=12e3?e:{preview:`${t.slice(0,12e3)}\u2026`,truncated:!0}}catch{return String(e).slice(0,12e3)}}function Xr(e){let t=typeof e=="string"?e:String(e??"");return t.length>12e3?`${t.slice(0,12e3)}\u2026`:t}function Le(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function F(e){return typeof e=="string"?e:""}function Ul(e,t){let n=e.replace(/[/.]/g,"-");return`${_l()}/.claude/projects/${n}/${t}.jsonl`}function Yb(e){try{return Hb(`${e}/.nvm/versions/node`).map(t=>`${e}/.nvm/versions/node/${t}/bin`).sort().reverse()}catch{return[]}}function Yr(){let e=_l(),t=[`${e}/.local/bin`,`${e}/.claude/local`,`${e}/.bun/bin`,`${e}/bin`,"/opt/homebrew/bin","/usr/local/bin",...Yb(e)],r=(process.env.PATH??"").split(Ll);for(let i of t)r.includes(i)||r.push(i);return r.join(Ll)}async function Qr(e){let t=e??"claude";return new Promise(n=>{let r=Jb(t,["--version"],{env:{...process.env,PATH:Yr()},stdio:["ignore","pipe","ignore"]}),i="";r.stdout.on("data",o=>{i+=o.toString("utf8")}),r.on("error",()=>n(null)),r.on("close",o=>{if(o!==0)return n(null);let c=i.trim().split(`
48
+ `)[0]??"";n(c?{bin:t,version:c}:null)})})}var Qb=new Set(["","default","best"]);function Jo(e){let t=e.filter(o=>o.text.trim());if(t.length===0)return"";let n=t[t.length-1],r=t.slice(0,-1);return r.length===0?n.text:`<conversation-history>
49
49
  ${r.map(o=>`${o.role==="assistant"?"Assistant":"User"}: ${o.text}`).join(`
50
50
 
51
51
  `)}
52
52
  </conversation-history>
53
53
 
54
- ${n.text}`}function Wo(e,t){return t?e.messages.filter(r=>r.text.trim()).at(-1)?.text??"":Ko(e.messages)}function Xb({abortController:e,input:t,resumeSessionId:n,workspace:r}){let i=(t.modelId??"").trim(),o=t.thinking??null,c={abortController:e,allowedTools:["WebSearch","WebFetch"],cwd:r,env:{...process.env,PATH:Xr()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return Hb.has(i)||(c.model=i),t.effort&&(c.effort=t.effort),o&&o!=="disabled"&&(c.thinking={display:"summarized",type:o==="enabled"?"enabled":"adaptive"}),n?c.resume=n:t.system?.trim()&&(c.systemPrompt=t.system),c}async function Ul(e){let t=Wo(e.input,e.resumeSessionId);if(!t)throw new Error("Chat turn has no user text to send.");let n=new AbortController,r=()=>n.abort();e.signal?.addEventListener("abort",r,{once:!0});let i=null,o=null,c=null,l=null,d=null,g=0,y=new Set;try{let T=Jb({prompt:t,options:Xb({abortController:n,input:e.input,resumeSessionId:e.resumeSessionId,workspace:e.workspace})});for await(let L of T){let $=L;if($.type==="system"&&$.subtype==="init"){typeof $.session_id=="string"&&(o=$.session_id,e.onEvent({eventType:"chat.session",payload:{sessionId:o,sessionPath:Nl(e.workspace,o)}})),typeof $.model=="string"&&(i=$.model,e.onEvent({eventType:"chat.model",payload:{modelId:$.model}}));continue}if($.type==="stream_event"){let N=$.event;if(N?.type!=="content_block_delta")continue;let S=N.delta;if(!S)continue;S.type==="text_delta"&&typeof S.text=="string"?(g+=S.text.length,e.onEvent({eventType:"chat.text.delta",payload:{text:S.text}})):S.type==="thinking_delta"&&typeof S.thinking=="string"&&e.onEvent({eventType:"chat.reasoning.delta",payload:{text:S.thinking}});continue}if($.type==="assistant"){let N=Le($.message),S=Array.isArray(N.content)?N.content:[];for(let E of S){let A=Le(E);if(A.type!=="tool_use")continue;let D=F(A.id),re=F(A.name);!D||!re||y.has(D)||(y.add(D),e.onEvent({eventType:"chat.tool.started",payload:{input:Ne(A.input),toolCallId:D,toolName:re}}))}continue}if($.type==="user"){let N=Le($.message),S=Array.isArray(N.content)?N.content:[];for(let E of S){let A=Le(E);if(A.type!=="tool_result")continue;let D=F(A.tool_use_id);D&&e.onEvent({eventType:"chat.tool.completed",payload:{...A.is_error===!0?{errorText:typeof A.content=="string"?Hr(A.content):"Claude tool call failed."}:{},output:Ne(A.content),toolCallId:D}})}continue}$.type==="result"&&(typeof $.result=="string"&&(l=$.result),$.usage&&typeof $.usage=="object"&&(c=$.usage),typeof $.session_id=="string"&&(o=$.session_id),($.is_error===!0||$.subtype!=="success")&&(d=typeof $.result=="string"&&$.result||`Claude turn failed (${String($.subtype)}).`,e.onEvent({eventType:"chat.error",message:d,payload:{message:d}})))}}finally{e.signal?.removeEventListener("abort",r)}if(e.signal?.aborted)throw new Error("Chat turn cancelled.");if(d)throw new Error(d);let v=l??"";g===0&&v&&e.onEvent({eventType:"chat.text.delta",payload:{text:v}});let x=o?Nl(e.workspace,o):null;return{modelId:i,sessionId:o,sessionPath:x&&Kb(x)?x:null,text:v,usage:c}}import{spawn as Yb}from"child_process";import{closeSync as Qb,fstatSync as Zb,openSync as ew,readdirSync as tw,readSync as nw}from"fs";import{homedir as rw}from"os";import{join as _l}from"path";import{Codex as iw}from"@openai/codex-sdk";var ow=["/Applications/Codex.app/Contents/Resources/codex"];async function Qr(e){let t=e?[e]:["codex",...ow];for(let n of t){let r=await aw(n);if(r)return{bin:n,version:r}}return null}function aw(e){return new Promise(t=>{let n=Yb(e,["--version"],{env:{...process.env,PATH:Xr()},stdio:["ignore","pipe","ignore"]}),r="";n.stdout.on("data",i=>{r+=i.toString("utf8")}),n.on("error",()=>t(null)),n.on("close",i=>{if(i!==0)return t(null);let o=r.trim().split(`
55
- `)[0]??"";t(o||null)})})}var sw=24,dw=4*1024*1024,Ml=new Set(["custom_tool_call","custom_tool_call_output","dynamic_tool_call","function_call"]);function cw(e){let t;try{t=lw(e).split(`
56
- `)}catch{return[]}let n=new Set,r=new Map,i=null;for(let o of t){if(!o.trim())continue;let c;try{c=JSON.parse(o)}catch{continue}let l=Le(c.payload);if(c.type==="response_item"&&l.type==="custom_tool_call"){let d=F(l.call_id),g=F(l.input);d&&l.name==="exec"&&/\btools\.web__run\s*\(/.test(g)&&(n.add(d),i=d);continue}if(c.type==="event_msg"&&l.type==="web_search_end"){let d=F(l.call_id);if(!d||!i)continue;let g=F(l.query),y=Le(l.action),x={action:{...y,...g&&!F(y.query)?{query:g}:{}},query:g,sources:jl(l.results),toolCallId:d},T=r.get(i)??[];T.push(x),r.set(i,T);continue}if(c.type==="response_item"&&l.type==="custom_tool_call_output"){let d=F(l.call_id);if(!d||!n.has(d))continue;let g=jl(l.output);for(let y of r.get(d)??[])y.sources.length===0&&(y.sources=g);i===d&&(i=null)}}return Array.from(r.values()).flat()}function lw(e){let t=ew(e,"r");try{let n=Zb(t).size,r=Math.max(0,n-dw),i=Buffer.alloc(n-r);nw(t,i,0,i.length,r);let o=i.toString("utf8");if(r===0)return o;let c=o.indexOf(`
57
- `);return c===-1?"":o.slice(c+1)}finally{Qb(t)}}function jl(e){let n=Ho(e).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],r=new Set,i=[];for(let o of n){let c=o.replace(/[.,;:!?]+$/,"");try{let l=new URL(c);if(l.protocol!=="http:"&&l.protocol!=="https:"||r.has(l.href))continue;if(r.add(l.href),i.push({type:"url",url:l.href}),i.length>=sw)break}catch{}}return i}function Ho(e){return typeof e=="string"?e:Array.isArray(e)?e.map(Ho).join(`
58
- `):e&&typeof e=="object"?Object.values(e).map(Ho).join(`
59
- `):""}function Jo(e,t){let n=Le(e),r=F(n.type),i=F(n.id),o=F(n.call_id)||F(n.tool_call_id),c=Ml.has(r)?o||i:i||o;if(!c)return null;if(r==="command_execution"){let l=F(n.command),d=F(n.status),g={exitCode:typeof n.exit_code=="number"?n.exit_code:null,output:Ne(n.aggregated_output)};return{...t&&d==="failed"?{errorText:Hr(n.aggregated_output)||"Command failed."}:{},input:{command:l},...t?{output:g}:{},toolCallId:c,toolName:"Bash"}}if(r==="mcp_tool_call"){let l=Le(n.error);return{...t&&F(l.message)?{errorText:F(l.message)}:{},input:Ne(n.arguments),...t?{output:Ne(n.result??{status:n.status??"completed"})}:{},toolCallId:c,toolName:F(n.tool)||F(n.name)||"Codex tool"}}if(r==="web_search"){let l=F(n.query);return{input:{query:l},...t?{output:{query:l}}:{},toolCallId:c,toolName:"web_search"}}if(r==="file_change"){let l=F(n.status);return{...t&&l==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:Ne(n.changes)},...t?{output:{changes:Ne(n.changes),status:l}}:{},toolCallId:c,toolName:"ApplyPatch"}}if(r==="custom_tool_call_output")return{input:{},...t?{output:Ne(n.output)}:{},toolCallId:c,toolName:"Codex tool"};if(r==="custom_tool_call"||r==="dynamic_tool_call"||r==="function_call"){let l=F(n.name)||F(n.tool)||"Codex tool",d=n.input??n.arguments??{};return{input:l==="exec"&&typeof d=="string"?{command:d}:Ne(d),...t?{output:Ne(n.output??n.result??{status:n.status??"completed"})}:{},toolCallId:c,toolName:l}}return null}function zo(e,t=_l(rw(),".codex","sessions")){try{let r=tw(t,{recursive:!0}).find(i=>typeof i=="string"&&i.endsWith(`${e}.jsonl`));return r?_l(t,r):null}catch{return null}}function mw(e,t){return t?Wo(e,t):Ko(e.messages)}function pw(e,t,n=f.codexSelfConnectorAppId){let r=t.system?.trim(),i={...r?{developer_instructions:r}:{},...n?{apps:{[n]:{enabled:!1}}}:{}};return{codexPathOverride:e,...Object.keys(i).length>0?{config:i}:{}}}var uw=new Set(["minimal","low","medium","high","xhigh","max"]);function gw(e,t){let n={networkAccessEnabled:!0,sandboxMode:"workspace-write",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:t},r=(e.modelId??"").trim();return r&&r!=="default"&&(n.model=r),e.effort&&uw.has(e.effort)&&(n.modelReasoningEffort=e.effort),n}async function Vl(e){let t=mw(e.input,e.resumeSessionId);if(!t)throw new Error("Chat turn has no user text to send.");let n=new iw(pw(e.bin,e.input)),r=gw(e.input,e.workspace),i=e.resumeSessionId?n.resumeThread(e.resumeSessionId,r):n.startThread(r),o=e.resumeSessionId??null,c=null,l=null,d=[],g=new Set,y=new Set,v=null,x=$=>{v??=zo($,e.sessionsRoot),e.onEvent({eventType:"chat.session",payload:{sessionId:$,sessionPath:v}})},T=$=>{o&&(v??=zo(o,e.sessionsRoot));let N=v?cw(v):[],S=F(Le($.input).query),E=ql(S),A=N.find(D=>!g.has(D.toolCallId)&&ql(D.query)===E)??N.find(D=>!g.has(D.toolCallId));A&&g.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:{...$,output:A?{action:A.action,query:A.query,sources:A.sources}:{action:{query:S,type:"search"},sourceListUnavailable:!0,sources:[]}}})},{events:L}=await i.runStreamed(t);o&&x(o);for await(let $ of L){if(e.signal?.aborted)throw await L.return?.(void 0),new Error("Chat turn cancelled.");let N=$;if(N.type==="thread.started"){typeof N.thread_id=="string"&&(o=N.thread_id,x(N.thread_id));continue}if(N.type==="item.started"){let S=Jo(N.item,!1);if(S){e.onEvent({eventType:"chat.tool.started",payload:S});let E=Le(N.item);if(Ml.has(F(E.type))&&F(E.status)==="completed"){let A=Jo(E,!0);A&&(y.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:A}))}}continue}if(N.type==="item.completed"){let S=N.item;if(!S)continue;if(S.type==="agent_message"&&typeof S.text=="string")d.push(S.text),e.onEvent({eventType:"chat.text.delta",payload:{text:S.text}});else if(S.type==="reasoning"&&typeof S.text=="string")e.onEvent({eventType:"chat.reasoning.delta",payload:{text:S.text}});else{let E=Jo(S,!0);E&&(S.type==="web_search"?T(E):S.type==="custom_tool_call"&&y.has(E.toolCallId)||e.onEvent({eventType:"chat.tool.completed",payload:E}))}continue}if(N.type==="turn.completed"){N.usage&&typeof N.usage=="object"&&(c=N.usage);continue}if(N.type==="turn.failed"){let S=N.error;l=typeof S?.message=="string"&&S.message||"Codex turn failed.",e.onEvent({eventType:"chat.error",message:l,payload:{message:l}})}}if(l)throw new Error(l);return o=i.id??o,o&&(v??=zo(o,e.sessionsRoot)),{modelId:e.input.modelId??null,sessionId:o,sessionPath:v,text:d.join(`
60
-
61
- `),usage:c}}function ql(e){return e.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as ww}from"crypto";import{mkdir as vw}from"fs/promises";import{hostname as ei,platform as Iw}from"os";import{join as kw}from"path";var vn=class extends Error{constructor(n,r,i=!1){super(n);this.statusCode=r;this.reRegister=i;this.name="RunnerApiError"}statusCode;reRegister};async function In(e,t={}){let n=await fe();t.body!==void 0&&(n["Content-Type"]="application/json");let r=new AbortController,i=setTimeout(()=>r.abort(),t.timeoutMs??3e4),o=()=>r.abort();t.signal?.addEventListener("abort",o,{once:!0});try{let c=await fetch(`${K()}${e}`,{body:t.body!==void 0?JSON.stringify(t.body):void 0,headers:n,method:t.method??"GET",signal:r.signal}),l=await c.text(),d={};try{d=l?JSON.parse(l):{}}catch{d={}}if(!c.ok){let g=mt(l,c.status);throw new vn(`[${g.code}] ${g.message}`,c.status,d.reRegister===!0)}return d}finally{clearTimeout(i),t.signal?.removeEventListener("abort",o)}}async function Fl(e){await In("/api/runner/register",{body:e,method:"POST",timeoutMs:15e3})}async function Bl(e,t){return(await In(`/api/runner/work?runnerId=${encodeURIComponent(e)}`,{signal:t,timeoutMs:28e3})).job??null}async function Gl(e){await In("/api/runner/heartbeat",{body:{runnerId:e},method:"POST",timeoutMs:1e4})}async function Kl(e,t){return{cancelRequested:(await In(`/api/runner/jobs/${encodeURIComponent(e)}/events`,{body:{events:t},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function Xo(e,t,n){await In(`/api/runner/jobs/${encodeURIComponent(e)}/complete`,{body:{result:n,runnerId:t},method:"POST",timeoutMs:15e3})}async function Zr(e,t,n,r=!0){await In(`/api/runner/jobs/${encodeURIComponent(e)}/fail`,{body:{message:n,retryable:r,runnerId:t},method:"POST",timeoutMs:15e3})}var kn=class extends Error{runId;timeoutMs;constructor(t,n){super(t),this.name="PollTimeoutError",this.runId=n.runId,this.timeoutMs=n.timeoutMs}};function Wl(e,t){let n=Math.max(0,e-1),r=Math.min(t.capMs,t.baseMs*2**Math.min(n,30));return Math.floor(r*(t.random??Math.random)())}function Yo(e,t){return e<=0||t?.aborted?Promise.resolve():new Promise(n=>{let r=setTimeout(i,e);function i(){clearTimeout(r),t?.removeEventListener("abort",i),n()}t?.addEventListener("abort",i,{once:!0})})}async function Jl(e){let t=e.timeoutMs??18e5;if(!Number.isFinite(t)||t<=0)throw new Error("pollUntil requires a positive finite timeoutMs.");let n=e.now??Date.now,r=n()+t,i=await e.poll();for(;!e.isDone(i);){e.onValue?.(i);let o=r-n();if(o<=0)throw e.timeoutError?.(t)??new kn(`Poll timed out after ${Math.round(t/1e3)}s.`,{timeoutMs:t});await Yo(Math.min(Math.max(0,e.intervalMs(i)),o),e.signal),i=await e.poll()}return i}import{mkdirSync as fw,readFileSync as hw,writeFileSync as zl}from"fs";import{dirname as yw,join as bw}from"path";function Qo(e){return bw(e,"sessions.json")}function Zo(e){try{let t=hw(Qo(e),"utf8"),n=JSON.parse(t);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}return{}}function Hl(e,t,n){return t?Zo(e)[t]?.[n]??null:null}function Xl(e,t,n,r){if(!(!t||!r))try{let i=Qo(e);fw(yw(i),{recursive:!0});let o=Zo(e);o[t]={...o[t],[n]:r},zl(i,`${JSON.stringify(o,null," ")}
62
- `,"utf8")}catch{}}function Yl(e,t,n){if(t)try{let r=Zo(e);if(!r[t])return;delete r[t][n],zl(Qo(e),`${JSON.stringify(r,null," ")}
63
- `,"utf8")}catch{}}var xw=300,Rw=3e4,Cw=5*6e4;async function Ql(e){let[t,n]=await Promise.all([Yr(e.claudeBin),Qr(e.codexBin)]);if(!t&&!n)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");t?e.log(`Claude Code detected: ${t.version} (${t.bin})`):e.log("Claude Code not found \u2014 Claude turns will be declined."),n?e.log(`Codex detected: ${n.version} (${n.bin})`):e.log("Codex not found \u2014 Codex turns will be declined.");let r=[...t?["claude-code"]:[],...n?["codex"]:[]],i=`${ei().split(".")[0]}-${ww().slice(0,8)}`,o=()=>Fl({capabilities:["chat_turn","proof"],claudeCodeVersion:t?.version??null,cliVersion:e.version,codexVersion:n?.version??null,hostname:ei(),platform:Iw(),runnerId:i,runtimes:r});await o(),e.log(`Registered as ${i} (runtimes: ${r.join(", ")}). Waiting for work\u2026`);let c=0,l=0;for(;!e.signal?.aborted;){let d=null;try{d=await Bl(i,e.signal),c=0}catch(g){if(e.signal?.aborted)break;if(g instanceof vn&&g.reRegister){e.log("Server asked for re-registration.");try{await o(),l=0}catch(y){l+=1;let v=y instanceof Error?y.message:String(y);e.log(`Re-registration failed (${l} consecutive): ${v} Retrying with backoff.`)}}else e.log("Work poll failed; retrying\u2026");c+=1,await Yo(Wl(c,{baseMs:e.pollBackoffMs??5e3,capMs:Cw}),e.signal);continue}if(!d){if(e.once)continue;continue}if(e.log(`Claimed ${d.jobType} job ${d.runId}.`),await Sw({claude:t,codex:n,job:d,options:e,runnerId:i}),e.once)break}}async function Sw({claude:e,codex:t,job:n,options:r,runnerId:i}){let o=new AbortController,c=()=>o.abort();r.signal?.addEventListener("abort",c,{once:!0});let l=setInterval(()=>{Gl(i).catch(()=>{})},Rw),d=[],g=!1,y=async()=>{if(g||d.length===0)return;g=!0;let T=d.splice(0,100);try{let{cancelRequested:L}=await Kl(n.runId,T);L&&o.abort()}catch(L){L instanceof vn&&L.statusCode===409&&o.abort()}finally{g=!1}},v=setInterval(()=>{y()},xw),x=T=>{d.push(T)};try{if(n.jobType==="runner.proof"){let T=typeof n.input.message=="string"?n.input.message:"proof";x({eventType:"proof.echo",payload:{message:T}}),await ea(y,d),await Xo(n.runId,i,{echo:T}),r.log(`Proof job ${n.runId} completed.`);return}if(n.jobType==="runner.chat_turn"){let T=n.input.runtime==="codex"?"codex":"claude-code",L=T==="codex"?t&&{detection:t,run:Vl}:e&&{detection:e,run:Ul};if(!L){await Zr(n.runId,i,T==="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 $=typeof n.input.chatId=="string"&&n.input.chatId?n.input.chatId:null,N=kw(r.workspaceRoot,"chats",$??n.runId);await vw(N,{recursive:!0});let S=Ew(n.input),E=re=>x({eventType:re.eventType,message:re.message??null,payload:re.eventType==="chat.session"?{host:ei(),runtime:T,runtimeVersion:L.detection.version,...re.payload??{}}:re.payload??{}}),A=Hl(r.workspaceRoot,$,T),D;try{D=await L.run({bin:L.detection.bin,input:S,onEvent:E,resumeSessionId:A,signal:o.signal,workspace:N})}catch(re){if(!A||o.signal.aborted)throw re;r.log(`Resume of ${T} session failed; retrying fresh.`),Yl(r.workspaceRoot,$,T),D=await L.run({bin:L.detection.bin,input:S,onEvent:E,resumeSessionId:null,signal:o.signal,workspace:N})}Xl(r.workspaceRoot,$,T,D.sessionId),x({eventType:"chat.session",payload:{host:ei(),runtime:T,runtimeVersion:L.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath}}),await ea(y,d),await Xo(n.runId,i,{modelId:D.modelId,runtime:T,runtimeVersion:L.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath,text:D.text,usage:D.usage??{}}),r.log(`Chat turn ${n.runId} (${T}) completed.`);return}await Zr(n.runId,i,`This runner does not support ${n.jobType} jobs. Update the desktop app / CLI.`,!1)}catch{let L="Local runner job crashed.";r.log(`Job ${n.runId} failed: ${L}`),await ea(y,d).catch(()=>{}),await Zr(n.runId,i,L).catch(()=>{})}finally{clearInterval(v),clearInterval(l),r.signal?.removeEventListener("abort",c)}}function Ew(e){let t=Array.isArray(e.messages)?e.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 e.effort=="string"?e.effort:null,messages:t,modelId:typeof e.modelId=="string"?e.modelId:null,system:typeof e.system=="string"?e.system:null,thinking:typeof e.thinking=="string"?e.thinking:null}}async function ea(e,t){for(;t.length>0;)await e(),t.length>0&&await new Promise(n=>setTimeout(n,25))}function Ow(){return Aw(Pw(),`.${f.commands[0]}-runner`,"runs")}var ti=new Tw("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");ti.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[e,t]=await Promise.all([Yr(),Qr()]);if(console.log(e?qe.green(`\u2713 Claude Code ${e.version}`):qe.red("\u2717 Claude Code not found on PATH")),console.log(t?qe.green(`\u2713 Codex ${t.version} (${t.bin})`):qe.red("\u2717 Codex not found (PATH or Codex.app)")),!Ze()){console.log(qe.red(`\u2717 Not logged in. Run '${f.commands[0]} login' first.`)),process.exitCode=2;return}try{let n=await Je();console.log(qe.green(`\u2713 Logged in as ${n.user.email}`))}catch{console.log(qe.red("\u2717 Auth check failed. Please sign in again and retry.")),process.exitCode=2}});ti.command("start").description("Start the local runner (register + wait for work)").option("--once","Execute a single job, then exit").option("--workspace <dir>","Workspace root for job scratch directories").option("--claude-bin <path>","Path to the claude binary").option("--codex-bin <path>","Path to the codex binary").action(async e=>{Ze()||(console.error(qe.red(`Not authenticated. Run '${f.commands[0]} login' first.`)),process.exit(2));let t=new AbortController,n=()=>{console.log(qe.gray(`
64
- Stopping runner\u2026`)),t.abort()};process.on("SIGINT",n),process.on("SIGTERM",n);try{await Ql({claudeBin:e.claudeBin,codexBin:e.codexBin,log:r=>console.log(qe.gray(`[runner] ${r}`)),once:e.once,signal:t.signal,version:"0.3.27",workspaceRoot:e.workspace??Ow()})}catch{console.error(qe.red("The local runner failed. Check the runner logs and try again.")),process.exit(1)}});import se from"chalk";import{Command as k$}from"commander";import{Command as ta}from"commander";import{readFileSync as $w}from"fs";function _(e,t=()=>$w(0,"utf8")){if(e.approvalReceipt&&e.approvalReceiptStdin)throw new P("Pass only one approval receipt input mode.",400);let n=e.approvalReceiptStdin?t().trim():e.approvalReceipt;if(e.approvalReceiptStdin&&!n)throw new P("No approval receipt was provided on stdin.",400);return n}function $t(e,t){return[...t,e]}function Dw(e){let[t,n]=e.split("@");return n?{templateId:t,version:Number.parseInt(n,10)}:{templateId:t}}function Nw(e){if(typeof e.static=="string")return JSON.parse(e.static);let t=e.template;if(t.length)return{allowPreLaunch:e.allowPreLaunch?!0:void 0,audience:e.audience,imagery:e.imagery,market:e.market,productId:e.productId,sizes:e.size,templates:t.map(Dw),variations:e.variations??1}}var Lw=new ta("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",$t,[]).option("--angle <text>","Creative angle (repeat)",$t,[]).option("--cta <text>","Call to action (repeat)",$t,[]).option("--voice <text>","Voice or persona (repeat)",$t,[]).option("--aspect <ratio>","9:16, 1:1, or 16:9 (repeat)",$t,[]).option("--duration <seconds>","Creative duration in seconds",e=>Number.parseInt(e,10)).option("--max-variations <count>","Maximum generated variations",e=>Number.parseInt(e,10)).option("--review-policy <policy>","review or auto_save").option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--format <format>","video (default) or static").option("--template <id[@version]>","Static: approved ad template (repeat)",$t,[]).option("--size <id>","Static: size id, e.g. 300x250 (repeat)",$t,[]).option("--variations <count>","Static: distinct variations per template",e=>Number.parseInt(e,10)).option("--audience <audience>","Static: claim scope audience").option("--market <market>","Static: claim scope market").option("--product-id <id>","Static: claim scope product").option("--allow-pre-launch","Static: allow pre-launch claims (flagged)").option("--imagery <mode>","Static: approved-only (default) or generate-backgrounds").option("--static <json>","Static: the whole static block as JSON").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(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{let n=Nw(t),r=t.format??(n?"static":void 0);m(await p("createAdSet",{format:r,static:n,angles:t.angle.length?t.angle:void 0,approvalReceipt:_(t),aspects:t.aspect.length?t.aspect:void 0,brandingId:t.brandingId,brief:t.brief,ctas:t.cta.length?t.cta:void 0,durationSec:t.duration,hooks:r==="static"?void 0:t.hook.length?t.hook:[t.brief],maxVariations:t.maxVariations,reviewPolicy:t.reviewPolicy,style:r==="static"?void 0:t.style,teamId:t.teamId,title:e,voices:t.voice.length?t.voice:void 0},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),Uw=new ta("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createAdSet",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Zl=new ta("ad-set").description("Generate a set of ad creatives (hooks, copy, visuals) from a campaign brief").addCommand(Lw).addCommand(Uw);import{randomUUID as em}from"crypto";import{readFileSync as _w}from"fs";import{Command as Yn}from"commander";var jw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ni(e,t){jw.test(e)||(a(`"${e}" is not a ${t} id.`),process.exit(s.INVALID_INPUT))}function tm(e,t){try{return _w(e,"utf8")}catch{a(`${t}: cannot read file "${e}".`),process.exit(s.INVALID_INPUT)}}function na(e,t){let n=tm(e,t);try{return JSON.parse(n)}catch{a(`${t}: "${e}" is not valid JSON.`),process.exit(s.INVALID_INPUT)}}function ra(e,t){let n=Number(e);return(!Number.isInteger(n)||n<1)&&(a(`${t} must be a positive integer.`),process.exit(s.INVALID_INPUT)),n}function nm(e){return{html:tm(e.html,"--html"),legalPlacement:na(e.legalPlacement,"--legal-placement"),sizes:na(e.sizes,"--sizes"),slotSchema:na(e.slotSchema,"--slot-schema"),...e.teamId?{teamId:e.teamId}:{}}}function rm(e){return e.requiredOption("--html <file>","Template HTML file").requiredOption("--slot-schema <file>","JSON file: slot name \u2192 { type, required, label?, maxLength?, maxItems? }").requiredOption("--sizes <file>",'JSON file: [{ "id": "1x1", "label": "Feed square", "width": 1080, "height": 1080 }]').requiredOption("--legal-placement <file>",'JSON file: size id \u2192 { "isi": { "variant": "abbreviated", "minFontPx": 12 } }').option("--idempotency-key <key>","Reuse a request key to retry this same save").option("--team-id <id>","Workspace ID")}async function ri(e,t,n,r){try{m(await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}var qw=new Yn("list").description("List a brand's governed ad templates").option("--brand-id <id>","Brand profile ID (default: the default brand)").option("--format-family <family>","static, carousel or video").option("--limit <n>","Maximum templates to return (1-100)").option("--team-id <id>","Workspace ID").action(async e=>{await w(),e.brandId&&ni(e.brandId,"brand"),await ri("listAdTemplates",{...e.brandId?{brandId:e.brandId}:{},...e.formatFamily?{formatFamily:e.formatFamily}:{},...e.limit?{limit:ra(e.limit,"--limit")}:{},...e.teamId?{teamId:e.teamId}:{}},"List failed")}),Mw=new Yn("get").description("Read one ad template version with its HTML and lint report").argument("<template-id>","Ad template ID").option("--template-version <n>","Version to read (default: latest)").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),ni(e,"template"),await ri("getAdTemplate",{templateId:e,...t.templateVersion?{version:ra(t.templateVersion,"--template-version")}:{},...t.teamId?{teamId:t.teamId}:{}},"Read failed")}),Vw=rm(new Yn("create").description("Create an ad template as a draft (version 1)").requiredOption("--brand-id <id>","Brand profile ID").requiredOption("--name <name>","Template name").option("--format-family <family>","static (default), carousel or video")).action(async e=>{await w(),ni(e.brandId,"brand"),await ri("createAdTemplate",{brandId:e.brandId,name:e.name,...e.formatFamily?{formatFamily:e.formatFamily}:{},...nm(e)},"Create failed",e.idempotencyKey??em())}),Fw=rm(new Yn("update").description("Save an edited template as a new draft version (earlier versions stay unchanged)").argument("<template-id>","Ad template ID").requiredOption("--expected-latest-version <n>","The latest version you edited; a stale value is refused").option("--name <name>","Rename the template")).action(async(e,t)=>{await w(),ni(e,"template"),await ri("updateAdTemplate",{templateId:e,expectedLatestVersion:ra(t.expectedLatestVersion,"--expected-latest-version"),...t.name?{name:t.name}:{},...nm(t)},"Save failed",t.idempotencyKey??em())}),im=new Yn("ad-template").description("Governed ad templates: list, read, and save drafts (a person approves them in the app)").addCommand(qw).addCommand(Mw).addCommand(Vw).addCommand(Fw);import{randomUUID as dm}from"crypto";import{readFileSync as cm}from"fs";import{readFile as Jw}from"fs/promises";import{Command as Me}from"commander";import{randomUUID as Bw}from"crypto";function nt(e,t){a(u(e,t)),process.exit(e instanceof P?e.exitCode:s.GENERAL_ERROR)}function Qn(e){return`cli:agent-management:${e}:${Bw()}`}function xn(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 Zn}from"commander";var Gw=new Zn("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{m(await p("listAgentRoster",{cursor:e.cursor,pageSize:xn(e.pageSize,"--page-size"),teamId:e.teamId}))}catch(t){nt(t,"Could not list the Agent roster")}}),Kw=new Zn("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{m(await p("getRosterAgent",{agentId:e,teamId:t.teamId}))}catch(n){nt(n,"Could not read the roster Agent")}}),om=new Zn("roster").description("Discover Agents shared inside the current workspace; never cross-workspace").addCommand(Gw).addCommand(Kw),Ww=new Zn("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",b("visibility",["private","team"])).requiredOption("--expected-visibility <visibility>","Current value from agent roster get: private, team, or legacy public",b("--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{m(await p("setAgentVisibility",{agentId:e,expectedVisibility:n.expectedVisibility,teamId:n.teamId,visibility:t},n.idempotencyKey?.trim()||Qn("visibility")))}catch(r){nt(r,"Could not change Agent visibility")}}),am=new Zn("visibility").description("Control whether an owned Agent is private or team-visible").addCommand(Ww);function Rn(e,t){return[...t,e]}function zw(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new Error("Expected a positive integer.");return t}async function ii(e,t){let n=t.trim(),r=n.startsWith("{")?n:await Jw(n,"utf8"),i=JSON.parse(r);if(!i||typeof i!="object"||Array.isArray(i))throw new Error(`${e} must contain one JSON object.`);return i}var Hw=new Me("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",zw).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 lm("Agent activation failed",()=>p("createAgent",{approvalReceipt:t.approvalReceipt,draftId:e,expectedVersion:t.expectedVersion,teamId:t.teamId},t.idempotencyKey))}),Xw=new Me("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)",Rn,[]).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)",Rn,[]).option("--output-config <json-or-path>","Full output slot configuration (repeatable)",Rn,[]).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 lm("Agent recommendation failed",async()=>p("recommendAgent",{deliveryAdapter:t.deliveryAdapter,deliveryConfig:t.deliveryConfig?await ii("--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=>ii("--output-config",n))):void 0,rationale:t.rationale,reviewPolicy:t.reviewPolicy,runtime:t.runtime?await ii("--runtime",t.runtime):void 0,sandboxBlueprintId:t.sandboxBlueprintId,schedule:t.schedule,scheduleConfig:t.scheduleConfig?await ii("--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??dm()))});async function lm(e,t){try{m(await t())}catch(n){if(n instanceof P){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:u(n,e),retryable:!1},ok:!1})),process.exit(s.GENERAL_ERROR)}}function Yw(e,t){return e==="none"?null:xn(e,t)}function Qw(e){return e==="none"?null:e}function Dt(e,t){let n;try{n=cm(e,"utf8")}catch(r){throw new Error(`${t} could not read ${e}: ${u(r,"unknown file error")}`)}try{return JSON.parse(n)}catch(r){throw new Error(`${t} must point to valid JSON: ${u(r,"invalid JSON")}`)}}function Zw(e,t){try{return cm(e,"utf8")}catch(n){throw new Error(`${t} could not read ${e}: ${u(n,"unknown file error")}`)}}var ev=new Me("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 p("listAgents",{cursor:n,pageSize:xn(e.pageSize,"--page-size"),teamId:e.teamId});if(t.push(...r.agents),!r.hasMore||!r.nextCursor)break;n=r.nextCursor}m({agents:t,total:t.length})}catch(t){nt(t,"Could not list Agents")}}),tv=new Me("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{m(await p("getAgent",{agentId:e,teamId:t.teamId}))}catch(n){nt(n,"Could not read the Agent")}}),nv=new Me("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{m(await p("updateAgentConfiguration",{additionalFiles:t.filesFile?Dt(t.filesFile,"--files-file"):void 0,agentId:e,delivery:t.deliveryFile?Dt(t.deliveryFile,"--delivery-file"):void 0,description:t.description,expectedVersion:xn(t.expectedVersion,"--expected-version"),goal:t.goal,instructionsMarkdown:t.instructionsFile?Zw(t.instructionsFile,"--instructions-file"):void 0,name:t.name,output:t.outputFile?Dt(t.outputFile,"--output-file"):void 0,outputs:t.outputsFile?Dt(t.outputsFile,"--outputs-file"):void 0,perRunCreditCap:t.perRunCreditCap===void 0?void 0:Yw(t.perRunCreditCap,"--per-run-credit-cap"),reviewPolicy:t.reviewPolicy,runtime:t.runtimeFile?Dt(t.runtimeFile,"--runtime-file"):void 0,sandboxBlueprintId:t.sandboxBlueprintId===void 0?void 0:Qw(t.sandboxBlueprintId),schedule:t.scheduleFile?Dt(t.scheduleFile,"--schedule-file"):void 0,sources:t.sourcesFile?Dt(t.sourcesFile,"--sources-file"):void 0,teamId:t.teamId},t.idempotencyKey??Qn("configure")))}catch(n){nt(n,"Could not update the Agent")}});function sm(e){return new Me(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{m(await p(e==="pause"?"pauseAgentSchedule":"resumeAgentSchedule",{agentId:t,teamId:n.teamId},n.idempotencyKey??Qn(e)))}catch(r){nt(r,`Could not ${e} the Agent schedule`)}})}function ia(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function rv(e){return`cli:agent-memory:${e}:${dm()}`}function iv(e,t){let n=e.indexOf("="),r=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n+1);return[...t,{name:r.trim(),note:i.trim()}]}var ov=new Me("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{m(await p("getAgentMemory",{agentId:e,teamId:t.teamId}))}catch(n){ia(n,"Could not read the agent's memory")}}),av=new Me("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)",Rn,[]).option("--always <text>","Standing instruction to add (repeatable)",Rn,[]).option("--never <text>","Thing it must not do, to add (repeatable)",Rn,[]).option("--track <name=note>","Entity to track, as name=note (repeatable)",iv,[]).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,i=t.operation==="remove"||!!n;try{m(await p("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:i?"remove":"add",recurringInstructions:t.always.length?t.always:void 0,removeField:n,removeValue:r,teamId:t.teamId},t.idempotencyKey??rv(i?"remove":"add")))}catch(o){ia(o,"Could not update the agent's memory")}}),sv=new Me("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=_(t);m(await p("forgetAgentMemory",{approvalReceipt:n,agentId:e,teamId:t.teamId},t.idempotencyKey))}catch(n){ia(n,"Could not erase the agent's memory")}}),dv=new Me("memory").description("Read, edit, and erase what a scheduled agent remembers").addCommand(ov).addCommand(av).addCommand(sv),mm=new Me("agent").description("Recommend, activate, configure, and manage scheduled Agents").addCommand(ev).addCommand(tv).addCommand(om).addCommand(am).addCommand(nv).addCommand(sm("pause")).addCommand(sm("resume")).addCommand(Hw).addCommand(Xw).addCommand(dv);import{randomUUID as cv}from"crypto";import{password as lv}from"@inquirer/prompts";import{Command as oi}from"commander";function oa(e){if(e==="claude-code"||e==="codex")return e;throw new Error("--runtime must be claude-code or codex")}function mv(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 pv(){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 uv=new oi("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=oa(e.runtime),n=mv(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 pv():(await lv({mask:"*",message:"Provider API key:"})).trim();if(!r)throw new Error("Provider API key is required");let i=await Yd({apiKey:r,...e.baseUrl?{baseUrl:e.baseUrl}:{},label:e.label,makeDefault:e.use??!1,modelId:e.model,provider:n,runtime:t});C(`Saved connection profile ${i.label} (${i.id})`)}catch(t){a(u(t,"Profile enrollment failed")),process.exit(s.GENERAL_ERROR)}}),gv=new oi("list").description("List secret-free Claude Code or Codex connection profiles").requiredOption("--runtime <runtime>","claude-code or codex").action(async e=>{try{let t=oa(e.runtime);m(await p("listAiConnectionProfiles",{runtime:t}))}catch(t){a(u(t,"Profile list failed")),process.exit(s.GENERAL_ERROR)}}),fv=new oi("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=oa(e.runtime),n=await p("selectAiConnectionProfile",{profileId:e.profileId,runtime:t},e.idempotencyKey?.trim()||cv());C(n.selectedProfileId?`Selected connection profile ${n.selectedProfileId}`:"Selected the native provider route")}catch(t){a(u(t,"Profile selection failed")),process.exit(s.GENERAL_ERROR)}}),pm=new oi("ai-connections").description("Manage Claude Code and Codex inference routes").addCommand(uv).addCommand(gv).addCommand(fv);import{Command as sa}from"commander";import{Command as um}from"commander";var hv=new um("set").description("Set the poster an artifact shows on cards").argument("<artifact-kind>","Artifact kind: presentation, video, microsite, survey, \u2026").argument("<target-id>","Artifact id \u2014 a presentation's documentId, other kinds' row id").option("--slide <number>","Presentations: rendered slide number").option("--at-seconds <seconds>","Videos: moment 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,n)=>{[n.slide,n.atSeconds,n.imageUrl,n.uploadKey].filter(o=>o!==void 0).length>1&&(a("Name at most one poster source: --slide, --at-seconds, --image-url or --upload-key. Name none to restore the automatic preview."),process.exit(s.INVALID_INPUT));let i={artifactKind:e,targetId:t};if(n.slide!==void 0){let o=Number(n.slide);(!Number.isInteger(o)||o<1)&&(a("--slide must be a whole slide number, 1 or more."),process.exit(s.INVALID_INPUT)),i.slideNumber=o}if(n.atSeconds!==void 0){let o=Number(n.atSeconds);(!Number.isFinite(o)||o<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),i.atSeconds=o}n.imageUrl!==void 0&&(i.imageUrl=n.imageUrl),n.uploadKey!==void 0&&(i.uploadKey=n.uploadKey),n.teamId!==void 0&&(i.teamId=n.teamId);try{let o=await U(n.teamId),c=await p("setArtifactPoster",i,Q({command:"artifact poster set",payload:i,workspaceId:o}));m(c),C(c.posterUrl===null?"Poster reset to the automatic preview.":`Poster set from ${c.source}.`)}catch(o){a(u(o,"Setting the poster failed")),process.exit(s.GENERAL_ERROR)}}),gm=new um("poster").description("Set the poster an artifact shows on cards").addCommand(hv);var aa=["article","document","footageProject","microsite","presentation","presentationVideo","video"];function fm(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function yv(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 bv=new sa("read").description("Read an owned artifact's full content").argument("<kind>",`Artifact kind: ${aa.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").option("--version-id <id>","Footage projects only: saved version UUID").action(async(e,t,n)=>{aa.includes(e)||(a(`Unknown artifact kind "${e}". Expected one of: ${aa.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("readArtifact",{artifactId:t,kind:e,slides:yv(n.slides),versionId:n.versionId,teamId:n.teamId});m(r)}catch(r){fm(r,"Could not read the artifact")}}),wv=new sa("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",e=>{let t=Number(e);return(!Number.isInteger(t)||t<0)&&(a("--file-size expects the exact whole-number byte size."),process.exit(s.GENERAL_ERROR)),t}).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 e=>{try{m(await p("createUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},e.idempotencyKey))}catch(t){fm(t,"Could not mint the upload URL")}}),hm=new sa("artifact").description("Read artifacts this workspace owns").addCommand(bv).addCommand(wv).addCommand(gm);import{Command as bm}from"commander";var ym=1e3;function vv(e,t){let n=Number(e);return(!Number.isInteger(n)||n<1)&&(a(`${t} must be a positive whole number`),process.exit(s.GENERAL_ERROR)),n}function Iv(e){return e.split(",").map(t=>t.trim()).filter(Boolean)}var kv=new bm("export").description("Export who did what in the workspace (admins of governed workspaces). Newest first.").option("--from <iso>","Window start, ISO 8601 (default: 30 days before --to)").option("--to <iso>","Window end, ISO 8601 (default: now)").option("--categories <list>","Comma-separated: access,approvals,brand,features,governed_content,settings,sharing (default: all)").option("--format <format>","json (default) or csv").option("--limit <count>","Events per page, 1-1000 (default 200)").option("--cursor <cursor>","Continue from a previous page's nextCursor").option("--all","Follow nextCursor until the window is exhausted").option("--team-id <id>","Workspace ID").action(async e=>{try{let t=e.format??"json",n={categories:e.categories===void 0?void 0:Iv(e.categories),format:t,from:e.from,limit:e.limit===void 0?void 0:vv(e.limit,"--limit"),teamId:e.teamId,to:e.to},r=e.cursor,i=[];for(let l=0;l<ym;l+=1){let d=await p("exportWorkspaceAuditLog",{...n,cursor:r});if(i.push(d),!e.all||!d.nextCursor)break;n.from=d.window.from,n.to=d.window.to,r=d.nextCursor}let o=i[i.length-1],c=!!(e.all&&o?.nextCursor);if(t==="csv"){let[l,...d]=i.map(y=>y.csv??""),g=d.map(y=>y.slice(y.indexOf(`\r
65
- `)+2));process.stdout.write([l,...g].join(""))}else i.length===1?m(i[0]):m({...o,events:i.flatMap(l=>l.events),nextCursor:o?.nextCursor??null,window:i[0]?.window});c&&(a(`Export incomplete: stopped after ${ym} pages. Continue with --cursor ${o?.nextCursor} --from ${n.from} --to ${n.to}`),process.exit(s.GENERAL_ERROR))}catch(t){a(u(t,"Exporting the workspace audit log failed")),process.exit(s.GENERAL_ERROR)}}),wm=new bm("audit-log").description("Workspace audit log").addCommand(kv);import{randomUUID as si}from"crypto";import{readFileSync as Tv}from"fs";import{readFile as Ov}from"fs/promises";import Nt from"chalk";import{Command as Pe}from"commander";import $v from"ora";import{mkdir as xv,writeFile as vm}from"fs/promises";import{dirname as Rv}from"path";async function Ie(e,t){if(await xv(Rv(t),{recursive:!0}),e.startsWith("data:")){let i=e.match(/^data:[^;]+;base64,(.+)$/);if(!i)throw new Error("Invalid data URL format");let o=Buffer.from(i[1],"base64");if(o.length===0)throw new Error("Downloaded media was empty");await vm(t,o);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 vm(t,r)}import{existsSync as Im}from"fs";import{resolve as Cv}from"path";var Sv=/^([A-Za-z][A-Za-z0-9_-]*)=(.+)$/;function Ev(e){let t=e.trim();if(!t)throw new P("A reference image value cannot be empty.",400);if(Im(t))return{source:t};let n=Sv.exec(t);return n?{label:n[1],source:n[2]}:{source:t}}function Pv(e,t,n){if(!e.startsWith("image/")&&e!=="application/octet-stream")throw new P(`Reference image ${t} (${n}) is ${e}, not an image. A reference must be an image; pass an image file or a public image URL.`,400)}function Av(e,t){let n;try{n=new URL(e)}catch{throw new P(`Reference image ${t} (${e}) must be an existing local file or an HTTP(S) URL.`,400)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new P(`Reference image ${t} (${e}) must use an HTTP(S) URL.`,400);return n}async function ai(e,t){if(e?.length){if(t.maxCount!==void 0&&e.length>t.maxCount)throw new P(`${t.maxCountSubject??"This command"} accepts at most ${t.maxCount} reference images; ${e.length} were provided.`,400);return Promise.all(e.map(async(n,r)=>{let i=r+1,{label:o,source:c}=Ev(n);if(Im(c)){let d=Cv(c),g=gn(d);t.rejectNonImageFiles&&Pv(g,i,c);let y=await ie(d,{idempotencyKey:`${t.idempotencyKey}:reference:${i}`}),v=y.type||g;return{...o?{label:o}:{},...v.startsWith("image/")?{mediaType:v}:{},url:y.url}}let l=Av(c,i);return{...o?{label:o}:{},url:l.toString()}}))}}var Dv=15e3,Nv=40,Lv=3;function Uv(e,t){return[...t,e]}async function _v(e){let t=e.trim(),n=t.startsWith("[")?t:await Ov(t,"utf8"),r=JSON.parse(n);if(!Array.isArray(r)||r.some(i=>!i||typeof i!="object"||Array.isArray(i)))throw new Error("--starter-looks-json must contain one JSON array of objects.");return r}async function km(e,t){return(await ai(e,{idempotencyKey:t,maxCount:Lv,maxCountSubject:"A presenter Look"}))?.map(r=>({url:r.url}))}function da(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.durationSec!=null&&I(`Duration: ${e.durationSec}s`),e.videoUrl&&C(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}var jv=new Pe("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await vc(e.language,e.teamId);if(e.format==="json"){m(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){I("Your presenters:");for(let r of n)console.log(` ${r.id} ${r.name}`)}I("Avatars:");for(let r of t.avatars){let i=r.renderTiers?.length?` [${r.renderTiers.join(", ")}]`:"";console.log(` ${r.id} ${r.name}${i}`)}I("Voices:");for(let r of t.voices)console.log(` ${r.id} ${r.name}${r.language?` (${r.language})`:""}`)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),qv=new Pe("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await p("listPresenterCreationOptions",{locale:e.locale,teamId:e.teamId});if(e.format==="json")return m(t);if(e.format==="quiet"){for(let n of t.options)console.log(n.id);return}I(t.canCreate?"Presenter creation is enabled.":"Presenter creation is not enabled for this account.");for(let n of t.options)console.log(`
66
- ${Nt.bold(n.label)} ${Nt.gray(n.id)}`),console.log(` ${n.description}`),console.log(` Sources: ${n.supportedKinds.join(", ")}`),console.log(` Credits: ${Object.entries(n.creationCredits).map(([r,i])=>`${r}=${i}`).join(", ")}`),console.log(` Consent: ${n.consentCopyText}`)}catch(t){a(u(t,"Options failed")),process.exit(s.GENERAL_ERROR)}}),Mv=new Pe("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",Uv,[]).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").option("--wait-timeout-seconds <n>","Max seconds to wait for the presenter creation run (default 3600)",Number).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?Tv(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??si();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 ie(e.source,{idempotencyKey:`${n}:source`,storagePrefix:"presenters"}):void 0,i=await Promise.all(e.referenceImage.map((l,d)=>ie(l,{idempotencyKey:`${n}:reference:${d}`,storagePrefix:"presenters"}))),o=e.starterLooksJson?await _v(e.starterLooksJson):[],c=await p("createPresenter",{approvalReceipt:t,consentCopyLocale:e.locale,consentCopyText:e.consentStatement,engineId:e.engine,kind:e.kind,name:e.name,...e.prompt?{prompt:e.prompt}:{},...i.length?{referenceImageS3Keys:i.map(l=>l.s3Key)}:{},...r?{s3Key:r.s3Key}:{},starterLooks:o,teamId:e.teamId},n);if(!e.wait){m(c),I(`Check progress with: ${f.commands[0]} avatar presenter status ${c.runId}`);return}m(await z("createPresenter",c.runId,e.teamId,null,{maxWaitMs:(e.waitTimeoutSeconds??3600)*1e3,statusCommand:"avatar presenter status"}))}catch(r){let i=u(r);a(i),i.includes("approval")&&I(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${n}`),process.exit(s.GENERAL_ERROR)}}),Vv=new Pe("status").description("Read personal-presenter creation status").argument("<run-id>","Durable run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createPresenter",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Fv=new Pe("presenter").description("Discover and create reusable personal presenters").addCommand(qv).addCommand(Mv).addCommand(Vv),Bv=new Pe("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",b("--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"?$v("Generating presenter clip...").start():null;try{let i=e.idempotencyKey??si(),o=e.audioUrl?{audioUrl:e.audioUrl}:{script:e.script??"",...e.voiceId?{voiceId:e.voiceId}:{}},c=await Ic({...o,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},i);if(!e.wait){r?.stop(),da(c,e.format);return}let l=await $e(()=>_o(c.requestId),Nv,Dv);if(l.status==="failed")throw new de(l.error||"Presenter generation failed");if(!l.videoUrl)throw new Error("Presenter generation completed without a video URL");r&&(r.text="Downloading presenter clip..."),await Ie(l.videoUrl,e.output),r?.stop(),da(l,e.format),e.format==="human"&&C(`Saved to: ${e.output}`)}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Gv=new Pe("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{da(await _o(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Kv=new Pe("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??si(),r=await km(t.referenceImage,n),i=await p("generatePresenterLook",{baseProfileId:e,description:t.description,id:t.lookId,prompt:t.prompt,...r?{referenceImages:r}:{},title:t.name},n);m(i)}catch(n){a(u(n,"Look generation failed")),process.exit(s.GENERAL_ERROR)}}),Wv=new Pe("status").description("Read presenter look generation status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("generatePresenterLook",e);if(t.format==="json")return m(n);if(t.format==="quiet")return console.log(n.status);I(`Run ID: ${e}`),I(`Status: ${n.status}`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Jv=new Pe("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??si(),r=await km(t.referenceImage,n),i=await p("revisePresenterLook",{instruction:t.instruction,...r?{referenceImages:r}:{},sourceLookId:e},n);m(i)}catch(n){a(u(n,"Look revision failed")),process.exit(s.GENERAL_ERROR)}}),zv=new Pe("revision-status").description("Read presenter Look revision status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("revisePresenterLook",e);if(t.format==="json")return m(n);if(t.format==="quiet")return console.log(n.status);I(`Run ID: ${e}`),I(`Status: ${n.status}`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Revision status failed")),process.exit(s.GENERAL_ERROR)}}),Hv=new Pe("look").description("Manage looks under an existing personal presenter").addCommand(Kv).addCommand(Jv).addCommand(zv).addCommand(Wv),ca=new Pe("avatar").description("Generate presenter clips and looks; avatar options lists the voices and looks used by presentation video presenter and cast preset").addCommand(jv).addCommand(Fv).addCommand(Bv).addCommand(Hv).addCommand(Gv);ca.addHelpText("after",`
54
+ ${n.text}`}function zo(e,t){return t?e.messages.filter(r=>r.text.trim()).at(-1)?.text??"":Jo(e.messages)}function Zb({abortController:e,input:t,resumeSessionId:n,workspace:r}){let i=(t.modelId??"").trim(),o=t.thinking??null,c={abortController:e,allowedTools:["WebSearch","WebFetch"],cwd:r,env:{...process.env,PATH:Yr()},includePartialMessages:!0,maxTurns:16,permissionMode:"dontAsk"};return Qb.has(i)||(c.model=i),t.effort&&(c.effort=t.effort),o&&o!=="disabled"&&(c.thinking={display:"summarized",type:o==="enabled"?"enabled":"adaptive"}),n?c.resume=n:t.system?.trim()&&(c.systemPrompt=t.system),c}async function jl(e){let t=zo(e.input,e.resumeSessionId);if(!t)throw new Error("Chat turn has no user text to send.");let n=new AbortController,r=()=>n.abort();e.signal?.addEventListener("abort",r,{once:!0});let i=null,o=null,c=null,l=null,d=null,g=0,y=new Set;try{let T=Xb({prompt:t,options:Zb({abortController:n,input:e.input,resumeSessionId:e.resumeSessionId,workspace:e.workspace})});for await(let L of T){let $=L;if($.type==="system"&&$.subtype==="init"){typeof $.session_id=="string"&&(o=$.session_id,e.onEvent({eventType:"chat.session",payload:{sessionId:o,sessionPath:Ul(e.workspace,o)}})),typeof $.model=="string"&&(i=$.model,e.onEvent({eventType:"chat.model",payload:{modelId:$.model}}));continue}if($.type==="stream_event"){let N=$.event;if(N?.type!=="content_block_delta")continue;let S=N.delta;if(!S)continue;S.type==="text_delta"&&typeof S.text=="string"?(g+=S.text.length,e.onEvent({eventType:"chat.text.delta",payload:{text:S.text}})):S.type==="thinking_delta"&&typeof S.thinking=="string"&&e.onEvent({eventType:"chat.reasoning.delta",payload:{text:S.thinking}});continue}if($.type==="assistant"){let N=Le($.message),S=Array.isArray(N.content)?N.content:[];for(let E of S){let A=Le(E);if(A.type!=="tool_use")continue;let D=F(A.id),re=F(A.name);!D||!re||y.has(D)||(y.add(D),e.onEvent({eventType:"chat.tool.started",payload:{input:Ne(A.input),toolCallId:D,toolName:re}}))}continue}if($.type==="user"){let N=Le($.message),S=Array.isArray(N.content)?N.content:[];for(let E of S){let A=Le(E);if(A.type!=="tool_result")continue;let D=F(A.tool_use_id);D&&e.onEvent({eventType:"chat.tool.completed",payload:{...A.is_error===!0?{errorText:typeof A.content=="string"?Xr(A.content):"Claude tool call failed."}:{},output:Ne(A.content),toolCallId:D}})}continue}$.type==="result"&&(typeof $.result=="string"&&(l=$.result),$.usage&&typeof $.usage=="object"&&(c=$.usage),typeof $.session_id=="string"&&(o=$.session_id),($.is_error===!0||$.subtype!=="success")&&(d=typeof $.result=="string"&&$.result||`Claude turn failed (${String($.subtype)}).`,e.onEvent({eventType:"chat.error",message:d,payload:{message:d}})))}}finally{e.signal?.removeEventListener("abort",r)}if(e.signal?.aborted)throw new Error("Chat turn cancelled.");if(d)throw new Error(d);let v=l??"";g===0&&v&&e.onEvent({eventType:"chat.text.delta",payload:{text:v}});let x=o?Ul(e.workspace,o):null;return{modelId:i,sessionId:o,sessionPath:x&&zb(x)?x:null,text:v,usage:c}}import{spawn as ew}from"child_process";import{closeSync as tw,fstatSync as nw,openSync as rw,readdirSync as iw,readSync as ow}from"fs";import{homedir as aw}from"os";import{join as ql}from"path";import{Codex as sw}from"@openai/codex-sdk";var dw=["/Applications/Codex.app/Contents/Resources/codex"];async function Zr(e){let t=e?[e]:["codex",...dw];for(let n of t){let r=await cw(n);if(r)return{bin:n,version:r}}return null}function cw(e){return new Promise(t=>{let n=ew(e,["--version"],{env:{...process.env,PATH:Yr()},stdio:["ignore","pipe","ignore"]}),r="";n.stdout.on("data",i=>{r+=i.toString("utf8")}),n.on("error",()=>t(null)),n.on("close",i=>{if(i!==0)return t(null);let o=r.trim().split(`
55
+ `)[0]??"";t(o||null)})})}var lw=24,mw=4*1024*1024,Fl=new Set(["custom_tool_call","custom_tool_call_output","dynamic_tool_call","function_call"]);function pw(e){let t;try{t=uw(e).split(`
56
+ `)}catch{return[]}let n=new Set,r=new Map,i=null;for(let o of t){if(!o.trim())continue;let c;try{c=JSON.parse(o)}catch{continue}let l=Le(c.payload);if(c.type==="response_item"&&l.type==="custom_tool_call"){let d=F(l.call_id),g=F(l.input);d&&l.name==="exec"&&/\btools\.web__run\s*\(/.test(g)&&(n.add(d),i=d);continue}if(c.type==="event_msg"&&l.type==="web_search_end"){let d=F(l.call_id);if(!d||!i)continue;let g=F(l.query),y=Le(l.action),x={action:{...y,...g&&!F(y.query)?{query:g}:{}},query:g,sources:Ml(l.results),toolCallId:d},T=r.get(i)??[];T.push(x),r.set(i,T);continue}if(c.type==="response_item"&&l.type==="custom_tool_call_output"){let d=F(l.call_id);if(!d||!n.has(d))continue;let g=Ml(l.output);for(let y of r.get(d)??[])y.sources.length===0&&(y.sources=g);i===d&&(i=null)}}return Array.from(r.values()).flat()}function uw(e){let t=rw(e,"r");try{let n=nw(t).size,r=Math.max(0,n-mw),i=Buffer.alloc(n-r);ow(t,i,0,i.length,r);let o=i.toString("utf8");if(r===0)return o;let c=o.indexOf(`
57
+ `);return c===-1?"":o.slice(c+1)}finally{tw(t)}}function Ml(e){let n=Yo(e).match(/https?:\/\/[^\s<>"'()[\]{}\\]+/g)??[],r=new Set,i=[];for(let o of n){let c=o.replace(/[.,;:!?]+$/,"");try{let l=new URL(c);if(l.protocol!=="http:"&&l.protocol!=="https:"||r.has(l.href))continue;if(r.add(l.href),i.push({type:"url",url:l.href}),i.length>=lw)break}catch{}}return i}function Yo(e){return typeof e=="string"?e:Array.isArray(e)?e.map(Yo).join(`
58
+ `):e&&typeof e=="object"?Object.values(e).map(Yo).join(`
59
+ `):""}function Ho(e,t){let n=Le(e),r=F(n.type),i=F(n.id),o=F(n.call_id)||F(n.tool_call_id),c=Fl.has(r)?o||i:i||o;if(!c)return null;if(r==="command_execution"){let l=F(n.command),d=F(n.status),g={exitCode:typeof n.exit_code=="number"?n.exit_code:null,output:Ne(n.aggregated_output)};return{...t&&d==="failed"?{errorText:Xr(n.aggregated_output)||"Command failed."}:{},input:{command:l},...t?{output:g}:{},toolCallId:c,toolName:"Bash"}}if(r==="mcp_tool_call"){let l=Le(n.error);return{...t&&F(l.message)?{errorText:F(l.message)}:{},input:Ne(n.arguments),...t?{output:Ne(n.result??{status:n.status??"completed"})}:{},toolCallId:c,toolName:F(n.tool)||F(n.name)||"Codex tool"}}if(r==="web_search"){let l=F(n.query);return{input:{query:l},...t?{output:{query:l}}:{},toolCallId:c,toolName:"web_search"}}if(r==="file_change"){let l=F(n.status);return{...t&&l==="failed"?{errorText:"Codex could not apply the file changes."}:{},input:{changes:Ne(n.changes)},...t?{output:{changes:Ne(n.changes),status:l}}:{},toolCallId:c,toolName:"ApplyPatch"}}if(r==="custom_tool_call_output")return{input:{},...t?{output:Ne(n.output)}:{},toolCallId:c,toolName:"Codex tool"};if(r==="custom_tool_call"||r==="dynamic_tool_call"||r==="function_call"){let l=F(n.name)||F(n.tool)||"Codex tool",d=n.input??n.arguments??{};return{input:l==="exec"&&typeof d=="string"?{command:d}:Ne(d),...t?{output:Ne(n.output??n.result??{status:n.status??"completed"})}:{},toolCallId:c,toolName:l}}return null}function Xo(e,t=ql(aw(),".codex","sessions")){try{let r=iw(t,{recursive:!0}).find(i=>typeof i=="string"&&i.endsWith(`${e}.jsonl`));return r?ql(t,r):null}catch{return null}}function gw(e,t){return t?zo(e,t):Jo(e.messages)}function fw(e,t,n=f.codexSelfConnectorAppId){let r=t.system?.trim(),i={...r?{developer_instructions:r}:{},...n?{apps:{[n]:{enabled:!1}}}:{}};return{codexPathOverride:e,...Object.keys(i).length>0?{config:i}:{}}}var hw=new Set(["minimal","low","medium","high","xhigh","max"]);function yw(e,t){let n={networkAccessEnabled:!0,sandboxMode:"workspace-write",skipGitRepoCheck:!0,webSearchEnabled:!0,workingDirectory:t},r=(e.modelId??"").trim();return r&&r!=="default"&&(n.model=r),e.effort&&hw.has(e.effort)&&(n.modelReasoningEffort=e.effort),n}async function Bl(e){let t=gw(e.input,e.resumeSessionId);if(!t)throw new Error("Chat turn has no user text to send.");let n=new sw(fw(e.bin,e.input)),r=yw(e.input,e.workspace),i=e.resumeSessionId?n.resumeThread(e.resumeSessionId,r):n.startThread(r),o=e.resumeSessionId??null,c=null,l=null,d=[],g=new Set,y=new Set,v=null,x=$=>{v??=Xo($,e.sessionsRoot),e.onEvent({eventType:"chat.session",payload:{sessionId:$,sessionPath:v}})},T=$=>{o&&(v??=Xo(o,e.sessionsRoot));let N=v?pw(v):[],S=F(Le($.input).query),E=Vl(S),A=N.find(D=>!g.has(D.toolCallId)&&Vl(D.query)===E)??N.find(D=>!g.has(D.toolCallId));A&&g.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:{...$,output:A?{action:A.action,query:A.query,sources:A.sources}:{action:{query:S,type:"search"},sourceListUnavailable:!0,sources:[]}}})},{events:L}=await i.runStreamed(t);o&&x(o);for await(let $ of L){if(e.signal?.aborted)throw await L.return?.(void 0),new Error("Chat turn cancelled.");let N=$;if(N.type==="thread.started"){typeof N.thread_id=="string"&&(o=N.thread_id,x(N.thread_id));continue}if(N.type==="item.started"){let S=Ho(N.item,!1);if(S){e.onEvent({eventType:"chat.tool.started",payload:S});let E=Le(N.item);if(Fl.has(F(E.type))&&F(E.status)==="completed"){let A=Ho(E,!0);A&&(y.add(A.toolCallId),e.onEvent({eventType:"chat.tool.completed",payload:A}))}}continue}if(N.type==="item.completed"){let S=N.item;if(!S)continue;if(S.type==="agent_message"&&typeof S.text=="string")d.push(S.text),e.onEvent({eventType:"chat.text.delta",payload:{text:S.text}});else if(S.type==="reasoning"&&typeof S.text=="string")e.onEvent({eventType:"chat.reasoning.delta",payload:{text:S.text}});else{let E=Ho(S,!0);E&&(S.type==="web_search"?T(E):S.type==="custom_tool_call"&&y.has(E.toolCallId)||e.onEvent({eventType:"chat.tool.completed",payload:E}))}continue}if(N.type==="turn.completed"){N.usage&&typeof N.usage=="object"&&(c=N.usage);continue}if(N.type==="turn.failed"){let S=N.error;l=typeof S?.message=="string"&&S.message||"Codex turn failed.",e.onEvent({eventType:"chat.error",message:l,payload:{message:l}})}}if(l)throw new Error(l);return o=i.id??o,o&&(v??=Xo(o,e.sessionsRoot)),{modelId:e.input.modelId??null,sessionId:o,sessionPath:v,text:d.join(`
60
+
61
+ `),usage:c}}function Vl(e){return e.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as kw}from"crypto";import{mkdir as xw}from"fs/promises";import{hostname as ti,platform as Rw}from"os";import{join as Cw}from"path";var vn=class extends Error{constructor(n,r,i=!1){super(n);this.statusCode=r;this.reRegister=i;this.name="RunnerApiError"}statusCode;reRegister};async function In(e,t={}){let n=await fe();t.body!==void 0&&(n["Content-Type"]="application/json");let r=new AbortController,i=setTimeout(()=>r.abort(),t.timeoutMs??3e4),o=()=>r.abort();t.signal?.addEventListener("abort",o,{once:!0});try{let c=await fetch(`${K()}${e}`,{body:t.body!==void 0?JSON.stringify(t.body):void 0,headers:n,method:t.method??"GET",signal:r.signal}),l=await c.text(),d={};try{d=l?JSON.parse(l):{}}catch{d={}}if(!c.ok){let g=mt(l,c.status);throw new vn(`[${g.code}] ${g.message}`,c.status,d.reRegister===!0)}return d}finally{clearTimeout(i),t.signal?.removeEventListener("abort",o)}}async function Gl(e){await In("/api/runner/register",{body:e,method:"POST",timeoutMs:15e3})}async function Kl(e,t){return(await In(`/api/runner/work?runnerId=${encodeURIComponent(e)}`,{signal:t,timeoutMs:28e3})).job??null}async function Wl(e){await In("/api/runner/heartbeat",{body:{runnerId:e},method:"POST",timeoutMs:1e4})}async function Jl(e,t){return{cancelRequested:(await In(`/api/runner/jobs/${encodeURIComponent(e)}/events`,{body:{events:t},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function Qo(e,t,n){await In(`/api/runner/jobs/${encodeURIComponent(e)}/complete`,{body:{result:n,runnerId:t},method:"POST",timeoutMs:15e3})}async function ei(e,t,n,r=!0){await In(`/api/runner/jobs/${encodeURIComponent(e)}/fail`,{body:{message:n,retryable:r,runnerId:t},method:"POST",timeoutMs:15e3})}var kn=class extends Error{runId;timeoutMs;constructor(t,n){super(t),this.name="PollTimeoutError",this.runId=n.runId,this.timeoutMs=n.timeoutMs}};function zl(e,t){let n=Math.max(0,e-1),r=Math.min(t.capMs,t.baseMs*2**Math.min(n,30));return Math.floor(r*(t.random??Math.random)())}function Zo(e,t){return e<=0||t?.aborted?Promise.resolve():new Promise(n=>{let r=setTimeout(i,e);function i(){clearTimeout(r),t?.removeEventListener("abort",i),n()}t?.addEventListener("abort",i,{once:!0})})}async function Hl(e){let t=e.timeoutMs??18e5;if(!Number.isFinite(t)||t<=0)throw new Error("pollUntil requires a positive finite timeoutMs.");let n=e.now??Date.now,r=n()+t,i=await e.poll();for(;!e.isDone(i);){e.onValue?.(i);let o=r-n();if(o<=0)throw e.timeoutError?.(t)??new kn(`Poll timed out after ${Math.round(t/1e3)}s.`,{timeoutMs:t});await Zo(Math.min(Math.max(0,e.intervalMs(i)),o),e.signal),i=await e.poll()}return i}import{mkdirSync as bw,readFileSync as ww,writeFileSync as Xl}from"fs";import{dirname as vw,join as Iw}from"path";function ea(e){return Iw(e,"sessions.json")}function ta(e){try{let t=ww(ea(e),"utf8"),n=JSON.parse(t);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}return{}}function Yl(e,t,n){return t?ta(e)[t]?.[n]??null:null}function Ql(e,t,n,r){if(!(!t||!r))try{let i=ea(e);bw(vw(i),{recursive:!0});let o=ta(e);o[t]={...o[t],[n]:r},Xl(i,`${JSON.stringify(o,null," ")}
62
+ `,"utf8")}catch{}}function Zl(e,t,n){if(t)try{let r=ta(e);if(!r[t])return;delete r[t][n],Xl(ea(e),`${JSON.stringify(r,null," ")}
63
+ `,"utf8")}catch{}}var Sw=300,Ew=3e4,Pw=5*6e4;async function em(e){let[t,n]=await Promise.all([Qr(e.claudeBin),Zr(e.codexBin)]);if(!t&&!n)throw new Error("Neither Claude Code nor Codex was found on this machine. Install one and log in, then retry.");t?e.log(`Claude Code detected: ${t.version} (${t.bin})`):e.log("Claude Code not found \u2014 Claude turns will be declined."),n?e.log(`Codex detected: ${n.version} (${n.bin})`):e.log("Codex not found \u2014 Codex turns will be declined.");let r=[...t?["claude-code"]:[],...n?["codex"]:[]],i=`${ti().split(".")[0]}-${kw().slice(0,8)}`,o=()=>Gl({capabilities:["chat_turn","proof"],claudeCodeVersion:t?.version??null,cliVersion:e.version,codexVersion:n?.version??null,hostname:ti(),platform:Rw(),runnerId:i,runtimes:r});await o(),e.log(`Registered as ${i} (runtimes: ${r.join(", ")}). Waiting for work\u2026`);let c=0,l=0;for(;!e.signal?.aborted;){let d=null;try{d=await Kl(i,e.signal),c=0}catch(g){if(e.signal?.aborted)break;if(g instanceof vn&&g.reRegister){e.log("Server asked for re-registration.");try{await o(),l=0}catch(y){l+=1;let v=y instanceof Error?y.message:String(y);e.log(`Re-registration failed (${l} consecutive): ${v} Retrying with backoff.`)}}else e.log("Work poll failed; retrying\u2026");c+=1,await Zo(zl(c,{baseMs:e.pollBackoffMs??5e3,capMs:Pw}),e.signal);continue}if(!d){if(e.once)continue;continue}if(e.log(`Claimed ${d.jobType} job ${d.runId}.`),await Aw({claude:t,codex:n,job:d,options:e,runnerId:i}),e.once)break}}async function Aw({claude:e,codex:t,job:n,options:r,runnerId:i}){let o=new AbortController,c=()=>o.abort();r.signal?.addEventListener("abort",c,{once:!0});let l=setInterval(()=>{Wl(i).catch(()=>{})},Ew),d=[],g=!1,y=async()=>{if(g||d.length===0)return;g=!0;let T=d.splice(0,100);try{let{cancelRequested:L}=await Jl(n.runId,T);L&&o.abort()}catch(L){L instanceof vn&&L.statusCode===409&&o.abort()}finally{g=!1}},v=setInterval(()=>{y()},Sw),x=T=>{d.push(T)};try{if(n.jobType==="runner.proof"){let T=typeof n.input.message=="string"?n.input.message:"proof";x({eventType:"proof.echo",payload:{message:T}}),await na(y,d),await Qo(n.runId,i,{echo:T}),r.log(`Proof job ${n.runId} completed.`);return}if(n.jobType==="runner.chat_turn"){let T=n.input.runtime==="codex"?"codex":"claude-code",L=T==="codex"?t&&{detection:t,run:Bl}:e&&{detection:e,run:jl};if(!L){await ei(n.runId,i,T==="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 $=typeof n.input.chatId=="string"&&n.input.chatId?n.input.chatId:null,N=Cw(r.workspaceRoot,"chats",$??n.runId);await xw(N,{recursive:!0});let S=Tw(n.input),E=re=>x({eventType:re.eventType,message:re.message??null,payload:re.eventType==="chat.session"?{host:ti(),runtime:T,runtimeVersion:L.detection.version,...re.payload??{}}:re.payload??{}}),A=Yl(r.workspaceRoot,$,T),D;try{D=await L.run({bin:L.detection.bin,input:S,onEvent:E,resumeSessionId:A,signal:o.signal,workspace:N})}catch(re){if(!A||o.signal.aborted)throw re;r.log(`Resume of ${T} session failed; retrying fresh.`),Zl(r.workspaceRoot,$,T),D=await L.run({bin:L.detection.bin,input:S,onEvent:E,resumeSessionId:null,signal:o.signal,workspace:N})}Ql(r.workspaceRoot,$,T,D.sessionId),x({eventType:"chat.session",payload:{host:ti(),runtime:T,runtimeVersion:L.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath}}),await na(y,d),await Qo(n.runId,i,{modelId:D.modelId,runtime:T,runtimeVersion:L.detection.version,sessionId:D.sessionId,sessionPath:D.sessionPath,text:D.text,usage:D.usage??{}}),r.log(`Chat turn ${n.runId} (${T}) completed.`);return}await ei(n.runId,i,`This runner does not support ${n.jobType} jobs. Update the desktop app / CLI.`,!1)}catch{let L="Local runner job crashed.";r.log(`Job ${n.runId} failed: ${L}`),await na(y,d).catch(()=>{}),await ei(n.runId,i,L).catch(()=>{})}finally{clearInterval(v),clearInterval(l),r.signal?.removeEventListener("abort",c)}}function Tw(e){let t=Array.isArray(e.messages)?e.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 e.effort=="string"?e.effort:null,messages:t,modelId:typeof e.modelId=="string"?e.modelId:null,system:typeof e.system=="string"?e.system:null,thinking:typeof e.thinking=="string"?e.thinking:null}}async function na(e,t){for(;t.length>0;)await e(),t.length>0&&await new Promise(n=>setTimeout(n,25))}function Nw(){return $w(Ow(),`.${f.commands[0]}-runner`,"runs")}var ni=new Dw("runner").description("Run agent work locally with your own Claude Code / Codex login (desktop lane)");ni.command("status").description("Check local Claude Code / Codex detection and account auth").action(async()=>{let[e,t]=await Promise.all([Qr(),Zr()]);if(console.log(e?qe.green(`\u2713 Claude Code ${e.version}`):qe.red("\u2717 Claude Code not found on PATH")),console.log(t?qe.green(`\u2713 Codex ${t.version} (${t.bin})`):qe.red("\u2717 Codex not found (PATH or Codex.app)")),!Ze()){console.log(qe.red(`\u2717 Not logged in. Run '${f.commands[0]} login' first.`)),process.exitCode=2;return}try{let n=await Je();console.log(qe.green(`\u2713 Logged in as ${n.user.email}`))}catch{console.log(qe.red("\u2717 Auth check failed. Please sign in again and retry.")),process.exitCode=2}});ni.command("start").description("Start the local runner (register + wait for work)").option("--once","Execute a single job, then exit").option("--workspace <dir>","Workspace root for job scratch directories").option("--claude-bin <path>","Path to the claude binary").option("--codex-bin <path>","Path to the codex binary").action(async e=>{Ze()||(console.error(qe.red(`Not authenticated. Run '${f.commands[0]} login' first.`)),process.exit(2));let t=new AbortController,n=()=>{console.log(qe.gray(`
64
+ Stopping runner\u2026`)),t.abort()};process.on("SIGINT",n),process.on("SIGTERM",n);try{await em({claudeBin:e.claudeBin,codexBin:e.codexBin,log:r=>console.log(qe.gray(`[runner] ${r}`)),once:e.once,signal:t.signal,version:"0.3.28",workspaceRoot:e.workspace??Nw()})}catch{console.error(qe.red("The local runner failed. Check the runner logs and try again.")),process.exit(1)}});import se from"chalk";import{Command as P$}from"commander";import{Command as ra}from"commander";import{readFileSync as Lw}from"fs";function _(e,t=()=>Lw(0,"utf8")){if(e.approvalReceipt&&e.approvalReceiptStdin)throw new P("Pass only one approval receipt input mode.",400);let n=e.approvalReceiptStdin?t().trim():e.approvalReceipt;if(e.approvalReceiptStdin&&!n)throw new P("No approval receipt was provided on stdin.",400);return n}function $t(e,t){return[...t,e]}function Uw(e){let[t,n]=e.split("@");return n?{templateId:t,version:Number.parseInt(n,10)}:{templateId:t}}function _w(e){if(typeof e.static=="string")return JSON.parse(e.static);let t=e.template;if(t.length)return{allowPreLaunch:e.allowPreLaunch?!0:void 0,audience:e.audience,imagery:e.imagery,market:e.market,productId:e.productId,sizes:e.size,templates:t.map(Uw),variations:e.variations??1}}var jw=new ra("create").description("Start durable ad-set generation").argument("<title>","Ad-set title").requiredOption("--brief <brief>","Campaign brief").option("--hook <text>","Opening hook (repeat)",$t,[]).option("--angle <text>","Creative angle (repeat)",$t,[]).option("--cta <text>","Call to action (repeat)",$t,[]).option("--voice <text>","Voice or persona (repeat)",$t,[]).option("--aspect <ratio>","9:16, 1:1, or 16:9 (repeat)",$t,[]).option("--duration <seconds>","Creative duration in seconds",e=>Number.parseInt(e,10)).option("--max-variations <count>","Maximum generated variations",e=>Number.parseInt(e,10)).option("--review-policy <policy>","review or auto_save").option("--style <style>","ugc, clean, cinematic, or testimonial","ugc").option("--format <format>","video (default) or static").option("--template <id[@version]>","Static: approved ad template (repeat)",$t,[]).option("--size <id>","Static: size id, e.g. 300x250 (repeat)",$t,[]).option("--variations <count>","Static: distinct variations per template",e=>Number.parseInt(e,10)).option("--audience <audience>","Static: claim scope audience").option("--market <market>","Static: claim scope market").option("--product-id <id>","Static: claim scope product").option("--allow-pre-launch","Static: allow pre-launch claims (flagged)").option("--imagery <mode>","Static: approved-only (default) or generate-backgrounds").option("--static <json>","Static: the whole static block as JSON").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(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{let n=_w(t),r=t.format??(n?"static":void 0);m(await p("createAdSet",{format:r,static:n,angles:t.angle.length?t.angle:void 0,approvalReceipt:_(t),aspects:t.aspect.length?t.aspect:void 0,brandingId:t.brandingId,brief:t.brief,ctas:t.cta.length?t.cta:void 0,durationSec:t.duration,hooks:r==="static"?void 0:t.hook.length?t.hook:[t.brief],maxVariations:t.maxVariations,reviewPolicy:t.reviewPolicy,style:r==="static"?void 0:t.style,teamId:t.teamId,title:e,voices:t.voice.length?t.voice:void 0},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),qw=new ra("status").description("Read ad-set generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createAdSet",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),tm=new ra("ad-set").description("Generate a set of ad creatives (hooks, copy, visuals) from a campaign brief").addCommand(jw).addCommand(qw);import{randomUUID as nm}from"crypto";import{readFileSync as Mw}from"fs";import{Command as Qn}from"commander";var Vw=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ri(e,t){Vw.test(e)||(a(`"${e}" is not a ${t} id.`),process.exit(s.INVALID_INPUT))}function rm(e,t){try{return Mw(e,"utf8")}catch{a(`${t}: cannot read file "${e}".`),process.exit(s.INVALID_INPUT)}}function ia(e,t){let n=rm(e,t);try{return JSON.parse(n)}catch{a(`${t}: "${e}" is not valid JSON.`),process.exit(s.INVALID_INPUT)}}function oa(e,t){let n=Number(e);return(!Number.isInteger(n)||n<1)&&(a(`${t} must be a positive integer.`),process.exit(s.INVALID_INPUT)),n}function im(e){return{html:rm(e.html,"--html"),legalPlacement:ia(e.legalPlacement,"--legal-placement"),sizes:ia(e.sizes,"--sizes"),slotSchema:ia(e.slotSchema,"--slot-schema"),...e.teamId?{teamId:e.teamId}:{}}}function om(e){return e.requiredOption("--html <file>","Template HTML file").requiredOption("--slot-schema <file>","JSON file: slot name \u2192 { type, required, label?, maxLength?, maxItems? }").requiredOption("--sizes <file>",'JSON file: [{ "id": "1x1", "label": "Feed square", "width": 1080, "height": 1080 }]').requiredOption("--legal-placement <file>",'JSON file: size id \u2192 { "isi": { "variant": "abbreviated", "minFontPx": 12 } }').option("--idempotency-key <key>","Reuse a request key to retry this same save").option("--team-id <id>","Workspace ID")}async function ii(e,t,n,r){try{m(await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}var Fw=new Qn("list").description("List a brand's governed ad templates").option("--brand-id <id>","Brand profile ID (default: the default brand)").option("--format-family <family>","static, carousel or video").option("--limit <n>","Maximum templates to return (1-100)").option("--team-id <id>","Workspace ID").action(async e=>{await w(),e.brandId&&ri(e.brandId,"brand"),await ii("listAdTemplates",{...e.brandId?{brandId:e.brandId}:{},...e.formatFamily?{formatFamily:e.formatFamily}:{},...e.limit?{limit:oa(e.limit,"--limit")}:{},...e.teamId?{teamId:e.teamId}:{}},"List failed")}),Bw=new Qn("get").description("Read one ad template version with its HTML and lint report").argument("<template-id>","Ad template ID").option("--template-version <n>","Version to read (default: latest)").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),ri(e,"template"),await ii("getAdTemplate",{templateId:e,...t.templateVersion?{version:oa(t.templateVersion,"--template-version")}:{},...t.teamId?{teamId:t.teamId}:{}},"Read failed")}),Gw=om(new Qn("create").description("Create an ad template as a draft (version 1)").requiredOption("--brand-id <id>","Brand profile ID").requiredOption("--name <name>","Template name").option("--format-family <family>","static (default), carousel or video")).action(async e=>{await w(),ri(e.brandId,"brand"),await ii("createAdTemplate",{brandId:e.brandId,name:e.name,...e.formatFamily?{formatFamily:e.formatFamily}:{},...im(e)},"Create failed",e.idempotencyKey??nm())}),Kw=om(new Qn("update").description("Save an edited template as a new draft version (earlier versions stay unchanged)").argument("<template-id>","Ad template ID").requiredOption("--expected-latest-version <n>","The latest version you edited; a stale value is refused").option("--name <name>","Rename the template")).action(async(e,t)=>{await w(),ri(e,"template"),await ii("updateAdTemplate",{templateId:e,expectedLatestVersion:oa(t.expectedLatestVersion,"--expected-latest-version"),...t.name?{name:t.name}:{},...im(t)},"Save failed",t.idempotencyKey??nm())}),am=new Qn("ad-template").description("Governed ad templates: list, read, and save drafts (a person approves them in the app)").addCommand(Fw).addCommand(Bw).addCommand(Gw).addCommand(Kw);import{randomUUID as lm}from"crypto";import{readFileSync as mm}from"fs";import{readFile as Xw}from"fs/promises";import{Command as Me}from"commander";import{randomUUID as Ww}from"crypto";function nt(e,t){a(u(e,t)),process.exit(e instanceof P?e.exitCode:s.GENERAL_ERROR)}function Zn(e){return`cli:agent-management:${e}:${Ww()}`}function xn(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 er}from"commander";var Jw=new er("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{m(await p("listAgentRoster",{cursor:e.cursor,pageSize:xn(e.pageSize,"--page-size"),teamId:e.teamId}))}catch(t){nt(t,"Could not list the Agent roster")}}),zw=new er("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{m(await p("getRosterAgent",{agentId:e,teamId:t.teamId}))}catch(n){nt(n,"Could not read the roster Agent")}}),sm=new er("roster").description("Discover Agents shared inside the current workspace; never cross-workspace").addCommand(Jw).addCommand(zw),Hw=new er("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",b("visibility",["private","team"])).requiredOption("--expected-visibility <visibility>","Current value from agent roster get: private, team, or legacy public",b("--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{m(await p("setAgentVisibility",{agentId:e,expectedVisibility:n.expectedVisibility,teamId:n.teamId,visibility:t},n.idempotencyKey?.trim()||Zn("visibility")))}catch(r){nt(r,"Could not change Agent visibility")}}),dm=new er("visibility").description("Control whether an owned Agent is private or team-visible").addCommand(Hw);function Rn(e,t){return[...t,e]}function Yw(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new Error("Expected a positive integer.");return t}async function oi(e,t){let n=t.trim(),r=n.startsWith("{")?n:await Xw(n,"utf8"),i=JSON.parse(r);if(!i||typeof i!="object"||Array.isArray(i))throw new Error(`${e} must contain one JSON object.`);return i}var Qw=new Me("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",Yw).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 pm("Agent activation failed",()=>p("createAgent",{approvalReceipt:t.approvalReceipt,draftId:e,expectedVersion:t.expectedVersion,teamId:t.teamId},t.idempotencyKey))}),Zw=new Me("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)",Rn,[]).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)",Rn,[]).option("--output-config <json-or-path>","Full output slot configuration (repeatable)",Rn,[]).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 pm("Agent recommendation failed",async()=>p("recommendAgent",{deliveryAdapter:t.deliveryAdapter,deliveryConfig:t.deliveryConfig?await oi("--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=>oi("--output-config",n))):void 0,rationale:t.rationale,reviewPolicy:t.reviewPolicy,runtime:t.runtime?await oi("--runtime",t.runtime):void 0,sandboxBlueprintId:t.sandboxBlueprintId,schedule:t.schedule,scheduleConfig:t.scheduleConfig?await oi("--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??lm()))});async function pm(e,t){try{m(await t())}catch(n){if(n instanceof P){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:u(n,e),retryable:!1},ok:!1})),process.exit(s.GENERAL_ERROR)}}function ev(e,t){return e==="none"?null:xn(e,t)}function tv(e){return e==="none"?null:e}function Dt(e,t){let n;try{n=mm(e,"utf8")}catch(r){throw new Error(`${t} could not read ${e}: ${u(r,"unknown file error")}`)}try{return JSON.parse(n)}catch(r){throw new Error(`${t} must point to valid JSON: ${u(r,"invalid JSON")}`)}}function nv(e,t){try{return mm(e,"utf8")}catch(n){throw new Error(`${t} could not read ${e}: ${u(n,"unknown file error")}`)}}var rv=new Me("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 p("listAgents",{cursor:n,pageSize:xn(e.pageSize,"--page-size"),teamId:e.teamId});if(t.push(...r.agents),!r.hasMore||!r.nextCursor)break;n=r.nextCursor}m({agents:t,total:t.length})}catch(t){nt(t,"Could not list Agents")}}),iv=new Me("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{m(await p("getAgent",{agentId:e,teamId:t.teamId}))}catch(n){nt(n,"Could not read the Agent")}}),ov=new Me("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{m(await p("updateAgentConfiguration",{additionalFiles:t.filesFile?Dt(t.filesFile,"--files-file"):void 0,agentId:e,delivery:t.deliveryFile?Dt(t.deliveryFile,"--delivery-file"):void 0,description:t.description,expectedVersion:xn(t.expectedVersion,"--expected-version"),goal:t.goal,instructionsMarkdown:t.instructionsFile?nv(t.instructionsFile,"--instructions-file"):void 0,name:t.name,output:t.outputFile?Dt(t.outputFile,"--output-file"):void 0,outputs:t.outputsFile?Dt(t.outputsFile,"--outputs-file"):void 0,perRunCreditCap:t.perRunCreditCap===void 0?void 0:ev(t.perRunCreditCap,"--per-run-credit-cap"),reviewPolicy:t.reviewPolicy,runtime:t.runtimeFile?Dt(t.runtimeFile,"--runtime-file"):void 0,sandboxBlueprintId:t.sandboxBlueprintId===void 0?void 0:tv(t.sandboxBlueprintId),schedule:t.scheduleFile?Dt(t.scheduleFile,"--schedule-file"):void 0,sources:t.sourcesFile?Dt(t.sourcesFile,"--sources-file"):void 0,teamId:t.teamId},t.idempotencyKey??Zn("configure")))}catch(n){nt(n,"Could not update the Agent")}});function cm(e){return new Me(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{m(await p(e==="pause"?"pauseAgentSchedule":"resumeAgentSchedule",{agentId:t,teamId:n.teamId},n.idempotencyKey??Zn(e)))}catch(r){nt(r,`Could not ${e} the Agent schedule`)}})}function aa(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function av(e){return`cli:agent-memory:${e}:${lm()}`}function sv(e,t){let n=e.indexOf("="),r=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n+1);return[...t,{name:r.trim(),note:i.trim()}]}var dv=new Me("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{m(await p("getAgentMemory",{agentId:e,teamId:t.teamId}))}catch(n){aa(n,"Could not read the agent's memory")}}),cv=new Me("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)",Rn,[]).option("--always <text>","Standing instruction to add (repeatable)",Rn,[]).option("--never <text>","Thing it must not do, to add (repeatable)",Rn,[]).option("--track <name=note>","Entity to track, as name=note (repeatable)",sv,[]).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,i=t.operation==="remove"||!!n;try{m(await p("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:i?"remove":"add",recurringInstructions:t.always.length?t.always:void 0,removeField:n,removeValue:r,teamId:t.teamId},t.idempotencyKey??av(i?"remove":"add")))}catch(o){aa(o,"Could not update the agent's memory")}}),lv=new Me("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=_(t);m(await p("forgetAgentMemory",{approvalReceipt:n,agentId:e,teamId:t.teamId},t.idempotencyKey))}catch(n){aa(n,"Could not erase the agent's memory")}}),mv=new Me("memory").description("Read, edit, and erase what a scheduled agent remembers").addCommand(dv).addCommand(cv).addCommand(lv),um=new Me("agent").description("Recommend, activate, configure, and manage scheduled Agents").addCommand(rv).addCommand(iv).addCommand(sm).addCommand(dm).addCommand(ov).addCommand(cm("pause")).addCommand(cm("resume")).addCommand(Qw).addCommand(Zw).addCommand(mv);import{randomUUID as pv}from"crypto";import{password as uv}from"@inquirer/prompts";import{Command as ai}from"commander";function sa(e){if(e==="claude-code"||e==="codex")return e;throw new Error("--runtime must be claude-code or codex")}function gv(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 fv(){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 hv=new ai("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=sa(e.runtime),n=gv(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 fv():(await uv({mask:"*",message:"Provider API key:"})).trim();if(!r)throw new Error("Provider API key is required");let i=await Zd({apiKey:r,...e.baseUrl?{baseUrl:e.baseUrl}:{},label:e.label,makeDefault:e.use??!1,modelId:e.model,provider:n,runtime:t});C(`Saved connection profile ${i.label} (${i.id})`)}catch(t){a(u(t,"Profile enrollment failed")),process.exit(s.GENERAL_ERROR)}}),yv=new ai("list").description("List secret-free Claude Code or Codex connection profiles").requiredOption("--runtime <runtime>","claude-code or codex").action(async e=>{try{let t=sa(e.runtime);m(await p("listAiConnectionProfiles",{runtime:t}))}catch(t){a(u(t,"Profile list failed")),process.exit(s.GENERAL_ERROR)}}),bv=new ai("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=sa(e.runtime),n=await p("selectAiConnectionProfile",{profileId:e.profileId,runtime:t},e.idempotencyKey?.trim()||pv());C(n.selectedProfileId?`Selected connection profile ${n.selectedProfileId}`:"Selected the native provider route")}catch(t){a(u(t,"Profile selection failed")),process.exit(s.GENERAL_ERROR)}}),gm=new ai("ai-connections").description("Manage Claude Code and Codex inference routes").addCommand(hv).addCommand(yv).addCommand(bv);import{Command as ca}from"commander";import{Command as fm}from"commander";var wv=new fm("set").description("Set the poster an artifact shows on cards").argument("<artifact-kind>","Artifact kind: presentation, video, microsite, survey, \u2026").argument("<target-id>","Artifact id \u2014 a presentation's documentId, other kinds' row id").option("--slide <number>","Presentations: rendered slide number").option("--at-seconds <seconds>","Videos: moment 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,n)=>{[n.slide,n.atSeconds,n.imageUrl,n.uploadKey].filter(o=>o!==void 0).length>1&&(a("Name at most one poster source: --slide, --at-seconds, --image-url or --upload-key. Name none to restore the automatic preview."),process.exit(s.INVALID_INPUT));let i={artifactKind:e,targetId:t};if(n.slide!==void 0){let o=Number(n.slide);(!Number.isInteger(o)||o<1)&&(a("--slide must be a whole slide number, 1 or more."),process.exit(s.INVALID_INPUT)),i.slideNumber=o}if(n.atSeconds!==void 0){let o=Number(n.atSeconds);(!Number.isFinite(o)||o<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),i.atSeconds=o}n.imageUrl!==void 0&&(i.imageUrl=n.imageUrl),n.uploadKey!==void 0&&(i.uploadKey=n.uploadKey),n.teamId!==void 0&&(i.teamId=n.teamId);try{let o=await U(n.teamId),c=await p("setArtifactPoster",i,Q({command:"artifact poster set",payload:i,workspaceId:o}));m(c),C(c.posterUrl===null?"Poster reset to the automatic preview.":`Poster set from ${c.source}.`)}catch(o){a(u(o,"Setting the poster failed")),process.exit(s.GENERAL_ERROR)}}),hm=new fm("poster").description("Set the poster an artifact shows on cards").addCommand(wv);var da=["article","document","footageProject","microsite","presentation","presentationVideo","video"];function ym(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function vv(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 Iv=new ca("read").description("Read an owned artifact's full content").argument("<kind>",`Artifact kind: ${da.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").option("--version-id <id>","Footage projects only: saved version UUID").action(async(e,t,n)=>{da.includes(e)||(a(`Unknown artifact kind "${e}". Expected one of: ${da.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("readArtifact",{artifactId:t,kind:e,slides:vv(n.slides),versionId:n.versionId,teamId:n.teamId});m(r)}catch(r){ym(r,"Could not read the artifact")}}),kv=new ca("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",e=>{let t=Number(e);return(!Number.isInteger(t)||t<0)&&(a("--file-size expects the exact whole-number byte size."),process.exit(s.GENERAL_ERROR)),t}).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 e=>{try{m(await p("createUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},e.idempotencyKey))}catch(t){ym(t,"Could not mint the upload URL")}}),bm=new ca("artifact").description("Read artifacts this workspace owns").addCommand(Iv).addCommand(kv).addCommand(hm);import{Command as vm}from"commander";var wm=1e3;function xv(e,t){let n=Number(e);return(!Number.isInteger(n)||n<1)&&(a(`${t} must be a positive whole number`),process.exit(s.GENERAL_ERROR)),n}function Rv(e){return e.split(",").map(t=>t.trim()).filter(Boolean)}var Cv=new vm("export").description("Export who did what in the workspace (admins of governed workspaces). Newest first.").option("--from <iso>","Window start, ISO 8601 (default: 30 days before --to)").option("--to <iso>","Window end, ISO 8601 (default: now)").option("--categories <list>","Comma-separated: access,approvals,brand,features,governed_content,settings,sharing (default: all)").option("--format <format>","json (default) or csv").option("--limit <count>","Events per page, 1-1000 (default 200)").option("--cursor <cursor>","Continue from a previous page's nextCursor").option("--all","Follow nextCursor until the window is exhausted").option("--team-id <id>","Workspace ID").action(async e=>{try{let t=e.format??"json",n={categories:e.categories===void 0?void 0:Rv(e.categories),format:t,from:e.from,limit:e.limit===void 0?void 0:xv(e.limit,"--limit"),teamId:e.teamId,to:e.to},r=e.cursor,i=[];for(let l=0;l<wm;l+=1){let d=await p("exportWorkspaceAuditLog",{...n,cursor:r});if(i.push(d),!e.all||!d.nextCursor)break;n.from=d.window.from,n.to=d.window.to,r=d.nextCursor}let o=i[i.length-1],c=!!(e.all&&o?.nextCursor);if(t==="csv"){let[l,...d]=i.map(y=>y.csv??""),g=d.map(y=>y.slice(y.indexOf(`\r
65
+ `)+2));process.stdout.write([l,...g].join(""))}else i.length===1?m(i[0]):m({...o,events:i.flatMap(l=>l.events),nextCursor:o?.nextCursor??null,window:i[0]?.window});c&&(a(`Export incomplete: stopped after ${wm} pages. Continue with --cursor ${o?.nextCursor} --from ${n.from} --to ${n.to}`),process.exit(s.GENERAL_ERROR))}catch(t){a(u(t,"Exporting the workspace audit log failed")),process.exit(s.GENERAL_ERROR)}}),Im=new vm("audit-log").description("Workspace audit log").addCommand(Cv);import{randomUUID as di}from"crypto";import{readFileSync as Dv}from"fs";import{readFile as Nv}from"fs/promises";import Nt from"chalk";import{Command as Pe}from"commander";import Lv from"ora";import{mkdir as Sv,writeFile as km}from"fs/promises";import{dirname as Ev}from"path";async function Ie(e,t){if(await Sv(Ev(t),{recursive:!0}),e.startsWith("data:")){let i=e.match(/^data:[^;]+;base64,(.+)$/);if(!i)throw new Error("Invalid data URL format");let o=Buffer.from(i[1],"base64");if(o.length===0)throw new Error("Downloaded media was empty");await km(t,o);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 km(t,r)}import{existsSync as xm}from"fs";import{resolve as Pv}from"path";var Av=/^([A-Za-z][A-Za-z0-9_-]*)=(.+)$/;function Tv(e){let t=e.trim();if(!t)throw new P("A reference image value cannot be empty.",400);if(xm(t))return{source:t};let n=Av.exec(t);return n?{label:n[1],source:n[2]}:{source:t}}function Ov(e,t,n){if(!e.startsWith("image/")&&e!=="application/octet-stream")throw new P(`Reference image ${t} (${n}) is ${e}, not an image. A reference must be an image; pass an image file or a public image URL.`,400)}function $v(e,t){let n;try{n=new URL(e)}catch{throw new P(`Reference image ${t} (${e}) must be an existing local file or an HTTP(S) URL.`,400)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new P(`Reference image ${t} (${e}) must use an HTTP(S) URL.`,400);return n}async function si(e,t){if(e?.length){if(t.maxCount!==void 0&&e.length>t.maxCount)throw new P(`${t.maxCountSubject??"This command"} accepts at most ${t.maxCount} reference images; ${e.length} were provided.`,400);return Promise.all(e.map(async(n,r)=>{let i=r+1,{label:o,source:c}=Tv(n);if(xm(c)){let d=Pv(c),g=gn(d);t.rejectNonImageFiles&&Ov(g,i,c);let y=await ie(d,{idempotencyKey:`${t.idempotencyKey}:reference:${i}`}),v=y.type||g;return{...o?{label:o}:{},...v.startsWith("image/")?{mediaType:v}:{},url:y.url}}let l=$v(c,i);return{...o?{label:o}:{},url:l.toString()}}))}}var Uv=15e3,_v=40,jv=3;function qv(e,t){return[...t,e]}async function Mv(e){let t=e.trim(),n=t.startsWith("[")?t:await Nv(t,"utf8"),r=JSON.parse(n);if(!Array.isArray(r)||r.some(i=>!i||typeof i!="object"||Array.isArray(i)))throw new Error("--starter-looks-json must contain one JSON array of objects.");return r}async function Rm(e,t){return(await si(e,{idempotencyKey:t,maxCount:jv,maxCountSubject:"A presenter Look"}))?.map(r=>({url:r.url}))}function la(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.durationSec!=null&&I(`Duration: ${e.durationSec}s`),e.videoUrl&&C(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}var Vv=new Pe("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await kc(e.language,e.teamId);if(e.format==="json"){m(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){I("Your presenters:");for(let r of n)console.log(` ${r.id} ${r.name}`)}I("Avatars:");for(let r of t.avatars){let i=r.renderTiers?.length?` [${r.renderTiers.join(", ")}]`:"";console.log(` ${r.id} ${r.name}${i}`)}I("Voices:");for(let r of t.voices)console.log(` ${r.id} ${r.name}${r.language?` (${r.language})`:""}`)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Fv=new Pe("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await p("listPresenterCreationOptions",{locale:e.locale,teamId:e.teamId});if(e.format==="json")return m(t);if(e.format==="quiet"){for(let n of t.options)console.log(n.id);return}I(t.canCreate?"Presenter creation is enabled.":"Presenter creation is not enabled for this account.");for(let n of t.options)console.log(`
66
+ ${Nt.bold(n.label)} ${Nt.gray(n.id)}`),console.log(` ${n.description}`),console.log(` Sources: ${n.supportedKinds.join(", ")}`),console.log(` Credits: ${Object.entries(n.creationCredits).map(([r,i])=>`${r}=${i}`).join(", ")}`),console.log(` Consent: ${n.consentCopyText}`)}catch(t){a(u(t,"Options failed")),process.exit(s.GENERAL_ERROR)}}),Bv=new Pe("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",qv,[]).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").option("--wait-timeout-seconds <n>","Max seconds to wait for the presenter creation run (default 3600)",Number).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?Dv(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??di();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 ie(e.source,{idempotencyKey:`${n}:source`,storagePrefix:"presenters"}):void 0,i=await Promise.all(e.referenceImage.map((l,d)=>ie(l,{idempotencyKey:`${n}:reference:${d}`,storagePrefix:"presenters"}))),o=e.starterLooksJson?await Mv(e.starterLooksJson):[],c=await p("createPresenter",{approvalReceipt:t,consentCopyLocale:e.locale,consentCopyText:e.consentStatement,engineId:e.engine,kind:e.kind,name:e.name,...e.prompt?{prompt:e.prompt}:{},...i.length?{referenceImageS3Keys:i.map(l=>l.s3Key)}:{},...r?{s3Key:r.s3Key}:{},starterLooks:o,teamId:e.teamId},n);if(!e.wait){m(c),I(`Check progress with: ${f.commands[0]} avatar presenter status ${c.runId}`);return}m(await z("createPresenter",c.runId,e.teamId,null,{maxWaitMs:(e.waitTimeoutSeconds??3600)*1e3,statusCommand:"avatar presenter status"}))}catch(r){let i=u(r);a(i),i.includes("approval")&&I(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${n}`),process.exit(s.GENERAL_ERROR)}}),Gv=new Pe("status").description("Read personal-presenter creation status").argument("<run-id>","Durable run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createPresenter",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Kv=new Pe("presenter").description("Discover and create reusable personal presenters").addCommand(Fv).addCommand(Bv).addCommand(Gv),Wv=new Pe("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",b("--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"?Lv("Generating presenter clip...").start():null;try{let i=e.idempotencyKey??di(),o=e.audioUrl?{audioUrl:e.audioUrl}:{script:e.script??"",...e.voiceId?{voiceId:e.voiceId}:{}},c=await xc({...o,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},i);if(!e.wait){r?.stop(),la(c,e.format);return}let l=await $e(()=>qo(c.requestId),_v,Uv);if(l.status==="failed")throw new de(l.error||"Presenter generation failed");if(!l.videoUrl)throw new Error("Presenter generation completed without a video URL");r&&(r.text="Downloading presenter clip..."),await Ie(l.videoUrl,e.output),r?.stop(),la(l,e.format),e.format==="human"&&C(`Saved to: ${e.output}`)}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Jv=new Pe("status").description("Check a presenter clip generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{la(await qo(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),zv=new Pe("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??di(),r=await Rm(t.referenceImage,n),i=await p("generatePresenterLook",{baseProfileId:e,description:t.description,id:t.lookId,prompt:t.prompt,...r?{referenceImages:r}:{},title:t.name},n);m(i)}catch(n){a(u(n,"Look generation failed")),process.exit(s.GENERAL_ERROR)}}),Hv=new Pe("status").description("Read presenter look generation status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("generatePresenterLook",e);if(t.format==="json")return m(n);if(t.format==="quiet")return console.log(n.status);I(`Run ID: ${e}`),I(`Status: ${n.status}`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Xv=new Pe("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??di(),r=await Rm(t.referenceImage,n),i=await p("revisePresenterLook",{instruction:t.instruction,...r?{referenceImages:r}:{},sourceLookId:e},n);m(i)}catch(n){a(u(n,"Look revision failed")),process.exit(s.GENERAL_ERROR)}}),Yv=new Pe("revision-status").description("Read presenter Look revision status").argument("<run-id>","Durable run ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("revisePresenterLook",e);if(t.format==="json")return m(n);if(t.format==="quiet")return console.log(n.status);I(`Run ID: ${e}`),I(`Status: ${n.status}`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Revision status failed")),process.exit(s.GENERAL_ERROR)}}),Qv=new Pe("look").description("Manage looks under an existing personal presenter").addCommand(zv).addCommand(Xv).addCommand(Yv).addCommand(Hv),ma=new Pe("avatar").description("Generate presenter clips and looks; avatar options lists the voices and looks used by presentation video presenter and cast preset").addCommand(Vv).addCommand(Kv).addCommand(Wv).addCommand(Qv).addCommand(Jv);ma.addHelpText("after",`
67
67
  ${Nt.bold("Examples:")}
68
68
  ${Nt.gray("# Discover the presenter avatars and voices you can use")}
69
69
  $ ${f.commands[0]} avatar options
@@ -74,55 +74,55 @@ ${Nt.bold("See also:")}
74
74
 
75
75
  ${Nt.gray("# Apply an avatar, look, or preset to one presentation-video scene")}
76
76
  $ ${f.commands[0]} presentation video presenter <project-id>
77
- `);import{randomUUID as uR}from"crypto";import{readFileSync as gR}from"fs";import{writeFile as fR}from"fs/promises";import Z from"chalk";import{Command as Dn,InvalidArgumentError as zp}from"commander";import hR from"ora";import{createHash as pI}from"crypto";import{Command as rr,InvalidArgumentError as nr}from"commander";import{createHash as tI}from"crypto";import{existsSync as nI,readFileSync as rI}from"fs";import{basename as iI}from"path";import{Command as oI,InvalidArgumentError as er}from"commander";import aI from"ora";import{createHash as Xv}from"crypto";import{Command as Yv,InvalidArgumentError as xm}from"commander";var Qv=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Zv(e){if(!Qv.test(e))throw new xm("brand-id expects a UUID from `mf branding list`.");return e}function eI(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new xm("--file-size expects the exact positive whole-number byte size.");return t}async function ma(e){let{idempotencyKey:t,...n}=e;return p("createBrandAssetUploadUrl",n,t)}function la(e){if(e===void 0)return"";if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(la).join(",")}]`;let t=e;return`{${Object.keys(t).filter(n=>t[n]!==void 0).sort().map(n=>`${JSON.stringify(n)}:${la(t[n])}`).join(",")}}`}function pa(e){return Xv("sha256").update(`createBrandAssetUploadUrl:${la(e)}`).digest("hex").slice(0,32)}var Rm=new Yv("upload-url").description("Mint a short-lived brand-scoped storage POST; this does not upload bytes").argument("<brand-id>","Brand UUID you may manage",Zv).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",eI).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 w();try{m(await ma({brandId:e,...t,idempotencyKey:t.idempotencyKey??pa({brandId:e,fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType})}))}catch(n){a(u(n,"Brand asset upload URL creation failed")),process.exit(s.GENERAL_ERROR)}});var sI=["footage","image","before_after","logo","audio"],dI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function cI(e){if(!dI.test(e))throw new er("brand-id expects a UUID from `mf branding list`.");return e}function Cm(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new er(`${e} expects a whole number of 0 or more.`);return n}}function lI(e){let t=Number(e);if(!Number.isFinite(t)||t<0)throw new er("--duration-sec expects a number of 0 or more.");return t}function mI(e){let t;try{t=JSON.parse(e)}catch{throw new er("--metadata expects valid JSON.")}if(!t||typeof t!="object"||Array.isArray(t))throw new er("--metadata expects a JSON object.");return t}var Sm=new oI("upload").description("Upload one local file, register it on a brand, and print the asset JSON").argument("<brand-id>","Brand UUID",cI).requiredOption("--file <path>","Local file to upload through Mindframes storage").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",b("--kind",sI)).option("--label <text>","Display label; defaults to the local filename").option("--width <px>","Image or video width in pixels",Cm("--width")).option("--height <px>","Image or video height in pixels",Cm("--height")).option("--duration-sec <n>","Audio or video duration in seconds",lI).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",b("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',mI).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 w(),nI(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=tI("sha256").update(rI(t.file)).digest("hex"),r=et(t.file),i={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},o=t.idempotencyKey??pa(i),c=aI({text:`Uploading ${iI(t.file)}...`,stream:process.stderr}).start();try{let l=await ma({brandId:e,...r,idempotencyKey:o,teamId:t.teamId}),d=await tt(t.file,l);c.succeed("Uploaded"),m(await p("registerBrandAsset",{brandId:e,durationSec:t.durationSec,height:t.height,kind:t.kind,label:i.label,metadata:t.metadata,mimeType:d.type,role:t.role,s3Key:d.s3Key,setKey:t.setKey,sizeBytes:d.size,teamId:t.teamId,url:d.url,width:t.width},o))}catch(l){c.fail("Asset upload failed"),a(u(l,"Asset upload failed")),process.exit(s.GENERAL_ERROR)}});var Em=["footage","image","before_after","logo","audio"],uI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cn(e){return t=>{if(!uI.test(t))throw new nr(`${e} expects a UUID from \`mf branding list\` or \`mf branding asset list\`.`);return t}}function tr(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t)throw new nr(`${e} expects a whole number from ${t} upward.`);return r}}function gI(e){return t=>{let n=Number(t);if(!Number.isFinite(n)||n<0)throw new nr(`${e} expects a number of 0 or more.`);return n}}function fI(e){let t;try{t=JSON.parse(e)}catch(n){throw new nr(`--metadata expects JSON: ${u(n)}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new nr("--metadata expects a JSON object.");return t}function ua(e){return pI("sha256").update(e).digest("hex").slice(0,32)}function di(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var hI=new rr("list").description("List one brand's uploaded assets and print stable asset IDs").argument("<brand-id>","Brand UUID",Cn("brand-id")).option("--kind <kind>","Filter: footage | image | before_after | logo | audio",b("--kind",Em)).option("--limit <count>","Caller-selected page size; omit to return every matching asset",tr("--limit",1)).option("--offset <count>","Matching assets to skip before returning results (default: 0)",tr("--offset",0)).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("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){di(n,"Asset list failed")}}),yI=new rr("register").description("Register one app-owned upload from its exact URL, key, MIME, and metadata").argument("<brand-id>","Brand UUID",Cn("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",b("--kind",Em)).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",tr("--size-bytes",0)).option("--width <px>","Image or video width in pixels",tr("--width",0)).option("--height <px>","Image or video height in pixels",tr("--height",0)).option("--duration-sec <n>","Audio or video duration in seconds",gI("--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",b("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',fI).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 w(),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??ua(`registerBrandAsset:${JSON.stringify(n)}`);try{m(await p("registerBrandAsset",n,r))}catch(i){di(i,"Asset registration failed")}}),bI=new rr("rename").description("Rename one asset, then print its stored label and metadata").argument("<asset-id>","Asset UUID from `mf branding asset list`",Cn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Cn("--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 w();let n=t.label.trim();n||(a("--label cannot be empty."),process.exit(s.INVALID_INPUT));try{m(await p("renameBrandAsset",{assetId:e,brandId:t.brand,label:n,teamId:t.teamId},t.idempotencyKey??ua(`renameBrandAsset:${e}:${n}`)))}catch(r){di(r,"Asset rename failed")}}),wI=new rr("delete").description("Remove one asset record from the brand while keeping its uploaded file").argument("<asset-id>","Asset UUID from `mf branding asset list`",Cn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Cn("--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 w(),t.yes||(a("Refusing removal from the brand library without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandAsset",{assetId:e,brandId:t.brand,teamId:t.teamId},t.idempotencyKey??ua(`deleteBrandAsset:${e}`)))}catch(n){di(n,"Asset deletion failed")}}),Pm=new rr("asset").description("List, upload, rename, and remove a brand's private asset library").addCommand(hI).addCommand(yI).addCommand(Rm).addCommand(Sm).addCommand(bI).addCommand(wI);import{createHash as vI,randomUUID as Tm}from"crypto";import{existsSync as Am,readdirSync as II,readFileSync as kI,statSync as xI}from"fs";import{join as Om}from"path";import{Command as rt}from"commander";var $m=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ut(e){$m.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ci(e,t=[]){return[...t,e]}function ga(e){return vI("sha256").update(e).digest("hex").slice(0,32)}function fa(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 li(e,t){let n=Number(t);if(Number.isInteger(n)&&n>0)return n;a(`${e} must be a positive whole number; got "${t}".`),process.exit(s.INVALID_INPUT)}function Lt(e,t){try{return JSON.parse(t)}catch{a(`${e} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}async function Sn(e,t,n,r){try{m(r===void 0?await p(e,t):await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}function Dm(e,t){let n={brandId:e,teamId:t.teamId};return t.audience!==void 0&&(n.audience=t.audience),t.market!==void 0&&(n.market=t.market),t.productId!==void 0&&(n.productId=t.productId),t.status!==void 0&&(n.status=t.status),t.usableOnly&&(n.usableOnly=!0),n}function Nm(e){return e.option("--product-id <id>","Only items scoped to this brand product").option("--market <market>","Only items scoped to this market, e.g. US").option("--audience <audience>","Only items scoped to this audience").option("--status <status>","draft | approved | pre-launch | restricted | withdrawn | retired; repeat for several",ci).option("--usable-only","Only items usable now: approved and in scope (never restricted, retired or draft)").option("--team-id <id>","Workspace ID")}var RI=Nm(new rt("list").description("List a brand's claims library").argument("<brand-id>","Brand profile ID").option("--claim-type <type>","efficacy | safety | dosing | indication | mechanism | comparative | outcomes | disease-awareness | cost | cta | qualifier | other")).action(async(e,t)=>{await w(),Ut(e);let n=Dm(e,t);t.claimType!==void 0&&(n.claimType=t.claimType),await Sn("listClaims",n,"List failed")}),CI=new rt("get").description("Read one claim, its references and its versions").argument("<brand-id>","Brand profile ID").argument("<node-key>","Claim key, e.g. claim.a1c-reduction").option("--version-number <n>","Read this version instead of the current one").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.versionNumber!==void 0&&(r.version=li("--version-number",n.versionNumber)),await Sn("getClaim",r,"Read failed")}),SI=new rt("set").description("Create or edit a draft claim, or restrict, withdraw or retire one (people approve in the app)").argument("<brand-id>","Brand profile ID").option("--node-key <key>","Key of an existing claim to UPDATE, as `claims list` shows it. Omit to create.").option("--slug <slug>","Kebab-case slug for a NEW claim's key").option("--text <text>","The claim, verbatim").option("--claim-type <type>","efficacy | safety | dosing | indication | mechanism | comparative | outcomes | disease-awareness | cost | cta | qualifier | other").option("--status <status>","draft | restricted | withdrawn | retired (only a signed-in person can approve, in the app)").option("--restriction-reason <text>","Why the claim must not be used").option("--footnote <text>",'Verbatim footnote that must accompany it ("" removes it)').option("--reviewer-note <text>",'Note for reviewers ("" removes it)').option("--require-legal-block <key>","Legal block (rule.legal.*) that must appear with the claim; repeat for several",ci).option("--require-qualifier <claim-key>","Qualifier claim (claimType qualifier) that must appear directly with the claim; repeat for several",ci).option("--scope <json>",`Products, markets and audiences, as JSON, e.g. '{"markets":["US"]}'`).option("--external <json>",`Where the claim lives in your system of record, as JSON, e.g. '{"system":"promomats","id":"CLM-000123","status":"Approved"}'`).option("--references <json>",`Supporting citations, as a JSON array; anchor each with the document, page and exact passage, e.g. '[{"citation":"Prescribing Information \xA714.1","externalDocumentId":"VV-00123","documentVersion":"2.0","page":"12","passage":"\u2026"}]'`).option("--expected-version <n>","Refuse the write if the claim is no longer at this version").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Ut(e),!t.nodeKey&&(!t.text||!t.claimType)&&(a("A new claim needs --text and --claim-type."),process.exit(s.INVALID_INPUT));let n={brandId:e,teamId:t.teamId};t.nodeKey!==void 0&&(n.nodeKey=t.nodeKey),t.slug!==void 0&&(n.slug=t.slug),t.text!==void 0&&(n.text=t.text),t.claimType!==void 0&&(n.claimType=t.claimType),t.status!==void 0&&(n.status=t.status),t.restrictionReason!==void 0&&(n.restrictionReason=t.restrictionReason),t.footnote!==void 0&&(n.footnote=t.footnote===""?null:t.footnote),t.reviewerNote!==void 0&&(n.reviewerNote=t.reviewerNote===""?null:t.reviewerNote),t.requireLegalBlock!==void 0&&(n.requiredLegalBlockKeys=t.requireLegalBlock),t.requireQualifier!==void 0&&(n.requiredQualifierKeys=t.requireQualifier),t.scope!==void 0&&(n.scope=Lt("--scope",t.scope)),t.references!==void 0&&(n.references=Lt("--references",t.references)),t.external!==void 0&&(n.external=Lt("--external",t.external)),t.expectedVersion!==void 0&&(n.expectedVersion=li("--expected-version",t.expectedVersion)),t.publish!==void 0&&(n.publish=fa("--publish",t.publish)),await Sn("setClaim",n,"Write failed",ga(`setClaim:${e}:${JSON.stringify(n)}`))}),EI={anchors:"anchors.csv",claimTargets:"3_annotation_keyword_targets__sys.csv",claims:"1_annotation_keywords__sys.csv",documents:"documents.csv",linkTargets:"2_link_target__sys.csv"},PI=/\.(pdf|txt)$/i;function AI(e){(!Am(e)||!xI(e).isDirectory())&&(a(`${e} is not a folder. Pass the folder holding the export.`),process.exit(s.INVALID_INPUT));let t={};for(let[n,r]of Object.entries(EI)){let i=Om(e,r);if(!Am(i)){n==="claims"&&(a(`${e} has no ${r}: export the claims (Text Assets) first.`),process.exit(s.INVALID_INPUT)),t[n]="";continue}t[n]=kI(i,"utf8")}return t}function TI(e){let t=new Map;for(let n of e){let r=n.lastIndexOf("="),i=n.slice(0,r).trim(),o=n.slice(r+1).trim();(r<1||!$m.test(o))&&(a(`--rendition expects <file name>=<Library file id>; got "${n}".`),process.exit(s.INVALID_INPUT)),t.set(i,o)}return t}async function OI(e,t,n){let r=[...t].map(([i,o])=>({fileName:i,libraryFileId:o}));for(let i of II(e).sort()){if(!PI.test(i)||t.has(i))continue;let o=Om(e,i),c=`cli:claims-import:rendition:${Tm()}`,l=await p("createLibraryFileUploadUrl",{...et(o),teamId:n},`${c}:upload`),d=await tt(o,l),y=(await p("addLibraryFile",{mediaType:d.type,name:d.name,size:d.size,teamId:n,uploadKey:d.s3Key,url:d.url},c)).files[0]?.fileId;y&&r.push({fileName:i,libraryFileId:y})}return r}var $I=new rt("import").description("Import claims from a PromoMats export; a dry run unless --commit (people approve in the app)").argument("<brand-id>","Brand profile ID").argument("<export-dir>","Folder with the export: 1_annotation_keywords__sys.csv, 2_link_target__sys.csv, 3_annotation_keyword_targets__sys.csv, anchors.csv, documents.csv and the reference renditions (PDF or text) documents.csv names").option("--commit","Write the plan. Without --plan-id the import is previewed and that preview committed").option("--plan-id <id>","Commit exactly this plan, from an earlier preview; refused if anything changed since").option("--rendition <file=id>","Use a reference already on the Library shelf instead of uploading the local file; repeat for several",ci).option("--columns <json>",`Column renames for a customised Vault, as JSON, e.g. '{"claims":{"category":"claim_category__c"}}'; a commit saves them for the workspace`).option("--publish <bool>","Publish a brand snapshot after a commit; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e),n.planId&&!n.commit&&(a("--plan-id names a plan to commit; add --commit."),process.exit(s.INVALID_INPUT));let r=AI(t),i={brandId:e,files:r,teamId:n.teamId};n.columns!==void 0&&(i.columnOverrides=Lt("--columns",n.columns)),n.publish!==void 0&&(i.publish=fa("--publish",n.publish));try{i.renditions=await OI(t,TI(n.rendition??[]),n.teamId);let o=n.planId;if(!n.commit||!o){let c=await p("importClaims",{...i,mode:"preview"},`cli:claims-import:preview:${Tm()}`);if(!n.commit||c.problems?.length){m(c),c.problems?.length&&process.exit(s.INVALID_INPUT);return}o=c.planId}m(await p("importClaims",{...i,mode:"commit",planId:o},ga(`importClaims:${e}:${o}`)))}catch(o){a(u(o,"Import failed")),process.exit(s.GENERAL_ERROR)}}),Lm=new rt("claims").description("Brand claims library (governed, verbatim claims)").addCommand(RI).addCommand(CI).addCommand(SI).addCommand($I),DI=Nm(new rt("list").description("List a brand's ISI and legal blocks").argument("<brand-id>","Brand profile ID").option("--block-type <type>","isi | indication | fair-balance | footnote | disclaimer | legal-line").option("--variant <variant>","full | abbreviated | story-strip | end-card")).action(async(e,t)=>{await w(),Ut(e);let n=Dm(e,t);t.blockType!==void 0&&(n.blockType=t.blockType),t.variant!==void 0&&(n.variant=t.variant),await Sn("listLegalBlocks",n,"List failed")}),NI=new rt("get").description("Read one legal block and its versions").argument("<brand-id>","Brand profile ID").argument("<node-key>","Legal block key, e.g. rule.legal.isi-full").option("--version-number <n>","Read this version instead of the current one").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.versionNumber!==void 0&&(r.version=li("--version-number",n.versionNumber)),await Sn("getLegalBlock",r,"Read failed")}),LI=new rt("set").description("Create or edit a draft legal block, or restrict, withdraw or retire one").argument("<brand-id>","Brand profile ID").option("--node-key <key>","Key of an existing block to UPDATE, as `legal-blocks list` shows it. Omit to create.").option("--slug <slug>","Kebab-case slug for a NEW block's key").option("--name <name>","Display name, e.g. Important Safety Information").option("--block-type <type>","isi | indication | fair-balance | footnote | disclaimer | legal-line").option("--variant <variant>","full | abbreviated | story-strip | end-card").option("--content <json>",`Verbatim text as JSON blocks of runs, e.g. '[{"type":"paragraph","runs":[{"text":"Warning:","bold":true},{"text":" \u2026"}]}]'`).option("--placement <json>",`Rendering constraints as JSON, e.g. '{"minFontSizePx":10,"minAreaPercent":20,"position":"bottom"}'`).option("--scope <json>",`Products, markets and audiences, as JSON, e.g. '{"markets":["US"]}'`).option("--source-url <url>",'Where the verbatim text comes from ("" removes it)').option("--notes <text>","Note for reviewers").option("--status <status>","draft | restricted | withdrawn | retired").option("--restriction-reason <text>","Why the block must not be used").option("--expected-version <n>","Refuse the write if the block is no longer at this version").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Ut(e),!t.nodeKey&&(!t.name||!t.blockType||!t.variant||!t.content||!t.placement)&&(a("A new legal block needs --name, --block-type, --variant, --content and --placement."),process.exit(s.INVALID_INPUT));let n={brandId:e,teamId:t.teamId};t.nodeKey!==void 0&&(n.nodeKey=t.nodeKey),t.slug!==void 0&&(n.slug=t.slug),t.name!==void 0&&(n.name=t.name),t.blockType!==void 0&&(n.blockType=t.blockType),t.variant!==void 0&&(n.variant=t.variant),t.content!==void 0&&(n.content=Lt("--content",t.content)),t.placement!==void 0&&(n.placement=Lt("--placement",t.placement)),t.scope!==void 0&&(n.scope=Lt("--scope",t.scope)),t.sourceUrl!==void 0&&(n.sourceUrl=t.sourceUrl===""?null:t.sourceUrl),t.notes!==void 0&&(n.notes=t.notes),t.status!==void 0&&(n.status=t.status),t.restrictionReason!==void 0&&(n.restrictionReason=t.restrictionReason),t.expectedVersion!==void 0&&(n.expectedVersion=li("--expected-version",t.expectedVersion)),t.publish!==void 0&&(n.publish=fa("--publish",t.publish)),await Sn("setLegalBlock",n,"Write failed",ga(`setLegalBlock:${e}:${JSON.stringify(n)}`))}),Um=new rt("legal-blocks").description("Brand ISI and legal blocks (governed, verbatim)").addCommand(DI).addCommand(NI).addCommand(LI);import{Command as _m,InvalidArgumentError as UI}from"commander";var _I=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,jI=["presentation","reel","story","video","walkthrough","slide","microsite","article"];function qI(e){if(!_I.test(e))throw new UI("Expected a brand UUID from `mf branding list`.");return e}var MI=new _m("resolve").description("Resolve design tokens, node trace, rules, and conflicts").argument("<brand-id>","Brand UUID",qI).requiredOption("--artifact <type>","Artifact type",b("--artifact",[...jI])).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 w();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{m(await p("resolveBrandDesign",n))}catch(r){a(u(r,"Brand design resolve failed")),process.exit(s.GENERAL_ERROR)}}),jm=new _m("design").description("Inspect resolved brand design state").addCommand(MI);import{createHash as VI,randomUUID as FI}from"crypto";import{Command as it,InvalidArgumentError as qm}from"commander";var BI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ir(e){if(!BI.test(e))throw new qm("Expected a brand UUID from `mf branding list`.");return e}function GI(e){if(e==="true")return!0;if(e==="false")return!1;throw new qm("--show expects true or false.")}function mi(e,t){return VI("sha256").update(JSON.stringify([e,t])).digest("hex").slice(0,32)}function En(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var KI=new it("set").description("Create or update one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",ir).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 w();let i={brandId:e,hex:n,role:t,teamId:r.teamId};try{m(await p("setBrandCustomColor",i,r.idempotencyKey??mi("setBrandCustomColor",i)))}catch(o){En(o,"Custom colour update failed")}}),WI=new it("delete").description("Remove one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",ir).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 w(),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{m(await p("deleteBrandCustomColor",r,n.idempotencyKey??mi("deleteBrandCustomColor",r)))}catch(i){En(i,"Custom colour removal failed")}}),JI=new it("sync").description("Synchronize current brand data into the canonical brand graph").argument("<brand-id>","Brand UUID",ir).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 w();let n={brandId:e,teamId:t.teamId};try{let r=await p("syncBrandFoundation",n,t.idempotencyKey??mi("syncBrandFoundation",[n,FI()]));m(t.wait===!1?r:await qc(r.runId,t.teamId))}catch(r){En(r,"Brand foundation sync failed")}}),zI=new it("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 w();try{m(await R("syncBrandFoundation",e,t.teamId))}catch(n){En(n,"Brand foundation sync status failed")}}),Mm=new it("foundation").description("Manage atomic Foundation settings backed by the brand DAG").addCommand(new it("color").description("Manage custom colour roles").addCommand(KI).addCommand(WI)).addCommand(JI).addCommand(zI),HI=new it("get").description("Read the complete current footer and its source").argument("<brand-id>","Brand UUID",ir).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("getBrandFooter",{brandId:e,teamId:t.teamId}))}catch(n){En(n,"Footer read failed")}}),XI=new it("set").description("Patch footer text, visibility, or alignment atomically").argument("<brand-id>","Brand UUID",ir).option("--text <text>","Complete footer text; pass an empty string to clear it").option("--show <boolean>","Whether artifacts show the footer: true | false",GI).option("--alignment <value>","Footer alignment: left | center | right",b("--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 w(),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{m(await p("setBrandFooter",n,t.idempotencyKey??mi("setBrandFooter",n)))}catch(r){En(r,"Footer update failed")}}),Vm=new it("footer").description("Read or update the brand footer").addCommand(HI).addCommand(XI);import{createHash as YI}from"crypto";import{Command as Fm}from"commander";var QI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ZI(e){QI.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ek(e){return YI("sha256").update(e).digest("hex").slice(0,32)}function Bm(e,t){try{return JSON.parse(t)}catch(n){a(`${e} is not valid JSON: ${u(n)}`),process.exit(s.INVALID_INPUT)}}function tk(e,t){let n=Bm(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 nk(e,t){let n=Bm(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 rk=new Fm("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 w(),ZI(e);let n={brandId:e,gradients:tk("--gradients",t.gradients),teamId:t.teamId};t.roles!==void 0&&(n.gradientRoles=nk("--roles",t.roles));try{m(await p("setBrandGradients",n,ek(`setBrandGradients:${e}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),Gm=new Fm("gradient").description("Brand gradient library commands").addCommand(rk);import{createHash as ik}from"crypto";import{Command as _t}from"commander";var ok=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function or(e){ok.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ak(e,t=[]){return[...t,e]}function ba(e){return ik("sha256").update(e).digest("hex").slice(0,32)}function ya(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 ha(e,t){try{return JSON.parse(t)}catch{a(`${e} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}var sk=new _t("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 w(),or(e);try{m(await p("getBrandGuardrails",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),dk=new _t("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(e,t)=>{await w(),or(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 p("testBrandGuardrails",n);m(r),r.passed===!1&&process.exit(s.GENERAL_ERROR)}catch(r){a(u(r,"Test failed")),process.exit(s.GENERAL_ERROR)}}),ck=new _t("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("--kind <kind>","deterministic | semantic; defaults to deterministic. Semantic rules can only warn or shadow").option("--semantic <json>",`Plain-English rule for --kind semantic, as JSON, e.g. '{"rule":"no unexplained acronyms"}'`).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(e,t)=>{await w(),or(e),(!t.name||!t.category||!t.severity)&&(a("Pass --name, --category and --severity."),process.exit(s.INVALID_INPUT));let n=t.kind??"deterministic";n==="semantic"?t.semantic===void 0&&(a(`Pass --semantic, e.g. '{"rule":"no unexplained acronyms"}'.`),process.exit(s.INVALID_INPUT)):t.require===void 0&&(a(`Pass --require, e.g. '{"component":"banned-phrase"}'.`),process.exit(s.INVALID_INPUT));let r={brandId:e,category:t.category,kind:n,name:t.name,severity:t.severity,teamId:t.teamId};t.require!==void 0&&(r.require=ha("--require",t.require)),t.semantic!==void 0&&(r.semantic=ha("--semantic",t.semantic)),t.conditions!==void 0&&(r.conditions=ha("--conditions",t.conditions)),t.enabled!==void 0&&(r.enabled=ya("--enabled",t.enabled)),t.nodeKey!==void 0&&(r.nodeKey=t.nodeKey),t.notes!==void 0&&(r.notes=t.notes),t.slug!==void 0&&(r.slug=t.slug),t.publish!==void 0&&(r.publish=ya("--publish",t.publish));try{m(await p("setBrandGuardrail",r,ba(`setBrandGuardrail:${e}:${JSON.stringify(r)}`)))}catch(i){a(u(i,"Write failed")),process.exit(s.GENERAL_ERROR)}}),lk=new _t("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 w(),or(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.publish!==void 0&&(r.publish=ya("--publish",n.publish));try{m(await p("deleteBrandGuardrail",r,ba(`deleteBrandGuardrail:${e}:${t}`)))}catch(i){a(u(i,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),mk=new _t("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.",ak).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 w(),or(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 p("generateBrandGuardrails",n,ba(`generateBrandGuardrails:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await Uc(r.runId,t.teamId))}catch(r){a(u(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),pk=new _t("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 w();try{m(await R("generateBrandGuardrails",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Km=new _t("guardrails").description("Brand guardrail rule commands").addCommand(sk).addCommand(dk).addCommand(ck).addCommand(lk).addCommand(mk).addCommand(pk);import{randomUUID as uk}from"crypto";import{readFile as Wm}from"fs/promises";import{Command as gk}from"commander";var Jm=new gk("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 w();try{let n=await Wm(e,"utf8"),r=t.urlEvidence?JSON.parse(await Wm(t.urlEvidence,"utf8")):void 0,i=t.idempotencyKey??uk();m(await p("importBrandDesignMd",{designMd:n,name:t.name,teamId:t.teamId,url:t.url,urlExtractedRaw:r},i))}catch(n){a(u(n,"Import failed")),process.exit(s.GENERAL_ERROR)}});import{Command as zm,InvalidArgumentError as Hm}from"commander";var fk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function hk(e){if(!fk.test(e))throw new Hm("Expected a brand UUID from `mf branding list`.");return e}function yk(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>50)throw new Hm("--limit expects a whole number from 1 to 50.");return t}var bk=new zm("list").description("List recent safe job summaries for one brand").argument("<brand-id>","Brand UUID",hk).option("--limit <count>","Newest jobs to return, 1-50 (default: 20)",yk).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("listBrandJobs",{brandId:e,limit:t.limit,teamId:t.teamId}))}catch(n){a(u(n,"Brand job history failed")),process.exit(s.GENERAL_ERROR)}}),Xm=new zm("jobs").description("Inspect brand background activity").addCommand(bk);import{createHash as wk}from"crypto";import{Command as ut}from"commander";var vk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gt(e){vk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Pn(e){return wk("sha256").update(e).digest("hex").slice(0,32)}var Ym=new ut("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 w(),t.parent&&gt(t.parent);try{m(await p("createBrand",{name:e,parentBrandingId:t.parent,teamId:t.teamId}))}catch(n){a(u(n,"Create failed")),process.exit(s.GENERAL_ERROR)}}),Qm=new ut("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 w(),gt(e);let n=!t.off;try{m(await p("setBrandStar",{brandId:e,starred:n,teamId:t.teamId},Pn(`setBrandStar:${e}:${n}`)))}catch(r){a(u(r,"Star failed")),process.exit(s.GENERAL_ERROR)}});async function Ik(e,t){let n=await p("getBrandProfile",{brandId:e,teamId:t.teamId});return typeof n.name=="string"?n.name:e}var Zm=new ut("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 w(),gt(e),!t.yes&&process.stdin.isTTY){let n;try{n=await Ik(e,t)}catch(r){a(u(r,"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{m(await p("deleteBrand",{brandId:e,teamId:t.teamId},Pn(`deleteBrand:${e}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),wa="none",ep=new ut("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 "${wa}" to detach it`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),gt(e);let n=t.parent?.toLowerCase()===wa;t.parent!==void 0&&!n&&gt(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 ${wa} 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{m(await p("updateBrand",r,Pn(`updateBrand:${e}:${t.name??""}:${t.parent??""}`)))}catch(i){a(u(i,"Update failed")),process.exit(s.GENERAL_ERROR)}}),tp=new ut("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 w(),gt(e);try{m(await p("setDefaultBrand",{brandId:e,teamId:t.teamId},Pn(`setDefaultBrand:${e}`)))}catch(n){a(u(n,"Set default failed")),process.exit(s.GENERAL_ERROR)}}),np=new ut("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 w(),gt(e);try{let n=await U(t.teamId);m(await p("approveBrand",{brandId:e,teamId:n},Pn(`approveBrand:${n}:${e}`)))}catch(n){a(u(n,"Approve failed")),process.exit(s.GENERAL_ERROR)}}),rp=new ut("onboarding").description("Manage the brand onboarding review state").addCommand(new ut("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 w(),gt(e);try{let n=await U(t.teamId);m(await p("completeBrandOnboarding",{brandId:e,teamId:n},Pn(`completeBrandOnboarding:${n}:${e}`)))}catch(n){a(u(n,"Complete onboarding failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as va}from"crypto";import{existsSync as kk,readFileSync as xk}from"fs";import{basename as Rk}from"path";import{Command as pi}from"commander";import Ck from"ora";function Sk(e,t,n){return va("sha256").update(JSON.stringify([e,t,n??null])).digest("hex").slice(0,32)}var ip=new pi("logo").description("Upload primary, dark-background, and favicon logo files").addCommand(new pi("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 w();try{m(await p("listBrandLogos",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Logo list failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new pi("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 w(),n.yes||(a("Refusing to remove a logo candidate without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("removeBrandLogo",{brandId:e,logoUrl:t,teamId:n.teamId},n.idempotencyKey??Sk("removeBrandLogo",e,t)))}catch(r){a(u(r,"Logo removal failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new pi("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 w();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)),kk(t.file)||(a(`File not found: ${t.file}`),process.exit(s.INVALID_INPUT));let r=va("sha256").update(xk(t.file)).digest("hex"),i=t.idempotencyKey??va("sha256").update(`setBrandLogo:${t.teamId??"current"}:${e??"default"}:${n}:${r}`).digest("hex").slice(0,32),o=Ck({text:`Uploading ${Rk(t.file)}...`,stream:process.stderr}).start(),c;try{c=(await ie(t.file,{idempotencyKey:`${i}:upload`,storagePrefix:"brand-logos"})).url,o.succeed("Uploaded")}catch(l){o.fail("Upload failed"),a(u(l)),process.exit(s.GENERAL_ERROR)}try{m(await p("setBrandLogo",{brandId:e,fileUrl:c,teamId:t.teamId,variant:n},i))}catch(l){a(u(l,"Write failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as Ek,randomUUID as Pk}from"crypto";import{Command as An,InvalidArgumentError as ui}from"commander";var Ak=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Tk=["admin","editor","viewer"],op=["cancelled","completed","failed","info","queued","running"],ap=["activity","brand-extraction-request","brand-resolution","brand-sync-job"];function jt(e){return t=>{if(!Ak.test(t))throw new ui(`${e} expects a UUID from \`mf branding list\` or the workspace member list.`);return t}}function dp(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>200)throw new ui("--limit expects a whole number from 1 to 200.");return t}function sp(e,t){return n=>{let r=n.split(",").map(o=>o.trim()).filter(Boolean);if(r.find(o=>!t.includes(o))||r.length===0)throw new ui(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function cp(e,t){return Ek("sha256").update(JSON.stringify([e,t,Pk()])).digest("hex").slice(0,32)}function ar(e,t){a(u(e,t)),process.exit(typeof e=="object"&&e!==null&&"exitCode"in e&&typeof e.exitCode=="number"?e.exitCode:s.GENERAL_ERROR)}var Ok=new An("list").description("List explicit member access overrides for one team brand").argument("<brand-id>","Team brand UUID",jt("brand-id")).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("listBrandPermissions",{brandId:e,teamId:t.teamId}))}catch(n){ar(n,"Brand permission list failed")}}),$k=new An("candidates").description("List member IDs eligible for one team brand's access overrides").argument("<brand-id>","Team brand UUID",jt("brand-id")).option("--query <text>","Search member name, username, or email").option("--limit <count>","Maximum members, 1-200 (default: 50)",dp).option("--offset <count>","Members to skip (default: 0)",e=>{let t=Number(e);if(!Number.isInteger(t)||t<0)throw new ui("--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 w();try{m(await p("listBrandPermissionCandidates",{brandId:e,limit:t.limit,offset:t.offset,query:t.query,teamId:t.teamId}))}catch(n){ar(n,"Brand permission candidate list failed")}}),Dk=new An("set").description("Set one team member's explicit role for a team brand").argument("<brand-id>","Team brand UUID",jt("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",jt("--user")).requiredOption("--role <role>","Desired override: admin | editor | viewer",b("--role",Tk)).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 w();try{m(await p("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId,userId:t.user},t.idempotencyKey??cp("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId??null,userId:t.user})))}catch(n){ar(n,"Brand permission update failed")}}),Nk=new An("remove").description("Remove one member override so the team role applies again").argument("<brand-id>","Team brand UUID",jt("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",jt("--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 w(),t.yes||(a("Refusing to remove a brand access override without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("removeBrandPermission",{brandId:e,teamId:t.teamId,userId:t.user},t.idempotencyKey??cp("removeBrandPermission",{brandId:e,teamId:t.teamId??null,userId:t.user})))}catch(n){ar(n,"Brand permission removal failed")}}),lp=new An("permission").description("Administer explicit member access overrides for a team brand").addCommand($k).addCommand(Ok).addCommand(Dk).addCommand(Nk),mp=new An("activity").description("Read a brand's filtered, cursor-paginated activity feed").argument("<brand-id>","Brand UUID",jt("brand-id")).option("--query <text>","Search action, summary, detail, entity, and metadata").option("--status <statuses>",`Comma-separated statuses: ${op.join(" | ")}`,sp("--status",op)).option("--source-type <types>",`Comma-separated sources: ${ap.join(" | ")}`,sp("--source-type",ap)).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)",dp).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 w();try{m(await p("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){ar(n,"Brand activity read failed")}});import{createHash as Lk}from"crypto";import{Command as qt,InvalidArgumentError as ka}from"commander";var Uk=/^[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 Ia(e,t){if(Uk.test(e))return e;throw new ka(`${t} must be a UUID.`)}function _k(e){let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=50)return t;throw new ka("limit must be a whole number from 1 to 50.")}function jk(e){let t=Number(e);if(Number.isInteger(t)&&t>=0)return t;throw new ka("offset must be a whole number of 0 or more.")}function qk(e){return Lk("sha256").update(e).digest("hex").slice(0,32)}async function sr(e,t){await w();try{m(await e())}catch(n){a(u(n,t)),process.exit(s.GENERAL_ERROR)}}var pp=new qt("presentations").description("Inspect presentations already linked to a brand").addCommand(new qt("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)",_k,50).option("--offset <n>","Zero-based offset (default 0)",jk,0).option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{let n=Ia(e,"brand-id");await sr(()=>p("listBrandPresentations",{brandId:n,limit:t.limit,offset:t.offset,teamId:t.teamId}),"Could not list linked presentations")})),up=new qt("presentation").description("Inspect or update one deck from its already-linked brand").addCommand(new qt("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 sr(()=>p("getPresentationBrandDrift",{presentationId:e,teamId:t.teamId}),"Could not read presentation brand drift")})).addCommand(new qt("guardrails").description("Check the saved version against its linked brand's guardrail rules").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{await sr(()=>p("checkPresentationGuardrails",{presentationId:e,teamId:t.teamId}),"Could not check presentation guardrails")})).addCommand(new qt("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 sr(()=>p("applyPresentationBrandChanges",{presentationId:e,teamId:t.teamId},t.idempotencyKey),"Could not apply linked-brand changes")})),gp=new qt("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=Ia(e,"brand-id"),i=Ia(t,"run-id");await sr(()=>p("cancelBrandPresentationSync",{brandId:r,runId:i,teamId:n.teamId},qk(`cancelBrandPresentationSync:${r}:${i}`)),"Could not cancel brand sync")});import{createHash as Mk,randomUUID as bp}from"crypto";import{Command as ft}from"commander";var Vk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,fp=["product","service","platform","solution"],gi=["candidate","draft","approved"],hp=["brand-site","brand-site-scan","brand-site-extract","product-url"];function Tn(e){Vk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function fi(e,t,n){if(n.includes(t))return t;a(`${e} must be one of: ${n.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Fk(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 xa(e){return Mk("sha256").update(e).digest("hex").slice(0,32)}var Bk=new ft("list").description("List the products a brand sells").argument("<brand-id>","Brand profile ID").option("--status <status>",`Only products in this state. One of: ${gi.join(", ")}. Omit for the saved catalogue.`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Tn(e),t.status!==void 0&&fi("--status",t.status,gi);let n={brandId:e,teamId:t.teamId};t.status!==void 0&&(n.status=t.status);try{m(await p("listBrandProducts",n))}catch(r){a(u(r,"List failed")),process.exit(s.GENERAL_ERROR)}}),Gk=new ft("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: ${fp.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: ${gi.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 w(),Tn(e),t.type!==void 0&&fi("--type",t.type,fp),t.status!==void 0&&fi("--status",t.status,gi),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{m(await p("saveBrandProduct",n,xa(`saveBrandProduct:${e}:${t.product??t.url??t.name??"new"}`)))}catch(r){a(u(r,"Save failed")),process.exit(s.GENERAL_ERROR)}}),yp=(e,t=[])=>[...t,e],Kk=new ft("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.",yp).option("--approve <id>","Product from --product that should finish approved; repeat as needed. Others finish draft.",yp).option("--idempotency-key <key>","Stable retry key for this selection").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Tn(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{m(await p("setBrandProductSelection",n,t.idempotencyKey??bp()))}catch(r){a(u(r,"Selection failed")),process.exit(s.GENERAL_ERROR)}}),Wk=new ft("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 w(),Tn(e);let n={brandId:e,productId:t.product,teamId:t.teamId};t.name!==void 0&&(n.name=t.name);try{m(await p("duplicateBrandProduct",n,t.idempotencyKey??bp()))}catch(r){a(u(r,"Duplicate failed")),process.exit(s.GENERAL_ERROR)}}),Jk=new ft("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 w(),Tn(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{m(await p("deleteBrandProduct",{brandId:e,productId:t.product,teamId:t.teamId},xa(`deleteBrandProduct:${e}:${t.product}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),zk=new ft("extract").description("Discover a brand's products by crawling its site").argument("<brand-id>","Brand profile ID").option("--mode <mode>",`One of: ${hp.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 w(),Tn(e),t.mode!==void 0&&fi("--mode",t.mode,hp);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=Fk("--max-products",t.maxProducts)),t.product?.length&&(n.productIds=t.product);try{let r=await p("extractBrandProducts",n,xa(`extractBrandProducts:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await Nc(r.runId,t.teamId))}catch(r){a(u(r,"Extract failed")),process.exit(s.GENERAL_ERROR)}}),Hk=new ft("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 w();try{m(await R("extractBrandProducts",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),wp=new ft("product").description("Brand product catalogue commands").addCommand(Bk).addCommand(Gk).addCommand(Kk).addCommand(Wk).addCommand(Jk).addCommand(zk).addCommand(Hk);import{randomUUID as Ca}from"crypto";import{Command as On}from"commander";import{randomUUID as Xk}from"crypto";import{Command as Ip}from"commander";function k(e,t){let n={...t},r=e.parent,i=!1;for(;r;){let o=r.opts?.();if(o){i=!0;for(let[c,l]of Object.entries(o))n[c]===void 0&&l!==void 0&&(n[c]=l)}r=r.parent}return i?n:t}function ce(e){return e._checkForMissingMandatoryOptions=function(){for(let t of this.options)t.mandatory&&this.getOptionValue(t.attributeName())===void 0&&this.missingMandatoryOptionValue(t)},e}function vp(e){return e._checkForMissingMandatoryOptions=function(){let t=k(this,this.opts());for(let n of this.options)n.mandatory&&t[n.attributeName()]===void 0&&this.missingMandatoryOptionValue(n)},e}var Ra="listenBrandPronunciations";function kp(e){let t=zn(e);if(t)throw Object.assign(new P(t,500),{[pn]:!0});let n=e.output;if(typeof n?.brandId!="string"||!Array.isArray(n.items))throw new P("Pronunciation listening completed without its audio list.",500);let r=n.items.map(i=>{if(!i||typeof i!="object"||!("word"in i)||typeof i.word!="string"||!("audioUrl"in i)||typeof i.audioUrl!="string")throw new P("Pronunciation listening returned an invalid audio entry.",500);return{word:i.word,audioUrl:i.audioUrl}});m({brandId:n.brandId,items:r})}function xp(e,t=""){a(`${u(e,"Pronunciation listening failed")}${t}`);let n=e&&typeof e=="object"&&"exitCode"in e?e.exitCode:void 0;process.exit(typeof n=="number"?n:s.GENERAL_ERROR)}var Yk=new Ip("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(e,t,n)=>{let r=k(n,t);await w();try{let i=await R(Ra,e,r.teamId);i.done?kp(i):m(i)}catch(i){xp(i)}}),Rp=new Ip("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").addCommand(Yk).action(async(e,t)=>{let n;try{if(!e)throw new P("Brand ID is required to start listening.",400,s.INVALID_INPUT);if(t.words!==void 0)try{n=JSON.parse(t.words)}catch{throw new P("--words must be valid JSON.",400,s.INVALID_INPUT)}}catch(o){a(u(o,"Invalid pronunciation listening input.")),process.exit(s.INVALID_INPUT);return}await w();let r=t.idempotencyKey??Xk(),i;try{let o=await p(Ra,{brandId:e,...t.words!==void 0?{words:n}:{},...t.voiceId!==void 0?{voiceId:t.voiceId}:{},teamId:t.teamId},r);if(i=o.runId,t.wait===!1){m(o);return}kp(await z(Ra,i,t.teamId))}catch(o){xp(Object.assign(new P(oe(o,i),500),{exitCode:o&&typeof o=="object"&&"exitCode"in o?o.exitCode:void 0}),un(o)?"":`${Ee(o,r)}${i?` Recover with branding pronunciation listen status ${i}.`:""}`)}});async function dr(e,t,n){await w();try{m(await p(e,t,n))}catch(r){a(u(r,"Pronunciation command failed"));let i=r&&typeof r=="object"&&"exitCode"in r?r.exitCode:void 0;process.exit(typeof i=="number"?i:s.GENERAL_ERROR)}}var Qk=new On("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(e,t)=>{await dr("listBrandPronunciations",{brandId:e,teamId:t.teamId})}),Zk=new On("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(e,t,n)=>{await dr("getBrandPronunciation",{brandId:e,word:t,teamId:n.teamId})}),ex=new On("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(e,t,n)=>{await dr("setBrandPronunciation",{brandId:e,word:t,pronunciation:n.pronunciation,teamId:n.teamId},n.idempotencyKey??Ca())}),tx=new On("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(e,t,n)=>{await dr("deleteBrandPronunciation",{brandId:e,word:t,teamId:n.teamId},n.idempotencyKey??Ca())}),nx=new On("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(e,t)=>{let n;try{n=JSON.parse(t.rules??"")}catch{a("--rules must be valid JSON."),process.exit(s.INVALID_INPUT);return}await dr("setBrandPronunciations",{brandId:e,rules:n,teamId:t.teamId},t.idempotencyKey??Ca())}),Cp=new On("pronunciation").description("Manage the words and spoken forms in a brand's pronunciation dictionary").addCommand(Qk).addCommand(Zk).addCommand(ex).addCommand(nx).addCommand(tx).addCommand(Rp);import{createHash as rx}from"crypto";import{Command as hi}from"commander";var ix=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Sp(e){ix.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ox(e,t=[]){return[...t,e]}function ax(e){return rx("sha256").update(e).digest("hex").slice(0,32)}var sx=new hi("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 w(),Sp(e);try{m(await p("getBrandQuality",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),dx=new hi("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.",ox).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 w(),Sp(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 p("repairBrandQuality",n,ax(`repairBrandQuality:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await _c(r.runId,t.teamId))}catch(r){a(u(r,"Repair failed")),process.exit(s.GENERAL_ERROR)}}),cx=new hi("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 w();try{m(await R("repairBrandQuality",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Ep=new hi("quality").description("Brand deck quality commands").addCommand(sx).addCommand(dx).addCommand(cx);function Sa(e){return Array.isArray(e.items)}function ot(e){return typeof e=="string"&&e.length>0?e:void 0}function Ea(e){return ot(e.resolvedTokens?.logoUrl)??ot(e.brandData?.assets?.logo)??ot(e.brandData?.assets?.logoUrl)??ot(e.brandData?.logoUrl)}function Pa(e){return ot(e.resolvedTokens?.colors?.primary)??ot(e.brandData?.colors?.primary)??ot(e.brandData?.enhancedColors?.palette?.[0]?.hex)}function Pp(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:i,role:o}=r;typeof i=="string"&&n.push({hex:i,...typeof o=="string"?{role:o}:{}})}}return n}function lx(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 mx(e){let t=ot(e.extractedFrom)??ot(e.normalizedUrl),n=Ea(e),r=Pa(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 Ap(e){return Sa(e)?e.items.map(mx):e.brandings.map(lx)}import{createHash as px}from"crypto";import{Command as yt,InvalidArgumentError as ux}from"commander";var gx=["x","instagram","facebook","linkedin","tiktok","youtube"],fx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ht(e){if(!fx.test(e))throw new ux("Expected a UUID returned by the corresponding list command.");return e}function yi(e,t){return px("sha256").update(JSON.stringify([e,...t])).digest("hex")}function $n(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var hx=new yt("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",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await w();try{m(await p("getBrandCompetitors",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){$n(t,"Competitor list failed")}}),yx=new yt("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",ht).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 w();let n={brandingId:t.brandingId,name:e,resolveHandle:t.resolveHandle,teamId:t.teamId,website:t.website,xAvatarUrl:t.xAvatarUrl,xHandle:t.xHandle};try{m(await p("addCompetitor",n,yi("addCompetitor",[t.brandingId??"default",e.trim(),t.website??null,t.xHandle??null,t.xAvatarUrl??null,t.resolveHandle])))}catch(r){$n(r,"Competitor write failed")}}),bx=new yt("delete").description("Remove one competitor by the stable ID from competitor list").argument("<competitor-id>","Competitor UUID",ht).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await w(),t.yes||(a("Refusing to remove a competitor without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandCompetitor",{brandingId:t.brandingId,competitorId:e,teamId:t.teamId},yi("deleteBrandCompetitor",[t.brandingId??"default",e])))}catch(n){$n(n,"Competitor removal failed")}}),Tp=new yt("competitor").description("List, add, update, or remove a brand's competitor watch rows").addCommand(hx).addCommand(yx).addCommand(bx),wx=new yt("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",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await w();try{m(await p("listBrandSocialHandles",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){$n(t,"Social-account list failed")}}),vx=new yt("add").description("Record one social account and print its stable saved row").argument("<platform>","Social network: x | instagram | facebook | linkedin | tiktok | youtube",b("platform",gx)).argument("<handle>","Account handle on that social network").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t,n)=>{await w();try{m(await p("addBrandSocialHandle",{brandingId:n.brandingId,handle:t,platform:e,teamId:n.teamId},yi("addBrandSocialHandle",[n.brandingId??"default",e,t.replace(/^@/,"")])))}catch(r){$n(r,"Social-account write failed")}}),Ix=new yt("delete").description("Remove one social account by the stable ID from social list").argument("<handle-id>","Social-handle UUID",ht).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await w(),t.yes||(a("Refusing to remove a social account without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandSocialHandle",{brandingId:t.brandingId,handleId:e,teamId:t.teamId},yi("deleteBrandSocialHandle",[t.brandingId??"default",e])))}catch(n){$n(n,"Social-account removal failed")}}),Op=new yt("social").description("List, record, or remove the social accounts owned by a brand").addCommand(wx).addCommand(vx).addCommand(Ix);import{createHash as kx}from"crypto";import{Command as $p}from"commander";var xx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Rx(e){xx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Cx(e){return kx("sha256").update(e).digest("hex").slice(0,32)}var Dp=new $p("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 w(),Rx(e);let n={brandId:e,teamId:t.teamId};try{let r=await p("syncBrandToPresentations",n,Cx(`syncBrandToPresentations:${e}`));if(t.wait===!1){m(r);return}m(await jc(r.runId,t.teamId))}catch(r){a(u(r,"Sync failed")),process.exit(s.GENERAL_ERROR)}}),Np=new $p("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 w();try{m(await R("syncBrandToPresentations",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Sx}from"crypto";import{readFile as Ex}from"fs/promises";import{Command as Lp}from"commander";var Px=["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 Ax(e){let t=e.split(".").filter(Boolean);for(let n=t.length;n>=2;n--){let r=t.slice(0,n).join(".");if(Px.includes(r))return{fieldPath:t.slice(n),nodeKey:r}}return{fieldPath:t.slice(2),nodeKey:t.slice(0,2).join(".")}}function Tx(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 i=n.slice(0,r).trim(),o=n.slice(r+1);if(i.split(".").filter(Boolean).length<2)throw new Error(`"${i}" is not a brand token key. Expected something like color.primary or typography.h1.size`);let{fieldPath:l,nodeKey:d}=Ax(i),g=Ox(o);if(l.length===0){t[d]=g;continue}let y=t[d],v=y&&typeof y=="object"&&!Array.isArray(y)?y:{},x=v;for(let T of l.slice(0,-1)){let L=x[T],$=L&&typeof L=="object"&&!Array.isArray(L)?L:{};x[T]=$,x=$}x[l[l.length-1]]=g,t[d]=v}return t}function Ox(e){return e==="true"?!0:e==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(e)?Number(e):e}function $x(e,t){return e===void 0?{assignments:[...t]}:e.includes("=")?{assignments:[e,...t]}:{assignments:[...t],brandId:e}}var Up=new Lp("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 p("getBrandProfile",{brandId:e,format:t.format,teamId:t.teamId});if(t.format==="md"&&typeof n.designMd=="string"){console.log(n.designMd);return}m(n)}catch(n){a(u(n,"Profile read failed")),process.exit(s.GENERAL_ERROR)}}),_p=new Lp("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:i}=$x(e,t),o;try{o=r.length>0?Tx(r):void 0}catch(l){a(u(l,"Invalid token pair")),process.exit(s.INVALID_INPUT)}let c;if(n.designMd)try{c=await Ex(n.designMd,"utf8")}catch(l){a(`Could not read ${n.designMd}: ${u(l)}`),process.exit(s.INVALID_INPUT)}!o&&!c&&(a("Nothing to write. Pass token assignments (color.primary=#114b97) or --design-md <file>."),process.exit(s.INVALID_INPUT));try{m(await p("updateBrandTokens",{brandId:i,designMd:c,publish:n.publish===!1?!1:void 0,teamId:n.teamId,tokens:o},Sx()))}catch(l){a(u(l,"Write failed")),process.exit(s.GENERAL_ERROR)}});import{createHash as Dx}from"crypto";import{Command as vi}from"commander";var Nx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,wi=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Ta(e){Nx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function jp(e){return Dx("sha256").update(e).digest("hex").slice(0,32)}function qp(e){if(wi.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${wi.join(", ")}.`),process.exit(s.INVALID_INPUT)}function bi(e){return e===""?null:e}function Aa(e,t){if(t==="")return null;let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${u(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 Lx(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 Ux(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 _x=new vi("list").description("List a brand's per-channel design variants").argument("<brand-id>","Brand profile ID").option("--channel <key>",`One of: ${wi.join(", ")}`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Ta(e),t.channel!==void 0&&qp(t.channel);try{m(await p("listBrandVariants",{brandId:e,channelKey:t.channel,teamId:t.teamId}))}catch(n){a(u(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),jx=new vi("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: ${wi.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 w(),Ta(e),t.channel!==void 0&&qp(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=Lx("--default",t.default)),t.colors!==void 0&&(n.colors=Aa("--colors",t.colors)),t.logoTreatment!==void 0&&(n.logoTreatment=Aa("--logo-treatment",t.logoTreatment)),t.backgroundGradient!==void 0&&(n.backgroundGradient=Aa("--background-gradient",t.backgroundGradient)),t.aspect!==void 0&&(n.aspect=bi(t.aspect)),t.maxSeconds!==void 0&&(n.maxSeconds=Ux(t.maxSeconds)),t.voiceTone!==void 0&&(n.voiceOverride=t.voiceTone===""?null:{tone:t.voiceTone}),t.openingStyle!==void 0&&(n.openingStyle=bi(t.openingStyle)),t.logoPosition!==void 0&&(n.logoPosition=bi(t.logoPosition)),t.constraints!==void 0&&(n.constraints=bi(t.constraints));try{m(await p("setBrandVariant",n,t.variant===void 0?void 0:jp(`setBrandVariant:${e}:${t.variant}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),qx=new vi("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 w(),Ta(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{m(await p("deleteBrandVariant",{brandId:e,teamId:t.teamId,variantId:t.variant},jp(`deleteBrandVariant:${e}:${t.variant}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Mp=new vi("variant").description("Per-channel brand design variant commands").addCommand(_x).addCommand(jx).addCommand(qx);import{createHash as Mx}from"crypto";import{Command as Da}from"commander";var Vx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Oa=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Fx(e){Vx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Bx(e){if(Oa.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${Oa.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Gx(e,t){let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${u(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 Kx(e){return Mx("sha256").update(e).digest("hex").slice(0,32)}var $a=["replace","append"];function Wx(e){if($a.includes(e))return e;a(`"${e}" is not a mode. Pass one of: ${$a.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Jx(e){let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=6)return t;a(`"${e}" is not a count. Pass a whole number from 1 to 6.`),process.exit(s.INVALID_INPUT)}var zx=new Da("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: ${Oa.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("--mode <mode>",`One of: ${$a.join(", ")}. append adds new variants and deletes nothing; replace (default) swaps the generated set`).option("--count <n>","With --mode append, add only the first N generated variants (1-6)").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),e!==void 0&&Fx(e),t.channel!==void 0&&Bx(t.channel),t.mode!==void 0&&Wx(t.mode);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.mode!==void 0&&(n.mode=t.mode),t.count!==void 0&&(n.count=Jx(t.count)),t.tone!==void 0&&(n.brandTone=t.tone),t.style!==void 0&&(n.brandStyle=t.style),t.colors!==void 0&&(n.sourceColors=Gx("--colors",t.colors));try{let r=await p("generateBrandVariations",n,Kx(`generateBrandVariations:${e??"preview"}:${t.channel??"deck-16-9"}${n.mode==="append"?`:append:${n.count??""}`:""}`));if(t.wait===!1){m(r);return}m(await Dc(r.runId,t.teamId))}catch(r){a(u(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),Hx=new Da("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 w();try{m(await R("generateBrandVariations",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Vp=new Da("variations").description("Generated brand design variations").addCommand(zx).addCommand(Hx);import{createHash as Xx}from"crypto";import{Command as Ii}from"commander";var Na=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function La(e){Na.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Yx(e,t){if(t==="head"||Na.test(t))return t;a(`${e} must be a version id or "head".`),process.exit(s.INVALID_INPUT)}function Qx(e,t){if(Na.test(t))return t;a(`${e} must be a version id from \`branding version list\`.`),process.exit(s.INVALID_INPUT)}function Zx(e){return Xx("sha256").update(e).digest("hex").slice(0,32)}var eR=new Ii("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 w(),La(e);try{m(await p("listBrandVersions",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),tR=new Ii("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 w(),La(e);let n={brandId:e,teamId:t.teamId};t.from!==void 0&&(n.from=Qx("--from",t.from)),t.to!==void 0&&(n.to=Yx("--to",t.to));try{m(await p("diffBrandVersions",n))}catch(r){a(u(r,"Diff failed")),process.exit(s.GENERAL_ERROR)}}),nR=new Ii("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 w(),La(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{m(await p("publishBrandVersion",n,Zx(`publishBrandVersion:${e}:${t.label??"auto"}`)))}catch(r){a(u(r,"Publish failed")),process.exit(s.GENERAL_ERROR)}}),Fp=new Ii("version").description("Brand version history commands").addCommand(eR).addCommand(tR).addCommand(nR);import{randomUUID as rR}from"crypto";import{Command as ki}from"commander";var iR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function _a(e){iR.test(e)||(a(`"${e}" is not a brand id.`),process.exit(s.INVALID_INPUT))}function Ua(e,t){try{return JSON.parse(e)}catch{a(`${t} must contain valid JSON.`),process.exit(s.INVALID_INPUT)}}function Gp(e){if(e===void 0)return;let t=Number(e);return(!Number.isInteger(t)||t<0)&&(a("--expected-revision must be a non-negative integer."),process.exit(s.INVALID_INPUT)),t}var oR=new ki("get").description("Read a brand's video voice, presenter and intro/outro defaults").argument("<brand-id>","Brand profile ID").action(async e=>{await w(),_a(e);try{m(await p("getBrandVideoDefaults",{brandId:e}))}catch(t){a(u(t,"Read failed")),process.exit(s.GENERAL_ERROR)}});function Bp(e,t,n){return new ki(e).description(`Replace a brand's saved video ${n}`).argument("<brand-id>","Brand profile ID").requiredOption(`--${n} <json>`,`The complete ${n} list as JSON`).option("--expected-revision <number>","Revision read before this write").action(async(r,i)=>{await w(),_a(r);let o=i[n],c={brandId:r,[n]:Ua(o,`--${n}`)},l=Gp(i.expectedRevision);l!==void 0&&(c.expectedRevision=l);try{m(await p(t,c))}catch(d){a(u(d,"Save failed")),process.exit(s.GENERAL_ERROR)}})}var aR=new ki("set-bookends").description("Set or clear a brand's default opening and closing card scenes").argument("<brand-id>","Brand profile ID").option("--intro-json <json>",'Opening scene as a JSON card object, e.g. {"kind":"image","imageSource":"brand-logo","title":"Acme","durationSeconds":6}').option("--outro-json <json>","Closing scene as a JSON card object").option("--clear-intro","Remove the default opening scene").option("--clear-outro","Remove the default closing scene").option("--expected-revision <number>","Revision read before this write").option("--idempotency-key <key>","Reuse a request key to retry this same write").action(async(e,t)=>{await w(),_a(e);let n=t.clearIntro?null:t.introJson===void 0?void 0:Ua(t.introJson,"--intro-json"),r=t.clearOutro?null:t.outroJson===void 0?void 0:Ua(t.outroJson,"--outro-json");n===void 0&&r===void 0&&(a("Provide --intro-json/--outro-json, or --clear-intro/--clear-outro."),process.exit(s.INVALID_INPUT));let i=Gp(t.expectedRevision);try{m(await p("setBrandVideoBookends",{brandId:e,...n!==void 0?{intro:n}:{},...r!==void 0?{outro:r}:{},...i!==void 0?{expectedRevision:i}:{}},t.idempotencyKey??rR()))}catch(o){a(u(o,"Save failed")),process.exit(s.GENERAL_ERROR)}}),Kp=new ki("video-defaults").description("Manage a brand's video voice, presenter and intro/outro defaults").addCommand(oR).addCommand(Bp("set-voices","setBrandVideoVoices","voices")).addCommand(Bp("set-presenters","setBrandVideoPresenters","presenters")).addCommand(aR);import{createHash as sR}from"crypto";import{Command as cr}from"commander";var dR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function qa(e){dR.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ja(e,t=[]){return[...t,e]}function Wp(e){return sR("sha256").update(e).digest("hex").slice(0,32)}var cR=new cr("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 w(),qa(e);try{m(await p("getBrandVoice",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),lR=new cr("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 w(),qa(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{m(await p("setBrandVoice",n,Wp(`setBrandVoice:${e}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Write failed")),process.exit(s.GENERAL_ERROR)}}),mR=new cr("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",ja).option("--text <text>","Pasted source material; repeat for several",ja).option("--file <name:source>","Document to read, as name:source; repeat for several",ja).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),qa(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 i=r.indexOf(":");return(i<=0||i===r.length-1)&&(a(`--file must be name:source; got "${r}".`),process.exit(s.INVALID_INPUT)),{name:r.slice(0,i),source:r.slice(i+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 p("buildBrandVoice",n,Wp(`buildBrandVoice:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await Lc(r.runId,t.teamId))}catch(r){a(u(r,"Build failed")),process.exit(s.GENERAL_ERROR)}}),pR=new cr("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 w();try{m(await R("buildBrandVoice",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Jp=new cr("voice").description("Brand voice and context commands").addCommand(cR).addCommand(lR).addCommand(mR).addCommand(pR);function yR(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new zp(`${e} expects a whole number of 0 or more.`);return n}}function bR(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new zp(`${e} expects a whole number of 1+.`);return n}}var wR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,vR=50;function IR(e){let t=e.extractedFrom??e.normalizedUrl??null,n=Pa(e),r=Pp(e),i=Ea(e);if(De("Brand Profile"),console.log(),O("ID",e.id),O("Name",e.name),O("Source URL",t??Z.gray("None")),O("Default",e.isDefault?Z.green("Yes"):"No"),e.createdAt&&O("Created",new Date(e.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 y of r.slice(0,10)){let v=y.role?Z.gray(` (${y.role})`):"";console.log(` ${Z.bgHex(y.hex)(" ")} ${y.hex}${v}`)}}console.log()}i&&(console.log(Z.bold(" Logo")),console.log(` ${i}`),console.log());let o=e.brandData?.typography,c=e.resolvedTokens?.headingFont??o?.primary??o?.headings,l=e.resolvedTokens?.bodyFont??o?.secondary??o?.body;(c||l)&&(console.log(Z.bold(" Typography")),console.log(` Headings: ${c??"-"}`),console.log(` Body: ${l??"-"}`),console.log());let d=e.brandData?.confidence,g=e.brandData?.extractionMethod;(typeof d=="number"||typeof g=="string")&&(console.log(Z.bold(" Extraction")),typeof d=="number"&&console.log(` Confidence: ${Math.round(d*100)}%`),typeof g=="string"&&console.log(` Method: ${g}`),console.log()),console.log(Z.gray(" Use --format json for full details")),console.log()}var Hp=new Dn("branding").description("Read and manage workspace brands, design rules, assets, permissions, and social presence").addCommand(Up).addCommand(_p).addCommand(Pm).addCommand(jm).addCommand(lp).addCommand(mp).addCommand(Xm).addCommand(new Dn("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)",b("--filter",["all","mine","team"])).option("--sort <sort>","Sort key (created, name, updated)",b("--sort",["created","name","updated"])).option("--shape <shape>","Result shape: list (paged rows, default) or chat (compact matches)",b("--shape",["chat","list"])).option("--limit <n>","Page size (server default: 12 for the list shape, 50 for chat)",bR("--limit")).option("--offset <n>","Brands to skip before the page",yR("--offset")).option("--team-id <id>","Workspace ID").option("--json","Print the complete JSON response instead of a table").action(async e=>{await w();try{let t=e.shape??"list",n=await p("listBrandings",{filter:e.filter,limit:e.limit,offset:e.offset,search:e.search,shape:t,sort:e.sort,teamId:e.teamId});if(e.json){m(n);return}let r=Ap(n);if(r.length===0){I("No brand profiles found"),console.log(),console.log(Z.gray(`Create one with: ${f.commands[0]} branding extract <url>`));return}console.log(dl(r));let i=e.offset??0;Sa(n)?n.hasMore&&console.log(Z.gray(` ${i+r.length} of ${n.total}. Next page: --offset ${i+r.length}`)):r.length>=(e.limit??vR)&&console.log(Z.gray(` Showing ${r.length} from --offset ${i}; there may be more. Next page: --offset ${i+r.length}`))}catch(t){a("The command failed. Please try again."),process.exit(t.exitCode??1)}})).addCommand(new Dn("get").description("Read one brand as a summary or complete JSON").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)",b("--format",["summary","json"]),"summary").option("-o, --output <path>","Save JSON to file").option("--team-id <id>","Workspace ID").action(async(e,t)=>{if(await w(),!wR.test(e)){a(`"${e}" is not a brand id. Pass the UUID from \`${f.commands[0]} branding list\`, or search by name with \`${f.commands[0]} branding find <query>\`.`),process.exit(s.INVALID_INPUT);return}try{let r=(await p("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 fR(t.output,JSON.stringify(r,null,2)),C(`Brand profile saved to ${t.output}`);return}if(t.format==="json"){console.log(JSON.stringify(r,null,2));return}IR(r)}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Dn("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 w();try{let r=(await p("listBrandings",{search:e,shape:"chat",teamId:t.teamId})).brandings;if(r.length===0){I(`No brand profiles matching "${e}"`),console.log(Z.gray(` Extract one with: ${f.commands[0]} branding extract <url>`));return}console.log(`Found ${r.length} brand${r.length>1?"s":""}:
78
- `);for(let i of r){let o=i.primaryColor?`${Z.bgHex(i.primaryColor)(" ")} ${i.primaryColor}`:"";console.log(` ${Z.bold(i.name)} ${Z.gray(i.id)}`),i.domain&&console.log(` ${Z.gray(i.domain)}`),o&&console.log(` ${o}`),console.log()}console.log(Z.gray(` Export with: ${f.commands[0]} branding get <id> -o branding.json`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Dn("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(e,t)=>{await w(),t.yes||(a("Pass --yes to confirm brand extraction."),process.exit(s.INVALID_INPUT));try{new URL(e.startsWith("http")?e:`https://${e}`)}catch{a("Invalid URL format"),process.exit(6)}let n=e.startsWith("http")?e:`https://${e}`,r=t.teamId??ve(),i=t.idempotencyKey??uR();t.approvalReceipt&&t.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let o=t.approvalReceiptStdin?gR(0,"utf8").trim():t.approvalReceipt;t.approvalReceiptStdin&&!o&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let c=hR({text:`Extracting branding from ${n}...`,stream:process.stdout}).start(),l;try{let d=await dc(n,r,o,t.skipExistingLookup,i);if(d.status==="needs_choice"){c.stop(),I(`This workspace already has ${d.matches.length} related brand${d.matches.length===1?"":"s"} for ${n}. Nothing was extracted and nothing was charged.`),console.log();for(let g of d.matches)console.log(` ${Z.bold(g.name??"Untitled")}`),console.log(` ${Z.gray(g.id)}`),g.extractedFrom&&console.log(` ${Z.gray(g.extractedFrom)}`);console.log(),I(`Use one of the above, or re-run with --skip-existing-lookup to extract ${n} anyway.`),l=s.INVALID_INPUT}else c.succeed("Brand extraction started"),console.log(JSON.stringify(d,null,2)),I(`Check progress with: ${f.commands[0]} branding status ${d.runId}`),console.log()}catch(d){let g=u(d);g.includes("approval")&&(c.stop(),a(g),console.log(),I(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${i}`),process.exit(s.INVALID_INPUT)),c.fail("Extraction failed"),a(g),process.exit(d.exitCode??1)}l!==void 0&&process.exit(l)})).addCommand(new Dn("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(e,t)=>{try{m(await R("extractBranding",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(Ym).addCommand(Jm).addCommand(ep).addCommand(Qm).addCommand(tp).addCommand(np).addCommand(rp).addCommand(Zm).addCommand(Tp).addCommand(ip).addCommand(Mm).addCommand(Vm).addCommand(Gm).addCommand(wp).addCommand(Mp).addCommand(Vp).addCommand(Fp).addCommand(Jp).addCommand(Kp).addCommand(Km).addCommand(Lm).addCommand(Um).addCommand(Cp).addCommand(Ep).addCommand(pp).addCommand(up).addCommand(Dp).addCommand(Np).addCommand(gp).addCommand(Op);import lr from"chalk";import{Command as Nn}from"commander";function kR(e){switch(e.background){case"color":{if(!e.backgroundColor)throw new Error("--background color needs --background-color <hex>, e.g. #1d4ed8");return{hex:e.backgroundColor,kind:"color"}}case"image":{if(!e.backgroundImage)throw new Error("--background image needs --background-image <url>");return{fit:e.fit,kind:"image",url:e.backgroundImage}}default:return{kind:e.background}}}function Xp(e,t){return{background:kR(t),name:e,presenterProfileId:t.presenter,...t.voiceId?{voiceId:t.voiceId}:{}}}function xi(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.id);return}C(`${e.name} (${e.id})`),I(` Presenter: ${e.presenterProfileId}`),I(` Backdrop: ${xR(e.background)}`),e.voiceId&&I(` Voice: ${e.voiceId}`)}function xR(e){switch(e.kind){case"color":return`color ${e.hex}`;case"image":return`image ${e.url} (${e.fit})`;default:return e.kind}}function Yp(e){return e.requiredOption("--presenter <profileId>",`Trained personal presenter id (pp_*), from \`${f.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",b("--format",["human","json","quiet"]),"human")}var RR=new Nn("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await tl({...e.brandingId?{brandingId:e.brandingId}:{},...e.castMemberId?{castMemberId:e.castMemberId}:{},...e.teamId?{teamId:e.teamId}:{}});if(e.format==="json"){m(t);return}if(e.format==="quiet"){for(let n of t.presets)console.log(n.id);return}if(t.presets.length===0){I("No presets saved yet.");return}for(let n of t.presets)xi(n,"human")}catch(t){a(u(t)),process.exit(s.API_ERROR)}}),CR=Yp(new Nn("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(e,t)=>{try{let n=await nl({castMemberId:t.castMemberId,...Xp(e,t),...t.teamId?{teamId:t.teamId}:{}});xi(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),SR=Yp(new Nn("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(e,t)=>{try{let n=await rl({presetId:e,...Xp(t.name,t),...t.teamId?{teamId:t.teamId}:{}});xi(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),ER=new Nn("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await il(e,t.teamId);if(t.format==="human"){C(`Retired "${n.preset.name}".`);return}xi(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),PR=new Nn("preset").description("Saved ways a cast member appears").addCommand(RR).addCommand(CR).addCommand(SR).addCommand(ER),Ma=new Nn("cast").description("The faces and voices your videos can use").addCommand(PR);Ma.addHelpText("after",`
79
- ${lr.bold("Examples:")}
80
- ${lr.gray("# List the saved presenter/backdrop/voice combinations")}
77
+ `);import{randomUUID as hR}from"crypto";import{readFileSync as yR}from"fs";import{writeFile as bR}from"fs/promises";import Z from"chalk";import{Command as Dn,InvalidArgumentError as Xp}from"commander";import wR from"ora";import{createHash as fI}from"crypto";import{Command as ir,InvalidArgumentError as rr}from"commander";import{createHash as iI}from"crypto";import{existsSync as oI,readFileSync as aI}from"fs";import{basename as sI}from"path";import{Command as dI,InvalidArgumentError as tr}from"commander";import cI from"ora";import{createHash as Zv}from"crypto";import{Command as eI,InvalidArgumentError as Cm}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(e){if(!tI.test(e))throw new Cm("brand-id expects a UUID from `mf branding list`.");return e}function rI(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new Cm("--file-size expects the exact positive whole-number byte size.");return t}async function ua(e){let{idempotencyKey:t,...n}=e;return p("createBrandAssetUploadUrl",n,t)}function pa(e){if(e===void 0)return"";if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(pa).join(",")}]`;let t=e;return`{${Object.keys(t).filter(n=>t[n]!==void 0).sort().map(n=>`${JSON.stringify(n)}:${pa(t[n])}`).join(",")}}`}function ga(e){return Zv("sha256").update(`createBrandAssetUploadUrl:${pa(e)}`).digest("hex").slice(0,32)}var Sm=new eI("upload-url").description("Mint a short-lived brand-scoped storage POST; this does not upload bytes").argument("<brand-id>","Brand UUID you may manage",nI).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",rI).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 w();try{m(await ua({brandId:e,...t,idempotencyKey:t.idempotencyKey??ga({brandId:e,fileName:t.fileName,fileSize:t.fileSize,fileType:t.fileType})}))}catch(n){a(u(n,"Brand asset upload URL creation failed")),process.exit(s.GENERAL_ERROR)}});var lI=["footage","image","before_after","logo","audio"],mI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function pI(e){if(!mI.test(e))throw new tr("brand-id expects a UUID from `mf branding list`.");return e}function Em(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new tr(`${e} expects a whole number of 0 or more.`);return n}}function uI(e){let t=Number(e);if(!Number.isFinite(t)||t<0)throw new tr("--duration-sec expects a number of 0 or more.");return t}function gI(e){let t;try{t=JSON.parse(e)}catch{throw new tr("--metadata expects valid JSON.")}if(!t||typeof t!="object"||Array.isArray(t))throw new tr("--metadata expects a JSON object.");return t}var Pm=new dI("upload").description("Upload one local file, register it on a brand, and print the asset JSON").argument("<brand-id>","Brand UUID",pI).requiredOption("--file <path>","Local file to upload through Mindframes storage").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",b("--kind",lI)).option("--label <text>","Display label; defaults to the local filename").option("--width <px>","Image or video width in pixels",Em("--width")).option("--height <px>","Image or video height in pixels",Em("--height")).option("--duration-sec <n>","Audio or video duration in seconds",uI).option("--set-key <key>","Pair key; required when --kind before_after").option("--role <role>","Pair role: before | after; required when --kind before_after",b("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',gI).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 w(),oI(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=iI("sha256").update(aI(t.file)).digest("hex"),r=et(t.file),i={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},o=t.idempotencyKey??ga(i),c=cI({text:`Uploading ${sI(t.file)}...`,stream:process.stderr}).start();try{let l=await ua({brandId:e,...r,idempotencyKey:o,teamId:t.teamId}),d=await tt(t.file,l);c.succeed("Uploaded"),m(await p("registerBrandAsset",{brandId:e,durationSec:t.durationSec,height:t.height,kind:t.kind,label:i.label,metadata:t.metadata,mimeType:d.type,role:t.role,s3Key:d.s3Key,setKey:t.setKey,sizeBytes:d.size,teamId:t.teamId,url:d.url,width:t.width},o))}catch(l){c.fail("Asset upload failed"),a(u(l,"Asset upload failed")),process.exit(s.GENERAL_ERROR)}});var Am=["footage","image","before_after","logo","audio"],hI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cn(e){return t=>{if(!hI.test(t))throw new rr(`${e} expects a UUID from \`mf branding list\` or \`mf branding asset list\`.`);return t}}function nr(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<t)throw new rr(`${e} expects a whole number from ${t} upward.`);return r}}function yI(e){return t=>{let n=Number(t);if(!Number.isFinite(n)||n<0)throw new rr(`${e} expects a number of 0 or more.`);return n}}function bI(e){let t;try{t=JSON.parse(e)}catch(n){throw new rr(`--metadata expects JSON: ${u(n)}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new rr("--metadata expects a JSON object.");return t}function fa(e){return fI("sha256").update(e).digest("hex").slice(0,32)}function ci(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var wI=new ir("list").description("List one brand's uploaded assets and print stable asset IDs").argument("<brand-id>","Brand UUID",Cn("brand-id")).option("--kind <kind>","Filter: footage | image | before_after | logo | audio",b("--kind",Am)).option("--limit <count>","Caller-selected page size; omit to return every matching asset",nr("--limit",1)).option("--offset <count>","Matching assets to skip before returning results (default: 0)",nr("--offset",0)).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("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){ci(n,"Asset list failed")}}),vI=new ir("register").description("Register one app-owned upload from its exact URL, key, MIME, and metadata").argument("<brand-id>","Brand UUID",Cn("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",b("--kind",Am)).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",nr("--size-bytes",0)).option("--width <px>","Image or video width in pixels",nr("--width",0)).option("--height <px>","Image or video height in pixels",nr("--height",0)).option("--duration-sec <n>","Audio or video duration in seconds",yI("--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",b("--role",["before","after"])).option("--metadata <json>",'Optional metadata JSON: {"pairLabel":"Summer","source":"upload"}',bI).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 w(),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??fa(`registerBrandAsset:${JSON.stringify(n)}`);try{m(await p("registerBrandAsset",n,r))}catch(i){ci(i,"Asset registration failed")}}),II=new ir("rename").description("Rename one asset, then print its stored label and metadata").argument("<asset-id>","Asset UUID from `mf branding asset list`",Cn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Cn("--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 w();let n=t.label.trim();n||(a("--label cannot be empty."),process.exit(s.INVALID_INPUT));try{m(await p("renameBrandAsset",{assetId:e,brandId:t.brand,label:n,teamId:t.teamId},t.idempotencyKey??fa(`renameBrandAsset:${e}:${n}`)))}catch(r){ci(r,"Asset rename failed")}}),kI=new ir("delete").description("Remove one asset record from the brand while keeping its uploaded file").argument("<asset-id>","Asset UUID from `mf branding asset list`",Cn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Cn("--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 w(),t.yes||(a("Refusing removal from the brand library without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandAsset",{assetId:e,brandId:t.brand,teamId:t.teamId},t.idempotencyKey??fa(`deleteBrandAsset:${e}`)))}catch(n){ci(n,"Asset deletion failed")}}),Tm=new ir("asset").description("List, upload, rename, and remove a brand's private asset library").addCommand(wI).addCommand(vI).addCommand(Sm).addCommand(Pm).addCommand(II).addCommand(kI);import{createHash as xI,randomUUID as $m}from"crypto";import{existsSync as Om,readdirSync as RI,readFileSync as CI,statSync as SI}from"fs";import{join as Dm}from"path";import{Command as rt}from"commander";var Nm=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ut(e){Nm.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function li(e,t=[]){return[...t,e]}function ha(e){return xI("sha256").update(e).digest("hex").slice(0,32)}function ya(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 mi(e,t){let n=Number(t);if(Number.isInteger(n)&&n>0)return n;a(`${e} must be a positive whole number; got "${t}".`),process.exit(s.INVALID_INPUT)}function Lt(e,t){try{return JSON.parse(t)}catch{a(`${e} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}async function Sn(e,t,n,r){try{m(r===void 0?await p(e,t):await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}function Lm(e,t){let n={brandId:e,teamId:t.teamId};return t.audience!==void 0&&(n.audience=t.audience),t.market!==void 0&&(n.market=t.market),t.productId!==void 0&&(n.productId=t.productId),t.status!==void 0&&(n.status=t.status),t.usableOnly&&(n.usableOnly=!0),n}function Um(e){return e.option("--product-id <id>","Only items scoped to this brand product").option("--market <market>","Only items scoped to this market, e.g. US").option("--audience <audience>","Only items scoped to this audience").option("--status <status>","draft | approved | pre-launch | restricted | withdrawn | retired; repeat for several",li).option("--usable-only","Only items usable now: approved and in scope (never restricted, retired or draft)").option("--team-id <id>","Workspace ID")}var EI=Um(new rt("list").description("List a brand's claims library").argument("<brand-id>","Brand profile ID").option("--claim-type <type>","efficacy | safety | dosing | indication | mechanism | comparative | outcomes | disease-awareness | cost | cta | qualifier | other")).action(async(e,t)=>{await w(),Ut(e);let n=Lm(e,t);t.claimType!==void 0&&(n.claimType=t.claimType),await Sn("listClaims",n,"List failed")}),PI=new rt("get").description("Read one claim, its references and its versions").argument("<brand-id>","Brand profile ID").argument("<node-key>","Claim key, e.g. claim.a1c-reduction").option("--version-number <n>","Read this version instead of the current one").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.versionNumber!==void 0&&(r.version=mi("--version-number",n.versionNumber)),await Sn("getClaim",r,"Read failed")}),AI=new rt("set").description("Create or edit a draft claim, or restrict, withdraw or retire one (people approve in the app)").argument("<brand-id>","Brand profile ID").option("--node-key <key>","Key of an existing claim to UPDATE, as `claims list` shows it. Omit to create.").option("--slug <slug>","Kebab-case slug for a NEW claim's key").option("--text <text>","The claim, verbatim").option("--claim-type <type>","efficacy | safety | dosing | indication | mechanism | comparative | outcomes | disease-awareness | cost | cta | qualifier | other").option("--status <status>","draft | restricted | withdrawn | retired (only a signed-in person can approve, in the app)").option("--restriction-reason <text>","Why the claim must not be used").option("--footnote <text>",'Verbatim footnote that must accompany it ("" removes it)').option("--reviewer-note <text>",'Note for reviewers ("" removes it)').option("--require-legal-block <key>","Legal block (rule.legal.*) that must appear with the claim; repeat for several",li).option("--require-qualifier <claim-key>","Qualifier claim (claimType qualifier) that must appear directly with the claim; repeat for several",li).option("--scope <json>",`Products, markets and audiences, as JSON, e.g. '{"markets":["US"]}'`).option("--external <json>",`Where the claim lives in your system of record, as JSON, e.g. '{"system":"promomats","id":"CLM-000123","status":"Approved"}'`).option("--references <json>",`Supporting citations, as a JSON array; anchor each with the document, page and exact passage, e.g. '[{"citation":"Prescribing Information \xA714.1","externalDocumentId":"VV-00123","documentVersion":"2.0","page":"12","passage":"\u2026"}]'`).option("--expected-version <n>","Refuse the write if the claim is no longer at this version").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Ut(e),!t.nodeKey&&(!t.text||!t.claimType)&&(a("A new claim needs --text and --claim-type."),process.exit(s.INVALID_INPUT));let n={brandId:e,teamId:t.teamId};t.nodeKey!==void 0&&(n.nodeKey=t.nodeKey),t.slug!==void 0&&(n.slug=t.slug),t.text!==void 0&&(n.text=t.text),t.claimType!==void 0&&(n.claimType=t.claimType),t.status!==void 0&&(n.status=t.status),t.restrictionReason!==void 0&&(n.restrictionReason=t.restrictionReason),t.footnote!==void 0&&(n.footnote=t.footnote===""?null:t.footnote),t.reviewerNote!==void 0&&(n.reviewerNote=t.reviewerNote===""?null:t.reviewerNote),t.requireLegalBlock!==void 0&&(n.requiredLegalBlockKeys=t.requireLegalBlock),t.requireQualifier!==void 0&&(n.requiredQualifierKeys=t.requireQualifier),t.scope!==void 0&&(n.scope=Lt("--scope",t.scope)),t.references!==void 0&&(n.references=Lt("--references",t.references)),t.external!==void 0&&(n.external=Lt("--external",t.external)),t.expectedVersion!==void 0&&(n.expectedVersion=mi("--expected-version",t.expectedVersion)),t.publish!==void 0&&(n.publish=ya("--publish",t.publish)),await Sn("setClaim",n,"Write failed",ha(`setClaim:${e}:${JSON.stringify(n)}`))}),TI={anchors:"anchors.csv",claimTargets:"3_annotation_keyword_targets__sys.csv",claims:"1_annotation_keywords__sys.csv",documents:"documents.csv",linkTargets:"2_link_target__sys.csv"},OI=/\.(pdf|txt)$/i;function $I(e){(!Om(e)||!SI(e).isDirectory())&&(a(`${e} is not a folder. Pass the folder holding the export.`),process.exit(s.INVALID_INPUT));let t={};for(let[n,r]of Object.entries(TI)){let i=Dm(e,r);if(!Om(i)){n==="claims"&&(a(`${e} has no ${r}: export the claims (Text Assets) first.`),process.exit(s.INVALID_INPUT)),t[n]="";continue}t[n]=CI(i,"utf8")}return t}function DI(e){let t=new Map;for(let n of e){let r=n.lastIndexOf("="),i=n.slice(0,r).trim(),o=n.slice(r+1).trim();(r<1||!Nm.test(o))&&(a(`--rendition expects <file name>=<Library file id>; got "${n}".`),process.exit(s.INVALID_INPUT)),t.set(i,o)}return t}async function NI(e,t,n){let r=[...t].map(([i,o])=>({fileName:i,libraryFileId:o}));for(let i of RI(e).sort()){if(!OI.test(i)||t.has(i))continue;let o=Dm(e,i),c=`cli:claims-import:rendition:${$m()}`,l=await p("createLibraryFileUploadUrl",{...et(o),teamId:n},`${c}:upload`),d=await tt(o,l),y=(await p("addLibraryFile",{mediaType:d.type,name:d.name,size:d.size,teamId:n,uploadKey:d.s3Key,url:d.url},c)).files[0]?.fileId;y&&r.push({fileName:i,libraryFileId:y})}return r}var LI=new rt("import").description("Import claims from a PromoMats export; a dry run unless --commit (people approve in the app)").argument("<brand-id>","Brand profile ID").argument("<export-dir>","Folder with the export: 1_annotation_keywords__sys.csv, 2_link_target__sys.csv, 3_annotation_keyword_targets__sys.csv, anchors.csv, documents.csv and the reference renditions (PDF or text) documents.csv names").option("--commit","Write the plan. Without --plan-id the import is previewed and that preview committed").option("--plan-id <id>","Commit exactly this plan, from an earlier preview; refused if anything changed since").option("--rendition <file=id>","Use a reference already on the Library shelf instead of uploading the local file; repeat for several",li).option("--columns <json>",`Column renames for a customised Vault, as JSON, e.g. '{"claims":{"category":"claim_category__c"}}'; a commit saves them for the workspace`).option("--publish <bool>","Publish a brand snapshot after a commit; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e),n.planId&&!n.commit&&(a("--plan-id names a plan to commit; add --commit."),process.exit(s.INVALID_INPUT));let r=$I(t),i={brandId:e,files:r,teamId:n.teamId};n.columns!==void 0&&(i.columnOverrides=Lt("--columns",n.columns)),n.publish!==void 0&&(i.publish=ya("--publish",n.publish));try{i.renditions=await NI(t,DI(n.rendition??[]),n.teamId);let o=n.planId;if(!n.commit||!o){let c=await p("importClaims",{...i,mode:"preview"},`cli:claims-import:preview:${$m()}`);if(!n.commit||c.problems?.length){m(c),c.problems?.length&&process.exit(s.INVALID_INPUT);return}o=c.planId}m(await p("importClaims",{...i,mode:"commit",planId:o},ha(`importClaims:${e}:${o}`)))}catch(o){a(u(o,"Import failed")),process.exit(s.GENERAL_ERROR)}}),_m=new rt("claims").description("Brand claims library (governed, verbatim claims)").addCommand(EI).addCommand(PI).addCommand(AI).addCommand(LI),UI=Um(new rt("list").description("List a brand's ISI and legal blocks").argument("<brand-id>","Brand profile ID").option("--block-type <type>","isi | indication | fair-balance | footnote | disclaimer | legal-line").option("--variant <variant>","full | abbreviated | story-strip | end-card")).action(async(e,t)=>{await w(),Ut(e);let n=Lm(e,t);t.blockType!==void 0&&(n.blockType=t.blockType),t.variant!==void 0&&(n.variant=t.variant),await Sn("listLegalBlocks",n,"List failed")}),_I=new rt("get").description("Read one legal block and its versions").argument("<brand-id>","Brand profile ID").argument("<node-key>","Legal block key, e.g. rule.legal.isi-full").option("--version-number <n>","Read this version instead of the current one").option("--team-id <id>","Workspace ID").action(async(e,t,n)=>{await w(),Ut(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.versionNumber!==void 0&&(r.version=mi("--version-number",n.versionNumber)),await Sn("getLegalBlock",r,"Read failed")}),jI=new rt("set").description("Create or edit a draft legal block, or restrict, withdraw or retire one").argument("<brand-id>","Brand profile ID").option("--node-key <key>","Key of an existing block to UPDATE, as `legal-blocks list` shows it. Omit to create.").option("--slug <slug>","Kebab-case slug for a NEW block's key").option("--name <name>","Display name, e.g. Important Safety Information").option("--block-type <type>","isi | indication | fair-balance | footnote | disclaimer | legal-line").option("--variant <variant>","full | abbreviated | story-strip | end-card").option("--content <json>",`Verbatim text as JSON blocks of runs, e.g. '[{"type":"paragraph","runs":[{"text":"Warning:","bold":true},{"text":" \u2026"}]}]'`).option("--placement <json>",`Rendering constraints as JSON, e.g. '{"minFontSizePx":10,"minAreaPercent":20,"position":"bottom"}'`).option("--scope <json>",`Products, markets and audiences, as JSON, e.g. '{"markets":["US"]}'`).option("--source-url <url>",'Where the verbatim text comes from ("" removes it)').option("--notes <text>","Note for reviewers").option("--status <status>","draft | restricted | withdrawn | retired").option("--restriction-reason <text>","Why the block must not be used").option("--expected-version <n>","Refuse the write if the block is no longer at this version").option("--publish <bool>","Publish a brand snapshot after the write; defaults to true").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Ut(e),!t.nodeKey&&(!t.name||!t.blockType||!t.variant||!t.content||!t.placement)&&(a("A new legal block needs --name, --block-type, --variant, --content and --placement."),process.exit(s.INVALID_INPUT));let n={brandId:e,teamId:t.teamId};t.nodeKey!==void 0&&(n.nodeKey=t.nodeKey),t.slug!==void 0&&(n.slug=t.slug),t.name!==void 0&&(n.name=t.name),t.blockType!==void 0&&(n.blockType=t.blockType),t.variant!==void 0&&(n.variant=t.variant),t.content!==void 0&&(n.content=Lt("--content",t.content)),t.placement!==void 0&&(n.placement=Lt("--placement",t.placement)),t.scope!==void 0&&(n.scope=Lt("--scope",t.scope)),t.sourceUrl!==void 0&&(n.sourceUrl=t.sourceUrl===""?null:t.sourceUrl),t.notes!==void 0&&(n.notes=t.notes),t.status!==void 0&&(n.status=t.status),t.restrictionReason!==void 0&&(n.restrictionReason=t.restrictionReason),t.expectedVersion!==void 0&&(n.expectedVersion=mi("--expected-version",t.expectedVersion)),t.publish!==void 0&&(n.publish=ya("--publish",t.publish)),await Sn("setLegalBlock",n,"Write failed",ha(`setLegalBlock:${e}:${JSON.stringify(n)}`))}),jm=new rt("legal-blocks").description("Brand ISI and legal blocks (governed, verbatim)").addCommand(UI).addCommand(_I).addCommand(jI);import{Command as qm,InvalidArgumentError as qI}from"commander";var MI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,VI=["presentation","reel","story","video","walkthrough","slide","microsite","article"];function FI(e){if(!MI.test(e))throw new qI("Expected a brand UUID from `mf branding list`.");return e}var BI=new qm("resolve").description("Resolve design tokens, node trace, rules, and conflicts").argument("<brand-id>","Brand UUID",FI).requiredOption("--artifact <type>","Artifact type",b("--artifact",[...VI])).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 w();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{m(await p("resolveBrandDesign",n))}catch(r){a(u(r,"Brand design resolve failed")),process.exit(s.GENERAL_ERROR)}}),Mm=new qm("design").description("Inspect resolved brand design state").addCommand(BI);import{createHash as GI,randomUUID as KI}from"crypto";import{Command as it,InvalidArgumentError as Vm}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 or(e){if(!WI.test(e))throw new Vm("Expected a brand UUID from `mf branding list`.");return e}function JI(e){if(e==="true")return!0;if(e==="false")return!1;throw new Vm("--show expects true or false.")}function pi(e,t){return GI("sha256").update(JSON.stringify([e,t])).digest("hex").slice(0,32)}function En(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var zI=new it("set").description("Create or update one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",or).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 w();let i={brandId:e,hex:n,role:t,teamId:r.teamId};try{m(await p("setBrandCustomColor",i,r.idempotencyKey??pi("setBrandCustomColor",i)))}catch(o){En(o,"Custom colour update failed")}}),HI=new it("delete").description("Remove one custom colour role and print the committed snapshot").argument("<brand-id>","Brand UUID",or).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 w(),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{m(await p("deleteBrandCustomColor",r,n.idempotencyKey??pi("deleteBrandCustomColor",r)))}catch(i){En(i,"Custom colour removal failed")}}),XI=new it("sync").description("Synchronize current brand data into the canonical brand graph").argument("<brand-id>","Brand UUID",or).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 w();let n={brandId:e,teamId:t.teamId};try{let r=await p("syncBrandFoundation",n,t.idempotencyKey??pi("syncBrandFoundation",[n,KI()]));m(t.wait===!1?r:await Vc(r.runId,t.teamId))}catch(r){En(r,"Brand foundation sync failed")}}),YI=new it("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 w();try{m(await R("syncBrandFoundation",e,t.teamId))}catch(n){En(n,"Brand foundation sync status failed")}}),Fm=new it("foundation").description("Manage atomic Foundation settings backed by the brand DAG").addCommand(new it("color").description("Manage custom colour roles").addCommand(zI).addCommand(HI)).addCommand(XI).addCommand(YI),QI=new it("get").description("Read the complete current footer and its source").argument("<brand-id>","Brand UUID",or).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("getBrandFooter",{brandId:e,teamId:t.teamId}))}catch(n){En(n,"Footer read failed")}}),ZI=new it("set").description("Patch footer text, visibility, or alignment atomically").argument("<brand-id>","Brand UUID",or).option("--text <text>","Complete footer text; pass an empty string to clear it").option("--show <boolean>","Whether artifacts show the footer: true | false",JI).option("--alignment <value>","Footer alignment: left | center | right",b("--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 w(),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{m(await p("setBrandFooter",n,t.idempotencyKey??pi("setBrandFooter",n)))}catch(r){En(r,"Footer update failed")}}),Bm=new it("footer").description("Read or update the brand footer").addCommand(QI).addCommand(ZI);import{createHash as ek}from"crypto";import{Command as Gm}from"commander";var tk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function nk(e){tk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function rk(e){return ek("sha256").update(e).digest("hex").slice(0,32)}function Km(e,t){try{return JSON.parse(t)}catch(n){a(`${e} is not valid JSON: ${u(n)}`),process.exit(s.INVALID_INPUT)}}function ik(e,t){let n=Km(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 ok(e,t){let n=Km(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 ak=new Gm("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 w(),nk(e);let n={brandId:e,gradients:ik("--gradients",t.gradients),teamId:t.teamId};t.roles!==void 0&&(n.gradientRoles=ok("--roles",t.roles));try{m(await p("setBrandGradients",n,rk(`setBrandGradients:${e}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),Wm=new Gm("gradient").description("Brand gradient library commands").addCommand(ak);import{createHash as sk}from"crypto";import{Command as _t}from"commander";var dk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ar(e){dk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ck(e,t=[]){return[...t,e]}function va(e){return sk("sha256").update(e).digest("hex").slice(0,32)}function wa(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 ba(e,t){try{return JSON.parse(t)}catch{a(`${e} must be valid JSON.`),process.exit(s.INVALID_INPUT)}}var lk=new _t("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 w(),ar(e);try{m(await p("getBrandGuardrails",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),mk=new _t("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(e,t)=>{await w(),ar(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 p("testBrandGuardrails",n);m(r),r.passed===!1&&process.exit(s.GENERAL_ERROR)}catch(r){a(u(r,"Test failed")),process.exit(s.GENERAL_ERROR)}}),pk=new _t("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("--kind <kind>","deterministic | semantic; defaults to deterministic. Semantic rules can only warn or shadow").option("--semantic <json>",`Plain-English rule for --kind semantic, as JSON, e.g. '{"rule":"no unexplained acronyms"}'`).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(e,t)=>{await w(),ar(e),(!t.name||!t.category||!t.severity)&&(a("Pass --name, --category and --severity."),process.exit(s.INVALID_INPUT));let n=t.kind??"deterministic";n==="semantic"?t.semantic===void 0&&(a(`Pass --semantic, e.g. '{"rule":"no unexplained acronyms"}'.`),process.exit(s.INVALID_INPUT)):t.require===void 0&&(a(`Pass --require, e.g. '{"component":"banned-phrase"}'.`),process.exit(s.INVALID_INPUT));let r={brandId:e,category:t.category,kind:n,name:t.name,severity:t.severity,teamId:t.teamId};t.require!==void 0&&(r.require=ba("--require",t.require)),t.semantic!==void 0&&(r.semantic=ba("--semantic",t.semantic)),t.conditions!==void 0&&(r.conditions=ba("--conditions",t.conditions)),t.enabled!==void 0&&(r.enabled=wa("--enabled",t.enabled)),t.nodeKey!==void 0&&(r.nodeKey=t.nodeKey),t.notes!==void 0&&(r.notes=t.notes),t.slug!==void 0&&(r.slug=t.slug),t.publish!==void 0&&(r.publish=wa("--publish",t.publish));try{m(await p("setBrandGuardrail",r,va(`setBrandGuardrail:${e}:${JSON.stringify(r)}`)))}catch(i){a(u(i,"Write failed")),process.exit(s.GENERAL_ERROR)}}),uk=new _t("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 w(),ar(e);let r={brandId:e,nodeKey:t,teamId:n.teamId};n.publish!==void 0&&(r.publish=wa("--publish",n.publish));try{m(await p("deleteBrandGuardrail",r,va(`deleteBrandGuardrail:${e}:${t}`)))}catch(i){a(u(i,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),gk=new _t("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.",ck).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 w(),ar(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 p("generateBrandGuardrails",n,va(`generateBrandGuardrails:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await jc(r.runId,t.teamId))}catch(r){a(u(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),fk=new _t("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 w();try{m(await R("generateBrandGuardrails",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Jm=new _t("guardrails").description("Brand guardrail rule commands").addCommand(lk).addCommand(mk).addCommand(pk).addCommand(uk).addCommand(gk).addCommand(fk);import{randomUUID as hk}from"crypto";import{readFile as zm}from"fs/promises";import{Command as yk}from"commander";var Hm=new yk("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 w();try{let n=await zm(e,"utf8"),r=t.urlEvidence?JSON.parse(await zm(t.urlEvidence,"utf8")):void 0,i=t.idempotencyKey??hk();m(await p("importBrandDesignMd",{designMd:n,name:t.name,teamId:t.teamId,url:t.url,urlExtractedRaw:r},i))}catch(n){a(u(n,"Import failed")),process.exit(s.GENERAL_ERROR)}});import{Command as Xm,InvalidArgumentError as Ym}from"commander";var bk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function wk(e){if(!bk.test(e))throw new Ym("Expected a brand UUID from `mf branding list`.");return e}function vk(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>50)throw new Ym("--limit expects a whole number from 1 to 50.");return t}var Ik=new Xm("list").description("List recent safe job summaries for one brand").argument("<brand-id>","Brand UUID",wk).option("--limit <count>","Newest jobs to return, 1-50 (default: 20)",vk).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("listBrandJobs",{brandId:e,limit:t.limit,teamId:t.teamId}))}catch(n){a(u(n,"Brand job history failed")),process.exit(s.GENERAL_ERROR)}}),Qm=new Xm("jobs").description("Inspect brand background activity").addCommand(Ik);import{createHash as kk}from"crypto";import{Command as ut}from"commander";var xk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gt(e){xk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Pn(e){return kk("sha256").update(e).digest("hex").slice(0,32)}var Zm=new ut("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 w(),t.parent&&gt(t.parent);try{m(await p("createBrand",{name:e,parentBrandingId:t.parent,teamId:t.teamId}))}catch(n){a(u(n,"Create failed")),process.exit(s.GENERAL_ERROR)}}),ep=new ut("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 w(),gt(e);let n=!t.off;try{m(await p("setBrandStar",{brandId:e,starred:n,teamId:t.teamId},Pn(`setBrandStar:${e}:${n}`)))}catch(r){a(u(r,"Star failed")),process.exit(s.GENERAL_ERROR)}});async function Rk(e,t){let n=await p("getBrandProfile",{brandId:e,teamId:t.teamId});return typeof n.name=="string"?n.name:e}var tp=new ut("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 w(),gt(e),!t.yes&&process.stdin.isTTY){let n;try{n=await Rk(e,t)}catch(r){a(u(r,"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{m(await p("deleteBrand",{brandId:e,teamId:t.teamId},Pn(`deleteBrand:${e}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Ia="none",np=new ut("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 "${Ia}" to detach it`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),gt(e);let n=t.parent?.toLowerCase()===Ia;t.parent!==void 0&&!n&&gt(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 ${Ia} 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{m(await p("updateBrand",r,Pn(`updateBrand:${e}:${t.name??""}:${t.parent??""}`)))}catch(i){a(u(i,"Update failed")),process.exit(s.GENERAL_ERROR)}}),rp=new ut("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 w(),gt(e);try{m(await p("setDefaultBrand",{brandId:e,teamId:t.teamId},Pn(`setDefaultBrand:${e}`)))}catch(n){a(u(n,"Set default failed")),process.exit(s.GENERAL_ERROR)}}),ip=new ut("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 w(),gt(e);try{let n=await U(t.teamId);m(await p("approveBrand",{brandId:e,teamId:n},Pn(`approveBrand:${n}:${e}`)))}catch(n){a(u(n,"Approve failed")),process.exit(s.GENERAL_ERROR)}}),op=new ut("onboarding").description("Manage the brand onboarding review state").addCommand(new ut("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 w(),gt(e);try{let n=await U(t.teamId);m(await p("completeBrandOnboarding",{brandId:e,teamId:n},Pn(`completeBrandOnboarding:${n}:${e}`)))}catch(n){a(u(n,"Complete onboarding failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as ka}from"crypto";import{existsSync as Ck,readFileSync as Sk}from"fs";import{basename as Ek}from"path";import{Command as ui}from"commander";import Pk from"ora";function Ak(e,t,n){return ka("sha256").update(JSON.stringify([e,t,n??null])).digest("hex").slice(0,32)}var ap=new ui("logo").description("Upload primary, dark-background, and favicon logo files").addCommand(new ui("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 w();try{m(await p("listBrandLogos",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Logo list failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new ui("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 w(),n.yes||(a("Refusing to remove a logo candidate without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("removeBrandLogo",{brandId:e,logoUrl:t,teamId:n.teamId},n.idempotencyKey??Ak("removeBrandLogo",e,t)))}catch(r){a(u(r,"Logo removal failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(new ui("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 w();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)),Ck(t.file)||(a(`File not found: ${t.file}`),process.exit(s.INVALID_INPUT));let r=ka("sha256").update(Sk(t.file)).digest("hex"),i=t.idempotencyKey??ka("sha256").update(`setBrandLogo:${t.teamId??"current"}:${e??"default"}:${n}:${r}`).digest("hex").slice(0,32),o=Pk({text:`Uploading ${Ek(t.file)}...`,stream:process.stderr}).start(),c;try{c=(await ie(t.file,{idempotencyKey:`${i}:upload`,storagePrefix:"brand-logos"})).url,o.succeed("Uploaded")}catch(l){o.fail("Upload failed"),a(u(l)),process.exit(s.GENERAL_ERROR)}try{m(await p("setBrandLogo",{brandId:e,fileUrl:c,teamId:t.teamId,variant:n},i))}catch(l){a(u(l,"Write failed")),process.exit(s.GENERAL_ERROR)}}));import{createHash as Tk,randomUUID as Ok}from"crypto";import{Command as An,InvalidArgumentError as gi}from"commander";var $k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Dk=["admin","editor","viewer"],sp=["cancelled","completed","failed","info","queued","running"],dp=["activity","brand-extraction-request","brand-resolution","brand-sync-job"];function jt(e){return t=>{if(!$k.test(t))throw new gi(`${e} expects a UUID from \`mf branding list\` or the workspace member list.`);return t}}function lp(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>200)throw new gi("--limit expects a whole number from 1 to 200.");return t}function cp(e,t){return n=>{let r=n.split(",").map(o=>o.trim()).filter(Boolean);if(r.find(o=>!t.includes(o))||r.length===0)throw new gi(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function mp(e,t){return Tk("sha256").update(JSON.stringify([e,t,Ok()])).digest("hex").slice(0,32)}function sr(e,t){a(u(e,t)),process.exit(typeof e=="object"&&e!==null&&"exitCode"in e&&typeof e.exitCode=="number"?e.exitCode:s.GENERAL_ERROR)}var Nk=new An("list").description("List explicit member access overrides for one team brand").argument("<brand-id>","Team brand UUID",jt("brand-id")).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w();try{m(await p("listBrandPermissions",{brandId:e,teamId:t.teamId}))}catch(n){sr(n,"Brand permission list failed")}}),Lk=new An("candidates").description("List member IDs eligible for one team brand's access overrides").argument("<brand-id>","Team brand UUID",jt("brand-id")).option("--query <text>","Search member name, username, or email").option("--limit <count>","Maximum members, 1-200 (default: 50)",lp).option("--offset <count>","Members to skip (default: 0)",e=>{let t=Number(e);if(!Number.isInteger(t)||t<0)throw new gi("--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 w();try{m(await p("listBrandPermissionCandidates",{brandId:e,limit:t.limit,offset:t.offset,query:t.query,teamId:t.teamId}))}catch(n){sr(n,"Brand permission candidate list failed")}}),Uk=new An("set").description("Set one team member's explicit role for a team brand").argument("<brand-id>","Team brand UUID",jt("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",jt("--user")).requiredOption("--role <role>","Desired override: admin | editor | viewer",b("--role",Dk)).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 w();try{m(await p("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId,userId:t.user},t.idempotencyKey??mp("setBrandPermission",{brandId:e,role:t.role,teamId:t.teamId??null,userId:t.user})))}catch(n){sr(n,"Brand permission update failed")}}),_k=new An("remove").description("Remove one member override so the team role applies again").argument("<brand-id>","Team brand UUID",jt("brand-id")).requiredOption("--user <user-id>","Target workspace member UUID",jt("--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 w(),t.yes||(a("Refusing to remove a brand access override without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("removeBrandPermission",{brandId:e,teamId:t.teamId,userId:t.user},t.idempotencyKey??mp("removeBrandPermission",{brandId:e,teamId:t.teamId??null,userId:t.user})))}catch(n){sr(n,"Brand permission removal failed")}}),pp=new An("permission").description("Administer explicit member access overrides for a team brand").addCommand(Lk).addCommand(Nk).addCommand(Uk).addCommand(_k),up=new An("activity").description("Read a brand's filtered, cursor-paginated activity feed").argument("<brand-id>","Brand UUID",jt("brand-id")).option("--query <text>","Search action, summary, detail, entity, and metadata").option("--status <statuses>",`Comma-separated statuses: ${sp.join(" | ")}`,cp("--status",sp)).option("--source-type <types>",`Comma-separated sources: ${dp.join(" | ")}`,cp("--source-type",dp)).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)",lp).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 w();try{m(await p("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){sr(n,"Brand activity read failed")}});import{createHash as jk}from"crypto";import{Command as qt,InvalidArgumentError as Ra}from"commander";var qk=/^[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 xa(e,t){if(qk.test(e))return e;throw new Ra(`${t} must be a UUID.`)}function Mk(e){let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=50)return t;throw new Ra("limit must be a whole number from 1 to 50.")}function Vk(e){let t=Number(e);if(Number.isInteger(t)&&t>=0)return t;throw new Ra("offset must be a whole number of 0 or more.")}function Fk(e){return jk("sha256").update(e).digest("hex").slice(0,32)}async function dr(e,t){await w();try{m(await e())}catch(n){a(u(n,t)),process.exit(s.GENERAL_ERROR)}}var gp=new qt("presentations").description("Inspect presentations already linked to a brand").addCommand(new qt("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)",Mk,50).option("--offset <n>","Zero-based offset (default 0)",Vk,0).option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{let n=xa(e,"brand-id");await dr(()=>p("listBrandPresentations",{brandId:n,limit:t.limit,offset:t.offset,teamId:t.teamId}),"Could not list linked presentations")})),fp=new qt("presentation").description("Inspect or update one deck from its already-linked brand").addCommand(new qt("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 dr(()=>p("getPresentationBrandDrift",{presentationId:e,teamId:t.teamId}),"Could not read presentation brand drift")})).addCommand(new qt("guardrails").description("Check the saved version against its linked brand's guardrail rules").argument("<presentation>","Presentation UUID, document UUID, or slug").option("--team-id <id>","Workspace UUID; defaults to the selected workspace").action(async(e,t)=>{await dr(()=>p("checkPresentationGuardrails",{presentationId:e,teamId:t.teamId}),"Could not check presentation guardrails")})).addCommand(new qt("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 dr(()=>p("applyPresentationBrandChanges",{presentationId:e,teamId:t.teamId},t.idempotencyKey),"Could not apply linked-brand changes")})),hp=new qt("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=xa(e,"brand-id"),i=xa(t,"run-id");await dr(()=>p("cancelBrandPresentationSync",{brandId:r,runId:i,teamId:n.teamId},Fk(`cancelBrandPresentationSync:${r}:${i}`)),"Could not cancel brand sync")});import{createHash as Bk,randomUUID as vp}from"crypto";import{Command as ft}from"commander";var Gk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,yp=["product","service","platform","solution"],fi=["candidate","draft","approved"],bp=["brand-site","brand-site-scan","brand-site-extract","product-url"];function Tn(e){Gk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function hi(e,t,n){if(n.includes(t))return t;a(`${e} must be one of: ${n.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Kk(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 Ca(e){return Bk("sha256").update(e).digest("hex").slice(0,32)}var Wk=new ft("list").description("List the products a brand sells").argument("<brand-id>","Brand profile ID").option("--status <status>",`Only products in this state. One of: ${fi.join(", ")}. Omit for the saved catalogue.`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Tn(e),t.status!==void 0&&hi("--status",t.status,fi);let n={brandId:e,teamId:t.teamId};t.status!==void 0&&(n.status=t.status);try{m(await p("listBrandProducts",n))}catch(r){a(u(r,"List failed")),process.exit(s.GENERAL_ERROR)}}),Jk=new ft("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: ${yp.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: ${fi.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 w(),Tn(e),t.type!==void 0&&hi("--type",t.type,yp),t.status!==void 0&&hi("--status",t.status,fi),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{m(await p("saveBrandProduct",n,Ca(`saveBrandProduct:${e}:${t.product??t.url??t.name??"new"}`)))}catch(r){a(u(r,"Save failed")),process.exit(s.GENERAL_ERROR)}}),wp=(e,t=[])=>[...t,e],zk=new ft("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.",wp).option("--approve <id>","Product from --product that should finish approved; repeat as needed. Others finish draft.",wp).option("--idempotency-key <key>","Stable retry key for this selection").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Tn(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{m(await p("setBrandProductSelection",n,t.idempotencyKey??vp()))}catch(r){a(u(r,"Selection failed")),process.exit(s.GENERAL_ERROR)}}),Hk=new ft("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 w(),Tn(e);let n={brandId:e,productId:t.product,teamId:t.teamId};t.name!==void 0&&(n.name=t.name);try{m(await p("duplicateBrandProduct",n,t.idempotencyKey??vp()))}catch(r){a(u(r,"Duplicate failed")),process.exit(s.GENERAL_ERROR)}}),Xk=new ft("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 w(),Tn(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{m(await p("deleteBrandProduct",{brandId:e,productId:t.product,teamId:t.teamId},Ca(`deleteBrandProduct:${e}:${t.product}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Yk=new ft("extract").description("Discover a brand's products by crawling its site").argument("<brand-id>","Brand profile ID").option("--mode <mode>",`One of: ${bp.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 w(),Tn(e),t.mode!==void 0&&hi("--mode",t.mode,bp);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=Kk("--max-products",t.maxProducts)),t.product?.length&&(n.productIds=t.product);try{let r=await p("extractBrandProducts",n,Ca(`extractBrandProducts:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await Uc(r.runId,t.teamId))}catch(r){a(u(r,"Extract failed")),process.exit(s.GENERAL_ERROR)}}),Qk=new ft("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 w();try{m(await R("extractBrandProducts",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Ip=new ft("product").description("Brand product catalogue commands").addCommand(Wk).addCommand(Jk).addCommand(zk).addCommand(Hk).addCommand(Xk).addCommand(Yk).addCommand(Qk);import{randomUUID as Ea}from"crypto";import{Command as On}from"commander";import{randomUUID as Zk}from"crypto";import{Command as xp}from"commander";function k(e,t){let n={...t},r=e.parent,i=!1;for(;r;){let o=r.opts?.();if(o){i=!0;for(let[c,l]of Object.entries(o))n[c]===void 0&&l!==void 0&&(n[c]=l)}r=r.parent}return i?n:t}function ce(e){return e._checkForMissingMandatoryOptions=function(){for(let t of this.options)t.mandatory&&this.getOptionValue(t.attributeName())===void 0&&this.missingMandatoryOptionValue(t)},e}function kp(e){return e._checkForMissingMandatoryOptions=function(){let t=k(this,this.opts());for(let n of this.options)n.mandatory&&t[n.attributeName()]===void 0&&this.missingMandatoryOptionValue(n)},e}var Sa="listenBrandPronunciations";function Rp(e){let t=Hn(e);if(t)throw Object.assign(new P(t,500),{[pn]:!0});let n=e.output;if(typeof n?.brandId!="string"||!Array.isArray(n.items))throw new P("Pronunciation listening completed without its audio list.",500);let r=n.items.map(i=>{if(!i||typeof i!="object"||!("word"in i)||typeof i.word!="string"||!("audioUrl"in i)||typeof i.audioUrl!="string")throw new P("Pronunciation listening returned an invalid audio entry.",500);return{word:i.word,audioUrl:i.audioUrl}});m({brandId:n.brandId,items:r})}function Cp(e,t=""){a(`${u(e,"Pronunciation listening failed")}${t}`);let n=e&&typeof e=="object"&&"exitCode"in e?e.exitCode:void 0;process.exit(typeof n=="number"?n:s.GENERAL_ERROR)}var ex=new xp("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(e,t,n)=>{let r=k(n,t);await w();try{let i=await R(Sa,e,r.teamId);i.done?Rp(i):m(i)}catch(i){Cp(i)}}),Sp=new xp("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").addCommand(ex).action(async(e,t)=>{let n;try{if(!e)throw new P("Brand ID is required to start listening.",400,s.INVALID_INPUT);if(t.words!==void 0)try{n=JSON.parse(t.words)}catch{throw new P("--words must be valid JSON.",400,s.INVALID_INPUT)}}catch(o){a(u(o,"Invalid pronunciation listening input.")),process.exit(s.INVALID_INPUT);return}await w();let r=t.idempotencyKey??Zk(),i;try{let o=await p(Sa,{brandId:e,...t.words!==void 0?{words:n}:{},...t.voiceId!==void 0?{voiceId:t.voiceId}:{},teamId:t.teamId},r);if(i=o.runId,t.wait===!1){m(o);return}Rp(await z(Sa,i,t.teamId))}catch(o){Cp(Object.assign(new P(oe(o,i),500),{exitCode:o&&typeof o=="object"&&"exitCode"in o?o.exitCode:void 0}),un(o)?"":`${Ee(o,r)}${i?` Recover with branding pronunciation listen status ${i}.`:""}`)}});async function cr(e,t,n){await w();try{m(await p(e,t,n))}catch(r){a(u(r,"Pronunciation command failed"));let i=r&&typeof r=="object"&&"exitCode"in r?r.exitCode:void 0;process.exit(typeof i=="number"?i:s.GENERAL_ERROR)}}var tx=new On("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(e,t)=>{await cr("listBrandPronunciations",{brandId:e,teamId:t.teamId})}),nx=new On("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(e,t,n)=>{await cr("getBrandPronunciation",{brandId:e,word:t,teamId:n.teamId})}),rx=new On("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(e,t,n)=>{await cr("setBrandPronunciation",{brandId:e,word:t,pronunciation:n.pronunciation,teamId:n.teamId},n.idempotencyKey??Ea())}),ix=new On("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(e,t,n)=>{await cr("deleteBrandPronunciation",{brandId:e,word:t,teamId:n.teamId},n.idempotencyKey??Ea())}),ox=new On("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(e,t)=>{let n;try{n=JSON.parse(t.rules??"")}catch{a("--rules must be valid JSON."),process.exit(s.INVALID_INPUT);return}await cr("setBrandPronunciations",{brandId:e,rules:n,teamId:t.teamId},t.idempotencyKey??Ea())}),Ep=new On("pronunciation").description("Manage the words and spoken forms in a brand's pronunciation dictionary").addCommand(tx).addCommand(nx).addCommand(rx).addCommand(ox).addCommand(ix).addCommand(Sp);import{createHash as ax}from"crypto";import{Command as yi}from"commander";var sx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Pp(e){sx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function dx(e,t=[]){return[...t,e]}function cx(e){return ax("sha256").update(e).digest("hex").slice(0,32)}var lx=new yi("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 w(),Pp(e);try{m(await p("getBrandQuality",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),mx=new yi("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.",dx).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 w(),Pp(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 p("repairBrandQuality",n,cx(`repairBrandQuality:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await qc(r.runId,t.teamId))}catch(r){a(u(r,"Repair failed")),process.exit(s.GENERAL_ERROR)}}),px=new yi("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 w();try{m(await R("repairBrandQuality",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Ap=new yi("quality").description("Brand deck quality commands").addCommand(lx).addCommand(mx).addCommand(px);function Pa(e){return Array.isArray(e.items)}function ot(e){return typeof e=="string"&&e.length>0?e:void 0}function Aa(e){return ot(e.resolvedTokens?.logoUrl)??ot(e.brandData?.assets?.logo)??ot(e.brandData?.assets?.logoUrl)??ot(e.brandData?.logoUrl)}function Ta(e){return ot(e.resolvedTokens?.colors?.primary)??ot(e.brandData?.colors?.primary)??ot(e.brandData?.enhancedColors?.palette?.[0]?.hex)}function Tp(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:i,role:o}=r;typeof i=="string"&&n.push({hex:i,...typeof o=="string"?{role:o}:{}})}}return n}function ux(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 gx(e){let t=ot(e.extractedFrom)??ot(e.normalizedUrl),n=Aa(e),r=Ta(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 Op(e){return Pa(e)?e.items.map(gx):e.brandings.map(ux)}import{createHash as fx}from"crypto";import{Command as yt,InvalidArgumentError as hx}from"commander";var yx=["x","instagram","facebook","linkedin","tiktok","youtube"],bx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ht(e){if(!bx.test(e))throw new hx("Expected a UUID returned by the corresponding list command.");return e}function bi(e,t){return fx("sha256").update(JSON.stringify([e,...t])).digest("hex")}function $n(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var wx=new yt("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",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await w();try{m(await p("getBrandCompetitors",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){$n(t,"Competitor list failed")}}),vx=new yt("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",ht).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 w();let n={brandingId:t.brandingId,name:e,resolveHandle:t.resolveHandle,teamId:t.teamId,website:t.website,xAvatarUrl:t.xAvatarUrl,xHandle:t.xHandle};try{m(await p("addCompetitor",n,bi("addCompetitor",[t.brandingId??"default",e.trim(),t.website??null,t.xHandle??null,t.xAvatarUrl??null,t.resolveHandle])))}catch(r){$n(r,"Competitor write failed")}}),Ix=new yt("delete").description("Remove one competitor by the stable ID from competitor list").argument("<competitor-id>","Competitor UUID",ht).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await w(),t.yes||(a("Refusing to remove a competitor without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandCompetitor",{brandingId:t.brandingId,competitorId:e,teamId:t.teamId},bi("deleteBrandCompetitor",[t.brandingId??"default",e])))}catch(n){$n(n,"Competitor removal failed")}}),$p=new yt("competitor").description("List, add, update, or remove a brand's competitor watch rows").addCommand(wx).addCommand(vx).addCommand(Ix),kx=new yt("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",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async e=>{await w();try{m(await p("listBrandSocialHandles",{brandingId:e.brandingId,teamId:e.teamId}))}catch(t){$n(t,"Social-account list failed")}}),xx=new yt("add").description("Record one social account and print its stable saved row").argument("<platform>","Social network: x | instagram | facebook | linkedin | tiktok | youtube",b("platform",yx)).argument("<handle>","Account handle on that social network").option("--branding-id <id>","Brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t,n)=>{await w();try{m(await p("addBrandSocialHandle",{brandingId:n.brandingId,handle:t,platform:e,teamId:n.teamId},bi("addBrandSocialHandle",[n.brandingId??"default",e,t.replace(/^@/,"")])))}catch(r){$n(r,"Social-account write failed")}}),Rx=new yt("delete").description("Remove one social account by the stable ID from social list").argument("<handle-id>","Social-handle UUID",ht).option("--branding-id <id>","Owning brand UUID; defaults to the workspace brand",ht).option("--team-id <id>","Workspace ID; defaults to the selected workspace").option("--yes","Confirm removal without an interactive prompt").action(async(e,t)=>{await w(),t.yes||(a("Refusing to remove a social account without --yes."),process.exit(s.INVALID_INPUT));try{m(await p("deleteBrandSocialHandle",{brandingId:t.brandingId,handleId:e,teamId:t.teamId},bi("deleteBrandSocialHandle",[t.brandingId??"default",e])))}catch(n){$n(n,"Social-account removal failed")}}),Dp=new yt("social").description("List, record, or remove the social accounts owned by a brand").addCommand(kx).addCommand(xx).addCommand(Rx);import{createHash as Cx}from"crypto";import{Command as Np}from"commander";var Sx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ex(e){Sx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Px(e){return Cx("sha256").update(e).digest("hex").slice(0,32)}var Lp=new Np("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 w(),Ex(e);let n={brandId:e,teamId:t.teamId};try{let r=await p("syncBrandToPresentations",n,Px(`syncBrandToPresentations:${e}`));if(t.wait===!1){m(r);return}m(await Mc(r.runId,t.teamId))}catch(r){a(u(r,"Sync failed")),process.exit(s.GENERAL_ERROR)}}),Up=new Np("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 w();try{m(await R("syncBrandToPresentations",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Ax}from"crypto";import{readFile as Tx}from"fs/promises";import{Command as _p}from"commander";var Ox=["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 $x(e){let t=e.split(".").filter(Boolean);for(let n=t.length;n>=2;n--){let r=t.slice(0,n).join(".");if(Ox.includes(r))return{fieldPath:t.slice(n),nodeKey:r}}return{fieldPath:t.slice(2),nodeKey:t.slice(0,2).join(".")}}function Dx(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 i=n.slice(0,r).trim(),o=n.slice(r+1);if(i.split(".").filter(Boolean).length<2)throw new Error(`"${i}" is not a brand token key. Expected something like color.primary or typography.h1.size`);let{fieldPath:l,nodeKey:d}=$x(i),g=Nx(o);if(l.length===0){t[d]=g;continue}let y=t[d],v=y&&typeof y=="object"&&!Array.isArray(y)?y:{},x=v;for(let T of l.slice(0,-1)){let L=x[T],$=L&&typeof L=="object"&&!Array.isArray(L)?L:{};x[T]=$,x=$}x[l[l.length-1]]=g,t[d]=v}return t}function Nx(e){return e==="true"?!0:e==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(e)?Number(e):e}function Lx(e,t){return e===void 0?{assignments:[...t]}:e.includes("=")?{assignments:[e,...t]}:{assignments:[...t],brandId:e}}var jp=new _p("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 p("getBrandProfile",{brandId:e,format:t.format,teamId:t.teamId});if(t.format==="md"&&typeof n.designMd=="string"){console.log(n.designMd);return}m(n)}catch(n){a(u(n,"Profile read failed")),process.exit(s.GENERAL_ERROR)}}),qp=new _p("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:i}=Lx(e,t),o;try{o=r.length>0?Dx(r):void 0}catch(l){a(u(l,"Invalid token pair")),process.exit(s.INVALID_INPUT)}let c;if(n.designMd)try{c=await Tx(n.designMd,"utf8")}catch(l){a(`Could not read ${n.designMd}: ${u(l)}`),process.exit(s.INVALID_INPUT)}!o&&!c&&(a("Nothing to write. Pass token assignments (color.primary=#114b97) or --design-md <file>."),process.exit(s.INVALID_INPUT));try{m(await p("updateBrandTokens",{brandId:i,designMd:c,publish:n.publish===!1?!1:void 0,teamId:n.teamId,tokens:o},Ax()))}catch(l){a(u(l,"Write failed")),process.exit(s.GENERAL_ERROR)}});import{createHash as Ux}from"crypto";import{Command as Ii}from"commander";var _x=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,vi=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function $a(e){_x.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Mp(e){return Ux("sha256").update(e).digest("hex").slice(0,32)}function Vp(e){if(vi.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${vi.join(", ")}.`),process.exit(s.INVALID_INPUT)}function wi(e){return e===""?null:e}function Oa(e,t){if(t==="")return null;let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${u(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 jx(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 qx(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 Mx=new Ii("list").description("List a brand's per-channel design variants").argument("<brand-id>","Brand profile ID").option("--channel <key>",`One of: ${vi.join(", ")}`).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),$a(e),t.channel!==void 0&&Vp(t.channel);try{m(await p("listBrandVariants",{brandId:e,channelKey:t.channel,teamId:t.teamId}))}catch(n){a(u(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),Vx=new Ii("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: ${vi.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 w(),$a(e),t.channel!==void 0&&Vp(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=jx("--default",t.default)),t.colors!==void 0&&(n.colors=Oa("--colors",t.colors)),t.logoTreatment!==void 0&&(n.logoTreatment=Oa("--logo-treatment",t.logoTreatment)),t.backgroundGradient!==void 0&&(n.backgroundGradient=Oa("--background-gradient",t.backgroundGradient)),t.aspect!==void 0&&(n.aspect=wi(t.aspect)),t.maxSeconds!==void 0&&(n.maxSeconds=qx(t.maxSeconds)),t.voiceTone!==void 0&&(n.voiceOverride=t.voiceTone===""?null:{tone:t.voiceTone}),t.openingStyle!==void 0&&(n.openingStyle=wi(t.openingStyle)),t.logoPosition!==void 0&&(n.logoPosition=wi(t.logoPosition)),t.constraints!==void 0&&(n.constraints=wi(t.constraints));try{m(await p("setBrandVariant",n,t.variant===void 0?void 0:Mp(`setBrandVariant:${e}:${t.variant}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Set failed")),process.exit(s.GENERAL_ERROR)}}),Fx=new Ii("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 w(),$a(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{m(await p("deleteBrandVariant",{brandId:e,teamId:t.teamId,variantId:t.variant},Mp(`deleteBrandVariant:${e}:${t.variant}`)))}catch(n){a(u(n,"Delete failed")),process.exit(s.GENERAL_ERROR)}}),Fp=new Ii("variant").description("Per-channel brand design variant commands").addCommand(Mx).addCommand(Vx).addCommand(Fx);import{createHash as Bx}from"crypto";import{Command as La}from"commander";var Gx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Da=["deck-16-9","reel-9-16","story-9-16","walkthrough-16-9"];function Kx(e){Gx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Wx(e){if(Da.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${Da.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Jx(e,t){let n;try{n=JSON.parse(t)}catch(r){a(`${e} is not valid JSON: ${u(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 zx(e){return Bx("sha256").update(e).digest("hex").slice(0,32)}var Na=["replace","append"];function Hx(e){if(Na.includes(e))return e;a(`"${e}" is not a mode. Pass one of: ${Na.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Xx(e){let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=6)return t;a(`"${e}" is not a count. Pass a whole number from 1 to 6.`),process.exit(s.INVALID_INPUT)}var Yx=new La("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: ${Da.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("--mode <mode>",`One of: ${Na.join(", ")}. append adds new variants and deletes nothing; replace (default) swaps the generated set`).option("--count <n>","With --mode append, add only the first N generated variants (1-6)").option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),e!==void 0&&Kx(e),t.channel!==void 0&&Wx(t.channel),t.mode!==void 0&&Hx(t.mode);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.mode!==void 0&&(n.mode=t.mode),t.count!==void 0&&(n.count=Xx(t.count)),t.tone!==void 0&&(n.brandTone=t.tone),t.style!==void 0&&(n.brandStyle=t.style),t.colors!==void 0&&(n.sourceColors=Jx("--colors",t.colors));try{let r=await p("generateBrandVariations",n,zx(`generateBrandVariations:${e??"preview"}:${t.channel??"deck-16-9"}${n.mode==="append"?`:append:${n.count??""}`:""}`));if(t.wait===!1){m(r);return}m(await Lc(r.runId,t.teamId))}catch(r){a(u(r,"Generate failed")),process.exit(s.GENERAL_ERROR)}}),Qx=new La("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 w();try{m(await R("generateBrandVariations",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Bp=new La("variations").description("Generated brand design variations").addCommand(Yx).addCommand(Qx);import{createHash as Zx}from"crypto";import{Command as ki}from"commander";var Ua=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function _a(e){Ua.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function eR(e,t){if(t==="head"||Ua.test(t))return t;a(`${e} must be a version id or "head".`),process.exit(s.INVALID_INPUT)}function tR(e,t){if(Ua.test(t))return t;a(`${e} must be a version id from \`branding version list\`.`),process.exit(s.INVALID_INPUT)}function nR(e){return Zx("sha256").update(e).digest("hex").slice(0,32)}var rR=new ki("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 w(),_a(e);try{m(await p("listBrandVersions",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"List failed")),process.exit(s.GENERAL_ERROR)}}),iR=new ki("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 w(),_a(e);let n={brandId:e,teamId:t.teamId};t.from!==void 0&&(n.from=tR("--from",t.from)),t.to!==void 0&&(n.to=eR("--to",t.to));try{m(await p("diffBrandVersions",n))}catch(r){a(u(r,"Diff failed")),process.exit(s.GENERAL_ERROR)}}),oR=new ki("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 w(),_a(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{m(await p("publishBrandVersion",n,nR(`publishBrandVersion:${e}:${t.label??"auto"}`)))}catch(r){a(u(r,"Publish failed")),process.exit(s.GENERAL_ERROR)}}),Gp=new ki("version").description("Brand version history commands").addCommand(rR).addCommand(iR).addCommand(oR);import{randomUUID as aR}from"crypto";import{Command as xi}from"commander";var sR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function qa(e){sR.test(e)||(a(`"${e}" is not a brand id.`),process.exit(s.INVALID_INPUT))}function ja(e,t){try{return JSON.parse(e)}catch{a(`${t} must contain valid JSON.`),process.exit(s.INVALID_INPUT)}}function Wp(e){if(e===void 0)return;let t=Number(e);return(!Number.isInteger(t)||t<0)&&(a("--expected-revision must be a non-negative integer."),process.exit(s.INVALID_INPUT)),t}var dR=new xi("get").description("Read a brand's video voice, presenter and intro/outro defaults").argument("<brand-id>","Brand profile ID").action(async e=>{await w(),qa(e);try{m(await p("getBrandVideoDefaults",{brandId:e}))}catch(t){a(u(t,"Read failed")),process.exit(s.GENERAL_ERROR)}});function Kp(e,t,n){return new xi(e).description(`Replace a brand's saved video ${n}`).argument("<brand-id>","Brand profile ID").requiredOption(`--${n} <json>`,`The complete ${n} list as JSON`).option("--expected-revision <number>","Revision read before this write").action(async(r,i)=>{await w(),qa(r);let o=i[n],c={brandId:r,[n]:ja(o,`--${n}`)},l=Wp(i.expectedRevision);l!==void 0&&(c.expectedRevision=l);try{m(await p(t,c))}catch(d){a(u(d,"Save failed")),process.exit(s.GENERAL_ERROR)}})}var cR=new xi("set-bookends").description("Set or clear a brand's default opening and closing card scenes").argument("<brand-id>","Brand profile ID").option("--intro-json <json>",'Opening scene as a JSON card object, e.g. {"kind":"image","imageSource":"brand-logo","title":"Acme","durationSeconds":6}').option("--outro-json <json>","Closing scene as a JSON card object").option("--clear-intro","Remove the default opening scene").option("--clear-outro","Remove the default closing scene").option("--expected-revision <number>","Revision read before this write").option("--idempotency-key <key>","Reuse a request key to retry this same write").action(async(e,t)=>{await w(),qa(e);let n=t.clearIntro?null:t.introJson===void 0?void 0:ja(t.introJson,"--intro-json"),r=t.clearOutro?null:t.outroJson===void 0?void 0:ja(t.outroJson,"--outro-json");n===void 0&&r===void 0&&(a("Provide --intro-json/--outro-json, or --clear-intro/--clear-outro."),process.exit(s.INVALID_INPUT));let i=Wp(t.expectedRevision);try{m(await p("setBrandVideoBookends",{brandId:e,...n!==void 0?{intro:n}:{},...r!==void 0?{outro:r}:{},...i!==void 0?{expectedRevision:i}:{}},t.idempotencyKey??aR()))}catch(o){a(u(o,"Save failed")),process.exit(s.GENERAL_ERROR)}}),Jp=new xi("video-defaults").description("Manage a brand's video voice, presenter and intro/outro defaults").addCommand(dR).addCommand(Kp("set-voices","setBrandVideoVoices","voices")).addCommand(Kp("set-presenters","setBrandVideoPresenters","presenters")).addCommand(cR);import{createHash as lR}from"crypto";import{Command as lr}from"commander";var mR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Va(e){mR.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Ma(e,t=[]){return[...t,e]}function zp(e){return lR("sha256").update(e).digest("hex").slice(0,32)}var pR=new lr("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 w(),Va(e);try{m(await p("getBrandVoice",{brandId:e,teamId:t.teamId}))}catch(n){a(u(n,"Read failed")),process.exit(s.GENERAL_ERROR)}}),uR=new lr("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 w(),Va(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{m(await p("setBrandVoice",n,zp(`setBrandVoice:${e}:${JSON.stringify(n)}`)))}catch(r){a(u(r,"Write failed")),process.exit(s.GENERAL_ERROR)}}),gR=new lr("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",Ma).option("--text <text>","Pasted source material; repeat for several",Ma).option("--file <name:source>","Document to read, as name:source; repeat for several",Ma).option("--no-wait","Return the run id immediately instead of waiting").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),Va(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 i=r.indexOf(":");return(i<=0||i===r.length-1)&&(a(`--file must be name:source; got "${r}".`),process.exit(s.INVALID_INPUT)),{name:r.slice(0,i),source:r.slice(i+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 p("buildBrandVoice",n,zp(`buildBrandVoice:${JSON.stringify(n)}`));if(t.wait===!1){m(r);return}m(await _c(r.runId,t.teamId))}catch(r){a(u(r,"Build failed")),process.exit(s.GENERAL_ERROR)}}),fR=new lr("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 w();try{m(await R("buildBrandVoice",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Hp=new lr("voice").description("Brand voice and context commands").addCommand(pR).addCommand(uR).addCommand(gR).addCommand(fR);function vR(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<0)throw new Xp(`${e} expects a whole number of 0 or more.`);return n}}function IR(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new Xp(`${e} expects a whole number of 1+.`);return n}}var kR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,xR=50;function RR(e){let t=e.extractedFrom??e.normalizedUrl??null,n=Ta(e),r=Tp(e),i=Aa(e);if(De("Brand Profile"),console.log(),O("ID",e.id),O("Name",e.name),O("Source URL",t??Z.gray("None")),O("Default",e.isDefault?Z.green("Yes"):"No"),e.createdAt&&O("Created",new Date(e.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 y of r.slice(0,10)){let v=y.role?Z.gray(` (${y.role})`):"";console.log(` ${Z.bgHex(y.hex)(" ")} ${y.hex}${v}`)}}console.log()}i&&(console.log(Z.bold(" Logo")),console.log(` ${i}`),console.log());let o=e.brandData?.typography,c=e.resolvedTokens?.headingFont??o?.primary??o?.headings,l=e.resolvedTokens?.bodyFont??o?.secondary??o?.body;(c||l)&&(console.log(Z.bold(" Typography")),console.log(` Headings: ${c??"-"}`),console.log(` Body: ${l??"-"}`),console.log());let d=e.brandData?.confidence,g=e.brandData?.extractionMethod;(typeof d=="number"||typeof g=="string")&&(console.log(Z.bold(" Extraction")),typeof d=="number"&&console.log(` Confidence: ${Math.round(d*100)}%`),typeof g=="string"&&console.log(` Method: ${g}`),console.log()),console.log(Z.gray(" Use --format json for full details")),console.log()}var Yp=new Dn("branding").description("Read and manage workspace brands, design rules, assets, permissions, and social presence").addCommand(jp).addCommand(qp).addCommand(Tm).addCommand(Mm).addCommand(pp).addCommand(up).addCommand(Qm).addCommand(new Dn("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)",b("--filter",["all","mine","team"])).option("--sort <sort>","Sort key (created, name, updated)",b("--sort",["created","name","updated"])).option("--shape <shape>","Result shape: list (paged rows, default) or chat (compact matches)",b("--shape",["chat","list"])).option("--limit <n>","Page size (server default: 12 for the list shape, 50 for chat)",IR("--limit")).option("--offset <n>","Brands to skip before the page",vR("--offset")).option("--team-id <id>","Workspace ID").option("--json","Print the complete JSON response instead of a table").action(async e=>{await w();try{let t=e.shape??"list",n=await p("listBrandings",{filter:e.filter,limit:e.limit,offset:e.offset,search:e.search,shape:t,sort:e.sort,teamId:e.teamId});if(e.json){m(n);return}let r=Op(n);if(r.length===0){I("No brand profiles found"),console.log(),console.log(Z.gray(`Create one with: ${f.commands[0]} branding extract <url>`));return}console.log(ll(r));let i=e.offset??0;Pa(n)?n.hasMore&&console.log(Z.gray(` ${i+r.length} of ${n.total}. Next page: --offset ${i+r.length}`)):r.length>=(e.limit??xR)&&console.log(Z.gray(` Showing ${r.length} from --offset ${i}; there may be more. Next page: --offset ${i+r.length}`))}catch(t){a("The command failed. Please try again."),process.exit(t.exitCode??1)}})).addCommand(new Dn("get").description("Read one brand as a summary or complete JSON").argument("<id>","Brand profile ID").option("-f, --format <format>","Output format (summary, json)",b("--format",["summary","json"]),"summary").option("-o, --output <path>","Save JSON to file").option("--team-id <id>","Workspace ID").action(async(e,t)=>{if(await w(),!kR.test(e)){a(`"${e}" is not a brand id. Pass the UUID from \`${f.commands[0]} branding list\`, or search by name with \`${f.commands[0]} branding find <query>\`.`),process.exit(s.INVALID_INPUT);return}try{let r=(await p("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 bR(t.output,JSON.stringify(r,null,2)),C(`Brand profile saved to ${t.output}`);return}if(t.format==="json"){console.log(JSON.stringify(r,null,2));return}RR(r)}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Dn("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 w();try{let r=(await p("listBrandings",{search:e,shape:"chat",teamId:t.teamId})).brandings;if(r.length===0){I(`No brand profiles matching "${e}"`),console.log(Z.gray(` Extract one with: ${f.commands[0]} branding extract <url>`));return}console.log(`Found ${r.length} brand${r.length>1?"s":""}:
78
+ `);for(let i of r){let o=i.primaryColor?`${Z.bgHex(i.primaryColor)(" ")} ${i.primaryColor}`:"";console.log(` ${Z.bold(i.name)} ${Z.gray(i.id)}`),i.domain&&console.log(` ${Z.gray(i.domain)}`),o&&console.log(` ${o}`),console.log()}console.log(Z.gray(` Export with: ${f.commands[0]} branding get <id> -o branding.json`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Dn("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(e,t)=>{await w(),t.yes||(a("Pass --yes to confirm brand extraction."),process.exit(s.INVALID_INPUT));try{new URL(e.startsWith("http")?e:`https://${e}`)}catch{a("Invalid URL format"),process.exit(6)}let n=e.startsWith("http")?e:`https://${e}`,r=t.teamId??ve(),i=t.idempotencyKey??hR();t.approvalReceipt&&t.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let o=t.approvalReceiptStdin?yR(0,"utf8").trim():t.approvalReceipt;t.approvalReceiptStdin&&!o&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let c=wR({text:`Extracting branding from ${n}...`,stream:process.stdout}).start(),l;try{let d=await lc(n,r,o,t.skipExistingLookup,i);if(d.status==="needs_choice"){c.stop(),I(`This workspace already has ${d.matches.length} related brand${d.matches.length===1?"":"s"} for ${n}. Nothing was extracted and nothing was charged.`),console.log();for(let g of d.matches)console.log(` ${Z.bold(g.name??"Untitled")}`),console.log(` ${Z.gray(g.id)}`),g.extractedFrom&&console.log(` ${Z.gray(g.extractedFrom)}`);console.log(),I(`Use one of the above, or re-run with --skip-existing-lookup to extract ${n} anyway.`),l=s.INVALID_INPUT}else c.succeed("Brand extraction started"),console.log(JSON.stringify(d,null,2)),I(`Check progress with: ${f.commands[0]} branding status ${d.runId}`),console.log()}catch(d){let g=u(d);g.includes("approval")&&(c.stop(),a(g),console.log(),I(`Retry with the receipt and the same key: --approval-receipt <receipt> --idempotency-key ${i}`),process.exit(s.INVALID_INPUT)),c.fail("Extraction failed"),a(g),process.exit(d.exitCode??1)}l!==void 0&&process.exit(l)})).addCommand(new Dn("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(e,t)=>{try{m(await R("extractBranding",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}})).addCommand(Zm).addCommand(Hm).addCommand(np).addCommand(ep).addCommand(rp).addCommand(ip).addCommand(op).addCommand(tp).addCommand($p).addCommand(ap).addCommand(Fm).addCommand(Bm).addCommand(Wm).addCommand(Ip).addCommand(Fp).addCommand(Bp).addCommand(Gp).addCommand(Hp).addCommand(Jp).addCommand(Jm).addCommand(_m).addCommand(jm).addCommand(Ep).addCommand(Ap).addCommand(gp).addCommand(fp).addCommand(Lp).addCommand(Up).addCommand(hp).addCommand(Dp);import mr from"chalk";import{Command as Nn}from"commander";function CR(e){switch(e.background){case"color":{if(!e.backgroundColor)throw new Error("--background color needs --background-color <hex>, e.g. #1d4ed8");return{hex:e.backgroundColor,kind:"color"}}case"image":{if(!e.backgroundImage)throw new Error("--background image needs --background-image <url>");return{fit:e.fit,kind:"image",url:e.backgroundImage}}default:return{kind:e.background}}}function Qp(e,t){return{background:CR(t),name:e,presenterProfileId:t.presenter,...t.voiceId?{voiceId:t.voiceId}:{}}}function Ri(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.id);return}C(`${e.name} (${e.id})`),I(` Presenter: ${e.presenterProfileId}`),I(` Backdrop: ${SR(e.background)}`),e.voiceId&&I(` Voice: ${e.voiceId}`)}function SR(e){switch(e.kind){case"color":return`color ${e.hex}`;case"image":return`image ${e.url} (${e.fit})`;default:return e.kind}}function Zp(e){return e.requiredOption("--presenter <profileId>",`Trained personal presenter id (pp_*), from \`${f.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",b("--format",["human","json","quiet"]),"human")}var ER=new Nn("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",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await rl({...e.brandingId?{brandingId:e.brandingId}:{},...e.castMemberId?{castMemberId:e.castMemberId}:{},...e.teamId?{teamId:e.teamId}:{}});if(e.format==="json"){m(t);return}if(e.format==="quiet"){for(let n of t.presets)console.log(n.id);return}if(t.presets.length===0){I("No presets saved yet.");return}for(let n of t.presets)Ri(n,"human")}catch(t){a(u(t)),process.exit(s.API_ERROR)}}),PR=Zp(new Nn("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(e,t)=>{try{let n=await il({castMemberId:t.castMemberId,...Qp(e,t),...t.teamId?{teamId:t.teamId}:{}});Ri(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),AR=Zp(new Nn("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(e,t)=>{try{let n=await ol({presetId:e,...Qp(t.name,t),...t.teamId?{teamId:t.teamId}:{}});Ri(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),TR=new Nn("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await al(e,t.teamId);if(t.format==="human"){C(`Retired "${n.preset.name}".`);return}Ri(n.preset,t.format)}catch(n){a(u(n)),process.exit(s.API_ERROR)}}),OR=new Nn("preset").description("Saved ways a cast member appears").addCommand(ER).addCommand(PR).addCommand(AR).addCommand(TR),Fa=new Nn("cast").description("The faces and voices your videos can use").addCommand(OR);Fa.addHelpText("after",`
79
+ ${mr.bold("Examples:")}
80
+ ${mr.gray("# List the saved presenter/backdrop/voice combinations")}
81
81
  $ ${f.commands[0]} cast preset list
82
82
 
83
- ${lr.bold("See also:")}
84
- ${lr.gray("# The presenter avatars, looks, and voices a preset is built from")}
83
+ ${mr.bold("See also:")}
84
+ ${mr.gray("# The presenter avatars, looks, and voices a preset is built from")}
85
85
  $ ${f.commands[0]} avatar options
86
86
 
87
- ${lr.gray("# Use a preset on one presentation-video scene")}
87
+ ${mr.gray("# Use a preset on one presentation-video scene")}
88
88
  $ ${f.commands[0]} presentation video presenter <project-id>
89
- `);import{randomUUID as AR}from"crypto";import{readFile as TR}from"fs/promises";import mr from"chalk";import{Command as Qp}from"commander";var OR=new Qp("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=e,r;e.includes("://")||(n=await TR(e,"utf8"),r=e);let i=await p("extractContent",{filename:t.filename??r,maxLength:Number.parseInt(t.maxLength,10),mimeType:t.mimeType,reason:t.reason,source:n,teamId:t.teamId},t.idempotencyKey??AR());t.format!=="quiet"&&m(i)}catch(n){a(u(n,"Extraction failed")),process.exit(s.GENERAL_ERROR)}}),Va=new Qp("content").description("Extract normalized text from a URL, a local file, or an encoded document").addCommand(OR);Va.addHelpText("after",`
90
- ${mr.bold("Examples:")}
91
- ${mr.gray("# Normalized text from a local document")}
89
+ `);import{randomUUID as $R}from"crypto";import{readFile as DR}from"fs/promises";import pr from"chalk";import{Command as eu}from"commander";var NR=new eu("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=e,r;e.includes("://")||(n=await DR(e,"utf8"),r=e);let i=await p("extractContent",{filename:t.filename??r,maxLength:Number.parseInt(t.maxLength,10),mimeType:t.mimeType,reason:t.reason,source:n,teamId:t.teamId},t.idempotencyKey??$R());t.format!=="quiet"&&m(i)}catch(n){a(u(n,"Extraction failed")),process.exit(s.GENERAL_ERROR)}}),Ba=new eu("content").description("Extract normalized text from a URL, a local file, or an encoded document").addCommand(NR);Ba.addHelpText("after",`
90
+ ${pr.bold("Examples:")}
91
+ ${pr.gray("# Normalized text from a local document")}
92
92
  $ ${f.commands[0]} content extract ./paper.pdf
93
93
 
94
- ${mr.bold("See also:")}
95
- ${mr.gray("# Web pages, with page metadata and cost reporting")}
94
+ ${pr.bold("See also:")}
95
+ ${pr.gray("# Web pages, with page metadata and cost reporting")}
96
96
  $ ${f.commands[0]} scrape https://example.com/post
97
97
 
98
- ${mr.gray("# Spoken words out of audio or video")}
98
+ ${pr.gray("# Spoken words out of audio or video")}
99
99
  $ ${f.commands[0]} transcript --help
100
- `);import{existsSync as $R,readFileSync as DR}from"fs";import NR,{resolve as eu}from"path";import le from"chalk";import{Command as LR}from"commander";function Fa(e,t){if(t)try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("expected an object");return n}catch(n){throw new Error(`${e} must be a valid JSON object.`,{cause:n})}}function UR(e,t,n){if(e!=="as-is"||t)return t;let r=n.filter(i=>i.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 tu=new LR("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)",b("--family",["minimal","editorial","bold","dashboard"])).option("--generation-request-id <id>","Generation funnel correlation ID").option("--image-policy <policy>","Image policy (auto, none)",b("--image-policy",["auto","none"])).option("--content-sources <json>","Canonical content-sources JSON object").option("--source-mode <mode>","Attached deck mode (reference, as-is)",b("--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)",b("--format",["human","json","quiet"])).option("-o, --output <format>","Output format (human, json, quiet) \u2014 short form of --format",b("--output",["human","json","quiet"])).option("--no-stream","Wait for completion without streaming progress").option("--wait","Poll until generation completes").option("--wait-timeout <seconds>",`Max seconds --wait polls before giving up (default ${18e5/1e3})`).option("--idempotency-key <key>","Stable retry key").option("--approval-receipt <receipt>","Server-issued approval receipt for this exact generation request").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--debug","Enable debug logging").option("--open","Open in browser after creation").option("--id <uuid>","Use a specific UUID for the presentation").option("--studio","Studio mode: use current directory name as presentation ID (auto-links to Studio preview)").action(async(e,t)=>{if(t.output=t.format??t.output,await w(),t.stdin&&t.approvalReceiptStdin)throw new Error("Content stdin and approval receipt stdin cannot share the same input stream.");let n=_(t),r=t.idempotencyKey??Q({command:"presentation:create",payload:{...t,approvalReceipt:void 0,approvalReceiptStdin:void 0,idempotencyKey:void 0,topic:e},workspaceId:t.teamId??"configured-default"}),i=18e5;if(t.waitTimeout!==void 0){let j=Number(t.waitTimeout);(!Number.isFinite(j)||j<=0)&&(a("--wait-timeout must be a positive number of seconds"),process.exit(6)),i=j*1e3}let o;t.slides!==void 0&&(o=parseInt(t.slides,10),(Number.isNaN(o)||o<1||o>20)&&(a("Slide count must be between 1 and 20"),process.exit(6)));let c=["best","balanced","fast","ultrafast","instant","image-min","image","image-max"];t.mode&&!c.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Valid: ${c.join(", ")}`),process.exit(6));let l=["smart","fast","balanced","best"];t.imageTier&&!l.includes(t.imageTier)&&(a(`Invalid image tier: ${t.imageTier}. Valid: ${l.join(", ")}`),process.exit(6));let d=["creative","professional","educational","formal","casual"];t.tone&&!d.includes(t.tone)&&(a(`Invalid tone: ${t.tone}. Valid: ${d.join(", ")}`),process.exit(6));let g=["minimal","concise","detailed","extensive"];t.amount&&!g.includes(t.amount)&&(a(`Invalid amount: ${t.amount}. Valid: ${g.join(", ")}`),process.exit(6));let y=["freeform","brand-only","brand-plus-style","style-only","no-styling"];t.styling&&!y.includes(t.styling)&&(a(`Invalid styling: ${t.styling}. Valid: ${y.join(", ")}`),process.exit(6));let v=["quick","moderate","deep","profound"];t.thinkingDepth&&!v.includes(t.thinkingDepth)&&(a(`Invalid thinking-depth: ${t.thinkingDepth}. Valid: ${v.join(", ")}`),process.exit(6));let x=["inform","persuade","train","learn","entertain","report"];t.goal&&!x.includes(t.goal)&&(a(`Invalid goal: ${t.goal}. Valid: ${x.join(", ")}`),process.exit(6));let T=["blue","violet","rose","orange","green"];t.theme&&!T.includes(t.theme)&&(a(`Invalid theme: ${t.theme}. Valid: ${T.join(", ")}`),process.exit(6));let L=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];t.decorations&&!L.includes(t.decorations)&&(a(`Invalid decorations: ${t.decorations}. Valid: ${L.join(", ")}`),process.exit(6));let $=t.theme||t.primaryColor||t.secondaryColor||t.accentColor||t.backgroundColor||t.foregroundColor||t.decorations;$&&t.mode&&t.mode!=="instant"&&(a("--theme, --primary-color, --decorations and other color options are only supported with --mode instant"),process.exit(6));let N=t.mode??($?"instant":"fast"),S=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[j,we]of[["primary-color",t.primaryColor],["secondary-color",t.secondaryColor],["accent-color",t.accentColor],["background-color",t.backgroundColor],["foreground-color",t.foregroundColor]])we&&!S.test(we)&&(a(`Invalid ${j}: ${we}. Must be hex (e.g., #0066CC)`),process.exit(6));try{t.output!=="json"&&t.output!=="quiet"&&process.stdout.write(le.gray("Checking generation limits... "));let j=await mc(N,o??10,t.teamId);if(t.output!=="json"&&t.output!=="quiet"){console.log(le.green("\u2713"));let we=j.remaining[N],ue=j.limits[N],St=we===void 0||ue===void 0?"":` | ${N}: ${we}/${ue} remaining`;console.log(le.gray(` Plan: ${j.planName}${St}`))}}catch(j){t.output==="json"?console.log(JSON.stringify({success:!1,error:"The operation could not be completed."})):(console.log(le.red("\u2717")),a("The command failed. Please try again.")),process.exit(j.exitCode??1)}let E=[];if(t.file&&t.file.length>0){for(let j of t.file)$R(eu(j))||(a(`File not found: ${j}`),process.exit(6));t.output!=="json"&&t.output!=="quiet"&&console.log(le.gray(`
101
- Uploading ${t.file.length} file(s)...`));try{E=await Qd(t.file.map(j=>eu(j)),(j,we,ue)=>{t.output!=="json"&&t.output!=="quiet"&&ue&&process.stdout.write(`\r ${le.cyan("\u2B06")} Uploading: ${ue} (${j+1}/${we})`)},{idempotencyKey:r}),t.output!=="json"&&t.output!=="quiet"&&console.log(`\r ${le.green("\u2713")} Uploaded ${E.length} file(s) `)}catch{a("Failed to upload files. Please try again."),process.exit(1)}}let A;!t.approvalReceiptStdin&&(t.stdin||!process.stdin.isTTY)&&(A=await _R(),t.stdin&&!A&&(a("No content received from stdin"),process.exit(6)));let D=t.context;if(t.contextFile)try{D=DR(t.contextFile,"utf-8"),D.trim()||(a(`Context file is empty: ${t.contextFile}`),process.exit(6))}catch{a(`Failed to read context file: ${t.contextFile}`),process.exit(6)}!A&&!D&&!t.additionalContext&&!t.contentSources&&!t.sourcePresentation&&E.length===0&&(a("Context is required to create a presentation."),console.log(),console.log(le.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(le.gray(" -c, --context <text> Inline text context")),console.log(le.gray(" --context-file <path> Read from a file")),console.log(le.gray(` cat file | ${f.commands[0]} Pipe content`)),process.exit(6));let re=[...E];A&&re.push({id:`stdin-${r}`,content:A,title:"Piped Content",mime:"text/plain",selected:!0}),D&&re.push({id:`context-${r}`,content:D,title:"Context",mime:"text/plain",selected:!0});let _e,Id=t.primaryColor||t.secondaryColor||t.accentColor||t.backgroundColor||t.foregroundColor;(t.theme||Id||t.decorations)&&(_e={},t.theme&&(_e.preset=t.theme),Id&&(_e.custom={},t.primaryColor&&(_e.custom.primary=t.primaryColor),t.secondaryColor&&(_e.custom.secondary=t.secondaryColor),t.accentColor&&(_e.custom.accent=t.accentColor),t.backgroundColor&&(_e.custom.background=t.backgroundColor),t.foregroundColor&&(_e.custom.foreground=t.foregroundColor)),t.decorations&&(_e.decorations=t.decorations));try{let j=Fa("--content-sources",t.contentSources),we=UR(t.sourceMode,Fa("--source-presentation",t.sourcePresentation),E),ue=await Zd({topic:e,...t.additionalContext&&{additionalContext:t.additionalContext},...o!==void 0&&{slideCount:o},mode:N,...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:Fa("--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},...we&&{sourcePresentation:we},...t.widgetSessionId&&{widgetSessionId:t.widgetSessionId},..._e&&{theme:_e},...t.studio?{documentId:NR.basename(process.cwd())}:t.id?{documentId:t.id}:{},...j?{contentSources:j}:re.length>0&&{contentSources:{uploadedFiles:re,contextFiles:[]}}},r,n);if(!t.wait){t.output==="json"?console.log(JSON.stringify({success:!0,run:ue},null,2)):t.output!=="quiet"&&(C("Presentation generation queued"),O("Run ID",ue.runId),O("Status",ue.status),console.log(le.gray(` Check later with presentation status ${ue.runId}`)));return}let St=await Jl({poll:()=>R("createSlides",ue.runId,t.teamId),isDone:je=>je.done,intervalMs:je=>(je.nextPollAfterSeconds??5)*1e3,onValue:je=>{t.output!=="json"&&t.output!=="quiet"&&console.log(le.gray(` ${je.message}`))},timeoutMs:i,timeoutError:je=>new kn("Generation is still running, but --wait stopped polling.",{runId:ue.runId,timeoutMs:je})});if(St.error)throw new Error(ge(St.error));let Et=St.entity?await fn(St.entity.id):void 0;if(t.output==="json")console.log(JSON.stringify({success:!0,presentation:Et,run:St,viewUrl:Et?yn(Et.slug,t.language??"en"):void 0},null,2));else{console.log(),C("Presentation created successfully"),console.log(),O("Title",Et?.title??e),O("Slides",String(Et?.numberOfSlides??o??"\u2014")),console.log();let je=Et?yn(Et.slug,t.language??"en"):"N/A";je!=="N/A"&&(console.log(le.bold(" Open: ")+le.cyan.underline(je)),t.open&&await(await import("open")).default(je)),console.log()}}catch(j){if(j instanceof kn){let we=`${f.commands[0]} presentation status ${j.runId}`,ue=j.timeoutMs<1e3?`${j.timeoutMs}ms`:`${Math.round(j.timeoutMs/1e3)}s`;t.output==="json"?console.log(JSON.stringify({success:!1,error:`Timed out after ${ue} waiting for the run to finish.`,errorCode:"wait_timed_out",runId:j.runId,statusCommand:we})):(a(`Timed out after ${ue} waiting for the run to finish. It is still running.`),O("Run ID",j.runId),console.log(le.gray(` Check progress with ${we}`))),process.exit(1)}t.output==="json"?console.log(JSON.stringify(Ot(j)?zr({caught:j,error:"The operation could not be completed.",idempotencyKey:r}):{success:!1,error:"The operation could not be completed."})):Ot(j)?a(Jr(j,r)):a("The command failed. Please try again."),process.exit(j.exitCode??1)}});async function _R(){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 Ga}from"commander";function Ba(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 jR=new Ga("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{m(await p("listCreditActivity",{limit:e.limit===void 0?void 0:Ba(e.limit,"--limit"),offset:e.offset===void 0?void 0:Ba(e.offset,"--offset"),teamId:e.teamId}))}catch(t){a(u(t,"Reading credit activity failed")),process.exit(s.GENERAL_ERROR)}}),qR=new Ga("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{m(await p("getCreditActivityGroup",{groupId:e,groupType:t.groupType,limit:t.limit===void 0?void 0:Ba(t.limit,"--limit"),teamId:t.teamId}))}catch(n){a(u(n,"Reading the credit activity group failed")),process.exit(s.GENERAL_ERROR)}}),nu=new Ga("credits").description("Credit spend reporting").addCommand(jR).addCommand(qR);import{randomUUID as MR}from"crypto";import{readFile as VR}from"fs/promises";import{Command as H,InvalidArgumentError as Ka}from"commander";function Fe(e){return t=>{if(!t.trim())throw new Ka(`${e} must not be blank.`);return t}}function FR(e,t){return[...t??[],e]}function BR(e){let t=e.indexOf(":"),n=e.slice(0,t),r=e.slice(t+1);if(n!=="user"&&n!=="agent"||!r.trim())throw new Ka("--mention must be user:<uuid> or agent:<uuid>.");return{kind:n,id:r}}function Mt(e,t){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<t)throw new Ka(`${e} must be a whole number of ${t} or more.`);return r}}function iu(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}function Ve(e){return iu(e).option("--idempotency-key <key>","Exact retry key; a new key is generated when omitted",Fe("--idempotency-key"))}function Ln(e){return iu(e).option("--cursor <cursor>","Continue from the previous nextCursor").option("--page-size <n>","Rows per page; follow nextCursor for all rows",Mt("--page-size",1),50)}function Un(e,t){return{documentId:e,cursor:t.cursor,pageSize:t.pageSize}}async function ru(e){if(e.startsWith("@file:"))return VR(e.slice(6),"utf8");if(e!=="-")return e;let t=[];for await(let n of process.stdin)t.push(Buffer.from(n));return Buffer.concat(t).toString("utf8")}async function ae(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:discussion:${MR()}`:void 0;try{m(await p(e,{...await n(),teamId:t.teamId},i))}catch(o){let c=u(o,"Discussion request failed.");a(`${c}${i?` For an exact retry, reuse --idempotency-key ${i}.`:""}`),process.exit(o instanceof P?o.exitCode:s.GENERAL_ERROR)}}function GR(){let e=Ve(new H("register").description("Register this authenticated credential as an external discussion agent").argument("<display-name>","Declared agent name; does not attest the executable",Fe("display-name"))).action(async(S,E)=>ae("registerDiscussionActor",E,()=>({displayName:S}),!0)),t=Ve(new H("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",b("permission",["none","read","comment"])).requiredOption("--expected-revision <revision>","Current grant revision; use 0 when no grant exists",Mt("--expected-revision",0))).action(async(S,E,A,D)=>ae("setDiscussionGrant",D,()=>({documentId:S,actorId:E,permission:A,expectedRevision:D.expectedRevision}),!0)),n=Ln(new H("list").description("Read one page of external-agent grants for a private deck").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionGrants",E,()=>Un(S,E))),r=Ve(new H("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",Fe("--anchor-slide-id")).option("--room-id <id>","Post into this guest review room; omit for the internal space",Fe("--room-id")).option("--mention <target>","Mention a team member or roster agent: user:<uuid> or agent:<uuid>; repeatable",(S,E)=>[...E??[],BR(S)])).action(async(S,E,A)=>ae("postDiscussionMessage",A,async()=>({documentId:S,threadId:A.threadId,anchorSlideId:A.anchorSlideId,roomId:A.roomId,body:Fe("body")(await ru(E)),mentions:A.mention}),!0)),i=Ve(new H("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",b("state",["open","resolved"])).requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1))).action(async(S,E,A,D)=>ae("setDiscussionState",D,()=>({documentId:S,threadId:E,state:A,expectedRevision:D.expectedRevision}),!0)),o=Ln(new H("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",Fe("--anchor-slide-id")).option("--room-id <id>","Only threads in this guest review room; 'internal' selects the member space",Fe("--room-id"))).action(async(S,E)=>ae("listDiscussionThreads",E,()=>({...Un(S,E),anchorSlideId:E.anchorSlideId,roomId:E.roomId===void 0?void 0:E.roomId==="internal"?null:E.roomId}))),c=Ln(new H("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(S,E,A)=>ae("readDiscussionThread",A,()=>({...Un(S,A),threadId:E}))),l=Ln(new H("events").description("Read one ordered page of durable discussion events; resume with nextCursor").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("readDiscussionEvents",E,()=>Un(S,E))),d=Ve(new H("assign").description("Assign one accountable team member to a thread; 'none' clears the assignee").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<assignee-user-id>","Team member user UUID, or 'none' to unassign").requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1))).action(async(S,E,A,D)=>ae("setDiscussionAssignee",D,()=>({documentId:S,threadId:E,assigneeUserId:A.toLowerCase()==="none"?null:A,expectedRevision:D.expectedRevision}),!0)),g=Ve(new H("reviewers").description("Replace a thread's requested reviewers; repeat --reviewer per member, omit all to clear").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1)).option("--reviewer <user-id>","Team member user UUID to request review from; repeatable",FR)).action(async(S,E,A)=>ae("setDiscussionReviewers",A,()=>({documentId:S,threadId:E,reviewerUserIds:A.reviewer??[],expectedRevision:A.expectedRevision}),!0)),y=Ln(new H("mentionables").description("List team members and roster agents that can be mentioned on a deck").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionMentionables",E,()=>Un(S,E))),v=Ve(new H("update").description("Edit your own discussion message; sets editedAt").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<message-id>","Discussion message UUID").argument("<body>","Replacement message: literal text, @file:<path> for a UTF-8 file, or '-' for stdin")).action(async(S,E,A,D,re)=>ae("updateDiscussionMessage",re,async()=>({documentId:S,threadId:E,messageId:A,body:Fe("body")(await ru(D))}),!0)),x=Ve(new H("visibility").description("Hide or restore a discussion message; authors hide their own, members moderate").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<message-id>","Discussion message UUID").argument("<hidden>","Visibility: hide or show",b("hidden",["hide","show"]))).action(async(S,E,A,D,re)=>ae("setDiscussionMessageVisibility",re,()=>({documentId:S,threadId:E,messageId:A,hidden:D==="hide"}),!0)),T=Ve(new H("create").description("Mint a guest review link pinned to the presentation's current revision").argument("<document-id>","Presentation document family UUID").requiredOption("--room-scope <scope>","isolated: private room for this link; shared: the document's shared guest room",b("room-scope",["isolated","shared"])).option("--post-policy <policy>","unverified: name-only guests may post; verified: email-verified guests only",b("post-policy",["unverified","verified"])).option("--label <label>","Owner-facing link name",Fe("--label")).option("--recipient-email <email>","Optional intended recipient address",Fe("--recipient-email")).option("--expires-at <iso>","Absolute expiry timestamp (ISO 8601)",Fe("--expires-at"))).action(async(S,E)=>ae("createDiscussionReviewLink",E,()=>({documentId:S,roomScope:E.roomScope,postPolicy:E.postPolicy,label:E.label,recipientEmail:E.recipientEmail,expiresAt:E.expiresAt}),!0)),L=Ln(new H("list").description("List a deck's guest review links and their state").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionReviewLinks",E,()=>Un(S,E))),$=Ve(new H("update").description("Update a review link's label, posting policy, expiry or pinned revision").argument("<document-id>","Presentation document family UUID").argument("<link-id>","Review link UUID").requiredOption("--expected-revision <revision>","Current link revision from review-link list",Mt("--expected-revision",1)).option("--label <label>","New label; 'none' clears it").option("--post-policy <policy>","unverified or verified",b("post-policy",["unverified","verified"])).option("--expires-at <iso>","New expiry (ISO 8601); 'none' clears it").option("--repin","Move the pin to the document's latest revision")).action(async(S,E,A)=>ae("updateDiscussionReviewLink",A,()=>({documentId:S,linkId:E,expectedRevision:A.expectedRevision,label:A.label===void 0?void 0:A.label==="none"?null:A.label,postPolicy:A.postPolicy,expiresAt:A.expiresAt===void 0?void 0:A.expiresAt==="none"?null:A.expiresAt,repin:A.repin}),!0)),N=Ve(new H("revoke").description("Revoke a guest review link; its sessions are fenced immediately").argument("<document-id>","Presentation document family UUID").argument("<link-id>","Review link UUID").requiredOption("--expected-revision <revision>","Current link revision from review-link list",Mt("--expected-revision",1))).action(async(S,E,A)=>ae("revokeDiscussionReviewLink",A,()=>({documentId:S,linkId:E,expectedRevision:A.expectedRevision}),!0));return new H("discussion").description("Collaborate on private decks with attributed human and external-agent messages").addCommand(new H("actor").description("Register the current external-agent credential").addCommand(e)).addCommand(new H("grant").description("Manage external-agent discussion access").addCommand(t).addCommand(n)).addCommand(r).addCommand(new H("state").description("Resolve or reopen discussion threads").addCommand(i)).addCommand(new H("message").description("Edit or moderate an existing discussion message").addCommand(v).addCommand(x)).addCommand(new H("review-link").description("Mint and manage guest review links").addCommand(T).addCommand(L).addCommand($).addCommand(N)).addCommand(d).addCommand(g).addCommand(y).addCommand(o).addCommand(c).addCommand(l)}var ou=GR();import{randomUUID as KR}from"crypto";import{readFile as WR}from"fs/promises";import{Command as bt}from"commander";var Wa=["text/markdown","text/csv","text/plain"];async function au(e){let t=e.content;if(t!==void 0&&t!=="-"&&!t.startsWith("@"))return t;if(t?.startsWith("@"))return WR(t.slice(1),"utf8");if(t==="-"||!process.stdin.isTTY)return JR();a("No document body. Pass --content <text>, --content @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function JR(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function Ri(e){return`cli:document:${e}:${KR()}`}function Vt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function zR(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 HR=new bt("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 ${Wa.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??zR(t.content?.startsWith("@")?t.content.slice(1):void 0);n||(a(`Cannot tell what this document is. Pass --media-type (${Wa.join(", ")}).`),process.exit(s.GENERAL_ERROR)),m(await p("createDocument",{content:await au(t),mediaType:n,summary:t.summary,teamId:t.teamId,title:e},Ri("create")))}catch(n){Vt(n,"Could not save the document")}}),XR=new bt("list").description("List the workspace's documents, newest first").option("--team-id <id>","Workspace ID").option("--media-type <type>",`Filter to one of ${Wa.join(", ")}`).option("--limit <n>","Maximum documents to return (default 50)").action(async e=>{try{m(await p("listDocuments",{limit:e.limit?Number(e.limit):void 0,mediaType:e.mediaType,teamId:e.teamId}))}catch(t){Vt(t,"Could not list documents")}}),YR=new bt("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 p("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
102
- `),process.stdout.write(r.content)}catch(n){Vt(n,"Could not read the document")}}),QR=new bt("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(e,t)=>{try{let n=t.content!==void 0;m(await p("updateDocument",{changeSummary:t.changeSummary,content:n?await au(t):void 0,documentId:e,expectedVersion:Number(t.expectedVersion),summary:t.summary,teamId:t.teamId,title:t.title},Ri("update")))}catch(n){Vt(n,"Could not update the document")}}),ZR=new bt("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(e,t)=>{try{!t.yes&&process.stdin.isTTY&&(a("Refusing to delete without confirmation. Re-run with --yes to remove this document."),process.exit(s.GENERAL_ERROR)),m(await p("deleteDocument",{documentId:e,teamId:t.teamId},Ri("delete")))}catch(n){Vt(n,"Could not delete the document")}}),eC=new bt("versions").description("List a document's version history").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("listDocumentVersions",{documentId:e,teamId:t.teamId}))}catch(n){Vt(n,"Could not list versions")}}),tC=new bt("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(e,t)=>{try{m(await p("restoreDocumentVersion",{documentId:e,expectedVersion:Number(t.expectedVersion),teamId:t.teamId,versionNumber:Number(t.versionNumber)},Ri("restore")))}catch(n){Vt(n,"Could not restore the version")}}),su=new bt("document").description("Create, read and edit Library documents").addCommand(HR).addCommand(XR).addCommand(YR).addCommand(QR).addCommand(ZR).addCommand(eC).addCommand(tC);import{writeFile as nC}from"fs/promises";import{resolve as du}from"path";import pr from"chalk";import{Command as rC}from"commander";import iC from"ora";var oC=["html","pdf","pptx"],Ja=new rC("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",b("--format",oC),"html").option("--team-id <id>","Workspace ID (uses configured default)").action(async(e,t)=>{await w();let n=iC("Exporting presentation...").start();try{let r=t.teamId??ve();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let i=await oc(e,t.format,{teamId:r}),o=t.output?du(t.output):du(process.cwd(),i.fileName);n.text="Downloading...";let c=await hn(i.downloadUrl);await nC(o,Buffer.from(c)),n.succeed("Export complete!"),console.log(),I(`File saved: ${o}`),I(`Format: ${i.format}`),I(`Slides: ${i.slideCount}`),I(`Size: ${aC(c.byteLength)}`),console.log()}catch(r){n.fail("Export failed"),a("The command failed. Please try again."),process.exit(r.exitCode??1)}});function aC(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}Ja.addHelpText("after",`
103
- ${pr.bold("Examples:")}
104
- ${pr.gray("# Self-contained interactive HTML (default)")}
100
+ `);import{existsSync as LR,readFileSync as UR}from"fs";import _R,{resolve as nu}from"path";import le from"chalk";import{Command as jR}from"commander";function Ga(e,t){if(t)try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("expected an object");return n}catch(n){throw new Error(`${e} must be a valid JSON object.`,{cause:n})}}function qR(e,t,n){if(e!=="as-is"||t)return t;let r=n.filter(i=>i.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 ru=new jR("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)",b("--family",["minimal","editorial","bold","dashboard"])).option("--generation-request-id <id>","Generation funnel correlation ID").option("--image-policy <policy>","Image policy (auto, none)",b("--image-policy",["auto","none"])).option("--content-sources <json>","Canonical content-sources JSON object").option("--source-mode <mode>","Attached deck mode (reference, as-is)",b("--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)",b("--format",["human","json","quiet"])).option("-o, --output <format>","Output format (human, json, quiet) \u2014 short form of --format",b("--output",["human","json","quiet"])).option("--no-stream","Wait for completion without streaming progress").option("--wait","Poll until generation completes").option("--wait-timeout <seconds>",`Max seconds --wait polls before giving up (default ${18e5/1e3})`).option("--idempotency-key <key>","Stable retry key").option("--approval-receipt <receipt>","Server-issued approval receipt for this exact generation request").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--debug","Enable debug logging").option("--open","Open in browser after creation").option("--id <uuid>","Use a specific UUID for the presentation").option("--studio","Studio mode: use current directory name as presentation ID (auto-links to Studio preview)").action(async(e,t)=>{if(t.output=t.format??t.output,await w(),t.stdin&&t.approvalReceiptStdin)throw new Error("Content stdin and approval receipt stdin cannot share the same input stream.");let n=_(t),r=t.idempotencyKey??Q({command:"presentation:create",payload:{...t,approvalReceipt:void 0,approvalReceiptStdin:void 0,idempotencyKey:void 0,topic:e},workspaceId:t.teamId??"configured-default"}),i=18e5;if(t.waitTimeout!==void 0){let j=Number(t.waitTimeout);(!Number.isFinite(j)||j<=0)&&(a("--wait-timeout must be a positive number of seconds"),process.exit(6)),i=j*1e3}let o;t.slides!==void 0&&(o=parseInt(t.slides,10),(Number.isNaN(o)||o<1||o>20)&&(a("Slide count must be between 1 and 20"),process.exit(6)));let c=["best","balanced","fast","ultrafast","instant","image-min","image","image-max"];t.mode&&!c.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Valid: ${c.join(", ")}`),process.exit(6));let l=["smart","fast","balanced","best"];t.imageTier&&!l.includes(t.imageTier)&&(a(`Invalid image tier: ${t.imageTier}. Valid: ${l.join(", ")}`),process.exit(6));let d=["creative","professional","educational","formal","casual"];t.tone&&!d.includes(t.tone)&&(a(`Invalid tone: ${t.tone}. Valid: ${d.join(", ")}`),process.exit(6));let g=["minimal","concise","detailed","extensive"];t.amount&&!g.includes(t.amount)&&(a(`Invalid amount: ${t.amount}. Valid: ${g.join(", ")}`),process.exit(6));let y=["freeform","brand-only","brand-plus-style","style-only","no-styling"];t.styling&&!y.includes(t.styling)&&(a(`Invalid styling: ${t.styling}. Valid: ${y.join(", ")}`),process.exit(6));let v=["quick","moderate","deep","profound"];t.thinkingDepth&&!v.includes(t.thinkingDepth)&&(a(`Invalid thinking-depth: ${t.thinkingDepth}. Valid: ${v.join(", ")}`),process.exit(6));let x=["inform","persuade","train","learn","entertain","report"];t.goal&&!x.includes(t.goal)&&(a(`Invalid goal: ${t.goal}. Valid: ${x.join(", ")}`),process.exit(6));let T=["blue","violet","rose","orange","green"];t.theme&&!T.includes(t.theme)&&(a(`Invalid theme: ${t.theme}. Valid: ${T.join(", ")}`),process.exit(6));let L=["none","waves-bottom-left","waves-top-right","blob-corners","minimal"];t.decorations&&!L.includes(t.decorations)&&(a(`Invalid decorations: ${t.decorations}. Valid: ${L.join(", ")}`),process.exit(6));let $=t.theme||t.primaryColor||t.secondaryColor||t.accentColor||t.backgroundColor||t.foregroundColor||t.decorations;$&&t.mode&&t.mode!=="instant"&&(a("--theme, --primary-color, --decorations and other color options are only supported with --mode instant"),process.exit(6));let N=t.mode??($?"instant":"fast"),S=/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;for(let[j,we]of[["primary-color",t.primaryColor],["secondary-color",t.secondaryColor],["accent-color",t.accentColor],["background-color",t.backgroundColor],["foreground-color",t.foregroundColor]])we&&!S.test(we)&&(a(`Invalid ${j}: ${we}. Must be hex (e.g., #0066CC)`),process.exit(6));try{t.output!=="json"&&t.output!=="quiet"&&process.stdout.write(le.gray("Checking generation limits... "));let j=await uc(N,o??10,t.teamId);if(t.output!=="json"&&t.output!=="quiet"){console.log(le.green("\u2713"));let we=j.remaining[N],ue=j.limits[N],St=we===void 0||ue===void 0?"":` | ${N}: ${we}/${ue} remaining`;console.log(le.gray(` Plan: ${j.planName}${St}`))}}catch(j){t.output==="json"?console.log(JSON.stringify({success:!1,error:"The operation could not be completed."})):(console.log(le.red("\u2717")),a("The command failed. Please try again.")),process.exit(j.exitCode??1)}let E=[];if(t.file&&t.file.length>0){for(let j of t.file)LR(nu(j))||(a(`File not found: ${j}`),process.exit(6));t.output!=="json"&&t.output!=="quiet"&&console.log(le.gray(`
101
+ Uploading ${t.file.length} file(s)...`));try{E=await ec(t.file.map(j=>nu(j)),(j,we,ue)=>{t.output!=="json"&&t.output!=="quiet"&&ue&&process.stdout.write(`\r ${le.cyan("\u2B06")} Uploading: ${ue} (${j+1}/${we})`)},{idempotencyKey:r}),t.output!=="json"&&t.output!=="quiet"&&console.log(`\r ${le.green("\u2713")} Uploaded ${E.length} file(s) `)}catch{a("Failed to upload files. Please try again."),process.exit(1)}}let A;!t.approvalReceiptStdin&&(t.stdin||!process.stdin.isTTY)&&(A=await MR(),t.stdin&&!A&&(a("No content received from stdin"),process.exit(6)));let D=t.context;if(t.contextFile)try{D=UR(t.contextFile,"utf-8"),D.trim()||(a(`Context file is empty: ${t.contextFile}`),process.exit(6))}catch{a(`Failed to read context file: ${t.contextFile}`),process.exit(6)}!A&&!D&&!t.additionalContext&&!t.contentSources&&!t.sourcePresentation&&E.length===0&&(a("Context is required to create a presentation."),console.log(),console.log(le.gray(" -f, --file <paths...> Upload files (PDF, PPTX, images)")),console.log(le.gray(" -c, --context <text> Inline text context")),console.log(le.gray(" --context-file <path> Read from a file")),console.log(le.gray(` cat file | ${f.commands[0]} Pipe content`)),process.exit(6));let re=[...E];A&&re.push({id:`stdin-${r}`,content:A,title:"Piped Content",mime:"text/plain",selected:!0}),D&&re.push({id:`context-${r}`,content:D,title:"Context",mime:"text/plain",selected:!0});let _e,xd=t.primaryColor||t.secondaryColor||t.accentColor||t.backgroundColor||t.foregroundColor;(t.theme||xd||t.decorations)&&(_e={},t.theme&&(_e.preset=t.theme),xd&&(_e.custom={},t.primaryColor&&(_e.custom.primary=t.primaryColor),t.secondaryColor&&(_e.custom.secondary=t.secondaryColor),t.accentColor&&(_e.custom.accent=t.accentColor),t.backgroundColor&&(_e.custom.background=t.backgroundColor),t.foregroundColor&&(_e.custom.foreground=t.foregroundColor)),t.decorations&&(_e.decorations=t.decorations));try{let j=Ga("--content-sources",t.contentSources),we=qR(t.sourceMode,Ga("--source-presentation",t.sourcePresentation),E),ue=await tc({topic:e,...t.additionalContext&&{additionalContext:t.additionalContext},...o!==void 0&&{slideCount:o},mode:N,...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:Ga("--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},...we&&{sourcePresentation:we},...t.widgetSessionId&&{widgetSessionId:t.widgetSessionId},..._e&&{theme:_e},...t.studio?{documentId:_R.basename(process.cwd())}:t.id?{documentId:t.id}:{},...j?{contentSources:j}:re.length>0&&{contentSources:{uploadedFiles:re,contextFiles:[]}}},r,n);if(!t.wait){t.output==="json"?console.log(JSON.stringify({success:!0,run:ue},null,2)):t.output!=="quiet"&&(C("Presentation generation queued"),O("Run ID",ue.runId),O("Status",ue.status),console.log(le.gray(` Check later with presentation status ${ue.runId}`)));return}let St=await Hl({poll:()=>R("createSlides",ue.runId,t.teamId),isDone:je=>je.done,intervalMs:je=>(je.nextPollAfterSeconds??5)*1e3,onValue:je=>{t.output!=="json"&&t.output!=="quiet"&&console.log(le.gray(` ${je.message}`))},timeoutMs:i,timeoutError:je=>new kn("Generation is still running, but --wait stopped polling.",{runId:ue.runId,timeoutMs:je})});if(St.error)throw new Error(ge(St.error));let Et=St.entity?await fn(St.entity.id):void 0;if(t.output==="json")console.log(JSON.stringify({success:!0,presentation:Et,run:St,viewUrl:Et?yn(Et.slug,t.language??"en"):void 0},null,2));else{console.log(),C("Presentation created successfully"),console.log(),O("Title",Et?.title??e),O("Slides",String(Et?.numberOfSlides??o??"\u2014")),console.log();let je=Et?yn(Et.slug,t.language??"en"):"N/A";je!=="N/A"&&(console.log(le.bold(" Open: ")+le.cyan.underline(je)),t.open&&await(await import("open")).default(je)),console.log()}}catch(j){if(j instanceof kn){let we=`${f.commands[0]} presentation status ${j.runId}`,ue=j.timeoutMs<1e3?`${j.timeoutMs}ms`:`${Math.round(j.timeoutMs/1e3)}s`;t.output==="json"?console.log(JSON.stringify({success:!1,error:`Timed out after ${ue} waiting for the run to finish.`,errorCode:"wait_timed_out",runId:j.runId,statusCommand:we})):(a(`Timed out after ${ue} waiting for the run to finish. It is still running.`),O("Run ID",j.runId),console.log(le.gray(` Check progress with ${we}`))),process.exit(1)}t.output==="json"?console.log(JSON.stringify(Ot(j)?Hr({caught:j,error:"The operation could not be completed.",idempotencyKey:r}):{success:!1,error:"The operation could not be completed."})):Ot(j)?a(zr(j,r)):a("The command failed. Please try again."),process.exit(j.exitCode??1)}});async function MR(){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 Wa}from"commander";function Ka(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 VR=new Wa("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{m(await p("listCreditActivity",{limit:e.limit===void 0?void 0:Ka(e.limit,"--limit"),offset:e.offset===void 0?void 0:Ka(e.offset,"--offset"),teamId:e.teamId}))}catch(t){a(u(t,"Reading credit activity failed")),process.exit(s.GENERAL_ERROR)}}),FR=new Wa("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{m(await p("getCreditActivityGroup",{groupId:e,groupType:t.groupType,limit:t.limit===void 0?void 0:Ka(t.limit,"--limit"),teamId:t.teamId}))}catch(n){a(u(n,"Reading the credit activity group failed")),process.exit(s.GENERAL_ERROR)}}),iu=new Wa("credits").description("Credit spend reporting").addCommand(VR).addCommand(FR);import{randomUUID as BR}from"crypto";import{readFile as GR}from"fs/promises";import{Command as H,InvalidArgumentError as Ja}from"commander";function Fe(e){return t=>{if(!t.trim())throw new Ja(`${e} must not be blank.`);return t}}function KR(e,t){return[...t??[],e]}function WR(e){let t=e.indexOf(":"),n=e.slice(0,t),r=e.slice(t+1);if(n!=="user"&&n!=="agent"||!r.trim())throw new Ja("--mention must be user:<uuid> or agent:<uuid>.");return{kind:n,id:r}}function Mt(e,t){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<t)throw new Ja(`${e} must be a whole number of ${t} or more.`);return r}}function au(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}function Ve(e){return au(e).option("--idempotency-key <key>","Exact retry key; a new key is generated when omitted",Fe("--idempotency-key"))}function Ln(e){return au(e).option("--cursor <cursor>","Continue from the previous nextCursor").option("--page-size <n>","Rows per page; follow nextCursor for all rows",Mt("--page-size",1),50)}function Un(e,t){return{documentId:e,cursor:t.cursor,pageSize:t.pageSize}}async function ou(e){if(e.startsWith("@file:"))return GR(e.slice(6),"utf8");if(e!=="-")return e;let t=[];for await(let n of process.stdin)t.push(Buffer.from(n));return Buffer.concat(t).toString("utf8")}async function ae(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:discussion:${BR()}`:void 0;try{m(await p(e,{...await n(),teamId:t.teamId},i))}catch(o){let c=u(o,"Discussion request failed.");a(`${c}${i?` For an exact retry, reuse --idempotency-key ${i}.`:""}`),process.exit(o instanceof P?o.exitCode:s.GENERAL_ERROR)}}function JR(){let e=Ve(new H("register").description("Register this authenticated credential as an external discussion agent").argument("<display-name>","Declared agent name; does not attest the executable",Fe("display-name"))).action(async(S,E)=>ae("registerDiscussionActor",E,()=>({displayName:S}),!0)),t=Ve(new H("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",b("permission",["none","read","comment"])).requiredOption("--expected-revision <revision>","Current grant revision; use 0 when no grant exists",Mt("--expected-revision",0))).action(async(S,E,A,D)=>ae("setDiscussionGrant",D,()=>({documentId:S,actorId:E,permission:A,expectedRevision:D.expectedRevision}),!0)),n=Ln(new H("list").description("Read one page of external-agent grants for a private deck").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionGrants",E,()=>Un(S,E))),r=Ve(new H("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",Fe("--anchor-slide-id")).option("--room-id <id>","Post into this guest review room; omit for the internal space",Fe("--room-id")).option("--mention <target>","Mention a team member or roster agent: user:<uuid> or agent:<uuid>; repeatable",(S,E)=>[...E??[],WR(S)])).action(async(S,E,A)=>ae("postDiscussionMessage",A,async()=>({documentId:S,threadId:A.threadId,anchorSlideId:A.anchorSlideId,roomId:A.roomId,body:Fe("body")(await ou(E)),mentions:A.mention}),!0)),i=Ve(new H("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",b("state",["open","resolved"])).requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1))).action(async(S,E,A,D)=>ae("setDiscussionState",D,()=>({documentId:S,threadId:E,state:A,expectedRevision:D.expectedRevision}),!0)),o=Ln(new H("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",Fe("--anchor-slide-id")).option("--room-id <id>","Only threads in this guest review room; 'internal' selects the member space",Fe("--room-id"))).action(async(S,E)=>ae("listDiscussionThreads",E,()=>({...Un(S,E),anchorSlideId:E.anchorSlideId,roomId:E.roomId===void 0?void 0:E.roomId==="internal"?null:E.roomId}))),c=Ln(new H("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(S,E,A)=>ae("readDiscussionThread",A,()=>({...Un(S,A),threadId:E}))),l=Ln(new H("events").description("Read one ordered page of durable discussion events; resume with nextCursor").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("readDiscussionEvents",E,()=>Un(S,E))),d=Ve(new H("assign").description("Assign one accountable team member to a thread; 'none' clears the assignee").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<assignee-user-id>","Team member user UUID, or 'none' to unassign").requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1))).action(async(S,E,A,D)=>ae("setDiscussionAssignee",D,()=>({documentId:S,threadId:E,assigneeUserId:A.toLowerCase()==="none"?null:A,expectedRevision:D.expectedRevision}),!0)),g=Ve(new H("reviewers").description("Replace a thread's requested reviewers; repeat --reviewer per member, omit all to clear").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").requiredOption("--expected-revision <revision>","Current thread revision from discussion read",Mt("--expected-revision",1)).option("--reviewer <user-id>","Team member user UUID to request review from; repeatable",KR)).action(async(S,E,A)=>ae("setDiscussionReviewers",A,()=>({documentId:S,threadId:E,reviewerUserIds:A.reviewer??[],expectedRevision:A.expectedRevision}),!0)),y=Ln(new H("mentionables").description("List team members and roster agents that can be mentioned on a deck").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionMentionables",E,()=>Un(S,E))),v=Ve(new H("update").description("Edit your own discussion message; sets editedAt").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<message-id>","Discussion message UUID").argument("<body>","Replacement message: literal text, @file:<path> for a UTF-8 file, or '-' for stdin")).action(async(S,E,A,D,re)=>ae("updateDiscussionMessage",re,async()=>({documentId:S,threadId:E,messageId:A,body:Fe("body")(await ou(D))}),!0)),x=Ve(new H("visibility").description("Hide or restore a discussion message; authors hide their own, members moderate").argument("<document-id>","Presentation document family UUID").argument("<thread-id>","Discussion thread UUID").argument("<message-id>","Discussion message UUID").argument("<hidden>","Visibility: hide or show",b("hidden",["hide","show"]))).action(async(S,E,A,D,re)=>ae("setDiscussionMessageVisibility",re,()=>({documentId:S,threadId:E,messageId:A,hidden:D==="hide"}),!0)),T=Ve(new H("create").description("Mint a guest review link pinned to the presentation's current revision").argument("<document-id>","Presentation document family UUID").requiredOption("--room-scope <scope>","isolated: private room for this link; shared: the document's shared guest room",b("room-scope",["isolated","shared"])).option("--post-policy <policy>","unverified: name-only guests may post; verified: email-verified guests only",b("post-policy",["unverified","verified"])).option("--label <label>","Owner-facing link name",Fe("--label")).option("--recipient-email <email>","Optional intended recipient address",Fe("--recipient-email")).option("--expires-at <iso>","Absolute expiry timestamp (ISO 8601)",Fe("--expires-at"))).action(async(S,E)=>ae("createDiscussionReviewLink",E,()=>({documentId:S,roomScope:E.roomScope,postPolicy:E.postPolicy,label:E.label,recipientEmail:E.recipientEmail,expiresAt:E.expiresAt}),!0)),L=Ln(new H("list").description("List a deck's guest review links and their state").argument("<document-id>","Presentation document family UUID")).action(async(S,E)=>ae("listDiscussionReviewLinks",E,()=>Un(S,E))),$=Ve(new H("update").description("Update a review link's label, posting policy, expiry or pinned revision").argument("<document-id>","Presentation document family UUID").argument("<link-id>","Review link UUID").requiredOption("--expected-revision <revision>","Current link revision from review-link list",Mt("--expected-revision",1)).option("--label <label>","New label; 'none' clears it").option("--post-policy <policy>","unverified or verified",b("post-policy",["unverified","verified"])).option("--expires-at <iso>","New expiry (ISO 8601); 'none' clears it").option("--repin","Move the pin to the document's latest revision")).action(async(S,E,A)=>ae("updateDiscussionReviewLink",A,()=>({documentId:S,linkId:E,expectedRevision:A.expectedRevision,label:A.label===void 0?void 0:A.label==="none"?null:A.label,postPolicy:A.postPolicy,expiresAt:A.expiresAt===void 0?void 0:A.expiresAt==="none"?null:A.expiresAt,repin:A.repin}),!0)),N=Ve(new H("revoke").description("Revoke a guest review link; its sessions are fenced immediately").argument("<document-id>","Presentation document family UUID").argument("<link-id>","Review link UUID").requiredOption("--expected-revision <revision>","Current link revision from review-link list",Mt("--expected-revision",1))).action(async(S,E,A)=>ae("revokeDiscussionReviewLink",A,()=>({documentId:S,linkId:E,expectedRevision:A.expectedRevision}),!0));return new H("discussion").description("Collaborate on private decks with attributed human and external-agent messages").addCommand(new H("actor").description("Register the current external-agent credential").addCommand(e)).addCommand(new H("grant").description("Manage external-agent discussion access").addCommand(t).addCommand(n)).addCommand(r).addCommand(new H("state").description("Resolve or reopen discussion threads").addCommand(i)).addCommand(new H("message").description("Edit or moderate an existing discussion message").addCommand(v).addCommand(x)).addCommand(new H("review-link").description("Mint and manage guest review links").addCommand(T).addCommand(L).addCommand($).addCommand(N)).addCommand(d).addCommand(g).addCommand(y).addCommand(o).addCommand(c).addCommand(l)}var su=JR();import{randomUUID as zR}from"crypto";import{readFile as HR}from"fs/promises";import{Command as bt}from"commander";var za=["text/markdown","text/csv","text/plain"];async function du(e){let t=e.content;if(t!==void 0&&t!=="-"&&!t.startsWith("@"))return t;if(t?.startsWith("@"))return HR(t.slice(1),"utf8");if(t==="-"||!process.stdin.isTTY)return XR();a("No document body. Pass --content <text>, --content @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function XR(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function Ci(e){return`cli:document:${e}:${zR()}`}function Vt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function YR(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 QR=new bt("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 ${za.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??YR(t.content?.startsWith("@")?t.content.slice(1):void 0);n||(a(`Cannot tell what this document is. Pass --media-type (${za.join(", ")}).`),process.exit(s.GENERAL_ERROR)),m(await p("createDocument",{content:await du(t),mediaType:n,summary:t.summary,teamId:t.teamId,title:e},Ci("create")))}catch(n){Vt(n,"Could not save the document")}}),ZR=new bt("list").description("List the workspace's documents, newest first").option("--team-id <id>","Workspace ID").option("--media-type <type>",`Filter to one of ${za.join(", ")}`).option("--limit <n>","Maximum documents to return (default 50)").action(async e=>{try{m(await p("listDocuments",{limit:e.limit?Number(e.limit):void 0,mediaType:e.mediaType,teamId:e.teamId}))}catch(t){Vt(t,"Could not list documents")}}),eC=new bt("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 p("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
102
+ `),process.stdout.write(r.content)}catch(n){Vt(n,"Could not read the document")}}),tC=new bt("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(e,t)=>{try{let n=t.content!==void 0;m(await p("updateDocument",{changeSummary:t.changeSummary,content:n?await du(t):void 0,documentId:e,expectedVersion:Number(t.expectedVersion),summary:t.summary,teamId:t.teamId,title:t.title},Ci("update")))}catch(n){Vt(n,"Could not update the document")}}),nC=new bt("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(e,t)=>{try{!t.yes&&process.stdin.isTTY&&(a("Refusing to delete without confirmation. Re-run with --yes to remove this document."),process.exit(s.GENERAL_ERROR)),m(await p("deleteDocument",{documentId:e,teamId:t.teamId},Ci("delete")))}catch(n){Vt(n,"Could not delete the document")}}),rC=new bt("versions").description("List a document's version history").argument("<document-id>","Document id").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("listDocumentVersions",{documentId:e,teamId:t.teamId}))}catch(n){Vt(n,"Could not list versions")}}),iC=new bt("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(e,t)=>{try{m(await p("restoreDocumentVersion",{documentId:e,expectedVersion:Number(t.expectedVersion),teamId:t.teamId,versionNumber:Number(t.versionNumber)},Ci("restore")))}catch(n){Vt(n,"Could not restore the version")}}),cu=new bt("document").description("Create, read and edit Library documents").addCommand(QR).addCommand(ZR).addCommand(eC).addCommand(tC).addCommand(nC).addCommand(rC).addCommand(iC);import{writeFile as oC}from"fs/promises";import{resolve as lu}from"path";import ur from"chalk";import{Command as aC}from"commander";import sC from"ora";var dC=["html","pdf","pptx"],Ha=new aC("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",b("--format",dC),"html").option("--team-id <id>","Workspace ID (uses configured default)").action(async(e,t)=>{await w();let n=sC("Exporting presentation...").start();try{let r=t.teamId??ve();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let i=await sc(e,t.format,{teamId:r}),o=t.output?lu(t.output):lu(process.cwd(),i.fileName);n.text="Downloading...";let c=await hn(i.downloadUrl);await oC(o,Buffer.from(c)),n.succeed("Export complete!"),console.log(),I(`File saved: ${o}`),I(`Format: ${i.format}`),I(`Slides: ${i.slideCount}`),I(`Size: ${cC(c.byteLength)}`),console.log()}catch(r){n.fail("Export failed"),a("The command failed. Please try again."),process.exit(r.exitCode??1)}});function cC(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}Ha.addHelpText("after",`
103
+ ${ur.bold("Examples:")}
104
+ ${ur.gray("# Self-contained interactive HTML (default)")}
105
105
  $ ${f.commands[0]} export <id-or-slug> -o deck.html
106
106
 
107
- ${pr.gray("# PDF or PowerPoint")}
107
+ ${ur.gray("# PDF or PowerPoint")}
108
108
  $ ${f.commands[0]} export <id-or-slug> -f pdf -o deck.pdf
109
109
  $ ${f.commands[0]} export <id-or-slug> -f pptx -o deck.pptx
110
110
 
111
- ${pr.bold("See also:")}
112
- ${pr.gray("# For an MP4 instead")}
111
+ ${ur.bold("See also:")}
112
+ ${ur.gray("# For an MP4 instead")}
113
113
  $ ${f.commands[0]} presentation video <id-or-slug>
114
- `);import{randomUUID as sC}from"crypto";import{existsSync as dC}from"fs";import{Command as wt,InvalidArgumentError as cu}from"commander";var cC=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function lu(e){if(!cC.test(e))throw new cu("file-id expects a UUID from `mf file list`.");return e}function ur(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new cu(`${e} expects a whole number above 0.`);return n}}function Ci(e){return`cli:file:${e}:${sC()}`}function Ft(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var lC=new wt("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(e,t)=>{await w(),dC(e)||(a(`File not found: ${e}`),process.exit(s.INVALID_INPUT));try{let n=et(e),r=Ci("add"),i=await p("createLibraryFileUploadUrl",{...n,teamId:t.teamId},`${r}:upload`),o=await tt(e,i);m(await p("addLibraryFile",{archiveMemberPaths:t.archiveMemberPaths,mediaType:o.type,name:o.name,size:o.size,teamId:t.teamId,uploadKey:o.s3Key,url:o.url},r))}catch(n){Ft(n,"Could not add that file to the Library")}}),mC=new wt("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",ur("--file-size")).requiredOption("--file-type <mime>","Media type of the file").option("--team-id <id>","Workspace ID").action(async e=>{await w();try{m(await p("createLibraryFileUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},Ci("upload-url")))}catch(t){Ft(t,"Could not mint an upload target")}}),pC=new wt("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)",ur("--limit")).action(async e=>{await w();try{m(await p("listLibraryFiles",{limit:e.limit,teamId:e.teamId}))}catch(t){Ft(t,"Could not list Library files")}}),uC=new wt("excerpt").description("Read part of a Library file's text (for example its chapter list); cached, not billed").argument("<file-id>","File id from `mf file list`",lu).option("--team-id <id>","Workspace ID").option("--offset <n>","Character offset to start from",ur("--offset")).option("--max-chars <n>","Characters to return (200-20000, default 4000)",ur("--max-chars")).action(async(e,t)=>{await w();try{m(await p("readLibraryFileExcerpt",{fileId:e,...t.offset===void 0?{}:{offset:t.offset},...t.maxChars===void 0?{}:{maxChars:t.maxChars},teamId:t.teamId}))}catch(n){Ft(n,"Could not read that file")}}),gC=new wt("remove").description("Take a file off the shelf and delete its stored bytes").argument("<file-id>","File id from `mf file list`",lu).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w();try{m(await p("removeLibraryFile",{fileId:e,teamId:t.teamId},Ci("remove")))}catch(n){Ft(n,"Could not remove that file")}}),fC=new wt("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 e=>{await w();try{m(await p("inspectLibraryArchive",e))}catch(t){Ft(t,"Could not inspect that ZIP upload")}}),hC=new wt("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",ur("--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 w();try{m(await p("addLibraryFile",{archiveMemberPaths:e.archiveMemberPaths,mediaType:e.mediaType,name:e.name,size:e.size,teamId:e.teamId,uploadKey:e.uploadKey,url:e.url},Ci("save")))}catch(t){Ft(t,"Could not file that object")}}),mu=new wt("file").description("Library files you can mention in chat with @").addCommand(lC).addCommand(hC).addCommand(fC).addCommand(uC).addCommand(pC).addCommand(gC).addCommand(mC);import{Command as Ue}from"commander";var yC=new Ue("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 at("createFootageProject",{input:{musicAssetId:e.musicAssetId??null,outputs:fr(e.outputs,"outputs"),overlays:fr(e.overlays,"overlays"),ranges:fr(e.ranges,"ranges"),sourceAssetIds:e.source,sourceChatId:e.sourceChatId,strategy:fr(e.strategy,"strategy"),teamId:e.teamId,title:e.title},idempotencyKey:e.idempotencyKey})}),bC=new Ue("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 at("getFootageProject",{input:{projectId:e,teamId:t.teamId,versionId:t.versionId}})}),wC=new Ue("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("--caption-patches <json>","Caption edits by outputId; select an exact treatment id/version or patch its parameters").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 at("reviseFootageProject",{input:gu({baseVersionId:t.baseVersionId,changeSummary:t.changeSummary,musicAssetId:t.musicAssetId==="null"?null:t.musicAssetId,outputs:gr(t.outputs,"outputs"),captionPatches:gr(t.captionPatches,"caption patches"),overlays:gr(t.overlays,"overlays"),projectId:e,ranges:gr(t.ranges,"ranges"),strategy:gr(t.strategy,"strategy"),teamId:t.teamId,title:t.title}),idempotencyKey:t.idempotencyKey})}),vC=new Ue("caption-treatments").description("List available immutable footage caption treatment versions and concrete defaults").option("--team-id <id>","Workspace ID").action(async e=>{await at("listFootageCaptionTreatments",{input:{teamId:e.teamId}})}),IC=new Ue("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 at("restoreFootageProjectVersion",{input:{changeSummary:n.changeSummary,projectId:e,teamId:n.teamId,versionId:t},idempotencyKey:n.idempotencyKey})}),kC=new Ue("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 at("branchFootageProjectVersion",{input:{projectId:e,teamId:n.teamId,title:n.title,versionId:t},idempotencyKey:n.idempotencyKey})}),xC=new Ue("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 at("inspectFootageRange",{input:{projectId:e,rangeId:t,teamId:n.teamId,versionId:n.versionId},idempotencyKey:n.idempotencyKey})}),RC=new Ue("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 uu("inspectFootageRange",e,t.teamId)}),CC=new Ue("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=_(t);await at("renderFootageProject",{input:gu({approvalReceipt:n,outputIds:t.output,projectId:e,teamId:t.teamId,versionId:t.versionId}),idempotencyKey:t.idempotencyKey})}),SC=new Ue("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 uu("renderFootageProject",e,t.teamId)}),EC=new Ue("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 at("importFootageProviderTakes",{input:{invocationId:t.invocationId,projectId:e,teamId:t.teamId},idempotencyKey:t.idempotencyKey})}),pu=new Ue("footage").description("Create, inspect, revise, and render transcript-native footage edits").addCommand(yC).addCommand(bC).addCommand(wC).addCommand(vC).addCommand(IC).addCommand(kC).addCommand(xC).addCommand(RC).addCommand(CC).addCommand(SC).addCommand(EC);async function at(e,t){try{m(await p(e,t.input,t.idempotencyKey))}catch(n){a(u(n,"Footage operation failed")),process.exit(s.GENERAL_ERROR)}}async function uu(e,t,n){try{m(await R(e,t,n))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}function fr(e,t){try{return JSON.parse(e)}catch{throw new Error(`${t} must be valid JSON.`)}}function gr(e,t){return typeof e=="string"?fr(e,t):void 0}function gu(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}import Bt from"chalk";import{Command as PC}from"commander";function AC(e){return new Set((e??"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean))}function TC(e){if(!e)throw new Error("Slides were requested but the server returned none. Retry, or read the deck in the browser.");De("Slides"),console.log();for(let t of e){console.log(Bt.bold(` ${t.number}. ${t.title||"Untitled"}`));let n=t.text?.trim();console.log(n?fu(n):Bt.gray(" (no text on this slide \u2014 image or empty)"));let r=t.speakerNotes?.trim();r&&(console.log(Bt.gray(" Narration/notes:")),console.log(Bt.gray(fu(r)))),console.log()}}function fu(e){return e.split(`
114
+ `);import{randomUUID as lC}from"crypto";import{existsSync as mC}from"fs";import{Command as wt,InvalidArgumentError as mu}from"commander";var pC=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function pu(e){if(!pC.test(e))throw new mu("file-id expects a UUID from `mf file list`.");return e}function gr(e){return t=>{let n=Number(t);if(!Number.isInteger(n)||n<1)throw new mu(`${e} expects a whole number above 0.`);return n}}function Si(e){return`cli:file:${e}:${lC()}`}function Ft(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var uC=new wt("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(e,t)=>{await w(),mC(e)||(a(`File not found: ${e}`),process.exit(s.INVALID_INPUT));try{let n=et(e),r=Si("add"),i=await p("createLibraryFileUploadUrl",{...n,teamId:t.teamId},`${r}:upload`),o=await tt(e,i);m(await p("addLibraryFile",{archiveMemberPaths:t.archiveMemberPaths,mediaType:o.type,name:o.name,size:o.size,teamId:t.teamId,uploadKey:o.s3Key,url:o.url},r))}catch(n){Ft(n,"Could not add that file to the Library")}}),gC=new wt("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",gr("--file-size")).requiredOption("--file-type <mime>","Media type of the file").option("--team-id <id>","Workspace ID").action(async e=>{await w();try{m(await p("createLibraryFileUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},Si("upload-url")))}catch(t){Ft(t,"Could not mint an upload target")}}),fC=new wt("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)",gr("--limit")).action(async e=>{await w();try{m(await p("listLibraryFiles",{limit:e.limit,teamId:e.teamId}))}catch(t){Ft(t,"Could not list Library files")}}),hC=new wt("excerpt").description("Read part of a Library file's text (for example its chapter list); cached, not billed").argument("<file-id>","File id from `mf file list`",pu).option("--team-id <id>","Workspace ID").option("--offset <n>","Character offset to start from",gr("--offset")).option("--max-chars <n>","Characters to return (200-20000, default 4000)",gr("--max-chars")).action(async(e,t)=>{await w();try{m(await p("readLibraryFileExcerpt",{fileId:e,...t.offset===void 0?{}:{offset:t.offset},...t.maxChars===void 0?{}:{maxChars:t.maxChars},teamId:t.teamId}))}catch(n){Ft(n,"Could not read that file")}}),yC=new wt("remove").description("Take a file off the shelf and delete its stored bytes").argument("<file-id>","File id from `mf file list`",pu).option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w();try{m(await p("removeLibraryFile",{fileId:e,teamId:t.teamId},Si("remove")))}catch(n){Ft(n,"Could not remove that file")}}),bC=new wt("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 e=>{await w();try{m(await p("inspectLibraryArchive",e))}catch(t){Ft(t,"Could not inspect that ZIP upload")}}),wC=new wt("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",gr("--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 w();try{m(await p("addLibraryFile",{archiveMemberPaths:e.archiveMemberPaths,mediaType:e.mediaType,name:e.name,size:e.size,teamId:e.teamId,uploadKey:e.uploadKey,url:e.url},Si("save")))}catch(t){Ft(t,"Could not file that object")}}),uu=new wt("file").description("Library files you can mention in chat with @").addCommand(uC).addCommand(wC).addCommand(bC).addCommand(hC).addCommand(fC).addCommand(yC).addCommand(gC);import{Command as Ue}from"commander";var vC=new Ue("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 at("createFootageProject",{input:{musicAssetId:e.musicAssetId??null,outputs:hr(e.outputs,"outputs"),overlays:hr(e.overlays,"overlays"),ranges:hr(e.ranges,"ranges"),sourceAssetIds:e.source,sourceChatId:e.sourceChatId,strategy:hr(e.strategy,"strategy"),teamId:e.teamId,title:e.title},idempotencyKey:e.idempotencyKey})}),IC=new Ue("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 at("getFootageProject",{input:{projectId:e,teamId:t.teamId,versionId:t.versionId}})}),kC=new Ue("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("--caption-patches <json>","Caption edits by outputId; select an exact treatment id/version or patch its parameters").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 at("reviseFootageProject",{input:hu({baseVersionId:t.baseVersionId,changeSummary:t.changeSummary,musicAssetId:t.musicAssetId==="null"?null:t.musicAssetId,outputs:fr(t.outputs,"outputs"),captionPatches:fr(t.captionPatches,"caption patches"),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})}),xC=new Ue("caption-treatments").description("List available immutable footage caption treatment versions and concrete defaults").option("--team-id <id>","Workspace ID").action(async e=>{await at("listFootageCaptionTreatments",{input:{teamId:e.teamId}})}),RC=new Ue("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 at("restoreFootageProjectVersion",{input:{changeSummary:n.changeSummary,projectId:e,teamId:n.teamId,versionId:t},idempotencyKey:n.idempotencyKey})}),CC=new Ue("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 at("branchFootageProjectVersion",{input:{projectId:e,teamId:n.teamId,title:n.title,versionId:t},idempotencyKey:n.idempotencyKey})}),SC=new Ue("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 at("inspectFootageRange",{input:{projectId:e,rangeId:t,teamId:n.teamId,versionId:n.versionId},idempotencyKey:n.idempotencyKey})}),EC=new Ue("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 fu("inspectFootageRange",e,t.teamId)}),PC=new Ue("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=_(t);await at("renderFootageProject",{input:hu({approvalReceipt:n,outputIds:t.output,projectId:e,teamId:t.teamId,versionId:t.versionId}),idempotencyKey:t.idempotencyKey})}),AC=new Ue("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 fu("renderFootageProject",e,t.teamId)}),TC=new Ue("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 at("importFootageProviderTakes",{input:{invocationId:t.invocationId,projectId:e,teamId:t.teamId},idempotencyKey:t.idempotencyKey})}),gu=new Ue("footage").description("Create, inspect, revise, and render transcript-native footage edits").addCommand(vC).addCommand(IC).addCommand(kC).addCommand(xC).addCommand(RC).addCommand(CC).addCommand(SC).addCommand(EC).addCommand(PC).addCommand(AC).addCommand(TC);async function at(e,t){try{m(await p(e,t.input,t.idempotencyKey))}catch(n){a(u(n,"Footage operation failed")),process.exit(s.GENERAL_ERROR)}}async function fu(e,t,n){try{m(await R(e,t,n))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}function hr(e,t){try{return JSON.parse(e)}catch{throw new Error(`${t} must be valid JSON.`)}}function fr(e,t){return typeof e=="string"?hr(e,t):void 0}function hu(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}import Bt from"chalk";import{Command as OC}from"commander";function $C(e){return new Set((e??"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean))}function DC(e){if(!e)throw new Error("Slides were requested but the server returned none. Retry, or read the deck in the browser.");De("Slides"),console.log();for(let t of e){console.log(Bt.bold(` ${t.number}. ${t.title||"Untitled"}`));let n=t.text?.trim();console.log(n?yu(n):Bt.gray(" (no text on this slide \u2014 image or empty)"));let r=t.speakerNotes?.trim();r&&(console.log(Bt.gray(" Narration/notes:")),console.log(Bt.gray(yu(r)))),console.log()}}function yu(e){return e.split(`
115
115
  `).map(t=>` ${t}`).join(`
116
- `)}var hu=new PC("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)",b("--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 w();try{let n=this.getOptionValueSource("includeSlides")==="cli"?t.includeSlides:this.getOptionValueSource("include")==="cli"?AC(t.include).has("slides"):!0,r=t.teamId??ve();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let i=await fn(e,{includeSlides:n,teamId:r,includeGenerating:!0});if(t.format==="json"){console.log(JSON.stringify(i,null,2));return}if("done"in i){De("Presentation is generating"),O("Status",i.status),O("Presentation ID",i.presentationId),O("Job ID",i.jobId),console.log(i.instructions);return}let o=yn(i.slug,t.language);De("Presentation Details"),console.log(),O("Slug",i.slug),O("Title",i.title||"Untitled"),O("Description",i.description||Bt.gray("None")),O("Slides",String(i.numberOfSlides||"-")),O("Mode",i.mode||"-"),O("Created",qo(i.createdAt)),i.updatedAt&&O("Updated",qo(i.updatedAt)),console.log(),o!=="N/A"&&console.log(Bt.bold(" Open: ")+Bt.cyan.underline(o)),console.log(),n&&TC(i.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 OC}from"crypto";import{Command as Ei}from"commander";import $C from"ora";function DC(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function NC(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:DC(e.source),transparentBackground:t==="icon"}}}function LC(e){let t=e.url||e.imageUrl;if(!t)throw new Error("Image search returned a result without a URL");return t}function UC(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function _C(e){let t=[],n=e.reduce((r,i)=>Math.max(r,i.length),0);for(let r=0;r<n;r+=1)for(let i of e){let o=i[r];o!==void 0&&t.push(o)}return t}function jC(e,t){let n=e.data.results.map(r=>r.results.map(i=>{let o=i,c=UC(o);if(t==="icon"&&c!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...o,url:LC(o),provider:r.providerName,assetType:t,...c!==void 0?{transparent:c}:{}}}));return _C(n)}function qC(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 Si(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function MC(e){return{requestId:e.runId,status:qC(e),...e.entity?.url?{url:e.entity.url}:{},...e.error?{error:ge(e.error)}:{},...Si(e.output?.width)!==void 0?{width:Si(e.output?.width)}:{},...Si(e.output?.height)!==void 0?{height:Si(e.output?.height)}:{}}}async function yu(e,t){return MC(await R("createImage",e,t))}function za(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.output??e.url??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.url&&C(`Image URL: ${e.url}`),e.output&&C(`Saved to: ${e.output}`),e.error&&a(`Error: ${e.error}`)}var VC=new Ei("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format,n=t==="human"?$C("Searching for images...").start():null,r;try{r=NC(e)}catch(i){n?.stop(),a(u(i,"Invalid image search request")),process.exit(s.INVALID_INPUT);return}try{let i=await yc(r);n?.stop(),i.success||(a("Search failed"),process.exit(s.GENERAL_ERROR));let o=r.options?.assetType??"image",c=jC(i,o);if(t==="json"){m({success:!0,query:e.query,assetType:o,totalResults:c.length,images:c});return}if(t==="quiet"){for(let l of c)console.log(l.url);return}if(c.length===0){I("No images found");return}C(`Found ${c.length} images for "${e.query}"`),console.log();for(let l=0;l<c.length;l++){let d=c[l];console.log(`[${l+1}] ${d.title||"Untitled"}`),console.log(` URL: ${d.url}`),console.log(` Size: ${d.width}x${d.height}`),d.author&&console.log(` Author: ${d.author}`),console.log(` Provider: ${d.provider}`),console.log()}}catch(i){n?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),FC=new Ei("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>","Image lane override: standard, transparent, reference, or pro").option("--model <model>","Model override").option("--aspect-ratio <ratio>","Output aspect ratio: square, wide, or tall",b("--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, vector, or edit; omitted means general. edit changes the first --reference-image as the prompt instructs and keeps everything else",b("--purpose",["general","draft","infographic","brand-max","vector","edit"])).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 reference --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",b("--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)&&q("--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&&q("Reference images without --model route to a light model that returns a similar-looking, not identical, subject. A recognisable likeness needs --provider reference --model gemini-3-pro-image on a workspace with the image-model-override flag.",t.format);let i=t.idempotencyKey??OC(),o;try{o=await ai(t.referenceImage,{idempotencyKey:i,rejectNonImageFiles:!0})}catch(c){a(u(c,"Could not resolve --reference-image"),t.format),process.exit(s.INVALID_INPUT)}try{let c=await p("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}:{},...o?{referenceImages:o}:{},reason:t.reason,teamId:t.teamId,width:t.width?Number.parseInt(t.width,10):void 0},i);if(n=c.runId,!t.wait){za({requestId:c.runId,status:"pending"},t.format);return}let l=await $e(()=>yu(c.runId,t.teamId),180,2e3);if(l.status==="failed")throw new de(l.error||"Image generation failed");if(!l.url)throw new Error("Image generation completed without an image URL");let d=t.output?{...l,output:t.output}:l;t.output&&await Ie(l.url,t.output),za(d,t.format)}catch(c){a(oe(c,n),t.format),process.exit(s.GENERAL_ERROR)}}),BC=new Ei("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await yu(e,t.teamId);if(t.output){if(n.status!=="completed"||!n.url)throw new Error("Image generation is not complete");await Ie(n.url,t.output),n.output=t.output}za(n,t.format)}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),bu=new Ei("image").description("Image search and generation commands").addCommand(VC).addCommand(FC).addCommand(BC);import{randomUUID as GC}from"crypto";import{Command as Ha,InvalidArgumentError as KC}from"commander";function WC(e,t){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<t)throw new KC(`${e} must be a whole number of ${t} or more.`);return r}}function wu(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}async function vu(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:inbox:${GC()}`:void 0;try{m(await p(e,{...n(),teamId:t.teamId},i))}catch(o){let c=u(o,"Inbox request failed.");a(`${c}${i?` For an exact retry, reuse --idempotency-key ${i}.`:""}`),process.exit(o instanceof P?o.exitCode:s.GENERAL_ERROR)}}function JC(){let e=wu(new Ha("list").description("List your collaboration inbox items: mentions, assignments, review requests").option("--cursor <cursor>","Continue from the previous nextCursor").option("--page-size <n>","Rows per page; follow nextCursor for all rows",WC("--page-size",1),50).option("--unread-only","Only items you have not marked read")).action(async n=>vu("listInboxItems",n,()=>({cursor:n.cursor,pageSize:n.pageSize,unreadOnly:n.unreadOnly??!1}))),t=wu(new Ha("mark-read").description("Mark inbox items as read").requiredOption("--item <id>","Inbox item UUID to mark read; repeatable",(n,r)=>[...r??[],n]).option("--idempotency-key <key>","Exact retry key; a new key is generated when omitted")).action(async n=>vu("markInboxItemsRead",n,()=>({itemIds:n.item}),!0));return new Ha("inbox").description("Your durable collaboration inbox").addCommand(e).addCommand(t)}var Iu=JC();import{Command as Xa}from"commander";var zC=new Xa("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").option("--mission <id>","Only this mission's deliverables").option("--mission-status <statuses>","Only mission deliverables at these comma-separated statuses").action(async(e,t)=>{try{m(await p("searchKnowledge",{kind:t.kind,limit:Number.parseInt(t.limit,10),provenance:t.provenance,...t.mission?{missionId:t.mission}:{},...t.missionStatus?{missionStatus:String(t.missionStatus).split(",").map(n=>n.trim()).filter(Boolean)}:{},query:e,teamId:t.teamId}))}catch(n){a(u(n,"Knowledge search failed")),process.exit(s.GENERAL_ERROR)}}),HC=new Xa("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async e=>{try{m(await p("getKnowledgeBundle",{kind:e.kind,teamId:e.teamId}))}catch(t){a(u(t,"Knowledge bundle failed")),process.exit(s.GENERAL_ERROR)}}),ku=new Xa("knowledge").description("Search the workspace Knowledge Hub and read bounded knowledge bundles").addCommand(zC).addCommand(HC);import{randomUUID as XC}from"crypto";import Pi from"chalk";import{Command as st}from"commander";function Ya(e){if(e!==void 0)return e==="root"?null:e}function _n(e){return`cli:library:${e}:${XC()}`}function Gt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var YC=new st("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{m(await p("listLibraryFolders",{includeEntryCounts:!!e.counts,teamId:e.teamId}))}catch(t){Gt(t,"Could not list folders")}}),QC=new st("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{m(await p("createLibraryFolder",{color:t.color,name:e,parentId:Ya(t.parent),teamId:t.teamId},_n("create")))}catch(n){Gt(n,"Could not create the folder")}}),ZC=new st("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{m(await p("renameLibraryFolder",{folderId:e,name:t,teamId:n.teamId},_n("rename")))}catch(r){Gt(r,"Could not rename the folder")}}),eS=new st("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{m(await p("recolorLibraryFolder",{color:t.color==="none"?null:t.color,folderId:e,teamId:t.teamId},_n("recolor")))}catch(n){Gt(n,"Could not recolour the folder")}}),tS=new st("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{m(await p("moveLibraryFolder",{folderId:e,newParentId:Ya(t.to),teamId:t.teamId},_n("move")))}catch(n){Gt(n,"Could not move the folder")}}),nS=new st("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{m(await p("deleteLibraryFolder",{folderId:e,teamId:t.teamId},_n("delete")))}catch(n){Gt(n,"Could not delete the folder")}}),rS=new st("folders").description("Manage Library folders").addCommand(YC).addCommand(QC).addCommand(ZC).addCommand(eS).addCommand(tS).addCommand(nS),iS=new st("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{m(await p("fileArtifactIntoFolder",{folderId:Ya(n.folder),kind:e,targetId:t,teamId:n.teamId},_n("file")))}catch(r){Gt(r,"Could not file that item")}}),Qa=new st("library").description("Library folders and filing").addCommand(rS).addCommand(iS);Qa.addHelpText("after",`
117
- ${Pi.bold("Examples:")}
118
- ${Pi.gray("# Browse the folder tree and file an artifact into a folder")}
116
+ `)}var bu=new OC("get").description("Get presentation details").argument("<slug>","Presentation slug (e.g., my-presentation-v1-abc123)").option("-f, --format <format>","Output format (summary, full, json)",b("--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 w();try{let n=this.getOptionValueSource("includeSlides")==="cli"?t.includeSlides:this.getOptionValueSource("include")==="cli"?$C(t.include).has("slides"):!0,r=t.teamId??ve();if(!r)throw new Error("Team ID required. Set one with 'mf config set team-id <id>' or pass --team-id.");let i=await fn(e,{includeSlides:n,teamId:r,includeGenerating:!0});if(t.format==="json"){console.log(JSON.stringify(i,null,2));return}if("done"in i){De("Presentation is generating"),O("Status",i.status),O("Presentation ID",i.presentationId),O("Job ID",i.jobId),console.log(i.instructions);return}let o=yn(i.slug,t.language);De("Presentation Details"),console.log(),O("Slug",i.slug),O("Title",i.title||"Untitled"),O("Description",i.description||Bt.gray("None")),O("Slides",String(i.numberOfSlides||"-")),O("Mode",i.mode||"-"),O("Created",Vo(i.createdAt)),i.updatedAt&&O("Updated",Vo(i.updatedAt)),console.log(),o!=="N/A"&&console.log(Bt.bold(" Open: ")+Bt.cyan.underline(o)),console.log(),n&&DC(i.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 NC}from"crypto";import{Command as Pi}from"commander";import LC from"ora";function UC(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function _C(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:UC(e.source),transparentBackground:t==="icon"}}}function jC(e){let t=e.url||e.imageUrl;if(!t)throw new Error("Image search returned a result without a URL");return t}function qC(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function MC(e){let t=[],n=e.reduce((r,i)=>Math.max(r,i.length),0);for(let r=0;r<n;r+=1)for(let i of e){let o=i[r];o!==void 0&&t.push(o)}return t}function VC(e,t){let n=e.data.results.map(r=>r.results.map(i=>{let o=i,c=qC(o);if(t==="icon"&&c!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...o,url:jC(o),provider:r.providerName,assetType:t,...c!==void 0?{transparent:c}:{}}}));return MC(n)}function FC(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 Ei(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function BC(e){return{requestId:e.runId,status:FC(e),...e.entity?.url?{url:e.entity.url}:{},...e.error?{error:ge(e.error)}:{},...Ei(e.output?.width)!==void 0?{width:Ei(e.output?.width)}:{},...Ei(e.output?.height)!==void 0?{height:Ei(e.output?.height)}:{}}}async function wu(e,t){return BC(await R("createImage",e,t))}function Xa(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.output??e.url??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.url&&C(`Image URL: ${e.url}`),e.output&&C(`Saved to: ${e.output}`),e.error&&a(`Error: ${e.error}`)}var GC=new Pi("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format,n=t==="human"?LC("Searching for images...").start():null,r;try{r=_C(e)}catch(i){n?.stop(),a(u(i,"Invalid image search request")),process.exit(s.INVALID_INPUT);return}try{let i=await wc(r);n?.stop(),i.success||(a("Search failed"),process.exit(s.GENERAL_ERROR));let o=r.options?.assetType??"image",c=VC(i,o);if(t==="json"){m({success:!0,query:e.query,assetType:o,totalResults:c.length,images:c});return}if(t==="quiet"){for(let l of c)console.log(l.url);return}if(c.length===0){I("No images found");return}C(`Found ${c.length} images for "${e.query}"`),console.log();for(let l=0;l<c.length;l++){let d=c[l];console.log(`[${l+1}] ${d.title||"Untitled"}`),console.log(` URL: ${d.url}`),console.log(` Size: ${d.width}x${d.height}`),d.author&&console.log(` Author: ${d.author}`),console.log(` Provider: ${d.provider}`),console.log()}}catch(i){n?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),KC=new Pi("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>","Image lane override: standard, transparent, reference, or pro").option("--model <model>","Model override").option("--aspect-ratio <ratio>","Output aspect ratio: square, wide, or tall",b("--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, vector, or edit; omitted means general. edit changes the first --reference-image as the prompt instructs and keeps everything else",b("--purpose",["general","draft","infographic","brand-max","vector","edit"])).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 reference --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",b("--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)&&q("--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&&q("Reference images without --model route to a light model that returns a similar-looking, not identical, subject. A recognisable likeness needs --provider reference --model gemini-3-pro-image on a workspace with the image-model-override flag.",t.format);let i=t.idempotencyKey??NC(),o;try{o=await si(t.referenceImage,{idempotencyKey:i,rejectNonImageFiles:!0})}catch(c){a(u(c,"Could not resolve --reference-image"),t.format),process.exit(s.INVALID_INPUT)}try{let c=await p("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}:{},...o?{referenceImages:o}:{},reason:t.reason,teamId:t.teamId,width:t.width?Number.parseInt(t.width,10):void 0},i);if(n=c.runId,!t.wait){Xa({requestId:c.runId,status:"pending"},t.format);return}let l=await $e(()=>wu(c.runId,t.teamId),180,2e3);if(l.status==="failed")throw new de(l.error||"Image generation failed");if(!l.url)throw new Error("Image generation completed without an image URL");let d=t.output?{...l,output:t.output}:l;t.output&&await Ie(l.url,t.output),Xa(d,t.format)}catch(c){a(oe(c,n),t.format),process.exit(s.GENERAL_ERROR)}}),WC=new Pi("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await wu(e,t.teamId);if(t.output){if(n.status!=="completed"||!n.url)throw new Error("Image generation is not complete");await Ie(n.url,t.output),n.output=t.output}Xa(n,t.format)}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),vu=new Pi("image").description("Image search and generation commands").addCommand(GC).addCommand(KC).addCommand(WC);import{randomUUID as JC}from"crypto";import{Command as Ya,InvalidArgumentError as zC}from"commander";function HC(e,t){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<t)throw new zC(`${e} must be a whole number of ${t} or more.`);return r}}function Iu(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}async function ku(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:inbox:${JC()}`:void 0;try{m(await p(e,{...n(),teamId:t.teamId},i))}catch(o){let c=u(o,"Inbox request failed.");a(`${c}${i?` For an exact retry, reuse --idempotency-key ${i}.`:""}`),process.exit(o instanceof P?o.exitCode:s.GENERAL_ERROR)}}function XC(){let e=Iu(new Ya("list").description("List your collaboration inbox items: mentions, assignments, review requests").option("--cursor <cursor>","Continue from the previous nextCursor").option("--page-size <n>","Rows per page; follow nextCursor for all rows",HC("--page-size",1),50).option("--unread-only","Only items you have not marked read")).action(async n=>ku("listInboxItems",n,()=>({cursor:n.cursor,pageSize:n.pageSize,unreadOnly:n.unreadOnly??!1}))),t=Iu(new Ya("mark-read").description("Mark inbox items as read").requiredOption("--item <id>","Inbox item UUID to mark read; repeatable",(n,r)=>[...r??[],n]).option("--idempotency-key <key>","Exact retry key; a new key is generated when omitted")).action(async n=>ku("markInboxItemsRead",n,()=>({itemIds:n.item}),!0));return new Ya("inbox").description("Your durable collaboration inbox").addCommand(e).addCommand(t)}var xu=XC();import{Command as Qa}from"commander";var YC=new Qa("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").option("--mission <id>","Only this mission's deliverables").option("--mission-status <statuses>","Only mission deliverables at these comma-separated statuses").action(async(e,t)=>{try{m(await p("searchKnowledge",{kind:t.kind,limit:Number.parseInt(t.limit,10),provenance:t.provenance,...t.mission?{missionId:t.mission}:{},...t.missionStatus?{missionStatus:String(t.missionStatus).split(",").map(n=>n.trim()).filter(Boolean)}:{},query:e,teamId:t.teamId}))}catch(n){a(u(n,"Knowledge search failed")),process.exit(s.GENERAL_ERROR)}}),QC=new Qa("bundle").description("Read a bounded Open Knowledge Format bundle").option("--team-id <id>","Workspace ID").option("--kind <kind>","Knowledge kind").action(async e=>{try{m(await p("getKnowledgeBundle",{kind:e.kind,teamId:e.teamId}))}catch(t){a(u(t,"Knowledge bundle failed")),process.exit(s.GENERAL_ERROR)}}),Ru=new Qa("knowledge").description("Search the workspace Knowledge Hub and read bounded knowledge bundles").addCommand(YC).addCommand(QC);import{randomUUID as ZC}from"crypto";import Ai from"chalk";import{Command as st}from"commander";function Za(e){if(e!==void 0)return e==="root"?null:e}function _n(e){return`cli:library:${e}:${ZC()}`}function Gt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var eS=new st("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{m(await p("listLibraryFolders",{includeEntryCounts:!!e.counts,teamId:e.teamId}))}catch(t){Gt(t,"Could not list folders")}}),tS=new st("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{m(await p("createLibraryFolder",{color:t.color,name:e,parentId:Za(t.parent),teamId:t.teamId},_n("create")))}catch(n){Gt(n,"Could not create the folder")}}),nS=new st("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{m(await p("renameLibraryFolder",{folderId:e,name:t,teamId:n.teamId},_n("rename")))}catch(r){Gt(r,"Could not rename the folder")}}),rS=new st("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{m(await p("recolorLibraryFolder",{color:t.color==="none"?null:t.color,folderId:e,teamId:t.teamId},_n("recolor")))}catch(n){Gt(n,"Could not recolour the folder")}}),iS=new st("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{m(await p("moveLibraryFolder",{folderId:e,newParentId:Za(t.to),teamId:t.teamId},_n("move")))}catch(n){Gt(n,"Could not move the folder")}}),oS=new st("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{m(await p("deleteLibraryFolder",{folderId:e,teamId:t.teamId},_n("delete")))}catch(n){Gt(n,"Could not delete the folder")}}),aS=new st("folders").description("Manage Library folders").addCommand(eS).addCommand(tS).addCommand(nS).addCommand(rS).addCommand(iS).addCommand(oS),sS=new st("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{m(await p("fileArtifactIntoFolder",{folderId:Za(n.folder),kind:e,targetId:t,teamId:n.teamId},_n("file")))}catch(r){Gt(r,"Could not file that item")}}),es=new st("library").description("Library folders and filing").addCommand(aS).addCommand(sS);es.addHelpText("after",`
117
+ ${Ai.bold("Examples:")}
118
+ ${Ai.gray("# Browse the folder tree and file an artifact into a folder")}
119
119
  $ ${f.commands[0]} library folders list
120
120
  $ ${f.commands[0]} library file presentation <id> --folder <folder-id>
121
121
 
122
- ${Pi.bold("See also:")}
123
- ${Pi.gray("# A different thing: reusable video clips, not Library folders")}
122
+ ${Ai.bold("See also:")}
123
+ ${Ai.gray("# A different thing: reusable video clips, not Library folders")}
124
124
  $ ${f.commands[0]} video library --help
125
- `);import{randomUUID as Ru}from"crypto";import{Command as jn,InvalidArgumentError as Cu}from"commander";var Su=new jn("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??Ru();try{m(await p("analyzeMediaAsset",{assetId:e,diarize:t.diarize,language:t.language,teamId:t.teamId},n))}catch(r){a(`${u(r,"Analysis failed")} Retry with --idempotency-key ${n}.`),process.exit(s.GENERAL_ERROR)}}),oS=new jn("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=k(this,t);try{m(await R("analyzeMediaAsset",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});Su.addCommand(oS);var Eu=new jn("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(e,t)=>{try{m(await p("importConnectorRecording",{connectorId:t.connector,providerId:t.provider,remoteFileId:e,sourceChatId:t.chat,teamId:t.teamId,title:t.title},t.idempotencyKey??Ru()))}catch(n){a(u(n,"Import failed")),process.exit(s.GENERAL_ERROR)}}),aS=new jn("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=k(this,t);try{m(await R("importConnectorRecording",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});Eu.addCommand(ce(aS));function Za(e,t){return n=>{let r=Number(n);if(!/^\d+$/u.test(n)||!Number.isSafeInteger(r)||r<e||r>t)throw new Cu(`Expected an integer from ${e} to ${t}.`);return r}}function xu(e){let t=Number(e);if(!e.trim()||!Number.isFinite(t)||t<0)throw new Cu("Expected nonnegative source seconds.");return t}var sS=new jn("show").description("Read recording metadata and a page of its timestamped transcript").argument("<asset-id>","Recording ID or slug").option("--after-segment-index <index>","Continue after the previous page's segment index",Za(0,Number.MAX_SAFE_INTEGER)).option("--limit <count>","Maximum segments (1\u2013200; default 100)",Za(1,200)).option("--evidence <kind>","segments (discovery) or words (precise cuts)").option("--after-word-index <index>","Continue precise evidence after the word cursor",Za(0,Number.MAX_SAFE_INTEGER)).option("--start-sec <seconds>","Precise evidence window start",xu).option("--end-sec <seconds>","Precise evidence window end",xu).option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getMediaAsset",{assetId:e,evidence:t.evidence,afterWordIndex:t.afterWordIndex,startSec:t.startSec,endSec:t.endSec,afterSegmentIndex:t.afterSegmentIndex,limit:t.limit,teamId:t.teamId}))}catch(n){a(u(n,"Recording read failed")),process.exit(s.GENERAL_ERROR)}}),Pu=new jn("media").description("Ingest and transcribe recordings you already own").addCommand(sS).addCommand(Su).addCommand(Eu);import{Command as es}from"commander";function dS(e,t){let n=e.indexOf("=");return n<=0&&(a("Pass --additional-page as /path=Title"),process.exit(s.INVALID_INPUT)),[...t,{path:e.slice(0,n),title:e.slice(n+1)}]}var cS=new es("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)",dS,[]).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(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{m(await p("createMicrosite",{additionalPages:t.additionalPage.length?t.additionalPage:void 0,approvalReceipt:_(t),audience:t.audience,brandingId:t.brandingId,description:t.description,designBrandReference:t.designBrandReference,language:t.language,teamId:t.teamId,title:e,tone:t.tone},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),lS=new es("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createMicrosite",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Au=new es("microsite").description("Generate a shareable multi-section web microsite from a brief").addCommand(cS).addCommand(lS);import{randomUUID as Tu}from"crypto";import{readFile as mS}from"fs/promises";import{Command as B,InvalidArgumentError as Be}from"commander";function Ai(e){let t=Number(e);if(!e.trim()||!Number.isSafeInteger(t)||t<0)throw new Be("Expected a nonnegative whole number.");return t}function rs(e){let t=Number(e);if(!e.trim()||!Number.isSafeInteger(t)||t<=0)throw new Be("Expected a positive whole number.");return t}function pS(e){if(!/^[a-f0-9]{64}$/u.test(e))throw new Be("Expected a lowercase SHA-256 fingerprint.");return e}function Kt(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}function ze(e){return Kt(e).option("--idempotency-key <key>","Stable key for an exact retry")}var ts='Where the mission stops for a person: each_step, key_steps (import review + narration script + final), autopilot, or {preset:"custom",stopAt:[import|generatedDeck|narrationScript|render|final]} as inline JSON or @file:path';function uS(e){let t=Number(e);if(!Number.isInteger(t)||t<=0)throw new Be("--credit-ceiling must be a positive whole number of credits.");return t}async function ns(e){return["each_step","key_steps","autopilot"].includes(e)?{preset:e}:Ae(e)}async function Ae(e){return JSON.parse(e.startsWith("@file:")?await mS(e.slice(6),"utf8"):e)}async function me(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:mission:${Tu()}`:void 0;try{m(await p(e,{...await n(),teamId:t.teamId},i))}catch(o){let c=o instanceof P&&o.errorCode==="approval_required"?`${o.approvalUrl?` Open ${o.approvalUrl}.`:""} Retry this exact request with --approval-receipt <receipt> --idempotency-key ${i}.`:"";a(`${u(o,"Mission request failed.")}${c||(i?Ee(o,i):"")}`),process.exit(s.GENERAL_ERROR)}}async function Ti(e,t,n,r="Mission render failed."){let i=t.idempotencyKey??`cli:mission:${Tu()}`;try{let o=await p(e,{...await n(),teamId:t.teamId},i);m(t.wait===!1?o:await z(e,o.runId,t.teamId))}catch(o){a(un(o)?oe(o):`${u(o,r)}${Ee(o,i)}`),process.exit(s.GENERAL_ERROR)}}function Oi(e,t){e.yes||(a(`Pass --yes to confirm ${t}; browser approval still requires --approval-receipt.`),process.exit(s.INVALID_INPUT))}function gS(e){e.yes||(a("Pass --yes to start rendering the human-approved narration."),process.exit(s.INVALID_INPUT))}function dt(e){return ze(e).requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--expected-item-revision <n>","Current item revision from mission status",rs)}function $i(e){return e.option("--approval-receipt <receipt>","Browser-issued receipt for this exact request; omit first to receive its confirmation URL").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin instead of argv").option("--yes","Confirm intent only; a browser-issued approval receipt is still required")}function fS(){let e=new B("mission").description("Track a mission's intended outcomes and connect existing artifacts");e.addCommand(ze(new B("create")).description("Create a scoped set of intended narrated-video outcomes; no generation starts").requiredOption("--title <title>","Name for this mission").option("--goal <goal>","Optional desired outcome").option("--scope <scope>","Finite scope or ongoing collection",b("--scope",["finite","ongoing"]),"finite").option("--source-mode <mode>","How item sources become slides: as-is imports PowerPoint decks, reference generates a new deck from each document",b("--source-mode",["as-is","reference"])).option("--generation <json-or-file>","Default deck-generation settings for document sources {language?,tone?,audience?,amount?,additionalContext?}; inline JSON or @file:path").option("--phases <json-or-file>","Ordered array of {key,label,brief?}; items join one with phaseKey; inline JSON or @file:path").option("--review-policy <policy>",ts).option("--destination-folder <folder-id>","Library folder approved outputs are filed into (default: one named after the mission)").option("--visibility <visibility>","team (default: every member sees it) or private (only you)",b("--visibility",["team","private"])).option("--output-plan <json-or-file>",'Default outputs per deliverable item as {slots:[{slotKey,kind:presentation|video|document|reel,label,parent:"source"|{slotKey},countsTowardDone,fulfillment:{mode:"manual"}|{mode:"automated",runtimeKey}|{mode:"agent",agentId}}]}, up to 8 slots; omit for deck -> narrated video; inline JSON or @file:path').requiredOption("--items <json-or-file>","Array of {key,label,role?:deliverable|reference,phaseKey?,sourceFileId?,supportingSourceFileIds?[],sourceMode?,generation?,outputPlan?} in order; groupKey is a deprecated alias of phaseKey; inline JSON or @file:path").action(async d=>me("createMission",d,async()=>({title:d.title,goal:d.goal,scope:d.scope,...d.phases===void 0?{}:{phases:await Ae(d.phases)},...d.outputPlan===void 0?{}:{outputPlan:await Ae(d.outputPlan)},...d.reviewPolicy===void 0?{}:{reviewPolicy:await ns(d.reviewPolicy)},...d.destinationFolder===void 0?{}:{destinationFolderId:d.destinationFolder},...d.visibility===void 0?{}:{visibility:d.visibility},...d.sourceMode===void 0?{}:{sourceMode:d.sourceMode},...d.generation===void 0?{}:{generation:await Ae(d.generation)},items:await Ae(d.items)}),!0)));let t=new B("source").description("Create an independent presentation from an item's current Library source"),n=dt(new B("import")).description("Start or explicitly retry this item's independent PowerPoint import").option("--no-wait","Return the run ID; recover with mission source import status <run-id>").action(async d=>{await Ti("startMissionSourceImport",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId}),"Mission source import failed.")});n.addCommand(ce(Kt(new B("status"))).description("Read one mission source import run").argument("<run-id>","Run ID returned by mission source import").action(async function(d,g){let y=k(this,g);try{m(await R("startMissionSourceImport",d,y.teamId))}catch(v){a(u(v,"Source import status failed.")),process.exit(s.GENERAL_ERROR)}})),t.addCommand(n),t.addCommand(dt(new B("replace")).description("Replace a blocked item's source with another Library PowerPoint").requiredOption("--source-file-id <file-id>","Replacement Library PowerPoint file").action(async d=>me("replaceMissionItemSource",d,()=>({missionId:d.missionId,itemId:d.itemId,expectedItemRevision:d.expectedItemRevision,sourceFileId:d.sourceFileId}),"Mission source replacement failed."))),e.addCommand(t),e.addCommand(ze(new B("update")).description("Update intent, scope, or source links; existing accepted outputs remain recorded").requiredOption("--mission-id <id>","Mission ID").requiredOption("--expected-revision <n>","Current mission revision from status",rs).option("--title <title>","Replacement mission title").option("--goal <goal>","Replacement desired outcome").option("--clear-goal","Remove the saved desired outcome").option("--scope <scope>","Finite scope or ongoing collection",b("--scope",["finite","ongoing"])).option("--source-mode <mode>","How item sources become slides: as-is imports PowerPoint decks, reference generates a new deck from each document",b("--source-mode",["as-is","reference"])).option("--clear-source-mode","Remove the saved source-mode default; item-level modes still apply").option("--generation <json-or-file>","Replacement deck-generation defaults for document sources; inline JSON or @file:path").option("--clear-generation","Remove the saved deck-generation defaults; item-level settings still apply").option("--phases <json-or-file>","Phase upserts as {key,label?,brief?,archived?}; new keys are appended, archived:true needs the phase empty, archived:false restores it; reorder with mission reorder; inline JSON or @file:path").option("--output-plan <json-or-file>","Replacement default output plan (see mission create); items with outputs keep their slots unless --apply-output-plan; inline JSON or @file:path").option("--clear-output-plan","Return the default to deck -> narrated video").option("--review-policy <policy>",ts).option("--clear-review-policy","Return to checking each step").option("--destination-folder <folder-id>","Library folder approved outputs are filed into from now on").option("--clear-destination-folder","Return to the default folder named after the mission").option("--visibility <visibility>","team (every member sees it) or private (only you); only the mission's creator may change it",b("--visibility",["team","private"])).option("--apply-output-plan","Apply the effective plan to every live deliverable now, including items with outputs (changed slots restart empty; history is kept)").option("--items <json-or-file>","Upserts as {key,label,role?,phaseKey?,sourceFileId?,supportingSourceFileIds?[],sourceMode?,generation?,outputPlan?,archived?}; outputPlan:null follows the mission default; phaseKey:null moves an item to unplanned; sourceFileId:null clears a source; archived:true parks an item, re-adding its key revives it; inline JSON or @file:path").action(async d=>{if(d.goal!==void 0&&d.clearGoal)throw new Be("Use either --goal or --clear-goal, not both.");if(d.sourceMode!==void 0&&d.clearSourceMode)throw new Be("Use either --source-mode or --clear-source-mode, not both.");if(d.generation!==void 0&&d.clearGeneration)throw new Be("Use either --generation or --clear-generation, not both.");if(d.outputPlan!==void 0&&d.clearOutputPlan)throw new Be("Use either --output-plan or --clear-output-plan, not both.");if(d.reviewPolicy!==void 0&&d.clearReviewPolicy)throw new Be("Use either --review-policy or --clear-review-policy, not both.");if(d.destinationFolder!==void 0&&d.clearDestinationFolder)throw new Be("Use either --destination-folder or --clear-destination-folder, not both.");await me("updateMission",d,async()=>({missionId:d.missionId,expectedRevision:d.expectedRevision,...d.title===void 0?{}:{title:d.title},...d.goal===void 0&&!d.clearGoal?{}:{goal:d.clearGoal?null:d.goal},...d.scope===void 0?{}:{scope:d.scope},...d.sourceMode===void 0&&!d.clearSourceMode?{}:{sourceMode:d.clearSourceMode?null:d.sourceMode},...d.generation===void 0&&!d.clearGeneration?{}:{generation:d.clearGeneration?null:await Ae(d.generation)},...d.phases===void 0?{}:{phases:await Ae(d.phases)},...d.outputPlan===void 0&&!d.clearOutputPlan?{}:{outputPlan:d.clearOutputPlan?null:await Ae(d.outputPlan)},...d.reviewPolicy===void 0&&!d.clearReviewPolicy?{}:{reviewPolicy:d.clearReviewPolicy?null:await ns(d.reviewPolicy)},...d.destinationFolder===void 0&&!d.clearDestinationFolder?{}:{destinationFolderId:d.clearDestinationFolder?null:d.destinationFolder},...d.visibility===void 0?{}:{visibility:d.visibility},...d.applyOutputPlan?{applyOutputPlan:!0}:{},...d.items===void 0?{}:{items:await Ae(d.items)}}),!0)})),e.addCommand(ze(new B("reorder")).description("Replace the complete order: phases in bucket order and every live item once; moves items between phases without touching running preparation").argument("<mission-id>","Mission ID").requiredOption("--expected-order-revision <n>","Current orderRevision from mission status",rs).requiredOption("--buckets <json-or-file>","Ordered array of {phaseId|null,itemIds[]} listing every live phase and item; inline JSON or @file:path").action(async(d,g)=>me("reorderMission",g,async()=>({missionId:d,expectedOrderRevision:g.expectedOrderRevision,buckets:await Ae(g.buckets)}),!0))),e.addCommand(Kt(new B("list")).description("List saved missions").option("--limit <n>","Rows to return, maximum 50",Ai,20).option("--offset <n>","Zero-based offset",Ai,0).option("--archived <mode>","exclude (default), only, or all archived missions",b("--archived",["exclude","only","all"]),"exclude").option("--favorite","Only missions you have starred").option("--q <text>","Case-insensitive title or goal match").option("--attention","Include how many items in each mission need you").option("--view <view>","personal (your private missions), team_mine (team missions you created) or team_others (team missions others created)",b("--view",["personal","team_mine","team_others"])).action(async d=>me("listMissions",d,()=>({limit:d.limit,offset:d.offset,archived:d.archived,favorite:d.favorite===!0,attention:d.attention===!0,...d.q===void 0?{}:{q:d.q},...d.view===void 0?{}:{view:d.view}}))));for(let[d,g,y,v]of[["favorite","setMissionFavorite","favorite","Star a mission so it stays at the top of your list; --favorite false removes the star"],["pin","setMissionPin","pinned","Pin a mission for the whole workspace; --pinned false lifts the pin"],["archive","setMissionArchived","archived","Archive a mission so it leaves the active list; --archived false restores it"]])e.addCommand(ze(new B(d)).description(v).argument("<mission-id>","Mission ID").option(`--${y} <${y}>`,"true to apply, false to remove",b(`--${y}`,["true","false"]),"true").action(async(x,T)=>me(g,T,()=>({missionId:x,[y]:T[y]==="true"}),!0)));for(let[d,g,y]of[["status","getMissionStatus","Read counts and currently accessible selected artifacts"],["reconcile","reconcileMission","Discover candidate artifact links without changing the mission"]]){let v=Kt(new B(d)).description(y).requiredOption("--mission-id <id>","Mission ID");g==="getMissionStatus"&&v.option("--history-item <id>","Also return this item's version history").option("--wait-for-import-ms <n>","Hold up to this long (max 15000) while the mission's import runs",Ai),e.addCommand(v.action(async x=>me(g,x,()=>({missionId:x.missionId,...x.historyItem?{historyItemId:x.historyItem}:{},...x.waitForImportMs?{waitForSourceImportMs:x.waitForImportMs}:{}}))))}e.addCommand(ze(new B("adopt")).description("Select an existing artifact chain; does not approve or regenerate content").requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--expected-revision <n>","Revision from the latest status or reconciliation",Ai).requiredOption("--selection <json-or-file>","Selected presentationId, projectId and renderId; nulls detach links").action(async d=>me("adoptMission",d,async()=>({missionId:d.missionId,itemId:d.itemId,expectedRevision:d.expectedRevision,selection:await Ae(d.selection)}),!0)));let r=ze(new B("prepare")).description("Prepare items for narration review; each advances independently and waits at its own review").argument("<mission-id>","Mission ID").option("--items <json-or-file>","Array of {itemId,expectedItemRevision} from mission status; inline JSON or @file:path").option("--phase-id <id>","Prepare every live deliverable item of this phase instead of --items; membership is frozen when admitted").option("--stages <stages>","Comma-separated stages: import,draft,notes,narrate,review,post,reel,agent,voice,render; defaults to import,draft,review").option("--no-wait","Return the run ID; recover with mission prepare status <run-id>").option("--yes","Required when --stages includes notes, narrate, post, reel, agent, voice or render").option("--allow-deck-generation","Authorize billed deck generation for document (non-PowerPoint) sources").option("--review-policy <policy>",`This request's own review policy, overriding the mission's. ${ts}`).option("--credit-ceiling <credits>","The most credits this request may commit; a billed step that would pass it does not start").action(async(d,g)=>{g.items===void 0==(g.phaseId===void 0)&&(a("Pass either --items or --phase-id."),process.exit(s.INVALID_INPUT));let y=g.stages===void 0?void 0:String(g.stages).split(",").map(v=>v.trim()).filter(Boolean);if(y!==void 0){let v=new Set(["import","draft","notes","narrate","review","post","reel","agent","voice","render"]);for(let T of y)if(!v.has(T))throw new Be(`Unknown prepare stage '${T}'.`);let x=["notes","narrate","post","reel","agent","voice","render"].filter(T=>y.includes(T));x.length>0&&!g.yes&&(a(`Pass --yes to authorize billed generation for these items (${x.join(", ")}).`),process.exit(s.INVALID_INPUT))}await Ti("prepareMission",g,async()=>({...g.items===void 0?{phaseId:g.phaseId}:{items:await Ae(String(g.items))},...g.allowDeckGeneration===!0?{allowDeckGeneration:!0}:{},...g.reviewPolicy===void 0?{}:{reviewPolicy:await ns(String(g.reviewPolicy))},...g.creditCeiling===void 0?{}:{creditCeiling:uS(String(g.creditCeiling))},...y===void 0?{}:{stages:y},missionId:d}),"Mission preparation failed.")});r.addCommand(ce(ze(new B("stop"))).description("Stop in-flight preparation: cancels running generation, import and narration work; completed work is kept").argument("<mission-id>","Mission ID").option("--item-ids <json-or-file>","Optional array of item IDs to stop; inline JSON or @file:path; defaults to every live item").action(async function(d,g){let y=k(this,g);await me("stopMissionPreparation",y,async()=>({missionId:d,...y.itemIds===void 0?{}:{itemIds:await Ae(y.itemIds)}}),!0)})),r.addCommand(ce(Kt(new B("status"))).description("Read one mission preparation run's progress").argument("<run-id>","Run ID returned by mission prepare").action(async function(d,g){let y=k(this,g);try{m(await R("prepareMission",d,y.teamId))}catch(v){a(u(v,"Prepare status failed.")),process.exit(s.GENERAL_ERROR)}})),e.addCommand(r);let i=new B("review").description("Freeze narration for human review, then record the browser-approved decision");i.addCommand(dt(new B("request")).description("Freeze the selected narration draft for review; does not render").requiredOption("--expected-review-fingerprint <fingerprint>","SHA-256 fingerprint of the narration draft to freeze",pS).action(async d=>me("requestMissionNarrationReview",d,()=>({expectedItemRevision:d.expectedItemRevision,expectedReviewFingerprint:d.expectedReviewFingerprint,itemId:d.itemId,missionId:d.missionId}),!0))),i.addCommand($i(dt(new B("approve"))).description("Record a browser-approved narration review; does not render").requiredOption("--review-id <id>","Frozen narration review ID").action(async d=>{Oi(d,"narration approval"),await me("approveMissionNarration",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,reviewId:d.reviewId,missionId:d.missionId}),!0)})),e.addCommand(i);let o=new B("output").description("Link, render and accept item outputs; linking never accepts");o.addCommand($i(dt(new B("accept"))).description("Record browser-approved acceptance of one completed render").requiredOption("--render-id <id>","Completed render ID").action(async d=>{Oi(d,"output acceptance"),await me("acceptMissionOutput",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,renderId:d.renderId,missionId:d.missionId}),!0)})),o.addCommand($i(dt(new B("accept-slot"))).description("Record browser-approved acceptance of the artifact filling one output").requiredOption("--slot <key>","Output slot key from mission status").requiredOption("--fulfillment-id <id>","The output's fulfillmentId from mission status").action(async d=>{Oi(d,"output acceptance"),await me("acceptMissionOutputSlot",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,fulfillmentId:d.fulfillmentId,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot}),!0)})),o.addCommand(dt(new B("link")).description("Fill one of an item's manual outputs with an existing presentation or finished video; never accepts it").requiredOption("--slot <key>","Output slot key from mission status").requiredOption("--target-id <id>","Presentation ID, or narrated-video project ID").option("--target-version <id>","For a video, the finished render ID to link").action(async d=>me("linkMissionOutput",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot,targetId:d.targetId,...d.targetVersion===void 0?{}:{targetVersion:d.targetVersion}}),!0)));let c=dt(new B("render")).description("Start or resume the approved narration render; waits by default").requiredOption("--review-id <id>","Human-approved narration review ID").option("--no-wait","Return the run ID; recover with mission output render status <run-id>").option("--yes","Confirm starting this approved render").action(async d=>{gS(d),await Ti("renderMissionOutput",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,reviewId:d.reviewId,missionId:d.missionId}))});c.addCommand(vp(ze(new B("recover"))).description("Finish a recorded render start, or read its recovery state").requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--review-id <id>","Narration review ID the render intent was recorded against").requiredOption("--intent-id <id>","Render intent ID from mission status").action(async function(d){let g=k(this,d);await me("recoverMissionRenderIntent",g,()=>({itemId:g.itemId,intentId:g.intentId,reviewId:g.reviewId,missionId:g.missionId}),!0)})),c.addCommand(ce(Kt(new B("status"))).description("Read one mission render run's progress or result").argument("<run-id>","Run ID returned by mission output render start").action(async function(d,g){let y=k(this,g);try{m(await R("renderMissionOutput",d,y.teamId))}catch(v){a(u(v,"Render status failed.")),process.exit(s.GENERAL_ERROR)}})),o.addCommand(c);let l=dt(new B("regenerate")).description("Regenerate one automated output (deck from its source; narrated video, LinkedIn post or reel from the current deck); the current output stays until the new one is ready").requiredOption("--slot <key>","Output slot key from mission status").option("--allow-deck-generation","Consent to billed deck generation for a document source").option("--allow-narration","Consent to billed new narration").option("--allow-text-generation","Consent to a billed model-written post (LinkedIn post output)").option("--allow-reel-render","Consent to a billed reel render").option("--allow-agent-runs","Consent to a billed agent run (an output a team agent delivers)").option("--no-wait","Return the run ID; recover with mission output regenerate status <run-id>").option("--yes","Confirm regenerating this output").action(async d=>{d.yes||(a("Pass --yes to confirm regenerating this output."),process.exit(s.INVALID_INPUT)),await Ti("regenerateMissionOutput",d,()=>({...d.allowDeckGeneration===!0?{allowDeckGeneration:!0}:{},...d.allowNarration===!0?{allowNarration:!0}:{},...d.allowTextGeneration===!0?{allowTextGeneration:!0}:{},...d.allowReelRender===!0?{allowReelRender:!0}:{},...d.allowAgentRuns===!0?{allowAgentRuns:!0}:{},expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot}))});return l.addCommand(ce(Kt(new B("status"))).description("Read one output regeneration run's progress or result").argument("<run-id>","Run ID returned by mission output regenerate").action(async function(d,g){let y=k(this,g);try{m(await R("regenerateMissionOutput",d,y.teamId))}catch(v){a(u(v,"Regenerate status failed.")),process.exit(s.GENERAL_ERROR)}})),o.addCommand(l),e.addCommand(o),e.addCommand($i(ze(new B("delete"))).description("Permanently delete a mission and its bookkeeping; produced artifacts stay in the Library unless --delete-artifacts destroys them too").argument("<mission-id>","Mission ID").option("--delete-artifacts","Also destroy the decks and narrated-video projects this mission produced or adopted").action(async(d,g)=>{Oi(g,"mission deletion"),await me("deleteMission",g,()=>({approvalReceipt:_(g),deleteArtifacts:g.deleteArtifacts===!0,missionId:d}),!0)})),e}var Ou=fS();import{randomUUID as hS}from"crypto";import{Command as as}from"commander";import is from"ora";function os(e,t){if(t==="json"){m(e);return}if(t==="quiet"){e.outputUrl?console.log(e.outputUrl):console.log(e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.outputUrl&&C(`Output URL: ${e.outputUrl}`),e.error&&a(`Error: ${e.error}`)}var yS=new as("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(g){a(u(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 i=e.format,o=i==="human"?is("Mixing audio...").start():null,c=e.inputsJson?bS("--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 l,d=e.idempotencyKey??hS();try{let g=e.optionsJson?wS("--options-json",e.optionsJson):{},y=await hc({operation:e.operation,inputs:c,options:e.inputsJson?g:{...g,musicVolume:n,voiceVolume:r}},{approvalReceipt:t,idempotencyKey:d});if(l=y.requestId,!e.wait){o?.stop(),os(y,i);return}o&&(o.text=`Processing (ID: ${y.requestId})...`);let v=await $e(()=>Lo(y.requestId),120,3e3);if(o?.stop(),v.status==="failed")throw new de(v.error||"Audio mixing failed");if(os(v,i),e.output){if(!v.outputUrl)throw new Error("Audio mix completed without an output URL");let x=i==="human"?is("Downloading...").start():null;await Ie(v.outputUrl,e.output),x?.stop(),i==="human"&&C(`Saved to: ${e.output}`)}}catch(g){o?.stop(),a(`${oe(g,l)}${Ee(g,d)}`,i),process.exit(s.GENERAL_ERROR)}});function bS(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 wS(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 vS=new as("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format==="human"?is("Checking status...").start():null;try{let r=await Lo(e);n?.stop(),os(r,t.format)}catch(r){n?.stop(),a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),$u=new as("mix").description("Audio mixing commands").addCommand(yS).addCommand(vS);import{randomUUID as ES}from"crypto";import{Command as ds}from"commander";import PS from"ora";import{readFileSync as IS}from"fs";var Du=500,Nu=1e4,Di=100,Lu=1e4,Uu=1e3,ju=["duration_s","idempotency_key","narration","schema_version","video_description"],kS=["end_s","id","start_s","text","words"],xS=["end","id","start","text"],RS=["description","end_s","id","start_s"];function qu(e){let t=Vu(e);if(Fu(t),hr(t,ju,""),t.duration_s<3)throw new Error("Music request duration_s must be between 3 and 600");return t}function Mu(e){let t=Vu(e);Fu(t),hr(t,[...ju,"visual_event"],"");let n=t.visual_event;if(!Ni(n))throw new Error("SFX request visual_event is required");if(hr(n,RS,"visual_event"),!vt(n.description))throw new Error("SFX request visual_event.description is required");if(!vt(n.id)||!It(n.start_s))throw new Error("SFX request visual_event requires id and start_s");if(n.end_s!==void 0&&(!It(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 Vu(e){try{let t=JSON.parse(IS(e,"utf8"));if(!Ni(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 Fu(e){if(e.schema_version!==1)throw new Error("Audio request schema_version must be 1");if(!vt(e.video_description))throw new Error("Audio request video_description is required");if(!It(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>Du)throw new Error(`Audio request narration holds at most ${Du} lines`);if(e.narration.forEach(CS),e.idempotency_key!==void 0&&!vt(e.idempotency_key))throw new Error("Audio request idempotency_key must be a non-empty string")}function CS(e,t){let n=`narration.${t}`;if(!Ni(e))throw new Error(`Audio request ${n} must be an object`);if(hr(e,kS,n),!vt(e.id)||e.id.length>Di)throw new Error(`Audio request ${n}.id is required (1-${Di} characters)`);if(!vt(e.text)||e.text.trim().length>Lu)throw new Error(`Audio request ${n}.text is required (1-${Lu} characters)`);if(_u(e.start_s,`${n}.start_s`),_u(e.end_s,`${n}.end_s`),It(e.start_s)&&It(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>Nu)throw new Error(`Audio request ${n}.words must be an array of at most ${Nu} entries`);e.words.forEach((r,i)=>{SS(r,`${n}.words.${i}`)})}}function SS(e,t){if(!Ni(e))throw new Error(`Audio request ${t} must be an object`);if(hr(e,xS,t),!vt(e.text)||e.text.trim().length>Uu)throw new Error(`Audio request ${t}.text is required (1-${Uu} characters)`);if(!It(e.start)||!It(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&&(!vt(e.id)||e.id.length>Di))throw new Error(`Audio request ${t}.id must be 1-${Di} characters`)}function _u(e,t){if(e!==void 0&&!It(e))throw new Error(`Audio request ${t} must be a non-negative number`)}function hr(e,t,n){let r=Object.keys(e).filter(o=>!t.includes(o));if(r.length===0)return;let i=n?`${n} `:"";throw new Error(`Audio request ${i}has unknown field(s): ${r.join(", ")}. Allowed: ${t.join(", ")}`)}function Ni(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function vt(e){return typeof e=="string"&&e.trim().length>0}function It(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0}function ss(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.audioUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.audioUrl&&C(`Audio URL: ${e.audioUrl}`),e.error&&a(`Error: ${e.error}`)}var AS=new ds("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(l){a(u(l)),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?qu(e.request):{...e.duration?{duration:Number(e.duration)}:{},...e.durationSeconds?{duration_s:Number(e.durationSeconds)}:{},...e.narrationJson?{narration:Bu("--narration-json",e.narrationJson)}:{},...e.optionsJson?{options:Bu("--options-json",e.optionsJson)}:{},...e.prompt?{prompt:e.prompt}:{},...e.schemaVersion?{schema_version:Number(e.schemaVersion)}:{},...e.videoDescription?{video_description:e.videoDescription}:{}}}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?PS("Generating music for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??ES();try{let l=await fc(n,{approvalReceipt:t,idempotencyKey:c});if(o=l.requestId,!e.wait){i?.stop(),ss(l,r);return}i&&(i.text=`Processing (ID: ${l.requestId})...`);let d=l.status==="completed"||l.status==="failed"?l:await $e(()=>No(l.requestId),180,2e3);if(i?.stop(),d.status==="failed")throw new de(d.error||"Music generation failed");if(e.output){if(!d.audioUrl)throw new Error("Music completed without an audio URL");await Ie(d.audioUrl,e.output),r==="human"&&C(`Saved to: ${e.output}`),d.output=e.output}ss(d,r)}catch(l){i?.stop(),a(`${oe(l,o)}${Ee(l,c)}`,r),process.exit(s.GENERAL_ERROR)}});function Bu(e,t){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON`)}}var TS=new ds("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{ss(await No(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Gu=new ds("music").description("Video-aware music generation commands").addCommand(AS).addCommand(TS);import{Command as cs,InvalidArgumentError as OS}from"commander";function Ku(e,t){return[...t,e]}function Wu(e){return t=>{if(t==="true")return!0;if(t==="false")return!1;throw new OS(`Expected one of: true, false. Run the command with --help to see what ${e} accepts.`)}}function Ju(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var $S=new cs("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",Ku,[]).option("--type <type>","single, multiple, or word-cloud",b("--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",b("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",Wu("--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(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll creation");try{m(await p("createPoll",{approvalReceipt:_(t),closesAt:t.closesAt,description:t.description,options:t.option.map(n=>({text:n})),pollType:t.type,question:e,respondentPolicy:t.respondentPolicy,showResultsToParticipants:t.showResultsToParticipants,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){Ju(n,"Poll creation failed")}}),DS=new cs("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",Ku).option("--type <type>","single, multiple, or word-cloud",b("--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",b("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",Wu("--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(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll update");try{m(await p("editPoll",{approvalReceipt:_(t),chartType:t.chartType,closesAt:t.closesAt,description:t.description,options:t.option?.map(n=>({text:n})),pollId:e,pollType:t.type,question:t.question,respondentPolicy:t.respondentPolicy,showResultsToParticipants:t.showResultsToParticipants,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){Ju(n,"Poll update failed")}}),zu=new cs("poll").description("Standalone poll commands").addCommand($S).addCommand(DS);import{randomUUID as Mn}from"crypto";import{readFile as bf}from"fs/promises";import W from"chalk";import{Command as Y,InvalidArgumentError as eo}from"commander";import{createParser as NS}from"eventsource-parser";async function Ge(e,t,n,r={}){let i=null,o=!1;try{let c;for(;;){let l=await US(await n(c));if(i=l.failure,o=l.completed,i||o||!l.reconnect)break;c=l.lastEventId??c,l.retryMs!==void 0&&l.retryMs>0&&await new Promise(d=>setTimeout(d,l.retryMs))}}catch(c){let l=u(c,"the event stream ended unexpectedly");if(q(`Stopped following run ${e}: ${l}. The run is unaffected \u2014 check it with '${f.commands[0]} ${t} ${e}'.`),r.requireCompletion)throw c;return}if(i)throw new Error(`Run ${e} ${i.status}: ${i.message} Inspect it with '${f.commands[0]} ${t} ${e}'.`);if(r.requireCompletion&&!o)throw new Error(`Completion of run ${e} could not be verified. Check '${f.commands[0]} ${t} ${e}'.`)}function LS(e){let t=e.type==="durable_run_state"&&e.terminal?`durable_run.${e.status}`: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 US(e){if(!e.ok)throw new Error(`Event stream request failed (${e.status})`);let t=e.body?.getReader();if(!t)throw new Error("Speaker notes event stream is unavailable");let n=new TextDecoder,r=null,i=!1,o=!1,c,l,d=NS({onRetry:v=>{l=v},onEvent:v=>{if(v.id!==void 0&&(c=v.id),v.event==="reconnect"){o=!0;return}let x=JSON.parse(v.data);if(v.event==="stream_error"||x.type==="stream_error")throw new Error(x.message?.trim()||"Durable event stream failed.");if(x.type==="reconnect"){o=!0;return}x.eventType?.startsWith("slide.")&&I(`${x.eventType}${x.payload?.slideId?` \xB7 ${x.payload.slideId}`:""}`);let T=LS(x);T==="completed"?(r=null,i=!0):T&&(r=T,i=!1)}}),g=[],y={failure:null,completed:!1,reconnect:!1};try{for(;;){let{done:v,value:x}=await t.read();if(d.feed(n.decode(x,{stream:!v})),v){y={failure:r,completed:i,reconnect:o||l!==void 0,lastEventId:c,retryMs:l};break}}}catch(v){g.push(v)}finally{try{await t.cancel()}catch(v){g.includes(v)||g.push(v)}finally{try{t.releaseLock()}catch(v){g.includes(v)||g.push(v)}}}if(g.length===1)throw g[0];if(g.length>1)throw new AggregateError(g,"Following the run failed and its stream cleanup also failed.",{cause:g[0]});return y}function Li(e){return e instanceof P&&e.errorCode==="not_found"}async function Ui(e){let t=Br.filter(c=>c.id!==e.excludeCapabilityId&&c.lifecycle.mode==="background"&&typeof c.lifecycle.status?.cliCommand=="string"&&c.lifecycle.status.cliCommand.startsWith(e.cliCommandPrefix)),r=(await Promise.allSettled(t.map(c=>R(c.id,e.runId,e.teamId)))).findIndex(c=>c.status==="fulfilled");if(r<0)return null;let i=t[r],o=i.lifecycle.status?.cliCommand;return o?{capabilityId:i.id,statusCommand:o}:null}import{randomUUID as _S}from"crypto";import{Command as _i}from"commander";async function ls(e,t,n,r,i){let o=k(e,r);try{m(await p(t,{...n,teamId:o.teamId},i?o.idempotencyKey??_S():void 0))}catch(c){a(u(c,"Deck embed share request failed")),process.exit(s.GENERAL_ERROR)}}var jS=new _i("mint").description("Mint a revocable embed URL for a public deck (Team plan)").argument("<presentation-id>","Presentation ID or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Unique mint key; reuse is rejected").action(async function(e,t){await ls(this,"mintPresentationDeckEmbedShare",{presentationId:e},t,!0)}),qS=new _i("list").description("List embed shares and revocation state without tokens").argument("<presentation-id>","Presentation ID or slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){await ls(this,"listPresentationDeckEmbedShares",{presentationId:e},t,!1)}),MS=new _i("revoke").description("Revoke an embed share; repeated calls preserve the timestamp").argument("<presentation-id>","Presentation ID or slug").argument("<share-id>","Share ID from mint or list").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Request key").action(async function(e,t,n){await ls(this,"revokePresentationDeckEmbedShare",{presentationId:e,shareId:t},n,!0)}),Hu=new _i("embed").description("Mint, list and revoke standalone deck embed shares").addCommand(jS).addCommand(qS).addCommand(MS);import{readFile as VS}from"fs/promises";import{Command as Xu}from"commander";var FS=new Xu("status").description("Read the saved result and credit-settlement status of a presentation edit").argument("<run-id>","Run ID returned by presentation edit").option("--team-id <id>","Workspace ID override").action(async function(e,t){try{let n=k(this,t);m(await R("editPresentation",e,n.teamId))}catch(n){a(u(n,"Could not read the edit run")),process.exit(s.GENERAL_ERROR)}});async function ms(e){return e?JSON.parse(await VS(e,"utf8")):void 0}var Yu=new Xu("edit").description("Edit a saved deck using Mindframes models and existing metered credits").argument("<presentation-id>","Presentation UUID from presentation list/read").option("--expected-version-slug <slug>","Exact saved version you read; stale edits are refused").option("--instruction <text>","Requested change to the deck (required for editing)").option("--slides <ids>","Comma-separated stable slide IDs; omit for the full deck").option("--tier <tier>","fast, basic, advanced, auto; defaults to your Mindframes preference",b("--tier",["fast","basic","advanced","auto"])).option("--interaction-context <path>","JSON file containing Studio selection/target context").option("--slide-annotations <path>","JSON file containing slide annotations").option("--attachments <path>","JSON file containing authorized upload references").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this exact edit").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--yes","Confirm use of existing metered credits; server approval is still required").option("--no-wait","Return the recovery run ID immediately").addCommand(FS).action(async function(e,t){let n=k(this,t),r=n.idempotencyKey;try{if(!n.expectedVersionSlug||!n.instruction?.trim())throw new Error("Editing requires --expected-version-slug and --instruction. Status reads require only a run ID.");if(!n.yes)throw new Error("Pass --yes to confirm metered credits. Mindframes also requires browser approval for this exact edit.");await w();let i=await U(n.teamId),o={presentationId:e,expectedVersionSlug:n.expectedVersionSlug,instruction:n.instruction,...n.slides?{targetSlideIds:n.slides.split(",").map(d=>d.trim()).filter(Boolean)}:{},...n.tier?{tier:n.tier}:{},...n.interactionContext?{interactionContext:await ms(n.interactionContext)}:{},...n.slideAnnotations?{slideAnnotations:await ms(n.slideAnnotations)}:{},...n.attachments?{attachments:await ms(n.attachments)}:{}};r??=Q({command:"presentation:edit",payload:o,workspaceId:i});let c=_(n),l=await p("editPresentation",{...o,teamId:i,...c?{approvalReceipt:c}:{}},r);if(m({...l,idempotencyKey:r}),n.wait!==!1){await Ge(l.runId,"presentation edit status",g=>Xd(l.runId,i,g),{requireCompletion:!0});let d=await R("editPresentation",l.runId,i);if(d.status!=="completed")throw new Error(`Edit ${l.runId} is ${d.status}. Use presentation edit status to inspect its saved result.`);m(d)}}catch(i){r&&q(`Retry this exact input with --idempotency-key ${r}`),a(u(i,"Could not edit the presentation")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as Zu}from"crypto";import{Command as ji}from"commander";var BS=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Qu(e,t){BS.test(e)||(a(`"${e}" is not a ${t} id.`),process.exit(s.INVALID_INPUT))}function ps(e,t,n){let r=Number(e);return(!Number.isInteger(r)||r<1||n&&r>n)&&(a(`${t} must be a whole number from 1${n?` to ${n}`:" up"}.`),process.exit(s.INVALID_INPUT)),r}async function us(e,t,n,r){try{m(await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}var GS=new ji("create").description("Build a governed HCP deck from a brand's approved claims, ISI and references").requiredOption("--brand-id <id>","Brand whose claims library is used").requiredOption("--title <title>","Neutral deck title (a title that states a claim is refused)").option("--brief <text>","What the deck is for; steers claim choice only").option("--audience <audience>","Claims library audience (default: hcp)").option("--market <market>","Market, e.g. US").option("--product-id <id>","Brand product to narrow claims to").option("--product-label <label>","Product name for the title slide").option("--content-slides <n>","Claim slides, 1-8 (default: 4)").option("--allow-pre-launch","Also use claims signed off for pre-launch use only").option("--idempotency-key <key>","Reuse a request key to retry this same create").option("--team-id <id>","Workspace ID").action(async e=>{await w(),Qu(e.brandId,"brand"),e.productId&&Qu(e.productId,"product"),await us("createGovernedDeck",{brandId:e.brandId,title:e.title,...e.brief?{brief:e.brief}:{},...e.audience?{audience:e.audience}:{},...e.market?{market:e.market}:{},...e.productId?{productId:e.productId}:{},...e.productLabel?{productLabel:e.productLabel}:{},...e.contentSlides?{contentSlides:ps(e.contentSlides,"--content-slides",8)}:{},...e.allowPreLaunch?{allowPreLaunch:!0}:{},...e.teamId?{teamId:e.teamId}:{}},"Create failed",e.idempotencyKey??Zu())}),KS=new ji("get").description("Read a governed deck version: claim map, fresh checks, approval and claim options").argument("<id-or-slug>","Presentation ID or slug").option("--version-number <n>","Deck version (default: latest)").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),await us("getGovernedDeck",{presentationId:e,...t.versionNumber?{versionNumber:ps(t.versionNumber,"--version-number")}:{},...t.teamId?{teamId:t.teamId}:{}},"Read failed")}),WS=new ji("set-claim").description("Switch one claim slot to another approved claim (a new deck version)").argument("<id-or-slug>","Presentation ID or slug").requiredOption("--slide-id <id>","Slide the claim slot is on").requiredOption("--from <claim-key>","Claim now in the slot").requiredOption("--to <claim-key>","Approved claim to put in the slot").requiredOption("--expected-version-number <n>","The deck version you read; a stale value is refused").option("--idempotency-key <key>","Reuse a request key to retry this same change").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),await us("setGovernedDeckClaim",{expectedVersionNumber:ps(t.expectedVersionNumber,"--expected-version-number"),fromClaimKey:t.from,presentationId:e,slideId:t.slideId,toClaimKey:t.to,...t.teamId?{teamId:t.teamId}:{}},"Claim change failed",t.idempotencyKey??Zu())}),gs=new ji("governed").description("Governed HCP decks: claims only from the approved library, locked ISI and References (a person approves versions in the app)").addCommand(GS).addCommand(KS).addCommand(WS);gs.addHelpText("after",`
125
+ `);import{randomUUID as Su}from"crypto";import{Command as jn,InvalidArgumentError as Eu}from"commander";var Pu=new jn("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??Su();try{m(await p("analyzeMediaAsset",{assetId:e,diarize:t.diarize,language:t.language,teamId:t.teamId},n))}catch(r){a(`${u(r,"Analysis failed")} Retry with --idempotency-key ${n}.`),process.exit(s.GENERAL_ERROR)}}),dS=new jn("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=k(this,t);try{m(await R("analyzeMediaAsset",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});Pu.addCommand(dS);var Au=new jn("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(e,t)=>{try{m(await p("importConnectorRecording",{connectorId:t.connector,providerId:t.provider,remoteFileId:e,sourceChatId:t.chat,teamId:t.teamId,title:t.title},t.idempotencyKey??Su()))}catch(n){a(u(n,"Import failed")),process.exit(s.GENERAL_ERROR)}}),cS=new jn("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=k(this,t);try{m(await R("importConnectorRecording",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}});Au.addCommand(ce(cS));function ts(e,t){return n=>{let r=Number(n);if(!/^\d+$/u.test(n)||!Number.isSafeInteger(r)||r<e||r>t)throw new Eu(`Expected an integer from ${e} to ${t}.`);return r}}function Cu(e){let t=Number(e);if(!e.trim()||!Number.isFinite(t)||t<0)throw new Eu("Expected nonnegative source seconds.");return t}var lS=new jn("show").description("Read recording metadata and a page of its timestamped transcript").argument("<asset-id>","Recording ID or slug").option("--after-segment-index <index>","Continue after the previous page's segment index",ts(0,Number.MAX_SAFE_INTEGER)).option("--limit <count>","Maximum segments (1\u2013200; default 100)",ts(1,200)).option("--evidence <kind>","segments (discovery) or words (precise cuts)").option("--after-word-index <index>","Continue precise evidence after the word cursor",ts(0,Number.MAX_SAFE_INTEGER)).option("--start-sec <seconds>","Precise evidence window start",Cu).option("--end-sec <seconds>","Precise evidence window end",Cu).option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getMediaAsset",{assetId:e,evidence:t.evidence,afterWordIndex:t.afterWordIndex,startSec:t.startSec,endSec:t.endSec,afterSegmentIndex:t.afterSegmentIndex,limit:t.limit,teamId:t.teamId}))}catch(n){a(u(n,"Recording read failed")),process.exit(s.GENERAL_ERROR)}}),Tu=new jn("media").description("Ingest and transcribe recordings you already own").addCommand(lS).addCommand(Pu).addCommand(Au);import{Command as ns}from"commander";function mS(e,t){let n=e.indexOf("=");return n<=0&&(a("Pass --additional-page as /path=Title"),process.exit(s.INVALID_INPUT)),[...t,{path:e.slice(0,n),title:e.slice(n+1)}]}var pS=new ns("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)",mS,[]).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(e,t)=>{if(!t.yes)return a("Pass --yes to approve generation");try{m(await p("createMicrosite",{additionalPages:t.additionalPage.length?t.additionalPage:void 0,approvalReceipt:_(t),audience:t.audience,brandingId:t.brandingId,description:t.description,designBrandReference:t.designBrandReference,language:t.language,teamId:t.teamId,title:e,tone:t.tone},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),uS=new ns("status").description("Read microsite generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createMicrosite",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Ou=new ns("microsite").description("Generate a shareable multi-section web microsite from a brief").addCommand(pS).addCommand(uS);import{randomUUID as $u}from"crypto";import{readFile as gS}from"fs/promises";import{Command as B,InvalidArgumentError as Be}from"commander";function Ti(e){let t=Number(e);if(!e.trim()||!Number.isSafeInteger(t)||t<0)throw new Be("Expected a nonnegative whole number.");return t}function os(e){let t=Number(e);if(!e.trim()||!Number.isSafeInteger(t)||t<=0)throw new Be("Expected a positive whole number.");return t}function fS(e){if(!/^[a-f0-9]{64}$/u.test(e))throw new Be("Expected a lowercase SHA-256 fingerprint.");return e}function Kt(e){return e.option("--team-id <id>","Workspace ID; defaults to the selected workspace")}function ze(e){return Kt(e).option("--idempotency-key <key>","Stable key for an exact retry")}var rs='Where the mission stops for a person: each_step, key_steps (import review + narration script + final), autopilot, or {preset:"custom",stopAt:[import|generatedDeck|narrationScript|render|final]} as inline JSON or @file:path';function hS(e){let t=Number(e);if(!Number.isInteger(t)||t<=0)throw new Be("--credit-ceiling must be a positive whole number of credits.");return t}async function is(e){return["each_step","key_steps","autopilot"].includes(e)?{preset:e}:Ae(e)}async function Ae(e){return JSON.parse(e.startsWith("@file:")?await gS(e.slice(6),"utf8"):e)}async function me(e,t,n,r=!1){let i=r?t.idempotencyKey??`cli:mission:${$u()}`:void 0;try{m(await p(e,{...await n(),teamId:t.teamId},i))}catch(o){let c=o instanceof P&&o.errorCode==="approval_required"?`${o.approvalUrl?` Open ${o.approvalUrl}.`:""} Retry this exact request with --approval-receipt <receipt> --idempotency-key ${i}.`:"";a(`${u(o,"Mission request failed.")}${c||(i?Ee(o,i):"")}`),process.exit(s.GENERAL_ERROR)}}async function Oi(e,t,n,r="Mission render failed."){let i=t.idempotencyKey??`cli:mission:${$u()}`;try{let o=await p(e,{...await n(),teamId:t.teamId},i);m(t.wait===!1?o:await z(e,o.runId,t.teamId))}catch(o){a(un(o)?oe(o):`${u(o,r)}${Ee(o,i)}`),process.exit(s.GENERAL_ERROR)}}function $i(e,t){e.yes||(a(`Pass --yes to confirm ${t}; browser approval still requires --approval-receipt.`),process.exit(s.INVALID_INPUT))}function yS(e){e.yes||(a("Pass --yes to start rendering the human-approved narration."),process.exit(s.INVALID_INPUT))}function dt(e){return ze(e).requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--expected-item-revision <n>","Current item revision from mission status",os)}function Di(e){return e.option("--approval-receipt <receipt>","Browser-issued receipt for this exact request; omit first to receive its confirmation URL").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin instead of argv").option("--yes","Confirm intent only; a browser-issued approval receipt is still required")}function bS(){let e=new B("mission").description("Track a mission's intended outcomes and connect existing artifacts");e.addCommand(ze(new B("create")).description("Create a scoped set of intended narrated-video outcomes; no generation starts").requiredOption("--title <title>","Name for this mission").option("--goal <goal>","Optional desired outcome").option("--scope <scope>","Finite scope or ongoing collection",b("--scope",["finite","ongoing"]),"finite").option("--source-mode <mode>","How item sources become slides: as-is imports PowerPoint decks, reference generates a new deck from each document",b("--source-mode",["as-is","reference"])).option("--generation <json-or-file>","Default deck-generation settings for document sources {language?,tone?,audience?,amount?,additionalContext?}; inline JSON or @file:path").option("--phases <json-or-file>","Ordered array of {key,label,brief?}; items join one with phaseKey; inline JSON or @file:path").option("--review-policy <policy>",rs).option("--destination-folder <folder-id>","Library folder approved outputs are filed into (default: one named after the mission)").option("--visibility <visibility>","team (default: every member sees it) or private (only you)",b("--visibility",["team","private"])).option("--output-plan <json-or-file>",'Default outputs per deliverable item as {slots:[{slotKey,kind:presentation|video|document|reel,label,parent:"source"|{slotKey},countsTowardDone,fulfillment:{mode:"manual"}|{mode:"automated",runtimeKey}|{mode:"agent",agentId}}]}, up to 8 slots; omit for deck -> narrated video; inline JSON or @file:path').requiredOption("--items <json-or-file>","Array of {key,label,role?:deliverable|reference,phaseKey?,sourceFileId?,supportingSourceFileIds?[],sourceMode?,generation?,outputPlan?} in order; groupKey is a deprecated alias of phaseKey; inline JSON or @file:path").action(async d=>me("createMission",d,async()=>({title:d.title,goal:d.goal,scope:d.scope,...d.phases===void 0?{}:{phases:await Ae(d.phases)},...d.outputPlan===void 0?{}:{outputPlan:await Ae(d.outputPlan)},...d.reviewPolicy===void 0?{}:{reviewPolicy:await is(d.reviewPolicy)},...d.destinationFolder===void 0?{}:{destinationFolderId:d.destinationFolder},...d.visibility===void 0?{}:{visibility:d.visibility},...d.sourceMode===void 0?{}:{sourceMode:d.sourceMode},...d.generation===void 0?{}:{generation:await Ae(d.generation)},items:await Ae(d.items)}),!0)));let t=new B("source").description("Create an independent presentation from an item's current Library source"),n=dt(new B("import")).description("Start or explicitly retry this item's independent PowerPoint import").option("--no-wait","Return the run ID; recover with mission source import status <run-id>").action(async d=>{await Oi("startMissionSourceImport",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId}),"Mission source import failed.")});n.addCommand(ce(Kt(new B("status"))).description("Read one mission source import run").argument("<run-id>","Run ID returned by mission source import").action(async function(d,g){let y=k(this,g);try{m(await R("startMissionSourceImport",d,y.teamId))}catch(v){a(u(v,"Source import status failed.")),process.exit(s.GENERAL_ERROR)}})),t.addCommand(n),t.addCommand(dt(new B("replace")).description("Replace a blocked item's source with another Library PowerPoint").requiredOption("--source-file-id <file-id>","Replacement Library PowerPoint file").action(async d=>me("replaceMissionItemSource",d,()=>({missionId:d.missionId,itemId:d.itemId,expectedItemRevision:d.expectedItemRevision,sourceFileId:d.sourceFileId}),"Mission source replacement failed."))),e.addCommand(t),e.addCommand(ze(new B("update")).description("Update intent, scope, or source links; existing accepted outputs remain recorded").requiredOption("--mission-id <id>","Mission ID").requiredOption("--expected-revision <n>","Current mission revision from status",os).option("--title <title>","Replacement mission title").option("--goal <goal>","Replacement desired outcome").option("--clear-goal","Remove the saved desired outcome").option("--scope <scope>","Finite scope or ongoing collection",b("--scope",["finite","ongoing"])).option("--source-mode <mode>","How item sources become slides: as-is imports PowerPoint decks, reference generates a new deck from each document",b("--source-mode",["as-is","reference"])).option("--clear-source-mode","Remove the saved source-mode default; item-level modes still apply").option("--generation <json-or-file>","Replacement deck-generation defaults for document sources; inline JSON or @file:path").option("--clear-generation","Remove the saved deck-generation defaults; item-level settings still apply").option("--phases <json-or-file>","Phase upserts as {key,label?,brief?,archived?}; new keys are appended, archived:true needs the phase empty, archived:false restores it; reorder with mission reorder; inline JSON or @file:path").option("--output-plan <json-or-file>","Replacement default output plan (see mission create); items with outputs keep their slots unless --apply-output-plan; inline JSON or @file:path").option("--clear-output-plan","Return the default to deck -> narrated video").option("--review-policy <policy>",rs).option("--clear-review-policy","Return to checking each step").option("--destination-folder <folder-id>","Library folder approved outputs are filed into from now on").option("--clear-destination-folder","Return to the default folder named after the mission").option("--visibility <visibility>","team (every member sees it) or private (only you); only the mission's creator may change it",b("--visibility",["team","private"])).option("--apply-output-plan","Apply the effective plan to every live deliverable now, including items with outputs (changed slots restart empty; history is kept)").option("--items <json-or-file>","Upserts as {key,label,role?,phaseKey?,sourceFileId?,supportingSourceFileIds?[],sourceMode?,generation?,outputPlan?,archived?}; outputPlan:null follows the mission default; phaseKey:null moves an item to unplanned; sourceFileId:null clears a source; archived:true parks an item, re-adding its key revives it; inline JSON or @file:path").action(async d=>{if(d.goal!==void 0&&d.clearGoal)throw new Be("Use either --goal or --clear-goal, not both.");if(d.sourceMode!==void 0&&d.clearSourceMode)throw new Be("Use either --source-mode or --clear-source-mode, not both.");if(d.generation!==void 0&&d.clearGeneration)throw new Be("Use either --generation or --clear-generation, not both.");if(d.outputPlan!==void 0&&d.clearOutputPlan)throw new Be("Use either --output-plan or --clear-output-plan, not both.");if(d.reviewPolicy!==void 0&&d.clearReviewPolicy)throw new Be("Use either --review-policy or --clear-review-policy, not both.");if(d.destinationFolder!==void 0&&d.clearDestinationFolder)throw new Be("Use either --destination-folder or --clear-destination-folder, not both.");await me("updateMission",d,async()=>({missionId:d.missionId,expectedRevision:d.expectedRevision,...d.title===void 0?{}:{title:d.title},...d.goal===void 0&&!d.clearGoal?{}:{goal:d.clearGoal?null:d.goal},...d.scope===void 0?{}:{scope:d.scope},...d.sourceMode===void 0&&!d.clearSourceMode?{}:{sourceMode:d.clearSourceMode?null:d.sourceMode},...d.generation===void 0&&!d.clearGeneration?{}:{generation:d.clearGeneration?null:await Ae(d.generation)},...d.phases===void 0?{}:{phases:await Ae(d.phases)},...d.outputPlan===void 0&&!d.clearOutputPlan?{}:{outputPlan:d.clearOutputPlan?null:await Ae(d.outputPlan)},...d.reviewPolicy===void 0&&!d.clearReviewPolicy?{}:{reviewPolicy:d.clearReviewPolicy?null:await is(d.reviewPolicy)},...d.destinationFolder===void 0&&!d.clearDestinationFolder?{}:{destinationFolderId:d.clearDestinationFolder?null:d.destinationFolder},...d.visibility===void 0?{}:{visibility:d.visibility},...d.applyOutputPlan?{applyOutputPlan:!0}:{},...d.items===void 0?{}:{items:await Ae(d.items)}}),!0)})),e.addCommand(ze(new B("reorder")).description("Replace the complete order: phases in bucket order and every live item once; moves items between phases without touching running preparation").argument("<mission-id>","Mission ID").requiredOption("--expected-order-revision <n>","Current orderRevision from mission status",os).requiredOption("--buckets <json-or-file>","Ordered array of {phaseId|null,itemIds[]} listing every live phase and item; inline JSON or @file:path").action(async(d,g)=>me("reorderMission",g,async()=>({missionId:d,expectedOrderRevision:g.expectedOrderRevision,buckets:await Ae(g.buckets)}),!0))),e.addCommand(Kt(new B("list")).description("List saved missions").option("--limit <n>","Rows to return, maximum 50",Ti,20).option("--offset <n>","Zero-based offset",Ti,0).option("--archived <mode>","exclude (default), only, or all archived missions",b("--archived",["exclude","only","all"]),"exclude").option("--favorite","Only missions you have starred").option("--q <text>","Case-insensitive title or goal match").option("--attention","Include how many items in each mission need you").option("--view <view>","personal (your private missions), team_mine (team missions you created) or team_others (team missions others created)",b("--view",["personal","team_mine","team_others"])).action(async d=>me("listMissions",d,()=>({limit:d.limit,offset:d.offset,archived:d.archived,favorite:d.favorite===!0,attention:d.attention===!0,...d.q===void 0?{}:{q:d.q},...d.view===void 0?{}:{view:d.view}}))));for(let[d,g,y,v]of[["favorite","setMissionFavorite","favorite","Star a mission so it stays at the top of your list; --favorite false removes the star"],["pin","setMissionPin","pinned","Pin a mission for the whole workspace; --pinned false lifts the pin"],["archive","setMissionArchived","archived","Archive a mission so it leaves the active list; --archived false restores it"]])e.addCommand(ze(new B(d)).description(v).argument("<mission-id>","Mission ID").option(`--${y} <${y}>`,"true to apply, false to remove",b(`--${y}`,["true","false"]),"true").action(async(x,T)=>me(g,T,()=>({missionId:x,[y]:T[y]==="true"}),!0)));for(let[d,g,y]of[["status","getMissionStatus","Read counts and currently accessible selected artifacts"],["reconcile","reconcileMission","Discover candidate artifact links without changing the mission"]]){let v=Kt(new B(d)).description(y).requiredOption("--mission-id <id>","Mission ID");g==="getMissionStatus"&&v.option("--history-item <id>","Also return this item's version history").option("--wait-for-import-ms <n>","Hold up to this long (max 15000) while the mission's import runs",Ti),e.addCommand(v.action(async x=>me(g,x,()=>({missionId:x.missionId,...x.historyItem?{historyItemId:x.historyItem}:{},...x.waitForImportMs?{waitForSourceImportMs:x.waitForImportMs}:{}}))))}e.addCommand(ze(new B("adopt")).description("Select an existing artifact chain; does not approve or regenerate content").requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--expected-revision <n>","Revision from the latest status or reconciliation",Ti).requiredOption("--selection <json-or-file>","Selected presentationId, projectId and renderId; nulls detach links").action(async d=>me("adoptMission",d,async()=>({missionId:d.missionId,itemId:d.itemId,expectedRevision:d.expectedRevision,selection:await Ae(d.selection)}),!0)));let r=ze(new B("prepare")).description("Prepare items for narration review; each advances independently and waits at its own review").argument("<mission-id>","Mission ID").option("--items <json-or-file>","Array of {itemId,expectedItemRevision} from mission status; inline JSON or @file:path").option("--phase-id <id>","Prepare every live deliverable item of this phase instead of --items; membership is frozen when admitted").option("--stages <stages>","Comma-separated stages: import,draft,notes,narrate,review,post,reel,agent,voice,render; defaults to import,draft,review").option("--no-wait","Return the run ID; recover with mission prepare status <run-id>").option("--yes","Required when --stages includes notes, narrate, post, reel, agent, voice or render").option("--allow-deck-generation","Authorize billed deck generation for document (non-PowerPoint) sources").option("--review-policy <policy>",`This request's own review policy, overriding the mission's. ${rs}`).option("--credit-ceiling <credits>","The most credits this request may commit; a billed step that would pass it does not start").action(async(d,g)=>{g.items===void 0==(g.phaseId===void 0)&&(a("Pass either --items or --phase-id."),process.exit(s.INVALID_INPUT));let y=g.stages===void 0?void 0:String(g.stages).split(",").map(v=>v.trim()).filter(Boolean);if(y!==void 0){let v=new Set(["import","draft","notes","narrate","review","post","reel","agent","voice","render"]);for(let T of y)if(!v.has(T))throw new Be(`Unknown prepare stage '${T}'.`);let x=["notes","narrate","post","reel","agent","voice","render"].filter(T=>y.includes(T));x.length>0&&!g.yes&&(a(`Pass --yes to authorize billed generation for these items (${x.join(", ")}).`),process.exit(s.INVALID_INPUT))}await Oi("prepareMission",g,async()=>({...g.items===void 0?{phaseId:g.phaseId}:{items:await Ae(String(g.items))},...g.allowDeckGeneration===!0?{allowDeckGeneration:!0}:{},...g.reviewPolicy===void 0?{}:{reviewPolicy:await is(String(g.reviewPolicy))},...g.creditCeiling===void 0?{}:{creditCeiling:hS(String(g.creditCeiling))},...y===void 0?{}:{stages:y},missionId:d}),"Mission preparation failed.")});r.addCommand(ce(ze(new B("stop"))).description("Stop in-flight preparation: cancels running generation, import and narration work; completed work is kept").argument("<mission-id>","Mission ID").option("--item-ids <json-or-file>","Optional array of item IDs to stop; inline JSON or @file:path; defaults to every live item").action(async function(d,g){let y=k(this,g);await me("stopMissionPreparation",y,async()=>({missionId:d,...y.itemIds===void 0?{}:{itemIds:await Ae(y.itemIds)}}),!0)})),r.addCommand(ce(Kt(new B("status"))).description("Read one mission preparation run's progress").argument("<run-id>","Run ID returned by mission prepare").action(async function(d,g){let y=k(this,g);try{m(await R("prepareMission",d,y.teamId))}catch(v){a(u(v,"Prepare status failed.")),process.exit(s.GENERAL_ERROR)}})),e.addCommand(r);let i=new B("review").description("Freeze narration for human review, then record the browser-approved decision");i.addCommand(dt(new B("request")).description("Freeze the selected narration draft for review; does not render").requiredOption("--expected-review-fingerprint <fingerprint>","SHA-256 fingerprint of the narration draft to freeze",fS).action(async d=>me("requestMissionNarrationReview",d,()=>({expectedItemRevision:d.expectedItemRevision,expectedReviewFingerprint:d.expectedReviewFingerprint,itemId:d.itemId,missionId:d.missionId}),!0))),i.addCommand(Di(dt(new B("approve"))).description("Record a browser-approved narration review; does not render").requiredOption("--review-id <id>","Frozen narration review ID").action(async d=>{$i(d,"narration approval"),await me("approveMissionNarration",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,reviewId:d.reviewId,missionId:d.missionId}),!0)})),e.addCommand(i);let o=new B("output").description("Link, render and accept item outputs; linking never accepts");o.addCommand(Di(dt(new B("accept"))).description("Record browser-approved acceptance of one completed render").requiredOption("--render-id <id>","Completed render ID").action(async d=>{$i(d,"output acceptance"),await me("acceptMissionOutput",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,renderId:d.renderId,missionId:d.missionId}),!0)})),o.addCommand(Di(dt(new B("accept-slot"))).description("Record browser-approved acceptance of the artifact filling one output").requiredOption("--slot <key>","Output slot key from mission status").requiredOption("--fulfillment-id <id>","The output's fulfillmentId from mission status").action(async d=>{$i(d,"output acceptance"),await me("acceptMissionOutputSlot",d,()=>({approvalReceipt:_(d),expectedItemRevision:d.expectedItemRevision,fulfillmentId:d.fulfillmentId,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot}),!0)})),o.addCommand(dt(new B("link")).description("Fill one of an item's manual outputs with an existing presentation or finished video; never accepts it").requiredOption("--slot <key>","Output slot key from mission status").requiredOption("--target-id <id>","Presentation ID, or narrated-video project ID").option("--target-version <id>","For a video, the finished render ID to link").action(async d=>me("linkMissionOutput",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot,targetId:d.targetId,...d.targetVersion===void 0?{}:{targetVersion:d.targetVersion}}),!0)));let c=dt(new B("render")).description("Start or resume the approved narration render; waits by default").requiredOption("--review-id <id>","Human-approved narration review ID").option("--no-wait","Return the run ID; recover with mission output render status <run-id>").option("--yes","Confirm starting this approved render").action(async d=>{yS(d),await Oi("renderMissionOutput",d,()=>({expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,reviewId:d.reviewId,missionId:d.missionId}))});c.addCommand(kp(ze(new B("recover"))).description("Finish a recorded render start, or read its recovery state").requiredOption("--mission-id <id>","Mission ID").requiredOption("--item-id <id>","Intended outcome ID").requiredOption("--review-id <id>","Narration review ID the render intent was recorded against").requiredOption("--intent-id <id>","Render intent ID from mission status").action(async function(d){let g=k(this,d);await me("recoverMissionRenderIntent",g,()=>({itemId:g.itemId,intentId:g.intentId,reviewId:g.reviewId,missionId:g.missionId}),!0)})),c.addCommand(ce(Kt(new B("status"))).description("Read one mission render run's progress or result").argument("<run-id>","Run ID returned by mission output render start").action(async function(d,g){let y=k(this,g);try{m(await R("renderMissionOutput",d,y.teamId))}catch(v){a(u(v,"Render status failed.")),process.exit(s.GENERAL_ERROR)}})),o.addCommand(c);let l=dt(new B("regenerate")).description("Regenerate one automated output (deck from its source; narrated video, LinkedIn post or reel from the current deck); the current output stays until the new one is ready").requiredOption("--slot <key>","Output slot key from mission status").option("--allow-deck-generation","Consent to billed deck generation for a document source").option("--allow-narration","Consent to billed new narration").option("--allow-text-generation","Consent to a billed model-written post (LinkedIn post output)").option("--allow-reel-render","Consent to a billed reel render").option("--allow-agent-runs","Consent to a billed agent run (an output a team agent delivers)").option("--no-wait","Return the run ID; recover with mission output regenerate status <run-id>").option("--yes","Confirm regenerating this output").action(async d=>{d.yes||(a("Pass --yes to confirm regenerating this output."),process.exit(s.INVALID_INPUT)),await Oi("regenerateMissionOutput",d,()=>({...d.allowDeckGeneration===!0?{allowDeckGeneration:!0}:{},...d.allowNarration===!0?{allowNarration:!0}:{},...d.allowTextGeneration===!0?{allowTextGeneration:!0}:{},...d.allowReelRender===!0?{allowReelRender:!0}:{},...d.allowAgentRuns===!0?{allowAgentRuns:!0}:{},expectedItemRevision:d.expectedItemRevision,itemId:d.itemId,missionId:d.missionId,slotKey:d.slot}))});return l.addCommand(ce(Kt(new B("status"))).description("Read one output regeneration run's progress or result").argument("<run-id>","Run ID returned by mission output regenerate").action(async function(d,g){let y=k(this,g);try{m(await R("regenerateMissionOutput",d,y.teamId))}catch(v){a(u(v,"Regenerate status failed.")),process.exit(s.GENERAL_ERROR)}})),o.addCommand(l),e.addCommand(o),e.addCommand(Di(ze(new B("delete"))).description("Permanently delete a mission and its bookkeeping; produced artifacts stay in the Library unless --delete-artifacts destroys them too").argument("<mission-id>","Mission ID").option("--delete-artifacts","Also destroy the decks and narrated-video projects this mission produced or adopted").action(async(d,g)=>{$i(g,"mission deletion"),await me("deleteMission",g,()=>({approvalReceipt:_(g),deleteArtifacts:g.deleteArtifacts===!0,missionId:d}),!0)})),e}var Du=bS();import{randomUUID as wS}from"crypto";import{Command as ds}from"commander";import as from"ora";function ss(e,t){if(t==="json"){m(e);return}if(t==="quiet"){e.outputUrl?console.log(e.outputUrl):console.log(e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.outputUrl&&C(`Output URL: ${e.outputUrl}`),e.error&&a(`Error: ${e.error}`)}var vS=new ds("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(g){a(u(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 i=e.format,o=i==="human"?as("Mixing audio...").start():null,c=e.inputsJson?IS("--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 l,d=e.idempotencyKey??wS();try{let g=e.optionsJson?kS("--options-json",e.optionsJson):{},y=await bc({operation:e.operation,inputs:c,options:e.inputsJson?g:{...g,musicVolume:n,voiceVolume:r}},{approvalReceipt:t,idempotencyKey:d});if(l=y.requestId,!e.wait){o?.stop(),ss(y,i);return}o&&(o.text=`Processing (ID: ${y.requestId})...`);let v=await $e(()=>_o(y.requestId),120,3e3);if(o?.stop(),v.status==="failed")throw new de(v.error||"Audio mixing failed");if(ss(v,i),e.output){if(!v.outputUrl)throw new Error("Audio mix completed without an output URL");let x=i==="human"?as("Downloading...").start():null;await Ie(v.outputUrl,e.output),x?.stop(),i==="human"&&C(`Saved to: ${e.output}`)}}catch(g){o?.stop(),a(`${oe(g,l)}${Ee(g,d)}`,i),process.exit(s.GENERAL_ERROR)}});function IS(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 kS(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 xS=new ds("status").description("Check status of an audio mix request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format==="human"?as("Checking status...").start():null;try{let r=await _o(e);n?.stop(),ss(r,t.format)}catch(r){n?.stop(),a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Nu=new ds("mix").description("Audio mixing commands").addCommand(vS).addCommand(xS);import{randomUUID as TS}from"crypto";import{Command as ls}from"commander";import OS from"ora";import{readFileSync as RS}from"fs";var Lu=500,Uu=1e4,Ni=100,_u=1e4,ju=1e3,Mu=["duration_s","idempotency_key","narration","schema_version","video_description"],CS=["end_s","id","start_s","text","words"],SS=["end","id","start","text"],ES=["description","end_s","id","start_s"];function Vu(e){let t=Bu(e);if(Gu(t),yr(t,Mu,""),t.duration_s<3)throw new Error("Music request duration_s must be between 3 and 600");return t}function Fu(e){let t=Bu(e);Gu(t),yr(t,[...Mu,"visual_event"],"");let n=t.visual_event;if(!Li(n))throw new Error("SFX request visual_event is required");if(yr(n,ES,"visual_event"),!vt(n.description))throw new Error("SFX request visual_event.description is required");if(!vt(n.id)||!It(n.start_s))throw new Error("SFX request visual_event requires id and start_s");if(n.end_s!==void 0&&(!It(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 Bu(e){try{let t=JSON.parse(RS(e,"utf8"));if(!Li(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 Gu(e){if(e.schema_version!==1)throw new Error("Audio request schema_version must be 1");if(!vt(e.video_description))throw new Error("Audio request video_description is required");if(!It(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>Lu)throw new Error(`Audio request narration holds at most ${Lu} lines`);if(e.narration.forEach(PS),e.idempotency_key!==void 0&&!vt(e.idempotency_key))throw new Error("Audio request idempotency_key must be a non-empty string")}function PS(e,t){let n=`narration.${t}`;if(!Li(e))throw new Error(`Audio request ${n} must be an object`);if(yr(e,CS,n),!vt(e.id)||e.id.length>Ni)throw new Error(`Audio request ${n}.id is required (1-${Ni} characters)`);if(!vt(e.text)||e.text.trim().length>_u)throw new Error(`Audio request ${n}.text is required (1-${_u} characters)`);if(qu(e.start_s,`${n}.start_s`),qu(e.end_s,`${n}.end_s`),It(e.start_s)&&It(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>Uu)throw new Error(`Audio request ${n}.words must be an array of at most ${Uu} entries`);e.words.forEach((r,i)=>{AS(r,`${n}.words.${i}`)})}}function AS(e,t){if(!Li(e))throw new Error(`Audio request ${t} must be an object`);if(yr(e,SS,t),!vt(e.text)||e.text.trim().length>ju)throw new Error(`Audio request ${t}.text is required (1-${ju} characters)`);if(!It(e.start)||!It(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&&(!vt(e.id)||e.id.length>Ni))throw new Error(`Audio request ${t}.id must be 1-${Ni} characters`)}function qu(e,t){if(e!==void 0&&!It(e))throw new Error(`Audio request ${t} must be a non-negative number`)}function yr(e,t,n){let r=Object.keys(e).filter(o=>!t.includes(o));if(r.length===0)return;let i=n?`${n} `:"";throw new Error(`Audio request ${i}has unknown field(s): ${r.join(", ")}. Allowed: ${t.join(", ")}`)}function Li(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function vt(e){return typeof e=="string"&&e.trim().length>0}function It(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0}function cs(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.audioUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.audioUrl&&C(`Audio URL: ${e.audioUrl}`),e.error&&a(`Error: ${e.error}`)}var $S=new ls("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(l){a(u(l)),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?Vu(e.request):{...e.duration?{duration:Number(e.duration)}:{},...e.durationSeconds?{duration_s:Number(e.durationSeconds)}:{},...e.narrationJson?{narration:Ku("--narration-json",e.narrationJson)}:{},...e.optionsJson?{options:Ku("--options-json",e.optionsJson)}:{},...e.prompt?{prompt:e.prompt}:{},...e.schemaVersion?{schema_version:Number(e.schemaVersion)}:{},...e.videoDescription?{video_description:e.videoDescription}:{}}}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?OS("Generating music for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??TS();try{let l=await yc(n,{approvalReceipt:t,idempotencyKey:c});if(o=l.requestId,!e.wait){i?.stop(),cs(l,r);return}i&&(i.text=`Processing (ID: ${l.requestId})...`);let d=l.status==="completed"||l.status==="failed"?l:await $e(()=>Uo(l.requestId),180,2e3);if(i?.stop(),d.status==="failed")throw new de(d.error||"Music generation failed");if(e.output){if(!d.audioUrl)throw new Error("Music completed without an audio URL");await Ie(d.audioUrl,e.output),r==="human"&&C(`Saved to: ${e.output}`),d.output=e.output}cs(d,r)}catch(l){i?.stop(),a(`${oe(l,o)}${Ee(l,c)}`,r),process.exit(s.GENERAL_ERROR)}});function Ku(e,t){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON`)}}var DS=new ls("status").description("Check status of a music generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{cs(await Uo(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Wu=new ls("music").description("Video-aware music generation commands").addCommand($S).addCommand(DS);import{Command as ms,InvalidArgumentError as NS}from"commander";function Ju(e,t){return[...t,e]}function zu(e){return t=>{if(t==="true")return!0;if(t==="false")return!1;throw new NS(`Expected one of: true, false. Run the command with --help to see what ${e} accepts.`)}}function Hu(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var LS=new ms("create").description("Create a standalone poll").argument("<question>","Poll question").option("--option <text>","Choice (repeat 2-10 times)",Ju,[]).option("--type <type>","single, multiple, or word-cloud",b("--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",b("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",zu("--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(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll creation");try{m(await p("createPoll",{approvalReceipt:_(t),closesAt:t.closesAt,description:t.description,options:t.option.map(n=>({text:n})),pollType:t.type,question:e,respondentPolicy:t.respondentPolicy,showResultsToParticipants:t.showResultsToParticipants,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){Hu(n,"Poll creation failed")}}),US=new ms("edit").description("Edit a standalone poll").argument("<poll-id>","Poll UUID").option("--question <question>","New question").option("--option <text>","Replacement choice (repeat)",Ju).option("--type <type>","single, multiple, or word-cloud",b("--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",b("--respondent-policy",["anonymous","name","email"])).option("--show-results-to-participants <bool>","Whether participants see results",zu("--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(e,t)=>{if(!t.yes)return a("Pass --yes to approve poll update");try{m(await p("editPoll",{approvalReceipt:_(t),chartType:t.chartType,closesAt:t.closesAt,description:t.description,options:t.option?.map(n=>({text:n})),pollId:e,pollType:t.type,question:t.question,respondentPolicy:t.respondentPolicy,showResultsToParticipants:t.showResultsToParticipants,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){Hu(n,"Poll update failed")}}),Xu=new ms("poll").description("Standalone poll commands").addCommand(LS).addCommand(US);import{randomUUID as Vn}from"crypto";import{readFile as If}from"fs/promises";import W from"chalk";import{Command as Y,InvalidArgumentError as no}from"commander";import{createParser as _S}from"eventsource-parser";async function Ge(e,t,n,r={}){let i=null,o=!1;try{let c;for(;;){let l=await qS(await n(c));if(i=l.failure,o=l.completed,i||o||!l.reconnect)break;c=l.lastEventId??c,l.retryMs!==void 0&&l.retryMs>0&&await new Promise(d=>setTimeout(d,l.retryMs))}}catch(c){let l=u(c,"the event stream ended unexpectedly");if(q(`Stopped following run ${e}: ${l}. The run is unaffected \u2014 check it with '${f.commands[0]} ${t} ${e}'.`),r.requireCompletion)throw c;return}if(i)throw new Error(`Run ${e} ${i.status}: ${i.message} Inspect it with '${f.commands[0]} ${t} ${e}'.`);if(r.requireCompletion&&!o)throw new Error(`Completion of run ${e} could not be verified. Check '${f.commands[0]} ${t} ${e}'.`)}function jS(e){let t=e.type==="durable_run_state"&&e.terminal?`durable_run.${e.status}`: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 qS(e){if(!e.ok)throw new Error(`Event stream request failed (${e.status})`);let t=e.body?.getReader();if(!t)throw new Error("Speaker notes event stream is unavailable");let n=new TextDecoder,r=null,i=!1,o=!1,c,l,d=_S({onRetry:v=>{l=v},onEvent:v=>{if(v.id!==void 0&&(c=v.id),v.event==="reconnect"){o=!0;return}let x=JSON.parse(v.data);if(v.event==="stream_error"||x.type==="stream_error")throw new Error(x.message?.trim()||"Durable event stream failed.");if(x.type==="reconnect"){o=!0;return}x.eventType?.startsWith("slide.")&&I(`${x.eventType}${x.payload?.slideId?` \xB7 ${x.payload.slideId}`:""}`);let T=jS(x);T==="completed"?(r=null,i=!0):T&&(r=T,i=!1)}}),g=[],y={failure:null,completed:!1,reconnect:!1};try{for(;;){let{done:v,value:x}=await t.read();if(d.feed(n.decode(x,{stream:!v})),v){y={failure:r,completed:i,reconnect:o||l!==void 0,lastEventId:c,retryMs:l};break}}}catch(v){g.push(v)}finally{try{await t.cancel()}catch(v){g.includes(v)||g.push(v)}finally{try{t.releaseLock()}catch(v){g.includes(v)||g.push(v)}}}if(g.length===1)throw g[0];if(g.length>1)throw new AggregateError(g,"Following the run failed and its stream cleanup also failed.",{cause:g[0]});return y}function Ui(e){return e instanceof P&&e.errorCode==="not_found"}async function _i(e){let t=Gr.filter(c=>c.id!==e.excludeCapabilityId&&c.lifecycle.mode==="background"&&typeof c.lifecycle.status?.cliCommand=="string"&&c.lifecycle.status.cliCommand.startsWith(e.cliCommandPrefix)),r=(await Promise.allSettled(t.map(c=>R(c.id,e.runId,e.teamId)))).findIndex(c=>c.status==="fulfilled");if(r<0)return null;let i=t[r],o=i.lifecycle.status?.cliCommand;return o?{capabilityId:i.id,statusCommand:o}:null}import{randomUUID as MS}from"crypto";import{Command as ji}from"commander";async function ps(e,t,n,r,i){let o=k(e,r);try{m(await p(t,{...n,teamId:o.teamId},i?o.idempotencyKey??MS():void 0))}catch(c){a(u(c,"Deck embed share request failed")),process.exit(s.GENERAL_ERROR)}}var VS=new ji("mint").description("Mint a revocable embed URL for a public deck (Team plan)").argument("<presentation-id>","Presentation ID or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Unique mint key; reuse is rejected").action(async function(e,t){await ps(this,"mintPresentationDeckEmbedShare",{presentationId:e},t,!0)}),FS=new ji("list").description("List embed shares and revocation state without tokens").argument("<presentation-id>","Presentation ID or slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){await ps(this,"listPresentationDeckEmbedShares",{presentationId:e},t,!1)}),BS=new ji("revoke").description("Revoke an embed share; repeated calls preserve the timestamp").argument("<presentation-id>","Presentation ID or slug").argument("<share-id>","Share ID from mint or list").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Request key").action(async function(e,t,n){await ps(this,"revokePresentationDeckEmbedShare",{presentationId:e,shareId:t},n,!0)}),Yu=new ji("embed").description("Mint, list and revoke standalone deck embed shares").addCommand(VS).addCommand(FS).addCommand(BS);import{readFile as GS}from"fs/promises";import{Command as Qu}from"commander";var KS=new Qu("status").description("Read the saved result and credit-settlement status of a presentation edit").argument("<run-id>","Run ID returned by presentation edit").option("--team-id <id>","Workspace ID override").action(async function(e,t){try{let n=k(this,t);m(await R("editPresentation",e,n.teamId))}catch(n){a(u(n,"Could not read the edit run")),process.exit(s.GENERAL_ERROR)}});async function us(e){return e?JSON.parse(await GS(e,"utf8")):void 0}var Zu=new Qu("edit").description("Edit a saved deck using Mindframes models and existing metered credits").argument("<presentation-id>","Presentation UUID from presentation list/read").option("--expected-version-slug <slug>","Exact saved version you read; stale edits are refused").option("--instruction <text>","Requested change to the deck (required for editing)").option("--slides <ids>","Comma-separated stable slide IDs; omit for the full deck").option("--tier <tier>","fast, basic, advanced, auto; defaults to your Mindframes preference",b("--tier",["fast","basic","advanced","auto"])).option("--interaction-context <path>","JSON file containing Studio selection/target context").option("--slide-annotations <path>","JSON file containing slide annotations").option("--attachments <path>","JSON file containing authorized upload references").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this exact edit").option("--approval-receipt-stdin","Read the browser-issued receipt from stdin").option("--yes","Confirm use of existing metered credits; server approval is still required").option("--no-wait","Return the recovery run ID immediately").addCommand(KS).action(async function(e,t){let n=k(this,t),r=n.idempotencyKey;try{if(!n.expectedVersionSlug||!n.instruction?.trim())throw new Error("Editing requires --expected-version-slug and --instruction. Status reads require only a run ID.");if(!n.yes)throw new Error("Pass --yes to confirm metered credits. Mindframes also requires browser approval for this exact edit.");await w();let i=await U(n.teamId),o={presentationId:e,expectedVersionSlug:n.expectedVersionSlug,instruction:n.instruction,...n.slides?{targetSlideIds:n.slides.split(",").map(d=>d.trim()).filter(Boolean)}:{},...n.tier?{tier:n.tier}:{},...n.interactionContext?{interactionContext:await us(n.interactionContext)}:{},...n.slideAnnotations?{slideAnnotations:await us(n.slideAnnotations)}:{},...n.attachments?{attachments:await us(n.attachments)}:{}};r??=Q({command:"presentation:edit",payload:o,workspaceId:i});let c=_(n),l=await p("editPresentation",{...o,teamId:i,...c?{approvalReceipt:c}:{}},r);if(m({...l,idempotencyKey:r}),n.wait!==!1){await Ge(l.runId,"presentation edit status",g=>Qd(l.runId,i,g),{requireCompletion:!0});let d=await R("editPresentation",l.runId,i);if(d.status!=="completed")throw new Error(`Edit ${l.runId} is ${d.status}. Use presentation edit status to inspect its saved result.`);m(d)}}catch(i){r&&q(`Retry this exact input with --idempotency-key ${r}`),a(u(i,"Could not edit the presentation")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as tg}from"crypto";import{Command as qi}from"commander";var WS=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function eg(e,t){WS.test(e)||(a(`"${e}" is not a ${t} id.`),process.exit(s.INVALID_INPUT))}function gs(e,t,n){let r=Number(e);return(!Number.isInteger(r)||r<1||n&&r>n)&&(a(`${t} must be a whole number from 1${n?` to ${n}`:" up"}.`),process.exit(s.INVALID_INPUT)),r}async function fs(e,t,n,r){try{m(await p(e,t,r))}catch(i){a(u(i,n)),process.exit(s.GENERAL_ERROR)}}var JS=new qi("create").description("Build a governed HCP deck from a brand's approved claims, ISI and references").requiredOption("--brand-id <id>","Brand whose claims library is used").requiredOption("--title <title>","Neutral deck title (a title that states a claim is refused)").option("--brief <text>","What the deck is for; steers claim choice only").option("--audience <audience>","Claims library audience (default: hcp)").option("--market <market>","Market, e.g. US").option("--product-id <id>","Brand product to narrow claims to").option("--product-label <label>","Product name for the title slide").option("--content-slides <n>","Claim slides, 1-8 (default: 4)").option("--allow-pre-launch","Also use claims signed off for pre-launch use only").option("--idempotency-key <key>","Reuse a request key to retry this same create").option("--team-id <id>","Workspace ID").action(async e=>{await w(),eg(e.brandId,"brand"),e.productId&&eg(e.productId,"product"),await fs("createGovernedDeck",{brandId:e.brandId,title:e.title,...e.brief?{brief:e.brief}:{},...e.audience?{audience:e.audience}:{},...e.market?{market:e.market}:{},...e.productId?{productId:e.productId}:{},...e.productLabel?{productLabel:e.productLabel}:{},...e.contentSlides?{contentSlides:gs(e.contentSlides,"--content-slides",8)}:{},...e.allowPreLaunch?{allowPreLaunch:!0}:{},...e.teamId?{teamId:e.teamId}:{}},"Create failed",e.idempotencyKey??tg())}),zS=new qi("get").description("Read a governed deck version: claim map, fresh checks, approval and claim options").argument("<id-or-slug>","Presentation ID or slug").option("--version-number <n>","Deck version (default: latest)").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),await fs("getGovernedDeck",{presentationId:e,...t.versionNumber?{versionNumber:gs(t.versionNumber,"--version-number")}:{},...t.teamId?{teamId:t.teamId}:{}},"Read failed")}),HS=new qi("set-claim").description("Switch one claim slot to another approved claim (a new deck version)").argument("<id-or-slug>","Presentation ID or slug").requiredOption("--slide-id <id>","Slide the claim slot is on").requiredOption("--from <claim-key>","Claim now in the slot").requiredOption("--to <claim-key>","Approved claim to put in the slot").requiredOption("--expected-version-number <n>","The deck version you read; a stale value is refused").option("--idempotency-key <key>","Reuse a request key to retry this same change").option("--team-id <id>","Workspace ID").action(async(e,t)=>{await w(),await fs("setGovernedDeckClaim",{expectedVersionNumber:gs(t.expectedVersionNumber,"--expected-version-number"),fromClaimKey:t.from,presentationId:e,slideId:t.slideId,toClaimKey:t.to,...t.teamId?{teamId:t.teamId}:{}},"Claim change failed",t.idempotencyKey??tg())}),hs=new qi("governed").description("Governed HCP decks: claims only from the approved library, locked ISI and References (a person approves versions in the app)").addCommand(JS).addCommand(zS).addCommand(HS);hs.addHelpText("after",`
126
126
  Examples:
127
127
  $ ${f.commands[0]} presentation governed create --brand-id <brand> --title "Product overview for HCPs" --market US
128
128
  $ ${f.commands[0]} presentation governed get <slug>
@@ -133,7 +133,7 @@ Examples:
133
133
  Approval:
134
134
  A deck version is approved by a signed-in person in the app after reviewing
135
135
  the pre-submission checks. There is no CLI or API approval.
136
- `);import{Command as fs}from"commander";function JS(e,t){return[...t,e]}function eg(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var zS=new fs("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",JS,[]).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(e){let t=k(this,e);try{let n=await U(t.teamId),r=await p("requestPresentationReview",{agentId:t.agentId,approvalReceipt:_(t),documentId:t.documentId,instructions:t.instructions,maxCredits:t.maxCredits?Number.parseInt(t.maxCredits,10):void 0,priorReviewRunId:t.priorReviewRunId,slideIds:t.slideId.length?t.slideId:void 0,teamId:n},t.idempotencyKey);if(t.wait===!1)return m(r);m(await z("requestPresentationReview",r.runId,n))}catch(n){eg(n,"Review request failed")}}).addHelpText("after",`
136
+ `);import{Command as ys}from"commander";function XS(e,t){return[...t,e]}function ng(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var YS=new ys("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",XS,[]).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(e){let t=k(this,e);try{let n=await U(t.teamId),r=await p("requestPresentationReview",{agentId:t.agentId,approvalReceipt:_(t),documentId:t.documentId,instructions:t.instructions,maxCredits:t.maxCredits?Number.parseInt(t.maxCredits,10):void 0,priorReviewRunId:t.priorReviewRunId,slideIds:t.slideId.length?t.slideId:void 0,teamId:n},t.idempotencyKey);if(t.wait===!1)return m(r);m(await z("requestPresentationReview",r.runId,n))}catch(n){ng(n,"Review request failed")}}).addHelpText("after",`
137
137
  What happens:
138
138
  Freezes the deck's newest immutable version, runs the named roster specialist in one
139
139
  bounded pass, and posts each finding into the deck's private discussion as an
@@ -152,7 +152,7 @@ Re-review:
152
152
 
153
153
  Recovery:
154
154
  $ ${f.commands[0]} presentation review status <run-id>
155
- `),HS=new fs("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(e,t){let n=k(this,t);try{m(await R("requestPresentationReview",e,n.teamId))}catch(r){eg(r,"Review run status failed")}}),tg=new fs("review").description("Bounded specialist reviews of a frozen presentation revision").addCommand(zS).addCommand(HS);import{readFileSync as XS}from"fs";import{Command as YS}from"commander";var ng=new YS("studio-launch").description("Prepare finite read-only access to a deck, owned run progress, or the workspace catalog").option("--presentation-id <id>","Presentation UUID or saved slug").option("--run-id <id>","Owned presentation creation, edit, or speaker-notes run UUID").option("--approval-request-file <path>","Read an approval selector JSON file; use - for stdin").option("--team-id <id>","Workspace ID override").action(async function(e){let t=k(this,e);try{m(await p("createPresentationStudioLaunch",{presentationId:t.presentationId,...t.approvalRequestFile?{approval:JSON.parse(XS(t.approvalRequestFile==="-"?0:t.approvalRequestFile,"utf8"))}:{},...t.runId?{runId:t.runId}:{},teamId:t.teamId}))}catch(n){a(u(n,"Studio access could not be prepared")),process.exit(s.GENERAL_ERROR)}});import{Command as rg,InvalidArgumentError as QS}from"commander";var ig=new rg("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)",ag(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await sg("Chat thread list failed",()=>p("listPresentationVideoChatThreads",{limit:n.limit,projectId:e,teamId:n.teamId}))}),og=new rg("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)",ag(1,50)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=k(this,n);await sg("Chat thread read failed",()=>p("getPresentationVideoChatThread",{before:r.before,chatId:t,limit:r.limit,projectId:e,teamId:r.teamId}))});function ag(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new QS(`Expected an integer between ${e} and ${t}.`);return r}}async function sg(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{Command as ZS}from"commander";var dg=new ZS("copy-presenter").description("Copy a scene's avatar and box as a clipboard string for paste-presenter").argument("<project-id>","Presentation video project ID").argument("<slide-id>","Slide or intro/outro scene ID").option("--team-id <id>","Workspace ID override").option("--json","Print the complete structured response").action(async function(e,t,n){let r=k(this,n);try{let i=await p("copyPresentationVideoPresenter",{projectId:e,slideId:t,teamId:r.teamId});if(r.json){m(i);return}console.log(i.clip)}catch(i){a(u(i,"Presenter copy failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as hs}from"crypto";import{readFile as eE}from"fs/promises";import{Command as Mi}from"commander";function cg(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1)throw new Error("Draft version numbers must be positive integers.");return t}function ke(e){return e.option("--based-on-version-number <number>","Immutable selected draft baseline",cg).option("--branch-id <id>","Selected draft editor branch UUID").option("--expected-head-version-number <number>","Expected current draft history head",cg)}function xe(e){let{basedOnVersionNumber:t,branchId:n,expectedHeadVersionNumber:r}=e,i=[t,n,r].filter(o=>o!==void 0).length;if(i===0)return{};if(i!==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:t,branchId:n,expectedHeadVersionNumber:r}}var lg=ke(new Mi("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=k(this,t);await Vi("Draft edit failed",async()=>p("editPresentationVideoDraft",{edit:await tE(n.edit),...xe(n),projectId:e,teamId:n.teamId},n.idempotencyKey??hs()))}),mg=new Mi("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",qi(1)).option("--limit <number>","Maximum versions",qi(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Vi("Version list failed",()=>p("listPresentationVideoVersions",{beforeVersion:n.beforeVersion,limit:n.limit,projectId:e,teamId:n.teamId}))}),pg=new Mi("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",qi(1)).option("--expected-current-version <number>","Refuse to restore if a newer draft version exists",qi(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=k(this,n);await Vi("Version restore failed",()=>p("restorePresentationVideoVersion",{expectedCurrentVersion:r.expectedCurrentVersion,expectedProjectUpdatedAt:r.expectedProjectUpdatedAt,projectId:e,teamId:r.teamId,versionNumber:t},r.idempotencyKey??hs()))}),ug=new Mi("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(e,t){let n=k(this,t);await Vi("Slide refresh failed",()=>p("refreshPresentationVideoSlides",{projectId:e,teamId:n.teamId,keepNarration:t.keepNarration,expectedVersionId:n.expectedVersionId,visualSlideIds:n.visualSlideIds},n.idempotencyKey??hs()))});async function tE(e){let t=e.trim(),n=t.startsWith("{")?t:await eE(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 qi(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 Vi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as nE}from"crypto";import{Command as Fi}from"commander";async function ys(e,t,n,r,i){let o=k(e,r);try{m(await p(t,{...n,teamId:o.teamId},i?o.idempotencyKey??nE():void 0))}catch(c){a(u(c,"Video embed share request failed")),process.exit(s.GENERAL_ERROR)}}var rE=new Fi("mint").description("Mint a revocable embed URL for a finished video (Team plan)").argument("<project-id>","Presentation-video project ID or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Unique mint key; reuse is rejected").action(async function(e,t){await ys(this,"mintPresentationVideoEmbedShare",{projectId:e},t,!0)}),iE=new Fi("list").description("List embed shares and revocation state without tokens").argument("<project-id>","Presentation-video project ID or slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){await ys(this,"listPresentationVideoEmbedShares",{projectId:e},t,!1)}),oE=new Fi("revoke").description("Revoke an embed share; repeated calls preserve the timestamp").argument("<project-id>","Presentation-video project ID or slug").argument("<share-id>","Share ID from mint or list").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Request key").action(async function(e,t,n){await ys(this,"revokePresentationVideoEmbedShare",{projectId:e,shareId:t},n,!0)}),gg=new Fi("embed").description("Mint, list and revoke standalone video embed shares").addCommand(rE).addCommand(iE).addCommand(oE);import{createHash as fg}from"crypto";import{Command as Wt,InvalidArgumentError as aE}from"commander";var hg=new Wt("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=k(this,t);await Jt("Draft list failed",()=>p("listPresentationVideoProjects",{presentationId:e,teamId:n.teamId}))}),yg=new Wt("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=k(this,t);await Jt("Freshness read failed",()=>p("getPresentationVideoFreshness",{projectId:e,teamId:n.teamId}))}),bg=new Wt("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",xg(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=k(this,n);await Jt("Version read failed",()=>p("getPresentationVideoVersion",{projectId:e,teamId:r.teamId,versionNumber:t}))}),wg=new Wt("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",xg(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Jt("Render history failed",()=>p("listPresentationVideoRenders",{limit:n.limit,projectId:e,teamId:n.teamId}))}),vg=new Wt("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=k(this,n);await Jt("Render read failed",()=>p("getPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId}))}),Ig=new Wt("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=k(this,n);await Jt("Render cancellation failed",()=>p("cancelPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId},r.idempotencyKey??sE(e,t)))}),kg=new Wt("delete-render").description("Delete one finished, failed, or cancelled render attempt; the MP4 stays unless --delete-video").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","Render attempt UUID to forget").option("--delete-video","Also delete the finished video this attempt produced").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=k(this,n);await Jt("Render deletion failed",()=>p("deletePresentationVideoRender",{deleteVideo:r.deleteVideo===!0,projectId:e,renderId:t,teamId:r.teamId},r.idempotencyKey??dE(e,t,r.deleteVideo===!0)))});function xg(e,t=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new aE(`Expected an integer between ${e} and ${t}.`);return r}}function sE(e,t){return`presentation-video-cancel:${fg("sha256").update(`${e}\0${t}`).digest("hex")}`}function dE(e,t,n){return`presentation-video-delete-render:${fg("sha256").update(`${e}\0${t}\0${n?"1":"0"}`).digest("hex")}`}async function Jt(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as Ag}from"crypto";import{Command as br}from"commander";import{existsSync as cE}from"fs";var Rg=["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full"];function qn(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||!Rg.includes(n))throw new Error(`--placement box needs an anchor: box:${Rg.join(" | box:")}.`);return{kind:"box",placement:{anchor:n}}}throw new Error("--placement must be background, split:left, split:right, full, or box:<anchor>.")}function Bi(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 zt(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 yr(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 he(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 Gi(e,t={}){if(e.startsWith("https://"))return{url:e};if(e.startsWith("http://"))throw new Error("A layer image URL must use https.");if(cE(e))return{uploadKey:(await ie(e,{idempotencyKey:t.idempotencyKey,storagePrefix:"scene-layers"})).s3Key};if(Pg(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 Ki=["brand","alert"],bs="::",Cg=";;";function Is(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=vs(e.tone);if(e.textTitle!==void 0)return{heading:ws(e.textTitle,"--text-title"),tone:n,variant:"title"};if(e.textCallout!==void 0){let[r,i]=Sg(e.textCallout,bs);return{...i?.trim()?{body:i.trim()}:{},heading:ws(r,"--text-callout"),tone:n,variant:"callout"}}if(e.textList!==void 0){let[r,i]=Sg(e.textList,bs),o=(i??"").split(Cg).map(c=>c.trim()).filter(Boolean);if(o.length===0)throw new Error(`--text-list needs a heading and its points: --text-list "Heading${bs}first${Cg}second".`);return{heading:ws(r,"--text-list"),items:o,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 Eg(e){let t=Is({...e,tone:void 0});return t?{align:null,body:t.body??null,color:null,fontFamily:null,fontScale:null,bold:null,italic:null,strikethrough:null,underline:null,background:null,heading:t.heading,items:t.items??null,style:null,text:null,...e.tone!==void 0?{tone:vs(e.tone)}:{},variant:t.variant}:e.tone===void 0?void 0:{tone:vs(e.tone)}}function vs(e){if(e===void 0)return"brand";if(e!=="alert"&&e!=="brand")throw new Error(`--tone must be ${Ki.join(" or ")}.`);return e}function ws(e,t){let n=(e??"").trim();if(!n)throw new Error(`${t} needs the text to show.`);return n}function Sg(e,t){let n=e.indexOf(t);return n<0?[e,void 0]:[e.slice(0,n),e.slice(n+t.length)]}function Pg(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)}var Wi=["top-left","top-right","center","bottom-left","bottom-center","bottom-right"],Ji=["open-url","jump","continue"],Tg=["jump","end"],lE=["a","b","c","d"];function Og(e,t=[]){return[...t,e]}function X(e){a(e),process.exit(s.INVALID_INPUT)}function $g(e){let t=[];return e.button!==void 0&&t.push("button"),e.choice!==void 0&&t.push("choice"),e.question&&t.push("question"),e.sceneEnd!==void 0&&t.push("scene_end"),t}function Dg(e){return(e.length<2||e.length>4)&&X('--choice needs --option "<label>=<scene-id>" repeated two to four times.'),e.map((t,n)=>{let r=t.indexOf("="),i=r<0?"":t.slice(0,r).trim(),o=r<0?"":t.slice(r+1).trim();return(!i||!o)&&X(`--option needs "<label>=<scene-id>"; got "${t}".`),{id:lE[n],label:i,targetSceneId:o}})}function Ng(e){return e.action==="open-url"?(e.url===void 0&&X("--action open-url needs --url <https-url>."),{type:"open_url",url:e.url}):e.action==="jump"?(e.targetScene===void 0&&X("--action jump needs --target-scene <scene-id>."),{type:"jump_to_scene",sceneId:e.targetScene}):{type:"continue"}}function Lg(e){return e.sceneEnd==="end"?{type:"end"}:(e.targetScene===void 0&&X("--scene-end jump needs --target-scene <scene-id>."),{type:"jump_to_scene",sceneId:e.targetScene})}function mE(e,t){e.url!==void 0&&!(t==="button"&&e.action==="open-url")&&X("--url only applies to --button --action open-url."),e.targetScene!==void 0&&!(t==="button"&&e.action==="jump")&&!(t==="scene_end"&&e.sceneEnd==="jump")&&X("--target-scene only applies to --action jump or --scene-end jump."),e.option!==void 0&&t!=="choice"&&X("--option only applies to --choice."),(e.studySet!==void 0||e.item!==void 0)&&t!=="question"&&X("--study-set and --item only apply to --question."),(e.duration!==void 0||e.placement!==void 0||e.pause===!1)&&t!=="button"&&X("--duration, --placement and --no-pause only apply to --button."),e.at!==void 0&&t==="scene_end"&&X("--at does not apply to --scene-end: it always fires at the scene's end."),e.action!==void 0&&t!=="button"&&X("--action only applies to --button; --scene-end takes jump|end as its value.")}function pE(e){let t=$g(e);t.length===0&&X("Pass the interaction kind: --button <label>, --choice <prompt>, --question, or --scene-end <jump|end>."),t.length>1&&X("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive.");let n=t[0];mE(e,n);let r=e.scene;switch(n){case"button":return e.action===void 0&&X("--button needs --action: open-url, jump or continue."),{action:Ng(e),atSec:e.at??0,...e.duration!==void 0?{durationSec:e.duration}:{},kind:"button",label:e.button,placement:e.placement??"bottom-right",pausesVideo:e.pause!==!1,sceneId:r};case"choice":return e.option===void 0&&X('--choice needs --option "<label>=<scene-id>", repeated two to four times.'),{atSec:e.at??0,kind:"choice",options:Dg(e.option),prompt:e.choice,sceneId:r};case"question":return e.studySet===void 0&&X("--question needs --study-set <study-set-id>."),e.item===void 0&&X("--question needs --item <item-id>."),{atSec:e.at??0,itemId:e.item,kind:"question",sceneId:r,studySetId:e.studySet};case"scene_end":return{action:Lg(e),kind:"scene_end",sceneId:r}}}function uE(e){$g(e).length>1&&X("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive."),e.action!==void 0&&e.sceneEnd!==void 0&&X("--action and --scene-end both set the action; pass only one."),e.url!==void 0&&e.action!=="open-url"&&X("--url needs --action open-url."),e.targetScene!==void 0&&e.action!=="jump"&&e.sceneEnd!=="jump"&&X("--target-scene needs --action jump or --scene-end jump.");let t={};return e.scene!==void 0&&(t.sceneId=e.scene),e.at!==void 0&&(t.atSec=e.at),e.duration!==void 0&&(t.durationSec=e.duration===!1?null:e.duration),e.placement!==void 0&&(t.placement=e.placement),e.button!==void 0&&(t.label=e.button),e.choice!==void 0&&(t.prompt=e.choice),e.option!==void 0&&(t.options=Dg(e.option)),e.studySet!==void 0&&(t.studySetId=e.studySet),e.item!==void 0&&(t.itemId=e.item),e.pause!==void 0&&(t.pausesVideo=e.pause),e.action!==void 0&&(t.action=Ng(e)),e.sceneEnd!==void 0&&(t.action=Lg(e)),Object.keys(t).length===0&&X("Provide at least one change: --scene, --at, --duration or --no-duration, --placement, --button, --choice, --option, --question fields (--study-set, --item), --action, --scene-end, --pause or --no-pause."),t}async function zi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function ks(e,t,n){return p("editPresentationVideoDraft",{edit:n,projectId:e,teamId:t.teamId},t.idempotencyKey??Ag())}var gE=new br("add").description("Add an interaction to one scene of a video draft").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--scene <scene-id>","Composition scene id the interaction anchors to").option("--button <label>","A pausing button with this label").option("--choice <prompt>","A multi-option prompt; pair with --option two to four times").option("--question","A quiz question from a workspace study set; pair with --study-set and --item").option("--scene-end <action>","What happens when the scene finishes: jump | end",b("--scene-end",Tg)).option("--action <action>",`Button action: ${Ji.join(" | ")}`,b("--action",Ji)).option("--url <https-url>","https URL for --action open-url").option("--target-scene <scene-id>","Scene a jump action sends the viewer to").option("--option <label=scene-id>",'Choice option as "<label>=<scene-id>" (repeat two to four times)',Og).option("--study-set <id>","Study set UUID for --question").option("--item <item-id>","Study item id for --question").option("--at <seconds>","Second of the scene the interaction opens at (default 0)",he("--at")).option("--duration <seconds>","Seconds a button stays up; omit to keep it to the scene end",he("--duration")).option("--placement <placement>",`Button placement: ${Wi.join(" | ")} (default bottom-right)`,b("--placement",Wi)).option("--no-pause","The button does not pause the video while it waits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t),r=pE(n);await zi("Interaction add failed",()=>ks(e,n,{interaction:r,type:"add_interaction"}))}),fE=new br("update").description("Change fields of one interaction on a draft; pass only what changes").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<interaction-id>","Interaction id from the project read").option("--scene <scene-id>","Re-anchor the interaction to another scene").option("--button <label>","New label for a button interaction").option("--choice <prompt>","New prompt for a choice interaction").option("--question","Declares question fields (with --study-set/--item)").option("--scene-end <action>","New scene-end action: jump | end",b("--scene-end",Tg)).option("--action <action>",`New button action: ${Ji.join(" | ")}`,b("--action",Ji)).option("--url <https-url>","URL for --action open-url").option("--target-scene <scene-id>","Target scene for a jump action").option("--option <label=scene-id>",`Replace a choice's options: "<label>=<scene-id>" (repeat two to four times)`,Og).option("--study-set <id>","New study set UUID for a question").option("--item <item-id>","New study item id for a question").option("--at <seconds>","Move the moment the interaction opens",he("--at")).option("--duration <seconds>","Seconds a button stays up",he("--duration")).option("--no-duration","Clear a button's stay-up seconds so it rides to the scene end").option("--placement <placement>",`Button placement: ${Wi.join(" | ")}`,b("--placement",Wi)).option("--pause","A button pauses the video while it waits").option("--no-pause","A button does not pause the video while it waits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n){let r=k(this,n),i=uE(r);await zi("Interaction update failed",()=>ks(e,r,{interactionId:t,patch:i,type:"update_interaction"}))}),hE=new br("publish").description("Freeze the draft's interactions onto the finished video as an immutable, versioned manifest").argument("<project-id>","Presentation-video project UUID or editor slug").option("--render <id>","Render attempt id to publish against; defaults to the render behind the project's current video").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t);await zi("Interaction publish failed",()=>p("publishPresentationVideoInteractions",{projectId:e,...n.render?{renderId:n.render}:{},teamId:n.teamId},n.idempotencyKey??Ag()))}),yE=new br("remove").description("Remove one interaction from a video draft").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<interaction-id>","Interaction 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){let r=k(this,n);await zi("Interaction remove failed",()=>ks(e,r,{interactionId:t,type:"remove_interaction"}))}),Ug=new br("interaction").description("Add, change or remove the interactions on a video draft").addCommand(gE).addCommand(fE).addCommand(yE).addCommand(hE).addHelpText("after",`
155
+ `),QS=new ys("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(e,t){let n=k(this,t);try{m(await R("requestPresentationReview",e,n.teamId))}catch(r){ng(r,"Review run status failed")}}),rg=new ys("review").description("Bounded specialist reviews of a frozen presentation revision").addCommand(YS).addCommand(QS);import{readFileSync as ZS}from"fs";import{Command as eE}from"commander";var ig=new eE("studio-launch").description("Prepare finite read-only access to a deck, owned run progress, or the workspace catalog").option("--presentation-id <id>","Presentation UUID or saved slug").option("--run-id <id>","Owned presentation creation, edit, or speaker-notes run UUID").option("--approval-request-file <path>","Read an approval selector JSON file; use - for stdin").option("--team-id <id>","Workspace ID override").action(async function(e){let t=k(this,e);try{m(await p("createPresentationStudioLaunch",{presentationId:t.presentationId,...t.approvalRequestFile?{approval:JSON.parse(ZS(t.approvalRequestFile==="-"?0:t.approvalRequestFile,"utf8"))}:{},...t.runId?{runId:t.runId}:{},teamId:t.teamId}))}catch(n){a(u(n,"Studio access could not be prepared")),process.exit(s.GENERAL_ERROR)}});import{Command as og,InvalidArgumentError as tE}from"commander";var ag=new og("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)",dg(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await cg("Chat thread list failed",()=>p("listPresentationVideoChatThreads",{limit:n.limit,projectId:e,teamId:n.teamId}))}),sg=new og("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)",dg(1,50)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=k(this,n);await cg("Chat thread read failed",()=>p("getPresentationVideoChatThread",{before:r.before,chatId:t,limit:r.limit,projectId:e,teamId:r.teamId}))});function dg(e,t){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new tE(`Expected an integer between ${e} and ${t}.`);return r}}async function cg(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{Command as nE}from"commander";var lg=new nE("copy-presenter").description("Copy a scene's avatar and box as a clipboard string for paste-presenter").argument("<project-id>","Presentation video project ID").argument("<slide-id>","Slide or intro/outro scene ID").option("--team-id <id>","Workspace ID override").option("--json","Print the complete structured response").action(async function(e,t,n){let r=k(this,n);try{let i=await p("copyPresentationVideoPresenter",{projectId:e,slideId:t,teamId:r.teamId});if(r.json){m(i);return}console.log(i.clip)}catch(i){a(u(i,"Presenter copy failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as bs}from"crypto";import{readFile as rE}from"fs/promises";import{Command as Vi}from"commander";function mg(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1)throw new Error("Draft version numbers must be positive integers.");return t}function ke(e){return e.option("--based-on-version-number <number>","Immutable selected draft baseline",mg).option("--branch-id <id>","Selected draft editor branch UUID").option("--expected-head-version-number <number>","Expected current draft history head",mg)}function xe(e){let{basedOnVersionNumber:t,branchId:n,expectedHeadVersionNumber:r}=e,i=[t,n,r].filter(o=>o!==void 0).length;if(i===0)return{};if(i!==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:t,branchId:n,expectedHeadVersionNumber:r}}var pg=ke(new Vi("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=k(this,t);await Fi("Draft edit failed",async()=>p("editPresentationVideoDraft",{edit:await iE(n.edit),...xe(n),projectId:e,teamId:n.teamId},n.idempotencyKey??bs()))}),ug=new Vi("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",Mi(1)).option("--limit <number>","Maximum versions",Mi(1,100)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Fi("Version list failed",()=>p("listPresentationVideoVersions",{beforeVersion:n.beforeVersion,limit:n.limit,projectId:e,teamId:n.teamId}))}),gg=new Vi("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",Mi(1)).option("--expected-current-version <number>","Refuse to restore if a newer draft version exists",Mi(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=k(this,n);await Fi("Version restore failed",()=>p("restorePresentationVideoVersion",{expectedCurrentVersion:r.expectedCurrentVersion,expectedProjectUpdatedAt:r.expectedProjectUpdatedAt,projectId:e,teamId:r.teamId,versionNumber:t},r.idempotencyKey??bs()))}),fg=new Vi("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(e,t){let n=k(this,t);await Fi("Slide refresh failed",()=>p("refreshPresentationVideoSlides",{projectId:e,teamId:n.teamId,keepNarration:t.keepNarration,expectedVersionId:n.expectedVersionId,visualSlideIds:n.visualSlideIds},n.idempotencyKey??bs()))});async function iE(e){let t=e.trim(),n=t.startsWith("{")?t:await rE(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 Mi(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 Fi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as oE}from"crypto";import{Command as Bi}from"commander";async function ws(e,t,n,r,i){let o=k(e,r);try{m(await p(t,{...n,teamId:o.teamId},i?o.idempotencyKey??oE():void 0))}catch(c){a(u(c,"Video embed share request failed")),process.exit(s.GENERAL_ERROR)}}var aE=new Bi("mint").description("Mint a revocable embed URL for a finished video (Team plan)").argument("<project-id>","Presentation-video project ID or slug").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Unique mint key; reuse is rejected").action(async function(e,t){await ws(this,"mintPresentationVideoEmbedShare",{projectId:e},t,!0)}),sE=new Bi("list").description("List embed shares and revocation state without tokens").argument("<project-id>","Presentation-video project ID or slug").option("--team-id <id>","Workspace ID override").action(async function(e,t){await ws(this,"listPresentationVideoEmbedShares",{projectId:e},t,!1)}),dE=new Bi("revoke").description("Revoke an embed share; repeated calls preserve the timestamp").argument("<project-id>","Presentation-video project ID or slug").argument("<share-id>","Share ID from mint or list").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Request key").action(async function(e,t,n){await ws(this,"revokePresentationVideoEmbedShare",{projectId:e,shareId:t},n,!0)}),hg=new Bi("embed").description("Mint, list and revoke standalone video embed shares").addCommand(aE).addCommand(sE).addCommand(dE);import{createHash as yg}from"crypto";import{Command as Wt,InvalidArgumentError as cE}from"commander";var bg=new Wt("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=k(this,t);await Jt("Draft list failed",()=>p("listPresentationVideoProjects",{presentationId:e,teamId:n.teamId}))}),wg=new Wt("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=k(this,t);await Jt("Freshness read failed",()=>p("getPresentationVideoFreshness",{projectId:e,teamId:n.teamId}))}),vg=new Wt("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",Cg(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t,n){let r=k(this,n);await Jt("Version read failed",()=>p("getPresentationVideoVersion",{projectId:e,teamId:r.teamId,versionNumber:t}))}),Ig=new Wt("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",Cg(1)).option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Jt("Render history failed",()=>p("listPresentationVideoRenders",{limit:n.limit,projectId:e,teamId:n.teamId}))}),kg=new Wt("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=k(this,n);await Jt("Render read failed",()=>p("getPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId}))}),xg=new Wt("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=k(this,n);await Jt("Render cancellation failed",()=>p("cancelPresentationVideoRender",{projectId:e,renderId:t,teamId:r.teamId},r.idempotencyKey??lE(e,t)))}),Rg=new Wt("delete-render").description("Delete one finished, failed, or cancelled render attempt; the MP4 stays unless --delete-video").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<render-id>","Render attempt UUID to forget").option("--delete-video","Also delete the finished video this attempt produced").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=k(this,n);await Jt("Render deletion failed",()=>p("deletePresentationVideoRender",{deleteVideo:r.deleteVideo===!0,projectId:e,renderId:t,teamId:r.teamId},r.idempotencyKey??mE(e,t,r.deleteVideo===!0)))});function Cg(e,t=Number.MAX_SAFE_INTEGER){return n=>{let r=Number(n);if(!Number.isInteger(r)||r<e||r>t)throw new cE(`Expected an integer between ${e} and ${t}.`);return r}}function lE(e,t){return`presentation-video-cancel:${yg("sha256").update(`${e}\0${t}`).digest("hex")}`}function mE(e,t,n){return`presentation-video-delete-render:${yg("sha256").update(`${e}\0${t}\0${n?"1":"0"}`).digest("hex")}`}async function Jt(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{randomUUID as Og}from"crypto";import{Command as wr}from"commander";import{existsSync as pE}from"fs";var Sg=["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full"];function qn(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||!Sg.includes(n))throw new Error(`--placement box needs an anchor: box:${Sg.join(" | box:")}.`);return{kind:"box",placement:{anchor:n}}}throw new Error("--placement must be background, split:left, split:right, full, or box:<anchor>.")}function Gi(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 zt(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 br(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 he(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 Ki(e,t={}){if(e.startsWith("https://"))return{url:e};if(e.startsWith("http://"))throw new Error("A layer image URL must use https.");if(pE(e))return{uploadKey:(await ie(e,{idempotencyKey:t.idempotencyKey,storagePrefix:"scene-layers"})).s3Key};if(Tg(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 Wi=["brand","alert"],vs="::",Eg=";;";function xs(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=ks(e.tone);if(e.textTitle!==void 0)return{heading:Is(e.textTitle,"--text-title"),tone:n,variant:"title"};if(e.textCallout!==void 0){let[r,i]=Pg(e.textCallout,vs);return{...i?.trim()?{body:i.trim()}:{},heading:Is(r,"--text-callout"),tone:n,variant:"callout"}}if(e.textList!==void 0){let[r,i]=Pg(e.textList,vs),o=(i??"").split(Eg).map(c=>c.trim()).filter(Boolean);if(o.length===0)throw new Error(`--text-list needs a heading and its points: --text-list "Heading${vs}first${Eg}second".`);return{heading:Is(r,"--text-list"),items:o,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 Ag(e){let t=xs({...e,tone:void 0});return t?{align:null,body:t.body??null,color:null,fontFamily:null,fontScale:null,bold:null,italic:null,strikethrough:null,underline:null,background:null,heading:t.heading,items:t.items??null,style:null,text:null,...e.tone!==void 0?{tone:ks(e.tone)}:{},variant:t.variant}:e.tone===void 0?void 0:{tone:ks(e.tone)}}function ks(e){if(e===void 0)return"brand";if(e!=="alert"&&e!=="brand")throw new Error(`--tone must be ${Wi.join(" or ")}.`);return e}function Is(e,t){let n=(e??"").trim();if(!n)throw new Error(`${t} needs the text to show.`);return n}function Pg(e,t){let n=e.indexOf(t);return n<0?[e,void 0]:[e.slice(0,n),e.slice(n+t.length)]}function Tg(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)}var Ji=["top-left","top-right","center","bottom-left","bottom-center","bottom-right"],zi=["open-url","jump","continue"],$g=["jump","end"],uE=["a","b","c","d"];function Dg(e,t=[]){return[...t,e]}function X(e){a(e),process.exit(s.INVALID_INPUT)}function Ng(e){let t=[];return e.button!==void 0&&t.push("button"),e.choice!==void 0&&t.push("choice"),e.question&&t.push("question"),e.sceneEnd!==void 0&&t.push("scene_end"),t}function Lg(e){return(e.length<2||e.length>4)&&X('--choice needs --option "<label>=<scene-id>" repeated two to four times.'),e.map((t,n)=>{let r=t.indexOf("="),i=r<0?"":t.slice(0,r).trim(),o=r<0?"":t.slice(r+1).trim();return(!i||!o)&&X(`--option needs "<label>=<scene-id>"; got "${t}".`),{id:uE[n],label:i,targetSceneId:o}})}function Ug(e){return e.action==="open-url"?(e.url===void 0&&X("--action open-url needs --url <https-url>."),{type:"open_url",url:e.url}):e.action==="jump"?(e.targetScene===void 0&&X("--action jump needs --target-scene <scene-id>."),{type:"jump_to_scene",sceneId:e.targetScene}):{type:"continue"}}function _g(e){return e.sceneEnd==="end"?{type:"end"}:(e.targetScene===void 0&&X("--scene-end jump needs --target-scene <scene-id>."),{type:"jump_to_scene",sceneId:e.targetScene})}function gE(e,t){e.url!==void 0&&!(t==="button"&&e.action==="open-url")&&X("--url only applies to --button --action open-url."),e.targetScene!==void 0&&!(t==="button"&&e.action==="jump")&&!(t==="scene_end"&&e.sceneEnd==="jump")&&X("--target-scene only applies to --action jump or --scene-end jump."),e.option!==void 0&&t!=="choice"&&X("--option only applies to --choice."),(e.studySet!==void 0||e.item!==void 0)&&t!=="question"&&X("--study-set and --item only apply to --question."),(e.duration!==void 0||e.placement!==void 0||e.pause===!1)&&t!=="button"&&X("--duration, --placement and --no-pause only apply to --button."),e.at!==void 0&&t==="scene_end"&&X("--at does not apply to --scene-end: it always fires at the scene's end."),e.action!==void 0&&t!=="button"&&X("--action only applies to --button; --scene-end takes jump|end as its value.")}function fE(e){let t=Ng(e);t.length===0&&X("Pass the interaction kind: --button <label>, --choice <prompt>, --question, or --scene-end <jump|end>."),t.length>1&&X("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive.");let n=t[0];gE(e,n);let r=e.scene;switch(n){case"button":return e.action===void 0&&X("--button needs --action: open-url, jump or continue."),{action:Ug(e),atSec:e.at??0,...e.duration!==void 0?{durationSec:e.duration}:{},kind:"button",label:e.button,placement:e.placement??"bottom-right",pausesVideo:e.pause!==!1,sceneId:r};case"choice":return e.option===void 0&&X('--choice needs --option "<label>=<scene-id>", repeated two to four times.'),{atSec:e.at??0,kind:"choice",options:Lg(e.option),prompt:e.choice,sceneId:r};case"question":return e.studySet===void 0&&X("--question needs --study-set <study-set-id>."),e.item===void 0&&X("--question needs --item <item-id>."),{atSec:e.at??0,itemId:e.item,kind:"question",sceneId:r,studySetId:e.studySet};case"scene_end":return{action:_g(e),kind:"scene_end",sceneId:r}}}function hE(e){Ng(e).length>1&&X("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive."),e.action!==void 0&&e.sceneEnd!==void 0&&X("--action and --scene-end both set the action; pass only one."),e.url!==void 0&&e.action!=="open-url"&&X("--url needs --action open-url."),e.targetScene!==void 0&&e.action!=="jump"&&e.sceneEnd!=="jump"&&X("--target-scene needs --action jump or --scene-end jump.");let t={};return e.scene!==void 0&&(t.sceneId=e.scene),e.at!==void 0&&(t.atSec=e.at),e.duration!==void 0&&(t.durationSec=e.duration===!1?null:e.duration),e.placement!==void 0&&(t.placement=e.placement),e.button!==void 0&&(t.label=e.button),e.choice!==void 0&&(t.prompt=e.choice),e.option!==void 0&&(t.options=Lg(e.option)),e.studySet!==void 0&&(t.studySetId=e.studySet),e.item!==void 0&&(t.itemId=e.item),e.pause!==void 0&&(t.pausesVideo=e.pause),e.action!==void 0&&(t.action=Ug(e)),e.sceneEnd!==void 0&&(t.action=_g(e)),Object.keys(t).length===0&&X("Provide at least one change: --scene, --at, --duration or --no-duration, --placement, --button, --choice, --option, --question fields (--study-set, --item), --action, --scene-end, --pause or --no-pause."),t}async function Hi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function Rs(e,t,n){return p("editPresentationVideoDraft",{edit:n,projectId:e,teamId:t.teamId},t.idempotencyKey??Og())}var yE=new wr("add").description("Add an interaction to one scene of a video draft").argument("<project-id>","Presentation-video project UUID or editor slug").requiredOption("--scene <scene-id>","Composition scene id the interaction anchors to").option("--button <label>","A pausing button with this label").option("--choice <prompt>","A multi-option prompt; pair with --option two to four times").option("--question","A quiz question from a workspace study set; pair with --study-set and --item").option("--scene-end <action>","What happens when the scene finishes: jump | end",b("--scene-end",$g)).option("--action <action>",`Button action: ${zi.join(" | ")}`,b("--action",zi)).option("--url <https-url>","https URL for --action open-url").option("--target-scene <scene-id>","Scene a jump action sends the viewer to").option("--option <label=scene-id>",'Choice option as "<label>=<scene-id>" (repeat two to four times)',Dg).option("--study-set <id>","Study set UUID for --question").option("--item <item-id>","Study item id for --question").option("--at <seconds>","Second of the scene the interaction opens at (default 0)",he("--at")).option("--duration <seconds>","Seconds a button stays up; omit to keep it to the scene end",he("--duration")).option("--placement <placement>",`Button placement: ${Ji.join(" | ")} (default bottom-right)`,b("--placement",Ji)).option("--no-pause","The button does not pause the video while it waits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t),r=fE(n);await Hi("Interaction add failed",()=>Rs(e,n,{interaction:r,type:"add_interaction"}))}),bE=new wr("update").description("Change fields of one interaction on a draft; pass only what changes").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<interaction-id>","Interaction id from the project read").option("--scene <scene-id>","Re-anchor the interaction to another scene").option("--button <label>","New label for a button interaction").option("--choice <prompt>","New prompt for a choice interaction").option("--question","Declares question fields (with --study-set/--item)").option("--scene-end <action>","New scene-end action: jump | end",b("--scene-end",$g)).option("--action <action>",`New button action: ${zi.join(" | ")}`,b("--action",zi)).option("--url <https-url>","URL for --action open-url").option("--target-scene <scene-id>","Target scene for a jump action").option("--option <label=scene-id>",`Replace a choice's options: "<label>=<scene-id>" (repeat two to four times)`,Dg).option("--study-set <id>","New study set UUID for a question").option("--item <item-id>","New study item id for a question").option("--at <seconds>","Move the moment the interaction opens",he("--at")).option("--duration <seconds>","Seconds a button stays up",he("--duration")).option("--no-duration","Clear a button's stay-up seconds so it rides to the scene end").option("--placement <placement>",`Button placement: ${Ji.join(" | ")}`,b("--placement",Ji)).option("--pause","A button pauses the video while it waits").option("--no-pause","A button does not pause the video while it waits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t,n){let r=k(this,n),i=hE(r);await Hi("Interaction update failed",()=>Rs(e,r,{interactionId:t,patch:i,type:"update_interaction"}))}),wE=new wr("publish").description("Freeze the draft's interactions onto the finished video as an immutable, versioned manifest").argument("<project-id>","Presentation-video project UUID or editor slug").option("--render <id>","Render attempt id to publish against; defaults to the render behind the project's current video").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t);await Hi("Interaction publish failed",()=>p("publishPresentationVideoInteractions",{projectId:e,...n.render?{renderId:n.render}:{},teamId:n.teamId},n.idempotencyKey??Og()))}),vE=new wr("remove").description("Remove one interaction from a video draft").argument("<project-id>","Presentation-video project UUID or editor slug").argument("<interaction-id>","Interaction 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){let r=k(this,n);await Hi("Interaction remove failed",()=>Rs(e,r,{interactionId:t,type:"remove_interaction"}))}),jg=new wr("interaction").description("Add, change or remove the interactions on a video draft").addCommand(yE).addCommand(bE).addCommand(vE).addCommand(wE).addHelpText("after",`
156
156
  Examples:
157
157
  ${f.commands[0]} presentation video interaction add <project-id> --scene slide-2 --button "Learn more" --action open-url --url https://example.com/details
158
158
  ${f.commands[0]} presentation video interaction add <project-id> --scene slide-2 --button "Try it yourself" --action jump --target-scene slide-5 --placement bottom-left --no-pause
@@ -163,7 +163,7 @@ Examples:
163
163
  ${f.commands[0]} presentation video interaction update <project-id> <interaction-id> --button "Read the guide" --action jump --target-scene slide-7
164
164
  ${f.commands[0]} presentation video interaction remove <project-id> <interaction-id>
165
165
  ${f.commands[0]} presentation video interaction publish <project-id> [--render <render-id>]
166
- `);import{randomUUID as bE}from"crypto";import{Command as wr}from"commander";function xs(e){try{return Bi(e)}catch(t){a(u(t,"Invalid layer timing.")),process.exit(s.INVALID_INPUT)}}function _g(e){try{return e()}catch(t){a(u(t,"Invalid layer text.")),process.exit(s.INVALID_INPUT)}}async function Hi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function Xi(e,t,n){return p("editPresentationVideoDraft",{edit:n,projectId:e,teamId:t.teamId},t.idempotencyKey??bE())}var wE=new wr("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: ${Ki.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",he("--start")).option("--duration <seconds>","Seconds shown; omit for the whole scene",he("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces --start/--duration",zt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive); omit for the whole scene",zt("--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=k(this,t),r=_g(()=>Is(n));[n.video,n.media,n.image,n.slide,n.stockVideoToken,r].filter(c=>c!==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 o=xs(n);await Hi("Layer add failed",async()=>{let c=r?{text:r}:n.stockVideoToken?{stockVideoToken:n.stockVideoToken}:n.video?{videoId:n.video}:n.media?{mediaAssetId:n.media}:n.slide?{slideId:n.slide}:await Gi(n.image,{idempotencyKey:n.idempotencyKey});return Xi(e,n,{...n.label?{label:n.label}:{},placement:qn(n.placement??"background"),sceneIds:yr(n.scenes),source:c,...o?{timing:o}:{},type:"add_scene_layer"})})}),vE=new wr("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",he("--start")).option("--duration <seconds>","Seconds shown",he("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces the seconds flags",zt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive)",zt("--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: ${Ki.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 i=k(this,r),o=xs(i),c=_g(()=>Eg(i));i.placement===void 0&&o===void 0&&c===void 0&&i.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 Hi("Layer update failed",()=>Xi(e,i,{...i.label!==void 0?{label:i.label}:{},layerId:n,...i.placement!==void 0?{placement:qn(i.placement)}:{},sceneId:t,...c?{text:c}:{},...o?{timing:o}:{},type:"update_scene_layer"}))}),IE=new wr("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 i=k(this,r);await Hi("Layer remove failed",()=>Xi(e,i,{layerId:n,sceneId:t,type:"remove_scene_layer"}))}),kE=new wr("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",he("--start")).option("--duration <seconds>","Retime the copies: seconds shown",he("--duration")).option("--start-word <index>","Retime the copies on each TARGET scene's narration words (0-based)",zt("--start-word")).option("--end-word <index>","Last narration word shown on each target (inclusive)",zt("--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 i=k(this,r),o=xs(i);await Hi("Layer copy failed",()=>Xi(e,i,{layerId:n,...i.placement!==void 0?{placement:qn(i.placement)}:{},sceneId:t,...o?{timing:o}:{},toSceneIds:yr(i.to),type:"copy_scene_layer"}))}),jg=new wr("layer").description("Add, move, remove or copy the timed layers on a scene").addCommand(wE).addCommand(vE).addCommand(IE).addCommand(kE).addHelpText("after",`
166
+ `);import{randomUUID as IE}from"crypto";import{Command as vr}from"commander";function Cs(e){try{return Gi(e)}catch(t){a(u(t,"Invalid layer timing.")),process.exit(s.INVALID_INPUT)}}function qg(e){try{return e()}catch(t){a(u(t,"Invalid layer text.")),process.exit(s.INVALID_INPUT)}}async function Xi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function Yi(e,t,n){return p("editPresentationVideoDraft",{edit:n,projectId:e,teamId:t.teamId},t.idempotencyKey??IE())}var kE=new vr("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: ${Wi.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",he("--start")).option("--duration <seconds>","Seconds shown; omit for the whole scene",he("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces --start/--duration",zt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive); omit for the whole scene",zt("--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=k(this,t),r=qg(()=>xs(n));[n.video,n.media,n.image,n.slide,n.stockVideoToken,r].filter(c=>c!==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 o=Cs(n);await Xi("Layer add failed",async()=>{let c=r?{text:r}:n.stockVideoToken?{stockVideoToken:n.stockVideoToken}:n.video?{videoId:n.video}:n.media?{mediaAssetId:n.media}:n.slide?{slideId:n.slide}:await Ki(n.image,{idempotencyKey:n.idempotencyKey});return Yi(e,n,{...n.label?{label:n.label}:{},placement:qn(n.placement??"background"),sceneIds:br(n.scenes),source:c,...o?{timing:o}:{},type:"add_scene_layer"})})}),xE=new vr("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",he("--start")).option("--duration <seconds>","Seconds shown",he("--duration")).option("--start-word <index>","Start on this narration word (0-based); replaces the seconds flags",zt("--start-word")).option("--end-word <index>","Last narration word shown (inclusive)",zt("--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: ${Wi.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 i=k(this,r),o=Cs(i),c=qg(()=>Ag(i));i.placement===void 0&&o===void 0&&c===void 0&&i.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 Xi("Layer update failed",()=>Yi(e,i,{...i.label!==void 0?{label:i.label}:{},layerId:n,...i.placement!==void 0?{placement:qn(i.placement)}:{},sceneId:t,...c?{text:c}:{},...o?{timing:o}:{},type:"update_scene_layer"}))}),RE=new vr("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 i=k(this,r);await Xi("Layer remove failed",()=>Yi(e,i,{layerId:n,sceneId:t,type:"remove_scene_layer"}))}),CE=new vr("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",he("--start")).option("--duration <seconds>","Retime the copies: seconds shown",he("--duration")).option("--start-word <index>","Retime the copies on each TARGET scene's narration words (0-based)",zt("--start-word")).option("--end-word <index>","Last narration word shown on each target (inclusive)",zt("--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 i=k(this,r),o=Cs(i);await Xi("Layer copy failed",()=>Yi(e,i,{layerId:n,...i.placement!==void 0?{placement:qn(i.placement)}:{},sceneId:t,...o?{timing:o}:{},toSceneIds:br(i.to),type:"copy_scene_layer"}))}),Mg=new vr("layer").description("Add, move, remove or copy the timed layers on a scene").addCommand(kE).addCommand(xE).addCommand(RE).addCommand(CE).addHelpText("after",`
167
167
  Examples:
168
168
  ${f.commands[0]} presentation video layer add <project-id> --scenes slide-1,slide-3 --image ./floor.jpg --placement background --label "Right way"
169
169
  ${f.commands[0]} presentation video layer add <project-id> --scenes slide-2 --video <video-id> --placement split:left --start 2 --duration 5
@@ -177,7 +177,24 @@ Examples:
177
177
  ${f.commands[0]} presentation video layer update <project-id> slide-1 layer-abc --clear-anchor --start 2 --duration 5
178
178
  ${f.commands[0]} presentation video layer copy <project-id> slide-1 layer-abc --to slide-4,slide-5 --placement full
179
179
  ${f.commands[0]} presentation video layer remove <project-id> slide-1 layer-abc
180
- `);import{randomUUID as xE}from"crypto";import{readFileSync as RE}from"fs";import{Command as CE}from"commander";var SE=16384;async function EE(){let e="";for await(let t of process.stdin)if(e+=String(t),e.length>SE)throw new Error("Clipboard input exceeds the avatar copy size limit.");return e}async function PE(e){if(+!!e.clip+ +!!e.clipFile+ +(e.clipStdin===!0)!==1)throw new Error("Pass exactly one of --clip, --clip-file, or --clip-stdin.");return e.clipFile?RE(e.clipFile,"utf8").trim():e.clipStdin?EE():e.clip}var Rs=new CE("paste-presenter").description("Paste a copied avatar \u2014 person and box \u2014 onto scenes of a presentation video").argument("<project-id>","Presentation video project ID").argument("<slide-id>","Slide or intro/outro scene ID").option("--clip <text>","Clipboard string from copy-presenter").option("--clip-file <path>","Read the clipboard string from a file").option("--clip-stdin","Read the clipboard string from stdin").option("--slide-ids <ids...>","Exact scene IDs to apply atomically; include the slide-id argument").option("--layout-only","Move each scene's own presenter into the copied box instead of pasting the avatar").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this update").action(async function(e,t,n){let r=k(this,n);try{let i=await PE(r),o=await p("pastePresentationVideoPresenter",{...xe(r),clip:i,mode:r.layoutOnly?"layout_only":"presenter_and_layout",projectId:e,slideId:t,slideIds:r.slideIds,teamId:r.teamId},r.idempotencyKey||xE());m(o)}catch(i){a(u(i,"Presenter paste failed")),process.exit(s.GENERAL_ERROR)}});ke(Rs);import{randomUUID as AE}from"crypto";import{Command as TE}from"commander";var OE=["basic","standard","premium"],Cs=new TE("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(e,t,n){let r=k(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&&!OE.includes(r.renderTier))throw new Error("--render-tier must be basic, standard, or premium.");m(await p("setPresentationVideoScenePresenter",{...xe(r),applyPresetVoice:r.castPresetId?r.applyPresetVoice:void 0,avatarId:r.avatarId,castPresetId:r.castPresetId,inherit:r.inherit,projectId:e,renderTier:r.renderTier,slideId:t,slideIds:r.slideIds,teamId:r.teamId},$E(r.idempotencyKey)))}catch(i){a(u(i,"Scene presenter update failed")),process.exit(s.GENERAL_ERROR)}});function $E(e){return e||AE()}ke(Cs);import{createHash as DE}from"crypto";import{Command as vr}from"commander";var NE=new vr("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(e,t){let n=k(this,t);await Yi("Preview preparation failed",async()=>{let r=await U(n.teamId),i=await p("preparePresentationVideoPreviews",{projectId:e,teamId:r},n.idempotencyKey??Mg("prepare",e,r));return n.wait===!1?i:$c(i.runId,r)})}).addHelpText("after",`
180
+ `);import{Command as SE}from"commander";function Mn(e){return`${(e*100).toFixed(1)}%`}function Qi(e){return`x ${Mn(e.left)}\u2013${Mn(e.left+e.width)}, y ${Mn(e.top)}\u2013${Mn(e.top+e.height)}`}function EE(e){for(let t of e.scenes){let n=[];n.push(`scene ${t.sceneId} \u2014 ${t.status}`),t.statusDetail&&n.push(` ${t.statusDetail}`),t.remedy&&n.push(` remedy: ${t.remedy}`),t.slideBox&&n.push(` slide: ${Qi(t.slideBox)}`);for(let r of t.overlays)n.push(` overlay ${r.kind.padEnd(18)} ${Qi(r.box)}`);if(t.blocks.length>0){n.push(` blocks (${t.blocks.length}):`);for(let r of t.blocks)n.push(` ${r.role.padEnd(7)} ${r.tag.padEnd(10)} ${Qi(r.box)}`)}if(t.conflicts.length>0){n.push(" conflicts:");for(let r of t.conflicts)n.push(` ${r.severity.toUpperCase().padEnd(6)} ${r.overlayLabel} ${r.kind} ${r.blockRole} block \u2014 covers ${Mn(r.blockOverlap)} of block, ${Mn(r.overlayOverlap)} of overlay`)}else t.status==="ready"&&n.push(" conflicts: none");for(let r of t.freeRegions)n.push(` free ${r.use.padEnd(10)} ${Qi(r.box)}`);console.log(n.join(`
181
+ `))}}function PE(e,t){return t.concat([e])}var Vg=new SE("layout").description("Read the measured layout report: content blocks, caption/presenter/layer overlays, conflicts, and free regions per scene").argument("<project-id>","Presentation-video project UUID or editor slug").option("--scene <id>","Restrict to one scene id; repeat for several",PE,[]).option("--format <format>","json (default) or human").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);try{let r=n.format??"json";if(r!=="json"&&r!=="human")throw new Error("--format must be json or human.");let i=await p("getPresentationVideoLayout",{projectId:e,sceneIds:n.scene?.length?n.scene:void 0,teamId:n.teamId});if(r==="human"){EE(i);return}m(i)}catch(r){a(u(r,"Layout report failed")),process.exit(s.GENERAL_ERROR)}}).addHelpText("after",`
182
+ What it answers:
183
+ Where each scene's captions, presenter, and layers land against the slide's
184
+ own content blocks \u2014 BEFORE paying for a render. Run it after setup and fix
185
+ any conflicts (move captions or the presenter, or resize the slide's own
186
+ blocks with deck block offsets) before asking for a scene render or the MP4.
187
+
188
+ Status:
189
+ ready \u2014 blocks, overlays, conflicts and free regions are reported.
190
+ preview_missing / geometry_missing / geometry_stale \u2014 run
191
+ $ ${f.commands[0]} presentation video previews prepare <project-id>
192
+ first; geometry is measured when previews are prepared.
193
+ standalone \u2014 card or clip scene; overlays apply, no deck blocks.
194
+ excluded \u2014 scene is excluded from the render.
195
+
196
+ This command is free and never renders video.
197
+ `);import{randomUUID as AE}from"crypto";import{readFileSync as TE}from"fs";import{Command as OE}from"commander";var $E=16384;async function DE(){let e="";for await(let t of process.stdin)if(e+=String(t),e.length>$E)throw new Error("Clipboard input exceeds the avatar copy size limit.");return e}async function NE(e){if(+!!e.clip+ +!!e.clipFile+ +(e.clipStdin===!0)!==1)throw new Error("Pass exactly one of --clip, --clip-file, or --clip-stdin.");return e.clipFile?TE(e.clipFile,"utf8").trim():e.clipStdin?DE():e.clip}var Ss=new OE("paste-presenter").description("Paste a copied avatar \u2014 person and box \u2014 onto scenes of a presentation video").argument("<project-id>","Presentation video project ID").argument("<slide-id>","Slide or intro/outro scene ID").option("--clip <text>","Clipboard string from copy-presenter").option("--clip-file <path>","Read the clipboard string from a file").option("--clip-stdin","Read the clipboard string from stdin").option("--slide-ids <ids...>","Exact scene IDs to apply atomically; include the slide-id argument").option("--layout-only","Move each scene's own presenter into the copied box instead of pasting the avatar").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this update").action(async function(e,t,n){let r=k(this,n);try{let i=await NE(r),o=await p("pastePresentationVideoPresenter",{...xe(r),clip:i,mode:r.layoutOnly?"layout_only":"presenter_and_layout",projectId:e,slideId:t,slideIds:r.slideIds,teamId:r.teamId},r.idempotencyKey||AE());m(o)}catch(i){a(u(i,"Presenter paste failed")),process.exit(s.GENERAL_ERROR)}});ke(Ss);import{randomUUID as LE}from"crypto";import{Command as UE}from"commander";var _E=["basic","standard","premium"],Es=new UE("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(e,t,n){let r=k(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&&!_E.includes(r.renderTier))throw new Error("--render-tier must be basic, standard, or premium.");m(await p("setPresentationVideoScenePresenter",{...xe(r),applyPresetVoice:r.castPresetId?r.applyPresetVoice:void 0,avatarId:r.avatarId,castPresetId:r.castPresetId,inherit:r.inherit,projectId:e,renderTier:r.renderTier,slideId:t,slideIds:r.slideIds,teamId:r.teamId},jE(r.idempotencyKey)))}catch(i){a(u(i,"Scene presenter update failed")),process.exit(s.GENERAL_ERROR)}});function jE(e){return e||LE()}ke(Es);import{createHash as qE}from"crypto";import{Command as Ir}from"commander";var ME=new Ir("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(e,t){let n=k(this,t);await Zi("Preview preparation failed",async()=>{let r=await U(n.teamId),i=await p("preparePresentationVideoPreviews",{projectId:e,teamId:r},n.idempotencyKey??Bg("prepare",e,r));return n.wait===!1?i:Nc(i.runId,r)})}).addHelpText("after",`
181
198
  What happens:
182
199
  Reuses the draft's checkpointed preview run and prepares only missing deck-slide images.
183
200
  Card and reusable-video scenes report not_required. This command is free and does not render MP4.
@@ -186,19 +203,19 @@ Recovery:
186
203
  $ ${f.commands[0]} presentation video previews status <run-id>
187
204
  $ ${f.commands[0]} presentation video previews inspect <project-id>
188
205
  $ ${f.commands[0]} presentation video previews retry <project-id> # only after failed/cancelled
189
- `),LE=new vr("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(e,t){let n=k(this,t);await Yi("Preview status read failed",()=>p("getPresentationVideoPreviews",{projectId:e,teamId:n.teamId}))}).addHelpText("after",`
206
+ `),VE=new Ir("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(e,t){let n=k(this,t);await Zi("Preview status read failed",()=>p("getPresentationVideoPreviews",{projectId:e,teamId:n.teamId}))}).addHelpText("after",`
190
207
  Output:
191
208
  summary.status is idle, preparing, ready, failed, or not_required.
192
209
  scenes[] reports ready, missing, or not_required plus stored horizontalUrl/verticalUrl.
193
210
  run contains the durable run ID, phase, progress, status, and typed public error.
194
- `),UE=new vr("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(e,t){let n=k(this,t);await Yi("Preview retry failed",async()=>{let r=await U(n.teamId);return p("retryPresentationVideoPreviews",{projectId:e,teamId:r},n.idempotencyKey??Mg("retry",e,r))})}).addHelpText("after",`
211
+ `),FE=new Ir("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(e,t){let n=k(this,t);await Zi("Preview retry failed",async()=>{let r=await U(n.teamId);return p("retryPresentationVideoPreviews",{projectId:e,teamId:r},n.idempotencyKey??Bg("retry",e,r))})}).addHelpText("after",`
195
212
  Rules:
196
213
  Only failed or cancelled preview runs can be retried. Active and completed runs are refused.
197
214
  Retry resumes unfinished scenes; it does not rebuild images already stored on the draft.
198
215
 
199
216
  Next:
200
217
  $ ${f.commands[0]} presentation video previews inspect <project-id>
201
- `),_E=new vr("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(e,t){let n=k(this,t);await Yi("Preview run status failed",()=>R("preparePresentationVideoPreviews",e,n.teamId))}),qg=new vr("previews").description("Prepare, inspect, or retry the slide images used by presentation-to-MP4").addCommand(NE).addCommand(LE).addCommand(UE).addCommand(_E);function Mg(e,t,n){return`presentation-video-previews:${e}:${DE("sha256").update(`${n}\0${t}`).digest("hex")}`}async function Yi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{Command as Ss}from"commander";var Vg=new Ss("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(e,t){let n=k(this,t);try{m(await p("getPresentationVideoProject",{projectId:e,teamId:n.teamId}))}catch(r){a(u(r,"Project read failed")),process.exit(s.GENERAL_ERROR)}}),jE=new Ss("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",qE).option("--query <text>","Filter clips by title").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);try{m(await p("listReusableVideoClips",{cursor:n.cursor,limit:n.limit,projectId:e,query:n.query,teamId:n.teamId}))}catch(r){a(u(r,"Clip list failed")),process.exit(s.GENERAL_ERROR)}}),Fg=new Ss("library").description("Reusable generated clips and uploaded recordings").addCommand(jE);function qE(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>100)throw new Error("--limit must be an integer between 1 and 100.");return t}import{randomUUID as BE}from"crypto";import{Command as Es}from"commander";import{readFile as ME}from"fs/promises";import{InvalidArgumentError as Bg}from"commander";async function VE(e){let t=e.trim(),n=t.startsWith("{")?t:await ME(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}async function Gg(e){let t=e.settings?await VE(e.settings):{},n=[e.captionHeight,e.captionWidth,e.captionX,e.captionY].some(o=>o!==void 0),r=[e.captionBackgroundColor,e.captionFontFamily,e.captionFontSize,e.captionHighlightColor,e.captionTextColor].some(o=>o!==void 0),i=[e.presenterAnchor,e.presenterApplyToAll,e.presenterBackground,e.presenterBackgroundFit,e.presenterBackgroundHex,e.presenterBackgroundUrl,e.presenterBorderRadius,e.presenterFramingX,e.presenterFramingY,e.presenterFramingZoom,e.presenterHeight,e.presenterOffsetX,e.presenterOffsetY,e.presenterSize,e.presenterUseDefault,e.presenterVisible,e.presenterX,e.presenterY].some(o=>o!==void 0);if(n&&t.captionPlacement!==void 0)throw new Error("Pass caption placement either as typed flags or inside --settings, not both.");if(r&&t.captionStyle!==void 0)throw new Error("Pass caption style either as typed flags or inside --settings, not both.");if(i&&t.presenter!==void 0)throw new Error("Pass presenter layout either as typed flags or as settings.presenter, not both.");return FE({captionBackgroundColor:e.captionBackgroundColor,captionFontFamily:e.captionFontFamily,captionFontSize:e.captionFontSize,captionHeight:e.captionHeight,captionHighlightColor:e.captionHighlightColor,captionTextColor:e.captionTextColor,captionWidth:e.captionWidth,captionX:e.captionX,captionY:e.captionY,presenterAnchor:e.presenterAnchor,presenterApplyToAll:e.presenterApplyToAll||void 0,presenterBackgroundFit:e.presenterBackgroundFit,presenterBackgroundHex:e.presenterBackgroundHex,presenterBackgroundKind:e.presenterBackground,presenterBackgroundUrl:e.presenterBackgroundUrl,presenterBorderRadius:e.presenterBorderRadius,presenterFramingX:e.presenterFramingX,presenterFramingY:e.presenterFramingY,presenterFramingZoom:e.presenterFramingZoom,presenterHeight:e.presenterHeight,presenterOffsetX:e.presenterOffsetX,presenterOffsetY:e.presenterOffsetY,presenterSize:e.presenterSize,presenterSlideId:e.presenterSlideId,presenterUseDefault:e.presenterUseDefault||void 0,presenterVisible:e.presenterVisible,presenterX:e.presenterX,presenterY:e.presenterY,settings:e.settings?t:void 0})}function ee(e,t,n,r=!1){return i=>{let o=Number(i);if(!Number.isFinite(o)||o<t||o>n||r&&!Number.isInteger(o))throw new Bg(`${e} must be ${r?"an integer":"a number"} from ${t} to ${n}.`);return o}}function Kg(e){return t=>{if(t==="true")return!0;if(t==="false")return!1;throw new Bg(`${e} must be true or false.`)}}function FE(e){return Object.fromEntries(Object.entries(e).filter(t=>t[1]!==void 0))}var GE=["right-way","wrong-way"],KE=new Es("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(e,t){let n=k(this,t);try{m(await R("generatePresentationVideoSceneClip",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Wg=new Es("generate").description("Create a right-way or wrong-way clip from a picture or prompt and attach it to video scenes").argument("<project-id>","Presentation video project ID or slug").option("--image <file-or-url-or-id>","Local image file to upload, an https image URL, or a media-library asset UUID. Omit for a text-only clip (needs --prompt)").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 (or, for a text-only clip, is described in the prompt). 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",he("--start")).option("--layer-duration <seconds>","Seconds the layer is on screen; omit for the whole scene",he("--layer-duration")).option("--label <text>",'Studio label, e.g. "Right way"').option("--duration-seconds <n>","Requested clip length, 5 to 15 seconds (default 6). Standard workspaces render the nearest of 5, 10 or 15; the result's durationSeconds is the rendered length",ee("--duration-seconds",5,15,!0)).option("--prompt <text>","Replace the derived scene description. Required without --image").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(e,t){let n=k(this,t);if(!n.yes)return a("Pass --yes to confirm generating a paid scene clip.");let r=n.preset??"right-way";GE.includes(r)||(a("--preset must be right-way or wrong-way."),process.exit(s.INVALID_INPUT));let i=n.realPerson===!1;r==="wrong-way"&&!i&&(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"&&i&&(a("--no-real-person only applies to --preset wrong-way."),process.exit(s.INVALID_INPUT)),!n.image&&!n.prompt?.trim()&&(a("Pass --image to stage the clip from a picture, or --prompt to generate it from text alone."),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 o=xe(n),c=n.image?await Gi(n.image,{idempotencyKey:n.idempotencyKey}):void 0,l=Bi({duration:n.layerDuration,start:n.start});m(await p("generatePresentationVideoSceneClip",{...o,destination:{...n.label?{label:n.label}:{},placement:qn(n.placement??"background"),sceneIds:yr(n.scenes),...l?{timing:l}:{}},durationSeconds:n.durationSeconds,...c?{image:c}:{},preset:r,projectId:e,prompt:n.prompt,teamId:n.teamId,...i?{wrongWay:{noRealPersonInImage:!0}}:{}},n.idempotencyKey??BE()))}catch(o){a(u(o,"Scene clip failed")),process.exit(s.GENERAL_ERROR)}});ke(Wg);var Jg=new Es("scene-clip").description("Generate scene-clip footage and attach it as a scene layer").addCommand(Wg).addCommand(KE).addHelpText("after",`
218
+ `),BE=new Ir("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(e,t){let n=k(this,t);await Zi("Preview run status failed",()=>R("preparePresentationVideoPreviews",e,n.teamId))}),Fg=new Ir("previews").description("Prepare, inspect, or retry the slide images used by presentation-to-MP4").addCommand(ME).addCommand(VE).addCommand(FE).addCommand(BE);function Bg(e,t,n){return`presentation-video-previews:${e}:${qE("sha256").update(`${n}\0${t}`).digest("hex")}`}async function Zi(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{Command as Ps}from"commander";var Gg=new Ps("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(e,t){let n=k(this,t);try{m(await p("getPresentationVideoProject",{projectId:e,teamId:n.teamId}))}catch(r){a(u(r,"Project read failed")),process.exit(s.GENERAL_ERROR)}}),GE=new Ps("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",KE).option("--query <text>","Filter clips by title").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);try{m(await p("listReusableVideoClips",{cursor:n.cursor,limit:n.limit,projectId:e,query:n.query,teamId:n.teamId}))}catch(r){a(u(r,"Clip list failed")),process.exit(s.GENERAL_ERROR)}}),Kg=new Ps("library").description("Reusable generated clips and uploaded recordings").addCommand(GE);function KE(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>100)throw new Error("--limit must be an integer between 1 and 100.");return t}import{randomUUID as HE}from"crypto";import{Command as As}from"commander";import{readFile as WE}from"fs/promises";import{InvalidArgumentError as Wg}from"commander";async function JE(e){let t=e.trim(),n=t.startsWith("{")?t:await WE(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}async function Jg(e){let t=e.settings?await JE(e.settings):{},n=[e.captionHeight,e.captionWidth,e.captionX,e.captionY].some(o=>o!==void 0),r=[e.captionBackgroundColor,e.captionFontFamily,e.captionFontSize,e.captionHighlightColor,e.captionTextColor].some(o=>o!==void 0),i=[e.presenterAnchor,e.presenterApplyToAll,e.presenterBackground,e.presenterBackgroundFit,e.presenterBackgroundHex,e.presenterBackgroundUrl,e.presenterBorderRadius,e.presenterFramingX,e.presenterFramingY,e.presenterFramingZoom,e.presenterHeight,e.presenterOffsetX,e.presenterOffsetY,e.presenterSize,e.presenterUseDefault,e.presenterVisible,e.presenterX,e.presenterY].some(o=>o!==void 0);if(n&&t.captionPlacement!==void 0)throw new Error("Pass caption placement either as typed flags or inside --settings, not both.");if(r&&t.captionStyle!==void 0)throw new Error("Pass caption style either as typed flags or inside --settings, not both.");if(i&&t.presenter!==void 0)throw new Error("Pass presenter layout either as typed flags or as settings.presenter, not both.");return zE({captionBackgroundColor:e.captionBackgroundColor,captionFontFamily:e.captionFontFamily,captionFontSize:e.captionFontSize,captionHeight:e.captionHeight,captionHighlightColor:e.captionHighlightColor,captionTextColor:e.captionTextColor,captionWidth:e.captionWidth,captionX:e.captionX,captionY:e.captionY,presenterAnchor:e.presenterAnchor,presenterApplyToAll:e.presenterApplyToAll||void 0,presenterBackgroundFit:e.presenterBackgroundFit,presenterBackgroundHex:e.presenterBackgroundHex,presenterBackgroundKind:e.presenterBackground,presenterBackgroundUrl:e.presenterBackgroundUrl,presenterBorderRadius:e.presenterBorderRadius,presenterFramingX:e.presenterFramingX,presenterFramingY:e.presenterFramingY,presenterFramingZoom:e.presenterFramingZoom,presenterHeight:e.presenterHeight,presenterOffsetX:e.presenterOffsetX,presenterOffsetY:e.presenterOffsetY,presenterSize:e.presenterSize,presenterSlideId:e.presenterSlideId,presenterUseDefault:e.presenterUseDefault||void 0,presenterVisible:e.presenterVisible,presenterX:e.presenterX,presenterY:e.presenterY,settings:e.settings?t:void 0})}function ee(e,t,n,r=!1){return i=>{let o=Number(i);if(!Number.isFinite(o)||o<t||o>n||r&&!Number.isInteger(o))throw new Wg(`${e} must be ${r?"an integer":"a number"} from ${t} to ${n}.`);return o}}function zg(e){return t=>{if(t==="true")return!0;if(t==="false")return!1;throw new Wg(`${e} must be true or false.`)}}function zE(e){return Object.fromEntries(Object.entries(e).filter(t=>t[1]!==void 0))}var XE=["right-way","wrong-way"],YE=new As("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(e,t){let n=k(this,t);try{m(await R("generatePresentationVideoSceneClip",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Hg=new As("generate").description("Create a right-way or wrong-way clip from a picture or prompt and attach it to video scenes").argument("<project-id>","Presentation video project ID or slug").option("--image <file-or-url-or-id>","Local image file to upload, an https image URL, or a media-library asset UUID. Omit for a text-only clip (needs --prompt)").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 (or, for a text-only clip, is described in the prompt). 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",he("--start")).option("--layer-duration <seconds>","Seconds the layer is on screen; omit for the whole scene",he("--layer-duration")).option("--label <text>",'Studio label, e.g. "Right way"').option("--duration-seconds <n>","Requested clip length, 5 to 15 seconds (default 6). Standard workspaces render the nearest of 5, 10 or 15; the result's durationSeconds is the rendered length",ee("--duration-seconds",5,15,!0)).option("--prompt <text>","Replace the derived scene description. Required without --image").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(e,t){let n=k(this,t);if(!n.yes)return a("Pass --yes to confirm generating a paid scene clip.");let r=n.preset??"right-way";XE.includes(r)||(a("--preset must be right-way or wrong-way."),process.exit(s.INVALID_INPUT));let i=n.realPerson===!1;r==="wrong-way"&&!i&&(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"&&i&&(a("--no-real-person only applies to --preset wrong-way."),process.exit(s.INVALID_INPUT)),!n.image&&!n.prompt?.trim()&&(a("Pass --image to stage the clip from a picture, or --prompt to generate it from text alone."),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 o=xe(n),c=n.image?await Ki(n.image,{idempotencyKey:n.idempotencyKey}):void 0,l=Gi({duration:n.layerDuration,start:n.start});m(await p("generatePresentationVideoSceneClip",{...o,destination:{...n.label?{label:n.label}:{},placement:qn(n.placement??"background"),sceneIds:br(n.scenes),...l?{timing:l}:{}},durationSeconds:n.durationSeconds,...c?{image:c}:{},preset:r,projectId:e,prompt:n.prompt,teamId:n.teamId,...i?{wrongWay:{noRealPersonInImage:!0}}:{}},n.idempotencyKey??HE()))}catch(o){a(u(o,"Scene clip failed")),process.exit(s.GENERAL_ERROR)}});ke(Hg);var Xg=new As("scene-clip").description("Generate scene-clip footage and attach it as a scene layer").addCommand(Hg).addCommand(YE).addHelpText("after",`
202
219
  Without --image the clip is generated from --prompt alone. A wrong-way clip
203
220
  is refused unless you declare it people-free with --no-real-person. Layers
204
221
  already in the project are managed with
@@ -209,7 +226,7 @@ Examples:
209
226
  ${f.commands[0]} presentation video scene-clip generate <project-id> --prompt "An operator closes the guard before starting the press" --scenes slide-2 --duration-seconds 10 --yes
210
227
  ${f.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
211
228
  ${f.commands[0]} presentation video scene-clip status <run-id>
212
- `);import{randomUUID as WE}from"crypto";import{Command as zg}from"commander";var Hg="designPresentationVideoScenes",Ps=new zg("video-scene-design").description("Design new or existing video scenes using the draft's presentation style (uses credits)").option("--project-id <id>","Video draft UUID or editor slug").option("--presentation-id <id>","Source presentation UUID or slug").option("--title <text>","Title for a new video draft").requiredOption("--topic <text>","Visual request and factual content").option("--quality <quality>","Scene design quality: basic, standard or best").option("--scene-count <count>","Number of new scenes, 1\u201310",Number,1).option("--desired-duration-sec <seconds>","Target duration for the video, in seconds",Number).option("--scene-ids <ids...>","Existing scene IDs to redesign instead of inserting").option("--after-scene-id <id>","Insert new scenes after this scene").option("--before-scene-id <id>","Insert new scenes before this scene").option("--additional-context <text>","Additional factual context").option("--amount <amount>","minimal, concise, detailed or extensive").option("--audience <text>","Intended audience").option("--branding-id <id>","Workspace brand override").option("--brand-variant-id <id>","Brand variant").option("--brand-enforcement <json>","Brand color/font enforcement object").option("--content-sources <json>","The same structured source context accepted by presentation creation").option("--conversation-context <text>","Conversation context").option("--design-brand-reference <text>","Visual direction").option("--goal <goal>","inform, persuade, train, learn, entertain or report").option("--language <language>","Output language").option("--image-policy <policy>","auto (search/generate) or none").option("--image-tier <tier>","smart, fast, balanced or best").option("--media <json>","Optional avatarId, avatarRenderTier, music and sfx settings").option("--reference-url <url>","Visual reference image").option("--tone <tone>","professional, creative, educational, formal or casual").option("--file <path>","Upload a local PDF, Office or text source").option("--yes","Confirm this generation uses credits").option("--team-id <id>","Workspace override").option("--idempotency-key <key>","Stable retry key").option("--no-follow","Return the run ID immediately").action(async function(e){try{let t=k(this,e);if(!t.yes){a("Scene design uses credits; pass --yes to confirm."),process.exit(s.GENERAL_ERROR);return}let n=typeof t.idempotencyKey=="string"?t.idempotencyKey:WE(),r=await U(typeof t.teamId=="string"?t.teamId:void 0),{file:i,yes:o,follow:c,idempotencyKey:l,teamId:d,...g}=t;if(typeof g.brandEnforcement=="string"&&(g.brandEnforcement=JSON.parse(g.brandEnforcement)),typeof g.media=="string"&&(g.media=JSON.parse(g.media)),typeof g.contentSources=="string"&&(g.contentSources=JSON.parse(g.contentSources)),typeof i=="string"){let v=await ie(i,{idempotencyKey:`scene-source:${n}`}),x=g.contentSources??{};g.contentSources={...x,uploadedFiles:[...x.uploadedFiles??[],v]}}let y=await p(Hg,{...g,teamId:r},n);if(m({...y,idempotencyKey:n}),!c||y.status==="completed")return;await Ge(y.runId,"presentation video-scene-design status",async v=>{let x=new URL(`/api/v1/presentation-videos/scene-designs/runs/${encodeURIComponent(y.runId)}/events`,K());x.searchParams.set("teamId",r);let T=await fetch(x,{headers:{...await fe(),...v?{"Last-Event-ID":v}:{}}});if(!T.ok)throw new Error("Scene design stream is unavailable; use the status command to recover.");return T})}catch(t){a(u(t,"Scene design failed")),process.exit(s.GENERAL_ERROR)}});Ps.addCommand(ce(new zg("status").description("Read owned scene design progress and saved-version receipt").argument("<run-id>","Scene design run ID").option("--team-id <id>","Workspace override").action(async function(e,t){try{m(await R(Hg,e,k(this,t).teamId))}catch(n){a(u(n,"Scene design status failed")),process.exit(s.GENERAL_ERROR)}})));import{randomUUID as JE}from"crypto";import{Command as As}from"commander";var zE=new As("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(e,t,n){let r=k(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{m(await p("renderPresentationVideoScene",{projectId:e,sceneId:t,teamId:r.teamId},r.idempotencyKey??JE()))}catch(i){a(u(i,"Scene render failed")),process.exit(s.GENERAL_ERROR)}}),HE=new As("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(e,t){let n=k(this,t);try{m(await R("renderPresentationVideoScene",e,n.teamId))}catch(r){if(Li(r)){let i=await Ui({cliCommandPrefix:"presentation video",excludeCapabilityId:"renderPresentationVideoScene",runId:e,teamId:n.teamId});i&&(a(`[wrong_capability] Run ${e} belongs to a different presentation-video capability. Read it with: ${f.commands[0]} ${i.statusCommand} ${e}`),process.exit(s.INVALID_INPUT))}a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Xg=new As("scene").description("Render and inspect one scene of a presentation video").addCommand(zE).addCommand(HE).addHelpText("after",`
229
+ `);import{randomUUID as QE}from"crypto";import{Command as Yg}from"commander";var Qg="designPresentationVideoScenes",Ts=new Yg("video-scene-design").description("Design new or existing video scenes using the draft's presentation style (uses credits)").option("--project-id <id>","Video draft UUID or editor slug").option("--presentation-id <id>","Source presentation UUID or slug").option("--title <text>","Title for a new video draft").requiredOption("--topic <text>","Visual request and factual content").option("--quality <quality>","Scene design quality: basic, standard or best").option("--scene-count <count>","Number of new scenes, 1\u201310",Number,1).option("--desired-duration-sec <seconds>","Target duration for the video, in seconds",Number).option("--scene-ids <ids...>","Existing scene IDs to redesign instead of inserting").option("--after-scene-id <id>","Insert new scenes after this scene").option("--before-scene-id <id>","Insert new scenes before this scene").option("--additional-context <text>","Additional factual context").option("--amount <amount>","minimal, concise, detailed or extensive").option("--audience <text>","Intended audience").option("--branding-id <id>","Workspace brand override").option("--brand-variant-id <id>","Brand variant").option("--brand-enforcement <json>","Brand color/font enforcement object").option("--content-sources <json>","The same structured source context accepted by presentation creation").option("--conversation-context <text>","Conversation context").option("--design-brand-reference <text>","Visual direction").option("--goal <goal>","inform, persuade, train, learn, entertain or report").option("--language <language>","Output language").option("--image-policy <policy>","auto (search/generate) or none").option("--image-tier <tier>","smart, fast, balanced or best").option("--media <json>","Optional avatarId, avatarRenderTier, music and sfx settings").option("--reference-url <url>","Visual reference image").option("--tone <tone>","professional, creative, educational, formal or casual").option("--file <path>","Upload a local PDF, Office or text source").option("--yes","Confirm this generation uses credits").option("--team-id <id>","Workspace override").option("--idempotency-key <key>","Stable retry key").option("--no-follow","Return the run ID immediately").action(async function(e){try{let t=k(this,e);if(!t.yes){a("Scene design uses credits; pass --yes to confirm."),process.exit(s.GENERAL_ERROR);return}let n=typeof t.idempotencyKey=="string"?t.idempotencyKey:QE(),r=await U(typeof t.teamId=="string"?t.teamId:void 0),{file:i,yes:o,follow:c,idempotencyKey:l,teamId:d,...g}=t;if(typeof g.brandEnforcement=="string"&&(g.brandEnforcement=JSON.parse(g.brandEnforcement)),typeof g.media=="string"&&(g.media=JSON.parse(g.media)),typeof g.contentSources=="string"&&(g.contentSources=JSON.parse(g.contentSources)),typeof i=="string"){let v=await ie(i,{idempotencyKey:`scene-source:${n}`}),x=g.contentSources??{};g.contentSources={...x,uploadedFiles:[...x.uploadedFiles??[],v]}}let y=await p(Qg,{...g,teamId:r},n);if(m({...y,idempotencyKey:n}),!c||y.status==="completed")return;await Ge(y.runId,"presentation video-scene-design status",async v=>{let x=new URL(`/api/v1/presentation-videos/scene-designs/runs/${encodeURIComponent(y.runId)}/events`,K());x.searchParams.set("teamId",r);let T=await fetch(x,{headers:{...await fe(),...v?{"Last-Event-ID":v}:{}}});if(!T.ok)throw new Error("Scene design stream is unavailable; use the status command to recover.");return T})}catch(t){a(u(t,"Scene design failed")),process.exit(s.GENERAL_ERROR)}});Ts.addCommand(ce(new Yg("status").description("Read owned scene design progress and saved-version receipt").argument("<run-id>","Scene design run ID").option("--team-id <id>","Workspace override").action(async function(e,t){try{m(await R(Qg,e,k(this,t).teamId))}catch(n){a(u(n,"Scene design status failed")),process.exit(s.GENERAL_ERROR)}})));import{randomUUID as ZE}from"crypto";import{Command as Os}from"commander";var eP=new Os("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(e,t,n){let r=k(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{m(await p("renderPresentationVideoScene",{projectId:e,sceneId:t,teamId:r.teamId},r.idempotencyKey??ZE()))}catch(i){a(u(i,"Scene render failed")),process.exit(s.GENERAL_ERROR)}}),tP=new Os("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(e,t){let n=k(this,t);try{m(await R("renderPresentationVideoScene",e,n.teamId))}catch(r){if(Ui(r)){let i=await _i({cliCommandPrefix:"presentation video",excludeCapabilityId:"renderPresentationVideoScene",runId:e,teamId:n.teamId});i&&(a(`[wrong_capability] Run ${e} belongs to a different presentation-video capability. Read it with: ${f.commands[0]} ${i.statusCommand} ${e}`),process.exit(s.INVALID_INPUT))}a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Zg=new Os("scene").description("Render and inspect one scene of a presentation video").addCommand(eP).addCommand(tP).addHelpText("after",`
213
230
  A scene render produces the same frames the final video uses, so rendering the
214
231
  whole video afterwards is not charged for the scenes it reuses. Editing a scene
215
232
  invalidates its segment; render it again to see the change.
@@ -217,13 +234,13 @@ invalidates its segment; render it again to see the change.
217
234
  Examples:
218
235
  ${f.commands[0]} presentation video scene render <project-id> slide-3 --yes
219
236
  ${f.commands[0]} presentation video scene status <run-id>
220
- `);import{randomUUID as Zg}from"crypto";import{writeFile as XE}from"fs/promises";import{resolve as YE}from"path";import{Command as Qi,InvalidArgumentError as QE}from"commander";var Yg=["1.2","2004"];function Qg(e){return t=>{let n=Number(t);if(!Number.isInteger(n))throw new QE(`Expected a whole-number percent. ${e} got "${t}".`);return n}}async function ef(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}var ZE=new Qi("export").description("Export a finished presentation video as a SCORM zip with a revocable embed link").argument("<project-id>","Presentation-video project UUID or editor slug").option("--scorm-version <version>",`SCORM version: ${Yg.join(" | ")}`,b("--scorm-version",Yg),"2004").option("--completion <percent>","Percent of the video that must be watched for completion (50-100)",Qg("--completion")).option("--pass-mark <percent>","Quiz pass mark percent; requires published questions on the video",Qg("--pass-mark")).option("--title <title>","Package title inside the SCORM manifest").option("--out <file>","Where to write the SCORM zip").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t),r;try{r=await p("exportPresentationVideoScorm",{projectId:e,...n.completion!==void 0?{completionThresholdPercent:n.completion}:{},...n.passMark!==void 0?{passMarkPercent:n.passMark}:{},...n.title?{title:n.title}:{},...n.scormVersion?{scormVersion:n.scormVersion}:{},teamId:n.teamId},n.idempotencyKey??Zg())}catch(o){a(u(o,"SCORM export failed")),process.exit(s.GENERAL_ERROR)}let i=YE(n.out??r.fileName);try{let o=await hn(r.downloadUrl);await XE(i,Buffer.from(o))}catch(o){a(u(o,"SCORM download failed")),process.exit(s.GENERAL_ERROR)}m({...r,outputPath:i})}),eP=new Qi("list").description("List a presentation video's SCORM exports and their state").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=k(this,t);await ef("SCORM export list failed",()=>p("listPresentationVideoScormExports",{projectId:e,teamId:n.teamId}))}),tP=new Qi("revoke").description("Revoke a SCORM export's embed link").argument("<export-id>","Export id from the export or list command").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t);await ef("SCORM export revoke failed",()=>p("revokePresentationVideoScormExport",{exportId:e,teamId:n.teamId},n.idempotencyKey??Zg()))}),tf=new Qi("scorm").description("Export a finished video as a SCORM package for an LMS").addCommand(ZE).addCommand(eP).addCommand(tP).addHelpText("after",`
237
+ `);import{randomUUID as nf}from"crypto";import{writeFile as nP}from"fs/promises";import{resolve as rP}from"path";import{Command as eo,InvalidArgumentError as iP}from"commander";var ef=["1.2","2004"];function tf(e){return t=>{let n=Number(t);if(!Number.isInteger(n))throw new iP(`Expected a whole-number percent. ${e} got "${t}".`);return n}}async function rf(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}var oP=new eo("export").description("Export a finished presentation video as a SCORM zip with a revocable embed link").argument("<project-id>","Presentation-video project UUID or editor slug").option("--scorm-version <version>",`SCORM version: ${ef.join(" | ")}`,b("--scorm-version",ef),"2004").option("--completion <percent>","Percent of the video that must be watched for completion (50-100)",tf("--completion")).option("--pass-mark <percent>","Quiz pass mark percent; requires published questions on the video",tf("--pass-mark")).option("--title <title>","Package title inside the SCORM manifest").option("--out <file>","Where to write the SCORM zip").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t),r;try{r=await p("exportPresentationVideoScorm",{projectId:e,...n.completion!==void 0?{completionThresholdPercent:n.completion}:{},...n.passMark!==void 0?{passMarkPercent:n.passMark}:{},...n.title?{title:n.title}:{},...n.scormVersion?{scormVersion:n.scormVersion}:{},teamId:n.teamId},n.idempotencyKey??nf())}catch(o){a(u(o,"SCORM export failed")),process.exit(s.GENERAL_ERROR)}let i=rP(n.out??r.fileName);try{let o=await hn(r.downloadUrl);await nP(i,Buffer.from(o))}catch(o){a(u(o,"SCORM download failed")),process.exit(s.GENERAL_ERROR)}m({...r,outputPath:i})}),aP=new eo("list").description("List a presentation video's SCORM exports and their state").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=k(this,t);await rf("SCORM export list failed",()=>p("listPresentationVideoScormExports",{projectId:e,teamId:n.teamId}))}),sP=new eo("revoke").description("Revoke a SCORM export's embed link").argument("<export-id>","Export id from the export or list command").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key").action(async function(e,t){let n=k(this,t);await rf("SCORM export revoke failed",()=>p("revokePresentationVideoScormExport",{exportId:e,teamId:n.teamId},n.idempotencyKey??nf()))}),of=new eo("scorm").description("Export a finished video as a SCORM package for an LMS").addCommand(oP).addCommand(aP).addCommand(sP).addHelpText("after",`
221
238
  Examples:
222
239
  ${f.commands[0]} presentation video scorm export <project-id> --scorm-version 2004 --completion 95 --pass-mark 80
223
240
  ${f.commands[0]} presentation video scorm export <project-id> --out course.zip
224
241
  ${f.commands[0]} presentation video scorm list <project-id>
225
242
  ${f.commands[0]} presentation video scorm revoke <export-id>
226
- `);import{createHash as nP,randomUUID as rP}from"crypto";import{Command as nf}from"commander";var rf="importPresentationVideoScript",of=new nf("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(e,t){try{let n=k(this,t);if(!!n.file==!!n.fileUrl)throw new Error("Provide exactly one of --file or --file-url.");let r=n.idempotencyKey??rP(),i=await U(n.teamId),o=n.file?(await ie(n.file,{idempotencyKey:`script:${nP("sha256").update(r).digest("hex")}`})).url:n.fileUrl,c=await p(rf,{projectId:e,fileUrl:o,instructions:n.instructions,teamId:i},r);if(m(c),!n.follow||c.status==="completed")return;I(`Script import run: ${c.runId}`),await Ge(c.runId,"presentation video-script-import-status",l=>iP(c.runId,i,l))}catch(n){a(u(n,"Script import failed")),process.exit(s.GENERAL_ERROR)}}),af=new nf("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(e,t){try{let n=k(this,t);m(await R(rf,e,n.teamId))}catch(n){a(u(n,"Script import status failed")),process.exit(s.GENERAL_ERROR)}});async function iP(e,t,n){let r=new URL(`/api/v1/presentation-videos/script-imports/runs/${encodeURIComponent(e)}/events`,K());r.searchParams.set("teamId",t);let i=await fetch(r,{headers:{...await fe(),...n?{"Last-Event-ID":n}:{}}});if(!i.ok)throw new P("Script import event stream is unavailable; use the status command to recover.",i.status);return i}import{Command as oP}from"commander";var Ts=new oP("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",ee("--caption-x",0,1)).option("--caption-y <ratio>","Caption box center on the vertical axis, from 0 to 1",ee("--caption-y",0,1)).option("--caption-width <ratio>","Caption box width as a frame fraction, from 0.18 to 0.95",ee("--caption-width",.18,.95)).option("--caption-height <ratio>","Caption box height as a frame fraction, from 0.05 to 0.5",ee("--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",ee("--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",b("--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",ee("--presenter-size",.08,.9)).option("--presenter-height <ratio>","Explicit presenter box height as a frame fraction, from 0.05 to 1",ee("--presenter-height",.05,1)).option("--presenter-x <ratio>","Horizontal center from 0 to 1; use with --presenter-anchor free",ee("--presenter-x",0,1)).option("--presenter-y <ratio>","Vertical center from 0 to 1; use with --presenter-anchor free",ee("--presenter-y",0,1)).option("--presenter-offset-x <ratio>","Horizontal edge offset for anchored placement, from 0 to 0.35",ee("--presenter-offset-x",0,.35)).option("--presenter-offset-y <ratio>","Vertical edge offset for anchored placement, from 0 to 0.35",ee("--presenter-offset-y",0,.35)).option("--presenter-border-radius <ratio>","Corner radius from 0 (square) to 0.5 (circle or pill)",ee("--presenter-border-radius",0,.5)).option("--presenter-framing-x <ratio>","Horizontal crop focus inside the presenter box, from 0 to 1",ee("--presenter-framing-x",0,1)).option("--presenter-framing-y <ratio>","Vertical crop focus inside the presenter box, from 0 to 1",ee("--presenter-framing-y",0,1)).option("--presenter-framing-zoom <ratio>","Crop zoom inside the presenter box, from 1 to 2",ee("--presenter-framing-zoom",1,2)).option("--presenter-background <kind>","Background: original, transparent, color, or image",b("--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",b("--presenter-background-fit",["cover","contain"])).option("--presenter-visible <true|false>","Show or hide the presenter on --presenter-slide-id",Kg("--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(e,t){let n=k(this,t),r;try{r=await Gg(n)}catch(i){a(u(i,"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 i=await U(n.teamId),o={projectId:e,...r,...xe(n),teamId:i};m(await p("updatePresentationVideoSettings",o,n.idempotencyKey??Q({command:"presentation video settings",payload:o,workspaceId:i})))}catch(i){a(u(i,"Settings update failed")),process.exit(s.GENERAL_ERROR)}}).addHelpText("after",`
243
+ `);import{createHash as dP,randomUUID as cP}from"crypto";import{Command as af}from"commander";var sf="importPresentationVideoScript",df=new af("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(e,t){try{let n=k(this,t);if(!!n.file==!!n.fileUrl)throw new Error("Provide exactly one of --file or --file-url.");let r=n.idempotencyKey??cP(),i=await U(n.teamId),o=n.file?(await ie(n.file,{idempotencyKey:`script:${dP("sha256").update(r).digest("hex")}`})).url:n.fileUrl,c=await p(sf,{projectId:e,fileUrl:o,instructions:n.instructions,teamId:i},r);if(m(c),!n.follow||c.status==="completed")return;I(`Script import run: ${c.runId}`),await Ge(c.runId,"presentation video-script-import-status",l=>lP(c.runId,i,l))}catch(n){a(u(n,"Script import failed")),process.exit(s.GENERAL_ERROR)}}),cf=new af("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(e,t){try{let n=k(this,t);m(await R(sf,e,n.teamId))}catch(n){a(u(n,"Script import status failed")),process.exit(s.GENERAL_ERROR)}});async function lP(e,t,n){let r=new URL(`/api/v1/presentation-videos/script-imports/runs/${encodeURIComponent(e)}/events`,K());r.searchParams.set("teamId",t);let i=await fetch(r,{headers:{...await fe(),...n?{"Last-Event-ID":n}:{}}});if(!i.ok)throw new P("Script import event stream is unavailable; use the status command to recover.",i.status);return i}import{Command as mP}from"commander";var $s=new mP("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",ee("--caption-x",0,1)).option("--caption-y <ratio>","Caption box center on the vertical axis, from 0 to 1",ee("--caption-y",0,1)).option("--caption-width <ratio>","Caption box width as a frame fraction, from 0.18 to 0.95",ee("--caption-width",.18,.95)).option("--caption-height <ratio>","Caption box height as a frame fraction, from 0.05 to 0.5",ee("--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",ee("--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",b("--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",ee("--presenter-size",.08,.9)).option("--presenter-height <ratio>","Explicit presenter box height as a frame fraction, from 0.05 to 1",ee("--presenter-height",.05,1)).option("--presenter-x <ratio>","Horizontal center from 0 to 1; use with --presenter-anchor free",ee("--presenter-x",0,1)).option("--presenter-y <ratio>","Vertical center from 0 to 1; use with --presenter-anchor free",ee("--presenter-y",0,1)).option("--presenter-offset-x <ratio>","Horizontal edge offset for anchored placement, from 0 to 0.35",ee("--presenter-offset-x",0,.35)).option("--presenter-offset-y <ratio>","Vertical edge offset for anchored placement, from 0 to 0.35",ee("--presenter-offset-y",0,.35)).option("--presenter-border-radius <ratio>","Corner radius from 0 (square) to 0.5 (circle or pill)",ee("--presenter-border-radius",0,.5)).option("--presenter-framing-x <ratio>","Horizontal crop focus inside the presenter box, from 0 to 1",ee("--presenter-framing-x",0,1)).option("--presenter-framing-y <ratio>","Vertical crop focus inside the presenter box, from 0 to 1",ee("--presenter-framing-y",0,1)).option("--presenter-framing-zoom <ratio>","Crop zoom inside the presenter box, from 1 to 2",ee("--presenter-framing-zoom",1,2)).option("--presenter-background <kind>","Background: original, transparent, color, or image",b("--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",b("--presenter-background-fit",["cover","contain"])).option("--presenter-visible <true|false>","Show or hide the presenter on --presenter-slide-id",zg("--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(e,t){let n=k(this,t),r;try{r=await Jg(n)}catch(i){a(u(i,"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 i=await U(n.teamId),o={projectId:e,...r,...xe(n),teamId:i};m(await p("updatePresentationVideoSettings",o,n.idempotencyKey??Q({command:"presentation video settings",payload:o,workspaceId:i})))}catch(i){a(u(i,"Settings update failed")),process.exit(s.GENERAL_ERROR)}}).addHelpText("after",`
227
244
  Caption geometry uses frame-relative values. x/y are the box center; width/height are its size.
228
245
  Omitted caption fields keep their saved values. Run presentation video inspect <project-id> to verify them.
229
246
  Presenter geometry also uses frame-relative values. Omit --presenter-slide-id to edit the default; pass it for one scene.
@@ -235,16 +252,16 @@ Examples:
235
252
  ${f.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
236
253
  ${f.commands[0]} presentation video settings <project-id> --presenter-slide-id <slide-id> --presenter-apply-to-all --yes
237
254
  ${f.commands[0]} presentation video settings <project-id> --presenter-background color --presenter-background-hex '#14213d' --yes
238
- `);ke(Ts);import{Command as Ir,InvalidArgumentError as mP}from"commander";import{createHash as aP}from"crypto";import{existsSync as sP,readFileSync as dP}from"fs";import{Command as sf,InvalidArgumentError as df}from"commander";function cP(e){let t=Number(e);if(!Number.isFinite(t)||t<0||t>1)throw new df("--volume must be a number from 0 to 1.");return t}function lP(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new df("--file-size must be a positive whole number.");return t}async function cf(e){let{idempotencyKey:t,teamId:n,...r}=e;return p("createPresentationVideoMusicUploadUrl",{...r,teamId:n},t)}var lf=new sf("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",lP).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(e,t){let n=k(this,t);await w();try{let r=await U(n.teamId),i={fileName:n.fileName,fileSize:n.fileSize,fileType:n.fileType,projectId:e};m(await cf({...i,idempotencyKey:n.idempotencyKey??Q({command:"presentation video music upload-url",payload:i,workspaceId:r}),teamId:r}))}catch(r){a(u(r,"Custom music upload URL creation failed")),process.exit(s.GENERAL_ERROR)}}),Os=new sf("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",cP,.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",`
255
+ `);ke($s);import{Command as kr,InvalidArgumentError as yP}from"commander";import{createHash as pP}from"crypto";import{existsSync as uP,readFileSync as gP}from"fs";import{Command as lf,InvalidArgumentError as mf}from"commander";function fP(e){let t=Number(e);if(!Number.isFinite(t)||t<0||t>1)throw new mf("--volume must be a number from 0 to 1.");return t}function hP(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw new mf("--file-size must be a positive whole number.");return t}async function pf(e){let{idempotencyKey:t,teamId:n,...r}=e;return p("createPresentationVideoMusicUploadUrl",{...r,teamId:n},t)}var uf=new lf("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",hP).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(e,t){let n=k(this,t);await w();try{let r=await U(n.teamId),i={fileName:n.fileName,fileSize:n.fileSize,fileType:n.fileType,projectId:e};m(await pf({...i,idempotencyKey:n.idempotencyKey??Q({command:"presentation video music upload-url",payload:i,workspaceId:r}),teamId:r}))}catch(r){a(u(r,"Custom music upload URL creation failed")),process.exit(s.GENERAL_ERROR)}}),Ds=new lf("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",fP,.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",`
239
256
  Postcondition: mode=upload, filename, and volume are read back from the saved project. This command never downloads an arbitrary URL.
240
- `).action(async function(e,t){let n=k(this,t);await w(),sP(n.file)||(a(`File not found: ${n.file}`),process.exit(s.INVALID_INPUT));try{let r=await U(n.teamId),i=xe(n),o=et(n.file),c=aP("sha256").update(dP(n.file)).digest("hex"),l={...i,contentSha256:c,...o,projectId:e,volume:n.volume},d=n.idempotencyKey??Q({command:"presentation video music upload",payload:l,workspaceId:r}),g=await cf({...o,idempotencyKey:`${d}:upload`,projectId:e,teamId:r}),y=await tt(n.file,g),v=await p("updatePresentationVideoSettings",{projectId:g.projectId,...i,settings:{music:{audioUrl:y.url,fileName:y.name,mode:"upload",volume:n.volume}},teamId:r},`${d}:settings`),T=(await p("getPresentationVideoProject",{projectId:g.projectId,teamId:r})).renderSettings.music;if(T.mode!=="upload"||T.uploadedFileName!==o.fileName||T.volume!==n.volume)throw new Error("Custom music upload completed but the saved project did not match it.");m({contentSha256:c,fileName:o.fileName,fileSize:o.fileSize,fileType:o.fileType,music:T,projectId:v.projectId,s3Key:g.s3Key,settings:v.settings.music})}catch(r){a(u(r,"Custom music upload failed")),process.exit(s.GENERAL_ERROR)}});ke(Os);function pP(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>24)throw new mP("--limit must be an integer from 1 to 24.");return t}var uP=new Ir("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",pP).option("--token <token>","Opaque nextToken from the previous page").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Ds("Stock-music search failed",()=>p("searchPresentationVideoStockMusic",{limit:n.limit,query:e,teamId:n.teamId,token:n.token}))}).addHelpText("after",`
257
+ `).action(async function(e,t){let n=k(this,t);await w(),uP(n.file)||(a(`File not found: ${n.file}`),process.exit(s.INVALID_INPUT));try{let r=await U(n.teamId),i=xe(n),o=et(n.file),c=pP("sha256").update(gP(n.file)).digest("hex"),l={...i,contentSha256:c,...o,projectId:e,volume:n.volume},d=n.idempotencyKey??Q({command:"presentation video music upload",payload:l,workspaceId:r}),g=await pf({...o,idempotencyKey:`${d}:upload`,projectId:e,teamId:r}),y=await tt(n.file,g),v=await p("updatePresentationVideoSettings",{projectId:g.projectId,...i,settings:{music:{audioUrl:y.url,fileName:y.name,mode:"upload",volume:n.volume}},teamId:r},`${d}:settings`),T=(await p("getPresentationVideoProject",{projectId:g.projectId,teamId:r})).renderSettings.music;if(T.mode!=="upload"||T.uploadedFileName!==o.fileName||T.volume!==n.volume)throw new Error("Custom music upload completed but the saved project did not match it.");m({contentSha256:c,fileName:o.fileName,fileSize:o.fileSize,fileType:o.fileType,music:T,projectId:v.projectId,s3Key:g.s3Key,settings:v.settings.music})}catch(r){a(u(r,"Custom music upload failed")),process.exit(s.GENERAL_ERROR)}});ke(Ds);function bP(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>24)throw new yP("--limit must be an integer from 1 to 24.");return t}var wP=new kr("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",bP).option("--token <token>","Opaque nextToken from the previous page").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await Ls("Stock-music search failed",()=>p("searchPresentationVideoStockMusic",{limit:n.limit,query:e,teamId:n.teamId,token:n.token}))}).addHelpText("after",`
241
258
  Output:
242
259
  tracks[].previewUrl is for audition only. tracks[].selectionToken is opaque and short-lived.
243
260
  To save one result, pass its id, name, and selectionToken to stock select.
244
261
 
245
262
  Example:
246
263
  $ ${f.commands[0]} presentation video music stock search "calm ambient" --limit 8
247
- `),mf=new Ir("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(e,t){let n=k(this,t);if(n.mode!=="manual"&&n.mode!=="auto")return $s("--mode must be manual or auto.");if(n.mode==="manual"&&(!n.selectionToken||!n.trackId||!n.trackName))return $s("Manual mode requires --selection-token, --track-id, and --track-name from stock search.");if(n.mode==="auto"&&(n.selectionToken||n.trackId||n.trackName))return $s("Auto mode derives the choice from the saved deck; omit manual track flags.");await Ds("Stock-music selection failed",async()=>{let r=await U(n.teamId),i={...xe(n),mode:n.mode,projectId:e,selectionToken:n.selectionToken,teamId:r,trackId:n.trackId,trackName:n.trackName},o=await p("selectPresentationVideoStockMusic",i,n.idempotencyKey??Q({command:"presentation-video-stock-music-select",payload:i,workspaceId:r}));return n.wait===!1?o:Ac(o.runId,r)})}).addHelpText("after",`
264
+ `),gf=new kr("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(e,t){let n=k(this,t);if(n.mode!=="manual"&&n.mode!=="auto")return Ns("--mode must be manual or auto.");if(n.mode==="manual"&&(!n.selectionToken||!n.trackId||!n.trackName))return Ns("Manual mode requires --selection-token, --track-id, and --track-name from stock search.");if(n.mode==="auto"&&(n.selectionToken||n.trackId||n.trackName))return Ns("Auto mode derives the choice from the saved deck; omit manual track flags.");await Ls("Stock-music selection failed",async()=>{let r=await U(n.teamId),i={...xe(n),mode:n.mode,projectId:e,selectionToken:n.selectionToken,teamId:r,trackId:n.trackId,trackName:n.trackName},o=await p("selectPresentationVideoStockMusic",i,n.idempotencyKey??Q({command:"presentation-video-stock-music-select",payload:i,workspaceId:r}));return n.wait===!1?o:Oc(o.runId,r)})}).addHelpText("after",`
248
265
  Postcondition:
249
266
  The completed run persists mode=stock, the durable audio URL, duration, track identity,
250
267
  and a new project draft version. It does not render an MP4.
@@ -254,7 +271,7 @@ Manual:
254
271
 
255
272
  Auto from saved slide titles and narration:
256
273
  $ ${f.commands[0]} presentation video music stock select <project-id> --mode auto
257
- `),gP=new Ir("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=k(this,t);await Ds("Stock-music status failed",()=>R("selectPresentationVideoStockMusic",e,n.teamId))});ke(mf);var pf=new Ir("music").description("Search and select music sources for an existing video project").addCommand(Os).addCommand(lf).addCommand(new Ir("stock").description("Preview catalog tracks and save a manual or deck-aware automatic selection").addCommand(uP).addCommand(mf).addCommand(gP));async function Ds(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function $s(e){a(e),process.exit(s.INVALID_INPUT)}import{randomUUID as Zi}from"crypto";import{Command as He,InvalidArgumentError as fP}from"commander";var hP=new He("prepare").description("Review a scene in context with concrete improvements; reuse useful suggestions").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").option("--no-wait","Return immediately with a resumable run ID").action(async function(e,t,n){let r=k(this,n);await kt("Scene suggestions could not be prepared",async()=>{let i=await U(r.teamId),o=await p("preparePresentationVideoMediaSuggestions",{projectId:e,sceneId:t,teamId:i},r.idempotencyKey??`scene-suggestions:${Zi()}`);return r.wait===!1?o:Tc(o.runId,i)})}),yP=new He("inspect").description("Read saved scene suggestions, version history and whether they match the current scene").argument("<project-id>","Video project UUID or editor slug").option("--scene-id <id>","Inspect one scene instead of the whole draft").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene suggestions could not be read",()=>p("getPresentationVideoMediaSuggestions",{projectId:e,...n.sceneId?{sceneId:n.sceneId}:{},teamId:n.teamId}))}),bP=new He("select").description("Select a saved version of a scene's suggestions").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").argument("<version-id>","Saved version ID returned by suggestions inspect").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").action(async function(e,t,n,r){let i=k(this,r);await kt("Scene suggestion version could not be selected",async()=>{let o=await U(i.teamId);return p("selectPresentationVideoMediaSuggestionsVersion",{projectId:e,sceneId:t,versionId:n,teamId:o},i.idempotencyKey??`scene-suggestions-select:${Zi()}`)})}),wP=new He("status").description("Read one scene-suggestion run's progress, result or error").argument("<run-id>","Run ID returned by suggestions prepare").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene suggestion run could not be read",()=>R("preparePresentationVideoMediaSuggestions",e,n.teamId))}),gf=new He("prepare").description("Prepare an isolated scene change for review; narration may use credits").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").argument("<suggestion-version-id>","Saved version ID from suggestions inspect").argument("<suggestion-index>","Zero-based index in that version's suggestions",xP).option("--yes","Confirm preparation; narration generation may use credits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").option("--no-wait","Return immediately with a resumable run ID").action(async function(e,t,n,r,i){let o=k(this,i);if(!o.yes){a("Preparing narration may use credits; pass --yes to confirm preparation."),process.exit(s.GENERAL_ERROR);return}await kt("Scene change could not be prepared",async()=>{let c=await U(o.teamId),l=await p("preparePresentationVideoSuggestionAction",{projectId:e,sceneId:t,suggestionVersionId:n,suggestionIndex:r,teamId:c},o.idempotencyKey??`scene-change-prepare:${Zi()}`);return o.wait===!1?l:l.ready===!0?p("getPresentationVideoSuggestionActions",{projectId:e,candidateId:l.candidateId,teamId:c}):Oc(l.runId,c)})}),vP=ce(new He("status")).description("Read a prepared scene-change run's progress, result or error").argument("<run-id>","Run ID returned by suggestions action prepare").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene change preparation could not be read",()=>R("preparePresentationVideoSuggestionAction",e,n.teamId))});gf.addCommand(vP);var IP=new He("inspect").description("Read prepared scene changes and their exact before/after values").argument("<project-id>","Video project UUID or editor slug").option("--scene-id <id>","Inspect candidates for one scene").option("--candidate-id <id>","Inspect one prepared change").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Prepared scene changes could not be read",()=>p("getPresentationVideoSuggestionActions",{projectId:e,...n.sceneId?{sceneId:n.sceneId}:{},...n.candidateId?{candidateId:n.candidateId}:{},teamId:n.teamId}))});function uf(e){return new He(e).description(e==="apply"?"Apply the exact inspected change to the video scene":"Restore the value saved before an applied change, if the draft still matches").argument("<project-id>","Video project UUID or editor slug").argument("<candidate-id>","Prepared change ID from action inspect").requiredOption("--reviewed-hash <hash>","Exact reviewedHash returned by action inspect").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").action(async function(t,n,r){let i=k(this,r);await kt(e==="apply"?"Scene change could not be applied":"Scene change could not be restored",async()=>{let o=await U(i.teamId);return p(e==="apply"?"applyPresentationVideoSuggestionAction":"restorePresentationVideoSuggestionAction",{projectId:t,candidateId:n,reviewedHash:i.reviewedHash,teamId:o},i.idempotencyKey??`scene-change-${e}:${Zi()}`)})})}var kP=new He("action").description("Prepare, review, apply or restore supported scene improvements").addCommand(gf).addCommand(IP).addCommand(uf("apply")).addCommand(uf("restore"));function xP(e){let t=Number(e);if(!/^\d+$/.test(e)||!Number.isSafeInteger(t))throw new fP("Expected a zero-based whole-number suggestion index.");return t}var ff=new He("suggestions").description("Scene critiques and visual ideas; prepare and apply supported improvements").addCommand(hP).addCommand(yP).addCommand(bP).addCommand(wP).addCommand(kP);async function kt(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{readFile as Ns}from"fs/promises";async function hf(e){if(!e)return;let t=e.trim().startsWith("{")?e:await Ns(e,"utf8"),n=JSON.parse(t);if(!n||Array.isArray(n)||typeof n!="object")throw new P("--slide-instructions must be a JSON object or file path",400);let r={};for(let[i,o]of Object.entries(n)){if(!i.trim()||typeof o!="string")throw new P("--slide-instructions must map non-empty slide IDs to text",400);r[i]=o}return r}async function yf(e){let t=e.slideId!==void 0||e.text!==void 0||e.textFile!==void 0;if(e.notes!==void 0){if(t)throw new P("Use either --notes or --slide-id with --text/--text-file, not both",400);let r=e.notes.trim().startsWith("[")?e.notes:await Ns(e.notes,"utf8"),i=JSON.parse(r);if(!Array.isArray(i)||i.length===0||!i.every(o=>o&&typeof o=="object"&&typeof o.slideId=="string"&&typeof o.text=="string"))throw new P('--notes must be a non-empty JSON array of {"slideId","text"} or a path to one',400);return i.map(({slideId:o,text:c})=>({slideId:o,text:c}))}if(!e.slideId)throw new P("Pass --slide-id with --text or --text-file, or --notes",400);if(e.text===void 0==(e.textFile===void 0))throw new P("Pass exactly one of --text or --text-file (an empty --text clears the note)",400);let n=e.text??await Ns(e.textFile,"utf8");return[{slideId:e.slideId,text:n}]}var RP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("createSlides",e,t.teamId);if(t.format==="json"){m(n);return}if(t.format==="quiet"){console.log(n.status);return}I(`Status: ${n.status}`),I(n.message),n.progress!==null&&I(`Progress: ${n.progress}%`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),CP=new Y("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??Q({command:"presentation:delete",payload:{presentationId:e},workspaceId:t.teamId??"configured-default"});try{m(await p("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},n))}catch(r){Ot(r)?m(zr({caught:r,error:"Could not delete the presentation.",idempotencyKey:n})):a(u(r,"Could not delete the presentation")),process.exit(s.GENERAL_ERROR)}}),SP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async e=>{await w();let t=e.teamId??ve();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 Do(t);if(e.format==="json")return m(n);if(e.format==="quiet")return console.log(n.planName);I(`Plan: ${n.planName}`),I(`Available modes: ${n.availableModes.join(", ")||"none"}`),I(`Maximum slides: ${n.maxSlidesPerPresentation}`)}catch(n){a(u(n,"Could not read generation limits")),process.exit(s.GENERAL_ERROR)}}),EP=new Y("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",b("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 w();try{m(await ic(e,{idempotencyKey:n.idempotencyKey,teamId:n.teamId,visibility:t}))}catch(r){a(u(r,"Could not update presentation visibility")),process.exit(s.GENERAL_ERROR)}});function wf(e){let t=Number(e);if(!Number.isInteger(t)||t<0)throw new eo("Expected a non-negative integer.");return t}async function PP(e){let t=e.trim(),n=t.startsWith("[")?t:await bf(t,"utf-8"),r=JSON.parse(n);if(!Array.isArray(r))throw new eo("--grants must be a JSON array.");for(let i of r)if(!i||typeof i!="object"||typeof i.userId!="string"||!["view","edit"].includes(i.permission))throw new eo('Every grant must be {"userId":"\u2026","permission":"view|edit"}.');return r}var AP=new Y("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{m(await p("getPresentationSharing",{documentId:e.documentId,teamId:e.teamId}))}catch(t){a(u(t,"Could not read presentation sharing")),process.exit(s.GENERAL_ERROR)}}),TP=new Y("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",wf).requiredOption("--team-access <access>","restricted, view, or edit",b("--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 U(e.teamId),n=await PP(e.grants),r=e.idempotencyKey??Q({command:"presentation:sharing:update",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess},workspaceId:t});m(await p("updatePresentationSharing",{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess,teamId:t},r))}catch(t){a(u(t,"Could not update presentation sharing")),process.exit(s.GENERAL_ERROR)}}),OP=new Y("sharing").description("Read or update presentation team access").addCommand(AP).addCommand(TP),$P=new Y("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",wf).option("--previous-owner-access <access>","Keep edit access or remove access",b("--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 U(e.teamId),n=e.idempotencyKey??Q({command:"presentation:transfer",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,toUserId:e.toUserId},workspaceId:t});m(await p("transferPresentationOwnership",{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,teamId:t,toUserId:e.toUserId},n))}catch(t){a(u(t,"Could not transfer presentation ownership")),process.exit(s.GENERAL_ERROR)}}),DP=new Y("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=k(this,t);try{let r=await p("transformPresentationImport",{importId:e},n.idempotencyKey);m(r)}catch(r){a(u(r,"Transform failed")),process.exit(s.GENERAL_ERROR)}});function vf(e){return new Y(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",b("--format",["human","json","quiet"]),"human").action(async(t,n)=>{try{let r=await R(e.capabilityId,t,n.teamId);n.format==="json"?m(r):n.format==="quiet"?console.log(r.status):(I(`Status: ${r.status}`),I(r.message),r.error&&a(ge(r.error)))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}})}var NP=vf({capabilityId:"importPowerPoint",description:"Read a PowerPoint import run",name:"status"}),LP=vf({capabilityId:"transformPresentationImport",description:"Read a PowerPoint transform run",name:"transform-status"}),If=new Y("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){If.help();return}e.file.toLowerCase().endsWith(".pptx")||(a("PowerPoint import requires a .pptx file."),process.exit(s.INVALID_INPUT));try{let t=await ie(e.file,{idempotencyKey:e.idempotencyKey}),n=await p("importPowerPoint",{brandingId:e.brandingId,filename:e.filename??t.name,mode:e.mode,sourceChatId:e.sourceChatId,sourceUrl:t.url,title:e.title},e.idempotencyKey??Mn());m(n)}catch(t){a(u(t,"Import failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(DP).addCommand(NP).addCommand(LP),UP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("generateSpeakerNotes",e,t.teamId);t.format==="json"?m(n):t.format==="quiet"?console.log(n.status):(I(`Status: ${n.status}`),I(n.message))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),_P=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("regeneratePresentationVideoNarration",e,t.teamId);t.format==="json"?m(n):t.format==="quiet"?console.log(n.status):(I(`Status: ${n.status}`),I(n.message))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),jP=new Y("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=k(this,t);try{m(await R("createPresentationVideo",e,n.teamId))}catch(r){if(Li(r)){let i=await Ui({cliCommandPrefix:"presentation video",excludeCapabilityId:"createPresentationVideo",runId:e,teamId:n.teamId});i&&(a(`[wrong_capability] Run ${e} belongs to a different presentation-video capability. Read it with: ${f.commands[0]} ${i.statusCommand} ${e}`),process.exit(s.INVALID_INPUT))}a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),qP=new Y("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").option("-f, --format <format>","Output format: json (default, unchanged machine contract), human, quiet",b("--format",["human","json","quiet"]),"json").action(async function(e,t){let n=k(this,t);if(n.narrate&&!n.yes)return a("Pass --yes to confirm. --narrate generates speaker notes and costs credits.");try{let r=await p("preparePresentationVideo",{forceNew:n.forceNew,narrate:n.narrate,presentationId:e,seedFrom:KP(n.seedFrom),teamId:n.teamId},n.idempotencyKey??Mn());if(n.format==="quiet"){console.log(r.projectId??"");return}if(n.format==="human"){if(O("Video project",r.projectSlug??r.projectId),r.narration){let i=r.narration.narratedSceneCount+r.narration.missingSceneCount;O("Narration",r.narration.complete?`complete (${r.narration.narratedSceneCount} scenes)`:`${r.narration.narratedSceneCount} of ${i} scenes narrated`)}r.voice?.status==="selected"&&r.voice.voice?.label?O("Voice",r.voice.voice.label):r.voice?.status==="unavailable"&&O("Voice","unavailable");return}m(r)}catch(r){a(u(r,"Prepare failed")),process.exit(s.GENERAL_ERROR)}}),MP=new Y("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=k(this,t);try{m(await R("ensurePresentationVideoNarration",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),VP=new Y("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",Ls,[]).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=k(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 p("ensurePresentationVideoNarration",{projectId:e,...n.keepCurrent?{slideIds:[]}:n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??Mn());if(n.wait===!1||r.runStatus==="completed"){m(r);return}m(r),await Ge(r.runId,"presentation video narrate status",i=>Fr(r.runId,i))}catch(r){a(u(r,"Narration failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(MP),FP=new Y("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)",Ls,[]).option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes apply").action(async function(e,t){let n=k(this,t);try{m(await p("applyPresentationVideoSpeakerNotes",{projectId:e,...n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??Mn()))}catch(r){a(u(r,"Speaker-notes apply failed")),process.exit(s.GENERAL_ERROR)}}),BP=new Y("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(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.");let n=t.draftVersionNumber===void 0?void 0:Number(t.draftVersionNumber);if(n!==void 0&&(!Number.isInteger(n)||n<1||!t.projectId))throw new Error("--draft-version-number requires a positive integer and --project-id.");m(await p("createPresentationVideo",{draftVersionNumber:n,forceNew:t.forceNew,forceRerender:t.forceRerender,presentationId:e,projectId:t.projectId,renderEngine:t.renderEngine,settings:t.settings?await GP(t.settings):void 0,slideAnimations:t.slideAnimations===!1?!1:void 0,teamId:t.teamId},t.idempotencyKey))}catch(n){let r=u(n,"Render failed");a(r);let i=Fd({binary:f.commands[0],message:r,projectId:t.projectId});i&&al(i),process.exit(s.GENERAL_ERROR)}}).addCommand(FP).addCommand(qP).addCommand(VP).addCommand(Vg).addCommand(lg).addCommand(pf).addCommand(ig).addCommand(og).addCommand(hg).addCommand(yg).addCommand(Cs).addCommand(dg).addCommand(Rs).addCommand(qg).addCommand(ff).addCommand(ug).addCommand(pg).addCommand(Ts).addCommand(jg).addCommand(Ug).addCommand(tf).addCommand(gg).addCommand(Jg).addCommand(Xg).addCommand(jP).addCommand(vg).addCommand(wg).addCommand(Ig).addCommand(kg).addCommand(bg).addCommand(mg);async function GP(e){let t=e.trim(),n=t.startsWith("{")?t:await bf(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 KP(e){if(!e)return;let t=e.trim();if(!t.startsWith("{"))return{projectId:t};try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{throw new eo('--seed-from must be a draft id or a JSON object like {"projectId":"<id>","carry":["narration","scenes","settings"]}.')}}function Ls(e,t){return[...t,e]}var WP=new Y("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)",Ls,[]).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",b("--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 U(t.teamId),r={density:t.density??(t.style==="detailed"?"deep":"balanced"),instructions:t.instructions,language:t.language,mode:t.mode,rewriteExisting:t.rewriteExisting||void 0,slideIds:t.slideId.length?t.slideId:void 0,slideInstructions:await hf(t.slideInstructions)},i=await tc(e,r,t.idempotencyKey??Q({command:"presentation speaker-notes",payload:r,workspaceId:n}),n);if(t.format==="json"||!t.follow){m(i);return}I(`Speaker notes run: ${i.runId}`),await Ge(i.runId,"presentation speaker-notes-status",o=>Fr(i.runId,o))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),JP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await yf(t),r=await U(t.teamId),i=await nc(e,n,t.idempotencyKey??Mn(),r);if(t.format==="json"){m(i);return}if(t.format==="quiet"){console.log(i.slides.length);return}for(let o of i.slides)I(o.status==="intentionally_empty"?`Slide ${o.slideNumber}: notes cleared`:`Slide ${o.slideNumber}: notes saved`)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),zP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async function(e,t){try{let n=k(this,t),r=await U(n.teamId),i={basedOnVersionNumber:t.basedOnVersionNumber===void 0?void 0:Number(t.basedOnVersionNumber),branchId:t.branchId,expectedHeadVersionNumber:t.expectedHeadVersionNumber===void 0?void 0:Number(t.expectedHeadVersionNumber)},o=Object.values(i).filter(d=>d!==void 0).length;if(o&&(o!==3||!Number.isInteger(i.basedOnVersionNumber)||Number(i.basedOnVersionNumber)<1||!Number.isInteger(i.expectedHeadVersionNumber)||Number(i.expectedHeadVersionNumber)<1))throw new Error("Selected narration edits require a positive base/head version and branch ID together.");if(t.density&&!["brief","balanced","deep"].includes(t.density))throw new Error("--density must be brief, balanced, or deep");let c={...i,density:t.density,visualSlideIds:t.refreshVisuals===!1?[]:t.visualSlideIds,expectedVersionId:t.expectedVersionId,instructions:t.instructions,projectId:e,slideId:t.slideId,slideIds:t.slideIds,teamId:r,useSpeakerNotes:t.speakerNotes===!1?!1:void 0},l=await p("regeneratePresentationVideoNarration",c,n.idempotencyKey??Mn());if(t.format==="json"||!t.follow){m(l);return}I(`Narration run: ${l.runId}`),await Ge(l.runId,"presentation video-narration-status",d=>Fr(l.runId,d))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),kr=new Y("presentation").description("Create an MP4 video from a finished presentation, plus speaker notes, PowerPoint import, and run status").addCommand(RP).addCommand(Go()).addCommand(SP).addCommand(Hu).addCommand(EP).addCommand(OP).addCommand($P).addCommand(CP).addCommand(If).addCommand(WP).addCommand(JP).addCommand(UP).addCommand(BP).addCommand(zP).addCommand(_P).addCommand(of).addCommand(Ps).addCommand(af).addCommand(tg).addCommand(gs);kr.addCommand(Yu);kr.addCommand(ng);kr.addHelpText("after",`
274
+ `),vP=new kr("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=k(this,t);await Ls("Stock-music status failed",()=>R("selectPresentationVideoStockMusic",e,n.teamId))});ke(gf);var ff=new kr("music").description("Search and select music sources for an existing video project").addCommand(Ds).addCommand(uf).addCommand(new kr("stock").description("Preview catalog tracks and save a manual or deck-aware automatic selection").addCommand(wP).addCommand(gf).addCommand(vP));async function Ls(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}function Ns(e){a(e),process.exit(s.INVALID_INPUT)}import{randomUUID as to}from"crypto";import{Command as He,InvalidArgumentError as IP}from"commander";var kP=new He("prepare").description("Review a scene in context with concrete improvements; reuse useful suggestions").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").option("--no-wait","Return immediately with a resumable run ID").action(async function(e,t,n){let r=k(this,n);await kt("Scene suggestions could not be prepared",async()=>{let i=await U(r.teamId),o=await p("preparePresentationVideoMediaSuggestions",{projectId:e,sceneId:t,teamId:i},r.idempotencyKey??`scene-suggestions:${to()}`);return r.wait===!1?o:$c(o.runId,i)})}),xP=new He("inspect").description("Read saved scene suggestions, version history and whether they match the current scene").argument("<project-id>","Video project UUID or editor slug").option("--scene-id <id>","Inspect one scene instead of the whole draft").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene suggestions could not be read",()=>p("getPresentationVideoMediaSuggestions",{projectId:e,...n.sceneId?{sceneId:n.sceneId}:{},teamId:n.teamId}))}),RP=new He("select").description("Select a saved version of a scene's suggestions").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").argument("<version-id>","Saved version ID returned by suggestions inspect").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").action(async function(e,t,n,r){let i=k(this,r);await kt("Scene suggestion version could not be selected",async()=>{let o=await U(i.teamId);return p("selectPresentationVideoMediaSuggestionsVersion",{projectId:e,sceneId:t,versionId:n,teamId:o},i.idempotencyKey??`scene-suggestions-select:${to()}`)})}),CP=new He("status").description("Read one scene-suggestion run's progress, result or error").argument("<run-id>","Run ID returned by suggestions prepare").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene suggestion run could not be read",()=>R("preparePresentationVideoMediaSuggestions",e,n.teamId))}),yf=new He("prepare").description("Prepare an isolated scene change for review; narration may use credits").argument("<project-id>","Video project UUID or editor slug").argument("<scene-id>","Scene ID from the video draft").argument("<suggestion-version-id>","Saved version ID from suggestions inspect").argument("<suggestion-index>","Zero-based index in that version's suggestions",AP).option("--yes","Confirm preparation; narration generation may use credits").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").option("--no-wait","Return immediately with a resumable run ID").action(async function(e,t,n,r,i){let o=k(this,i);if(!o.yes){a("Preparing narration may use credits; pass --yes to confirm preparation."),process.exit(s.GENERAL_ERROR);return}await kt("Scene change could not be prepared",async()=>{let c=await U(o.teamId),l=await p("preparePresentationVideoSuggestionAction",{projectId:e,sceneId:t,suggestionVersionId:n,suggestionIndex:r,teamId:c},o.idempotencyKey??`scene-change-prepare:${to()}`);return o.wait===!1?l:l.ready===!0?p("getPresentationVideoSuggestionActions",{projectId:e,candidateId:l.candidateId,teamId:c}):Dc(l.runId,c)})}),SP=ce(new He("status")).description("Read a prepared scene-change run's progress, result or error").argument("<run-id>","Run ID returned by suggestions action prepare").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Scene change preparation could not be read",()=>R("preparePresentationVideoSuggestionAction",e,n.teamId))});yf.addCommand(SP);var EP=new He("inspect").description("Read prepared scene changes and their exact before/after values").argument("<project-id>","Video project UUID or editor slug").option("--scene-id <id>","Inspect candidates for one scene").option("--candidate-id <id>","Inspect one prepared change").option("--team-id <id>","Workspace ID override").action(async function(e,t){let n=k(this,t);await kt("Prepared scene changes could not be read",()=>p("getPresentationVideoSuggestionActions",{projectId:e,...n.sceneId?{sceneId:n.sceneId}:{},...n.candidateId?{candidateId:n.candidateId}:{},teamId:n.teamId}))});function hf(e){return new He(e).description(e==="apply"?"Apply the exact inspected change to the video scene":"Restore the value saved before an applied change, if the draft still matches").argument("<project-id>","Video project UUID or editor slug").argument("<candidate-id>","Prepared change ID from action inspect").requiredOption("--reviewed-hash <hash>","Exact reviewedHash returned by action inspect").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable transport retry key").action(async function(t,n,r){let i=k(this,r);await kt(e==="apply"?"Scene change could not be applied":"Scene change could not be restored",async()=>{let o=await U(i.teamId);return p(e==="apply"?"applyPresentationVideoSuggestionAction":"restorePresentationVideoSuggestionAction",{projectId:t,candidateId:n,reviewedHash:i.reviewedHash,teamId:o},i.idempotencyKey??`scene-change-${e}:${to()}`)})})}var PP=new He("action").description("Prepare, review, apply or restore supported scene improvements").addCommand(yf).addCommand(EP).addCommand(hf("apply")).addCommand(hf("restore"));function AP(e){let t=Number(e);if(!/^\d+$/.test(e)||!Number.isSafeInteger(t))throw new IP("Expected a zero-based whole-number suggestion index.");return t}var bf=new He("suggestions").description("Scene critiques and visual ideas; prepare and apply supported improvements").addCommand(kP).addCommand(xP).addCommand(RP).addCommand(CP).addCommand(PP);async function kt(e,t){try{m(await t())}catch(n){a(u(n,e)),process.exit(s.GENERAL_ERROR)}}import{readFile as Us}from"fs/promises";async function wf(e){if(!e)return;let t=e.trim().startsWith("{")?e:await Us(e,"utf8"),n=JSON.parse(t);if(!n||Array.isArray(n)||typeof n!="object")throw new P("--slide-instructions must be a JSON object or file path",400);let r={};for(let[i,o]of Object.entries(n)){if(!i.trim()||typeof o!="string")throw new P("--slide-instructions must map non-empty slide IDs to text",400);r[i]=o}return r}async function vf(e){let t=e.slideId!==void 0||e.text!==void 0||e.textFile!==void 0;if(e.notes!==void 0){if(t)throw new P("Use either --notes or --slide-id with --text/--text-file, not both",400);let r=e.notes.trim().startsWith("[")?e.notes:await Us(e.notes,"utf8"),i=JSON.parse(r);if(!Array.isArray(i)||i.length===0||!i.every(o=>o&&typeof o=="object"&&typeof o.slideId=="string"&&typeof o.text=="string"))throw new P('--notes must be a non-empty JSON array of {"slideId","text"} or a path to one',400);return i.map(({slideId:o,text:c})=>({slideId:o,text:c}))}if(!e.slideId)throw new P("Pass --slide-id with --text or --text-file, or --notes",400);if(e.text===void 0==(e.textFile===void 0))throw new P("Pass exactly one of --text or --text-file (an empty --text clears the note)",400);let n=e.text??await Us(e.textFile,"utf8");return[{slideId:e.slideId,text:n}]}var TP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("createSlides",e,t.teamId);if(t.format==="json"){m(n);return}if(t.format==="quiet"){console.log(n.status);return}I(`Status: ${n.status}`),I(n.message),n.progress!==null&&I(`Progress: ${n.progress}%`),n.error&&a(ge(n.error))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),OP=new Y("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??Q({command:"presentation:delete",payload:{presentationId:e},workspaceId:t.teamId??"configured-default"});try{m(await p("deletePresentation",{approvalReceipt:t.approvalReceipt,presentationId:e,teamId:t.teamId},n))}catch(r){Ot(r)?m(Hr({caught:r,error:"Could not delete the presentation.",idempotencyKey:n})):a(u(r,"Could not delete the presentation")),process.exit(s.GENERAL_ERROR)}}),$P=new Y("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",b("--format",["human","json","quiet"]),"human").action(async e=>{await w();let t=e.teamId??ve();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 m(n);if(e.format==="quiet")return console.log(n.planName);I(`Plan: ${n.planName}`),I(`Available modes: ${n.availableModes.join(", ")||"none"}`),I(`Maximum slides: ${n.maxSlidesPerPresentation}`)}catch(n){a(u(n,"Could not read generation limits")),process.exit(s.GENERAL_ERROR)}}),DP=new Y("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",b("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 w();try{m(await ac(e,{idempotencyKey:n.idempotencyKey,teamId:n.teamId,visibility:t}))}catch(r){a(u(r,"Could not update presentation visibility")),process.exit(s.GENERAL_ERROR)}});function kf(e){let t=Number(e);if(!Number.isInteger(t)||t<0)throw new no("Expected a non-negative integer.");return t}async function NP(e){let t=e.trim(),n=t.startsWith("[")?t:await If(t,"utf-8"),r=JSON.parse(n);if(!Array.isArray(r))throw new no("--grants must be a JSON array.");for(let i of r)if(!i||typeof i!="object"||typeof i.userId!="string"||!["view","edit"].includes(i.permission))throw new no('Every grant must be {"userId":"\u2026","permission":"view|edit"}.');return r}var LP=new Y("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{m(await p("getPresentationSharing",{documentId:e.documentId,teamId:e.teamId}))}catch(t){a(u(t,"Could not read presentation sharing")),process.exit(s.GENERAL_ERROR)}}),UP=new Y("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",kf).requiredOption("--team-access <access>","restricted, view, or edit",b("--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 U(e.teamId),n=await NP(e.grants),r=e.idempotencyKey??Q({command:"presentation:sharing:update",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess},workspaceId:t});m(await p("updatePresentationSharing",{documentId:e.documentId,expectedRevision:e.expectedRevision,grants:n,teamAccess:e.teamAccess,teamId:t},r))}catch(t){a(u(t,"Could not update presentation sharing")),process.exit(s.GENERAL_ERROR)}}),_P=new Y("sharing").description("Read or update presentation team access").addCommand(LP).addCommand(UP),jP=new Y("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",kf).option("--previous-owner-access <access>","Keep edit access or remove access",b("--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 U(e.teamId),n=e.idempotencyKey??Q({command:"presentation:transfer",payload:{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,toUserId:e.toUserId},workspaceId:t});m(await p("transferPresentationOwnership",{documentId:e.documentId,expectedRevision:e.expectedRevision,previousOwnerAccess:e.previousOwnerAccess,teamId:t,toUserId:e.toUserId},n))}catch(t){a(u(t,"Could not transfer presentation ownership")),process.exit(s.GENERAL_ERROR)}}),qP=new Y("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=k(this,t);try{let r=await p("transformPresentationImport",{importId:e},n.idempotencyKey);m(r)}catch(r){a(u(r,"Transform failed")),process.exit(s.GENERAL_ERROR)}});function xf(e){return new Y(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",b("--format",["human","json","quiet"]),"human").action(async(t,n)=>{try{let r=await R(e.capabilityId,t,n.teamId);n.format==="json"?m(r):n.format==="quiet"?console.log(r.status):(I(`Status: ${r.status}`),I(r.message),r.error&&a(ge(r.error)))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}})}var MP=xf({capabilityId:"importPowerPoint",description:"Read a PowerPoint import run",name:"status"}),VP=xf({capabilityId:"transformPresentationImport",description:"Read a PowerPoint transform run",name:"transform-status"}),Rf=new Y("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){Rf.help();return}e.file.toLowerCase().endsWith(".pptx")||(a("PowerPoint import requires a .pptx file."),process.exit(s.INVALID_INPUT));try{let t=await ie(e.file,{idempotencyKey:e.idempotencyKey}),n=await p("importPowerPoint",{brandingId:e.brandingId,filename:e.filename??t.name,mode:e.mode,sourceChatId:e.sourceChatId,sourceUrl:t.url,title:e.title},e.idempotencyKey??Vn());m(n)}catch(t){a(u(t,"Import failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(qP).addCommand(MP).addCommand(VP),FP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("generateSpeakerNotes",e,t.teamId);t.format==="json"?m(n):t.format==="quiet"?console.log(n.status):(I(`Status: ${n.status}`),I(n.message))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),BP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await R("regeneratePresentationVideoNarration",e,t.teamId);t.format==="json"?m(n):t.format==="quiet"?console.log(n.status):(I(`Status: ${n.status}`),I(n.message))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),GP=new Y("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=k(this,t);try{m(await R("createPresentationVideo",e,n.teamId))}catch(r){if(Ui(r)){let i=await _i({cliCommandPrefix:"presentation video",excludeCapabilityId:"createPresentationVideo",runId:e,teamId:n.teamId});i&&(a(`[wrong_capability] Run ${e} belongs to a different presentation-video capability. Read it with: ${f.commands[0]} ${i.statusCommand} ${e}`),process.exit(s.INVALID_INPUT))}a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),KP=new Y("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").option("-f, --format <format>","Output format: json (default, unchanged machine contract), human, quiet",b("--format",["human","json","quiet"]),"json").action(async function(e,t){let n=k(this,t);if(n.narrate&&!n.yes)return a("Pass --yes to confirm. --narrate generates speaker notes and costs credits.");try{let r=await p("preparePresentationVideo",{forceNew:n.forceNew,narrate:n.narrate,presentationId:e,seedFrom:YP(n.seedFrom),teamId:n.teamId},n.idempotencyKey??Vn());if(n.format==="quiet"){console.log(r.projectId??"");return}if(n.format==="human"){if(O("Video project",r.projectSlug??r.projectId),r.narration){let i=r.narration.narratedSceneCount+r.narration.missingSceneCount;O("Narration",r.narration.complete?`complete (${r.narration.narratedSceneCount} scenes)`:`${r.narration.narratedSceneCount} of ${i} scenes narrated`)}r.voice?.status==="selected"&&r.voice.voice?.label?O("Voice",r.voice.voice.label):r.voice?.status==="unavailable"&&O("Voice","unavailable");return}m(r)}catch(r){a(u(r,"Prepare failed")),process.exit(s.GENERAL_ERROR)}}),WP=new Y("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=k(this,t);try{m(await R("ensurePresentationVideoNarration",e,n.teamId))}catch(r){a(u(r,"Status failed")),process.exit(s.GENERAL_ERROR)}}),JP=new Y("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",_s,[]).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=k(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 p("ensurePresentationVideoNarration",{projectId:e,...n.keepCurrent?{slideIds:[]}:n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??Vn());if(n.wait===!1||r.runStatus==="completed"){m(r);return}m(r),await Ge(r.runId,"presentation video narrate status",i=>Br(r.runId,i))}catch(r){a(u(r,"Narration failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(WP),zP=new Y("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)",_s,[]).option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this speaker-notes apply").action(async function(e,t){let n=k(this,t);try{m(await p("applyPresentationVideoSpeakerNotes",{projectId:e,...n.slideId?.length?{slideIds:n.slideId}:{},teamId:n.teamId},n.idempotencyKey??Vn()))}catch(r){a(u(r,"Speaker-notes apply failed")),process.exit(s.GENERAL_ERROR)}}),HP=new Y("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(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.");let n=t.draftVersionNumber===void 0?void 0:Number(t.draftVersionNumber);if(n!==void 0&&(!Number.isInteger(n)||n<1||!t.projectId))throw new Error("--draft-version-number requires a positive integer and --project-id.");m(await p("createPresentationVideo",{draftVersionNumber:n,forceNew:t.forceNew,forceRerender:t.forceRerender,presentationId:e,projectId:t.projectId,renderEngine:t.renderEngine,settings:t.settings?await XP(t.settings):void 0,slideAnimations:t.slideAnimations===!1?!1:void 0,teamId:t.teamId},t.idempotencyKey))}catch(n){let r=u(n,"Render failed");a(r);let i=Gd({binary:f.commands[0],message:r,projectId:t.projectId});i&&dl(i),process.exit(s.GENERAL_ERROR)}}).addCommand(zP).addCommand(KP).addCommand(JP).addCommand(Gg).addCommand(pg).addCommand(ff).addCommand(ag).addCommand(sg).addCommand(bg).addCommand(wg).addCommand(Es).addCommand(lg).addCommand(Ss).addCommand(Fg).addCommand(bf).addCommand(fg).addCommand(gg).addCommand($s).addCommand(Mg).addCommand(Vg).addCommand(jg).addCommand(of).addCommand(hg).addCommand(Xg).addCommand(Zg).addCommand(GP).addCommand(kg).addCommand(Ig).addCommand(xg).addCommand(Rg).addCommand(vg).addCommand(ug);async function XP(e){let t=e.trim(),n=t.startsWith("{")?t:await If(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 YP(e){if(!e)return;let t=e.trim();if(!t.startsWith("{"))return{projectId:t};try{let n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{throw new no('--seed-from must be a draft id or a JSON object like {"projectId":"<id>","carry":["narration","scenes","settings"]}.')}}function _s(e,t){return[...t,e]}var QP=new Y("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)",_s,[]).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",b("--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 U(t.teamId),r={density:t.density??(t.style==="detailed"?"deep":"balanced"),instructions:t.instructions,language:t.language,mode:t.mode,rewriteExisting:t.rewriteExisting||void 0,slideIds:t.slideId.length?t.slideId:void 0,slideInstructions:await wf(t.slideInstructions)},i=await rc(e,r,t.idempotencyKey??Q({command:"presentation speaker-notes",payload:r,workspaceId:n}),n);if(t.format==="json"||!t.follow){m(i);return}I(`Speaker notes run: ${i.runId}`),await Ge(i.runId,"presentation speaker-notes-status",o=>Br(i.runId,o))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),ZP=new Y("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await vf(t),r=await U(t.teamId),i=await ic(e,n,t.idempotencyKey??Vn(),r);if(t.format==="json"){m(i);return}if(t.format==="quiet"){console.log(i.slides.length);return}for(let o of i.slides)I(o.status==="intentionally_empty"?`Slide ${o.slideNumber}: notes cleared`:`Slide ${o.slideNumber}: notes saved`)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),eA=new Y("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",b("--format",["human","json","quiet"]),"human").action(async function(e,t){try{let n=k(this,t),r=await U(n.teamId),i={basedOnVersionNumber:t.basedOnVersionNumber===void 0?void 0:Number(t.basedOnVersionNumber),branchId:t.branchId,expectedHeadVersionNumber:t.expectedHeadVersionNumber===void 0?void 0:Number(t.expectedHeadVersionNumber)},o=Object.values(i).filter(d=>d!==void 0).length;if(o&&(o!==3||!Number.isInteger(i.basedOnVersionNumber)||Number(i.basedOnVersionNumber)<1||!Number.isInteger(i.expectedHeadVersionNumber)||Number(i.expectedHeadVersionNumber)<1))throw new Error("Selected narration edits require a positive base/head version and branch ID together.");if(t.density&&!["brief","balanced","deep"].includes(t.density))throw new Error("--density must be brief, balanced, or deep");let c={...i,density:t.density,visualSlideIds:t.refreshVisuals===!1?[]:t.visualSlideIds,expectedVersionId:t.expectedVersionId,instructions:t.instructions,projectId:e,slideId:t.slideId,slideIds:t.slideIds,teamId:r,useSpeakerNotes:t.speakerNotes===!1?!1:void 0},l=await p("regeneratePresentationVideoNarration",c,n.idempotencyKey??Vn());if(t.format==="json"||!t.follow){m(l);return}I(`Narration run: ${l.runId}`),await Ge(l.runId,"presentation video-narration-status",d=>Br(l.runId,d))}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),xr=new Y("presentation").description("Create an MP4 video from a finished presentation, plus speaker notes, PowerPoint import, and run status").addCommand(TP).addCommand(Wo()).addCommand($P).addCommand(Yu).addCommand(DP).addCommand(_P).addCommand(jP).addCommand(OP).addCommand(Rf).addCommand(QP).addCommand(ZP).addCommand(FP).addCommand(HP).addCommand(eA).addCommand(BP).addCommand(df).addCommand(Ts).addCommand(cf).addCommand(rg).addCommand(hs);xr.addCommand(Zu);xr.addCommand(ig);xr.addHelpText("after",`
258
275
  ${W.bold("Deck to MP4:")}
259
276
  $ ${f.commands[0]} presentation video prepare <slug> ${W.gray("# create/reuse the video project (free)")}
260
277
  $ ${f.commands[0]} presentation video narrate <project-id> --yes ${W.gray("# fill in missing narration")}
@@ -288,31 +305,31 @@ ${W.bold("Before rendering:")}
288
305
  ${W.bold("See also:")}
289
306
  ${W.gray("# Building a video from scratch instead of from a deck")}
290
307
  $ ${f.commands[0]} video --help
291
- `);import{writeFile as HP}from"fs/promises";import{resolve as XP}from"path";import kf from"chalk";import{Command as xf}from"commander";function Rf(e){return e.split(",").map(t=>t.trim()).filter(Boolean)}function YP(e){return Rf(e).map(t=>{let n=Number(t);return(!Number.isInteger(n)||n<1)&&(a(`--variants takes variation numbers, e.g. 1,2 (got "${t}").`),process.exit(s.INVALID_INPUT)),n})}var Cf=new xf("export").description("Export an approved governed static set or deck version as a PromoMats-ready zip").option("--ad-set <id>","Governed static ad set to export").option("--deck <id-or-slug>","Governed HCP deck to export").option("--sizes <list>","Static sets: comma-separated size ids, one page each (default: every approved size)").option("--variants <list>","Static sets: comma-separated variation numbers, one piece each (default: every approved one)").option("--version-number <n>","Decks: the approved version to export (default: latest)").option("--isi-document <id>","Vault document id of the ISI to relate each piece to").option("--pi-document <id>","Vault document id of the PI to relate each piece to (default: the claims' reference)").option("-o, --output <path>","Where to save the zip (default: its name)").option("--json","Print the result as JSON instead of downloading").option("--team-id <id>","Workspace ID").action(async e=>{await w(),!!e.adSet==!!e.deck&&(a("Pass exactly one of --ad-set <id> or --deck <id-or-slug>."),process.exit(s.INVALID_INPUT));let t;e.versionNumber!==void 0&&(t=Number(e.versionNumber),(!Number.isInteger(t)||t<1)&&(a("--version-number must be a whole number from 1 up."),process.exit(s.INVALID_INPUT)));let n;try{n=await p("exportForPromoMats",{...e.adSet?{adSetId:e.adSet}:{},...e.deck?{presentationId:e.deck}:{},...e.sizes?{sizes:Rf(e.sizes)}:{},...e.variants?{variants:YP(e.variants)}:{},...t?{versionNumber:t}:{},...e.isiDocument?{relatedIsiDocumentId:e.isiDocument}:{},...e.piDocument?{relatedPiDocumentId:e.piDocument}:{},...e.teamId?{teamId:e.teamId}:{}})}catch(r){a(u(r,"PromoMats export failed")),process.exit(s.GENERAL_ERROR)}if(e.json){m(n);return}try{let r=XP(e.output??n.fileName),i=await hn(n.downloadUrl);await HP(r,Buffer.from(i)),I(`Saved ${r} (sha256 ${n.sha256.slice(0,16)}\u2026)`);for(let o of n.pieces){I(`${o.name}: ${o.pages} pages, ${o.simulatedExactMatches}/${o.claimOccurrences} claim occurrences word for word, ${o.footnoteLinks} footnote/reference links`);for(let c of o.warnings)console.log(kf.yellow(` warning: ${c}`))}I("Upload each *.piece.pdf to PromoMats; never upload the review copy. See README.txt in the zip.")}catch(r){a(u(r,"Download failed")),process.exit(s.GENERAL_ERROR)}});Cf.addHelpText("after",`
292
- ${kf.bold("Examples:")}
308
+ `);import{writeFile as tA}from"fs/promises";import{resolve as nA}from"path";import Cf from"chalk";import{Command as Sf}from"commander";function Ef(e){return e.split(",").map(t=>t.trim()).filter(Boolean)}function rA(e){return Ef(e).map(t=>{let n=Number(t);return(!Number.isInteger(n)||n<1)&&(a(`--variants takes variation numbers, e.g. 1,2 (got "${t}").`),process.exit(s.INVALID_INPUT)),n})}var Pf=new Sf("export").description("Export an approved governed static set or deck version as a PromoMats-ready zip").option("--ad-set <id>","Governed static ad set to export").option("--deck <id-or-slug>","Governed HCP deck to export").option("--sizes <list>","Static sets: comma-separated size ids, one page each (default: every approved size)").option("--variants <list>","Static sets: comma-separated variation numbers, one piece each (default: every approved one)").option("--version-number <n>","Decks: the approved version to export (default: latest)").option("--isi-document <id>","Vault document id of the ISI to relate each piece to").option("--pi-document <id>","Vault document id of the PI to relate each piece to (default: the claims' reference)").option("-o, --output <path>","Where to save the zip (default: its name)").option("--json","Print the result as JSON instead of downloading").option("--team-id <id>","Workspace ID").action(async e=>{await w(),!!e.adSet==!!e.deck&&(a("Pass exactly one of --ad-set <id> or --deck <id-or-slug>."),process.exit(s.INVALID_INPUT));let t;e.versionNumber!==void 0&&(t=Number(e.versionNumber),(!Number.isInteger(t)||t<1)&&(a("--version-number must be a whole number from 1 up."),process.exit(s.INVALID_INPUT)));let n;try{n=await p("exportForPromoMats",{...e.adSet?{adSetId:e.adSet}:{},...e.deck?{presentationId:e.deck}:{},...e.sizes?{sizes:Ef(e.sizes)}:{},...e.variants?{variants:rA(e.variants)}:{},...t?{versionNumber:t}:{},...e.isiDocument?{relatedIsiDocumentId:e.isiDocument}:{},...e.piDocument?{relatedPiDocumentId:e.piDocument}:{},...e.teamId?{teamId:e.teamId}:{}})}catch(r){a(u(r,"PromoMats export failed")),process.exit(s.GENERAL_ERROR)}if(e.json){m(n);return}try{let r=nA(e.output??n.fileName),i=await hn(n.downloadUrl);await tA(r,Buffer.from(i)),I(`Saved ${r} (sha256 ${n.sha256.slice(0,16)}\u2026)`);for(let o of n.pieces){I(`${o.name}: ${o.pages} pages, ${o.simulatedExactMatches}/${o.claimOccurrences} claim occurrences word for word, ${o.footnoteLinks} footnote/reference links`);for(let c of o.warnings)console.log(Cf.yellow(` warning: ${c}`))}I("Upload each *.piece.pdf to PromoMats; never upload the review copy. See README.txt in the zip.")}catch(r){a(u(r,"Download failed")),process.exit(s.GENERAL_ERROR)}});Pf.addHelpText("after",`
309
+ ${Cf.bold("Examples:")}
293
310
  $ ${f.commands[0]} promomats export --ad-set <id> --sizes 1x1,9x16
294
311
  $ ${f.commands[0]} promomats export --deck <id-or-slug> --version-number 2 --isi-document 5104
295
- `);var Sf=new xf("promomats").description("Hand governed content to Veeva Vault PromoMats").addCommand(Cf);import{randomUUID as QP}from"crypto";import{writeFile as ZP}from"fs/promises";import xr from"chalk";import{Command as eA}from"commander";import tA from"ora";var Us=new eA("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format,r=n==="human"?tA("Scraping URL...").start():null;try{let i=await p("scrape",{provider:t.provider,reason:t.reason,responseFormat:t.responseFormat,teamId:t.teamId,url:e},t.idempotencyKey??QP());r?.stop();let o={content:i.content,metadata:{description:"",format:i.format??"unknown",tokenUsage:Math.ceil(i.content.length/4)},title:i.title??"",mode:i.mode,url:i.url};if(t.output&&(await ZP(t.output,o.content,"utf-8"),n==="human"&&C(`Content saved to: ${t.output}`)),n==="json"){m(o);return}if(n==="quiet"){console.log(o.content);return}o.title&&(console.log(),console.log(`Title: ${o.title}`)),o.metadata?.description&&console.log(`Description: ${o.metadata.description}`),console.log(`URL: ${o.url}`),console.log(`Tokens: ~${o.metadata?.tokenUsage?.toLocaleString()||"unknown"}`),o.warning&&q(o.warning),t.output||(console.log(),console.log("--- Content ---"),console.log(o.content))}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}});Us.addHelpText("after",`
296
- ${xr.bold("Examples:")}
297
- ${xr.gray("# Pull the readable content of a web page")}
312
+ `);var Af=new Sf("promomats").description("Hand governed content to Veeva Vault PromoMats").addCommand(Pf);import{randomUUID as iA}from"crypto";import{writeFile as oA}from"fs/promises";import Rr from"chalk";import{Command as aA}from"commander";import sA from"ora";var js=new aA("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format,r=n==="human"?sA("Scraping URL...").start():null;try{let i=await p("scrape",{provider:t.provider,reason:t.reason,responseFormat:t.responseFormat,teamId:t.teamId,url:e},t.idempotencyKey??iA());r?.stop();let o={content:i.content,metadata:{description:"",format:i.format??"unknown",tokenUsage:Math.ceil(i.content.length/4)},title:i.title??"",mode:i.mode,url:i.url};if(t.output&&(await oA(t.output,o.content,"utf-8"),n==="human"&&C(`Content saved to: ${t.output}`)),n==="json"){m(o);return}if(n==="quiet"){console.log(o.content);return}o.title&&(console.log(),console.log(`Title: ${o.title}`)),o.metadata?.description&&console.log(`Description: ${o.metadata.description}`),console.log(`URL: ${o.url}`),console.log(`Tokens: ~${o.metadata?.tokenUsage?.toLocaleString()||"unknown"}`),o.warning&&q(o.warning),t.output||(console.log(),console.log("--- Content ---"),console.log(o.content))}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}});js.addHelpText("after",`
313
+ ${Rr.bold("Examples:")}
314
+ ${Rr.gray("# Pull the readable content of a web page")}
298
315
  $ ${f.commands[0]} scrape https://example.com/post
299
316
 
300
- ${xr.bold("See also:")}
301
- ${xr.gray("# Local files and documents, not just URLs")}
317
+ ${Rr.bold("See also:")}
318
+ ${Rr.gray("# Local files and documents, not just URLs")}
302
319
  $ ${f.commands[0]} content extract ./paper.pdf
303
320
 
304
- ${xr.gray("# Spoken words out of audio or video")}
321
+ ${Rr.gray("# Spoken words out of audio or video")}
305
322
  $ ${f.commands[0]} transcript --help
306
- `);import{randomUUID as to}from"crypto";import _s from"chalk";import{Command as Rr}from"commander";function no(e,t){t!=="quiet"&&m(e)}var nA=new Rr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=[e,...t.queries??[]],r=await p("searchInternet",{gl:t.country,hl:t.language,maxResults:Number.parseInt(t.maxResults,10),queries:n,reason:t.reason,teamId:t.teamId,tbs:t.recency,timeframe:t.timeframe},t.idempotencyKey??to());no(r,t.format)}catch(n){a(u(n,"Search failed")),process.exit(s.GENERAL_ERROR)}}),rA=new Rr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await p("getNews",{maxResults:Number.parseInt(t.maxResults,10),teamId:t.teamId,timeframe:t.timeframe,topic:e},t.idempotencyKey??to());no(n,t.format)}catch(n){a(u(n,"News search failed")),process.exit(s.GENERAL_ERROR)}});function Ef(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function iA(e){if(!e?.length)return;let t=[...new Set(e.map(n=>n.toLowerCase()))];if(t.some(n=>n!=="embed"&&n!=="file"))throw new Error("Video kind must be embed or file");return t}var oA=new Rr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=[e,...t.queries??[]],r=await p("searchImages",{aspect:t.aspect,maxResults:Number.parseInt(t.maxResults,10),queries:n,reason:t.reason,sources:Ef(t.source),teamId:t.teamId},t.idempotencyKey??to());no(r,t.format)}catch(n){a(u(n,"Image search failed")),process.exit(s.GENERAL_ERROR)}}),aA=new Rr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await p("searchStockVideo",{kinds:iA(t.kind),license:t.license,maxResults:Number.parseInt(t.maxResults,10),orientation:t.orientation,query:e,sources:Ef(t.source),teamId:t.teamId},t.idempotencyKey??to());no(n,t.format)}catch(n){a(u(n,"Video search failed")),process.exit(s.GENERAL_ERROR)}}),js=new Rr("search").description("Web, news, image, and stock-video search").addCommand(nA).addCommand(rA).addCommand(oA).addCommand(aA);js.addHelpText("after",`
307
- ${_s.bold("Examples:")}
323
+ `);import{randomUUID as ro}from"crypto";import qs from"chalk";import{Command as Cr}from"commander";function io(e,t){t!=="quiet"&&m(e)}var dA=new Cr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=[e,...t.queries??[]],r=await p("searchInternet",{gl:t.country,hl:t.language,maxResults:Number.parseInt(t.maxResults,10),queries:n,reason:t.reason,teamId:t.teamId,tbs:t.recency,timeframe:t.timeframe},t.idempotencyKey??ro());io(r,t.format)}catch(n){a(u(n,"Search failed")),process.exit(s.GENERAL_ERROR)}}),cA=new Cr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await p("getNews",{maxResults:Number.parseInt(t.maxResults,10),teamId:t.teamId,timeframe:t.timeframe,topic:e},t.idempotencyKey??ro());io(n,t.format)}catch(n){a(u(n,"News search failed")),process.exit(s.GENERAL_ERROR)}});function Tf(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function lA(e){if(!e?.length)return;let t=[...new Set(e.map(n=>n.toLowerCase()))];if(t.some(n=>n!=="embed"&&n!=="file"))throw new Error("Video kind must be embed or file");return t}var mA=new Cr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=[e,...t.queries??[]],r=await p("searchImages",{aspect:t.aspect,maxResults:Number.parseInt(t.maxResults,10),queries:n,reason:t.reason,sources:Tf(t.source),teamId:t.teamId},t.idempotencyKey??ro());io(r,t.format)}catch(n){a(u(n,"Image search failed")),process.exit(s.GENERAL_ERROR)}}),pA=new Cr("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{let n=await p("searchStockVideo",{kinds:lA(t.kind),license:t.license,maxResults:Number.parseInt(t.maxResults,10),orientation:t.orientation,query:e,sources:Tf(t.source),teamId:t.teamId},t.idempotencyKey??ro());io(n,t.format)}catch(n){a(u(n,"Video search failed")),process.exit(s.GENERAL_ERROR)}}),Ms=new Cr("search").description("Web, news, image, and stock-video search").addCommand(dA).addCommand(cA).addCommand(mA).addCommand(pA);Ms.addHelpText("after",`
324
+ ${qs.bold("Examples:")}
308
325
  $ ${f.commands[0]} search web "state of AI video 2026"
309
326
  $ ${f.commands[0]} search news "vaccine approvals"
310
327
 
311
- ${_s.bold("See also:")}
312
- ${_s.gray("# `search images` and `search video` overlap with these")}
328
+ ${qs.bold("See also:")}
329
+ ${qs.gray("# `search images` and `search video` overlap with these")}
313
330
  $ ${f.commands[0]} image search --help
314
331
  $ ${f.commands[0]} video find --help
315
- `);import{randomUUID as sA}from"crypto";import{Command as Vs}from"commander";import dA from"ora";function Ms(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.audioUrl??e.requestId??e.id);return}I(`Request ID: ${e.requestId||e.id}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.audioUrl&&C(`Audio URL: ${e.audioUrl}`),e.error&&a(`Error: ${e.error}`)}var cA=new Vs("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(l){a(u(l)),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?Mu(e.request):{...e.duration?{duration:Number(e.duration)}:{},...e.durationSeconds?{duration_s:Number(e.durationSeconds)}:{},...e.narrationJson?{narration:qs("--narration-json",e.narrationJson)}:{},...e.optionsJson?{options:qs("--options-json",e.optionsJson)}:{},...e.schemaVersion?{schema_version:Number(e.schemaVersion)}:{},...e.text?{text:e.text}:{},...e.videoDescription?{video_description:e.videoDescription}:{},...e.visualEventJson?{visual_event:qs("--visual-event-json",e.visualEventJson)}:{}}}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?dA("Generating sound effect for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??sA();try{let l=await wc(n,{approvalReceipt:t,idempotencyKey:c});if(o=l.requestId||l.id,!e.wait){i?.stop(),Ms(l,r);return}let d=l.requestId||l.id;i&&(i.text=`Processing (ID: ${d})...`);let g=l.status==="completed"||l.status==="failed"?l:await $e(()=>Uo(d),60,2e3);if(i?.stop(),g.status==="failed")throw new de(g.error||"Sound effects generation failed");if(e.output){if(!g.audioUrl)throw new Error("Sound effect completed without an audio URL");await Ie(g.audioUrl,e.output),r==="human"&&C(`Saved to: ${e.output}`)}Ms(g,r)}catch(l){i?.stop(),a(`${oe(l,o)}${Ee(l,c)}`,r),process.exit(s.GENERAL_ERROR)}});function qs(e,t){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON`)}}var lA=new Vs("status").description("Check status of a sound effects generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{Ms(await Uo(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Pf=new Vs("sfx").description("Video-aware sound effects generation commands").addCommand(cA).addCommand(lA);import{randomUUID as mA}from"crypto";import{readdir as pA,readFile as ro,stat as uA}from"fs/promises";import{join as Fs}from"path";import{Command as Cr}from"commander";function io(e,t){a(`${t}: ${u(e)}`),process.exit(s.GENERAL_ERROR)}function Af(e){return`cli:skills:${e}:${mA()}`}async function gA(e){return e==="-"||e===void 0&&!process.stdin.isTTY?yA():(e===void 0&&(a("No SKILL.md given. Pass a path, @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)),ro(e.startsWith("@")?e.slice(1):e,"utf8"))}async function fA(e){let t=await ro(Fs(e,"SKILL.md"),"utf8").catch(o=>{throw new Error(`${e} is a directory but has no readable SKILL.md (${o.code??o})`)}),n=[],r=[],i=async o=>{let c=await pA(Fs(e,o||"."),{withFileTypes:!0});for(let l of c){if(l.name.startsWith("."))continue;let d=o?`${o}/${l.name}`:l.name;if(l.isDirectory()){await i(d);continue}if(!l.isFile()||l.name==="SKILL.md")continue;let g=await ro(Fs(e,d));if(g.includes(0))throw new Error(`${d} looks binary \u2014 skill assets are UTF-8 text only`);if(g.length===0){r.push(d);continue}n.push({content:g.toString("utf8"),path:d})}};return await i(""),r.length>0&&console.error(`warning: skipped ${r.length} empty file(s) \u2014 assets must have content: ${r.join(", ")}`),{assets:n,markdown:t}}async function hA(e){let t=e.indexOf("=");if(t<=0||t===e.length-1)throw new Error(`--asset expects "<remote/path>=<local/file>" \u2014 got "${e}"`);let n=e.slice(0,t).replaceAll("\\","/"),r=await ro(e.slice(t+1));if(r.includes(0))throw new Error(`${e.slice(t+1)} looks binary \u2014 UTF-8 only`);return{content:r.toString("utf8"),path:n}}async function yA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function bA(e,t){if(t==="true")return!0;if(t==="false")return!1;a(`${e} must be true or false`),process.exit(s.GENERAL_ERROR)}var wA=new Cr("list").description("List the skills available to the workspace, including its own disabled skills").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listSkills",{teamId:e.teamId}))}catch(t){io(t,"Could not list skills")}}),vA=new Cr("show").description("Show one skill's metadata and SKILL.md body").argument("<slug>","Skill slug").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getSkill",{slug:e,teamId:t.teamId}))}catch(n){io(n,"Could not read the skill")}}),IA=new Cr("create").description("Publish a SKILL.md or skill directory as a workspace-owned skill (admin/editor, team-skills flag)").argument("<file>","SKILL.md path, a skill directory (SKILL.md + bundled files), @<path>, or - for stdin").requiredOption("--slug <slug>","Skill slug \u2014 the $handle the agent uses").option("--asset <remote=local>","Bundle a file: remote path inside the skill = local file to read (repeatable)",(e,t)=>[...t,e],[]).option("--visibility <visibility>","team, private or personal (personal = visible only to you)").option("--enabled <bool>","true or false; defaults to keeping the current state (new skills start enabled)").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n={slug:t.slug,teamId:t.teamId},r=new Map,i=e?.startsWith("@")?e.slice(1):e;if(e!=="-"&&i&&(await uA(i).catch(()=>null))?.isDirectory()){let o=await fA(i);n.markdown=o.markdown;for(let c of o.assets)r.set(c.path,c)}else n.markdown=await gA(e);for(let o of t.asset){let c=await hA(o);r.set(c.path,c)}r.size>0&&(n.assets=[...r.values()]),t.visibility!==void 0&&(n.visibility=t.visibility),t.enabled!==void 0&&(n.enabled=bA("--enabled",t.enabled)),m(await p("upsertTeamSkill",n,t.idempotencyKey??Af("create")))}catch(n){io(n,"Could not publish the skill")}}),kA=new Cr("delete").description("Delete a workspace-owned skill (admin/editor, team-skills flag)").argument("<slug>","Skill slug").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("deleteTeamSkill",{slug:e,teamId:t.teamId},t.idempotencyKey??Af("delete")))}catch(n){io(n,"Could not delete the skill")}}),Tf=new Cr("skills").description("Manage the workspace's team skills").addCommand(wA).addCommand(vA).addCommand(IA).addCommand(kA);import{randomUUID as xA}from"crypto";import{readFile as $f}from"fs/promises";import{Command as oo}from"commander";var Df=["quiz","flashcards","cheat-sheet"],RA=["beginner","intermediate","advanced","mixed"];function CA(){return`cli:study-set:create:${xA()}`}function Gs(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function ao(e){a(e),process.exit(s.GENERAL_ERROR)}async function SA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function Bs(e,t){try{return JSON.parse(e)}catch{return ao(`${t} is not valid JSON.`)}}async function EA(e){if(e!=="-"&&!e.startsWith("@"))return Bs(e,"--items");let t=e==="-"?await SA():await $f(e.slice(1),"utf8");return Bs(t,"Items file")}async function PA(e){let t=Bs(await $f(e,"utf8"),"--file");return Array.isArray(t)?{items:t}:t&&typeof t=="object"?t:ao("--file must be a JSON object ({ kind, title, items, \u2026 }) or an items array.")}function Of(e,t){return e===void 0&&ao(`Missing ${t} \u2014 pass it or put it in the --file document.`),e}var AA=new oo("create").description("Create a quiz, flashcard set or cheat sheet from explicit items").option("--team-id <id>","Workspace ID").option("--file <path>","JSON request document (see the format below); a bare items array also works").option("--items <json>","Items only: inline JSON array, @<path>, or '-' for stdin").option("--kind <kind>",`One of ${Df.join(", ")}`).option("--title <text>","Study set title").option("--description <text>","Description shown with the set").option("--difficulty <level>",`One of ${RA.join(", ")}; defaults to 'mixed'`).option("--branding-id <id>","Brand UUID the set renders with").option("--source-presentation-id <id>","Presentation UUID this set was built for (provenance only)").option("--idempotency-key <key>","Stable retry key; generated when omitted").addHelpText("after",`
332
+ `);import{randomUUID as uA}from"crypto";import{Command as Bs}from"commander";import gA from"ora";function Fs(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.audioUrl??e.requestId??e.id);return}I(`Request ID: ${e.requestId||e.id}`),I(`Status: ${e.status}`),e.duration&&I(`Duration: ${e.duration}s`),e.audioUrl&&C(`Audio URL: ${e.audioUrl}`),e.error&&a(`Error: ${e.error}`)}var fA=new Bs("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{t=_(e)}catch(l){a(u(l)),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?Fu(e.request):{...e.duration?{duration:Number(e.duration)}:{},...e.durationSeconds?{duration_s:Number(e.durationSeconds)}:{},...e.narrationJson?{narration:Vs("--narration-json",e.narrationJson)}:{},...e.optionsJson?{options:Vs("--options-json",e.optionsJson)}:{},...e.schemaVersion?{schema_version:Number(e.schemaVersion)}:{},...e.text?{text:e.text}:{},...e.videoDescription?{video_description:e.videoDescription}:{},...e.visualEventJson?{visual_event:Vs("--visual-event-json",e.visualEventJson)}:{}}}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?gA("Generating sound effect for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??uA();try{let l=await Ic(n,{approvalReceipt:t,idempotencyKey:c});if(o=l.requestId||l.id,!e.wait){i?.stop(),Fs(l,r);return}let d=l.requestId||l.id;i&&(i.text=`Processing (ID: ${d})...`);let g=l.status==="completed"||l.status==="failed"?l:await $e(()=>jo(d),60,2e3);if(i?.stop(),g.status==="failed")throw new de(g.error||"Sound effects generation failed");if(e.output){if(!g.audioUrl)throw new Error("Sound effect completed without an audio URL");await Ie(g.audioUrl,e.output),r==="human"&&C(`Saved to: ${e.output}`)}Fs(g,r)}catch(l){i?.stop(),a(`${oe(l,o)}${Ee(l,c)}`,r),process.exit(s.GENERAL_ERROR)}});function Vs(e,t){try{return JSON.parse(t)}catch{throw new Error(`${e} must be valid JSON`)}}var hA=new Bs("status").description("Check status of a sound effects generation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{try{Fs(await jo(e),t.format)}catch(n){a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Of=new Bs("sfx").description("Video-aware sound effects generation commands").addCommand(fA).addCommand(hA);import{randomUUID as yA}from"crypto";import{readdir as bA,readFile as oo,stat as wA}from"fs/promises";import{join as Gs}from"path";import{Command as Sr}from"commander";function ao(e,t){a(`${t}: ${u(e)}`),process.exit(s.GENERAL_ERROR)}function $f(e){return`cli:skills:${e}:${yA()}`}async function vA(e){return e==="-"||e===void 0&&!process.stdin.isTTY?xA():(e===void 0&&(a("No SKILL.md given. Pass a path, @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)),oo(e.startsWith("@")?e.slice(1):e,"utf8"))}async function IA(e){let t=await oo(Gs(e,"SKILL.md"),"utf8").catch(o=>{throw new Error(`${e} is a directory but has no readable SKILL.md (${o.code??o})`)}),n=[],r=[],i=async o=>{let c=await bA(Gs(e,o||"."),{withFileTypes:!0});for(let l of c){if(l.name.startsWith("."))continue;let d=o?`${o}/${l.name}`:l.name;if(l.isDirectory()){await i(d);continue}if(!l.isFile()||l.name==="SKILL.md")continue;let g=await oo(Gs(e,d));if(g.includes(0))throw new Error(`${d} looks binary \u2014 skill assets are UTF-8 text only`);if(g.length===0){r.push(d);continue}n.push({content:g.toString("utf8"),path:d})}};return await i(""),r.length>0&&console.error(`warning: skipped ${r.length} empty file(s) \u2014 assets must have content: ${r.join(", ")}`),{assets:n,markdown:t}}async function kA(e){let t=e.indexOf("=");if(t<=0||t===e.length-1)throw new Error(`--asset expects "<remote/path>=<local/file>" \u2014 got "${e}"`);let n=e.slice(0,t).replaceAll("\\","/"),r=await oo(e.slice(t+1));if(r.includes(0))throw new Error(`${e.slice(t+1)} looks binary \u2014 UTF-8 only`);return{content:r.toString("utf8"),path:n}}async function xA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function RA(e,t){if(t==="true")return!0;if(t==="false")return!1;a(`${e} must be true or false`),process.exit(s.GENERAL_ERROR)}var CA=new Sr("list").description("List the skills available to the workspace, including its own disabled skills").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listSkills",{teamId:e.teamId}))}catch(t){ao(t,"Could not list skills")}}),SA=new Sr("show").description("Show one skill's metadata and SKILL.md body").argument("<slug>","Skill slug").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getSkill",{slug:e,teamId:t.teamId}))}catch(n){ao(n,"Could not read the skill")}}),EA=new Sr("create").description("Publish a SKILL.md or skill directory as a workspace-owned skill (admin/editor, team-skills flag)").argument("<file>","SKILL.md path, a skill directory (SKILL.md + bundled files), @<path>, or - for stdin").requiredOption("--slug <slug>","Skill slug \u2014 the $handle the agent uses").option("--asset <remote=local>","Bundle a file: remote path inside the skill = local file to read (repeatable)",(e,t)=>[...t,e],[]).option("--visibility <visibility>","team, private or personal (personal = visible only to you)").option("--enabled <bool>","true or false; defaults to keeping the current state (new skills start enabled)").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n={slug:t.slug,teamId:t.teamId},r=new Map,i=e?.startsWith("@")?e.slice(1):e;if(e!=="-"&&i&&(await wA(i).catch(()=>null))?.isDirectory()){let o=await IA(i);n.markdown=o.markdown;for(let c of o.assets)r.set(c.path,c)}else n.markdown=await vA(e);for(let o of t.asset){let c=await kA(o);r.set(c.path,c)}r.size>0&&(n.assets=[...r.values()]),t.visibility!==void 0&&(n.visibility=t.visibility),t.enabled!==void 0&&(n.enabled=RA("--enabled",t.enabled)),m(await p("upsertTeamSkill",n,t.idempotencyKey??$f("create")))}catch(n){ao(n,"Could not publish the skill")}}),PA=new Sr("delete").description("Delete a workspace-owned skill (admin/editor, team-skills flag)").argument("<slug>","Skill slug").option("--idempotency-key <key>","Stable retry key; generated when omitted").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("deleteTeamSkill",{slug:e,teamId:t.teamId},t.idempotencyKey??$f("delete")))}catch(n){ao(n,"Could not delete the skill")}}),Df=new Sr("skills").description("Manage the workspace's team skills").addCommand(CA).addCommand(SA).addCommand(EA).addCommand(PA);import{randomUUID as AA}from"crypto";import{readFile as Lf}from"fs/promises";import{Command as so}from"commander";var Uf=["quiz","flashcards","cheat-sheet"],TA=["beginner","intermediate","advanced","mixed"];function OA(){return`cli:study-set:create:${AA()}`}function Ws(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function co(e){a(e),process.exit(s.GENERAL_ERROR)}async function $A(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function Ks(e,t){try{return JSON.parse(e)}catch{return co(`${t} is not valid JSON.`)}}async function DA(e){if(e!=="-"&&!e.startsWith("@"))return Ks(e,"--items");let t=e==="-"?await $A():await Lf(e.slice(1),"utf8");return Ks(t,"Items file")}async function NA(e){let t=Ks(await Lf(e,"utf8"),"--file");return Array.isArray(t)?{items:t}:t&&typeof t=="object"?t:co("--file must be a JSON object ({ kind, title, items, \u2026 }) or an items array.")}function Nf(e,t){return e===void 0&&co(`Missing ${t} \u2014 pass it or put it in the --file document.`),e}var LA=new so("create").description("Create a quiz, flashcard set or cheat sheet from explicit items").option("--team-id <id>","Workspace ID").option("--file <path>","JSON request document (see the format below); a bare items array also works").option("--items <json>","Items only: inline JSON array, @<path>, or '-' for stdin").option("--kind <kind>",`One of ${Uf.join(", ")}`).option("--title <text>","Study set title").option("--description <text>","Description shown with the set").option("--difficulty <level>",`One of ${TA.join(", ")}; defaults to 'mixed'`).option("--branding-id <id>","Brand UUID the set renders with").option("--source-presentation-id <id>","Presentation UUID this set was built for (provenance only)").option("--idempotency-key <key>","Stable retry key; generated when omitted").addHelpText("after",`
316
333
  The --file document:
317
334
 
318
335
  {
@@ -339,14 +356,14 @@ The --file document:
339
356
  Item shapes follow --kind: quiz items carry question/options/answerIndex,
340
357
  flashcards carry front/back, cheat-sheet items carry term/definition(/group).
341
358
  Every created item gets a stable id back \u2014 the itemId a video "question"
342
- interaction references.`).action(async e=>{try{let t=e.file?await PA(e.file):{},n=e.items!==void 0?await EA(e.items):t.items;Array.isArray(n)||ao("No items. Pass --items, or a --file document carrying them.");let r=e.kind??t.kind,i=e.title??t.title;m(await p("createStudySet",{brandingId:e.brandingId??t.brandingId,description:e.description??t.description,difficulty:e.difficulty??t.difficulty,items:n,kind:Of(r,"--kind"),sourcePresentationId:e.sourcePresentationId??t.sourcePresentationId,teamId:e.teamId,title:Of(i,"--title")},e.idempotencyKey??CA()))}catch(t){Gs(t,"Could not create the study set")}}),TA=new oo("list").description("List the workspace's study sets, newest first").option("--team-id <id>","Workspace ID").option("--kind <kind>",`Filter to one of ${Df.join(", ")}`).option("--limit <n>","Maximum sets to return (default 50)").option("--cursor <cursor>","Cursor from a previous list's nextCursor for the next page").action(async e=>{try{m(await p("listStudySets",{cursor:e.cursor,kind:e.kind,limit:e.limit?Number(e.limit):void 0,teamId:e.teamId}))}catch(t){Gs(t,"Could not list study sets")}}),OA=new oo("get").description("Read a study set with its full items and their ids").argument("<study-set-id>","Study set id").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getStudySet",{studySetId:e,teamId:t.teamId}))}catch(n){Gs(n,"Could not read the study set")}}),Nf=new oo("study-set").description("Create and read quizzes, flashcards and cheat sheets").addCommand(AA).addCommand(TA).addCommand(OA);import{randomUUID as _f}from"crypto";import{readFile as UA}from"fs/promises";import{Command as Ks}from"commander";import{existsSync as $A,readFileSync as DA,statSync as NA}from"fs";import{basename as LA}from"path";var ct=class extends Error{constructor(n,r){super(n);this.code=r;this.name="SupportAttachmentError"}code};async function Lf(e,t){let n=await fetch(`${K()}${e}`,{body:JSON.stringify(t),headers:{"Content-Type":"application/json",...await fe()},method:"POST"}),r=await n.text().catch(()=>"");if(!n.ok){let i=mt(r,n.status);throw new ct(i.message,i.code)}try{return r?JSON.parse(r):null}catch{throw new ct("The attachment request returned an invalid response.","support_attachment_invalid_response")}}async function Uf(e,t){if(!$A(e))throw new ct(`No such file: ${e}`,"support_attachment_missing_file");let n=NA(e);if(!n.isFile()||n.size<=0)throw new ct(`Not a readable file with content: ${e}`,"support_attachment_missing_file");let r=LA(e),i=await Lf("/api/support/attachments/presign",{fileName:r,mediaType:gn(e),requestUuid:t.requestUuid,size:n.size,...t.teamId?{teamId:t.teamId}:{}}),o=new FormData;for(let[d,g]of Object.entries(i.upload.fields))o.append(d,g);o.append("file",new Blob([DA(e)],{type:i.mediaType}),r);let c=await fetch(i.upload.url,{body:o,method:"POST"});if(!c.ok)throw new ct(`Storage refused the upload of ${r} (${c.status}).`,"support_attachment_upload_failed");let l=await Lf("/api/support/attachments/confirm",{key:i.attachmentKey,originalName:r,...t.teamId?{teamId:t.teamId}:{}});return{bytes:l.attachment.bytes,key:l.attachmentKey,mediaType:l.attachment.mediaType,name:l.attachment.name}}var _A=["received","looking_into_it","planned","in_progress","fixed_awaiting_release","shipped","not_planned","needs_input","resolved"];async function jA(e){if(e!==void 0&&e!=="-"&&!e.startsWith("@"))return e;if(e?.startsWith("@"))return UA(e.slice(1),"utf8");if(e==="-"||!process.stdin.isTTY)return qA();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 qA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function MA(e){if(e===void 0)return{};let t;try{t=JSON.parse(e)}catch(n){a(`--context must be a JSON object: ${u(n)}`),process.exit(s.GENERAL_ERROR)}return(t===null||typeof t!="object"||Array.isArray(t))&&(a("--context must be a JSON object."),process.exit(s.GENERAL_ERROR)),t}function VA(e,t){return[...t,e]}async function FA(e,t){let n=[];for(let r of e)try{let i=await Uf(r,t);n.push(i.key)}catch(i){throw i instanceof ct&&(a(`${r}: ${i.message}`),process.exit(s.GENERAL_ERROR)),i}return n}function jf(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var BA=new Ks("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)",VA,[]).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(e,t)=>{try{let n=MA(t.context),r=_f(),i=await FA(t.attach??[],{requestUuid:r,teamId:t.teamId});m(await p("submitSupportRequest",{attachmentKeys:i.length>0?i:void 0,context:Object.keys(n).length>0?n:void 0,screenshotUrl:t.screenshotUrl,source:t.source,teamId:t.teamId,text:await jA(e)},t.idempotencyKey??`cli:support:report:${_f()}`))}catch(n){jf(n,"Could not file the report")}}),GA=new Ks("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 ${_A.join(", ")}`).option("--limit <n>","Maximum items to return (default 50)").action(async e=>{try{m(await p("listSupportRequests",{limit:e.limit?Number(e.limit):void 0,mine:e.mine?!0:void 0,status:e.status,teamId:e.teamId}))}catch(t){jf(t,"Could not list support requests")}}),qf=new Ks("support").description("File a report and follow what became of it").addCommand(BA).addCommand(GA);import Sr from"chalk";import{Command as KA}from"commander";var Mf=new KA("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)",b("--format",["table","json"]),"table").option("--limit <n>","Maximum templates to list","25").action(async(e,t)=>{await w();try{let n=Number.parseInt(t.limit??"25",10),{templates:r}=await sc(e,Number.isFinite(n)?n:25);if(r.length===0){t.format==="json"?console.log(JSON.stringify([])):I("No templates found");return}if(t.format==="json"){console.log(JSON.stringify(r,null,2));return}for(let i of r){let o=[i.isDefault?Sr.green("default"):null,i.category??null,i.recommendedModes?.length?`modes: ${i.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${Sr.bold(i.name)} ${Sr.gray(i.id)}${o?`
343
- ${Sr.gray(o)}`:""}`)}console.log(),console.log(Sr.gray(`Use one with: ${f.commands[0]} create "<topic>" --template <id>`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}});import{randomUUID as Ws}from"crypto";import{Command as xt}from"commander";function Ht(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function WA(e,t){try{let n=JSON.parse(t);if(!Array.isArray(n)||n.length===0)throw new Error("not a non-empty array");return n}catch{a(`${e} must be a non-empty JSON array, e.g. ${e} '[{"prompt":"Research X"}]'`),process.exit(s.GENERAL_ERROR)}}var JA=new xt("create").description("Spawn child chat threads that each run as their own durable turn").argument("<parent-chat-id>","Chat the threads hang under").requiredOption("--threads <json>",'JSON array of thread specs, e.g. [{"prompt":"\u2026","title":"\u2026"}]').option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ws()).action(async(e,t)=>{try{m(await p("createThreads",{parentChatId:e,teamId:t.teamId,threads:WA("--threads",t.threads)},t.idempotencyKey))}catch(n){Ht(n,"Thread creation failed")}}),zA=new xt("list").description("List the child threads under a parent chat").argument("<parent-chat-id>","Chat whose direct children to list").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("listThreads",{parentChatId:e,teamId:t.teamId}))}catch(n){Ht(n,"Thread listing failed")}}),HA=new xt("get").description("Read one thread's status, run id, and settled result").argument("<chat-id>","Child thread id, from thread create or thread list").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getThread",{chatId:e,teamId:t.teamId}))}catch(n){Ht(n,"Thread read failed")}}),XA=new xt("messages").description("Read a thread's transcript, newest page first").argument("<chat-id>","Child thread id, from thread create or thread list").option("--before <iso>","Return messages older than this ISO timestamp").option("--limit <n>","Page size (default 10, max 50)",Number).option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getThreadMessages",{before:t.before,chatId:e,limit:t.limit,teamId:t.teamId}))}catch(n){Ht(n,"Thread transcript read failed")}}),YA=new xt("send").description("Send a message into a thread \u2014 steers a running turn, queues it, or starts a new turn").argument("<chat-id>","Child thread id, from thread create or thread list").requiredOption("--text <text>","Message text").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ws()).action(async(e,t)=>{try{m(await p("sendThreadMessage",{chatId:e,teamId:t.teamId,text:t.text},t.idempotencyKey))}catch(n){Ht(n,"Thread message failed")}}),QA=new xt("wait").description("Wait until threads reach a terminal state").requiredOption("--chat-ids <ids>","Comma-separated thread ids",e=>e.split(",").map(t=>t.trim()).filter(Boolean)).option("--timeout-seconds <n>","Max seconds to wait (default 60, max 300)",Number).option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("waitThreads",{chatIds:e.chatIds,teamId:e.teamId,timeoutSeconds:e.timeoutSeconds}))}catch(t){Ht(t,"Thread wait failed")}}),ZA=new xt("stop").description("Stop a running thread").argument("<chat-id>","Child thread id, from thread create or thread list").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",Ws()).action(async(e,t)=>{try{m(await p("stopThread",{chatId:e,teamId:t.teamId},t.idempotencyKey))}catch(n){Ht(n,"Thread stop failed")}}),Vf=new xt("thread").description("Spawned chat threads \u2014 Devin-style child sessions").addCommand(JA).addCommand(zA).addCommand(HA).addCommand(XA).addCommand(YA).addCommand(QA).addCommand(ZA);import{randomUUID as eT}from"crypto";import{writeFile as tT}from"fs/promises";import{Command as nT}from"commander";import rT from"ora";var Ff=new nT("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format,r=n==="human"?rT("Fetching transcript...").start():null;try{let i=await p("getYoutubeTranscript",{language:t.language,reason:t.reason,teamId:t.teamId,url:e},t.idempotencyKey??eT());r?.stop();let o=t.timestamps?i.cues.map(c=>`[${c.timestamp}] ${c.text}`).join(`
359
+ interaction references.`).action(async e=>{try{let t=e.file?await NA(e.file):{},n=e.items!==void 0?await DA(e.items):t.items;Array.isArray(n)||co("No items. Pass --items, or a --file document carrying them.");let r=e.kind??t.kind,i=e.title??t.title;m(await p("createStudySet",{brandingId:e.brandingId??t.brandingId,description:e.description??t.description,difficulty:e.difficulty??t.difficulty,items:n,kind:Nf(r,"--kind"),sourcePresentationId:e.sourcePresentationId??t.sourcePresentationId,teamId:e.teamId,title:Nf(i,"--title")},e.idempotencyKey??OA()))}catch(t){Ws(t,"Could not create the study set")}}),UA=new so("list").description("List the workspace's study sets, newest first").option("--team-id <id>","Workspace ID").option("--kind <kind>",`Filter to one of ${Uf.join(", ")}`).option("--limit <n>","Maximum sets to return (default 50)").option("--cursor <cursor>","Cursor from a previous list's nextCursor for the next page").action(async e=>{try{m(await p("listStudySets",{cursor:e.cursor,kind:e.kind,limit:e.limit?Number(e.limit):void 0,teamId:e.teamId}))}catch(t){Ws(t,"Could not list study sets")}}),_A=new so("get").description("Read a study set with its full items and their ids").argument("<study-set-id>","Study set id").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getStudySet",{studySetId:e,teamId:t.teamId}))}catch(n){Ws(n,"Could not read the study set")}}),_f=new so("study-set").description("Create and read quizzes, flashcards and cheat sheets").addCommand(LA).addCommand(UA).addCommand(_A);import{randomUUID as Mf}from"crypto";import{readFile as FA}from"fs/promises";import{Command as Js}from"commander";import{existsSync as jA,readFileSync as qA,statSync as MA}from"fs";import{basename as VA}from"path";var ct=class extends Error{constructor(n,r){super(n);this.code=r;this.name="SupportAttachmentError"}code};async function jf(e,t){let n=await fetch(`${K()}${e}`,{body:JSON.stringify(t),headers:{"Content-Type":"application/json",...await fe()},method:"POST"}),r=await n.text().catch(()=>"");if(!n.ok){let i=mt(r,n.status);throw new ct(i.message,i.code)}try{return r?JSON.parse(r):null}catch{throw new ct("The attachment request returned an invalid response.","support_attachment_invalid_response")}}async function qf(e,t){if(!jA(e))throw new ct(`No such file: ${e}`,"support_attachment_missing_file");let n=MA(e);if(!n.isFile()||n.size<=0)throw new ct(`Not a readable file with content: ${e}`,"support_attachment_missing_file");let r=VA(e),i=await jf("/api/support/attachments/presign",{fileName:r,mediaType:gn(e),requestUuid:t.requestUuid,size:n.size,...t.teamId?{teamId:t.teamId}:{}}),o=new FormData;for(let[d,g]of Object.entries(i.upload.fields))o.append(d,g);o.append("file",new Blob([qA(e)],{type:i.mediaType}),r);let c=await fetch(i.upload.url,{body:o,method:"POST"});if(!c.ok)throw new ct(`Storage refused the upload of ${r} (${c.status}).`,"support_attachment_upload_failed");let l=await jf("/api/support/attachments/confirm",{key:i.attachmentKey,originalName:r,...t.teamId?{teamId:t.teamId}:{}});return{bytes:l.attachment.bytes,key:l.attachmentKey,mediaType:l.attachment.mediaType,name:l.attachment.name}}var BA=["received","looking_into_it","planned","in_progress","fixed_awaiting_release","shipped","not_planned","needs_input","resolved"];async function GA(e){if(e!==void 0&&e!=="-"&&!e.startsWith("@"))return e;if(e?.startsWith("@"))return FA(e.slice(1),"utf8");if(e==="-"||!process.stdin.isTTY)return KA();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 KA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function WA(e){if(e===void 0)return{};let t;try{t=JSON.parse(e)}catch(n){a(`--context must be a JSON object: ${u(n)}`),process.exit(s.GENERAL_ERROR)}return(t===null||typeof t!="object"||Array.isArray(t))&&(a("--context must be a JSON object."),process.exit(s.GENERAL_ERROR)),t}function JA(e,t){return[...t,e]}async function zA(e,t){let n=[];for(let r of e)try{let i=await qf(r,t);n.push(i.key)}catch(i){throw i instanceof ct&&(a(`${r}: ${i.message}`),process.exit(s.GENERAL_ERROR)),i}return n}function Vf(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var HA=new Js("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)",JA,[]).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(e,t)=>{try{let n=WA(t.context),r=Mf(),i=await zA(t.attach??[],{requestUuid:r,teamId:t.teamId});m(await p("submitSupportRequest",{attachmentKeys:i.length>0?i:void 0,context:Object.keys(n).length>0?n:void 0,screenshotUrl:t.screenshotUrl,source:t.source,teamId:t.teamId,text:await GA(e)},t.idempotencyKey??`cli:support:report:${Mf()}`))}catch(n){Vf(n,"Could not file the report")}}),XA=new Js("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 ${BA.join(", ")}`).option("--limit <n>","Maximum items to return (default 50)").action(async e=>{try{m(await p("listSupportRequests",{limit:e.limit?Number(e.limit):void 0,mine:e.mine?!0:void 0,status:e.status,teamId:e.teamId}))}catch(t){Vf(t,"Could not list support requests")}}),Ff=new Js("support").description("File a report and follow what became of it").addCommand(HA).addCommand(XA);import Er from"chalk";import{Command as YA}from"commander";var Bf=new YA("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)",b("--format",["table","json"]),"table").option("--limit <n>","Maximum templates to list","25").action(async(e,t)=>{await w();try{let n=Number.parseInt(t.limit??"25",10),{templates:r}=await cc(e,Number.isFinite(n)?n:25);if(r.length===0){t.format==="json"?console.log(JSON.stringify([])):I("No templates found");return}if(t.format==="json"){console.log(JSON.stringify(r,null,2));return}for(let i of r){let o=[i.isDefault?Er.green("default"):null,i.category??null,i.recommendedModes?.length?`modes: ${i.recommendedModes.join("/")}`:null].filter(Boolean).join(" \xB7 ");console.log(`${Er.bold(i.name)} ${Er.gray(i.id)}${o?`
360
+ ${Er.gray(o)}`:""}`)}console.log(),console.log(Er.gray(`Use one with: ${f.commands[0]} create "<topic>" --template <id>`))}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}});import{randomUUID as zs}from"crypto";import{Command as xt}from"commander";function Ht(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function QA(e,t){try{let n=JSON.parse(t);if(!Array.isArray(n)||n.length===0)throw new Error("not a non-empty array");return n}catch{a(`${e} must be a non-empty JSON array, e.g. ${e} '[{"prompt":"Research X"}]'`),process.exit(s.GENERAL_ERROR)}}var ZA=new xt("create").description("Spawn child chat threads that each run as their own durable turn").argument("<parent-chat-id>","Chat the threads hang under").requiredOption("--threads <json>",'JSON array of thread specs, e.g. [{"prompt":"\u2026","title":"\u2026"}]').option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",zs()).action(async(e,t)=>{try{m(await p("createThreads",{parentChatId:e,teamId:t.teamId,threads:QA("--threads",t.threads)},t.idempotencyKey))}catch(n){Ht(n,"Thread creation failed")}}),eT=new xt("list").description("List the child threads under a parent chat").argument("<parent-chat-id>","Chat whose direct children to list").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("listThreads",{parentChatId:e,teamId:t.teamId}))}catch(n){Ht(n,"Thread listing failed")}}),tT=new xt("get").description("Read one thread's status, run id, and settled result").argument("<chat-id>","Child thread id, from thread create or thread list").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getThread",{chatId:e,teamId:t.teamId}))}catch(n){Ht(n,"Thread read failed")}}),nT=new xt("messages").description("Read a thread's transcript, newest page first").argument("<chat-id>","Child thread id, from thread create or thread list").option("--before <iso>","Return messages older than this ISO timestamp").option("--limit <n>","Page size (default 10, max 50)",Number).option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getThreadMessages",{before:t.before,chatId:e,limit:t.limit,teamId:t.teamId}))}catch(n){Ht(n,"Thread transcript read failed")}}),rT=new xt("send").description("Send a message into a thread \u2014 steers a running turn, queues it, or starts a new turn").argument("<chat-id>","Child thread id, from thread create or thread list").requiredOption("--text <text>","Message text").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",zs()).action(async(e,t)=>{try{m(await p("sendThreadMessage",{chatId:e,teamId:t.teamId,text:t.text},t.idempotencyKey))}catch(n){Ht(n,"Thread message failed")}}),iT=new xt("wait").description("Wait until threads reach a terminal state").requiredOption("--chat-ids <ids>","Comma-separated thread ids",e=>e.split(",").map(t=>t.trim()).filter(Boolean)).option("--timeout-seconds <n>","Max seconds to wait (default 60, max 300)",Number).option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("waitThreads",{chatIds:e.chatIds,teamId:e.teamId,timeoutSeconds:e.timeoutSeconds}))}catch(t){Ht(t,"Thread wait failed")}}),oT=new xt("stop").description("Stop a running thread").argument("<chat-id>","Child thread id, from thread create or thread list").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable retry key",zs()).action(async(e,t)=>{try{m(await p("stopThread",{chatId:e,teamId:t.teamId},t.idempotencyKey))}catch(n){Ht(n,"Thread stop failed")}}),Gf=new xt("thread").description("Spawned chat threads \u2014 Devin-style child sessions").addCommand(ZA).addCommand(eT).addCommand(tT).addCommand(nT).addCommand(rT).addCommand(iT).addCommand(oT);import{randomUUID as aT}from"crypto";import{writeFile as sT}from"fs/promises";import{Command as dT}from"commander";import cT from"ora";var Kf=new dT("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let n=t.format,r=n==="human"?cT("Fetching transcript...").start():null;try{let i=await p("getYoutubeTranscript",{language:t.language,reason:t.reason,teamId:t.teamId,url:e},t.idempotencyKey??aT());r?.stop();let o=t.timestamps?i.cues.map(c=>`[${c.timestamp}] ${c.text}`).join(`
344
361
  `):i.cues.map(c=>c.text).join(`
345
- `);if(t.output&&(await tT(t.output,o,"utf-8"),n==="human"&&C(`Transcript saved to: ${t.output}`)),n==="json"){m(i);return}if(n==="quiet"){console.log(o);return}console.log(),console.log(`Title: ${i.title}`),i.channelName&&console.log(`Channel: ${i.channelName}`),i.durationFormatted&&console.log(`Duration: ${i.durationFormatted}`),console.log(`Language: ${i.language??"unknown"}${i.isAutoGenerated?" (auto-generated)":""}`),console.log(`Words: ${i.wordCount.toLocaleString()}`),console.log(`URL: ${i.url}`),i.truncated&&q("Transcript was truncated to fit the response budget."),t.output||(console.log(),console.log("--- Transcript ---"),console.log(o))}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as iT}from"crypto";import{mkdir as oT,writeFile as Bf}from"fs/promises";import{dirname as aT}from"path";import{Command as so}from"commander";import Gf from"ora";var sT=new so("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("--purpose <purpose>","What this take is for, stamped on the credit ledger row",b("--purpose",["narration","pronunciation-preview","voice-take","listen","clone-audition","manual"])).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.idempotencyKey??iT(),n;try{n=_(e)}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?Gf("Generating speech...").start():null,o;e.speed&&(o=parseFloat(e.speed),(Number.isNaN(o)||o<.1||o>4)&&(i?.stop(),a("Speed must be between 0.1 and 4.0"),process.exit(s.INVALID_INPUT)));let c;try{let l=e.optionsJson?dT("--options-json",e.optionsJson):{},d=await pc({text:e.text,...e.brandId!==void 0?{brandId:e.brandId}:{},...e.purpose!==void 0?{purpose:e.purpose}:{},options:{...l,language:e.lang,voiceId:e.voiceId,speed:o}},{approvalReceipt:n,idempotencyKey:t});c=d.requestId,i?.stop();let g=e.output.endsWith(`.${d.format}`)?e.output:`${e.output}.${d.format}`;await oT(aT(g),{recursive:!0}),await Bf(g,d.audioData);let y=g.replace(/\.[^.]+$/,".txt");if(await Bf(y,e.text,"utf-8"),r==="json"){m({status:"completed",requestId:d.requestId,output:g,audioUrl:d.audioUrl,duration:d.duration,format:d.format,speed:d.speed??o??1,lang:d.language??e.lang??null,langApplied:d.langApplied??!1,timestamps:d.timestamps??null,words:d.wordTimings??null});return}if(r==="quiet"){console.log(g);return}C(`Saved to: ${g}`),I(`Duration: ${d.duration.toFixed(2)}s`)}catch(l){i?.stop(),a(`${oe(l,c)}${Ee(l,t)}`,r),process.exit(s.GENERAL_ERROR)}});function dT(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 cT=new so("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json",b("--format",["human","json"]),"human").action(async e=>{let t=e.format==="human"?Gf("Fetching voices...").start():null;try{let n=await gc(e.provider);if(t?.stop(),e.format==="json"){m(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 i of n.voices)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}else for(let[r,i]of Object.entries(n.voices))if(!(!i||i.length===0)){console.log(),console.log(`${r.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let o of i)console.log(` ${o.name} (${o.id})`),console.log(` ${o.description}`)}}catch(n){t?.stop(),a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),lT=new so("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json",b("--format",["json"]),"json").action(async(e,t)=>{try{m(await R("generateSpeech",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),Kf=new so("tts").description("Text-to-speech commands").addCommand(sT).addCommand(cT).addCommand(lT);import{execSync as mo,spawnSync as LT}from"child_process";import{createHash as UT}from"crypto";import{access as Ys,readFile as _T,rm as ih}from"fs/promises";import{resolve as Er}from"path";import Re from"chalk";import{Command as Ce}from"commander";import jT from"ffmpeg-static";import oh from"ora";import{Command as Js}from"commander";var mT=new Js("list").description("List ready editable video templates").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listVideoTemplates",{teamId:e.teamId}))}catch(t){a(u(t,"Video templates could not be loaded")),process.exit(s.GENERAL_ERROR)}}),pT=new Js("create").description("Copy a pinned template into an editable Studio draft").requiredOption("--template-id <id>","Template ID from the catalog").requiredOption("--template-version <number>","Pinned template version").requiredOption("--idempotency-key <key>","Stable key for retrying the same pick").option("--title <text>","Draft title").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("createVideoFromTemplate",{templateId:e.templateId,version:Number(e.templateVersion),title:e.title,teamId:e.teamId},e.idempotencyKey))}catch(t){a(u(t,"Video template could not be opened")),process.exit(s.GENERAL_ERROR)}}),Wf=new Js("templates").description("Browse ready stock videos and copy them into Studio").addCommand(mT).addCommand(pT);import{randomUUID as uT}from"crypto";import{Command as gT}from"commander";var zs=["private","team","public"],Jf=new gT("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: ${zs.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(e,t,n)=>{zs.includes(t)||(a(`Invalid visibility "${t}". Expected one of: ${zs.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("setVideoVisibility",{teamId:n.teamId,videoId:e,visibility:t},n.idempotencyKey??uT());if(n.json){m(r);return}r.shareUrl?C(`Video is now ${r.visibility}: ${r.shareUrl}`):C(`Video is now ${r.visibility} (no public link).`)}catch(r){a(u(r,"Visibility update failed")),process.exit(s.GENERAL_ERROR)}});import{Command as fT}from"commander";var zf=new fT("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(i=>i!==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 i=Number(t.atSeconds);(!Number.isFinite(i)||i<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),r.atSeconds=i}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 i=await U(t.teamId),o=await p("setVideoThumbnail",r,Q({command:"video thumbnail set",payload:r,workspaceId:i}));m(o),C(`Poster set from ${o.source}.`)}catch(i){a(u(i,"Setting the poster failed")),process.exit(s.GENERAL_ERROR)}});import{mkdir as hT}from"fs/promises";import{join as yT}from"path";import{Command as Xt}from"commander";import Xf from"ora";var bT=5e3,wT=120,Hf=5;function Yf(e,t){return[...t,e]}function vT(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 co(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 IT(e){if(e.mode&&!["speed","precision"].includes(e.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:vT(e.audioUrl,"Audio URL"),...e.mode?{mode:e.mode}:{},sourceVideoId:co(e.sourceVideoId)}}function kT(e){let t=[],n=new Set;for(let i of e.targetLanguage){let o=i.trim(),c=o.toLocaleLowerCase("en-US");!o||n.has(c)||(n.add(c),t.push(o))}if(t.length===0)throw new Error("Provide at least one target language");if(t.length>Hf)throw new Error(`Provide at most ${Hf} target languages`);if(t.find(i=>i.length<2||i.length>40))throw new Error("Target languages must be between 2 and 40 characters");return{...e.captions?{captions:!0}:{},sourceVideoId:co(e.sourceVideoId),targetLanguages:t}}function xT(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:co(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:co(e.sourceVideoId),...e.title?{title:e.title}:{}}}function RT(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 lo(e){return{requestId:e.runId,status:RT(e),...e.entity?.url?{videoUrl:e.entity.url}:{},...e.output?{output:e.output}:{},...e.error?{error:ge(e.error)}:{}}}function Hs(e){return{requestId:e.runId,status:"pending"}}async function Xs(e,t){return $e(async()=>lo(await R(e,t)),wT,bT)}function lt(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.videoUrl&&C(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}function CT(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 ST(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function ET(e,t){let n=ST(e);if(!t.has(n))return t.add(n),n;let r=n.slice(0,-4),i=2;for(;t.has(`${r}-${i}.mp4`);)i+=1;let o=`${r}-${i}.mp4`;return t.add(o),o}async function PT(e,t){let n=CT(e.output).filter(o=>o.status==="completed"&&!!o.videoUrl);if(n.length===0)throw new Error("Video translation completed without downloadable results");await hT(t,{recursive:!0});let r=[],i=new Set;for(let o of n){let c=yT(t,ET(o.language,i));await Ie(o.videoUrl,c),r.push({language:o.language,path:c})}return r}var AT=new Xt("status").description("Check a video lip-sync request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let r=k(this,t).format??"human";try{lt(lo(await R("lipsyncVideo",e)),r)}catch(i){a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),Qf=new Xt("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Xf("Starting video lip-sync...").start():null,n;try{let r=await kc(IT(e),e.idempotencyKey,_(e));if(n=r.runId,!e.wait){t?.stop(),lt(Hs(r),e.format);return}t&&(t.text="Waiting for video lip-sync...");let i=await Xs("lipsyncVideo",r.runId);if(i.status==="failed")throw new de(i.error??"Video lip-sync failed");if(!i.videoUrl)throw new Error("Video lip-sync completed without a video URL");t&&(t.text="Downloading lip-synced video..."),await Ie(i.videoUrl,e.output),t?.stop(),lt(i,e.format),e.format==="human"&&C(`Saved to: ${e.output}`)}catch(r){t?.stop(),a(oe(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(AT)),Zf=new Xt("translate-languages").description("List supported video translation target languages").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await Rc();if(e.format==="json")m({languages:t});else for(let n of t)console.log(n)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),TT=new Xt("status").description("Check a video translation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let r=k(this,t).format??"human";try{lt(lo(await R("translateVideo",e)),r)}catch(i){a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),eh=new Xt("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)",Yf,[]).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Xf("Starting video translation...").start():null,n;try{let r=await Cc(kT(e),e.idempotencyKey,_(e));if(n=r.runId,!e.wait){t?.stop(),lt(Hs(r),e.format);return}t&&(t.text="Waiting for video translations...");let i=await Xs("translateVideo",r.runId);if(i.status==="failed")throw new de(i.error??"Video translation failed");t&&(t.text="Downloading translated videos...");let o=await PT(i,e.outputDir);if(t?.stop(),e.format==="json")m({...i,downloads:o});else if(e.format==="quiet")for(let c of o)console.log(c.path);else{lt(i,e.format);for(let c of o)C(`${c.language}: ${c.path}`)}}catch(r){t?.stop(),a(oe(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(TT)),OT=new Xt("status").description("Check a video clipping request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let n=k(this,t);try{lt(lo(await R("clipVideo",e)),n.format??"human")}catch(r){a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),th=new Xt("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",Yf,[]).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{let n=await xc(xT(e),e.idempotencyKey,_(e));if(t=n.runId,!e.wait)return lt(Hs(n),e.format);let r=await Xs("clipVideo",n.runId);if(r.status==="failed")throw new de(r.error??"Video clipping failed");lt(r,e.format)}catch(n){a(oe(n,t),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(OT));import{Command as $T}from"commander";function DT(e){return e===null?"\u2014":`${Math.round(e*100)}%`}function nh(e){return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function NT(e){return e.viewer?e.viewer.name??e.viewer.email??e.viewer.id:"Anonymous"}var rh=new $T("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(e,t)=>{try{let n=await p("getVideoViewAnalytics",{cursor:t.cursor,teamId:t.teamId,videoId:e});if(t.json){m(n);return}console.log(`${n.views} view${n.views===1?"":"s"} \xB7 ${n.completions} watched to the end \xB7 ${DT(n.averageCompletionRate)} average depth`),console.log(`${n.signedInViewers} signed-in viewer${n.signedInViewers===1?"":"s"} \xB7 ${nh(n.averageWatchedSeconds)} average watch time`);for(let r of n.sessions)console.log(` ${r.completed?"\u2713":"\xB7"} ${NT(r)} \u2014 ${nh(r.furthestSeconds)} reached, last seen ${r.lastViewedAt}`);n.nextCursor&&console.log(`More sittings \u2014 rerun with --cursor ${n.nextCursor}`)}catch(n){a(u(n,"View analytics read failed")),process.exit(s.GENERAL_ERROR)}});async function qT(){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 MT(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}var VT=new Ce("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let{maxResults:n,orientation:r,license:i,format:o}=t,c=o==="human"?oh("Finding videos...").start():null;try{let l=await bc({query:e,options:{maxResults:parseInt(n,10),orientation:r,license:i,sources:MT(t.source)}});c?.stop();let d=l.data.results.flatMap(g=>g.results);if(o==="json"){m(l);return}if(o==="quiet"){d.forEach(g=>{console.log(g.embedUrl||g.previewUrl||g.thumbnailUrl)});return}if(d.length===0){I("No videos found");return}C(`Found ${d.length} videos for "${e}"`),console.log(),d.forEach((g,y)=>{let v=g.kind==="embed";console.log(`[${y+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(l){c?.stop(),a(u(l,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),FT=new Ce("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{m(await Sc({quality:e.release?"release":void 0,sourceVideoId:e.sourceVideo,storyboardRevisionId:e.storyboardRevision,teamId:e.teamId},e.approvalReceipt,e.idempotencyKey))}catch(t){a(u(t,"Generation failed")),process.exit(s.GENERAL_ERROR)}});async function ah(e){let t=e==="-"?await qT():await _T(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 sh(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 i=Xe(r.handle),o=Xe(r.path),c=Xe(r.fileUrl)??Xe(r.url),l=Xe(r.purpose),d=Xe(r.videoRole),g=Xe(r.analysisId)??Xe(r.analysis);if(!i||!o&&!c||!l)throw new Error("Invalid --media binding. handle, purpose, and either path or url are required strings.");if(o&&c)throw new Error("A media binding cannot contain both path and url.");if(o&&l==="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(o&&!t.uploadIdempotencyKey)throw new Error("Local storyboard media requires the command idempotency key.");let y=o?await ie(Er(o),{idempotencyKey:`${t.uploadIdempotencyKey}:media:${i}`}):{name:Xe(r.name),size:Number(r.size),type:Xe(r.mime),url:c};if(!y.name||!y.type||!y.url||!Number.isSafeInteger(y.size)||y.size<=0)throw new Error(`URL media binding "${n}" requires name, mime, and positive integer size.`);let v=y.type.startsWith("video/")?"video":y.type.startsWith("audio/")?"audio":y.type.startsWith("image/")?"image":null;if(!v)throw new Error(`Unsupported media type for ${o??c}: ${y.type}`);if(!["source","style","identity","required"].includes(l))throw new Error(`Invalid media purpose: ${l}`);if(d&&!["reference","first-frame","last-frame"].includes(d))throw new Error(`Invalid videoRole: ${d}`);if(d&&v!=="image")throw new Error("videoRole is supported only for image bindings.");return{...g?{analysisId:g}:{},fileUrl:y.url,handle:i,kind:v,mime:y.type,name:y.name,purpose:l,size:y.size,...d?{videoRole:d}:{}}}))}function Xe(e){return typeof e=="string"&&e.length>0?e:void 0}var BT=new Ce("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{m(await p("createVideoStoryboard",{aspectRatio:e.aspect,durationSec:Number(e.duration),mediaBindings:await sh(e.media,{uploadIdempotencyKey:e.idempotencyKey}),storyboardMarkdown:await ah(e.file),teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(t){a(u(t,"Storyboard creation failed")),process.exit(s.GENERAL_ERROR)}}),GT=new Ce("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{m(await p("reviseVideoStoryboard",{aspectRatio:t.aspect,baseRevisionId:t.baseRevision,changeSummary:t.changeSummary,durationSec:Number(t.duration),mediaBindings:await sh(t.media,{uploadIdempotencyKey:t.idempotencyKey}),storyboardId:e,storyboardMarkdown:await ah(t.file),teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(u(n,"Storyboard revision failed")),process.exit(s.GENERAL_ERROR)}}),KT=new Ce("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 p("readVideoStoryboard",{revisionId:t.revision,storyboardId:e,teamId:t.teamId});if(t.json){m(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(u(n,"Storyboard read failed")),process.exit(s.GENERAL_ERROR)}}),WT=new Ce("storyboard").description("Create, revise, and read Markdown video storyboards").addCommand(BT).addCommand(GT).addCommand(KT),dh=new Ce("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 ie(Er(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 Ec({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){m({...n,binding:r,source:t});return}let i=await Pc(n.runId,e.teamId);if(e.json){m({...i,binding:r,source:t});return}let o=i.output?.analysis??{};console.log(typeof o.promptContext=="string"?o.promptContext:JSON.stringify(i.output,null,2)),console.error(`Analysis run: ${n.runId}`),console.error(`Storyboard media JSON: ${JSON.stringify(r)}`)}catch(t){a(u(t,"Reference analysis failed")),process.exit(s.GENERAL_ERROR)}});dh.addHelpText("after",`
362
+ `);if(t.output&&(await sT(t.output,o,"utf-8"),n==="human"&&C(`Transcript saved to: ${t.output}`)),n==="json"){m(i);return}if(n==="quiet"){console.log(o);return}console.log(),console.log(`Title: ${i.title}`),i.channelName&&console.log(`Channel: ${i.channelName}`),i.durationFormatted&&console.log(`Duration: ${i.durationFormatted}`),console.log(`Language: ${i.language??"unknown"}${i.isAutoGenerated?" (auto-generated)":""}`),console.log(`Words: ${i.wordCount.toLocaleString()}`),console.log(`URL: ${i.url}`),i.truncated&&q("Transcript was truncated to fit the response budget."),t.output||(console.log(),console.log("--- Transcript ---"),console.log(o))}catch(i){r?.stop(),a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as lT}from"crypto";import{mkdir as mT,writeFile as Wf}from"fs/promises";import{dirname as pT}from"path";import{Command as lo}from"commander";import Jf from"ora";var uT=new lo("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("--purpose <purpose>","What this take is for, stamped on the credit ledger row",b("--purpose",["narration","pronunciation-preview","voice-take","listen","clone-audition","manual"])).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.idempotencyKey??lT(),n;try{n=_(e)}catch(l){a(u(l)),process.exit(s.INVALID_INPUT)}let r=e.format,i=r==="human"?Jf("Generating speech...").start():null,o;e.speed&&(o=parseFloat(e.speed),(Number.isNaN(o)||o<.1||o>4)&&(i?.stop(),a("Speed must be between 0.1 and 4.0"),process.exit(s.INVALID_INPUT)));let c;try{let l=e.optionsJson?gT("--options-json",e.optionsJson):{},d=await gc({text:e.text,...e.brandId!==void 0?{brandId:e.brandId}:{},...e.purpose!==void 0?{purpose:e.purpose}:{},options:{...l,language:e.lang,voiceId:e.voiceId,speed:o}},{approvalReceipt:n,idempotencyKey:t});c=d.requestId,i?.stop();let g=e.output.endsWith(`.${d.format}`)?e.output:`${e.output}.${d.format}`;await mT(pT(g),{recursive:!0}),await Wf(g,d.audioData);let y=g.replace(/\.[^.]+$/,".txt");if(await Wf(y,e.text,"utf-8"),r==="json"){m({status:"completed",requestId:d.requestId,output:g,audioUrl:d.audioUrl,duration:d.duration,format:d.format,speed:d.speed??o??1,lang:d.language??e.lang??null,langApplied:d.langApplied??!1,timestamps:d.timestamps??null,words:d.wordTimings??null});return}if(r==="quiet"){console.log(g);return}C(`Saved to: ${g}`),I(`Duration: ${d.duration.toFixed(2)}s`)}catch(l){i?.stop(),a(`${oe(l,c)}${Ee(l,t)}`,r),process.exit(s.GENERAL_ERROR)}});function gT(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 fT=new lo("voices").description("List available voices").option("-p, --provider <provider>","Filter by provider: gemini, elevenlabs, openai").option("-f, --format <format>","Output format: human, json",b("--format",["human","json"]),"human").action(async e=>{let t=e.format==="human"?Jf("Fetching voices...").start():null;try{let n=await hc(e.provider);if(t?.stop(),e.format==="json"){m(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 i of n.voices)console.log(` ${i.name} (${i.id})`),console.log(` ${i.description}`)}else for(let[r,i]of Object.entries(n.voices))if(!(!i||i.length===0)){console.log(),console.log(`${r.toUpperCase()} Voices:`),console.log("-".repeat(50));for(let o of i)console.log(` ${o.name} (${o.id})`),console.log(` ${o.description}`)}}catch(n){t?.stop(),a(u(n,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),hT=new lo("status").description("Read speech generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").option("-f, --format <format>","Output format: json",b("--format",["json"]),"json").action(async(e,t)=>{try{m(await R("generateSpeech",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),zf=new lo("tts").description("Text-to-speech commands").addCommand(uT).addCommand(fT).addCommand(hT);import{execSync as uo,spawnSync as VT}from"child_process";import{createHash as FT}from"crypto";import{access as Zs,readFile as BT,rm as sh}from"fs/promises";import{resolve as Pr}from"path";import Re from"chalk";import{Command as Ce}from"commander";import GT from"ffmpeg-static";import dh from"ora";import{Command as Hs}from"commander";var yT=new Hs("list").description("List ready editable video templates").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listVideoTemplates",{teamId:e.teamId}))}catch(t){a(u(t,"Video templates could not be loaded")),process.exit(s.GENERAL_ERROR)}}),bT=new Hs("create").description("Copy a pinned template into an editable Studio draft").requiredOption("--template-id <id>","Template ID from the catalog").requiredOption("--template-version <number>","Pinned template version").requiredOption("--idempotency-key <key>","Stable key for retrying the same pick").option("--title <text>","Draft title").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("createVideoFromTemplate",{templateId:e.templateId,version:Number(e.templateVersion),title:e.title,teamId:e.teamId},e.idempotencyKey))}catch(t){a(u(t,"Video template could not be opened")),process.exit(s.GENERAL_ERROR)}}),Hf=new Hs("templates").description("Browse ready stock videos and copy them into Studio").addCommand(yT).addCommand(bT);import{randomUUID as wT}from"crypto";import{Command as vT}from"commander";var Xs=["private","team","public"],Xf=new vT("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: ${Xs.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(e,t,n)=>{Xs.includes(t)||(a(`Invalid visibility "${t}". Expected one of: ${Xs.join(", ")}`),process.exit(s.GENERAL_ERROR));try{let r=await p("setVideoVisibility",{teamId:n.teamId,videoId:e,visibility:t},n.idempotencyKey??wT());if(n.json){m(r);return}r.shareUrl?C(`Video is now ${r.visibility}: ${r.shareUrl}`):C(`Video is now ${r.visibility} (no public link).`)}catch(r){a(u(r,"Visibility update failed")),process.exit(s.GENERAL_ERROR)}});import{Command as IT}from"commander";var Yf=new IT("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(i=>i!==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 i=Number(t.atSeconds);(!Number.isFinite(i)||i<0)&&(a("--at-seconds must be a number of seconds, zero or more."),process.exit(s.INVALID_INPUT)),r.atSeconds=i}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 i=await U(t.teamId),o=await p("setVideoThumbnail",r,Q({command:"video thumbnail set",payload:r,workspaceId:i}));m(o),C(`Poster set from ${o.source}.`)}catch(i){a(u(i,"Setting the poster failed")),process.exit(s.GENERAL_ERROR)}});import{mkdir as kT}from"fs/promises";import{join as xT}from"path";import{Command as Xt}from"commander";import Zf from"ora";var RT=5e3,CT=120,Qf=5;function eh(e,t){return[...t,e]}function ST(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 mo(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 ET(e){if(e.mode&&!["speed","precision"].includes(e.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:ST(e.audioUrl,"Audio URL"),...e.mode?{mode:e.mode}:{},sourceVideoId:mo(e.sourceVideoId)}}function PT(e){let t=[],n=new Set;for(let i of e.targetLanguage){let o=i.trim(),c=o.toLocaleLowerCase("en-US");!o||n.has(c)||(n.add(c),t.push(o))}if(t.length===0)throw new Error("Provide at least one target language");if(t.length>Qf)throw new Error(`Provide at most ${Qf} target languages`);if(t.find(i=>i.length<2||i.length>40))throw new Error("Target languages must be between 2 and 40 characters");return{...e.captions?{captions:!0}:{},sourceVideoId:mo(e.sourceVideoId),targetLanguages:t}}function AT(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:mo(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:mo(e.sourceVideoId),...e.title?{title:e.title}:{}}}function TT(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 po(e){return{requestId:e.runId,status:TT(e),...e.entity?.url?{videoUrl:e.entity.url}:{},...e.output?{output:e.output}:{},...e.error?{error:ge(e.error)}:{}}}function Ys(e){return{requestId:e.runId,status:"pending"}}async function Qs(e,t){return $e(async()=>po(await R(e,t)),CT,RT)}function lt(e,t){if(t==="json"){m(e);return}if(t==="quiet"){console.log(e.videoUrl??e.requestId);return}I(`Request ID: ${e.requestId}`),I(`Status: ${e.status}`),e.videoUrl&&C(`Video URL: ${e.videoUrl}`),e.error&&a(`Error: ${e.error}`)}function OT(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 $T(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function DT(e,t){let n=$T(e);if(!t.has(n))return t.add(n),n;let r=n.slice(0,-4),i=2;for(;t.has(`${r}-${i}.mp4`);)i+=1;let o=`${r}-${i}.mp4`;return t.add(o),o}async function NT(e,t){let n=OT(e.output).filter(o=>o.status==="completed"&&!!o.videoUrl);if(n.length===0)throw new Error("Video translation completed without downloadable results");await kT(t,{recursive:!0});let r=[],i=new Set;for(let o of n){let c=xT(t,DT(o.language,i));await Ie(o.videoUrl,c),r.push({language:o.language,path:c})}return r}var LT=new Xt("status").description("Check a video lip-sync request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let r=k(this,t).format??"human";try{lt(po(await R("lipsyncVideo",e)),r)}catch(i){a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),th=new Xt("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Zf("Starting video lip-sync...").start():null,n;try{let r=await Rc(ET(e),e.idempotencyKey,_(e));if(n=r.runId,!e.wait){t?.stop(),lt(Ys(r),e.format);return}t&&(t.text="Waiting for video lip-sync...");let i=await Qs("lipsyncVideo",r.runId);if(i.status==="failed")throw new de(i.error??"Video lip-sync failed");if(!i.videoUrl)throw new Error("Video lip-sync completed without a video URL");t&&(t.text="Downloading lip-synced video..."),await Ie(i.videoUrl,e.output),t?.stop(),lt(i,e.format),e.format==="human"&&C(`Saved to: ${e.output}`)}catch(r){t?.stop(),a(oe(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(LT)),nh=new Xt("translate-languages").description("List supported video translation target languages").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"]),"human").action(async e=>{try{let t=await Sc();if(e.format==="json")m({languages:t});else for(let n of t)console.log(n)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),UT=new Xt("status").description("Check a video translation request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let r=k(this,t).format??"human";try{lt(po(await R("translateVideo",e)),r)}catch(i){a(u(i,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),rh=new Xt("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)",eh,[]).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format==="human"?Zf("Starting video translation...").start():null,n;try{let r=await Ec(PT(e),e.idempotencyKey,_(e));if(n=r.runId,!e.wait){t?.stop(),lt(Ys(r),e.format);return}t&&(t.text="Waiting for video translations...");let i=await Qs("translateVideo",r.runId);if(i.status==="failed")throw new de(i.error??"Video translation failed");t&&(t.text="Downloading translated videos...");let o=await NT(i,e.outputDir);if(t?.stop(),e.format==="json")m({...i,downloads:o});else if(e.format==="quiet")for(let c of o)console.log(c.path);else{lt(i,e.format);for(let c of o)C(`${c.language}: ${c.path}`)}}catch(r){t?.stop(),a(oe(r,n),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(UT)),_T=new Xt("status").description("Check a video clipping request").argument("<id>","Request ID").option("-f, --format <format>","Output format: human, json, quiet",b("--format",["human","json","quiet"])).action(async function(e,t){let n=k(this,t);try{lt(po(await R("clipVideo",e)),n.format??"human")}catch(r){a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),ih=new Xt("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",eh,[]).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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t;try{let n=await Cc(AT(e),e.idempotencyKey,_(e));if(t=n.runId,!e.wait)return lt(Ys(n),e.format);let r=await Qs("clipVideo",n.runId);if(r.status==="failed")throw new de(r.error??"Video clipping failed");lt(r,e.format)}catch(n){a(oe(n,t),e.format),process.exit(s.GENERAL_ERROR)}}).addCommand(ce(_T));import{Command as jT}from"commander";function qT(e){return e===null?"\u2014":`${Math.round(e*100)}%`}function oh(e){return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function MT(e){return e.viewer?e.viewer.name??e.viewer.email??e.viewer.id:"Anonymous"}var ah=new jT("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(e,t)=>{try{let n=await p("getVideoViewAnalytics",{cursor:t.cursor,teamId:t.teamId,videoId:e});if(t.json){m(n);return}console.log(`${n.views} view${n.views===1?"":"s"} \xB7 ${n.completions} watched to the end \xB7 ${qT(n.averageCompletionRate)} average depth`),console.log(`${n.signedInViewers} signed-in viewer${n.signedInViewers===1?"":"s"} \xB7 ${oh(n.averageWatchedSeconds)} average watch time`);for(let r of n.sessions)console.log(` ${r.completed?"\u2713":"\xB7"} ${MT(r)} \u2014 ${oh(r.furthestSeconds)} reached, last seen ${r.lastViewedAt}`);n.nextCursor&&console.log(`More sittings \u2014 rerun with --cursor ${n.nextCursor}`)}catch(n){a(u(n,"View analytics read failed")),process.exit(s.GENERAL_ERROR)}});async function KT(){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 WT(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}var JT=new Ce("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",b("--format",["human","json","quiet"]),"human").action(async(e,t)=>{let{maxResults:n,orientation:r,license:i,format:o}=t,c=o==="human"?dh("Finding videos...").start():null;try{let l=await vc({query:e,options:{maxResults:parseInt(n,10),orientation:r,license:i,sources:WT(t.source)}});c?.stop();let d=l.data.results.flatMap(g=>g.results);if(o==="json"){m(l);return}if(o==="quiet"){d.forEach(g=>{console.log(g.embedUrl||g.previewUrl||g.thumbnailUrl)});return}if(d.length===0){I("No videos found");return}C(`Found ${d.length} videos for "${e}"`),console.log(),d.forEach((g,y)=>{let v=g.kind==="embed";console.log(`[${y+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(l){c?.stop(),a(u(l,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),zT=new Ce("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{m(await Pc({quality:e.release?"release":void 0,sourceVideoId:e.sourceVideo,storyboardRevisionId:e.storyboardRevision,teamId:e.teamId},e.approvalReceipt,e.idempotencyKey))}catch(t){a(u(t,"Generation failed")),process.exit(s.GENERAL_ERROR)}});async function ch(e){let t=e==="-"?await KT():await BT(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 lh(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 i=Xe(r.handle),o=Xe(r.path),c=Xe(r.fileUrl)??Xe(r.url),l=Xe(r.purpose),d=Xe(r.videoRole),g=Xe(r.analysisId)??Xe(r.analysis);if(!i||!o&&!c||!l)throw new Error("Invalid --media binding. handle, purpose, and either path or url are required strings.");if(o&&c)throw new Error("A media binding cannot contain both path and url.");if(o&&l==="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(o&&!t.uploadIdempotencyKey)throw new Error("Local storyboard media requires the command idempotency key.");let y=o?await ie(Pr(o),{idempotencyKey:`${t.uploadIdempotencyKey}:media:${i}`}):{name:Xe(r.name),size:Number(r.size),type:Xe(r.mime),url:c};if(!y.name||!y.type||!y.url||!Number.isSafeInteger(y.size)||y.size<=0)throw new Error(`URL media binding "${n}" requires name, mime, and positive integer size.`);let v=y.type.startsWith("video/")?"video":y.type.startsWith("audio/")?"audio":y.type.startsWith("image/")?"image":null;if(!v)throw new Error(`Unsupported media type for ${o??c}: ${y.type}`);if(!["source","style","identity","required"].includes(l))throw new Error(`Invalid media purpose: ${l}`);if(d&&!["reference","first-frame","last-frame"].includes(d))throw new Error(`Invalid videoRole: ${d}`);if(d&&v!=="image")throw new Error("videoRole is supported only for image bindings.");return{...g?{analysisId:g}:{},fileUrl:y.url,handle:i,kind:v,mime:y.type,name:y.name,purpose:l,size:y.size,...d?{videoRole:d}:{}}}))}function Xe(e){return typeof e=="string"&&e.length>0?e:void 0}var HT=new Ce("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{m(await p("createVideoStoryboard",{aspectRatio:e.aspect,durationSec:Number(e.duration),mediaBindings:await lh(e.media,{uploadIdempotencyKey:e.idempotencyKey}),storyboardMarkdown:await ch(e.file),teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(t){a(u(t,"Storyboard creation failed")),process.exit(s.GENERAL_ERROR)}}),XT=new Ce("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{m(await p("reviseVideoStoryboard",{aspectRatio:t.aspect,baseRevisionId:t.baseRevision,changeSummary:t.changeSummary,durationSec:Number(t.duration),mediaBindings:await lh(t.media,{uploadIdempotencyKey:t.idempotencyKey}),storyboardId:e,storyboardMarkdown:await ch(t.file),teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(u(n,"Storyboard revision failed")),process.exit(s.GENERAL_ERROR)}}),YT=new Ce("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 p("readVideoStoryboard",{revisionId:t.revision,storyboardId:e,teamId:t.teamId});if(t.json){m(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(u(n,"Storyboard read failed")),process.exit(s.GENERAL_ERROR)}}),QT=new Ce("storyboard").description("Create, revise, and read Markdown video storyboards").addCommand(HT).addCommand(XT).addCommand(YT),mh=new Ce("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 ie(Pr(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 Ac({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){m({...n,binding:r,source:t});return}let i=await Tc(n.runId,e.teamId);if(e.json){m({...i,binding:r,source:t});return}let o=i.output?.analysis??{};console.log(typeof o.promptContext=="string"?o.promptContext:JSON.stringify(i.output,null,2)),console.error(`Analysis run: ${n.runId}`),console.error(`Storyboard media JSON: ${JSON.stringify(r)}`)}catch(t){a(u(t,"Reference analysis failed")),process.exit(s.GENERAL_ERROR)}});mh.addHelpText("after",`
346
363
  ${Re.gray("# Prints an analysisId plus a ready storyboard media binding. Pass that")}
347
364
  ${Re.gray("# binding to video storyboard create/revise --media; generation reads the")}
348
365
  ${Re.gray("# analysis from the analysisId, never from local files.")}
349
- `);var JT=new Ce("status").description("Read a video-reference analysis run").argument("<run-id>","Analysis run UUID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await R("analyzeVideoReference",e,t.teamId);m(n);let r=zn(n);if(r)throw new Error(r)}catch(n){a(u(n,"Status read failed")),process.exit(s.GENERAL_ERROR)}}),zT=new Ce("reference").description("Upload and inspect reusable video references").addCommand(dh).addCommand(JT),HT=new Ce("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(e,t){try{m(await p("cancelVideoRun",{runId:e,teamId:t.teamId},t.idempotencyKey??`video-cancel:${UT("sha256").update(e).digest("hex")}`))}catch(n){a(u(n,"Video cancellation failed")),process.exit(s.GENERAL_ERROR)}}),XT=new Ce("status").description("Read video background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await R("createVideo",e,t.teamId);m(n);let r=zn(n);if(r)throw new Error(r)}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),YT=new Ce("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format,n=t==="human"?oh("Injecting thumbnail...").start():null;try{let r=Er(e.video),i=Er(e.thumbnail),o=e.output?Er(e.output):r.replace(/\.mp4$/,"-with-thumb.mp4");await Ys(r),await Ys(i);let c=jT;if(c)try{await Ys(c)}catch{c=null}if(!c)try{c=mo("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let l=LT(c,["-i",r],{encoding:"utf8"});if(l.error)throw new Error(`Failed to probe video: ${l.error.message}`);let d=(l.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!d)throw new Error("Could not detect video dimensions");let[,g,y]=d;n&&(n.text="Creating thumbnail frame...");let v="/tmp/cc-thumb-frame.mp4";mo(`${c} -y -loop 1 -i "${i}" -vf "scale=${g}:${y}:force_original_aspect_ratio=decrease,pad=${g}:${y}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${v}"`,{stdio:"pipe"}),n&&(n.text="Concatenating with video...");let x="/tmp/cc-concat-video.mp4";if(mo(`${c} -y -i "${v}" -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 "${x}"`,{stdio:"pipe"}),n&&(n.text="Adding file icon thumbnail..."),mo(`${c} -y -i "${x}" -i "${i}" -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic "${o}"`,{stdio:"pipe"}),await ih(v,{force:!0}),await ih(x,{force:!0}),n?.stop(),t==="json"){m({success:!0,output:o});return}if(t==="quiet"){console.log(o);return}C(`Thumbnail injected: ${o}`)}catch(r){n?.stop(),a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),QT=new Ce("thumbnail").description("Thumbnail operations").addCommand(YT).addCommand(zf),po=new Ce("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(VT).addCommand(QT).addCommand(th).addCommand(Qf).addCommand(Zf).addCommand(eh).addCommand(Fg).addCommand(Wf).addCommand(Jf).addCommand(rh);po.addCommand(FT).addCommand(WT).addCommand(zT).addCommand(HT).addCommand(XT);po.addHelpText("after",`
366
+ `);var ZT=new Ce("status").description("Read a video-reference analysis run").argument("<run-id>","Analysis run UUID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await R("analyzeVideoReference",e,t.teamId);m(n);let r=Hn(n);if(r)throw new Error(r)}catch(n){a(u(n,"Status read failed")),process.exit(s.GENERAL_ERROR)}}),eO=new Ce("reference").description("Upload and inspect reusable video references").addCommand(mh).addCommand(ZT),tO=new Ce("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(e,t){try{m(await p("cancelVideoRun",{runId:e,teamId:t.teamId},t.idempotencyKey??`video-cancel:${FT("sha256").update(e).digest("hex")}`))}catch(n){a(u(n,"Video cancellation failed")),process.exit(s.GENERAL_ERROR)}}),nO=new Ce("status").description("Read video background status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{let n=await R("createVideo",e,t.teamId);m(n);let r=Hn(n);if(r)throw new Error(r)}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),rO=new Ce("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",b("--format",["human","json","quiet"]),"human").action(async e=>{let t=e.format,n=t==="human"?dh("Injecting thumbnail...").start():null;try{let r=Pr(e.video),i=Pr(e.thumbnail),o=e.output?Pr(e.output):r.replace(/\.mp4$/,"-with-thumb.mp4");await Zs(r),await Zs(i);let c=GT;if(c)try{await Zs(c)}catch{c=null}if(!c)try{c=uo("which ffmpeg",{encoding:"utf8"}).trim()}catch{throw new Error("ffmpeg not found. Install ffmpeg or ffmpeg-static.")}let l=VT(c,["-i",r],{encoding:"utf8"});if(l.error)throw new Error(`Failed to probe video: ${l.error.message}`);let d=(l.stderr??"").match(/(\d{2,5})x(\d{2,5})/);if(!d)throw new Error("Could not detect video dimensions");let[,g,y]=d;n&&(n.text="Creating thumbnail frame...");let v="/tmp/cc-thumb-frame.mp4";uo(`${c} -y -loop 1 -i "${i}" -vf "scale=${g}:${y}:force_original_aspect_ratio=decrease,pad=${g}:${y}:(ow-iw)/2:(oh-ih)/2,setsar=1" -t 0.033 -r 30 -c:v libx264 -pix_fmt yuv420p "${v}"`,{stdio:"pipe"}),n&&(n.text="Concatenating with video...");let x="/tmp/cc-concat-video.mp4";if(uo(`${c} -y -i "${v}" -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 "${x}"`,{stdio:"pipe"}),n&&(n.text="Adding file icon thumbnail..."),uo(`${c} -y -i "${x}" -i "${i}" -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic "${o}"`,{stdio:"pipe"}),await sh(v,{force:!0}),await sh(x,{force:!0}),n?.stop(),t==="json"){m({success:!0,output:o});return}if(t==="quiet"){console.log(o);return}C(`Thumbnail injected: ${o}`)}catch(r){n?.stop(),a(u(r,"Unknown error")),process.exit(s.GENERAL_ERROR)}}),iO=new Ce("thumbnail").description("Thumbnail operations").addCommand(rO).addCommand(Yf),go=new Ce("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(JT).addCommand(iO).addCommand(ih).addCommand(th).addCommand(nh).addCommand(rh).addCommand(Kg).addCommand(Hf).addCommand(Xf).addCommand(ah);go.addCommand(zT).addCommand(QT).addCommand(eO).addCommand(tO).addCommand(nO);go.addHelpText("after",`
350
367
  ${Re.bold("Examples:")}
351
368
  ${Re.gray("# Storyboard-first video from a brief")}
352
369
  $ ${f.commands[0]} video storyboard create --file brief.md --duration 15 --aspect 16:9 --idempotency-key launch-1
@@ -366,8 +383,8 @@ ${Re.bold("Before generating:")}
366
383
  ${Re.bold("See also:")}
367
384
  ${Re.gray("# Already have a deck? Render it to MP4 (narration, avatar, captions)")}
368
385
  $ ${f.commands[0]} presentation video <slug>
369
- `);import{Command as Qs}from"commander";var ZT=new Qs("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(e,t)=>{t.yes||(a("Pass --yes to confirm visual-abstract generation"),process.exit(s.INVALID_INPUT));try{let n=Array.isArray(t.referenceUrl)?t.referenceUrl.map((r,i)=>({label:`visual-reference-${i+1}`,url:r})):void 0;m(await p("createVisualAbstract",{approvalReceipt:_(t),aspectRatio:t.aspect,brandingId:t.brandingId,brandName:t.brandName,brief:e,context:t.context,customInstructions:t.customInstructions,outputPreset:t.preset,outputType:t.output,qualityTier:t.quality,referenceImages:n,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),eO=new Qs("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createVisualAbstract",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),ch=new Qs("visual-abstract").description("Generate a one-page visual abstract graphic (raster or vector) from a dense brief").addCommand(ZT).addCommand(eO);import Te from"chalk";import{Command as ye}from"commander";import{Command as tO}from"commander";var lh=new tO("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)",b("--preset",["professional","conversational","energetic"])).option("--stability <0-1>","Higher reads more evenly; lower widens the emotional range",ee("--stability",0,1)).option("--expressiveness <0-1>","How much the read exaggerates emphasis; 0 is neutral",ee("--expressiveness",0,1)).option("--speed <0.7-1.2>","Speaking pace; 1 is normal",ee("--speed",.7,1.2)).option("--clear","Remove the saved tone").option("--take <take-id>","Adopt a saved version as the voice's sample \u2014 its own words and tone, exactly as auditioned").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await zc({...t.clear?{clear:!0}:{},...t.take?{takeId:t.take}:{},...t.expressiveness===void 0?{}:{expressiveness:t.expressiveness},...t.preset?{preset:t.preset}:{},...t.speed===void 0?{}:{speed:t.speed},...t.stability===void 0?{}:{stability:t.stability},voiceId:e});if(t.format==="json"){m(n);return}if(!n.voice.tone){C(`${n.voice.name} reads with its natural delivery again.`);return}C(`${n.voice.name} now reads ${nO(n.voice.tone)}.`),I("Videos already narrated keep their audio until their next render re-voices them.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}});function nO(e){let t=[e.stability===void 0?null:`stability ${e.stability}`,e.expressiveness===void 0?null:`expressiveness ${e.expressiveness}`,e.speed===void 0?null:`speed ${e.speed}`].filter(Boolean),n=e.preset?`in a ${e.preset} tone`:"in a custom tone";return t.length>0?`${n} (${t.join(", ")})`:n}var mh=["male","female"],ph=["young","middle_aged","old"];function Zs(e){let t=[e.gender,e.age,e.accent,e.useCase].filter(Boolean).join(" \xB7 "),n=e.description?Te.gray(` \u2014 ${e.description}`):"",r=e.ready?"":Te.yellow(" (not ready)"),i=e.sharedBy?.name?.trim()||e.sharedBy?.email?.trim(),o=i?Te.gray(` shared by ${i}`):"";return`${Te.bold(e.name)}${r} ${Te.gray(e.id)}${o}
370
- ${t||Te.gray("no stated labels")}${n}`}var rO=new ye("list").description("The voices this workspace can narrate with").option("--gender <gender>","male or female",b("--gender",mh)).option("--age <age>","young, middle_aged or old",b("--age",ph)).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 e=>{try{let t=await Mc({...e.accent?{accent:e.accent}:{},...e.age?{age:e.age}:{},...e.gender?{gender:e.gender}:{},...e.language?{language:e.language}:{},...e.page?{page:Number(e.page)}:{},...e.pageSize?{pageSize:Number(e.pageSize)}:{},...e.query?{query:e.query}:{},...e.useCase?{useCase:e.useCase}:{}});if(e.format==="json"){m(t);return}if(t.catalogUnavailable&&I("Built-in voices are temporarily unavailable; showing yours only."),t.voices.length===0){I("No voices match those filters.");return}for(let n of t.voices)console.log(Zs(n));if(t.library.length>0){I(t.curated?`From the shared library \u2014 ${t.totalMatching} more behind these:`:`From the shared library \u2014 ${t.totalMatching} match:`);for(let n of t.library)console.log(Zs(n));I(`Add one with ${f.commands[0]} voice add <voice-id>`)}t.libraryUnavailable&&I("The shared library could not be searched; showing yours only."),t.canDesignVoice&&I(`Nothing fits? ${f.commands[0]} voice design "<description>"`)}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),iO=new ye("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("--remix-voice <voice>","Vary a voice this workspace already has; the original is never changed").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(e,t)=>{try{let n=await Qc({description:e,...t.includeAudio?{includeAudio:!0}:{},...t.remixOf?{remixOf:t.remixOf}:{},...t.remixVoice?{remixVoice:t.remixVoice}:{},...t.roundId?{roundId:t.roundId}:{},...t.seed?{seed:Number(t.seed)}:{},...t.text?{text:t.text}:{}});if(t.format==="json"){m(n);return}C(`${n.candidates.length} candidates \xB7 ${n.creditsCharged} credits`);for(let r of n.candidates){let i=r.durationSeconds?` (${r.durationSeconds.toFixed(1)}s)`:"";console.log(` ${Te.gray(r.id)}${i}`)}I(t.includeAudio?"Audio is in --format json. Keep one with:":"Add --include-audio --format json to hear them. Keep one with:"),I(` ${f.commands[0]} voice save <candidate-id> --name "<name>" --description "${e.slice(0,40)}\u2026"`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),oO=new ye("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",b("--gender",mh)).option("--age <age>","young, middle_aged or old",b("--age",ph)).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(e,t)=>{try{let n={...t.accent?{accent:t.accent}:{},...t.age?{age:t.age}:{},...t.gender?{gender:t.gender}:{},...t.useCase?{useCase:t.useCase}:{}},r=await Zc({candidateId:e,description:t.description,...n,name:t.name,...t.passedOver?{passedOver:t.passedOver.split(",").map(i=>i.trim()).filter(Boolean)}:{}});if(t.format==="json"){m(r);return}C(`Saved ${r.voice.name}`),console.log(Zs(r.voice)),Object.keys(n).length||I("No labels given, so this voice matches no gender/age/accent filter.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),aO=new ye("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(e,t)=>{try{let n=await el({voiceId:e});if(t.format==="json"){m(n);return}C("Voice removed."),n.heldProviderSlot&&!n.providerSlotReleased&&I("The voice slot was not released and is still held.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),sO=new ye("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(e,t)=>{try{let n=await Vc({...t.name?{name:t.name}:{},voiceId:e});if(t.format==="json"){m(n);return}C(`${n.voice.name} is now one of your voices.`),I(` ${Te.gray(n.voice.id)}`),I(`Use it with ${f.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),dO=new ye("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",b("--favorite",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=t.favorite==="true",r=await Fc({favorite:n,voiceId:e});if(t.format==="json"){m(r);return}C(n?`${r.voice.name} is starred.`:`${r.voice.name} is no longer starred.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),cO=new ye("shortlist").description("Add a voice to the workspace's shared shortlist, or remove it").argument("<voice-id>","A workspace voice id, or a library handle").option("--shortlisted <shortlisted>","true to shortlist, false to remove",b("--shortlisted",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=t.shortlisted==="true",r=await Bc({shortlisted:n,voiceId:e});if(t.format==="json"){m(r);return}C(n?`${r.voiceId} is on the team's shortlist.`:`${r.voiceId} came off the team's shortlist.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),lO=new ye("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",b("--visibility",["team","private"]),"team").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await Hc({visibility:t.visibility,voiceId:e});if(t.format==="json"){m(n);return}C(t.visibility==="team"?`${n.voice.name} is shared with the workspace.`:`${n.voice.name} is private to you again.`),t.visibility==="team"&&I("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(u(n)),process.exit(s.GENERAL_ERROR)}}),mO=new ye("policy").description("Whether approved voices are the only ones material may use").argument("<mode>","open, or enforced",b("<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(e,t)=>{try{if(e==="enforced"&&!t.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 Gc({...t.brand?{brandId:t.brand}:{},mode:e});if(t.format==="json"){m(n);return}let r=t.brand?"this brand":"this workspace";C(e==="enforced"?`Only approved voices may be used in ${r}'s material.`:`Any voice may be used in ${r}'s material.`),e==="enforced"&&I(`Videos that already exist are unaffected. Approve voices with ${f.commands[0]} voice approve <voice-id>`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),pO=new ye("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",b("--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(e,t)=>{try{let n=t.approved==="true",r=await Xc({approved:n,...t.brand?{brandId:t.brand}:{},...t.note?{note:t.note}:{},voiceId:e});if(t.format==="json"){m(r);return}let i=r.voice?.name??e;C(n?`${i} is approved for this workspace's material.`:`${i} is no longer approved.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),uO=new ye("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 e=>{try{let t=await Yc(e.brand?{brandId:e.brand}:{});if(e.format==="json"){m(t);return}I(t.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."),t.catalogUnavailable&&I("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 t.policies.filter(r=>r.mode==="enforced"))I(n.brandId?`Enforced for brand ${n.brandId}`:"Enforced for the whole team");if(t.voices.length===0){I("No voices are approved yet.");return}for(let n of t.voices){let r=n.voice?.name??"(voice no longer exists)",i=n.brandId?" [brand]":"",o=n.note?` \u2014 ${n.note}`:"";I(`${r}${i} ${n.voiceId}${o}`)}}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),gO=new ye("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(e,t)=>{try{let n=await Kc({...t.brand?{brandId:t.brand}:{},...t.note?{note:t.note}:{},voiceId:e});if(t.format==="json"){m(n);return}C(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(u(n)),process.exit(s.GENERAL_ERROR)}}),fO=new ye("requests").description("Voices people have asked to have admitted").option("--mine","Only your own requests").option("--state <state>","pending, approved, declined or withdrawn",b("--state",["pending","approved","declined","withdrawn"])).option("--format <format>","text or json","text").action(async e=>{try{let t=await Wc({...e.mine?{mine:!0}:{},...e.state?{state:e.state}:{}});if(e.format==="json"){m(t);return}if(t.requests.length===0){I("Nothing is waiting on a decision.");return}for(let n of t.requests){let r=n.requestedByViewer?"you":"a teammate",i=n.note?` \u2014 ${n.note}`:"";I(`${n.id} ${n.state.padEnd(9)} ${n.voiceId} (asked by ${r})${i}`)}t.canDecide&&I(`Settle one with ${f.commands[0]} voice decide <request-id> --state approved`)}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),hO=new ye("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",b("--state",["approved","declined","withdrawn"])).option("--approve-voice <approve>","true to admit the voice as well; ignored unless approving",b("--approve-voice",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await Jc({approveVoice:t.approveVoice==="true",requestId:e,state:t.state});if(t.format==="json"){m(n);return}C(`That request is ${n.request.state}.`),n.admittedVoice&&I("The voice is now approved for this workspace's material.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),ed=new ye("voice").description("The voices your narration can use").addCommand(rO).addCommand(iO).addCommand(oO).addCommand(sO).addCommand(dO).addCommand(cO).addCommand(lO).addCommand(lh).addCommand(mO).addCommand(pO).addCommand(uO).addCommand(gO).addCommand(fO).addCommand(hO).addCommand(aO);ed.addHelpText("after",`
386
+ `);import{Command as ed}from"commander";var oO=new ed("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(e,t)=>{t.yes||(a("Pass --yes to confirm visual-abstract generation"),process.exit(s.INVALID_INPUT));try{let n=Array.isArray(t.referenceUrl)?t.referenceUrl.map((r,i)=>({label:`visual-reference-${i+1}`,url:r})):void 0;m(await p("createVisualAbstract",{approvalReceipt:_(t),aspectRatio:t.aspect,brandingId:t.brandingId,brandName:t.brandName,brief:e,context:t.context,customInstructions:t.customInstructions,outputPreset:t.preset,outputType:t.output,qualityTier:t.quality,referenceImages:n,teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(u(n,"Generation failed")),process.exit(s.GENERAL_ERROR)}}),aO=new ed("status").description("Read visual-abstract generation status").argument("<run-id>","Run ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await R("createVisualAbstract",e,t.teamId))}catch(n){a(u(n,"Status failed")),process.exit(s.GENERAL_ERROR)}}),ph=new ed("visual-abstract").description("Generate a one-page visual abstract graphic (raster or vector) from a dense brief").addCommand(oO).addCommand(aO);import Te from"chalk";import{Command as ye}from"commander";import{Command as sO}from"commander";var uh=new sO("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)",b("--preset",["professional","conversational","energetic"])).option("--stability <0-1>","Higher reads more evenly; lower widens the emotional range",ee("--stability",0,1)).option("--expressiveness <0-1>","How much the read exaggerates emphasis; 0 is neutral",ee("--expressiveness",0,1)).option("--speed <0.7-1.2>","Speaking pace; 1 is normal",ee("--speed",.7,1.2)).option("--clear","Remove the saved tone").option("--take <take-id>","Adopt a saved version as the voice's sample \u2014 its own words and tone, exactly as auditioned").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await Xc({...t.clear?{clear:!0}:{},...t.take?{takeId:t.take}:{},...t.expressiveness===void 0?{}:{expressiveness:t.expressiveness},...t.preset?{preset:t.preset}:{},...t.speed===void 0?{}:{speed:t.speed},...t.stability===void 0?{}:{stability:t.stability},voiceId:e});if(t.format==="json"){m(n);return}if(!n.voice.tone){C(`${n.voice.name} reads with its natural delivery again.`);return}C(`${n.voice.name} now reads ${dO(n.voice.tone)}.`),I("Videos already narrated keep their audio until their next render re-voices them.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}});function dO(e){let t=[e.stability===void 0?null:`stability ${e.stability}`,e.expressiveness===void 0?null:`expressiveness ${e.expressiveness}`,e.speed===void 0?null:`speed ${e.speed}`].filter(Boolean),n=e.preset?`in a ${e.preset} tone`:"in a custom tone";return t.length>0?`${n} (${t.join(", ")})`:n}var gh=["male","female"],fh=["young","middle_aged","old"];function td(e){let t=[e.gender,e.age,e.accent,e.useCase].filter(Boolean).join(" \xB7 "),n=e.description?Te.gray(` \u2014 ${e.description}`):"",r=e.ready?"":Te.yellow(" (not ready)"),i=e.sharedBy?.name?.trim()||e.sharedBy?.email?.trim(),o=i?Te.gray(` shared by ${i}`):"";return`${Te.bold(e.name)}${r} ${Te.gray(e.id)}${o}
387
+ ${t||Te.gray("no stated labels")}${n}`}var cO=new ye("list").description("The voices this workspace can narrate with").option("--gender <gender>","male or female",b("--gender",gh)).option("--age <age>","young, middle_aged or old",b("--age",fh)).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 e=>{try{let t=await Fc({...e.accent?{accent:e.accent}:{},...e.age?{age:e.age}:{},...e.gender?{gender:e.gender}:{},...e.language?{language:e.language}:{},...e.page?{page:Number(e.page)}:{},...e.pageSize?{pageSize:Number(e.pageSize)}:{},...e.query?{query:e.query}:{},...e.useCase?{useCase:e.useCase}:{}});if(e.format==="json"){m(t);return}if(t.catalogUnavailable&&I("Built-in voices are temporarily unavailable; showing yours only."),t.voices.length===0){I("No voices match those filters.");return}for(let n of t.voices)console.log(td(n));if(t.library.length>0){I(t.curated?`From the shared library \u2014 ${t.totalMatching} more behind these:`:`From the shared library \u2014 ${t.totalMatching} match:`);for(let n of t.library)console.log(td(n));I(`Add one with ${f.commands[0]} voice add <voice-id>`)}t.libraryUnavailable&&I("The shared library could not be searched; showing yours only."),t.canDesignVoice&&I(`Nothing fits? ${f.commands[0]} voice design "<description>"`)}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),lO=new ye("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("--remix-voice <voice>","Vary a voice this workspace already has; the original is never changed").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(e,t)=>{try{let n=await el({description:e,...t.includeAudio?{includeAudio:!0}:{},...t.remixOf?{remixOf:t.remixOf}:{},...t.remixVoice?{remixVoice:t.remixVoice}:{},...t.roundId?{roundId:t.roundId}:{},...t.seed?{seed:Number(t.seed)}:{},...t.text?{text:t.text}:{}});if(t.format==="json"){m(n);return}C(`${n.candidates.length} candidates \xB7 ${n.creditsCharged} credits`);for(let r of n.candidates){let i=r.durationSeconds?` (${r.durationSeconds.toFixed(1)}s)`:"";console.log(` ${Te.gray(r.id)}${i}`)}I(t.includeAudio?"Audio is in --format json. Keep one with:":"Add --include-audio --format json to hear them. Keep one with:"),I(` ${f.commands[0]} voice save <candidate-id> --name "<name>" --description "${e.slice(0,40)}\u2026"`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),mO=new ye("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",b("--gender",gh)).option("--age <age>","young, middle_aged or old",b("--age",fh)).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(e,t)=>{try{let n={...t.accent?{accent:t.accent}:{},...t.age?{age:t.age}:{},...t.gender?{gender:t.gender}:{},...t.useCase?{useCase:t.useCase}:{}},r=await tl({candidateId:e,description:t.description,...n,name:t.name,...t.passedOver?{passedOver:t.passedOver.split(",").map(i=>i.trim()).filter(Boolean)}:{}});if(t.format==="json"){m(r);return}C(`Saved ${r.voice.name}`),console.log(td(r.voice)),Object.keys(n).length||I("No labels given, so this voice matches no gender/age/accent filter.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),pO=new ye("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(e,t)=>{try{let n=await nl({voiceId:e});if(t.format==="json"){m(n);return}C("Voice removed."),n.heldProviderSlot&&!n.providerSlotReleased&&I("The voice slot was not released and is still held.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),uO=new ye("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(e,t)=>{try{let n=await Bc({...t.name?{name:t.name}:{},voiceId:e});if(t.format==="json"){m(n);return}C(`${n.voice.name} is now one of your voices.`),I(` ${Te.gray(n.voice.id)}`),I(`Use it with ${f.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),gO=new ye("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",b("--favorite",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=t.favorite==="true",r=await Gc({favorite:n,voiceId:e});if(t.format==="json"){m(r);return}C(n?`${r.voice.name} is starred.`:`${r.voice.name} is no longer starred.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),fO=new ye("shortlist").description("Add a voice to the workspace's shared shortlist, or remove it").argument("<voice-id>","A workspace voice id, or a library handle").option("--shortlisted <shortlisted>","true to shortlist, false to remove",b("--shortlisted",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=t.shortlisted==="true",r=await Kc({shortlisted:n,voiceId:e});if(t.format==="json"){m(r);return}C(n?`${r.voiceId} is on the team's shortlist.`:`${r.voiceId} came off the team's shortlist.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),hO=new ye("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",b("--visibility",["team","private"]),"team").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await Yc({visibility:t.visibility,voiceId:e});if(t.format==="json"){m(n);return}C(t.visibility==="team"?`${n.voice.name} is shared with the workspace.`:`${n.voice.name} is private to you again.`),t.visibility==="team"&&I("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(u(n)),process.exit(s.GENERAL_ERROR)}}),yO=new ye("policy").description("Whether approved voices are the only ones material may use").argument("<mode>","open, or enforced",b("<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(e,t)=>{try{if(e==="enforced"&&!t.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 Wc({...t.brand?{brandId:t.brand}:{},mode:e});if(t.format==="json"){m(n);return}let r=t.brand?"this brand":"this workspace";C(e==="enforced"?`Only approved voices may be used in ${r}'s material.`:`Any voice may be used in ${r}'s material.`),e==="enforced"&&I(`Videos that already exist are unaffected. Approve voices with ${f.commands[0]} voice approve <voice-id>`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),bO=new ye("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",b("--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(e,t)=>{try{let n=t.approved==="true",r=await Qc({approved:n,...t.brand?{brandId:t.brand}:{},...t.note?{note:t.note}:{},voiceId:e});if(t.format==="json"){m(r);return}let i=r.voice?.name??e;C(n?`${i} is approved for this workspace's material.`:`${i} is no longer approved.`)}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),wO=new ye("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 e=>{try{let t=await Zc(e.brand?{brandId:e.brand}:{});if(e.format==="json"){m(t);return}I(t.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."),t.catalogUnavailable&&I("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 t.policies.filter(r=>r.mode==="enforced"))I(n.brandId?`Enforced for brand ${n.brandId}`:"Enforced for the whole team");if(t.voices.length===0){I("No voices are approved yet.");return}for(let n of t.voices){let r=n.voice?.name??"(voice no longer exists)",i=n.brandId?" [brand]":"",o=n.note?` \u2014 ${n.note}`:"";I(`${r}${i} ${n.voiceId}${o}`)}}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),vO=new ye("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(e,t)=>{try{let n=await Jc({...t.brand?{brandId:t.brand}:{},...t.note?{note:t.note}:{},voiceId:e});if(t.format==="json"){m(n);return}C(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(u(n)),process.exit(s.GENERAL_ERROR)}}),IO=new ye("requests").description("Voices people have asked to have admitted").option("--mine","Only your own requests").option("--state <state>","pending, approved, declined or withdrawn",b("--state",["pending","approved","declined","withdrawn"])).option("--format <format>","text or json","text").action(async e=>{try{let t=await zc({...e.mine?{mine:!0}:{},...e.state?{state:e.state}:{}});if(e.format==="json"){m(t);return}if(t.requests.length===0){I("Nothing is waiting on a decision.");return}for(let n of t.requests){let r=n.requestedByViewer?"you":"a teammate",i=n.note?` \u2014 ${n.note}`:"";I(`${n.id} ${n.state.padEnd(9)} ${n.voiceId} (asked by ${r})${i}`)}t.canDecide&&I(`Settle one with ${f.commands[0]} voice decide <request-id> --state approved`)}catch(t){a(u(t)),process.exit(s.GENERAL_ERROR)}}),kO=new ye("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",b("--state",["approved","declined","withdrawn"])).option("--approve-voice <approve>","true to admit the voice as well; ignored unless approving",b("--approve-voice",["true","false"]),"true").option("--format <format>","text or json","text").action(async(e,t)=>{try{let n=await Hc({approveVoice:t.approveVoice==="true",requestId:e,state:t.state});if(t.format==="json"){m(n);return}C(`That request is ${n.request.state}.`),n.admittedVoice&&I("The voice is now approved for this workspace's material.")}catch(n){a(u(n)),process.exit(s.GENERAL_ERROR)}}),nd=new ye("voice").description("The voices your narration can use").addCommand(cO).addCommand(lO).addCommand(mO).addCommand(uO).addCommand(gO).addCommand(fO).addCommand(hO).addCommand(uh).addCommand(yO).addCommand(bO).addCommand(wO).addCommand(vO).addCommand(IO).addCommand(kO).addCommand(pO);nd.addHelpText("after",`
371
388
  ${Te.bold("Examples:")}
372
389
  ${Te.gray("# The request a fixed catalog cannot answer")}
373
390
  $ ${f.commands[0]} voice list --gender male --age middle_aged --accent american --use-case conversational
@@ -379,14 +396,14 @@ ${Te.bold("Examples:")}
379
396
  ${Te.bold("See also:")}
380
397
  ${Te.gray("# Narrate a presentation video with the voice you chose")}
381
398
  $ ${f.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes
382
- `);import{randomUUID as td}from"crypto";import{Command as Yt}from"commander";function uh(e,t){try{let n=JSON.parse(t);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{a(`${e} must be a JSON object, e.g. --${e} '{"mode":"stock"}'`),process.exit(s.GENERAL_ERROR)}}async function gh(e,t,n){if(n.wait===!1){m(t);return}I(`Run ${t.runId} accepted (${t.status}). Waiting\u2026`);let r=await z(e,t.runId,n.teamId,n.maxAttempts);m(r)}var yO=new Yt("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",td()).action(async e=>{try{m(await p("createWalkthroughUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},e.idempotencyKey))}catch(t){a(u(t,"Upload URL failed")),process.exit(s.GENERAL_ERROR)}}),bO=new Yt("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",td()).option("--no-wait","Return the run ID instead of waiting for narration").action(async(e,t)=>{try{let n=await p("createWalkthrough",{audience:t.audience,captions:t.captions,costMode:t.costMode,musicConfig:t.musicConfig?uh("music-config",t.musicConfig):void 0,presenterConfig:t.presenterConfig?uh("presenter-config",t.presenterConfig):void 0,sourceAudioVolume:t.sourceAudioVolume,sourceChatId:t.sourceChatId,sourceDurationSec:t.sourceDuration,sourceHeight:t.sourceHeight,sourceMediaType:t.sourceMediaType,sourceVideoUrl:e,sourceWidth:t.sourceWidth,targetLength:t.targetLength,teamId:t.teamId,title:t.title,tone:t.tone,voiceId:t.voiceId},t.idempotencyKey);await gh("createWalkthrough",n,{...t,maxAttempts:180})}catch(n){a(u(n,"Creation failed")),process.exit(s.GENERAL_ERROR)}}),wO=new Yt("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",td()).option("--no-wait","Return the run ID instead of waiting for the render").action(async(e,t)=>{try{let n=await p("renderWalkthrough",{costMode:t.costMode,sourceAudioVolume:t.sourceAudioVolume,teamId:t.teamId,walkthroughId:e},t.idempotencyKey);await gh("renderWalkthrough",n,{...t,maxAttempts:300})}catch(n){a(u(n,"Render failed")),process.exit(s.GENERAL_ERROR)}}),vO=new Yt("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(e,t)=>{try{m(await R("createWalkthrough",e,t.teamId));return}catch(n){n instanceof P&&n.statusCode===404||(a(u(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR))}try{m(await R("renderWalkthrough",e,t.teamId))}catch(n){a(u(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR)}}),IO=new Yt("get").description("Read one walkthrough").argument("<walkthrough-id>","Walkthrough ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getWalkthrough",{teamId:t.teamId,walkthroughId:e}))}catch(n){a(u(n,"Lookup failed")),process.exit(s.GENERAL_ERROR)}}),kO=new Yt("list").description("List walkthroughs in the workspace").option("--limit <count>","Maximum rows to return",Number).option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listWalkthroughs",{limit:e.limit,teamId:e.teamId}))}catch(t){a(u(t,"List failed")),process.exit(s.GENERAL_ERROR)}}),fh=new Yt("walkthrough").description("Recorded walkthroughs: narrated videos from screen captures").addCommand(yO).addCommand(bO).addCommand(wO).addCommand(vO).addCommand(IO).addCommand(kO);import{Command as vh,InvalidArgumentError as Ih}from"commander";var hh=["article","cheat-sheet","flashcards","microsite","presentation","quiz","survey","video"],yh=["cancelled","draft","failed","in-progress","published","ready","setup"],bh=["mine","workspace"];function xO(e,t){return n=>{if(!t.includes(n))throw new Ih(`${e} expects one of: ${t.join(", ")}.`);return n}}function wh(e,t){return n=>{let r=n.split(",").map(o=>o.trim()).filter(Boolean);if(r.find(o=>!t.includes(o))||r.length===0)throw new Ih(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function RO(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var CO=new vh("list").description("List the workspace's in-flight, draft, failed, and finished work \u2014 continuation-first").option("--kinds <kinds>",`Filter to artifact kinds: ${hh.join(", ")}`,wh("--kinds",hh)).option("--lifecycle <states>",`Filter to lifecycle states: ${yh.join(", ")}`,wh("--lifecycle",yh)).option("--limit <n>","Maximum items to return (default 20, max 50)").option("--scope <scope>",`Whose work to list: ${bh.join(", ")}`,xO("--scope",bh)).option("--offset <n>","Zero-based result offset").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listWorkItems",{kinds:e.kinds,lifecycle:e.lifecycle,limit:e.limit?Number(e.limit):void 0,offset:e.offset?Number(e.offset):void 0,scope:e.scope,teamId:e.teamId}))}catch(t){RO(t,"Could not list work items")}}),kh=new vh("work").description("Inspect the workspace's recent and in-flight work").addCommand(CO);var nd=[tu,hu,hm,Hp,Kf,Gu,$u,bu,po,Us,Ff,Pf,kr,js,Va,ku,Qa,zu,mm,pm,ch,Au,Zl,im,ca,Pu,Ma,ed,su,ou,Iu,mu,pu,Ja,nu,wm,Sf,Tf,qf,Mf,Vf,fh,Ou,kh,Nf];function xh(e){for(let t of nd)e.addCommand(t)}function Rh(e,t,n){let r=t?`${t} ${e.name()}`:e.name();n.set(r,{arguments:e.registeredArguments.filter(i=>i.required).map(i=>`<${i.name()}>`),requiredOptions:e.options.filter(i=>i.mandatory).map(i=>i.long).filter(i=>!!i)});for(let i of e.commands)Rh(i,r,n)}var uo;function SO(){if(!uo){uo=new Map;for(let e of nd)Rh(e,"",uo)}return uo}function Ch(e){let t=SO().get(e);return t?[...t.arguments,...t.requiredOptions.map(n=>`${n} \u2026`)].join(" "):""}var Sh=["presentations","media","branding","knowledge","research","artifacts","agents","support"],rd={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"},EO="other";function PO(e){let t=e.category?.trim();return t&&t.length>0?t:EO}function Eh(e){let t=Sh.indexOf(e);return t===-1?Sh.length:t}function Pr(e){let t=new Map;for(let n of e){let r=PO(n),i=t.get(r);i?i.push(n):t.set(r,[n])}return[...t.entries()].sort(([n],[r])=>Eh(n)-Eh(r)||n.localeCompare(r)).map(([n,r])=>({capabilities:[...r].sort((i,o)=>i.name.localeCompare(o.name)),category:n}))}function id(e){return e.lifecycle?.mode==="background"}function od(e,t){let n=e.lifecycle?.status?.cliCommand?.trim();if(!(!id(e)||!n))return`${t} ${n} <run-id>`}function AO(e){switch(e.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 go(e){return e.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function TO(e,t){let n=od(e,t);return n?`run id \u2014 poll \`${n}\``:`immediate (${e.operation??"call"})`}function Rt(e,t){let n=["| Command | What it does | Takes | Returns | Cost | Scopes |","|---|---|---|---|---|---|"],r=e.map(i=>{let o=Ch(i.name),c=i.scopes?.length?i.scopes.map(l=>`\`${l}\``).join(", "):"\u2014";return`| \`${t} ${go(i.name)}\` | ${go(i.description??"")} | ${o?`\`${go(o)}\``:"\u2014"} | ${TO(i,t)} | ${AO(i)} | ${c} |`});return[...n,...r].join(`
383
- `)}function Se(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: ${go(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 Ph(e){return e.map(t=>`- [${t}](#${t.toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/ /g,"-")})`).join(`
384
- `)}function Ar(e){return[...new Set(e.flatMap(t=>[t.name,...t.lifecycle.status?.cliCommand?[t.lifecycle.status.cliCommand]:[]]))]}function be(e,t,n,r="direct-operation-smoke"){let i=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#${t}`,case:t,run:`pnpm smoke -- run ${e} --url <non-production-deployment>`,claim:`${i} ${n}`}}function Vn(e,t,n){return{level:"partial",boundary:"mocked-adapter-integration",kind:"integration",source:e,case:t,run:`pnpm exec vitest run ${e}`,claim:`In-memory adapter integration with mocked canonical operations; no real HTTP operation or fixture postcondition is reached. ${n}`}}function ad(e,t,n){return{level:"full",boundary:"real-cli-http-journey",kind:"smoke",source:`scripts/lib/deployment-smoke-catalog.ts#${t}`,case:t,run:`pnpm smoke:${e} -- --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 Ah="tests/integration/tool-surface/presentations.integration.test.ts",OO="tests/integration/tool-surface/branding.integration.test.ts";function Th(e){switch(e){case"create":return[Vn(Ah,"normalizes MCP and CLI starts into the same durable job input","MCP and CLI normalize the same generation input."),be("presentation","presentation.create","A real deck is generated and persisted.","ui-e2e")];case"export":return[be("presentation","presentation.export","Real PDF, PPTX, HTML, and PNG exports are validated.","ui-e2e")];case"presentation import":case"presentation import transform":return[be("presentation-import","presentation.import-powerpoint","A PowerPoint is imported, reviewed, and reopened.","ui-e2e")];case"presentation speaker-notes":case"presentation speaker-notes-status":return[be("presentation","presentation.speaker-notes","Persisted speaker notes are ready after reload.","ui-e2e")];default:return[]}}function $O(e){return["presentation video inspect","video library list"].includes(e)?[be("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(e)?[be("presentation-video-agent-edits","video.presentation.agent-edit-surfaces","Draft edits and restores persist through canonical agent operations.")]:e==="presentation video presenter"?[be("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(e)?[Vn(Ah,`generated MCP and CLI ${e}`,"The integration suite compares matching MCP and CLI adapter results.")]:e==="get"||e.startsWith("presentation speaker-notes")?Th(e):[]}function DO(e){if(["branding pronunciation listen","branding pronunciation listen status"].includes(e))return[{...be("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(e==="branding pronunciation set-batch")return[{...Vn("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(e))return[{...Vn("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(e))return[be("branding","branding.agent-read-surfaces","Brand reads resolve the same controlled brand across agent surfaces.")];if(e==="branding extract")return[be("branding","branding.extraction-approval-refusal","Only the approval refusal and no-charge boundary is proven.")];if(e==="branding create")return[be("branding","branding.create","Creation, idempotency, and plan-limit refusal reach the canonical operation.")];let t=[["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,i]of t)if(e.startsWith(n))return[be("branding",r,i)];return["branding star","branding default","branding delete"].some(n=>e.startsWith(n))?[be("branding","branding.lifecycle-pointers","Star, default, and deletion pointers reach canonical operations.")]:e==="branding update"?[be("branding","branding.record-fields","Rename and parent moves reach updateBrand.")]:e==="branding set"?[Vn(OO,"runs the free brand write on both lanes without an approval receipt","MCP and CLI invoke the same free brand write in memory.")]:[]}function NO(e){return["agent roster list","agent roster get","agent visibility set"].includes(e)?[ad("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(e)?[ad("agent-management","agent.management-primitives","Owned-Agent reads, configuration CAS, schedule transitions, replay, conflicts, and database postconditions are verified.")]:[]}function LO(e,t){return e==="presentation"?Th(t):e==="presentation-video"?$O(t):e==="agents"?NO(t):DO(t)}function sd(e,t){return Ar(t).map(n=>{let r=LO(e,n),i=r.length===0?"missing":r.some(o=>o.level==="full")?"full":"partial";return{command:n,evidence:r,level:i}})}function Oh(e){return e.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function Qt(e){let t=e.anyOf??[],n=t.some(i=>i.type==="null");return{inner:t.find(i=>i.type!=="null")??e,nullable:n}}function UO(e){let t=e.minimum!==void 0?String(e.minimum):e.exclusiveMinimum!==void 0?`>${e.exclusiveMinimum}`:void 0,n=e.maximum!==void 0?String(e.maximum):e.exclusiveMaximum!==void 0?`<${e.exclusiveMaximum}`:void 0;return t===void 0||n===void 0?"":` ${t}\u2013${n}`}function $h(e){let{inner:t}=Qt(e),n="value";return t.enum?n=t.enum.map(r=>`\`${String(r)}\``).join(" | "):t.type==="integer"||t.type==="number"?n=`${t.type}${UO(t)}`:t.type&&(n=t.type),t.default!==void 0&&(n+=`, default \`${String(t.default)}\``),n}function _O(e){let{inner:t,nullable:n}=Qt(e),r;return t.enum?r=t.enum.map(i=>`\`${String(i)}\``).join(" \\| "):t.type==="object"?t.additionalProperties&&t.additionalProperties!==!0?r="record":r=`object${dd(t)?" (see below)":""}`:r=t.type??"value",n?`${r} or \`null\``:r}function dd(e){let t=e.properties??{},n=Object.keys(t);return n.length>0&&n.every(r=>{let{inner:i}=Qt(t[r]);return i.properties===void 0&&!(i.additionalProperties&&i.additionalProperties!==!0)})}function Dh(e){return Object.keys(e).sort((t,n)=>t.localeCompare(n))}function Nh(e){let n=e.properties?.settings?.properties??{};return Object.keys(n).map(r=>({description:Oh(n[r].description??""),key:r,type:_O(n[r])}))}function Lh(e){let t=e.properties?.settings?.properties??{},n=[];for(let r of Object.keys(t)){let{inner:i}=Qt(t[r]);if(!dd(i))continue;let o=new Set(i.required??[]),c=Dh(i.properties??{}).map(l=>{let d=i.properties?.[l],g=o.size>0&&!o.has(l)?", optional":"";return`\`${l}\` (${$h(d)}${g})`});n.push(`\`${r}\` keys: ${c.join(", ")}.`)}return n}var jO=/([a-z0-9])([A-Z])/g;function Uh(e,t){let n=e.properties??{},r=e.properties?.settings?.properties??{},i=Object.keys(r).filter(c=>c.startsWith(t)&&dd(Qt(r[c]).inner)),o=[];for(let c of Dh(n)){if(!c.startsWith(t)||c.length===t.length||c.charAt(t.length)!==c.charAt(t.length).toUpperCase())continue;let l=c.charAt(t.length).toLowerCase()+c.slice(t.length+1),d=i.find(y=>{let v=Qt(r[y]).inner.properties??{};return l in v||Object.keys(v).some(x=>x.startsWith(l))}),g=d?(()=>{let y=Qt(r[d]).inner.properties??{};return Object.keys(y).find(v=>v===l||v.startsWith(l))??l})():l;o.push({description:Oh(n[c].description??""),flag:`--${c.replace(jO,"$1-$2").toLowerCase()}`,mapsTo:d?`${d}.${g}`:c,type:$h(n[c])})}return o}var qO=["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","study-set create","study-set list","study-set get","video library list","avatar options"];function MO(e){let t=Nh(e??{});if(t.length===0)return"This catalog does not carry the settings contract \u2014 run `presentation video settings --help` for the current fields.";let n=["| Key | Type / allowed values | Meaning |","|---|---|---|",...t.map(i=>`| \`${i.key}\` | ${i.type} | ${i.description} |`)].join(`
385
- `),r=Lh(e??{});return r.length>0?`${n}
399
+ `);import{randomUUID as rd}from"crypto";import{Command as Yt}from"commander";function hh(e,t){try{let n=JSON.parse(t);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error("not an object");return n}catch{a(`${e} must be a JSON object, e.g. --${e} '{"mode":"stock"}'`),process.exit(s.GENERAL_ERROR)}}async function yh(e,t,n){if(n.wait===!1){m(t);return}I(`Run ${t.runId} accepted (${t.status}). Waiting\u2026`);let r=await z(e,t.runId,n.teamId,n.maxAttempts);m(r)}var xO=new Yt("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",rd()).action(async e=>{try{m(await p("createWalkthroughUploadUrl",{fileName:e.fileName,fileSize:e.fileSize,fileType:e.fileType,teamId:e.teamId},e.idempotencyKey))}catch(t){a(u(t,"Upload URL failed")),process.exit(s.GENERAL_ERROR)}}),RO=new Yt("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",rd()).option("--no-wait","Return the run ID instead of waiting for narration").action(async(e,t)=>{try{let n=await p("createWalkthrough",{audience:t.audience,captions:t.captions,costMode:t.costMode,musicConfig:t.musicConfig?hh("music-config",t.musicConfig):void 0,presenterConfig:t.presenterConfig?hh("presenter-config",t.presenterConfig):void 0,sourceAudioVolume:t.sourceAudioVolume,sourceChatId:t.sourceChatId,sourceDurationSec:t.sourceDuration,sourceHeight:t.sourceHeight,sourceMediaType:t.sourceMediaType,sourceVideoUrl:e,sourceWidth:t.sourceWidth,targetLength:t.targetLength,teamId:t.teamId,title:t.title,tone:t.tone,voiceId:t.voiceId},t.idempotencyKey);await yh("createWalkthrough",n,{...t,maxAttempts:180})}catch(n){a(u(n,"Creation failed")),process.exit(s.GENERAL_ERROR)}}),CO=new Yt("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",rd()).option("--no-wait","Return the run ID instead of waiting for the render").action(async(e,t)=>{try{let n=await p("renderWalkthrough",{costMode:t.costMode,sourceAudioVolume:t.sourceAudioVolume,teamId:t.teamId,walkthroughId:e},t.idempotencyKey);await yh("renderWalkthrough",n,{...t,maxAttempts:300})}catch(n){a(u(n,"Render failed")),process.exit(s.GENERAL_ERROR)}}),SO=new Yt("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(e,t)=>{try{m(await R("createWalkthrough",e,t.teamId));return}catch(n){n instanceof P&&n.statusCode===404||(a(u(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR))}try{m(await R("renderWalkthrough",e,t.teamId))}catch(n){a(u(n,"Status lookup failed")),process.exit(s.GENERAL_ERROR)}}),EO=new Yt("get").description("Read one walkthrough").argument("<walkthrough-id>","Walkthrough ID").option("--team-id <id>","Workspace ID").action(async(e,t)=>{try{m(await p("getWalkthrough",{teamId:t.teamId,walkthroughId:e}))}catch(n){a(u(n,"Lookup failed")),process.exit(s.GENERAL_ERROR)}}),PO=new Yt("list").description("List walkthroughs in the workspace").option("--limit <count>","Maximum rows to return",Number).option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listWalkthroughs",{limit:e.limit,teamId:e.teamId}))}catch(t){a(u(t,"List failed")),process.exit(s.GENERAL_ERROR)}}),bh=new Yt("walkthrough").description("Recorded walkthroughs: narrated videos from screen captures").addCommand(xO).addCommand(RO).addCommand(CO).addCommand(SO).addCommand(EO).addCommand(PO);import{Command as xh,InvalidArgumentError as Rh}from"commander";var wh=["article","cheat-sheet","flashcards","microsite","presentation","quiz","survey","video"],vh=["cancelled","draft","failed","in-progress","published","ready","setup"],Ih=["mine","workspace"];function AO(e,t){return n=>{if(!t.includes(n))throw new Rh(`${e} expects one of: ${t.join(", ")}.`);return n}}function kh(e,t){return n=>{let r=n.split(",").map(o=>o.trim()).filter(Boolean);if(r.find(o=>!t.includes(o))||r.length===0)throw new Rh(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function TO(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var OO=new xh("list").description("List the workspace's in-flight, draft, failed, and finished work \u2014 continuation-first").option("--kinds <kinds>",`Filter to artifact kinds: ${wh.join(", ")}`,kh("--kinds",wh)).option("--lifecycle <states>",`Filter to lifecycle states: ${vh.join(", ")}`,kh("--lifecycle",vh)).option("--limit <n>","Maximum items to return (default 20, max 50)").option("--scope <scope>",`Whose work to list: ${Ih.join(", ")}`,AO("--scope",Ih)).option("--offset <n>","Zero-based result offset").option("--team-id <id>","Workspace ID").action(async e=>{try{m(await p("listWorkItems",{kinds:e.kinds,lifecycle:e.lifecycle,limit:e.limit?Number(e.limit):void 0,offset:e.offset?Number(e.offset):void 0,scope:e.scope,teamId:e.teamId}))}catch(t){TO(t,"Could not list work items")}}),Ch=new xh("work").description("Inspect the workspace's recent and in-flight work").addCommand(OO);var id=[ru,bu,bm,Yp,zf,Wu,Nu,vu,go,js,Kf,Of,xr,Ms,Ba,Ru,es,Xu,um,gm,ph,Ou,tm,am,ma,Tu,Fa,nd,cu,su,xu,uu,gu,Ha,iu,Im,Af,Df,Ff,Bf,Gf,bh,Du,Ch,_f];function Sh(e){for(let t of id)e.addCommand(t)}function Eh(e,t,n){let r=t?`${t} ${e.name()}`:e.name();n.set(r,{arguments:e.registeredArguments.filter(i=>i.required).map(i=>`<${i.name()}>`),requiredOptions:e.options.filter(i=>i.mandatory).map(i=>i.long).filter(i=>!!i)});for(let i of e.commands)Eh(i,r,n)}var fo;function $O(){if(!fo){fo=new Map;for(let e of id)Eh(e,"",fo)}return fo}function Ph(e){let t=$O().get(e);return t?[...t.arguments,...t.requiredOptions.map(n=>`${n} \u2026`)].join(" "):""}var Ah=["presentations","media","branding","knowledge","research","artifacts","agents","support"],od={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"},DO="other";function NO(e){let t=e.category?.trim();return t&&t.length>0?t:DO}function Th(e){let t=Ah.indexOf(e);return t===-1?Ah.length:t}function Ar(e){let t=new Map;for(let n of e){let r=NO(n),i=t.get(r);i?i.push(n):t.set(r,[n])}return[...t.entries()].sort(([n],[r])=>Th(n)-Th(r)||n.localeCompare(r)).map(([n,r])=>({capabilities:[...r].sort((i,o)=>i.name.localeCompare(o.name)),category:n}))}function ad(e){return e.lifecycle?.mode==="background"}function sd(e,t){let n=e.lifecycle?.status?.cliCommand?.trim();if(!(!ad(e)||!n))return`${t} ${n} <run-id>`}function LO(e){switch(e.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 ho(e){return e.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function UO(e,t){let n=sd(e,t);return n?`run id \u2014 poll \`${n}\``:`immediate (${e.operation??"call"})`}function Rt(e,t){let n=["| Command | What it does | Takes | Returns | Cost | Scopes |","|---|---|---|---|---|---|"],r=e.map(i=>{let o=Ph(i.name),c=i.scopes?.length?i.scopes.map(l=>`\`${l}\``).join(", "):"\u2014";return`| \`${t} ${ho(i.name)}\` | ${ho(i.description??"")} | ${o?`\`${ho(o)}\``:"\u2014"} | ${UO(i,t)} | ${LO(i)} | ${c} |`});return[...n,...r].join(`
400
+ `)}function Se(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: ${ho(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 Oh(e){return e.map(t=>`- [${t}](#${t.toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/ /g,"-")})`).join(`
401
+ `)}function Tr(e){return[...new Set(e.flatMap(t=>[t.name,...t.lifecycle.status?.cliCommand?[t.lifecycle.status.cliCommand]:[]]))]}function be(e,t,n,r="direct-operation-smoke"){let i=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#${t}`,case:t,run:`pnpm smoke -- run ${e} --url <non-production-deployment>`,claim:`${i} ${n}`}}function Fn(e,t,n){return{level:"partial",boundary:"mocked-adapter-integration",kind:"integration",source:e,case:t,run:`pnpm exec vitest run ${e}`,claim:`In-memory adapter integration with mocked canonical operations; no real HTTP operation or fixture postcondition is reached. ${n}`}}function dd(e,t,n){return{level:"full",boundary:"real-cli-http-journey",kind:"smoke",source:`scripts/lib/deployment-smoke-catalog.ts#${t}`,case:t,run:`pnpm smoke:${e} -- --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 $h="tests/integration/tool-surface/presentations.integration.test.ts",_O="tests/integration/tool-surface/branding.integration.test.ts";function Dh(e){switch(e){case"create":return[Fn($h,"normalizes MCP and CLI starts into the same durable job input","MCP and CLI normalize the same generation input."),be("presentation","presentation.create","A real deck is generated and persisted.","ui-e2e")];case"export":return[be("presentation","presentation.export","Real PDF, PPTX, HTML, and PNG exports are validated.","ui-e2e")];case"presentation import":case"presentation import transform":return[be("presentation-import","presentation.import-powerpoint","A PowerPoint is imported, reviewed, and reopened.","ui-e2e")];case"presentation speaker-notes":case"presentation speaker-notes-status":return[be("presentation","presentation.speaker-notes","Persisted speaker notes are ready after reload.","ui-e2e")];default:return[]}}function jO(e){return["presentation video inspect","video library list"].includes(e)?[be("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(e)?[be("presentation-video-agent-edits","video.presentation.agent-edit-surfaces","Draft edits and restores persist through canonical agent operations.")]:e==="presentation video presenter"?[be("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(e)?[Fn($h,`generated MCP and CLI ${e}`,"The integration suite compares matching MCP and CLI adapter results.")]:e==="get"||e.startsWith("presentation speaker-notes")?Dh(e):[]}function qO(e){if(["branding pronunciation listen","branding pronunciation listen status"].includes(e))return[{...be("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(e==="branding pronunciation set-batch")return[{...Fn("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(e))return[{...Fn("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(e))return[be("branding","branding.agent-read-surfaces","Brand reads resolve the same controlled brand across agent surfaces.")];if(e==="branding extract")return[be("branding","branding.extraction-approval-refusal","Only the approval refusal and no-charge boundary is proven.")];if(e==="branding create")return[be("branding","branding.create","Creation, idempotency, and plan-limit refusal reach the canonical operation.")];let t=[["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,i]of t)if(e.startsWith(n))return[be("branding",r,i)];return["branding star","branding default","branding delete"].some(n=>e.startsWith(n))?[be("branding","branding.lifecycle-pointers","Star, default, and deletion pointers reach canonical operations.")]:e==="branding update"?[be("branding","branding.record-fields","Rename and parent moves reach updateBrand.")]:e==="branding set"?[Fn(_O,"runs the free brand write on both lanes without an approval receipt","MCP and CLI invoke the same free brand write in memory.")]:[]}function MO(e){return["agent roster list","agent roster get","agent visibility set"].includes(e)?[dd("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(e)?[dd("agent-management","agent.management-primitives","Owned-Agent reads, configuration CAS, schedule transitions, replay, conflicts, and database postconditions are verified.")]:[]}function VO(e,t){return e==="presentation"?Dh(t):e==="presentation-video"?jO(t):e==="agents"?MO(t):qO(t)}function cd(e,t){return Tr(t).map(n=>{let r=VO(e,n),i=r.length===0?"missing":r.some(o=>o.level==="full")?"full":"partial";return{command:n,evidence:r,level:i}})}function Nh(e){return e.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function Qt(e){let t=e.anyOf??[],n=t.some(i=>i.type==="null");return{inner:t.find(i=>i.type!=="null")??e,nullable:n}}function FO(e){let t=e.minimum!==void 0?String(e.minimum):e.exclusiveMinimum!==void 0?`>${e.exclusiveMinimum}`:void 0,n=e.maximum!==void 0?String(e.maximum):e.exclusiveMaximum!==void 0?`<${e.exclusiveMaximum}`:void 0;return t===void 0||n===void 0?"":` ${t}\u2013${n}`}function Lh(e){let{inner:t}=Qt(e),n="value";return t.enum?n=t.enum.map(r=>`\`${String(r)}\``).join(" | "):t.type==="integer"||t.type==="number"?n=`${t.type}${FO(t)}`:t.type&&(n=t.type),t.default!==void 0&&(n+=`, default \`${String(t.default)}\``),n}function BO(e){let{inner:t,nullable:n}=Qt(e),r;return t.enum?r=t.enum.map(i=>`\`${String(i)}\``).join(" \\| "):t.type==="object"?t.additionalProperties&&t.additionalProperties!==!0?r="record":r=`object${ld(t)?" (see below)":""}`:r=t.type??"value",n?`${r} or \`null\``:r}function ld(e){let t=e.properties??{},n=Object.keys(t);return n.length>0&&n.every(r=>{let{inner:i}=Qt(t[r]);return i.properties===void 0&&!(i.additionalProperties&&i.additionalProperties!==!0)})}function Uh(e){return Object.keys(e).sort((t,n)=>t.localeCompare(n))}function _h(e){let n=e.properties?.settings?.properties??{};return Object.keys(n).map(r=>({description:Nh(n[r].description??""),key:r,type:BO(n[r])}))}function jh(e){let t=e.properties?.settings?.properties??{},n=[];for(let r of Object.keys(t)){let{inner:i}=Qt(t[r]);if(!ld(i))continue;let o=new Set(i.required??[]),c=Uh(i.properties??{}).map(l=>{let d=i.properties?.[l],g=o.size>0&&!o.has(l)?", optional":"";return`\`${l}\` (${Lh(d)}${g})`});n.push(`\`${r}\` keys: ${c.join(", ")}.`)}return n}var GO=/([a-z0-9])([A-Z])/g;function qh(e,t){let n=e.properties??{},r=e.properties?.settings?.properties??{},i=Object.keys(r).filter(c=>c.startsWith(t)&&ld(Qt(r[c]).inner)),o=[];for(let c of Uh(n)){if(!c.startsWith(t)||c.length===t.length||c.charAt(t.length)!==c.charAt(t.length).toUpperCase())continue;let l=c.charAt(t.length).toLowerCase()+c.slice(t.length+1),d=i.find(y=>{let v=Qt(r[y]).inner.properties??{};return l in v||Object.keys(v).some(x=>x.startsWith(l))}),g=d?(()=>{let y=Qt(r[d]).inner.properties??{};return Object.keys(y).find(v=>v===l||v.startsWith(l))??l})():l;o.push({description:Nh(n[c].description??""),flag:`--${c.replace(GO,"$1-$2").toLowerCase()}`,mapsTo:d?`${d}.${g}`:c,type:Lh(n[c])})}return o}var KO=["get","presentation video prepare","presentation video inspect","presentation video layout","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","study-set create","study-set list","study-set get","video library list","avatar options"];function WO(e){let t=_h(e??{});if(t.length===0)return"This catalog does not carry the settings contract \u2014 run `presentation video settings --help` for the current fields.";let n=["| Key | Type / allowed values | Meaning |","|---|---|---|",...t.map(i=>`| \`${i.key}\` | ${i.type} | ${i.description} |`)].join(`
402
+ `),r=jh(e??{});return r.length>0?`${n}
386
403
 
387
404
  ${r.join(`
388
- `)}`:n}function VO(e){let t=Uh(e??{},"caption");return t.length===0?"":["The caption fields also take typed flags \u2014 pass them or the matching","`settings` key, never both:","","| Flag | Maps to | Meaning |","|---|---|---|",...t.map(n=>`| \`${n.flag}\` | \`settings.${n.mapsTo}\` | ${n.description} |`)].join(`
389
- `)}function FO(e){let t=new Map(e.map(n=>[n.name,n]));return qO.map(n=>t.get(n)).filter(n=>n!==void 0)}function Fn(e,t){let{cmd:n}=e,r=FO(t.capabilities),i=t.capabilities.find(l=>l.name==="presentation video"),o=i?od(i,n)??`${n} presentation video status <run-id>`:`${n} presentation video status <run-id>`,c=t.settingsSchemas.updatePresentationVideoSettings;return`${Se(t,e)}
405
+ `)}`:n}function JO(e){let t=qh(e??{},"caption");return t.length===0?"":["The caption fields also take typed flags \u2014 pass them or the matching","`settings` key, never both:","","| Flag | Maps to | Meaning |","|---|---|---|",...t.map(n=>`| \`${n.flag}\` | \`settings.${n.mapsTo}\` | ${n.description} |`)].join(`
406
+ `)}function zO(e){let t=new Map(e.map(n=>[n.name,n]));return KO.map(n=>t.get(n)).filter(n=>n!==void 0)}function Bn(e,t){let{cmd:n}=e,r=zO(t.capabilities),i=t.capabilities.find(l=>l.name==="presentation video"),o=i?sd(i,n)??`${n} presentation video status <run-id>`:`${n} presentation video status <run-id>`,c=t.settingsSchemas.updatePresentationVideoSettings;return`${Se(t,e)}
390
407
 
391
408
  # Deck \u2192 MP4 (\`${n} presentation video\`)
392
409
 
@@ -526,22 +543,45 @@ ${n} presentation video refresh <project-id> # re-pull slid
526
543
  ${n} presentation video versions <project-id> # drafts are append-only; nothing is lost
527
544
  \`\`\`
528
545
 
529
- **Captions first.** When \`captions\` is on, check that the caption box does
530
- not cover slide content: the default box is centered at y 0.84 with height
531
- 0.14, which can overlap content near the bottom of a typical slide. Compare
532
- the box against the deck's own slide copy first (\`${n} get <presentation-id>
533
- --include slides\` is free). Seeing it for real means rendering ONE scene,
534
- and that render is billed: ask the user before running it, the same way you
535
- ask before the MP4 \u2014 \`--yes\` is not their consent. A rendered scene is
536
- reused by the final render, so it is not charged twice:
546
+ **Then the layout, while it is still free.** Once slide previews are
547
+ prepared, every scene's geometry is measurable \u2014 the slide's own content
548
+ blocks against the caption box and the presenter box, resolved with the same
549
+ math the renderer uses. Run the layout report before asking for anything
550
+ paid:
551
+
552
+ \`\`\`bash
553
+ ${n} presentation video layout <project-id> # free
554
+ ${n} presentation video layout <project-id> --format json
555
+ \`\`\`
556
+
557
+ Per scene it reports \`blocks[]\`, \`overlays[]\` (the caption box when
558
+ captions are on, the presenter box, occupied layers), \`conflicts[]\` with
559
+ severity \u2014 a caption over body copy is a defect, a caption over a logo is
560
+ usually fine \u2014 \`freeRegions[]\` the empty bands and corners placements can
561
+ move into, and a typed \`status\` when geometry is not ready yet (the remedy
562
+ is \`${n} presentation video previews prepare\`). A scene that is not ready
563
+ is never reported as clean.
564
+
565
+ The default caption box is centered at y 0.84 with height 0.14, which sits on
566
+ slide content that runs to the bottom of the frame, and a bottom-corner
567
+ presenter can cover a graphic on that side. Resolve every \`conflicts[]\`
568
+ entry before asking for a render: move or restyle captions with the typed
569
+ caption flags under [Render settings](#render-settings), move or remove the
570
+ presenter, or take a layer off the scene \u2014 then run \`layout\` again to
571
+ confirm it is clean.
572
+
573
+ **Captions first.** When \`captions\` is on, the layout report already
574
+ shows whether the caption box sits on slide content. Seeing it for real
575
+ still means rendering ONE scene, and that render is billed: ask the user before running it,
576
+ the same way you ask before the MP4 \u2014 \`--yes\` is not their consent.
577
+ A rendered scene is reused by the final render, so it is not charged twice:
537
578
 
538
579
  \`\`\`bash
539
580
  ${n} presentation video scene render <project-id> <scene-id> --yes
540
581
  \`\`\`
541
582
 
542
- If the box sits on top of slide content, move or restyle it with the typed
543
- caption flags under [Render settings](#render-settings), then check one scene
544
- again (billed again \u2014 ask again).
583
+ Use the billed scene render to settle a judgment call the report cannot
584
+ answer \u2014 never as the first look at layout.
545
585
 
546
586
  **Then, the spend.** Only once the user has read the script and approved the
547
587
  settings: \`${n} presentation video <presentation-id> --yes\`. That is the
@@ -555,7 +595,7 @@ Both \`presentation video settings --settings\` and the render's own
555
595
  file. At least one key is required. The table below is projected from the
556
596
  contract the server validates \u2014 a key that is not listed is refused.
557
597
 
558
- ${MO(c)}
598
+ ${WO(c)}
559
599
 
560
600
  Caption geometry is frame-relative: \`x\`/\`y\` are the box's CENTER (0\u20131) and
561
601
  \`width\`/\`height\` its size.
@@ -572,7 +612,7 @@ rest. Passing both forms of one setting (\`voice\` and \`voiceId\`, or
572
612
  \`presenter\` and \`avatarId\`) is refused rather than silently ranked;
573
613
  \`presenter: null\` remains how a presenter is removed.
574
614
 
575
- ${VO(c)}
615
+ ${JO(c)}
576
616
 
577
617
  Examples:
578
618
 
@@ -675,7 +715,7 @@ ${Rt(r,n)}
675
715
 
676
716
  If something you need is not in this table, do not conclude it is missing \u2014
677
717
  run \`${n} capabilities --search video\`.
678
- `}function _h(e){return e==="presentation video"||e.startsWith("presentation video ")||e.startsWith("presentation video-")}function cd(e,t){let n=new Set(t.capabilities.map(r=>r.name));return e.flow.filter(r=>n.has(r))}function BO(e,t){let n=new Set(t.capabilities.map(i=>i.name)),r=(i,o)=>n.has(i)?`- \`${e.cmd} ${i}\` \u2014 ${o}`:void 0;return`# Presentation workflow
718
+ `}function Mh(e){return e==="presentation video"||e.startsWith("presentation video ")||e.startsWith("presentation video-")}function md(e,t){let n=new Set(t.capabilities.map(r=>r.name));return e.flow.filter(r=>n.has(r))}function HO(e,t){let n=new Set(t.capabilities.map(i=>i.name)),r=(i,o)=>n.has(i)?`- \`${e.cmd} ${i}\` \u2014 ${o}`:void 0;return`# Presentation workflow
679
719
 
680
720
  Use this flow for decks, not MP4 production or brand-library maintenance.
681
721
 
@@ -692,7 +732,7 @@ ${[r("create","create a deck from a topic and context"),r("presentation import",
692
732
  `)}
693
733
 
694
734
  For narration, scenes, presenters, captions, or MP4 output, load \`${e.name}-presentation-video\`.
695
- `}function GO(e,t){let n=cd(Bn.branding,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
735
+ `}function XO(e,t){let n=md(Gn.branding,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
696
736
  `);return`# Branding workflow
697
737
 
698
738
  Branding owns saved private and team brand profiles. It does not edit arbitrary deck HTML.
@@ -709,7 +749,7 @@ Branding owns saved private and team brand profiles. It does not edit arbitrary
709
749
  ${n||"No common anchors are present in this snapshot; run discovery before acting."}
710
750
 
711
751
  Read [commands.md](commands.md) for every available brand operation and its scopes.
712
- `}function KO(e,t){let n=cd(Bn.agents,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
752
+ `}function YO(e,t){let n=md(Gn.agents,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
713
753
  `);return`# Agents workflow
714
754
 
715
755
  This skill owns scheduled Mindframes Agents. It is not a guide for software-development agents.
@@ -726,7 +766,7 @@ This skill owns scheduled Mindframes Agents. It is not a guide for software-deve
726
766
  ${n||"No common anchors are present in this snapshot; run discovery before acting."}
727
767
 
728
768
  Read [commands.md](commands.md) for current inputs, outputs, scopes, and exact CLI help.
729
- `}var WO=[{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."]}],JO=[{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."]}],zO=[{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."]}],HO=[{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."]}],Bn={presentation:{type:"presentation",title:"Presentation",description:e=>`Use whenever the user wants to create, import, inspect, export, organize, share, delete, or edit a ${e} presentation, deck, slides, pitch deck, or PowerPoint. Do not use for turning an existing deck into an MP4 (use ${e}-presentation-video), video from scratch (use ${e}-video), or maintaining saved brands (use ${e}-branding).`,discoveryQuery:"presentation",select:e=>e.category==="presentations"&&!_h(e.name),flow:["create","presentation status","get","export"],workflow:BO,evals:WO},"presentation-video":{type:"presentation-video",title:"Presentation to MP4",description:e=>`Use whenever an existing ${e} 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 ${e}-video), ordinary slide editing (use ${e}-presentation), or brand maintenance (use ${e}-branding).`,discoveryQuery:"presentation video",select:e=>_h(e.name)||e.name==="presentation speaker-notes"||e.name==="get"||e.name==="avatar options"||e.name==="video library list",flow:["presentation video prepare","presentation video inspect","presentation video settings","presentation video","presentation video status"],workflow:Fn,evals:JO},branding:{type:"branding",title:"Branding",description:e=>`Use whenever the user wants to discover, create, inspect, or maintain private or team ${e} 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:e=>e.category==="branding",flow:["branding list","branding profile","branding set","branding sync"],workflow:GO,evals:zO},agents:{type:"agents",title:"Agents",description:e=>`Use for scheduled ${e} 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:e=>e.category==="agents",flow:["agent list","agent roster list","agent roster get","agent visibility set"],workflow:KO,evals:HO}};function fo(e,t){return t.capabilities.filter(Bn[e].select).sort((n,r)=>n.name.localeCompare(r.name))}function XO(e,t,n){let r=fo(n.type,t),i=new Set(r.map(c=>c.name)),o=Ar(r).filter(c=>!i.has(c));return`${Se(t,e)}
769
+ `}var QO=[{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."]}],ZO=[{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."]}],e$=[{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."]}],t$=[{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."]}],Gn={presentation:{type:"presentation",title:"Presentation",description:e=>`Use whenever the user wants to create, import, inspect, export, organize, share, delete, or edit a ${e} presentation, deck, slides, pitch deck, or PowerPoint. Do not use for turning an existing deck into an MP4 (use ${e}-presentation-video), video from scratch (use ${e}-video), or maintaining saved brands (use ${e}-branding).`,discoveryQuery:"presentation",select:e=>e.category==="presentations"&&!Mh(e.name),flow:["create","presentation status","get","export"],workflow:HO,evals:QO},"presentation-video":{type:"presentation-video",title:"Presentation to MP4",description:e=>`Use whenever an existing ${e} 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 ${e}-video), ordinary slide editing (use ${e}-presentation), or brand maintenance (use ${e}-branding).`,discoveryQuery:"presentation video",select:e=>Mh(e.name)||e.name==="presentation speaker-notes"||e.name==="get"||e.name==="avatar options"||e.name==="video library list",flow:["presentation video prepare","presentation video inspect","presentation video settings","presentation video","presentation video status"],workflow:Bn,evals:ZO},branding:{type:"branding",title:"Branding",description:e=>`Use whenever the user wants to discover, create, inspect, or maintain private or team ${e} 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:e=>e.category==="branding",flow:["branding list","branding profile","branding set","branding sync"],workflow:XO,evals:e$},agents:{type:"agents",title:"Agents",description:e=>`Use for scheduled ${e} 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:e=>e.category==="agents",flow:["agent list","agent roster list","agent roster get","agent visibility set"],workflow:YO,evals:t$}};function yo(e,t){return t.capabilities.filter(Gn[e].select).sort((n,r)=>n.name.localeCompare(r.name))}function n$(e,t,n){let r=yo(n.type,t),i=new Set(r.map(c=>c.name)),o=Tr(r).filter(c=>!i.has(c));return`${Se(t,e)}
730
770
 
731
771
  # ${n.title} commands
732
772
 
@@ -738,7 +778,7 @@ ${o.length?`## Recovery commands
738
778
  ${o.map(c=>`- \`${e.cmd} ${c}\``).join(`
739
779
  `)}
740
780
  `:""}
741
- `}function YO(e,t,n){let r=sd(n.type,fo(n.type,t)),i=r.map(g=>{let y=g.evidence.length?g.evidence.map(x=>`**${x.kind}** ${x.source} \u2014 ${x.case}`).join("<br>"):"No non-unit evidence registered.",v=g.evidence.length?g.evidence.map(x=>x.claim).join(" "):"Do not claim integration or smoke coverage for this command.";return`| \`${e.cmd} ${g.command}\` | **${g.level.toUpperCase()}** | ${y} | ${v} |`}),o=[...new Set(r.flatMap(g=>g.evidence.map(y=>y.run)))],c=r.filter(g=>g.level==="full").length,l=r.filter(g=>g.level==="partial").length,d=r.length-c-l;return`${Se(t,e)}
781
+ `}function r$(e,t,n){let r=cd(n.type,yo(n.type,t)),i=r.map(g=>{let y=g.evidence.length?g.evidence.map(x=>`**${x.kind}** ${x.source} \u2014 ${x.case}`).join("<br>"):"No non-unit evidence registered.",v=g.evidence.length?g.evidence.map(x=>x.claim).join(" "):"Do not claim integration or smoke coverage for this command.";return`| \`${e.cmd} ${g.command}\` | **${g.level.toUpperCase()}** | ${y} | ${v} |`}),o=[...new Set(r.flatMap(g=>g.evidence.map(y=>y.run)))],c=r.filter(g=>g.level==="full").length,l=r.filter(g=>g.level==="partial").length,d=r.length-c-l;return`${Se(t,e)}
742
782
 
743
783
  # ${n.title} non-unit evidence
744
784
 
@@ -759,9 +799,9 @@ Smoke runs require an approved non-production target and their catalog prerequis
759
799
  ${o.length?o.join(`
760
800
  `):"# No non-unit evidence registered."}
761
801
  \`\`\`
762
- `}function jh(e){return`'${e.replace(/'/g,`'"'"'`)}'`}function QO(e,t,n){let r=fo(n.type,t),i=Ar(r),o=sd(n.type,r),c=o.filter(g=>g.level==="missing").map(g=>g.command).join(`
802
+ `}function Vh(e){return`'${e.replace(/'/g,`'"'"'`)}'`}function i$(e,t,n){let r=yo(n.type,t),i=Tr(r),o=cd(n.type,r),c=o.filter(g=>g.level==="missing").map(g=>g.command).join(`
763
803
  `),l=o.filter(g=>g.level==="partial").map(g=>g.command).join(`
764
- `),d=jh(e.cmd);return[{path:"scripts/check-auth.sh",executable:!0,content:`#!/usr/bin/env sh
804
+ `),d=Vh(e.cmd);return[{path:"scripts/check-auth.sh",executable:!0,content:`#!/usr/bin/env sh
765
805
  set -eu
766
806
  CLI=${d}
767
807
  command -v "$CLI" >/dev/null 2>&1 || { echo "$CLI is not installed" >&2; exit 127; }
@@ -771,7 +811,7 @@ printf '%s\\n' "Authentication and feature catalog are ready."
771
811
  `},{path:"scripts/discover-capabilities.sh",executable:!0,content:`#!/usr/bin/env sh
772
812
  set -eu
773
813
  CLI=${d}
774
- QUERY=\${1:-${jh(n.discoveryQuery)}}
814
+ QUERY=\${1:-${Vh(n.discoveryQuery)}}
775
815
  "$CLI" capabilities --search "$QUERY" --format json
776
816
  `},{path:"scripts/verify-help.sh",executable:!0,content:`#!/usr/bin/env sh
777
817
  set -eu
@@ -793,7 +833,7 @@ while IFS= read -r REQUIRED; do
793
833
  [ -z "$REQUIRED" ] && continue
794
834
  printf '%s\\n' "$AVAILABLE" | grep -Fqx "$REQUIRED" || { echo "Missing required capability: $REQUIRED" >&2; exit 1; }
795
835
  done <<'COMMANDS'
796
- ${cd(n,t).join(`
836
+ ${md(n,t).join(`
797
837
  `)}
798
838
  COMMANDS
799
839
  printf '%s\\n' "${n.title} flow anchors are available."
@@ -814,8 +854,8 @@ if [ -n "$PARTIAL" ] || [ -n "$MISSING" ]; then
814
854
  exit 1
815
855
  fi
816
856
  printf '%s\\n' 'Every documented command has full real-CLI journey evidence.'
817
- `}]}function ZO(e,t){return{path:"evals/evals.json",content:`${JSON.stringify({skill_name:e,evals:t.map(n=>({...n,files:[],expectations:[...n.expectations,"Consults references/coverage.md and never reports PARTIAL or MISSING as full command parity."]}))},null,2)}
818
- `}}function Ke(e,t,n){let r=Bn[n],i=`${e.name}-${n}`,o=fo(n,t).length;return`---
857
+ `}]}function o$(e,t){return{path:"evals/evals.json",content:`${JSON.stringify({skill_name:e,evals:t.map(n=>({...n,files:[],expectations:[...n.expectations,"Consults references/coverage.md and never reports PARTIAL or MISSING as full command parity."]}))},null,2)}
858
+ `}}function Ke(e,t,n){let r=Gn[n],i=`${e.name}-${n}`,o=yo(n,t).length;return`---
819
859
  name: ${i}
820
860
  description: >-
821
861
  ${r.description(e.name)}
@@ -847,7 +887,7 @@ Use this narrow workflow. Do not infer command names or reuse flags from UI, API
847
887
  - \`scripts/check-flow.sh\` \u2014 verify minimum flow anchors exist.
848
888
  - \`scripts/check-coverage.sh\` \u2014 fail unless every documented command has full real-CLI evidence.
849
889
  - \`evals/evals.json\` \u2014 realistic trigger and workflow evaluations.
850
- `}function Gn(e,t,n){let r=Bn[n];return[{name:"commands",content:XO(e,t,r)},{name:"coverage",content:YO(e,t,r)},{name:"workflow",content:r.workflow(e,t)}]}function Kn(e,t,n){let r=Bn[n];return[...QO(e,t,r),ZO(`${e.name}-${n}`,r.evals)]}var e$=["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 ld(e){let t=new Map(e.map(n=>[n.name,n]));return e$.map(n=>t.get(n)).filter(n=>n!==void 0)}function ho(e,t){let{cmd:n}=e,r=ld(t.capabilities);return`${Se(t,e)}
890
+ `}function Kn(e,t,n){let r=Gn[n];return[{name:"commands",content:n$(e,t,r)},{name:"coverage",content:r$(e,t,r)},{name:"workflow",content:r.workflow(e,t)}]}function Wn(e,t,n){let r=Gn[n];return[...i$(e,t,r),o$(`${e.name}-${n}`,r.evals)]}var a$=["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 pd(e){let t=new Map(e.map(n=>[n.name,n]));return a$.map(n=>t.get(n)).filter(n=>n!==void 0)}function bo(e,t){let{cmd:n}=e,r=pd(t.capabilities);return`${Se(t,e)}
851
891
 
852
892
  # Video from scratch (\`${n} video\`)
853
893
 
@@ -1021,17 +1061,17 @@ ${Rt(r,n)}
1021
1061
 
1022
1062
  If something you need is not in this table, do not conclude it is missing \u2014
1023
1063
  run \`${n} capabilities --search video\`.
1024
- `}var t$=12,n$={media:"video.md",presentations:"deck-to-video.md"};function r$(e,t,n,r){let{cmd:i}=e,o=rd[n]??n,c=r.filter(id),l=r.filter(y=>y.billing!==void 0&&y.billing!=="free"),d=n$[n],g=["Every capability",...c.length>0?["Background operations"]:[]];return`${Se(t,e)}
1064
+ `}var s$=12,d$={media:"video.md",presentations:"deck-to-video.md"};function c$(e,t,n,r){let{cmd:i}=e,o=od[n]??n,c=r.filter(ad),l=r.filter(y=>y.billing!==void 0&&y.billing!=="free"),d=d$[n],g=["Every capability",...c.length>0?["Background operations"]:[]];return`${Se(t,e)}
1025
1065
 
1026
1066
  # ${n} \u2014 ${o}
1027
1067
 
1028
1068
  ${r.length} capabilit${r.length===1?"y":"ies"} in this category${l.length>0?`, ${l.length} of which ${l.length===1?"costs":"cost"} credits or ${l.length===1?"counts":"count"} against a plan quota`:", all free"}.${d?`
1029
1069
 
1030
1070
  Step-by-step flow: [${d}](${d}).`:""}
1031
- ${r.length>t$?`
1071
+ ${r.length>s$?`
1032
1072
  ## Contents
1033
1073
 
1034
- ${Ph(g)}
1074
+ ${Oh(g)}
1035
1075
  `:""}
1036
1076
  ## Every capability
1037
1077
 
@@ -1047,12 +1087,12 @@ ${c.map(y=>`- \`${i} ${y.name}\` \u2192 \`${i} ${y.lifecycle?.status?.cliCommand
1047
1087
  `:""}
1048
1088
  Anything missing here? Run \`${i} capabilities --category ${n}\` \u2014 the
1049
1089
  catalog is authoritative and always current; this file is a snapshot of it.
1050
- `}function qh(e,t,n={}){let r=[{content:Fn(e,t),name:"deck-to-video"},{content:ho(e,t),name:"video"}];for(let{capabilities:i,category:o}of Pr(t.capabilities)){let c=n[o];r.push({content:r$(e,t,o,i)+(c?`
1090
+ `}function Fh(e,t,n={}){let r=[{content:Bn(e,t),name:"deck-to-video"},{content:bo(e,t),name:"video"}];for(let{capabilities:i,category:o}of Ar(t.capabilities)){let c=n[o];r.push({content:c$(e,t,o,i)+(c?`
1051
1091
  ---
1052
1092
 
1053
- ${c}`:""),name:o})}return r}function Mh(e){let t=[{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 Pr(e.capabilities))t.push({file:`${r}.md`,when:`${rd[r]??r} (${n.length} commands).`});return t}var i$=[{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:"ad-template list",intent:'"Use our approved ad templates" \u2014 read them; a person approves in the app',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"}],o$=["ai-connections","capabilities","config","delete","derive","export","footage","ideas","import","list","login","logout","runner","skill","templates","whoami"];function Tr(e,t=Gr("rendered without a catalog fetch")){let{name:n,cmd:r,pkg:i}=e,o=new Map(t.capabilities.map(v=>[v.name,v])),c=i$.filter(v=>o.has(v.capability)).map(v=>`| ${v.intent} | \`${r} ${v.capability}${v.suffix??""}\` | [${v.reference}](references/${v.reference}) |`).join(`
1054
- `),d=Pr(t.capabilities).map(({capabilities:v,category:x})=>`${x} (${v.length})`).join(", "),g=Mh(t).map(({file:v,when:x})=>`| [references/${v}](references/${v}) | ${x} |`).join(`
1055
- `),y=[...new Set([...t.capabilities.map(v=>v.name.split(" ")[0]),...o$])].sort().map(v=>`\`${v}\``).join(", ");return`---
1093
+ ${c}`:""),name:o})}return r}function Bh(e){let t=[{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 Ar(e.capabilities))t.push({file:`${r}.md`,when:`${od[r]??r} (${n.length} commands).`});return t}var l$=[{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:"ad-template list",intent:'"Use our approved ad templates" \u2014 read them; a person approves in the app',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"}],m$=["ai-connections","capabilities","config","delete","derive","export","footage","ideas","import","list","login","logout","runner","skill","templates","whoami"];function Or(e,t=Kr("rendered without a catalog fetch")){let{name:n,cmd:r,pkg:i}=e,o=new Map(t.capabilities.map(v=>[v.name,v])),c=l$.filter(v=>o.has(v.capability)).map(v=>`| ${v.intent} | \`${r} ${v.capability}${v.suffix??""}\` | [${v.reference}](references/${v.reference}) |`).join(`
1094
+ `),d=Ar(t.capabilities).map(({capabilities:v,category:x})=>`${x} (${v.length})`).join(", "),g=Bh(t).map(({file:v,when:x})=>`| [references/${v}](references/${v}) | ${x} |`).join(`
1095
+ `),y=[...new Set([...t.capabilities.map(v=>v.name.split(" ")[0]),...m$])].sort().map(v=>`\`${v}\``).join(", ");return`---
1056
1096
  name: ${n}
1057
1097
  description: >-
1058
1098
  Route any ${n} CLI task to the smallest installed domain skill. Trigger for
@@ -1118,7 +1158,7 @@ ${g}
1118
1158
  Run \`${r} <group> --help\` for any of these:
1119
1159
 
1120
1160
  ${y}
1121
- `}function Or(e){let{name:t,cmd:n}=e;return`---
1161
+ `}function $r(e){let{name:t,cmd:n}=e;return`---
1122
1162
  name: ${t}-presentation-edit
1123
1163
  description: >
1124
1164
  Use ONLY when editing an already-created presentation that has real slides:
@@ -1403,8 +1443,8 @@ Do NOT render or export the presentation \u2014 that's handled by the app.
1403
1443
  | Create brand-new presentation (5+ slides, new topic) | \`${n} create ...\` via CLI |
1404
1444
  | Redesign the whole deck | \`${n} create ...\` via CLI, then sync |
1405
1445
  | User provides a URL to base the presentation on | \`${n} scrape <url>\` \u2192 \`${n} create ...\` |
1406
- `}function $r(e,t){return Ke(e,t,"presentation")}var a$=[{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 Dr(e,t){let{cmd:n,name:r,pkg:i}=e,o=new Set(t.capabilities.map(d=>d.name)),c=a$.filter(d=>o.has(d.capability)).map((d,g)=>`${g+1}. \`${n} ${d.capability}\` \u2014 ${d.when}`).join(`
1407
- `),l=ld(t.capabilities).length;return`---
1446
+ `}function Dr(e,t){return Ke(e,t,"presentation")}var p$=[{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 Nr(e,t){let{cmd:n,name:r,pkg:i}=e,o=new Set(t.capabilities.map(d=>d.name)),c=p$.filter(d=>o.has(d.capability)).map((d,g)=>`${g+1}. \`${n} ${d.capability}\` \u2014 ${d.when}`).join(`
1447
+ `),l=pd(t.capabilities).length;return`---
1408
1448
  name: ${r}-video
1409
1449
  description: >-
1410
1450
  Use when a video must be built from scratch \u2014 a brief, a script, a storyboard,
@@ -1469,16 +1509,16 @@ ${n} video <sub> --help
1469
1509
  \`\`\`
1470
1510
 
1471
1511
  The catalog is authoritative and always current; this file is a snapshot of it.
1472
- `}function Vh(e,t){return[{content:ho(e,t),name:"video"},{content:Fn(e,t),name:"deck-to-video"}]}import{chmodSync as l$,existsSync as gd,mkdirSync as ud,readFileSync as m$,rmSync as p$,writeFileSync as yo}from"fs";import{homedir as Kh}from"os";import{basename as u$,dirname as g$,join as Ye,relative as f$,resolve as Nr}from"path";var Zt=[{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"}];import{createHash as s$}from"crypto";var Fh="mindframes.app-skill.json";function md(){return"0.3.27"}function pd(e,t,n){let r=s$("sha256");r.update(e);for(let i of t??[])r.update("\0ref:"),r.update(i.name),r.update("\0"),r.update(i.content);for(let i of[...n??[]].sort((o,c)=>o.path.localeCompare(c.path)))r.update("\0file:"),r.update(i.path),r.update("\0"),r.update(i.content);return r.digest("hex")}function d$(e){let t=e.match(/^description:\s*(.*)$/m);if(!t)return"";let n=t[1].trim().replace(/^["']|["']$/g,"");if(!n||/^[>|][-+]?$/.test(n)){let r=(t.index??0)+t[0].length,i=[];for(let o of e.slice(r).split(`
1473
- `).slice(1)){if(!/^\s+\S/.test(o))break;i.push(o.trim())}return i.join(" ").replace(/^["']|["']$/g,"")}return n}function c$(e,t){return["SKILL.md",...(e??[]).map(n=>`references/${n.name}.md`),...(t??[]).map(n=>n.path)]}function Bh(e,t){return{schemaVersion:1,id:e.name,name:e.name,version:md(),apiBaseUrl:e.url,mcp:{name:e.name,url:`${e.url.replace(/\/$/,"")}/api/mcp`},skills:t.map(n=>({slug:n.name,description:d$(n.content),sha256:pd(n.content,n.references,n.files),files:c$(n.references,n.files)}))}}var h$={sonnet:"claude-sonnet-5.5",haiku:"claude-haiku-4.5",opus:"claude-opus-5.5"},y$=["permissionMode","skills","subagentType"];function b$(e,t){if(t!=="copilot")return e;let n=e.match(/^---\n([\s\S]*?)\n---\n/);if(!n)return Gh(e);let r=n[1],i=e.slice((n.index??0)+n[0].length);r=r.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(c,l,d,g)=>`${l}${h$[d]??d}${g}`);for(let c of y$)r=r.replace(new RegExp(`^${c}:[^
1512
+ `}function Gh(e,t){return[{content:bo(e,t),name:"video"},{content:Bn(e,t),name:"deck-to-video"}]}import{chmodSync as h$,existsSync as hd,mkdirSync as fd,readFileSync as y$,rmSync as b$,writeFileSync as wo}from"fs";import{homedir as zh}from"os";import{basename as w$,dirname as v$,join as Ye,relative as I$,resolve as Lr}from"path";var Zt=[{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"}];import{createHash as u$}from"crypto";var Kh="mindframes.app-skill.json";function ud(){return"0.3.28"}function gd(e,t,n){let r=u$("sha256");r.update(e);for(let i of t??[])r.update("\0ref:"),r.update(i.name),r.update("\0"),r.update(i.content);for(let i of[...n??[]].sort((o,c)=>o.path.localeCompare(c.path)))r.update("\0file:"),r.update(i.path),r.update("\0"),r.update(i.content);return r.digest("hex")}function g$(e){let t=e.match(/^description:\s*(.*)$/m);if(!t)return"";let n=t[1].trim().replace(/^["']|["']$/g,"");if(!n||/^[>|][-+]?$/.test(n)){let r=(t.index??0)+t[0].length,i=[];for(let o of e.slice(r).split(`
1513
+ `).slice(1)){if(!/^\s+\S/.test(o))break;i.push(o.trim())}return i.join(" ").replace(/^["']|["']$/g,"")}return n}function f$(e,t){return["SKILL.md",...(e??[]).map(n=>`references/${n.name}.md`),...(t??[]).map(n=>n.path)]}function Wh(e,t){return{schemaVersion:1,id:e.name,name:e.name,version:ud(),apiBaseUrl:e.url,mcp:{name:e.name,url:`${e.url.replace(/\/$/,"")}/api/mcp`},skills:t.map(n=>({slug:n.name,description:g$(n.content),sha256:gd(n.content,n.references,n.files),files:f$(n.references,n.files)}))}}var k$={sonnet:"claude-sonnet-5.5",haiku:"claude-haiku-4.5",opus:"claude-opus-5.5"},x$=["permissionMode","skills","subagentType"];function R$(e,t){if(t!=="copilot")return e;let n=e.match(/^---\n([\s\S]*?)\n---\n/);if(!n)return Jh(e);let r=n[1],i=e.slice((n.index??0)+n[0].length);r=r.replace(/^(model:\s*)(\S+)([ \t]*)$/m,(c,l,d,g)=>`${l}${k$[d]??d}${g}`);for(let c of x$)r=r.replace(new RegExp(`^${c}:[^
1474
1514
  ]*
1475
- ?`,"m"),"");r=r.replace(/\n+$/,"");let o=Gh(i);return`---
1515
+ ?`,"m"),"");r=r.replace(/\n+$/,"");let o=Jh(i);return`---
1476
1516
  ${r}
1477
1517
  ---
1478
- ${o}`}function Gh(e){return e.replace(/\bAskUserQuestion\b/g,"ask the user directly in your response").replace(/\*\*Construct the Task prompt:\*\*/g,"**Construct the Task prompt (must be fully self-contained \u2014 sub-agents cannot read this conversation's history):**").replace(/\*\*Wait for all agents to complete\*\*/g,"**Wait for all agents to complete** (monitor with `/tasks` in Copilot CLI)").replace("**Launch ALL scene agents in parallel**","**Launch ALL scene agents in parallel** \u2014 each agent must write to its own `Scene[NN][Name].tsx` file. Two agents writing to the same file will silently overwrite each other (no error). Verify unique filenames before spawning.")}function Wh(e,t){let n=Nr(e),r=Nr(e,t);if(f$(n,r).startsWith("..")||Nr(r)!==r.replace(/\.\./g,""))throw new Error(`Invalid path: "${t}" would escape base directory`);return r}var Jh=".mf-skill.json";function w$(e){try{let t=JSON.parse(m$(Ye(e,Jh),"utf-8"));return typeof t.sha256!="string"?null:t}catch{return null}}function bo(e,t,n,r,i,o){let c=Ye(e,"SKILL.md");if(ud(e,{recursive:!0}),yo(c,b$(t,r),"utf-8"),n&&n.length>0){let l=Ye(e,"references");ud(l,{recursive:!0});for(let d of n){let g=Ye(l,`${d.name}.md`);yo(g,d.content,"utf-8")}}for(let l of i??[]){let d=Wh(e,l.path);ud(g$(d),{recursive:!0}),yo(d,l.content,"utf-8"),l.executable&&l$(d,493)}o&&yo(Ye(e,Jh),`${JSON.stringify(o,null," ")}
1479
- `,"utf-8")}function wo(e,t,n={},r,i){let o={installed:[],skipped:[],outdated:[],errors:[]},c=n.baseDir??(n.local?process.cwd():Kh()),l={schemaVersion:1,slug:e,version:md(),sha256:pd(t,r,i)};if(n.dir){let d=u$(Nr(n.dir)),g=Zt.find(y=>y.dir===d)?.provider;try{let y=Nr(n.dir),v=Wh(y,Ye("skills",e));bo(v,t,r,g,i,l),o.installed.push(n.dir)}catch(y){o.errors.push(`${n.dir}: ${u(y)}`)}}else for(let d of Zt){let g=Ye(c,d.dir),y=Ye(g,"skills",e),v=Ye(y,"SKILL.md");if(gd(g)){if(gd(v)&&!n.force){o.skipped.push(d.name);let x=w$(y);x&&x.sha256!==l.sha256&&o.outdated.push(d.name);continue}try{bo(y,t,r,d.provider,i,l),o.installed.push(d.name)}catch(x){o.errors.push(`${d.name}: ${u(x)}`)}}}return o}function vo(e,t={}){let n={removed:[],errors:[]},r=t.local?process.cwd():Kh();for(let i of Zt){let o=Ye(r,i.dir,"skills",e);if(gd(o))try{p$(o,{recursive:!0}),n.removed.push(i.name)}catch(c){n.errors.push(`${i.name}: ${u(c)}`)}}return n}function zh(){return Zt.map(e=>e.name)}import{mkdirSync as v$,writeFileSync as Hh}from"fs";import{join as Io}from"path";function Xh(e,t,n){for(let l of n)bo(Io(e,"skills",l.name),l.content,l.references,void 0,l.files);let r=Bh(t,n),i=Io(e,Fh);Hh(i,`${JSON.stringify(r,null," ")}
1480
- `,"utf-8");let o=Io(e,".claude-plugin");v$(o,{recursive:!0});let c=Io(o,"plugin.json");return Hh(c,`${JSON.stringify({name:f.name,version:r.version,description:`${f.displayName} skills for coding agents \u2014 presentations, video, branding and more via the ${f.packageName} CLI and ${f.displayName} MCP server.`},null," ")}
1481
- `,"utf-8"),{outDir:e,manifestPath:i,pluginPath:c,skillNames:n.map(l=>l.name)}}function ko(e){let{name:t,cmd:n}=e;return`---
1518
+ ${o}`}function Jh(e){return e.replace(/\bAskUserQuestion\b/g,"ask the user directly in your response").replace(/\*\*Construct the Task prompt:\*\*/g,"**Construct the Task prompt (must be fully self-contained \u2014 sub-agents cannot read this conversation's history):**").replace(/\*\*Wait for all agents to complete\*\*/g,"**Wait for all agents to complete** (monitor with `/tasks` in Copilot CLI)").replace("**Launch ALL scene agents in parallel**","**Launch ALL scene agents in parallel** \u2014 each agent must write to its own `Scene[NN][Name].tsx` file. Two agents writing to the same file will silently overwrite each other (no error). Verify unique filenames before spawning.")}function Hh(e,t){let n=Lr(e),r=Lr(e,t);if(I$(n,r).startsWith("..")||Lr(r)!==r.replace(/\.\./g,""))throw new Error(`Invalid path: "${t}" would escape base directory`);return r}var Xh=".mf-skill.json";function C$(e){try{let t=JSON.parse(y$(Ye(e,Xh),"utf-8"));return typeof t.sha256!="string"?null:t}catch{return null}}function vo(e,t,n,r,i,o){let c=Ye(e,"SKILL.md");if(fd(e,{recursive:!0}),wo(c,R$(t,r),"utf-8"),n&&n.length>0){let l=Ye(e,"references");fd(l,{recursive:!0});for(let d of n){let g=Ye(l,`${d.name}.md`);wo(g,d.content,"utf-8")}}for(let l of i??[]){let d=Hh(e,l.path);fd(v$(d),{recursive:!0}),wo(d,l.content,"utf-8"),l.executable&&h$(d,493)}o&&wo(Ye(e,Xh),`${JSON.stringify(o,null," ")}
1519
+ `,"utf-8")}function Io(e,t,n={},r,i){let o={installed:[],skipped:[],outdated:[],errors:[]},c=n.baseDir??(n.local?process.cwd():zh()),l={schemaVersion:1,slug:e,version:ud(),sha256:gd(t,r,i)};if(n.dir){let d=w$(Lr(n.dir)),g=Zt.find(y=>y.dir===d)?.provider;try{let y=Lr(n.dir),v=Hh(y,Ye("skills",e));vo(v,t,r,g,i,l),o.installed.push(n.dir)}catch(y){o.errors.push(`${n.dir}: ${u(y)}`)}}else for(let d of Zt){let g=Ye(c,d.dir),y=Ye(g,"skills",e),v=Ye(y,"SKILL.md");if(hd(g)){if(hd(v)&&!n.force){o.skipped.push(d.name);let x=C$(y);x&&x.sha256!==l.sha256&&o.outdated.push(d.name);continue}try{vo(y,t,r,d.provider,i,l),o.installed.push(d.name)}catch(x){o.errors.push(`${d.name}: ${u(x)}`)}}}return o}function ko(e,t={}){let n={removed:[],errors:[]},r=t.local?process.cwd():zh();for(let i of Zt){let o=Ye(r,i.dir,"skills",e);if(hd(o))try{b$(o,{recursive:!0}),n.removed.push(i.name)}catch(c){n.errors.push(`${i.name}: ${u(c)}`)}}return n}function Yh(){return Zt.map(e=>e.name)}import{mkdirSync as S$,writeFileSync as Qh}from"fs";import{join as xo}from"path";function Zh(e,t,n){for(let l of n)vo(xo(e,"skills",l.name),l.content,l.references,void 0,l.files);let r=Wh(t,n),i=xo(e,Kh);Qh(i,`${JSON.stringify(r,null," ")}
1520
+ `,"utf-8");let o=xo(e,".claude-plugin");S$(o,{recursive:!0});let c=xo(o,"plugin.json");return Qh(c,`${JSON.stringify({name:f.name,version:r.version,description:`${f.displayName} skills for coding agents \u2014 presentations, video, branding and more via the ${f.packageName} CLI and ${f.displayName} MCP server.`},null," ")}
1521
+ `,"utf-8"),{outDir:e,manifestPath:i,pluginPath:c,skillNames:n.map(l=>l.name)}}function Ro(e){let{name:t,cmd:n}=e;return`---
1482
1522
  name: ${t}-branding
1483
1523
  description: Brand profile management. Extract branding from websites, manage saved brands, apply consistent styling to presentations.
1484
1524
  ---
@@ -2949,7 +2989,7 @@ ${n} video find "city timelapse" --orientation landscape -n 10
2949
2989
  3. **Preview first** - Use preview URLs to check quality
2950
2990
  4. **License** - Verify license for commercial use
2951
2991
  5. **JSON export** - Save searches for batch processing
2952
- `}var I$=["main","video","presentation","presentation-video","presentation-edit","branding","agents"];function pe(e,t){return e===void 0||e==="main"?I$.some(n=>n===t):e===t}function fd(e,t,n){let r=[],i=[...qh(t,n,{branding:ko(t)}),{name:"tts",content:sn(t)},{name:"music",content:rn(t)},{name:"sfx",content:an(t)},{name:"mix",content:nn(t)},{name:"image",content:tn(t)},{name:"video-search",content:dn(t)},{name:"scrape",content:on(t)},{name:"config",content:en(t)}];return pe(e,"main")&&r.push({name:t.name,content:Tr(t,n),references:i}),pe(e,"video")&&r.push({content:Dr(t,n),name:`${t.name}-video`,references:Vh(t,n)}),pe(e,"presentation")&&r.push({name:`${t.name}-presentation`,content:$r(t,n),references:Gn(t,n,"presentation"),files:Kn(t,n,"presentation")}),pe(e,"presentation-video")&&r.push({name:`${t.name}-presentation-video`,content:Ke(t,n,"presentation-video"),references:Gn(t,n,"presentation-video"),files:Kn(t,n,"presentation-video")}),pe(e,"presentation-edit")&&r.push({name:`${t.name}-presentation-edit`,content:Or(t)}),pe(e,"branding")&&r.push({name:`${t.name}-branding`,content:Ke(t,n,"branding"),references:Gn(t,n,"branding"),files:Kn(t,n,"branding")}),pe(e,"agents")&&r.push({name:`${t.name}-agents`,content:Ke(t,n,"agents"),references:Gn(t,n,"agents"),files:Kn(t,n,"agents")}),pe(e,"tts")&&r.push({name:`${t.name}-tts`,content:sn(t)}),pe(e,"music")&&r.push({name:`${t.name}-music`,content:rn(t)}),pe(e,"sfx")&&r.push({name:`${t.name}-sfx`,content:an(t)}),pe(e,"mix")&&r.push({name:`${t.name}-mix`,content:nn(t)}),pe(e,"image")&&r.push({name:`${t.name}-image`,content:tn(t)}),pe(e,"video-search")&&r.push({name:`${t.name}-video-search`,content:dn(t)}),pe(e,"scrape")&&r.push({name:`${t.name}-scrape`,content:on(t)}),pe(e,"config")&&r.push({name:`${t.name}-config`,content:en(t)}),r}var Ct=["main","video","presentation","presentation-video","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","agents","config"],Wn=["standalone","studio"],hd={cmd:f.commands[0],pkg:f.packageName,url:f.apiUrl,name:f.name},cn=new k$("skill").description(`Manage ${f.displayName} skills for AI coding assistants`).addHelpText("after",`
2992
+ `}var E$=["main","video","presentation","presentation-video","presentation-edit","branding","agents"];function pe(e,t){return e===void 0||e==="main"?E$.some(n=>n===t):e===t}function yd(e,t,n){let r=[],i=[...Fh(t,n,{branding:Ro(t)}),{name:"tts",content:sn(t)},{name:"music",content:rn(t)},{name:"sfx",content:an(t)},{name:"mix",content:nn(t)},{name:"image",content:tn(t)},{name:"video-search",content:dn(t)},{name:"scrape",content:on(t)},{name:"config",content:en(t)}];return pe(e,"main")&&r.push({name:t.name,content:Or(t,n),references:i}),pe(e,"video")&&r.push({content:Nr(t,n),name:`${t.name}-video`,references:Gh(t,n)}),pe(e,"presentation")&&r.push({name:`${t.name}-presentation`,content:Dr(t,n),references:Kn(t,n,"presentation"),files:Wn(t,n,"presentation")}),pe(e,"presentation-video")&&r.push({name:`${t.name}-presentation-video`,content:Ke(t,n,"presentation-video"),references:Kn(t,n,"presentation-video"),files:Wn(t,n,"presentation-video")}),pe(e,"presentation-edit")&&r.push({name:`${t.name}-presentation-edit`,content:$r(t)}),pe(e,"branding")&&r.push({name:`${t.name}-branding`,content:Ke(t,n,"branding"),references:Kn(t,n,"branding"),files:Wn(t,n,"branding")}),pe(e,"agents")&&r.push({name:`${t.name}-agents`,content:Ke(t,n,"agents"),references:Kn(t,n,"agents"),files:Wn(t,n,"agents")}),pe(e,"tts")&&r.push({name:`${t.name}-tts`,content:sn(t)}),pe(e,"music")&&r.push({name:`${t.name}-music`,content:rn(t)}),pe(e,"sfx")&&r.push({name:`${t.name}-sfx`,content:an(t)}),pe(e,"mix")&&r.push({name:`${t.name}-mix`,content:nn(t)}),pe(e,"image")&&r.push({name:`${t.name}-image`,content:tn(t)}),pe(e,"video-search")&&r.push({name:`${t.name}-video-search`,content:dn(t)}),pe(e,"scrape")&&r.push({name:`${t.name}-scrape`,content:on(t)}),pe(e,"config")&&r.push({name:`${t.name}-config`,content:en(t)}),r}var Ct=["main","video","presentation","presentation-video","presentation-edit","tts","music","sfx","mix","image","video-search","scrape","branding","agents","config"],Jn=["standalone","studio"],bd={cmd:f.commands[0],pkg:f.packageName,url:f.apiUrl,name:f.name},cn=new P$("skill").description(`Manage ${f.displayName} skills for AI coding assistants`).addHelpText("after",`
2953
2993
  ${se.bold("Skill Types:")}
2954
2994
  ${se.cyan("main")} Intent router and capability index
2955
2995
  ${se.cyan("presentation")} Create, import, inspect, and export decks
@@ -2968,9 +3008,9 @@ ${se.bold("Examples:")}
2968
3008
  $ ${f.commands[0]} skill install agents
2969
3009
  $ ${f.commands[0]} skill show presentation
2970
3010
  $ ${f.commands[0]} skill pack -o ./dist-skill-bundle ${se.gray("# distributable plugin bundle")}
2971
- `);cn.command("install").description(`Install ${f.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(e,t)=>{t.mode&&!Wn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Wn.join(", ")}`),process.exit(1));let n={...hd,mode:t.mode},r=[];e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1));let i=await bn();i.source==="snapshot"&&(q(`Live capability catalog unavailable (${i.reason??"unknown reason"}) \u2014 generating from the snapshot baked into this CLI.`),console.log(se.gray(` Run \`${f.commands[0]} login\` then re-run with --force to regenerate from the live catalog.`))),r.push(...fd(e,n,i)),console.log();for(let o of r){I(`Installing ${o.name}...`);let c=wo(o.name,o.content,{dir:t.dir,local:t.local,force:t.force},o.references,o.files);if(c.installed.length>0&&(C(`${o.name} installed successfully`),O(" Installed to",c.installed.join(", "))),c.skipped.length>0&&(I(` Skipped (already exists): ${c.skipped.join(", ")}`),c.outdated.length>0&&q(` Newer skill content available for: ${c.outdated.join(", ")}`),console.log(se.gray(" Use --force to overwrite"))),c.errors.length>0)for(let l of c.errors)a(` ${l}`);c.installed.length===0&&c.skipped.length===0&&c.errors.length===0&&(I(" No supported AI coding assistants detected"),console.log(se.gray(` Supported editors: ${zh().join(", ")}`)),console.log(se.gray(" Use --dir <path> to install to a specific directory"))),console.log()}});cn.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action(async(e="main",t)=>{t.mode&&!Wn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Wn.join(", ")}`),process.exit(1));let n={...hd,mode:t.mode},r=await bn(),o={main:()=>Tr(n,r),video:()=>Dr(n,r),presentation:()=>$r(n,r),"presentation-video":()=>Ke(n,r,"presentation-video"),"presentation-edit":()=>Or(n),tts:()=>sn(n),music:()=>rn(n),sfx:()=>an(n),mix:()=>nn(n),image:()=>tn(n),"video-search":()=>dn(n),scrape:()=>on(n),branding:()=>Ke(n,r,"branding"),agents:()=>Ke(n,r,"agents"),config:()=>en(n)}[e];o?console.log(o()):(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1))});cn.command("pack").description(`Write the ${f.displayName} skill bundle to a directory \u2014 skills tree, app-skill manifest, and a Claude Code plugin descriptor`).argument("[type]","Skill type, or omit to pack the core skill suite").requiredOption("-o, --out <dir>","Output directory for the bundle").option("-m, --mode <mode>","Skill mode: standalone (render to file) or studio (Studio Preview)","standalone").action(async(e,t)=>{t.mode&&!Wn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Wn.join(", ")}`),process.exit(1)),e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1));let n={...hd,mode:t.mode},r=await bn(),i=fd(e,n,r);i.length===0&&(a(`Invalid skill type: ${e}`),process.exit(1));let o=Xh(String(t.out),n,i);C(`Packed ${o.skillNames.length} skill${o.skillNames.length===1?"":"s"}`),O(" Bundle",o.outDir),O(" Manifest",o.manifestPath),O(" Catalog source",r.source),console.log(se.gray(" The bundle is a Claude Code plugin as-is (.claude-plugin/plugin.json)."))});cn.command("uninstall").description(`Remove ${f.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(e,t)=>{let n=[];e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1)),(!e||e==="main")&&n.push(f.name),(!e||e==="video")&&n.push(`${f.name}-video`),(!e||e==="presentation")&&n.push(`${f.name}-presentation`),(!e||e==="presentation-video")&&n.push(`${f.name}-presentation-video`),(!e||e==="presentation-edit")&&n.push(`${f.name}-presentation-edit`),(!e||e==="tts")&&n.push(`${f.name}-tts`),(!e||e==="music")&&n.push(`${f.name}-music`),(!e||e==="sfx")&&n.push(`${f.name}-sfx`),(!e||e==="mix")&&n.push(`${f.name}-mix`),(!e||e==="image")&&n.push(`${f.name}-image`),(!e||e==="video-search")&&n.push(`${f.name}-video-search`),(!e||e==="scrape")&&n.push(`${f.name}-scrape`),(!e||e==="branding")&&n.push(`${f.name}-branding`),(!e||e==="agents")&&n.push(`${f.name}-agents`),(!e||e==="config")&&n.push(`${f.name}-config`),console.log();for(let r of n){let i=vo(r,{local:t.local});if(i.removed.length>0?(C(`${r} uninstalled`),O(" Removed from",i.removed.join(", "))):I(` ${r} not found`),i.errors.length>0)for(let o of i.errors)q(` Failed to remove: ${o}`)}console.log()});import yd from"chalk";import{Command as x$}from"commander";var Yh=new x$("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)",b("--format",["human","json"]),"human").action(async e=>{await w();try{let t=await Je();if(Vo(),e.format==="json"){console.log(JSON.stringify(t,null,2));return}De("User"),console.log(),O("Email",t.user.email),t.user.username&&O("Username",t.user.username),(t.user.firstName||t.user.lastName)&&O("Name",[t.user.firstName,t.user.lastName].filter(Boolean).join(" "));let n=t.authType==="apiKey"?"API Key":t.authType==="oauth"?"OAuth":"Session";if(O("Auth Type",n),t.currentTeam&&(console.log(),De("Current Team"),console.log(),O("ID",t.currentTeam.id),O("Name",t.currentTeam.name),O("Plan",t.currentTeam.planName),O("Role",t.currentTeam.isOwner?"Owner":"Member")),t.teams.length>1){console.log(),De("All Teams"),console.log();for(let r of t.teams){let i=r.isCurrent?yd.green(" (current)"):"";console.log(` ${yd.bold(r.name)}${i}`),console.log(yd.gray(` ID: ${r.id} | Plan: ${r.planName} | Role: ${r.role}`))}}console.log()}catch(t){a("The command failed. Please try again."),process.exit(t.exitCode??1)}});function Qh(e){return e[0]==="--"?e.slice(1):e}import bd from"chalk";function wd(e){e.configureOutput({outputError:(t,n)=>{n(bd.red(t));let r=/unknown option '(-{1,2}[^'\s=]+)/.exec(t);if(!r)return;let i=C$(e,r[1]);i&&n(bd.yellow(`Did you mean '${i}'?
2972
- `)),n(bd.gray(`Run '${R$(e)} --help' to see the accepted options.
2973
- `))}});for(let t of e.commands)wd(t)}function R$(e){let t=[],n=e;for(;n;)t.unshift(n.name()),n=n.parent;return t.join(" ")}function C$(e,t){let n,r=Number.POSITIVE_INFINITY;for(let o of e.options)if(!o.hidden)for(let c of[o.short,o.long]){if(!c)continue;let l=vd(t,c);l<r&&(r=l,n=o.flags)}let i=t.startsWith("--")?2:1;return n!==void 0&&r<=i?n:void 0}function vd(e,t){if(e===t)return 0;if(e.length===0)return t.length;if(t.length===0)return e.length;let n=Array.from({length:t.length+1},(r,i)=>i);for(let r=1;r<=e.length;r++){let i=[r];for(let o=1;o<=t.length;o++){let c=e[r-1]===t[o-1]?0:1;i[o]=Math.min(i[o-1]+1,n[o]+1,n[o-1]+c)}n=i}return n[t.length]}var E$="0.3.27",ne=new S$,G=f.commands[0];ne.name(G).description(`${f.displayName} CLI \u2014 presentations, videos, avatars, audio, branding, media and research`).version(E$,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output").option("--wait-for-approval","When a command needs browser approval, print the URL and read the minted receipt from stdin instead of exiting");ne.addCommand(ml);xh(ne);ne.addCommand(Sl);ne.addCommand(Cl);ne.addCommand(xl);ne.addCommand(wl);ne.addCommand(Yh);ne.addCommand(Ol);ne.addCommand($l);ne.addCommand(yl);ne.addCommand(cn);ne.addCommand(ti);var Zh=kl();Zh.commands.length>0&&ne.addCommand(Zh);function P$(e){let t=e.toLowerCase(),n=t.length<=4?1:2,r,i=Number.POSITIVE_INFINITY;for(let o of ne.commands)for(let c of[o.name(),...o.aliases()]){let l=vd(t,c.toLowerCase());l<i&&(i=l,r=o.name())}return r!==void 0&&i<=n?r:void 0}ne.on("command:*",e=>{let t=String(e[0]);console.error(te.red(`Error: Unknown command '${t}'`)),console.error();let n=P$(t);n&&console.error(`Did you mean '${n}'?`),console.error(`Run '${G} --help' to see available commands.`),console.error(`Run '${G} capabilities' for the full list of callable capabilities.`),process.exit(1)});ne.addHelpText("after",`
3011
+ `);cn.command("install").description(`Install ${f.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(e,t)=>{t.mode&&!Jn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Jn.join(", ")}`),process.exit(1));let n={...bd,mode:t.mode},r=[];e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1));let i=await bn();i.source==="snapshot"&&(q(`Live capability catalog unavailable (${i.reason??"unknown reason"}) \u2014 generating from the snapshot baked into this CLI.`),console.log(se.gray(` Run \`${f.commands[0]} login\` then re-run with --force to regenerate from the live catalog.`))),r.push(...yd(e,n,i)),console.log();for(let o of r){I(`Installing ${o.name}...`);let c=Io(o.name,o.content,{dir:t.dir,local:t.local,force:t.force},o.references,o.files);if(c.installed.length>0&&(C(`${o.name} installed successfully`),O(" Installed to",c.installed.join(", "))),c.skipped.length>0&&(I(` Skipped (already exists): ${c.skipped.join(", ")}`),c.outdated.length>0&&q(` Newer skill content available for: ${c.outdated.join(", ")}`),console.log(se.gray(" Use --force to overwrite"))),c.errors.length>0)for(let l of c.errors)a(` ${l}`);c.installed.length===0&&c.skipped.length===0&&c.errors.length===0&&(I(" No supported AI coding assistants detected"),console.log(se.gray(` Supported editors: ${Yh().join(", ")}`)),console.log(se.gray(" Use --dir <path> to install to a specific directory"))),console.log()}});cn.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action(async(e="main",t)=>{t.mode&&!Jn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Jn.join(", ")}`),process.exit(1));let n={...bd,mode:t.mode},r=await bn(),o={main:()=>Or(n,r),video:()=>Nr(n,r),presentation:()=>Dr(n,r),"presentation-video":()=>Ke(n,r,"presentation-video"),"presentation-edit":()=>$r(n),tts:()=>sn(n),music:()=>rn(n),sfx:()=>an(n),mix:()=>nn(n),image:()=>tn(n),"video-search":()=>dn(n),scrape:()=>on(n),branding:()=>Ke(n,r,"branding"),agents:()=>Ke(n,r,"agents"),config:()=>en(n)}[e];o?console.log(o()):(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1))});cn.command("pack").description(`Write the ${f.displayName} skill bundle to a directory \u2014 skills tree, app-skill manifest, and a Claude Code plugin descriptor`).argument("[type]","Skill type, or omit to pack the core skill suite").requiredOption("-o, --out <dir>","Output directory for the bundle").option("-m, --mode <mode>","Skill mode: standalone (render to file) or studio (Studio Preview)","standalone").action(async(e,t)=>{t.mode&&!Jn.includes(t.mode)&&(a(`Invalid mode: ${t.mode}. Must be one of: ${Jn.join(", ")}`),process.exit(1)),e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1));let n={...bd,mode:t.mode},r=await bn(),i=yd(e,n,r);i.length===0&&(a(`Invalid skill type: ${e}`),process.exit(1));let o=Zh(String(t.out),n,i);C(`Packed ${o.skillNames.length} skill${o.skillNames.length===1?"":"s"}`),O(" Bundle",o.outDir),O(" Manifest",o.manifestPath),O(" Catalog source",r.source),console.log(se.gray(" The bundle is a Claude Code plugin as-is (.claude-plugin/plugin.json)."))});cn.command("uninstall").description(`Remove ${f.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(e,t)=>{let n=[];e&&!Ct.includes(e)&&(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1)),(!e||e==="main")&&n.push(f.name),(!e||e==="video")&&n.push(`${f.name}-video`),(!e||e==="presentation")&&n.push(`${f.name}-presentation`),(!e||e==="presentation-video")&&n.push(`${f.name}-presentation-video`),(!e||e==="presentation-edit")&&n.push(`${f.name}-presentation-edit`),(!e||e==="tts")&&n.push(`${f.name}-tts`),(!e||e==="music")&&n.push(`${f.name}-music`),(!e||e==="sfx")&&n.push(`${f.name}-sfx`),(!e||e==="mix")&&n.push(`${f.name}-mix`),(!e||e==="image")&&n.push(`${f.name}-image`),(!e||e==="video-search")&&n.push(`${f.name}-video-search`),(!e||e==="scrape")&&n.push(`${f.name}-scrape`),(!e||e==="branding")&&n.push(`${f.name}-branding`),(!e||e==="agents")&&n.push(`${f.name}-agents`),(!e||e==="config")&&n.push(`${f.name}-config`),console.log();for(let r of n){let i=ko(r,{local:t.local});if(i.removed.length>0?(C(`${r} uninstalled`),O(" Removed from",i.removed.join(", "))):I(` ${r} not found`),i.errors.length>0)for(let o of i.errors)q(` Failed to remove: ${o}`)}console.log()});import wd from"chalk";import{Command as A$}from"commander";var ey=new A$("whoami").description("Show current user and team information").option("-f, --format <format>","Output format (human, json)",b("--format",["human","json"]),"human").action(async e=>{await w();try{let t=await Je();if(Bo(),e.format==="json"){console.log(JSON.stringify(t,null,2));return}De("User"),console.log(),O("Email",t.user.email),t.user.username&&O("Username",t.user.username),(t.user.firstName||t.user.lastName)&&O("Name",[t.user.firstName,t.user.lastName].filter(Boolean).join(" "));let n=t.authType==="apiKey"?"API Key":t.authType==="oauth"?"OAuth":"Session";if(O("Auth Type",n),t.currentTeam&&(console.log(),De("Current Team"),console.log(),O("ID",t.currentTeam.id),O("Name",t.currentTeam.name),O("Plan",t.currentTeam.planName),O("Role",t.currentTeam.isOwner?"Owner":"Member")),t.teams.length>1){console.log(),De("All Teams"),console.log();for(let r of t.teams){let i=r.isCurrent?wd.green(" (current)"):"";console.log(` ${wd.bold(r.name)}${i}`),console.log(wd.gray(` ID: ${r.id} | Plan: ${r.planName} | Role: ${r.role}`))}}console.log()}catch(t){a("The command failed. Please try again."),process.exit(t.exitCode??1)}});function ty(e){return e[0]==="--"?e.slice(1):e}import vd from"chalk";function Id(e){e.configureOutput({outputError:(t,n)=>{n(vd.red(t));let r=/unknown option '(-{1,2}[^'\s=]+)/.exec(t);if(!r)return;let i=O$(e,r[1]);i&&n(vd.yellow(`Did you mean '${i}'?
3012
+ `)),n(vd.gray(`Run '${T$(e)} --help' to see the accepted options.
3013
+ `))}});for(let t of e.commands)Id(t)}function T$(e){let t=[],n=e;for(;n;)t.unshift(n.name()),n=n.parent;return t.join(" ")}function O$(e,t){let n,r=Number.POSITIVE_INFINITY;for(let o of e.options)if(!o.hidden)for(let c of[o.short,o.long]){if(!c)continue;let l=kd(t,c);l<r&&(r=l,n=o.flags)}let i=t.startsWith("--")?2:1;return n!==void 0&&r<=i?n:void 0}function kd(e,t){if(e===t)return 0;if(e.length===0)return t.length;if(t.length===0)return e.length;let n=Array.from({length:t.length+1},(r,i)=>i);for(let r=1;r<=e.length;r++){let i=[r];for(let o=1;o<=t.length;o++){let c=e[r-1]===t[o-1]?0:1;i[o]=Math.min(i[o-1]+1,n[o]+1,n[o-1]+c)}n=i}return n[t.length]}var D$="0.3.28",ne=new $$,G=f.commands[0];ne.name(G).description(`${f.displayName} CLI \u2014 presentations, videos, avatars, audio, branding, media and research`).version(D$,"-v, --version","Show version number").option("--debug","Enable debug logging").option("--no-color","Disable colored output").option("--wait-for-approval","When a command needs browser approval, print the URL and read the minted receipt from stdin instead of exiting");ne.addCommand(ul);Sh(ne);ne.addCommand(Pl);ne.addCommand(El);ne.addCommand(Cl);ne.addCommand(Il);ne.addCommand(ey);ne.addCommand(Dl);ne.addCommand(Nl);ne.addCommand(wl);ne.addCommand(cn);ne.addCommand(ni);var ny=Rl();ny.commands.length>0&&ne.addCommand(ny);function N$(e){let t=e.toLowerCase(),n=t.length<=4?1:2,r,i=Number.POSITIVE_INFINITY;for(let o of ne.commands)for(let c of[o.name(),...o.aliases()]){let l=kd(t,c.toLowerCase());l<i&&(i=l,r=o.name())}return r!==void 0&&i<=n?r:void 0}ne.on("command:*",e=>{let t=String(e[0]);console.error(te.red(`Error: Unknown command '${t}'`)),console.error();let n=N$(t);n&&console.error(`Did you mean '${n}'?`),console.error(`Run '${G} --help' to see available commands.`),console.error(`Run '${G} capabilities' for the full list of callable capabilities.`),process.exit(1)});ne.addHelpText("after",`
2974
3014
  ${te.bold("Start here:")}
2975
3015
  $ ${G} capabilities ${te.gray("# every capability + its exact command path")}
2976
3016
  $ ${G} <group> --help ${te.gray("# drill into any command group above")}
@@ -3016,4 +3056,4 @@ ${te.bold("Note:")}
3016
3056
 
3017
3057
  ${te.bold("More Info:")}
3018
3058
  ${te.blue(f.docsUrl)}
3019
- `);wd(ne);ne.hook("preAction",()=>{zd(ne.opts().waitForApproval===!0)});ne.parse(Qh(process.argv.slice(2)),{from:"user"});
3059
+ `);Id(ne);ne.hook("preAction",()=>{Xd(ne.opts().waitForApproval===!0)});ne.parse(ty(process.argv.slice(2)),{from:"user"});