@vosjs/cli 0.12.0 → 0.13.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 @@
1
+ {"version":3,"sources":["../src/plugin/run.ts","../src/plugin/args.ts","../src/plugin/output.ts","../src/plugin/actions.ts","../src/plugin/validateDoc.ts","../src/plugin/mediaProbe.ts","../src/plugin/framesTake.ts","../src/plugin/take.ts","../src/plugin/server.ts","../src/plugin/renderAnimation.ts","../src/plugin/backdrops.ts","../src/plugin/docOverride.ts","../src/plugin/digestTake.ts","../src/plugin/deliver.ts","../src/plugin/renderTake.ts","../src/plugin/posterStill.ts","../src/plugin/validateKit.ts","../src/plugin/platform.ts","../src/plugin/recorder.ts","../src/plugin/recordingCap.ts","../src/plugin/encode.ts","../src/plugin/plan.ts","../src/plugin/reuse.ts","../src/plugin/sync.ts","../src/plugin/media.ts","../src/plugin/folder.ts","../src/plugin/program.ts","../src/plugin/login.ts","../src/plugin/asset.ts","../src/plugin/recipe.ts","../src/plugin/brand.ts","../src/plugin/agentBrowser.ts"],"sourcesContent":["import { mkdir, readFile, rm } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { totalDuration } from '@vosjs/timeline'\nimport { migrateHostedDoc, ratedSegments } from '@vosjs/studio-core'\nimport { UsageError, hasFlag, numFlag, parseArgs, strFlag } from './args'\nimport {\n EXIT_ERROR,\n EXIT_NO_BROWSER,\n EXIT_OK,\n EXIT_USAGE,\n createReporter,\n} from './output'\nimport { validateActions } from './actions'\nimport { lintDoc } from './validateDoc'\nimport {\n collectConfigMediaUrls,\n collectDocMediaUrls,\n mediaProbeLints,\n probeMediaUrls,\n} from './mediaProbe'\nimport { framesTake, parseTimes, writeIndexJson } from './framesTake'\nimport { deliverTake, resolveChannels } from './deliver'\nimport { validateKit } from './validateKit'\nimport { digestTake, parseTranscript } from './digestTake'\nimport { apiJson, platformOrigin, resolveCredential } from './platform'\nimport { startTakeServer } from './server'\nimport { PREV_DOC_NAME, ensureTakeDir, loadTake, prepareReRecord } from './take'\nimport { BrowserUnavailableError, launchBrowser } from '../browser'\nimport { recordTake } from './recorder'\nimport {\n defaultMaxDurationSeconds,\n formatDurationCap,\n hostedRecordingCap,\n} from './recordingCap'\nimport { encodeRecording } from './encode'\nimport { planTake } from './plan'\nimport { openingBackdrop } from './backdrops'\nimport { renderTake } from './renderTake'\nimport { pullTake, pushTake } from './sync'\nimport {\n cmdDuplicate,\n cmdFetch,\n cmdLogin,\n cmdPullProgram,\n cmdPushProgram,\n isTakeDir,\n preflightConfig,\n readProgramDoc,\n} from './program'\nimport { cmdFolder } from './folder'\nimport { cmdAsset } from './asset'\nimport { cmdRecipe } from './recipe'\nimport { cmdBrand } from './brand'\nimport { cmdActions } from './agentBrowser'\nimport type { Backdrop, ProjectDoc } from '@vosjs/studio-core'\nimport type { ActionsFile } from './actions'\nimport type { ParsedArgs } from './args'\n\nconst BOOLEAN_FLAGS = new Set([\n 'json',\n 'help',\n 'fresh',\n 'reuse',\n 'strict',\n 'draft',\n 'at-zooms',\n 'at-moments',\n 'no-frames',\n 'media',\n 'print',\n 'yes',\n])\n/** Repeatable value flags (accumulate): --set path=value on render/frames, --override id on push. */\nconst MULTI_FLAGS = new Set(['set', 'override'])\n\nconst HELP = `vos — record a browser flow, plan effects, render a product video; sync with vos.so\n\nTake pipeline\n vos create --actions actions.json [--url <url>] [--out take] [out.webm] [--strict] [--max-duration <s>] [--background <slug|url|none>] [render flags] [--json]\n vos record --actions actions.json [--url <url>] [--out take] [--strict] [--max-duration <s>] [--background <slug|url|none>] [--json]\n vos plan <take> [--fresh] [--reuse [--from <doc.json>]] [--style <doc.json|vosId>] [--background <slug|url|none>] [--json]\n vos render <take> [out.webm] [--width] [--height] [--fps] [--format webm|mp4] [--parallel N] [--range a..b] [--draft] [--frame <kind>] [--background <url|slug>] [--set <path=value>]... [--json]\n vos frames <take> [--times 0,25%,50%,75%,100%] [--frame <t>] [--at-zooms] [--at-moments] [--size WxH] [--out dir] [--background <url|slug>] [--set <path=value>]... [--json]\n vos deliver <take> --to cws,producthunt,x,linkedin,og,github,youtube (or all) [--poster <config.json|vosId>] [--shot-time <t>] [--poster-time <t>] [--composed] [--set path=value] [--release v2.1] [--out dir] [--times a,b] [--range a..b] [--parallel N] [--json]\n vos digest <take> [--out dir] [--full 960] [--crop 640] [--no-frames] [--transcript <file.json>] [--style <doc.json|vosId>] [--json]\n vos brand <url> [--out BRAND.md] [--json]\n vos open <take> [--studio <url>] [--print]\n vos validate <actions.json|take> [--json]\n vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url <url>] [--viewport WxH] [--json]\n\nPlatform (vos.so) — fetch, edit, push, pull, repeat\n vos login [--key <vos_sk_…>] [--label <name>] [--no-browser]\n sign in via the browser (approve at vos.so/cli/auth; works\n headless — print the URL, a human approves, the key stores\n itself). --key skips the browser (mint at vos.so/app/api)\n vos fetch <vosId|watch-url> [--out dir] [--media] [--json]\n writes config.json + vos.json (no auth needed for public programs);\n a take vos also gets its doc.json, and --media its footage\n vos push <config.json|take> [--vos id] [--title t] [--slug s] [--remix-of id]\n [--desc d] [--tags a,b] [--folder <folderId|slug>]\n [--note n] [--label l] [--base versionId] [--override <id>]... [--yes] [--json]\n [--claimable]\n a take DIRECTORY (doc.json) pushes recording + doc; a config.json\n pushes the program. No --vos: create a PRIVATE vos; with --vos:\n add a version against the tracked base — a stale push 409s WITH\n the platform's typed changelog. --claimable (programs only, NO\n credential): creates a 72h claim link instead — hand it to the\n user and nowhere else; unclaimed work is deleted after 72h.\n --override consents to touching\n protected (human-edited) nodes, ONLY when the user asked.\n vos pull [dir|take] [--vos <id>] [--since versionId] [--check] [--media] [--json]\n what changed on vos.so since your base; syncs config.json (backup\n kept) or the take's doc.json. ALWAYS pull before editing pushed work.\n --media also downloads the recording (+ mic/cam sidecars) beside\n the doc and re-anchors it, so digest/frames/render run locally\n auth: --key, VOS_API_KEY, or ~/.config/vos/credentials; keys can\n never publish (visibility stays private; humans publish on vos.so)\n vos folder list\n vos folder create <name> [--parent <folderId|slug>] [--desc <text>]\n vos folder move <vosId|assetId|watch-url>... --to <folderId|slug|none>\n organize the shelf: folders nest (≤5 deep, slugs stable); move\n takes vos ids AND asset ids (recipes, uploads) and files them\n into the folder (--to none unfiles). Add-only by design:\n folder rename/delete/reorder stay human gestures on vos.so\n vos asset rename <assetId> <newname.ext>\n rename one of your assets (recipes included) in place — bytes\n and fileUrl untouched; the extension must keep matching the\n asset's kind (a recipe stays .md)\n vos asset push <file...> [--folder <folderId|slug>]\n upload files onto your shelf (a key takes models .glb/.gltf,\n recipes .md and images .png/.jpg/.webp/.gif — posters and\n store stills file into the release's project; 40 images/24h)\n vos recipe push <file.md> --folder <folderId|slug>\n vos recipe push <file.md> --asset <assetId>\n put a recipe (a plain .md) on the shelf: --folder creates it\n filed into that folder, --asset replaces one in place (same\n id, the displaced body kept as the prior version). Reading is\n vos folder pull; restore stays a gesture on the recipe page\n\ncreate = record then render in one command: drives the flow, auto-plans effects, and writes the video.\n--strict aborts before rendering on any skipped selector. For the full\nloop (inspect frames, edit doc.json, re-render) use the verbs below.\n\nThe take directory is the unit of work: recording.webm + cursor.json +\nmeta.json + actions.json + doc.json. doc.json is the editable surface —\nzoom spans, trims, speed, cursor/frame styling; edit it (or let an agent),\nthen re-run render. plan preserves manual zoom spans, regenerating only\nsource:'auto' ones. Results on stdout, logs on stderr; --json = NDJSON.\n\nThe re-render loop (re-recording the same script after the product\nchanged): record into the SAME take dir — footage/cursor/meta are\nreplaced, the cut survives as doc.prev.json — then plan --reuse re-times\nit onto the new recording. meta.json carries steps (when each actions\nstep ran); a span may carry anchor {step, at, offset} tying it to a step\nid/index for exact re-timing; unanchored human spans map piecewise\nthrough matched step edges; autos re-plan; overlays/audio keep OUTPUT\ntimes. The done event's reuse block NAMES whatever could not follow —\nfix by exception, never re-cut from scratch. Give steps ids in\nactions.json so anchors survive script edits.\n\nrecord --strict exits 2 when any selector was skipped, the page never\nreached networkidle, or the take hit --max-duration (the done event lists\nskipped[] and capped either way). --max-duration defaults to the hosted\nrecording cap (1800s): the capture stops there and says so in one line.\nframes captures PNG stills at OUTPUT times (seconds or % of duration);\n--at-zooms adds every zoom span's apex, --at-moments every digest moment —\nthe agent's eyes AND exact-size posters/screenshots (--size WxH). render\n--range a..b --draft spot-checks a doc edit in seconds (half res, low\nbitrate; range in OUTPUT seconds); a --range render keeps its audio.\ndeliver renders the take to a release's destinations in one pass — the\nchannel specs (schema/channel-specs.json, verified sizes for the Chrome\nWeb Store, Product Hunt, X, LinkedIn, OG, GitHub, YouTube) drive stills at\nexact pixels and video cuts, every artifact is VERIFIED against its spec\n(px, bytes, duration; misses land in skipped[] with the reason), and\nkit.json beside the assets is the manifest. Still times default to the\nzoom apexes (--times overrides); --range cuts every video destination.\n--poster <config.json|vosId> is the CARD half: card-genre destinations\n(OG, LinkedIn, X, YouTube thumbnail, the CWS tile + marquee, GitHub\nsocial preview) render from your poster PROGRAM — the split-cover family\n— with this release's shot baked into its image element (id \"shot\"), PNG\nat exact pixels. --shot-time <t> picks the take moment (OUTPUT seconds;\ndefault the first still time — pick a zoom apex, the cut's camera makes\nthe shot the feature, not the whole page); --poster-time <t> is the instant\ninside the poster's OWN timeline (default 90% through it). Screenshot-genre\ndestinations (CWS screenshots, the PH gallery) are the real page at that\nmoment, FULL BLEED: no zoom, no tilt, no browser bar, no padding (store\npolicy); --composed keeps the cut's camera and chrome instead. --set\npath=value overrides the doc in memory for every render here (the user's\nsets apply last). Store uploads stay manual: hand the human the kit\ndirectory, then vos validate <kit.json> re-measures every asset from its\nbytes against the channel specs.\nbrand writes the product's BRAND.md, witnessed: it reads /design.md when\nthe site publishes one (the convention beside /llms.txt: fonts, logo assets,\nan avoid list), /llms.txt for the name and the claim, then the page itself\nin a browser (the body ground, the surfaces, the h1 and body faces and inks,\nthe accent buttons and links agree on, theme-color, the icons, og:image).\nThe frontmatter carries the roles the poster family binds (bgA/bgB/bgC,\nink, accent, fontDisplay, logoUrl); the prose says where every value came\nfrom and quotes the site's own avoid list. Resolve the brand BEFORE any\nasset is authored; file it with vos recipe push BRAND.md --folder <slug>.\ndigest is how an agent SEES a recording before it cuts: writes digest/ with\ndigest.json (the moments the cursor track says matter — click clusters,\ntyping sessions, scroll runs, dwells, idle gaps, scene changes — each with\nsource+output extents, a normalized focus/rect you can copy into a zoom span,\nper-second motion, and the planners' proposals beside it), one FOOTAGE frame\n+ a crop around the target per moment, and sheet.png (the contact sheet).\nRead digest.json, then the sheet, then crops only where you must decide.\n--full/--crop set the long edge in px (your token budget; the done event\nestimates it). --transcript merges Whisper-shaped segments (SOURCE seconds)\nonto moments as \"said\". --style REPORTS a reference doc's style fields.\nvalidate <take> lints doc.json semantics (span overlap/bounds, normalized\n[0..1] zoom focus coords, export honesty) — schema in schema/doc.schema.json.\nactions from-agent-browser turns the walk an agent made in agent-browser\ninto actions.json, so a feature verified there becomes a take with no\nsecond script. Input: one record per command in agent-browser's own batch\nshape, {command:[…], …result} — a bare --json result does not say what ran,\nso wrap each call (the product-video skill has the one-line function) or\nkeep a batch's output. Refs (@e27) resolve through the last snapshot -i\nbefore them (-u gives links their href); what the recorder cannot follow\n(a shortcut key, a drag, a second open) is named in the output, never\ndropped. Then: vos record --actions actions.json --strict.\nopen serves the take and loads it into the studio (?take=<server>) —\ndoc.json edits arrive intact; a human can drag every zoom span. Keeps\nserving until Ctrl-C; --studio overrides the default http://localhost:6060.\n\npush/pull — the hosted iteration loop (credentials: --key, VOS_API_KEY, or\n~/.config/vos/credentials via vos login; origin via VOS_ORIGIN, default\nhttps://vos.so). A take push uploads the recording ONCE (content-addressed),\nlowers doc.json, and creates a private vos (first push asks; --yes for\nheadless) or a new version against the base in vos.json — a stale base\nprints the human's typed changelog and exits 1 (run pull, re-apply, push\nagain). A protected conflict means the human touched those nodes in the\nstudio: keep their values, or --override <id> ONLY when the user asked for\nthat exact change. ALWAYS pass --label (what you did, one line) and --note\n(why: the user's ask) — the version history reads as a conversation, and an\nunlabelled push is a turn the human cannot read. pull prints what changed\nsince your base and writes the head back (doc.json for takes, config.json\nfor programs, backup kept). ALWAYS pull before editing pushed work.\n\nrender/frames doc overrides — check any presentation on the product surface\nwithout hand-editing doc.json (the disk file is untouched; the patched doc is\nlint-gated, so a bad override fails like a bad doc.json):\n --set <path=value> patch any doc field, repeatable; value is JSON when it\n parses else a string (e.g. --set tilt[0].rx=8\n --set frame.padding=120 --set frame.browserBar.kind=mac-light)\n --frame <kind> (render) browser frame: macos|mac-dark|windows|windows-dark|minimal|none\n --background <url|slug> background media: a URL (kind inferred), or a backdrop slug from GET /api/backdrops\n (.webm/.mp4 = video @10s loop, image otherwise); \"none\" clears.\n On create/record/plan it is the frame a FRESH take opens on; absent, the set's\n first ready loop (the house backdrop the studio opens on), or a flat ground offline\n`\n\nasync function loadActions(file: string): Promise<ActionsFile> {\n const raw = JSON.parse(await readFile(file, 'utf8')) as unknown\n const errors = validateActions(raw)\n if (errors.length)\n throw new UsageError(`invalid actions file:\\n ${errors.join('\\n ')}`)\n return raw as ActionsFile\n}\n\n/**\n * --max-duration <seconds>: where the capture stops. Defaults to the\n * hosted recording cap so a CLI take is never longer than vos.so will host.\n */\n/**\n * The cap a take records under: `--max-duration` when given; else the\n * hosted cap read live from `GET /api/limits` (the caller's plan when a\n * key resolves); else the built-in number, said in words, because a take\n * longer than the platform's cap is refused at push time.\n */\nasync function maxDuration(\n flags: ParsedArgs['flags'],\n r: { log: (line: string) => void },\n): Promise<number> {\n if (hasFlag(flags, 'max-duration')) {\n const v = numFlag(flags, 'max-duration', defaultMaxDurationSeconds())\n if (!(v > 0)) throw new UsageError('--max-duration expects seconds above 0')\n return v\n }\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const live = await hostedRecordingCap(\n origin,\n resolveCredential(strFlag(flags, 'key')),\n )\n if (live) return live\n r.log(\n `note: could not read the hosted cap from ${origin}/api/limits; recording up to the built-in ${formatDurationCap(defaultMaxDurationSeconds())}`,\n )\n return defaultMaxDurationSeconds()\n}\n\nfunction strictReason(rec: {\n skipped: unknown[]\n navTimeout: boolean\n capped: boolean\n}): string {\n const parts = [`${rec.skipped.length} skipped step(s)`]\n if (rec.navTimeout) parts.push('networkidle timeout')\n if (rec.capped) parts.push('stopped at --max-duration')\n return parts.join(' + ')\n}\n\n/**\n * The backdrop a FRESH take opens on: `--background <slug|url|none>`, or\n * absent, the set's house pick from `GET /api/backdrops`. Read once per\n * command; a set out of reach is said in words and the take opens on a\n * flat ground rather than failing.\n */\nasync function takeBackdrop(\n flags: ParsedArgs['flags'],\n r: { log: (line: string) => void },\n): Promise<Backdrop | null> {\n const { backdrop, note } = await openingBackdrop(\n strFlag(flags, 'background'),\n platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n )\n if (note) r.log(`note: ${note}`)\n return backdrop\n}\n\nasync function cmdRecord(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const actionsPath = strFlag(flags, 'actions') ?? positionals[0]\n if (!actionsPath)\n throw new UsageError(\n 'vos record --actions actions.json [--url <url>] [--out take]',\n )\n const r = createReporter(flags.json === true)\n const actions = await loadActions(actionsPath)\n const url = strFlag(flags, 'url') ?? actions.url\n if (!url)\n throw new UsageError('no URL — set \"url\" in the actions file or pass --url')\n const outDir = resolve(strFlag(flags, 'out') ?? 'take')\n const backdrop = await takeBackdrop(flags, r)\n const maxDurationSeconds = await maxDuration(flags, r)\n\n if (existsSync(join(outDir, 'meta.json'))) {\n // A re-record replaces the FOOTAGE, never the cut. The previous\n // doc.json survives as doc.prev.json (the reuse base), actions.json and\n // vos.json stay put, and derived artifacts of the old footage clear.\n const { prevDoc, kept } = await prepareReRecord(outDir)\n r.log(\n `note: re-recording ${outDir} — kept ${kept.length ? kept.join(', ') : 'nothing'}` +\n (prevDoc\n ? '; apply the previous cut to the new footage with: vos plan ' +\n outDir +\n ' --reuse'\n : ''),\n )\n }\n await mkdir(outDir, { recursive: true })\n const paths = await ensureTakeDir(outDir)\n\n const browser = await launchBrowser()\n try {\n r.log('recording…')\n r.event({ event: 'phase', phase: 'record' })\n const rec = await recordTake(browser, url, actions, paths, r.log, {\n maxDurationSeconds: maxDurationSeconds,\n })\n r.event({ event: 'phase', phase: 'encode' })\n r.log('encoding…')\n const enc = await encodeRecording(browser, outDir, (p) =>\n r.event({ event: 'progress', phase: 'encode', fraction: p }),\n )\n r.event({ event: 'phase', phase: 'plan' })\n const plan = await planTake(outDir, { backdrop })\n const clicks = rec.events.filter((e) => e.type === 'down').length\n const strict = flags.strict === true\n const strictFail =\n strict && (rec.skipped.length > 0 || rec.navTimeout || rec.capped)\n const skippedNote = rec.skipped.length\n ? `\\n SKIPPED ${rec.skipped.length} step(s): ${rec.skipped.map((s) => `#${s.step} ${s.do} ${s.selector}`).join(', ')}`\n : ''\n r.done(\n {\n take: outDir,\n durationMs: rec.meta.durationMs,\n frames: rec.frames.length,\n events: rec.events.length,\n clicks,\n recordingBytes: enc.bytes,\n zoomSpans: plan.doc.zoom.length,\n skipped: rec.skipped,\n navTimeout: rec.navTimeout,\n freezes: rec.freezes,\n freezePct: rec.freezePct,\n capped: rec.capped,\n ...(strictFail ? { strictFailed: true } : {}),\n },\n strictFail\n ? `STRICT: take recorded but incomplete — ${strictReason(rec)}; fix the flow and re-record.${skippedNote}`\n : `Take ready: ${outDir}\\n ${(rec.meta.durationMs / 1000).toFixed(1)}s · ${rec.frames.length} frames · ${rec.events.length} cursor events · ${clicks} clicks · ${plan.doc.zoom.length} zoom spans planned · ${rec.freezePct}% frozen${rec.freezePct >= 25 ? ' ⚠ keep motion in frame or trim' : ''}${skippedNote}\\n Next: edit ${join(outDir, 'doc.json')} (optional), then: vos render ${outDir}`,\n )\n return strictFail ? EXIT_USAGE : EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\n/**\n * The one-shot verb of the `vos <product> create` namespace: record the flow,\n * auto-plan effects, render the video — one command, one browser session.\n * The take dir still lands on disk, so the full loop (frames → doc.json edit\n * → re-render) stays available afterwards. --strict aborts BEFORE rendering\n * when the recording is incomplete (skipped selector / networkidle timeout).\n */\nasync function cmdCreate(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const actionsPath = strFlag(flags, 'actions')\n if (!actionsPath) {\n throw new UsageError(\n 'vos create --actions actions.json [--url <url>] [--out take] [out.webm]',\n )\n }\n const r = createReporter(flags.json === true)\n const actions = await loadActions(actionsPath)\n const url = strFlag(flags, 'url') ?? actions.url\n if (!url)\n throw new UsageError('no URL — set \"url\" in the actions file or pass --url')\n const outDir = resolve(strFlag(flags, 'out') ?? 'take')\n const fmtRaw = strFlag(flags, 'format') ?? 'webm'\n if (fmtRaw !== 'webm' && fmtRaw !== 'mp4')\n throw new UsageError('--format must be webm or mp4')\n const format = fmtRaw\n const out = positionals[0] ?? join(outDir, `out.${format}`)\n const parallel = numFlag(flags, 'parallel', 1)\n if (!Number.isInteger(parallel) || parallel < 1 || parallel > 16) {\n throw new UsageError('--parallel expects an integer between 1 and 16')\n }\n const backdrop = await takeBackdrop(flags, r)\n const maxDurationSeconds = await maxDuration(flags, r)\n\n if (existsSync(join(outDir, 'meta.json'))) {\n // A re-record replaces the FOOTAGE, never the cut. The previous\n // doc.json survives as doc.prev.json (the reuse base), actions.json and\n // vos.json stay put, and derived artifacts of the old footage clear.\n const { prevDoc, kept } = await prepareReRecord(outDir)\n r.log(\n `note: re-recording ${outDir} — kept ${kept.length ? kept.join(', ') : 'nothing'}` +\n (prevDoc\n ? '; apply the previous cut to the new footage with: vos plan ' +\n outDir +\n ' --reuse'\n : ''),\n )\n }\n await mkdir(outDir, { recursive: true })\n const paths = await ensureTakeDir(outDir)\n\n const browser = await launchBrowser()\n try {\n r.log('recording…')\n r.event({ event: 'phase', phase: 'record' })\n const rec = await recordTake(browser, url, actions, paths, r.log, {\n maxDurationSeconds: maxDurationSeconds,\n })\n r.event({ event: 'phase', phase: 'encode' })\n r.log('encoding…')\n await encodeRecording(browser, outDir, (p) =>\n r.event({ event: 'progress', phase: 'encode', fraction: p }),\n )\n r.event({ event: 'phase', phase: 'plan' })\n await planTake(outDir, { backdrop })\n\n if (\n flags.strict === true &&\n (rec.skipped.length > 0 || rec.navTimeout || rec.capped)\n ) {\n r.done(\n {\n take: outDir,\n skipped: rec.skipped,\n navTimeout: rec.navTimeout,\n capped: rec.capped,\n strictFailed: true,\n rendered: false,\n },\n `STRICT: take recorded but incomplete — ${strictReason(rec)}; NOT rendering. Fix the flow and re-run, or render the partial take with: vos render ${outDir}`,\n )\n return EXIT_USAGE\n }\n\n const result = await renderTake(browser, outDir, out, {\n width: hasFlag(flags, 'width') ? numFlag(flags, 'width', 0) : undefined,\n height: hasFlag(flags, 'height')\n ? numFlag(flags, 'height', 0)\n : undefined,\n fps: hasFlag(flags, 'fps') ? numFlag(flags, 'fps', 30) : undefined,\n format,\n parallel,\n draft: flags.draft === true,\n overrides: {\n set: multi.set,\n frame: strFlag(flags, 'frame'),\n background: strFlag(flags, 'background'),\n origin: platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n },\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n onProgress: (p) =>\n r.event({ event: 'progress', phase: 'render', fraction: p }),\n })\n r.done(\n {\n take: outDir,\n ...result,\n skipped: rec.skipped,\n navTimeout: rec.navTimeout,\n freezes: rec.freezes,\n freezePct: rec.freezePct,\n ...(flags.draft === true ? { draft: true } : {}),\n },\n `Created ${result.out} (${(result.bytes / 1024).toFixed(0)} KB, ${result.width}x${result.height}@${result.fps}, ${result.duration.toFixed(1)}s, ${result.zoomSpans} zoom spans, ${result.clicks} click effects${result.audio ? ', audio' : ''}${flags.draft === true ? ', DRAFT' : ''})\\n take: ${outDir} — inspect with: vos frames ${outDir} --at-zooms; edit doc.json and re-render with: vos render ${outDir}`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdPlan(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const dir = positionals[0]\n if (!dir)\n throw new UsageError(\n 'vos plan <take> [--fresh] [--reuse [--from <doc.json>]] [--style <doc.json|vosId>]',\n )\n const r = createReporter(flags.json === true)\n if (flags.fresh === true) {\n await rm(join(dir, 'doc.json'), { force: true })\n r.log('note: --fresh discarded the existing doc.json')\n }\n // The re-render loop: --reuse applies a previous cut of the same\n // script to this take's new footage. Default source is the doc a\n // re-record preserved (doc.prev.json); --from names another.\n let reuse: { from: string; doc: ProjectDoc } | undefined\n if (flags.reuse === true) {\n const from = resolve(strFlag(flags, 'from') ?? join(dir, PREV_DOC_NAME))\n if (!existsSync(from)) {\n throw new UsageError(\n `--reuse: ${from} does not exist — a re-record into this take writes doc.prev.json, or pass --from <doc.json>`,\n )\n }\n reuse = {\n from,\n doc: JSON.parse(await readFile(from, 'utf8')) as ProjectDoc,\n }\n }\n const style = await resolveStyleRef(flags)\n // A refresh keeps the doc's own frame; only a FRESH doc opens on the\n // house backdrop, so the set is read only when there is no doc.json.\n const backdrop = existsSync(join(dir, 'doc.json'))\n ? null\n : await takeBackdrop(flags, r)\n const s = await planTake(dir, {\n ...(style ? { style } : {}),\n ...(reuse ? { reuse } : {}),\n backdrop,\n })\n const reuseLines = s.reuse\n ? `\\n reused ${s.reuse.from}: ${s.reuse.anchored} anchored + ${s.reuse.mapped} mapped span(s)` +\n (s.reuse.flagged.length\n ? `\\n flagged:\\n ${s.reuse.flagged.join('\\n ')}`\n : '')\n : ''\n r.done(\n {\n take: resolve(dir),\n fresh: s.fresh,\n cursorKept: s.cursorKept,\n zoomAuto: s.zoomAuto,\n zoomManual: s.zoomManual,\n duration: s.doc.source.meta.durationMs / 1000,\n ...(s.backdrop !== undefined ? { backdrop: s.backdrop } : {}),\n ...(s.styleFrom\n ? { styleFrom: s.styleFrom, styleFields: s.styleFields }\n : {}),\n ...(s.reuse ? { reuse: s.reuse } : {}),\n },\n `${s.reuse ? 'Reused' : s.fresh ? 'Planned' : 'Refreshed'} ${join(dir, 'doc.json')}: ${s.zoomAuto} auto + ${s.zoomManual} manual zoom spans${s.cursorKept ? '' : ' (cursor track dropped)'}${reuseLines}`,\n )\n return EXIT_OK\n}\n\nasync function cmdRender(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const dir = positionals[0]\n if (!dir)\n throw new UsageError(\n 'vos render <take> [out] [--width] [--height] [--fps] [--format] [--parallel]',\n )\n const r = createReporter(flags.json === true)\n const fmtRaw = strFlag(flags, 'format') ?? 'webm'\n if (fmtRaw !== 'webm' && fmtRaw !== 'mp4')\n throw new UsageError('--format must be webm or mp4')\n const format = fmtRaw\n const out = positionals[1] ?? join(dir, `out.${format}`)\n const parallel = numFlag(flags, 'parallel', 1)\n if (!Number.isInteger(parallel) || parallel < 1 || parallel > 16) {\n throw new UsageError('--parallel expects an integer between 1 and 16')\n }\n let range: [number, number] | undefined\n const rangeRaw = strFlag(flags, 'range')\n if (rangeRaw !== undefined) {\n const m = /^(\\d+(?:\\.\\d+)?)\\.\\.(\\d+(?:\\.\\d+)?)$/.exec(rangeRaw)\n if (!m)\n throw new UsageError(\n '--range expects a..b in OUTPUT seconds (e.g. --range 4..8)',\n )\n range = [Number(m[1]), Number(m[2])]\n if (range[1] <= range[0])\n throw new UsageError('--range end must be > start')\n }\n\n const browser = await launchBrowser()\n try {\n const result = await renderTake(browser, dir, out, {\n width: hasFlag(flags, 'width') ? numFlag(flags, 'width', 0) : undefined,\n height: hasFlag(flags, 'height')\n ? numFlag(flags, 'height', 0)\n : undefined,\n fps: hasFlag(flags, 'fps') ? numFlag(flags, 'fps', 30) : undefined,\n format,\n parallel,\n range,\n draft: flags.draft === true,\n overrides: {\n set: multi.set,\n frame: strFlag(flags, 'frame'),\n background: strFlag(flags, 'background'),\n origin: platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n },\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n onProgress: (p) =>\n r.event({ event: 'progress', phase: 'render', fraction: p }),\n })\n r.done(\n {\n ...result,\n ...(range ? { range } : {}),\n ...(flags.draft === true ? { draft: true } : {}),\n },\n `Wrote ${result.out} (${(result.bytes / 1024).toFixed(0)} KB, ${result.width}x${result.height}@${result.fps}, ${result.duration.toFixed(1)}s, ${result.zoomSpans} zoom spans, ${result.clicks} click effects${result.audio ? ', audio' : ''}${result.chunks > 1 ? `, ${result.chunks} parallel chunks` : ''}${range ? `, range ${range[0]}..${range[1]}s` : ''}${flags.draft === true ? ', DRAFT' : ''})`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdFrames(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const dir = positionals[0]\n if (!dir)\n throw new UsageError(\n 'vos frames <take> [--times 0,50%,100%] [--frame <t>] [--at-zooms] [--size WxH] [--out dir]',\n )\n const r = createReporter(flags.json === true)\n\n const take = await loadTake(dir)\n if (!take.doc) throw new UsageError(`${dir} has no doc.json — run plan first`)\n\n let size: { width: number; height: number } | undefined\n const sizeRaw = strFlag(flags, 'size')\n if (sizeRaw !== undefined) {\n const m = /^(\\d+)x(\\d+)$/.exec(sizeRaw)\n if (!m) throw new UsageError('--size expects WxH (e.g. --size 1280x800)')\n size = { width: Number(m[1]), height: Number(m[2]) }\n }\n\n // Duration for % times: output-time total (trims/speed applied).\n const duration = totalDuration(ratedSegments(take.doc))\n const frameRaw = strFlag(flags, 'frame')\n const timesRaw = strFlag(flags, 'times')\n const atZooms = flags['at-zooms'] === true\n const atMoments = flags['at-moments'] === true\n let times: number[]\n try {\n times =\n frameRaw !== undefined\n ? parseTimes(frameRaw, duration)\n : timesRaw !== undefined\n ? parseTimes(timesRaw, duration)\n : atZooms || atMoments\n ? []\n : parseTimes('0,25%,50%,75%,100%', duration)\n } catch (e) {\n throw new UsageError(e instanceof Error ? e.message : String(e))\n }\n\n const browser = await launchBrowser()\n try {\n r.event({ event: 'phase', phase: 'frames' })\n const result = await framesTake(browser, dir, {\n times,\n atZooms,\n atMoments,\n width: size?.width,\n height: size?.height,\n outDir: strFlag(flags, 'out'),\n // NOTE: no --frame alias here — `frames --frame <t>` is the time selector.\n // Set the browser frame via --set frame.browserBar.kind=mac-light.\n overrides: {\n set: multi.set,\n background: strFlag(flags, 'background'),\n origin: platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n },\n })\n const index = await writeIndexJson(result)\n r.done(\n {\n outDir: result.outDir,\n index,\n width: result.width,\n height: result.height,\n duration: result.duration,\n frames: result.frames,\n },\n `Wrote ${result.frames.length} still(s) to ${result.outDir} (${result.width}x${result.height})\\n ${result.frames.map((f) => `${f.time.toFixed(2)}s${f.kind === 'zoom' ? ' [zoom apex]' : f.kind === 'moment' ? ` [${f.momentId}]` : ''} → ${f.file}`).join('\\n ')}`,\n )\n return EXIT_OK\n } finally {\n await browser.close()\n }\n}\n\nasync function cmdDeliver(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const dir = positionals[0]\n const toRaw = strFlag(flags, 'to')\n if (!dir || !toRaw)\n throw new UsageError(\n 'vos deliver <take> --to cws,producthunt,x,linkedin,og,github,youtube (or all) [--release v2.1] [--out dir] [--times a,b] [--range a..b] [--json]\\n(hosted work: vos pull <id> --media first — deliver runs on a local take)',\n )\n const r = createReporter(flags.json === true)\n if (!isTakeDir(dir))\n throw new UsageError(\n `${dir} is not a take directory (no doc.json) — for hosted work run: vos pull <vosId> --media`,\n )\n let channels: string[]\n try {\n channels = resolveChannels(toRaw)\n } catch (e) {\n throw new UsageError(e instanceof Error ? e.message : String(e))\n }\n let range: [number, number] | undefined\n const rangeRaw = strFlag(flags, 'range')\n if (rangeRaw !== undefined) {\n const m = /^(\\d+(?:\\.\\d+)?)\\.\\.(\\d+(?:\\.\\d+)?)$/.exec(rangeRaw)\n if (!m)\n throw new UsageError(\n '--range expects a..b in OUTPUT seconds (e.g. --range 4..24)',\n )\n range = [Number(m[1]), Number(m[2])]\n if (range[1] <= range[0])\n throw new UsageError('--range end must be > start')\n }\n const take = await loadTake(dir)\n if (!take.doc) throw new UsageError(`${dir} has no doc.json — run plan first`)\n const duration = totalDuration(ratedSegments(take.doc))\n const timesRaw = strFlag(flags, 'times')\n let times: number[] | undefined\n if (timesRaw !== undefined) {\n try {\n times = parseTimes(timesRaw, duration)\n } catch (e) {\n throw new UsageError(e instanceof Error ? e.message : String(e))\n }\n }\n const parallel = numFlag(flags, 'parallel', 1)\n if (!Number.isInteger(parallel) || parallel < 1 || parallel > 16) {\n throw new UsageError('--parallel expects an integer between 1 and 16')\n }\n\n // The poster leg: card-genre destinations render from the maker's poster\n // program (a local config.json, or a hosted vos id read with the key\n // ladder) with this release's shot baked in.\n let poster: { config: Record<string, unknown>; from: string } | undefined\n const posterRef = strFlag(flags, 'poster')\n if (posterRef !== undefined) {\n if (existsSync(posterRef)) {\n poster = {\n from: resolve(posterRef),\n config: JSON.parse(await readFile(posterRef, 'utf8')) as Record<\n string,\n unknown\n >,\n }\n } else {\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = await resolveCredential(strFlag(flags, 'key'))\n const res = (await apiJson(origin, `/api/vos/${posterRef}/config`, {\n key,\n })) as { config?: Record<string, unknown> }\n if (!res.config)\n throw new UsageError(\n `--poster ${posterRef}: not a file on disk and the platform returned no config`,\n )\n poster = { from: posterRef, config: res.config }\n }\n }\n\n const browser = await launchBrowser()\n try {\n const result = await deliverTake(browser, dir, {\n channels,\n outDir: strFlag(flags, 'out'),\n release: strFlag(flags, 'release'),\n times,\n range,\n parallel,\n poster,\n posterTime: hasFlag(flags, 'poster-time')\n ? numFlag(flags, 'poster-time', 0)\n : undefined,\n shotTime: hasFlag(flags, 'shot-time')\n ? numFlag(flags, 'shot-time', 0)\n : undefined,\n composed: hasFlag(flags, 'composed'),\n overrides: {\n set: multi.set,\n background: strFlag(flags, 'background'),\n origin: platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n },\n onPhase: (phase) => {\n r.log(`${phase}…`)\n r.event({ event: 'phase', phase })\n },\n onProgress: (p) =>\n r.event({ event: 'progress', phase: 'deliver', fraction: p }),\n })\n const { kit } = result\n const assetLines = kit.assets.map(\n (a) =>\n `${a.destination} → ${a.path} (${a.w}x${a.h}, ${(a.bytes / 1024).toFixed(0)} KB${a.seconds !== null ? `, ${a.seconds.toFixed(1)}s` : ''}${a.frameTime !== null ? `, frame ${a.frameTime.toFixed(2)}s` : ''}${a.source === 'poster' ? ', poster' : ''})`,\n )\n const skippedLines = kit.skipped.map((s) => `skipped: ${s}`)\n r.done(\n {\n outDir: result.outDir,\n kit: result.kitFile,\n assets: kit.assets,\n skipped: kit.skipped,\n },\n `Wrote ${kit.assets.length} asset(s) + kit.json to ${result.outDir}` +\n (assetLines.length ? `\\n ${assetLines.join('\\n ')}` : '') +\n (skippedLines.length ? `\\n ${skippedLines.join('\\n ')}` : '') +\n `\\nStore uploads stay manual: hand the human this directory and the manifest.`,\n )\n return kit.assets.length > 0 ? EXIT_OK : EXIT_ERROR\n } finally {\n await browser.close()\n }\n}\n\n/**\n * `--style <doc.json|take dir|vosId>`: the reference doc whose style fields\n * `vos plan` copies and `vos digest` reports. A file or take dir on\n * disk, else a hosted take's head doc read with the key ladder.\n */\nasync function resolveStyleRef(\n flags: ParsedArgs['flags'],\n): Promise<{ from: string; doc: ProjectDoc } | null> {\n const styleRef = strFlag(flags, 'style')\n if (!styleRef) return null\n const file = existsSync(styleRef)\n ? resolve(\n styleRef,\n existsSync(join(styleRef, 'doc.json')) ? 'doc.json' : '',\n )\n : null\n if (file && existsSync(file)) {\n return {\n from: file,\n doc: JSON.parse(await readFile(file, 'utf8')) as ProjectDoc,\n }\n }\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = resolveCredential(strFlag(flags, 'key'))\n const meta = await apiJson(origin, `/api/vos/${styleRef}`, { key })\n const head = (meta.body.vos as { currentVersionId?: string } | undefined)\n ?.currentVersionId\n if (meta.status !== 200 || !head)\n throw new UsageError(\n `--style: ${styleRef} is neither a doc.json nor a vos I can read`,\n )\n const doc = await apiJson(\n origin,\n `/api/vos/${styleRef}/versions/${head}/doc`,\n { key },\n )\n if (doc.status !== 200)\n throw new UsageError(`--style: ${styleRef} carries no doc (is it a take?)`)\n return {\n from: `${origin}/vos/${styleRef}`,\n doc: migrateHostedDoc(doc.body) as unknown as ProjectDoc,\n }\n}\n\nasync function cmdDigest(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const dir = positionals[0]\n if (!dir)\n throw new UsageError(\n 'vos digest <take> [--out dir] [--full 960] [--crop 640] [--no-frames] [--transcript <file>] [--style <doc.json|vosId>]',\n )\n const r = createReporter(flags.json === true)\n const take = await loadTake(dir)\n if (!take.doc) throw new UsageError(`${dir} has no doc.json — run plan first`)\n\n const transcriptPath = strFlag(flags, 'transcript')\n const transcript = transcriptPath\n ? parseTranscript(JSON.parse(await readFile(transcriptPath, 'utf8')))\n : null\n\n const style = await resolveStyleRef(flags)\n\n const noFrames = flags['no-frames'] === true\n let browser = null\n if (!noFrames) browser = await launchBrowser()\n try {\n r.event({ event: 'phase', phase: 'digest' })\n const result = await digestTake(browser, dir, {\n outDir: strFlag(flags, 'out'),\n full: strFlag(flags, 'full') ? numFlag(flags, 'full', 0) : undefined,\n crop: strFlag(flags, 'crop') ? numFlag(flags, 'crop', 0) : undefined,\n frames: !noFrames,\n transcript,\n style,\n })\n const d = result.digest\n const kinds = d.moments.reduce<Partial<Record<string, number>>>(\n (acc, m) => {\n acc[m.kind] = (acc[m.kind] ?? 0) + 1\n return acc\n },\n {},\n )\n r.done(\n {\n file: result.file,\n outDir: result.outDir,\n moments: d.moments.length,\n kinds,\n frames: d.images.full,\n crops: d.images.crop,\n sheet: d.images.sheet ? join(result.outDir, d.images.sheet) : null,\n scenes: kinds.scene ?? 0,\n sourceDuration: d.take.sourceDuration,\n outputDuration: d.take.outputDuration,\n hasCursor: d.take.hasCursor,\n tokensEstimate: d.images.tokensEstimate,\n bytes: result.bytes,\n },\n `Wrote ${result.file} — ${d.moments.length} moments (${Object.entries(\n kinds,\n )\n .map(([k, n]) => `${n} ${k}`)\n .join(', ')}), ${d.images.full} frames + ${d.images.crop} crops` +\n (d.images.sheet ? `, sheet.png` : '') +\n ` — ~${d.images.tokensEstimate} image tokens to read them all` +\n (d.take.hasCursor\n ? ''\n : '\\n no cursor track: moments are head/tail/scenes only — pace by activity, zoom only where the ask names a place') +\n `\\n Read digest.json, then the sheet, then a crop only where you must decide.`,\n )\n return EXIT_OK\n } finally {\n if (browser) await browser.close()\n }\n}\n\nasync function cmdOpen(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const dir = positionals[0]\n if (!dir) throw new UsageError('vos open <take> [--studio <url>]')\n const r = createReporter(flags.json === true)\n const take = await loadTake(dir) // validates it IS a take (meta.json)\n if (!existsSync(take.paths.recording)) {\n throw new UsageError(`${dir} has no recording.webm — re-run record`)\n }\n\n const studio = (strFlag(flags, 'studio') ?? 'http://localhost:6060').replace(\n /\\/+$/,\n '',\n )\n const server = await startTakeServer(resolve(dir), {})\n // /studio is the one editor route (older CLIs that open\n // /voila/studio ride a query-preserving 301 forever).\n const url = `${studio}/studio?take=${encodeURIComponent(server.base)}`\n r.event({ event: 'open', server: server.base, url })\n r.log(`take served at ${server.base}`)\n process.stdout.write(flags.json === true ? '' : `${url}\\n`)\n if (flags.print !== true) {\n r.log('opening the studio… (Ctrl-C to stop serving)')\n // Best-effort browser launch; the printed URL is the contract.\n const opener =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start'\n : 'xdg-open'\n const { exec } = await import('node:child_process')\n exec(`${opener} ${JSON.stringify(url)}`, () => {})\n } else {\n r.log('serving (— --print: not launching a browser; Ctrl-C to stop)')\n }\n\n // Serve until interrupted — the studio streams the recording from us.\n await new Promise<void>((resolvePromise) => {\n const stop = () => {\n server.close()\n resolvePromise()\n }\n process.once('SIGINT', stop)\n process.once('SIGTERM', stop)\n })\n return EXIT_OK\n}\n\nasync function cmdValidate(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const target = positionals[0]\n if (!target) throw new UsageError('vos validate <actions.json|take>')\n const r = createReporter(flags.json === true)\n // A kit manifest (deliver's output, or a hand-assembled PR kit): every\n // asset re-measured from its bytes against the channel specs.\n const kitTarget = target.endsWith('kit.json')\n ? target\n : existsSync(join(target, 'kit.json')) && !isTakeDir(target)\n ? join(target, 'kit.json')\n : null\n if (kitTarget) {\n const verdict = await validateKit(kitTarget)\n const tail = verdict.warnings.length\n ? `\\n warnings:\\n ${verdict.warnings.join('\\n ')}`\n : ''\n if (!verdict.valid) {\n r.done(\n { ...verdict, target: kitTarget },\n `${kitTarget}:\\n ${verdict.problems.join('\\n ')}${tail}`,\n )\n return EXIT_ERROR\n }\n r.done(\n { ...verdict, target: kitTarget },\n `${kitTarget}: ${verdict.measured.length} asset(s) match their bytes and their specs${tail}`,\n )\n return EXIT_OK\n }\n if (target.endsWith('.json')) {\n await loadActions(target)\n r.done({ valid: true, target }, `${target}: valid actions file`)\n return EXIT_OK\n }\n // A PROGRAM directory: config.json plus, optionally, a program\n // document — lint the document's shared layers against the program.\n if (!isTakeDir(target) && existsSync(join(target, 'config.json'))) {\n const parsed = JSON.parse(\n await readFile(join(target, 'config.json'), 'utf8'),\n ) as unknown\n const pre = preflightConfig(parsed)\n const problems = pre.ok ? [] : pre.issues.map((i) => `config.json: ${i}`)\n const warnings: string[] = []\n const doc = pre.config ? await readProgramDoc(target, pre.config) : null\n if (doc) {\n const lint = lintDoc(doc as never)\n problems.push(...lint.problems.map((p) => `doc.json: ${p}`))\n warnings.push(...lint.warnings.map((w) => `doc.json: ${w}`))\n }\n {\n const urls = [\n ...collectConfigMediaUrls(pre.config ?? parsed),\n ...collectDocMediaUrls(doc),\n ]\n const probe = mediaProbeLints(await probeMediaUrls([...new Set(urls)]))\n problems.push(...probe.problems)\n warnings.push(...probe.warnings)\n }\n if (problems.length) {\n r.done(\n { valid: false, target, problems, warnings },\n `${target}:\\n ${problems.join('\\n ')}${warnings.length ? `\\n warnings:\\n ${warnings.join('\\n ')}` : ''}`,\n )\n return EXIT_ERROR\n }\n r.done(\n { valid: true, target, warnings, doc: !!doc },\n `${target}: program${doc ? ' + document' : ''} is valid${warnings.length ? `\\n warnings:\\n ${warnings.join('\\n ')}` : ''}`,\n )\n return EXIT_OK\n }\n const take = await loadTake(target)\n const problems: string[] = []\n const warnings: string[] = []\n if (!existsSync(take.paths.recording))\n problems.push('missing recording.webm (re-run record)')\n if (!take.doc) problems.push('missing doc.json (run plan)')\n if (take.doc) {\n const lint = lintDoc(take.doc)\n problems.push(...lint.problems.map((p) => `doc.json: ${p}`))\n warnings.push(...lint.warnings.map((w) => `doc.json: ${w}`))\n const probe = mediaProbeLints(\n await probeMediaUrls(collectDocMediaUrls(take.doc)),\n )\n problems.push(...probe.problems)\n warnings.push(...probe.warnings)\n }\n if (problems.length) {\n r.done(\n { valid: false, target, problems, warnings },\n `${target}:\\n ${problems.join('\\n ')}${warnings.length ? `\\n warnings:\\n ${warnings.join('\\n ')}` : ''}`,\n )\n return EXIT_ERROR\n }\n r.done(\n { valid: true, target, warnings },\n `${target}: take is complete and renderable${warnings.length ? `\\n warnings:\\n ${warnings.join('\\n ')}` : ''}`,\n )\n return EXIT_OK\n}\n\nasync function cmdPush(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const dir = positionals[0]\n if (!dir)\n throw new UsageError(\n 'vos push <take> [--title|--label|--note|--folder|--override|--yes|--key|--api]',\n )\n const r = createReporter(flags.json === true)\n // Index access is typed present but is runtime-optional — pushTake guards.\n const overrides = multi.override\n const result = await pushTake(\n resolve(dir),\n {\n key: strFlag(flags, 'key'),\n api: strFlag(flags, 'api'),\n origin: strFlag(flags, 'origin'),\n yes: flags.yes === true,\n title: strFlag(flags, 'title'),\n label: strFlag(flags, 'label'),\n note: strFlag(flags, 'note'),\n folder: strFlag(flags, 'folder'),\n overrides,\n },\n r,\n )\n r.done(\n { ...result },\n `pushed v${result.versionNumber} → vos ${result.vosId}\\n review: https://vos.so/vos/${result.vosId}\\n studio: https://vos.so/studio?vos=${result.vosId}`,\n )\n return EXIT_OK\n}\n\nasync function cmdPull(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS, MULTI_FLAGS)\n const dir = positionals[0] ?? '.'\n const r = createReporter(flags.json === true)\n const result = await pullTake(\n resolve(dir),\n {\n key: strFlag(flags, 'key'),\n api: strFlag(flags, 'api'),\n origin: strFlag(flags, 'origin'),\n vos: strFlag(flags, 'vos'),\n media: flags.media === true,\n },\n r,\n )\n const mediaLine = result.media\n ? result.media.downloaded.length\n ? ` + ${result.media.downloaded.map((m) => m.file).join(', ')} (footage home — digest/frames/render run here now)`\n : result.media.kept.length\n ? ` (footage already here: ${result.media.kept.join(', ')})`\n : ' (no hosted media on this doc)'\n : ''\n r.done(\n { ...result },\n (result.changed\n ? `pulled v${result.versionNumber ?? '?'} into doc.json — your edit loop continues from the human's version`\n : 'up to date') + mediaLine,\n )\n return EXIT_OK\n}\n\n/** Entry point — the delegation contract for @vosjs/cli: the host forwards\n every non-engine verb here (`vos <verb>`; `vos voila <verb>` stays a\n hidden alias until public launch). The exported `manifest` (index.ts)\n tells the host which verbs exist and how to summarize them in help. */\nexport async function run(argv: string[]): Promise<number> {\n const [cmd, ...rest] = argv\n try {\n if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {\n process.stdout.write(HELP)\n return cmd ? EXIT_OK : EXIT_USAGE\n }\n switch (cmd) {\n case 'create':\n return await cmdCreate(rest)\n case 'record':\n return await cmdRecord(rest)\n case 'plan':\n return await cmdPlan(rest)\n case 'render':\n return await cmdRender(rest)\n case 'frames':\n return await cmdFrames(rest)\n case 'deliver':\n return await cmdDeliver(rest)\n case 'digest':\n return await cmdDigest(rest)\n case 'open':\n return await cmdOpen(rest)\n case 'validate':\n return await cmdValidate(rest)\n case 'fetch':\n return await cmdFetch(rest)\n case 'duplicate':\n return await cmdDuplicate(rest)\n case 'login':\n return await cmdLogin(rest)\n case 'push': {\n // Polymorphic by the deterministic sniff: a take DIRECTORY (doc.json)\n // pushes recording + doc; anything else is a program config push.\n const target = rest.find((a) => !a.startsWith('-'))\n if (target && isTakeDir(target)) {\n if (rest.includes('--claimable')) {\n throw new UsageError(\n '--claimable pushes are PROGRAMS only (a config.json) — takes carry recordings, which need an account: vos login, then vos push',\n )\n }\n return await cmdPush(rest)\n }\n return await cmdPushProgram(rest)\n }\n case 'pull': {\n const target = rest.find((a) => !a.startsWith('-')) ?? '.'\n return isTakeDir(target)\n ? await cmdPull(rest)\n : await cmdPullProgram(rest)\n }\n case 'folder':\n return await cmdFolder(rest)\n case 'asset':\n return await cmdAsset(rest)\n case 'recipe':\n return await cmdRecipe(rest)\n case 'brand':\n return await cmdBrand(rest)\n case 'actions':\n return await cmdActions(rest)\n default:\n throw new UsageError(`unknown command \"${cmd}\" — run: vos help`)\n }\n } catch (e) {\n if (e instanceof UsageError) {\n process.stderr.write(`usage error: ${e.message}\\n`)\n return EXIT_USAGE\n }\n if (e instanceof BrowserUnavailableError) {\n process.stderr.write(`${e.message}\\n`)\n return EXIT_NO_BROWSER\n }\n process.stderr.write(\n `error: ${e instanceof Error ? e.message : String(e)}\\n`,\n )\n return EXIT_ERROR\n }\n}\n","/** Minimal argv parser — mirrors @vosjs/cli's conventions. */\nexport interface ParsedArgs {\n positionals: string[]\n flags: Record<string, string | true>\n /** Values of flags declared repeatable (multiFlags) — accumulated in order. */\n multi: Record<string, string[]>\n}\n\nexport class UsageError extends Error {}\n\nexport function parseArgs(\n argv: string[],\n booleanFlags: ReadonlySet<string>,\n multiFlags: ReadonlySet<string> = new Set(),\n): ParsedArgs {\n const positionals: string[] = []\n const flags: Record<string, string | true> = {}\n const multi: Record<string, string[]> = {}\n const put = (name: string, value: string): void => {\n if (multiFlags.has(name)) (multi[name] ??= []).push(value)\n else flags[name] = value\n }\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 put(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 if (i + 1 >= argv.length || argv[i + 1].startsWith('--')) {\n throw new UsageError(`--${name} expects a value`)\n }\n put(name, argv[i + 1])\n i++\n continue\n }\n positionals.push(arg)\n }\n return { positionals, flags, multi }\n}\n\nexport function numFlag(\n flags: ParsedArgs['flags'],\n name: string,\n fallback: number,\n): number {\n const v = flags[name]\n if (typeof v !== 'string') return fallback\n const n = Number(v)\n if (!Number.isFinite(n))\n throw new UsageError(`--${name} expects a number, got \"${v}\"`)\n return n\n}\n\n/** String flag value, or undefined when absent (or boolean). */\nexport function strFlag(\n flags: ParsedArgs['flags'],\n name: string,\n): string | undefined {\n const v = flags[name]\n return typeof v === 'string' ? v : undefined\n}\n\nexport function hasFlag(flags: ParsedArgs['flags'], name: string): boolean {\n return Object.prototype.hasOwnProperty.call(flags, name)\n}\n","/** Output conventions — logs on stderr, results on stdout, --json NDJSON. */\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 log: (msg: string) => void\n event: (obj: Record<string, unknown>) => void\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 * The action script — the declarative recipe an agent (or human) writes to\n * drive a take. Small on purpose: selectors + a handful of verbs. The recorder\n * executes it with humanized cursor motion and synthesizes the CursorTrack\n * from its own dispatches.\n */\nexport interface ActionsFile {\n /** Page to record. `--url` overrides. */\n url?: string\n /** Recording viewport in CSS px (default 1280x720). */\n viewport?: { width: number; height: number }\n steps: ActionStep[]\n}\n\nexport type ActionStep = (\n | { do: 'wait'; ms: number }\n | { do: 'hover'; selector: string; ms?: number }\n | { do: 'click'; selector: string }\n /**\n * Type into `selector`. The recorder clicks the field first, which is what\n * opens the typing zoom on it; `focus: false` types into the field as it is\n * already focused, for a keystroke that follows earlier typing (a submitting\n * Enter) rather than starting it — a second click there rings a click effect\n * on empty space beside the text.\n */\n | {\n do: 'type'\n selector: string\n text: string\n delayMs?: number\n focus?: boolean\n }\n | { do: 'scroll'; dy: number }\n | { do: 'move'; x: number; y: number }\n /**\n * Press-move-release — real edits (drag an element on the stage canvas,\n * slide a range input, move a timeline clip). Start = the selector's center\n * when given, else (x, y); end = (tx, ty); eased over ms (default 700).\n */\n | {\n do: 'drag'\n selector?: string\n x?: number\n y?: number\n tx: number\n ty: number\n ms?: number\n }\n) & {\n /**\n * Optional stable identity: anchors in doc.json name a step by this\n * id (else by index), so a step can move or gain neighbours across script\n * edits without breaking the cut anchored to it. Unique when present.\n */\n id?: string\n}\n\nconst VERBS = new Set([\n 'wait',\n 'hover',\n 'click',\n 'type',\n 'scroll',\n 'move',\n 'drag',\n])\n\n/** Structural validation with actionable messages. Returns [] when valid. */\nexport function validateActions(value: unknown): string[] {\n const errors: string[] = []\n if (typeof value !== 'object' || value === null)\n return ['actions file must be a JSON object']\n const obj = value as Record<string, unknown>\n if (obj.url !== undefined && typeof obj.url !== 'string')\n errors.push('url must be a string')\n if (obj.viewport !== undefined) {\n const v: unknown = obj.viewport\n if (typeof v !== 'object' || v === null) {\n errors.push('viewport must be { width, height }')\n } else {\n const vp = v as Record<string, unknown>\n if (typeof vp.width !== 'number' || typeof vp.height !== 'number') {\n errors.push('viewport must be { width, height }')\n }\n }\n }\n if (!Array.isArray(obj.steps) || obj.steps.length === 0) {\n errors.push('steps must be a non-empty array')\n return errors\n }\n const seenIds = new Set<string>()\n obj.steps.forEach((raw, i) => {\n const at = `steps[${i}]`\n if (typeof raw !== 'object' || raw === null) {\n errors.push(`${at}: must be an object`)\n return\n }\n const s = raw as Record<string, unknown>\n if (typeof s.do !== 'string' || !VERBS.has(s.do)) {\n errors.push(`${at}: \"do\" must be one of ${[...VERBS].join(', ')}`)\n return\n }\n if (s.id !== undefined) {\n if (typeof s.id !== 'string' || !s.id.trim()) {\n errors.push(`${at}: id must be a non-empty string`)\n } else if (seenIds.has(s.id)) {\n errors.push(\n `${at}: duplicate id \"${s.id}\" — an anchor could not tell the two steps apart`,\n )\n } else {\n seenIds.add(s.id)\n }\n }\n const needSelector = s.do === 'hover' || s.do === 'click' || s.do === 'type'\n if (needSelector && typeof s.selector !== 'string')\n errors.push(`${at}: ${s.do} needs a selector`)\n if (s.do === 'wait' && typeof s.ms !== 'number')\n errors.push(`${at}: wait needs ms`)\n if (s.do === 'type' && typeof s.text !== 'string')\n errors.push(`${at}: type needs text`)\n if (\n s.do === 'type' &&\n s.focus !== undefined &&\n typeof s.focus !== 'boolean'\n )\n errors.push(`${at}: type focus must be true or false`)\n if (s.do === 'scroll' && typeof s.dy !== 'number')\n errors.push(`${at}: scroll needs dy`)\n if (\n s.do === 'move' &&\n (typeof s.x !== 'number' || typeof s.y !== 'number')\n ) {\n errors.push(`${at}: move needs x and y (CSS px)`)\n }\n if (s.do === 'drag') {\n if (typeof s.tx !== 'number' || typeof s.ty !== 'number') {\n errors.push(`${at}: drag needs tx and ty (CSS px)`)\n }\n const hasStart =\n typeof s.selector === 'string' ||\n (typeof s.x === 'number' && typeof s.y === 'number')\n if (!hasStart)\n errors.push(\n `${at}: drag needs a selector OR x and y as the start point`,\n )\n }\n })\n return errors\n}\n","/**\n * Semantic lints for a take's doc.json — the agent-editable ProjectDoc surface.\n * Mirrors schema/doc.schema.json (keep the two in sync): the schema documents\n * the shape for agents/editors; these lints enforce the semantic contracts a\n * schema can't (overlap, footage bounds, the normalized-coords trap).\n *\n * The input is UNTRUSTED JSON an agent may have hand-edited — every access is\n * guarded, hence the `unknown`-based reads despite the ProjectDoc signature.\n *\n * `problems` break or visibly corrupt a render; `warnings` are honesty/taste\n * notes (footage upscaling, sub-minimum spans) that still render fine.\n */\nimport {\n CAM_SIZE_MAX,\n CAM_SIZE_MIN,\n CAM_SPAN_MIN,\n EXPORT_RESOLUTION_OPTIONS,\n SPEED_RATE_MAX,\n SPEED_RATE_MIN,\n TILT_DEG_MAX,\n TILT_SPAN_MIN,\n ZOOM_LEVEL_MAX,\n ZOOM_LEVEL_MIN,\n ZOOM_SPAN_MIN,\n docCardLayout,\n ratedSegments,\n recommendedExportResolution,\n spanOutputExtent,\n zoomCoversRect,\n} from '@vosjs/studio-core'\nimport { TYPEFACE_CATALOG, findFontFamily, findTypeface } from '@vosjs/shared'\nimport type {\n ExportResolution,\n ProjectDoc,\n StudioDoc,\n} from '@vosjs/studio-core'\n\nexport interface DocLintResult {\n problems: string[]\n warnings: string[]\n}\n\nconst EPS = 1e-3\n\ntype Json = Record<string, unknown>\n\nconst isNum = (v: unknown): v is number =>\n typeof v === 'number' && Number.isFinite(v)\nconst isObj = (v: unknown): v is Json => typeof v === 'object' && v !== null\n\n/** Array field → object entries (non-arrays/non-objects handled by callers). */\nconst entries = (v: unknown): Json[] =>\n Array.isArray(v) ? v.filter(isObj) : []\n\nconst spanName = (label: string, s: Json): string =>\n `${label} ${typeof s.id === 'string' ? s.id : `@${String(s.in)}`}`\n\n/** Per-span transition speed (zoom/tilt/camMotion). */\nconst TRANSITION_SPEEDS = ['instant', 'fast', 'smooth', 'slow']\nfunction checkTransition(s: Json, name: string, problems: string[]): void {\n if (\n s.transition !== undefined &&\n !TRANSITION_SPEEDS.includes(s.transition as string)\n ) {\n problems.push(\n `${name}: transition must be ${TRANSITION_SPEEDS.join('|')} (got ${String(s.transition)})`,\n )\n }\n}\n\n/**\n * A step anchor is metadata for `vos plan --reuse` — never read by\n * lowering — but a malformed one silently loses the re-record tie, so it\n * lints like everything else: in words, at the span that carries it.\n */\nfunction checkAnchor(s: Json, name: string, problems: string[]): void {\n if (s.anchor === undefined) return\n if (!isObj(s.anchor)) {\n problems.push(`${name}: anchor must be { step, at?, offset? }`)\n return\n }\n const a = s.anchor\n if (\n typeof a.step !== 'string' &&\n !(isNum(a.step) && Number.isInteger(a.step) && a.step >= 0)\n ) {\n problems.push(\n `${name}: anchor.step must be a step id (string) or index (integer ≥ 0)`,\n )\n }\n if (a.at !== undefined && a.at !== 'start' && a.at !== 'end') {\n problems.push(`${name}: anchor.at must be \"start\" or \"end\"`)\n }\n if (a.offset !== undefined && !isNum(a.offset)) {\n problems.push(`${name}: anchor.offset must be a number (seconds)`)\n }\n}\n\nfunction checkSpanList(\n list: Json[],\n label: string,\n duration: number,\n problems: string[],\n): void {\n const sorted = [...list].sort(\n (a, b) => (isNum(a.in) ? a.in : 0) - (isNum(b.in) ? b.in : 0),\n )\n for (const s of sorted) {\n const name = spanName(label, s)\n checkAnchor(s, name, problems)\n if (!isNum(s.in) || !isNum(s.out)) {\n problems.push(`${name}: in/out must be finite numbers (SOURCE seconds)`)\n continue\n }\n if (s.out - s.in <= 0)\n problems.push(`${name}: out (${s.out}) must be > in (${s.in})`)\n if (s.in < -EPS || (duration > 0 && s.in > duration + EPS)) {\n problems.push(\n `${name}: in=${s.in}s is outside the footage (0..${duration.toFixed(2)}s)`,\n )\n }\n if (duration > 0 && s.out > duration + EPS) {\n problems.push(\n `${name}: out=${s.out}s exceeds the footage (${duration.toFixed(2)}s)`,\n )\n }\n }\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1]\n const curr = sorted[i]\n if (isNum(prev.out) && isNum(curr.in) && curr.in < prev.out - EPS) {\n problems.push(\n `${spanName(label, curr)} overlaps ${spanName(label, prev)} (spans must not overlap)`,\n )\n }\n }\n}\n\nexport function lintDoc(docIn: StudioDoc): DocLintResult {\n const doc = docIn as unknown as Json\n const problems: string[] = []\n const warnings: string[] = []\n // The anchor: a recording document carries `source` and lints its\n // footage-anchored tracks against the footage's length; a program\n // document lints the shared layers against the program's length.\n const recording = isObj(doc.source)\n const source = isObj(doc.source) ? doc.source : {}\n const meta = isObj(source.meta) ? source.meta : {}\n const program = isObj(doc.program) ? doc.program : undefined\n const programConfig =\n program && isObj(program.config) ? program.config : undefined\n const duration = recording\n ? (isNum(meta.durationMs) ? meta.durationMs : 0) / 1000\n : program && isNum(program.duration)\n ? program.duration\n : programConfig && isNum(programConfig.duration)\n ? programConfig.duration\n : 0\n if (!recording) {\n if (!program)\n problems.push(\n 'doc must carry `source` (a recording) or `program` (a program)',\n )\n else if (!programConfig)\n problems.push(\n 'program.config must be the config object (functions as strings)',\n )\n if (\n program &&\n program.tweenEdits !== undefined &&\n !isObj(program.tweenEdits)\n )\n problems.push('program.tweenEdits must be an object keyed by spec index')\n }\n\n // --- zoom spans (the highest-traffic agent surface) ---\n if (recording && !Array.isArray(doc.zoom))\n problems.push('zoom must be an array of spans')\n const zoom = recording ? entries(doc.zoom) : []\n if (recording) {\n checkSpanList(zoom, 'zoom', duration, problems)\n for (const z of zoom) {\n const name = spanName('zoom', z)\n if (\n !isNum(z.level) ||\n z.level < ZOOM_LEVEL_MIN - EPS ||\n z.level > ZOOM_LEVEL_MAX + EPS\n ) {\n problems.push(\n `${name}: level=${String(z.level)} out of range (${ZOOM_LEVEL_MIN}..${ZOOM_LEVEL_MAX})`,\n )\n }\n for (const axis of ['cx', 'cy'] as const) {\n const v = z[axis]\n if (!isNum(v) || v < 0 || v > 1) {\n problems.push(\n `${name}: ${axis}=${String(v)} — focus coords are NORMALIZED [0..1] video-frame fractions (0.5 = center), not pixels`,\n )\n }\n }\n checkTransition(z, name, problems)\n if (\n z.focusMode !== undefined &&\n z.focusMode !== 'manual' &&\n z.focusMode !== 'auto'\n ) {\n problems.push(`${name}: focusMode must be 'manual' or 'auto'`)\n }\n if (\n z.source !== undefined &&\n z.source !== 'manual' &&\n z.source !== 'auto'\n ) {\n problems.push(`${name}: source must be 'manual' or 'auto'`)\n }\n if (\n isNum(z.in) &&\n isNum(z.out) &&\n z.out - z.in > 0 &&\n z.out - z.in < ZOOM_SPAN_MIN\n ) {\n warnings.push(\n `${name}: span ${(z.out - z.in).toFixed(2)}s is under the ${ZOOM_SPAN_MIN}s minimum the studio enforces`,\n )\n }\n }\n\n // --- segments (kept footage) ---\n if (doc.segments !== undefined && !Array.isArray(doc.segments)) {\n problems.push('segments must be an array of {in, out} spans')\n }\n checkSpanList(entries(doc.segments), 'segment', duration, problems)\n }\n\n // --- speed spans ---\n const speed = entries(doc.speed)\n checkSpanList(speed, 'speed', duration, problems)\n for (const s of speed) {\n if (\n !isNum(s.rate) ||\n s.rate < SPEED_RATE_MIN - EPS ||\n s.rate > SPEED_RATE_MAX + EPS\n ) {\n problems.push(\n `${spanName('speed', s)}: rate=${String(s.rate)} out of range (${SPEED_RATE_MIN}..${SPEED_RATE_MAX})`,\n )\n }\n }\n\n if (recording) {\n // --- tilt spans (card pose regions — DEGREES, footage-anchored) ---\n if (doc.tilt !== undefined && !Array.isArray(doc.tilt)) {\n problems.push('tilt must be an array of spans')\n }\n const tilt = entries(doc.tilt)\n checkSpanList(tilt, 'tilt', duration, problems)\n for (const t of tilt) {\n const name = spanName('tilt', t)\n for (const ax of ['rx', 'ry'] as const) {\n const v = t[ax]\n if (!isNum(v) || v < -TILT_DEG_MAX || v > TILT_DEG_MAX) {\n problems.push(\n `${name}: ${ax}=${String(v)} — pose angles are DEGREES in -${TILT_DEG_MAX}..${TILT_DEG_MAX} (not radians, not fractions)`,\n )\n }\n }\n checkTransition(t, name, problems)\n if (isNum(t.rx) && isNum(t.ry) && Math.abs(t.rx) + Math.abs(t.ry) > 25) {\n warnings.push(\n `${name}: combined lean ${(Math.abs(t.rx) + Math.abs(t.ry)).toFixed(0)}° reads dramatic — the premium band is ±5..18° per axis`,\n )\n }\n if (\n t.source !== undefined &&\n t.source !== 'manual' &&\n t.source !== 'auto'\n ) {\n problems.push(`${name}: source must be 'manual' or 'auto'`)\n }\n if (\n isNum(t.in) &&\n isNum(t.out) &&\n t.out - t.in > 0 &&\n t.out - t.in < TILT_SPAN_MIN\n ) {\n warnings.push(\n `${name}: span ${(t.out - t.in).toFixed(2)}s is under the ${TILT_SPAN_MIN}s minimum the studio enforces (a pose needs ~0.9s ramps to settle)`,\n )\n }\n }\n if (\n doc.tiltStyle !== undefined &&\n !['off', 'subtle', 'medium', 'strong'].includes(doc.tiltStyle as string)\n ) {\n problems.push(\n `tiltStyle must be \"off\" | \"subtle\" | \"medium\" | \"strong\" (got ${String(doc.tiltStyle)})`,\n )\n }\n\n // --- rejected proposals (\"not this one\": a deleted auto span, kept) ---\n if (doc.rejected !== undefined && !Array.isArray(doc.rejected)) {\n problems.push('rejected must be an array of {id, lane, in, out}')\n }\n for (const r of entries(doc.rejected)) {\n const name = spanName('rejected', r)\n if (!['zoom', 'tilt', 'speed'].includes(r.lane as string)) {\n problems.push(\n `${name}: lane must be \"zoom\" | \"tilt\" | \"speed\" (got ${String(r.lane)})`,\n )\n }\n if (!isNum(r.in) || !isNum(r.out) || r.out <= r.in) {\n problems.push(`${name}: needs SOURCE seconds in < out`)\n } else if (r.in >= duration) {\n problems.push(\n `${name}: starts at ${r.in}s, past the footage (${duration.toFixed(2)}s) — nothing to reject there`,\n )\n }\n }\n\n // --- cam pose spans (MO: animated cam layouts — fractions, footage-anchored) ---\n if (doc.camMotion !== undefined && !Array.isArray(doc.camMotion)) {\n problems.push('camMotion must be an array of spans')\n }\n const camMotion = entries(doc.camMotion)\n checkSpanList(camMotion, 'camMotion', duration, problems)\n if (camMotion.length && typeof source.camKey !== 'string') {\n warnings.push(\n 'camMotion has spans but the take has no cam track (source.camKey) — nothing renders them',\n )\n }\n for (const m of camMotion) {\n const name = spanName('camMotion', m)\n for (const axis of ['x', 'y'] as const) {\n const v = m[axis]\n if (v !== undefined && (!isNum(v) || v < 0 || v > 1)) {\n problems.push(\n `${name}: ${axis}=${String(v)} — the bubble center is FRACTIONS of the frame [0..1] (the zoom cx/cy convention), not pixels`,\n )\n }\n }\n if (\n m.size !== undefined &&\n (!isNum(m.size) ||\n m.size < CAM_SIZE_MIN - EPS ||\n m.size > CAM_SIZE_MAX + EPS)\n ) {\n problems.push(\n `${name}: size=${String(m.size)} must be a fraction of the frame height in ${CAM_SIZE_MIN}..${CAM_SIZE_MAX}`,\n )\n }\n checkTransition(m, name, problems)\n if (m.x === undefined && m.y === undefined && m.size === undefined) {\n warnings.push(\n `${name}: no pose fields (x/y/size) — the span inherits the rest pose and changes nothing`,\n )\n }\n if (\n m.source !== undefined &&\n m.source !== 'manual' &&\n m.source !== 'auto'\n ) {\n problems.push(`${name}: source must be 'manual' or 'auto'`)\n }\n if (\n isNum(m.in) &&\n isNum(m.out) &&\n m.out - m.in > 0 &&\n m.out - m.in < CAM_SPAN_MIN\n ) {\n warnings.push(\n `${name}: span ${(m.out - m.in).toFixed(2)}s is under the ${CAM_SPAN_MIN}s minimum the studio enforces (a move needs its ~0.65s ramp to settle)`,\n )\n }\n }\n }\n\n // --- audio clips (OUTPUT-anchored) ---\n for (const a of entries(doc.audio)) {\n const name = `audio ${typeof a.id === 'string' ? a.id : `@${String(a.start)}`}`\n if (!isNum(a.start) || a.start < -EPS)\n problems.push(`${name}: start must be ≥ 0 (OUTPUT seconds)`)\n if (!isNum(a.in) || !isNum(a.out) || a.out - a.in <= 0) {\n problems.push(\n `${name}: in/out must be a positive span within the source file`,\n )\n }\n if (a.gain !== undefined && (!isNum(a.gain) || a.gain < 0 || a.gain > 1)) {\n problems.push(`${name}: gain must be 0..1`)\n }\n }\n\n if (recording) {\n // --- background media (frame.backgroundMedia) ---\n const frame = isObj(doc.frame) ? doc.frame : undefined\n const bgm =\n frame && isObj(frame.backgroundMedia) ? frame.backgroundMedia : undefined\n if (bgm) {\n if (bgm.kind !== 'video' && bgm.kind !== 'image') {\n problems.push(\n `frame.backgroundMedia.kind must be \"video\" or \"image\" (got ${String(bgm.kind)})`,\n )\n }\n if (typeof bgm.key !== 'string' || bgm.key.length === 0) {\n problems.push(\n 'frame.backgroundMedia.key must be a non-empty URL or take-dir file (e.g. \"/bg.webm\")',\n )\n }\n if (\n bgm.dim !== undefined &&\n (!isNum(bgm.dim) || bgm.dim < 0 || bgm.dim > 1)\n ) {\n problems.push(\n `frame.backgroundMedia.dim must be 0..1 (got ${String(bgm.dim)})`,\n )\n }\n if (bgm.kind === 'video') {\n if (bgm.duration === undefined) {\n // A video background with no duration can't compute its modulo loop —\n // it would freeze on the first frame.\n warnings.push(\n 'frame.backgroundMedia: a video background has no `duration` — the loop needs it (bgT = t % duration), else it freezes',\n )\n } else if (!isNum(bgm.duration) || bgm.duration <= 0) {\n problems.push(\n `frame.backgroundMedia.duration must be > 0 for a video background (got ${String(bgm.duration)})`,\n )\n }\n }\n }\n\n // --- frame depth dials (V2) ---\n if (frame) {\n for (const k of ['parallax'] as const) {\n const v = frame[k]\n if (v !== undefined && (!isNum(v) || v < 0 || v > 1)) {\n problems.push(`frame.${k} must be 0..1 (got ${String(v)})`)\n }\n }\n }\n\n // --- cover fit: fit is a closed pair, focus normalized fractions ---\n if (frame) {\n const fit = frame.fit\n if (fit !== undefined && fit !== 'contain' && fit !== 'cover') {\n problems.push(\n `frame.fit must be \"contain\" or \"cover\" (got ${String(fit)})`,\n )\n }\n const focus = frame.focus\n if (focus !== undefined) {\n if (!isObj(focus)) {\n problems.push('frame.focus must be { cx, cy } in 0..1')\n } else {\n for (const k of ['cx', 'cy'] as const) {\n const v = focus[k]\n if (v !== undefined && (!isNum(v) || v < 0 || v > 1)) {\n problems.push(\n `frame.focus.${k} must be a normalized video fraction 0..1 (got ${String(v)}) — the zoom cx/cy convention, never pixels`,\n )\n }\n }\n }\n if (fit !== 'cover') {\n warnings.push(\n 'frame.focus only acts under frame.fit: \"cover\" (contain ignores it)',\n )\n }\n }\n }\n\n // --- the card stroke: a switch (alpha) with a width and a colour ---\n // ON_FRAME falls back to the 1.5px white hairline for a width it cannot\n // use, so an out-of-range number would render as the default and read as\n // \"the field was ignored\". Say so here instead.\n if (frame) {\n const bw = frame.borderWidth\n if (bw !== undefined && (!isNum(bw) || bw <= 0 || bw > 24)) {\n problems.push(\n `frame.borderWidth must be 0..24 design px (got ${String(bw)}); absent = the 1.5px hairline`,\n )\n }\n const bc = frame.borderColor\n if (bc !== undefined && (typeof bc !== 'string' || !bc.trim())) {\n problems.push(\n `frame.borderColor must be a CSS colour string (got ${String(bc)}); absent = #ffffff`,\n )\n }\n if ((bw !== undefined || bc !== undefined) && !frame.border) {\n problems.push(\n 'frame.borderWidth/borderColor are set but frame.border is 0 — border is the switch AND the alpha, so nothing is drawn',\n )\n }\n // The border grows OUTWARD from the card's edge, into the padding ring,\n // and the frame crops whatever reaches past its own edge — so a border\n // wider than the padding renders cropped flat where the card meets the\n // frame (at padding 0, not at all on that axis). The doc still renders,\n // so this is honesty, not breakage.\n const ebw = isNum(bw) && bw > 0 && bw <= 24 ? bw : 1.5\n const pad = isNum(frame.padding) ? frame.padding : 0\n if (frame.border && ebw > pad) {\n warnings.push(\n `frame.borderWidth (${ebw}) is wider than frame.padding (${pad}) — the border grows outward from the card, so the frame edge crops it; raise the padding to at least the width to show the whole stroke`,\n )\n }\n }\n if (\n bgm &&\n bgm.blur !== undefined &&\n (!isNum(bgm.blur) || bgm.blur < 0 || bgm.blur > 100)\n ) {\n problems.push(\n `frame.backgroundMedia.blur must be 0..100 design px (got ${String(bgm.blur)})`,\n )\n }\n\n // --- removed fields (decided 2026-08-03) ---\n // The card's static pose and its V2 effects are gone: a lean is a tilt SPAN\n // on the timeline, nothing else poses the card. Say so instead of ignoring\n // the field, or a doc written against the old schema renders silently\n // without what it asked for.\n if (doc.card !== undefined) {\n problems.push(\n 'card was removed — lean the card with tilt spans (doc.tilt); entrance/exit/float/effect are gone',\n )\n }\n if (frame && frame.vignette !== undefined) {\n problems.push('frame.vignette was removed')\n }\n }\n\n // --- overlays (compositor v2 V1: text clips, OUTPUT-anchored) ---\n const overlays = Array.isArray(doc.overlays) ? doc.overlays : undefined\n if (doc.overlays !== undefined && !overlays) {\n problems.push('overlays must be an array of clips')\n }\n const TRANSITIONS = ['none', 'fade', 'rise']\n const PRESETS = ['title', 'caption', 'label']\n for (let i = 0; i < (overlays?.length ?? 0); i++) {\n const o = overlays![i]\n const name = `overlays[${i}]`\n if (!isObj(o)) {\n problems.push(`${name} must be an object`)\n continue\n }\n if (o.kind !== 'text' && o.kind !== 'image' && o.kind !== 'video') {\n problems.push(\n `${name}.kind must be \"text\" | \"image\" | \"video\" (got ${String(o.kind)})`,\n )\n }\n if (!isNum(o.start) || o.start < 0)\n problems.push(`${name}.start must be ≥ 0 (OUTPUT seconds)`)\n if (!isNum(o.duration) || o.duration <= 0) {\n problems.push(`${name}.duration must be > 0 (seconds)`)\n }\n if (o.kind === 'text') {\n if (typeof o.text !== 'string')\n problems.push(`${name}.text must be a string`)\n if (typeof o.preset === 'string' && !PRESETS.includes(o.preset)) {\n warnings.push(\n `${name}.preset \"${String(o.preset)}\" is not a known preset (${PRESETS.join('|')}) — falls back to \"title\"`,\n )\n }\n if (\n o.size !== undefined &&\n (!isNum(o.size) || o.size < 12 || o.size > 200)\n ) {\n problems.push(`${name}.size must be design px in 12..200`)\n }\n if (o.family !== undefined) {\n if (typeof o.family !== 'string' || o.family.length === 0) {\n problems.push(`${name}.family must be a font family name`)\n } else if (!findFontFamily(o.family)) {\n warnings.push(\n `${name}.family \"${String(o.family)}\" is not in the hosted catalog (GET https://vos.so/api/fonts) — the render fleet falls back to the preset font`,\n )\n }\n }\n if (\n o.weight !== undefined &&\n (!isNum(o.weight) || o.weight < 100 || o.weight > 900)\n ) {\n problems.push(`${name}.weight must be a CSS weight in 100..900`)\n }\n if (\n o.align !== undefined &&\n !['left', 'center', 'right'].includes(o.align as string)\n ) {\n problems.push(`${name}.align must be left|center|right`)\n }\n if (\n o.letterSpacing !== undefined &&\n (!isNum(o.letterSpacing) ||\n o.letterSpacing < -10 ||\n o.letterSpacing > 60)\n ) {\n problems.push(`${name}.letterSpacing must be design px in -10..60`)\n }\n if (\n o.lineHeight !== undefined &&\n (!isNum(o.lineHeight) || o.lineHeight < 0.8 || o.lineHeight > 3)\n ) {\n problems.push(`${name}.lineHeight must be a multiplier in 0.8..3`)\n }\n if (o.stroke !== undefined) {\n const rawStroke: unknown = o.stroke\n if (\n typeof rawStroke !== 'object' ||\n rawStroke === null ||\n Array.isArray(rawStroke)\n ) {\n problems.push(`${name}.stroke must be an object { color, width }`)\n } else {\n const sk = rawStroke as Record<string, unknown>\n if (typeof sk.color !== 'string' || sk.color.length === 0) {\n problems.push(`${name}.stroke.color must be a CSS color string`)\n }\n if (!isNum(sk.width) || sk.width < 0.5 || sk.width > 40) {\n problems.push(`${name}.stroke.width must be design px in 0.5..40`)\n }\n }\n }\n if (o.box !== undefined) {\n const raw: unknown = o.box\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n problems.push(`${name}.box must be an object { color, … }`)\n } else {\n const bx = raw as Record<string, unknown>\n if (typeof bx.color !== 'string' || bx.color.length === 0) {\n problems.push(`${name}.box.color must be a CSS color string`)\n }\n if (\n bx.opacity !== undefined &&\n (!isNum(bx.opacity) || bx.opacity < 0 || bx.opacity > 1)\n ) {\n problems.push(`${name}.box.opacity must be in 0..1`)\n }\n for (const k of ['paddingX', 'paddingY', 'radius'] as const) {\n const v = bx[k]\n if (v !== undefined && (!isNum(v) || v < 0 || v > 4)) {\n problems.push(\n `${name}.box.${k} must be EMs of the font size in 0..4`,\n )\n }\n }\n }\n }\n if (\n o.maxWidth !== undefined &&\n (!isNum(o.maxWidth) || o.maxWidth < 0.1 || o.maxWidth > 1)\n ) {\n problems.push(\n `${name}.maxWidth must be a FRACTION of the frame width in 0.1..1 (wrap budget; absent = no wrapping)`,\n )\n }\n // TX6 entrance animation: fx owns the entrance when present (`enter`\n // is ignored); exit stays clip-level. Pure f(t) — segmentation and\n // timing are baked at lowering.\n if (o.fx !== undefined) {\n if (!isObj(o.fx)) {\n problems.push(\n `${name}.fx must be { fx, unit?, direction?, stagger?, duration? }`,\n )\n } else {\n const fx = o.fx\n const FX_KINDS = ['fade', 'rise', 'pop', 'blur', 'typewriter']\n const FX_UNITS = ['block', 'line', 'word', 'char']\n const FX_DIRS = ['forward', 'reverse', 'center']\n if (typeof fx.fx !== 'string' || !FX_KINDS.includes(fx.fx)) {\n problems.push(\n `${name}.fx.fx must be ${FX_KINDS.join('|')} (got ${String(fx.fx)})`,\n )\n }\n if (\n fx.unit !== undefined &&\n (typeof fx.unit !== 'string' || !FX_UNITS.includes(fx.unit))\n ) {\n problems.push(`${name}.fx.unit must be ${FX_UNITS.join('|')}`)\n }\n if (\n fx.direction !== undefined &&\n (typeof fx.direction !== 'string' ||\n !FX_DIRS.includes(fx.direction))\n ) {\n problems.push(`${name}.fx.direction must be ${FX_DIRS.join('|')}`)\n }\n if (\n fx.stagger !== undefined &&\n (!isNum(fx.stagger) || fx.stagger < 0 || fx.stagger > 2)\n ) {\n problems.push(\n `${name}.fx.stagger must be seconds between unit starts in 0..2`,\n )\n }\n if (\n fx.duration !== undefined &&\n (!isNum(fx.duration) || fx.duration < 0.05 || fx.duration > 2)\n ) {\n problems.push(`${name}.fx.duration must be seconds in 0.05..2`)\n }\n if (\n fx.fx === 'typewriter' &&\n (fx.unit === undefined || fx.unit === 'block')\n ) {\n warnings.push(\n `${name}.fx: typewriter with unit \"block\" reveals everything at once — unit \"char\" or \"word\" is its nature`,\n )\n }\n if (o.enter !== undefined && o.enter !== 'none') {\n warnings.push(\n `${name}: fx owns the entrance — the \"enter\" transition is ignored while fx is set`,\n )\n }\n }\n }\n }\n if (o.kind === 'image' || o.kind === 'video') {\n if (o.fx !== undefined) {\n problems.push(`${name}.fx is text-only (media clips have enter/exit)`)\n }\n if (typeof o.key !== 'string' || o.key.length === 0) {\n problems.push(\n `${name}.key must be a non-empty media URL or take-dir file (e.g. \"/logo.png\")`,\n )\n }\n if (\n o.width !== undefined &&\n (!isNum(o.width) || o.width <= 0 || o.width > 1)\n ) {\n problems.push(\n `${name}.width must be a fraction of the frame width in (0..1] (got ${String(o.width)})`,\n )\n }\n if (o.radius !== undefined && (!isNum(o.radius) || o.radius < 0)) {\n problems.push(`${name}.radius must be ≥ 0 design px`)\n }\n if (\n o.opacity !== undefined &&\n (!isNum(o.opacity) || o.opacity < 0 || o.opacity > 1)\n ) {\n problems.push(`${name}.opacity must be 0..1`)\n }\n }\n const tf = isObj(o.transform) ? o.transform : undefined\n if (!tf) {\n problems.push(\n `${name}.transform must be { x, y, scale, rotation } — x/y are FRACTIONS of the frame [0..1] (0.5/0.5 = center; the zoom cx/cy convention), aspect-stable`,\n )\n } else {\n if (!isNum(tf.x) || !isNum(tf.y)) {\n problems.push(\n `${name}.transform.x/y must be numbers (frame fractions [0..1])`,\n )\n } else {\n // The cx/cy pixel trap: coords are FRACTIONS, not pixels.\n if (Math.abs(tf.x) > 2 || Math.abs(tf.y) > 2) {\n problems.push(\n `${name}.transform.x/y look like PIXELS (${String(tf.x)}, ${String(tf.y)}) — they are FRACTIONS of the frame [0..1] (center = 0.5/0.5, lower-third y ≈ 0.82)`,\n )\n } else if (tf.x < -0.1 || tf.x > 1.1 || tf.y < -0.1 || tf.y > 1.1) {\n warnings.push(\n `${name}.transform.x/y (${String(tf.x)}, ${String(tf.y)}) sit outside the frame [0..1] — the clip may be partly or fully invisible`,\n )\n }\n }\n if (tf.scale !== undefined && (!isNum(tf.scale) || tf.scale <= 0)) {\n problems.push(`${name}.transform.scale must be > 0`)\n }\n if (tf.rotation !== undefined && !isNum(tf.rotation)) {\n problems.push(`${name}.transform.rotation must be degrees (number)`)\n }\n }\n for (const key of ['enter', 'exit'] as const) {\n const v = o[key]\n if (\n v !== undefined &&\n (typeof v !== 'string' || !TRANSITIONS.includes(v))\n ) {\n problems.push(`${name}.${key} must be one of ${TRANSITIONS.join('|')}`)\n }\n }\n // Pose keyframes: clip-local, fractions, opacity as a multiplier.\n if (o.motion !== undefined) {\n if (!Array.isArray(o.motion)) {\n problems.push(`${name}.motion must be an array of poses`)\n } else {\n const clipDur = isNum(o.duration) ? o.duration : 0\n o.motion.filter(isObj).forEach((p, pi) => {\n const pn = `${name}.motion[${pi}]`\n if (!isNum(p.at) || p.at < -EPS) {\n problems.push(\n `${pn}.at must be ≥ 0 CLIP-LOCAL seconds (0 = the clip's start; poses ride along when the clip moves)`,\n )\n } else if (clipDur > 0 && p.at > clipDur + EPS) {\n warnings.push(\n `${pn}.at=${String(p.at)}s is past the clip's ${clipDur.toFixed(2)}s duration (clamped to the end)`,\n )\n }\n for (const axis of ['x', 'y'] as const) {\n const v = p[axis]\n if (v === undefined) continue\n if (!isNum(v)) {\n problems.push(`${pn}.${axis} must be a number (frame fraction)`)\n } else if (Math.abs(v) > 2) {\n problems.push(\n `${pn}.${axis} looks like PIXELS (${String(v)}) — pose coords are FRACTIONS of the frame [0..1], the transform.x/y convention`,\n )\n }\n }\n if (p.scale !== undefined && (!isNum(p.scale) || p.scale <= 0)) {\n problems.push(`${pn}.scale must be > 0`)\n }\n if (p.rotation !== undefined && !isNum(p.rotation)) {\n problems.push(`${pn}.rotation must be degrees (number)`)\n }\n if (\n p.opacity !== undefined &&\n (!isNum(p.opacity) || p.opacity < 0 || p.opacity > 1)\n ) {\n problems.push(\n `${pn}.opacity must be 0..1 (a multiplier on the clip's alpha)`,\n )\n }\n })\n }\n }\n }\n\n // --- object clips (V3 — the drafted V4 spec) ---\n const objects = Array.isArray(doc.objects) ? doc.objects : undefined\n if (doc.objects !== undefined && !objects)\n problems.push('objects must be an array of clips')\n const SHAPES = ['cube', 'sphere', 'torus', 'knot']\n const T3_MATERIALS = ['standard', 'metal', 'glass', 'neon']\n for (let i = 0; i < (objects?.length ?? 0); i++) {\n const o = objects![i]\n const name = `objects[${i}]`\n if (!isObj(o)) {\n problems.push(`${name} must be an object`)\n continue\n }\n const asset = isObj(o.asset) ? o.asset : undefined\n if (!asset)\n problems.push(\n `${name}.asset must be { kind: \"primitive\", shape } | { kind: \"gltf\", key } | { kind: \"text3d\", text }`,\n )\n else if (asset.kind === 'primitive') {\n if (typeof asset.shape !== 'string' || !SHAPES.includes(asset.shape)) {\n problems.push(`${name}.asset.shape must be one of ${SHAPES.join('|')}`)\n }\n } else if (asset.kind === 'gltf') {\n if (typeof asset.key !== 'string' || !asset.key)\n problems.push(\n `${name}.asset.key must be a non-empty URL/file (e.g. \"/model.glb\")`,\n )\n } else if (asset.kind === 'text3d') {\n // TX7: extruded text from the hosted typeface catalog. Materials are\n // preset names only — the fleet-audited set (single-sided, no\n // dispersion); depth is a fraction of the glyph height.\n if (typeof asset.text !== 'string' || !asset.text.trim())\n problems.push(`${name}.asset.text must be a non-empty string`)\n if (asset.typeface !== undefined) {\n if (typeof asset.typeface !== 'string')\n problems.push(`${name}.asset.typeface must be a string`)\n else if (!findTypeface(asset.typeface))\n warnings.push(\n `${name}.asset.typeface \"${asset.typeface}\" is not in the 3D typeface catalog — falls back to the house face (${TYPEFACE_CATALOG.map((t) => t.family).join(', ')})`,\n )\n }\n if (\n asset.material !== undefined &&\n !T3_MATERIALS.includes(asset.material as string)\n ) {\n problems.push(\n `${name}.asset.material must be ${T3_MATERIALS.join('|')}`,\n )\n }\n if (\n asset.depth !== undefined &&\n (!isNum(asset.depth) || asset.depth < 0.02 || asset.depth > 1)\n ) {\n problems.push(\n `${name}.asset.depth must be a fraction of the glyph height in 0.02..1`,\n )\n }\n if (asset.bevel !== undefined && typeof asset.bevel !== 'boolean')\n problems.push(`${name}.asset.bevel must be a boolean`)\n } else\n problems.push(\n `${name}.asset.kind must be \"primitive\" | \"gltf\" | \"text3d\"`,\n )\n const tf = isObj(o.transform3d) ? o.transform3d : undefined\n if (!tf)\n problems.push(\n `${name}.transform3d must be { x, y, z, rx, ry, rz, scale } — x/y are FRACTIONS of the frame [0..1], z = world units toward the camera, scale = fraction of frame height`,\n )\n else {\n if (!isNum(tf.x) || !isNum(tf.y))\n problems.push(\n `${name}.transform3d.x/y must be numbers (frame fractions [0..1])`,\n )\n else if (Math.abs(tf.x) > 2 || Math.abs(tf.y) > 2) {\n problems.push(\n `${name}.transform3d.x/y look like PIXELS (${String(tf.x)}, ${String(tf.y)}) — they are FRACTIONS of the frame (center = 0.5/0.5)`,\n )\n }\n if (tf.z !== undefined && (!isNum(tf.z) || tf.z < -2 || tf.z > 2.5))\n problems.push(\n `${name}.transform3d.z must be -2..2.5 world units (0 = the card plane; + toward camera)`,\n )\n if (\n tf.scale !== undefined &&\n (!isNum(tf.scale) || tf.scale <= 0 || tf.scale > 1)\n )\n problems.push(\n `${name}.transform3d.scale must be a fraction of the frame height in (0..1]`,\n )\n }\n const span = o.span\n if (span !== undefined) {\n if (\n !isObj(span) ||\n !isNum(span.start) ||\n span.start < 0 ||\n !isNum(span.duration) ||\n span.duration <= 0\n ) {\n problems.push(\n `${name}.span must be { start ≥ 0, duration > 0 } (OUTPUT seconds)`,\n )\n }\n }\n if (\n o.animation !== undefined &&\n o.animation !== null &&\n o.animation !== 'spin' &&\n o.animation !== 'float'\n ) {\n problems.push(`${name}.animation must be \"spin\" | \"float\" | null`)\n }\n // Pose keyframes: clip-local over transform3d; presets compose.\n if (o.motion !== undefined) {\n if (!Array.isArray(o.motion)) {\n problems.push(`${name}.motion must be an array of poses`)\n } else {\n o.motion.filter(isObj).forEach((p, pi) => {\n const pn = `${name}.motion[${pi}]`\n if (!isNum(p.at) || p.at < -EPS) {\n problems.push(\n `${pn}.at must be ≥ 0 CLIP-LOCAL seconds (from the clip's span start)`,\n )\n }\n for (const axis of ['x', 'y'] as const) {\n const v = p[axis]\n if (v === undefined) continue\n if (!isNum(v)) {\n problems.push(`${pn}.${axis} must be a number (frame fraction)`)\n } else if (Math.abs(v) > 2) {\n problems.push(\n `${pn}.${axis} looks like PIXELS (${String(v)}) — pose coords are FRACTIONS of the frame [0..1]`,\n )\n }\n }\n if (p.z !== undefined && (!isNum(p.z) || p.z < -2 || p.z > 2.5)) {\n problems.push(`${pn}.z must be -2..2.5 world units`)\n }\n for (const ax of ['rx', 'ry', 'rz'] as const) {\n if (p[ax] !== undefined && !isNum(p[ax])) {\n problems.push(`${pn}.${ax} must be degrees (number)`)\n }\n }\n if (\n p.scale !== undefined &&\n (!isNum(p.scale) || p.scale <= 0 || p.scale > 1)\n ) {\n problems.push(\n `${pn}.scale must be a fraction of the frame height in (0..1]`,\n )\n }\n })\n }\n }\n }\n\n // --- export block ---\n if (isObj(doc.export)) {\n const resolution = doc.export.resolution as ExportResolution\n const validResolution = EXPORT_RESOLUTION_OPTIONS.includes(resolution)\n if (!validResolution) {\n problems.push(\n `export.resolution \"${String(doc.export.resolution)}\" invalid — one of: ${EXPORT_RESOLUTION_OPTIONS.join(' | ')}`,\n )\n }\n if (doc.export.fps !== 30 && doc.export.fps !== 60) {\n problems.push(\n `export.fps must be 30 or 60 (got ${String(doc.export.fps)})`,\n )\n }\n if (validResolution && isNum(meta.durationMs)) {\n const recommended = recommendedExportResolution(docIn as ProjectDoc)\n const want = EXPORT_RESOLUTION_OPTIONS.indexOf(resolution)\n const rec = EXPORT_RESOLUTION_OPTIONS.indexOf(recommended)\n if (want > rec) {\n const capW = isNum(meta.captureWidth) ? meta.captureWidth : meta.width\n warnings.push(\n `export.resolution \"${resolution}\" upscales the footage (capture is ${String(capW)}px wide — \"${recommended}\" matches the recording)`,\n )\n }\n }\n }\n\n if (recording)\n framingWarnings(docIn as ProjectDoc, doc, zoom, overlays ?? [], warnings)\n return { problems, warnings }\n}\n\ninterface DownEvent {\n t: number\n rect: { x: number; y: number; w: number; h: number }\n}\n\n/** `down` events carrying a target rect, in seconds — the evidence. */\nfunction clicksWithRects(source: Json): DownEvent[] {\n const cursor = Array.isArray(source.cursor) ? source.cursor : []\n const out: DownEvent[] = []\n for (const e of cursor) {\n if (!isObj(e) || e.type !== 'down' || !isNum(e.t) || !isObj(e.rect))\n continue\n const r = e.rect\n if (!isNum(r.x) || !isNum(r.y) || !isNum(r.w) || !isNum(r.h)) continue\n out.push({ t: e.t / 1000, rect: { x: r.x, y: r.y, w: r.w, h: r.h } })\n }\n return out\n}\n\n/**\n * The framing checks — advisory, never a problem, never a\n * throw: a zoom must contain what was clicked under it (the planner solves\n * this from the rect; a hand- or agent-written span is re-checked against\n * the same evidence), and a caption must not sit over the thing being\n * clicked. Both need a cursor track with rects; a browser-recorder take\n * has none and warns nothing.\n */\nfunction framingWarnings(\n docIn: ProjectDoc,\n doc: Json,\n zoom: Json[],\n overlays: unknown[],\n warnings: string[],\n): void {\n try {\n const source = isObj(doc.source) ? doc.source : {}\n const meta = isObj(source.meta) ? source.meta : {}\n const w = isNum(meta.width) ? meta.width : 0\n const h = isNum(meta.height) ? meta.height : 0\n if (!(w > 0) || !(h > 0)) return\n const clicks = clicksWithRects(source)\n if (!clicks.length) return\n const layout = docCardLayout(docIn)\n\n for (const z of zoom) {\n if (\n !isNum(z.in) ||\n !isNum(z.out) ||\n !isNum(z.level) ||\n !isNum(z.cx) ||\n !isNum(z.cy) ||\n z.level <= 1.001\n )\n continue\n const zin = z.in\n const zout = z.out\n const under = clicks.filter((c) => c.t >= zin && c.t <= zout)\n if (!under.length) continue\n let x0 = Infinity\n let y0 = Infinity\n let x1 = -Infinity\n let y1 = -Infinity\n for (const c of under) {\n x0 = Math.min(x0, c.rect.x / w)\n y0 = Math.min(y0, c.rect.y / h)\n x1 = Math.max(x1, (c.rect.x + c.rect.w) / w)\n y1 = Math.max(y1, (c.rect.y + c.rect.h) / h)\n }\n const rect = { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n if (\n !zoomCoversRect({ level: z.level, cx: z.cx, cy: z.cy }, rect, layout)\n ) {\n warnings.push(\n `${spanName('zoom', z)}: points beside what was clicked at ${under[0].t.toFixed(1)}s — the target (center ${((x0 + x1) / 2).toFixed(2)}, ${((y0 + y1) / 2).toFixed(2)}) sits outside the visible window; move cx/cy toward it or lower the level`,\n )\n }\n }\n\n const rated = ratedSegments(docIn)\n const toFrame = (nx: number, ny: number) => ({\n x: (layout.dx + nx * layout.dw) / layout.W,\n y: (layout.dy + ny * layout.dh) / layout.H,\n })\n overlays.forEach((o, i) => {\n if (!isObj(o) || (o.kind !== undefined && o.kind !== 'text')) return\n const tf = isObj(o.transform) ? o.transform : null\n if (\n !tf ||\n !isNum(tf.x) ||\n !isNum(tf.y) ||\n !isNum(o.start) ||\n !isNum(o.duration)\n )\n return\n for (const c of clicks) {\n const out = spanOutputExtent(rated, c.t, c.t + 0.001)\n if (!out || out.start < o.start || out.start > o.start + o.duration)\n continue\n const a = toFrame(c.rect.x / w, c.rect.y / h)\n const b = toFrame((c.rect.x + c.rect.w) / w, (c.rect.y + c.rect.h) / h)\n if (tf.x >= a.x && tf.x <= b.x && tf.y >= a.y && tf.y <= b.y) {\n warnings.push(\n `overlays[${i}] sits over the thing being clicked at ${c.t.toFixed(1)}s (output ${out.start.toFixed(1)}s) — move it off the target`,\n )\n break\n }\n }\n })\n } catch {\n // Framing is advisory: a malformed doc is reported by the checks above.\n }\n}\n","/**\n * Remote-media probing for `vos validate` — the loud-failure sibling of the\n * dangling-reference ladder. A doc or config that references a\n * hosted file (a poster's shot, a backdrop loop, an audio bed) can go\n * quietly broken when that file is deleted: the render carries on without\n * it and nothing says so. Validate is the next touch, so validate probes.\n *\n * The COLLECTOR is pure and unit-tested; the PROBE is best-effort network:\n * an unreachable URL (>=400) is a PROBLEM in words, a failed probe (offline,\n * DNS, timeout) is a WARNING — validation must still work on a plane.\n */\n\nconst MEDIA_EXT =\n /\\.(png|jpe?g|webp|gif|webm|mp4|mov|mp3|wav|m4a|ogg|glb|gltf|hdr|exr|woff2?)($|\\?)/i\n\nconst isRemote = (v: unknown): v is string =>\n typeof v === 'string' && /^https?:\\/\\//i.test(v)\n\n/** A remote URL that plausibly names media bytes (an asset route or a media\n * extension) — never a page, a docs link, or an API endpoint. */\nconst isRemoteMedia = (v: unknown): v is string =>\n isRemote(v) && (/\\/api\\/assets\\/[^/]+\\/file/i.test(v) || MEDIA_EXT.test(v))\n\nconst isObj = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\n/**\n * Every remote media URL a doc references: the backdrop loop, image/video\n * overlay keys, audio clip keys. Local take-dir keys (\"/music.mp3\") and\n * blob/data URLs are not probeable and not collected.\n */\nexport function collectDocMediaUrls(doc: unknown): string[] {\n if (!isObj(doc)) return []\n const urls: string[] = []\n const frame = doc.frame\n if (isObj(frame) && isObj(frame.backgroundMedia)) {\n const key = frame.backgroundMedia.key\n if (isRemoteMedia(key)) urls.push(key)\n }\n for (const list of [doc.overlays, doc.audio]) {\n if (!Array.isArray(list)) continue\n for (const clip of list) {\n if (isObj(clip) && isRemoteMedia(clip.key)) urls.push(clip.key)\n if (isObj(clip) && isRemoteMedia(clip.src)) urls.push(clip.src)\n }\n }\n return [...new Set(urls)]\n}\n\n/**\n * Every remote media URL a CONFIG references: element srcs (image/video/svg\n * by URL), font files, and any data value that names hosted media (the\n * poster family's shotUrl, a model URL knob).\n */\nexport function collectConfigMediaUrls(config: unknown): string[] {\n if (!isObj(config)) return []\n const urls: string[] = []\n if (Array.isArray(config.elements)) {\n for (const el of config.elements) {\n if (isObj(el) && isRemoteMedia(el.src)) urls.push(el.src)\n }\n }\n if (Array.isArray(config.fonts)) {\n for (const f of config.fonts) {\n if (isObj(f) && isRemote(f.url)) urls.push(f.url)\n }\n }\n if (isObj(config.data)) {\n for (const v of Object.values(config.data)) {\n if (isRemoteMedia(v)) urls.push(v)\n }\n }\n return [...new Set(urls)]\n}\n\nexport interface MediaProbeResult {\n url: string\n /** true = reachable · false = the server answered >=400 · null = probe failed (offline, timeout) */\n ok: boolean | null\n status?: number\n error?: string\n}\n\nconst PROBE_CAP = 16\nconst PROBE_TIMEOUT_MS = 5000\n\nasync function probeOne(url: string): Promise<MediaProbeResult> {\n const attempt = async (method: 'HEAD' | 'GET') => {\n const ctl = new AbortController()\n const timer = setTimeout(() => ctl.abort(), PROBE_TIMEOUT_MS)\n try {\n return await fetch(url, {\n method,\n signal: ctl.signal,\n headers: method === 'GET' ? { range: 'bytes=0-0' } : undefined,\n })\n } finally {\n clearTimeout(timer)\n }\n }\n try {\n let res = await attempt('HEAD')\n // Some hosts refuse HEAD; one ranged GET settles it without the bytes.\n if (res.status === 405 || res.status === 501) res = await attempt('GET')\n return { url, ok: res.status < 400, status: res.status }\n } catch (e) {\n return { url, ok: null, error: e instanceof Error ? e.message : String(e) }\n }\n}\n\n/** Probe up to PROBE_CAP urls in parallel. */\nexport async function probeMediaUrls(\n urls: string[],\n): Promise<MediaProbeResult[]> {\n return Promise.all(urls.slice(0, PROBE_CAP).map(probeOne))\n}\n\n/** Fold probe results into validate's problems/warnings, in words. */\nexport function mediaProbeLints(results: MediaProbeResult[]): {\n problems: string[]\n warnings: string[]\n} {\n const problems: string[] = []\n const warnings: string[] = []\n for (const r of results) {\n if (r.ok === false) {\n problems.push(\n `media unreachable: ${r.url} answers ${String(r.status)} — a render will quietly carry on without it`,\n )\n } else if (r.ok === null) {\n warnings.push(`could not probe ${r.url} (${r.error ?? 'network error'})`)\n }\n }\n return { problems, warnings }\n}\n","/**\n * Stills from a take — the agent's eyes AND a first-class asset output\n * (posters, OG cards, store screenshots). Lowers + compiles exactly like\n * render, then seeks each requested time in ONE page and captures the canvas\n * as PNG at the exact output resolution. No encoder, no chunks.\n *\n * Times are OUTPUT seconds (what the rendered video shows). `--at-zooms`\n * samples the apex (output-time midpoint) of every zoom span — where quality\n * lives.\n */\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { compileVosConfig } from '@vosjs/core'\nimport {\n lowerToComposition,\n momentsFromDoc,\n planForDigest,\n ratedSegments,\n resolveExportSize,\n spanOutputExtent,\n} from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake } from './take'\nimport { startTakeServer, waitForPageDone } from './server'\nimport { renderPageHtml } from './renderAnimation'\nimport {\n applyAndValidate,\n hasOverrides,\n resolveBackdropSlug,\n} from './docOverride'\nimport { DIGEST_DIR } from './digestTake'\nimport type { DocOverrides } from './docOverride'\nimport type { Moment, ProjectDoc } from '@vosjs/studio-core'\nimport type { Browser } from 'playwright'\n\nconst VIDEO_TOKEN = '__VOILA_CLI_VIDEO__'\n\nexport interface FramesTakeOptions {\n /** OUTPUT-time seconds; each may also be given as a percent of duration upstream. */\n times: number[]\n /** Also sample every zoom span's output-time apex. */\n atZooms?: boolean\n /**\n * Also sample every digest moment that survives into the output (reads\n * digest/digest.json when present, else derives the moments — no frames).\n */\n atMoments?: boolean\n width?: number\n height?: number\n outDir?: string\n /** In-memory doc overrides (--set / --frame / --background); lint-gated. */\n overrides?: DocOverrides\n}\n\nexport interface CapturedFrame {\n file: string\n time: number\n /** 'time' = requested instant, 'zoom' = a zoom-span apex, 'moment' = a digest moment. */\n kind: 'time' | 'zoom' | 'moment'\n momentId?: string\n}\n\nexport interface FramesTakeResult {\n frames: CapturedFrame[]\n width: number\n height: number\n duration: number\n outDir: string\n}\n\n/** Runs inside the render page: seek each time, settle, capture PNG, POST it. */\nasync function stillsInPage(opts: {\n animationCode: string\n token: string\n videoUrl: string\n W: number\n H: number\n shots: { time: number; name: string }[]\n}) {\n const w = window as unknown as Record<string, any>\n try {\n const vblob = await (await fetch(opts.videoUrl)).blob()\n const vurl = URL.createObjectURL(vblob)\n const code = opts.animationCode.split(opts.token).join(vurl)\n const mod = await import(\n /* @vite-ignore */ URL.createObjectURL(\n new Blob([code], { type: 'text/javascript' }),\n )\n )\n\n w.__vos__ = w.__vos__ || {}\n w.__vos__.isPaused = true\n\n const deps = {\n THREE: w.__THREE__,\n gsap: w.__gsap__,\n resolution: {\n width: opts.W,\n height: opts.H,\n pixelRatio: 1,\n drawingBufferWidth: opts.W,\n drawingBufferHeight: opts.H,\n },\n preserveDrawingBuffer: true,\n }\n const result = await mod.initVos(document.body, deps)\n if (result.assetsReady) await result.assetsReady\n const { timeline } = result\n timeline.pause()\n timeline.seek(0, false)\n\n const canvas = document.querySelector('canvas') as HTMLCanvasElement\n canvas.width = opts.W\n canvas.height = opts.H\n canvas.style.width = opts.W + 'px'\n canvas.style.height = opts.H + 'px'\n\n const raf = () => new Promise((r) => requestAnimationFrame(r))\n const wvr = () =>\n w.__vos__?.waitForVideosReady ? w.__vos__.waitForVideosReady() : null\n const pending = () => w.__vos__?.pendingDecodes?.size ?? 0\n const toPng = () =>\n new Promise<Blob>((res, rej) =>\n canvas.toBlob(\n (b) => (b ? res(b) : rej(new Error('toBlob failed'))),\n 'image/png',\n ),\n )\n\n // Every still is a COLD seek — html5-path videos update currentTime\n // asynchronously, so wait for a completed, stable seek before capturing\n // (mirrors renderInPage's chunk-start guard; see renderAnimation.ts).\n const collectVideos = (): HTMLVideoElement[] => {\n const out = new Set<HTMLVideoElement>()\n const cache = w.__vos__?.videoCache\n if (cache) {\n const vals =\n cache instanceof Map ? [...cache.values()] : Object.values(cache)\n for (const v of vals) {\n if (v?.tagName === 'VIDEO') out.add(v)\n else if (v?.el?.tagName === 'VIDEO') out.add(v.el)\n else if (v?.video?.tagName === 'VIDEO') out.add(v.video)\n }\n }\n document.querySelectorAll('video').forEach((v) => out.add(v))\n return [...out]\n }\n const videosSettled = () =>\n collectVideos().every((v) => !v.seeking && v.readyState >= 2)\n const waitVideosSettled = async (maxMs: number) => {\n const t0 = performance.now()\n let stableTimes = ''\n while (performance.now() - t0 < maxMs) {\n await raf()\n if (videosSettled()) {\n const times = collectVideos()\n .map((v) => v.currentTime.toFixed(3))\n .join(',')\n if (times === stableTimes) return\n stableTimes = times\n } else {\n stableTimes = ''\n }\n }\n }\n\n for (let i = 0; i < opts.shots.length; i++) {\n const shot = opts.shots[i]\n timeline.seek(shot.time, false)\n await wvr()\n await raf()\n if (pending() > 0) {\n await wvr()\n await raf()\n }\n await waitVideosSettled(8000)\n const png = await toPng()\n await fetch('/save?name=' + shot.name, { method: 'POST', body: png })\n w.__progress = (i + 1) / opts.shots.length\n }\n w.__done = { ok: true, count: opts.shots.length }\n } catch (e) {\n w.__error = String((e instanceof Error && e.stack) || e)\n }\n}\n\nexport async function framesTake(\n browser: Browser,\n dir: string,\n opts: FramesTakeOptions,\n): Promise<FramesTakeResult> {\n const take = await loadTake(dir)\n if (!take.doc) throw new Error(`${dir} has no doc.json — run plan first`)\n const doc = take.doc\n\n // Product-surface overrides (--set/--frame/--background): patch + lint the doc\n // in memory (doc.json untouched) so a still can preview any presentation.\n if (opts.overrides && hasOverrides(opts.overrides)) {\n await resolveBackdropSlug(opts.overrides)\n applyAndValidate(doc, opts.overrides)\n }\n\n const res = resolveExportSize(doc)\n const width = opts.width ?? res.width\n const height = opts.height ?? res.height\n\n doc.source.videoKey = VIDEO_TOKEN\n const lowered = lowerToComposition(doc)\n const animationCode = compileVosConfig(lowered.config as never, {\n tweenEngine: 'vos',\n })\n const duration = lowered.duration\n\n const clamp = (t: number) =>\n Math.min(Math.max(0, t), Math.max(0, duration - 1 / 30))\n const shots: {\n time: number\n kind: 'time' | 'zoom' | 'moment'\n momentId?: string\n }[] = opts.times.map((t) => ({\n time: clamp(t),\n kind: 'time',\n }))\n if (opts.atZooms) {\n const rated = ratedSegments(doc)\n for (const z of doc.zoom) {\n const ext = spanOutputExtent(rated, z.in, z.out)\n if (ext)\n shots.push({ time: clamp((ext.start + ext.end) / 2), kind: 'zoom' })\n }\n }\n if (opts.atMoments) {\n for (const m of await momentsFor(dir, take.doc)) {\n if (m.outputAt === null) continue\n shots.push({ time: clamp(m.outputAt), kind: 'moment', momentId: m.id })\n }\n }\n shots.sort((a, b) => a.time - b.time)\n if (!shots.length)\n throw new Error(\n 'no frame times — pass --times/--frame, --at-zooms or --at-moments',\n )\n\n const outDir = resolve(opts.outDir ?? join(dir, 'stills'))\n await mkdir(outDir, { recursive: true })\n const named = shots.map((s, i) => ({\n ...s,\n name:\n s.kind === 'moment'\n ? `moment-${s.momentId}-${s.time.toFixed(2)}s.png`\n : `${s.kind === 'zoom' ? 'zoom' : 'frame'}-${String(i).padStart(2, '0')}-${s.time.toFixed(2)}s.png`,\n }))\n\n const server = await startTakeServer(dir, {\n '/render.html': renderPageHtml(),\n })\n const context = await browser.newContext({ viewport: { width, height } })\n try {\n const page = await context.newPage()\n page.on('console', (m) => {\n if (m.type() === 'error')\n process.stderr.write(` [stills page] ${m.text()}\\n`)\n })\n await page.addInitScript(() => {\n ;(globalThis as unknown as Record<string, unknown>).__name = (\n f: unknown,\n ) => f\n })\n await page.goto(`${server.base}/render.html`)\n await page.waitForFunction('window.__pageReady__ === true')\n void page\n .evaluate(stillsInPage, {\n animationCode,\n token: VIDEO_TOKEN,\n videoUrl: `/${RECORDING_NAME}`,\n W: width,\n H: height,\n shots: named.map(({ time, name }) => ({ time, name })),\n })\n .catch(() => {})\n await waitForPageDone(\n page,\n 'stills',\n () => {},\n 120_000 + named.length * 4_000,\n )\n\n // The take server saves into its root (the take dir) — move into outDir.\n const frames: CapturedFrame[] = []\n for (const n of named) {\n const from = join(dir, n.name)\n const to = join(outDir, n.name)\n if (from !== to) await rename(from, to)\n frames.push({\n file: to,\n time: n.time,\n kind: n.kind,\n ...(n.momentId ? { momentId: n.momentId } : {}),\n })\n }\n return { frames, width, height, duration, outDir }\n } finally {\n await context.close()\n server.close()\n }\n}\n\n/**\n * The moments to frame: the digest on disk when there is one (its scenes and\n * activity came from a real decode), else derived from the track alone.\n */\nasync function momentsFor(dir: string, doc: ProjectDoc): Promise<Moment[]> {\n const file = join(dir, DIGEST_DIR, 'digest.json')\n if (existsSync(file)) {\n try {\n const d = JSON.parse(await readFile(file, 'utf8')) as {\n moments?: Moment[]\n }\n if (Array.isArray(d.moments)) return d.moments\n } catch {\n // fall through to a fresh derivation\n }\n }\n return momentsFromDoc(doc, planForDigest(doc))\n}\n\n/** Parse a --times list: seconds (\"2.5\") and percents of duration (\"50%\"). */\nexport function parseTimes(spec: string, duration: number): number[] {\n return spec\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((s) => {\n if (s.endsWith('%')) {\n const p = Number(s.slice(0, -1))\n if (!Number.isFinite(p)) throw new Error(`bad time \"${s}\"`)\n return (p / 100) * duration\n }\n const t = Number(s)\n if (!Number.isFinite(t)) throw new Error(`bad time \"${s}\"`)\n return t\n })\n}\n\n/** Contact-sheet composite via PNGs written by framesTake (no deps; caller may skip). */\nexport async function writeIndexJson(\n result: FramesTakeResult,\n): Promise<string> {\n const index = join(result.outDir, 'stills.json')\n await writeFile(\n index,\n JSON.stringify(\n {\n width: result.width,\n height: result.height,\n duration: result.duration,\n frames: result.frames,\n },\n null,\n 2,\n ),\n )\n return index\n}\n","/**\n * The take directory — the CLI's unit of work, human-inspectable on purpose:\n * take/\n * recording.webm encoded footage (CFR)\n * frames/ raw screencast JPEGs + frames.json (kept for re-encode)\n * cursor.json synthesized CursorTrack\n * meta.json RecordingMeta (producer: 'cli')\n * actions.json the script that produced it (replay recipe)\n * doc.json ProjectDoc — the agent-editable surface\n */\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { CursorTrack, ProjectDoc, RecordingMeta } from '@vosjs/studio-core'\nimport type { ActionsFile } from './actions'\n\nexport const RECORDING_NAME = 'recording.webm'\n\n/** The previous cut, preserved by a re-record. */\nexport const PREV_DOC_NAME = 'doc.prev.json'\n\nexport interface TakePaths {\n dir: string\n recording: string\n framesDir: string\n framesIndex: string\n cursor: string\n meta: string\n actions: string\n doc: string\n}\n\nexport function takePaths(dir: string): TakePaths {\n return {\n dir,\n recording: join(dir, RECORDING_NAME),\n framesDir: join(dir, 'frames'),\n framesIndex: join(dir, 'frames.json'),\n cursor: join(dir, 'cursor.json'),\n meta: join(dir, 'meta.json'),\n actions: join(dir, 'actions.json'),\n doc: join(dir, 'doc.json'),\n }\n}\n\nexport async function ensureTakeDir(dir: string): Promise<TakePaths> {\n const p = takePaths(dir)\n await mkdir(p.framesDir, { recursive: true })\n return p\n}\n\n/**\n * Re-record into an existing take WITHOUT destroying the cut (the\n * re-render loop's first rung; `rm -rf` here is what made \"re-renders on the\n * next version\" a false claim). What the old footage produced is cleared\n * (recording, cursor, meta, raw frames, stills/, digest/ — all derived and\n * regenerable); what the human's work lives in survives: `doc.json` moves to\n * `doc.prev.json` — the explicit reuse base `vos plan --reuse` re-anchors\n * onto the new recording — and `actions.json` + `vos.json` stay put. The doc\n * is MOVED, never left in place: a doc.json embeds its footage's cursor and\n * meta (`doc.source`), so leaving it beside new footage would be a document\n * lying about its source, and the auto-plan after recording would replan\n * from the OLD cursor. Returns what was kept, for the terminal to say.\n */\nexport async function prepareReRecord(\n dir: string,\n): Promise<{ prevDoc: boolean; kept: string[] }> {\n const p = takePaths(dir)\n const kept: string[] = []\n let prevDoc = false\n if (existsSync(p.doc)) {\n await rename(p.doc, join(dir, PREV_DOC_NAME))\n prevDoc = true\n kept.push(PREV_DOC_NAME)\n }\n if (existsSync(p.actions)) kept.push('actions.json')\n if (existsSync(join(dir, 'vos.json'))) kept.push('vos.json')\n for (const stale of [\n p.recording,\n p.cursor,\n p.meta,\n p.framesIndex,\n p.framesDir,\n join(dir, 'stills'),\n join(dir, 'digest'),\n join(dir, 'mic.webm'),\n join(dir, 'cam.webm'),\n ]) {\n await rm(stale, { recursive: true, force: true })\n }\n return { prevDoc, kept }\n}\n\nexport async function readJson<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, 'utf8')) as T\n}\n\nexport async function writeJson(\n file: string,\n value: unknown,\n pretty = false,\n): Promise<void> {\n await writeFile(\n file,\n pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value),\n )\n}\n\nexport interface TakeData {\n paths: TakePaths\n cursor: CursorTrack\n meta: RecordingMeta\n actions: ActionsFile | null\n doc: ProjectDoc | null\n}\n\n/** Load a take directory; cursor+meta are required, doc/actions optional. */\nexport async function loadTake(dir: string): Promise<TakeData> {\n const paths = takePaths(dir)\n if (!existsSync(paths.meta)) {\n throw new Error(\n `${dir} is not a take directory (missing meta.json) — run record first`,\n )\n }\n const meta = await readJson<RecordingMeta>(paths.meta)\n const cursor = existsSync(paths.cursor)\n ? await readJson<CursorTrack>(paths.cursor)\n : []\n const actions = existsSync(paths.actions)\n ? await readJson<ActionsFile>(paths.actions)\n : null\n const doc = existsSync(paths.doc)\n ? await readJson<ProjectDoc>(paths.doc)\n : null\n return { paths, cursor, meta, actions, doc }\n}\n","import { createServer } from 'node:http'\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { writeFile } from 'node:fs/promises'\nimport { extname, join } from 'node:path'\nimport type { Page } from 'playwright'\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.json': 'application/json',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.webm': 'video/webm',\n '.mp4': 'video/mp4',\n // Take-dir audio (doc.audio keys like \"/music.mp3\") — decode goes through\n // fetch → arrayBuffer so the type is informational, but an <audio> element\n // would care; never serve these as octet-stream.\n '.mp3': 'audio/mpeg',\n '.wav': 'audio/wav',\n '.m4a': 'audio/mp4',\n '.ogg': 'audio/ogg',\n}\n\nexport interface TakeServer {\n base: string\n close: () => void\n}\n\n/**\n * Static server over the take dir + generated pages + a POST /save endpoint\n * the in-page encoder/renderer uses to hand bytes back to node. The recording\n * is fetched → blob URL (seekable), but a take-dir VIDEO BACKGROUND\n * (frame.backgroundMedia.key = \"/bg.webm\") is loaded directly by ON_FRAME and\n * seeked during export — so this serves Range/206 (an HTMLVideoElement hangs\n * forever seeking a naive 200-only static server).\n */\nexport function startTakeServer(\n rootDir: string,\n pages: Record<string, string>,\n): Promise<TakeServer> {\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', 'http://x')\n // The studio (a different origin) fetches take files for `vos voila open`.\n res.setHeader('access-control-allow-origin', '*')\n if (req.method === 'POST' && url.pathname === '/save') {\n const name = (url.searchParams.get('name') ?? 'out.bin').replace(\n /[^\\w.-]/g,\n '',\n )\n const chunks: Buffer[] = []\n req.on('data', (c: Buffer) => chunks.push(c))\n req.on('end', () => {\n void writeFile(join(rootDir, name), Buffer.concat(chunks)).then(\n () => res.writeHead(200).end('ok'),\n (e) => res.writeHead(500).end(String(e)),\n )\n })\n return\n }\n if (pages[url.pathname]) {\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(pages[url.pathname])\n return\n }\n const file = join(rootDir, decodeURIComponent(url.pathname))\n if (existsSync(file) && statSync(file).isFile()) {\n const type = MIME[extname(file)] ?? 'application/octet-stream'\n const size = statSync(file).size\n const buf = readFileSync(file)\n const range = req.headers.range\n // Range/206 so an HTMLVideoElement can seek a take-dir video background.\n const m = range && /^bytes=(\\d*)-(\\d*)$/.exec(range)\n if (m) {\n const start = m[1] ? parseInt(m[1], 10) : 0\n const end = m[2] ? Math.min(parseInt(m[2], 10), size - 1) : size - 1\n if (start > end || start >= size) {\n res.writeHead(416, { 'content-range': `bytes */${size}` }).end()\n return\n }\n res.writeHead(206, {\n 'content-type': type,\n 'accept-ranges': 'bytes',\n 'content-range': `bytes ${start}-${end}/${size}`,\n 'content-length': end - start + 1,\n })\n res.end(buf.subarray(start, end + 1))\n return\n }\n res.writeHead(200, {\n 'content-type': type,\n 'accept-ranges': 'bytes',\n 'content-length': size,\n })\n res.end(buf)\n return\n }\n res.writeHead(404).end()\n })\n return new Promise((resolve) =>\n server.listen(0, () => {\n const addr = server.address()\n const port = typeof addr === 'object' && addr ? addr.port : 0\n resolve({ base: `http://localhost:${port}`, close: () => server.close() })\n }),\n )\n}\n\n/** Poll a capture/encode page for window.__done / __error / __progress. */\nexport async function waitForPageDone(\n page: Page,\n label: string,\n onProgress: (fraction: number) => void,\n timeoutMs: number,\n): Promise<Record<string, unknown>> {\n const start = Date.now()\n let last = -1\n for (;;) {\n const state: {\n done: Record<string, unknown> | null\n progress: number | null\n error: string | null\n } = await page.evaluate(\n '({ done: window.__done ?? null, progress: window.__progress ?? null, error: window.__error ?? null })',\n )\n if (state.error) throw new Error(`${label} failed: ${state.error}`)\n if (state.done) return state.done\n if (typeof state.progress === 'number') {\n const pct = Math.floor(state.progress * 10) * 10\n if (pct !== last) {\n onProgress(state.progress)\n last = pct\n }\n }\n if (Date.now() - start > timeoutMs) {\n throw new Error(\n `${label} timed out after ${Math.round(timeoutMs / 1000)}s`,\n )\n }\n await new Promise((r) => setTimeout(r, 400))\n }\n}\n","/**\n * Generic deterministic render harness — runs compiled vos animation code in\n * headless page(s) and returns encoded video bytes.\n *\n * Chunk-parallel (R1 of the rendering plan): because vos evaluation is a pure\n * function of time, the timeline shards into independent frame ranges. Each\n * chunk renders in its own page with chunk-LOCAL timestamps and byte-identical\n * encoder params; the finalize step stream-copies the chunks into one file\n * (@vosjs/render-core concat — no re-encode, keyframe per chunk by\n * construction). parallel=1 renders exactly like the historical single-flight\n * path (one chunk, no concat).\n *\n * Take-flavored details (video token, recording file) are optional so the\n * same harness renders studio takes and plain compositions (films, verify\n * fixtures) alike.\n */\nimport { readFile, rm } from 'node:fs/promises'\nimport { tweenRuntimeCode } from '@vosjs/tween/bundle'\nimport { elementsBundleCode } from '@vosjs/elements/bundle'\nimport { concatEncodedVideo, planChunks } from '@vosjs/render-core'\nimport { startTakeServer, waitForPageDone } from './server'\nimport type { RenderChunk } from '@vosjs/render-core'\nimport type { Browser } from 'playwright'\n\nconst MEDIABUNNY_URL = 'https://esm.sh/mediabunny@1.27.3?target=es2022'\nconst THREE_URL = 'https://esm.sh/three@0.183.0?target=es2022'\nconst THREE_ADDONS = 'https://esm.sh/three@0.183.0&target=es2022/examples/jsm/'\n\nexport interface RenderAnimationOptions {\n /** Compiled vos animation code (module exporting initVos). */\n animationCode: string\n /** Directory the page server roots at; chunk artifacts land here too. */\n workDir: string\n /** Source video file name inside workDir (studio takes), served → blob URL. */\n videoFile?: string\n /** Token inside animationCode replaced with the video blob URL. */\n videoToken?: string\n width: number\n height: number\n fps: number\n duration: number\n format: 'webm' | 'mp4'\n /** Max simultaneous chunk pages; 1 = single-flight (no concat). */\n parallel?: number\n /**\n * First GLOBAL frame to render (a range render: seek time starts here while\n * output timestamps stay zero-based). duration then covers the range only.\n */\n frameOffset?: number\n /** Encoder bitrate override (draft renders); default 10 Mbps. */\n bitrate?: number\n /**\n * Mix + mux an audio track in the SAME render (single-flight only — audio\n * stays out of chunks by design, mirroring the cloud single-flight path).\n * `producerCode` defines window.__vosAudioProducer__ (render-core);\n * `data` is the lowered composition data (videoToken replaced in-page).\n * `duration` is the FULL timeline — the producer builds the whole mix and\n * the page slices its own frame window, so a range render keeps audio.\n */\n audio?: { producerCode: string; data: unknown; duration: number }\n onProgress?: (fraction: number) => void\n}\n\nexport interface RenderAnimationResult {\n bytes: Uint8Array\n totalFrames: number\n /** Number of chunks actually rendered (1 = single-flight). */\n chunks: number\n}\n\nexport function renderPageHtml(): string {\n const importmap = JSON.stringify({\n imports: { three: THREE_URL, 'three/addons/': THREE_ADDONS },\n })\n return `<!doctype html><html><head><meta charset=\"utf-8\"><link rel=\"icon\" href=\"data:,\">\n<style>html,body{margin:0;padding:0;background:#000;overflow:hidden}canvas{display:block}</style>\n<script type=\"importmap\">${importmap}</script>\n</head><body>\n<script type=\"module\">\n import * as THREE from 'three'\n ${tweenRuntimeCode}\n // Vos Element System (bundled IIFE) — the same injection the engine's\n // render template performs. Take configs never touch ctx.elements, but a\n // POSTER program (the deliver --poster leg) is element text + an image\n // over the ground, and without this the elements silently never draw.\n ${elementsBundleCode}\n window.__vos__ = window.__vos__ || {}\n window.__vos__.elements = __vosElementsFactory.createVosElements(THREE)\n window.__gsap__ = globalThis.__vosTween.createTweenRecorder()\n window.__THREE__ = THREE\n window.__pageReady__ = true\n</script></body></html>`\n}\n\n/**\n * Runs inside the render page (serialized by Playwright). Renders frames\n * [startFrame, endFrame) — seeks GLOBAL time, captures CHUNK-LOCAL\n * timestamps — so every chunk is an independent, concat-ready file.\n */\nasync function renderInPage(opts: {\n animationCode: string\n token?: string\n videoUrl?: string\n W: number\n H: number\n fps: number\n startFrame: number\n endFrame: number\n format: 'webm' | 'mp4'\n bitrate: number\n mediabunnyUrl: string\n outName: string\n debug?: boolean\n audioProducerCode?: string\n audioDataJson?: string\n audioDuration?: number\n}) {\n const w = window as unknown as Record<string, any>\n try {\n const MB = await import(/* @vite-ignore */ opts.mediabunnyUrl)\n let code = opts.animationCode\n let vurl: string | null = null\n if (opts.videoUrl && opts.token) {\n // Blob URL: HTMLVideoElement seeking needs HTTP range support the take\n // server doesn't provide — a local blob is fully seekable.\n const vblob = await (await fetch(opts.videoUrl)).blob()\n vurl = URL.createObjectURL(vblob)\n code = code.split(opts.token).join(vurl)\n }\n\n // Audio first: a producer failure aborts before any frame work.\n let audioBuffer: AudioBuffer | null = null\n if (opts.audioProducerCode && opts.audioDataJson) {\n ;(0, eval)(opts.audioProducerCode)\n const dataJson =\n vurl && opts.token\n ? opts.audioDataJson.split(opts.token).join(vurl)\n : opts.audioDataJson\n audioBuffer = await w.__vosAudioProducer__({\n data: JSON.parse(dataJson),\n duration: opts.audioDuration,\n sampleRate: 48000,\n })\n }\n // The producer mixes the WHOLE timeline; mux only this page's own frame\n // window. On a full render the slice is a no-op cap (the RF D1 overlong\n // guard); on a --range render it is what keeps the clip's audio synced.\n if (audioBuffer) {\n const sr = audioBuffer.sampleRate\n const sliceStart = Math.round((opts.startFrame / opts.fps) * sr)\n const wanted = Math.ceil(\n ((opts.endFrame - opts.startFrame) / opts.fps) * sr,\n )\n if (sliceStart > 0 || audioBuffer.length > wanted) {\n const len = Math.max(\n 0,\n Math.min(wanted, audioBuffer.length - sliceStart),\n )\n if (len === 0) {\n audioBuffer = null\n } else {\n const sliced = new AudioBuffer({\n length: len,\n numberOfChannels: audioBuffer.numberOfChannels,\n sampleRate: sr,\n })\n for (let ch = 0; ch < audioBuffer.numberOfChannels; ch++) {\n sliced.copyToChannel(\n audioBuffer\n .getChannelData(ch)\n .subarray(sliceStart, sliceStart + len),\n ch,\n )\n }\n audioBuffer = sliced\n }\n }\n }\n const mod = await import(\n /* @vite-ignore */ URL.createObjectURL(\n new Blob([code], { type: 'text/javascript' }),\n )\n )\n\n // Deterministic export: compositions must seek (not play) their videos.\n w.__vos__ = w.__vos__ || {}\n w.__vos__.isPaused = true\n\n const deps = {\n THREE: w.__THREE__,\n gsap: w.__gsap__,\n resolution: {\n width: opts.W,\n height: opts.H,\n pixelRatio: 1,\n drawingBufferWidth: opts.W,\n drawingBufferHeight: opts.H,\n },\n preserveDrawingBuffer: true,\n }\n const result = await mod.initVos(document.body, deps)\n if (result.assetsReady) await result.assetsReady\n const { timeline } = result\n timeline.pause()\n timeline.seek(0, false)\n\n const canvas = document.querySelector('canvas') as HTMLCanvasElement\n canvas.width = opts.W\n canvas.height = opts.H\n canvas.style.width = opts.W + 'px'\n canvas.style.height = opts.H + 'px'\n\n // Encoder params are PINNED (codec/bitrate identical for every chunk of\n // a render) — stream-copy concat at finalize depends on it.\n const output = new MB.Output({\n format:\n opts.format === 'mp4'\n ? new MB.Mp4OutputFormat()\n : new MB.WebMOutputFormat(),\n target: new MB.BufferTarget(),\n })\n const videoSource = new MB.CanvasSource(canvas, {\n codec: opts.format === 'mp4' ? 'avc' : 'vp9',\n bitrate: opts.bitrate,\n })\n output.addVideoTrack(videoSource, { frameRate: opts.fps })\n let audioSource: any = null\n if (audioBuffer) {\n // AAC first for mp4 (compatibility), Opus fallback — mirrors finalizePage.\n const preferred = opts.format === 'mp4' ? 'aac' : 'opus'\n const audioCodec =\n preferred === 'aac' && !(await MB.canEncodeAudio('aac'))\n ? 'opus'\n : preferred\n audioSource = new MB.AudioBufferSource({\n codec: audioCodec,\n bitrate: MB.QUALITY_HIGH,\n })\n output.addAudioTrack(audioSource)\n }\n await output.start()\n if (audioSource && audioBuffer) {\n await audioSource.add(audioBuffer)\n audioSource.close()\n }\n\n const frames = opts.endFrame - opts.startFrame\n const raf = () => new Promise((r) => requestAnimationFrame(r))\n const wvr = () =>\n w.__vos__?.waitForVideosReady ? w.__vos__.waitForVideosReady() : null\n const pending = () => w.__vos__?.pendingDecodes?.size ?? 0\n\n // html5-path videos seek currentTime ASYNCHRONOUSLY — a cold seek into the\n // middle of the timeline (every chunk start) displays the element's stale\n // initial frame until the seek lands, and the readiness hooks above only\n // cover the webcodecs path. Wait until every video element reports a\n // completed, stable seek before capturing. (The per-frame 33ms steps after\n // warm-up keep up on their own — this guards the COLD seeks.)\n const collectVideos = (): HTMLVideoElement[] => {\n const out = new Set<HTMLVideoElement>()\n const cache = w.__vos__?.videoCache\n if (cache) {\n const vals =\n cache instanceof Map ? [...cache.values()] : Object.values(cache)\n for (const v of vals) {\n if (v?.tagName === 'VIDEO') out.add(v)\n else if (v?.el?.tagName === 'VIDEO') out.add(v.el)\n else if (v?.video?.tagName === 'VIDEO') out.add(v.video)\n }\n }\n document.querySelectorAll('video').forEach((v) => out.add(v))\n return [...out]\n }\n const videosSettled = () =>\n collectVideos().every((v) => !v.seeking && v.readyState >= 2)\n const waitVideosSettled = async (maxMs: number) => {\n const t0 = performance.now()\n // Two consecutive settled reads with stable currentTime — a seek that\n // hasn't dispatched yet can read \"settled\" for one tick.\n let stableTimes = ''\n while (performance.now() - t0 < maxMs) {\n await raf()\n if (videosSettled()) {\n const times = collectVideos()\n .map((v) => v.currentTime.toFixed(3))\n .join(',')\n if (times === stableTimes) return\n stableTimes = times\n } else {\n stableTimes = ''\n }\n }\n }\n\n for (let frame = opts.startFrame; frame < opts.endFrame; frame++) {\n const time = frame / opts.fps\n timeline.seek(time, false)\n await wvr()\n await raf()\n if (pending() > 0) {\n await wvr()\n await raf()\n }\n if (frame === opts.startFrame) await waitVideosSettled(8000)\n if (opts.debug && frame === opts.startFrame) {\n const png: Blob = await new Promise((res, rej) =>\n canvas.toBlob(\n (b) => (b ? res(b) : rej(new Error('toBlob'))),\n 'image/png',\n ),\n )\n await fetch(\n '/save?name=' + opts.outName.replace('.tmp', '-first.png'),\n {\n method: 'POST',\n body: png,\n },\n )\n }\n // Chunk-local timestamp: this chunk's file starts at t=0.\n await videoSource.add((frame - opts.startFrame) / opts.fps, 1 / opts.fps)\n w.__progress = (frame - opts.startFrame) / frames\n }\n\n await output.finalize()\n const buf = output.target.buffer\n await fetch('/save?name=' + opts.outName, { method: 'POST', body: buf })\n w.__done = { ok: true, bytes: buf.byteLength }\n } catch (e) {\n w.__error = String((e instanceof Error && e.stack) || e)\n }\n}\n\nasync function renderChunk(\n context: Awaited<ReturnType<Browser['newContext']>>,\n serverBase: string,\n chunk: RenderChunk,\n opts: RenderAnimationOptions,\n onChunkProgress: (fraction: number) => void,\n): Promise<string> {\n const outName = `render-chunk-${chunk.index}.tmp`\n const page = await context.newPage()\n try {\n page.on('console', (m) => {\n if (m.type() === 'error' || process.env.VOS_RENDER_DEBUG)\n process.stderr.write(\n ` [render page ${chunk.index} ${m.type()}] ${m.text()}\\n`,\n )\n })\n if (process.env.VOS_RENDER_DEBUG)\n page.on('pageerror', (e) =>\n process.stderr.write(\n ` [render pageerror ${chunk.index}] ${String(e)}\\n`,\n ),\n )\n await page.addInitScript(() => {\n ;(globalThis as unknown as Record<string, unknown>).__name = (\n f: unknown,\n ) => f\n })\n await page.goto(`${serverBase}/render.html`)\n await page.waitForFunction('window.__pageReady__ === true')\n const frameOffset = opts.frameOffset ?? 0\n const audio = opts.audio\n void page\n .evaluate(renderInPage, {\n animationCode: opts.animationCode,\n token: opts.videoToken,\n videoUrl: opts.videoFile ? `/${opts.videoFile}` : undefined,\n W: opts.width,\n H: opts.height,\n fps: opts.fps,\n startFrame: chunk.startFrame + frameOffset,\n endFrame: chunk.endFrame + frameOffset,\n format: opts.format,\n bitrate: opts.bitrate ?? 10_000_000,\n mediabunnyUrl: MEDIABUNNY_URL,\n outName,\n debug: process.env.VOILA_DEBUG_CHUNKS === '1',\n audioProducerCode: audio?.producerCode,\n audioDataJson: audio ? JSON.stringify(audio.data) : undefined,\n audioDuration: audio?.duration,\n })\n .catch(() => {})\n const timeoutMs = 120_000 + chunk.frameCount * 500\n await waitForPageDone(\n page,\n `render chunk ${chunk.index}`,\n onChunkProgress,\n timeoutMs,\n )\n return outName\n } finally {\n await page.close()\n }\n}\n\nexport async function renderAnimation(\n browser: Browser,\n opts: RenderAnimationOptions,\n): Promise<RenderAnimationResult> {\n const totalFrames = Math.ceil(opts.duration * opts.fps)\n const chunks = planChunks(totalFrames, opts.fps, {\n maxParallel: Math.max(1, opts.parallel ?? 1),\n })\n\n // Audio stays out of chunks by design: only a single-flight render muxes\n // it (renderTake forces parallel=1 when audio is wanted). A range render\n // keeps audio — the page slices its frame window from the full mix.\n const effOpts: RenderAnimationOptions =\n opts.audio && chunks.length > 1 ? { ...opts, audio: undefined } : opts\n\n const server = await startTakeServer(opts.workDir, {\n '/render.html': renderPageHtml(),\n })\n // One context for all chunk pages: they share the HTTP cache, so CDN\n // module imports (three, mediabunny) are fetched once, not per chunk.\n const context = await browser.newContext({\n viewport: { width: opts.width, height: opts.height },\n })\n try {\n const progress = new Array<number>(chunks.length).fill(0)\n const reportProgress = () => {\n const done = chunks.reduce(\n (sum, c, i) => sum + c.frameCount * progress[i],\n 0,\n )\n opts.onProgress?.(done / totalFrames)\n }\n\n const outNames = await Promise.all(\n chunks.map((chunk) =>\n renderChunk(context, server.base, chunk, effOpts, (fraction) => {\n progress[chunk.index] = fraction\n reportProgress()\n }),\n ),\n )\n\n const files = await Promise.all(\n outNames.map((name) => readFile(`${opts.workDir}/${name}`)),\n )\n await Promise.all(\n outNames.map((name) => rm(`${opts.workDir}/${name}`, { force: true })),\n )\n\n if (chunks.length === 1) {\n return { bytes: new Uint8Array(files[0]), totalFrames, chunks: 1 }\n }\n\n const { bytes } = await concatEncodedVideo(\n chunks.map((chunk, i) => ({\n data: new Uint8Array(files[i]),\n duration: chunk.duration,\n })),\n { format: opts.format, frameRate: opts.fps },\n )\n return { bytes, totalFrames, chunks: chunks.length }\n } finally {\n await context.close()\n server.close()\n }\n}\n","/**\n * The backdrop SET: the loops the platform publishes at `GET /api/backdrops`\n * (public, no credential, each with its 1080p loop, poster, period and\n * ground). Two readers: `--background <slug>` on the verification verbs, and\n * the frame a FRESH take opens on, which is the set's first ready loop, the\n * house pick, so a take made here opens on what a take made in the studio\n * opens on. The pick is the platform's ordering of its set, never a\n * constant in this package: the studio names its own, the CLI reads it.\n */\nimport { UsageError } from './args'\nimport type { Backdrop } from '@vosjs/studio-core'\n\nexport interface BackdropRow {\n slug: string\n title?: string\n duration: number\n ground?: string\n urls: {\n '1080p': string | null\n '2k'?: string | null\n poster?: string | null\n }\n}\n\n/** A backdrop from the set, with the slug it was picked by. */\nexport interface NamedBackdrop extends Backdrop {\n slug: string\n}\n\n/** Reads the set. Throws when the origin cannot be reached or answers badly. */\nexport async function fetchBackdropSet(origin: string): Promise<BackdropRow[]> {\n const base = origin.replace(/\\/+$/, '')\n const res = await fetch(`${base}/api/backdrops`)\n if (!res.ok)\n throw new Error(`GET ${base}/api/backdrops answered ${res.status}`)\n const body = (await res.json()) as { backdrops?: unknown }\n return Array.isArray(body.backdrops) ? (body.backdrops as BackdropRow[]) : []\n}\n\nfunction rowBackdrop(row: BackdropRow): NamedBackdrop | null {\n const key = row.urls['1080p']\n if (!key) return null\n return {\n slug: row.slug,\n key,\n kind: 'video',\n duration: row.duration,\n ...(row.urls.poster ? { poster: row.urls.poster } : {}),\n ...(row.ground ? { ground: row.ground } : {}),\n }\n}\n\n/** The house backdrop: the first row of the set with a loop, or null. */\nexport function houseBackdrop(\n rows: readonly BackdropRow[],\n): NamedBackdrop | null {\n for (const row of rows) {\n const b = rowBackdrop(row)\n if (b) return b\n }\n return null\n}\n\n/** One row of the set by slug; null when it is absent or has no loop yet. */\nexport function backdropBySlug(\n rows: readonly BackdropRow[],\n slug: string,\n): NamedBackdrop | null {\n const row = rows.find((r) => r.slug === slug)\n return row ? rowBackdrop(row) : null\n}\n\n/** A bare slug (`soft-beams`), never a URL, a path or `none`. */\nexport function isBackdropSlug(value: string): boolean {\n return /^[a-z0-9][a-z0-9-]{0,49}$/.test(value) && value !== 'none'\n}\n\nconst VIDEO_EXT = /\\.(webm|mp4|mov|m4v)(\\?|#|$)/i\nconst IMAGE_EXT = /\\.(jpe?g|png|webp|gif|avif)(\\?|#|$)/i\n\n/**\n * The media kind a URL or take-dir path implies. Video when the extension\n * says nothing (the flagship case is a loop); `--set` gives precise control\n * when the URL is opaque.\n */\nexport function inferBackgroundKind(url: string): 'video' | 'image' {\n if (IMAGE_EXT.test(url)) return 'image'\n if (VIDEO_EXT.test(url)) return 'video'\n return 'video'\n}\n\n/** Default loop length assumed for a --background video with no explicit duration. */\nexport const BACKGROUND_DEFAULT_DURATION = 10\n\n/** A backdrop for a URL or take-dir path handed to `--background`. */\nexport function backdropFromKey(key: string, duration?: number): Backdrop {\n const kind = inferBackgroundKind(key)\n return kind === 'video'\n ? { key, kind, duration: duration ?? BACKGROUND_DEFAULT_DURATION }\n : { key, kind }\n}\n\n/**\n * The backdrop a fresh take opens on, from `--background`: `none` is the\n * bare frame, a slug is that loop (refused in words when the set lacks it),\n * a URL or path is taken as given, and ABSENT is the set's house pick. When\n * the set cannot be read and nothing was asked, the take opens on the bare\n * frame and `note` says so; an asked slug that cannot be read is an error.\n */\nexport async function openingBackdrop(\n background: string | undefined,\n origin: string,\n): Promise<{ backdrop: Backdrop | null; note?: string }> {\n if (background === 'none' || background === '') return { backdrop: null }\n if (background !== undefined && !isBackdropSlug(background)) {\n return { backdrop: backdropFromKey(background) }\n }\n let rows: BackdropRow[]\n try {\n rows = await fetchBackdropSet(origin)\n } catch (err) {\n if (background !== undefined) {\n throw new UsageError(\n `--background \"${background}\" — could not read the backdrop set from ${origin}/api/backdrops (${(err as Error).message}); pass a URL instead`,\n )\n }\n return {\n backdrop: null,\n note: `could not read the backdrop set from ${origin}/api/backdrops; the take opens on a flat ground (--background <slug|url> picks one later)`,\n }\n }\n if (background !== undefined) {\n const hit = backdropBySlug(rows, background)\n if (!hit) {\n throw new UsageError(\n `--background \"${background}\" is not in the set (${rows.map((b) => b.slug).join(' | ') || 'empty'}); GET ${origin}/api/backdrops lists it, or pass a URL`,\n )\n }\n return { backdrop: hit }\n }\n const house = houseBackdrop(rows)\n return house\n ? { backdrop: house }\n : {\n backdrop: null,\n note: `the backdrop set at ${origin}/api/backdrops has no ready loop; the take opens on a flat ground`,\n }\n}\n","/**\n * Doc-override flags for `render` / `frames` — the product-surface verification\n * seam (verification is how customers use it). The CLI and the studio are\n * producer AND consumer: when we want to CHECK a doc field\n * (a browser frame, a background, a tilt span), the right move is not a bespoke\n * harness but a flag that expresses it on the product surface — so the check and\n * the customer feature are the same thing. Every doc field is reachable via a\n * generic `--set <path>=<value>` (agents have the schema); the marquee\n * presentation knobs get named aliases (`--frame`, `--background`).\n *\n * Overrides patch the take's doc IN MEMORY only (doc.json on disk stays the\n * source of truth) and are LINT-GATED before rendering — a bad override fails\n * exactly like a bad doc.json, so the override path can't ship an invalid doc.\n */\nimport { lintDoc } from './validateDoc'\nimport { UsageError } from './args'\nimport {\n BACKGROUND_DEFAULT_DURATION,\n backdropBySlug,\n fetchBackdropSet,\n inferBackgroundKind,\n isBackdropSlug,\n} from './backdrops'\nimport type { ProjectDoc } from '@vosjs/studio-core'\n\nexport { BACKGROUND_DEFAULT_DURATION, isBackdropSlug } from './backdrops'\n\nexport interface DocOverrides {\n /** raw `path=value` expressions from repeated --set. */\n set?: string[]\n /** --frame alias → frame.browserBar.kind. */\n frame?: string\n /** --background alias → frame.backgroundMedia (kind inferred from the URL,\n * or a backdrop SLUG from GET /api/backdrops, resolved by\n * resolveBackdropSlug before the sync apply). */\n background?: string\n /** The loop length a resolved backdrop slug brought with it. */\n backgroundDuration?: number\n /** Platform origin for slug resolution (platformOrigin(flags)). */\n origin?: string\n}\n\n/**\n * `--background <slug>` names a backdrop from the set. The set is\n * public (`GET /api/backdrops`), so this needs no credential; it rewrites\n * the override IN PLACE to the loop's 1080p URL and its own period, and\n * refuses in words when the slug is not in the set. URLs pass untouched.\n */\nexport async function resolveBackdropSlug(o: DocOverrides): Promise<void> {\n if (!o.background || !isBackdropSlug(o.background)) return\n const origin = (o.origin ?? 'https://vos.so').replace(/\\/+$/, '')\n let list: Awaited<ReturnType<typeof fetchBackdropSet>>\n try {\n list = await fetchBackdropSet(origin)\n } catch {\n throw new UsageError(\n `--background \"${o.background}\" — could not read the backdrop set from ${origin}/api/backdrops; pass a URL instead`,\n )\n }\n const hit = backdropBySlug(list, o.background)\n if (!hit) {\n throw new UsageError(\n `--background \"${o.background}\" is not in the set (${list.map((b) => b.slug).join(' | ') || 'empty'}); GET ${origin}/api/backdrops lists it, or pass a URL`,\n )\n }\n o.background = hit.key\n o.backgroundDuration = hit.duration\n}\n\nexport function hasOverrides(o: DocOverrides): boolean {\n return !!(\n o.set?.length ||\n o.frame !== undefined ||\n o.background !== undefined\n )\n}\n\n/** Friendly --frame values → BrowserBarStyle.kind. */\nconst FRAME_KINDS: Record<string, string> = {\n macos: 'mac-light',\n mac: 'mac-light',\n 'mac-light': 'mac-light',\n 'mac-dark': 'mac-dark',\n windows: 'windows-light',\n 'windows-light': 'windows-light',\n 'windows-dark': 'windows-dark',\n minimal: 'minimal',\n none: 'none',\n hidden: 'none',\n}\n\n/**\n * Coerce a `--set` value: JSON when it parses (numbers, booleans, null, objects,\n * arrays), else the raw string — so `tilt[0].rx=8` is a number, `tilt=null`\n * clears it, `frame.background=#000` stays a string, and\n * `frame.backgroundMedia={\"kind\":\"video\",\"key\":\"…\",\"duration\":10,\"dim\":0.2}`\n * is an object.\n */\nexport function coerceValue(raw: string): unknown {\n try {\n return JSON.parse(raw)\n } catch {\n return raw\n }\n}\n\ninterface PathSeg {\n key: string | number\n}\n\n/**\n * Tokenize `frame.browserBar.kind` / `zoom[0].level` into path segments, strictly\n * (contiguous — no empty segments, no `a..b`, no leading/trailing dot).\n */\nfunction parsePath(path: string): PathSeg[] {\n const bad = (): never => {\n throw new UsageError(`--set: invalid path \"${path}\"`)\n }\n const segs: PathSeg[] = []\n let i = 0\n let expectKey = true // start of the path, or just after a '.'\n while (i < path.length) {\n const c = path[i]\n if (c === '.') {\n if (expectKey) bad() // leading '.' or '..'\n expectKey = true\n i++\n } else if (c === '[') {\n if (expectKey) bad() // '[' can only follow a name/index\n const j = path.indexOf(']', i)\n if (j < 0) bad()\n const num = path.slice(i + 1, j)\n if (!/^\\d+$/.test(num)) bad()\n segs.push({ key: Number(num) })\n i = j + 1\n } else {\n let j = i\n while (j < path.length && path[j] !== '.' && path[j] !== '[') j++\n segs.push({ key: path.slice(i, j) })\n expectKey = false\n i = j\n }\n }\n if (expectKey || !segs.length) bad() // trailing '.' or empty\n return segs\n}\n\n/** Set a nested path on an object, creating intermediate objects/arrays. */\nexport function setPath(\n root: Record<string, unknown>,\n path: string,\n value: unknown,\n): void {\n const segs = parsePath(path)\n let node: unknown = root\n for (let i = 0; i < segs.length - 1; i++) {\n const key = segs[i].key\n const nextIsIndex = typeof segs[i + 1].key === 'number'\n const container = node as Record<string | number, unknown>\n if (container[key] === undefined || container[key] === null) {\n container[key] = nextIsIndex ? [] : {}\n }\n node = container[key]\n if (typeof node !== 'object' || node === null) {\n throw new UsageError(\n `--set: \"${path}\" traverses a non-object at \"${String(key)}\"`,\n )\n }\n }\n ;(node as Record<string | number, unknown>)[segs[segs.length - 1].key] = value\n}\n\n/**\n * Apply overrides to `doc` IN PLACE. Named aliases first (so an explicit --set\n * can still override them), then --set expressions in order. Returns a\n * human-readable summary of what was applied. Throws UsageError on a malformed\n * expression; SEMANTIC validity is the caller's lint pass.\n */\nexport function applyDocOverrides(doc: ProjectDoc, o: DocOverrides): string[] {\n const applied: string[] = []\n const d = doc as unknown as Record<string, unknown>\n\n if (o.frame !== undefined) {\n const kind = FRAME_KINDS[o.frame.toLowerCase()]\n if (!kind) {\n throw new UsageError(\n `--frame \"${o.frame}\" — one of: ${Object.keys(FRAME_KINDS).join(' | ')}`,\n )\n }\n setPath(d, 'frame.browserBar.kind', kind)\n applied.push(`frame.browserBar.kind = ${kind}`)\n }\n\n if (o.background !== undefined) {\n if (o.background === 'none' || o.background === '') {\n setPath(d, 'frame.backgroundMedia', null)\n applied.push('frame.backgroundMedia = null')\n } else {\n const kind = inferBackgroundKind(o.background)\n const media: Record<string, unknown> = { kind, key: o.background, dim: 0 }\n if (kind === 'video')\n media.duration = o.backgroundDuration ?? BACKGROUND_DEFAULT_DURATION\n setPath(d, 'frame.backgroundMedia', media)\n applied.push(`frame.backgroundMedia = ${kind} ${o.background}`)\n }\n }\n\n for (const expr of o.set ?? []) {\n const eq = expr.indexOf('=')\n if (eq < 1) throw new UsageError(`--set expects path=value (got \"${expr}\")`)\n const path = expr.slice(0, eq)\n const value = coerceValue(expr.slice(eq + 1))\n setPath(d, path, value)\n applied.push(`${path} = ${JSON.stringify(value)}`)\n }\n\n return applied\n}\n\n/**\n * Apply overrides then LINT — the gate that makes the override path as safe as\n * editing doc.json. Throws UsageError (bad expression or resulting doc invalid)\n * so `render`/`frames` refuse an override that would produce a broken video.\n */\nexport function applyAndValidate(doc: ProjectDoc, o: DocOverrides): string[] {\n const applied = applyDocOverrides(doc, o)\n const lint = lintDoc(doc)\n if (lint.problems.length) {\n throw new UsageError(\n `override produced an invalid doc:\\n ${lint.problems.join('\\n ')}`,\n )\n }\n return applied\n}\n","/**\n * The take digest — the agent's eyes. Slices the FOOTAGE\n * (never the composed render) at the moments the cursor telemetry says\n * matter: one full frame + a crop around the target rect per moment, per-\n * second motion bins, the scene changes those bins reveal, the planners'\n * proposals beside each moment, all in the doc's own normalized units.\n *\n * Two page passes on one bare page over the take server: (1) motion bins by\n * seeking every source second and diffing a 64×36 luma thumbnail — cheap,\n * and the second witness for \"nothing happened here\"; (2) the moment frames.\n * CLI takes reuse their screencast JPEGs (nearest tMs) instead of decoding.\n * Everything the agent reads lands in `digest/` beside the take; `vos push`\n * never uploads it.\n */\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport {\n DIGEST_CROP_MAX,\n DIGEST_FULL_MAX,\n DIGEST_VERSION,\n MOTION_DELTA,\n buildDigest,\n cropBox,\n frameGeometry,\n momentsFromDoc,\n outputDurationOf,\n planForDigest,\n sceneChanges,\n} from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake, readJson } from './take'\nimport { startTakeServer, waitForPageDone } from './server'\nimport type {\n Digest,\n DigestImageRef,\n Moment,\n ProjectDoc,\n PxRect,\n TranscriptSegment,\n} from '@vosjs/studio-core'\nimport type { Browser } from 'playwright'\n\nexport const DIGEST_DIR = 'digest'\n// Geometry, thresholds and the document shape are studio-core's (shared\n// with the fleet's digest job): one crop geometry, one builder.\nexport {\n DIGEST_CROP_MAX,\n DIGEST_FULL_MAX,\n DIGEST_VERSION,\n} from '@vosjs/studio-core'\n\nexport interface DigestOptions {\n outDir?: string\n full?: number\n crop?: number\n /** Skip the browser passes (moments only; activity null). */\n frames?: boolean\n transcript?: readonly TranscriptSegment[] | null\n /** A reference doc whose style fields are REPORTED (never applied here). */\n style?: { from: string; doc: ProjectDoc } | null\n}\n\nexport type { Digest } from '@vosjs/studio-core'\n\nexport interface DigestResult {\n file: string\n outDir: string\n digest: Digest\n bytes: number\n}\n\ninterface FrameSource {\n kind: 'video' | 'frames'\n url?: string\n frames?: { t: number; url: string }[]\n}\n\n/** Pass 1 (in page): frame size + per-second motion bins. */\nasync function binsInPage(opts: {\n source: FrameSource\n durationS: number\n delta: number\n}) {\n const w = window as unknown as Record<string, any>\n try {\n const getFrame = await (window as any).__digestSource(opts.source)\n // The INTRINSIC size (videoWidth / naturalWidth), stamped on the source\n // by the page — a <video> element's own .width is its CSS box (0 here).\n const size = { width: getFrame.width, height: getFrame.height }\n await getFrame(0)\n const cw = 64\n const ch = 36\n const c = document.createElement('canvas')\n c.width = cw\n c.height = ch\n const ctx = c.getContext('2d', { willReadFrequently: true })!\n let prev: Uint8ClampedArray | null = null\n const bins: number[] = []\n const n = Math.max(1, Math.ceil(opts.durationS))\n for (let i = 0; i < n; i++) {\n const el = await getFrame(Math.min(opts.durationS, i + 0.5))\n ctx.drawImage(el, 0, 0, cw, ch)\n const d = ctx.getImageData(0, 0, cw, ch).data\n const luma = new Uint8ClampedArray(cw * ch)\n for (let p = 0; p < luma.length; p++) {\n const o = p * 4\n luma[p] = (d[o] * 299 + d[o + 1] * 587 + d[o + 2] * 114) / 1000\n }\n if (!prev) bins.push(0)\n else {\n let changed = 0\n for (let p = 0; p < luma.length; p++)\n if (Math.abs(luma[p] - prev[p]) > opts.delta) changed++\n bins.push(Math.round((changed / luma.length) * 1000) / 1000)\n }\n prev = luma\n w.__progress = (i + 1) / n\n }\n w.__done = { ok: true, bins, width: size.width, height: size.height }\n } catch (e) {\n w.__error = String((e instanceof Error && e.stack) || e)\n }\n}\n\n/** Pass 2 (in page): the moment frames, crops and the contact sheet. */\nasync function framesInPage(opts: {\n source: FrameSource\n shots: {\n id: string\n label: string\n t: number\n full: string\n crop: string | null\n region: { x: number; y: number; w: number; h: number }\n box: { x: number; y: number; w: number; h: number } | null\n }[]\n fullMax: number\n cropMax: number\n sheet: string\n}) {\n const w = window as unknown as Record<string, any>\n try {\n const getFrame = await (window as any).__digestSource(opts.source)\n const sizes: Record<string, { width: number; height: number }> = {}\n const toPng = (c: HTMLCanvasElement) =>\n new Promise<Blob>((res, rej) =>\n c.toBlob(\n (b) => (b ? res(b) : rej(new Error('toBlob failed'))),\n 'image/png',\n ),\n )\n const save = async (name: string, c: HTMLCanvasElement) => {\n await fetch('/save?name=' + name, {\n method: 'POST',\n body: await toPng(c),\n })\n sizes[name] = { width: c.width, height: c.height }\n }\n const fit = (bw: number, bh: number, max: number) => {\n const s = Math.min(1, max / Math.max(bw, bh))\n return {\n w: Math.max(1, Math.round(bw * s)),\n h: Math.max(1, Math.round(bh * s)),\n }\n }\n const tiles: { label: string; c: HTMLCanvasElement }[] = []\n for (let i = 0; i < opts.shots.length; i++) {\n const s = opts.shots[i]\n const el = await getFrame(s.t)\n const full = document.createElement('canvas')\n const f = fit(s.region.w, s.region.h, opts.fullMax)\n full.width = f.w\n full.height = f.h\n full\n .getContext('2d')!\n .drawImage(\n el,\n s.region.x,\n s.region.y,\n s.region.w,\n s.region.h,\n 0,\n 0,\n f.w,\n f.h,\n )\n await save(s.full, full)\n let tileSrc = full\n if (s.crop && s.box) {\n const crop = document.createElement('canvas')\n const k = fit(s.box.w, s.box.h, opts.cropMax)\n crop.width = k.w\n crop.height = k.h\n crop\n .getContext('2d')!\n .drawImage(el, s.box.x, s.box.y, s.box.w, s.box.h, 0, 0, k.w, k.h)\n await save(s.crop, crop)\n tileSrc = crop\n }\n const tile = document.createElement('canvas')\n const tw = 240\n const th = Math.max(1, Math.round((tw * tileSrc.height) / tileSrc.width))\n tile.width = tw\n tile.height = th\n tile.getContext('2d')!.drawImage(tileSrc, 0, 0, tw, th)\n tiles.push({ label: s.label, c: tile })\n w.__progress = (i + 1) / opts.shots.length\n }\n // The contact sheet: crops (or fulls) in time order, ids burned in.\n if (tiles.length) {\n const cols = Math.min(6, tiles.length)\n const tw = 240\n const th = Math.max(...tiles.map((t) => t.c.height))\n const rows = Math.ceil(tiles.length / cols)\n const sheet = document.createElement('canvas')\n sheet.width = cols * (tw + 8) + 8\n sheet.height = rows * (th + 26) + 8\n const ctx = sheet.getContext('2d')!\n ctx.fillStyle = '#111'\n ctx.fillRect(0, 0, sheet.width, sheet.height)\n ctx.font = '12px ui-monospace, Menlo, monospace'\n tiles.forEach((t, i) => {\n const x = 8 + (i % cols) * (tw + 8)\n const y = 8 + Math.floor(i / cols) * (th + 26)\n ctx.drawImage(t.c, x, y)\n ctx.fillStyle = '#eee'\n ctx.fillText(t.label, x, y + th + 16)\n })\n await save(opts.sheet, sheet)\n }\n w.__done = { ok: true, sizes }\n } catch (e) {\n w.__error = String((e instanceof Error && e.stack) || e)\n }\n}\n\n/** The bare page: a frame source over a <video> (seek + settle) or JPEGs. */\nexport function digestPageHtml(): string {\n return `<!doctype html><html><head><meta charset=\"utf-8\"><link rel=\"icon\" href=\"data:,\">\n<style>html,body{margin:0;background:#000}video,img{position:absolute;left:-99999px}</style>\n</head><body><script>\nwindow.__digestSource = async (source) => {\n const raf = () => new Promise((r) => requestAnimationFrame(r))\n if (source.kind === 'video') {\n const blob = await (await fetch(source.url)).blob()\n const v = document.createElement('video')\n v.muted = true\n v.preload = 'auto'\n v.src = URL.createObjectURL(blob)\n document.body.appendChild(v)\n await new Promise((res, rej) => {\n v.addEventListener('loadeddata', () => res(), { once: true })\n v.addEventListener('error', () => rej(new Error('video failed to load')), { once: true })\n })\n const settle = async () => {\n const t0 = performance.now()\n let last = ''\n while (performance.now() - t0 < 4000) {\n await raf()\n if (!v.seeking && v.readyState >= 2) {\n const now = v.currentTime.toFixed(3)\n if (now === last) return\n last = now\n } else last = ''\n }\n }\n const getFrame = async (t) => {\n const target = Math.max(0, Math.min(t, Math.max(0, (v.duration || t) - 0.02)))\n if (Math.abs(v.currentTime - target) > 0.0005 || v.readyState < 2) {\n await new Promise((res) => {\n const on = () => { v.removeEventListener('seeked', on); res() }\n v.addEventListener('seeked', on)\n v.currentTime = target\n })\n }\n await settle()\n return v\n }\n const first = await getFrame(0)\n getFrame.width = first.videoWidth\n return Object.assign(getFrame, { width: v.videoWidth, height: v.videoHeight })\n }\n const frames = source.frames\n const img = new Image()\n document.body.appendChild(img)\n const load = (url) => new Promise((res, rej) => {\n if (img.src.endsWith(url) && img.complete) return res(img)\n img.onload = () => res(img)\n img.onerror = () => rej(new Error('frame failed to load: ' + url))\n img.src = url\n })\n const getFrame = async (t) => {\n let best = frames[0]\n for (const f of frames) if (Math.abs(f.t - t) < Math.abs(best.t - t)) best = f\n await load(best.url)\n return img\n }\n const first = await getFrame(0)\n return Object.assign(getFrame, { width: first.naturalWidth, height: first.naturalHeight })\n}\nwindow.__pageReady__ = true\n</script></body></html>`\n}\n\nexport async function digestTake(\n browser: Browser | null,\n dir: string,\n opts: DigestOptions = {},\n): Promise<DigestResult> {\n const take = await loadTake(dir)\n if (!take.doc) throw new Error(`${dir} has no doc.json — run plan first`)\n const doc = take.doc\n const meta = doc.source.meta\n // Re-planned once the bins exist: the speed planner tells playback from\n // idle only with the activity witness.\n let plan = planForDigest(doc)\n // A transcript.json beside the take (Whisper's shape) is picked up\n // unasked; --transcript names another file.\n const transcript = opts.transcript ?? (await discoverTranscript(dir))\n const outDir = resolve(opts.outDir ?? join(dir, DIGEST_DIR))\n await mkdir(outDir, { recursive: true })\n const fullMax = opts.full ?? DIGEST_FULL_MAX\n const cropMax = opts.crop ?? DIGEST_CROP_MAX\n const wantFrames = opts.frames !== false && browser !== null\n const durS = meta.durationMs / 1000\n\n let bins: number[] | null = null\n let frameW: number | null = null\n let frameH: number | null = null\n let sizes: Partial<Record<string, { width: number; height: number }>> = {}\n let sheet: string | null = null\n let moments: Moment[]\n const boxes = new Map<string, PxRect>()\n\n // The frame source: screencast JPEGs when the take has them, else the video.\n let source: FrameSource = { kind: 'video', url: `/${RECORDING_NAME}` }\n if (existsSync(take.paths.framesIndex) && existsSync(take.paths.framesDir)) {\n const index = await readJson<{ file: string; tMs: number }[]>(\n take.paths.framesIndex,\n )\n if (Array.isArray(index) && index.length) {\n source = {\n kind: 'frames',\n frames: index.map((f) => ({\n t: f.tMs / 1000,\n url: `/frames/${f.file}`,\n })),\n }\n }\n }\n\n if (wantFrames) {\n if (source.kind === 'video' && !existsSync(take.paths.recording))\n throw new Error(\n `${dir} has no ${RECORDING_NAME} — pull it with \\`vos pull --media\\` first`,\n )\n const server = await startTakeServer(dir, {\n '/digest.html': digestPageHtml(),\n })\n const context = await browser.newContext({\n viewport: { width: 640, height: 360 },\n })\n try {\n const page = await context.newPage()\n page.on('console', (m) => {\n if (m.type() === 'error')\n process.stderr.write(` [digest page] ${m.text()}\\n`)\n })\n await page.addInitScript(() => {\n ;(globalThis as unknown as Record<string, unknown>).__name = (\n f: unknown,\n ) => f\n })\n await page.goto(`${server.base}/digest.html`)\n await page.waitForFunction('window.__pageReady__ === true')\n\n // Pass 1: bins.\n void page\n .evaluate(binsInPage, { source, durationS: durS, delta: MOTION_DELTA })\n .catch(() => {})\n const b = await waitForPageDone(\n page,\n 'digest bins',\n () => {},\n 60_000 + durS * 400,\n )\n bins = b.bins as number[]\n plan = planForDigest(doc, bins)\n frameW = b.width as number\n frameH = b.height as number\n\n moments = momentsFromDoc(doc, plan, {\n bins,\n scenes: sceneChanges(bins),\n transcript,\n })\n\n // Pass 2: frames.\n const geo = frameGeometry(doc, frameW, frameH)\n const shots = moments\n .filter((m) => m.at !== null)\n .map((m) => {\n const box = cropBox(m, geo, meta)\n if (box) boxes.set(m.id, box)\n return {\n id: m.id,\n label: `${m.id} ${m.kind} ${m.source.in.toFixed(1)}s`,\n t: m.at!,\n full: `${m.id}.full.png`,\n crop: box ? `${m.id}.crop.png` : null,\n region: geo.region,\n box,\n }\n })\n await page.evaluate('window.__done = null; window.__progress = null')\n void page\n .evaluate(framesInPage, {\n source,\n shots,\n fullMax,\n cropMax,\n sheet: 'sheet.png',\n })\n .catch(() => {})\n const f = await waitForPageDone(\n page,\n 'digest frames',\n () => {},\n 60_000 + shots.length * 4_000,\n )\n sizes = f.sizes as Record<string, { width: number; height: number }>\n for (const name of Object.keys(sizes)) {\n const from = join(dir, name)\n const to = join(outDir, name)\n if (from !== to && existsSync(from)) await rename(from, to)\n }\n if (sizes['sheet.png']) sheet = 'sheet.png'\n } finally {\n await context.close()\n server.close()\n }\n } else {\n // --no-frames after a real pass (the skill re-digests after retiming to\n // read fresh OUTPUT times): the prior digest's bins, scenes and images\n // are measurements of the FOOTAGE, which retiming does not change —\n // carry them forward instead of dropping them.\n const prior = await readPriorDigest(outDir)\n bins = prior?.activity ?? null\n if (bins) plan = planForDigest(doc, bins)\n frameW = prior?.take.frameWidth ?? null\n frameH = prior?.take.frameHeight ?? null\n moments = momentsFromDoc(doc, plan, {\n bins,\n scenes: bins ? sceneChanges(bins) : [],\n transcript,\n })\n if (prior) {\n for (const m of moments) {\n const p = prior.moments.find(\n (x) =>\n x.id === m.id && x.kind === m.kind && x.source.in === m.source.in,\n )\n if (!p) continue\n for (const f of [p.full, p.crop]) {\n if (!f) continue\n const size = await pngSize(join(outDir, f))\n if (size) sizes[f] = size\n }\n if (p.box) boxes.set(m.id, p.box)\n }\n if (prior.images.sheet && existsSync(join(outDir, prior.images.sheet)))\n sheet = prior.images.sheet\n }\n }\n\n const images = new Map<string, DigestImageRef>()\n for (const m of moments) {\n const full = sizes[`${m.id}.full.png`] ? `${m.id}.full.png` : null\n const crop = sizes[`${m.id}.crop.png`] ? `${m.id}.crop.png` : null\n if (!full && !crop) continue\n images.set(m.id, {\n full,\n crop,\n box: crop ? (boxes.get(m.id) ?? null) : null,\n fullSize: full ? (sizes[full] ?? null) : null,\n cropSize: crop ? (sizes[crop] ?? null) : null,\n })\n }\n const digest = buildDigest({\n doc,\n plan,\n moments,\n outputDuration: outputDurationOf(doc),\n bins,\n frame:\n frameW !== null && frameH !== null\n ? { width: frameW, height: frameH }\n : null,\n images,\n sheet,\n style: opts.style ?? null,\n transcript,\n })\n const file = join(outDir, 'digest.json')\n const body = JSON.stringify(digest, null, 2)\n await writeFile(file, body)\n return { file, outDir, digest, bytes: Buffer.byteLength(body) }\n}\n\n/** `<take>/transcript.json` when present and well-formed; never throws. */\nasync function discoverTranscript(\n dir: string,\n): Promise<TranscriptSegment[] | null> {\n const file = join(dir, 'transcript.json')\n if (!existsSync(file)) return null\n try {\n return parseTranscript(JSON.parse(await readFile(file, 'utf8')))\n } catch {\n return null\n }\n}\n\n/** The digest already in outDir, when it parses; never throws. */\nasync function readPriorDigest(outDir: string): Promise<Digest | null> {\n try {\n const raw = JSON.parse(\n await readFile(join(outDir, 'digest.json'), 'utf8'),\n ) as Digest\n return raw.digestVersion === DIGEST_VERSION && Array.isArray(raw.moments)\n ? raw\n : null\n } catch {\n return null\n }\n}\n\n/** Width/height from a PNG header (IHDR), or null when the file is not one. */\nasync function pngSize(\n file: string,\n): Promise<{ width: number; height: number } | null> {\n try {\n const buf = await readFile(file)\n if (buf.length < 24 || buf.readUInt32BE(0) !== 0x89504e47) return null\n return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) }\n } catch {\n return null\n }\n}\n\n/** Accept Whisper's `{segments:[…]}` or a bare `[{start,end,text}]`. */\nexport function parseTranscript(raw: unknown): TranscriptSegment[] {\n const list = Array.isArray(raw)\n ? raw\n : raw && typeof raw === 'object' && Array.isArray((raw as any).segments)\n ? (raw as any).segments\n : null\n if (!list)\n throw new Error('transcript must be [{start,end,text}] or {segments:[…]}')\n return (list as Record<string, unknown>[])\n .filter(\n (s) =>\n typeof s.start === 'number' &&\n typeof s.end === 'number' &&\n typeof s.text === 'string',\n )\n .map((s) => ({\n start: s.start as number,\n end: s.end as number,\n text: s.text as string,\n }))\n}\n","/**\n * Deliver — render one take to a release's destinations and write the kit\n * manifest. Loops the DESTINATIONS table (studio-core, generated from\n * schema/channel-specs.json): stills through framesTake at each spec's exact\n * pixels, videos through renderTake, then VERIFIES every artifact against\n * its spec (px, bytes, duration) and writes kit.json beside the assets —\n * the manifest the launch-kit skill describes, made real as a verb.\n *\n * Verification reports, it never guesses: an asset that misses its spec\n * (or a spec floor the take cannot fill — a 60 s minimum against a 35 s\n * take) lands in `skipped` with the reason in words. Store uploads stay\n * manual by policy — the verb hands the human a kit directory, it never\n * pushes to a store.\n */\nimport {\n copyFile,\n mkdir,\n mkdtemp,\n rename,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join, relative, resolve } from 'node:path'\nimport { totalDuration } from '@vosjs/timeline'\nimport {\n CHANNEL_SPECS_VERIFIED,\n DESTINATIONS,\n destinationsForChannel,\n ratedSegments,\n spanOutputExtent,\n} from '@vosjs/studio-core'\nimport { loadTake } from './take'\nimport { framesTake } from './framesTake'\nimport { renderTake } from './renderTake'\nimport { renderPosterStills } from './posterStill'\nimport type { Destination } from '@vosjs/studio-core'\nimport type { DocOverrides } from './docOverride'\nimport type { Browser } from 'playwright'\n\n/** `--to` shorthand → channel ids (the spec's own channel slugs also work). */\nexport const CHANNEL_ALIASES: Record<string, string> = {\n ph: 'producthunt',\n yt: 'youtube',\n gh: 'github',\n li: 'linkedin',\n shorts: 'shorts-linkedin',\n}\n\n/**\n * Destinations a take cannot honestly produce: brand art, not footage.\n * They are reported in `skipped`, never silently absent from the kit.\n */\nconst NOT_FROM_FOOTAGE: Record<string, string> = {\n 'cws-icon': 'an icon is brand art, not footage — supply it from the kit',\n}\n\nexport interface DeliverOptions {\n /** Resolved channel ids (aliases already applied). */\n channels: string[]\n /** Kit directory; default `<take>/kit`. */\n outDir?: string\n /** Stamped into kit.json (`--release v2.1`). */\n release?: string\n /** Still times override (OUTPUT seconds, already parsed). */\n times?: number[]\n /** OUTPUT-time cut window applied to every video destination. */\n range?: [number, number]\n /** Concurrent chunk renders for video destinations. */\n parallel?: number\n /** In-memory doc overrides (--set / --background); lint-gated. */\n overrides?: DocOverrides\n /**\n * The maker's poster program (the split-cover family). With one in hand,\n * CARD-genre destinations (OG, LinkedIn, X, YouTube thumbnail, the CWS\n * tile + marquee, GitHub social preview) render from the POSTER — the\n * verdict: the cover is a composition, never a raw frame — with this\n * release's full-bleed shot baked in as the poster's image element.\n * Screenshot-genre destinations always stay real take frames (store\n * policy demands real UX).\n */\n poster?: { config: Record<string, unknown>; from: string }\n /**\n * Capture instant INSIDE the poster program's own timeline (its text\n * enters over the first seconds); default 90% through it. Not the take\n * moment — that is `shotTime`.\n */\n posterTime?: number\n /**\n * The take moment (OUTPUT seconds) baked into the poster as its shot;\n * default the first still time. A zoom apex is the natural pick: the\n * cut's camera composes the frame, so the shot is the feature, not the\n * whole page.\n */\n shotTime?: number\n /**\n * Keep the cut's camera and the frame chrome on SCREENSHOT-genre stills.\n * By default a store screenshot is the real page at that moment, full\n * bleed: no zoom, no tilt, no browser bar, no padding (store policy says\n * real UX, full bleed, square corners; a zoomed crop under a mac bar on a\n * gradient reads as a marketing frame, and a text-heavy page zoomed to a\n * corner reads as an empty page).\n */\n composed?: boolean\n onPhase?: (phase: string) => void\n onProgress?: (fraction: number) => void\n}\n\n/** One produced asset, the launch-kit skill's kit.json entry shape. */\nexport interface KitAsset {\n channel: string\n asset: string\n /** The destination id (`cws-screenshot`) the entry was rendered for. */\n destination: string\n path: string\n w: number\n h: number\n bytes: number\n seconds: number | null\n frameTime: number | null\n /** Where the pixels came from: the take (absent = take) or the poster. */\n source?: 'poster'\n}\n\nexport interface KitManifest {\n release: string | null\n take: string\n produced: string\n /** channel-specs.json's own verified date — the spec sheet's freshness. */\n specsVerified: string\n skipped: string[]\n assets: KitAsset[]\n}\n\nexport interface DeliverResult {\n kit: KitManifest\n kitFile: string\n outDir: string\n}\n\n/** Resolve `--to` entries to channel ids; UsageError-shaped message on junk. */\nexport function resolveChannels(raw: string): string[] {\n const known = [...new Set(DESTINATIONS.map((d) => d.channel))]\n const wanted = raw\n .split(',')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean)\n if (!wanted.length) throw new Error('--to expects a channel list')\n if (wanted.includes('all')) return known\n const out: string[] = []\n for (const w of wanted) {\n const id = CHANNEL_ALIASES[w] ?? w\n if (!known.includes(id))\n throw new Error(\n `unknown channel \"${w}\" — channels: ${known.join(', ')} (or all)`,\n )\n if (!out.includes(id)) out.push(id)\n }\n return out\n}\n\n/**\n * Default still times: every zoom span's output-time apex (where quality\n * lives), else an even spread — the frames verb's own conventions. A span\n * trimmed out of the cut drops silently from the apex list, so the count\n * of dropped spans rides back for the phase note (the dogfood's \"2 spans,\n * 1 still\" surprise said nothing).\n */\nfunction defaultStillTimes(\n doc: NonNullable<Awaited<ReturnType<typeof loadTake>>['doc']>,\n duration: number,\n): { times: number[]; dropped: number } {\n const rated = ratedSegments(doc)\n const apexes: number[] = []\n for (const z of doc.zoom) {\n const ext = spanOutputExtent(rated, z.in, z.out)\n if (ext) apexes.push((ext.start + ext.end) / 2)\n }\n const dropped = doc.zoom.length - apexes.length\n if (apexes.length) return { times: apexes.sort((a, b) => a - b), dropped }\n return {\n times: [0.1, 0.3, 0.5, 0.7, 0.9].map((p) => p * duration),\n dropped,\n }\n}\n\n/**\n * A byte-ceiling miss in words that survive a 1% overshoot: ceil the size,\n * floor the ceiling, so the two figures can never round to the same number\n * (the dogfood printed \"1.0MB exceeds the 1.0MB ceiling\").\n */\nconst overCeiling = (bytes: number, maxBytes: number) =>\n `${Math.ceil(bytes / 1024)} KB exceeds the ${Math.floor(maxBytes / 1024)} KB ceiling`\n\nconst specWords = (d: Destination) => {\n const parts = [`${d.px.w}x${d.px.h}`]\n if (d.minSeconds !== undefined || d.maxSeconds !== undefined)\n parts.push(`${d.minSeconds ?? 0}-${d.maxSeconds ?? '∞'}s`)\n if (d.maxBytes !== undefined)\n parts.push(`≤${(d.maxBytes / 1024 / 1024).toFixed(0)}MB`)\n return parts.join(' ')\n}\n\n/**\n * The in-memory overrides a still destination rides, in apply order (the\n * user's own --set entries come LAST, so they win): the channel's fit, then\n * the screenshot genre's full-bleed defaults unless `composed` keeps the\n * cut's camera and chrome. Pure, so the policy is testable without a\n * browser.\n */\n/** The real page, edge to edge: no chrome, no cursor dot, no click ring. */\nexport const FULL_BLEED = [\n 'frame.padding=0',\n 'frame.radius=0',\n 'frame.shadow=0',\n 'frame.border=0',\n 'frame.browserBar.kind=none',\n 'cursor.visible=false',\n 'cursor.clickFx.style=none',\n]\n/** A store screenshot: the real page at that moment, the camera released. */\nexport const SCREENSHOT_DEFAULTS = [...FULL_BLEED, 'zoom=[]', 'tilt=[]']\n\nexport function stillOverridesFor(\n d: Pick<Destination, 'fit' | 'genre'>,\n opts: Pick<DeliverOptions, 'overrides' | 'composed'>,\n): DocOverrides | undefined {\n const set: string[] = []\n if (d.fit === 'cover') set.push('frame.fit=cover')\n if (d.genre === 'screenshot' && !opts.composed)\n set.push(...SCREENSHOT_DEFAULTS)\n // A card with no poster program to render from is a cover crop of the\n // real page (the cut's camera kept): never the card chrome and the padding\n // band, which a 2.5:1 marquee turns into a browser bar over a gradient.\n else if (d.genre === 'card' && !opts.composed) set.push(...FULL_BLEED)\n set.push(...(opts.overrides?.set ?? []))\n if (!set.length) return opts.overrides\n return { ...opts.overrides, set }\n}\n\nexport async function deliverTake(\n browser: Browser,\n dir: string,\n opts: DeliverOptions,\n): Promise<DeliverResult> {\n const take = await loadTake(dir)\n if (!take.doc) throw new Error(`${dir} has no doc.json — run plan first`)\n const doc = take.doc\n\n const duration = totalDuration(ratedSegments(doc))\n const videoSeconds = opts.range\n ? Math.min(opts.range[1], duration) - Math.min(opts.range[0], duration)\n : duration\n let stillTimes: number[]\n if (opts.times?.length) {\n stillTimes = opts.times\n } else {\n const derived = defaultStillTimes(doc, duration)\n stillTimes = derived.times\n if (derived.dropped > 0) {\n opts.onPhase?.(\n `note: ${derived.dropped} of ${doc.zoom.length} zoom apex(es) fall outside the cut — pass --times for more moments`,\n )\n }\n }\n\n const outDir = resolve(opts.outDir ?? join(dir, 'kit'))\n await mkdir(outDir, { recursive: true })\n\n const destinations = opts.channels.flatMap((c) => destinationsForChannel(c))\n const assets: KitAsset[] = []\n const skipped: string[] = []\n\n // The poster leg: with a poster program in hand, card-genre stills render\n // from IT (collected here, rendered after the take loop). Without one,\n // cards fall through to the take path like before.\n const posterCards =\n opts.poster !== undefined\n ? destinations.filter(\n (d) =>\n d.kind !== 'video' && d.genre === 'card' && !NOT_FROM_FOOTAGE[d.id],\n )\n : []\n const posterCardIds = new Set(posterCards.map((d) => d.id))\n\n // The poster pass (the verdict made mechanical): one full-bleed shot of\n // the release at the hero moment, baked into the poster program's image\n // element, rendered per card destination at its exact pixels — PNG from\n // our own page, so the webp-only thumbnail template never enters it.\n if (opts.poster && posterCards.length) {\n const meta = doc.source.meta\n const heroTime =\n opts.shotTime ?? (stillTimes.length ? stillTimes[0] : duration / 2)\n opts.onPhase?.(\n `poster shot (full bleed at ${heroTime.toFixed(2)}s) from ${opts.poster.from}`,\n )\n const serveDir = await mkdtemp(join(tmpdir(), 'vos-poster-'))\n try {\n const shot = await framesTake(browser, dir, {\n times: [heroTime],\n width: meta.captureWidth ?? meta.width,\n height: meta.captureHeight ?? meta.height,\n outDir: serveDir,\n overrides: {\n ...opts.overrides,\n set: [\n 'frame.fit=contain',\n 'frame.padding=0',\n 'frame.radius=0',\n 'frame.shadow=0',\n 'frame.border=0',\n 'frame.browserBar.kind=none',\n ...(opts.overrides?.set ?? []),\n ],\n },\n })\n await copyFile(shot.frames[0].file, join(serveDir, 'shot.png'))\n\n // Bake the release's shot in: the reserved image element id is\n // `shot` (the family convention); data.shotUrl rides along for\n // programs that wire it themselves. No image element = no poster —\n // the cards fall back to take frames, said in words.\n const config = structuredClone(opts.poster.config)\n const elements = Array.isArray(config.elements) ? config.elements : []\n const shotEl =\n (elements as { id?: string; type?: string; src?: unknown }[]).find(\n (e) => e.id === 'shot',\n ) ??\n (elements as { id?: string; type?: string; src?: unknown }[]).find(\n (e) => e.type === 'image',\n )\n if (!shotEl) {\n skipped.push(\n `poster ${opts.poster.from}: no image element (id \"shot\") to carry the release's screenshot — card destinations kept from the take`,\n )\n for (const d of posterCards) posterCardIds.delete(d.id)\n } else {\n shotEl.src = '/shot.png'\n const data =\n config.data && typeof config.data === 'object'\n ? (config.data as Record<string, unknown>)\n : {}\n data.shotUrl = '/shot.png'\n config.data = data\n const posterDuration =\n typeof config.duration === 'number' ? config.duration : 6\n const time = Math.min(\n opts.posterTime ?? posterDuration * 0.9,\n Math.max(0, posterDuration - 0.05),\n )\n opts.onPhase?.(\n `poster cards (${posterCards.map((d) => d.id).join(', ')}) at ${time.toFixed(2)}s`,\n )\n await renderPosterStills(\n browser,\n config,\n serveDir,\n posterCards.map((d) => ({\n name: `${d.id}.png`,\n width: d.px.w,\n height: d.px.h,\n })),\n time,\n )\n for (const d of posterCards) {\n const from = join(serveDir, `${d.id}.png`)\n const to = join(outDir, `${d.id}.png`)\n await rename(from, to)\n const bytes = (await stat(to)).size\n if (d.maxBytes !== undefined && bytes > d.maxBytes) {\n skipped.push(\n `${d.channel} ${d.asset}: ${overCeiling(bytes, d.maxBytes)} (kept at ${to})`,\n )\n continue\n }\n assets.push({\n channel: d.channel,\n asset: d.asset,\n destination: d.id,\n path: relative(outDir, to),\n w: d.px.w,\n h: d.px.h,\n bytes,\n seconds: null,\n frameTime: null,\n source: 'poster',\n })\n }\n }\n } finally {\n await rm(serveDir, { recursive: true, force: true })\n }\n }\n\n for (const d of destinations) {\n const label = `${d.channel} ${d.asset}`\n const excuse = NOT_FROM_FOOTAGE[d.id]\n if (excuse) {\n skipped.push(`${label}: ${excuse}`)\n continue\n }\n if (posterCardIds.has(d.id)) continue // rendered from the poster above\n\n if (d.kind === 'video') {\n // A spec floor the take cannot fill is a SKIP with the reason in\n // words, never padding — and never minutes of render first.\n if (d.minSeconds !== undefined && videoSeconds < d.minSeconds) {\n skipped.push(\n `${label}: spec wants ${d.minSeconds}-${d.maxSeconds ?? '∞'}s, the ${opts.range ? 'range' : 'take'} is ${videoSeconds.toFixed(0)}s`,\n )\n continue\n }\n if (d.maxSeconds !== undefined && videoSeconds > d.maxSeconds) {\n skipped.push(\n `${label}: spec caps at ${d.maxSeconds}s, the take is ${videoSeconds.toFixed(0)}s — cut it (--range, or trim segments in doc.json)`,\n )\n continue\n }\n opts.onPhase?.(`${label} (${specWords(d)})`)\n const outFile = join(outDir, `${d.id}.${d.format}`)\n // A byte ceiling becomes a bitrate budget (leave 15% for container +\n // audio); never raise the default for ceilings that don't bind.\n const bitrate =\n d.maxBytes !== undefined\n ? Math.min(\n 10_000_000,\n Math.floor(((d.maxBytes * 8) / videoSeconds) * 0.85),\n )\n : undefined\n const result = await renderTake(browser, dir, outFile, {\n width: d.px.w,\n height: d.px.h,\n format: 'mp4',\n parallel: opts.parallel,\n range: opts.range,\n bitrate,\n overrides: opts.overrides,\n onProgress: opts.onProgress,\n })\n if (d.maxBytes !== undefined && result.bytes > d.maxBytes) {\n skipped.push(\n `${label}: ${overCeiling(result.bytes, d.maxBytes)} (kept at ${outFile})`,\n )\n continue\n }\n assets.push({\n channel: d.channel,\n asset: d.asset,\n destination: d.id,\n path: relative(outDir, outFile),\n w: result.width,\n h: result.height,\n bytes: result.bytes,\n seconds: result.duration,\n frameTime: null,\n })\n continue\n }\n\n // Stills: capture at the spec's exact pixels; a set takes up to its\n // count ceiling of the hero times, a single still takes the first.\n const wanted =\n d.kind === 'still-set'\n ? stillTimes.slice(0, d.count?.max ?? stillTimes.length)\n : stillTimes.slice(0, 1)\n opts.onPhase?.(`${label} (${specWords(d)}, ${wanted.length} still(s))`)\n // The destination's fit is the channel's demand (\"fill the region\"): a\n // cover still rides an in-memory frame.fit override (cover fit), so\n // a 16:9 take fills a 440x280 tile instead of striping the background.\n // The doc on disk is untouched; an explicit --set frame.fit wins (later\n // entries apply last in docOverride).\n const overrides = stillOverridesFor(d, opts)\n const captured = await framesTake(browser, dir, {\n times: wanted,\n width: d.px.w,\n height: d.px.h,\n outDir,\n overrides,\n })\n for (let i = 0; i < captured.frames.length; i++) {\n const frame = captured.frames[i]\n const name =\n captured.frames.length > 1 ? `${d.id}-${i + 1}.png` : `${d.id}.png`\n const to = join(outDir, name)\n await rename(frame.file, to)\n const bytes = (await stat(to)).size\n if (d.maxBytes !== undefined && bytes > d.maxBytes) {\n skipped.push(\n `${label}: ${overCeiling(bytes, d.maxBytes)} (kept at ${to})`,\n )\n continue\n }\n assets.push({\n channel: d.channel,\n asset: d.asset,\n destination: d.id,\n path: relative(outDir, to),\n w: captured.width,\n h: captured.height,\n bytes,\n seconds: null,\n frameTime: frame.time,\n })\n }\n if (d.count && captured.frames.length < d.count.min) {\n skipped.push(\n `${label}: spec wants ${d.count.min}-${d.count.max}, only ${captured.frames.length} still time(s) available — pass --times`,\n )\n }\n }\n\n const kit: KitManifest = {\n release: opts.release ?? null,\n take: dir,\n produced: new Date().toISOString(),\n specsVerified: CHANNEL_SPECS_VERIFIED,\n skipped,\n assets,\n }\n const kitFile = join(outDir, 'kit.json')\n await writeFile(kitFile, JSON.stringify(kit, null, 2))\n return { kit, kitFile, outDir }\n}\n","/**\n * Render — lower the take's ProjectDoc to the studio composition, compile it,\n * and run the deterministic export frame-loop (seek → settle → capture →\n * mediabunny mux) through the shared renderAnimation harness. Same pipeline\n * as the studio's export; --parallel N shards the timeline into concurrent\n * chunk pages (see renderAnimation.ts).\n */\nimport { writeFile } from 'node:fs/promises'\nimport { compileVosConfig } from '@vosjs/core'\nimport {\n audioProducerCode,\n dataHasAudio,\n studioEntryData,\n} from '@vosjs/render-core'\nimport {\n lowerToComposition,\n resolveExportSize,\n studioAudioPlan,\n} from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake } from './take'\nimport { renderAnimation } from './renderAnimation'\nimport {\n applyAndValidate,\n hasOverrides,\n resolveBackdropSlug,\n} from './docOverride'\nimport type { EnvelopePoint, LoweredAudioClip } from '@vosjs/studio-core'\nimport type { DocOverrides } from './docOverride'\nimport type { Browser } from 'playwright'\n\nconst VIDEO_TOKEN = '__VOILA_CLI_VIDEO__'\n\nexport interface RenderTakeOptions {\n width?: number\n height?: number\n fps?: number\n format?: 'webm' | 'mp4'\n /** Concurrent chunk renders (timeline sharding); 1 = single-flight. */\n parallel?: number\n /** OUTPUT-time subrange [start, end) seconds — spot-check a doc edit cheaply. */\n range?: [number, number]\n /** Draft mode: half resolution + low bitrate, for iteration only. */\n draft?: boolean\n /** Encoder bitrate override (a destination's byte ceiling as a budget). */\n bitrate?: number\n /** In-memory doc overrides (--set / --frame / --background); lint-gated. */\n overrides?: DocOverrides\n onPhase?: (phase: string) => void\n onProgress?: (fraction: number) => void\n}\n\nexport interface RenderTakeResult {\n out: string\n bytes: number\n width: number\n height: number\n fps: number\n duration: number\n zoomSpans: number\n clicks: number\n /** Number of chunks rendered (1 unless --parallel raised it). */\n chunks: number\n /** An audio track was mixed + muxed (doc.audio clips / mic). */\n audio: boolean\n}\n\nexport async function renderTake(\n browser: Browser,\n dir: string,\n outFile: string,\n opts: RenderTakeOptions,\n): Promise<RenderTakeResult> {\n const take = await loadTake(dir)\n if (!take.doc) throw new Error(`${dir} has no doc.json — run plan first`)\n const doc = take.doc\n\n // Product-surface overrides (--set/--frame/--background): patch the doc in\n // memory + lint before anything renders (doc.json on disk is untouched).\n if (opts.overrides && hasOverrides(opts.overrides)) {\n await resolveBackdropSlug(opts.overrides)\n applyAndValidate(doc, opts.overrides)\n }\n\n // Same short-edge × aspect sizing as the studio's Export button (a preset\n // alone would letterbox portrait/native docs into a fixed 16:9 canvas).\n const res = resolveExportSize(doc)\n // Draft: half resolution (even), low bitrate — iteration speed over quality.\n const half = (n: number) => Math.max(2, Math.round(n / 2 / 2) * 2)\n const width = opts.width ?? (opts.draft ? half(res.width) : res.width)\n const height = opts.height ?? (opts.draft ? half(res.height) : res.height)\n const fps = opts.fps ?? doc.export.fps\n const format = opts.format ?? 'webm'\n\n opts.onPhase?.('compile')\n doc.source.videoKey = VIDEO_TOKEN\n const lowered = lowerToComposition(doc)\n const animationCode = compileVosConfig(lowered.config as never, {\n tweenEngine: 'vos',\n })\n const duration = lowered.duration\n const clicks = Array.isArray(lowered.data.clicks)\n ? (lowered.data.clicks as unknown[]).length\n : 0\n\n // Range render: clamp to the timeline, shift the frame clock, keep output\n // timestamps zero-based (the clip plays standalone).\n let frameOffset = 0\n let renderDuration = duration\n if (opts.range) {\n const start = Math.max(0, Math.min(opts.range[0], duration))\n const end = Math.max(start, Math.min(opts.range[1], duration))\n if (end - start <= 0)\n throw new Error(\n `--range ${opts.range[0]}..${opts.range[1]} is empty for a ${duration.toFixed(1)}s timeline`,\n )\n frameOffset = Math.round(start * fps)\n renderDuration = end - start\n }\n\n // Audio (doc.audio clips / mic) muxes in the SAME render — single-flight\n // only: chunks stay silent by design. A --range clip keeps its audio: the\n // producer mixes the whole timeline and the page slices the range window\n // (a cut-down is a deliverable, not just a spot check).\n let parallel = opts.parallel\n // The clips ride the studio stack entry, rendered as ONE engine\n // audio plan (studio-core builds it, the page's producer mixes it).\n const studioEntry = studioEntryData(lowered.stack)\n const studioClips = Array.isArray(studioEntry?.audio)\n ? (studioEntry.audio as LoweredAudioClip[])\n : []\n const audioPlan = studioClips.length\n ? studioAudioPlan(\n studioClips,\n Array.isArray(studioEntry?.duckEnv)\n ? (studioEntry.duckEnv as EnvelopePoint[])\n : [],\n duration,\n )\n : null\n const audioWanted = dataHasAudio(lowered.data, undefined, audioPlan)\n if (audioWanted && (parallel ?? 1) > 1) {\n parallel = 1\n opts.onPhase?.(\n 'note: audio present — forcing single-flight (--parallel ignored)',\n )\n }\n\n opts.onPhase?.('render')\n const result = await renderAnimation(browser, {\n animationCode,\n workDir: dir,\n videoFile: RECORDING_NAME,\n videoToken: VIDEO_TOKEN,\n width,\n height,\n fps,\n duration: renderDuration,\n format,\n parallel,\n frameOffset,\n bitrate: opts.bitrate ?? (opts.draft ? 3_000_000 : undefined),\n audio: audioWanted\n ? {\n producerCode: audioProducerCode({ plan: audioPlan }),\n data: lowered.data,\n duration,\n }\n : undefined,\n onProgress: opts.onProgress,\n })\n await writeFile(outFile, result.bytes)\n\n return {\n out: outFile,\n bytes: result.bytes.length,\n width,\n height,\n fps,\n duration: renderDuration,\n zoomSpans: doc.zoom.length,\n clicks,\n chunks: result.chunks,\n audio: audioWanted,\n }\n}\n","/**\n * Poster stills (the deliver --poster leg): render a PROGRAM\n * config — the maker's split-cover poster family — to PNG at exact\n * destination pixels, one fresh deterministic init per size (posters\n * recompose across aspects; that is the point of the family). Reuses the\n * plugin's own render page (renderPageHtml now carries the elements\n * runtime), so this is the existing harness pointed at a config, not a\n * second HTML generator. PNG by construction — the engine's thumbnail\n * template is webp-only (an engine ask), this page captures the canvas\n * itself.\n */\nimport { compileVosConfig } from '@vosjs/core'\nimport { renderPageHtml } from './renderAnimation'\nimport { startTakeServer, waitForPageDone } from './server'\nimport type { Browser } from 'playwright'\n\nexport interface PosterShot {\n /** Output filename (saved into serveDir). */\n name: string\n width: number\n height: number\n}\n\n/** Runs inside the render page: init at exact size, seek, settle, PNG. */\nasync function posterStillInPage(opts: {\n animationCode: string\n W: number\n H: number\n time: number\n outName: string\n}) {\n const w = window as unknown as Record<string, any>\n try {\n const mod = await import(\n /* @vite-ignore */ URL.createObjectURL(\n new Blob([opts.animationCode], { type: 'text/javascript' }),\n )\n )\n w.__vos__ = w.__vos__ || {}\n w.__vos__.isPaused = true\n const deps = {\n THREE: w.__THREE__,\n gsap: w.__gsap__,\n resolution: {\n width: opts.W,\n height: opts.H,\n pixelRatio: 1,\n drawingBufferWidth: opts.W,\n drawingBufferHeight: opts.H,\n },\n preserveDrawingBuffer: true,\n }\n const result = await mod.initVos(document.body, deps)\n if (result.assetsReady) await result.assetsReady\n const { timeline } = result\n timeline.pause()\n timeline.seek(opts.time, false)\n const canvas = document.querySelector('canvas') as HTMLCanvasElement\n canvas.width = opts.W\n canvas.height = opts.H\n canvas.style.width = opts.W + 'px'\n canvas.style.height = opts.H + 'px'\n // A few frames for element rasters (text canvases, the shot texture)\n // to land — assetsReady covers loads, the rAFs cover the first draw.\n const raf = () => new Promise((r) => requestAnimationFrame(r))\n await raf()\n await raf()\n await raf()\n const png = await new Promise<Blob | null>((res) =>\n canvas.toBlob((b) => res(b), 'image/png'),\n )\n if (!png) throw new Error('toBlob returned null')\n await fetch('/save?name=' + opts.outName, { method: 'POST', body: png })\n w.__done = { ok: true }\n } catch (e) {\n w.__error = String((e instanceof Error && e.stack) || e)\n }\n}\n\n/**\n * Render `shots` of a poster config into `serveDir` (which also serves the\n * config's local assets — deliver puts the release's shot there as\n * /shot.png before baking that path into the config).\n */\nexport async function renderPosterStills(\n browser: Browser,\n config: Record<string, unknown>,\n serveDir: string,\n shots: PosterShot[],\n time: number,\n): Promise<void> {\n const animationCode = compileVosConfig(config as never, {\n tweenEngine: 'vos',\n })\n const server = await startTakeServer(serveDir, {\n '/render.html': renderPageHtml(),\n })\n try {\n for (const shot of shots) {\n const context = await browser.newContext({\n viewport: { width: shot.width, height: shot.height },\n })\n try {\n const page = await context.newPage()\n page.on('console', (m) => {\n if (m.type() === 'error')\n process.stderr.write(` [poster page] ${m.text()}\\n`)\n })\n await page.addInitScript(() => {\n ;(globalThis as unknown as Record<string, unknown>).__name = (\n f: unknown,\n ) => f\n })\n await page.goto(`${server.base}/render.html`)\n await page.waitForFunction('window.__pageReady__ === true')\n void page\n .evaluate(posterStillInPage, {\n animationCode,\n W: shot.width,\n H: shot.height,\n time,\n outName: shot.name,\n })\n .catch(() => {})\n await waitForPageDone(page, `poster ${shot.name}`, () => {}, 120_000)\n } finally {\n await context.close()\n }\n }\n } finally {\n server.close()\n }\n}\n","/**\n * `vos validate <kit.json>` — the kit's own verifier, run AFTER deliver (or\n * after a hand-assembled kit): every asset in the manifest must exist, be\n * what its name says (a `.png` that is really WebP is the classic miss),\n * measure what the manifest claims, and meet its destination's spec (px,\n * bytes, duration, count). Reads dims and durations from the FILES, never\n * from intent, so a manifest that lies is caught the way a still that lies\n * is. Pure over a directory: no browser, no network.\n */\nimport { existsSync } from 'node:fs'\nimport { readFile, stat } from 'node:fs/promises'\nimport { dirname, isAbsolute, join } from 'node:path'\nimport { DESTINATIONS } from '@vosjs/studio-core'\nimport type { Destination } from '@vosjs/studio-core'\n\nexport interface KitAssetRecord {\n channel: string\n asset: string\n destination?: string\n path: string\n w: number\n h: number\n bytes: number\n seconds: number | null\n frameTime?: number | null\n source?: string\n}\n\nexport interface KitRecord {\n release?: string | null\n take?: string\n produced?: string\n skipped?: string[]\n assets: KitAssetRecord[]\n}\n\nexport interface KitVerdict {\n valid: boolean\n problems: string[]\n warnings: string[]\n /** Per asset: what the file measured. */\n measured: {\n destination: string\n path: string\n w: number | null\n h: number | null\n bytes: number\n seconds: number | null\n }[]\n}\n\nconst PNG_SIG = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])\n\n/** PNG dims from the IHDR chunk, or null when the bytes are not a PNG. */\nexport function pngDimensions(bytes: Buffer): { w: number; h: number } | null {\n if (bytes.length < 24 || !bytes.subarray(0, 8).equals(PNG_SIG)) return null\n if (bytes.toString('ascii', 12, 16) !== 'IHDR') return null\n return { w: bytes.readUInt32BE(16), h: bytes.readUInt32BE(20) }\n}\n\n/** What a file's leading bytes say it is, for the \"named .png, is WebP\" miss. */\nexport function sniffImage(bytes: Buffer): 'png' | 'webp' | 'jpeg' | 'unknown' {\n if (bytes.subarray(0, 8).equals(PNG_SIG)) return 'png'\n if (\n bytes.length >= 12 &&\n bytes.toString('ascii', 0, 4) === 'RIFF' &&\n bytes.toString('ascii', 8, 12) === 'WEBP'\n )\n return 'webp'\n if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8) return 'jpeg'\n return 'unknown'\n}\n\n/**\n * Video dims + duration through mediabunny (the render harness's own\n * demuxer), so a kit's mp4 is measured by the same library that wrote it.\n * Loaded lazily: a stills-only kit never pays for it.\n */\nasync function probeVideo(\n path: string,\n): Promise<{ w: number; h: number; seconds: number } | null> {\n const MB = await import('mediabunny')\n const input = new MB.Input({\n formats: MB.ALL_FORMATS,\n source: new MB.BufferSource(new Uint8Array(await readFile(path))),\n })\n try {\n const track = await input.getPrimaryVideoTrack()\n if (!track) return null\n const seconds = await input.computeDuration()\n return { w: track.displayWidth, h: track.displayHeight, seconds }\n } finally {\n input.dispose()\n }\n}\n\nconst specById = new Map<string, Destination>(\n DESTINATIONS.map((d) => [d.id, d]),\n)\n\nconst near = (a: number, b: number, tol: number) => Math.abs(a - b) <= tol\n\n/**\n * Verify a kit manifest against the files beside it and the channel specs.\n * `kitPath` is the manifest's path; relative asset paths resolve against\n * its directory (the deliver output layout) or against `take`-relative\n * `media/kit/…` paths a hand-assembled PR kit uses.\n */\nexport async function validateKit(kitPath: string): Promise<KitVerdict> {\n const problems: string[] = []\n const warnings: string[] = []\n const measured: KitVerdict['measured'] = []\n let kit: KitRecord\n try {\n kit = JSON.parse(await readFile(kitPath, 'utf8')) as KitRecord\n } catch (e) {\n return {\n valid: false,\n problems: [`${kitPath}: ${e instanceof Error ? e.message : String(e)}`],\n warnings,\n measured,\n }\n }\n if (!Array.isArray(kit.assets)) {\n return {\n valid: false,\n problems: [`${kitPath}: no assets[] in the manifest`],\n warnings,\n measured,\n }\n }\n const base = dirname(kitPath)\n const resolvePath = (p: string) => {\n // An absolute path from the machine that made the kit (a CI runner) is\n // honoured while it exists; a moved kit resolves beside its manifest.\n if (isAbsolute(p) && existsSync(p)) return p\n // A PR kit records paths as `media/kit/<name>`; the file sits beside the\n // manifest, so the last segment is what resolves.\n const beside = join(base, p.split('/').pop() ?? p)\n return beside\n }\n const perDestination = new Map<string, number>()\n\n for (const a of kit.assets) {\n const id = a.destination ?? `${a.channel}-${a.asset}`\n const label = `${a.channel} ${a.asset}`\n const file = resolvePath(a.path)\n let bytes: number\n try {\n bytes = (await stat(file)).size\n } catch {\n problems.push(`${label}: ${a.path} is missing`)\n continue\n }\n perDestination.set(id, (perDestination.get(id) ?? 0) + 1)\n if (bytes !== a.bytes)\n problems.push(\n `${label}: manifest says ${a.bytes} bytes, the file is ${bytes}`,\n )\n const spec = specById.get(id)\n let w: number | null = null\n let h: number | null = null\n let seconds: number | null = null\n if (/\\.(png|jpe?g|webp)$/i.test(file)) {\n const head = Buffer.from(await readFile(file))\n const kind = sniffImage(head)\n if (file.toLowerCase().endsWith('.png') && kind !== 'png')\n problems.push(\n `${label}: ${a.path} is named .png but its bytes are ${kind} — stores refuse a mislabelled image`,\n )\n const dims = kind === 'png' ? pngDimensions(head) : null\n if (dims) {\n w = dims.w\n h = dims.h\n if (w !== a.w || h !== a.h)\n problems.push(\n `${label}: manifest says ${a.w}x${a.h}, the file is ${w}x${h}`,\n )\n } else if (kind === 'png') {\n problems.push(`${label}: ${a.path} has no readable IHDR`)\n }\n } else if (/\\.(mp4|webm|mov)$/i.test(file)) {\n try {\n const v = await probeVideo(file)\n if (!v) problems.push(`${label}: ${a.path} has no video track`)\n else {\n w = v.w\n h = v.h\n seconds = v.seconds\n if (w !== a.w || h !== a.h)\n problems.push(\n `${label}: manifest says ${a.w}x${a.h}, the file is ${w}x${h}`,\n )\n if (a.seconds === null || !near(seconds, a.seconds, 0.25))\n problems.push(\n `${label}: manifest says ${a.seconds ?? 'no'} s, the file is ${seconds.toFixed(2)} s`,\n )\n }\n } catch (e) {\n problems.push(\n `${label}: could not read ${a.path} (${e instanceof Error ? e.message : String(e)})`,\n )\n }\n } else {\n warnings.push(\n `${label}: ${a.path} is not an image or video the kit verifies`,\n )\n }\n measured.push({ destination: id, path: a.path, w, h, bytes, seconds })\n\n if (!spec) {\n if (a.channel !== 'demo')\n warnings.push(\n `${label}: no channel spec for \"${id}\" — not verified against one`,\n )\n continue\n }\n if (w !== null && h !== null && (w !== spec.px.w || h !== spec.px.h))\n problems.push(\n `${label}: spec wants ${spec.px.w}x${spec.px.h}, the file is ${w}x${h}`,\n )\n if (spec.maxBytes !== undefined && bytes > spec.maxBytes)\n problems.push(\n `${label}: ${Math.ceil(bytes / 1024)} KB exceeds the ${Math.floor(spec.maxBytes / 1024)} KB ceiling`,\n )\n if (seconds !== null) {\n if (spec.minSeconds !== undefined && seconds < spec.minSeconds - 0.25)\n problems.push(\n `${label}: spec wants at least ${spec.minSeconds} s, the file is ${seconds.toFixed(1)} s`,\n )\n if (spec.maxSeconds !== undefined && seconds > spec.maxSeconds + 0.25)\n problems.push(\n `${label}: spec caps at ${spec.maxSeconds} s, the file is ${seconds.toFixed(1)} s`,\n )\n }\n if (spec.format === 'png' && !file.toLowerCase().endsWith('.png'))\n warnings.push(\n `${label}: spec renders png, the file is ${file.split('.').pop()}`,\n )\n }\n\n for (const [id, n] of perDestination) {\n const spec = specById.get(id)\n if (spec?.count && (n < spec.count.min || n > spec.count.max))\n problems.push(\n `${spec.channel} ${spec.asset}: spec wants ${spec.count.min}-${spec.count.max}, the kit has ${n}`,\n )\n }\n\n return { valid: problems.length === 0, problems, warnings, measured }\n}\n","/**\n * vos.so platform client — THE one HTTP surface of the vos CLI.\n * Every platform verb (fetch/push/pull for programs AND takes, login) goes\n * through here: one origin resolution, one credential ladder, one sync-state\n * file, one 409 conflict shape.\n *\n * Contract notes (mirrored at https://vos.so/llms.txt):\n * - public/unlisted programs read with no auth; writes ride a bearer key\n * - credentials resolve --key → VOS_API_KEY → ~/.config/vos/credentials\n * (first line; `vos login` writes it) and are NEVER printed — not in\n * logs, not in errors, not in NDJSON events\n * - pushed configs travel as the MIGRATED object with params/presets\n * untouched; the platform validates and compiles server-side\n */\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { UsageError } from './args'\n\n/**\n * Origin resolution: --origin (or legacy --api) → VOS_ORIGIN → legacy\n * VOS_API_BASE (which historically carried a trailing /api) → https://vos.so.\n * Every shape converges on a bare origin; paths below carry the /api prefix.\n */\nexport function platformOrigin(\n flags: { origin?: string; api?: string } = {},\n): string {\n const legacyEnv = process.env.VOS_API_BASE?.trim()\n const raw =\n flags.origin ??\n flags.api ??\n process.env.VOS_ORIGIN?.trim() ??\n legacyEnv ??\n 'https://vos.so'\n if (!flags.origin && !flags.api && !process.env.VOS_ORIGIN && legacyEnv) {\n process.stderr.write(\n 'note: VOS_API_BASE is deprecated — set VOS_ORIGIN (an origin, no /api suffix)\\n',\n )\n }\n return raw.replace(/\\/+$/, '').replace(/\\/api$/, '')\n}\n\n/**\n * Accepts a bare vos id, a watch URL (vos.so/vos/{id}), an embed URL\n * (/embed/vos/{id}), or a studio/stage URL (?vos={id}).\n */\nexport function parseVosId(input: string): string {\n if (!/^https?:\\/\\//.test(input)) {\n if (/^[A-Za-z0-9_-]+$/.test(input)) return input\n throw new UsageError(`\"${input}\" is not a vos id or URL`)\n }\n let url: URL\n try {\n url = new URL(input)\n } catch {\n throw new UsageError(`\"${input}\" is not a valid URL`)\n }\n const query = url.searchParams.get('vos')\n if (query) return query\n const path = url.pathname.match(/\\/vos\\/([A-Za-z0-9_-]+)/)\n if (path) return path[1]\n throw new UsageError(\n `could not find a vos id in ${input} — expected /vos/{id} or ?vos={id}`,\n )\n}\n\nexport function deriveSlug(title: string): string {\n return (\n title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 50)\n .replace(/-+$/, '') || 'remix'\n )\n}\n\nexport const CREDENTIALS_PATH = join(homedir(), '.config', 'vos', 'credentials')\n\n/**\n * The full documented ladder: explicit --key → VOS_API_KEY → the first line\n * of ~/.config/vos/credentials. A vos_rg_ remix grant is just a key here.\n * Returns null when nothing resolves — callers decide whether auth is needed.\n */\nexport function resolveCredential(explicit?: string): string | null {\n const flag = explicit?.trim()\n if (flag) return flag\n const env = process.env.VOS_API_KEY?.trim()\n if (env) return env\n try {\n const first = readFileSync(CREDENTIALS_PATH, 'utf8').split('\\n')[0].trim()\n return first || null\n } catch {\n return null\n }\n}\n\nexport function requireCredential(explicit?: string): string {\n const key = resolveCredential(explicit)\n if (!key) {\n throw new Error(\n 'no credential found — pass --key, set VOS_API_KEY, or run `vos login` ' +\n '(mint a content key at https://vos.so/app/api; a vos_rg_ remix grant works too)',\n )\n }\n return key\n}\n\n/** `vos login` writes here: 0700 dir, 0600 file, first line is the key. */\nexport function writeCredential(key: string): string {\n mkdirSync(join(homedir(), '.config', 'vos'), { recursive: true, mode: 0o700 })\n writeFileSync(CREDENTIALS_PATH, `${key.trim()}\\n`, { mode: 0o600 })\n return CREDENTIALS_PATH\n}\n\n/**\n * The self-reported client string stamped onto pushed versions (User-Agent\n * grammar). Display-only on the platform — attribution trust\n * stays with the credential. Agents driving this CLI override it with\n * VOS_CLIENT (e.g. VOS_CLIENT=claude-code/2.1) so history rows name the\n * tool, not just the transport.\n */\nexport function clientId(): string {\n const env = process.env.VOS_CLIENT?.trim()\n if (env && env.length <= 60 && !/[\\r\\n]/.test(env)) return env\n return 'vos-cli'\n}\n\nexport interface ApiResult {\n status: number\n body: Record<string, unknown>\n}\n\nexport async function apiJson(\n origin: string,\n path: string,\n init: {\n method?: string\n key?: string | null\n body?: unknown\n /** Raw request body (uploads) — used verbatim, with `headers`. */\n raw?: Uint8Array\n headers?: Record<string, string>\n } = {},\n): Promise<ApiResult> {\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...init.headers,\n }\n if (init.key) headers.authorization = `Bearer ${init.key}`\n if (init.body !== undefined) headers['content-type'] = 'application/json'\n const reqBody: BodyInit | undefined =\n init.raw !== undefined\n ? (init.raw as unknown as BodyInit)\n : init.body === undefined\n ? undefined\n : JSON.stringify(init.body)\n const res = await fetch(`${origin}${path}`, {\n method: init.method ?? 'GET',\n headers,\n body: reqBody,\n })\n let body: Record<string, unknown> = {}\n try {\n body = (await res.json()) as Record<string, unknown>\n } catch {\n // non-JSON error bodies stay {}\n }\n return { status: res.status, body }\n}\n\n/** Human-readable error line for a failed platform response. Never echoes credentials. */\nexport function apiError(what: string, r: ApiResult): string {\n const detail =\n typeof r.body.error === 'string'\n ? r.body.error\n : r.body.details !== undefined\n ? JSON.stringify(r.body.details)\n : ''\n const hint =\n r.status === 401\n ? ' (run `vos login`, or set VOS_API_KEY — mint a key at https://vos.so/app/api)'\n : ''\n return `${what} → ${r.status}${detail ? `: ${detail}` : ''}${hint}`\n}\n\n// ---------------------------------------------------------------------------\n// Sync state — ONE file (vos.json) for both artifact kinds, legacy-read\n// compatible with the two files it replaces: push.json (take dirs) and\n// meta.json (fetched program dirs).\n// ---------------------------------------------------------------------------\n\nexport const SYNC_STATE_NAME = 'vos.json'\n\nexport interface SyncState {\n vosId: string\n /** The hosted version this directory is based on — the next push's base. */\n versionId: string | null\n pushedAt?: string\n title?: string\n slug?: string\n remixOfId?: string\n}\n\nfunction readJsonFile(file: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(file, 'utf8')) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\n/**\n * vos.json → legacy push.json ({vosId, versionId}) → legacy meta.json\n * ({id, currentVersionId} — guarded on a string `id` so a take dir's\n * RecordingMeta meta.json is never misread as sync state).\n */\nexport function readSyncState(dir: string): SyncState | null {\n const own = readJsonFile(join(dir, SYNC_STATE_NAME))\n if (own && typeof own.vosId === 'string') {\n return {\n vosId: own.vosId,\n versionId: typeof own.versionId === 'string' ? own.versionId : null,\n ...(typeof own.pushedAt === 'string' ? { pushedAt: own.pushedAt } : {}),\n ...(typeof own.title === 'string' ? { title: own.title } : {}),\n ...(typeof own.slug === 'string' ? { slug: own.slug } : {}),\n ...(typeof own.remixOfId === 'string'\n ? { remixOfId: own.remixOfId }\n : {}),\n }\n }\n const push = readJsonFile(join(dir, 'push.json'))\n if (push && typeof push.vosId === 'string') {\n return {\n vosId: push.vosId,\n versionId: typeof push.versionId === 'string' ? push.versionId : null,\n ...(typeof push.pushedAt === 'string' ? { pushedAt: push.pushedAt } : {}),\n }\n }\n const meta = readJsonFile(join(dir, 'meta.json'))\n if (meta && typeof meta.id === 'string') {\n return {\n vosId: meta.id,\n versionId:\n typeof meta.currentVersionId === 'string'\n ? meta.currentVersionId\n : null,\n ...(typeof meta.title === 'string' ? { title: meta.title } : {}),\n ...(typeof meta.slug === 'string' ? { slug: meta.slug } : {}),\n ...(typeof meta.remixOfId === 'string'\n ? { remixOfId: meta.remixOfId }\n : {}),\n }\n }\n return null\n}\n\n/** Merge-writes vos.json; the legacy files are left alone (read-only compat). */\nexport function writeSyncState(\n dir: string,\n patch: Partial<SyncState> & { vosId: string },\n): SyncState {\n const merged = {\n ...(readSyncState(dir) ?? { versionId: null }),\n ...patch,\n } as SyncState\n writeFileSync(\n join(dir, SYNC_STATE_NAME),\n `${JSON.stringify(merged, null, 2)}\\n`,\n )\n return merged\n}\n\n// ---------------------------------------------------------------------------\n// The /changes payload (shape mirrored from the platform)\n// ---------------------------------------------------------------------------\n\nexport interface VersionChange {\n versionId?: string\n versionNumber?: number\n origin?: string\n label?: string | null\n note?: string | null\n summary?: string\n}\n\n/** Human lines for a changes walk — origin/label attributed, note indented. */\nexport function formatChanges(changes: readonly VersionChange[]): string[] {\n const lines: string[] = []\n for (const ch of changes) {\n const label = ch.label ? ` · ${ch.label}` : ''\n const who = ch.origin === 'studio' ? 'human' : (ch.origin ?? 'unknown')\n lines.push(\n `v${String(ch.versionNumber ?? '?')} (${who}${label}): ${ch.summary ?? ''}`,\n )\n if (ch.note) lines.push(` note: ${ch.note}`)\n }\n return lines\n}\n","/**\n * The recorder — Playwright drives the action script while:\n * - CDP Page.startScreencast collects JPEG frames (epoch-timestamped;\n * hold-last-frame gaps are filled at encode time), and\n * - every dispatched input is logged as a CursorEvent (the synthesized track:\n * exact coords, exact times, fresh element rects — no capture needed).\n */\nimport { readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { writeJson } from './take'\nimport { capReached, cappedLine, clampWait } from './recordingCap'\nimport type { Browser } from 'playwright'\nimport type {\n CursorEvent,\n RecordingMeta,\n Rect,\n StepSpan,\n} from '@vosjs/studio-core'\nimport type { ActionsFile } from './actions'\nimport type { TakePaths } from './take'\n\nexport interface FrameRec {\n file: string\n /** ms since t0 */\n tMs: number\n}\n\nexport interface SkippedStep {\n /** index into actions.steps */\n step: number\n do: string\n selector: string\n}\n\n/** A stretch with no screencast frames — the page pixels did not change. */\nexport interface FreezeSpan {\n /** seconds into the take */\n from: number\n to: number\n ms: number\n}\n\nexport interface RecordResult {\n events: CursorEvent[]\n frames: FrameRec[]\n meta: RecordingMeta\n /** steps whose selector never became visible — the take continued without them. */\n skipped: SkippedStep[]\n /** the initial goto never reached networkidle (recording proceeded anyway). */\n navTimeout: boolean\n /**\n * Smoothness telemetry: stretches ≥400ms with no visual change. Frozen\n * footage is the #1 enemy of a smooth product video — either the flow should\n * keep motion in frame (animate, hover a preview, scroll) or the doc should\n * trim/speed through these. freezePct = share of the take that is frozen.\n */\n freezes: FreezeSpan[]\n freezePct: number\n /** The take reached --max-duration and stopped there; later steps did not run. */\n capped: boolean\n}\n\nexport interface RecordOpts {\n /** Stop the capture at this many seconds (the hosted cap). */\n maxDurationSeconds?: number\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\nconst easeInOutCubic = (u: number) =>\n u < 0.5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2\n\n/** Minimal JPEG SOF parse for real encoded dimensions. */\nfunction jpegDims(buf: Buffer): { w: number; h: number } | null {\n let i = 2\n while (i < buf.length - 9) {\n if (buf[i] !== 0xff) return null\n const marker = buf[i + 1]\n const len = buf.readUInt16BE(i + 2)\n if (\n marker >= 0xc0 &&\n marker <= 0xcf &&\n marker !== 0xc4 &&\n marker !== 0xc8 &&\n marker !== 0xcc\n ) {\n return { h: buf.readUInt16BE(i + 5), w: buf.readUInt16BE(i + 7) }\n }\n i += 2 + len\n }\n return null\n}\n\nexport async function recordTake(\n browser: Browser,\n url: string,\n actions: ActionsFile,\n paths: TakePaths,\n log: (msg: string) => void,\n opts: RecordOpts = {},\n): Promise<RecordResult> {\n const maxSeconds = opts.maxDurationSeconds ?? Infinity\n const vw = actions.viewport?.width ?? 1280\n const vh = actions.viewport?.height ?? 720\n const context = await browser.newContext({\n viewport: { width: vw, height: vh },\n deviceScaleFactor: 1,\n })\n const page = await context.newPage()\n page.on('console', (m) => {\n if (m.type() === 'error') log(` [page error] ${m.text()}`)\n })\n\n log(`goto ${url}`)\n let navTimeout = false\n await page\n .goto(url, { waitUntil: 'networkidle', timeout: 45000 })\n .catch(() => {\n navTimeout = true\n log(' (networkidle timeout — continuing)')\n })\n await sleep(800) // hydration settle\n\n const cdp = await context.newCDPSession(page)\n const frames: FrameRec[] = []\n let frameIdx = 0\n let t0 = 0\n cdp.on('Page.screencastFrame', (ev) => {\n const tsMs = ev.metadata.timestamp\n ? ev.metadata.timestamp * 1000\n : Date.now()\n const file = `frame-${String(frameIdx++).padStart(5, '0')}.jpg`\n writeFileSync(join(paths.framesDir, file), Buffer.from(ev.data, 'base64'))\n frames.push({ file, tMs: Math.max(0, Math.round(tsMs - t0)) })\n cdp\n .send('Page.screencastFrameAck', { sessionId: ev.sessionId })\n .catch(() => {})\n })\n\n t0 = Date.now()\n await cdp.send('Page.startScreencast', {\n format: 'jpeg',\n quality: 90,\n maxWidth: vw,\n maxHeight: vh,\n everyNthFrame: 1,\n })\n\n const events: CursorEvent[] = []\n const cur = { x: 48, y: 48 }\n const now = () => Date.now() - t0\n const emit = (e: Omit<CursorEvent, 't'>) => events.push({ t: now(), ...e })\n\n await page.mouse.move(cur.x, cur.y)\n emit({ x: cur.x, y: cur.y, type: 'move' })\n\n const moveTo = async (tx: number, ty: number) => {\n const dist = Math.hypot(tx - cur.x, ty - cur.y)\n const dur = Math.min(1200, Math.max(350, dist * 1.4))\n const steps = Math.max(6, Math.round(dur / 16))\n const from = { ...cur }\n for (let i = 1; i <= steps; i++) {\n const u = easeInOutCubic(i / steps)\n cur.x = from.x + (tx - from.x) * u\n cur.y = from.y + (ty - from.y) * u\n await page.mouse.move(cur.x, cur.y)\n emit({ x: Math.round(cur.x), y: Math.round(cur.y), type: 'move' })\n await sleep(14)\n }\n }\n\n const boxOf = async (selector: string): Promise<Rect | null> => {\n const loc = page.locator(selector).first()\n try {\n await loc.waitFor({ state: 'visible', timeout: 8000 })\n await loc.scrollIntoViewIfNeeded()\n await sleep(250)\n const bb = await loc.boundingBox()\n if (!bb) return null\n return { x: bb.x, y: bb.y, w: bb.width, h: bb.height }\n } catch {\n log(` (selector not found, skipping: ${selector})`)\n return null\n }\n }\n\n const clickAt = async (rect: Rect) => {\n await moveTo(rect.x + rect.w / 2, rect.y + rect.h / 2)\n await sleep(120)\n emit({\n x: Math.round(cur.x),\n y: Math.round(cur.y),\n type: 'down',\n button: 0,\n rect,\n })\n await page.mouse.down()\n await sleep(90)\n await page.mouse.up()\n emit({\n x: Math.round(cur.x),\n y: Math.round(cur.y),\n type: 'up',\n button: 0,\n rect,\n })\n }\n\n const skipped: SkippedStep[] = []\n // The step timeline: when each step ran, in source seconds — what\n // lets a cut anchored to steps re-time onto a NEW recording of the same\n // script (`vos plan --reuse`). Every step that STARTED is recorded; a\n // skipped selector is marked, never silently absent.\n const stepSpans: StepSpan[] = []\n let capped = false\n for (const [stepIdx, step] of actions.steps.entries()) {\n // The cap is checked between steps (a step is one gesture and runs\n // whole); only a wait is cut short, since it is the one step that can\n // sit past the cap on its own.\n if (capReached(now(), maxSeconds)) {\n capped = true\n break\n }\n const stepStart = now()\n const skippedBefore = skipped.length\n switch (step.do) {\n case 'wait':\n await sleep(clampWait(step.ms, now(), maxSeconds))\n break\n case 'move':\n await moveTo(step.x, step.y)\n break\n case 'hover': {\n const rect = await boxOf(step.selector)\n if (rect) {\n await moveTo(rect.x + rect.w / 2, rect.y + rect.h / 2)\n log(`hover ${step.selector}`)\n await sleep(step.ms ?? 700) // parked cursor = dwell signal for the planner\n } else\n skipped.push({ step: stepIdx, do: step.do, selector: step.selector })\n break\n }\n case 'click': {\n const rect = await boxOf(step.selector)\n if (rect) {\n await clickAt(rect)\n log(`click ${step.selector}`)\n await sleep(500)\n } else\n skipped.push({ step: stepIdx, do: step.do, selector: step.selector })\n break\n }\n case 'type': {\n const rect = await boxOf(step.selector)\n if (rect) {\n // The click is what opens the typing zoom on the field. A step that\n // only finishes earlier typing (a submitting Enter) passes\n // focus:false: the field is already focused and a second click\n // rings a click effect on empty space beside the text.\n if (step.focus !== false) await clickAt(rect)\n // Typing-activity pings (TZ): one per ~350ms while characters land,\n // plus one at completion so the planner's hold starts at the true\n // typing end. When-and-where only — a ping never carries the text.\n // ~0.6s+ of typing earns the zoom (TYPING_MIN_DUR + ping floor), so\n // pace delayMs like a person for a camera moment, not a paste.\n const delay = step.delayMs ?? 40\n const ping = () =>\n emit({\n x: Math.round(rect.x + rect.w / 2),\n y: Math.round(rect.y + rect.h / 2),\n type: 'key',\n rect,\n })\n let lastPing = -Infinity\n for (const ch of step.text) {\n if (now() - lastPing >= 350) {\n lastPing = now()\n ping()\n }\n await page.keyboard.type(ch)\n await sleep(delay)\n }\n ping()\n log(`type \"${step.text}\" into ${step.selector}`)\n await sleep(300)\n } else\n skipped.push({ step: stepIdx, do: step.do, selector: step.selector })\n break\n }\n case 'scroll': {\n const total = Math.abs(step.dy)\n const dir = Math.sign(step.dy)\n for (let done = 0; done < total; done += 120) {\n await page.mouse.wheel(0, dir * Math.min(120, total - done))\n emit({ x: Math.round(cur.x), y: Math.round(cur.y), type: 'scroll' })\n await sleep(40)\n }\n await sleep(400)\n break\n }\n case 'drag': {\n // Start point: selector center when given, else explicit coords.\n let start: { x: number; y: number } | null = null\n let rect: Rect | undefined\n if (step.selector) {\n const box = await boxOf(step.selector)\n if (box) {\n rect = box\n start = { x: box.x + box.w / 2, y: box.y + box.h / 2 }\n } else {\n skipped.push({\n step: stepIdx,\n do: step.do,\n selector: step.selector,\n })\n break\n }\n } else if (typeof step.x === 'number' && typeof step.y === 'number') {\n start = { x: step.x, y: step.y }\n }\n if (!start) break\n await moveTo(start.x, start.y)\n await sleep(140)\n emit({\n x: Math.round(cur.x),\n y: Math.round(cur.y),\n type: 'down',\n button: 0,\n rect,\n })\n await page.mouse.down()\n await sleep(90)\n const dur = step.ms ?? 700\n const steps = Math.max(8, Math.round(dur / 16))\n const from = { ...cur }\n for (let i = 1; i <= steps; i++) {\n const u = easeInOutCubic(i / steps)\n cur.x = from.x + (step.tx - from.x) * u\n cur.y = from.y + (step.ty - from.y) * u\n await page.mouse.move(cur.x, cur.y)\n emit({ x: Math.round(cur.x), y: Math.round(cur.y), type: 'move' })\n await sleep(14)\n }\n await sleep(100)\n await page.mouse.up()\n emit({\n x: Math.round(cur.x),\n y: Math.round(cur.y),\n type: 'up',\n button: 0,\n rect,\n })\n log(\n `drag ${step.selector ?? `${start.x},${start.y}`} → ${step.tx},${step.ty}`,\n )\n await sleep(400)\n break\n }\n }\n const stepInfo = step as { id?: string; selector?: string }\n stepSpans.push({\n step: stepIdx,\n ...(stepInfo.id ? { id: stepInfo.id } : {}),\n do: step.do,\n ...(stepInfo.selector ? { selector: stepInfo.selector } : {}),\n tStart: +(stepStart / 1000).toFixed(3),\n tEnd: +(now() / 1000).toFixed(3),\n ...(skipped.length > skippedBefore ? { skipped: true } : {}),\n })\n }\n if (!capped) await sleep(600) // trailing hold\n if (capped || capReached(now(), maxSeconds)) {\n capped = true\n log(` ${cappedLine(maxSeconds)}`)\n }\n\n const durationMs = capped ? Math.min(now(), maxSeconds * 1000) : now()\n await cdp.send('Page.stopScreencast').catch(() => {})\n await sleep(200)\n const pageTitle = await page.title().catch(() => '')\n await context.close()\n\n const firstFrame = frames[0]\n ? jpegDims(readFileSync(join(paths.framesDir, frames[0].file)))\n : null\n const meta: RecordingMeta = {\n dpr: 1,\n zoom: 1,\n t0,\n durationMs,\n width: vw,\n height: vh,\n fps: 30,\n hasAudio: false,\n captureWidth: firstFrame?.w ?? vw,\n captureHeight: firstFrame?.h ?? vh,\n captureSurface: 'tab',\n pageUrl: url,\n pageTitle,\n platform:\n process.platform === 'darwin'\n ? 'mac'\n : process.platform === 'win32'\n ? 'windows'\n : 'linux',\n producer: 'cli',\n steps: stepSpans,\n }\n\n // Smoothness telemetry: screencast emits only on visual change, so frame\n // gaps = frozen pixels. ≥400ms reads as dead time in a product video.\n const freezes: FreezeSpan[] = []\n for (let i = 1; i < frames.length; i++) {\n const gap = frames[i].tMs - frames[i - 1].tMs\n if (gap >= 400) {\n freezes.push({\n from: +(frames[i - 1].tMs / 1000).toFixed(2),\n to: +(frames[i].tMs / 1000).toFixed(2),\n ms: gap,\n })\n }\n }\n const frozenMs = freezes.reduce((sum, f) => sum + f.ms, 0)\n const freezePct =\n durationMs > 0 ? Math.round((frozenMs / durationMs) * 100) : 0\n if (freezePct >= 25) {\n log(\n ` WARNING: ${freezePct}% of the take is visually frozen (${freezes.length} freezes, longest ${Math.max(...freezes.map((f) => f.ms))}ms) — keep motion in frame or trim these spans in doc.json`,\n )\n }\n\n await writeJson(paths.cursor, events)\n await writeJson(paths.meta, meta, true)\n await writeJson(paths.framesIndex, frames)\n await writeJson(paths.actions, { ...actions, url }, true)\n return {\n events,\n frames,\n meta,\n skipped,\n navTimeout,\n freezes,\n freezePct,\n capped,\n }\n}\n","/**\n * The hosted recording cap as `vos record` applies it: the default for\n * `--max-duration`. A CLI take that runs past it is stopped at the cap so\n * what lands is what vos.so hosts.\n *\n * The number's home is the platform's plan table, served public at\n * `GET /api/limits`; `hostedRecordingCap` reads it before a take (with the\n * caller's key when one resolves, so a plan with a longer cap gets it).\n * The constant below is the offline fallback, stated here because this is\n * the platform client. `--max-duration` overrides either for a take that\n * never leaves the machine.\n */\nexport const HOSTED_RECORDING_CAP_SECONDS = 30 * 60\n\n/**\n * The cap in a limits payload, or null when the payload is not one: an\n * integer number of seconds above zero under `limits.recordingMaxSeconds`.\n */\nexport function parseHostedCap(body: unknown): number | null {\n const limits =\n body && typeof body === 'object'\n ? (body as { limits?: { recordingMaxSeconds?: unknown } }).limits\n : undefined\n const cap = limits?.recordingMaxSeconds\n return typeof cap === 'number' && Number.isInteger(cap) && cap > 0\n ? cap\n : null\n}\n\n/**\n * The hosted cap read live from `GET /api/limits`. Bounded and fail-open:\n * null within ~2 s or on any refusal, and the caller uses the constant.\n * A key, when given, asks for the caller's own plan.\n */\nexport async function hostedRecordingCap(\n origin: string,\n key?: string | null,\n fetchImpl: typeof fetch = fetch,\n): Promise<number | null> {\n const ctl = new AbortController()\n const timer = setTimeout(() => ctl.abort(), 2000)\n try {\n const res = await fetchImpl(`${origin.replace(/\\/+$/, '')}/api/limits`, {\n signal: ctl.signal,\n ...(key ? { headers: { authorization: `Bearer ${key}` } } : {}),\n })\n if (!res.ok) return null\n return parseHostedCap(await res.json())\n } catch {\n return null\n } finally {\n clearTimeout(timer)\n }\n}\n\nexport function defaultMaxDurationSeconds(): number {\n return HOSTED_RECORDING_CAP_SECONDS\n}\n\n/** True once the take has reached the cap — the recorder stops driving steps. */\nexport function capReached(elapsedMs: number, capSeconds: number): boolean {\n return elapsedMs >= capSeconds * 1000\n}\n\n/** A wait step never sleeps past the cap. */\nexport function clampWait(\n waitMs: number,\n elapsedMs: number,\n capSeconds: number,\n): number {\n return Math.max(0, Math.min(waitMs, capSeconds * 1000 - elapsedMs))\n}\n\n/** `30 min`, `1 h 30 min`, `45 s` — the duration cap in words. */\nexport function formatDurationCap(seconds: number): string {\n if (seconds < 60) return `${seconds} s`\n const m = Math.round(seconds / 60)\n if (m < 60) return `${m} min`\n const h = Math.floor(m / 60)\n const rest = m % 60\n return rest ? `${h} h ${rest} min` : `${h} h`\n}\n\n/** The one line printed when the cap stopped the take. */\nexport function cappedLine(capSeconds: number): string {\n return `stopped at ${formatDurationCap(capSeconds)} (--max-duration ${capSeconds}); the remaining steps did not run`\n}\n","/**\n * Frames → CFR WebM. The VFR screencast JPEGs are drawn hold-last-frame onto a\n * canvas at a fixed 30fps and encoded with mediabunny (WebCodecs) inside a\n * headless page — no ffmpeg dependency.\n */\nimport { startTakeServer, waitForPageDone } from './server'\nimport { RECORDING_NAME } from './take'\nimport type { Browser } from 'playwright'\n\nconst MEDIABUNNY_URL = 'https://esm.sh/mediabunny@1.27.3?target=es2022'\n\nconst ENCODE_HTML = `<!doctype html><html><head><meta charset=\"utf-8\"></head><body>\n<script type=\"module\">\ntry {\n const MB = await import('${MEDIABUNNY_URL}')\n const frames = await (await fetch('/frames.json')).json()\n const meta = await (await fetch('/meta.json')).json()\n const W = meta.captureWidth ?? meta.width, H = meta.captureHeight ?? meta.height\n const FPS = 30\n const durSec = meta.durationMs / 1000\n const cv = document.createElement('canvas')\n cv.width = W; cv.height = H\n const c2 = cv.getContext('2d')\n const output = new MB.Output({ format: new MB.WebMOutputFormat(), target: new MB.BufferTarget() })\n const src = new MB.CanvasSource(cv, { codec: 'vp9', bitrate: 8_000_000 })\n output.addVideoTrack(src, { frameRate: FPS })\n await output.start()\n let fi = -1\n const total = Math.ceil(durSec * FPS)\n for (let i = 0; i < total; i++) {\n const t = i / FPS\n let next = fi\n while (next + 1 < frames.length && frames[next + 1].tMs <= t * 1000) next++\n if (next < 0) next = 0\n if (next !== fi) {\n fi = next\n const blob = await (await fetch('/frames/' + frames[fi].file)).blob()\n const bmp = await createImageBitmap(blob)\n c2.drawImage(bmp, 0, 0, W, H)\n bmp.close()\n }\n await src.add(t, 1 / FPS)\n window.__progress = i / total\n }\n await output.finalize()\n const buf = output.target.buffer\n await fetch('/save?name=${RECORDING_NAME}', { method: 'POST', body: buf })\n window.__done = { ok: true, bytes: buf.byteLength }\n} catch (e) { window.__error = String(e && e.stack || e) }\n</script></body></html>`\n\nexport async function encodeRecording(\n browser: Browser,\n takeDir: string,\n onProgress: (fraction: number) => void,\n): Promise<{ bytes: number }> {\n const server = await startTakeServer(takeDir, { '/encode.html': ENCODE_HTML })\n const page = await browser.newPage()\n try {\n await page.goto(`${server.base}/encode.html`)\n const done = await waitForPageDone(page, 'encode', onProgress, 600_000)\n return { bytes: Number(done.bytes ?? 0) }\n } finally {\n await page.close()\n server.close()\n }\n}\n","/**\n * Plan — build or refresh the take's ProjectDoc (doc.json), the agent-editable\n * surface. Fresh takes run the real studio ingest + auto-zoom planner. Reruns\n * honor the wand contract: `source:'manual'` zoom spans (and every other doc\n * edit) are preserved; only `source:'auto'` spans are regenerated, and new\n * suggestions overlapping a manual span are dropped.\n */\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport {\n DEFAULT_FRAME_STYLE,\n STYLE_FIELDS,\n copyStyle,\n isRejected,\n planAutoSpeed,\n planAutoZoom,\n projectFromArtifact,\n withBackdrop,\n} from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake, writeJson } from './take'\nimport { retimeCut } from './reuse'\nimport type { ReuseReport } from './reuse'\nimport type {\n Backdrop,\n ProjectDoc,\n RecordingArtifact,\n ZoomSpan,\n} from '@vosjs/studio-core'\n\nexport interface PlanSummary {\n doc: ProjectDoc\n zoomAuto: number\n zoomManual: number\n cursorKept: boolean\n fresh: boolean\n /** The loop the fresh doc opened on when one was handed in (`none` if a reference's frame won without one). */\n backdrop?: string\n /** The style fields copied from `--style`'s reference, when given. */\n styleFrom?: string\n styleFields?: readonly string[]\n /** `--reuse`: what the re-anchor did and what it could not. */\n reuse?: ReuseReport & { from: string }\n}\n\nexport interface PlanOptions {\n /**\n * Style transfer at the data layer: a signed-off take whose\n * zoomStyle/zoomParams/speedParams/tiltStyle/frame/cursor/cam/export are\n * copied onto this take BEFORE the planners run, so the auto spans are\n * proposed under the series' camera. The cut (spans, overlays, audio) is\n * never touched; a field absent on the reference is removed here too.\n */\n style?: { from: string; doc: ProjectDoc }\n /**\n * The re-render loop: a PREVIOUS cut of the same script (a\n * re-record's doc.prev.json) applied to this take's NEW footage. Style\n * fields copy over like --style; the human's camera spans and trims\n * re-time through the step map / explicit anchors; output-anchored work\n * (overlays, audio, objects) carries at its output times; auto spans\n * re-plan on the new cursor. The report NAMES whatever could not follow.\n */\n reuse?: { from: string; doc: ProjectDoc }\n /**\n * The backdrop a FRESH doc opens on (the set's house pick, or what\n * `--background` named), written under a `--style`/`--reuse` reference's\n * frame, which still wins. Null or absent: the bare frame.\n */\n backdrop?: Backdrop | null\n}\n\nconst overlaps = (a: ZoomSpan, b: ZoomSpan) => a.in < b.out && b.in < a.out\n\n/** `<take>/digest/digest.json`'s activity bins, when a digest exists. */\nasync function readDigestActivity(\n dir: string,\n): Promise<readonly number[] | null> {\n const file = join(dir, 'digest', 'digest.json')\n if (!existsSync(file)) return null\n try {\n const d = JSON.parse(await readFile(file, 'utf8')) as {\n activity?: unknown\n }\n return Array.isArray(d.activity) &&\n d.activity.every((v) => typeof v === 'number')\n ? d.activity\n : null\n } catch {\n return null\n }\n}\n\nexport async function planTake(\n dir: string,\n opts: PlanOptions = {},\n): Promise<PlanSummary> {\n const take = await loadTake(dir)\n const { meta, cursor } = take\n // A digest's activity bins, when one exists: the speed planner then tells\n // playback from idle (the studio's ingest has no such witness).\n const activity = await readDigestActivity(dir)\n // The frame a fresh doc opens on: the house backdrop on the bare frame\n // when one was handed in. The ingest still derives the browser bar from\n // the footage on top of it.\n const ingest = opts.backdrop\n ? { frame: withBackdrop(DEFAULT_FRAME_STYLE, opts.backdrop) }\n : {}\n\n let doc: ProjectDoc\n let fresh: boolean\n if (opts.reuse) {\n // The re-render loop: fresh ingest of the NEW footage, the\n // previous cut's style + human work re-timed onto it, autos re-planned.\n const prev = opts.reuse.doc\n const artifact: RecordingArtifact = {\n videoKey: RECORDING_NAME,\n cursor,\n meta,\n }\n doc = projectFromArtifact(artifact, RECORDING_NAME, ingest).doc\n doc = copyStyle(prev, doc)\n const rt = retimeCut(prev, meta.steps ?? [], meta.durationMs)\n doc.segments = rt.segments\n // The previous cut's deletions come along too: a proposal the human\n // rejected stays rejected on the new footage.\n if (rt.rejected.length) doc.rejected = rt.rejected\n const manualZoom = rt.zoom\n const autoZoom = planAutoZoom(doc.source.cursor, {\n width: doc.source.meta.width,\n height: doc.source.meta.height,\n style: doc.zoomStyle,\n params: doc.zoomParams,\n })\n .filter((z) => !manualZoom.some((m) => overlaps(z, m)))\n .filter((z) => !isRejected('zoom', z, doc.rejected))\n doc.zoom = [...manualZoom, ...autoZoom].sort((a, b) => a.in - b.in)\n const manualSpeed = rt.speed\n const autoSpeed = planAutoSpeed(doc.source.cursor, {\n durationMs: doc.source.meta.durationMs,\n params: doc.speedParams,\n activity,\n })\n .filter((s) => !manualSpeed.some((m) => s.in < m.out && s.out > m.in))\n .filter((s) => !isRejected('speed', s, doc.rejected))\n doc.speed = [...manualSpeed, ...autoSpeed].sort((a, b) => a.in - b.in)\n if (rt.tilt.length) doc.tilt = rt.tilt\n // Output-anchored work carries at its output times — a title at 1s is\n // still a title at 1s (the constant-perceived-position contract).\n if (prev.overlays?.length) doc.overlays = prev.overlays\n if (prev.objects?.length) doc.objects = prev.objects\n if (prev.audio.length) doc.audio = prev.audio\n if (prev.camMotion?.length) doc.camMotion = prev.camMotion\n\n await writeJson(take.paths.doc, doc, true)\n return {\n doc,\n zoomAuto: doc.zoom.filter((z) => z.source !== 'manual').length,\n zoomManual: doc.zoom.filter((z) => z.source === 'manual').length,\n cursorKept: doc.source.cursor.length > 0,\n fresh: false,\n reuse: { ...rt.report, from: opts.reuse.from },\n }\n }\n if (take.doc) {\n doc = opts.style ? copyStyle(opts.style.doc, take.doc) : take.doc\n fresh = false\n const manual = doc.zoom.filter((z) => z.source === 'manual')\n const auto = planAutoZoom(doc.source.cursor, {\n width: doc.source.meta.width,\n height: doc.source.meta.height,\n style: doc.zoomStyle,\n params: doc.zoomParams,\n })\n .filter((z) => !manual.some((m) => overlaps(z, m)))\n .filter((z) => !isRejected('zoom', z, doc.rejected))\n doc.zoom = [...manual, ...auto].sort((a, b) => a.in - b.in)\n // The speed wand: absent `source` counts as manual — spans from before\n // the wand are user work and always survive a re-plan.\n const manualSpeed = (doc.speed ?? []).filter((s) => s.source !== 'auto')\n const autoSpeed = planAutoSpeed(doc.source.cursor, {\n durationMs: doc.source.meta.durationMs,\n params: doc.speedParams,\n activity,\n })\n .filter((s) => !manualSpeed.some((m) => s.in < m.out && s.out > m.in))\n .filter((s) => !isRejected('speed', s, doc.rejected))\n doc.speed = [...manualSpeed, ...autoSpeed].sort((a, b) => a.in - b.in)\n } else {\n const artifact: RecordingArtifact = {\n videoKey: RECORDING_NAME,\n cursor,\n meta,\n }\n doc = projectFromArtifact(artifact, RECORDING_NAME, ingest).doc\n if (opts.style) doc = copyStyle(opts.style.doc, doc)\n doc.zoom = planAutoZoom(doc.source.cursor, {\n width: doc.source.meta.width,\n height: doc.source.meta.height,\n style: doc.zoomStyle,\n params: doc.zoomParams,\n })\n doc.speed = planAutoSpeed(doc.source.cursor, {\n durationMs: doc.source.meta.durationMs,\n params: doc.speedParams,\n activity,\n })\n fresh = true\n }\n\n await writeJson(take.paths.doc, doc, true)\n return {\n doc,\n zoomAuto: doc.zoom.filter((z) => z.source !== 'manual').length,\n zoomManual: doc.zoom.filter((z) => z.source === 'manual').length,\n cursorKept: doc.source.cursor.length > 0,\n fresh,\n ...(opts.backdrop\n ? { backdrop: doc.frame.backgroundMedia?.key ?? 'none' }\n : {}),\n ...(opts.style\n ? {\n styleFrom: opts.style.from,\n styleFields: STYLE_FIELDS.filter(\n (k) => opts.style!.doc[k] !== undefined,\n ),\n }\n : {}),\n }\n}\n","/**\n * Reuse: re-time a previous cut onto a NEW recording of the same\n * script. The recorder's `meta.steps` say when each actions.json step ran\n * in BOTH takes, so the old timeline maps onto the new one piecewise —\n * matched step edges are the control points, and any source time in\n * between interpolates. Explicit `anchor`s on camera spans resolve\n * directly against the new steps and win over the map.\n *\n * Report, never guess: every span that\n * could not re-anchor cleanly is NAMED in `flagged` with the reason in\n * words — a vanished step, a skipped selector, a span clamped or dropped\n * at the new take's edge. The agent fixes actions.json and re-runs; the\n * verb never silently invents a cut.\n *\n * Pure functions, no I/O — reuse.test.ts drives them with synthetic\n * step timelines; the browser gate is smoke-recut.ts.\n */\nimport type {\n ProjectDoc,\n RejectedSpan,\n SpeedSpan,\n StepAnchor,\n StepSpan,\n TiltSpan,\n ZoomSpan,\n} from '@vosjs/studio-core'\n\n/** Minimum surviving span length (seconds) — anything shorter drops. */\nconst MIN_SPAN = 0.15\n\nexport interface StepMap {\n /** old SOURCE seconds → new SOURCE seconds (piecewise linear, clamped). */\n map: (t: number) => number\n /** old steps with no usable match in the new recording. */\n unmatched: StepSpan[]\n matched: number\n}\n\n/**\n * Match an old step to a new one: by `id` when both carry one; else the\n * same index when the verb + selector still agree there; else a UNIQUE\n * (do, selector) match anywhere. A new step that was skipped (selector\n * never appeared) is no match — its gesture did not happen.\n */\nfunction matchStep(old: StepSpan, newSteps: StepSpan[]): StepSpan | null {\n const usable = (s: StepSpan | undefined): s is StepSpan =>\n !!s && s.skipped !== true\n if (old.id) {\n const byId = newSteps.find((s) => s.id === old.id)\n return usable(byId) ? byId : null\n }\n const atIndex = newSteps.find((s) => s.step === old.step)\n if (\n usable(atIndex) &&\n atIndex.do === old.do &&\n atIndex.selector === old.selector\n ) {\n return atIndex\n }\n const bySignature = newSteps.filter(\n (s) => s.do === old.do && s.selector === old.selector && !s.skipped,\n )\n return old.selector !== undefined && bySignature.length === 1\n ? bySignature[0]\n : usable(atIndex) && old.selector === undefined && atIndex.do === old.do\n ? atIndex\n : null\n}\n\nexport function buildStepMap(\n oldSteps: StepSpan[],\n newSteps: StepSpan[],\n oldDuration: number,\n newDuration: number,\n): StepMap {\n const points: { from: number; to: number }[] = [\n { from: 0, to: 0 },\n { from: oldDuration, to: newDuration },\n ]\n const unmatched: StepSpan[] = []\n let matched = 0\n for (const old of oldSteps) {\n if (old.skipped) continue // never ran in the old take; nothing anchored to it\n const hit = matchStep(old, newSteps)\n if (!hit) {\n unmatched.push(old)\n continue\n }\n matched++\n points.push({ from: old.tStart, to: hit.tStart })\n points.push({ from: old.tEnd, to: hit.tEnd })\n }\n // Sort and keep the mapping monotonic: a control point that would send\n // time backwards (steps reordered between takes) is dropped — the\n // interpolation through its neighbours is the honest fallback.\n points.sort((a, b) => a.from - b.from || a.to - b.to)\n const clean: { from: number; to: number }[] = []\n for (const p of points) {\n const last = clean.at(-1)\n if (!last) {\n clean.push(p)\n continue\n }\n if (p.from <= last.from + 1e-9) continue\n if (p.to < last.to) continue\n clean.push(p)\n }\n const map = (t: number): number => {\n const x = Math.max(0, Math.min(t, oldDuration))\n let i = 1\n while (i < clean.length - 1 && clean[i].from < x) i++\n const a = clean[i - 1] ?? clean[0]\n const b = clean[i] ?? a\n const span = b.from - a.from\n const u = span > 1e-9 ? (x - a.from) / span : 0\n return Math.max(0, Math.min(a.to + (b.to - a.to) * u, newDuration))\n }\n return { map, unmatched, matched }\n}\n\n/** Resolve an explicit anchor against the NEW steps; null when it cannot. */\nexport function resolveAnchor(\n anchor: StepAnchor,\n newSteps: StepSpan[],\n): number | null {\n const step =\n typeof anchor.step === 'string'\n ? newSteps.find((s) => s.id === anchor.step)\n : newSteps.find((s) => s.step === anchor.step)\n if (!step || step.skipped) return null\n const base = anchor.at === 'end' ? step.tEnd : step.tStart\n return base + (anchor.offset ?? 0)\n}\n\ninterface SourceSpan {\n id: string\n in: number\n out: number\n anchor?: StepAnchor\n}\n\nexport interface ReuseReport {\n /** spans re-timed through an explicit anchor. */\n anchored: number\n /** spans re-timed through the step map (approximate by nature). */\n mapped: number\n /** everything that needs a human/agent look, in words. */\n flagged: string[]\n}\n\nfunction retimeSpans<T extends SourceSpan>(\n kind: string,\n spans: T[],\n stepMap: StepMap,\n newSteps: StepSpan[],\n newDuration: number,\n report: ReuseReport,\n): T[] {\n const out: T[] = []\n for (const span of spans) {\n const length = span.out - span.in\n let nextIn: number | null = null\n if (span.anchor) {\n nextIn = resolveAnchor(span.anchor, newSteps)\n if (nextIn === null) {\n report.flagged.push(\n `${kind} ${span.id}: its anchored step (${String(span.anchor.step)}) is missing or skipped in the new recording — fell back to the step map`,\n )\n } else {\n report.anchored++\n }\n }\n if (nextIn === null) {\n nextIn = stepMap.map(span.in)\n report.mapped++\n }\n const nextOut = Math.min(nextIn + length, newDuration)\n const clampedIn = Math.max(0, Math.min(nextIn, newDuration))\n if (nextOut - clampedIn < MIN_SPAN) {\n report.flagged.push(\n `${kind} ${span.id}: lands outside the new recording (${clampedIn.toFixed(2)}s) — dropped`,\n )\n continue\n }\n out.push({ ...span, in: +clampedIn.toFixed(3), out: +nextOut.toFixed(3) })\n }\n // Source spans must not overlap: sort, then trim a later span's head to\n // its neighbour's tail (a shifted step can squeeze two spans together).\n out.sort((a, b) => a.in - b.in)\n const kept: T[] = []\n for (const span of out) {\n const prev = kept.at(-1)\n if (prev && span.in < prev.out) {\n const trimmed = { ...span, in: +prev.out.toFixed(3) }\n if (trimmed.out - trimmed.in < MIN_SPAN) {\n report.flagged.push(\n `${kind} ${span.id}: fully overlapped ${prev.id} after re-timing — dropped`,\n )\n continue\n }\n report.flagged.push(\n `${kind} ${span.id}: overlapped ${prev.id} after re-timing — trimmed to ${trimmed.in.toFixed(2)}s`,\n )\n kept.push(trimmed)\n continue\n }\n kept.push(span)\n }\n return kept\n}\n\nexport interface ReusedCut {\n segments: { in: number; out: number }[]\n zoom: ZoomSpan[]\n speed: SpeedSpan[]\n tilt: TiltSpan[]\n /** The previous cut's rejected proposals, re-timed like its manual spans. */\n rejected: RejectedSpan[]\n report: ReuseReport\n}\n\n/**\n * The previous cut's HUMAN work, re-timed onto the new recording. Auto\n * spans are deliberately absent — the planners re-propose them on the new\n * cursor track, exactly as a refresh does. Output-anchored work (overlays,\n * audio, objects) is not retimed here: a title at 1s stays a title at 1s,\n * the constant-perceived-position contract those clips already keep\n * through trims and speed changes.\n */\nexport function retimeCut(\n prev: ProjectDoc,\n newSteps: StepSpan[],\n newDurationMs: number,\n): ReusedCut {\n const report: ReuseReport = { anchored: 0, mapped: 0, flagged: [] }\n const oldSteps = prev.source.meta.steps ?? []\n const oldDuration = prev.source.meta.durationMs / 1000\n const newDuration = newDurationMs / 1000\n const stepMap = buildStepMap(oldSteps, newSteps, oldDuration, newDuration)\n for (const miss of stepMap.unmatched) {\n // An unmatched wait is dead time nothing anchors to — reporting it is\n // noise (the smoke's v1 tail wait \"vanished\" on every reindex).\n if (miss.do === 'wait') continue\n report.flagged.push(\n `step ${miss.id ?? miss.step} (${miss.do}${miss.selector ? ` ${miss.selector}` : ''}) has no match in the new recording — times near it interpolate`,\n )\n }\n\n // Segments: an untrimmed take stays untrimmed at the new length; a real\n // trim re-times edge-wise through the map.\n const untrimmed =\n prev.segments.length === 0 ||\n (prev.segments.length === 1 &&\n prev.segments[0].in <= 0.05 &&\n prev.segments[0].out >= oldDuration - 0.05)\n const segments = untrimmed\n ? [{ in: 0, out: +newDuration.toFixed(3) }]\n : prev.segments\n .map((s) => ({\n in: +stepMap.map(s.in).toFixed(3),\n out: +stepMap.map(s.out).toFixed(3),\n }))\n .filter((s) => s.out - s.in >= MIN_SPAN)\n if (!untrimmed && segments.length < prev.segments.length) {\n report.flagged.push(\n `${prev.segments.length - segments.length} trimmed segment(s) collapsed to nothing in the new recording — dropped`,\n )\n }\n\n const zoom = retimeSpans(\n 'zoom',\n prev.zoom.filter((z) => z.source === 'manual'),\n stepMap,\n newSteps,\n newDuration,\n report,\n )\n // The speed wand's contract: absent source = manual, always kept.\n const speed = retimeSpans(\n 'speed',\n (prev.speed ?? []).filter((s) => s.source !== 'auto'),\n stepMap,\n newSteps,\n newDuration,\n report,\n )\n const tilt = retimeSpans(\n 'tilt',\n (prev.tilt ?? []).filter((t) => t.source !== 'auto'),\n stepMap,\n newSteps,\n newDuration,\n report,\n )\n // A rejected proposal is a deletion the human made; it follows the\n // footage the way the spans it stands beside do, one lane at a time\n // (two lanes may legitimately reject the same seconds).\n const rejected: RejectedSpan[] = []\n for (const lane of ['zoom', 'tilt', 'speed'] as const) {\n rejected.push(\n ...retimeSpans(\n `rejected ${lane}`,\n (prev.rejected ?? []).filter((r) => r.lane === lane),\n stepMap,\n newSteps,\n newDuration,\n report,\n ),\n )\n }\n\n return { segments, zoom, speed, tilt, rejected, report }\n}\n","/**\n * Push/pull — the take side of the versioned human↔agent loop.\n *\n * `vos push <take>` uploads the recording (content-addressed: same bytes\n * upload once), lowers doc.json through the real studio pipeline, and\n * creates a hosted vos/version carrying BOTH the compiled program and the\n * doc — always against the base recorded in vos.json, so a stale push\n * 409s with the human's typed changelog instead of clobbering it.\n *\n * `vos pull <take>` fetches what the human changed (the semantic diff per\n * intervening version) and writes the head's doc.json back into the take\n * dir — the local edit loop continues exactly where the human left off.\n *\n * Local-first doctrine: the first push of a take asks (TTY) or\n * requires --yes (headless). vos.json records the consent, the vos id and\n * the base version (legacy push.json still reads); delete it to unlink.\n *\n * All HTTP + credentials + state ride the ONE platform client (platform.ts).\n */\nimport { createHash } from 'node:crypto'\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { createInterface } from 'node:readline/promises'\nimport { basename, join } from 'node:path'\nimport { lowerToComposition, migrateHostedDoc } from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake, writeJson } from './take'\nimport { lintDoc } from './validateDoc'\nimport { pullMedia } from './media'\nimport { listFolders, resolveFolder } from './folder'\nimport {\n apiJson,\n clientId,\n platformOrigin,\n readSyncState,\n requireCredential,\n writeSyncState,\n} from './platform'\nimport type { MediaPullResult } from './media'\nimport type { ProjectDoc } from '@vosjs/studio-core'\nimport type { Reporter } from './output'\n\nexport interface ApiContext {\n origin: string\n key: string\n}\n\n/** Auth + origin: flags win, then the documented ladder (platform.ts). */\nexport function apiContext(flags: {\n key?: string\n api?: string\n origin?: string\n}): ApiContext {\n return {\n origin: platformOrigin(flags),\n key: requireCredential(flags.key),\n }\n}\n\nasync function api(\n ctx: ApiContext,\n path: string,\n init?: {\n method?: string\n body?: unknown\n raw?: Uint8Array\n headers?: Record<string, string>\n },\n): Promise<{ status: number; json: Record<string, unknown> }> {\n const r = await apiJson(ctx.origin, `/api${path}`, { ...init, key: ctx.key })\n return { status: r.status, json: r.body }\n}\n\n/**\n * A 400's zod issues, in words an agent can act on (`label: String must\n * contain at most 60 character(s)`). A bare \"Invalid input\" cost a real push\n * a round trip (DF1, 2026-08-25).\n */\nfunction detailLine(body: Record<string, unknown>): string {\n const details = body.details\n if (!Array.isArray(details) || !details.length) return ''\n const lines = (details as Record<string, unknown>[]).map((d) => {\n const path = Array.isArray(d.path) ? d.path.join('.') : ''\n return `${path ? `${path}: ` : ''}${String(d.message ?? JSON.stringify(d))}`\n })\n return `\\n ${lines.join('\\n ')}`\n}\n\n/** Print a /changes payload's summaries — the human's half of the loop. */\nfunction printChanges(\n r: Reporter,\n changes: unknown,\n protectedIds: unknown,\n): void {\n if (Array.isArray(changes)) {\n for (const entry of changes as Record<string, unknown>[]) {\n const who = entry.origin === 'studio' ? 'human' : String(entry.origin)\n r.log(` v${entry.versionNumber} (${who}): ${entry.summary}`)\n if (entry.note) r.log(` note: ${String(entry.note)}`)\n r.event({ event: 'change', ...entry })\n }\n }\n if (Array.isArray(protectedIds) && protectedIds.length) {\n r.log(\n ` protected (human-touched, keep their values): ${(protectedIds as string[]).join(', ')}`,\n )\n r.event({ event: 'protected', nodes: protectedIds })\n }\n}\n\nexport async function pushTake(\n dir: string,\n flags: {\n key?: string\n api?: string\n origin?: string\n yes?: boolean\n title?: string\n label?: string\n note?: string\n folder?: string\n overrides?: string[]\n },\n r: Reporter,\n): Promise<{ vosId: string; versionId: string; versionNumber: number }> {\n const take = await loadTake(dir)\n if (!take.doc) {\n throw new Error('no doc.json in this take — run `vos plan` first')\n }\n const lint = lintDoc(take.doc)\n if (lint.problems.length) {\n throw new Error(`doc.json fails lint:\\n ${lint.problems.join('\\n ')}`)\n }\n if (!existsSync(take.paths.recording)) {\n throw new Error('no recording.webm in this take')\n }\n\n const ctx = apiContext(flags)\n const state = readSyncState(dir)\n\n // --folder files the CREATED vos into a project (keys add\n // organization). Refused in words on an already-pushed take, and resolved\n // BEFORE any upload so a bad slug costs nothing — the flag used to parse\n // and silently drop, which is worse than either.\n let folderId: string | undefined\n if (flags.folder) {\n if (state) {\n throw new Error(\n '--folder applies when CREATING a vos — this take is already pushed; file it with: vos folder move <vosId> --to <folder>',\n )\n }\n folderId = resolveFolder(\n await listFolders(ctx.origin, ctx.key),\n flags.folder,\n ).id\n }\n\n // Never upload unprompted: explicit consent on the first push.\n if (!state && !flags.yes) {\n if (!process.stdin.isTTY) {\n throw new Error(\n 'first push of this take uploads its recording — pass --yes to consent headlessly',\n )\n }\n const rl = createInterface({ input: process.stdin, output: process.stderr })\n const answer = await rl.question(\n `Push this take (recording + doc.json) to ${ctx.origin}? [y/N] `,\n )\n rl.close()\n if (!/^y(es)?$/i.test(answer.trim())) {\n throw new Error('push cancelled')\n }\n }\n\n // 1. The recording, content-addressed — re-pushes reuse the same asset.\n const bytes = await readFile(take.paths.recording)\n const hash = createHash('sha256').update(bytes).digest('hex')\n r.log(`uploading recording (${Math.round(bytes.length / 1024)} kB)…`)\n const upload = await api(ctx, '/assets/recording', {\n method: 'POST',\n headers: {\n 'Content-Type': 'video/webm',\n 'Content-Length': String(bytes.length),\n 'X-Filename': RECORDING_NAME,\n 'X-Content-Hash': hash,\n // The take's length so the server holds it to the plan's cap.\n ...(take.meta.durationMs > 0\n ? { 'X-Content-Duration': (take.meta.durationMs / 1000).toFixed(3) }\n : {}),\n },\n raw: new Uint8Array(bytes),\n })\n if (upload.status !== 201 && upload.status !== 200) {\n throw new Error(\n `recording upload failed (${upload.status}): ${String(upload.json.error ?? '')}`,\n )\n }\n const assetId = String(upload.json.id)\n const assetUrl = String(upload.json.url)\n r.event({\n event: 'recording',\n assetId,\n reused: upload.json.reused === true,\n })\n if (upload.json.reused === true) r.log(' recording already hosted — reused')\n\n // 2. The doc, keys rewritten to hosted URLs; lower through the real\n // pipeline so the hosted program is exactly what renders locally.\n const docForPush: ProjectDoc = structuredClone(take.doc)\n docForPush.source.videoKey = assetUrl\n if (\n docForPush.source.camKey &&\n !/^(https?:)?\\//.test(docForPush.source.camKey)\n ) {\n r.log(' cam track is local-only — dropped from the push')\n delete docForPush.source.camKey\n }\n if (\n docForPush.source.micKey &&\n !/^(https?:)?\\//.test(docForPush.source.micKey)\n ) {\n r.log(' mic track is local-only — dropped from the push')\n delete docForPush.source.micKey\n }\n const lowered = lowerToComposition(docForPush)\n const config = { ...lowered.config, data: lowered.data }\n\n // 3. Create or iterate — always against the recorded base.\n if (!state) {\n const title =\n flags.title ??\n `Take ${basename(dir)} ${new Date().toISOString().slice(0, 10)}`\n const slug = `${\n title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'take'\n }-${Date.now().toString(36)}`\n const created = await api(ctx, '/vos', {\n method: 'POST',\n body: {\n title,\n slug,\n visibility: 'private',\n config,\n doc: docForPush,\n assetIds: [assetId],\n client: clientId(),\n ...(folderId ? { folderId } : {}),\n ...(flags.label ? { label: flags.label } : {}),\n ...(flags.note ? { note: flags.note } : {}),\n },\n })\n if (created.status !== 201) {\n throw new Error(\n `push failed (${created.status}): ${String(created.json.error ?? '')}${detailLine(created.json)}`,\n )\n }\n const vos = created.json.vos as { id: string; currentVersionId?: string }\n const meta = await api(ctx, `/vos/${vos.id}`)\n const versionId = String(\n (meta.json.vos as { currentVersionId?: string } | undefined)\n ?.currentVersionId ?? '',\n )\n writeSyncState(dir, {\n vosId: vos.id,\n versionId,\n pushedAt: new Date().toISOString(),\n title,\n slug,\n })\n return { vosId: vos.id, versionId, versionNumber: 1 }\n }\n\n const pushed = await api(ctx, `/vos/${state.vosId}/versions`, {\n method: 'POST',\n body: {\n config,\n doc: docForPush,\n client: clientId(),\n ...(state.versionId ? { baseVersionId: state.versionId } : {}),\n ...(flags.label ? { label: flags.label } : {}),\n ...(flags.note ? { note: flags.note } : {}),\n ...(flags.overrides?.length ? { overrides: flags.overrides } : {}),\n },\n })\n if (pushed.status === 409) {\n r.log(\n pushed.json.error === 'stale_base'\n ? 'HEAD moved while you worked — what changed:'\n : `protected nodes (${String((pushed.json.nodes as string[] | undefined)?.join(', '))}) — the human touched these since your last push:`,\n )\n printChanges(r, pushed.json.changes, pushed.json.protected)\n r.event({ event: 'conflict', ...pushed.json })\n throw new Error(\n pushed.json.error === 'stale_base'\n ? 'stale base — run `vos pull` to take the human’s changes, re-apply yours on top, then push again'\n : 'protected conflict — keep the human’s values, or push with --override <id> ONLY if the user asked for that exact change',\n )\n }\n if (pushed.status !== 201) {\n throw new Error(\n `push failed (${pushed.status}): ${String(pushed.json.error ?? '')}${detailLine(pushed.json)}`,\n )\n }\n const version = pushed.json.version as { id: string; versionNumber: number }\n writeSyncState(dir, {\n vosId: state.vosId,\n versionId: version.id,\n pushedAt: new Date().toISOString(),\n })\n return {\n vosId: state.vosId,\n versionId: version.id,\n versionNumber: version.versionNumber,\n }\n}\n\nexport async function pullTake(\n dir: string,\n flags: {\n key?: string\n api?: string\n origin?: string\n vos?: string\n /** Also download the recording + sidecars and re-anchor the doc. */\n media?: boolean\n },\n r: Reporter,\n): Promise<{\n vosId: string\n versionId: string\n versionNumber: number | null\n changed: boolean\n media?: MediaPullResult\n}> {\n const ctx = apiContext(flags)\n const state = readSyncState(dir)\n const vosId = flags.vos ?? state?.vosId\n if (!vosId) {\n throw new Error('this take was never pushed — pass --vos <id> to link it')\n }\n\n const meta = await api(ctx, `/vos/${vosId}`)\n if (meta.status !== 200) {\n throw new Error(\n `fetch failed (${meta.status}): ${String(meta.json.error ?? '')}`,\n )\n }\n const head = String(\n (meta.json.vos as { currentVersionId?: string } | undefined)\n ?.currentVersionId ?? '',\n )\n if (!head) throw new Error('this vos has no versions')\n\n if (state && state.versionId === head) {\n r.log('up to date — HEAD is your last push')\n let media: MediaPullResult | undefined\n if (flags.media && existsSync(join(dir, 'doc.json'))) {\n const local = JSON.parse(\n await readFile(join(dir, 'doc.json'), 'utf8'),\n ) as ProjectDoc\n media = await pullMedia(ctx, dir, local, r.log)\n }\n return {\n vosId,\n versionId: head,\n versionNumber: null,\n changed: false,\n media,\n }\n }\n\n // The typed changelog: what the human did since this take's base.\n if (state?.versionId) {\n const changes = await api(\n ctx,\n `/vos/${vosId}/changes?since=${state.versionId}`,\n )\n if (changes.status === 200) {\n r.log('changes since your last push:')\n printChanges(r, changes.json.changes, changes.json.protected)\n }\n }\n\n // The head doc, migrated on read, re-anchored to the local recording —\n // same bytes by construction (content-addressed upload).\n const docRes = await api(ctx, `/vos/${vosId}/versions/${head}/doc`)\n if (docRes.status !== 200) {\n throw new Error(\n docRes.status === 404\n ? 'the head version carries no doc — is this a take vos?'\n : `doc fetch failed (${docRes.status})`,\n )\n }\n const hostedDoc = migrateHostedDoc(docRes.json)\n const doc = hostedDoc as unknown as ProjectDoc\n if (existsSync(join(dir, RECORDING_NAME))) {\n doc.source.videoKey = RECORDING_NAME\n }\n await writeJson(join(dir, 'doc.json'), doc, true)\n // --media: the footage (and sidecars) come home beside the doc, so digest,\n // frames and render work on this directory as on a local take.\n const media = flags.media ? await pullMedia(ctx, dir, doc, r.log) : undefined\n\n const versions = await api(ctx, `/vos/${vosId}/versions`)\n const headRow = (\n (versions.json.versions ?? []) as { id: string; versionNumber: number }[]\n ).find((v) => v.id === head)\n\n writeSyncState(dir, {\n vosId,\n versionId: head,\n pushedAt: state?.pushedAt ?? new Date().toISOString(),\n })\n return {\n vosId,\n versionId: head,\n versionNumber: headRow?.versionNumber ?? null,\n changed: true,\n media,\n }\n}\n","/**\n * A hosted take comes home: download the recording (and the\n * mic/cam sidecars when the doc carries them) beside a pulled doc.json, and\n * re-anchor the doc's keys to the local files, so `vos digest`, `frames` and\n * `render` run on a pulled take exactly as on a local one. Also writes the\n * take-dir markers (meta.json, cursor.json) from the doc when absent, so the\n * directory IS a take directory to every other verb.\n *\n * Same consent shape as the upload direction: nothing moves without the verb\n * the user ran (`--media`). A file already on disk is kept, never re-fetched.\n */\nimport { createWriteStream, existsSync } from 'node:fs'\nimport { writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport { RECORDING_NAME, writeJson } from './take'\nimport type { ProjectDoc } from '@vosjs/studio-core'\n\nexport const MIC_NAME = 'mic.webm'\nexport const CAM_NAME = 'cam.webm'\n\nconst KEYS = [\n { key: 'videoKey', file: RECORDING_NAME },\n { key: 'micKey', file: MIC_NAME },\n { key: 'camKey', file: CAM_NAME },\n] as const\n\n/** An asset file URL (relative `/api/assets/{id}/file` or absolute). */\nexport function assetIdOf(url: string | undefined): string | null {\n if (!url) return null\n const m = /\\/api\\/assets\\/([A-Za-z0-9_-]+)\\/file/.exec(url)\n return m ? m[1] : null\n}\n\nexport interface MediaPullResult {\n downloaded: { file: string; assetId: string; bytes: number }[]\n kept: string[]\n}\n\nexport async function pullMedia(\n ctx: { origin: string; key: string | null },\n dir: string,\n doc: ProjectDoc,\n log: (line: string) => void,\n): Promise<MediaPullResult> {\n const result: MediaPullResult = { downloaded: [], kept: [] }\n for (const { key, file } of KEYS) {\n const url = doc.source[key]\n const assetId = assetIdOf(url)\n if (!assetId) continue\n const target = join(dir, file)\n if (existsSync(target)) {\n result.kept.push(file)\n } else {\n const abs = /^https?:/.test(url!) ? url! : `${ctx.origin}${url}`\n const res = await fetch(abs, {\n headers: ctx.key ? { authorization: `Bearer ${ctx.key}` } : {},\n })\n if (!res.ok || !res.body) {\n throw new Error(\n `download of ${file} failed (${res.status})${\n res.status === 404\n ? ' — a private recording needs a content key of its owner'\n : ''\n }`,\n )\n }\n await pipeline(\n Readable.fromWeb(res.body as never),\n createWriteStream(target),\n )\n const bytes = (\n await import('node:fs/promises').then((fs) => fs.stat(target))\n ).size\n result.downloaded.push({ file, assetId, bytes })\n log(` ${file} ← asset ${assetId} (${Math.round(bytes / 1024)} kB)`)\n }\n doc.source[key] = file\n }\n // The take-dir markers: meta.json and cursor.json live on the doc for a\n // hosted take; write them out so loadTake() recognizes the directory.\n const metaPath = join(dir, 'meta.json')\n if (!existsSync(metaPath)) await writeJson(metaPath, doc.source.meta, true)\n const cursorPath = join(dir, 'cursor.json')\n if (!existsSync(cursorPath)) await writeJson(cursorPath, doc.source.cursor)\n await writeFile(join(dir, 'doc.json'), JSON.stringify(doc, null, 2))\n return result\n}\n","/**\n * `vos folder` — the shelf verbs: list your folders, create one, move\n * work into one, PULL one (the folder contract on disk). The additive half\n * of the shelf rule: an agent may ADD organization\n * (create a folder, file voses and assets into it) but never reshape or\n * destroy what the human made — rename/delete/reorder have no CLI verb on\n * purpose; those stay session gestures on vos.so.\n *\n * vos folder list [--json]\n * vos folder create <name> [--parent <folderId|slug>] [--desc <text>] [--json]\n * vos folder move <vosId|assetId|watch-url>... --to <folderId|slug|none> [--json]\n * vos folder pull <folderId|slug> [--out dir] [--media] [--json]\n *\n * pull writes the folder's whole context package to disk — the one step of\n * the \"create in my style\" flow the CLI could not do: recipes (own and\n * inherited, bodies inline) and every member's config.json (+ doc.json for\n * takes) each in a directory that TRACKS its vos, so `vos push` from any of\n * them lands as a version. One line per recipe prints what it governs and\n * where it says to start, read from the optional hints.\n *\n * move accepts vos ids AND asset ids (recipes, uploads): it tries the vos\n * first and falls back to the asset route on 404, so the caller never has\n * to say which kind an id is.\n */\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { recipeHints } from '@vosjs/shared/frontmatter'\nimport { migrateHostedDoc } from '@vosjs/studio-core'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { pullMedia } from './media'\nimport { EXIT_ERROR, EXIT_OK, createReporter } from './output'\nimport {\n apiError,\n apiJson,\n parseVosId,\n platformOrigin,\n requireCredential,\n writeSyncState,\n} from './platform'\nimport type { ProjectDoc } from '@vosjs/studio-core'\n\nconst BOOLEAN_FLAGS = new Set(['json', 'help', 'media'])\n\nexport interface FolderRow {\n id: string\n name: string\n slug: string\n parentId: string | null\n counts?: { voses?: number; recipes?: number; assets?: number }\n}\n\nexport async function listFolders(\n origin: string,\n key: string,\n): Promise<FolderRow[]> {\n const r = await apiJson(origin, '/api/folders', { key })\n if (r.status !== 200) throw new Error(apiError('list folders', r))\n return (r.body.folders ?? []) as FolderRow[]\n}\n\n/** Resolve a folder reference (id or slug) against the caller's own shelf. */\nexport function resolveFolder(rows: FolderRow[], ref: string): FolderRow {\n const hit = rows.find((f) => f.id === ref) ?? rows.find((f) => f.slug === ref)\n if (!hit) {\n const shelf = rows.map((f) => f.slug).join(', ') || '(no folders yet)'\n throw new UsageError(`no folder \"${ref}\" on your shelf — have: ${shelf}`)\n }\n return hit\n}\n\nfunction printTree(rows: FolderRow[]): void {\n const children = new Map<string | null, FolderRow[]>()\n for (const f of rows) {\n const list = children.get(f.parentId) ?? []\n list.push(f)\n children.set(f.parentId, list)\n }\n const walk = (parentId: string | null, depth: number) => {\n for (const f of children.get(parentId) ?? []) {\n const c = f.counts ?? {}\n const held = [\n c.voses ? `${c.voses} vos${c.voses === 1 ? '' : 'es'}` : '',\n c.recipes ? `${c.recipes} recipe${c.recipes === 1 ? '' : 's'}` : '',\n c.assets ? `${c.assets} asset${c.assets === 1 ? '' : 's'}` : '',\n ]\n .filter(Boolean)\n .join(', ')\n process.stdout.write(\n `${' '.repeat(depth)}${f.name} (${f.slug})${held ? ` — ${held}` : ''}\\n`,\n )\n walk(f.id, depth + 1)\n }\n }\n walk(null, 0)\n}\n\nasync function cmdList(argv: string[]): Promise<number> {\n const { flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n const rows = await listFolders(origin, key)\n if (r.json) {\n r.done({ folders: rows }, '')\n return EXIT_OK\n }\n if (rows.length === 0) {\n r.done({}, 'no folders yet — vos folder create <name>')\n return EXIT_OK\n }\n printTree(rows)\n return EXIT_OK\n}\n\nasync function cmdCreate(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const name = positionals.join(' ').trim()\n if (!name)\n throw new UsageError(\n 'vos folder create <name> [--parent <folderId|slug>] [--desc <text>]',\n )\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n\n const parentRef = strFlag(flags, 'parent')\n let parentId: string | undefined\n if (parentRef) {\n parentId = resolveFolder(await listFolders(origin, key), parentRef).id\n }\n\n const res = await apiJson(origin, '/api/folders', {\n method: 'POST',\n key,\n body: {\n name,\n ...(strFlag(flags, 'desc')\n ? { description: strFlag(flags, 'desc') }\n : {}),\n ...(parentId ? { parentId } : {}),\n },\n })\n if (res.status !== 201) throw new Error(apiError('create folder', res))\n const created = res.body.folder as FolderRow\n r.done(\n { id: created.id, slug: created.slug, parentId: created.parentId },\n `created ${created.name} (${created.slug}, ${created.id})${parentRef ? ` inside ${parentRef}` : ''}`,\n )\n return EXIT_OK\n}\n\nasync function cmdMove(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const toRef = strFlag(flags, 'to')\n if (positionals.length === 0 || !toRef)\n throw new UsageError(\n 'vos folder move <vosId|assetId|watch-url>... --to <folderId|slug|none>',\n )\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n\n const folderId =\n toRef === 'none'\n ? null\n : resolveFolder(await listFolders(origin, key), toRef).id\n\n let failed = 0\n const moved: { id: string; kind: string }[] = []\n for (const raw of positionals) {\n const id = parseVosId(raw)\n // A move target is a vos or an asset; ids don't say which, so try the\n // vos first and fall back to the asset route on its 404.\n const asVos = await apiJson(origin, `/api/vos/${id}`, {\n method: 'PATCH',\n key,\n body: { folderId },\n })\n if (asVos.status === 200) {\n moved.push({ id, kind: 'vos' })\n r.log(`moved vos ${id}`)\n continue\n }\n if (asVos.status === 404) {\n const asAsset = await apiJson(origin, `/api/assets/${id}`, {\n method: 'PATCH',\n key,\n body: { folderId },\n })\n if (asAsset.status === 200) {\n moved.push({ id, kind: 'asset' })\n r.log(`moved asset ${id}`)\n continue\n }\n failed++\n r.log(apiError(`move ${id}`, asAsset))\n continue\n }\n failed++\n r.log(apiError(`move ${id}`, asVos))\n }\n r.done(\n { moved, failed, folderId },\n `moved ${moved.length}/${positionals.length} into ${toRef === 'none' ? 'the top level' : toRef}${failed ? ` — ${failed} failed` : ''}`,\n )\n return failed ? EXIT_ERROR : EXIT_OK\n}\n\ninterface PullPayload {\n folder: { id: string; name: string; slug: string; description?: string }\n subfolders: { id: string; name: string; slug: string }[]\n recipes: { id: string; filename: string; body?: string }[]\n inheritedRecipes: {\n id: string\n filename: string\n body?: string\n folderSlug?: string\n folderName?: string\n }[]\n voses: {\n id: string\n title: string\n slug?: string | null\n currentVersionId?: string | null\n hasDoc?: boolean\n contentUrls?: { config?: string }\n }[]\n assets: { id: string; filename: string; category: string; fileUrl: string }[]\n}\n\n/** The one line a recipe earns in the pull summary, from its hints. */\nexport function recipeLine(filename: string, body: string): string {\n const h = recipeHints(body)\n const facts = [\n h.applies\n ? `applies to ${h.applies === 'any' ? 'everything' : `${h.applies}s`}`\n : '',\n h.seed ? `starts from ${h.seed}` : '',\n ].filter(Boolean)\n return `${filename}${facts.length ? ` (${facts.join(' · ')})` : ''}`\n}\n\nconst safeName = (v: string) =>\n v\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 60) || 'file'\n\nasync function cmdPull(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const ref = positionals[0]\n if (!ref)\n throw new UsageError(\n 'vos folder pull <folderId|slug> [--out dir] [--media]',\n )\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n const folder = resolveFolder(await listFolders(origin, key), ref)\n const res = await apiJson(origin, `/api/folders/${folder.id}`, { key })\n if (res.status !== 200)\n throw new Error(apiError(`pull folder ${folder.slug}`, res))\n const payload = res.body as unknown as PullPayload\n const out = strFlag(flags, 'out') ?? folder.slug\n await mkdir(join(out, 'recipes'), { recursive: true })\n\n const lines: string[] = []\n const recipes: { path: string; line: string }[] = []\n for (const rec of payload.recipes) {\n const path = join(out, 'recipes', safeName(rec.filename))\n await writeFile(path, rec.body ?? '')\n recipes.push({ path, line: recipeLine(rec.filename, rec.body ?? '') })\n }\n for (const rec of payload.inheritedRecipes) {\n const from = safeName(rec.folderSlug ?? 'inherited')\n await mkdir(join(out, 'recipes', '_inherited', from), { recursive: true })\n const path = join(\n out,\n 'recipes',\n '_inherited',\n from,\n safeName(rec.filename),\n )\n await writeFile(path, rec.body ?? '')\n recipes.push({\n path,\n line: `${recipeLine(rec.filename, rec.body ?? '')} [inherited from ${rec.folderName ?? from}]`,\n })\n }\n\n const members: { dir: string; id: string; title: string; take: boolean }[] =\n []\n for (const v of payload.voses) {\n const dir = join(out, 'members', safeName(v.slug || v.title || v.id))\n await mkdir(dir, { recursive: true })\n const cfg = await apiJson(origin, `/api/vos/${v.id}/config`, { key })\n if (cfg.status !== 200) {\n lines.push(`skipped ${v.title}: ${apiError('fetch config', cfg)}`)\n continue\n }\n await writeFile(\n join(dir, 'config.json'),\n JSON.stringify(cfg.body.config, null, 2),\n )\n let take = false\n if (v.hasDoc && v.currentVersionId) {\n const doc = await apiJson(\n origin,\n `/api/vos/${v.id}/versions/${v.currentVersionId}/doc`,\n { key },\n )\n if (doc.status === 200) {\n await writeFile(\n join(dir, 'doc.json'),\n JSON.stringify(doc.body, null, 2),\n )\n take = true\n // --media: the footage comes home beside the doc.\n if (flags.media === true) {\n const hosted = migrateHostedDoc(doc.body) as unknown as ProjectDoc\n await pullMedia({ origin, key }, dir, hosted, r.log)\n }\n }\n }\n writeSyncState(dir, {\n vosId: v.id,\n versionId: v.currentVersionId ?? null,\n title: v.title,\n ...(v.slug ? { slug: v.slug } : {}),\n })\n members.push({ dir, id: v.id, title: v.title, take })\n }\n\n const assets = payload.assets.filter((a) => a.category !== 'recipe')\n const summary = [\n `Pulled ${folder.name} (${folder.slug}) → ${out}/`,\n ...(folder.id && payload.folder.description\n ? [` ${payload.folder.description}`]\n : []),\n ` recipes (${recipes.length}) — read EVERY one:`,\n ...recipes.map((x) => ` ${x.line}`),\n ` members (${members.length}):`,\n ...members.map(\n (m) => ` ${m.title}${m.take ? ' [take]' : ''} → ${m.dir}/`,\n ),\n ...(assets.length\n ? [\n ` assets (${assets.length}): ${assets.map((a) => a.filename).join(', ')}`,\n ]\n : []),\n ...(payload.subfolders.length\n ? [\n ` subfolders (not inlined): ${payload.subfolders.map((s) => s.slug).join(', ')}`,\n ]\n : []),\n ...lines,\n `Then: vos push <file> --folder ${folder.slug} --label \"…\" --note \"…\"`,\n ].join('\\n')\n r.done(\n {\n out,\n folder: payload.folder,\n recipes: recipes.map((x) => x.path),\n members,\n assets,\n subfolders: payload.subfolders,\n },\n summary,\n )\n return EXIT_OK\n}\n\nexport async function cmdFolder(argv: string[]): Promise<number> {\n const sub = argv[0]\n const rest = argv.slice(1)\n switch (sub) {\n case 'list':\n case 'ls':\n return cmdList(rest)\n case 'create':\n return cmdCreate(rest)\n case 'move':\n return cmdMove(rest)\n case 'pull':\n return cmdPull(rest)\n default:\n throw new UsageError(\n 'vos folder <list|create|move|pull> — list your shelf, create a folder, move voses/assets into one, pull a folder to disk',\n )\n }\n}\n","/**\n * Program-path platform verbs — fetch / push / pull for config.json programs,\n * plus `vos login`. Moved here from @vosjs/cli under the CLI boundary (the MIT\n * host owns engine verbs only; every vos.so verb lives in this package).\n *\n * Full local validation stays the host's `vos check` (the one home of the\n * check pipeline); push runs a preflight (migrate → schema → function syntax,\n * all MIT @vosjs/core) so an obviously broken config never burns a request.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { createInterface } from 'node:readline/promises'\nimport { basename, dirname, join } from 'node:path'\nimport {\n CURRENT_CONFIG_VERSION,\n migrateConfig,\n vosConfigJsonSchema,\n} from '@vosjs/core'\nimport { migrateHostedDoc } from '@vosjs/studio-core'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { EXIT_OK, createReporter } from './output'\nimport { LoginUnsupportedError, browserLogin } from './login'\nimport {\n apiError,\n apiJson,\n clientId,\n deriveSlug,\n formatChanges,\n parseVosId,\n platformOrigin,\n readSyncState,\n requireCredential,\n resolveCredential,\n writeCredential,\n writeSyncState,\n} from './platform'\nimport { listFolders, resolveFolder } from './folder'\nimport { pullMedia } from './media'\nimport { lintDoc } from './validateDoc'\nimport type { ProjectDoc } from '@vosjs/studio-core'\nimport type { VersionChange } from './platform'\nimport type { Reporter } from './output'\n\nconst BOOLEAN_FLAGS = new Set([\n 'json',\n 'help',\n 'media',\n 'check',\n 'yes',\n 'claimable',\n 'no-browser',\n])\nconst MULTI_FLAGS = new Set(['override'])\n\ninterface Preflight {\n ok: boolean\n issues: string[]\n /** The migrated config (params/presets untouched) — what a push sends. */\n config: Record<string, unknown> | null\n}\n\n/** Envelope unwrap → migrate → schema → function-string syntax. */\nexport function preflightConfig(parsed: unknown): Preflight {\n const issues: string[] = []\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return { ok: false, issues: ['not a JSON object'], config: null }\n }\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 // A push makes a config DURABLE, so it must say which schema era it was\n // written against. Migrating an absent version would stamp a guess about\n // WHEN the file was authored: a config.json can sit in a repository for\n // years, and reading it as the current schema is silent and unrecoverable.\n // Refuse here rather than send a config the server would refuse anyway.\n if (obj.version === undefined) {\n return {\n ok: false,\n issues: [\n `missing \"version\": a config that is pushed must say which schema it was written against. Add \"version\": ${CURRENT_CONFIG_VERSION}.`,\n ],\n config: null,\n }\n }\n let migrated: Record<string, unknown>\n try {\n migrated = migrateConfig(obj as never) as unknown as Record<string, unknown>\n } catch (e) {\n return {\n ok: false,\n issues: [\n `migration failed: ${e instanceof Error ? e.message : String(e)}`,\n ],\n config: null,\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(`schema ${i.path.join('.') || '(root)'}: ${i.message}`)\n }\n return { ok: false, issues, config: null }\n }\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 issues.push(\n `syntax ${key}: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n return {\n ok: issues.length === 0,\n issues,\n config: issues.length ? null : migrated,\n }\n}\n\n/** `vos push <target>`: a .json file, or a dir holding config.json. */\nexport function resolveConfigPath(target: string): string {\n if (target.endsWith('.json')) return target\n const inDir = join(target, 'config.json')\n if (existsSync(inDir)) return inDir\n throw new UsageError(\n `${target} has no config.json (and is not a take — no doc.json)`,\n )\n}\n\nexport async function cmdFetch(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source)\n throw new UsageError('vos fetch <vosId|watch-url> [--out dir] [--media]')\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const id = parseVosId(source)\n // Attached when present so your own private programs fetch too; public and\n // unlisted programs need no credential at all.\n const key = resolveCredential(strFlag(flags, 'key'))\n\n const meta = await apiJson(origin, `/api/vos/${id}`, { key })\n if (meta.status !== 200) throw new Error(apiError(`fetch vos ${id}`, meta))\n const vosMeta = (meta.body.vos ?? {}) as Record<string, unknown>\n // The metadata route resolves slugs; byte routes want the canonical id.\n const vosId = typeof vosMeta.id === 'string' && vosMeta.id ? vosMeta.id : id\n const cfg = await apiJson(origin, `/api/vos/${vosId}/config`, { key })\n if (cfg.status !== 200)\n throw new Error(apiError(`fetch config for ${vosId}`, cfg))\n\n const slug =\n typeof vosMeta.slug === 'string' && vosMeta.slug ? vosMeta.slug : vosId\n const out = strFlag(flags, 'out') ?? slug\n await mkdir(out, { recursive: true })\n // The config is written EXACTLY as stored (params/presets included) — this\n // file round-trips back through `vos push`.\n await writeFile(\n join(out, 'config.json'),\n JSON.stringify(cfg.body.config, null, 2),\n )\n const title = typeof vosMeta.title === 'string' ? vosMeta.title : ''\n const head =\n typeof vosMeta.currentVersionId === 'string'\n ? vosMeta.currentVersionId\n : null\n writeSyncState(out, {\n vosId,\n versionId: head,\n ...(title ? { title } : {}),\n slug,\n })\n\n // A TAKE vos carries a doc beside its program: write it (and, with\n // --media, bring the footage home) so the directory is a take directory.\n let take = false\n let mediaLine = ''\n if (head) {\n const doc = await apiJson(\n origin,\n `/api/vos/${vosId}/versions/${head}/doc`,\n {\n key,\n },\n )\n if (doc.status === 200 && !('source' in doc.body)) {\n // A PROGRAM document: the user's config is the doc's own; the\n // stored config is the composed one (what plays), so config.json is\n // written from the doc and doc.json omits it.\n const hosted = migrateHostedDoc(doc.body)\n const { config: own } = await writeProgramDoc(out, hosted)\n if (own) {\n await writeFile(join(out, 'config.json'), JSON.stringify(own, null, 2))\n }\n } else if (doc.status === 200) {\n take = true\n const hosted = migrateHostedDoc(doc.body) as unknown as ProjectDoc\n await writeFile(join(out, 'doc.json'), JSON.stringify(hosted, null, 2))\n if (flags.media === true) {\n const media = await pullMedia({ origin, key }, out, hosted, r.log)\n mediaLine = media.downloaded.length\n ? ` + ${media.downloaded.map((m) => m.file).join(', ')}`\n : ''\n }\n }\n }\n\n r.done(\n {\n out,\n id: vosId,\n slug,\n title,\n currentVersionId: head,\n take,\n },\n take\n ? `Wrote ${out}/doc.json + config.json + vos.json${mediaLine} (${title || id}, a take)\\n` +\n (flags.media === true\n ? `Then: vos digest ${out} — look before you cut; edit doc.json; vos validate ${out}; vos push ${out}`\n : `Add --media to bring the recording home (digest/frames/render need it); then edit doc.json and vos push ${out}`)\n : `Wrote ${out}/config.json + vos.json (${title || id})\\n` +\n `Edit config.json, then: vos check ${out}/config.json && vos push ${out}/config.json`,\n )\n return EXIT_OK\n}\n\n/**\n * `vos duplicate <vosId|watch-url>` — a private sibling of YOUR OWN vos.\n * Head only, same folder, named \"Copy of <title>\" by the SERVER so\n * the shelf and the CLI can never disagree about what a copy is called.\n *\n * Someone else's work is REMIXED, not duplicated: fetch it and push with\n * `--remix-of`. The route answers 403 saying exactly that.\n */\nexport async function cmdDuplicate(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const source = positionals[0]\n if (!source) throw new UsageError('vos duplicate <vosId|watch-url> [--json]')\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const id = parseVosId(source)\n const key = resolveCredential(strFlag(flags, 'key'))\n\n const res = await apiJson(origin, `/api/vos/${id}/duplicate`, {\n method: 'POST',\n key,\n })\n if (res.status !== 201) throw new Error(apiError(`duplicate ${id}`, res))\n const created = (res.body.vos ?? {}) as Record<string, unknown>\n const newId = String(created.id ?? '')\n const title = typeof created.title === 'string' ? created.title : ''\n const slug = typeof created.slug === 'string' ? created.slug : newId\n\n r.done(\n {\n id: newId,\n title,\n slug,\n remixedFromId: id,\n currentVersionId: created.currentVersionId ?? null,\n },\n `Duplicated as \"${title}\" (private, beside the original)\\n` +\n ` edit ${origin}/studio?vos=${newId}\\n` +\n ` fetch vos fetch ${newId}`,\n )\n return EXIT_OK\n}\n\n/**\n * THE program-create call — the one implementation behind `vos push` for a\n * new vos (and any in-repo script that creates programs). Creates a PRIVATE\n * vos, retrying the slug on collision (unless the caller chose it). No\n * sync-state side effects: tracking is the CLI verb's concern, not the\n * create's.\n */\nexport interface CreateProgramOptions {\n origin: string\n key: string\n config: Record<string, unknown>\n title: string\n /** Caller-chosen slug (no retry on collision); absent = derived + retried. */\n slug?: string\n description?: string\n tags?: string[]\n folderId?: string\n remixOfId?: string\n /** Attribution on v1: what you did and why — the first turn. */\n label?: string\n note?: string\n log?: (msg: string) => void\n}\n\nexport interface CreateProgramResult {\n id: string\n slug: string\n currentVersionId: string | null\n}\n\nexport async function createProgramVos(\n opts: CreateProgramOptions,\n): Promise<CreateProgramResult> {\n const title = opts.title.slice(0, 100)\n const slugGiven = opts.slug !== undefined\n const baseSlug = opts.slug ?? deriveSlug(title)\n for (let attempt = 0; ; attempt++) {\n const slug =\n attempt === 0 ? baseSlug : `${baseSlug}-${attempt + 1}`.slice(0, 50)\n const body: Record<string, unknown> = {\n title,\n slug,\n visibility: 'private',\n config: opts.config,\n client: clientId(),\n }\n if (opts.description) body.description = opts.description\n if (opts.tags?.length) body.tags = opts.tags\n if (opts.folderId) body.folderId = opts.folderId\n if (opts.remixOfId) body.remixOfId = opts.remixOfId\n if (opts.label) body.label = opts.label\n if (opts.note) body.note = opts.note\n const res = await apiJson(opts.origin, '/api/vos', {\n method: 'POST',\n key: opts.key,\n body,\n })\n if (res.status === 409 && !slugGiven && attempt < 3) {\n opts.log?.(`slug \"${slug}\" is taken — retrying`)\n continue\n }\n if (res.status !== 201) throw new Error(apiError('push vos', res))\n const created = (res.body.vos ?? {}) as Record<string, unknown>\n return {\n id: String(created.id ?? ''),\n slug: typeof created.slug === 'string' ? created.slug : slug,\n currentVersionId:\n typeof created.currentVersionId === 'string'\n ? created.currentVersionId\n : null,\n }\n }\n}\n\nexport async function cmdPushProgram(argv: string[]): Promise<number> {\n const { positionals, flags, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n MULTI_FLAGS,\n )\n const target = positionals[0]\n if (!target) {\n throw new UsageError(\n 'vos push <config.json|take> [--vos id] [--title t] [--slug s] [--desc d] [--tags a,b] [--folder <id|slug>] [--remix-of id] [--note n] [--label l] [--base versionId] [--override id]...',\n )\n }\n const source = resolveConfigPath(target)\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const dir = dirname(source)\n\n const parsed = JSON.parse(await readFile(source, 'utf8')) as unknown\n const pre = preflightConfig(parsed)\n if (!pre.ok || !pre.config) {\n for (const issue of pre.issues) r.log(`error ${issue}`)\n throw new Error(\n `config does not validate — full report: vos check ${source}`,\n )\n }\n const config = pre.config\n const state = readSyncState(dir)\n const vosFlag = strFlag(flags, 'vos')\n const vosId = vosFlag ? parseVosId(vosFlag) : null\n // A program document beside the config: the shared layers, the tween\n // overlay, the anchor's own length. Lint-gated like a take's doc.\n const programDoc = await readProgramDoc(dir, config)\n if (programDoc) {\n const lint = lintDoc(programDoc as never)\n if (lint.problems.length) {\n throw new Error(`doc.json fails lint:\\n ${lint.problems.join('\\n ')}`)\n }\n for (const w of lint.warnings) r.log(`warning doc.json: ${w}`)\n }\n\n // --claimable: the credential-free rung. Creates a NEW claimable vos (72h\n // claim link, programs only) — no key resolved, no vos.json written (the\n // agent cannot iterate an unclaimed vos; after the human claims it, the\n // loop rides THEIR key). One-shot by design.\n if (flags.claimable === true) {\n if (vosId) {\n throw new UsageError(\n '--claimable creates a NEW claimable vos and cannot iterate (--vos). After the human claims it, iterate with their key: vos push --vos <id>',\n )\n }\n const fallback = state?.title\n ? `${state.title} remix`\n : basename(source).replace(/\\.json$/i, '') || 'vos program'\n const title = (strFlag(flags, 'title') ?? fallback).slice(0, 100)\n const body: Record<string, unknown> = { title, config }\n const slug = strFlag(flags, 'slug')\n if (slug) body.slug = slug\n const res = await apiJson(origin, '/api/claim', { method: 'POST', body })\n if (res.status !== 201) throw new Error(apiError('claimable push', res))\n const claimUrl = String(res.body.claimUrl ?? '')\n const expiresAt = String(res.body.expiresAt ?? '')\n const created = (res.body.vos ?? {}) as Record<string, unknown>\n r.done(\n { id: created.id ?? null, title, claimUrl, expiresAt },\n `Claimable push created (${title})\\n` +\n ` claim: ${claimUrl}\\n` +\n ` expires: ${expiresAt} — unclaimed work is deleted after 72h\\n` +\n `Hand the claim link to the user and NOWHERE else — it is the only\\n` +\n `reference and the only credential. After they claim it, iterate\\n` +\n `with their key: vos push ${source} --vos ${String(created.id ?? '<id>')}`,\n )\n return EXIT_OK\n }\n\n const key = requireCredential(strFlag(flags, 'key'))\n // Accept both the repeatable --override id and the legacy --overrides id,id.\n // multi's index access is typed present but runtime-optional — hence the cast.\n const overrides = [\n ...((multi.override as string[] | undefined) ?? []),\n ...(strFlag(flags, 'overrides')?.split(',') ?? []),\n ]\n .map((s) => s.trim())\n .filter(Boolean)\n\n const desc = strFlag(flags, 'desc')\n const tagsFlag = strFlag(flags, 'tags')\n const folderRef = strFlag(flags, 'folder')\n if (vosId && (desc || tagsFlag || folderRef)) {\n throw new UsageError(\n '--desc/--tags/--folder apply when CREATING a vos. On an existing one: vos folder move <id> --to <folder> for filing; edit title/description/tags on vos.so',\n )\n }\n\n if (vosId) {\n // Iterate an existing vos: add a version. --base names the version this\n // edit was made FROM (defaulting to the tracked base in vos.json, so a\n // fetch→edit→push loop gets stale detection for free); --overrides\n // consents to touching protected (human-edited) nodes — ONLY when the\n // user asked for that change.\n const trackedBase =\n state && state.vosId === vosId && state.versionId\n ? state.versionId\n : undefined\n const body: Record<string, unknown> = { config, client: clientId() }\n if (programDoc) body.doc = programDoc\n const base = strFlag(flags, 'base') ?? trackedBase\n if (base) body.baseVersionId = base\n const note = strFlag(flags, 'note')\n if (note) body.note = note\n const label = strFlag(flags, 'label')\n if (label) body.label = label\n if (overrides.length) body.overrides = overrides\n const res = await apiJson(origin, `/api/vos/${vosId}/versions`, {\n method: 'POST',\n key,\n body,\n })\n if (res.status === 409) {\n // The correction path is the data path: both 409 shapes carry what to\n // read. stale_base embeds the changes made on the platform since your\n // base; protected_conflict lists the human-touched nodes you'd clobber.\n const changes = Array.isArray(res.body.changes)\n ? (res.body.changes as VersionChange[])\n : []\n for (const line of formatChanges(changes)) r.log(`platform: ${line}`)\n const protectedIds = Array.isArray(res.body.protected)\n ? res.body.protected\n : []\n const nodes = Array.isArray(res.body.nodes) ? res.body.nodes : []\n r.event({\n event: 'conflict',\n reason: res.body.error ?? 'conflict',\n changes,\n protected: protectedIds,\n nodes,\n })\n if (res.body.error === 'protected_conflict') {\n throw new Error(\n `push touches human-edited nodes: ${nodes.join(', ')} — keep the human's values, ` +\n `or re-push with --overrides ${nodes.join(',')} ONLY if the user asked for this change`,\n )\n }\n throw new Error(\n `version base is stale — the platform copy changed (${changes.length} edit${changes.length === 1 ? 's' : ''} above). ` +\n `Run: vos pull ${dir} — then re-apply your edit and push again`,\n )\n }\n if (res.status !== 201)\n throw new Error(apiError(`push version to ${vosId}`, res))\n const version = (res.body.version ?? {}) as Record<string, unknown>\n // Track what we just made: the new version is the next push's base.\n if (typeof version.id === 'string') {\n writeSyncState(dir, { vosId, versionId: version.id })\n }\n const watchUrl = `${origin}/vos/${vosId}`\n const studioUrl = `${origin}/studio?vos=${vosId}`\n r.done(\n {\n id: vosId,\n versionId: version.id ?? null,\n versionNumber: version.versionNumber ?? null,\n base: base ?? null,\n watchUrl,\n studioUrl,\n },\n `Pushed version ${String(version.versionNumber ?? '?')} of ${vosId}\\n` +\n ` watch: ${watchUrl}\\n studio: ${studioUrl}`,\n )\n return EXIT_OK\n }\n\n // Create a new PRIVATE vos. Lineage comes from vos.json (written by\n // `vos fetch` beside the config) or --remix-of; the platform validates it.\n const remixOfId = strFlag(flags, 'remix-of') ?? state?.vosId\n const fallbackTitle = state?.title\n ? `${state.title} remix`\n : basename(source).replace(/\\.json$/i, '') || 'vos remix'\n const title = (strFlag(flags, 'title') ?? fallbackTitle).slice(0, 100)\n const folderId = folderRef\n ? resolveFolder(await listFolders(origin, key), folderRef).id\n : undefined\n\n const created = await createProgramVos({\n origin,\n key,\n config,\n title,\n slug: strFlag(flags, 'slug'),\n description: desc,\n tags: tagsFlag\n ?.split(',')\n .map((t) => t.trim())\n .filter(Boolean),\n folderId,\n remixOfId,\n label: strFlag(flags, 'label'),\n note: strFlag(flags, 'note'),\n log: (msg) => r.log(msg),\n })\n // The directory now TRACKS the created vos (its source stays as\n // remixOfId) — the next push/pull needs no flags.\n writeSyncState(dir, {\n vosId: created.id,\n versionId: created.currentVersionId,\n title,\n slug: created.slug,\n ...(remixOfId ? { remixOfId } : {}),\n })\n const watchUrl = `${origin}/vos/${created.id}`\n const studioUrl = `${origin}/studio?vos=${created.id}`\n r.done(\n {\n id: created.id,\n slug: created.slug,\n title,\n visibility: 'private',\n remixOfId: remixOfId ?? null,\n currentVersionId: created.currentVersionId,\n watchUrl,\n studioUrl,\n },\n `Created private vos ${created.id} (${title})\\n` +\n ` watch: ${watchUrl}\\n studio: ${studioUrl}\\n` +\n `Iterate with: vos push ${source} --vos ${created.id}`,\n )\n return EXIT_OK\n}\n\nexport async function cmdPullProgram(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n // Positional: the tracked directory or its config.json (default cwd).\n const target = positionals[0] ?? '.'\n const dir = target.endsWith('.json') ? dirname(target) : target\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n\n const state = readSyncState(dir)\n const vosFlag = strFlag(flags, 'vos')\n const vosId = vosFlag ? parseVosId(vosFlag) : (state?.vosId ?? null)\n if (!vosId) {\n throw new UsageError(\n `no tracked vos in ${dir}/vos.json — pass --vos <id>, or fetch/push first`,\n )\n }\n const since = strFlag(flags, 'since') ?? state?.versionId ?? null\n if (!since) {\n throw new UsageError(\n `no base version in ${dir}/vos.json — pass --since <versionId>`,\n )\n }\n // The changelog walk is owner-only (edits on private work).\n const key = requireCredential(strFlag(flags, 'key'))\n\n const res = await apiJson(\n origin,\n `/api/vos/${vosId}/changes?since=${encodeURIComponent(since)}`,\n { key },\n )\n if (res.status !== 200)\n throw new Error(apiError(`pull changes for ${vosId}`, res))\n\n const head = (res.body.head ?? {}) as Record<string, unknown>\n const changes = Array.isArray(res.body.changes)\n ? (res.body.changes as VersionChange[])\n : []\n const protectedIds = Array.isArray(res.body.protected)\n ? (res.body.protected as string[])\n : []\n\n if (changes.length === 0) {\n r.done(\n { id: vosId, upToDate: true, head: head.id ?? since },\n `${vosId}: up to date (base ${since.slice(0, 8)}… is the head)`,\n )\n return EXIT_OK\n }\n\n for (const line of formatChanges(changes)) r.log(line)\n if (protectedIds.length) {\n r.log(\n `protected (human-edited — keep their values unless asked): ${protectedIds.join(', ')}`,\n )\n }\n if (res.body.truncated === true) {\n r.log('walk truncated — more versions exist; pull again after syncing')\n }\n\n if (flags.check === true) {\n r.done(\n {\n id: vosId,\n upToDate: false,\n versions: changes.length,\n head: head.id ?? null,\n protected: protectedIds,\n changes,\n },\n `${changes.length} version${changes.length === 1 ? '' : 's'} behind — run without --check to sync`,\n )\n return EXIT_OK\n }\n\n // Sync: the head config replaces config.json (the old file is kept as\n // config.backup.json), and vos.json repoints so the next push has the fresh\n // base. Your uncommitted local edits live in the backup — re-apply on top.\n const cfg = await apiJson(origin, `/api/vos/${vosId}/config`, { key })\n if (cfg.status !== 200)\n throw new Error(apiError(`fetch head config for ${vosId}`, cfg))\n const configPath = join(dir, 'config.json')\n let backedUp = false\n if (existsSync(configPath)) {\n await writeFile(join(dir, 'config.backup.json'), await readFile(configPath))\n backedUp = true\n }\n // A program DOCUMENT on the head: the user's config is the doc's\n // own (the stored config is the composed one), and doc.json comes home\n // beside it without that config.\n let headConfig = cfg.body.config as Record<string, unknown>\n const headId = typeof head.id === 'string' ? head.id : null\n if (headId) {\n const docRes = await apiJson(\n origin,\n `/api/vos/${vosId}/versions/${headId}/doc`,\n { key },\n )\n if (docRes.status === 200 && !('source' in docRes.body)) {\n const { config: own } = await writeProgramDoc(\n dir,\n migrateHostedDoc(docRes.body),\n )\n if (own) headConfig = own\n }\n }\n await writeFile(configPath, JSON.stringify(headConfig, null, 2))\n writeSyncState(dir, {\n vosId,\n versionId: typeof head.id === 'string' ? head.id : since,\n })\n\n r.done(\n {\n id: vosId,\n upToDate: false,\n versions: changes.length,\n head: head.id ?? null,\n protected: protectedIds,\n changes,\n out: configPath,\n backup: backedUp ? join(dir, 'config.backup.json') : null,\n },\n `Pulled ${changes.length} version${changes.length === 1 ? '' : 's'} → ${configPath}` +\n (backedUp ? ` (previous copy: config.backup.json)` : '') +\n `\\nRe-apply your edit on the new head, then: vos push ${configPath} --vos ${vosId}`,\n )\n return EXIT_OK\n}\n\nexport async function cmdLogin(argv: string[]): Promise<number> {\n const { flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n\n // The paste ladder keeps its lanes: an explicit --key (or a VOS_API_KEY\n // already in the env) validates and stores without any browser.\n const explicit = strFlag(flags, 'key') ?? process.env.VOS_API_KEY?.trim()\n if (explicit) return storeKey(explicit, origin, r)\n\n // Default: the browser device flow. Works TTY-less by design — that is\n // the agent path (print URL + code, the human approves, the poll lands).\n try {\n const openBrowser =\n process.stdout.isTTY === true &&\n !process.env.SSH_CONNECTION &&\n !process.env.SSH_TTY &&\n flags.json !== true &&\n flags['no-browser'] !== true\n const { path, user } = await browserLogin(origin, r, {\n label: strFlag(flags, 'label'),\n openBrowser,\n })\n r.done(\n { path, origin, user },\n `Signed in${user ? ` as ${user}` : ''} — key stored at ${path} (used by every vos platform verb)`,\n )\n return EXIT_OK\n } catch (e) {\n if (!(e instanceof LoginUnsupportedError)) throw e\n }\n\n // Older origin without the device flow — the pre-device-flow paste prompt.\n if (!process.stdin.isTTY) {\n throw new UsageError(\n 'vos login --key <vos_sk_…> (headless), or run interactively — mint a key at https://vos.so/app/api',\n )\n }\n const rl = createInterface({ input: process.stdin, output: process.stderr })\n const key = (\n await rl.question(`Paste a content key from ${origin}/app/api: `)\n ).trim()\n rl.close()\n if (!key) throw new UsageError('no key given')\n return storeKey(key, origin, r)\n}\n\n/** Validate (cheapest key-readable read) and store a pasted/env key. */\nasync function storeKey(\n key: string,\n origin: string,\n r: Reporter,\n): Promise<number> {\n const probe = await apiJson(origin, '/api/folders', { key })\n if (probe.status === 401 || probe.status === 403) {\n throw new Error(apiError('validate key', probe))\n }\n const path = writeCredential(key)\n r.done(\n { path, origin },\n `Signed in — key stored at ${path} (used by every vos platform verb)`,\n )\n return EXIT_OK\n}\n\n/**\n * A directory is a TAKE when its doc.json is a RECORDING document (it carries\n * `source`) — the deterministic sniff. A program directory may carry a\n * doc.json too (a program document, `program` + the shared layers,\n * with config.json as its config); that is a program push.\n */\nexport function isTakeDir(target: string): boolean {\n try {\n if (!statSync(target).isDirectory()) return false\n const docPath = join(target, 'doc.json')\n if (!existsSync(docPath)) return false\n try {\n const doc: unknown = JSON.parse(readFileSync(docPath, 'utf8'))\n return typeof doc === 'object' && doc !== null && 'source' in doc\n } catch {\n return true // unparsable: leave it to the take path's own error\n }\n } catch {\n return false\n }\n}\n\n/**\n * The program document beside a config.json, if any: doc.json without\n * `source`. On disk it omits `program.config` (config.json IS the config);\n * on the wire it carries it. Returns the doc as pushed (config attached) or\n * null when the directory has none.\n */\nexport async function readProgramDoc(\n dir: string,\n config: Record<string, unknown>,\n): Promise<Record<string, unknown> | null> {\n const docPath = join(dir, 'doc.json')\n if (!existsSync(docPath)) return null\n const parsed: unknown = JSON.parse(await readFile(docPath, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null || 'source' in parsed)\n return null\n const raw = parsed as Record<string, unknown>\n const program =\n raw.program && typeof raw.program === 'object'\n ? (raw.program as Record<string, unknown>)\n : {}\n return { ...raw, program: { ...program, config } }\n}\n\n/** Write a hosted program document to disk: config.json + doc.json sans config. */\nexport async function writeProgramDoc(\n dir: string,\n hosted: Record<string, unknown>,\n): Promise<{ config: Record<string, unknown> | null }> {\n const program =\n hosted.program && typeof hosted.program === 'object'\n ? (hosted.program as Record<string, unknown>)\n : {}\n const { config, ...rest } = program\n const onDisk = { ...hosted, program: rest }\n await writeFile(join(dir, 'doc.json'), JSON.stringify(onDisk, null, 2))\n return {\n config:\n config && typeof config === 'object'\n ? (config as Record<string, unknown>)\n : null,\n }\n}\n","/**\n * `vos login` browser flow — the RFC-8628-shaped device flow behind\n * the AgentDoor promise (\"run `vos login` and let me finish the browser\n * sign-in\"). The CLI asks the platform for a short user code + a vos_dc_\n * poll secret, shows the approval URL (the printed URL is the contract;\n * the browser launch is best-effort), and polls until a signed-in human\n * approves at /cli/auth. The key arrives exactly once and goes STRAIGHT to\n * ~/.config/vos/credentials — never into stdout, NDJSON, or logs (the\n * attribution doctrine: never print a credential).\n */\nimport { hostname } from 'node:os'\nimport { apiError, apiJson, writeCredential } from './platform'\nimport type { Reporter } from './output'\n\n/** The origin has no device-flow endpoints (older server) — caller falls\n back to the paste-a-key ladder. */\nexport class LoginUnsupportedError extends Error {\n constructor() {\n super('this origin does not support browser login')\n }\n}\n\n/** Consecutive network failures tolerated before the loop gives up. */\nconst MAX_TRANSIENT_FAILURES = 5\n/** Backoff ceiling when the server answers 429. */\nconst MAX_INTERVAL_MS = 30_000\n\nexport interface BrowserLoginOptions {\n /** Optional requester label shown on the approval page (--label). */\n label?: string\n /** Attempt the OS browser launch (TTY, local, not --json/--no-browser). */\n openBrowser: boolean\n /** Injected for tests. */\n sleep?: (ms: number) => Promise<void>\n /** Injected for tests — defaults to the real credentials file. */\n store?: (key: string) => string\n}\n\n/** Best-effort OS launch — the printed URL stays the contract (vos open). */\nasync function launchDefaultBrowser(url: string): Promise<void> {\n const opener =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start'\n : 'xdg-open'\n const { exec } = await import('node:child_process')\n exec(`${opener} ${JSON.stringify(url)}`, () => {})\n}\n\n/**\n * Run the device flow to completion. Returns the credential path and the\n * signed-in display name; throws on deny/expiry/timeout with the next step\n * in words.\n */\nexport async function browserLogin(\n origin: string,\n r: Reporter,\n opts: BrowserLoginOptions,\n): Promise<{ path: string; user: string }> {\n const create = await apiJson(origin, '/api/cli/login', {\n method: 'POST',\n body: {\n hostname: hostname().slice(0, 64),\n ...(opts.label ? { label: opts.label.slice(0, 64) } : {}),\n },\n })\n if (create.status === 404) throw new LoginUnsupportedError()\n if (create.status !== 201) throw new Error(apiError('start login', create))\n const code = create.body.code as string\n const secret = create.body.secret as string\n const verifyUrl = create.body.verifyUrl as string\n const expiresAt = Date.parse(String(create.body.expiresAt ?? ''))\n const baseIntervalMs =\n (typeof create.body.interval === 'number' ? create.body.interval : 3) * 1000\n if (!code || !secret || !verifyUrl || Number.isNaN(expiresAt)) {\n throw new Error('start login → malformed response from the platform')\n }\n\n // The agent relay: everything the human needs, nothing secret.\n r.event({ event: 'login_await', url: verifyUrl, code, expiresAt })\n r.log(`Confirm this code in the browser: ${code}`)\n r.log(`Sign in at ${verifyUrl}`)\n if (opts.openBrowser) void launchDefaultBrowser(verifyUrl)\n r.log('Waiting for approval… (Ctrl-C to cancel)')\n\n const sleep =\n opts.sleep ?? ((ms: number) => new Promise((res) => setTimeout(res, ms)))\n let intervalMs = baseIntervalMs\n let failures = 0\n let capNoted = false\n while (Date.now() < expiresAt) {\n await sleep(intervalMs)\n let res\n try {\n res = await apiJson(origin, '/api/cli/login/poll', {\n method: 'POST',\n body: { secret },\n })\n failures = 0\n } catch (e) {\n if (++failures >= MAX_TRANSIENT_FAILURES) {\n throw new Error(\n `lost the connection while waiting (${e instanceof Error ? e.message : String(e)}) — run \\`vos login\\` again`,\n )\n }\n continue\n }\n const status = res.body.status as string | undefined\n if (res.status === 200 && status === 'pending') {\n intervalMs = baseIntervalMs\n continue\n }\n if (res.status === 200 && status === 'ok') {\n // The one delivery — straight to disk, never through any output path.\n const path = (opts.store ?? writeCredential)(res.body.key as string)\n const user =\n typeof res.body.user === 'object' && res.body.user !== null\n ? ((res.body.user as { name?: string }).name ?? '')\n : ''\n return { path, user }\n }\n if (res.status === 429) {\n // key_limit carries the fix in words and keeps the approval alive —\n // say it once, keep polling so a revoke over on /app/api resumes us.\n if (status === 'key_limit' && !capNoted) {\n capNoted = true\n r.log(`${res.body.error as string} — ${res.body.hint as string}`)\n }\n intervalMs = Math.min(intervalMs * 2, MAX_INTERVAL_MS)\n continue\n }\n if (res.status === 403 && status === 'denied') {\n throw new Error('the sign-in was denied in the browser')\n }\n throw new Error(\n typeof res.body.error === 'string'\n ? res.body.error\n : apiError('poll login', res),\n )\n }\n throw new Error(\n 'no approval within 15 minutes — run `vos login` again, or mint a key at https://vos.so/app/api and pass --key',\n )\n}\n","/**\n * `vos asset` — the work verbs on individual assets. Deliberately\n * NOT a folder verb: folders are shelf structure (the human's, add-only),\n * assets are WORK — and renaming your own work is an ordinary edit.\n *\n * vos asset rename <assetId> <newname.ext> [--json]\n * vos asset push <file...> [--folder <folderId|slug>] [--json]\n *\n * rename is the CLI face of `PATCH /assets/:id { filename }`: a\n * one-column update, bytes and fileUrl untouched. The server holds the\n * extension to the asset's category (a recipe stays .md).\n *\n * push is `POST /assets/upload` per file (SKQ: the launch-kit loop files\n * its posters and store stills into the release's project). A content key\n * uploads models (.glb/.gltf), recipes (.md — though `vos recipe push` is\n * the recipe verb, with replace-in-place) and images (.png/.jpg/.jpeg/\n * .webp/.gif, 40/24h); the server refuses anything else in words. Files\n * upload one by one and a refusal names the file it stopped on, so a\n * partial push is legible, never silent.\n */\nimport { readFileSync } from 'node:fs'\nimport { basename, extname } from 'node:path'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { listFolders, resolveFolder } from './folder'\nimport { EXIT_OK, createReporter } from './output'\nimport {\n apiError,\n apiJson,\n platformOrigin,\n requireCredential,\n} from './platform'\n\nconst BOOLEAN_FLAGS = new Set(['json', 'help'])\n\nconst MIME_BY_EXT: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.webp': 'image/webp',\n '.gif': 'image/gif',\n '.glb': 'model/gltf-binary',\n '.gltf': 'model/gltf+json',\n '.md': 'text/markdown',\n}\n\nasync function cmdRename(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const [assetId, filename] = positionals\n if (!assetId || !filename) {\n throw new UsageError('vos asset rename <assetId> <newname.ext>')\n }\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n\n const res = await apiJson(origin, `/api/assets/${assetId}`, {\n method: 'PATCH',\n key,\n body: { filename },\n })\n if (res.status !== 200) throw new Error(apiError(`rename ${assetId}`, res))\n r.done(\n { id: assetId, filename: res.body.filename },\n `renamed asset ${assetId} → ${String(res.body.filename)}`,\n )\n return EXIT_OK\n}\n\nasync function cmdPush(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n if (positionals.length === 0) {\n throw new UsageError('vos asset push <file...> [--folder <folderId|slug>]')\n }\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n const folderRef = strFlag(flags, 'folder')\n const folder = folderRef\n ? resolveFolder(await listFolders(origin, key), folderRef)\n : null\n\n const uploaded: { id: unknown; filename: unknown }[] = []\n for (const file of positionals) {\n const name = basename(file)\n const mime =\n MIME_BY_EXT[extname(name).toLowerCase()] ?? 'application/octet-stream'\n const body = readFileSync(file)\n const form = new FormData()\n form.set('file', new Blob([body], { type: mime }), name)\n if (folder) form.set('folderId', folder.id)\n const res = await fetch(`${origin}/api/assets/upload`, {\n method: 'POST',\n headers: { accept: 'application/json', authorization: `Bearer ${key}` },\n body: form,\n })\n let payload: Record<string, unknown> = {}\n try {\n payload = (await res.json()) as Record<string, unknown>\n } catch {\n // non-JSON error bodies stay {}\n }\n if (res.status !== 200 && res.status !== 201) {\n const landed = uploaded.length\n ? ` (${uploaded.length} of ${positionals.length} landed before it)`\n : ''\n throw new Error(\n apiError(`push ${name}${landed}`, {\n status: res.status,\n body: payload,\n }),\n )\n }\n uploaded.push({ id: payload.id, filename: payload.filename })\n r.log(\n `uploaded ${String(payload.filename ?? name)} (${String(payload.id)})`,\n )\n }\n r.done(\n {\n uploaded,\n count: uploaded.length,\n folder: folder?.slug ?? null,\n },\n `pushed ${uploaded.length} asset${uploaded.length === 1 ? '' : 's'}${\n folder ? ` into ${folder.slug}` : ''\n }`,\n )\n return EXIT_OK\n}\n\nexport async function cmdAsset(argv: string[]): Promise<number> {\n const sub = argv[0]\n const rest = argv.slice(1)\n switch (sub) {\n case 'rename':\n return cmdRename(rest)\n case 'push':\n return cmdPush(rest)\n default:\n throw new UsageError(\n 'vos asset <rename|push> — rename one of your assets, or push files onto the shelf (vos asset push <file...> [--folder <slug>])',\n )\n }\n}\n","/**\n * `vos recipe` — put a recipe document on the shelf. A recipe is a plain\n * markdown ASSET (category `recipe`), the one asset an agent is expected to\n * WRITE: the write-back prompt line and the kept-prior-body history exist\n * for exactly this act, and until now the CLI had no verb for it.\n *\n * vos recipe push <file.md> --folder <folderId|slug> [--json] create\n * vos recipe push <file.md> --asset <assetId> [--json] replace\n *\n * Create is `POST /assets/upload` (multipart, filed into the folder you\n * pulled); replace is `PUT /assets/:id/file` (raw markdown, same id and\n * fileUrl, the displaced body kept as the one prior version). ONE verb for\n * both because from the agent's side they are the same act: put this\n * document where the collection reads it. Reading is `vos folder pull`\n * (every recipe, inherited ones included); restore stays a human gesture\n * on the recipe page — a verb that undoes the owner's edit is not one to\n * hand an agent.\n */\nimport { readFileSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { listFolders, resolveFolder } from './folder'\nimport { EXIT_OK, createReporter } from './output'\nimport {\n apiError,\n apiJson,\n platformOrigin,\n requireCredential,\n} from './platform'\n\nconst BOOLEAN_FLAGS = new Set(['json', 'help'])\nconst USAGE =\n 'vos recipe push <file.md> (--folder <folderId|slug> | --asset <assetId>)'\n\n/** The server holds recipes to .md; refuse locally so the error names the file. */\nexport function recipeFilename(file: string): string {\n const name = basename(file)\n if (!/\\.md$/i.test(name)) {\n throw new UsageError(`a recipe is a markdown file — ${name} is not .md`)\n }\n return name\n}\n\nasync function cmdPush(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const [file] = positionals\n const folderRef = strFlag(flags, 'folder')\n const assetId = strFlag(flags, 'asset')\n if (!file || (!folderRef && !assetId) || (folderRef && assetId)) {\n throw new UsageError(USAGE)\n }\n const filename = recipeFilename(file)\n const body = readFileSync(file)\n const r = createReporter(flags.json === true)\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const key = requireCredential(strFlag(flags, 'key'))\n\n if (assetId) {\n const res = await apiJson(origin, `/api/assets/${assetId}/file`, {\n method: 'PUT',\n key,\n raw: new Uint8Array(body),\n headers: { 'content-type': 'text/markdown' },\n })\n if (res.status !== 200) {\n throw new Error(apiError(`replace recipe ${assetId}`, res))\n }\n r.done(\n { id: assetId, filename: res.body.filename, replaced: true },\n `replaced recipe ${assetId} (${String(res.body.filename)}) in place — the prior body is kept, restore it from the recipe page`,\n )\n return EXIT_OK\n }\n\n const folder = resolveFolder(await listFolders(origin, key), folderRef!)\n const form = new FormData()\n form.set('file', new Blob([body], { type: 'text/markdown' }), filename)\n form.set('folderId', folder.id)\n const res = await fetch(`${origin}/api/assets/upload`, {\n method: 'POST',\n headers: { accept: 'application/json', authorization: `Bearer ${key}` },\n body: form,\n })\n let payload: Record<string, unknown> = {}\n try {\n payload = (await res.json()) as Record<string, unknown>\n } catch {\n // non-JSON error bodies stay {}\n }\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(\n apiError(`push recipe ${filename}`, {\n status: res.status,\n body: payload,\n }),\n )\n }\n const meta = (payload.metadata ?? {}) as Record<string, unknown>\n // The SERVER names the file (a recipe a key files takes the CAPS\n // convention, CUT.md), so report what landed — never the local basename,\n // or the terminal and the shelf describe the same recipe differently.\n const stored =\n typeof payload.filename === 'string' ? payload.filename : filename\n r.done(\n {\n id: payload.id,\n filename: payload.filename,\n folder: folder.slug,\n name: meta.name,\n description: meta.description,\n },\n `pushed ${stored} into ${folder.slug} (${String(payload.id)})${\n typeof meta.name === 'string' ? ` — ${meta.name}` : ''\n }\\nReplace it later with: vos recipe push ${file} --asset ${String(payload.id)}`,\n )\n return EXIT_OK\n}\n\nexport async function cmdRecipe(argv: string[]): Promise<number> {\n const sub = argv[0]\n const rest = argv.slice(1)\n switch (sub) {\n case 'push':\n return cmdPush(rest)\n default:\n throw new UsageError(`vos recipe <push> — ${USAGE}`)\n }\n}\n","/**\n * `vos brand <url>` — the brand kit, witnessed. The launch-kit loop must\n * resolve the brand BEFORE any asset is authored (a template's own palette\n * on a deliverable shipped once, and that run is why this verb exists).\n * The kit is a `BRAND.md` recipe: frontmatter carries the roles the poster\n * family binds (`bgA/bgB/bgC`, `ink`, `accent`, `fontDisplay`, `logoUrl`),\n * prose carries where each value came from and what the site says to avoid.\n *\n * Three sources, in order, each read when it exists:\n * 1. `/design.md` — the convention Vercel is teaching companies to\n * publish beside `/llms.txt`: prose for agents, font names, logo\n * assets, a reject list. Colours there are usually CSS variable names,\n * not values, so it never replaces witnessing; it wins on fonts, logos\n * and the avoid list.\n * 2. `/llms.txt` — the product's name and one-line claim.\n * 3. The page itself, in a browser: theme-color, icons, og:image, the\n * computed heading and body faces and inks, the body ground, the\n * surfaces, and the accent (the saturated colour buttons and links\n * agree on).\n *\n * Everything is a pure function over fetched text and one witnessed object,\n * so the composition is testable without a browser.\n */\nimport { writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { parseFrontmatter } from '@vosjs/shared/frontmatter'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { createReporter } from './output'\nimport { launchBrowser } from '../browser'\nimport type { Browser } from 'playwright'\n\nexport interface BrandKit {\n name: string\n site: string\n witnessed: string\n bgA: string\n bgB: string\n bgC: string\n ink: string\n accent: string\n fontDisplay: string\n fontBody: string\n logoUrl: string | null\n iconUrl: string | null\n ogImage: string | null\n wordmark: string\n designMd: string | null\n llmsTxt: string | null\n}\n\nexport interface DesignMdFacts {\n name: string | null\n description: string | null\n fonts: string[]\n logos: string[]\n hexes: string[]\n avoid: string[]\n}\n\nexport interface Witness {\n title: string\n siteName: string | null\n themeColor: string | null\n icons: string[]\n ogImage: string | null\n h1: { fontFamily: string; color: string } | null\n body: { fontFamily: string; color: string; backgroundColor: string }\n /** Background colours of sections, headers, cards, in document order. */\n surfaces: string[]\n /** Background colours of buttons and the colours of links. */\n accents: string[]\n}\n\nconst HEX_RE = /#(?:[0-9a-f]{6}|[0-9a-f]{3})\\b/gi\n\n/** Every hex colour in a text, in order, deduped, lowercased. */\nexport function extractHexes(text: string): string[] {\n const out: string[] = []\n for (const m of text.match(HEX_RE) ?? []) {\n const h = normalizeHex(m)\n if (h && !out.includes(h)) out.push(h)\n }\n return out\n}\n\n/** `#abc` → `#aabbcc`; anything else lowercased; null when not a hex. */\nexport function normalizeHex(raw: string): string | null {\n const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(raw.trim())\n if (!m) return null\n const h = m[1].toLowerCase()\n return (\n '#' +\n (h.length === 3\n ? h\n .split('')\n .map((c) => c + c)\n .join('')\n : h)\n )\n}\n\n/** `rgb(1, 2, 3)` / `rgba(1,2,3,.5)` → `#010203`, or null (transparent, none). */\nexport function rgbToHex(raw: string): string | null {\n const m =\n /rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/.exec(raw)\n if (!m) return normalizeHex(raw)\n const alpha = m[4] as string | undefined\n if (alpha !== undefined && Number(alpha) === 0) return null\n const hex = (n: string) => Number(n).toString(16).padStart(2, '0')\n return `#${hex(m[1])}${hex(m[2])}${hex(m[3])}`\n}\n\nfunction hsl(hex: string): { h: number; s: number; l: number } {\n const r = parseInt(hex.slice(1, 3), 16) / 255\n const g = parseInt(hex.slice(3, 5), 16) / 255\n const b = parseInt(hex.slice(5, 7), 16) / 255\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n const d = max - min\n const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1))\n let h = 0\n if (d !== 0) {\n if (max === r) h = ((g - b) / d) % 6\n else if (max === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h = (h * 60 + 360) % 360\n }\n return { h, s, l }\n}\n\n/** A colour with real chroma: neither a neutral nor near-white/black. */\nexport function isSaturated(hex: string): boolean {\n const { s, l } = hsl(hex)\n return s >= 0.25 && l > 0.12 && l < 0.88\n}\n\nconst isLight = (hex: string) => hsl(hex).l >= 0.5\n\n/** Mix `b` into `a` by `t` (0..1), in sRGB, as hex. */\nexport function mixHex(a: string, b: string, t: number): string {\n const ch = (i: number) =>\n Math.round(\n parseInt(a.slice(i, i + 2), 16) * (1 - t) +\n parseInt(b.slice(i, i + 2), 16) * t,\n )\n .toString(16)\n .padStart(2, '0')\n return `#${ch(1)}${ch(3)}${ch(5)}`\n}\n\n/** The most frequent entry, ties by first appearance. */\nfunction mostCommon(values: string[]): string | null {\n const counts = new Map<string, number>()\n for (const v of values) counts.set(v, (counts.get(v) ?? 0) + 1)\n let best: string | null = null\n let n = 0\n for (const [v, c] of counts)\n if (c > n) {\n best = v\n n = c\n }\n return best\n}\n\n/** The first family of a CSS `font-family` list, unquoted. */\nexport function firstFamily(fontFamily: string): string {\n const first = fontFamily.split(',')[0]?.trim() ?? ''\n return first.replace(/^[\"']|[\"']$/g, '')\n}\n\nconst FONT_HINT_RE =\n /\\b(?:[Uu]se|[Uu]ses|[Ss]et in)\\s+([A-Z][A-Za-z0-9]+(?:\\s+[A-Z][A-Za-z0-9]+){0,3}(?:\\s+(?:Sans|Serif|Mono|Display|Text))?)\\s+(?:for|as|on|everywhere|only)\\b/g\nconst FONT_FAMILY_RE = /font-family\\s*:\\s*[\"']?([^;\"',\\n]+)/gi\nconst LOGO_URL_RE =\n /https?:\\/\\/[^\\s)\"'<>]+?(?:logo|wordmark|mark|brand|icon)[^\\s)\"'<>]*?\\.(?:svg|png|webp)/gi\n\n/**\n * What a `/design.md` says, without pretending it is structured: the\n * frontmatter's name and description, the font families it names (\"Use\n * Geist Sans for prose\"), the logo assets it links, any hex colours it\n * quotes, and the bullets of its reject / avoid / never section verbatim.\n */\nexport function parseDesignMd(text: string): DesignMdFacts {\n const fm = parseFrontmatter(text)\n const fonts: string[] = []\n for (const m of text.matchAll(FONT_HINT_RE)) {\n const f = m[1].trim()\n if (!fonts.includes(f) && !/^(The|This|That|Use|It|A|An)$/.test(f))\n fonts.push(f)\n }\n for (const m of text.matchAll(FONT_FAMILY_RE)) {\n const f = m[1].trim().replace(/^[\"']|[\"']$/g, '')\n if (f && !fonts.includes(f)) fonts.push(f)\n }\n const logos: string[] = []\n for (const m of text.matchAll(LOGO_URL_RE))\n if (!logos.includes(m[0])) logos.push(m[0])\n const avoid: string[] = []\n const lines = text.split('\\n')\n let inAvoid = false\n for (const line of lines) {\n const heading = /^#{1,6}\\s+(.*)$/.exec(line)\n if (heading) {\n inAvoid = /\\b(reject|avoid|never|don'?t|do not|anti-?patterns?)\\b/i.test(\n heading[1],\n )\n continue\n }\n if (!inAvoid) continue\n const bullet = /^\\s*(?:[-*]|\\d+\\.)\\s+(.*)$/.exec(line)\n if (bullet) avoid.push(bullet[1].trim())\n }\n return {\n name: (fm as Record<string, string | undefined>).name ?? null,\n description: (fm as Record<string, string | undefined>).description ?? null,\n fonts,\n logos,\n hexes: extractHexes(text),\n avoid,\n }\n}\n\n/** The product's name and claim from `/llms.txt`: `# name — claim` + `> claim`. */\nexport function parseLlmsTxt(text: string): {\n name: string | null\n claim: string | null\n} {\n const h1 = /^#\\s+(.+)$/m.exec(text)?.[1]?.trim() ?? null\n // The blockquote WRAPS (llms.txt files are written at 80 columns), so\n // join its consecutive `> ` lines and keep the first sentence: the claim\n // is one line by contract, and a recipe heading that stops mid-sentence\n // reads as broken (vos.so's own claim did, on the verb's first run).\n const block = /^>\\s*.+(?:\\n>\\s*.*)*/m.exec(text)?.[0]\n const joined = block\n ? block\n .split('\\n')\n .map((line) => line.replace(/^>\\s*/, '').trim())\n .filter(Boolean)\n .join(' ')\n : ''\n const quote = joined\n ? (/^(.*?[.!?])(?:\\s|$)/.exec(joined)?.[1] ?? joined)\n : null\n let name = h1\n if (h1) {\n const split = /^(.+?)\\s+[—–-]\\s+(.+)$/.exec(h1)\n if (split) name = split[1].trim()\n }\n return { name, claim: quote ?? (h1 && h1 !== name ? h1 : null) }\n}\n\nconst WITNESS_IN_PAGE = `(() => {\n const cs = (el) => el ? getComputedStyle(el) : null\n const meta = (sel) => { const m = document.querySelector(sel); return m ? m.getAttribute('content') : null }\n const abs = (href) => { try { return new URL(href, location.href).toString() } catch { return null } }\n const icons = []\n for (const l of document.querySelectorAll('link[rel~=\"icon\"], link[rel=\"apple-touch-icon\"], link[rel=\"apple-touch-icon-precomposed\"]')) {\n const u = abs(l.getAttribute('href') || ''); if (u && !icons.includes(u)) icons.push(u)\n }\n const h1 = document.querySelector('h1')\n const h1s = cs(h1)\n const bodys = cs(document.body)\n const surfaces = []\n for (const el of document.querySelectorAll('header, nav, main > section, section, footer, article, aside, [class*=\"card\"], [class*=\"Card\"], [class*=\"surface\"], [class*=\"panel\"]')) {\n const bg = cs(el).backgroundColor; if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') surfaces.push(bg)\n if (surfaces.length > 60) break\n }\n const accents = []\n for (const el of document.querySelectorAll('button, [role=\"button\"], a[class*=\"btn\"], a[class*=\"button\"], a[class*=\"Button\"], input[type=\"submit\"]')) {\n const bg = cs(el).backgroundColor; if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') accents.push(bg)\n if (accents.length > 80) break\n }\n let links = 0\n for (const el of document.querySelectorAll('a[href]')) {\n if (links++ > 80) break\n const c = cs(el).color; if (c) accents.push(c)\n }\n return {\n title: document.title,\n siteName: meta('meta[property=\"og:site_name\"]'),\n themeColor: meta('meta[name=\"theme-color\"]'),\n icons,\n ogImage: abs(meta('meta[property=\"og:image\"]') || '') || null,\n h1: h1s ? { fontFamily: h1s.fontFamily, color: h1s.color } : null,\n body: { fontFamily: bodys.fontFamily, color: bodys.color, backgroundColor: bodys.backgroundColor },\n surfaces,\n accents,\n }\n})()`\n\n/** Read the page's own facts in a browser; the one impure step. */\nexport async function witnessSite(\n browser: Browser,\n url: string,\n): Promise<Witness> {\n const ctx = await browser.newContext({\n viewport: { width: 1440, height: 900 },\n deviceScaleFactor: 1,\n })\n try {\n const page = await ctx.newPage()\n await page\n .goto(url, { waitUntil: 'networkidle', timeout: 45_000 })\n .catch(async () => {\n await page.goto(url, { waitUntil: 'load', timeout: 45_000 })\n })\n await page.waitForTimeout(800)\n return await page.evaluate(WITNESS_IN_PAGE)\n } finally {\n await ctx.close()\n }\n}\n\nexport interface BrandComposition {\n kit: BrandKit\n /** One line per role: where its value came from. */\n provenance: Record<string, string>\n avoid: string[]\n}\n\n/**\n * Compose the kit from what was read, in priority order: the design.md\n * wins on fonts, logos and the avoid list; llms.txt on the name and the\n * claim; the witness on every colour and on whatever the others left out.\n */\nexport function composeBrand(input: {\n url: string\n witness: Witness\n design: DesignMdFacts | null\n designUrl: string | null\n llms: { name: string | null; claim: string | null } | null\n llmsUrl: string | null\n today: string\n}): BrandComposition {\n const { witness: w, design, llms } = input\n const p: Record<string, string> = {}\n\n const bgA = rgbToHex(w.body.backgroundColor) ?? '#ffffff'\n p.bgA = `the body's background`\n const surfaceHexes = w.surfaces\n .map(rgbToHex)\n .filter((h): h is string => h !== null && h !== bgA)\n const neutralSurface = mostCommon(surfaceHexes.filter((h) => !isSaturated(h)))\n const bgB =\n neutralSurface ?? mixHex(bgA, isLight(bgA) ? '#000000' : '#ffffff', 0.04)\n p.bgB = neutralSurface\n ? `the most common section / card ground`\n : `no distinct surface found; bgA stepped 4% toward ${isLight(bgA) ? 'black' : 'white'}`\n\n const accentHexes = w.accents\n .map(rgbToHex)\n .filter((h): h is string => h !== null && isSaturated(h))\n const themeHex = w.themeColor ? rgbToHex(w.themeColor) : null\n let accent = mostCommon(accentHexes)\n if (!accent && themeHex && isSaturated(themeHex)) accent = themeHex\n if (!accent) accent = design?.hexes.find(isSaturated) ?? null\n const inkHex =\n rgbToHex(w.h1?.color ?? w.body.color) ??\n (isLight(bgA) ? '#111111' : '#f5f5f5')\n if (!accent) accent = inkHex\n p.accent = accentHexes.length\n ? `the saturated colour buttons and links agree on`\n : themeHex && isSaturated(themeHex)\n ? `the theme-color meta`\n : design?.hexes.find(isSaturated)\n ? `a hex quoted in design.md`\n : `no saturated colour on the page; the ink stands in`\n\n const bgC = mixHex(bgA, accent, 0.14)\n p.bgC = `bgA tinted 14% toward the accent (a highlight ground)`\n p.ink = w.h1 ? `the h1's colour` : `the body's colour`\n\n const fontDisplay =\n design?.fonts[0] ??\n (w.h1 ? firstFamily(w.h1.fontFamily) : firstFamily(w.body.fontFamily))\n p.fontDisplay = design?.fonts[0]\n ? `named in design.md`\n : w.h1\n ? `the h1's computed face`\n : `the body's computed face (no h1)`\n // design.md's second face is usually the code face (\"Geist Mono only for\n // code\"); a mono family is never the body, so the page's own wins then.\n const designBody = design?.fonts.slice(1).find((f) => !/\\bmono\\b/i.test(f))\n const fontBody = designBody ?? firstFamily(w.body.fontFamily)\n p.fontBody = designBody ? `named in design.md` : `the body's computed face`\n\n const logoUrl = design?.logos.find((u) => /wordmark|logo/i.test(u)) ?? null\n const iconUrl =\n w.icons.find((u) => /apple-touch/i.test(u)) ??\n (w.icons.length ? w.icons[0] : null)\n p.logoUrl = logoUrl\n ? `linked from design.md`\n : `none linked; the icon stands in`\n p.iconUrl = iconUrl ? `the page's icon link` : `no icon link`\n\n const host = new URL(input.url).hostname.replace(/^www\\./, '')\n const wordmark =\n llms?.name ??\n design?.name ??\n w.siteName ??\n (w.title.split(/[|—–-]/)[0].trim() || host)\n p.wordmark = llms?.name\n ? `llms.txt's title`\n : design?.name\n ? `design.md's name`\n : w.siteName\n ? `og:site_name`\n : `the page title`\n\n const kit: BrandKit = {\n name: wordmark,\n site: input.url,\n witnessed: input.today,\n bgA,\n bgB,\n bgC,\n ink: inkHex,\n accent,\n fontDisplay,\n fontBody,\n logoUrl: logoUrl ?? iconUrl,\n iconUrl,\n ogImage: w.ogImage,\n wordmark,\n designMd: input.designUrl,\n llmsTxt: input.llmsUrl,\n }\n return { kit, provenance: p, avoid: design?.avoid ?? [] }\n}\n\n/** The recipe file: frontmatter roles + provenance prose + the avoid list. */\nexport function renderBrandMd(\n c: BrandComposition,\n claim: string | null,\n): string {\n const k = c.kit\n const q = (v: string | null) => (v === null ? 'null' : JSON.stringify(v))\n const fm = [\n '---',\n `name: ${JSON.stringify(k.name)}`,\n `description: ${JSON.stringify(`${k.name}'s brand kit, witnessed from ${new URL(k.site).hostname} on ${k.witnessed}`)}`,\n 'applies: any',\n 'seed: none',\n `site: ${q(k.site)}`,\n `witnessed: ${q(k.witnessed)}`,\n `bgA: ${q(k.bgA)}`,\n `bgB: ${q(k.bgB)}`,\n `bgC: ${q(k.bgC)}`,\n `ink: ${q(k.ink)}`,\n `accent: ${q(k.accent)}`,\n `fontDisplay: ${q(k.fontDisplay)}`,\n `fontBody: ${q(k.fontBody)}`,\n `logoUrl: ${q(k.logoUrl)}`,\n `iconUrl: ${q(k.iconUrl)}`,\n `ogImage: ${q(k.ogImage)}`,\n `wordmark: ${q(k.wordmark)}`,\n `designMd: ${q(k.designMd)}`,\n `llmsTxt: ${q(k.llmsTxt)}`,\n '---',\n ].join('\\n')\n const lines = [\n fm,\n '',\n `# ${k.name}`,\n '',\n claim\n ? `${claim}`\n : `The brand of ${k.name}, as witnessed on ${new URL(k.site).hostname}.`,\n '',\n '## Where each value came from',\n '',\n ...Object.entries(c.provenance).map(\n ([role, why]) => `- \\`${role}\\`: ${why}`,\n ),\n '',\n k.designMd\n ? `The site publishes a design.md (${k.designMd}); it wins on fonts, logos and the avoid list below. Colours there are CSS variable names, so every colour above was witnessed on the page.`\n : `The site publishes no design.md; every value above was witnessed on the page, so re-run \\`vos brand\\` after a redesign.`,\n '',\n '## Use',\n '',\n `The poster family binds these roles: \\`bgA/bgB/bgC\\` for the ground, \\`ink\\` for type, \\`fontDisplay\\` for the headline (if it is not in the hosted catalog, \\`vos check\\` warns and the nearest hosted serif or sans stands in), \\`logoUrl\\` for the mark. A take's frame ground is a gradient of \\`accent\\` toward \\`bgC\\` unless the brand is paper, in which case \\`bgB\\` toward \\`bgC\\`.`,\n ]\n if (c.avoid.length) {\n lines.push('', '## Avoid (the site says)', '')\n for (const a of c.avoid) lines.push(`- ${a}`)\n }\n return lines.join('\\n') + '\\n'\n}\n\nasync function fetchText(url: string): Promise<string | null> {\n try {\n const res = await fetch(url, { redirect: 'follow' })\n if (!res.ok) return null\n const type = res.headers.get('content-type') ?? ''\n if (/text\\/html/i.test(type)) return null // a soft 404 page is not a file\n return await res.text()\n } catch {\n return null\n }\n}\n\nexport async function cmdBrand(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, new Set(['json']))\n const raw = positionals[0]\n if (!raw) throw new UsageError('vos brand <url> [--out BRAND.md] [--json]')\n const url = /^https?:\\/\\//i.test(raw) ? raw : `https://${raw}`\n let origin: string\n try {\n origin = new URL(url).origin\n } catch {\n throw new UsageError(`not a URL: ${raw}`)\n }\n const r = createReporter(flags.json === true)\n const out = resolve(strFlag(flags, 'out') ?? 'BRAND.md')\n\n r.log(`reading ${origin}/design.md and /llms.txt…`)\n const [designText, llmsText] = await Promise.all([\n fetchText(`${origin}/design.md`),\n fetchText(`${origin}/llms.txt`),\n ])\n const design = designText ? parseDesignMd(designText) : null\n const llms = llmsText ? parseLlmsTxt(llmsText) : null\n r.event({\n event: 'sources',\n designMd: design !== null,\n llmsTxt: llms !== null,\n })\n\n r.log(`witnessing ${url}…`)\n const browser = await launchBrowser()\n let witness: Witness\n try {\n witness = await witnessSite(browser, url)\n } finally {\n await browser.close()\n }\n\n const composition = composeBrand({\n url,\n witness,\n design,\n designUrl: design ? `${origin}/design.md` : null,\n llms,\n llmsUrl: llms ? `${origin}/llms.txt` : null,\n today: new Date().toISOString().slice(0, 10),\n })\n const md = renderBrandMd(\n composition,\n llms?.claim ?? design?.description ?? null,\n )\n await writeFile(out, md)\n const k = composition.kit\n r.done(\n {\n out,\n kit: k,\n provenance: composition.provenance,\n avoid: composition.avoid,\n },\n `Wrote ${out}\\n ${k.name}: ground ${k.bgA} / ${k.bgB} / ${k.bgC}, ink ${k.ink}, accent ${k.accent}, ${k.fontDisplay} over ${k.fontBody}${k.designMd ? `\\n design.md read (${composition.avoid.length} avoid line(s))` : ''}\\n file it: vos recipe push ${out} --folder <slug>`,\n )\n return 0\n}\n","/**\n * `vos actions from-agent-browser <steps.jsonl>` — the agent that verified\n * the feature already walked the product in agent-browser (Vercel Labs);\n * this turns that walk into an actions.json so `vos record` replays it with\n * a synthesized cursor track, auto-zooms and cuts it. One walk, one take,\n * no second script.\n *\n * What agent-browser leaves behind, measured: no command log (a session\n * persists cookies and state, `trace` is performance events, `record` a\n * raw WebM), and a command's `--json` RESULT does not carry its arguments.\n * `scroll` answers `{scrolled:true}`, `mouse move` `{moved:true}`, `type`\n * echoes the text but not the target, `click @e27` echoes `\"@e27\"`, and a\n * ref is `{role, name}` in the preceding snapshot's `refs` map and nothing\n * else (no selector, no coordinates, no timestamps). So the input is the\n * RECORD agent-browser's own `batch` emits, `{command: [...], result: {…},\n * success, error}`, one per line or the batch array itself, which the\n * skill tells the agent to keep while it verifies (a shell function wraps\n * each call). Refs resolve through the last snapshot line before them.\n *\n * Every mapping is pure and every command that cannot follow is NAMED in\n * the notes, never dropped silently: a recording that skips a step the\n * agent made is a different walk.\n */\nimport { writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { validateActions } from './actions'\nimport { UsageError, parseArgs, strFlag } from './args'\nimport { EXIT_ERROR, EXIT_OK, createReporter } from './output'\nimport type { ActionStep, ActionsFile } from './actions'\n\n/** One agent-browser command with its result: the `batch` record shape. */\nexport interface AgentBrowserRecord {\n command: string[] | string\n /** Single-command `--json` lines carry `data`; batch records carry `result`. */\n data?: unknown\n result?: unknown\n success?: boolean\n error?: string | null\n}\n\nexport interface ConvertOptions {\n /** Overrides the walk's first `open`. */\n url?: string\n /** Overrides the walk's `set viewport`. */\n viewport?: { width: number; height: number }\n}\n\nexport interface ConvertResult {\n actions: ActionsFile\n /** Every command that became no step, or a different step, with its line. */\n notes: string[]\n /** Commands that produced a step. */\n steps: number\n /** Reads and session verbs: nothing to replay. */\n ignored: number\n /** Actions the recorder cannot follow, or that failed in the walk. */\n skipped: number\n}\n\n/** Parse a steps.jsonl (or a batch array) into records; malformed lines are named. */\nexport function parseAgentBrowserLog(text: string): {\n records: AgentBrowserRecord[]\n problems: string[]\n} {\n const records: AgentBrowserRecord[] = []\n const problems: string[] = []\n const trimmed = text.trim()\n if (!trimmed) return { records, problems: ['the log is empty'] }\n const push = (value: unknown, where: string): void => {\n if (Array.isArray(value)) {\n value.forEach((v, i) => push(v, `${where}[${i}]`))\n return\n }\n if (typeof value !== 'object' || value === null) {\n problems.push(`${where}: not a record`)\n return\n }\n const rec = value as Record<string, unknown>\n if (typeof rec.command !== 'string' && !Array.isArray(rec.command)) {\n problems.push(\n `${where}: no \"command\" — keep each call as {command:[…], …result} (the batch shape); a bare --json result does not say what ran`,\n )\n return\n }\n records.push(rec as unknown as AgentBrowserRecord)\n }\n if (trimmed.startsWith('[')) {\n try {\n push(JSON.parse(trimmed), 'batch')\n } catch (e) {\n problems.push(`not JSON: ${(e as Error).message}`)\n }\n return { records, problems }\n }\n trimmed.split('\\n').forEach((line, i) => {\n const l = line.trim()\n if (!l) return\n try {\n push(JSON.parse(l), `line ${i + 1}`)\n } catch {\n problems.push(`line ${i + 1}: not JSON`)\n }\n })\n return { records, problems }\n}\n\n/** Shell-style split for a `command` kept as one string: quotes group, backslash escapes. */\nexport function splitCommand(command: string): string[] {\n const out: string[] = []\n let cur = ''\n let quote: string | null = null\n let has = false\n for (let i = 0; i < command.length; i++) {\n const c = command[i]\n if (quote) {\n if (c === quote) quote = null\n else if (c === '\\\\' && i + 1 < command.length) cur += command[++i]\n else cur += c\n continue\n }\n if (c === '\"' || c === \"'\") {\n quote = c\n has = true\n continue\n }\n if (c === '\\\\' && i + 1 < command.length) {\n cur += command[++i]\n has = true\n continue\n }\n if (/\\s/.test(c)) {\n if (has) out.push(cur)\n cur = ''\n has = false\n continue\n }\n cur += c\n has = true\n }\n if (has) out.push(cur)\n return out\n}\n\ntype Refs = Record<string, { role?: string; name?: string; href?: string }>\n\nconst READ_VERBS = new Set([\n 'get',\n 'is',\n 'eval',\n 'screenshot',\n 'tab',\n 'session',\n 'close',\n 'doctor',\n 'cookies',\n 'storage',\n 'console',\n 'network',\n 'trace',\n 'record',\n 'pdf',\n 'version',\n 'help',\n])\n\nconst quoteAttr = (s: string): string =>\n `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`\n\n/**\n * The snapshot's `url=` is the RESOLVED absolute URL, while the DOM's href\n * attribute is usually the relative path the author wrote, and a CSS\n * attribute selector matches the attribute literally. So a link gets both\n * forms, comma-joined (one Playwright locator); a cross-origin href only\n * ever appears absolute.\n */\nexport function hrefSelector(href: string): string {\n try {\n const u = new URL(href)\n const relative = `${u.pathname}${u.search}${u.hash}`\n return `a[href=${quoteAttr(relative)}], a[href=${quoteAttr(href)}]`\n } catch {\n return `a[href=${quoteAttr(href)}]`\n }\n}\n\n/** A ref or CSS target → a Playwright selector the recorder's `page.locator` takes. */\nfunction resolveTarget(\n target: string,\n refs: Refs,\n): { selector: string } | { reason: string } {\n const m = /^@(e\\d+)$/.exec(target)\n if (!m) return { selector: target }\n const ref = Object.hasOwn(refs, m[1]) ? refs[m[1]] : undefined\n if (!ref)\n return {\n reason: `${target} is not in the last snapshot — keep the \\`snapshot -i\\` line that named it before the step`,\n }\n if (ref.role === 'link' && ref.href)\n return { selector: hrefSelector(ref.href) }\n if (ref.role && ref.name)\n return { selector: `role=${ref.role}[name=${quoteAttr(ref.name)}]` }\n if (ref.role) return { selector: `role=${ref.role}` }\n return { reason: `${target} has no role or name in the snapshot` }\n}\n\n/** The `find <kind> <query>` locators → Playwright selectors. */\nfunction findSelector(\n kind: string,\n query: string,\n flags: { name?: string; exact: boolean },\n): { selector: string } | { reason: string } {\n switch (kind) {\n case 'text':\n return {\n selector: flags.exact ? `text=${quoteAttr(query)}` : `text=${query}`,\n }\n case 'role':\n return {\n selector: flags.name\n ? `role=${query}[name=${quoteAttr(flags.name)}]`\n : `role=${query}`,\n }\n case 'label':\n // Playwright's getByLabel form; the public engines have no label=.\n return {\n selector: `internal:label=${quoteAttr(query)}${flags.exact ? 's' : 'i'}`,\n }\n case 'placeholder':\n return { selector: `[placeholder=${quoteAttr(query)}]` }\n case 'alt':\n return { selector: `[alt=${quoteAttr(query)}]` }\n case 'title':\n return { selector: `[title=${quoteAttr(query)}]` }\n case 'testid':\n return { selector: `[data-testid=${quoteAttr(query)}]` }\n case 'first':\n return { selector: query }\n case 'last':\n case 'nth':\n return {\n reason: `find ${kind} is a position, not a stable selector — name the element by role, text or testid`,\n }\n default:\n return { reason: `find ${kind} is not a locator agent-browser documents` }\n }\n}\n\n/** Pull `--flag value` and `--bool` pairs out of a command's tail. */\nfunction takeFlags(\n args: string[],\n valued: ReadonlySet<string>,\n): { positionals: string[]; flags: Record<string, string | true> } {\n const positionals: string[] = []\n const flags: Record<string, string | true> = {}\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a.startsWith('--')) {\n const name = a.slice(2)\n if (valued.has(name) && i + 1 < args.length) flags[name] = args[++i]\n else flags[name] = true\n continue\n }\n if (a.startsWith('-') && a.length === 2) {\n // agent-browser's short flags: -i (interactive refs), -u (urls), -s <sel>\n if (a === '-s' && i + 1 < args.length) flags.selector = args[++i]\n else flags[a.slice(1)] = true\n continue\n }\n positionals.push(a)\n }\n return { positionals, flags }\n}\n\n/** `[ref=e27, url=https://…]` markers in a snapshot's text tree → href per ref. */\nfunction snapshotHrefs(snapshot: string): Record<string, string> {\n const out: Record<string, string> = {}\n for (const m of snapshot.matchAll(/\\[([^\\]]*?\\bref=(e\\d+)[^\\]]*?)\\]/g)) {\n const url = /\\burl=([^,\\]\\s]+)/.exec(m[1])?.[1]\n if (url) out[m[2]] = url\n }\n return out\n}\n\n/** The walk, as steps the recorder can replay. Pure. */\nexport function convertAgentBrowser(\n records: AgentBrowserRecord[],\n opts: ConvertOptions = {},\n): ConvertResult {\n const steps: ActionStep[] = []\n const notes: string[] = []\n let url: string | undefined\n let viewport: ActionsFile['viewport']\n let refs: Refs = {}\n let lastTarget: string | null = null\n let ignored = 0\n let skipped = 0\n let fillNoted = false\n\n const skip = (n: number, reason: string): void => {\n skipped++\n notes.push(`line ${n}: skipped — ${reason}`)\n }\n const emit = (n: number, step: ActionStep): void => {\n steps.push({ ...step, id: `ab${n}` })\n }\n\n records.forEach((rec, i) => {\n const n = i + 1\n const argv = Array.isArray(rec.command)\n ? rec.command\n : splitCommand(rec.command)\n const [verb, ...args] = argv\n const payload = (rec.data ?? rec.result ?? null) as Record<\n string,\n unknown\n > | null\n if (!verb) {\n skip(n, 'an empty command')\n return\n }\n if (rec.success === false) {\n skip(\n n,\n `\\`${argv.join(' ')}\\` failed in the walk${rec.error ? ` (${rec.error})` : ''}`,\n )\n return\n }\n switch (verb) {\n case 'open': {\n const target = args.find((a) => !a.startsWith('-'))\n if (!target) {\n skip(n, 'open without a URL')\n return\n }\n if (!url) {\n url = target\n ignored++\n return\n }\n skip(\n n,\n `a second open (${target}) — actions.json records ONE page; reach it by clicking, or split the walk`,\n )\n return\n }\n case 'snapshot': {\n const map = (payload?.refs ?? {}) as Record<\n string,\n { role?: string; name?: string }\n >\n const hrefs =\n typeof payload?.snapshot === 'string'\n ? snapshotHrefs(payload.snapshot)\n : {}\n refs = {}\n for (const [id, r] of Object.entries(map))\n refs[id] = { ...r, href: hrefs[id] }\n ignored++\n return\n }\n case 'set': {\n if (args[0] === 'viewport') {\n const w = Number(args[1])\n const h = Number(args[2])\n if (Number.isFinite(w) && Number.isFinite(h)) {\n viewport = { width: w, height: h }\n if (args[3] && Number(args[3]) !== 1)\n notes.push(\n `line ${n}: viewport scale ${args[3]} ignored — the recorder captures at the viewport's CSS size`,\n )\n ignored++\n return\n }\n }\n skip(n, `\\`set ${args.join(' ')}\\` has no recording equivalent`)\n return\n }\n case 'click':\n case 'hover': {\n const target = args.find((a) => !a.startsWith('-'))\n if (!target) {\n skip(n, `${verb} without a target`)\n return\n }\n const r = resolveTarget(target, refs)\n if ('reason' in r) {\n skip(n, r.reason)\n return\n }\n lastTarget = r.selector\n emit(\n n,\n verb === 'click'\n ? { do: 'click', selector: r.selector }\n : { do: 'hover', selector: r.selector },\n )\n return\n }\n case 'fill':\n case 'type': {\n const [target, ...textParts] = args\n if (!target || textParts.length === 0) {\n skip(n, `${verb} needs a target and text`)\n return\n }\n const r = resolveTarget(target, refs)\n if ('reason' in r) {\n skip(n, r.reason)\n return\n }\n if (verb === 'fill' && !fillNoted) {\n fillNoted = true\n notes.push(\n `line ${n}: fill became type — the recorder types into the field as it is; an empty field reads the same, a prefilled one does not`,\n )\n }\n lastTarget = r.selector\n emit(n, { do: 'type', selector: r.selector, text: textParts.join(' ') })\n return\n }\n case 'keyboard': {\n const [mode, ...textParts] = args\n if ((mode === 'type' || mode === 'inserttext') && textParts.length) {\n if (!lastTarget) {\n skip(\n n,\n 'keyboard type before any click or fill — the recorder needs a field to type into',\n )\n return\n }\n emit(n, {\n do: 'type',\n selector: lastTarget,\n text: textParts.join(' '),\n })\n return\n }\n skip(n, `\\`keyboard ${args.join(' ')}\\` has no recording equivalent`)\n return\n }\n case 'press':\n case 'key': {\n const key = args.at(0)\n if (key === 'Enter' && lastTarget) {\n // `focus: false`: agent-browser's press goes to whatever is focused\n // and never clicks, so neither does this. A type step that clicks\n // rings a click effect in the middle of a field the walk had already\n // filled — a bloom on empty space beside the text.\n emit(n, {\n do: 'type',\n selector: lastTarget,\n text: '\\n',\n focus: false,\n })\n notes.push(\n `line ${n}: press Enter became a newline typed into the last field`,\n )\n return\n }\n skip(\n n,\n `press ${key ?? ''} — actions.json has no key verb; a shortcut's effect needs a click on the control that does it`,\n )\n return\n }\n case 'scroll': {\n const { positionals, flags } = takeFlags(args, new Set(['selector']))\n const dir = positionals.at(0) ?? 'down'\n const amountArg = positionals.at(1)\n const amount = amountArg !== undefined ? Number(amountArg) : 300\n if (!Number.isFinite(amount)) {\n skip(n, `scroll amount ${amountArg} is not a number`)\n return\n }\n if (dir === 'left' || dir === 'right') {\n skip(n, 'horizontal scroll has no recording equivalent')\n return\n }\n if (flags.selector)\n notes.push(\n `line ${n}: scroll --selector ${String(flags.selector)} became a page scroll`,\n )\n emit(n, { do: 'scroll', dy: dir === 'up' ? -amount : amount })\n return\n }\n case 'mouse': {\n const [mode, xs, ys] = args\n if (mode === 'move') {\n const x = Number(xs)\n const y = Number(ys)\n if (Number.isFinite(x) && Number.isFinite(y)) {\n emit(n, { do: 'move', x, y })\n return\n }\n }\n skip(\n n,\n `\\`mouse ${args.join(' ')}\\` — only mouse move maps; a click by coordinates needs a selector`,\n )\n return\n }\n case 'wait': {\n const first = args.at(0)\n if (\n first !== undefined &&\n !first.startsWith('-') &&\n /^\\d+$/.test(first)\n ) {\n emit(n, { do: 'wait', ms: Number(first) })\n return\n }\n emit(n, { do: 'wait', ms: 500 })\n notes.push(\n `line ${n}: \\`wait ${args.join(' ')}\\` became 500 ms — the recorder waits for the page itself`,\n )\n return\n }\n case 'find': {\n const { positionals, flags } = takeFlags(args, new Set(['name']))\n const kind = positionals.at(0)\n const query = positionals.at(1)\n const action = positionals.at(2) ?? 'click'\n const rest = positionals.slice(3)\n if (!kind || query === undefined) {\n skip(n, 'find needs a locator and a query')\n return\n }\n const r = findSelector(kind, query, {\n name: typeof flags.name === 'string' ? flags.name : undefined,\n exact: flags.exact === true,\n })\n if ('reason' in r) {\n skip(n, r.reason)\n return\n }\n switch (action) {\n case 'click':\n case 'check':\n lastTarget = r.selector\n emit(n, { do: 'click', selector: r.selector })\n return\n case 'hover':\n lastTarget = r.selector\n emit(n, { do: 'hover', selector: r.selector })\n return\n case 'fill':\n if (!rest.length) {\n skip(n, 'find … fill without text')\n return\n }\n lastTarget = r.selector\n emit(n, { do: 'type', selector: r.selector, text: rest.join(' ') })\n return\n case 'text':\n ignored++\n return\n default:\n skip(n, `find … ${action} has no recording equivalent`)\n return\n }\n }\n case 'drag':\n skip(\n n,\n 'drag needs the end point in px — `get box` the target and write a drag step by hand',\n )\n return\n case 'batch':\n skip(\n n,\n 'a batch line inside the log — keep the batch OUTPUT (its array) instead',\n )\n return\n default:\n if (READ_VERBS.has(verb)) {\n ignored++\n return\n }\n skip(n, `\\`${argv.join(' ')}\\` has no recording equivalent`)\n }\n })\n\n const actions: ActionsFile = {\n ...((opts.url ?? url) ? { url: opts.url ?? url } : {}),\n ...((opts.viewport ?? viewport)\n ? { viewport: opts.viewport ?? viewport }\n : {}),\n steps,\n }\n return { actions, notes, steps: steps.length, ignored, skipped }\n}\n\n/** `vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url u] [--viewport WxH] [--json]` */\nexport async function cmdActions(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, new Set(['json']))\n const [sub, input] = positionals\n if (sub !== 'from-agent-browser' || !input) {\n throw new UsageError(\n 'vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url <url>] [--viewport WxH] [--json]',\n )\n }\n const r = createReporter(flags.json === true)\n const out = resolve(strFlag(flags, 'out') ?? 'actions.json')\n const viewportFlag = strFlag(flags, 'viewport')\n let viewport: ConvertOptions['viewport']\n if (viewportFlag) {\n const m = /^(\\d+)x(\\d+)$/.exec(viewportFlag)\n if (!m) throw new UsageError('--viewport expects WxH, e.g. 1280x720')\n viewport = { width: Number(m[1]), height: Number(m[2]) }\n }\n const { readFile } = await import('node:fs/promises')\n const text = await readFile(resolve(input), 'utf8')\n const { records, problems } = parseAgentBrowserLog(text)\n for (const p of problems) r.log(` ${p}`)\n const result = convertAgentBrowser(records, {\n url: strFlag(flags, 'url'),\n viewport,\n })\n const errors = validateActions(result.actions)\n if (errors.length) {\n r.done(\n { ok: false, errors, ...summary(result) },\n `${input}: no actions file written\\n ${errors.join('\\n ')}\\n ${result.notes.join('\\n ')}`,\n )\n return EXIT_ERROR\n }\n await writeFile(out, `${JSON.stringify(result.actions, null, 2)}\\n`)\n r.done(\n { ok: true, out, url: result.actions.url ?? null, ...summary(result) },\n `Wrote ${out}: ${result.steps} step${result.steps === 1 ? '' : 's'} from ${records.length} record${records.length === 1 ? '' : 's'} (${result.ignored} read/session, ${result.skipped} skipped)` +\n (result.notes.length ? `\\n ${result.notes.join('\\n ')}` : '') +\n `\\nThen: vos record --actions ${out} --out take --strict`,\n )\n return EXIT_OK\n}\n\nfunction summary(result: ConvertResult): {\n steps: number\n ignored: number\n skipped: number\n notes: string[]\n} {\n return {\n steps: result.steps,\n ignored: result.ignored,\n skipped: result.skipped,\n notes: result.notes,\n }\n}\n"],"mappings":"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","names":["mkdir","readFile","rm","existsSync","join","resolve","totalDuration","migrateHostedDoc","ratedSegments","isObj","mkdir","readFile","rename","writeFile","existsSync","join","resolve","momentsFromDoc","planForDigest","ratedSegments","spanOutputExtent","existsSync","writeFile","join","resolve","readFile","rm","readFile","rm","mkdir","readFile","rename","writeFile","existsSync","join","DIGEST_CROP_MAX","DIGEST_FULL_MAX","DIGEST_VERSION","join","mkdir","existsSync","f","rename","writeFile","readFile","ratedSegments","spanOutputExtent","resolve","join","mkdir","rename","existsSync","readFile","momentsFromDoc","planForDigest","writeFile","mkdir","rename","rm","writeFile","join","resolve","ratedSegments","spanOutputExtent","writeFile","compileVosConfig","lowerToComposition","resolveExportSize","VIDEO_TOKEN","resolveExportSize","lowerToComposition","compileVosConfig","writeFile","compileVosConfig","compileVosConfig","ratedSegments","spanOutputExtent","resolve","join","mkdir","rename","rm","writeFile","existsSync","readFile","stat","join","DESTINATIONS","readFileSync","join","join","readFileSync","readFileSync","writeFileSync","join","writeFileSync","join","readFileSync","MEDIABUNNY_URL","existsSync","readFile","join","join","existsSync","readFile","existsSync","readFile","join","lowerToComposition","migrateHostedDoc","existsSync","writeFile","join","join","existsSync","writeFile","mkdir","writeFile","join","mkdir","join","writeFile","summary","existsSync","readFile","lowerToComposition","media","join","migrateHostedDoc","existsSync","readFileSync","statSync","mkdir","readFile","writeFile","createInterface","basename","dirname","join","migrateHostedDoc","sleep","BOOLEAN_FLAGS","join","existsSync","mkdir","writeFile","migrateHostedDoc","dirname","readFile","basename","title","created","watchUrl","studioUrl","createInterface","statSync","readFileSync","readFileSync","basename","extname","BOOLEAN_FLAGS","basename","extname","readFileSync","readFileSync","basename","BOOLEAN_FLAGS","basename","cmdPush","readFileSync","res","writeFile","resolve","resolve","writeFile","writeFile","resolve","relative","resolve","readFile","writeFile","BOOLEAN_FLAGS","MULTI_FLAGS","readFile","resolve","existsSync","join","mkdir","cmdCreate","rm","totalDuration","ratedSegments","migrateHostedDoc","problems","warnings","cmdPush","cmdPull"]}