cueframe 0.4.4 → 0.4.6

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.
@@ -5,6 +5,23 @@ description: Use when editing, clipping, or rendering video via the CueFrame CLI
5
5
 
6
6
  # CueFrame CLI
7
7
 
8
+ ## MCP is the primary surface — read this before using the CLI
9
+
10
+ **If you are an agent that can call tools, connect to CueFrame's MCP server instead of shelling
11
+ out to this CLI.** MCP is the supported, maintained integration surface: it hides transport and
12
+ contract details, its tools are generated from the same OpenAPI SSOT the CLI is, and it is where
13
+ new capability lands first. The `cueframe-connect` skill owns the setup for every host
14
+ (Claude Code, Claude/ChatGPT connectors, Cursor/Codex/VS Code/Windsurf/Zed, and the
15
+ no-account pay-per-call path) — load it rather than copying a connection command from here.
16
+
17
+ **Use this CLI when MCP is not available to you:** a terminal or CI job with no MCP host, a
18
+ scripted batch, or a human at a shell. It is a first-class path, not a deprecated one — but it is
19
+ the *second* thing to reach for.
20
+
21
+ **Do not hand-roll `curl` against `/v1`.** Raw REST is the fallback beneath the fallback: it is
22
+ where undocumented contract edges bite (components' runtime params were discovered that way), and
23
+ both MCP and this CLI exist so you do not have to.
24
+
8
25
  ## Overview
9
26
 
10
27
  The `cueframe` CLI drives the CueFrame platform from the terminal. Optimized for agents — every command supports `--json` (NDJSON event stream) and the binary self-describes via `npx -y cueframe describe --json`.
@@ -28,7 +45,7 @@ the real wire schema the server enforces); confirm any draft with
28
45
  free and instant; a render is neither. The examples here are orientation — the
29
46
  schema is the source of truth.
30
47
 
31
- **Core principle:** Drive everything through `cueframe`. Never `curl` the v1 API around it — that invalidates the work and hides CLI bugs.
48
+ **Core principle:** once you are ON this path, drive everything through `cueframe` — never `curl` the v1 API around it, which invalidates the work and hides CLI bugs. (Choosing MCP over the CLI in the first place is not "going around it"; see the banner above.)
32
49
 
33
50
  ## Framework workflow (upload → compose → render)
34
51
 
@@ -23,3 +23,23 @@ resume the user's original task immediately afterward.
23
23
 
24
24
  Do not ask the user to configure a model provider for CueFrame. This connection exposes CueFrame's
25
25
  tools; the host agent keeps using its already-selected CueFrame Gateway, BYOK, or local model.
26
+
27
+ ## Then confirm it works, before you plan anything
28
+
29
+ Connected is not the same as working, and finding out at the first *paid* call is the expensive
30
+ way. Two free read-only calls prove the whole path:
31
+
32
+ 1. **Discover the surface.** List the tools your host now exposes. You should see the compose loop
33
+ (`new_composition`, `apply_composition`, `validate_composition`, `create_render`) alongside
34
+ discovery reads (`list_catalog`, `list_media`, `get_account`). There are also resources
35
+ (`cueframe://scene-shot` for 3D product shots) and workflow prompts — a flat tool list is not
36
+ the whole surface.
37
+ 2. **Smoke-call `get_account`.** It takes no arguments, costs nothing, and answers the questions
38
+ worth knowing before you spend: which org the key is bound to, the plan, per-feature
39
+ entitlements and — the one that matters — `balance`, not `included`. CueFrame is credit-funded,
40
+ so rendering, generation, preview stills, the judge and the Director all draw on ONE shared
41
+ wallet. If `get_account` returns, authentication, routing and scope are all proven.
42
+
43
+ If a later call fails on scope, the error names the exact missing permission (for example
44
+ `billing:read`, which `get_usage` needs and a creative-only key will not have). Mint a key with
45
+ that scope rather than guessing at the surface.
@@ -8,8 +8,14 @@ description: Use when turning a screen recording (with cursor/click events) into
8
8
  A **use-case recipe**, not new framework surface. CueFrame's engine only knows
9
9
  primitives (`upload` → `composition put` → `render`, the `reframe` viewport, the
10
10
  overlay/effect primitives). This skill is the *judgment* on top: how to turn a
11
- captured walkthrough into a product video that looks good. Drive the primitives
12
- with the `cueframe-cli` skill; this tells you *what* to author.
11
+ captured walkthrough into a product video that looks good. This tells you *what*
12
+ to author, not how to transport it.
13
+
14
+ **Drive the primitives over MCP if you can call tools** (`new_composition` /
15
+ `apply_composition` / `validate_composition` / `create_render` — see the
16
+ `cueframe-connect` skill for the one-line setup). The `npx -y cueframe …` commands
17
+ written out below are the same operations for a terminal or CI job with no MCP
18
+ host; see the `cueframe-cli` skill.
13
19
 
14
20
  ## The pipeline
15
21
 
@@ -9,6 +9,8 @@ Use `scene.add` and `scene.update` through `apply_composition`. Author the scene
9
9
 
10
10
  Before authoring, read `cueframe://scene-shot`. It serves the canonical generated `SceneShotSpecV2` schema, exact operation contracts, supported brand tokens, refusal rules, and a copyable nested slab-and-page recipe. Do not infer fields from an older example.
11
11
 
12
+ On the CueFrame desktop app that resource is unreachable — its MCP surface is tools-only and no `cueframe://` URI resolves there. Call the `get_scene_contract` tool instead: same document, served in sections (`essentials` by default, then `rules` and `schema`).
13
+
12
14
  ## Workflow
13
15
 
14
16
  Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
@@ -17,7 +19,7 @@ not only keyframes. A scene tweak can finish with preview evidence; export for f
17
19
 
18
20
  1. Create or open a composition at the target aspect and FPS.
19
21
  2. Register every image or video source. Capture-backed component surfaces use an exact component id, source version id, capture frame, layout, and optional bake scale.
20
- 3. Read `cueframe://scene-shot`, copy its `world-objects` recipe, and replace placeholder ids and copy.
22
+ 3. Read `cueframe://scene-shot` (desktop: `get_scene_contract`), copy its `world-objects` recipe, and replace placeholder ids and copy.
21
23
  4. Send `apply_composition` with `dry_run: true`. Fix the exact reported field path.
22
24
  5. Apply the same batch for real. Preview the first frame, object entrances, focus transitions, and the last frame.
23
25
  6. Revise with `scene.update`; do not hand-edit a generated wrapper.
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cueframe",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Agent-native CLI for CueFrame — author compositions and render video from the terminal (early-access preview).",
5
5
  "keywords": [
6
6
  "cueframe",
@@ -39,21 +39,15 @@
39
39
  "pino": "^10.3.1",
40
40
  "typescript": "^5.9.3"
41
41
  },
42
- "scripts": {
43
- "build": "node ../../apps/director-agent/scripts/generate-marketplace.mjs && node ../../apps/director-agent/scripts/validate-agent.mjs && tsup && node scripts/copy-agent-skills.mjs",
44
- "check": "tsc --noEmit",
45
- "test": "vitest run",
46
- "prepublishOnly": "npm run build"
47
- },
48
42
  "devDependencies": {
49
- "@cueframe/component-runtime": "workspace:*",
50
- "@cueframe/composition": "workspace:*",
51
- "@cueframe/sdk": "workspace:*",
52
43
  "zod": "^4.5.4",
53
44
  "@types/node": "^24.0.0",
54
45
  "tsup": "^8.5.1",
55
46
  "vitest": "^4.1.2",
56
- "@cueframe/primitives": "workspace:*"
47
+ "@cueframe/component-runtime": "0.1.0",
48
+ "@cueframe/sdk": "0.1.5",
49
+ "@cueframe/composition": "0.1.0",
50
+ "@cueframe/primitives": "0.1.0"
57
51
  },
58
52
  "repository": {
59
53
  "type": "git",
@@ -62,5 +56,10 @@
62
56
  },
63
57
  "bugs": {
64
58
  "url": "https://github.com/cueframe-ai/cueframe/issues"
59
+ },
60
+ "scripts": {
61
+ "build": "node ../../apps/director-agent/scripts/generate-marketplace.mjs && node ../../apps/director-agent/scripts/validate-agent.mjs && tsup && node scripts/copy-agent-skills.mjs",
62
+ "check": "tsc --noEmit",
63
+ "test": "vitest run"
65
64
  }
66
- }
65
+ }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{E as a}from"./chunk-CTELK3ZK.js";import"./chunk-MCQRX24V.js";export{a as analyzeCommand};
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env node
2
- import{b as y}from"./chunk-MCQRX24V.js";var u=class extends Error{status;code;details;requestId;constructor(t,r,s){super(r.message),this.name="ApiError",this.status=t,this.code=r.code,this.details=r.details,this.requestId=s}},v=class extends Error{url;timeoutMs;constructor(t,r){super(`Request timed out after ${r}ms: ${t}`),this.name="TimeoutError",this.url=t,this.timeoutMs=r}},k=class extends Error{url;constructor(t,r){super(`Request failed before a response: ${t}`,{cause:r}),this.name="NetworkError",this.url=t}},g={baseUrl:""};function j(e){return g={timeoutMs:3e4,...e},g}function T(){return g}function rt(e,t){return/^https?:\/\//.test(t)?t:e.replace(/\/$/,"")+(t.startsWith("/")?t:`/${t}`)}async function U(e,t={}){if(!g.baseUrl)throw new Error("@cueframe/sdk: createClient({baseUrl}) must be called before issuing requests.");let r=g.fetch??fetch,s=rt(g.baseUrl,e),o=new Headers({accept:"application/json"});for(let[c,f]of Object.entries(g.headers??{}))o.set(c,f);t.headers&&new Headers(t.headers).forEach((c,f)=>o.set(f,c)),g.apiKey&&!o.has("authorization")&&o.set("authorization",`Bearer ${g.apiKey}`);let n=g.timeoutMs??3e4,i=new AbortController,p=setTimeout(()=>i.abort(),n),m=t.signal?AbortSignal.any([t.signal,i.signal]):i.signal;try{let c=await r(s,{...t,headers:o,signal:m}),f={};c.headers.forEach((b,x)=>{f[x.toLowerCase()]=b});let l=null;if(c.status!==204)if((c.headers.get("content-type")??"").includes("application/json"))try{l=await c.json()}catch{l=null}else l=await c.text();return{status:c.status,statusText:c.statusText,headers:f,body:l,requestId:f["x-request-id"]}}catch(c){throw t.signal?.aborted?c:i.signal.aborted?new v(s,n):new k(s,c)}finally{clearTimeout(p)}}async function a(e,t={}){let r=await U(e,t);if(r.status>=400){let s;throw r.body&&typeof r.body=="object"&&"error"in r.body?s=r.body.error??{code:"unknown",message:r.statusText}:s={code:"unknown",message:r.statusText},new u(r.status,s,r.requestId)}if(r.status!==204)return r.body}var ot={unauthorized:"The API key is invalid or expired for this target. Run `cueframe login` (or `cueframe auth <api-key>`), and check the key matches the target environment.",forbidden:"The key's scopes don't allow this operation. Create a key with the needed preset (`cueframe keys create --preset ...`) or use a key with wider scopes.",not_found:"No such resource in this org (cross-org access also reads as 404). Check the id, or enumerate with the matching list command/tool.",media_not_ready:"Media is still processing. Wait for the `media.transcribed` webhook or retry after ~30s.",suggestions_already_complete:"Suggestions already exist for this media item. To re-run, call DELETE /v1/media/:id/suggestions first to reset state.",precondition_required:"Fetch the resource with GET first to obtain its ETag, then resend the write with `If-Match: <etag>`. `cueframe composition get` returns one for you.",stale_etag:"Resource was modified since your last GET \u2014 `details.currentEtag` is the value to thread next. Re-GET (or run `cueframe composition get`) and rebase your edits before retrying.",conflict:"ETag mismatch \u2014 the resource was modified since your last GET. Re-fetch and merge before retrying.",media_in_use:"Media is referenced by other resources. See `details.projectIds` and `details.sessionIds` \u2014 remove those references before deleting.",session_in_use:"Session is referenced by a composition. See `details.projectIds` \u2014 remove those references before deleting.",render_not_cancellable:"Render is already in a terminal state (complete / error / cancelled) and cannot be cancelled.",rate_limited:"Rate limit exceeded. Back off using the `retry-after` response header.",invalid_composition:"Composition violates an invariant (see `details`). Common ones: clip_source_track_kind_mismatch, track_clips_overlap, transition_no_predecessor.",clip_not_found:"The clip suggestion publicId doesn't exist in this org. Run `cueframe clips <mediaItemId>` to enumerate valid sug_* ids.",service_unavailable:"The processing pipeline is temporarily unavailable. Retry shortly; if it persists, contact support@cueframe.ai with the requestId.",payment_required:"The request exceeds a billing limit. For generation, the estimated cost is over the per-call ceiling (see `details.estimateUsd` / `details.ceilingUsd`) \u2014 lower the requested duration or raise the ceiling."};function I(e){return e instanceof u?ot[e.code]??null:null}async function*st(e,t,r){let s=T();if(!s?.baseUrl)throw new Error(`@cueframe/sdk: createClient({baseUrl}) must be called before ${t}.`);let o=s.baseUrl.replace(/\/$/,"")+e,n=new Headers({accept:"text/event-stream",...s.headers??{}});s.apiKey&&!n.has("authorization")&&n.set("authorization",`Bearer ${s.apiKey}`);let p=await(s.fetch??fetch)(o,{method:"GET",headers:n,signal:r.signal});if(!p.ok){let l;try{l=(await p.json()).error??{code:"unknown",message:p.statusText}}catch{l={code:"unknown",message:p.statusText}}throw new u(p.status,l,p.headers.get("x-request-id")??void 0)}if(!p.body)throw new Error("SSE response has no body");let m=p.body.getReader(),c=new TextDecoder("utf-8"),f="";try{for(;;){let{value:l,done:b}=await m.read();if(b)break;f+=c.decode(l,{stream:!0});let x=f.indexOf(`
3
-
4
- `);for(;x!==-1;){let tt=f.slice(0,x);f=f.slice(x+2);let K=nt(tt);K&&(yield K),x=f.indexOf(`
5
-
6
- `)}}}finally{try{m.releaseLock()}catch{}}}function nt(e){if(!e.trim())return null;let t=null,r=[];for(let s of e.split(`
7
- `)){if(!s||s.startsWith(":"))continue;let o=s.indexOf(":");if(o===-1)continue;let n=s.slice(0,o),i=s.slice(o+1).replace(/^ /,"");n==="event"?t=i:n==="data"&&r.push(i)}return!t||r.length===0?null:{event:t,data:r.join(`
8
- `)}}async function*it(e,t,r={}){let s=`/v1/projects/${encodeURIComponent(e)}/renders/${encodeURIComponent(t)}/stream`;for await(let o of st(s,"iterRenderEvents",r)){let n=at(o);n&&(yield n)}}function at(e){let{event:t,data:r}=e;if(r===null||t!=="progress"&&t!=="complete"&&t!=="error")return null;let s;try{s=JSON.parse(r)}catch{return null}return{event:t,data:s}}var _={};y(_,{createBrandKit:()=>mt,createExemplarUploads:()=>yt,extractBrandKit:()=>ut,getBrandKit:()=>lt,getBrandKitExemplars:()=>gt,getCreateBrandKitUrl:()=>N,getCreateExemplarUploadsUrl:()=>J,getExtractBrandKitUrl:()=>G,getGetBrandKitExemplarsUrl:()=>L,getGetBrandKitUrl:()=>$,getListBrandKitsUrl:()=>F,listBrandKits:()=>dt});var F=()=>"/v1/brand-kits",dt=async e=>a(F(),{...e,method:"GET"}),N=()=>"/v1/brand-kits",mt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(N(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},G=()=>"/v1/brand-kits/extract",ut=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(G(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},$=e=>`/v1/brand-kits/${e}`,lt=async(e,t)=>a($(e),{...t,method:"GET"}),L=e=>`/v1/brand-kits/${e}/exemplars`,gt=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(L(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},J=()=>"/v1/brand-kits/exemplar-uploads",yt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(J(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})};var h={};y(h,{composeFromSuggestion:()=>Ct,getComposeFromSuggestionUrl:()=>H,getListMediaSuggestionsUrl:()=>W,getResetMediaSuggestionsUrl:()=>z,getSuggestBriefsUrl:()=>D,listMediaSuggestions:()=>bt,resetMediaSuggestions:()=>Pt,suggestBriefs:()=>ht});var H=e=>`/v1/projects/${e}/composition/from-suggestion`,Ct=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(H(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},W=e=>`/v1/media/${e}/suggestions`,bt=async(e,t)=>a(W(e),{...t,method:"GET"}),D=e=>`/v1/media/${e}/suggestions`,ht=async(e,t)=>a(D(e),{...t,method:"POST"}),z=e=>`/v1/media/${e}/suggestions`,Pt=async(e,t)=>a(z(e),{...t,method:"DELETE"});var ee={};y(ee,{createComponent:()=>vt,getComponent:()=>qt,getComponentSource:()=>Et,getCreateComponentUrl:()=>Y,getGetComponentSourceUrl:()=>X,getGetComponentUrl:()=>Q,getListCatalogUrl:()=>V,getUpdateComponentUrl:()=>Z,listCatalog:()=>St,updateComponent:()=>kt});var V=e=>{let t=new URLSearchParams;Object.entries(e||{}).forEach(([s,o])=>{o!==void 0&&t.append(s,o===null?"null":String(o))});let r=t.toString();return r.length>0?`/v1/components?${r}`:"/v1/components"},St=async(e,t)=>a(V(e),{...t,method:"GET"}),Y=()=>"/v1/components",vt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(Y(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},Z=e=>`/v1/components/${e}`,kt=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(Z(e),{...r,method:"PUT",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Q=e=>`/v1/components/${e}`,qt=async(e,t)=>a(Q(e),{...t,method:"GET"}),X=e=>`/v1/components/${e}/source`,Et=async(e,t)=>a(X(e),{...t,method:"GET"});var ne={};y(ne,{cancelExport:()=>Ut,createFcpxmlExport:()=>Mt,createPremiereExport:()=>Bt,getCancelExportUrl:()=>se,getCreateFcpxmlExportUrl:()=>te,getCreatePremiereExportUrl:()=>re,getExport:()=>Kt,getGetExportUrl:()=>oe});var te=e=>`/v1/projects/${e}/exports/fcpxml`,Mt=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(te(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},re=e=>`/v1/projects/${e}/exports/premiere`,Bt=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(re(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},oe=(e,t)=>`/v1/projects/${e}/exports/${t}`,Kt=async(e,t,r)=>a(oe(e,t),{...r,method:"GET"}),se=(e,t)=>`/v1/projects/${e}/exports/${t}/cancel`,Ut=async(e,t,r)=>a(se(e,t),{...r,method:"POST"});var Se={};y(Se,{analyzeTimeline:()=>or,analyzeTranscript:()=>rr,createMediaUpload:()=>Jt,createUploadToken:()=>Lt,deleteMedia:()=>zt,finalizeMedia:()=>Ht,generateMedia:()=>Wt,getAnalyzeTimelineUrl:()=>Pe,getAnalyzeTranscriptUrl:()=>he,getCreateMediaUploadUrl:()=>pe,getCreateUploadTokenUrl:()=>ae,getDeleteMediaUrl:()=>ue,getFinalizeMediaUrl:()=>fe,getGenerateMediaUrl:()=>de,getGetMediaContextUrl:()=>ye,getGetMediaTranscriptUrl:()=>ge,getGetMediaUrl:()=>le,getImportMediaUrl:()=>me,getListMediaFactsUrl:()=>Ce,getListMediaUrl:()=>ce,getMedia:()=>Vt,getMediaContext:()=>Zt,getMediaTranscript:()=>Yt,getPurchaseMediaFactUrl:()=>be,getSearchLibraryUrl:()=>ie,getTriggerMatteBakeUrl:()=>Re,getTriggerSubjectDetectionUrl:()=>xe,importMedia:()=>Dt,listMedia:()=>_t,listMediaFacts:()=>er,purchaseMediaFact:()=>tr,searchLibrary:()=>$t,triggerMatteBake:()=>Xt,triggerSubjectDetection:()=>Qt});var ie=e=>{let t=new URLSearchParams;Object.entries(e||{}).forEach(([s,o])=>{o!==void 0&&t.append(s,o===null?"null":String(o))});let r=t.toString();return r.length>0?`/v1/media/search?${r}`:"/v1/media/search"},$t=async(e,t)=>a(ie(e),{...t,method:"GET"}),ae=()=>"/v1/uploads/token",Lt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(ae(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},pe=()=>"/v1/media",Jt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(pe(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},ce=()=>"/v1/media",_t=async e=>a(ce(),{...e,method:"GET"}),fe=e=>`/v1/media/${e}/finalize`,Ht=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(fe(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},de=()=>"/v1/media/generate",Wt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(de(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},me=()=>"/v1/media/import",Dt=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(me(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},ue=e=>`/v1/media/${e}`,zt=async(e,t)=>a(ue(e),{...t,method:"DELETE"}),le=e=>`/v1/media/${e}`,Vt=async(e,t)=>a(le(e),{...t,method:"GET"}),ge=(e,t)=>{let r=new URLSearchParams;Object.entries(t||{}).forEach(([o,n])=>{n!==void 0&&r.append(o,n===null?"null":String(n))});let s=r.toString();return s.length>0?`/v1/media/${e}/transcript?${s}`:`/v1/media/${e}/transcript`},Yt=async(e,t,r)=>a(ge(e,t),{...r,method:"GET"}),ye=e=>`/v1/media/${e}/context`,Zt=async(e,t)=>a(ye(e),{...t,method:"GET"}),xe=e=>`/v1/media/${e}/detect-subjects`,Qt=async(e,t)=>a(xe(e),{...t,method:"POST"}),Re=e=>`/v1/media/${e}/matte`,Xt=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(Re(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Ce=(e,t)=>{let r=new URLSearchParams;Object.entries(t||{}).forEach(([o,n])=>{n!==void 0&&r.append(o,n===null?"null":String(n))});let s=r.toString();return s.length>0?`/v1/media/${e}/facts?${s}`:`/v1/media/${e}/facts`},er=async(e,t,r)=>a(Ce(e,t),{...r,method:"GET"}),be=e=>`/v1/media/${e}/facts`,tr=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(be(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},he=e=>`/v1/media/${e}/transcript/analyze`,rr=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(he(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Pe=()=>"/v1/timeline-analysis",or=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(Pe(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})};var Ie={};y(Ie,{createProject:()=>nr,deleteProject:()=>pr,getCreateProjectUrl:()=>ke,getDeleteProjectUrl:()=>je,getGetProjectContextUrl:()=>Te,getGetProjectUrl:()=>qe,getListProjectsUrl:()=>ve,getPatchProjectUrl:()=>Ee,getProject:()=>ir,getProjectContext:()=>cr,listProjects:()=>sr,patchProject:()=>ar});var ve=()=>"/v1/projects",sr=async e=>a(ve(),{...e,method:"GET"}),ke=()=>"/v1/projects",nr=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a(ke(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},qe=e=>`/v1/projects/${e}`,ir=async(e,t)=>a(qe(e),{...t,method:"GET"}),Ee=e=>`/v1/projects/${e}`,ar=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(Ee(e),{...r,method:"PATCH",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},je=e=>`/v1/projects/${e}`,pr=async(e,t)=>a(je(e),{...t,method:"DELETE"}),Te=e=>`/v1/projects/${e}/context`,cr=async(e,t)=>a(Te(e),{...t,method:"GET"});var Ne={};y(Ne,{cancelRender:()=>lr,createRender:()=>fr,getCancelRenderUrl:()=>Be,getCreateRenderUrl:()=>Oe,getGetRenderUrl:()=>Me,getListProjectRendersUrl:()=>Ae,getPreviewClipUrl:()=>we,getRefreshRenderUrlUrl:()=>Ue,getRender:()=>ur,getRetryRenderUrl:()=>Ke,getStreamRenderUrl:()=>Fe,listProjectRenders:()=>dr,previewClip:()=>mr,refreshRenderUrl:()=>yr,retryRender:()=>gr,streamRender:()=>xr});var Oe=e=>`/v1/projects/${e}/renders`,fr=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(Oe(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Ae=e=>`/v1/projects/${e}/renders`,dr=async(e,t)=>a(Ae(e),{...t,method:"GET"}),we=e=>`/v1/projects/${e}/preview-clip`,mr=async(e,t,r)=>{let s=o=>{if(!o)return{};if(o instanceof Headers)return Object.fromEntries(o.entries());if(Symbol.iterator in o)return Object.fromEntries(Array.from(o,i=>Array.from(i)));let n={};for(let[i,p]of Object.entries(o))p!==void 0&&(n[i]=p);return n};return a(we(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Me=(e,t)=>`/v1/projects/${e}/renders/${t}`,ur=async(e,t,r)=>a(Me(e,t),{...r,method:"GET"}),Be=(e,t)=>`/v1/projects/${e}/renders/${t}/cancel`,lr=async(e,t,r)=>a(Be(e,t),{...r,method:"POST"}),Ke=(e,t)=>`/v1/projects/${e}/renders/${t}/retry`,gr=async(e,t,r)=>a(Ke(e,t),{...r,method:"POST"}),Ue=(e,t)=>`/v1/projects/${e}/renders/${t}/refresh-url`,yr=async(e,t,r)=>a(Ue(e,t),{...r,method:"POST"}),Fe=(e,t)=>`/v1/projects/${e}/renders/${t}/stream`,xr=async(e,t,r)=>a(Fe(e,t),{...r,method:"GET"});var We={};y(We,{createSession:()=>hr,deleteSession:()=>Sr,getCreateSessionUrl:()=>$e,getDeleteSessionUrl:()=>Je,getGetMuxJobUrl:()=>He,getGetSessionUrl:()=>Le,getListSessionsUrl:()=>Ge,getMuxJob:()=>kr,getSession:()=>Pr,getTriggerMuxJobUrl:()=>_e,listSessions:()=>br,triggerMuxJob:()=>vr});var Ge=()=>"/v1/sessions",br=async e=>a(Ge(),{...e,method:"GET"}),$e=()=>"/v1/sessions",hr=async(e,t)=>{let r=s=>{if(!s)return{};if(s instanceof Headers)return Object.fromEntries(s.entries());if(Symbol.iterator in s)return Object.fromEntries(Array.from(s,n=>Array.from(n)));let o={};for(let[n,i]of Object.entries(s))i!==void 0&&(o[n]=i);return o};return a($e(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},Le=e=>`/v1/sessions/${e}`,Pr=async(e,t)=>a(Le(e),{...t,method:"GET"}),Je=e=>`/v1/sessions/${e}`,Sr=async(e,t)=>a(Je(e),{...t,method:"DELETE"}),_e=e=>`/v1/sessions/${e}/mux-job`,vr=async(e,t)=>a(_e(e),{...t,method:"POST"}),He=e=>`/v1/sessions/${e}/mux-job`,kr=async(e,t)=>a(He(e),{...t,method:"GET"});import{readFileSync as Ir,writeFileSync as Or,mkdirSync as Ar,existsSync as wr}from"fs";import{join as De}from"path";import{homedir as Mr}from"os";var d={Success:0,UserError:2,ApiClientError:3,ApiServerError:4,NetworkError:5,PaymentRequired:6};function O(e){if(e instanceof u){if(e.status===402)return d.PaymentRequired;if(e.status>=500)return d.ApiServerError;if(e.status>=400)return d.ApiClientError}let t=e?.exitCode;return typeof t=="number"?t:d.NetworkError}function TR(e){return e===402?d.PaymentRequired:e>=500?d.ApiServerError:e>=400?d.ApiClientError:d.Success}function P(e){process.exit(e)}var ze=De(Mr(),".cueframe"),q=De(ze,"auth.json"),R={local:"http://127.0.0.1:3211",dev:"https://api-dev.cueframe.ai",prod:"https://api.cueframe.ai"},Br="prod";function BR(e=Br){return process.env.CUEFRAME_API_URL??R[e]??R.prod}var S=class extends Error{constructor(r,s){super(s);this.code=r;this.name="AuthStoreError"}code;exitCode=d.UserError};function KR(e){if(!/^cf_(?:live|test)_[A-Za-z0-9_-]{8,}$/.test(e))throw new S("auth_invalid","Invalid API key. Expected a key beginning with cf_live_ or cf_test_.")}function Ve(){if(!wr(q))return{targets:{}};let e=Ir(q,"utf-8");try{return JSON.parse(e)}catch{throw new S("auth_config_corrupt",`${q} is corrupt and cannot be parsed. Delete it and re-run \`cueframe login\`.`)}}function Kr(e){Ar(ze,{recursive:!0,mode:448}),Or(q,JSON.stringify(e,null,2),{mode:384})}function UR(e,t="prod",r){let s=Ve(),o=R[t]??R.prod;s.targets[t]={apiKey:e,apiUrl:r??o},Kr(s)}function Ye(e="prod"){let t=process.env.CUEFRAME_API_KEY,r=process.env.CUEFRAME_API_URL;if(t)return{apiKey:t,apiUrl:r??R[e]??R.prod};let o=Ve().targets[e];if(!o)throw new S("auth_missing",`No auth configured for target "${e}". Run \`cueframe login --target ${e}\` (browser sign-in) or \`cueframe auth <api-key> --target ${e}\` (CI / headless).`);return o}function Ze(e){let{apiKey:t,apiUrl:r}=Ye(e);j({baseUrl:r,apiKey:t})}function E(e){let t=e instanceof u?`${e.message} (${e.code}${e.status?`, ${e.status}`:""})`:e instanceof Error?e.message:String(e),r=I(e);return r?`${t}
9
- \u2192 ${r}`:t}import Ur from"ora";import Fr from"pino";var Nr="v1",Qe=Fr({level:"trace",base:{schemaVersion:Nr},messageKey:"event",timestamp:()=>`,"ts":${Date.now()}`,formatters:{level:()=>({_:0})}});function A(e,t){return Ur({text:e,isSilent:!!t}).start()}function C(e,t,r={}){e.json&&Qe.info(r,t)}function HR(e,t,r){if(e.json){console.log(JSON.stringify(t,null,2));return}r()}function w(e,t,r,s){let o=r instanceof Error?r.message:String(r),n=typeof r?.code=="string"?r.code:void 0,i=r?.status;e.json?Qe.info({phase:t,message:o,...n?{code:n}:{},...typeof i=="number"?{status:i}:{},exitCode:s},"error"):process.stderr.write(`\u2716 ${t}: ${E(r)}
10
- `)}function M(e,t,r,s){e.json&&w(e,t,r,s)}function WR(e,t){t.json||console.log(e)}function Gr(e){for(let t=0;t<e.length;t++){let r=e.charCodeAt(t);if(r<=31||r===127)return!0}return!1}function et(e,t,r){e.length===0&&Xe(`${t} is empty.`,r),Gr(e)&&Xe(`${t} contains a control character (newline, tab, or null byte). Identifiers must be plain text \u2014 check for a stray copy-paste artifact.`,r)}function Xe(e,t){w(t,"preflight",new Error(e),d.UserError),P(d.UserError)}var $r=5e3,B=300*1e3;async function rC(e,t){if(et(e,"mediaItemId",t),t.dryRun){C(t,"analyze_dry_run",{mediaItemId:e,target:t.target,wait:!!t.wait,wouldCall:"POST /v1/media/:id/suggestions"}),t.json||console.log(`[dry-run] Would trigger clip analysis for ${e} on ${t.target}.`);return}Ze(t.target),C(t,"analyze_prepare",{mediaItemId:e,target:t.target,wait:!!t.wait});let r=A("Triggering clip analysis\u2026",t.json),s;try{s=await h.suggestBriefs(e),r.succeed(`Analysis ${s.alreadyRunning?"already running":"started"}`)}catch(i){r.fail(`Failed to start analysis: ${E(i)}`),M(t,"analyze_prepare",i,O(i)),P(O(i))}if(C(t,"analyze_ready",{mediaItemId:e,status:s.status,alreadyRunning:!!s.alreadyRunning}),!t.wait){t.json||console.log(`
11
- Run \`cueframe clips ${e}\` to check results.`);return}let o=A("Waiting for analysis to complete\u2026",t.json),n=Date.now();for(;;){await new Promise(i=>setTimeout(i,$r)),Date.now()-n>B&&(o.fail(`Timed out after ${Math.round(B/1e3)}s. Run \`cueframe clips ${e}\` to check later.`),M(t,"analyze_progress",new Error(`Analysis did not complete within ${Math.round(B/1e3)}s`),d.UserError),P(d.UserError));try{let i=await h.listMediaSuggestions(e);if(i.suggestions.length>0){o.succeed(`Analysis complete \u2014 ${i.suggestions.length} clips found`),C(t,"analyze_complete",{mediaItemId:e,durationMs:Date.now()-n,suggestionCount:i.suggestions.length,suggestions:i.suggestions}),t.json||i.suggestions.forEach((m,c)=>{let f=(m.trim.end-m.trim.start).toFixed(1);console.log(`
12
- ${c+1}. ${m.title} (${m.id})`),console.log(` ${m.trim.start.toFixed(1)}s \u2013 ${m.trim.end.toFixed(1)}s (${f}s) score: ${m.score}`),console.log(` ${m.reason}`)});return}let p=Math.round((Date.now()-n)/1e3);o.text=`Waiting for analysis\u2026 (${p}s)`,C(t,"analyze_progress",{mediaItemId:e,elapsedSec:p})}catch{}}}export{u as a,j as b,U as c,a as d,I as e,it as f,_ as g,h,ee as i,ne as j,Se as k,Ie as l,Ne as m,We as n,d as o,O as p,TR as q,P as r,BR as s,KR as t,UR as u,Ze as v,E as w,A as x,C as y,HR as z,w as A,M as B,WR as C,et as D,rC as E};