@vosjs/cli 0.8.5 → 0.9.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.
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/browser.ts
4
+ import { chromium } from "playwright";
5
+ var BrowserUnavailableError = class extends Error {
6
+ constructor(cause) {
7
+ super(
8
+ `Could not launch a Chromium-family browser (${cause}).
9
+ Fixes, in order of preference:
10
+ 1. Install Google Chrome (used automatically), or
11
+ 2. npx playwright install chromium, or
12
+ 3. Set VOS_BROWSER_PATH to a Chrome/Chromium executable.`
13
+ );
14
+ }
15
+ };
16
+ async function launchBrowser() {
17
+ const explicit = process.env.VOS_BROWSER_PATH;
18
+ if (explicit) {
19
+ return chromium.launch({ executablePath: explicit }).catch((e) => {
20
+ throw new BrowserUnavailableError(
21
+ `VOS_BROWSER_PATH failed: ${e.message}`
22
+ );
23
+ });
24
+ }
25
+ try {
26
+ return await chromium.launch({ channel: "chrome" });
27
+ } catch {
28
+ try {
29
+ return await chromium.launch();
30
+ } catch (e) {
31
+ throw new BrowserUnavailableError(
32
+ e.message.split("\n")[0] ?? "unknown"
33
+ );
34
+ }
35
+ }
36
+ }
37
+
38
+ export {
39
+ BrowserUnavailableError,
40
+ launchBrowser
41
+ };
42
+ //# sourceMappingURL=chunk-A2VSDK3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/browser.ts"],"sourcesContent":["import { chromium } from 'playwright'\nimport type { Browser } from 'playwright'\n\nexport class BrowserUnavailableError extends Error {\n constructor(cause: string) {\n super(\n `Could not launch a Chromium-family browser (${cause}).\\n` +\n `Fixes, in order of preference:\\n` +\n ` 1. Install Google Chrome (used automatically), or\\n` +\n ` 2. npx playwright install chromium, or\\n` +\n ` 3. Set VOS_BROWSER_PATH to a Chrome/Chromium executable.`,\n )\n }\n}\n\n/**\n * Launch headless Chromium: explicit VOS_BROWSER_PATH → system Chrome\n * (no download needed) → Playwright's bundled Chromium.\n */\nexport async function launchBrowser(): Promise<Browser> {\n const explicit = process.env.VOS_BROWSER_PATH\n if (explicit) {\n return chromium.launch({ executablePath: explicit }).catch((e) => {\n throw new BrowserUnavailableError(\n `VOS_BROWSER_PATH failed: ${(e as Error).message}`,\n )\n })\n }\n try {\n return await chromium.launch({ channel: 'chrome' })\n } catch {\n try {\n return await chromium.launch()\n } catch (e) {\n throw new BrowserUnavailableError(\n (e as Error).message.split('\\n')[0] ?? 'unknown',\n )\n }\n }\n}\n"],"mappings":";;;AAAA,SAAS,gBAAgB;AAGlB,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACjD,YAAY,OAAe;AACzB;AAAA,MACE,+CAA+C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,IAKtD;AAAA,EACF;AACF;AAMA,eAAsB,gBAAkC;AACtD,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,UAAU;AACZ,WAAO,SAAS,OAAO,EAAE,gBAAgB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM;AAChE,YAAM,IAAI;AAAA,QACR,4BAA6B,EAAY,OAAO;AAAA,MAClD;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI;AACF,WAAO,MAAM,SAAS,OAAO,EAAE,SAAS,SAAS,CAAC;AAAA,EACpD,QAAQ;AACN,QAAI;AACF,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,SAAS,GAAG;AACV,YAAM,IAAI;AAAA,QACP,EAAY,QAAQ,MAAM,IAAI,EAAE,CAAC,KAAK;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -99,41 +99,6 @@ function configDuration(config) {
99
99
  return typeof d === "number" && Number.isFinite(d) && d > 0 ? d : void 0;
100
100
  }
101
101
 
102
- // src/browser.ts
103
- import { chromium } from "playwright";
104
- var BrowserUnavailableError = class extends Error {
105
- constructor(cause) {
106
- super(
107
- `Could not launch a Chromium-family browser (${cause}).
108
- Fixes, in order of preference:
109
- 1. Install Google Chrome (used automatically), or
110
- 2. npx playwright install chromium, or
111
- 3. Set VOS_BROWSER_PATH to a Chrome/Chromium executable.`
112
- );
113
- }
114
- };
115
- async function launchBrowser() {
116
- const explicit = process.env.VOS_BROWSER_PATH;
117
- if (explicit) {
118
- return chromium.launch({ executablePath: explicit }).catch((e) => {
119
- throw new BrowserUnavailableError(
120
- `VOS_BROWSER_PATH failed: ${e.message}`
121
- );
122
- });
123
- }
124
- try {
125
- return await chromium.launch({ channel: "chrome" });
126
- } catch {
127
- try {
128
- return await chromium.launch();
129
- } catch (e) {
130
- throw new BrowserUnavailableError(
131
- e.message.split("\n")[0] ?? "unknown"
132
- );
133
- }
134
- }
135
- }
136
-
137
102
  // src/render.ts
138
103
  import { compileVosConfig } from "@vosjs/core";
139
104
  import { generateRenderTemplate } from "@vosjs/core/runtime";
@@ -294,10 +259,8 @@ export {
294
259
  numFlag,
295
260
  loadVosConfig,
296
261
  configDuration,
297
- BrowserUnavailableError,
298
- launchBrowser,
299
262
  renderVideo,
300
263
  renderStill,
301
264
  previewPages
302
265
  };
303
- //# sourceMappingURL=chunk-3VPLPEMZ.js.map
266
+ //# sourceMappingURL=chunk-X2BKHZ56.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/args.ts","../src/loadConfig.ts","../src/render.ts"],"sourcesContent":["/**\n * Minimal argv parser — positionals + `--flag value` / `--flag=value` /\n * boolean flags. Deliberately tiny: the CLI has a small, stable surface and\n * agents benefit from predictable, dependency-free parsing.\n */\nexport interface ParsedArgs {\n positionals: string[]\n flags: Record<string, string | true>\n}\n\nexport class UsageError extends Error {}\n\nexport function parseArgs(\n argv: string[],\n booleanFlags: ReadonlySet<string>,\n): ParsedArgs {\n const positionals: string[] = []\n const flags: Record<string, string | true> = {}\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]\n if (arg === '--') {\n positionals.push(...argv.slice(i + 1))\n break\n }\n if (arg.startsWith('--')) {\n const eq = arg.indexOf('=')\n if (eq !== -1) {\n flags[arg.slice(2, eq)] = arg.slice(eq + 1)\n continue\n }\n const name = arg.slice(2)\n if (booleanFlags.has(name)) {\n flags[name] = true\n continue\n }\n const next = argv[i + 1]\n if (next === undefined || next.startsWith('--')) {\n throw new UsageError(`--${name} expects a value`)\n }\n flags[name] = next\n i++\n continue\n }\n positionals.push(arg)\n }\n return { positionals, flags }\n}\n\nexport function numFlag(\n flags: ParsedArgs['flags'],\n name: string,\n fallback: number,\n): number {\n const v = flags[name]\n if (v === undefined) return fallback\n const n = Number(v)\n if (!Number.isFinite(n))\n throw new UsageError(`--${name} expects a number, got \"${String(v)}\"`)\n return n\n}\n","import { readFile } from 'node:fs/promises'\nimport {\n CURRENT_CONFIG_VERSION,\n migrateConfig,\n vosConfigJsonSchema,\n} from '@vosjs/core'\nimport { UsageError } from './args'\n\nexport interface LoadedConfig {\n config: Record<string, unknown>\n warnings: string[]\n}\n\n/**\n * Load a VosConfigJson from a file path or http(s) URL, unwrap API `{ config }`\n * envelopes, migrate old versions, and validate against the schema.\n */\nexport async function loadVosConfig(source: string): Promise<LoadedConfig> {\n const warnings: string[] = []\n let raw: string\n if (/^https?:\\/\\//.test(source)) {\n const res = await fetch(source)\n if (!res.ok) throw new Error(`fetch ${source} → ${res.status}`)\n raw = await res.text()\n } else {\n raw = await readFile(source, 'utf8')\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (e) {\n throw new UsageError(`${source} is not valid JSON: ${(e as Error).message}`)\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new UsageError(`${source} does not contain a JSON object`)\n }\n\n // API endpoints wrap the config: { config: {...} }.\n let obj = parsed as Record<string, unknown>\n if (\n typeof obj.config === 'object' &&\n obj.config !== null &&\n !('createTimeline' in obj)\n ) {\n obj = obj.config as Record<string, unknown>\n warnings.push('unwrapped { config } envelope')\n }\n\n const version = obj.version\n const migrated = migrateConfig(obj)\n if (version === undefined) {\n // Plays fine (the stamp happens above), but a storer refuses it.\n warnings.push(\n `config declares no \"version\". Add \"version\": ${CURRENT_CONFIG_VERSION} before pushing it.`,\n )\n } else if (version !== CURRENT_CONFIG_VERSION) {\n warnings.push(\n `migrated config v${String(version)} to v${CURRENT_CONFIG_VERSION}`,\n )\n }\n\n const check = vosConfigJsonSchema.safeParse(migrated)\n if (!check.success) {\n const issues = check.error.issues\n .slice(0, 5)\n .map((i) => ` ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n')\n throw new UsageError(`invalid vos config:\\n${issues}`)\n }\n\n return { config: migrated, warnings }\n}\n\n/** Best-effort duration from the config (seconds). */\nexport function configDuration(\n config: Record<string, unknown>,\n): number | undefined {\n const d = config.duration\n return typeof d === 'number' && Number.isFinite(d) && d > 0 ? d : undefined\n}\n","import { compileVosConfig } from '@vosjs/core'\nimport { generateRenderTemplate } from '@vosjs/core/runtime'\nimport { elementsBundleCode } from '@vosjs/elements/bundle'\nimport { tweenRuntimeCode } from '@vosjs/tween/bundle'\nimport type { Browser, Page } from 'playwright'\n\n/** Fake secure origin the render page is served from (WebCodecs needs one). */\nconst RENDER_ORIGIN = 'https://vos-cli.render'\n\nexport interface RenderCommonOptions {\n config: Record<string, unknown>\n width: number\n height: number\n /** Phase callback for progress reporting. */\n onPhase?: (phase: string) => void\n}\n\nexport interface RenderVideoOptions extends RenderCommonOptions {\n fps: number\n /** Output duration in seconds. */\n duration: number\n format: 'webm' | 'mp4'\n}\n\nexport interface RenderStillOptions extends RenderCommonOptions {\n /** Seek time for the captured frame, seconds. */\n time: number\n}\n\nexport interface RenderResult {\n bytes: Uint8Array\n mimeType: string\n}\n\ninterface RenderComplete {\n success: boolean\n data?: string\n error?: string\n}\n\nfunction compile(config: Record<string, unknown>): string {\n return compileVosConfig(config as never, { tweenEngine: 'vos' })\n}\n\nasync function runCapturePage(\n browser: Browser,\n html: string,\n opts: { width: number; height: number; timeoutMs: number },\n): Promise<RenderComplete> {\n const context = await browser.newContext({\n viewport: { width: opts.width, height: opts.height },\n })\n const page: Page = await context.newPage()\n const errors: string[] = []\n page.on('console', (m) => {\n if (m.type() === 'error') errors.push(m.text())\n })\n try {\n await page.route(`${RENDER_ORIGIN}/**`, (route) =>\n route.fulfill({ status: 200, contentType: 'text/html', body: html }),\n )\n await page.goto(`${RENDER_ORIGIN}/render`, {\n waitUntil: 'domcontentloaded',\n })\n const start = Date.now()\n for (;;) {\n const done = (await page.evaluate(\n 'window.__renderComplete ?? null',\n )) as RenderComplete | null\n if (done) return done\n if (Date.now() - start > opts.timeoutMs) {\n return {\n success: false,\n error: `render timed out after ${Math.round(opts.timeoutMs / 1000)}s${\n errors.length\n ? ` (page errors: ${errors.slice(0, 3).join(' | ')})`\n : ''\n }`,\n }\n }\n await new Promise((r) => setTimeout(r, 400))\n }\n } finally {\n await context.close()\n }\n}\n\nfunction decodeDataUrl(dataUrl: string): RenderResult {\n const m = /^data:([^;,]+);base64,(.*)$/s.exec(dataUrl)\n if (!m) throw new Error('capture page returned an unexpected payload')\n return { bytes: Uint8Array.from(Buffer.from(m[2], 'base64')), mimeType: m[1] }\n}\n\n/** Render a vos config to a video (WebM/MP4) in a headless browser. */\nexport async function renderVideo(\n browser: Browser,\n opts: RenderVideoOptions,\n): Promise<RenderResult> {\n opts.onPhase?.('compile')\n const code = compile(opts.config)\n const html = generateRenderTemplate(code, {\n mode: 'capture-video',\n capture: {\n width: opts.width,\n height: opts.height,\n duration: opts.duration,\n fps: opts.fps,\n format: opts.format,\n },\n elementsBundleCode,\n tweenEngine: 'vos',\n tweenBundleCode: tweenRuntimeCode,\n })\n opts.onPhase?.('render')\n // Generous ceiling: startup + CDN module fetch + ~4× realtime per frame batch.\n const timeoutMs = 90_000 + opts.duration * opts.fps * 400\n const done = await runCapturePage(browser, html, {\n width: opts.width,\n height: opts.height,\n timeoutMs,\n })\n if (!done.success || !done.data)\n throw new Error(done.error ?? 'render failed')\n return decodeDataUrl(done.data)\n}\n\n/** Render a single frame of a vos config to an image in a headless browser. */\nexport async function renderStill(\n browser: Browser,\n opts: RenderStillOptions,\n): Promise<RenderResult> {\n opts.onPhase?.('compile')\n const code = compile(opts.config)\n const html = generateRenderTemplate(code, {\n mode: 'capture-thumbnail',\n capture: {\n width: opts.width,\n height: opts.height,\n duration: Math.max(1, opts.time + 1),\n fps: 30,\n thumbnailTime: opts.time,\n },\n elementsBundleCode,\n tweenEngine: 'vos',\n tweenBundleCode: tweenRuntimeCode,\n })\n opts.onPhase?.('render')\n const done = await runCapturePage(browser, html, {\n width: opts.width,\n height: opts.height,\n timeoutMs: 120_000,\n })\n if (!done.success || !done.data)\n throw new Error(done.error ?? 'still render failed')\n return decodeDataUrl(done.data)\n}\n\nexport interface PreviewPages {\n /** Host page: iframes the player and drives it over the bridge. */\n hostHtml: string\n /** The engine's playback-mode player (waits for a LOAD postMessage). */\n playerHtml: string\n}\n\n/**\n * Pages for `vos preview`. The playback template is the iframe HALF of the\n * player bridge — it renders nothing until a host posts `LOAD`, so the CLI\n * serves a minimal host page that sends `LOAD { code, autoplay }` and shows\n * a transport line (time / duration, click to play-pause).\n */\nexport function previewPages(config: Record<string, unknown>): PreviewPages {\n const code = compile(config)\n const playerHtml = generateRenderTemplate(code, {\n mode: 'playback',\n elementsBundleCode,\n tweenEngine: 'vos',\n tweenBundleCode: tweenRuntimeCode,\n })\n const codeJson = JSON.stringify(code).replace(/<\\//g, '<\\\\/')\n const hostHtml = `<!doctype html><html><head><meta charset=\"utf-8\"><title>vos preview</title>\n<style>\n html,body{margin:0;height:100%;background:#000;overflow:hidden}\n iframe{position:absolute;inset:0;width:100%;height:100%;border:0}\n #cover{position:fixed;inset:0;cursor:pointer}\n #hud{position:fixed;left:12px;bottom:10px;color:#fff;opacity:.75;font:12px/1.4 ui-monospace,monospace;\n background:rgba(0,0,0,.45);padding:4px 8px;border-radius:6px;pointer-events:none}\n</style></head><body>\n<iframe id=\"p\" src=\"/player\" allow=\"autoplay\"></iframe>\n<div id=\"cover\"></div>\n<div id=\"hud\">loading…</div>\n<script>\n const code = ${codeJson}\n const frame = document.getElementById('p')\n const hud = document.getElementById('hud')\n let ready = false\n let playing = true\n const post = (msg) => frame.contentWindow && frame.contentWindow.postMessage(msg, '*')\n const load = () => post({ type: 'LOAD', code, autoplay: true })\n window.addEventListener('message', (e) => {\n const msg = e.data || {}\n if (msg.type === 'BRIDGE_READY') load()\n if (msg.type === 'READY') { ready = true; hud.textContent = '0.0 / ' + msg.duration.toFixed(1) + 's — click to pause' }\n if (msg.type === 'UPDATE') hud.textContent = msg.time.toFixed(1) + ' / ' + msg.duration.toFixed(1) + 's — click to ' + (playing ? 'pause' : 'play')\n if (msg.type === 'ERROR') hud.textContent = 'error: ' + msg.error\n })\n // Belt and braces: if BRIDGE_READY raced the host, retry LOAD until READY.\n let tries = 0\n const iv = setInterval(() => {\n if (ready || tries++ > 20) return clearInterval(iv)\n load()\n }, 400)\n // The iframe swallows clicks — capture them on an overlay above it.\n document.getElementById('cover').addEventListener('click', () => {\n if (!ready) return\n playing = !playing\n post({ type: playing ? 'PLAY' : 'PAUSE' })\n hud.textContent = hud.textContent.replace(/click to (pause|play)/, 'click to ' + (playing ? 'pause' : 'play'))\n })\n</script></body></html>`\n return { hostHtml, playerHtml }\n}\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- BrowserUnavailableError,
4
3
  UsageError,
5
4
  configDuration,
6
- launchBrowser,
7
5
  loadVosConfig,
8
6
  numFlag,
9
7
  parseArgs,
10
8
  previewPages,
11
9
  renderStill,
12
10
  renderVideo
13
- } from "./chunk-3VPLPEMZ.js";
11
+ } from "./chunk-X2BKHZ56.js";
12
+ import {
13
+ BrowserUnavailableError,
14
+ launchBrowser
15
+ } from "./chunk-A2VSDK3C.js";
14
16
 
15
17
  // src/cli.ts
16
18
  import { readFile, writeFile } from "fs/promises";
@@ -198,12 +200,6 @@ Engine verbs (local, no account, no network beyond the render page's CDN deps)
198
200
  vos preview <config.json|url> [--port 0]
199
201
  vos versions [--json]
200
202
  `;
201
- var HELP_PLUGIN_HINT = `
202
- Everything else \u2014 the take pipeline (screen recordings in, product video out)
203
- and the vos.so platform verbs (fetch/push/pull/login) \u2014 ships as a plugin:
204
- npm i -D @vosso/vos-plugin
205
- Installed plugin verbs appear here and run as plain \`vos <verb>\`.
206
- `;
207
203
  var HELP_CONVENTIONS = `
208
204
  Conventions
209
205
  Results go to stdout; logs go to stderr. --json switches stdout to NDJSON
@@ -389,17 +385,16 @@ async function cmdVersions(argv) {
389
385
  "@vosjs/core",
390
386
  "@vosjs/elements",
391
387
  "@vosjs/tween",
388
+ "@vosjs/editor",
389
+ "@vosjs/timeline",
390
+ "@vosjs/studio-core",
391
+ "@vosjs/render-core",
392
+ "@vosjs/shared",
393
+ "mediabunny",
392
394
  "playwright"
393
395
  ]) {
394
396
  versions[name] = packageVersion(name) ?? "(not found)";
395
397
  }
396
- for (const name of PLUGIN_PACKAGES) {
397
- const v = packageVersion(name);
398
- if (v) {
399
- versions[name] = v;
400
- break;
401
- }
402
- }
403
398
  if (r.json) r.done({ versions }, "");
404
399
  else
405
400
  for (const [k, v] of Object.entries(versions))
@@ -488,75 +483,24 @@ async function cmdCheck(argv) {
488
483
  }
489
484
  return result.ok ? EXIT_OK : EXIT_ERROR;
490
485
  }
491
- var PLUGIN_PACKAGES = ["@vosso/vos-plugin", "@vosso/cli", "@vosso/voila-cli"];
492
- async function loadPlugin() {
493
- for (const name of PLUGIN_PACKAGES) {
494
- let mod;
495
- try {
496
- mod = await import(name);
497
- } catch {
498
- continue;
499
- }
500
- if (typeof mod.run === "function") return mod;
501
- }
502
- return null;
503
- }
504
- function versionAtLeast(version, min) {
505
- const pa = version.split(".").map((n) => Number.parseInt(n, 10));
506
- const pb = min.split(".").map((n) => Number.parseInt(n, 10));
507
- for (let i = 0; i < 3; i++) {
508
- const a = pa[i] ?? 0;
509
- const b = pb[i] ?? 0;
510
- if (a !== b) return a > b;
511
- }
512
- return true;
513
- }
514
486
  async function delegate(argv, viaAlias = false) {
515
- const plugin = await loadPlugin();
516
- if (!plugin?.run) {
517
- process.stderr.write(
518
- `vos ${argv[0] ?? ""}: not an engine verb.
519
- The take pipeline and the vos.so platform verbs (create, record, plan,
520
- frames, open, validate, fetch, push, pull, login) ship as a plugin:
521
- npm i -D @vosso/vos-plugin
522
- then re-run: vos ${argv.join(" ")}
523
- (If this was a typo, run: vos help)
524
- `
525
- );
526
- return EXIT_ERROR;
527
- }
528
- const range = plugin.manifest?.hostRange;
529
- const min = range ? /^>=\s*(\d+\.\d+\.\d+)/.exec(range)?.[1] : void 0;
530
- if (min && !versionAtLeast(ownVersion(), min)) {
531
- process.stderr.write(
532
- `note: the installed plugin expects @vosjs/cli ${range} (this is ${ownVersion()}) \u2014 upgrade with: npm i -D @vosjs/cli@latest
533
- `
534
- );
535
- }
487
+ const { run } = await import("./run-22RIQESF.js");
536
488
  if (viaAlias && argv[0]) {
537
489
  process.stderr.write(
538
490
  `note: "vos voila ${argv[0]}" is now "vos ${argv[0]}".
539
491
  `
540
492
  );
541
493
  }
542
- return await plugin.run(argv);
494
+ return await run(argv);
543
495
  }
544
496
  async function printHelp() {
545
497
  process.stdout.write(HELP_ENGINE);
546
- const plugin = await loadPlugin();
547
- const verbs = plugin?.manifest?.verbs;
548
- if (verbs?.length) {
549
- const label = plugin?.manifest?.name ?? "vos plugin";
550
- process.stdout.write(`
551
- Platform + take pipeline (via ${label})
498
+ const { manifest } = await import("./manifest-3LIL5M3F.js");
499
+ process.stdout.write("\nTake pipeline + vos.so verbs\n");
500
+ for (const v of manifest.verbs) {
501
+ if (v.name === "render") continue;
502
+ process.stdout.write(` vos ${v.name.padEnd(8)} ${v.summary}
552
503
  `);
553
- for (const v of verbs) {
554
- if (v.name === "render") continue;
555
- process.stdout.write(` vos ${v.name.padEnd(8)} ${v.summary}
556
- `);
557
- }
558
- } else {
559
- process.stdout.write(HELP_PLUGIN_HINT);
560
504
  }
561
505
  process.stdout.write(HELP_CONVENTIONS);
562
506
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/output.ts","../src/check.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { basename, dirname, join } from 'node:path'\nimport { createServer } from 'node:http'\nimport { createRequire } from 'node:module'\nimport { fileURLToPath } from 'node:url'\nimport { parseArgs, numFlag, UsageError } from './args'\nimport {\n createReporter,\n EXIT_ERROR,\n EXIT_NO_BROWSER,\n EXIT_OK,\n EXIT_USAGE,\n} from './output'\nimport { loadVosConfig, configDuration } from './loadConfig'\nimport { launchBrowser, BrowserUnavailableError } from './browser'\nimport { renderVideo, renderStill, previewPages } from './render'\nimport { runCheck } from './check'\n\nconst BOOLEAN_FLAGS = new Set(['json', 'help', 'version'])\n\nconst HELP_ENGINE = `vos — command line for the vos programmatic video engine (https://vos.so/engine)\n\nEngine verbs (local, no account, no network beyond the render page's CDN deps)\n vos render <config.json|url|take> [out] [--width 1920] [--height 1080] [--fps 30]\n [--duration <s>] [--format webm|mp4] [--json]\n vos still <config.json|url> [out.webp] [--time 0] [--width] [--height] [--json]\n vos info <config.json|url> [--json]\n vos check <config.json|url> [--json]\n migrate → schema → syntax → compile → determinism/dialect lints, all local\n vos preview <config.json|url> [--port 0]\n vos versions [--json]\n`\n\nconst HELP_PLUGIN_HINT = `\nEverything else — the take pipeline (screen recordings in, product video out)\nand the vos.so platform verbs (fetch/push/pull/login) — ships as a plugin:\n npm i -D @vosso/vos-plugin\nInstalled plugin verbs appear here and run as plain \\`vos <verb>\\`.\n`\n\nconst HELP_CONVENTIONS = `\nConventions\n Results go to stdout; logs go to stderr. --json switches stdout to NDJSON\n events ending with {\"event\":\"done\",…}. Exit codes: 0 ok, 1 error, 2 usage,\n 3 no browser available.\n`\n\nfunction outName(source: string, ext: string): string {\n const base = basename(source).replace(/\\.[a-z0-9]+$/i, '') || 'vos'\n return `${base}.${ext}`\n}\n\nasync function cmdRender(argv: string[]): Promise<number> {\n // Polymorphic render: a take DIRECTORY (detected by its doc.json — the take\n // pipeline's editable document) renders through the plugin; anything else\n // is an engine config render. A deterministic sniff, never a flag.\n const first = argv.find((a) => !a.startsWith('-'))\n if (first && existsSync(join(first, 'doc.json'))) {\n return delegate(['render', ...argv])\n }\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos render <config.json|url|take> [out]')\n const r = createReporter(flags.json === true)\n const format = (flags.format as string) ?? 'webm'\n if (format !== 'webm' && format !== 'mp4')\n throw new UsageError('--format must be webm or mp4')\n\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const duration = numFlag(flags, 'duration', configDuration(config) ?? 5)\n const width = numFlag(flags, 'width', 1920)\n const height = numFlag(flags, 'height', 1080)\n const fps = numFlag(flags, 'fps', 30)\n const out = positionals[1] ?? outName(source, format)\n\n const browser = await launchBrowser()\n try {\n const result = await renderVideo(browser, {\n config,\n width,\n height,\n fps,\n duration,\n format,\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n })\n await writeFile(out, result.bytes)\n r.done(\n { out, bytes: result.bytes.length, width, height, fps, duration, format },\n `Wrote ${out} (${(result.bytes.length / 1024).toFixed(0)} KB, ${width}x${height}@${fps}, ${duration}s)`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdStill(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos still <config.json|url> [out.webp]')\n const r = createReporter(flags.json === true)\n\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const time = numFlag(flags, 'time', 0)\n const width = numFlag(flags, 'width', 1280)\n const height = numFlag(flags, 'height', 720)\n const out = positionals[1] ?? outName(source, 'webp')\n // The capture template encodes WebP; a .png/.jpg name would ship WebP\n // bytes under a lying extension (stores refuse a mislabelled image), so\n // refuse in words instead of writing it.\n if (/\\.(png|jpe?g)$/i.test(out))\n throw new UsageError(\n `vos still writes WebP (the engine's capture format): name the output .webp, or convert afterwards (ffmpeg -i out.webp out.png)`,\n )\n\n const browser = await launchBrowser()\n try {\n const result = await renderStill(browser, {\n config,\n width,\n height,\n time,\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n })\n await writeFile(out, result.bytes)\n r.done(\n {\n out,\n bytes: result.bytes.length,\n width,\n height,\n time,\n mimeType: result.mimeType,\n },\n `Wrote ${out} (${(result.bytes.length / 1024).toFixed(0)} KB, ${width}x${height} @ t=${time}s)`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdInfo(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos info <config.json|url>')\n const r = createReporter(flags.json === true)\n\n const { config, warnings } = await loadVosConfig(source)\n const elements = Array.isArray(config.elements) ? config.elements.length : 0\n const data =\n typeof config.data === 'object' && config.data !== null\n ? Object.keys(config.data)\n : []\n const fns = ['setup', 'createContent', 'createTimeline', 'onFrame'].filter(\n (k) => typeof config[k] === 'string',\n )\n const info = {\n version: config.version,\n duration: configDuration(config) ?? null,\n camera:\n (config.camera as Record<string, unknown> | undefined)?.preset ?? null,\n elements,\n dataKeys: data,\n functions: fns,\n warnings,\n }\n if (r.json) r.done(info, '')\n else {\n for (const w of warnings) r.log(`note: ${w}`)\n process.stdout.write(\n `version: v${String(info.version)}\\n` +\n `duration: ${info.duration === null ? '(none)' : `${info.duration}s`}\\n` +\n `camera: ${String(info.camera ?? '(default)')}\\n` +\n `elements: ${elements}\\n` +\n `data keys: ${data.length ? data.join(', ') : '(none)'}\\n` +\n `functions: ${fns.join(', ')}\\n`,\n )\n }\n return EXIT_OK\n}\n\nfunction packageVersion(name: string): string | null {\n const require = createRequire(import.meta.url)\n // Fast path — packages that export ./package.json (e.g. playwright).\n try {\n return (require(`${name}/package.json`) as { version: string }).version\n } catch {\n // Strict `exports` maps (the @vosjs packages) hide package.json — resolve\n // the entry module instead and walk up to the owning package.json.\n }\n let entry: string | null = null\n try {\n entry = fileURLToPath(import.meta.resolve(name))\n } catch {\n try {\n entry = require.resolve(name)\n } catch {\n return null\n }\n }\n let dir = dirname(entry)\n for (let i = 0; i < 6; i++) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, 'package.json'), 'utf8'),\n ) as {\n name?: string\n version?: string\n }\n if (pkg.name === name && pkg.version) return pkg.version\n } catch {\n // keep walking\n }\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n return null\n}\n\nfunction ownVersion(): string {\n try {\n const own = JSON.parse(\n readFileSync(\n fileURLToPath(new URL('../package.json', import.meta.url)),\n 'utf8',\n ),\n ) as { version: string }\n return own.version\n } catch {\n return '(unknown)'\n }\n}\n\nasync function cmdVersions(argv: string[]): Promise<number> {\n const { flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const r = createReporter(flags.json === true)\n const versions: Record<string, string> = {}\n versions['@vosjs/cli'] = ownVersion()\n for (const name of [\n '@vosjs/core',\n '@vosjs/elements',\n '@vosjs/tween',\n 'playwright',\n ]) {\n versions[name] = packageVersion(name) ?? '(not found)'\n }\n // The plugin, under whichever of its names is installed (the doctor's row).\n for (const name of PLUGIN_PACKAGES) {\n const v = packageVersion(name)\n if (v) {\n versions[name] = v\n break\n }\n }\n if (r.json) r.done({ versions }, '')\n else\n for (const [k, v] of Object.entries(versions))\n process.stdout.write(`${k} ${v}\\n`)\n return EXIT_OK\n}\n\nasync function cmdPreview(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos preview <config.json|url> [--port 0]')\n const r = createReporter(false)\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const { hostHtml, playerHtml } = previewPages(config)\n const server = createServer((req, res) => {\n const path = new URL(req.url ?? '/', 'http://x').pathname\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(path === '/player' ? playerHtml : hostHtml)\n })\n const port = numFlag(flags, 'port', 0)\n await new Promise<void>((resolve) => server.listen(port, resolve))\n const addr = server.address()\n const url = `http://localhost:${typeof addr === 'object' && addr ? addr.port : port}/`\n process.stdout.write(`${url}\\n`)\n r.log('Serving playback preview — Ctrl-C to stop.')\n await new Promise(() => {}) // keep alive until interrupted\n return EXIT_OK\n}\n\nasync function cmdCheck(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos check <config.json>')\n const r = createReporter(flags.json === true)\n\n let raw: string\n if (/^https?:\\/\\//.test(source)) {\n const res = await fetch(source)\n if (!res.ok) throw new Error(`fetch ${source} → ${res.status}`)\n raw = await res.text()\n } else {\n raw = await readFile(source, 'utf8')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (e) {\n parsed = undefined\n if (!r.json) process.stdout.write(`error [json] ${(e as Error).message}\\n`)\n r.done(\n {\n ok: false,\n errors: 1,\n warnings: 0,\n issues: [\n { level: 'error', source: 'json', message: (e as Error).message },\n ],\n },\n `${source}: 1 error`,\n )\n return EXIT_ERROR\n }\n\n const result = runCheck(parsed)\n if (r.json) {\n r.done(\n {\n ok: result.ok,\n errors: result.errors,\n warnings: result.warnings,\n issues: result.issues,\n },\n '',\n )\n } else {\n for (const i of result.issues) {\n process.stdout.write(`${i.level} [${i.source}] ${i.message}\\n`)\n }\n process.stdout.write(\n result.ok\n ? `${source}: ok (${result.warnings} warning${result.warnings === 1 ? '' : 's'})\\n`\n : `${source}: ${result.errors} error${result.errors === 1 ? '' : 's'}, ${result.warnings} warning${result.warnings === 1 ? '' : 's'}\\n`,\n )\n }\n return result.ok ? EXIT_OK : EXIT_ERROR\n}\n\n// ---------------------------------------------------------------------------\n// The extension seam: every verb this CLI does not own delegates to the vos\n// plugin (the vosso platform layer — take pipeline + vos.so verbs). The\n// contract is the plugin's `run(argv)` export; its optional `manifest`\n// (verb list + supported host range) feeds `vos help` and the doctor, so a\n// new plugin verb never needs a release of this package.\n// ---------------------------------------------------------------------------\n\nconst PLUGIN_PACKAGES = ['@vosso/vos-plugin', '@vosso/cli', '@vosso/voila-cli']\n\ninterface PluginManifest {\n name?: string\n hostRange?: string\n verbs?: { name: string; summary: string }[]\n}\n\ninterface PluginModule {\n run?: (argv: string[]) => Promise<number>\n manifest?: PluginManifest\n}\n\nasync function loadPlugin(): Promise<PluginModule | null> {\n for (const name of PLUGIN_PACKAGES) {\n let mod: PluginModule\n try {\n mod = (await import(name as string)) as PluginModule\n } catch {\n continue\n }\n if (typeof mod.run === 'function') return mod\n }\n return null\n}\n\nfunction versionAtLeast(version: string, min: string): boolean {\n const pa = version.split('.').map((n) => Number.parseInt(n, 10))\n const pb = min.split('.').map((n) => Number.parseInt(n, 10))\n for (let i = 0; i < 3; i++) {\n const a = pa[i] ?? 0\n const b = pb[i] ?? 0\n if (a !== b) return a > b\n }\n return true\n}\n\nasync function delegate(argv: string[], viaAlias = false): Promise<number> {\n const plugin = await loadPlugin()\n if (!plugin?.run) {\n process.stderr.write(\n `vos ${argv[0] ?? ''}: not an engine verb.\\n` +\n 'The take pipeline and the vos.so platform verbs (create, record, plan,\\n' +\n 'frames, open, validate, fetch, push, pull, login) ship as a plugin:\\n' +\n ' npm i -D @vosso/vos-plugin\\n' +\n `then re-run: vos ${argv.join(' ')}\\n` +\n '(If this was a typo, run: vos help)\\n',\n )\n return EXIT_ERROR\n }\n const range = plugin.manifest?.hostRange\n const min = range ? /^>=\\s*(\\d+\\.\\d+\\.\\d+)/.exec(range)?.[1] : undefined\n if (min && !versionAtLeast(ownVersion(), min)) {\n process.stderr.write(\n `note: the installed plugin expects @vosjs/cli ${range} (this is ${ownVersion()}) — upgrade with: npm i -D @vosjs/cli@latest\\n`,\n )\n }\n if (viaAlias && argv[0]) {\n process.stderr.write(\n `note: \"vos voila ${argv[0]}\" is now \"vos ${argv[0]}\".\\n`,\n )\n }\n return await plugin.run(argv)\n}\n\nasync function printHelp(): Promise<void> {\n process.stdout.write(HELP_ENGINE)\n const plugin = await loadPlugin()\n const verbs = plugin?.manifest?.verbs\n if (verbs?.length) {\n const label = plugin?.manifest?.name ?? 'vos plugin'\n process.stdout.write(`\\nPlatform + take pipeline (via ${label})\\n`)\n for (const v of verbs) {\n if (v.name === 'render') continue // polymorphic — already listed above\n process.stdout.write(` vos ${v.name.padEnd(8)} ${v.summary}\\n`)\n }\n } else {\n process.stdout.write(HELP_PLUGIN_HINT)\n }\n process.stdout.write(HELP_CONVENTIONS)\n}\n\nconst ENGINE_VERBS = new Set([\n 'render',\n 'still',\n 'info',\n 'versions',\n 'preview',\n 'check',\n])\n\nasync function main(): Promise<number> {\n const [cmd, ...rest] = process.argv.slice(2)\n if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {\n await printHelp()\n return cmd ? EXIT_OK : EXIT_USAGE\n }\n if (cmd === '--version') return cmdVersions(['--json'])\n if (!ENGINE_VERBS.has(cmd) && cmd !== 'voila') return delegate([cmd, ...rest])\n switch (cmd) {\n case 'render':\n return cmdRender(rest)\n case 'still':\n return cmdStill(rest)\n case 'info':\n return cmdInfo(rest)\n case 'versions':\n return cmdVersions(rest)\n case 'preview':\n return cmdPreview(rest)\n case 'check':\n return cmdCheck(rest)\n // Hidden alias for existing scripts; not in HELP. Same code path as the\n // promoted verbs, plus a one-line pointer at the new spelling.\n case 'voila':\n return delegate(rest, true)\n default:\n throw new UsageError(`unknown command \"${cmd}\" — run vos help`)\n }\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((e) => {\n if (e instanceof UsageError) {\n process.stderr.write(`usage error: ${e.message}\\n`)\n process.exit(EXIT_USAGE)\n }\n if (e instanceof BrowserUnavailableError) {\n process.stderr.write(`${e.message}\\n`)\n process.exit(EXIT_NO_BROWSER)\n }\n process.stderr.write(\n `error: ${e instanceof Error ? e.message : String(e)}\\n`,\n )\n process.exit(EXIT_ERROR)\n })\n","/**\n * Output conventions (agent-safe by construction):\n * - logs/progress → stderr (human readable)\n * - results → stdout; with --json, NDJSON events (`{\"event\":\"phase\"...}` then\n * `{\"event\":\"done\"...}`) so scripts and agents never parse prose\n * - exit codes: 0 ok · 1 failure · 2 usage · 3 browser unavailable\n */\nexport const EXIT_OK = 0\nexport const EXIT_ERROR = 1\nexport const EXIT_USAGE = 2\nexport const EXIT_NO_BROWSER = 3\n\nexport interface Reporter {\n json: boolean\n /** Human log line (stderr; suppressed in --json mode). */\n log: (msg: string) => void\n /** Machine event (stdout NDJSON in --json mode; no-op otherwise). */\n event: (obj: Record<string, unknown>) => void\n /** Final result: NDJSON `done` event in --json mode, plain line otherwise. */\n done: (obj: Record<string, unknown>, humanLine: string) => void\n}\n\nexport function createReporter(json: boolean): Reporter {\n return {\n json,\n log: (msg) => {\n if (!json) process.stderr.write(`${msg}\\n`)\n },\n event: (obj) => {\n if (json) process.stdout.write(`${JSON.stringify(obj)}\\n`)\n },\n done: (obj, humanLine) => {\n if (json)\n process.stdout.write(`${JSON.stringify({ event: 'done', ...obj })}\\n`)\n else process.stdout.write(`${humanLine}\\n`)\n },\n }\n}\n","/**\n * `vos check` — the local validation pipeline, pure so it can be unit-tested:\n * envelope unwrap → migrate → schema → compile → determinism + dialect lints.\n * Everything runs locally (no network, no browser). The platform runs the\n * same compiler server-side, so a clean check is a push that will compile.\n */\nimport {\n CURRENT_CONFIG_VERSION,\n compileVosConfig,\n migrateConfig,\n vosConfigJsonSchema,\n} from '@vosjs/core'\nimport { lintVosConfig, lintVosDialect, lintVosFonts } from '@vosjs/core/lint'\n\nexport interface CheckIssue {\n level: 'error' | 'warn'\n source:\n | 'schema'\n | 'syntax'\n | 'compile'\n | 'determinism'\n | 'dialect'\n | 'shape'\n | 'fonts'\n message: string\n}\n\nexport interface CheckResult {\n ok: boolean\n errors: number\n warnings: number\n issues: CheckIssue[]\n /** The migrated config (params/presets untouched) — what a push should send. */\n config: Record<string, unknown> | null\n}\n\n// Top-level keys the schema does not know but the platform preserves on push.\nconst PLATFORM_EXTRA_KEYS = new Set(['params', 'presets'])\n\nexport function runCheck(parsed: unknown): CheckResult {\n const issues: CheckIssue[] = []\n const finish = (config: Record<string, unknown> | null): CheckResult => {\n const errors = issues.filter((i) => i.level === 'error').length\n return {\n ok: errors === 0,\n errors,\n warnings: issues.length - errors,\n issues,\n config,\n }\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n issues.push({\n level: 'error',\n source: 'shape',\n message: 'not a JSON object',\n })\n return finish(null)\n }\n\n // API endpoints wrap the config: { config: {...} } — accept both shapes.\n let obj = parsed as Record<string, unknown>\n if (\n typeof obj.config === 'object' &&\n obj.config !== null &&\n !('createTimeline' in obj)\n ) {\n obj = obj.config as Record<string, unknown>\n }\n\n const version = obj.version\n let migrated: Record<string, unknown>\n try {\n migrated = migrateConfig(obj) as Record<string, unknown>\n } catch (e) {\n issues.push({\n level: 'error',\n source: 'shape',\n message: `migration failed: ${e instanceof Error ? e.message : String(e)}`,\n })\n return finish(null)\n }\n if (version === undefined) {\n // It compiles (the engine reads an absent version as the current one),\n // but a push is refused: a stored config must say which schema era it was\n // written against, and nobody can tell that from the file later.\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `config declares no \"version\". It plays here, but a push is refused without one. Add \"version\": ${CURRENT_CONFIG_VERSION}.`,\n })\n } else if (version !== CURRENT_CONFIG_VERSION) {\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `config is v${String(version)}, migrated to v${CURRENT_CONFIG_VERSION}. Save the migrated form.`,\n })\n }\n\n const schema = vosConfigJsonSchema.safeParse(migrated)\n if (!schema.success) {\n for (const i of schema.error.issues.slice(0, 10)) {\n issues.push({\n level: 'error',\n source: 'schema',\n message: `${i.path.join('.') || '(root)'}: ${i.message}`,\n })\n }\n return finish(null)\n }\n\n // Keys the platform's schema will silently drop on push (params/presets\n // excepted — those are re-attached by contract).\n const known = new Set([\n ...Object.keys(vosConfigJsonSchema.shape),\n ...PLATFORM_EXTRA_KEYS,\n ])\n for (const key of Object.keys(migrated)) {\n if (!known.has(key)) {\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `unknown top-level key \"${key}\" — the platform drops it on push`,\n })\n }\n }\n\n // Function strings are pasted into the template as text, so the compiler\n // cannot see a syntax error — parse each one here (construction only,\n // nothing executes).\n let syntaxErrors = 0\n for (const key of [\n 'setup',\n 'createContent',\n 'createTimeline',\n 'onFrame',\n ] as const) {\n const src = migrated[key]\n if (typeof src !== 'string' || !src.length) continue\n try {\n new Function(`\"use strict\"; return (${src}\\n)`)\n } catch (e) {\n syntaxErrors++\n issues.push({\n level: 'error',\n source: 'syntax',\n message: `${key}: ${e instanceof Error ? e.message : String(e)}`,\n })\n }\n }\n if (syntaxErrors) return finish(migrated)\n\n try {\n // Same options as `vos render` — a clean check is a config the CLI's own\n // render path will accept.\n compileVosConfig(migrated as never, { tweenEngine: 'vos' })\n } catch (e) {\n issues.push({\n level: 'error',\n source: 'compile',\n message: e instanceof Error ? e.message : String(e),\n })\n return finish(migrated)\n }\n\n for (const i of lintVosConfig(migrated as never)) {\n issues.push({\n level: i.severity === 'error' ? 'error' : 'warn',\n source: 'determinism',\n message: `${i.fn}:${i.line} [${i.rule}] ${i.message}`,\n })\n }\n for (const i of lintVosDialect(migrated as never)) {\n issues.push({\n level: i.severity === 'error' ? 'error' : 'warn',\n source: 'dialect',\n message: `${i.fn}:${i.line} [${i.rule}] ${i.message}`,\n })\n }\n for (const i of lintVosFonts(migrated as never)) {\n issues.push({\n level: 'warn',\n source: 'fonts',\n message: `[${i.rule}] ${i.message}`,\n })\n }\n\n return finish(migrated)\n}\n"],"mappings":"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","names":["require"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/output.ts","../src/check.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { basename, dirname, join } from 'node:path'\nimport { createServer } from 'node:http'\nimport { createRequire } from 'node:module'\nimport { fileURLToPath } from 'node:url'\nimport { parseArgs, numFlag, UsageError } from './args'\nimport {\n createReporter,\n EXIT_ERROR,\n EXIT_NO_BROWSER,\n EXIT_OK,\n EXIT_USAGE,\n} from './output'\nimport { loadVosConfig, configDuration } from './loadConfig'\nimport { launchBrowser, BrowserUnavailableError } from './browser'\nimport { renderVideo, renderStill, previewPages } from './render'\nimport { runCheck } from './check'\n\nconst BOOLEAN_FLAGS = new Set(['json', 'help', 'version'])\n\nconst HELP_ENGINE = `vos — command line for the vos programmatic video engine (https://vos.so/engine)\n\nEngine verbs (local, no account, no network beyond the render page's CDN deps)\n vos render <config.json|url|take> [out] [--width 1920] [--height 1080] [--fps 30]\n [--duration <s>] [--format webm|mp4] [--json]\n vos still <config.json|url> [out.webp] [--time 0] [--width] [--height] [--json]\n vos info <config.json|url> [--json]\n vos check <config.json|url> [--json]\n migrate → schema → syntax → compile → determinism/dialect lints, all local\n vos preview <config.json|url> [--port 0]\n vos versions [--json]\n`\n\nconst HELP_CONVENTIONS = `\nConventions\n Results go to stdout; logs go to stderr. --json switches stdout to NDJSON\n events ending with {\"event\":\"done\",…}. Exit codes: 0 ok, 1 error, 2 usage,\n 3 no browser available.\n`\n\nfunction outName(source: string, ext: string): string {\n const base = basename(source).replace(/\\.[a-z0-9]+$/i, '') || 'vos'\n return `${base}.${ext}`\n}\n\nasync function cmdRender(argv: string[]): Promise<number> {\n // Polymorphic render: a take DIRECTORY (detected by its doc.json — the take\n // pipeline's editable document) renders through the plugin; anything else\n // is an engine config render. A deterministic sniff, never a flag.\n const first = argv.find((a) => !a.startsWith('-'))\n if (first && existsSync(join(first, 'doc.json'))) {\n return delegate(['render', ...argv])\n }\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos render <config.json|url|take> [out]')\n const r = createReporter(flags.json === true)\n const format = (flags.format as string) ?? 'webm'\n if (format !== 'webm' && format !== 'mp4')\n throw new UsageError('--format must be webm or mp4')\n\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const duration = numFlag(flags, 'duration', configDuration(config) ?? 5)\n const width = numFlag(flags, 'width', 1920)\n const height = numFlag(flags, 'height', 1080)\n const fps = numFlag(flags, 'fps', 30)\n const out = positionals[1] ?? outName(source, format)\n\n const browser = await launchBrowser()\n try {\n const result = await renderVideo(browser, {\n config,\n width,\n height,\n fps,\n duration,\n format,\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n })\n await writeFile(out, result.bytes)\n r.done(\n { out, bytes: result.bytes.length, width, height, fps, duration, format },\n `Wrote ${out} (${(result.bytes.length / 1024).toFixed(0)} KB, ${width}x${height}@${fps}, ${duration}s)`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdStill(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos still <config.json|url> [out.webp]')\n const r = createReporter(flags.json === true)\n\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const time = numFlag(flags, 'time', 0)\n const width = numFlag(flags, 'width', 1280)\n const height = numFlag(flags, 'height', 720)\n const out = positionals[1] ?? outName(source, 'webp')\n // The capture template encodes WebP; a .png/.jpg name would ship WebP\n // bytes under a lying extension (stores refuse a mislabelled image), so\n // refuse in words instead of writing it.\n if (/\\.(png|jpe?g)$/i.test(out))\n throw new UsageError(\n `vos still writes WebP (the engine's capture format): name the output .webp, or convert afterwards (ffmpeg -i out.webp out.png)`,\n )\n\n const browser = await launchBrowser()\n try {\n const result = await renderStill(browser, {\n config,\n width,\n height,\n time,\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n })\n await writeFile(out, result.bytes)\n r.done(\n {\n out,\n bytes: result.bytes.length,\n width,\n height,\n time,\n mimeType: result.mimeType,\n },\n `Wrote ${out} (${(result.bytes.length / 1024).toFixed(0)} KB, ${width}x${height} @ t=${time}s)`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdInfo(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos info <config.json|url>')\n const r = createReporter(flags.json === true)\n\n const { config, warnings } = await loadVosConfig(source)\n const elements = Array.isArray(config.elements) ? config.elements.length : 0\n const data =\n typeof config.data === 'object' && config.data !== null\n ? Object.keys(config.data)\n : []\n const fns = ['setup', 'createContent', 'createTimeline', 'onFrame'].filter(\n (k) => typeof config[k] === 'string',\n )\n const info = {\n version: config.version,\n duration: configDuration(config) ?? null,\n camera:\n (config.camera as Record<string, unknown> | undefined)?.preset ?? null,\n elements,\n dataKeys: data,\n functions: fns,\n warnings,\n }\n if (r.json) r.done(info, '')\n else {\n for (const w of warnings) r.log(`note: ${w}`)\n process.stdout.write(\n `version: v${String(info.version)}\\n` +\n `duration: ${info.duration === null ? '(none)' : `${info.duration}s`}\\n` +\n `camera: ${String(info.camera ?? '(default)')}\\n` +\n `elements: ${elements}\\n` +\n `data keys: ${data.length ? data.join(', ') : '(none)'}\\n` +\n `functions: ${fns.join(', ')}\\n`,\n )\n }\n return EXIT_OK\n}\n\nfunction packageVersion(name: string): string | null {\n const require = createRequire(import.meta.url)\n // Fast path — packages that export ./package.json (e.g. playwright).\n try {\n return (require(`${name}/package.json`) as { version: string }).version\n } catch {\n // Strict `exports` maps (the @vosjs packages) hide package.json — resolve\n // the entry module instead and walk up to the owning package.json.\n }\n let entry: string | null = null\n try {\n entry = fileURLToPath(import.meta.resolve(name))\n } catch {\n try {\n entry = require.resolve(name)\n } catch {\n return null\n }\n }\n let dir = dirname(entry)\n for (let i = 0; i < 6; i++) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, 'package.json'), 'utf8'),\n ) as {\n name?: string\n version?: string\n }\n if (pkg.name === name && pkg.version) return pkg.version\n } catch {\n // keep walking\n }\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n return null\n}\n\nfunction ownVersion(): string {\n try {\n const own = JSON.parse(\n readFileSync(\n fileURLToPath(new URL('../package.json', import.meta.url)),\n 'utf8',\n ),\n ) as { version: string }\n return own.version\n } catch {\n return '(unknown)'\n }\n}\n\nasync function cmdVersions(argv: string[]): Promise<number> {\n const { flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const r = createReporter(flags.json === true)\n const versions: Record<string, string> = {}\n versions['@vosjs/cli'] = ownVersion()\n for (const name of [\n '@vosjs/core',\n '@vosjs/elements',\n '@vosjs/tween',\n '@vosjs/editor',\n '@vosjs/timeline',\n '@vosjs/studio-core',\n '@vosjs/render-core',\n '@vosjs/shared',\n 'mediabunny',\n 'playwright',\n ]) {\n versions[name] = packageVersion(name) ?? '(not found)'\n }\n if (r.json) r.done({ versions }, '')\n else\n for (const [k, v] of Object.entries(versions))\n process.stdout.write(`${k} ${v}\\n`)\n return EXIT_OK\n}\n\nasync function cmdPreview(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos preview <config.json|url> [--port 0]')\n const r = createReporter(false)\n const { config, warnings } = await loadVosConfig(source)\n for (const w of warnings) r.log(`note: ${w}`)\n const { hostHtml, playerHtml } = previewPages(config)\n const server = createServer((req, res) => {\n const path = new URL(req.url ?? '/', 'http://x').pathname\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(path === '/player' ? playerHtml : hostHtml)\n })\n const port = numFlag(flags, 'port', 0)\n await new Promise<void>((resolve) => server.listen(port, resolve))\n const addr = server.address()\n const url = `http://localhost:${typeof addr === 'object' && addr ? addr.port : port}/`\n process.stdout.write(`${url}\\n`)\n r.log('Serving playback preview — Ctrl-C to stop.')\n await new Promise(() => {}) // keep alive until interrupted\n return EXIT_OK\n}\n\nasync function cmdCheck(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos check <config.json>')\n const r = createReporter(flags.json === true)\n\n let raw: string\n if (/^https?:\\/\\//.test(source)) {\n const res = await fetch(source)\n if (!res.ok) throw new Error(`fetch ${source} → ${res.status}`)\n raw = await res.text()\n } else {\n raw = await readFile(source, 'utf8')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (e) {\n parsed = undefined\n if (!r.json) process.stdout.write(`error [json] ${(e as Error).message}\\n`)\n r.done(\n {\n ok: false,\n errors: 1,\n warnings: 0,\n issues: [\n { level: 'error', source: 'json', message: (e as Error).message },\n ],\n },\n `${source}: 1 error`,\n )\n return EXIT_ERROR\n }\n\n const result = runCheck(parsed)\n if (r.json) {\n r.done(\n {\n ok: result.ok,\n errors: result.errors,\n warnings: result.warnings,\n issues: result.issues,\n },\n '',\n )\n } else {\n for (const i of result.issues) {\n process.stdout.write(`${i.level} [${i.source}] ${i.message}\\n`)\n }\n process.stdout.write(\n result.ok\n ? `${source}: ok (${result.warnings} warning${result.warnings === 1 ? '' : 's'})\\n`\n : `${source}: ${result.errors} error${result.errors === 1 ? '' : 's'}, ${result.warnings} warning${result.warnings === 1 ? '' : 's'}\\n`,\n )\n }\n return result.ok ? EXIT_OK : EXIT_ERROR\n}\n\n// ---------------------------------------------------------------------------\n// Every verb this file does not own is a take-pipeline or vos.so verb from\n// `./plugin` (what used to ship separately as @vosso/vos-plugin). It loads on\n// demand, so the engine verbs never pay for the recorder's imports, and the\n// old names (`@vosso/cli`, `@vosso/voila-cli`, the `vos voila` alias) keep\n// resolving here for scripts that still use them.\n// ---------------------------------------------------------------------------\n\nasync function delegate(argv: string[], viaAlias = false): Promise<number> {\n const { run } = await import('./plugin/run')\n if (viaAlias && argv[0]) {\n process.stderr.write(\n `note: \"vos voila ${argv[0]}\" is now \"vos ${argv[0]}\".\\n`,\n )\n }\n return await run(argv)\n}\n\nasync function printHelp(): Promise<void> {\n process.stdout.write(HELP_ENGINE)\n const { manifest } = await import('./plugin/manifest')\n process.stdout.write('\\nTake pipeline + vos.so verbs\\n')\n for (const v of manifest.verbs) {\n if (v.name === 'render') continue // polymorphic — already listed above\n process.stdout.write(` vos ${v.name.padEnd(8)} ${v.summary}\\n`)\n }\n process.stdout.write(HELP_CONVENTIONS)\n}\n\nconst ENGINE_VERBS = new Set([\n 'render',\n 'still',\n 'info',\n 'versions',\n 'preview',\n 'check',\n])\n\nasync function main(): Promise<number> {\n const [cmd, ...rest] = process.argv.slice(2)\n if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {\n await printHelp()\n return cmd ? EXIT_OK : EXIT_USAGE\n }\n if (cmd === '--version') return cmdVersions(['--json'])\n if (!ENGINE_VERBS.has(cmd) && cmd !== 'voila') return delegate([cmd, ...rest])\n switch (cmd) {\n case 'render':\n return cmdRender(rest)\n case 'still':\n return cmdStill(rest)\n case 'info':\n return cmdInfo(rest)\n case 'versions':\n return cmdVersions(rest)\n case 'preview':\n return cmdPreview(rest)\n case 'check':\n return cmdCheck(rest)\n // Hidden alias for existing scripts; not in HELP. Same code path as the\n // promoted verbs, plus a one-line pointer at the new spelling.\n case 'voila':\n return delegate(rest, true)\n default:\n throw new UsageError(`unknown command \"${cmd}\" — run vos help`)\n }\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((e) => {\n if (e instanceof UsageError) {\n process.stderr.write(`usage error: ${e.message}\\n`)\n process.exit(EXIT_USAGE)\n }\n if (e instanceof BrowserUnavailableError) {\n process.stderr.write(`${e.message}\\n`)\n process.exit(EXIT_NO_BROWSER)\n }\n process.stderr.write(\n `error: ${e instanceof Error ? e.message : String(e)}\\n`,\n )\n process.exit(EXIT_ERROR)\n })\n","/**\n * Output conventions (agent-safe by construction):\n * - logs/progress → stderr (human readable)\n * - results → stdout; with --json, NDJSON events (`{\"event\":\"phase\"...}` then\n * `{\"event\":\"done\"...}`) so scripts and agents never parse prose\n * - exit codes: 0 ok · 1 failure · 2 usage · 3 browser unavailable\n */\nexport const EXIT_OK = 0\nexport const EXIT_ERROR = 1\nexport const EXIT_USAGE = 2\nexport const EXIT_NO_BROWSER = 3\n\nexport interface Reporter {\n json: boolean\n /** Human log line (stderr; suppressed in --json mode). */\n log: (msg: string) => void\n /** Machine event (stdout NDJSON in --json mode; no-op otherwise). */\n event: (obj: Record<string, unknown>) => void\n /** Final result: NDJSON `done` event in --json mode, plain line otherwise. */\n done: (obj: Record<string, unknown>, humanLine: string) => void\n}\n\nexport function createReporter(json: boolean): Reporter {\n return {\n json,\n log: (msg) => {\n if (!json) process.stderr.write(`${msg}\\n`)\n },\n event: (obj) => {\n if (json) process.stdout.write(`${JSON.stringify(obj)}\\n`)\n },\n done: (obj, humanLine) => {\n if (json)\n process.stdout.write(`${JSON.stringify({ event: 'done', ...obj })}\\n`)\n else process.stdout.write(`${humanLine}\\n`)\n },\n }\n}\n","/**\n * `vos check` — the local validation pipeline, pure so it can be unit-tested:\n * envelope unwrap → migrate → schema → compile → determinism + dialect lints.\n * Everything runs locally (no network, no browser). The platform runs the\n * same compiler server-side, so a clean check is a push that will compile.\n */\nimport {\n CURRENT_CONFIG_VERSION,\n compileVosConfig,\n migrateConfig,\n vosConfigJsonSchema,\n} from '@vosjs/core'\nimport { lintVosConfig, lintVosDialect, lintVosFonts } from '@vosjs/core/lint'\n\nexport interface CheckIssue {\n level: 'error' | 'warn'\n source:\n | 'schema'\n | 'syntax'\n | 'compile'\n | 'determinism'\n | 'dialect'\n | 'shape'\n | 'fonts'\n message: string\n}\n\nexport interface CheckResult {\n ok: boolean\n errors: number\n warnings: number\n issues: CheckIssue[]\n /** The migrated config (params/presets untouched) — what a push should send. */\n config: Record<string, unknown> | null\n}\n\n// Top-level keys the schema does not know but the platform preserves on push.\nconst PLATFORM_EXTRA_KEYS = new Set(['params', 'presets'])\n\nexport function runCheck(parsed: unknown): CheckResult {\n const issues: CheckIssue[] = []\n const finish = (config: Record<string, unknown> | null): CheckResult => {\n const errors = issues.filter((i) => i.level === 'error').length\n return {\n ok: errors === 0,\n errors,\n warnings: issues.length - errors,\n issues,\n config,\n }\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n issues.push({\n level: 'error',\n source: 'shape',\n message: 'not a JSON object',\n })\n return finish(null)\n }\n\n // API endpoints wrap the config: { config: {...} } — accept both shapes.\n let obj = parsed as Record<string, unknown>\n if (\n typeof obj.config === 'object' &&\n obj.config !== null &&\n !('createTimeline' in obj)\n ) {\n obj = obj.config as Record<string, unknown>\n }\n\n const version = obj.version\n let migrated: Record<string, unknown>\n try {\n migrated = migrateConfig(obj) as Record<string, unknown>\n } catch (e) {\n issues.push({\n level: 'error',\n source: 'shape',\n message: `migration failed: ${e instanceof Error ? e.message : String(e)}`,\n })\n return finish(null)\n }\n if (version === undefined) {\n // It compiles (the engine reads an absent version as the current one),\n // but a push is refused: a stored config must say which schema era it was\n // written against, and nobody can tell that from the file later.\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `config declares no \"version\". It plays here, but a push is refused without one. Add \"version\": ${CURRENT_CONFIG_VERSION}.`,\n })\n } else if (version !== CURRENT_CONFIG_VERSION) {\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `config is v${String(version)}, migrated to v${CURRENT_CONFIG_VERSION}. Save the migrated form.`,\n })\n }\n\n const schema = vosConfigJsonSchema.safeParse(migrated)\n if (!schema.success) {\n for (const i of schema.error.issues.slice(0, 10)) {\n issues.push({\n level: 'error',\n source: 'schema',\n message: `${i.path.join('.') || '(root)'}: ${i.message}`,\n })\n }\n return finish(null)\n }\n\n // Keys the platform's schema will silently drop on push (params/presets\n // excepted — those are re-attached by contract).\n const known = new Set([\n ...Object.keys(vosConfigJsonSchema.shape),\n ...PLATFORM_EXTRA_KEYS,\n ])\n for (const key of Object.keys(migrated)) {\n if (!known.has(key)) {\n issues.push({\n level: 'warn',\n source: 'shape',\n message: `unknown top-level key \"${key}\" — the platform drops it on push`,\n })\n }\n }\n\n // Function strings are pasted into the template as text, so the compiler\n // cannot see a syntax error — parse each one here (construction only,\n // nothing executes).\n let syntaxErrors = 0\n for (const key of [\n 'setup',\n 'createContent',\n 'createTimeline',\n 'onFrame',\n ] as const) {\n const src = migrated[key]\n if (typeof src !== 'string' || !src.length) continue\n try {\n new Function(`\"use strict\"; return (${src}\\n)`)\n } catch (e) {\n syntaxErrors++\n issues.push({\n level: 'error',\n source: 'syntax',\n message: `${key}: ${e instanceof Error ? e.message : String(e)}`,\n })\n }\n }\n if (syntaxErrors) return finish(migrated)\n\n try {\n // Same options as `vos render` — a clean check is a config the CLI's own\n // render path will accept.\n compileVosConfig(migrated as never, { tweenEngine: 'vos' })\n } catch (e) {\n issues.push({\n level: 'error',\n source: 'compile',\n message: e instanceof Error ? e.message : String(e),\n })\n return finish(migrated)\n }\n\n for (const i of lintVosConfig(migrated as never)) {\n issues.push({\n level: i.severity === 'error' ? 'error' : 'warn',\n source: 'determinism',\n message: `${i.fn}:${i.line} [${i.rule}] ${i.message}`,\n })\n }\n for (const i of lintVosDialect(migrated as never)) {\n issues.push({\n level: i.severity === 'error' ? 'error' : 'warn',\n source: 'dialect',\n message: `${i.fn}:${i.line} [${i.rule}] ${i.message}`,\n })\n }\n for (const i of lintVosFonts(migrated as never)) {\n issues.push({\n level: 'warn',\n source: 'fonts',\n message: `[${i.rule}] ${i.message}`,\n })\n }\n\n return finish(migrated)\n}\n"],"mappings":"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","names":["require"]}