@conceptcraft/mindframes 0.3.29 → 0.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +97 -97
- 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
|
|
4
|
-
`);let t=
|
|
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
|
|
6
|
-
`):null}var
|
|
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(`
|
|
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 U$}from"commander";import Xn from"chalk";import{Command as Gy}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 z}from"crypto";import{readFileSync as Wd,statSync as Jd}from"fs";import{basename as Do}from"path";import oy from"readline";async function Cd(e){process.stderr.write(`${JSON.stringify({event:"approval_required",...e.approvalUrl?{approvalUrl:e.approvalUrl}:{}})}
|
|
4
|
+
`);let t=oy.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 ay}from"child_process";import{existsSync as sy,mkdtempSync as dy,rmSync as cy,writeFileSync as ly}from"fs";import{tmpdir as my}from"os";import{join as Sd}from"path";import Co from"ffmpeg-static";var py=/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/;function uy(e){let t=py.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&&sy(Co)?Co:"ffmpeg",r=/^[a-z0-9]+$/i.test(t)?t:"audio",i=dy(Sd(my(),"mf-tts-duration-")),o=Sd(i,`speech.${r}`);try{ly(o,e);let c=ay(n,["-hide_banner","-i",o],{encoding:"utf8"});return c.error?void 0:uy(c.stderr??"")}finally{cy(i,{force:!0,recursive:!0})}}import qr from"chalk";import gy from"conf";import Pd from"path";var Td=f.apiUrl,fy={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 hy(e=f.apiKeyEnvVar){return e.endsWith("_API_KEY")?`${e.slice(0,-8)}_CONFIG_DIR`:`${e}_CONFIG_DIR`}function yy(e=process.env){let t=hy(),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=yy(),M=new gy({projectName:f.name,schema:fy,...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 mn(e){M.set("defaultTeamId",e)}function Ur(){M.clear()}function zn(){return M.path}function pn(){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 by(){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()?by():$d()||null:null}function Ze(){return Pt()||pn()}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 wy(e){return e.length<=14?"****":`${e.slice(0,10)}...${e.slice(-4)}`}function qd(){let e=Qe();if(e)return wy(e)}function Po(e){return["cc_slides_","mcp_","cc_sk_","sk_"].some(n=>e.startsWith(n))}import{mkdirSync as vy,readFileSync as Iy,writeFileSync as ky}from"fs";import{homedir as xy}from"os";import{join as Md}from"path";import Ry from"ajv/dist/2020.js";var Ao=new Map;function Vd(){return Md(xy(),".conceptcraft","schemas")}function Fd(e){return Md(Vd(),`${e}.json`)}function Cy(e){try{let t=JSON.parse(Iy(Fd(e),"utf8"));return typeof t?.catalogVersion=="number"&&t.schema?t:null}catch{return null}}function Sy(e,t){try{vy(Vd(),{recursive:!0}),ky(Fd(e),JSON.stringify(t))}catch{}}async function Ey(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 Sy(e,r),Ao.set(e,r),r}catch{let n=Cy(e);return Ao.set(e,n),n}}function Py(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 Ey(e);if(!n)return;let r;try{r=new Ry({allErrors:!0,strict:!1}).compile(n.schema)}catch{return}if(r(t))return;let i=(r.errors??[]).slice(0,10).map(Py);throw new Error(`Request does not match the ${e} contract \u2014 ${i.join("; ")}`)}function Ay(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 un="terminalRunFailure",de=class extends Error{[un]=!0};function gn(e){return!!e&&typeof e=="object"&&e[un]===!0}function oe(e,t){let n=t?null:Ay(e);if(n)return n;if(gn(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 gn(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 Ty(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!(e instanceof FormData)}function Oy(e){return e&&e!=="GET"?{[zd]:z()}:{}}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,...Oy(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&&Ty(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 $y(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 Dy(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 Ny(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=$y(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:Dy(o.message),code:o.code,details:Ny(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 Ly=1800*1e3;async function H(e,t,n,r=120,i){let o=Date.now()+(i?.maxWaitMs??Ly),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),{[un]:!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 Uy(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 fn(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:fn(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??z(),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=fn(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 hn(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:${z()}`)}async function sc(e,t,n){return p("exportPresentation",{format:t,presentationId:e,teamId:n?.teamId})}async function yn(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 _y(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:_y(e.text)};await Mr("generateSpeech",n);let r=await p("generateSpeech",{approvalReceipt:t?.approvalReceipt,...n},t?.idempotencyKey),i=await H("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)??Uy(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:jy(l.timestamps),wordTimings:qy(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 jy(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 qy(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??z())}async function Cc(e,t,n){return p("clipVideo",{...e,approvalReceipt:n},t??z())}async function Sc(){return(await p("listTranslationLanguages",{})).languages}async function Ec(e,t,n){return p("translateVideo",{...e,approvalReceipt:n},t??z())}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 H("analyzeVideoReference",e,t)}async function Oc(e,t){return H("selectPresentationVideoStockMusic",e,t)}async function $c(e,t){return H("preparePresentationVideoMediaSuggestions",e,t,null,{statusCommand:"presentation video suggestions status"})}async function Dc(e,t){return H("preparePresentationVideoSuggestionAction",e,t,null,{statusCommand:"presentation video suggestions action prepare status"})}async function Nc(e,t){return H("preparePresentationVideoPreviews",e,t,null,{statusCommand:"presentation video previews status"})}async function Lc(e,t){return H("generateBrandVariations",e,t)}async function Uc(e,t){return H("extractBrandProducts",e,t)}async function _c(e,t){return H("buildBrandVoice",e,t)}async function jc(e,t){return H("generateBrandGuardrails",e,t)}async function qc(e,t){return H("repairBrandQuality",e,t)}async function Mc(e,t){return H("syncBrandToPresentations",e,t)}async function Vc(e,t){return H("syncBrandFoundation",e,t)}async function Fc(e){return p("listVoices",e)}async function Bc(e){return p("adoptLibraryVoice",e,z())}async function Gc(e){return p("setVoiceFavorite",e,z())}async function Kc(e){return p("setVoiceShortlisted",e,z())}async function Wc(e){return p("setVoicePolicy",e,z())}async function Jc(e){return p("requestVoiceApproval",e,z())}async function zc(e){return p("listVoiceApprovalRequests",e,z())}async function Hc(e){return p("decideVoiceApprovalRequest",e,z())}async function Xc(e){return p("setVoiceTone",e,z())}async function Yc(e){return p("setVoiceVisibility",e,z())}async function Qc(e){return p("setVoiceApproval",e,z())}async function Zc(e){return p("listVoiceApprovals",e,z())}async function el(e){return p("designVoice",e,z())}async function tl(e){return p("saveDesignedVoice",e,z())}async function nl(e){return p("retireVoice",e,z())}async function rl(e){return p("listCastPresets",e)}async function il(e){return p("createCastPreset",e,z())}async function ol(e){return p("updateCastPreset",e,z())}async function al(e,t){return p("deleteCastPreset",{presetId:e,...t?{teamId:t}:{}},z())}var My="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=My){return e instanceof P&&e.message.trim()?[e.message,...To(e.details)].join(`
|
|
8
|
+
`):t}import{InvalidArgumentError as Vy}from"commander";function b(e,t){return n=>{if(t.includes(n))return n;throw new Vy(`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 bn(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),bn(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 Fy(e){return JSON.stringify(e,null,2)}function m(e){console.log(Fy(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 wn(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"],Ky=80,Wy=30;function Jy(e){return e.billing!==void 0&&e.billing!=="free"&&e.billing!=="quota"}function zy(e){return e.lifecycle?.mode==="background"}function Hy(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 Xy(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 Yy(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(Wy,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=`${Jy(l)?"$":" "}${zy(l)?"*":" "}`,g=l.name.padEnd(r),y=2+r+1+d.length+1,v=Math.max(24,Ky-y),x=Hy(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 Qy(e){return e.map(t=>`${t.name} ${t.state} ${t.milestone}`)}function Zy(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 Qy(e);let r=f.commands[0],i=Yy(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 Gy("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 wn(),n=Xy(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 Zy(n,{filtered:r}))console.log(i)}catch(t){a(u(t,"Unknown error")),process.exit(s.GENERAL_ERROR)}});import{mkdirSync as rb,writeFileSync as ib}from"fs";import{dirname as yl,join as ob}from"path";import{confirm as bl,input as ab,password as sb,select as db}from"@inquirer/prompts";import Yn from"chalk";import{Command as pt}from"commander";import Jr from"ora";import eb from"conf";var Wr=new eb({projectName:"conceptcraft",configName:"feature-cache"}),tb=3600*1e3,nb=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(!pn())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>nb?null:(n>tb&&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 sb({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 ab({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];mn(i.id),I(`Team: ${i.name} (${i.planName})`)}else{console.log(),I(`You have access to ${r.teams.length} teams.`);let i=await db({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});mn(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":mn(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=ob(yl(zn()),"settings.toml");rb(yl(i),{recursive:!0}),ib(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 lb}from"@inquirer/prompts";import{Command as mb}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 cb}from"crypto";function Q(e){let t=cb("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 mb("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 lb({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 vn}from"commander";import pb from"ora";import{createParser as YN}from"eventsource-parser";import ZN from"chalk";import t0 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 ub(){return new vn("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=pb("Fetching presentation...").start();try{let o=await hn(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 gb(){return new vn("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 fb(){return new vn("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 hb(){return new vn("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 yb(){return new vn("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 vn("derive").description("Generate derivative content from a presentation");return e&&(e.deckToBlog&&t.addCommand(ub()),e.deckToTweets&&t.addCommand(gb()),e.linkedInCarousel&&t.addCommand(fb()),e.redTeamQuestions&&t.addCommand(hb()),e.presenterCheatSheet&&t.addCommand(yb())),t}import{Command as bb}from"commander";import Ko from"chalk";var Cl=new bb("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 wb}from"fs/promises";import{basename as vb,resolve as Ib}from"path";import{Command as kb}from"commander";import xb from"ora";var Sl=new kb("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=Ib(e),r=vb(n);r.endsWith(".zip")||(a("File must be a ZIP archive"),process.exit(6));let i=xb("Reading file...").start();try{let o=await wb(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 Rb}from"commander";function Wo(){return new Rb("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 Cb,randomBytes as Ol}from"crypto";import $l from"http";import Al from"chalk";import{Command as Sb}from"commander";import Eb from"open";import Tl from"ora";var Pb=`${f.displayName} CLI`,Ab=8765,Tb=8775,Ob=["presentations:read","presentations:write","brands:read","brands:write","media:read","media:write"];function $b(){return Ol(32).toString("base64url")}function Db(e){return Cb("sha256").update(e).digest("base64url")}function Nb(){return Ol(16).toString("hex")}async function Lb(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 Ub(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 _b(e){let t=e.scopes_supported?.filter(n=>typeof n=="string"&&n.trim().length>0);return(t?.length?t:Ob).join(" ")}function jb(e,t){if(!t?.trim())return _b(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 qb(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 Mb(e){return new URLSearchParams({...e,response_type:"code",code_challenge_method:"S256"})}async function Vb(e,t,n){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:Pb,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 Fb(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 Bb(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
|
|
48
|
-
`)[0]??"";n(c?{bin:t,version:c}:null)})})}var
|
|
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 Gb(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 Kb(e){let t=K(),n=Tl("Discovering OAuth server...").start();try{let r=await Ub(t),i=jb(r,e.scopes),o=await qb(t,e.resource,r.issuer);n.succeed(`Connecting to ${t}`);let c=await Lb(Ab,Tb),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 Vb(r.registration_endpoint,l,i),g=d.client_id;_d(g,d.client_secret);let y=$b(),v=Db(y),x=Nb(),T=Mb({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 Eb(L)):(console.log(Al.bold("Open this URL in your browser:")),console.log(Al.cyan(L)));let $=Bb(c,x),{code:N}=await $;n=Tl("Completing login...").start();let S=await Fb(r.token_endpoint,N,y,l,g,o);_r(S.access_token,S.refresh_token,S.expires_in);let E=await Gb(t,S.access_token);n.succeed("Logged in!"),console.log(),O("Logged in as",E.user.email),E.currentTeam&&(mn(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 Sb("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 Kb(e),process.exit(0)}catch{process.exit(1)}});import{Command as Wb}from"commander";import{confirm as Jb}from"@inquirer/prompts";var Nl=new Wb("logout").description("Log out and clear authentication").option("--all","Clear all config including API key").action(async e=>{console.log();let t=Pt(),n=pn();if(!t&&!n){q("You are not logged in."),console.log();return}if(e.all)try{await Jb({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 $w}from"os";import{join as Dw}from"path";import qe from"chalk";import{Command as Nw}from"commander";import{spawn as zb}from"child_process";import{existsSync as Hb,readdirSync as Xb}from"fs";import{homedir as _l}from"os";import{delimiter as Ll}from"path";import{query as Yb}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 Qb(e){try{return Xb(`${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",...Qb(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=zb(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 Zb=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 zo(e,t){return t?e.messages.filter(r=>r.text.trim()).at(-1)?.text??"":Jo(e.messages)}function
|
|
55
|
-
`)[0]??"";t(o||null)})})}var
|
|
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
|
|
57
|
-
`);return c===-1?"":o.slice(c+1)}finally{
|
|
54
|
+
${n.text}`}function zo(e,t){return t?e.messages.filter(r=>r.text.trim()).at(-1)?.text??"":Jo(e.messages)}function ew({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 Zb.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=Yb({prompt:t,options:ew({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&&Hb(x)?x:null,text:v,usage:c}}import{spawn as tw}from"child_process";import{closeSync as nw,fstatSync as rw,openSync as iw,readdirSync as ow,readSync as aw}from"fs";import{homedir as sw}from"os";import{join as ql}from"path";import{Codex as dw}from"@openai/codex-sdk";var cw=["/Applications/Codex.app/Contents/Resources/codex"];async function Zr(e){let t=e?[e]:["codex",...cw];for(let n of t){let r=await lw(n);if(r)return{bin:n,version:r}}return null}function lw(e){return new Promise(t=>{let n=tw(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 mw=24,pw=4*1024*1024,Fl=new Set(["custom_tool_call","custom_tool_call_output","dynamic_tool_call","function_call"]);function uw(e){let t;try{t=gw(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 gw(e){let t=iw(e,"r");try{let n=rw(t).size,r=Math.max(0,n-pw),i=Buffer.alloc(n-r);aw(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{nw(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>=mw)break}catch{}}return i}function Yo(e){return typeof e=="string"?e:Array.isArray(e)?e.map(Yo).join(`
|
|
58
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(
|
|
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(sw(),".codex","sessions")){try{let r=ow(t,{recursive:!0}).find(i=>typeof i=="string"&&i.endsWith(`${e}.jsonl`));return r?ql(t,r):null}catch{return null}}function fw(e,t){return t?zo(e,t):Jo(e.messages)}function hw(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 yw=new Set(["minimal","low","medium","high","xhigh","max"]);function bw(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&&yw.has(e.effort)&&(n.modelReasoningEffort=e.effort),n}async function Bl(e){let t=fw(e.input,e.resumeSessionId);if(!t)throw new Error("Chat turn has no user text to send.");let n=new dw(hw(e.bin,e.input)),r=bw(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?uw(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
60
|
|
|
61
|
-
`),usage:c}}function Vl(e){return e.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as
|
|
61
|
+
`),usage:c}}function Vl(e){return e.trim().replace(/\s+/g," ").toLocaleLowerCase()}import{randomUUID as xw}from"crypto";import{mkdir as Rw}from"fs/promises";import{hostname as ti,platform as Cw}from"os";import{join as Sw}from"path";var In=class extends Error{constructor(n,r,i=!1){super(n);this.statusCode=r;this.reRegister=i;this.name="RunnerApiError"}statusCode;reRegister};async function kn(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 In(`[${g.code}] ${g.message}`,c.status,d.reRegister===!0)}return d}finally{clearTimeout(i),t.signal?.removeEventListener("abort",o)}}async function Gl(e){await kn("/api/runner/register",{body:e,method:"POST",timeoutMs:15e3})}async function Kl(e,t){return(await kn(`/api/runner/work?runnerId=${encodeURIComponent(e)}`,{signal:t,timeoutMs:28e3})).job??null}async function Wl(e){await kn("/api/runner/heartbeat",{body:{runnerId:e},method:"POST",timeoutMs:1e4})}async function Jl(e,t){return{cancelRequested:(await kn(`/api/runner/jobs/${encodeURIComponent(e)}/events`,{body:{events:t},method:"POST",timeoutMs:15e3})).cancelRequested===!0}}async function Qo(e,t,n){await kn(`/api/runner/jobs/${encodeURIComponent(e)}/complete`,{body:{result:n,runnerId:t},method:"POST",timeoutMs:15e3})}async function ei(e,t,n,r=!0){await kn(`/api/runner/jobs/${encodeURIComponent(e)}/fail`,{body:{message:n,retryable:r,runnerId:t},method:"POST",timeoutMs:15e3})}var xn=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 xn(`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 ww,readFileSync as vw,writeFileSync as Xl}from"fs";import{dirname as Iw,join as kw}from"path";function ea(e){return kw(e,"sessions.json")}function ta(e){try{let t=vw(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);ww(Iw(i),{recursive:!0});let o=ta(e);o[t]={...o[t],[n]:r},Xl(i,`${JSON.stringify(o,null," ")}
|
|
62
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
|
|
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.29",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(
|
|
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",`
|
|
63
|
+
`,"utf8")}catch{}}var Ew=300,Pw=3e4,Aw=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]}-${xw().slice(0,8)}`,o=()=>Gl({capabilities:["chat_turn","proof"],claudeCodeVersion:t?.version??null,cliVersion:e.version,codexVersion:n?.version??null,hostname:ti(),platform:Cw(),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 In&&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:Aw}),e.signal);continue}if(!d){if(e.once)continue;continue}if(e.log(`Claimed ${d.jobType} job ${d.runId}.`),await Tw({claude:t,codex:n,job:d,options:e,runnerId:i}),e.once)break}}async function Tw({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(()=>{})},Pw),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 In&&L.statusCode===409&&o.abort()}finally{g=!1}},v=setInterval(()=>{y()},Ew),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=Sw(r.workspaceRoot,"chats",$??n.runId);await Rw(N,{recursive:!0});let S=Ow(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 Ow(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 Lw(){return Dw($w(),`.${f.commands[0]}-runner`,"runs")}var ni=new Nw("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.30",workspaceRoot:e.workspace??Lw()})}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 $$}from"commander";import{Command as ra}from"commander";import{readFileSync as Uw}from"fs";function _(e,t=()=>Uw(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 _w(e){let[t,n]=e.split("@");return n?{templateId:t,version:Number.parseInt(n,10)}:{templateId:t}}function jw(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(_w),variations:e.variations??1}}var qw=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=jw(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)}}),Mw=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(qw).addCommand(Mw);import{randomUUID as nm}from"crypto";import{readFileSync as Vw}from"fs";import{Command as Qn}from"commander";var Fw=/^[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){Fw.test(e)||(a(`"${e}" is not a ${t} id.`),process.exit(s.INVALID_INPUT))}function rm(e,t){try{return Vw(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 Bw=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")}),Gw=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")}),Kw=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())}),Ww=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(Bw).addCommand(Gw).addCommand(Kw).addCommand(Ww);import{randomUUID as lm}from"crypto";import{readFileSync as mm}from"fs";import{readFile as Yw}from"fs/promises";import{Command as Me}from"commander";import{randomUUID as Jw}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}:${Jw()}`}function Rn(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 zw=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:Rn(e.pageSize,"--page-size"),teamId:e.teamId}))}catch(t){nt(t,"Could not list the Agent roster")}}),Hw=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(zw).addCommand(Hw),Xw=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(Xw);function Cn(e,t){return[...t,e]}function Qw(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 Yw(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 Zw=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",Qw).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))}),ev=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)",Cn,[]).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)",Cn,[]).option("--output-config <json-or-path>","Full output slot configuration (repeatable)",Cn,[]).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 tv(e,t){return e==="none"?null:Rn(e,t)}function nv(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 rv(e,t){try{return mm(e,"utf8")}catch(n){throw new Error(`${t} could not read ${e}: ${u(n,"unknown file error")}`)}}var iv=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:Rn(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")}}),ov=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")}}),av=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:Rn(t.expectedVersion,"--expected-version"),goal:t.goal,instructionsMarkdown:t.instructionsFile?rv(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:tv(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:nv(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 sv(e){return`cli:agent-memory:${e}:${lm()}`}function dv(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 cv=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")}}),lv=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)",Cn,[]).option("--always <text>","Standing instruction to add (repeatable)",Cn,[]).option("--never <text>","Thing it must not do, to add (repeatable)",Cn,[]).option("--track <name=note>","Entity to track, as name=note (repeatable)",dv,[]).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??sv(i?"remove":"add")))}catch(o){aa(o,"Could not update the agent's memory")}}),mv=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")}}),pv=new Me("memory").description("Read, edit, and erase what a scheduled agent remembers").addCommand(cv).addCommand(lv).addCommand(mv),um=new Me("agent").description("Recommend, activate, configure, and manage scheduled Agents").addCommand(iv).addCommand(ov).addCommand(sm).addCommand(dm).addCommand(av).addCommand(cm("pause")).addCommand(cm("resume")).addCommand(Zw).addCommand(ev).addCommand(pv);import{randomUUID as uv}from"crypto";import{password as gv}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 fv(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 hv(){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 yv=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=fv(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 hv():(await gv({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)}}),bv=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)}}),wv=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()||uv());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(yv).addCommand(bv).addCommand(wv);import{Command as ca}from"commander";import{Command as fm}from"commander";var vv=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(vv);var da=["article","document","footageProject","microsite","presentation","presentationVideo","video"];function ym(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function Iv(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 kv=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:Iv(n.slides),versionId:n.versionId,teamId:n.teamId});m(r)}catch(r){ym(r,"Could not read the artifact")}}),xv=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(kv).addCommand(xv).addCommand(hm);import{Command as vm}from"commander";var wm=1e3;function Rv(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 Cv(e){return e.split(",").map(t=>t.trim()).filter(Boolean)}var Sv=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:Cv(e.categories),format:t,from:e.from,limit:e.limit===void 0?void 0:Rv(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(Sv);import{randomUUID as di}from"crypto";import{readFileSync as Nv}from"fs";import{readFile as Lv}from"fs/promises";import Nt from"chalk";import{Command as Pe}from"commander";import Uv from"ora";import{mkdir as Ev,writeFile as km}from"fs/promises";import{dirname as Pv}from"path";async function Ie(e,t){if(await Ev(Pv(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 Av}from"path";var Tv=/^([A-Za-z][A-Za-z0-9_-]*)=(.+)$/;function Ov(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=Tv.exec(t);return n?{label:n[1],source:n[2]}:{source:t}}function $v(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 Dv(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}=Ov(n);if(xm(c)){let d=Av(c),g=fn(d);t.rejectNonImageFiles&&$v(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=Dv(c,i);return{...o?{label:o}:{},url:l.toString()}}))}}var _v=15e3,jv=40,qv=3;function Mv(e,t){return[...t,e]}async function Vv(e){let t=e.trim(),n=t.startsWith("[")?t:await Lv(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:qv,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 Fv=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)}}),Bv=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)}}),Gv=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",Mv,[]).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?Nv(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 Vv(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 H("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)}}),Kv=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)}}),Wv=new Pe("presenter").description("Discover and create reusable personal presenters").addCommand(Bv).addCommand(Gv).addCommand(Kv),Jv=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"?Uv("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),jv,_v);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)}}),zv=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)}}),Hv=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)}}),Xv=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)}}),Yv=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)}}),Qv=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)}}),Zv=new Pe("look").description("Manage looks under an existing personal presenter").addCommand(Hv).addCommand(Yv).addCommand(Qv).addCommand(Xv),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(Fv).addCommand(Wv).addCommand(Jv).addCommand(Zv).addCommand(zv);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,8 +74,8 @@ ${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 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&>(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&>(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
|
|
77
|
+
`);import{randomUUID as yR}from"crypto";import{readFileSync as bR}from"fs";import{writeFile as wR}from"fs/promises";import Z from"chalk";import{Command as Nn,InvalidArgumentError as Xp}from"commander";import vR from"ora";import{createHash as hI}from"crypto";import{Command as ir,InvalidArgumentError as rr}from"commander";import{createHash as oI}from"crypto";import{existsSync as aI,readFileSync as sI}from"fs";import{basename as dI}from"path";import{Command as cI,InvalidArgumentError as tr}from"commander";import lI from"ora";import{createHash as eI}from"crypto";import{Command as tI,InvalidArgumentError as Cm}from"commander";var nI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function rI(e){if(!nI.test(e))throw new Cm("brand-id expects a UUID from `mf branding list`.");return e}function iI(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 eI("sha256").update(`createBrandAssetUploadUrl:${pa(e)}`).digest("hex").slice(0,32)}var Sm=new tI("upload-url").description("Mint a short-lived brand-scoped storage POST; this does not upload bytes").argument("<brand-id>","Brand UUID you may manage",rI).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",iI).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 mI=["footage","image","before_after","logo","audio"],pI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function uI(e){if(!pI.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 gI(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 fI(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 cI("upload").description("Upload one local file, register it on a brand, and print the asset JSON").argument("<brand-id>","Brand UUID",uI).requiredOption("--file <path>","Local file to upload through Mindframes storage").requiredOption("--kind <kind>","Asset kind: footage | image | before_after | logo | audio",b("--kind",mI)).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",gI).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 file bytes and complete registration input").option("--team-id <id>","Workspace ID; defaults to the selected workspace").action(async(e,t)=>{await w(),aI(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=oI("sha256").update(sI(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=lI({text:`Uploading ${dI(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"],yI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Sn(e){return t=>{if(!yI.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 bI(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 wI(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 hI("sha256").update(e).digest("hex").slice(0,32)}function ci(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var vI=new ir("list").description("List one brand's uploaded assets and print stable asset IDs").argument("<brand-id>","Brand UUID",Sn("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")}}),II=new ir("register").description("Register one app-owned upload from its exact URL, key, MIME, and metadata").argument("<brand-id>","Brand UUID",Sn("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",bI("--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"}',wI).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")}}),kI=new ir("rename").description("Rename one asset, then print its stored label and metadata").argument("<asset-id>","Asset UUID from `mf branding asset list`",Sn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Sn("--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")}}),xI=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`",Sn("asset-id")).requiredOption("--brand <brand-id>","Owning brand UUID",Sn("--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(vI).addCommand(II).addCommand(Sm).addCommand(Pm).addCommand(kI).addCommand(xI);import{createHash as RI,randomUUID as $m}from"crypto";import{existsSync as Om,readdirSync as CI,readFileSync as SI,statSync as EI}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 RI("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 En(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 PI=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 En("listClaims",n,"List failed")}),AI=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 En("getClaim",r,"Read failed")}),TI=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 En("setClaim",n,"Write failed",ha(`setClaim:${e}:${JSON.stringify(n)}`))}),OI={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"},$I=/\.(pdf|txt)$/i;function DI(e){(!Om(e)||!EI(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(OI)){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]=SI(i,"utf8")}return t}function NI(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 LI(e,t,n){let r=[...t].map(([i,o])=>({fileName:i,libraryFileId:o}));for(let i of CI(e).sort()){if(!$I.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 UI=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=DI(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 LI(t,NI(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(PI).addCommand(AI).addCommand(TI).addCommand(UI),_I=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 En("listLegalBlocks",n,"List failed")}),jI=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 En("getLegalBlock",r,"Read failed")}),qI=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 En("setLegalBlock",n,"Write failed",ha(`setLegalBlock:${e}:${JSON.stringify(n)}`))}),jm=new rt("legal-blocks").description("Brand ISI and legal blocks (governed, verbatim)").addCommand(_I).addCommand(jI).addCommand(qI);import{Command as qm,InvalidArgumentError as MI}from"commander";var VI=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,FI=["presentation","reel","story","video","walkthrough","slide","microsite","article"];function BI(e){if(!VI.test(e))throw new MI("Expected a brand UUID from `mf branding list`.");return e}var GI=new qm("resolve").description("Resolve design tokens, node trace, rules, and conflicts").argument("<brand-id>","Brand UUID",BI).requiredOption("--artifact <type>","Artifact type",b("--artifact",[...FI])).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(GI);import{createHash as KI,randomUUID as WI}from"crypto";import{Command as it,InvalidArgumentError as Vm}from"commander";var JI=/^[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(!JI.test(e))throw new Vm("Expected a brand UUID from `mf branding list`.");return e}function zI(e){if(e==="true")return!0;if(e==="false")return!1;throw new Vm("--show expects true or false.")}function pi(e,t){return KI("sha256").update(JSON.stringify([e,t])).digest("hex").slice(0,32)}function Pn(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var HI=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){Pn(o,"Custom colour update failed")}}),XI=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){Pn(i,"Custom colour removal failed")}}),YI=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,WI()]));m(t.wait===!1?r:await Vc(r.runId,t.teamId))}catch(r){Pn(r,"Brand foundation sync failed")}}),QI=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){Pn(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(HI).addCommand(XI)).addCommand(YI).addCommand(QI),ZI=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){Pn(n,"Footer read failed")}}),ek=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",zI).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){Pn(r,"Footer update failed")}}),Bm=new it("footer").description("Read or update the brand footer").addCommand(ZI).addCommand(ek);import{createHash as tk}from"crypto";import{Command as Gm}from"commander";var nk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function rk(e){nk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function ik(e){return tk("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 ok(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 ak(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 sk=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(),rk(e);let n={brandId:e,gradients:ok("--gradients",t.gradients),teamId:t.teamId};t.roles!==void 0&&(n.gradientRoles=ak("--roles",t.roles));try{m(await p("setBrandGradients",n,ik(`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(sk);import{createHash as dk}from"crypto";import{Command as _t}from"commander";var ck=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ar(e){ck.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function lk(e,t=[]){return[...t,e]}function va(e){return dk("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 mk=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)}}),pk=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)}}),uk=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)}}),gk=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)}}),fk=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.",lk).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)}}),hk=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(mk).addCommand(pk).addCommand(uk).addCommand(gk).addCommand(fk).addCommand(hk);import{randomUUID as yk}from"crypto";import{readFile as zm}from"fs/promises";import{Command as bk}from"commander";var Hm=new bk("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??yk();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 wk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function vk(e){if(!wk.test(e))throw new Ym("Expected a brand UUID from `mf branding list`.");return e}function Ik(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 kk=new Xm("list").description("List recent safe job summaries for one brand").argument("<brand-id>","Brand UUID",vk).option("--limit <count>","Newest jobs to return, 1-50 (default: 20)",Ik).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(kk);import{createHash as xk}from"crypto";import{Command as ut}from"commander";var Rk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gt(e){Rk.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function An(e){return xk("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&>(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},An(`setBrandStar:${e}:${n}`)))}catch(r){a(u(r,"Star failed")),process.exit(s.GENERAL_ERROR)}});async function Ck(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 Ck(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},An(`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&>(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,An(`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},An(`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},An(`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},An(`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 Sk,readFileSync as Ek}from"fs";import{basename as Pk}from"path";import{Command as ui}from"commander";import Ak from"ora";function Tk(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??Tk("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)),Sk(t.file)||(a(`File not found: ${t.file}`),process.exit(s.INVALID_INPUT));let r=ka("sha256").update(Ek(t.file)).digest("hex"),i=t.idempotencyKey??ka("sha256").update(`setBrandLogo:${t.teamId??"current"}:${e??"default"}:${n}:${r}`).digest("hex").slice(0,32),o=Ak({text:`Uploading ${Pk(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 Ok,randomUUID as $k}from"crypto";import{Command as Tn,InvalidArgumentError as gi}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,Nk=["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(!Dk.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 Ok("sha256").update(JSON.stringify([e,t,$k()])).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 Lk=new Tn("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")}}),Uk=new Tn("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")}}),_k=new Tn("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",Nk)).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")}}),jk=new Tn("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 Tn("permission").description("Administer explicit member access overrides for a team brand").addCommand(Uk).addCommand(Lk).addCommand(_k).addCommand(jk),up=new Tn("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 qk}from"crypto";import{Command as qt,InvalidArgumentError as Ra}from"commander";var Mk=/^[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(Mk.test(e))return e;throw new Ra(`${t} must be a UUID.`)}function Vk(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 Fk(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 Bk(e){return qk("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)",Vk,50).option("--offset <n>","Zero-based offset (default 0)",Fk,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},Bk(`cancelBrandPresentationSync:${r}:${i}`)),"Could not cancel brand sync")});import{createHash as Gk,randomUUID as vp}from"crypto";import{Command as ft}from"commander";var Kk=/^[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 On(e){Kk.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 Wk(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 Gk("sha256").update(e).digest("hex").slice(0,32)}var Jk=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(),On(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)}}),zk=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(),On(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],Hk=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(),On(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)}}),Xk=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(),On(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)}}),Yk=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(),On(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)}}),Qk=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(),On(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=Wk("--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)}}),Zk=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(Jk).addCommand(zk).addCommand(Hk).addCommand(Xk).addCommand(Yk).addCommand(Qk).addCommand(Zk);import{randomUUID as Ea}from"crypto";import{Command as $n}from"commander";import{randomUUID as ex}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),{[un]:!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 tx=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(tx).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??ex(),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 H(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}),gn(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 nx=new $n("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})}),rx=new $n("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})}),ix=new $n("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())}),ox=new $n("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())}),ax=new $n("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 $n("pronunciation").description("Manage the words and spoken forms in a brand's pronunciation dictionary").addCommand(nx).addCommand(rx).addCommand(ix).addCommand(ax).addCommand(ox).addCommand(Sp);import{createHash as sx}from"crypto";import{Command as yi}from"commander";var dx=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Pp(e){dx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function cx(e,t=[]){return[...t,e]}function lx(e){return sx("sha256").update(e).digest("hex").slice(0,32)}var mx=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)}}),px=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.",cx).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,lx(`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)}}),ux=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(mx).addCommand(px).addCommand(ux);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 gx(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 fx(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(fx):e.brandings.map(gx)}import{createHash as hx}from"crypto";import{Command as yt,InvalidArgumentError as yx}from"commander";var bx=["x","instagram","facebook","linkedin","tiktok","youtube"],wx=/^[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(!wx.test(e))throw new yx("Expected a UUID returned by the corresponding list command.");return e}function bi(e,t){return hx("sha256").update(JSON.stringify([e,...t])).digest("hex")}function Dn(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var vx=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){Dn(t,"Competitor list failed")}}),Ix=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){Dn(r,"Competitor write failed")}}),kx=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){Dn(n,"Competitor removal failed")}}),$p=new yt("competitor").description("List, add, update, or remove a brand's competitor watch rows").addCommand(vx).addCommand(Ix).addCommand(kx),xx=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){Dn(t,"Social-account list failed")}}),Rx=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",bx)).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){Dn(r,"Social-account write failed")}}),Cx=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){Dn(n,"Social-account removal failed")}}),Dp=new yt("social").description("List, record, or remove the social accounts owned by a brand").addCommand(xx).addCommand(Rx).addCommand(Cx);import{createHash as Sx}from"crypto";import{Command as Np}from"commander";var Ex=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Px(e){Ex.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Ax(e){return Sx("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(),Px(e);let n={brandId:e,teamId:t.teamId};try{let r=await p("syncBrandToPresentations",n,Ax(`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 Tx}from"crypto";import{readFile as Ox}from"fs/promises";import{Command as _p}from"commander";var $x=["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 Dx(e){let t=e.split(".").filter(Boolean);for(let n=t.length;n>=2;n--){let r=t.slice(0,n).join(".");if($x.includes(r))return{fieldPath:t.slice(n),nodeKey:r}}return{fieldPath:t.slice(2),nodeKey:t.slice(0,2).join(".")}}function Nx(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}=Dx(i),g=Lx(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 Lx(e){return e==="true"?!0:e==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(e)?Number(e):e}function Ux(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}=Ux(e,t),o;try{o=r.length>0?Nx(r):void 0}catch(l){a(u(l,"Invalid token pair")),process.exit(s.INVALID_INPUT)}let c;if(n.designMd)try{c=await Ox(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},Tx()))}catch(l){a(u(l,"Write failed")),process.exit(s.GENERAL_ERROR)}});import{createHash as _x}from"crypto";import{Command as Ii}from"commander";var jx=/^[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){jx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Mp(e){return _x("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 qx(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 Mx(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 Vx=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)}}),Fx=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=qx("--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=Mx(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)}}),Bx=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(Vx).addCommand(Fx).addCommand(Bx);import{createHash as Gx}from"crypto";import{Command as La}from"commander";var Kx=/^[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 Wx(e){Kx.test(e)||(a(`"${e}" is not a brand id. Pass the UUID from \`branding list\`.`),process.exit(s.INVALID_INPUT))}function Jx(e){if(Da.includes(e))return e;a(`"${e}" is not a channel. Pass one of: ${Da.join(", ")}.`),process.exit(s.INVALID_INPUT)}function zx(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 Hx(e){return Gx("sha256").update(e).digest("hex").slice(0,32)}var Na=["replace","append"];function Xx(e){if(Na.includes(e))return e;a(`"${e}" is not a mode. Pass one of: ${Na.join(", ")}.`),process.exit(s.INVALID_INPUT)}function Yx(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 Qx=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&&Wx(e),t.channel!==void 0&&Jx(t.channel),t.mode!==void 0&&Xx(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=Yx(t.count)),t.tone!==void 0&&(n.brandTone=t.tone),t.style!==void 0&&(n.brandStyle=t.style),t.colors!==void 0&&(n.sourceColors=zx("--colors",t.colors));try{let r=await p("generateBrandVariations",n,Hx(`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)}}),Zx=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(Qx).addCommand(Zx);import{createHash as eR}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 tR(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 nR(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 rR(e){return eR("sha256").update(e).digest("hex").slice(0,32)}var iR=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)}}),oR=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=nR("--from",t.from)),t.to!==void 0&&(n.to=tR("--to",t.to));try{m(await p("diffBrandVersions",n))}catch(r){a(u(r,"Diff failed")),process.exit(s.GENERAL_ERROR)}}),aR=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,rR(`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(iR).addCommand(oR).addCommand(aR);import{randomUUID as sR}from"crypto";import{Command as xi}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.`),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 cR=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 lR=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??sR()))}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(cR).addCommand(Kp("set-voices","setBrandVideoVoices","voices")).addCommand(Kp("set-presenters","setBrandVideoPresenters","presenters")).addCommand(lR);import{createHash as mR}from"crypto";import{Command as lr}from"commander";var pR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Va(e){pR.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 mR("sha256").update(e).digest("hex").slice(0,32)}var uR=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)}}),gR=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)}}),fR=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)}}),hR=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(uR).addCommand(gR).addCommand(fR).addCommand(hR);function IR(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 kR(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 xR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,RR=50;function CR(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 Nn("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 Nn("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)",kR("--limit")).option("--offset <n>","Brands to skip before the page",IR("--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??RR)&&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 Nn("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(),!xR.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 wR(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}CR(r)}catch(n){a("The command failed. Please try again."),process.exit(n.exitCode??1)}})).addCommand(new Nn("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 Nn("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??yR();t.approvalReceipt&&t.approvalReceiptStdin&&(a("Pass only one approval receipt input mode."),process.exit(s.INVALID_INPUT));let o=t.approvalReceiptStdin?bR(0,"utf8").trim():t.approvalReceipt;t.approvalReceiptStdin&&!o&&(a("No approval receipt was provided on stdin."),process.exit(s.INVALID_INPUT));let c=vR({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 Nn("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 Ln}from"commander";function SR(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:SR(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: ${ER(e.background)}`),e.voiceId&&I(` Voice: ${e.voiceId}`)}function ER(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 PR=new Ln("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)}}),AR=Zp(new Ln("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)}}),TR=Zp(new Ln("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)}}),OR=new Ln("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)}}),$R=new Ln("preset").description("Saved ways a cast member appears").addCommand(PR).addCommand(AR).addCommand(TR).addCommand(OR),Fa=new Ln("cast").description("The faces and voices your videos can use").addCommand($R);Fa.addHelpText("after",`
|
|
79
79
|
${mr.bold("Examples:")}
|
|
80
80
|
${mr.gray("# List the saved presenter/backdrop/voice combinations")}
|
|
81
81
|
$ ${f.commands[0]} cast preset list
|
|
@@ -86,7 +86,7 @@ ${mr.bold("See also:")}
|
|
|
86
86
|
|
|
87
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
|
|
89
|
+
`);import{randomUUID as DR}from"crypto";import{readFile as NR}from"fs/promises";import pr from"chalk";import{Command as eu}from"commander";var LR=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 NR(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??DR());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(LR);Ba.addHelpText("after",`
|
|
90
90
|
${pr.bold("Examples:")}
|
|
91
91
|
${pr.gray("# Normalized text from a local document")}
|
|
92
92
|
$ ${f.commands[0]} content extract ./paper.pdf
|
|
@@ -97,9 +97,9 @@ ${pr.bold("See also:")}
|
|
|
97
97
|
|
|
98
98
|
${pr.gray("# Spoken words out of audio or video")}
|
|
99
99
|
$ ${f.commands[0]} transcript --help
|
|
100
|
-
`);import{existsSync as
|
|
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")}}),
|
|
100
|
+
`);import{existsSync as UR,readFileSync as _R}from"fs";import jR,{resolve as nu}from"path";import le from"chalk";import{Command as qR}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 MR(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 qR("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)UR(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 VR(),t.stdin&&!A&&(a("No content received from stdin"),process.exit(6)));let D=t.context;if(t.contextFile)try{D=_R(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=MR(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:jR.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 xn("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 hn(St.entity.id):void 0;if(t.output==="json")console.log(JSON.stringify({success:!0,presentation:Et,run:St,viewUrl:Et?bn(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?bn(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 xn){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 VR(){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 FR=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)}}),BR=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(FR).addCommand(BR);import{randomUUID as GR}from"crypto";import{readFile as KR}from"fs/promises";import{Command as X,InvalidArgumentError as Ja}from"commander";function Fe(e){return t=>{if(!t.trim())throw new Ja(`${e} must not be blank.`);return t}}function WR(e,t){return[...t??[],e]}function JR(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 Un(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 _n(e,t){return{documentId:e,cursor:t.cursor,pageSize:t.pageSize}}async function ou(e){if(e.startsWith("@file:"))return KR(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:${GR()}`: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 zR(){let e=Ve(new X("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 X("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=Un(new X("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,()=>_n(S,E))),r=Ve(new X("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??[],JR(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 X("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=Un(new X("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,()=>({..._n(S,E),anchorSlideId:E.anchorSlideId,roomId:E.roomId===void 0?void 0:E.roomId==="internal"?null:E.roomId}))),c=Un(new X("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,()=>({..._n(S,A),threadId:E}))),l=Un(new X("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,()=>_n(S,E))),d=Ve(new X("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 X("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",WR)).action(async(S,E,A)=>ae("setDiscussionReviewers",A,()=>({documentId:S,threadId:E,reviewerUserIds:A.reviewer??[],expectedRevision:A.expectedRevision}),!0)),y=Un(new X("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,()=>_n(S,E))),v=Ve(new X("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 X("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 X("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=Un(new X("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,()=>_n(S,E))),$=Ve(new X("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 X("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 X("discussion").description("Collaborate on private decks with attributed human and external-agent messages").addCommand(new X("actor").description("Register the current external-agent credential").addCommand(e)).addCommand(new X("grant").description("Manage external-agent discussion access").addCommand(t).addCommand(n)).addCommand(r).addCommand(new X("state").description("Resolve or reopen discussion threads").addCommand(i)).addCommand(new X("message").description("Edit or moderate an existing discussion message").addCommand(v).addCommand(x)).addCommand(new X("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=zR();import{randomUUID as HR}from"crypto";import{readFile as XR}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 XR(t.slice(1),"utf8");if(t==="-"||!process.stdin.isTTY)return YR();a("No document body. Pass --content <text>, --content @<path>, or pipe it on stdin."),process.exit(s.GENERAL_ERROR)}async function YR(){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}:${HR()}`}function Vt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function QR(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 ZR=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??QR(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")}}),eC=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")}}),tC=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")}}),nC=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")}}),rC=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")}}),iC=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")}}),oC=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(ZR).addCommand(eC).addCommand(tC).addCommand(nC).addCommand(rC).addCommand(iC).addCommand(oC);import{writeFile as aC}from"fs/promises";import{resolve as lu}from"path";import ur from"chalk";import{Command as sC}from"commander";import dC from"ora";var cC=["html","pdf","pptx"],Ha=new sC("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",cC),"html").option("--team-id <id>","Workspace ID (uses configured default)").action(async(e,t)=>{await w();let n=dC("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 yn(i.downloadUrl);await aC(o,Buffer.from(c)),n.succeed("Export complete!"),console.log(),I(`File saved: ${o}`),I(`Format: ${i.format}`),I(`Slides: ${i.slideCount}`),I(`Size: ${lC(c.byteLength)}`),console.log()}catch(r){n.fail("Export failed"),a("The command failed. Please try again."),process.exit(r.exitCode??1)}});function lC(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}Ha.addHelpText("after",`
|
|
103
103
|
${ur.bold("Examples:")}
|
|
104
104
|
${ur.gray("# Self-contained interactive HTML (default)")}
|
|
105
105
|
$ ${f.commands[0]} export <id-or-slug> -o deck.html
|
|
@@ -111,9 +111,9 @@ ${ur.bold("Examples:")}
|
|
|
111
111
|
${ur.bold("See also:")}
|
|
112
112
|
${ur.gray("# For an MP4 instead")}
|
|
113
113
|
$ ${f.commands[0]} presentation video <id-or-slug>
|
|
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(`
|
|
114
|
+
`);import{randomUUID as mC}from"crypto";import{existsSync as pC}from"fs";import{Command as wt,InvalidArgumentError as mu}from"commander";var uC=/^[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(!uC.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}:${mC()}`}function Ft(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var gC=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(),pC(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")}}),fC=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")}}),hC=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")}}),yC=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")}}),bC=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")}}),wC=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")}}),vC=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(gC).addCommand(vC).addCommand(wC).addCommand(yC).addCommand(hC).addCommand(bC).addCommand(fC);import{Command as Ue}from"commander";var IC=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})}),kC=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}})}),xC=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})}),RC=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}})}),CC=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})}),SC=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})}),EC=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})}),PC=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)}),AC=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})}),TC=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)}),OC=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(IC).addCommand(kC).addCommand(xC).addCommand(RC).addCommand(CC).addCommand(SC).addCommand(EC).addCommand(PC).addCommand(AC).addCommand(TC).addCommand(OC);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 $C}from"commander";function DC(e){return new Set((e??"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean))}function NC(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 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",`
|
|
116
|
+
`)}var bu=new $C("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"?DC(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 hn(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=bn(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&&NC(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 LC}from"crypto";import{Command as Pi}from"commander";import UC from"ora";function _C(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}function jC(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:_C(e.source),transparentBackground:t==="icon"}}}function qC(e){let t=e.url||e.imageUrl;if(!t)throw new Error("Image search returned a result without a URL");return t}function MC(e){return e.transparent??e.isTransparent??e.metadata?.transparent??e.metadata?.isTransparent}function VC(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 FC(e,t){let n=e.data.results.map(r=>r.results.map(i=>{let o=i,c=MC(o);if(t==="icon"&&c!==!0)throw new Error("Icon search returned a result without a verified transparent background");return{...o,url:qC(o),provider:r.providerName,assetType:t,...c!==void 0?{transparent:c}:{}}}));return VC(n)}function BC(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 GC(e){return{requestId:e.runId,status:BC(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 GC(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 KC=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"?UC("Searching for images...").start():null,r;try{r=jC(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=FC(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)}}),WC=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??LC(),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)}}),JC=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(KC).addCommand(WC).addCommand(JC);import{randomUUID as zC}from"crypto";import{Command as Ya,InvalidArgumentError as HC}from"commander";function XC(e,t){return n=>{let r=Number(n);if(!n.trim()||!Number.isSafeInteger(r)||r<t)throw new HC(`${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:${zC()}`: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 YC(){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",XC("--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=YC();import{Command as Qa}from"commander";var QC=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)}}),ZC=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(QC).addCommand(ZC);import{randomUUID as eS}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 jn(e){return`cli:library:${e}:${eS()}`}function Gt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var tS=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")}}),nS=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},jn("create")))}catch(n){Gt(n,"Could not create the folder")}}),rS=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},jn("rename")))}catch(r){Gt(r,"Could not rename the folder")}}),iS=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},jn("recolor")))}catch(n){Gt(n,"Could not recolour the folder")}}),oS=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},jn("move")))}catch(n){Gt(n,"Could not move the folder")}}),aS=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},jn("delete")))}catch(n){Gt(n,"Could not delete the folder")}}),sS=new st("folders").description("Manage Library folders").addCommand(tS).addCommand(nS).addCommand(rS).addCommand(iS).addCommand(oS).addCommand(aS),dS=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},jn("file")))}catch(r){Gt(r,"Could not file that item")}}),es=new st("library").description("Library folders and filing").addCommand(sS).addCommand(dS);es.addHelpText("after",`
|
|
117
117
|
${Ai.bold("Examples:")}
|
|
118
118
|
${Ai.gray("# Browse the folder tree and file an artifact into a folder")}
|
|
119
119
|
$ ${f.commands[0]} library folders list
|
|
@@ -122,7 +122,7 @@ ${Ai.bold("Examples:")}
|
|
|
122
122
|
${Ai.bold("See also:")}
|
|
123
123
|
${Ai.gray("# A different thing: reusable video clips, not Library folders")}
|
|
124
124
|
$ ${f.commands[0]} video library --help
|
|
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",`
|
|
125
|
+
`);import{randomUUID as Su}from"crypto";import{Command as qn,InvalidArgumentError as Eu}from"commander";var Pu=new qn("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)}}),cS=new qn("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(cS);var Au=new qn("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)}}),lS=new qn("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(lS));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 mS=new qn("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 qn("media").description("Ingest and transcribe recordings you already own").addCommand(mS).addCommand(Pu).addCommand(Au);import{Command as ns}from"commander";function pS(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 uS=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)",pS,[]).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)}}),gS=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(uS).addCommand(gS);import{randomUUID as $u}from"crypto";import{readFile as fS}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 hS(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 yS(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 fS(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 H(e,o.runId,t.teamId))}catch(o){a(gn(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 bS(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 wS(){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:yS(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",hS).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=>{bS(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=wS();import{randomUUID as vS}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 IS=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?kS("--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??vS();try{let g=e.optionsJson?xS("--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 kS(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 xS(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 RS=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(IS).addCommand(RS);import{randomUUID as OS}from"crypto";import{Command as ls}from"commander";import $S from"ora";import{readFileSync as CS}from"fs";var Lu=500,Uu=1e4,Ni=100,_u=1e4,ju=1e3,Mu=["duration_s","idempotency_key","narration","schema_version","video_description"],SS=["end_s","id","start_s","text","words"],ES=["end","id","start","text"],PS=["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,PS,"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(CS(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(AS),e.idempotency_key!==void 0&&!vt(e.idempotency_key))throw new Error("Audio request idempotency_key must be a non-empty string")}function AS(e,t){let n=`narration.${t}`;if(!Li(e))throw new Error(`Audio request ${n} must be an object`);if(yr(e,SS,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)=>{TS(r,`${n}.words.${i}`)})}}function TS(e,t){if(!Li(e))throw new Error(`Audio request ${t} must be an object`);if(yr(e,ES,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 DS=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"?$S("Generating music for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??OS();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 NS=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(DS).addCommand(NS);import{Command as ms,InvalidArgumentError as LS}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 LS(`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 US=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")}}),_S=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(US).addCommand(_S);import{randomUUID as Ht}from"crypto";import{readFile as If}from"fs/promises";import W from"chalk";import{Command as J,InvalidArgumentError as no}from"commander";import{createParser as jS}from"eventsource-parser";async function Ge(e,t,n,r={}){let i=null,o=!1;try{let c;for(;;){let l=await MS(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 qS(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 MS(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=jS({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=qS(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 VS}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??VS():void 0))}catch(c){a(u(c,"Deck embed share request failed")),process.exit(s.GENERAL_ERROR)}}var FS=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)}),BS=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)}),GS=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(FS).addCommand(BS).addCommand(GS);import{readFile as KS}from"fs/promises";import{Command as Qu}from"commander";var WS=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 KS(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(WS).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 JS=/^[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){JS.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 zS=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())}),HS=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")}),XS=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(zS).addCommand(HS).addCommand(XS);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 ys}from"commander";function
|
|
136
|
+
`);import{Command as ys}from"commander";function YS(e,t){return[...t,e]}function ng(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var QS=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",YS,[]).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 H("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
|
-
`),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",`
|
|
155
|
+
`),ZS=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(QS).addCommand(ZS);import{readFileSync as eE}from"fs";import{Command as tE}from"commander";var ig=new tE("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(eE(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 nE}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 nE(`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 rE}from"commander";var lg=new rE("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 iE}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 oE(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 oE(e){let t=e.trim(),n=t.startsWith("{")?t:await iE(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 aE}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??aE():void 0))}catch(c){a(u(c,"Video embed share request failed")),process.exit(s.GENERAL_ERROR)}}var sE=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)}),dE=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)}),cE=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(sE).addCommand(dE).addCommand(cE);import{createHash as yg}from"crypto";import{Command as Wt,InvalidArgumentError as lE}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??mE(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??pE(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 lE(`Expected an integer between ${e} and ${t}.`);return r}}function mE(e,t){return`presentation-video-cancel:${yg("sha256").update(`${e}\0${t}`).digest("hex")}`}function pE(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 uE}from"fs";var Sg=["bottom-left","bottom-right","top-left","top-right","left-half","right-half","left-overlay","right-overlay","full"];function Mn(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(uE(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"],gE=["a","b","c","d"];function Dg(e,t=[]){return[...t,e]}function Y(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)&&Y('--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)&&Y(`--option needs "<label>=<scene-id>"; got "${t}".`),{id:gE[n],label:i,targetSceneId:o}})}function Ug(e){return e.action==="open-url"?(e.url===void 0&&Y("--action open-url needs --url <https-url>."),{type:"open_url",url:e.url}):e.action==="jump"?(e.targetScene===void 0&&Y("--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&&Y("--scene-end jump needs --target-scene <scene-id>."),{type:"jump_to_scene",sceneId:e.targetScene})}function fE(e,t){e.url!==void 0&&!(t==="button"&&e.action==="open-url")&&Y("--url only applies to --button --action open-url."),e.targetScene!==void 0&&!(t==="button"&&e.action==="jump")&&!(t==="scene_end"&&e.sceneEnd==="jump")&&Y("--target-scene only applies to --action jump or --scene-end jump."),e.option!==void 0&&t!=="choice"&&Y("--option only applies to --choice."),(e.studySet!==void 0||e.item!==void 0)&&t!=="question"&&Y("--study-set and --item only apply to --question."),(e.duration!==void 0||e.placement!==void 0||e.pause===!1)&&t!=="button"&&Y("--duration, --placement and --no-pause only apply to --button."),e.at!==void 0&&t==="scene_end"&&Y("--at does not apply to --scene-end: it always fires at the scene's end."),e.action!==void 0&&t!=="button"&&Y("--action only applies to --button; --scene-end takes jump|end as its value.")}function hE(e){let t=Ng(e);t.length===0&&Y("Pass the interaction kind: --button <label>, --choice <prompt>, --question, or --scene-end <jump|end>."),t.length>1&&Y("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive.");let n=t[0];fE(e,n);let r=e.scene;switch(n){case"button":return e.action===void 0&&Y("--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&&Y('--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&&Y("--question needs --study-set <study-set-id>."),e.item===void 0&&Y("--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 yE(e){Ng(e).length>1&&Y("Pass only one kind flag: --button, --choice, --question and --scene-end are exclusive."),e.action!==void 0&&e.sceneEnd!==void 0&&Y("--action and --scene-end both set the action; pass only one."),e.url!==void 0&&e.action!=="open-url"&&Y("--url needs --action open-url."),e.targetScene!==void 0&&e.action!=="jump"&&e.sceneEnd!=="jump"&&Y("--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&&Y("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 bE=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=hE(n);await Hi("Interaction add failed",()=>Rs(e,n,{interaction:r,type:"add_interaction"}))}),wE=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=yE(r);await Hi("Interaction update failed",()=>Rs(e,r,{interactionId:t,patch:i,type:"update_interaction"}))}),vE=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()))}),IE=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(bE).addCommand(wE).addCommand(IE).addCommand(vE).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
|
|
166
|
+
`);import{randomUUID as kE}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??kE())}var xE=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:Mn(n.placement??"background"),sceneIds:br(n.scenes),source:c,...o?{timing:o}:{},type:"add_scene_layer"})})}),RE=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:Mn(i.placement)}:{},sceneId:t,...c?{text:c}:{},...o?{timing:o}:{},type:"update_scene_layer"}))}),CE=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"}))}),SE=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:Mn(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(xE).addCommand(RE).addCommand(CE).addCommand(SE).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,8 +177,8 @@ 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{Command as
|
|
181
|
-
`))}}function
|
|
180
|
+
`);import{Command as EE}from"commander";function Vn(e){return`${(e*100).toFixed(1)}%`}function Qi(e){return`x ${Vn(e.left)}\u2013${Vn(e.left+e.width)}, y ${Vn(e.top)}\u2013${Vn(e.top+e.height)}`}function PE(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 ${Vn(r.blockOverlap)} of block, ${Vn(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 AE(e,t){return t.concat([e])}var Vg=new EE("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",AE,[]).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"){PE(i);return}m(i)}catch(r){a(u(r,"Layout report failed")),process.exit(s.GENERAL_ERROR)}}).addHelpText("after",`
|
|
182
182
|
What it answers:
|
|
183
183
|
Where each scene's captions, presenter, and layers land against the slide's
|
|
184
184
|
own content blocks \u2014 BEFORE paying for a render. Run it after setup and fix
|
|
@@ -194,7 +194,7 @@ Status:
|
|
|
194
194
|
excluded \u2014 scene is excluded from the render.
|
|
195
195
|
|
|
196
196
|
This command is free and never renders video.
|
|
197
|
-
`);import{randomUUID as
|
|
197
|
+
`);import{randomUUID as TE}from"crypto";import{readFileSync as OE}from"fs";import{Command as $E}from"commander";var DE=16384;async function NE(){let e="";for await(let t of process.stdin)if(e+=String(t),e.length>DE)throw new Error("Clipboard input exceeds the avatar copy size limit.");return e}async function LE(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?OE(e.clipFile,"utf8").trim():e.clipStdin?NE():e.clip}var Ss=new $E("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 LE(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||TE());m(o)}catch(i){a(u(i,"Presenter paste failed")),process.exit(s.GENERAL_ERROR)}});ke(Ss);import{randomUUID as UE}from"crypto";import{Command as _E}from"commander";var jE=["basic","standard","premium"],Es=new _E("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&&!jE.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},qE(r.idempotencyKey)))}catch(i){a(u(i,"Scene presenter update failed")),process.exit(s.GENERAL_ERROR)}});function qE(e){return e||UE()}ke(Es);import{createHash as ME}from"crypto";import{Command as Ir}from"commander";var VE=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",`
|
|
198
198
|
What happens:
|
|
199
199
|
Reuses the draft's checkpointed preview run and prepares only missing deck-slide images.
|
|
200
200
|
Card and reusable-video scenes report not_required. This command is free and does not render MP4.
|
|
@@ -203,19 +203,19 @@ Recovery:
|
|
|
203
203
|
$ ${f.commands[0]} presentation video previews status <run-id>
|
|
204
204
|
$ ${f.commands[0]} presentation video previews inspect <project-id>
|
|
205
205
|
$ ${f.commands[0]} presentation video previews retry <project-id> # only after failed/cancelled
|
|
206
|
-
`),
|
|
206
|
+
`),FE=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",`
|
|
207
207
|
Output:
|
|
208
208
|
summary.status is idle, preparing, ready, failed, or not_required.
|
|
209
209
|
scenes[] reports ready, missing, or not_required plus stored horizontalUrl/verticalUrl.
|
|
210
210
|
run contains the durable run ID, phase, progress, status, and typed public error.
|
|
211
|
-
`),
|
|
211
|
+
`),BE=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",`
|
|
212
212
|
Rules:
|
|
213
213
|
Only failed or cancelled preview runs can be retried. Active and completed runs are refused.
|
|
214
214
|
Retry resumes unfinished scenes; it does not rebuild images already stored on the draft.
|
|
215
215
|
|
|
216
216
|
Next:
|
|
217
217
|
$ ${f.commands[0]} presentation video previews inspect <project-id>
|
|
218
|
-
`),
|
|
218
|
+
`),GE=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(VE).addCommand(FE).addCommand(BE).addCommand(GE);function Bg(e,t,n){return`presentation-video-previews:${e}:${ME("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)}}),KE=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",WE).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(KE);function WE(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 XE}from"crypto";import{Command as As}from"commander";import{readFile as JE}from"fs/promises";import{InvalidArgumentError as Wg}from"commander";async function zE(e){let t=e.trim(),n=t.startsWith("{")?t:await JE(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 zE(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 HE({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 HE(e){return Object.fromEntries(Object.entries(e).filter(t=>t[1]!==void 0))}var YE=["right-way","wrong-way"],QE=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";YE.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:Mn(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??XE()))}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(QE).addHelpText("after",`
|
|
219
219
|
Without --image the clip is generated from --prompt alone. A wrong-way clip
|
|
220
220
|
is refused unless you declare it people-free with --no-real-person. Layers
|
|
221
221
|
already in the project are managed with
|
|
@@ -226,7 +226,7 @@ Examples:
|
|
|
226
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
|
|
227
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
|
|
228
228
|
${f.commands[0]} presentation video scene-clip status <run-id>
|
|
229
|
-
`);import{randomUUID as
|
|
229
|
+
`);import{randomUUID as ZE}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:ZE(),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 eP}from"crypto";import{Command as Os}from"commander";var tP=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??eP()))}catch(i){a(u(i,"Scene render failed")),process.exit(s.GENERAL_ERROR)}}),nP=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(tP).addCommand(nP).addHelpText("after",`
|
|
230
230
|
A scene render produces the same frames the final video uses, so rendering the
|
|
231
231
|
whole video afterwards is not charged for the scenes it reuses. Editing a scene
|
|
232
232
|
invalidates its segment; render it again to see the change.
|
|
@@ -234,13 +234,13 @@ invalidates its segment; render it again to see the change.
|
|
|
234
234
|
Examples:
|
|
235
235
|
${f.commands[0]} presentation video scene render <project-id> slide-3 --yes
|
|
236
236
|
${f.commands[0]} presentation video scene status <run-id>
|
|
237
|
-
`);import{randomUUID as nf}from"crypto";import{writeFile as
|
|
237
|
+
`);import{randomUUID as nf}from"crypto";import{writeFile as rP}from"fs/promises";import{resolve as iP}from"path";import{Command as eo,InvalidArgumentError as oP}from"commander";var ef=["1.2","2004"];function tf(e){return t=>{let n=Number(t);if(!Number.isInteger(n))throw new oP(`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 aP=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=iP(n.out??r.fileName);try{let o=await yn(r.downloadUrl);await rP(i,Buffer.from(o))}catch(o){a(u(o,"SCORM download failed")),process.exit(s.GENERAL_ERROR)}m({...r,outputPath:i})}),sP=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}))}),dP=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(aP).addCommand(sP).addCommand(dP).addHelpText("after",`
|
|
238
238
|
Examples:
|
|
239
239
|
${f.commands[0]} presentation video scorm export <project-id> --scorm-version 2004 --completion 95 --pass-mark 80
|
|
240
240
|
${f.commands[0]} presentation video scorm export <project-id> --out course.zip
|
|
241
241
|
${f.commands[0]} presentation video scorm list <project-id>
|
|
242
242
|
${f.commands[0]} presentation video scorm revoke <export-id>
|
|
243
|
-
`);import{createHash as
|
|
243
|
+
`);import{createHash as cP,randomUUID as lP}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??lP(),i=await U(n.teamId),o=n.file?(await ie(n.file,{idempotencyKey:`script:${cP("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=>mP(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 mP(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 pP}from"commander";var $s=new pP("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",`
|
|
244
244
|
Caption geometry uses frame-relative values. x/y are the box center; width/height are its size.
|
|
245
245
|
Omitted caption fields keep their saved values. Run presentation video inspect <project-id> to verify them.
|
|
246
246
|
Presenter geometry also uses frame-relative values. Omit --presenter-slide-id to edit the default; pass it for one scene.
|
|
@@ -252,9 +252,9 @@ Examples:
|
|
|
252
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
|
|
253
253
|
${f.commands[0]} presentation video settings <project-id> --presenter-slide-id <slide-id> --presenter-apply-to-all --yes
|
|
254
254
|
${f.commands[0]} presentation video settings <project-id> --presenter-background color --presenter-background-hex '#14213d' --yes
|
|
255
|
-
`);ke($s);import{Command as kr,InvalidArgumentError as
|
|
255
|
+
`);ke($s);import{Command as kr,InvalidArgumentError as bP}from"commander";import{createHash as uP}from"crypto";import{existsSync as gP,readFileSync as fP}from"fs";import{Command as lf,InvalidArgumentError as mf}from"commander";function hP(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 yP(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",yP).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",hP,.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",`
|
|
256
256
|
Postcondition: mode=upload, filename, and volume are read back from the saved project. This command never downloads an arbitrary URL.
|
|
257
|
-
`).action(async function(e,t){let n=k(this,t);await w(),
|
|
257
|
+
`).action(async function(e,t){let n=k(this,t);await w(),gP(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=uP("sha256").update(fP(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 wP(e){let t=Number(e);if(!Number.isInteger(t)||t<1||t>24)throw new bP("--limit must be an integer from 1 to 24.");return t}var vP=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",wP).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",`
|
|
258
258
|
Output:
|
|
259
259
|
tracks[].previewUrl is for audition only. tracks[].selectionToken is opaque and short-lived.
|
|
260
260
|
To save one result, pass its id, name, and selectionToken to stock select.
|
|
@@ -271,7 +271,7 @@ Manual:
|
|
|
271
271
|
|
|
272
272
|
Auto from saved slide titles and narration:
|
|
273
273
|
$ ${f.commands[0]} presentation video music stock select <project-id> --mode auto
|
|
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",`
|
|
274
|
+
`),IP=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(vP).addCommand(gf).addCommand(IP));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 kP}from"commander";var xP=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)})}),RP=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}))}),CP=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()}`)})}),SP=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",TP).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)})}),EP=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(EP);var PP=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 AP=new He("action").description("Prepare, review, apply or restore supported scene improvements").addCommand(yf).addCommand(PP).addCommand(hf("apply")).addCommand(hf("restore"));function TP(e){let t=Number(e);if(!/^\d+$/.test(e)||!Number.isSafeInteger(t))throw new kP("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(xP).addCommand(RP).addCommand(CP).addCommand(SP).addCommand(AP);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 OP=new J("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)}}),$P=new J("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)}}),DP=new J("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)}}),NP=new J("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 LP(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 UP=new J("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)}}),_P=new J("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 LP(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)}}),jP=new J("sharing").description("Read or update presentation team access").addCommand(UP).addCommand(_P),qP=new J("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)}}),MP=new J("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 J(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 VP=xf({capabilityId:"importPowerPoint",description:"Read a PowerPoint import run",name:"status"}),FP=xf({capabilityId:"transformPresentationImport",description:"Read a PowerPoint transform run",name:"transform-status"}),Rf=new J("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??Ht());m(n)}catch(t){a(u(t,"Import failed")),process.exit(s.GENERAL_ERROR)}}).addCommand(MP).addCommand(VP).addCommand(FP),BP=new J("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)}}),GP=new J("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)}}),KP=new J("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)}}),WP=new J("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:ZP(n.seedFrom),teamId:n.teamId},n.idempotencyKey??Ht());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)}}),JP=new J("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)}}),zP=new J("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??Ht());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(JP),HP=new J("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??Ht()))}catch(r){a(u(r,"Speaker-notes apply failed")),process.exit(s.GENERAL_ERROR)}}),XP=new J("rename").description("Rename a presentation video and its latest finished video (share link follows)").argument("<project-id>","Presentation video project ID").argument("<title>","The new name (quote it)").option("--team-id <id>","Workspace ID override").option("--idempotency-key <key>","Stable retry key for this rename").action(async function(e,t,n){let r=k(this,n);try{m(await p("renamePresentationVideo",{projectId:e,teamId:r.teamId,title:t},r.idempotencyKey??Ht()))}catch(i){a(u(i,"Rename failed")),process.exit(s.GENERAL_ERROR)}}),YP=new J("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 QP(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(HP).addCommand(XP).addCommand(WP).addCommand(zP).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(KP).addCommand(kg).addCommand(Ig).addCommand(xg).addCommand(Rg).addCommand(vg).addCommand(ug);async function QP(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 ZP(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 eA=new J("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)}}),tA=new J("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??Ht(),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)}}),nA=new J("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??Ht());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 J("presentation").description("Create an MP4 video from a finished presentation, plus speaker notes, PowerPoint import, and run status").addCommand(OP).addCommand(Wo()).addCommand(DP).addCommand(Yu).addCommand(NP).addCommand(jP).addCommand(qP).addCommand($P).addCommand(Rf).addCommand(eA).addCommand(tA).addCommand(BP).addCommand(YP).addCommand(nA).addCommand(GP).addCommand(df).addCommand(Ts).addCommand(cf).addCommand(rg).addCommand(hs);xr.addCommand(Zu);xr.addCommand(ig);xr.addHelpText("after",`
|
|
275
275
|
${W.bold("Deck to MP4:")}
|
|
276
276
|
$ ${f.commands[0]} presentation video prepare <slug> ${W.gray("# create/reuse the video project (free)")}
|
|
277
277
|
$ ${f.commands[0]} presentation video narrate <project-id> --yes ${W.gray("# fill in missing narration")}
|
|
@@ -305,11 +305,11 @@ ${W.bold("Before rendering:")}
|
|
|
305
305
|
${W.bold("See also:")}
|
|
306
306
|
${W.gray("# Building a video from scratch instead of from a deck")}
|
|
307
307
|
$ ${f.commands[0]} video --help
|
|
308
|
-
`);import{writeFile as
|
|
308
|
+
`);import{writeFile as rA}from"fs/promises";import{resolve as iA}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 oA(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:oA(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=iA(e.output??n.fileName),i=await yn(n.downloadUrl);await rA(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
309
|
${Cf.bold("Examples:")}
|
|
310
310
|
$ ${f.commands[0]} promomats export --ad-set <id> --sizes 1x1,9x16
|
|
311
311
|
$ ${f.commands[0]} promomats export --deck <id-or-slug> --version-number 2 --isi-document 5104
|
|
312
|
-
`);var Af=new Sf("promomats").description("Hand governed content to Veeva Vault PromoMats").addCommand(Pf);import{randomUUID as
|
|
312
|
+
`);var Af=new Sf("promomats").description("Hand governed content to Veeva Vault PromoMats").addCommand(Pf);import{randomUUID as aA}from"crypto";import{writeFile as sA}from"fs/promises";import Rr from"chalk";import{Command as dA}from"commander";import cA from"ora";var js=new dA("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"?cA("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??aA());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 sA(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
313
|
${Rr.bold("Examples:")}
|
|
314
314
|
${Rr.gray("# Pull the readable content of a web page")}
|
|
315
315
|
$ ${f.commands[0]} scrape https://example.com/post
|
|
@@ -320,7 +320,7 @@ ${Rr.bold("See also:")}
|
|
|
320
320
|
|
|
321
321
|
${Rr.gray("# Spoken words out of audio or video")}
|
|
322
322
|
$ ${f.commands[0]} transcript --help
|
|
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
|
|
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 lA=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)}}),mA=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 pA(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 uA=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)}}),gA=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:pA(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(lA).addCommand(mA).addCommand(uA).addCommand(gA);Ms.addHelpText("after",`
|
|
324
324
|
${qs.bold("Examples:")}
|
|
325
325
|
$ ${f.commands[0]} search web "state of AI video 2026"
|
|
326
326
|
$ ${f.commands[0]} search news "vaccine approvals"
|
|
@@ -329,7 +329,7 @@ ${qs.bold("See also:")}
|
|
|
329
329
|
${qs.gray("# `search images` and `search video` overlap with these")}
|
|
330
330
|
$ ${f.commands[0]} image search --help
|
|
331
331
|
$ ${f.commands[0]} video find --help
|
|
332
|
-
`);import{randomUUID as
|
|
332
|
+
`);import{randomUUID as fA}from"crypto";import{Command as Bs}from"commander";import hA 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 yA=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"?hA("Generating sound effect for video...").start():null,o,c=e.idempotencyKey??n.idempotency_key??fA();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 bA=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(yA).addCommand(bA);import{randomUUID as wA}from"crypto";import{readdir as vA,readFile as oo,stat as IA}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}:${wA()}`}async function kA(e){return e==="-"||e===void 0&&!process.stdin.isTTY?CA():(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 xA(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 vA(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 RA(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 CA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function SA(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 EA=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")}}),PA=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")}}),AA=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 IA(i).catch(()=>null))?.isDirectory()){let o=await xA(i);n.markdown=o.markdown;for(let c of o.assets)r.set(c.path,c)}else n.markdown=await kA(e);for(let o of t.asset){let c=await RA(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=SA("--enabled",t.enabled)),m(await p("upsertTeamSkill",n,t.idempotencyKey??$f("create")))}catch(n){ao(n,"Could not publish the skill")}}),TA=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(EA).addCommand(PA).addCommand(AA).addCommand(TA);import{randomUUID as OA}from"crypto";import{readFile as Lf}from"fs/promises";import{Command as so}from"commander";var Uf=["quiz","flashcards","cheat-sheet"],$A=["beginner","intermediate","advanced","mixed"];function DA(){return`cli:study-set:create:${OA()}`}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 NA(){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 LA(e){if(e!=="-"&&!e.startsWith("@"))return Ks(e,"--items");let t=e==="-"?await NA():await Lf(e.slice(1),"utf8");return Ks(t,"Items file")}async function UA(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 _A=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 ${$A.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",`
|
|
333
333
|
The --file document:
|
|
334
334
|
|
|
335
335
|
{
|
|
@@ -356,14 +356,14 @@ The --file document:
|
|
|
356
356
|
Item shapes follow --kind: quiz items carry question/options/answerIndex,
|
|
357
357
|
flashcards carry front/back, cheat-sheet items carry term/definition(/group).
|
|
358
358
|
Every created item gets a stable id back \u2014 the itemId a video "question"
|
|
359
|
-
interaction references.`).action(async e=>{try{let t=e.file?await
|
|
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
|
|
359
|
+
interaction references.`).action(async e=>{try{let t=e.file?await UA(e.file):{},n=e.items!==void 0?await LA(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??DA()))}catch(t){Ws(t,"Could not create the study set")}}),jA=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")}}),qA=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(_A).addCommand(jA).addCommand(qA);import{randomUUID as Mf}from"crypto";import{readFile as GA}from"fs/promises";import{Command as Js}from"commander";import{existsSync as MA,readFileSync as VA,statSync as FA}from"fs";import{basename as BA}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(!MA(e))throw new ct(`No such file: ${e}`,"support_attachment_missing_file");let n=FA(e);if(!n.isFile()||n.size<=0)throw new ct(`Not a readable file with content: ${e}`,"support_attachment_missing_file");let r=BA(e),i=await jf("/api/support/attachments/presign",{fileName:r,mediaType:fn(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([VA(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 KA=["received","looking_into_it","planned","in_progress","fixed_awaiting_release","shipped","not_planned","needs_input","resolved"];async function WA(e){if(e!==void 0&&e!=="-"&&!e.startsWith("@"))return e;if(e?.startsWith("@"))return GA(e.slice(1),"utf8");if(e==="-"||!process.stdin.isTTY)return JA();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 JA(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}function zA(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 HA(e,t){return[...t,e]}async function XA(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 YA=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)",HA,[]).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=zA(t.context),r=Mf(),i=await XA(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 WA(e)},t.idempotencyKey??`cli:support:report:${Mf()}`))}catch(n){Vf(n,"Could not file the report")}}),QA=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 ${KA.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(YA).addCommand(QA);import Er from"chalk";import{Command as ZA}from"commander";var Bf=new ZA("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 Xt(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}function eT(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 tT=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:eT("--threads",t.threads)},t.idempotencyKey))}catch(n){Xt(n,"Thread creation failed")}}),nT=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){Xt(n,"Thread listing failed")}}),rT=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){Xt(n,"Thread read failed")}}),iT=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){Xt(n,"Thread transcript read failed")}}),oT=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){Xt(n,"Thread message failed")}}),aT=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){Xt(t,"Thread wait failed")}}),sT=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){Xt(n,"Thread stop failed")}}),Gf=new xt("thread").description("Spawned chat threads \u2014 Devin-style child sessions").addCommand(tT).addCommand(nT).addCommand(rT).addCommand(iT).addCommand(oT).addCommand(aT).addCommand(sT);import{randomUUID as dT}from"crypto";import{writeFile as cT}from"fs/promises";import{Command as lT}from"commander";import mT from"ora";var Kf=new lT("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"?mT("Fetching transcript...").start():null;try{let i=await p("getYoutubeTranscript",{language:t.language,reason:t.reason,teamId:t.teamId,url:e},t.idempotencyKey??dT());r?.stop();let o=t.timestamps?i.cues.map(c=>`[${c.timestamp}] ${c.text}`).join(`
|
|
361
361
|
`):i.cues.map(c=>c.text).join(`
|
|
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",`
|
|
362
|
+
`);if(t.output&&(await cT(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 pT}from"crypto";import{mkdir as uT,writeFile as Wf}from"fs/promises";import{dirname as gT}from"path";import{Command as lo}from"commander";import Jf from"ora";var fT=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??pT(),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?hT("--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 uT(gT(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 hT(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 yT=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)}}),bT=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(fT).addCommand(yT).addCommand(bT);import{execSync as uo,spawnSync as KT}from"child_process";import{createHash as WT}from"crypto";import{access as Zs,readFile as JT,rm as dh}from"fs/promises";import{resolve as Pr}from"path";import Re from"chalk";import{Command as Ce}from"commander";import zT from"ffmpeg-static";import ch from"ora";import{Command as Hs}from"commander";var wT=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)}}),vT=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(wT).addCommand(vT);import{randomUUID as IT}from"crypto";import{Command as kT}from"commander";var Xf=new kT("rename").description("Rename a video; its share link follows the new name and old links keep working").argument("<video-id>","Video UUID").argument("<title>","The new name (quote it)").option("--team-id <id>","Workspace ID").option("--idempotency-key <key>","Stable key so a retried rename is applied once").option("--json","Print the complete structured response").action(async(e,t,n)=>{try{let r=await p("renameVideo",{teamId:n.teamId,title:t,videoId:e},n.idempotencyKey??IT());if(n.json){m(r);return}C(r.shareUrl?`Renamed to "${r.title}": ${r.shareUrl}`:`Renamed to "${r.title}" (not shared).`)}catch(r){a(u(r,"Rename failed")),process.exit(s.GENERAL_ERROR)}});import{randomUUID as xT}from"crypto";import{Command as RT}from"commander";var Xs=["private","team","public"],Yf=new RT("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??xT());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 CT}from"commander";var Qf=new CT("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 ST}from"fs/promises";import{join as ET}from"path";import{Command as Yt}from"commander";import eh from"ora";var PT=5e3,AT=120,Zf=5;function th(e,t){return[...t,e]}function TT(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 OT(e){if(e.mode&&!["speed","precision"].includes(e.mode))throw new Error("Lip-sync mode must be speed or precision");return{audioUrl:TT(e.audioUrl,"Audio URL"),...e.mode?{mode:e.mode}:{},sourceVideoId:mo(e.sourceVideoId)}}function $T(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>Zf)throw new Error(`Provide at most ${Zf} 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 DT(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 NT(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:NT(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)),AT,PT)}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 LT(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 UT(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"translation"}.mp4`}function _T(e,t){let n=UT(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 jT(e,t){let n=LT(e.output).filter(o=>o.status==="completed"&&!!o.videoUrl);if(n.length===0)throw new Error("Video translation completed without downloadable results");await ST(t,{recursive:!0});let r=[],i=new Set;for(let o of n){let c=ET(t,_T(o.language,i));await Ie(o.videoUrl,c),r.push({language:o.language,path:c})}return r}var qT=new Yt("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)}}),nh=new Yt("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"?eh("Starting video lip-sync...").start():null,n;try{let r=await Rc(OT(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(qT)),rh=new Yt("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)}}),MT=new Yt("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)}}),ih=new Yt("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)",th,[]).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"?eh("Starting video translation...").start():null,n;try{let r=await Ec($T(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 jT(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(MT)),VT=new Yt("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)}}),oh=new Yt("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",th,[]).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(DT(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(VT));import{Command as FT}from"commander";function BT(e){return e===null?"\u2014":`${Math.round(e*100)}%`}function ah(e){return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function GT(e){return e.viewer?e.viewer.name??e.viewer.email??e.viewer.id:"Anonymous"}var sh=new FT("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 ${BT(n.averageCompletionRate)} average depth`),console.log(`${n.signedInViewers} signed-in viewer${n.signedInViewers===1?"":"s"} \xB7 ${ah(n.averageWatchedSeconds)} average watch time`);for(let r of n.sessions)console.log(` ${r.completed?"\u2713":"\xB7"} ${GT(r)} \u2014 ${ah(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 HT(){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 XT(e){let t=e?.trim().toLowerCase();if(!(!t||t==="any"||t==="all"))return t==="web"||t==="stock"?[t]:void 0}var YT=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"?ch("Finding videos...").start():null;try{let l=await vc({query:e,options:{maxResults:parseInt(n,10),orientation:r,license:i,sources:XT(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)}}),QT=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 lh(e){let t=e==="-"?await HT():await JT(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 mh(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 ZT=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 mh(e.media,{uploadIdempotencyKey:e.idempotencyKey}),storyboardMarkdown:await lh(e.file),teamId:e.teamId,title:e.title},e.idempotencyKey))}catch(t){a(u(t,"Storyboard creation failed")),process.exit(s.GENERAL_ERROR)}}),eO=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 mh(t.media,{uploadIdempotencyKey:t.idempotencyKey}),storyboardId:e,storyboardMarkdown:await lh(t.file),teamId:t.teamId,title:t.title},t.idempotencyKey))}catch(n){a(u(n,"Storyboard revision failed")),process.exit(s.GENERAL_ERROR)}}),tO=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)}}),nO=new Ce("storyboard").description("Create, revise, and read Markdown video storyboards").addCommand(ZT).addCommand(eO).addCommand(tO),ph=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)}});ph.addHelpText("after",`
|
|
363
363
|
${Re.gray("# Prints an analysisId plus a ready storyboard media binding. Pass that")}
|
|
364
364
|
${Re.gray("# binding to video storyboard create/revise --media; generation reads the")}
|
|
365
365
|
${Re.gray("# analysis from the analysisId, never from local files.")}
|
|
366
|
-
`);var
|
|
366
|
+
`);var rO=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)}}),iO=new Ce("reference").description("Upload and inspect reusable video references").addCommand(ph).addCommand(rO),oO=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:${WT("sha256").update(e).digest("hex")}`))}catch(n){a(u(n,"Video cancellation failed")),process.exit(s.GENERAL_ERROR)}}),aO=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)}}),sO=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"?ch("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=zT;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=KT(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 dh(v,{force:!0}),await dh(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)}}),dO=new Ce("thumbnail").description("Thumbnail operations").addCommand(sO).addCommand(Qf),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(YT).addCommand(dO).addCommand(oh).addCommand(nh).addCommand(rh).addCommand(ih).addCommand(Kg).addCommand(Hf).addCommand(Xf).addCommand(Yf).addCommand(sh);go.addCommand(QT).addCommand(nO).addCommand(iO).addCommand(oO).addCommand(aO);go.addHelpText("after",`
|
|
367
367
|
${Re.bold("Examples:")}
|
|
368
368
|
${Re.gray("# Storyboard-first video from a brief")}
|
|
369
369
|
$ ${f.commands[0]} video storyboard create --file brief.md --duration 15 --aspect 16:9 --idempotency-key launch-1
|
|
@@ -383,8 +383,8 @@ ${Re.bold("Before generating:")}
|
|
|
383
383
|
${Re.bold("See also:")}
|
|
384
384
|
${Re.gray("# Already have a deck? Render it to MP4 (narration, avatar, captions)")}
|
|
385
385
|
$ ${f.commands[0]} presentation video <slug>
|
|
386
|
-
`);import{Command as ed}from"commander";var
|
|
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",`
|
|
386
|
+
`);import{Command as ed}from"commander";var cO=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)}}),lO=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)}}),uh=new ed("visual-abstract").description("Generate a one-page visual abstract graphic (raster or vector) from a dense brief").addCommand(cO).addCommand(lO);import Te from"chalk";import{Command as ye}from"commander";import{Command as mO}from"commander";var gh=new mO("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 ${pO(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 pO(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 fh=["male","female"],hh=["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 uO=new ye("list").description("The voices this workspace can narrate with").option("--gender <gender>","male or female",b("--gender",fh)).option("--age <age>","young, middle_aged or old",b("--age",hh)).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)}}),gO=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)}}),fO=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",fh)).option("--age <age>","young, middle_aged or old",b("--age",hh)).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)}}),hO=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)}}),yO=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)}}),bO=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)}}),wO=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)}}),vO=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)}}),IO=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)}}),kO=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)}}),xO=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)}}),RO=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)}}),CO=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)}}),SO=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(uO).addCommand(gO).addCommand(fO).addCommand(yO).addCommand(bO).addCommand(wO).addCommand(vO).addCommand(gh).addCommand(IO).addCommand(kO).addCommand(xO).addCommand(RO).addCommand(CO).addCommand(SO).addCommand(hO);nd.addHelpText("after",`
|
|
388
388
|
${Te.bold("Examples:")}
|
|
389
389
|
${Te.gray("# The request a fixed catalog cannot answer")}
|
|
390
390
|
$ ${f.commands[0]} voice list --gender male --age middle_aged --accent american --use-case conversational
|
|
@@ -396,14 +396,14 @@ ${Te.bold("Examples:")}
|
|
|
396
396
|
${Te.bold("See also:")}
|
|
397
397
|
${Te.gray("# Narrate a presentation video with the voice you chose")}
|
|
398
398
|
$ ${f.commands[0]} presentation video settings <project-id> --settings '{"voiceId":"<voice-id>"}' --yes
|
|
399
|
-
`);import{randomUUID as rd}from"crypto";import{Command as
|
|
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
|
|
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=
|
|
399
|
+
`);import{randomUUID as rd}from"crypto";import{Command as Qt}from"commander";function yh(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 bh(e,t,n){if(n.wait===!1){m(t);return}I(`Run ${t.runId} accepted (${t.status}). Waiting\u2026`);let r=await H(e,t.runId,n.teamId,n.maxAttempts);m(r)}var EO=new Qt("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)}}),PO=new Qt("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?yh("music-config",t.musicConfig):void 0,presenterConfig:t.presenterConfig?yh("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 bh("createWalkthrough",n,{...t,maxAttempts:180})}catch(n){a(u(n,"Creation failed")),process.exit(s.GENERAL_ERROR)}}),AO=new Qt("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 bh("renderWalkthrough",n,{...t,maxAttempts:300})}catch(n){a(u(n,"Render failed")),process.exit(s.GENERAL_ERROR)}}),TO=new Qt("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)}}),OO=new Qt("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)}}),$O=new Qt("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)}}),wh=new Qt("walkthrough").description("Recorded walkthroughs: narrated videos from screen captures").addCommand(EO).addCommand(PO).addCommand(AO).addCommand(TO).addCommand(OO).addCommand($O);import{Command as Rh,InvalidArgumentError as Ch}from"commander";var vh=["article","cheat-sheet","flashcards","microsite","presentation","quiz","survey","video"],Ih=["cancelled","draft","failed","in-progress","published","ready","setup"],kh=["mine","workspace"];function DO(e,t){return n=>{if(!t.includes(n))throw new Ch(`${e} expects one of: ${t.join(", ")}.`);return n}}function xh(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 Ch(`${e} expects comma-separated values from: ${t.join(", ")}.`);return r}}function NO(e,t){a(u(e,t)),process.exit(s.GENERAL_ERROR)}var LO=new Rh("list").description("List the workspace's in-flight, draft, failed, and finished work \u2014 continuation-first").option("--kinds <kinds>",`Filter to artifact kinds: ${vh.join(", ")}`,xh("--kinds",vh)).option("--lifecycle <states>",`Filter to lifecycle states: ${Ih.join(", ")}`,xh("--lifecycle",Ih)).option("--limit <n>","Maximum items to return (default 20, max 50)").option("--scope <scope>",`Whose work to list: ${kh.join(", ")}`,DO("--scope",kh)).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){NO(t,"Could not list work items")}}),Sh=new Rh("work").description("Inspect the workspace's recent and in-flight work").addCommand(LO);var id=[ru,bu,bm,Yp,zf,Wu,Nu,vu,go,js,Kf,Of,xr,Ms,Ba,Ru,es,Xu,um,gm,uh,Ou,tm,am,ma,Tu,Fa,nd,cu,su,xu,uu,gu,Ha,iu,Im,Af,Df,Ff,Bf,Gf,wh,Du,Sh,_f];function Eh(e){for(let t of id)e.addCommand(t)}function Ph(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)Ph(i,r,n)}var fo;function UO(){if(!fo){fo=new Map;for(let e of id)Ph(e,"",fo)}return fo}function Ah(e){let t=UO().get(e);return t?[...t.arguments,...t.requiredOptions.map(n=>`${n} \u2026`)].join(" "):""}var Th=["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"},_O="other";function jO(e){let t=e.category?.trim();return t&&t.length>0?t:_O}function Oh(e){let t=Th.indexOf(e);return t===-1?Th.length:t}function Ar(e){let t=new Map;for(let n of e){let r=jO(n),i=t.get(r);i?i.push(n):t.set(r,[n])}return[...t.entries()].sort(([n],[r])=>Oh(n)-Oh(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 qO(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 MO(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=Ah(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"} | ${MO(i,t)} | ${qO(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 $h(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 Dh="tests/integration/tool-surface/presentations.integration.test.ts",VO="tests/integration/tool-surface/branding.integration.test.ts";function Nh(e){switch(e){case"create":return[Fn(Dh,"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 FO(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(Dh,`generated MCP and CLI ${e}`,"The integration suite compares matching MCP and CLI adapter results.")]:e==="get"||e.startsWith("presentation speaker-notes")?Nh(e):[]}function BO(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(VO,"runs the free brand write on both lanes without an approval receipt","MCP and CLI invoke the same free brand write in memory.")]:[]}function GO(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 KO(e,t){return e==="presentation"?Nh(t):e==="presentation-video"?FO(t):e==="agents"?GO(t):BO(t)}function cd(e,t){return Tr(t).map(n=>{let r=KO(e,n),i=r.length===0?"missing":r.some(o=>o.level==="full")?"full":"partial";return{command:n,evidence:r,level:i}})}function Lh(e){return e.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function Zt(e){let t=e.anyOf??[],n=t.some(i=>i.type==="null");return{inner:t.find(i=>i.type!=="null")??e,nullable:n}}function WO(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 Uh(e){let{inner:t}=Zt(e),n="value";return t.enum?n=t.enum.map(r=>`\`${String(r)}\``).join(" | "):t.type==="integer"||t.type==="number"?n=`${t.type}${WO(t)}`:t.type&&(n=t.type),t.default!==void 0&&(n+=`, default \`${String(t.default)}\``),n}function JO(e){let{inner:t,nullable:n}=Zt(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}=Zt(t[r]);return i.properties===void 0&&!(i.additionalProperties&&i.additionalProperties!==!0)})}function _h(e){return Object.keys(e).sort((t,n)=>t.localeCompare(n))}function jh(e){let n=e.properties?.settings?.properties??{};return Object.keys(n).map(r=>({description:Lh(n[r].description??""),key:r,type:JO(n[r])}))}function qh(e){let t=e.properties?.settings?.properties??{},n=[];for(let r of Object.keys(t)){let{inner:i}=Zt(t[r]);if(!ld(i))continue;let o=new Set(i.required??[]),c=_h(i.properties??{}).map(l=>{let d=i.properties?.[l],g=o.size>0&&!o.has(l)?", optional":"";return`\`${l}\` (${Uh(d)}${g})`});n.push(`\`${r}\` keys: ${c.join(", ")}.`)}return n}var zO=/([a-z0-9])([A-Z])/g;function Mh(e,t){let n=e.properties??{},r=e.properties?.settings?.properties??{},i=Object.keys(r).filter(c=>c.startsWith(t)&&ld(Zt(r[c]).inner)),o=[];for(let c of _h(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=Zt(r[y]).inner.properties??{};return l in v||Object.keys(v).some(x=>x.startsWith(l))}),g=d?(()=>{let y=Zt(r[d]).inner.properties??{};return Object.keys(y).find(v=>v===l||v.startsWith(l))??l})():l;o.push({description:Lh(n[c].description??""),flag:`--${c.replace(zO,"$1-$2").toLowerCase()}`,mapsTo:d?`${d}.${g}`:c,type:Uh(n[c])})}return o}var HO=["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 XO(e){let t=jh(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=qh(e??{});return r.length>0?`${n}
|
|
403
403
|
|
|
404
404
|
${r.join(`
|
|
405
|
-
`)}`:n}function
|
|
406
|
-
`)}function
|
|
405
|
+
`)}`:n}function YO(e){let t=Mh(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 QO(e){let t=new Map(e.map(n=>[n.name,n]));return HO.map(n=>t.get(n)).filter(n=>n!==void 0)}function Bn(e,t){let{cmd:n}=e,r=QO(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)}
|
|
407
407
|
|
|
408
408
|
# Deck \u2192 MP4 (\`${n} presentation video\`)
|
|
409
409
|
|
|
@@ -595,7 +595,7 @@ Both \`presentation video settings --settings\` and the render's own
|
|
|
595
595
|
file. At least one key is required. The table below is projected from the
|
|
596
596
|
contract the server validates \u2014 a key that is not listed is refused.
|
|
597
597
|
|
|
598
|
-
${
|
|
598
|
+
${XO(c)}
|
|
599
599
|
|
|
600
600
|
Caption geometry is frame-relative: \`x\`/\`y\` are the box's CENTER (0\u20131) and
|
|
601
601
|
\`width\`/\`height\` its size.
|
|
@@ -612,7 +612,7 @@ rest. Passing both forms of one setting (\`voice\` and \`voiceId\`, or
|
|
|
612
612
|
\`presenter\` and \`avatarId\`) is refused rather than silently ranked;
|
|
613
613
|
\`presenter: null\` remains how a presenter is removed.
|
|
614
614
|
|
|
615
|
-
${
|
|
615
|
+
${YO(c)}
|
|
616
616
|
|
|
617
617
|
Examples:
|
|
618
618
|
|
|
@@ -725,7 +725,7 @@ ${Rt(r,n)}
|
|
|
725
725
|
|
|
726
726
|
If something you need is not in this table, do not conclude it is missing \u2014
|
|
727
727
|
run \`${n} capabilities --search video\`.
|
|
728
|
-
`}function
|
|
728
|
+
`}function Vh(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 ZO(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
|
|
729
729
|
|
|
730
730
|
Use this flow for decks, not MP4 production or brand-library maintenance.
|
|
731
731
|
|
|
@@ -742,7 +742,7 @@ ${[r("create","create a deck from a topic and context"),r("presentation import",
|
|
|
742
742
|
`)}
|
|
743
743
|
|
|
744
744
|
For narration, scenes, presenters, captions, or MP4 output, load \`${e.name}-presentation-video\`.
|
|
745
|
-
`}function
|
|
745
|
+
`}function e$(e,t){let n=md(Gn.branding,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
|
|
746
746
|
`);return`# Branding workflow
|
|
747
747
|
|
|
748
748
|
Branding owns saved private and team brand profiles. It does not edit arbitrary deck HTML.
|
|
@@ -759,7 +759,7 @@ Branding owns saved private and team brand profiles. It does not edit arbitrary
|
|
|
759
759
|
${n||"No common anchors are present in this snapshot; run discovery before acting."}
|
|
760
760
|
|
|
761
761
|
Read [commands.md](commands.md) for every available brand operation and its scopes.
|
|
762
|
-
`}function
|
|
762
|
+
`}function t$(e,t){let n=md(Gn.agents,t).map(r=>`- \`${e.cmd} ${r}\``).join(`
|
|
763
763
|
`);return`# Agents workflow
|
|
764
764
|
|
|
765
765
|
This skill owns scheduled Mindframes Agents. It is not a guide for software-development agents.
|
|
@@ -776,7 +776,7 @@ This skill owns scheduled Mindframes Agents. It is not a guide for software-deve
|
|
|
776
776
|
${n||"No common anchors are present in this snapshot; run discovery before acting."}
|
|
777
777
|
|
|
778
778
|
Read [commands.md](commands.md) for current inputs, outputs, scopes, and exact CLI help.
|
|
779
|
-
`}var
|
|
779
|
+
`}var n$=[{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."]}],r$=[{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."]}],i$=[{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."]}],o$=[{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"&&!Vh(e.name),flow:["create","presentation status","get","export"],workflow:ZO,evals:n$},"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=>Vh(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:r$},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:e$,evals:i$},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:t$,evals:o$}};function yo(e,t){return t.capabilities.filter(Gn[e].select).sort((n,r)=>n.name.localeCompare(r.name))}function a$(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)}
|
|
780
780
|
|
|
781
781
|
# ${n.title} commands
|
|
782
782
|
|
|
@@ -788,7 +788,7 @@ ${o.length?`## Recovery commands
|
|
|
788
788
|
${o.map(c=>`- \`${e.cmd} ${c}\``).join(`
|
|
789
789
|
`)}
|
|
790
790
|
`:""}
|
|
791
|
-
`}function
|
|
791
|
+
`}function s$(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)}
|
|
792
792
|
|
|
793
793
|
# ${n.title} non-unit evidence
|
|
794
794
|
|
|
@@ -809,9 +809,9 @@ Smoke runs require an approved non-production target and their catalog prerequis
|
|
|
809
809
|
${o.length?o.join(`
|
|
810
810
|
`):"# No non-unit evidence registered."}
|
|
811
811
|
\`\`\`
|
|
812
|
-
`}function
|
|
812
|
+
`}function Fh(e){return`'${e.replace(/'/g,`'"'"'`)}'`}function d$(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(`
|
|
813
813
|
`),l=o.filter(g=>g.level==="partial").map(g=>g.command).join(`
|
|
814
|
-
`),d=
|
|
814
|
+
`),d=Fh(e.cmd);return[{path:"scripts/check-auth.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
815
815
|
set -eu
|
|
816
816
|
CLI=${d}
|
|
817
817
|
command -v "$CLI" >/dev/null 2>&1 || { echo "$CLI is not installed" >&2; exit 127; }
|
|
@@ -821,7 +821,7 @@ printf '%s\\n' "Authentication and feature catalog are ready."
|
|
|
821
821
|
`},{path:"scripts/discover-capabilities.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
822
822
|
set -eu
|
|
823
823
|
CLI=${d}
|
|
824
|
-
QUERY=\${1:-${
|
|
824
|
+
QUERY=\${1:-${Fh(n.discoveryQuery)}}
|
|
825
825
|
"$CLI" capabilities --search "$QUERY" --format json
|
|
826
826
|
`},{path:"scripts/verify-help.sh",executable:!0,content:`#!/usr/bin/env sh
|
|
827
827
|
set -eu
|
|
@@ -864,7 +864,7 @@ if [ -n "$PARTIAL" ] || [ -n "$MISSING" ]; then
|
|
|
864
864
|
exit 1
|
|
865
865
|
fi
|
|
866
866
|
printf '%s\\n' 'Every documented command has full real-CLI journey evidence.'
|
|
867
|
-
`}]}function
|
|
867
|
+
`}]}function c$(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)}
|
|
868
868
|
`}}function Ke(e,t,n){let r=Gn[n],i=`${e.name}-${n}`,o=yo(n,t).length;return`---
|
|
869
869
|
name: ${i}
|
|
870
870
|
description: >-
|
|
@@ -897,7 +897,7 @@ Use this narrow workflow. Do not infer command names or reuse flags from UI, API
|
|
|
897
897
|
- \`scripts/check-flow.sh\` \u2014 verify minimum flow anchors exist.
|
|
898
898
|
- \`scripts/check-coverage.sh\` \u2014 fail unless every documented command has full real-CLI evidence.
|
|
899
899
|
- \`evals/evals.json\` \u2014 realistic trigger and workflow evaluations.
|
|
900
|
-
`}function Kn(e,t,n){let r=Gn[n];return[{name:"commands",content:
|
|
900
|
+
`}function Kn(e,t,n){let r=Gn[n];return[{name:"commands",content:a$(e,t,r)},{name:"coverage",content:s$(e,t,r)},{name:"workflow",content:r.workflow(e,t)}]}function Wn(e,t,n){let r=Gn[n];return[...d$(e,t,r),c$(`${e.name}-${n}`,r.evals)]}var l$=["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 l$.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)}
|
|
901
901
|
|
|
902
902
|
# Video from scratch (\`${n} video\`)
|
|
903
903
|
|
|
@@ -1071,17 +1071,17 @@ ${Rt(r,n)}
|
|
|
1071
1071
|
|
|
1072
1072
|
If something you need is not in this table, do not conclude it is missing \u2014
|
|
1073
1073
|
run \`${n} capabilities --search video\`.
|
|
1074
|
-
`}var
|
|
1074
|
+
`}var m$=12,p$={media:"video.md",presentations:"deck-to-video.md"};function u$(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=p$[n],g=["Every capability",...c.length>0?["Background operations"]:[]];return`${Se(t,e)}
|
|
1075
1075
|
|
|
1076
1076
|
# ${n} \u2014 ${o}
|
|
1077
1077
|
|
|
1078
1078
|
${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?`
|
|
1079
1079
|
|
|
1080
1080
|
Step-by-step flow: [${d}](${d}).`:""}
|
|
1081
|
-
${r.length>
|
|
1081
|
+
${r.length>m$?`
|
|
1082
1082
|
## Contents
|
|
1083
1083
|
|
|
1084
|
-
${
|
|
1084
|
+
${$h(g)}
|
|
1085
1085
|
`:""}
|
|
1086
1086
|
## Every capability
|
|
1087
1087
|
|
|
@@ -1097,12 +1097,12 @@ ${c.map(y=>`- \`${i} ${y.name}\` \u2192 \`${i} ${y.lifecycle?.status?.cliCommand
|
|
|
1097
1097
|
`:""}
|
|
1098
1098
|
Anything missing here? Run \`${i} capabilities --category ${n}\` \u2014 the
|
|
1099
1099
|
catalog is authoritative and always current; this file is a snapshot of it.
|
|
1100
|
-
`}function
|
|
1100
|
+
`}function Bh(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:u$(e,t,o,i)+(c?`
|
|
1101
1101
|
---
|
|
1102
1102
|
|
|
1103
|
-
${c}`:""),name:o})}return r}function
|
|
1104
|
-
`),d=Ar(t.capabilities).map(({capabilities:v,category:x})=>`${x} (${v.length})`).join(", "),g=
|
|
1105
|
-
`),y=[...new Set([...t.capabilities.map(v=>v.name.split(" ")[0]),...
|
|
1103
|
+
${c}`:""),name:o})}return r}function Gh(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 g$=[{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"}],f$=["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=g$.filter(v=>o.has(v.capability)).map(v=>`| ${v.intent} | \`${r} ${v.capability}${v.suffix??""}\` | [${v.reference}](references/${v.reference}) |`).join(`
|
|
1104
|
+
`),d=Ar(t.capabilities).map(({capabilities:v,category:x})=>`${x} (${v.length})`).join(", "),g=Gh(t).map(({file:v,when:x})=>`| [references/${v}](references/${v}) | ${x} |`).join(`
|
|
1105
|
+
`),y=[...new Set([...t.capabilities.map(v=>v.name.split(" ")[0]),...f$])].sort().map(v=>`\`${v}\``).join(", ");return`---
|
|
1106
1106
|
name: ${n}
|
|
1107
1107
|
description: >-
|
|
1108
1108
|
Route any ${n} CLI task to the smallest installed domain skill. Trigger for
|
|
@@ -1453,7 +1453,7 @@ Do NOT render or export the presentation \u2014 that's handled by the app.
|
|
|
1453
1453
|
| Create brand-new presentation (5+ slides, new topic) | \`${n} create ...\` via CLI |
|
|
1454
1454
|
| Redesign the whole deck | \`${n} create ...\` via CLI, then sync |
|
|
1455
1455
|
| User provides a URL to base the presentation on | \`${n} scrape <url>\` \u2192 \`${n} create ...\` |
|
|
1456
|
-
`}function Dr(e,t){return Ke(e,t,"presentation")}var
|
|
1456
|
+
`}function Dr(e,t){return Ke(e,t,"presentation")}var h$=[{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=h$.filter(d=>o.has(d.capability)).map((d,g)=>`${g+1}. \`${n} ${d.capability}\` \u2014 ${d.when}`).join(`
|
|
1457
1457
|
`),l=pd(t.capabilities).length;return`---
|
|
1458
1458
|
name: ${r}-video
|
|
1459
1459
|
description: >-
|
|
@@ -1519,15 +1519,15 @@ ${n} video <sub> --help
|
|
|
1519
1519
|
\`\`\`
|
|
1520
1520
|
|
|
1521
1521
|
The catalog is authoritative and always current; this file is a snapshot of it.
|
|
1522
|
-
`}function
|
|
1523
|
-
`).slice(1)){if(!/^\s+\S/.test(o))break;i.push(o.trim())}return i.join(" ").replace(/^["']|["']$/g,"")}return n}function
|
|
1522
|
+
`}function Kh(e,t){return[{content:bo(e,t),name:"video"},{content:Bn(e,t),name:"deck-to-video"}]}import{chmodSync as v$,existsSync as hd,mkdirSync as fd,readFileSync as I$,rmSync as k$,writeFileSync as wo}from"fs";import{homedir as Hh}from"os";import{basename as x$,dirname as R$,join as Ye,relative as C$,resolve as Lr}from"path";var en=[{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 y$}from"crypto";var Wh="mindframes.app-skill.json";function ud(){return"0.3.30"}function gd(e,t,n){let r=y$("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 b$(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(`
|
|
1523
|
+
`).slice(1)){if(!/^\s+\S/.test(o))break;i.push(o.trim())}return i.join(" ").replace(/^["']|["']$/g,"")}return n}function w$(e,t){return["SKILL.md",...(e??[]).map(n=>`references/${n.name}.md`),...(t??[]).map(n=>n.path)]}function Jh(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:b$(n.content),sha256:gd(n.content,n.references,n.files),files:w$(n.references,n.files)}))}}var S$={sonnet:"claude-sonnet-5.5",haiku:"claude-haiku-4.5",opus:"claude-opus-5.5"},E$=["permissionMode","skills","subagentType"];function P$(e,t){if(t!=="copilot")return e;let n=e.match(/^---\n([\s\S]*?)\n---\n/);if(!n)return zh(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}${S$[d]??d}${g}`);for(let c of E$)r=r.replace(new RegExp(`^${c}:[^
|
|
1524
1524
|
]*
|
|
1525
|
-
?`,"m"),"");r=r.replace(/\n+$/,"");let o=
|
|
1525
|
+
?`,"m"),"");r=r.replace(/\n+$/,"");let o=zh(i);return`---
|
|
1526
1526
|
${r}
|
|
1527
1527
|
---
|
|
1528
|
-
${o}`}function
|
|
1529
|
-
`,"utf-8")}function Io(e,t,n={},r,i){let o={installed:[],skipped:[],outdated:[],errors:[]},c=n.baseDir??(n.local?process.cwd():
|
|
1530
|
-
`,"utf-8");let o=xo(e,".claude-plugin");
|
|
1528
|
+
${o}`}function zh(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 Xh(e,t){let n=Lr(e),r=Lr(e,t);if(C$(n,r).startsWith("..")||Lr(r)!==r.replace(/\.\./g,""))throw new Error(`Invalid path: "${t}" would escape base directory`);return r}var Yh=".mf-skill.json";function A$(e){try{let t=JSON.parse(I$(Ye(e,Yh),"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,P$(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=Xh(e,l.path);fd(R$(d),{recursive:!0}),wo(d,l.content,"utf-8"),l.executable&&v$(d,493)}o&&wo(Ye(e,Yh),`${JSON.stringify(o,null," ")}
|
|
1529
|
+
`,"utf-8")}function Io(e,t,n={},r,i){let o={installed:[],skipped:[],outdated:[],errors:[]},c=n.baseDir??(n.local?process.cwd():Hh()),l={schemaVersion:1,slug:e,version:ud(),sha256:gd(t,r,i)};if(n.dir){let d=x$(Lr(n.dir)),g=en.find(y=>y.dir===d)?.provider;try{let y=Lr(n.dir),v=Xh(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 en){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=A$(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():Hh();for(let i of en){let o=Ye(r,i.dir,"skills",e);if(hd(o))try{k$(o,{recursive:!0}),n.removed.push(i.name)}catch(c){n.errors.push(`${i.name}: ${u(c)}`)}}return n}function Qh(){return en.map(e=>e.name)}import{mkdirSync as T$,writeFileSync as Zh}from"fs";import{join as xo}from"path";function ey(e,t,n){for(let l of n)vo(xo(e,"skills",l.name),l.content,l.references,void 0,l.files);let r=Jh(t,n),i=xo(e,Wh);Zh(i,`${JSON.stringify(r,null," ")}
|
|
1530
|
+
`,"utf-8");let o=xo(e,".claude-plugin");T$(o,{recursive:!0});let c=xo(o,"plugin.json");return Zh(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," ")}
|
|
1531
1531
|
`,"utf-8"),{outDir:e,manifestPath:i,pluginPath:c,skillNames:n.map(l=>l.name)}}function Ro(e){let{name:t,cmd:n}=e;return`---
|
|
1532
1532
|
name: ${t}-branding
|
|
1533
1533
|
description: Brand profile management. Extract branding from websites, manage saved brands, apply consistent styling to presentations.
|
|
@@ -1638,7 +1638,7 @@ ${n} branding set-default abc123
|
|
|
1638
1638
|
2. **If extraction fails** \u2014 Proceed without branding. Do not manually create brand assets.
|
|
1639
1639
|
3. **Set default** \u2014 If you mostly work with one brand, set it as default.
|
|
1640
1640
|
4. **Override** \u2014 Use \`--brand\` flag to override default for specific presentations.
|
|
1641
|
-
`}function
|
|
1641
|
+
`}function tn(e){let{name:t,cmd:n}=e,r=t.toUpperCase().replace(/[^A-Z0-9]/g,"_");return`---
|
|
1642
1642
|
name: ${t}-config
|
|
1643
1643
|
description: CLI configuration management. Set API keys, team IDs, custom API URLs. Verify authentication status.
|
|
1644
1644
|
---
|
|
@@ -1799,7 +1799,7 @@ ${n} config show --verify # Test API key
|
|
|
1799
1799
|
\`\`\`bash
|
|
1800
1800
|
${n} config set team-id <correct-team-id>
|
|
1801
1801
|
\`\`\`
|
|
1802
|
-
`}function
|
|
1802
|
+
`}function nn(e){let{name:t,cmd:n}=e;return`---
|
|
1803
1803
|
name: ${t}-image
|
|
1804
1804
|
description: Image search across the web and licensed stock, plus AI image generation with reference images. Find licensed photos to publish, web images for specific real-world subjects, generate a custom image, or generate one that keeps a real person's face, a product or a logo by passing a local photo or URL as a reference. For videos, presentations, marketing.
|
|
1805
1805
|
---
|
|
@@ -2197,7 +2197,7 @@ things you wrote on their behalf.
|
|
|
2197
2197
|
likeness additionally needs \`--provider reference --model gemini-3-pro-image\`
|
|
2198
2198
|
**and** the \`image-model-override\` flag on the workspace; without the flag
|
|
2199
2199
|
the server drops the pin and the likeness is close, not exact.
|
|
2200
|
-
`}function
|
|
2200
|
+
`}function rn(e){let{name:t,cmd:n}=e;return`---
|
|
2201
2201
|
name: ${t}-mix
|
|
2202
2202
|
description: Audio mixing for video production. Combine video with voiceover and background music. Supports volume control, fade effects, and multiple audio tracks.
|
|
2203
2203
|
---
|
|
@@ -2347,7 +2347,7 @@ ${n} mix status <request-id>
|
|
|
2347
2347
|
2. **Music selection** - Choose music that doesn't compete with voice frequency.
|
|
2348
2348
|
3. **Consistent levels** - Keep voice at 100%, adjust music only.
|
|
2349
2349
|
4. **File sizes** - Use \`--no-wait\` for large files to avoid timeout.
|
|
2350
|
-
`}function
|
|
2350
|
+
`}function on(e){let{name:t,cmd:n}=e;return`---
|
|
2351
2351
|
name: ${t}-music
|
|
2352
2352
|
description: Generate music that follows a video's narration and final timing. Gemini plans the provider prompt on the backend.
|
|
2353
2353
|
---
|
|
@@ -2373,7 +2373,7 @@ ${n} music status <request-id>
|
|
|
2373
2373
|
\`\`\`
|
|
2374
2374
|
|
|
2375
2375
|
The backend sends these facts to Gemini, receives the provider-ready musical direction, and makes the paid music-provider request. Retrying the same unchanged request is idempotent.
|
|
2376
|
-
`}function
|
|
2376
|
+
`}function an(e){let{name:t,cmd:n}=e;return`---
|
|
2377
2377
|
name: ${t}-scrape
|
|
2378
2378
|
description: Scrape any URL the user provides. Use when user says "check this site", "look at this URL", "use this website", "here's the link", or shares any URL for context. Supports websites, YouTube, Twitter/X.
|
|
2379
2379
|
---
|
|
@@ -2563,7 +2563,7 @@ ${n} scrape https://blog.example.com -f quiet | ${n} create "Blog Summary"
|
|
|
2563
2563
|
3. **Use JSON** - For programmatic processing of results
|
|
2564
2564
|
4. **Combine sources** - Scrape multiple URLs for comprehensive context
|
|
2565
2565
|
5. **Token count** - Check token usage for large documents
|
|
2566
|
-
`}function
|
|
2566
|
+
`}function sn(e){let{name:t,cmd:n}=e;return`---
|
|
2567
2567
|
name: ${t}-sfx
|
|
2568
2568
|
description: Generate one sound effect aligned with a final visual event and narration. Gemini plans the provider prompt on the backend.
|
|
2569
2569
|
---
|
|
@@ -2601,7 +2601,7 @@ ${n} sfx status <request-id>
|
|
|
2601
2601
|
\`\`\`
|
|
2602
2602
|
|
|
2603
2603
|
The backend sends these facts to Gemini, receives one provider-ready SFX description, and makes the paid SFX-provider request. Retrying the same unchanged request is idempotent.
|
|
2604
|
-
`}function
|
|
2604
|
+
`}function dn(e){let{name:t,cmd:n}=e;return`---
|
|
2605
2605
|
name: ${t}-tts
|
|
2606
2606
|
description: Text-to-speech generation. Convert text to natural speech with multiple providers (Gemini, ElevenLabs, OpenAI) and voices. Use for voiceovers, narration, accessibility.
|
|
2607
2607
|
---
|
|
@@ -2802,7 +2802,7 @@ ${n} tts generate \\
|
|
|
2802
2802
|
2. **Voice matching** - Match voice style to content: Puck for upbeat, Charon for serious
|
|
2803
2803
|
3. **Speed adjustment** - Use 0.9-0.95 for narration, 1.0-1.1 for casual
|
|
2804
2804
|
4. **Multiple voiceovers** - Run \`${n} tts generate\` once per line and poll each run with \`${n} tts status <run-id>\`
|
|
2805
|
-
`}function
|
|
2805
|
+
`}function cn(e){let{name:t,cmd:n}=e;return`---
|
|
2806
2806
|
name: ${t}-video-search
|
|
2807
2807
|
description: Video search across the web and licensed stock. Find downloadable stock clips for b-roll and backgrounds, or web videos (YouTube, Vimeo) to embed in a slide or microsite.
|
|
2808
2808
|
---
|
|
@@ -2999,7 +2999,7 @@ ${n} video find "city timelapse" --orientation landscape -n 10
|
|
|
2999
2999
|
3. **Preview first** - Use preview URLs to check quality
|
|
3000
3000
|
4. **License** - Verify license for commercial use
|
|
3001
3001
|
5. **JSON export** - Save searches for batch processing
|
|
3002
|
-
`}var
|
|
3002
|
+
`}var O$=["main","video","presentation","presentation-video","presentation-edit","branding","agents"];function pe(e,t){return e===void 0||e==="main"?O$.some(n=>n===t):e===t}function yd(e,t,n){let r=[],i=[...Bh(t,n,{branding:Ro(t)}),{name:"tts",content:dn(t)},{name:"music",content:on(t)},{name:"sfx",content:sn(t)},{name:"mix",content:rn(t)},{name:"image",content:nn(t)},{name:"video-search",content:cn(t)},{name:"scrape",content:an(t)},{name:"config",content:tn(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:Kh(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:dn(t)}),pe(e,"music")&&r.push({name:`${t.name}-music`,content:on(t)}),pe(e,"sfx")&&r.push({name:`${t.name}-sfx`,content:sn(t)}),pe(e,"mix")&&r.push({name:`${t.name}-mix`,content:rn(t)}),pe(e,"image")&&r.push({name:`${t.name}-image`,content:nn(t)}),pe(e,"video-search")&&r.push({name:`${t.name}-video-search`,content:cn(t)}),pe(e,"scrape")&&r.push({name:`${t.name}-scrape`,content:an(t)}),pe(e,"config")&&r.push({name:`${t.name}-config`,content:tn(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},ln=new $$("skill").description(`Manage ${f.displayName} skills for AI coding assistants`).addHelpText("after",`
|
|
3003
3003
|
${se.bold("Skill Types:")}
|
|
3004
3004
|
${se.cyan("main")} Intent router and capability index
|
|
3005
3005
|
${se.cyan("presentation")} Create, import, inspect, and export decks
|
|
@@ -3018,9 +3018,9 @@ ${se.bold("Examples:")}
|
|
|
3018
3018
|
$ ${f.commands[0]} skill install agents
|
|
3019
3019
|
$ ${f.commands[0]} skill show presentation
|
|
3020
3020
|
$ ${f.commands[0]} skill pack -o ./dist-skill-bundle ${se.gray("# distributable plugin bundle")}
|
|
3021
|
-
`);
|
|
3022
|
-
`)),n(vd.gray(`Run '${
|
|
3023
|
-
`))}});for(let t of e.commands)Id(t)}function
|
|
3021
|
+
`);ln.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 wn();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: ${Qh().join(", ")}`)),console.log(se.gray(" Use --dir <path> to install to a specific directory"))),console.log()}});ln.command("show").description("Display skill content").argument("[type]","Skill type (default: main)").option("-m, --mode <mode>","Skill mode: standalone or studio","standalone").action(async(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 wn(),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:()=>dn(n),music:()=>on(n),sfx:()=>sn(n),mix:()=>rn(n),image:()=>nn(n),"video-search":()=>cn(n),scrape:()=>an(n),branding:()=>Ke(n,r,"branding"),agents:()=>Ke(n,r,"agents"),config:()=>tn(n)}[e];o?console.log(o()):(a(`Invalid skill type: ${e}. Must be one of: ${Ct.join(", ")}`),process.exit(1))});ln.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 wn(),i=yd(e,n,r);i.length===0&&(a(`Invalid skill type: ${e}`),process.exit(1));let o=ey(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)."))});ln.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 D$}from"commander";var ty=new D$("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 ny(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=L$(e,r[1]);i&&n(vd.yellow(`Did you mean '${i}'?
|
|
3022
|
+
`)),n(vd.gray(`Run '${N$(e)} --help' to see the accepted options.
|
|
3023
|
+
`))}});for(let t of e.commands)Id(t)}function N$(e){let t=[],n=e;for(;n;)t.unshift(n.name()),n=n.parent;return t.join(" ")}function L$(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 _$="0.3.30",ne=new U$,G=f.commands[0];ne.name(G).description(`${f.displayName} CLI \u2014 presentations, videos, avatars, audio, branding, media and research`).version(_$,"-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);Eh(ne);ne.addCommand(Pl);ne.addCommand(El);ne.addCommand(Cl);ne.addCommand(Il);ne.addCommand(ty);ne.addCommand(Dl);ne.addCommand(Nl);ne.addCommand(wl);ne.addCommand(ln);ne.addCommand(ni);var ry=Rl();ry.commands.length>0&&ne.addCommand(ry);function j$(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=j$(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",`
|
|
3024
3024
|
${te.bold("Start here:")}
|
|
3025
3025
|
$ ${G} capabilities ${te.gray("# every capability + its exact command path")}
|
|
3026
3026
|
$ ${G} <group> --help ${te.gray("# drill into any command group above")}
|
|
@@ -3066,4 +3066,4 @@ ${te.bold("Note:")}
|
|
|
3066
3066
|
|
|
3067
3067
|
${te.bold("More Info:")}
|
|
3068
3068
|
${te.blue(f.docsUrl)}
|
|
3069
|
-
`);Id(ne);ne.hook("preAction",()=>{Xd(ne.opts().waitForApproval===!0)});ne.parse(
|
|
3069
|
+
`);Id(ne);ne.hook("preAction",()=>{Xd(ne.opts().waitForApproval===!0)});ne.parse(ny(process.argv.slice(2)),{from:"user"});
|