@vosjs/cli 0.8.5 → 0.9.1

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.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import { Browser } from 'playwright';
1
+ import { Browser, Page } from 'playwright';
2
+ import { CursorTrack, RecordingMeta, ProjectDoc, CursorEvent, TranscriptSegment, Digest } from '@vosjs/studio-core';
3
+ export { Digest } from '@vosjs/studio-core';
2
4
 
3
5
  interface RenderCommonOptions {
4
6
  config: Record<string, unknown>;
@@ -60,4 +62,477 @@ declare class BrowserUnavailableError extends Error {
60
62
  */
61
63
  declare function launchBrowser(): Promise<Browser>;
62
64
 
63
- export { BrowserUnavailableError, type LoadedConfig, type RenderResult, type RenderStillOptions, type RenderVideoOptions, configDuration, launchBrowser, loadVosConfig, previewPages, renderStill, renderVideo };
65
+ /** Entry point the delegation contract for @vosjs/cli: the host forwards
66
+ every non-engine verb here (`vos <verb>`; `vos voila <verb>` stays a
67
+ hidden alias until public launch). The exported `manifest` (index.ts)
68
+ tells the host which verbs exist and how to summarize them in help. */
69
+ declare function run(argv: string[]): Promise<number>;
70
+
71
+ /**
72
+ * The verb manifest of the take pipeline and the vos.so verbs — what
73
+ * `vos help` lists under the engine verbs. It kept the shape a separately
74
+ * installed plugin once handed the host (name + host range), so a script
75
+ * reading it keeps working.
76
+ */
77
+ interface PluginVerb {
78
+ name: string;
79
+ summary: string;
80
+ }
81
+ interface PluginManifest {
82
+ name: string;
83
+ /** Host versions this plugin speaks the run(argv) contract with. */
84
+ hostRange: string;
85
+ verbs: PluginVerb[];
86
+ }
87
+ declare const manifest: PluginManifest;
88
+
89
+ /**
90
+ * The action script — the declarative recipe an agent (or human) writes to
91
+ * drive a take. Small on purpose: selectors + a handful of verbs. The recorder
92
+ * executes it with humanized cursor motion and synthesizes the CursorTrack
93
+ * from its own dispatches.
94
+ */
95
+ interface ActionsFile {
96
+ /** Page to record. `--url` overrides. */
97
+ url?: string;
98
+ /** Recording viewport in CSS px (default 1280x720). */
99
+ viewport?: {
100
+ width: number;
101
+ height: number;
102
+ };
103
+ steps: ActionStep[];
104
+ }
105
+ type ActionStep = ({
106
+ do: 'wait';
107
+ ms: number;
108
+ } | {
109
+ do: 'hover';
110
+ selector: string;
111
+ ms?: number;
112
+ } | {
113
+ do: 'click';
114
+ selector: string;
115
+ } | {
116
+ do: 'type';
117
+ selector: string;
118
+ text: string;
119
+ delayMs?: number;
120
+ } | {
121
+ do: 'scroll';
122
+ dy: number;
123
+ } | {
124
+ do: 'move';
125
+ x: number;
126
+ y: number;
127
+ }
128
+ /**
129
+ * Press-move-release — real edits (drag an element on the stage canvas,
130
+ * slide a range input, move a timeline clip). Start = the selector's center
131
+ * when given, else (x, y); end = (tx, ty); eased over ms (default 700).
132
+ */
133
+ | {
134
+ do: 'drag';
135
+ selector?: string;
136
+ x?: number;
137
+ y?: number;
138
+ tx: number;
139
+ ty: number;
140
+ ms?: number;
141
+ }) & {
142
+ /**
143
+ * Optional stable identity: anchors in doc.json name a step by this
144
+ * id (else by index), so a step can move or gain neighbours across script
145
+ * edits without breaking the cut anchored to it. Unique when present.
146
+ */
147
+ id?: string;
148
+ };
149
+ /** Structural validation with actionable messages. Returns [] when valid. */
150
+ declare function validateActions(value: unknown): string[];
151
+
152
+ declare const RECORDING_NAME = "recording.webm";
153
+ interface TakePaths {
154
+ dir: string;
155
+ recording: string;
156
+ framesDir: string;
157
+ framesIndex: string;
158
+ cursor: string;
159
+ meta: string;
160
+ actions: string;
161
+ doc: string;
162
+ }
163
+ declare function takePaths(dir: string): TakePaths;
164
+ interface TakeData {
165
+ paths: TakePaths;
166
+ cursor: CursorTrack;
167
+ meta: RecordingMeta;
168
+ actions: ActionsFile | null;
169
+ doc: ProjectDoc | null;
170
+ }
171
+ /** Load a take directory; cursor+meta are required, doc/actions optional. */
172
+ declare function loadTake(dir: string): Promise<TakeData>;
173
+
174
+ interface FrameRec {
175
+ file: string;
176
+ /** ms since t0 */
177
+ tMs: number;
178
+ }
179
+ interface SkippedStep {
180
+ /** index into actions.steps */
181
+ step: number;
182
+ do: string;
183
+ selector: string;
184
+ }
185
+ /** A stretch with no screencast frames — the page pixels did not change. */
186
+ interface FreezeSpan {
187
+ /** seconds into the take */
188
+ from: number;
189
+ to: number;
190
+ ms: number;
191
+ }
192
+ interface RecordResult {
193
+ events: CursorEvent[];
194
+ frames: FrameRec[];
195
+ meta: RecordingMeta;
196
+ /** steps whose selector never became visible — the take continued without them. */
197
+ skipped: SkippedStep[];
198
+ /** the initial goto never reached networkidle (recording proceeded anyway). */
199
+ navTimeout: boolean;
200
+ /**
201
+ * Smoothness telemetry: stretches ≥400ms with no visual change. Frozen
202
+ * footage is the #1 enemy of a smooth product video — either the flow should
203
+ * keep motion in frame (animate, hover a preview, scroll) or the doc should
204
+ * trim/speed through these. freezePct = share of the take that is frozen.
205
+ */
206
+ freezes: FreezeSpan[];
207
+ freezePct: number;
208
+ /** The take reached --max-duration and stopped there; later steps did not run. */
209
+ capped: boolean;
210
+ }
211
+ interface RecordOpts {
212
+ /** Stop the capture at this many seconds (the hosted cap). */
213
+ maxDurationSeconds?: number;
214
+ }
215
+ declare function recordTake(browser: Browser, url: string, actions: ActionsFile, paths: TakePaths, log: (msg: string) => void, opts?: RecordOpts): Promise<RecordResult>;
216
+
217
+ declare function encodeRecording(browser: Browser, takeDir: string, onProgress: (fraction: number) => void): Promise<{
218
+ bytes: number;
219
+ }>;
220
+
221
+ /**
222
+ * Reuse: re-time a previous cut onto a NEW recording of the same
223
+ * script. The recorder's `meta.steps` say when each actions.json step ran
224
+ * in BOTH takes, so the old timeline maps onto the new one piecewise —
225
+ * matched step edges are the control points, and any source time in
226
+ * between interpolates. Explicit `anchor`s on camera spans resolve
227
+ * directly against the new steps and win over the map.
228
+ *
229
+ * Report, never guess: every span that
230
+ * could not re-anchor cleanly is NAMED in `flagged` with the reason in
231
+ * words — a vanished step, a skipped selector, a span clamped or dropped
232
+ * at the new take's edge. The agent fixes actions.json and re-runs; the
233
+ * verb never silently invents a cut.
234
+ *
235
+ * Pure functions, no I/O — reuse.test.ts drives them with synthetic
236
+ * step timelines; the browser gate is smoke-recut.ts.
237
+ */
238
+
239
+ interface ReuseReport {
240
+ /** spans re-timed through an explicit anchor. */
241
+ anchored: number;
242
+ /** spans re-timed through the step map (approximate by nature). */
243
+ mapped: number;
244
+ /** everything that needs a human/agent look, in words. */
245
+ flagged: string[];
246
+ }
247
+
248
+ interface PlanSummary {
249
+ doc: ProjectDoc;
250
+ zoomAuto: number;
251
+ zoomManual: number;
252
+ cursorKept: boolean;
253
+ fresh: boolean;
254
+ /** The style fields copied from `--style`'s reference, when given. */
255
+ styleFrom?: string;
256
+ styleFields?: readonly string[];
257
+ /** `--reuse`: what the re-anchor did and what it could not. */
258
+ reuse?: ReuseReport & {
259
+ from: string;
260
+ };
261
+ }
262
+ interface PlanOptions {
263
+ /**
264
+ * Style transfer at the data layer: a signed-off take whose
265
+ * zoomStyle/zoomParams/speedParams/tiltStyle/frame/cursor/cam/export are
266
+ * copied onto this take BEFORE the planners run, so the auto spans are
267
+ * proposed under the series' camera. The cut (spans, overlays, audio) is
268
+ * never touched; a field absent on the reference is removed here too.
269
+ */
270
+ style?: {
271
+ from: string;
272
+ doc: ProjectDoc;
273
+ };
274
+ /**
275
+ * The re-render loop: a PREVIOUS cut of the same script (a
276
+ * re-record's doc.prev.json) applied to this take's NEW footage. Style
277
+ * fields copy over like --style; the human's camera spans and trims
278
+ * re-time through the step map / explicit anchors; output-anchored work
279
+ * (overlays, audio, objects) carries at its output times; auto spans
280
+ * re-plan on the new cursor. The report NAMES whatever could not follow.
281
+ */
282
+ reuse?: {
283
+ from: string;
284
+ doc: ProjectDoc;
285
+ };
286
+ }
287
+ declare function planTake(dir: string, opts?: PlanOptions): Promise<PlanSummary>;
288
+
289
+ interface DigestOptions {
290
+ outDir?: string;
291
+ full?: number;
292
+ crop?: number;
293
+ /** Skip the browser passes (moments only; activity null). */
294
+ frames?: boolean;
295
+ transcript?: readonly TranscriptSegment[] | null;
296
+ /** A reference doc whose style fields are REPORTED (never applied here). */
297
+ style?: {
298
+ from: string;
299
+ doc: ProjectDoc;
300
+ } | null;
301
+ }
302
+
303
+ interface DigestResult {
304
+ file: string;
305
+ outDir: string;
306
+ digest: Digest;
307
+ bytes: number;
308
+ }
309
+ declare function digestTake(browser: Browser | null, dir: string, opts?: DigestOptions): Promise<DigestResult>;
310
+ /** Accept Whisper's `{segments:[…]}` or a bare `[{start,end,text}]`. */
311
+ declare function parseTranscript(raw: unknown): TranscriptSegment[];
312
+
313
+ interface MediaPullResult {
314
+ downloaded: {
315
+ file: string;
316
+ assetId: string;
317
+ bytes: number;
318
+ }[];
319
+ kept: string[];
320
+ }
321
+ declare function pullMedia(ctx: {
322
+ origin: string;
323
+ key: string | null;
324
+ }, dir: string, doc: ProjectDoc, log: (line: string) => void): Promise<MediaPullResult>;
325
+
326
+ interface DocOverrides {
327
+ /** raw `path=value` expressions from repeated --set. */
328
+ set?: string[];
329
+ /** --frame alias → frame.browserBar.kind. */
330
+ frame?: string;
331
+ /** --background alias → frame.backgroundMedia (kind inferred from the URL,
332
+ * or a backdrop SLUG from GET /api/backdrops, resolved by
333
+ * resolveBackdropSlug before the sync apply). */
334
+ background?: string;
335
+ /** The loop length a resolved backdrop slug brought with it. */
336
+ backgroundDuration?: number;
337
+ /** Platform origin for slug resolution (platformOrigin(flags)). */
338
+ origin?: string;
339
+ }
340
+
341
+ interface RenderTakeOptions {
342
+ width?: number;
343
+ height?: number;
344
+ fps?: number;
345
+ format?: 'webm' | 'mp4';
346
+ /** Concurrent chunk renders (timeline sharding); 1 = single-flight. */
347
+ parallel?: number;
348
+ /** OUTPUT-time subrange [start, end) seconds — spot-check a doc edit cheaply. */
349
+ range?: [number, number];
350
+ /** Draft mode: half resolution + low bitrate, for iteration only. */
351
+ draft?: boolean;
352
+ /** Encoder bitrate override (a destination's byte ceiling as a budget). */
353
+ bitrate?: number;
354
+ /** In-memory doc overrides (--set / --frame / --background); lint-gated. */
355
+ overrides?: DocOverrides;
356
+ onPhase?: (phase: string) => void;
357
+ onProgress?: (fraction: number) => void;
358
+ }
359
+ interface RenderTakeResult {
360
+ out: string;
361
+ bytes: number;
362
+ width: number;
363
+ height: number;
364
+ fps: number;
365
+ duration: number;
366
+ zoomSpans: number;
367
+ clicks: number;
368
+ /** Number of chunks rendered (1 unless --parallel raised it). */
369
+ chunks: number;
370
+ /** An audio track was mixed + muxed (doc.audio clips / mic). */
371
+ audio: boolean;
372
+ }
373
+ declare function renderTake(browser: Browser, dir: string, outFile: string, opts: RenderTakeOptions): Promise<RenderTakeResult>;
374
+
375
+ interface RenderAnimationOptions {
376
+ /** Compiled vos animation code (module exporting initVos). */
377
+ animationCode: string;
378
+ /** Directory the page server roots at; chunk artifacts land here too. */
379
+ workDir: string;
380
+ /** Source video file name inside workDir (studio takes), served → blob URL. */
381
+ videoFile?: string;
382
+ /** Token inside animationCode replaced with the video blob URL. */
383
+ videoToken?: string;
384
+ width: number;
385
+ height: number;
386
+ fps: number;
387
+ duration: number;
388
+ format: 'webm' | 'mp4';
389
+ /** Max simultaneous chunk pages; 1 = single-flight (no concat). */
390
+ parallel?: number;
391
+ /**
392
+ * First GLOBAL frame to render (a range render: seek time starts here while
393
+ * output timestamps stay zero-based). duration then covers the range only.
394
+ */
395
+ frameOffset?: number;
396
+ /** Encoder bitrate override (draft renders); default 10 Mbps. */
397
+ bitrate?: number;
398
+ /**
399
+ * Mix + mux an audio track in the SAME render (single-flight only — audio
400
+ * stays out of chunks by design, mirroring the cloud single-flight path).
401
+ * `producerCode` defines window.__vosAudioProducer__ (render-core);
402
+ * `data` is the lowered composition data (videoToken replaced in-page).
403
+ * `duration` is the FULL timeline — the producer builds the whole mix and
404
+ * the page slices its own frame window, so a range render keeps audio.
405
+ */
406
+ audio?: {
407
+ producerCode: string;
408
+ data: unknown;
409
+ duration: number;
410
+ };
411
+ onProgress?: (fraction: number) => void;
412
+ }
413
+ interface RenderAnimationResult {
414
+ bytes: Uint8Array;
415
+ totalFrames: number;
416
+ /** Number of chunks actually rendered (1 = single-flight). */
417
+ chunks: number;
418
+ }
419
+ declare function renderAnimation(browser: Browser, opts: RenderAnimationOptions): Promise<RenderAnimationResult>;
420
+
421
+ /** One agent-browser command with its result: the `batch` record shape. */
422
+ interface AgentBrowserRecord {
423
+ command: string[] | string;
424
+ /** Single-command `--json` lines carry `data`; batch records carry `result`. */
425
+ data?: unknown;
426
+ result?: unknown;
427
+ success?: boolean;
428
+ error?: string | null;
429
+ }
430
+ interface ConvertOptions {
431
+ /** Overrides the walk's first `open`. */
432
+ url?: string;
433
+ /** Overrides the walk's `set viewport`. */
434
+ viewport?: {
435
+ width: number;
436
+ height: number;
437
+ };
438
+ }
439
+ interface ConvertResult {
440
+ actions: ActionsFile;
441
+ /** Every command that became no step, or a different step, with its line. */
442
+ notes: string[];
443
+ /** Commands that produced a step. */
444
+ steps: number;
445
+ /** Reads and session verbs: nothing to replay. */
446
+ ignored: number;
447
+ /** Actions the recorder cannot follow, or that failed in the walk. */
448
+ skipped: number;
449
+ }
450
+ /** Parse a steps.jsonl (or a batch array) into records; malformed lines are named. */
451
+ declare function parseAgentBrowserLog(text: string): {
452
+ records: AgentBrowserRecord[];
453
+ problems: string[];
454
+ };
455
+ /** Shell-style split for a `command` kept as one string: quotes group, backslash escapes. */
456
+ declare function splitCommand(command: string): string[];
457
+ /** The walk, as steps the recorder can replay. Pure. */
458
+ declare function convertAgentBrowser(records: AgentBrowserRecord[], opts?: ConvertOptions): ConvertResult;
459
+
460
+ interface TakeServer {
461
+ base: string;
462
+ close: () => void;
463
+ }
464
+ /**
465
+ * Static server over the take dir + generated pages + a POST /save endpoint
466
+ * the in-page encoder/renderer uses to hand bytes back to node. The recording
467
+ * is fetched → blob URL (seekable), but a take-dir VIDEO BACKGROUND
468
+ * (frame.backgroundMedia.key = "/bg.webm") is loaded directly by ON_FRAME and
469
+ * seeked during export — so this serves Range/206 (an HTMLVideoElement hangs
470
+ * forever seeking a naive 200-only static server).
471
+ */
472
+ declare function startTakeServer(rootDir: string, pages: Record<string, string>): Promise<TakeServer>;
473
+ /** Poll a capture/encode page for window.__done / __error / __progress. */
474
+ declare function waitForPageDone(page: Page, label: string, onProgress: (fraction: number) => void, timeoutMs: number): Promise<Record<string, unknown>>;
475
+
476
+ /**
477
+ * Origin resolution: --origin (or legacy --api) → VOS_ORIGIN → legacy
478
+ * VOS_API_BASE (which historically carried a trailing /api) → https://vos.so.
479
+ * Every shape converges on a bare origin; paths below carry the /api prefix.
480
+ */
481
+ declare function platformOrigin(flags?: {
482
+ origin?: string;
483
+ api?: string;
484
+ }): string;
485
+ /**
486
+ * Accepts a bare vos id, a watch URL (vos.so/vos/{id}), an embed URL
487
+ * (/embed/vos/{id}), or a studio/stage URL (?vos={id}).
488
+ */
489
+ declare function parseVosId(input: string): string;
490
+ /**
491
+ * The full documented ladder: explicit --key → VOS_API_KEY → the first line
492
+ * of ~/.config/vos/credentials. A vos_rg_ remix grant is just a key here.
493
+ * Returns null when nothing resolves — callers decide whether auth is needed.
494
+ */
495
+ declare function resolveCredential(explicit?: string): string | null;
496
+ interface ApiResult {
497
+ status: number;
498
+ body: Record<string, unknown>;
499
+ }
500
+ declare function apiJson(origin: string, path: string, init?: {
501
+ method?: string;
502
+ key?: string | null;
503
+ body?: unknown;
504
+ /** Raw request body (uploads) — used verbatim, with `headers`. */
505
+ raw?: Uint8Array;
506
+ headers?: Record<string, string>;
507
+ }): Promise<ApiResult>;
508
+ /** Human-readable error line for a failed platform response. Never echoes credentials. */
509
+ declare function apiError(what: string, r: ApiResult): string;
510
+ interface SyncState {
511
+ vosId: string;
512
+ /** The hosted version this directory is based on — the next push's base. */
513
+ versionId: string | null;
514
+ pushedAt?: string;
515
+ title?: string;
516
+ slug?: string;
517
+ remixOfId?: string;
518
+ }
519
+ /**
520
+ * vos.json → legacy push.json ({vosId, versionId}) → legacy meta.json
521
+ * ({id, currentVersionId} — guarded on a string `id` so a take dir's
522
+ * RecordingMeta meta.json is never misread as sync state).
523
+ */
524
+ declare function readSyncState(dir: string): SyncState | null;
525
+ /** Merge-writes vos.json; the legacy files are left alone (read-only compat). */
526
+ declare function writeSyncState(dir: string, patch: Partial<SyncState> & {
527
+ vosId: string;
528
+ }): SyncState;
529
+ interface VersionChange {
530
+ versionId?: string;
531
+ versionNumber?: number;
532
+ origin?: string;
533
+ label?: string | null;
534
+ note?: string | null;
535
+ summary?: string;
536
+ }
537
+
538
+ export { type ActionStep, type ActionsFile, type AgentBrowserRecord, BrowserUnavailableError, type ConvertOptions, type ConvertResult, type DigestOptions, type DigestResult, type LoadedConfig, RECORDING_NAME, type RenderAnimationOptions, type RenderAnimationResult, type RenderResult, type RenderStillOptions, type RenderTakeOptions, type RenderTakeResult, type RenderVideoOptions, type SyncState, type TakeData, type TakePaths, type TakeServer, type VersionChange, apiError, apiJson, configDuration, convertAgentBrowser, digestTake, encodeRecording, launchBrowser, loadTake, loadVosConfig, manifest, parseAgentBrowserLog, parseTranscript, parseVosId, planTake, platformOrigin, previewPages, pullMedia, readSyncState, recordTake, renderAnimation, renderStill, renderTake, renderVideo, resolveCredential, run, splitCommand, startTakeServer, takePaths, validateActions, waitForPageDone, writeSyncState };
package/dist/index.js CHANGED
@@ -1,20 +1,78 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- BrowserUnavailableError,
4
3
  configDuration,
5
- launchBrowser,
6
4
  loadVosConfig,
7
5
  previewPages,
8
6
  renderStill,
9
7
  renderVideo
10
- } from "./chunk-3VPLPEMZ.js";
8
+ } from "./chunk-X2BKHZ56.js";
9
+ import {
10
+ RECORDING_NAME,
11
+ apiError,
12
+ apiJson,
13
+ convertAgentBrowser,
14
+ digestTake,
15
+ encodeRecording,
16
+ loadTake,
17
+ parseAgentBrowserLog,
18
+ parseTranscript,
19
+ parseVosId,
20
+ planTake,
21
+ platformOrigin,
22
+ pullMedia,
23
+ readSyncState,
24
+ recordTake,
25
+ renderAnimation,
26
+ renderTake,
27
+ resolveCredential,
28
+ run,
29
+ splitCommand,
30
+ startTakeServer,
31
+ takePaths,
32
+ validateActions,
33
+ waitForPageDone,
34
+ writeSyncState
35
+ } from "./chunk-74MSNLT2.js";
36
+ import {
37
+ BrowserUnavailableError,
38
+ launchBrowser
39
+ } from "./chunk-A2VSDK3C.js";
40
+ import {
41
+ manifest
42
+ } from "./chunk-5BFGODBI.js";
11
43
  export {
12
44
  BrowserUnavailableError,
45
+ RECORDING_NAME,
46
+ apiError,
47
+ apiJson,
13
48
  configDuration,
49
+ convertAgentBrowser,
50
+ digestTake,
51
+ encodeRecording,
14
52
  launchBrowser,
53
+ loadTake,
15
54
  loadVosConfig,
55
+ manifest,
56
+ parseAgentBrowserLog,
57
+ parseTranscript,
58
+ parseVosId,
59
+ planTake,
60
+ platformOrigin,
16
61
  previewPages,
62
+ pullMedia,
63
+ readSyncState,
64
+ recordTake,
65
+ renderAnimation,
17
66
  renderStill,
18
- renderVideo
67
+ renderTake,
68
+ renderVideo,
69
+ resolveCredential,
70
+ run,
71
+ splitCommand,
72
+ startTakeServer,
73
+ takePaths,
74
+ validateActions,
75
+ waitForPageDone,
76
+ writeSyncState
19
77
  };
20
78
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ manifest
4
+ } from "./chunk-5BFGODBI.js";
5
+ export {
6
+ manifest
7
+ };
8
+ //# sourceMappingURL=manifest-3LIL5M3F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ run
4
+ } from "./chunk-74MSNLT2.js";
5
+ import "./chunk-A2VSDK3C.js";
6
+ export {
7
+ run
8
+ };
9
+ //# sourceMappingURL=run-I2XSZAWI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@vosjs/cli",
3
- "version": "0.8.5",
4
- "description": "Command line for the vos programmatic video engine render deterministic videos and stills from vos configs, headlessly, from your terminal or an AI agent.",
3
+ "version": "0.9.1",
4
+ "description": "The vos CLI: record the real product from a scripted browser flow, auto-zoom from the cursor track, cut as data in doc.json, render deterministic video and stills, deliver a release's media per destination spec, and sync with vos.so. One binary, every verb, MIT.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "vosso",
8
- "homepage": "https://vos.so/engine",
8
+ "homepage": "https://vos.so/cli",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/vosjs/vos.git",
@@ -23,7 +23,11 @@
23
23
  "headless",
24
24
  "agent",
25
25
  "animation",
26
- "three"
26
+ "three",
27
+ "screen-recording",
28
+ "product-video",
29
+ "demo",
30
+ "auto-zoom"
27
31
  ],
28
32
  "bin": {
29
33
  "vos": "./dist/cli.js"
@@ -37,13 +41,20 @@
37
41
  }
38
42
  },
39
43
  "files": [
40
- "dist"
44
+ "dist",
45
+ "schema"
41
46
  ],
42
47
  "sideEffects": false,
43
48
  "dependencies": {
49
+ "mediabunny": "^1.27.3",
44
50
  "playwright": "^1.49.0",
45
51
  "@vosjs/core": "^0.23.1",
52
+ "@vosjs/editor": "^1.3.0",
53
+ "@vosjs/render-core": "^0.1.0",
54
+ "@vosjs/shared": "^0.1.0",
46
55
  "@vosjs/elements": "^0.8.0",
56
+ "@vosjs/studio-core": "^0.1.0",
57
+ "@vosjs/timeline": "^0.4.0",
47
58
  "@vosjs/tween": "^0.8.1"
48
59
  },
49
60
  "devDependencies": {