cueframe 0.4.6 → 0.4.8
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/LICENSE +105 -661
- package/README.md +1 -1
- package/dist/analyze-4KYPG6F7.js +2 -0
- package/dist/chunk-EGBS3VAH.js +68 -0
- package/dist/cueframe.js +61 -107
- package/dist/skills/clip-a-talking-head/SKILL.md +6 -3
- package/dist/skills/cueframe-cli/SKILL.md +3 -2
- package/dist/skills/cueframe-component-authoring/SKILL.md +20 -8
- package/dist/skills/cueframe-compose-loop/references/preview-workflow.md +1 -1
- package/dist/skills/launch-video/SKILL.md +5 -3
- package/dist/skills/make-a-social-reel/SKILL.md +6 -1
- package/dist/skills/video-craft-standards/SKILL.md +3 -1
- package/package.json +6 -5
- package/dist/analyze-AERAX5QI.js +0 -2
- package/dist/chunk-LFRF3TXV.js +0 -12
|
@@ -50,8 +50,11 @@ correction, retain the approved edit and check relevant regressions without auto
|
|
|
50
50
|
`focus:{mode:"active-speaker"}` as the base, `all-faces` to hold a two-shot, a `face` +
|
|
51
51
|
`shotScale:"close"` punch-in on the emphasis line. A static center crop is the amateur tell;
|
|
52
52
|
the camera should move because the conversation moved.
|
|
53
|
-
6. **Captions from the
|
|
54
|
-
|
|
53
|
+
6. **Captions from the edited clip.** Save cuts and exclusions first, then call
|
|
54
|
+
`captions.fromComposition` with the speech track ID in a separate `apply_composition` call.
|
|
55
|
+
It projects the real transcript through every saved edit; clips must have saved duration matching playable source duration divided by playbackRate. Re-run after later edits. Get the
|
|
56
|
+
exact input from `describe_composition_ops({type:"captions.fromComposition"})` and style via
|
|
57
|
+
`setCaptionStyle` — plated, high-contrast, never over the mouth or
|
|
55
58
|
eyes. Where the footage allows, put the emphasized keyword BEHIND the speaker as an overlay
|
|
56
59
|
clip at `zPlane:"behind-subject"` — the focused signature depth move. If the user explicitly
|
|
57
60
|
wants every running caption behind the speaker, set the caption layer's own
|
|
@@ -79,7 +82,7 @@ Quoted from `video-craft-standards` §4 (Talking-head clip) — the full checkli
|
|
|
79
82
|
> **MUST** Active-speaker reframe (`focus: active-speaker` / `face`) — a moving camera, not a
|
|
80
83
|
> static center crop.
|
|
81
84
|
|
|
82
|
-
> **MUST** Captions timed to the
|
|
85
|
+
> **MUST** Captions timed to the edited clip (`captions.fromComposition`); behind-speaker
|
|
83
86
|
> placement where the footage allows it. **MUST** Dead air and false starts cut
|
|
84
87
|
> (`addExcludedRange` / `cutAndRipple`).
|
|
85
88
|
|
|
@@ -203,8 +203,9 @@ npx -y cueframe new component my-badge --json
|
|
|
203
203
|
npx -y cueframe push my-badge --json # one component
|
|
204
204
|
npx -y cueframe sync --json # every component in the workspace
|
|
205
205
|
|
|
206
|
-
# 5. Reference the component id in your composition
|
|
207
|
-
# with the same verb. Preview a single component first via the MCP
|
|
206
|
+
# 5. Reference the component id in your composition as a {kind:'component', componentId, props}
|
|
207
|
+
# clip, then render with the same verb. Preview a single component first via the MCP
|
|
208
|
+
# preview_component loop.
|
|
208
209
|
npx -y cueframe render <projectId> -o ./out.mp4 --json
|
|
209
210
|
```
|
|
210
211
|
|
|
@@ -42,11 +42,17 @@ Single self-contained module per component (`create_component` takes one `tsxSou
|
|
|
42
42
|
verified artifact produced by the same bundle contract used by final render. A failed
|
|
43
43
|
`component_does_not_compile` job carries the compiler error — read it, fix via `update_component`
|
|
44
44
|
(same id, in place), and preview again.
|
|
45
|
+
**Once the component is placed in a project, pass that project on every update:**
|
|
46
|
+
`update_component({ componentId, body: { tsxSource, projectId, compositionId? } })`. A placed clip
|
|
47
|
+
renders the exact version it pins; only the composition you name moves to the new version in the
|
|
48
|
+
same write (`repinned` says what moved). Without `projectId` your clips keep rendering the old
|
|
49
|
+
version, and `placementsPinnedToPrevious` counts them.
|
|
45
50
|
Set preview duration deliberately: `durationInFrames` is not a trim window and can retime
|
|
46
51
|
duration-dependent motion. Preserve production timing; inspect the live tool's request shape.
|
|
47
|
-
4. **Check integration:** add it as
|
|
48
|
-
saved-composition stills or a scoped `preview_clip` for
|
|
49
|
-
`create_render` → `wait_job kind:"render"` when delivering a
|
|
52
|
+
4. **Check integration:** add it as a `{kind:'component', componentId, props}` clip
|
|
53
|
+
(`apply_composition`), then inspect saved-composition stills or a scoped `preview_clip` for
|
|
54
|
+
placement and motion. Use `create_render` → `wait_job kind:"render"` when delivering a
|
|
55
|
+
finished MP4, not per tweak.
|
|
50
56
|
|
|
51
57
|
## Path B — CLI / coding agent (customer-owned source under git)
|
|
52
58
|
|
|
@@ -72,10 +78,12 @@ MCP path stores. To preview before a full render, push it and use the MCP `previ
|
|
|
72
78
|
## Path C — Director editing a local desktop project (project-embedded source)
|
|
73
79
|
|
|
74
80
|
When `get_context` reports the project lane as local, motion does not require an account or an org
|
|
75
|
-
component. When exposed, use `open_component_preview` to compile an isolated preview,
|
|
76
|
-
`
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
component. When exposed, use `open_component_preview` to compile an isolated preview (new source,
|
|
82
|
+
or `component_id` for a component already in the desktop's library), `update_component_preview`
|
|
83
|
+
with exact-text edits (`{oldText, newText, replaceAll?}`, each `oldText` matching once), and
|
|
84
|
+
`render_component_preview_frame` for exact frame evidence. Inspect playback for motion;
|
|
85
|
+
`commit_component_preview` publishes the checked source to the library and pins the clip, with a
|
|
86
|
+
fresh ETag. `read_component` and `edit_component` read and edit the library directly. Close the preview when finished. This loop does not bake a timeline video and
|
|
79
87
|
does not imply HMR: source updates still compile.
|
|
80
88
|
|
|
81
89
|
If those tools are unavailable, add/update through `apply_composition` and inspect the local
|
|
@@ -103,7 +111,9 @@ timeline. An inline custom overlay has this shape:
|
|
|
103
111
|
}
|
|
104
112
|
```
|
|
105
113
|
|
|
106
|
-
The desktop compiles the module in an isolated child process and
|
|
114
|
+
The desktop compiles the module in an isolated child process and creates it in the desktop's component
|
|
115
|
+
library. Inline source creates a component only: a clip whose component already exists with other
|
|
116
|
+
source is refused as `component_exists`, and that component changes through edits.
|
|
107
117
|
The timeline and final export render that exact version; no preview media is baked. A compile failure
|
|
108
118
|
refuses the whole batch and leaves the composition untouched. Use `create_component` only for a reusable
|
|
109
119
|
org-catalog component on a reachable cloud lane.
|
|
@@ -165,3 +175,5 @@ const R = params.region ?? { x: 0, y: 0, w: 1, h: 1 };
|
|
|
165
175
|
- Don't hand-roll a graphic from zero when a built-in is close — fork it (fetch the source with
|
|
166
176
|
`get_component_source`, paste it into a `npx -y cueframe new component` scaffold) and edit.
|
|
167
177
|
- Don't `create_component` a fresh id each fix iteration — `update_component` (same id) is the loop.
|
|
178
|
+
- Don't update a placed component without its `projectId` in the body — the placed clips keep the
|
|
179
|
+
version they pin, so the next preview or render shows the old graphic.
|
|
@@ -9,7 +9,7 @@ Read the current tool contracts and project context. Do not infer a hosted sessi
|
|
|
9
9
|
| Need | Hosted evidence | Local desktop evidence, when exposed |
|
|
10
10
|
|---|---|---|
|
|
11
11
|
| Isolated HTML card layout | `preview_card` with the card's HTML and tokens | Inspect the card in the local project |
|
|
12
|
-
| Authored component layout or motion | `preview_component`, with explicit dimensions, FPS, params, assets, and appropriate duration | `open_component_preview` → `update_component_preview
|
|
12
|
+
| Authored component layout or motion | `preview_component`, with explicit dimensions, FPS, params, assets, and appropriate duration | `open_component_preview` → `update_component_preview` (exact-text edits); inspect playback and `render_component_preview_frame` at exact frames |
|
|
13
13
|
| Saved composition layout and overlap | `preview_frame`, batching the needed timestamps | The local composition preview/capture tools |
|
|
14
14
|
| Cuts, entrances, camera motion, or audio timing | `preview_clip` for the affected `[fromSec, toSec)` window, including its lead-in and settle | Play/seek the affected window; capture matching frames when needed |
|
|
15
15
|
| Finished deliverable | `create_render` and verify the resulting file | The project's export path and verification of its resulting file |
|
|
@@ -56,9 +56,11 @@ affected window and regressions without automatically rerunning the full-film ju
|
|
|
56
56
|
narrated: the VO is the rhythm authority instead — cut to the voice and duck the bed under
|
|
57
57
|
it. Silence is almost never right for a launch; if chosen anyway, record the decision and
|
|
58
58
|
reason in the delivery note.
|
|
59
|
-
7. **Caption narration.**
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
7. **Caption narration.** For transcribed voice, save the edits first, then call
|
|
60
|
+
`captions.fromComposition` with the narration track ID in a separate `apply_composition`
|
|
61
|
+
call. Speech clips must have saved duration matching playable source duration divided by
|
|
62
|
+
playbackRate. Re-run after later edits. Use authored word timings for generated VO without a
|
|
63
|
+
transcript, and style legibly via `setCaptionStyle`. Captions are mandatory when narrated.
|
|
62
64
|
8. **Preview, judge, one render.** `preview_frame` at t=0, hook-end, the reveal, and the end
|
|
63
65
|
card; describe each still — is that a REAL capture on screen? Then `score_composition` with
|
|
64
66
|
the payoff line as `editorialIntent`; fix worst-first to ≥ 7.5; `create_render` →
|
|
@@ -61,7 +61,12 @@ affected window and regressions without automatically rerunning the full-film ju
|
|
|
61
61
|
`{ grid:"beat" }` and land your cut points and transition midpoints on the markers. If the
|
|
62
62
|
piece is genuinely better silent, that is a decision — record it and its reason in the
|
|
63
63
|
delivery note. A reel whose silence nobody chose is not done.
|
|
64
|
-
7. **Caption any speech.**
|
|
64
|
+
7. **Caption any speech.** After saving the edited clips, use
|
|
65
|
+
`captions.fromComposition` with the speech track ID in a separate `apply_composition`
|
|
66
|
+
call. It follows trims, excluded ranges and clip placement across the reel. Speech clips
|
|
67
|
+
must have saved duration matching playable source duration divided by playbackRate.
|
|
68
|
+
Re-run it after later edits. Discover its exact input with
|
|
69
|
+
`describe_composition_ops({type:"captions.fromComposition"})`, then style via
|
|
65
70
|
`setCaptionStyle` (plated, bottom, out of the mouth/eyes). Most social viewing is sound-off;
|
|
66
71
|
don't karaoke a beat with no speech.
|
|
67
72
|
8. **Look, then get judged.** `preview_frame` at t=0, hook-end, and every beat boundary;
|
|
@@ -108,7 +108,9 @@ Everything in §1, plus:
|
|
|
108
108
|
never open on wind-up.
|
|
109
109
|
- **MUST** Active-speaker reframe (`focus: active-speaker` / `face`) — a
|
|
110
110
|
moving camera, not a static center crop.
|
|
111
|
-
- **MUST** Captions timed to the
|
|
111
|
+
- **MUST** Captions timed to the saved edited timeline (`captions.fromComposition`
|
|
112
|
+
after the clip edits; re-run after later edits). Speech clips must have saved duration matching playable source duration divided by
|
|
113
|
+
playbackRate.
|
|
112
114
|
The focused behind-the-speaker LOOK is an overlay text layer at
|
|
113
115
|
`zPlane:"behind-subject"` where the footage allows. Use caption-layer
|
|
114
116
|
`zPlane:"behind-subject"` only when the user explicitly wants every running
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cueframe",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
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",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"homepage": "https://docs.cueframe.ai",
|
|
16
16
|
"author": "CueFrame, Inc.",
|
|
17
|
-
"license": "
|
|
17
|
+
"license": "FSL-1.1-ALv2",
|
|
18
18
|
"type": "module",
|
|
19
19
|
"bin": {
|
|
20
20
|
"cueframe": "dist/cueframe.js"
|
|
@@ -45,9 +45,10 @@
|
|
|
45
45
|
"tsup": "^8.5.1",
|
|
46
46
|
"vitest": "^4.1.2",
|
|
47
47
|
"@cueframe/component-runtime": "0.1.0",
|
|
48
|
-
"@cueframe/
|
|
49
|
-
"@cueframe/
|
|
50
|
-
"@cueframe/primitives": "0.1.0"
|
|
48
|
+
"@cueframe/plane": "0.1.0",
|
|
49
|
+
"@cueframe/sdk": "0.2.1",
|
|
50
|
+
"@cueframe/primitives": "0.1.0",
|
|
51
|
+
"@cueframe/composition": "0.1.0"
|
|
51
52
|
},
|
|
52
53
|
"repository": {
|
|
53
54
|
"type": "git",
|
package/dist/analyze-AERAX5QI.js
DELETED
package/dist/chunk-LFRF3TXV.js
DELETED
|
@@ -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 ot(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=ot(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 st={unauthorized:"The credential is invalid or expired for this target, or it belongs to a different environment. Re-authenticate the way you connected: reconnect the MCP server, run `cueframe login` in a terminal, or supply a current API key.",forbidden:"The credential's permissions don't cover this operation. The server message above names the exact missing ones and the `permissions` body that grants them; a key's permissions are fixed at creation, so this needs a NEW key, not a change to this one.",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?st[e.code]??null:null}async function*nt(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 rt=f.slice(0,x);f=f.slice(x+2);let K=it(rt);K&&(yield K),x=f.indexOf(`
|
|
5
|
-
|
|
6
|
-
`)}}}finally{try{m.releaseLock()}catch{}}}function it(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*at(e,t,r={}){let s=`/v1/projects/${encodeURIComponent(e)}/renders/${encodeURIComponent(t)}/stream`;for await(let o of nt(s,"iterRenderEvents",r)){let n=pt(o);n&&(yield n)}}function pt(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:()=>ut,createExemplarUploads:()=>xt,extractBrandKit:()=>lt,getBrandKit:()=>gt,getBrandKitExemplars:()=>yt,getCreateBrandKitUrl:()=>L,getCreateExemplarUploadsUrl:()=>J,getExtractBrandKitUrl:()=>G,getGetBrandKitExemplarsUrl:()=>$,getGetBrandKitUrl:()=>N,getListBrandKitsUrl:()=>F,listBrandKits:()=>mt});var F=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/brand-kits?${r}`:"/v1/brand-kits"},mt=async(e,t)=>a(F(e),{...t,method:"GET"}),L=()=>"/v1/brand-kits",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(L(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},G=()=>"/v1/brand-kits/extract",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(G(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},N=e=>`/v1/brand-kits/${e}`,gt=async(e,t)=>a(N(e),{...t,method:"GET"}),$=e=>`/v1/brand-kits/${e}/exemplars`,yt=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($(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},J=()=>"/v1/brand-kits/exemplar-uploads",xt=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 P={};y(P,{composeFromSuggestion:()=>bt,getComposeFromSuggestionUrl:()=>H,getListMediaSuggestionsUrl:()=>D,getResetMediaSuggestionsUrl:()=>z,getSuggestBriefsUrl:()=>W,listMediaSuggestions:()=>Pt,resetMediaSuggestions:()=>St,suggestBriefs:()=>ht});var H=e=>`/v1/projects/${e}/composition/from-suggestion`,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(H(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},D=(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}/suggestions?${s}`:`/v1/media/${e}/suggestions`},Pt=async(e,t,r)=>a(D(e,t),{...r,method:"GET"}),W=e=>`/v1/media/${e}/suggestions`,ht=async(e,t)=>a(W(e),{...t,method:"POST"}),z=e=>`/v1/media/${e}/suggestions`,St=async(e,t)=>a(z(e),{...t,method:"DELETE"});var te={};y(te,{createComponent:()=>kt,getComponent:()=>jt,getComponentSource:()=>Tt,getCreateComponentUrl:()=>Y,getGetComponentSourceUrl:()=>ee,getGetComponentUrl:()=>Q,getListCatalogUrl:()=>V,getPatchComponentUrl:()=>X,getUpdateComponentUrl:()=>Z,listCatalog:()=>vt,patchComponent:()=>Et,updateComponent:()=>qt});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"},vt=async(e,t)=>a(V(e),{...t,method:"GET"}),Y=()=>"/v1/components",kt=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}`,qt=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)})},X=e=>`/v1/components/${e}`,Et=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(X(e),{...r,method:"PATCH",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Q=e=>`/v1/components/${e}`,jt=async(e,t)=>a(Q(e),{...t,method:"GET"}),ee=e=>`/v1/components/${e}/source`,Tt=async(e,t)=>a(ee(e),{...t,method:"GET"});var ie={};y(ie,{cancelExport:()=>Lt,createFcpxmlExport:()=>Kt,createPremiereExport:()=>Ut,getCancelExportUrl:()=>ne,getCreateFcpxmlExportUrl:()=>re,getCreatePremiereExportUrl:()=>oe,getExport:()=>Ft,getGetExportUrl:()=>se});var re=e=>`/v1/projects/${e}/exports/fcpxml`,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(re(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},oe=e=>`/v1/projects/${e}/exports/premiere`,Ut=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)})},se=(e,t)=>`/v1/projects/${e}/exports/${t}`,Ft=async(e,t,r)=>a(se(e,t),{...r,method:"GET"}),ne=(e,t)=>`/v1/projects/${e}/exports/${t}/cancel`,Lt=async(e,t,r)=>a(ne(e,t),{...r,method:"POST"});var ve={};y(ve,{analyzeTimeline:()=>nr,analyzeTranscript:()=>sr,createMediaUpload:()=>Ht,createUploadToken:()=>_t,deleteMedia:()=>Yt,finalizeMedia:()=>Wt,generateMedia:()=>zt,getAnalyzeTimelineUrl:()=>Se,getAnalyzeTranscriptUrl:()=>he,getCreateMediaUploadUrl:()=>ce,getCreateUploadTokenUrl:()=>pe,getDeleteMediaUrl:()=>le,getFinalizeMediaUrl:()=>de,getGenerateMediaUrl:()=>me,getGetMediaContextUrl:()=>xe,getGetMediaTranscriptUrl:()=>ye,getGetMediaUrl:()=>ge,getImportMediaUrl:()=>ue,getListMediaFactsUrl:()=>be,getListMediaUrl:()=>fe,getMedia:()=>Zt,getMediaContext:()=>Qt,getMediaTranscript:()=>Xt,getPurchaseMediaFactUrl:()=>Pe,getSearchLibraryUrl:()=>ae,getTriggerMatteBakeUrl:()=>Ce,getTriggerSubjectDetectionUrl:()=>Re,importMedia:()=>Vt,listMedia:()=>Dt,listMediaFacts:()=>rr,purchaseMediaFact:()=>or,searchLibrary:()=>Jt,triggerMatteBake:()=>tr,triggerSubjectDetection:()=>er});var ae=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"},Jt=async(e,t)=>a(ae(e),{...t,method:"GET"}),pe=()=>"/v1/uploads/token",_t=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",Ht=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(ce(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},fe=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?${r}`:"/v1/media"},Dt=async(e,t)=>a(fe(e),{...t,method:"GET"}),de=e=>`/v1/media/${e}/finalize`,Wt=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(de(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},me=()=>"/v1/media/generate",zt=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=()=>"/v1/media/import",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(ue(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},le=e=>`/v1/media/${e}`,Yt=async(e,t)=>a(le(e),{...t,method:"DELETE"}),ge=e=>`/v1/media/${e}`,Zt=async(e,t)=>a(ge(e),{...t,method:"GET"}),ye=(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`},Xt=async(e,t,r)=>a(ye(e,t),{...r,method:"GET"}),xe=e=>`/v1/media/${e}/context`,Qt=async(e,t)=>a(xe(e),{...t,method:"GET"}),Re=(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}/detect-subjects?${s}`:`/v1/media/${e}/detect-subjects`},er=async(e,t,r)=>a(Re(e,t),{...r,method:"POST"}),Ce=e=>`/v1/media/${e}/matte`,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(Ce(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},be=(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`},rr=async(e,t,r)=>a(be(e,t),{...r,method:"GET"}),Pe=e=>`/v1/media/${e}/facts`,or=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(Pe(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},he=e=>`/v1/media/${e}/transcript/analyze`,sr=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)})},Se=()=>"/v1/timeline-analysis",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(Se(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})};var Oe={};y(Oe,{createProject:()=>ar,deleteProject:()=>fr,getCreateProjectUrl:()=>qe,getDeleteProjectUrl:()=>Te,getGetProjectContextUrl:()=>Ie,getGetProjectUrl:()=>Ee,getListProjectsUrl:()=>ke,getPatchProjectUrl:()=>je,getProject:()=>pr,getProjectContext:()=>dr,listProjects:()=>ir,patchProject:()=>cr});var ke=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/projects?${r}`:"/v1/projects"},ir=async(e,t)=>a(ke(e),{...t,method:"GET"}),qe=()=>"/v1/projects",ar=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(qe(),{...t,method:"POST",headers:{"Content-Type":"application/json",...r(t?.headers)},body:JSON.stringify(e)})},Ee=e=>`/v1/projects/${e}`,pr=async(e,t)=>a(Ee(e),{...t,method:"GET"}),je=e=>`/v1/projects/${e}`,cr=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(je(e),{...r,method:"PATCH",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Te=e=>`/v1/projects/${e}`,fr=async(e,t)=>a(Te(e),{...t,method:"DELETE"}),Ie=e=>`/v1/projects/${e}/context`,dr=async(e,t)=>a(Ie(e),{...t,method:"GET"});var Ge={};y(Ge,{cancelRender:()=>yr,createRender:()=>mr,getCancelRenderUrl:()=>Ke,getCreateRenderUrl:()=>Ae,getGetRenderUrl:()=>Be,getListProjectRendersUrl:()=>we,getPreviewClipUrl:()=>Me,getRefreshRenderUrlUrl:()=>Fe,getRender:()=>gr,getRetryRenderUrl:()=>Ue,getStreamRenderUrl:()=>Le,listProjectRenders:()=>ur,previewClip:()=>lr,refreshRenderUrl:()=>Rr,retryRender:()=>xr,streamRender:()=>Cr});var Ae=e=>`/v1/projects/${e}/renders`,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(Ae(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},we=(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/projects/${e}/renders?${s}`:`/v1/projects/${e}/renders`},ur=async(e,t,r)=>a(we(e,t),{...r,method:"GET"}),Me=e=>`/v1/projects/${e}/preview-clip`,lr=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(Me(e),{...r,method:"POST",headers:{"Content-Type":"application/json",...s(r?.headers)},body:JSON.stringify(t)})},Be=(e,t)=>`/v1/projects/${e}/renders/${t}`,gr=async(e,t,r)=>a(Be(e,t),{...r,method:"GET"}),Ke=(e,t)=>`/v1/projects/${e}/renders/${t}/cancel`,yr=async(e,t,r)=>a(Ke(e,t),{...r,method:"POST"}),Ue=(e,t)=>`/v1/projects/${e}/renders/${t}/retry`,xr=async(e,t,r)=>a(Ue(e,t),{...r,method:"POST"}),Fe=(e,t)=>`/v1/projects/${e}/renders/${t}/refresh-url`,Rr=async(e,t,r)=>a(Fe(e,t),{...r,method:"POST"}),Le=(e,t)=>`/v1/projects/${e}/renders/${t}/stream`,Cr=async(e,t,r)=>a(Le(e,t),{...r,method:"GET"});var We={};y(We,{createSession:()=>Sr,deleteSession:()=>kr,getCreateSessionUrl:()=>$e,getDeleteSessionUrl:()=>_e,getGetMuxJobUrl:()=>De,getGetSessionUrl:()=>Je,getListSessionsUrl:()=>Ne,getMuxJob:()=>Er,getSession:()=>vr,getTriggerMuxJobUrl:()=>He,listSessions:()=>hr,triggerMuxJob:()=>qr});var Ne=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/sessions?${r}`:"/v1/sessions"},hr=async(e,t)=>a(Ne(e),{...t,method:"GET"}),$e=()=>"/v1/sessions",Sr=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)})},Je=e=>`/v1/sessions/${e}`,vr=async(e,t)=>a(Je(e),{...t,method:"GET"}),_e=e=>`/v1/sessions/${e}`,kr=async(e,t)=>a(_e(e),{...t,method:"DELETE"}),He=e=>`/v1/sessions/${e}/mux-job`,qr=async(e,t)=>a(He(e),{...t,method:"POST"}),De=e=>`/v1/sessions/${e}/mux-job`,Er=async(e,t)=>a(De(e),{...t,method:"GET"});import{readFileSync as Ar,writeFileSync as wr,mkdirSync as Mr,existsSync as Br}from"fs";import{join as ze}from"path";import{homedir as Kr}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 JR(e){return e===402?d.PaymentRequired:e>=500?d.ApiServerError:e>=400?d.ApiClientError:d.Success}function h(e){process.exit(e)}var Ve=ze(Kr(),".cueframe"),q=ze(Ve,"auth.json"),R={local:"http://127.0.0.1:3211",dev:"https://api-dev.cueframe.ai",prod:"https://api.cueframe.ai"},Ur="prod";function VR(e=Ur){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 YR(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 Ye(){if(!Br(q))return{targets:{}};let e=Ar(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 Fr(e){Mr(Ve,{recursive:!0,mode:448}),wr(q,JSON.stringify(e,null,2),{mode:384})}function ZR(e,t="prod",r){let s=Ye(),o=R[t]??R.prod;s.targets[t]={apiKey:e,apiUrl:r??o},Fr(s)}function Ze(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=Ye().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 Xe(e){let{apiKey:t,apiUrl:r}=Ze(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 Lr from"ora";import Gr from"pino";var Nr="v1",Qe=Gr({level:"trace",base:{schemaVersion:Nr},messageKey:"event",timestamp:()=>`,"ts":${Date.now()}`,formatters:{level:()=>({_:0})}});function A(e,t){return Lr({text:e,isSilent:!!t}).start()}function C(e,t,r={}){e.json&&Qe.info(r,t)}function nC(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 iC(e,t){t.json||console.log(e)}function $r(e){for(let t=0;t<e.length;t++){let r=e.charCodeAt(t);if(r<=31||r===127)return!0}return!1}function tt(e,t,r){e.length===0&&et(`${t} is empty.`,r),$r(e)&&et(`${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 et(e,t){w(t,"preflight",new Error(e),d.UserError),h(d.UserError)}var Jr=5e3,B=300*1e3;async function yC(e,t){if(tt(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}Xe(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 P.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)),h(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,Jr)),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),h(d.UserError));try{let i=await P.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,at as f,_ as g,P as h,te as i,ie as j,ve as k,Oe as l,Ge as m,We as n,d as o,O as p,JR as q,h as r,VR as s,YR as t,ZR as u,Xe as v,E as w,A as x,C as y,nC as z,w as A,M as B,iC as C,tt as D,yC as E};
|