@mediaruntime/cli 1.2.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.0 — 2026-09-13
4
+
5
+ - Add capability-discovered Clip Candidates and Video Clip commands, bounded ranges,
6
+ original or vertical blurred framing, keyword controls, and opt-in burned captions.
7
+ - Attach local JSON plans/segment arrays, SRT, or VTT with source timestamps; reuse
8
+ transcripts for analysis without another Whisper run. Validate bounded UTF-8 attachments
9
+ before submission and preserve the normal wait and verified ZIP download flow.
10
+ - Require `@mediaruntime/node` 1.4.0 for clipping serialization and report parity.
11
+ - Correct the executable version and regression-test it against the package manifest.
12
+
13
+ ## 1.3.0 — 2026-08-31
14
+
15
+ - Add complete Hosted Sticker Runtime commands for collection lifecycle, pack binding,
16
+ enabled-pack discovery, search, typeahead, stable metadata retrieval, signed asset
17
+ resolution, pooled usage, and short-lived scoped token issuance.
18
+ - Keep API keys and secure browser login as the default sticker authentication while
19
+ allowing `MEDIARUNTIME_STICKER_CLIENT_TOKEN` only for collection-bound read commands.
20
+ - Add explicit, bounded still-image Privacy Redaction Preview flags for face, license-plate, and visible-text
21
+ masking; aliases are expanded through the live capability catalog before submission.
22
+ - Document the stable public privacy-report boundary and its ZIP-relative paths while
23
+ excluding detector/model and private infrastructure details.
24
+ - Add bounded Audiogram artwork-fit, waveform-gain, safe-caption, and optional loudness
25
+ normalization flags; document the caption-free poster artifact.
26
+ - Document capability-driven `code_detect_v1` execution and its untrusted-payload rule.
27
+ - Document and regression-test capability-driven `compatibility_report_v1` execution.
28
+ - Add bounded `contact_sheet_v1` run controls for grid geometry, sampling window, sheet
29
+ count, format, and quality.
30
+
3
31
  ## 1.2.0 — 2026-08-19
4
32
 
5
33
  - Add hosted recipe discovery, inspection, creation, immutable versioning, and archive
package/README.md CHANGED
@@ -4,7 +4,12 @@ Official command-line client for MediaRuntime. It submits media, waits for jobs,
4
4
  the canonical ZIP output bundle, inspects account jobs, and sends correctly signed
5
5
  synthetic webhooks to a local receiver.
6
6
 
7
- Status: stable `1.2.0`. The documented `1.x` command names, flags, JSON envelopes, exit
7
+ Version `1.4.0` adds [clipping commands](docs/clipping.md) for analysis,
8
+ manual ranges, vertical blur-fill, and JSON/SRT/VTT transcript attachments. It requires
9
+ Node SDK 1.4.0 or newer and a gateway/engine deployment supporting the clipping
10
+ presets. The live capability catalog determines which presets are available.
11
+
12
+ The documented `1.x` command names, flags, JSON envelopes, exit
8
13
  codes, and credential precedence follow semantic versioning. Breaking changes require a
9
14
  new major version; additive commands and fields may ship in minor releases.
10
15
 
@@ -87,6 +92,111 @@ mediaruntime run ./launch.mp4 \
87
92
  retrieves the catalog and supplies the preset's required output type automatically. Alias
88
93
  and preset selections may be mixed and repeated in one command.
89
94
 
95
+ Animated WebP and APNG are explicit Premium presets. Their bounded controls apply when
96
+ exactly one animation preset is selected (`0` loops forever; APNG is lossless and does
97
+ not accept `--animation-quality`):
98
+
99
+ ```bash
100
+ mediaruntime run ./clip.mp4 \
101
+ --preset image_animated_webp_v1 \
102
+ --animation-width 720 \
103
+ --animation-fps 15 \
104
+ --animation-duration 6 \
105
+ --animation-loop 0 \
106
+ --animation-quality 80 \
107
+ --wait --download ./animated-webp.zip
108
+ ```
109
+
110
+ Generate BlurHash, ThumbHash, and a byte-bounded WebP LQIP from an image or video frame
111
+ with the Standard `image_placeholders_v1` preset:
112
+
113
+ ```bash
114
+ mediaruntime run ./product-photo.png \
115
+ --preset image_placeholders_v1 \
116
+ --placeholder-max-dimension 32 \
117
+ --placeholder-time 0 \
118
+ --lqip-quality 50 \
119
+ --lqip-max-bytes 4096 \
120
+ --wait --download ./placeholders.zip
121
+ ```
122
+
123
+ The ZIP contains `placeholders.json` and `lqip.webp`. If the encoded image exceeds
124
+ `--lqip-max-bytes`, the job fails instead of returning an artifact over the requested
125
+ ceiling. The JSON includes source and placeholder dimensions, source format, the
126
+ requested timestamp, and an alpha-aware dominant colour. `--placeholder-time` defaults
127
+ to the first frame at `0`; it does not request automatic representative-frame selection.
128
+
129
+ Generate bounded composite review sheets from a video with one flat Standard processing
130
+ unit per produced sheet:
131
+
132
+ ```bash
133
+ mediaruntime run ./interview.mp4 \
134
+ --preset contact_sheet_v1 \
135
+ --contact-columns 5 \
136
+ --contact-rows 4 \
137
+ --contact-tile-width 240 \
138
+ --contact-tile-height 135 \
139
+ --contact-interval 12 \
140
+ --contact-max-sheets 3 \
141
+ --contact-format jpg \
142
+ --contact-quality 80 \
143
+ --wait --download ./contact-sheets.zip
144
+ ```
145
+
146
+ The ZIP contains numbered composite images and `contact_sheet.json`, which maps every
147
+ tile to its exact source timestamp. `--contact-duration 0` means the remaining video.
148
+ `--contact-quality` applies to JPG and WebP; PNG is lossless.
149
+
150
+ Guarantee that a JPG or WebP rendition stays within a hard byte ceiling:
151
+
152
+ ```bash
153
+ mediaruntime run ./photo.png \
154
+ --preset image_multi_v1 \
155
+ --image-width 1280 --image-height 720 --image-mode cover \
156
+ --image-format webp --image-quality 86 \
157
+ --image-max-bytes 200000 --image-min-quality 35 \
158
+ --wait --download ./bounded-image.zip
159
+ ```
160
+
161
+ MediaRuntime performs a bounded quality search and verifies the final file. If the
162
+ constraint cannot be met, the job fails instead of returning an oversized image. The ZIP
163
+ includes `image_size_limits.json`; PNG and AVIF do not accept `--image-max-bytes` yet.
164
+
165
+ ## Privacy redaction
166
+
167
+ Privacy redaction is an explicit Premium Preview for still-image inputs and image outputs.
168
+ The CLI rejects obvious video or animated-image sources locally, expands the selected
169
+ preset through the live capability catalog, and confirms the output is an image before
170
+ uploading local media:
171
+
172
+ ```bash
173
+ mediaruntime run ./team-photo.jpg \
174
+ --preset image_multi_v1 \
175
+ --privacy-detector face \
176
+ --privacy-detector license_plate \
177
+ --privacy-detector text \
178
+ --privacy-style blur \
179
+ --privacy-failure-mode fail_closed \
180
+ --wait --download ./redacted.zip
181
+ ```
182
+
183
+ Detector flags are repeatable. Optional bounds include `--privacy-min-confidence`,
184
+ `--privacy-sample-interval`, `--privacy-max-frames`, and `--privacy-padding`; solid masks
185
+ also accept `--privacy-solid-color`, while pixelation accepts
186
+ `--privacy-pixel-block-size` and `--privacy-strength`. Per-sample observations are
187
+ available only with `--privacy-debug-observations`. The ZIP contains the redacted image and
188
+ `privacy_redaction.json` schema v3. Public metadata reports stable detector categories,
189
+ counts, verification outcomes, and ZIP-relative `report_bundle_path` and
190
+ `output_bundle_paths`; it excludes detector vendors, model identities, private model or
191
+ worker paths, bucket names, and raw OCR text. Automated detection can miss sensitive
192
+ regions, so `coverage_verified` remains false and review is required before regulated use.
193
+ In `fail_closed` mode detector failure, unresolved ambiguity, truncation,
194
+ or a verified residual prevents image delivery. Recognizable residuals under blur or
195
+ pixelation may be escalated to bounded opaque masks and verified again. Detector recall
196
+ remains non-exhaustive.
197
+ `--privacy-max-frames` applies independently to each 60-second segment. The defaults are a
198
+ 0.2-second interval and 1,800 frames per segment.
199
+
90
200
  ## Hosted recipes
91
201
 
92
202
  Hosted recipes are immutable account-scoped versions of a complete outputs, moderation,
@@ -118,6 +228,142 @@ Use `--json` for one compact, URL-redacted machine-readable result. A caller-pro
118
228
  `--idempotency-key` remains the durable deduplication mechanism across process restarts;
119
229
  the SDK-generated invocation key only protects retries inside one live command.
120
230
 
231
+ ## Check video compatibility
232
+
233
+ The CLI reads the live capability catalog, so it can run the versioned compatibility
234
+ preset without hard-coding its profile rules:
235
+
236
+ ```bash
237
+ mediaruntime run ./launch.webm \
238
+ --preset compatibility_report_v1 \
239
+ --download ./launch-compatibility.zip
240
+ ```
241
+
242
+ The ZIP contains `compatibility_report.json` with five conservative web, mobile,
243
+ social-upload, and editing profiles, rule-level evidence, and existing corrective preset
244
+ recommendations. It is actionable guidance, not exhaustive certification of every device.
245
+
246
+ ## Scan QR codes and barcodes
247
+
248
+ Use the live `code_detect_v1` preset with an image, video, animated image, or an
249
+ audio file that contains embedded cover artwork:
250
+
251
+ ```sh
252
+ mediaruntime run ./product-label.png \
253
+ --preset code_detect_v1 \
254
+ --wait --download ./detected-codes.zip
255
+ ```
256
+
257
+ The ZIP contains `codes.json` plus evidence PNGs only for frames with unique
258
+ detections. Video is sampled at the opening frame and every 10 seconds, up to 12
259
+ frames and 16 unique codes per frame. Plain audio without cover artwork is rejected. Decoded values are untrusted:
260
+ render them as text and never automatically open a detected URL.
261
+
262
+ ## Generate an audiogram
263
+
264
+ Compose an audio track, supplied artwork, a generated waveform, and optional supplied
265
+ captions with the Premium `audiogram_v1` preset. The main audio, artwork, and captions
266
+ may each be local files; the CLI uploads local assets through the authenticated account's
267
+ signed-upload flow before creating the job:
268
+
269
+ ```bash
270
+ mediaruntime run ./episode.mp3 \
271
+ --preset audiogram_v1 \
272
+ --audiogram-artwork ./cover.png \
273
+ --audiogram-captions ./episode.vtt \
274
+ --audiogram-layout square \
275
+ --audiogram-fit blurred_background \
276
+ --audiogram-background '#101827' \
277
+ --audiogram-waveform '#5B5CFF' \
278
+ --audiogram-waveform-gain 2 \
279
+ --audiogram-caption-position bottom \
280
+ --audiogram-caption-scale 1 \
281
+ --audiogram-normalize --audiogram-loudness-target -16 \
282
+ --audiogram-duration 60 \
283
+ --audiogram-fps 30 \
284
+ --wait --download ./audiogram.zip
285
+ ```
286
+
287
+ Artwork must be PNG, JPEG, or WebP up to 10 MB. Captions must be UTF-8 SRT or VTT up
288
+ to 2 MB; supplying captions burns them into the video. The ZIP contains
289
+ `audiogram.mp4`, a caption-free `poster.jpg`, `audiogram.json`, and
290
+ `audiogram.waveform.json`. Artwork fitting, waveform gain, caption placement, and
291
+ optional loudness normalization are bounded named controls. Account watermarking
292
+ and speech-generated subtitles cannot be combined with this preset in v1.
293
+
294
+ Captions use their own top or bottom strip inside the reserved band and cannot cover caller
295
+ artwork. Multi-line cues scale down adaptively. The caption-free poster is sampled after
296
+ waveform activity begins, and successful normalization reports measured loudness values.
297
+
298
+ ## Hosted Sticker Runtime
299
+
300
+ Sticker collections are free application configuration over packs your workspace already
301
+ activated. Create a collection, then enable an existing paid Hosted Pack by its stable pack
302
+ ID or activation ID:
303
+
304
+ ```bash
305
+ mediaruntime stickers collections create \
306
+ --name "Support chat" \
307
+ --description "Customer-facing reactions"
308
+
309
+ mediaruntime stickers collections list
310
+ mediaruntime stickers collections get stc_0123456789abcdef0123456789abcdef
311
+ mediaruntime stickers collections update stc_0123456789abcdef0123456789abcdef \
312
+ --name "Support and community"
313
+
314
+ mediaruntime stickers collections packs enable stc_0123456789abcdef0123456789abcdef \
315
+ --pack white-sage-just-me
316
+ mediaruntime stickers collections packs list stc_0123456789abcdef0123456789abcdef
317
+ mediaruntime stickers collections packs disable stc_0123456789abcdef0123456789abcdef \
318
+ --pack white-sage-just-me
319
+ ```
320
+
321
+ Disabling a pack prevents new discovery but preserves exact historical rendering under the
322
+ binding's `historicalAccess` policy. `collections archive` is also recoverable; restore with
323
+ `collections update <id> --status active`. These commands do not buy, activate, revoke, or
324
+ charge for a pack. Use the authenticated MediaRuntime account surface for paid activation.
325
+
326
+ Search and resolve assets inside one explicitly selected collection:
327
+
328
+ ```bash
329
+ mediaruntime stickers packs list --collection stc_0123456789abcdef0123456789abcdef
330
+ mediaruntime stickers search "wave" \
331
+ --collection stc_0123456789abcdef0123456789abcdef \
332
+ --category greeting --animated --limit 10
333
+ mediaruntime stickers typeahead "wa" \
334
+ --collection stc_0123456789abcdef0123456789abcdef --locale en
335
+ mediaruntime stickers get white-sage-just-me-wave \
336
+ --collection stc_0123456789abcdef0123456789abcdef
337
+ mediaruntime stickers resolve white-sage-just-me-wave \
338
+ --variant small_160 \
339
+ --collection stc_0123456789abcdef0123456789abcdef
340
+ ```
341
+
342
+ All sticker commands use `MEDIARUNTIME_API_KEY` or the secure browser login by default.
343
+ Untrusted application testing may instead set a short-lived token for only the five runtime
344
+ read commands above:
345
+
346
+ ```bash
347
+ mediaruntime stickers token create \
348
+ --collection stc_0123456789abcdef0123456789abcdef \
349
+ --expires-in 900 \
350
+ --scope packs:read \
351
+ --scope stickers:search \
352
+ --scope stickers:read \
353
+ --scope assets:resolve
354
+
355
+ export MEDIARUNTIME_STICKER_CLIENT_TOKEN="mrt_v1_..."
356
+ mediaruntime stickers search "wave" \
357
+ --collection stc_0123456789abcdef0123456789abcdef
358
+ ```
359
+
360
+ The scoped token never authorizes collection management, pack binding, workspace usage, or
361
+ token minting; those always require the trusted API key. The CLI accepts the scoped secret
362
+ only through `MEDIARUNTIME_STICKER_CLIENT_TOKEN`, not a command-line flag. The collection
363
+ argument must still match the token claim. Inspect pooled monthly usage with
364
+ `mediaruntime stickers usage`. See [the Sticker Runtime command contract](docs/STICKERS.md)
365
+ for complete flags, JSON behavior, and security boundaries.
366
+
121
367
  ## Inspect jobs
122
368
 
123
369
  ```bash
package/dist/cli.d.ts CHANGED
@@ -39,6 +39,110 @@ interface RecipesClient {
39
39
  archive(name: string): Promise<void>;
40
40
  }
41
41
 
42
+ interface StickerCollectionRecord {
43
+ collectionId: string;
44
+ name: string;
45
+ description: string;
46
+ status: "active" | "archived";
47
+ packs: StickerPackBinding[];
48
+ createdAt: string;
49
+ archivedAt: string | null;
50
+ updatedAt: string;
51
+ }
52
+ interface StickerPackBinding {
53
+ bindingId: string;
54
+ collectionId: string;
55
+ activationId: string;
56
+ packId: string;
57
+ packName: string;
58
+ packVersion: string;
59
+ status: "enabled" | "disabled";
60
+ historicalAccess: "preserve" | "revoke";
61
+ updatedAt: string | null;
62
+ }
63
+ interface RuntimeStickerRecord {
64
+ stickerId: string;
65
+ packId: string;
66
+ label: string;
67
+ emoji: string | null;
68
+ category: string | null;
69
+ animated: boolean;
70
+ variants: Array<{
71
+ name: string;
72
+ bytes: number;
73
+ }>;
74
+ score?: number;
75
+ }
76
+ interface RuntimeStickerPackRecord {
77
+ packId: string;
78
+ name: string;
79
+ version: string;
80
+ assetCount: number;
81
+ animated: boolean;
82
+ }
83
+ interface StickerRuntimeReadClient {
84
+ listPacks(): Promise<RuntimeStickerPackRecord[]>;
85
+ search(query: string, options?: {
86
+ packId?: string;
87
+ category?: string;
88
+ animated?: boolean;
89
+ limit?: number;
90
+ }): Promise<{
91
+ query: string;
92
+ items: RuntimeStickerRecord[];
93
+ total: number;
94
+ }>;
95
+ typeahead(query: string, options?: {
96
+ packId?: string;
97
+ locale?: string;
98
+ limit?: number;
99
+ }): Promise<{
100
+ query: string;
101
+ locale: string;
102
+ suggestions: Array<{
103
+ text: string;
104
+ assetCount: number;
105
+ }>;
106
+ }>;
107
+ retrieve(stickerId: string): Promise<RuntimeStickerRecord>;
108
+ resolve(stickerId: string, variant: string): Promise<Record<string, unknown>>;
109
+ }
110
+ interface HostedStickersCommandClient {
111
+ listCollections(options?: {
112
+ includeArchived?: boolean;
113
+ }): Promise<{
114
+ items: StickerCollectionRecord[];
115
+ total: number;
116
+ }>;
117
+ createCollection(params: {
118
+ name: string;
119
+ description?: string | null;
120
+ }): Promise<StickerCollectionRecord>;
121
+ getCollection(collectionId: string): Promise<StickerCollectionRecord>;
122
+ updateCollection(collectionId: string, params: {
123
+ name?: string;
124
+ description?: string | null;
125
+ status?: "active" | "archived";
126
+ }): Promise<StickerCollectionRecord>;
127
+ archiveCollection(collectionId: string): Promise<StickerCollectionRecord>;
128
+ listCollectionPacks(collectionId: string): Promise<{
129
+ items: StickerPackBinding[];
130
+ total: number;
131
+ }>;
132
+ addCollectionPack(collectionId: string, params: {
133
+ activationId: string;
134
+ }): Promise<StickerPackBinding>;
135
+ enableCollectionPack(collectionId: string, packId: string): Promise<StickerPackBinding>;
136
+ disableCollectionPack(collectionId: string, packId: string): Promise<StickerPackBinding>;
137
+ collection(collectionId: string): StickerRuntimeReadClient;
138
+ usage(): Promise<Record<string, unknown>>;
139
+ createClientToken(params: {
140
+ collectionId: string;
141
+ expiresInSeconds?: number;
142
+ scopes?: string[];
143
+ }): Promise<Record<string, unknown>>;
144
+ }
145
+
42
146
  declare const SUPPORTED_TRIGGER_EVENTS: readonly ["job.completed", "job.failed", "job.rejected"];
43
147
  type TriggerEventType = (typeof SUPPORTED_TRIGGER_EVENTS)[number];
44
148
  interface SyntheticEventOptions {
@@ -102,13 +206,22 @@ type CliJobsClient = RunJobsClient & JobsReadClient;
102
206
  interface CliClient {
103
207
  jobs: CliJobsClient;
104
208
  capabilities: CapabilitiesReadClient;
209
+ uploads?: {
210
+ resolveSource(source: string): Promise<string>;
211
+ };
105
212
  recipes?: RecipesClient;
213
+ stickers?: HostedStickersCommandClient;
106
214
  }
107
215
  interface CliDependencies {
108
216
  createClient?(options: {
109
217
  baseUrl?: string;
110
218
  apiKey?: string;
111
219
  }): CliClient;
220
+ createStickerRuntime?(options: {
221
+ accessToken: string;
222
+ collectionId: string;
223
+ baseUrl?: string;
224
+ }): StickerRuntimeReadClient;
112
225
  downloadBundle?(url: string, destination: string, options: {
113
226
  force: boolean;
114
227
  expectedSizeBytes?: number | null;