codai-sdk 0.66.0 → 0.68.0

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 CHANGED
@@ -1583,7 +1583,7 @@ function decodeBase64(b64) {
1583
1583
  for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
1584
1584
  return out;
1585
1585
  }
1586
- function abortableSleep$6(ms, signal) {
1586
+ function abortableSleep$7(ms, signal) {
1587
1587
  return new Promise((resolve, reject) => {
1588
1588
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1589
1589
  const t = setTimeout(() => {
@@ -1698,7 +1698,7 @@ var Videos = class {
1698
1698
  }
1699
1699
  if (st.status === "failed" || st.status === "filtered") throw new Error(`codai video job ${st.status}: ${st.error ?? "no details"}`);
1700
1700
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai video job ${job.id} did not finish within ${timeoutMs} ms`);
1701
- await abortableSleep$6(pollIntervalMs, signal);
1701
+ await abortableSleep$7(pollIntervalMs, signal);
1702
1702
  }
1703
1703
  }
1704
1704
  };
@@ -1797,14 +1797,14 @@ var Renders = class {
1797
1797
  }
1798
1798
  if (st.status === "failed") throw new Error(`codai render failed: ${st.error ?? "no details"}`);
1799
1799
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai render ${job.id} did not finish within ${timeoutMs} ms`);
1800
- await abortableSleep$6(pollIntervalMs, signal);
1800
+ await abortableSleep$7(pollIntervalMs, signal);
1801
1801
  }
1802
1802
  }
1803
1803
  };
1804
1804
 
1805
1805
  //#endregion
1806
1806
  //#region src/resources/documents.ts
1807
- function abortableSleep$5(ms, signal) {
1807
+ function abortableSleep$6(ms, signal) {
1808
1808
  return new Promise((resolve, reject) => {
1809
1809
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1810
1810
  const t = setTimeout(() => {
@@ -1897,7 +1897,7 @@ var Documents = class {
1897
1897
  if (st.status === "succeeded") return st;
1898
1898
  if (st.status === "failed") throw new Error(`codai document preview failed: ${st.error ?? "no details"}`);
1899
1899
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai document preview ${job.id} did not finish within ${timeoutMs} ms`);
1900
- await abortableSleep$5(pollIntervalMs, signal);
1900
+ await abortableSleep$6(pollIntervalMs, signal);
1901
1901
  }
1902
1902
  }
1903
1903
  /** Queue a deck video and poll `renders.retrieve` until it succeeds. Throws on `failed` or timeout. */
@@ -1929,7 +1929,7 @@ var Documents = class {
1929
1929
  }
1930
1930
  if (st.status === "failed") throw new Error(`codai deck video failed: ${st.error ?? "no details"}`);
1931
1931
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai deck video ${accepted.id} did not finish within ${timeoutMs} ms`);
1932
- await abortableSleep$5(pollIntervalMs, signal);
1932
+ await abortableSleep$6(pollIntervalMs, signal);
1933
1933
  }
1934
1934
  }
1935
1935
  };
@@ -1937,7 +1937,7 @@ var Documents = class {
1937
1937
  //#endregion
1938
1938
  //#region src/resources/exports.ts
1939
1939
  const path$6 = (id) => `/v1/studio/exports/${encodeURIComponent(id)}`;
1940
- function abortableSleep$4(ms, signal) {
1940
+ function abortableSleep$5(ms, signal) {
1941
1941
  return new Promise((resolve, reject) => {
1942
1942
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1943
1943
  const t = setTimeout(() => {
@@ -1978,7 +1978,7 @@ var Exports = class {
1978
1978
  });
1979
1979
  if (st.status === "succeeded" || st.status === "failed") return st;
1980
1980
  if (Date.now() + intervalMs > deadline) throw new Error(`codai export ${id} did not finish within ${timeoutMs} ms`);
1981
- await abortableSleep$4(intervalMs, signal);
1981
+ await abortableSleep$5(intervalMs, signal);
1982
1982
  }
1983
1983
  }
1984
1984
  };
@@ -2159,6 +2159,24 @@ var Creatives = class {
2159
2159
  });
2160
2160
  }
2161
2161
  /**
2162
+ * Mixdown + mastering + exports of an `audio` creative (MU-05; same `POST …/render` route, HTTP 202). `formats`
2163
+ * (default `['wav', 'mp3']`), `stems: true` adds one WAV per audible track (+50 %), `lrc` exports the timed lyrics
2164
+ * (default on when the document has them), `loudness` is `streaming` (−14) | `podcast` (−16) | `broadcast` (−23) or
2165
+ * LUFS (−40…−5). Poll `renders.retrieve(render_id)`: the finished render's `data[]` holds one signed asset per output
2166
+ * (`output: mix | stem | lrc`). $0.001 per output second, minimum $0.01; held up front, billed on the measured length.
2167
+ * 400 `empty_audio` / `too_long` (20 min) / `no_lyrics`; video creatives use `render`.
2168
+ */
2169
+ renderAudio(id, body = {}, opts = {}) {
2170
+ return this.http.json(path$5(id, "/render"), {
2171
+ method: "POST",
2172
+ body,
2173
+ headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
2174
+ ext: opts.ext,
2175
+ signal: opts.signal,
2176
+ noRetry: !opts.idempotencyKey
2177
+ });
2178
+ }
2179
+ /**
2162
2180
  * PNG still frames at up to 6 times (`t_ms`). `exact: false` (default) screenshots the compiled HTML; `exact: true`
2163
2181
  * cuts them from a draft render of the covering scenes. Waits up to ~90 s: frames (`status: 'succeeded'`) or a
2164
2182
  * running job (`status: 'running'`) to poll with `frameJob(id, frame_job_id)`. Cached frames are free; 60 frame
@@ -2705,7 +2723,7 @@ var Templates = class {
2705
2723
  //#endregion
2706
2724
  //#region src/resources/productions.ts
2707
2725
  const path$2 = (id) => `/v1/studio/productions/${encodeURIComponent(id)}`;
2708
- function abortableSleep$3(ms, signal) {
2726
+ function abortableSleep$4(ms, signal) {
2709
2727
  return new Promise((resolve, reject) => {
2710
2728
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
2711
2729
  const t = setTimeout(() => {
@@ -2754,7 +2772,7 @@ var Productions = class {
2754
2772
  const p = await this.retrieve(id, opts);
2755
2773
  if (isProductionFinished(p)) return p;
2756
2774
  if (Date.now() + interval > deadline) throw new Error(`codai: production ${id} did not finish in time (phase ${p.phase})`);
2757
- await abortableSleep$3(interval, opts.signal);
2775
+ await abortableSleep$4(interval, opts.signal);
2758
2776
  }
2759
2777
  }
2760
2778
  /** `create` + `wait`. */
@@ -2764,6 +2782,292 @@ var Productions = class {
2764
2782
  }
2765
2783
  };
2766
2784
 
2785
+ //#endregion
2786
+ //#region src/resources/media-ops.ts
2787
+ const BASE$1 = "/v1/studio/media-ops";
2788
+ const opPath = (op) => `${BASE$1}/${encodeURIComponent(op)}`;
2789
+ function abortableSleep$3(ms, signal) {
2790
+ return new Promise((resolve, reject) => {
2791
+ if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
2792
+ const t = setTimeout(() => {
2793
+ signal?.removeEventListener("abort", onAbort);
2794
+ resolve();
2795
+ }, ms);
2796
+ const onAbort = () => {
2797
+ clearTimeout(t);
2798
+ reject(signal?.reason ?? /* @__PURE__ */ new Error("Aborted"));
2799
+ };
2800
+ signal?.addEventListener("abort", onAbort, { once: true });
2801
+ });
2802
+ }
2803
+ const toBody = (input) => ({
2804
+ asset_ids: input.assetIds ?? [],
2805
+ params: input.params ?? {}
2806
+ });
2807
+ /** A run answer is a job (async op, HTTP 202) when `object` is `media_op.job`. */
2808
+ const isMediaOpJob = (r) => r.object === "media_op.job";
2809
+ const isMediaOpJobFinished = (j) => j.status === "ready" || j.status === "failed";
2810
+ var MediaOps = class {
2811
+ http;
2812
+ constructor(http) {
2813
+ this.http = http;
2814
+ }
2815
+ /** `GET /v1/studio/media-ops` — every op with engine, mode, inputs, `available` and a list quote (free). */
2816
+ list(opts = {}) {
2817
+ return this.http.json(BASE$1, {
2818
+ ext: opts.ext,
2819
+ signal: opts.signal
2820
+ });
2821
+ }
2822
+ /** `POST /v1/studio/media-ops/{op}/quote` — exact price of this request; nothing is held or billed. */
2823
+ quote(op, input = {}, opts = {}) {
2824
+ return this.http.json(`${opPath(op)}/quote`, {
2825
+ method: "POST",
2826
+ body: toBody(input),
2827
+ ext: opts.ext,
2828
+ signal: opts.signal
2829
+ });
2830
+ }
2831
+ /**
2832
+ * `POST /v1/studio/media-ops/{op}` — sync ops resolve to a `media_op.result` with the outputs, async ops to a
2833
+ * `media_op.job` (`status: pending`; poll with `job` / `wait`). Use `isMediaOpJob` to tell them apart.
2834
+ */
2835
+ run(op, input = {}, opts = {}) {
2836
+ return this.http.json(opPath(op), {
2837
+ method: "POST",
2838
+ body: toBody(input),
2839
+ headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
2840
+ noRetry: !opts.idempotencyKey,
2841
+ ext: opts.ext,
2842
+ signal: opts.signal
2843
+ });
2844
+ }
2845
+ /** `GET /v1/studio/media-ops/jobs/{id}` — the job; reading a finished one stores its outputs and bills it once. */
2846
+ job(id, opts = {}) {
2847
+ return this.http.json(`${BASE$1}/jobs/${encodeURIComponent(id)}`, {
2848
+ ext: opts.ext,
2849
+ signal: opts.signal
2850
+ });
2851
+ }
2852
+ /**
2853
+ * Poll `job` every `intervalMs` (default 3 s) until it is `ready` or `failed` (a failed job resolves too — check
2854
+ * `status` / `error`). Throws after `timeoutMs` (default 20 min) or when `signal` aborts.
2855
+ */
2856
+ async wait(id, opts = {}) {
2857
+ const interval = opts.intervalMs ?? 3e3;
2858
+ const deadline = Date.now() + (opts.timeoutMs ?? 12e5);
2859
+ for (;;) {
2860
+ const j = await this.job(id, opts);
2861
+ if (isMediaOpJobFinished(j)) return j;
2862
+ if (Date.now() + interval > deadline) throw new Error(`codai: media job ${id} did not finish in time (status ${j.status})`);
2863
+ await abortableSleep$3(interval, opts.signal);
2864
+ }
2865
+ }
2866
+ /** `run`, then `wait` when the op is async. */
2867
+ async runAndWait(op, input = {}, opts = {}) {
2868
+ const r = await this.run(op, input, opts);
2869
+ return isMediaOpJob(r) && !isMediaOpJobFinished(r) ? this.wait(r.id, opts) : r;
2870
+ }
2871
+ };
2872
+
2873
+ //#endregion
2874
+ //#region src/resources/lyrics.ts
2875
+ const BASE = "/v1/studio/lyrics";
2876
+ var LyricsResource = class {
2877
+ http;
2878
+ constructor(http) {
2879
+ this.http = http;
2880
+ }
2881
+ post(path, body, opts) {
2882
+ return this.http.json(path, {
2883
+ method: "POST",
2884
+ body,
2885
+ headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
2886
+ noRetry: !opts.idempotencyKey,
2887
+ ext: opts.ext,
2888
+ signal: opts.signal
2889
+ });
2890
+ }
2891
+ /**
2892
+ * `POST /v1/studio/lyrics` — `{ brief, language: 'ro' | 'en', genre?, mood?, structure?, syllables_per_line?,
2893
+ * rhyme_scheme?, lines_per_section?, title? }` → `studio.lyrics` with every line's syllables and rhyme letter, the
2894
+ * whole song as `text` (`[kind]` headers) and a `report`. `repaired: true` when the repair turn won.
2895
+ */
2896
+ write(body, opts = {}) {
2897
+ return this.post(BASE, body, opts);
2898
+ }
2899
+ /**
2900
+ * `POST /v1/studio/lyrics/align` — `{ creative_id, clip_id, lyrics_text, language?, apply?, base_seq?,
2901
+ * retranscribe? }` → `studio.lyrics_alignment`: timed `lines`, `lrc`, `match_ratio`, `cached`, and `seq` /
2902
+ * `doc_hash` of the new version when applied.
2903
+ */
2904
+ align(body, opts = {}) {
2905
+ return this.post(`${BASE}/align`, body, opts);
2906
+ }
2907
+ };
2908
+
2909
+ //#endregion
2910
+ //#region src/resources/jam.ts
2911
+ const JAM_SUBPROTOCOL = "codai-jam";
2912
+ /** WebSocket close codes of `/v1/studio/jam`. */
2913
+ const JAM_CLOSE_CODES = {
2914
+ invalidMessage: 4400,
2915
+ unauthorized: 4401,
2916
+ insufficientFunds: 4402,
2917
+ forbidden: 4403,
2918
+ maxDuration: 4408,
2919
+ busy: 4409,
2920
+ upstream: 4502,
2921
+ unavailable: 4503
2922
+ };
2923
+ const JAM_SCALES = [
2924
+ "SCALE_UNSPECIFIED",
2925
+ "C_MAJOR_A_MINOR",
2926
+ "D_FLAT_MAJOR_B_FLAT_MINOR",
2927
+ "D_MAJOR_B_MINOR",
2928
+ "E_FLAT_MAJOR_C_MINOR",
2929
+ "E_MAJOR_D_FLAT_MINOR",
2930
+ "F_MAJOR_D_MINOR",
2931
+ "G_FLAT_MAJOR_E_FLAT_MINOR",
2932
+ "G_MAJOR_E_MINOR",
2933
+ "A_FLAT_MAJOR_F_MINOR",
2934
+ "A_MAJOR_G_FLAT_MINOR",
2935
+ "B_FLAT_MAJOR_G_MINOR",
2936
+ "B_MAJOR_A_FLAT_MINOR"
2937
+ ];
2938
+ const OPEN$1 = 1;
2939
+ function toArrayBuffer(data) {
2940
+ if (data instanceof ArrayBuffer) return data;
2941
+ if (ArrayBuffer.isView(data)) {
2942
+ const v = data;
2943
+ return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength);
2944
+ }
2945
+ return null;
2946
+ }
2947
+ /** A live jam session: `on()` listeners for status / audio / errors and typed senders. */
2948
+ var JamSession = class {
2949
+ socket;
2950
+ listeners = /* @__PURE__ */ new Map();
2951
+ outbox = [];
2952
+ closed = false;
2953
+ /** Resolves when the socket is open (rejects if it closes first). */
2954
+ ready;
2955
+ constructor(socket) {
2956
+ this.socket = socket;
2957
+ let resolveReady;
2958
+ let rejectReady;
2959
+ this.ready = new Promise((res, rej) => {
2960
+ resolveReady = res;
2961
+ rejectReady = rej;
2962
+ });
2963
+ this.ready.catch(() => void 0);
2964
+ socket.onopen = () => {
2965
+ for (const f of this.outbox.splice(0)) socket.send(f);
2966
+ resolveReady();
2967
+ };
2968
+ socket.onmessage = (ev) => {
2969
+ if (typeof ev.data !== "string") {
2970
+ const buf = toArrayBuffer(ev.data);
2971
+ if (buf) this.emit({
2972
+ type: "audio",
2973
+ data: buf
2974
+ });
2975
+ return;
2976
+ }
2977
+ let parsed;
2978
+ try {
2979
+ parsed = JSON.parse(ev.data);
2980
+ } catch {
2981
+ return;
2982
+ }
2983
+ if (parsed && typeof parsed === "object" && typeof parsed.type === "string") this.emit(parsed);
2984
+ };
2985
+ socket.onerror = () => {};
2986
+ socket.onclose = (ev) => {
2987
+ rejectReady(/* @__PURE__ */ new Error(`jam socket closed before open (${String(ev.code)} ${ev.reason})`));
2988
+ this.closed = true;
2989
+ this.emit({
2990
+ type: "close",
2991
+ code: ev.code,
2992
+ reason: ev.reason
2993
+ });
2994
+ };
2995
+ }
2996
+ on(type, fn) {
2997
+ let set = this.listeners.get(type);
2998
+ if (!set) this.listeners.set(type, set = /* @__PURE__ */ new Set());
2999
+ set.add(fn);
3000
+ return () => set.delete(fn);
3001
+ }
3002
+ /** Send one client message (JSON). Queued until the socket opens. */
3003
+ send(msg) {
3004
+ if (this.closed) throw new Error("jam session is closed");
3005
+ const frame = JSON.stringify(msg);
3006
+ if (this.socket.readyState === OPEN$1) this.socket.send(frame);
3007
+ else this.outbox.push(frame);
3008
+ }
3009
+ prompts(prompts) {
3010
+ this.send({
3011
+ type: "prompts",
3012
+ prompts
3013
+ });
3014
+ }
3015
+ config(config) {
3016
+ this.send({
3017
+ type: "config",
3018
+ ...config
3019
+ });
3020
+ }
3021
+ play() {
3022
+ this.send({ type: "play" });
3023
+ }
3024
+ pause() {
3025
+ this.send({ type: "pause" });
3026
+ }
3027
+ stop() {
3028
+ this.send({ type: "stop" });
3029
+ }
3030
+ reset() {
3031
+ this.send({ type: "reset" });
3032
+ }
3033
+ close(code = 1e3, reason = "client closed") {
3034
+ if (this.closed) return;
3035
+ this.socket.close(code, reason);
3036
+ }
3037
+ emit(ev) {
3038
+ for (const fn of this.listeners.get(ev.type) ?? []) fn(ev);
3039
+ for (const fn of this.listeners.get("*") ?? []) fn(ev);
3040
+ }
3041
+ };
3042
+ /** Build the `wss://…/v1/studio/jam` URL (exported for tests and custom transports). */
3043
+ function jamUrl(baseUrl, opts = {}) {
3044
+ const url = new URL(`${baseUrl.replace(/\/$/, "").replace(/^http/, "ws")}/v1/studio/jam`);
3045
+ if (opts.sessionId) url.searchParams.set("session_id", opts.sessionId);
3046
+ return url.toString();
3047
+ }
3048
+ var Jam = class {
3049
+ defaults;
3050
+ constructor(defaults) {
3051
+ this.defaults = defaults;
3052
+ }
3053
+ /** Open a live jam. Returns immediately; `await session.ready` to wait for the socket. */
3054
+ connect(opts = {}) {
3055
+ const Ctor = opts.WebSocket ?? globalThis.WebSocket;
3056
+ if (!Ctor) throw new Error("codai.jam: no WebSocket available — pass options.WebSocket");
3057
+ let token = opts.token;
3058
+ let apiKey = token ? void 0 : opts.apiKey ?? this.defaults.apiKey;
3059
+ if (apiKey?.startsWith("codai_eph_v1.")) {
3060
+ token = apiKey;
3061
+ apiKey = void 0;
3062
+ }
3063
+ if (!token && !apiKey) throw new Error("codai.jam: pass `token` (browser) or `apiKey`");
3064
+ const url = jamUrl(opts.baseUrl ?? this.defaults.baseUrl, opts);
3065
+ const socket = apiKey ? new Ctor(url, [JAM_SUBPROTOCOL], { headers: { Authorization: `Bearer ${apiKey}` } }) : new Ctor(url, [JAM_SUBPROTOCOL, `bearer.${token}`]);
3066
+ if ("binaryType" in socket) socket.binaryType = "arraybuffer";
3067
+ return new JamSession(socket);
3068
+ }
3069
+ };
3070
+
2767
3071
  //#endregion
2768
3072
  //#region src/resources/batches.ts
2769
3073
  const BATCH_DONE = [
@@ -3036,6 +3340,10 @@ var VoiceRevocations = class {
3036
3340
 
3037
3341
  //#endregion
3038
3342
  //#region src/resources/vault.ts
3343
+ /** The UTF-8 message an unlock proof covers: `codai-vault/unlock/v1|<challenge>|<device_id or "passkey">`. */
3344
+ function vaultUnlockMessage(challenge, deviceIdOrPasskey) {
3345
+ return `codai-vault/unlock/v1|${challenge}|${deviceIdOrPasskey}`;
3346
+ }
3039
3347
  const seg = (base, id, suffix = "") => `${base}/${encodeURIComponent(id)}${suffix}`;
3040
3348
  /** `/v1/vault/devices/*` — hardware-backed device approval keys (public keys only; revocation is instant). */
3041
3349
  var VaultDevices = class {
@@ -3124,6 +3432,53 @@ var Vault = class {
3124
3432
  setDefaultTier(defaultTier, opts = {}) {
3125
3433
  return this.send("PATCH", "/v1/vault/settings", opts, { default_tier: defaultTier });
3126
3434
  }
3435
+ /**
3436
+ * `PATCH /v1/vault/settings` — `default_tier` and/or partial anomaly `guards` (merged over the current ones).
3437
+ * Answers the effective `{ default_tier, guards }`.
3438
+ */
3439
+ updateSettings(body, opts = {}) {
3440
+ if (body.default_tier === void 0 && body.guards === void 0) return Promise.reject(/* @__PURE__ */ new TypeError("updateSettings needs default_tier and/or guards"));
3441
+ return this.send("PATCH", "/v1/vault/settings", opts, { ...body });
3442
+ }
3443
+ /**
3444
+ * `POST /v1/vault/lock` — panic: revoke every live grant, deny every pending approval, lock the vault (agent uses
3445
+ * then answer `vault_locked`). Device keys stay enrolled. Idempotent.
3446
+ */
3447
+ lock(params = {}, opts = {}) {
3448
+ return this.send("POST", "/v1/vault/lock", opts, { via: params.via });
3449
+ }
3450
+ /** `POST /v1/vault/unlock/challenge` — single-use unlock challenge, valid 5 minutes. */
3451
+ unlockChallenge(opts = {}) {
3452
+ return this.send("POST", "/v1/vault/unlock/challenge", opts, {});
3453
+ }
3454
+ /**
3455
+ * `POST /v1/vault/unlock` — end a lock with a device-key proof over {@link vaultUnlockMessage} or a passkey whose
3456
+ * challenge is base64url(SHA-256(that message with `passkey`)). 403 `challenge_invalid`, `wear_t3_only`, …
3457
+ */
3458
+ unlock(body, opts = {}) {
3459
+ return this.send("POST", "/v1/vault/unlock", opts, { ...body });
3460
+ }
3461
+ /** `GET /v1/vault/limits` — per-handle usage caps on your items. */
3462
+ async limits(opts = {}) {
3463
+ return [...(await this.get("/v1/vault/limits", opts)).limits];
3464
+ }
3465
+ /**
3466
+ * `PUT /v1/vault/items/{id}/limits` — all three keys required; `null` removes a cap, all `null` removes the limits
3467
+ * (answers `null`). Over a cap the broker calls answer 429 `vault_rate_limited` with `Retry-After`.
3468
+ */
3469
+ async setLimits(id, limits, opts = {}) {
3470
+ return (await this.http.json(seg("/v1/vault/items", id, "/limits"), {
3471
+ method: "PUT",
3472
+ body: {
3473
+ per_minute: limits.per_minute,
3474
+ per_day: limits.per_day,
3475
+ units_per_day: limits.units_per_day
3476
+ },
3477
+ ext: opts.ext,
3478
+ signal: opts.signal,
3479
+ noRetry: true
3480
+ })).limits ?? null;
3481
+ }
3127
3482
  /** `GET /v1/vault/vaults` — vaults you belong to, with your role and sealed vault key. */
3128
3483
  vaults(opts = {}) {
3129
3484
  return this.get("/v1/vault/vaults", opts);
@@ -3174,6 +3529,10 @@ var Vault = class {
3174
3529
  revokeGrant(id, opts = {}) {
3175
3530
  return this.send("DELETE", seg("/v1/vault/grants", id), opts);
3176
3531
  }
3532
+ /** `POST /v1/vault/grants/revoke-task` — revoke every live grant of a task / session; answers `{ revoked }`. */
3533
+ revokeTaskGrants(task, opts = {}) {
3534
+ return this.send("POST", "/v1/vault/grants/revoke-task", opts, { task });
3535
+ }
3177
3536
  /** `GET /v1/vault/events` — append-only audit log (never contains secret values). */
3178
3537
  events(params = {}, opts = {}) {
3179
3538
  return this.get("/v1/vault/events", opts, { limit: params.limit });
@@ -6354,7 +6713,13 @@ const OPERATION_METHODS = {
6354
6713
  createVoiceRevocation: "voiceRevocations.create",
6355
6714
  getVaultAccount: "vault.account",
6356
6715
  putVaultAccount: "vault.putAccount",
6357
- patchVaultSettings: "vault.setDefaultTier",
6716
+ patchVaultSettings: "vault.updateSettings",
6717
+ lockVault: "vault.lock",
6718
+ createVaultUnlockChallenge: "vault.unlockChallenge",
6719
+ unlockVault: "vault.unlock",
6720
+ listVaultLimits: "vault.limits",
6721
+ setVaultItemLimits: "vault.setLimits",
6722
+ revokeVaultTaskGrants: "vault.revokeTaskGrants",
6358
6723
  listVaults: "vault.vaults",
6359
6724
  createVault: "vault.createVault",
6360
6725
  listVaultItems: "vault.items",
@@ -6392,6 +6757,12 @@ const OPERATION_METHODS = {
6392
6757
  listCreativeTemplates: "templates.list",
6393
6758
  createStudioProduction: "productions.create",
6394
6759
  getStudioProduction: "productions.retrieve",
6760
+ listStudioMediaOps: "mediaOps.list",
6761
+ quoteStudioMediaOp: "mediaOps.quote",
6762
+ runStudioMediaOp: "mediaOps.run",
6763
+ getStudioMediaOpJob: "mediaOps.job",
6764
+ writeStudioLyrics: "lyrics.write",
6765
+ alignStudioLyrics: "lyrics.align",
6395
6766
  getCreativeTemplate: "templates.retrieve",
6396
6767
  deleteCreativeTemplate: "templates.delete",
6397
6768
  exportCreativeFcpxml: "creatives.exportFcpxml",
@@ -6860,6 +7231,13 @@ var CodaiApps = class {
6860
7231
  * built-in starters; free; use with creatives.create({ kind, template, vars }))
6861
7232
  * client.productions.create / .retrieve / .wait / .run (codai Studio brief → promo video: storyboard, images,
6862
7233
  * voice-over, editable creative, draft render, one review + repair; billed as the parts are produced)
7234
+ * client.mediaOps.list / .quote / .run / .job / .wait / .runAndWait (codai Studio media operations on your assets:
7235
+ * background removal, upscale, inpaint / outpaint / erase, stems, denoise, MIDI, mastering, analysis, ACE-Step
7236
+ * music and sound effects; quote held, measured cost billed; async ops return a job)
7237
+ * client.lyrics.write / .align (codai Studio lyrics writer with syllable + rhyme checks; karaoke alignment to a clip
7238
+ * of an audio creative with LRC; token-metered / transcription billed)
7239
+ * client.creatives.renderAudio (mixdown + mastering of an audio creative: WAV / MP3 / FLAC, stems, LRC)
7240
+ * client.jam.connect (WebSocket live jam on Lyria RealTime; not an OpenAPI operation)
6863
7241
  * client.exports.retrieve / .wait (codai Studio FCPXML exports queued with creatives.exportFcpxml; only newly
6864
7242
  * rendered seconds are billed; Lottie exports from creatives.exportLottie are free and ready at once)
6865
7243
  * client.batches.create / .dryRun / .list / .get / .cancel / .retry / .exportCsv / .zip / .wait (codai Studio
@@ -6869,6 +7247,7 @@ var CodaiApps = class {
6869
7247
  * client.voiceRevocations.create (public takedown ticket for a voice cloned in codai Studio; no key needed)
6870
7248
  * client.vault.account / .items / .putItem / .rules / .approvals / .decide / .catalog / .use / .httpCall / .resolve
6871
7249
  * client.vault.devices.challenge / .enroll / .list / .rename / .revoke (device approval keys, V-27)
7250
+ * client.vault.updateSettings / .lock / .unlockChallenge / .unlock / .limits / .setLimits / .revokeTaskGrants (guards, v4)
6872
7251
  * (zero-knowledge credentials vault: ciphertext only; the broker calls never return secret values)
6873
7252
  * client.abuseReports.create (public DSA notice about a codai Studio share / review link; no key needed)
6874
7253
  * client.provenance.check (public: which codai AI-provenance marks a file carries; no key needed)
@@ -6927,6 +7306,12 @@ var Codai = class {
6927
7306
  templates;
6928
7307
  /** codai Studio productions (`productions.run({ brief, language: 'ro' })` → a finished promo video + editable creative). */
6929
7308
  productions;
7309
+ /** codai Studio media operations (`mediaOps.run('audio.separate_stems', { assetIds })` → job; `mediaOps.wait(id)`). */
7310
+ mediaOps;
7311
+ /** codai Studio lyrics (`lyrics.write({ brief, language: 'ro' })`, `lyrics.align({ creative_id, clip_id, lyrics_text })`). */
7312
+ lyrics;
7313
+ /** codai Studio live jam over WebSocket (`jam.connect({ token })` → PCM16 48 kHz stereo; `prompts`, `config`, `play`). */
7314
+ jam;
6930
7315
  /** codai Studio FCPXML exports (`creatives.exportFcpxml(id)` queues one; `exports.wait(id)` polls until the zip is ready). */
6931
7316
  exports;
6932
7317
  /** codai Studio batches (`batches.create({ source: { template_id }, csv })` → one creative per row; `batches.wait(id)`). */
@@ -7031,6 +7416,12 @@ var Codai = class {
7031
7416
  this.brandKits = new BrandKits(http);
7032
7417
  this.templates = new Templates(http);
7033
7418
  this.productions = new Productions(http);
7419
+ this.mediaOps = new MediaOps(http);
7420
+ this.lyrics = new LyricsResource(http);
7421
+ this.jam = new Jam({
7422
+ baseUrl: http.baseUrl,
7423
+ apiKey: opts.apiKey
7424
+ });
7034
7425
  this.exports = new Exports(http);
7035
7426
  this.batches = new Batches(http);
7036
7427
  this.shares = new Shares(http);
@@ -7165,5 +7556,5 @@ function allKeys(obj) {
7165
7556
  }
7166
7557
 
7167
7558
  //#endregion
7168
- export { AbuseReports, Account, AgentRuns, Agents, Assets, Audio, Batches, Billing, BrandKits, Cards, Chat, ChatCompletions, Codai, Codai as default, CodaiApps, CodaiError, Creatives, Devices, Documents, Embeddings, EnvironmentFiles, EnvironmentJobs, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Exports, Feedback, Health, Heartbeats, Hosts, HttpClient, Images, Keys, Lists, Memory, Messages, Models, Music, Notifications, OPERATION_METHODS, OrgMembers, Orgs, OsGate, PROVENANCE_MAX_BYTES, PhoneModels, Productions, Projects, Prompts, Provenance, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Referrals, Renders, Research, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, SandboxFiles, Sandboxes, ScheduleExecutor, SchedulerHosts, Schedules, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Settings, Sfx, Shares, SystemOne, TUS_CHUNK_BYTES, Tasks, Templates, Tokens, Tools, Transcripts, Triggers, Usage, Vault, VaultDevices, Verify, Videos, VoiceRevocations, extensionHeaders, frameJson, isAssetDto, isProductionFinished, isResearchFinished, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, shareTokenFrom, uploadIdFromLocation, verifyAttestationWithKeys, verifyResolveWebhook };
7559
+ export { AbuseReports, Account, AgentRuns, Agents, Assets, Audio, Batches, Billing, BrandKits, Cards, Chat, ChatCompletions, Codai, Codai as default, CodaiApps, CodaiError, Creatives, Devices, Documents, Embeddings, EnvironmentFiles, EnvironmentJobs, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Exports, Feedback, Health, Heartbeats, Hosts, HttpClient, Images, JAM_CLOSE_CODES, JAM_SCALES, JAM_SUBPROTOCOL, Jam, JamSession, Keys, Lists, LyricsResource, MediaOps, Memory, Messages, Models, Music, Notifications, OPERATION_METHODS, OrgMembers, Orgs, OsGate, PROVENANCE_MAX_BYTES, PhoneModels, Productions, Projects, Prompts, Provenance, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Referrals, Renders, Research, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, SandboxFiles, Sandboxes, ScheduleExecutor, SchedulerHosts, Schedules, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Settings, Sfx, Shares, SystemOne, TUS_CHUNK_BYTES, Tasks, Templates, Tokens, Tools, Transcripts, Triggers, Usage, Vault, VaultDevices, Verify, Videos, VoiceRevocations, extensionHeaders, frameJson, isAssetDto, isMediaOpJob, isMediaOpJobFinished, isProductionFinished, isResearchFinished, jamUrl, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, shareTokenFrom, uploadIdFromLocation, vaultUnlockMessage, verifyAttestationWithKeys, verifyResolveWebhook };
7169
7560
  //# sourceMappingURL=index.js.map