@vosjs/cli 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/{chunk-I3UUIBSH.js → chunk-T35XY4YW.js} +154 -6
- package/dist/chunk-T35XY4YW.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-VSENMRFF.js → run-QAI3HGTK.js} +2 -2
- package/package.json +5 -5
- package/schema/doc.schema.json +54 -4
- package/dist/chunk-I3UUIBSH.js.map +0 -1
- /package/dist/{run-VSENMRFF.js.map → run-QAI3HGTK.js.map} +0 -0
|
@@ -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/moments.ts","../src/plugin/picture.ts","../src/plugin/motionPlan.ts","../src/plugin/posterDoc.ts","../src/plugin/platform.ts","../src/plugin/markAsset.ts","../src/plugin/officialTemplates.ts","../src/plugin/music.ts","../src/plugin/judge.ts","../src/plugin/shotBake.ts","../src/plugin/kitPicture.ts","../src/plugin/validateKit.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 {\n END_CARD_FROM,\n docOutputDuration,\n migrateHostedDoc,\n} 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 {\n deliverTake,\n readLaunchBesideTake,\n resolveChannels,\n resolveLook,\n} from './deliver'\nimport { fetchBrandMarks } from './markAsset'\nimport { endCardInk } from './motionPlan'\nimport type { MotionAnchor, MotionTemplate } from './motionPlan'\nimport { OFFICIAL_END_CARD_TITLE, findOfficialByRef } from './officialTemplates'\nimport type { OfficialRow } from './officialTemplates'\nimport { fetchMusicCatalog } from './music'\nimport { judgeKit, winRate } from './judge'\nimport { resolveStepTime } from './moments'\nimport { formatFinding } from './kitPicture'\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 'picture',\n 'fresh',\n 'reuse',\n 'strict',\n 'draft',\n 'at-zooms',\n 'at-moments',\n 'at-still',\n 'no-frames',\n 'media',\n 'print',\n 'yes',\n 'composed',\n 'check',\n 'motion',\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>] [--with <doc.json|vosId>[@end|@start|@step:<id>|@<s>]]... [--background <slug|url|none>] [--motion] [--headline \"…\"] [--kicker \"…\"] [--launch LAUNCH.md] [--brand BRAND.md] [--music <slug|mood|none>] [--entrance tilt-in|pull-out|rise|fade|slide|none] [--transitions slide|fade|scale|none] [--end-card on|none|<doc.json|vosId>] [--captions none] [--clicks none] [--still <t>] [--release v2.1] [--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] [--at-still] [--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) [--launch LAUNCH.md] [--look plate|gradient|dark|none] [--brand BRAND.md] [--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|kit.json> [--picture] [--json]\n vos judge <kit.json> --against <MANIFEST.json> [--out dir] [--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, read live from GET /api/limits (30 min when the origin is\nunreachable): 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 come from the\nSTORY: every step's end plus a 0.4 s settle (the response, not the\ntravel), then the zoom apexes, then an even spread; each candidate is\nread once as the real page, blank ones (a wallpaper, an empty canvas) are\ndropped and two of one frame collapse to one, with every drop said in\nskipped[]. --times overrides with seconds, percents or step:<id>[+offset]\n(the id from actions.json); --range cuts every video destination.\nThe LOOK presents the card: card-genre stills with no poster document\nand every video cut sit on a ground (a cream plate, the house gradient, a\ndark plate with a light streak) at ~84% of the width with headroom, a\nsoft ambient shadow plus a tight contact shadow, and a hairline when card\nand ground are both light; a wide frame runs the card off the bottom.\n--look picks a house look (or none for the pre-look crops); with no flag\nthe BRAND.md beside the take (or --brand <file>) decides from its look\nrole or its own ground, and with no brand the house gradient.\nScreenshot-genre stills never take a look.\nA POSTER is a document, never a template: a plain take whose card sits\nwhere the poster wants it (frame.inset), leans (the tilt track), carries\nthe words and the mark as clips (ids stage-title, stage-kicker,\nstage-brand, stage-mark) and ends on a trailing freeze whose start is the\nstill. Card-genre destinations (OG, LinkedIn, X, YouTube thumbnail, the\nCWS tile + marquee, GitHub social preview) render from the poster\ndocument of their aspect CLASS (landscape, square, portrait, tile), found\nbeside the take as poster/<class>/doc.json (poster/doc.json serves every\nclass) or named in LAUNCH.md (poster: <path>, poster-landscape: …), at\nthe document's rest; kit.json records source poster, the class, the file,\nthe vos it tracks, the shot rect and the text boxes read FROM the\ndocument. A class with no document is the take's own frame, said once.\ndeliver renders and verifies; it composes nothing. The composition is\nmade with plan --style <poster>, which copies a poster's layout onto a\ntake (its card placement, its stage clips with the release's words\npatched in from LAUNCH.md's headline and kicker roles or --headline and\n--kicker, its rest lean, its freeze), or by hand in doc.json.\nThe cut's MOTION is the document's too, in ONE vocabulary: every visual\nthing (the card, a text, image or video clip, a prop) carries anim.enter,\nanim.exit and anim.idle; the output lasts until the last clip ends, and\nthe card leaves with its clip (a freeze keeps it under what follows).\nThere is no end-card field and no entrance field: a\nCOMPONENT is a TEMPLATE, a plain take on a shelf whose clips carry stable\nids, laid onto the take at an anchor (LAUNCH.md with: <ref>[@end|@start|\n@step:<id>|@<s>], comma list; --with the same, repeatable; endCard: <ref>\nnames one at the end), its clips stamped with where they came from\n(from). plan proposes on a fresh plan (--motion re-proposes, replacing\nonly its own work): the card's ENTER (tilt-in by default), the templates\nnamed, the END CARD when endCard is on or absent (the official End card\ntemplate on vos.so, laid at the end with the release's words, the mark\nfrom BRAND.md logoUrl and a freeze of the last frame under it, from:\nendcard; offline, the house clips stand in), a CAPTION per\nactions.json step at the step's moment, a music BED from LAUNCH.md's music\nrole (a catalog slug or a mood) and a click sound on every press when the\ntake has no mic. LAUNCH.md's entrance, transitions, endCard, captions, music and clicks\nroles, or the flags, change or switch each off; a deleted proposal stays\ndeleted on a refresh. deliver applies each destination's MECHANICS and\nnothing more: the README loop drops the card's motion, every clip a\ntemplate placed and every sound; a channel that autoplays muted drops the\nbed; the 9:16 cut is a reframe, not a letterbox, and the crop follows\nthe camera. 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; --picture adds what each asset LOOKS\nlike, read from its pixels: blank (a wallpaper or an empty canvas where\nthe product should be), duplicate (two stills of one frame), subject (the\ncard off the 60 to 92% band, or a crop where a card was asked for),\nseparation (a light card on a light ground with no shadow), halfsize (a\ntile that loses its edges when the store shrinks it), and, where the kit\nrecords its text boxes, sliced, safe and contrast (APCA Lc 60/75); a\nvideo's first and last frames are read through ffmpeg. Every finding\ncarries a code, a severity, a fix hint and a box; an error fails the\nverdict beside the spec problems.\njudge puts the kit beside its REFERENCES: for every still that has a\nreference of its role in the manifest (a template family, a card genre),\ntwo sheets at a common height (the asset left, then right, so order\ncannot bias the call) and the rubric in words, plus judge.json, a slot\nper pair the judge fills (win true, false or null for a tie, with the\nrule numbers). No model runs inside the verb: the skill judges the\nsheets pairwise, both orders, and the verb reports the win rate beside\nthe spec and picture counts. The reference set is the maker's own\nfixture folder with a MANIFEST.json (id, file, role, layout, facts,\nrule per asset).\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, multi } = parseArgs(\n argv,\n BOOLEAN_FLAGS,\n new Set(['with']),\n )\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>] [--with <doc.json|vosId>[@end|@start|@step:<id>|@<seconds>]]... [--motion] [--headline \"…\"] [--launch LAUNCH.md] [--brand BRAND.md]',\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 hasDoc = existsSync(join(dir, 'doc.json'))\n const backdrop = hasDoc ? null : await takeBackdrop(flags, r)\n // The release's words and roles (LAUNCH.md and BRAND.md beside the take,\n // flags over them): the words patch a layout's stage clips and name the\n // end card; the roles decide the motion proposals; the brand's mark is\n // fetched into the take's brand/ folder for the layout and the end card.\n const release = await releaseInputs(dir, flags, r, multi.with ?? [])\n const motionWanted = !hasDoc || flags.motion === true || flags.fresh === true\n // The frame that stands for the take: --still, else LAUNCH.md's still:.\n const stillRaw = strFlag(flags, 'still') ?? release.launchRoles.still\n const still = stillRaw === undefined ? null : Number(stillRaw)\n if (still !== null && !(Number.isFinite(still) && still >= 0))\n throw new UsageError(\n `--still expects output seconds ≥ 0, got \"${stillRaw}\"`,\n )\n const s = await planTake(dir, {\n ...(style ? { style } : {}),\n ...(reuse ? { reuse } : {}),\n backdrop,\n words: release.words,\n mark: release.mark,\n ...(still !== null ? { still } : {}),\n ...(motionWanted\n ? {\n motion: {\n words: release.words,\n launch: release.launchRoles,\n ink: release.ink,\n mark: release.mark,\n captions: release.captions,\n catalog: release.catalog,\n templates: release.templates,\n again: flags.motion === true,\n },\n }\n : {}),\n })\n const layoutLines = s.layout\n ? `\\n layout from ${s.styleFrom}: ${[\n s.layout.clips.length ? `${s.layout.clips.length} stage clip(s)` : '',\n s.layout.lean ? 'the rest lean' : '',\n s.layout.freeze ? 'the freeze' : '',\n ]\n .filter(Boolean)\n .join(', ')}` +\n (s.layout.notes.length ? `\\n ${s.layout.notes.join('\\n ')}` : '')\n : ''\n const motionLines = s.motion\n ? (s.motion.notes.length\n ? `\\n proposed: ${s.motion.notes.join(', ')}`\n : '') +\n (s.motion.skipped.length\n ? `\\n not proposed: ${s.motion.skipped.join('; ')}`\n : '')\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.layout ? { layout: s.layout } : {}),\n ...(s.motion ? { motion: s.motion } : {}),\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)'}${layoutLines}${motionLines}${reuseLines}`,\n )\n return EXIT_OK\n}\n\n/**\n * The release's inputs beside a take, for `plan`: the words (LAUNCH.md's\n * headline and kicker roles, BRAND.md's wordmark; flags override), the\n * motion roles (LAUNCH.md's music, entrance, transitions, endCard, captions, clicks;\n * flags override), the end card's ink from the brand's look, the brand's\n * mark fetched into `<take>/brand/`, the step captions from actions.json,\n * and the music catalog when a bed is asked for (one network read, only\n * then).\n */\nasync function releaseInputs(\n dir: string,\n flags: ParsedArgs['flags'],\n r: ReturnType<typeof createReporter>,\n withRefs: string[] = [],\n): Promise<{\n words: {\n headline: string | null\n kicker: string | null\n brand: string | null\n release: string | null\n }\n launchRoles: Record<string, string>\n ink: string | null\n mark: { key: string; aspect: number } | null\n captions: { step: number; id?: string; caption: string }[]\n catalog: Awaited<ReturnType<typeof fetchMusicCatalog>> | null\n templates: MotionTemplate[]\n}> {\n let lookPick: Awaited<ReturnType<typeof resolveLook>>\n try {\n lookPick = await resolveLook(dir, {\n look: strFlag(flags, 'look'),\n brand: strFlag(flags, 'brand'),\n })\n } catch (e) {\n throw new UsageError(e instanceof Error ? e.message : String(e))\n }\n const launch = await readLaunchBesideTake(dir, strFlag(flags, 'launch'))\n // A literal \\n in a frontmatter value or a flag is a line break: a headline\n // is written over its lines on purpose.\n const lines = (v: string | null | undefined) =>\n v === null || v === undefined ? null : v.replace(/\\\\n/g, '\\n')\n const words = {\n headline: lines(strFlag(flags, 'headline') ?? launch?.roles.headline),\n kicker: lines(strFlag(flags, 'kicker') ?? launch?.roles.kicker),\n brand: strFlag(flags, 'brand-name') ?? lookPick.roles?.wordmark ?? null,\n release: strFlag(flags, 'release') ?? null,\n }\n if (launch) r.log(`words: ${launch.file}`)\n const launchRoles: Record<string, string> = { ...(launch?.roles ?? {}) }\n for (const [flag, role] of [\n ['music', 'music'],\n ['entrance', 'entrance'],\n ['transitions', 'transitions'],\n ['end-card', 'endCard'],\n ['captions', 'captions'],\n ['clicks', 'clicks'],\n ] as const) {\n const v = strFlag(flags, flag)\n if (v !== undefined) launchRoles[role] = v\n }\n // The brand's mark: BRAND.md's logoUrl on a light ground, its\n // logoOnDarkUrl on a dark one; a dark ground with no on-dark mark keeps\n // the wordmark in words rather than an invisible ink mark.\n const marks = await fetchBrandMarks(dir, lookPick.roles)\n for (const n of marks.notes) r.log(`note: ${n}`)\n const mark = lookPick.look?.kind === 'dark' ? marks.dark : marks.light\n if (mark) r.log(`brand mark: ${mark.key} (${mark.aspect.toFixed(2)}:1)`)\n const off = (v: string | undefined) =>\n v !== undefined && /^(none|off|no|false)$/i.test(v)\n let catalog: Awaited<ReturnType<typeof fetchMusicCatalog>> | null = null\n if (launchRoles.music && !off(launchRoles.music)) {\n try {\n catalog = await fetchMusicCatalog(\n platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }),\n )\n } catch (e) {\n r.log(\n `music catalog: ${e instanceof Error ? e.message : String(e)} — no bed`,\n )\n }\n }\n const take = await loadTake(dir)\n const captions = (take.actions?.steps ?? []).flatMap((st, i) => {\n const step = st as { id?: string; caption?: string }\n return typeof step.caption === 'string' && step.caption.trim()\n ? [{ step: i, id: step.id, caption: step.caption.trim() }]\n : []\n })\n // The templates: `--with <ref>[@anchor]` (repeatable), LAUNCH.md's\n // `with:` role (a comma list of the same), and an `endCard:` role that\n // names a document instead of on/none (anchored at the end). A ref is a\n // doc.json, a take dir, or a vos id read with the key ladder.\n const refs: { ref: string; at: MotionAnchor }[] = []\n const parseRef = (raw: string, fallback: MotionAnchor) => {\n const m = /^(.*?)(?:@(end|start|step:[^@\\s]+|\\d+(?:\\.\\d+)?))?$/.exec(\n raw.trim(),\n )\n const ref = m?.[1]?.trim() ?? raw.trim()\n const anchor = m?.[2]\n const at: MotionAnchor = !anchor\n ? fallback\n : anchor === 'end' || anchor === 'start'\n ? anchor\n : anchor.startsWith('step:')\n ? { step: anchor.slice(5) }\n : Number(anchor)\n if (ref) refs.push({ ref, at })\n }\n for (const raw of withRefs) parseRef(raw, 'end')\n for (const raw of (launchRoles.with ?? '').split(','))\n if (raw.trim()) parseRef(raw, 'end')\n const endCardRole = launchRoles.endCard\n if (\n endCardRole &&\n !/^(none|off|no|false|on|yes|true)$/i.test(endCardRole.trim())\n )\n parseRef(endCardRole, 'end')\n const templates: MotionTemplate[] = []\n for (const { ref, at } of refs) {\n const found = await resolveDocRef(ref, flags, '--with')\n templates.push({ from: found.from, doc: found.doc, at })\n r.log(`template: ${found.from}`)\n }\n // The end card the recipe leaves on (or unsaid) is the OFFICIAL one on\n // vos.so, laid at the end and stamped `from: endcard` so a loop drops it\n // and a re-plan replaces it; offline, `plan` falls back to the house\n // clips. A recipe that names its own end card took the branch above.\n if (!endCardRole || /^(on|yes|true)$/i.test(endCardRole.trim())) {\n const origin = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n })\n const official = await officialTemplate(origin, OFFICIAL_END_CARD_TITLE)\n if (official) {\n try {\n const found = await resolveDocRef(official.id, flags, 'endCard')\n templates.push({ from: END_CARD_FROM, doc: found.doc, at: 'end' })\n r.log(`template: ${found.from} (the official end card)`)\n } catch {\n r.log(\n 'end card: the official template is unreadable here; the house clips stand in',\n )\n }\n }\n }\n return {\n words,\n launchRoles,\n ink: endCardInk(lookPick.look, lookPick.roles),\n mark,\n captions,\n catalog,\n templates,\n }\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: the output's end (trims, speed and the clips\n // after the footage applied).\n const duration = docOutputDuration(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 const atStill = flags['at-still'] === 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 atStill,\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 = docOutputDuration(take.doc)\n const timesRaw = strFlag(flags, 'times')\n let times: number[] | undefined\n if (timesRaw !== undefined) {\n // Entries are seconds, percents, or `step:<id>[+offset]` against the\n // take's step timeline (the still is the step's response, settled).\n try {\n const doc = take.doc\n times = timesRaw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((s) => resolveStepTime(doc, s) ?? parseTimes(s, duration)[0])\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 let lookPick: Awaited<ReturnType<typeof resolveLook>>\n try {\n lookPick = await resolveLook(dir, {\n look: strFlag(flags, 'look'),\n brand: strFlag(flags, 'brand'),\n })\n } catch (e) {\n throw new UsageError(e instanceof Error ? e.message : String(e))\n }\n r.log(`look: ${lookPick.from}`)\n // LAUNCH.md beside the take: its poster roles name the documents the\n // card destinations render from. The words and the motion are the\n // document's own since `vos plan` wrote them.\n const launch = await readLaunchBesideTake(dir, strFlag(flags, 'launch'))\n if (launch) r.log(`launch: ${launch.file}`)\n\n const browser = await launchBrowser()\n try {\n const result = await deliverTake(browser, dir, {\n look: lookPick.look,\n launchRoles: launch?.roles ?? null,\n channels,\n outDir: strFlag(flags, 'out'),\n release: strFlag(flags, 'release'),\n times,\n range,\n parallel,\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.poster ? `, poster ${a.poster.class}` : ''})`,\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 return resolveDocRef(styleRef, flags, '--style')\n}\n\n/**\n * A document reference: a doc.json or a take dir on disk, else a hosted\n * take's head doc read with the key ladder. What a template, a style seed\n * and a digest's reference all are. A local file is read into the current\n * vocabulary too.\n */\nasync function resolveDocRef(\n ref: string,\n flags: ParsedArgs['flags'],\n what: string,\n): Promise<{ from: string; doc: ProjectDoc }> {\n const styleRef = ref\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: migrateHostedDoc(\n JSON.parse(await readFile(file, 'utf8')) as Record<string, unknown>,\n ) as unknown 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 // Not an id or a slug: a TITLE on the official shelf (\"End card\",\n // \"Split cover, landscape\"), the platform's registry of templates.\n const official = await officialTemplate(origin, styleRef)\n if (official && official.id !== styleRef)\n return resolveDocRef(official.id, flags, what)\n throw new UsageError(\n `${what}: ${styleRef} is neither a doc.json, a vos I can read, nor an official template's title`,\n )\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(`${what}: ${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\n/** The official vos a ref names by title or slug, or null (offline = null). */\nasync function officialTemplate(\n origin: string,\n ref: string,\n): Promise<OfficialRow | null> {\n try {\n const list = await apiJson(origin, '/api/vos/official', {})\n if (list.status !== 200) return null\n const rows = (list.body as { voses?: OfficialRow[] }).voses ?? []\n return findOfficialByRef(rows, ref)\n } catch {\n return null\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 cmdJudge(argv: string[]): Promise<number> {\n const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS)\n const target = positionals[0]\n const against = strFlag(flags, 'against')\n if (!target || !against)\n throw new UsageError(\n 'vos judge <kit.json> --against <MANIFEST.json> [--out dir] [--json]\\n(the manifest names the reference set: id, file, role, layout, facts, rule per asset)',\n )\n const r = createReporter(flags.json === true)\n const kitFile = target.endsWith('kit.json')\n ? target\n : join(target, 'kit.json')\n if (!existsSync(kitFile)) throw new UsageError(`${kitFile}: no kit manifest`)\n if (!existsSync(against))\n throw new UsageError(`${against}: no reference manifest`)\n const result = await judgeKit(kitFile, against, strFlag(flags, 'out'))\n const verdicts = (\n JSON.parse(await readFile(result.verdictFile, 'utf8')) as {\n verdicts: { win: boolean | null; reasons?: number[] }[]\n }\n ).verdicts\n const rate = winRate(verdicts)\n const lines = result.sheets.map(\n (s) =>\n `${s.asset} vs ${s.reference}: ${s.sheetA}, ${s.sheetB}, ${s.rubric}`,\n )\n r.done(\n { ...result, winRate: rate },\n `Wrote ${result.sheets.length} sheet pair(s) to ${result.outDir}` +\n (lines.length ? `\\n ${lines.join('\\n ')}` : '') +\n (result.skipped.length\n ? `\\n skipped: ${result.skipped.join('\\n skipped: ')}`\n : '') +\n `\\nJudge each pair both ways (the rubric is beside it) and fill ${result.verdictFile}` +\n (rate.judged\n ? `\\nWin rate so far: ${rate.wins} win(s), ${rate.ties} tie(s) of ${rate.judged} judged (${(rate.rate! * 100).toFixed(0)}%; a tie counts a half); parity with the references is 50%, the marketability bar is 40%`\n : ''),\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 picture = flags.picture === true\n const verdict = await validateKit(kitTarget, { picture })\n const pictureLines = (verdict.picture ?? []).map(formatFinding)\n const pictureErrors = (verdict.picture ?? []).filter(\n (f) => f.severity === 'error',\n ).length\n const tail =\n (verdict.warnings.length\n ? `\\n warnings:\\n ${verdict.warnings.join('\\n ')}`\n : '') +\n (picture\n ? `\\n picture: ${pictureErrors} problem(s), ${(verdict.picture ?? []).length - pictureErrors} note(s)` +\n (pictureLines.length ? `\\n ${pictureLines.join('\\n ')}` : '')\n : '')\n if (!verdict.valid) {\n r.done(\n { ...verdict, target: kitTarget },\n `${kitTarget}:${verdict.problems.length ? `\\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 // The links name the origin the push went to, so a local dev push does\n // not point at the public site.\n const pushedTo = platformOrigin({\n origin: strFlag(flags, 'origin'),\n api: strFlag(flags, 'api'),\n }).replace(/\\/+$/, '')\n r.done(\n { ...result },\n `pushed v${result.versionNumber} → vos ${result.vosId}\\n review: ${pushedTo}/vos/${result.vosId}\\n studio: ${pushedTo}/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 since: strFlag(flags, 'since'),\n check: flags.check === true,\n },\n r,\n )\n if (result.checked) {\n r.done(\n { ...result },\n result.behind === null\n ? `${result.vosId}: head is ${result.versionId.slice(0, 8)}… — no base to count from; run without --check to sync`\n : result.behind === 0\n ? `${result.vosId}: up to date`\n : `${result.behind} version${result.behind === 1 ? '' : 's'} behind — run without --check to sync`,\n )\n return EXIT_OK\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 'judge':\n return await cmdJudge(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 CARD_ENTER_KINDS,\n SEGMENT_ENTER_KINDS,\n SEGMENT_EXIT_KINDS,\n enterOf,\n exitOf,\n segmentOutputExtents,\n transitionSeconds,\n CARD_EXIT_KINDS,\n EXPORT_RESOLUTION_OPTIONS,\n FREEZE_SECONDS_MAX,\n FREEZE_SECONDS_MIN,\n IDLE_KINDS,\n MEDIA_ENTER_KINDS,\n MEDIA_EXIT_KINDS,\n MEDIA_FRAME_KEYS,\n SPEED_RATE_MAX,\n SPEED_RATE_MIN,\n TEXT_ENTER_KINDS,\n TEXT_EXIT_KINDS,\n TILT_DEG_MAX,\n TILT_SPAN_MIN,\n ZOOM_LEVEL_MAX,\n ZOOM_LEVEL_MIN,\n ZOOM_SPAN_MIN,\n docCardLayout,\n outputEnd,\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\nconst STEP_KINDS_ALL = [\n 'none',\n 'fade',\n 'rise',\n 'pop',\n 'blur',\n 'typewriter',\n 'tilt-in',\n 'pull-out',\n 'recede',\n 'slide',\n 'scale',\n]\nconst STEP_SIDES = ['left', 'right', 'up', 'down']\nconst STEP_UNITS = ['block', 'line', 'word', 'char']\nconst STEP_DIRS = ['forward', 'reverse', 'center']\n\n/**\n * The one vocabulary, checked per primitive: which kinds a thing accepts\n * is its own (the card cannot typewrite, a word cannot tilt in), the\n * per-unit grammar belongs to words, and idle belongs to props.\n */\nfunction lintAnim(\n name: string,\n anim: unknown,\n kinds: {\n enter: readonly string[]\n exit: readonly string[]\n idle: readonly string[] | null\n words: boolean\n },\n problems: string[],\n): void {\n if (anim === undefined) return\n if (typeof anim !== 'object' || anim === null || Array.isArray(anim)) {\n problems.push(`${name}.anim must be { enter?, exit?, idle? }`)\n return\n }\n const a = anim as Record<string, unknown>\n for (const side of ['enter', 'exit'] as const) {\n const step = a[side]\n if (step === undefined) continue\n const allowed = kinds[side]\n const spelled = typeof step === 'string' ? step : null\n const obj =\n typeof step === 'object' && step !== null && !Array.isArray(step)\n ? (step as Record<string, unknown>)\n : null\n const kind = spelled ?? (obj ? obj.kind : undefined)\n if (typeof kind !== 'string' || !STEP_KINDS_ALL.includes(kind)) {\n problems.push(\n `${name}.anim.${side} must be a kind or { kind, seconds?${kinds.words ? ', unit?, direction?, stagger?' : ''} } (got ${JSON.stringify(step)})`,\n )\n continue\n }\n if (!allowed.includes(kind)) {\n problems.push(\n `${name}.anim.${side} cannot be \"${kind}\" here; one of ${allowed.join(' | ')}`,\n )\n }\n if (!obj) continue\n const secs = obj.seconds\n if (\n secs !== undefined &&\n (typeof secs !== 'number' ||\n !Number.isFinite(secs) ||\n secs < 0.05 ||\n secs > 3)\n ) {\n problems.push(`${name}.anim.${side}.seconds must be 0.05..3`)\n }\n for (const key of ['unit', 'direction', 'stagger'] as const) {\n if (obj[key] === undefined) continue\n if (!kinds.words) {\n problems.push(`${name}.anim.${side}.${key} is for words only`)\n continue\n }\n if (\n key === 'unit' &&\n (typeof obj.unit !== 'string' || !STEP_UNITS.includes(obj.unit))\n )\n problems.push(\n `${name}.anim.${side}.unit must be ${STEP_UNITS.join('|')}`,\n )\n if (\n key === 'direction' &&\n (typeof obj.direction !== 'string' ||\n !STEP_DIRS.includes(obj.direction))\n )\n problems.push(\n `${name}.anim.${side}.direction must be ${STEP_DIRS.join('|')}`,\n )\n if (\n key === 'stagger' &&\n (typeof obj.stagger !== 'number' || obj.stagger < 0 || obj.stagger > 2)\n )\n problems.push(`${name}.anim.${side}.stagger must be seconds in 0..2`)\n }\n if (obj.side !== undefined) {\n if (kind !== 'slide')\n problems.push(`${name}.anim.${side}.side is for a slide`)\n else if (typeof obj.side !== 'string' || !STEP_SIDES.includes(obj.side))\n problems.push(\n `${name}.anim.${side}.side must be ${STEP_SIDES.join(' | ')}`,\n )\n }\n }\n if (a.idle !== undefined && a.idle !== null) {\n if (!kinds.idle) problems.push(`${name}.anim.idle is for props only`)\n else if (typeof a.idle !== 'string' || !kinds.idle.includes(a.idle))\n problems.push(\n `${name}.anim.idle must be ${kinds.idle.join(' | ')} | null`,\n )\n }\n}\n\nfunction lintFrom(name: string, from: unknown, problems: string[]): void {\n if (from !== undefined && (typeof from !== 'string' || !from.length))\n problems.push(`${name}.from must be the id of the template that placed it`)\n}\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 // The take's other media (concat): a span that names one is measured\n // against THAT media's length, never the primary's.\n const mediaLen = new Map<string, number>()\n if (recording && doc.media !== undefined) {\n if (!Array.isArray(doc.media)) problems.push('media must be an array')\n for (const [i, raw] of (Array.isArray(doc.media)\n ? (doc.media as unknown[])\n : []\n ).entries()) {\n const m = isObj(raw) ? raw : {}\n const id = typeof m.id === 'string' ? m.id : ''\n if (!id) problems.push(`media[${i}]: id must be a string`)\n else if (mediaLen.has(id))\n problems.push(`media[${i}] (${id}): duplicate id`)\n // A media's own card: card-owned fields only (the frame-wide ones,\n // the aspect, the padding, the ground, the backdrop, the card's\n // animation, are the take's and read wrong on a media).\n const mf = (m as { frame?: unknown }).frame\n if (mf !== undefined) {\n if (!isObj(mf)) {\n problems.push(\n `media[${i}]${id ? ` (${id})` : ''}: frame must be an object`,\n )\n } else {\n for (const k of Object.keys(mf)) {\n if (!(MEDIA_FRAME_KEYS as readonly string[]).includes(k))\n problems.push(\n `media[${i}]${id ? ` (${id})` : ''}.frame.${k}: not a card field (a media's frame carries ${MEDIA_FRAME_KEYS.join(', ')}; the rest is the take's frame)`,\n )\n }\n }\n }\n if (typeof m.videoKey !== 'string')\n problems.push(\n `media[${i}]${id ? ` (${id})` : ''}: videoKey must be a string`,\n )\n const mm = isObj(m.meta) ? m.meta : {}\n const ms = isNum(mm.durationMs) ? mm.durationMs : 0\n if (id) mediaLen.set(id, ms / 1000)\n }\n }\n /** Check a span list media by media: each against its own footage. */\n const checkByMedia = (list: Json[], label: string): void => {\n const groups = new Map<string, Json[]>()\n for (const s of list) {\n const m = typeof s.media === 'string' ? s.media : ''\n if (m && !mediaLen.has(m)) {\n problems.push(\n `${spanName(label, s)}: media \"${m}\" is not one of media[].id`,\n )\n continue\n }\n groups.set(m, [...(groups.get(m) ?? []), s])\n }\n for (const [m, group] of groups)\n checkSpanList(\n group,\n label,\n m ? (mediaLen.get(m) ?? 0) : duration,\n problems,\n )\n }\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 checkByMedia(zoom, 'zoom')\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 // --- the still: the frame that stands for the take, output seconds ---\n if (recording && doc.still !== undefined) {\n const st = doc.still\n if (!isNum(st) || st < 0) {\n problems.push('still must be a number ≥ 0 (OUTPUT seconds)')\n } else {\n const rated = ratedSegments(doc as unknown as ProjectDoc)\n const end = outputEnd(\n doc as unknown as ProjectDoc,\n rated.reduce((a, s) => a + (s.out - s.in) / (s.rate ?? 1), 0),\n )\n if (st > end + 1e-6)\n problems.push(\n `still=${String(st)} is past the output's end (${end.toFixed(2)}s)`,\n )\n }\n }\n // --- freezes and the end card: a freeze is output seconds, never long ---\n for (const [i, seg] of (Array.isArray(doc.segments)\n ? (doc.segments as unknown[])\n : []\n ).entries()) {\n const hold = (seg as { hold?: unknown }).hold\n if (hold === undefined) continue\n if (!isNum(hold) || hold < 0 || hold > FREEZE_SECONDS_MAX) {\n problems.push(\n `segments[${i}].hold must be 0..${FREEZE_SECONDS_MAX} output seconds (got ${String(hold)})`,\n )\n } else if (hold > 0) {\n warnings.push(\n `segments[${i}].hold is a legacy spelling, read as a freeze at ${String((seg as { out?: unknown }).out)}s (doc.freeze); vos plan writes that shape`,\n )\n }\n }\n if (doc.freeze !== undefined && !Array.isArray(doc.freeze)) {\n problems.push('freeze must be an array of {id, at, seconds}')\n }\n const freezes = Array.isArray(doc.freeze) ? (doc.freeze as unknown[]) : []\n const freezeIds = new Set<string>()\n for (const [i, raw] of freezes.entries()) {\n const f = raw as { id?: unknown; at?: unknown; seconds?: unknown }\n const name = `freeze[${i}]${typeof f.id === 'string' ? ` (${f.id})` : ''}`\n if (typeof f.id !== 'string' || !f.id)\n problems.push(`${name}: id must be a string`)\n else if (freezeIds.has(f.id)) problems.push(`${name}: duplicate id`)\n else freezeIds.add(f.id)\n const fm =\n typeof (f as { media?: unknown }).media === 'string'\n ? ((f as { media?: string }).media as string)\n : ''\n const fLen = fm ? mediaLen.get(fm) : duration\n if (fm && fLen === undefined) {\n problems.push(`${name}: media \"${fm}\" is not one of media[].id`)\n } else if (!isNum(f.at) || f.at < 0 || f.at > (fLen ?? duration) + EPS) {\n problems.push(\n `${name}: at must be a SOURCE moment inside the recording (0..${(fLen ?? duration).toFixed(2)}s, got ${String(f.at)})`,\n )\n }\n if (\n !isNum(f.seconds) ||\n f.seconds < FREEZE_SECONDS_MIN - EPS ||\n f.seconds > FREEZE_SECONDS_MAX + EPS\n ) {\n problems.push(\n `${name}: seconds must be ${FREEZE_SECONDS_MIN}..${FREEZE_SECONDS_MAX} output seconds (got ${String(f.seconds)})`,\n )\n }\n }\n const endCard = (doc as { endCard?: unknown }).endCard\n if (endCard !== undefined) {\n warnings.push(\n 'endCard is a legacy spelling, read as clips after the footage plus a card exit (frame.anim.exit); vos plan writes that shape',\n )\n if (typeof endCard !== 'object' || endCard === null) {\n problems.push(\n 'endCard must be an object: {seconds?, headline?, sub?, wordmark?}',\n )\n } else {\n const ec = endCard as {\n seconds?: unknown\n headline?: unknown\n sub?: unknown\n wordmark?: unknown\n }\n if (\n ec.seconds !== undefined &&\n (!isNum(ec.seconds) || ec.seconds < 1 || ec.seconds > 8)\n ) {\n problems.push(\n `endCard.seconds must be 1..8 (got ${String(ec.seconds)}); absent = 2.5`,\n )\n }\n for (const k of ['headline', 'sub', 'wordmark'] as const) {\n if (ec[k] !== undefined && typeof ec[k] !== 'string') {\n problems.push(`endCard.${k} must be a string`)\n }\n }\n if (\n !['headline', 'sub', 'wordmark'].some(\n (k) =>\n typeof ec[k as keyof typeof ec] === 'string' &&\n (ec[k as keyof typeof ec] as string).trim(),\n )\n ) {\n warnings.push(\n 'endCard carries no words: it holds the last frame and recedes the card over nothing',\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 checkByMedia(entries(doc.segments), 'segment')\n // A clip's transitions: the vocabulary a footage clip accepts, never\n // longer than half the shorter clip at its boundary (the clip must be\n // seen still before it moves), and the outer edges are the card's.\n const segs = Array.isArray(doc.segments)\n ? (doc.segments as Record<string, unknown>[]).filter(isObj)\n : []\n segs.forEach((seg, i) => {\n lintAnim(\n `segments[${i}]`,\n seg.anim,\n {\n enter: SEGMENT_ENTER_KINDS,\n exit: SEGMENT_EXIT_KINDS,\n idle: null,\n words: false,\n },\n problems,\n )\n })\n if (segs.length && segs.every((s) => isNum(s.in) && isNum(s.out))) {\n const anims = segs.map(\n (s) => s.anim as ProjectDoc['segments'][number]['anim'],\n )\n if (enterOf(anims[0]) && enterOf(anims[0])!.kind !== 'none')\n warnings.push(\n 'segments[0].anim.enter is ignored: the first clip arrives with the card (frame.anim.enter)',\n )\n const last = segs.length - 1\n if (\n last > 0 &&\n exitOf(anims[last]) &&\n exitOf(anims[last])!.kind !== 'none'\n )\n warnings.push(\n `segments[${last}].anim.exit is ignored: the last clip leaves with the card (frame.anim.exit)`,\n )\n let extents: { start: number; end: number }[] = []\n try {\n extents = segmentOutputExtents(doc as unknown as ProjectDoc)\n } catch {\n extents = []\n }\n for (\n let i = 0;\n i + 1 < segs.length && extents.length === segs.length;\n i++\n ) {\n const cap =\n Math.min(\n extents[i].end - extents[i].start,\n extents[i + 1].end - extents[i + 1].start,\n ) / 2\n const exitS = transitionSeconds(exitOf(anims[i]))\n const enterS = transitionSeconds(enterOf(anims[i + 1]))\n if (exitS > cap + EPS)\n problems.push(\n `segments[${i}].anim.exit: ${exitS}s is longer than half the shorter clip at that boundary (${cap.toFixed(2)}s); the clip must be seen still before it moves`,\n )\n if (enterS > cap + EPS)\n problems.push(\n `segments[${i + 1}].anim.enter: ${enterS}s is longer than half the shorter clip at that boundary (${cap.toFixed(2)}s); the clip must be seen still before it moves`,\n )\n }\n }\n }\n\n // --- speed spans ---\n const speed = entries(doc.speed)\n checkByMedia(speed, 'speed')\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 checkByMedia(tilt, 'tilt')\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 checkByMedia(camMotion, 'camMotion')\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 // --- the second shadow layer and its colour ---\n const sc = frame.shadowContact\n if (sc !== undefined && (!isNum(sc) || sc < 0 || sc > 1)) {\n problems.push(\n `frame.shadowContact must be 0..1 (got ${String(sc)}); absent = no contact layer`,\n )\n }\n const shc = frame.shadowColor\n if (shc !== undefined && !/^#[0-9a-fA-F]{6}$/.test(String(shc))) {\n problems.push(\n `frame.shadowColor must be a #rrggbb hex (got ${String(shc)}); absent = black`,\n )\n }\n // --- the entrance and the crop that follows the camera ---\n const ent = frame.entrance\n if (ent !== undefined) {\n warnings.push(\n 'frame.entrance is a legacy spelling; write frame.anim.enter',\n )\n const kinds = ['tilt-in', 'pull-out', 'rise', 'none']\n if (\n typeof ent !== 'object' ||\n ent === null ||\n !kinds.includes(String((ent as { kind?: unknown }).kind))\n ) {\n problems.push(\n `frame.entrance.kind must be one of ${kinds.join(' | ')} (got ${JSON.stringify(ent)})`,\n )\n } else {\n const secs = (ent as { seconds?: unknown }).seconds\n if (secs !== undefined && (!isNum(secs) || secs < 0.2 || secs > 3)) {\n problems.push(\n `frame.entrance.seconds must be 0.2..3 (got ${String(secs)}); absent = 1.2`,\n )\n }\n }\n }\n lintAnim(\n 'frame',\n frame.anim,\n {\n enter: CARD_ENTER_KINDS,\n exit: CARD_EXIT_KINDS,\n idle: null,\n words: false,\n },\n problems,\n )\n if (frame.focusFollow !== undefined && frame.focusFollow !== 'camera') {\n problems.push(\n `frame.focusFollow must be \"camera\" (got ${String(frame.focusFollow)}); it reads under fit: cover only`,\n )\n }\n // --- per-side placement: fractions, a negative side bleeds ---\n const ins = frame.inset\n if (ins !== undefined) {\n if (typeof ins !== 'object' || ins === null || Array.isArray(ins)) {\n problems.push(\n 'frame.inset must be an object of {top, right, bottom, left} fractions',\n )\n } else {\n const sides = ins as Record<string, unknown>\n for (const side of ['top', 'right', 'bottom', 'left']) {\n const v = sides[side]\n if (v !== undefined && (!isNum(v) || v < -2 || v > 0.9)) {\n problems.push(\n `frame.inset.${side} must be a fraction of the frame in -2..0.9 (got ${String(v)}); negative bleeds the card past the edge`,\n )\n }\n }\n const l = isNum(sides.left) ? sides.left : 0\n const r = isNum(sides.right) ? sides.right : 0\n const t = isNum(sides.top) ? sides.top : 0\n const b = isNum(sides.bottom) ? sides.bottom : 0\n if (l + r >= 1 || t + b >= 1) {\n problems.push(\n `frame.inset leaves no room for the card (left+right ${l + r}, top+bottom ${t + b}; each pair must stay under 1)`,\n )\n }\n }\n }\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 && ins === undefined) {\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 // A layer that shows a document media: the reference must name one\n // (`media:` alone is the primary), and its card carries card fields.\n if (typeof o.key === 'string' && o.key.startsWith('media:')) {\n const ref = o.key.slice('media:'.length)\n const ids = new Set(\n (Array.isArray((doc as { media?: unknown }).media)\n ? ((doc as { media: unknown[] }).media as { id?: unknown }[])\n : []\n ).map((m) => (typeof m.id === 'string' ? m.id : '')),\n )\n if (ref !== '' && !ids.has(ref))\n problems.push(\n `${name}.key names media \"${ref}\", which is not one of media[].id (media: alone is the primary)`,\n )\n }\n const lcf = (o as { frame?: unknown }).frame\n if (lcf !== undefined) {\n if (!isObj(lcf)) {\n problems.push(`${name}.frame must be an object (the layer's card)`)\n } else {\n const LCF = [\n 'browserBar',\n 'lean',\n 'shadow',\n 'shadowContact',\n 'shadowColor',\n 'cursor',\n ]\n for (const k of Object.keys(lcf))\n if (!LCF.includes(k))\n problems.push(\n `${name}.frame.${k}: not a layer card field (${LCF.join(', ')})`,\n )\n const lean = (lcf as { lean?: unknown }).lean\n if (\n lean !== undefined &&\n (!isObj(lean) ||\n !isNum((lean as { rx?: unknown }).rx) ||\n !isNum((lean as { ry?: unknown }).ry))\n )\n problems.push(`${name}.frame.lean must be { rx, ry } in degrees`)\n }\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 if (o.enter !== undefined || o.exit !== undefined || o.fx !== undefined)\n warnings.push(\n `${name}: enter, exit and fx are legacy spellings; write anim.enter / anim.exit`,\n )\n lintAnim(\n name,\n o.anim,\n o.kind === 'text'\n ? {\n enter: TEXT_ENTER_KINDS,\n exit: TEXT_EXIT_KINDS,\n idle: null,\n words: true,\n }\n : {\n enter: MEDIA_ENTER_KINDS,\n exit: MEDIA_EXIT_KINDS,\n idle: null,\n words: false,\n },\n problems,\n )\n lintFrom(name, o.from, problems)\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 if (o.animation !== undefined)\n warnings.push(`${name}.animation is a legacy spelling; write anim.idle`)\n lintAnim(\n name,\n o.anim,\n {\n enter: MEDIA_ENTER_KINDS,\n exit: MEDIA_EXIT_KINDS,\n idle: IDLE_KINDS,\n words: false,\n },\n problems,\n )\n lintFrom(name, o.from, problems)\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 docStillTime,\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\n/**\n * The supersample factor a still renders at: small destinations (a 440\n * px store tile, a 240 px thumbnail) render at two or three times their\n * pixels and downscale once with the browser's high-quality resampler,\n * so footage recorded at 1920 px is not one bilinear tap away from a\n * 270 px card. A still already past 1800 px on its long side renders 1:1.\n */\nexport function stillSupersample(w: number, h: number): number {\n return Math.min(3, Math.max(1, Math.ceil(1800 / Math.max(1, w, h))))\n}\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 /** Also sample the frame that stands for the take (docStillTime). */\n atStill?: 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 * Render THIS document over the take's footage instead of its doc.json\n * (a poster document beside the take). Cloned before any override.\n */\n doc?: ProjectDoc\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' | 'still'\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 /** Render at W*ss × H*ss, downscale to W × H for the PNG. */\n ss: number\n shots: { time: number; name: string }[]\n}) {\n const w = window as unknown as Record<string, any>\n const RW = opts.W * opts.ss\n const RH = opts.H * opts.ss\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: RW,\n height: RH,\n pixelRatio: 1,\n drawingBufferWidth: RW,\n drawingBufferHeight: RH,\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 = RW\n canvas.height = RH\n canvas.style.width = RW + 'px'\n canvas.style.height = RH + 'px'\n // The downscale target, when supersampled.\n const out = document.createElement('canvas')\n out.width = opts.W\n out.height = opts.H\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 let src = canvas\n if (opts.ss > 1) {\n const g = out.getContext('2d')!\n g.imageSmoothingEnabled = true\n g.imageSmoothingQuality = 'high'\n g.clearRect(0, 0, opts.W, opts.H)\n g.drawImage(canvas, 0, 0, opts.W, opts.H)\n src = out\n }\n src.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 const doc = opts.doc ? structuredClone(opts.doc) : take.doc\n if (!doc) throw new Error(`${dir} has no doc.json — run plan first`)\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' | 'still'\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, doc)) {\n if (m.outputAt === null) continue\n shots.push({ time: clamp(m.outputAt), kind: 'moment', momentId: m.id })\n }\n }\n if (opts.atStill)\n shots.push({ time: clamp(docStillTime(doc)), kind: 'still' })\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, --at-moments or --at-still',\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 ss = stillSupersample(width, height)\n const context = await browser.newContext({\n viewport: { width: width * ss, height: height * ss },\n })\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 ss,\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 // A brand mark or an image overlay: an <img> refuses an SVG served as an\n // octet stream, so the kinds a doc can key are named.\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n '.gif': 'image/gif',\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.55.7?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 /** Top-level or nested paths to REMOVE after the sets (a destination's mechanics drop a field a null could not express). */\n unset?: 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.unset?.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 for (const path of o.unset ?? []) {\n const segs = parsePath(path)\n let node: unknown = d\n for (\n let i = 0;\n i < segs.length - 1 && node && typeof node === 'object';\n i++\n )\n node = (node as Record<string | number, unknown>)[segs[i].key]\n if (node && typeof node === 'object') {\n delete (node as Record<string | number, unknown>)[\n segs[segs.length - 1].key\n ]\n applied.push(`${path} removed`)\n }\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 { mkdir, mkdtemp, rename, rm, stat, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join, relative, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { parseFrontmatter } from '@vosjs/shared/frontmatter'\nimport {\n CHANNEL_SPECS_VERIFIED,\n DESTINATIONS,\n cardInset,\n destinationsForChannel,\n houseLook,\n isLookKind,\n lookFromBrand,\n docOutputDuration,\n} from '@vosjs/studio-core'\nimport { loadTake } from './take'\nimport { framesTake } from './framesTake'\nimport { renderTake } from './renderTake'\nimport { momentCandidates, pickMoments } from './moments'\nimport { decodePng, differenceHash, inkCoverage } from './picture'\nimport { LOOP_DESTINATIONS, destinationMechanics } from './motionPlan'\nimport {\n findPosterDocs,\n posterClassFor,\n posterShotRect,\n posterStillTime,\n posterTextBoxes,\n} from './posterDoc'\nimport type { PosterClass } from './posterDoc'\nimport type { MomentCandidate } from './moments'\nimport type { TextBox } from './kitPicture'\nimport type { Destination, Look, LookPlacement } 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 * LAUNCH.md's roles beside the take. The POSTER roles name the document a\n * card destination renders from (`poster: <path>`, `poster-landscape`,\n * `poster-square`, `poster-portrait`, `poster-tile`); the folder\n * convention `poster/<class>/doc.json` needs no role.\n */\n launchRoles?: Record<string, string> | null\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 /**\n * The card's presentation, resolved before the run (`resolveLook`): a\n * house look, the maker's BRAND.md, or null for the pre-look behaviour\n * (cards as cover crops, videos as the doc frames them). Card-genre\n * stills without a poster and every video destination ride it; the\n * screenshot genre never does (store policy: the real page, full bleed).\n */\n look?: Look | null\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 a poster DOCUMENT beside it. */\n source?: 'poster'\n /** The poster document a card rendered from: its class, its file (relative to the take), the vos it tracks. */\n poster?: { class: PosterClass; file: string; vosId?: string }\n /** Where the words landed, as fractions of the asset (the picture checks read them). */\n text?: TextBox[]\n /** Where the card sits on a poster, fractions of the asset (a bleed runs past the edge). */\n shot?: { x: number; y: number; w: number; h: number }\n /** The card runs past both edges: a close crop of the subject (a tile), so the picture checks skip the card band. */\n crop?: boolean\n /**\n * A screenshot-genre still rendered with the cut's camera and chrome\n * (`--composed`), which store policy refuses; the picture checks read it.\n */\n composed?: boolean\n}\n\nexport interface KitManifest {\n release: string | null\n /** The look the cards and cuts were presented in (null = none). */\n look: 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 /** The still moments, in order, and where each came from. */\n moments: MomentCandidate[]\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 * Read the brand kit's frontmatter beside a take: `BRAND.md` in the take\n * directory, else in its parent (a release's `media/` folder holds the\n * takes under it), else an explicit path. Null when there is none.\n */\nexport async function readBrandBesideTake(\n dir: string,\n explicit?: string,\n): Promise<{ file: string; roles: Record<string, string> } | null> {\n const candidates = explicit\n ? [explicit]\n : [join(dir, 'BRAND.md'), join(dir, '..', 'BRAND.md')]\n for (const file of candidates) {\n if (!existsSync(file)) continue\n const roles = parseFrontmatter(await readFile(file, 'utf8'))\n return { file, roles }\n }\n return null\n}\n\n/** LAUNCH.md beside a take (or its parent, or an explicit path): the release's roles. */\nexport async function readLaunchBesideTake(\n dir: string,\n explicit?: string,\n): Promise<{ file: string; roles: Record<string, string> } | null> {\n const candidates = explicit\n ? [explicit]\n : [join(dir, 'LAUNCH.md'), join(dir, '..', 'LAUNCH.md')]\n for (const file of candidates) {\n if (!existsSync(file)) continue\n return { file, roles: parseFrontmatter(await readFile(file, 'utf8')) }\n }\n return null\n}\n\n/**\n * The look a run presents its cards and cuts in, in precedence: `--look\n * none` (the pre-look behaviour), `--look <kind>` (a house look), the\n * brand kit beside the take (its `look` role, else its own ground decides),\n * then the house gradient. Says where it came from, for the phase note.\n */\nexport async function resolveLook(\n dir: string,\n opts: { look?: string; brand?: string },\n): Promise<{\n look: Look | null\n from: string\n roles: Record<string, string> | null\n}> {\n const brand = await readBrandBesideTake(dir, opts.brand)\n const roles = brand?.roles ?? null\n if (opts.look === 'none') return { look: null, from: '--look none', roles }\n if (opts.look !== undefined) {\n if (!isLookKind(opts.look))\n throw new Error(\n `--look \"${opts.look}\" — one of plate | gradient | dark | none`,\n )\n return { look: houseLook(opts.look), from: `--look ${opts.look}`, roles }\n }\n if (brand) {\n const look = lookFromBrand(brand.roles)\n return { look, from: `${brand.file} (${look.kind})`, roles }\n }\n return {\n look: houseLook('gradient'),\n from: 'the house gradient (no BRAND.md beside the take)',\n roles,\n }\n}\n\n/**\n * The overrides that present the card in a look at one destination size:\n * the ground, the placement (inset from the footage's aspect), the radius,\n * both shadow layers and the hairline; a still also releases the camera\n * and hides the cursor (a card shows the whole window at rest, and a\n * zoomed crop inside a small card reads as a broken screenshot). The\n * document's bar kind stays. Pure, so the policy is testable.\n */\nexport function lookOverrides(\n look: Look,\n placement: LookPlacement,\n size: { w: number; h: number },\n video: { w: number; h: number },\n opts: { still: boolean; keepMedia?: boolean },\n): string[] {\n const inset = cardInset(look, size, video, placement)\n const set = [\n 'frame.fit=contain',\n `frame.background=${JSON.stringify(look.ground)}`,\n `frame.inset=${JSON.stringify(inset)}`,\n `frame.radius=${look.radius}`,\n `frame.shadow=${look.shadow}`,\n `frame.shadowContact=${look.shadowContact}`,\n `frame.border=${look.border}`,\n ]\n if (look.shadowColor) set.push(`frame.shadowColor=${look.shadowColor}`)\n if (look.border > 0) {\n set.push('frame.borderWidth=1')\n set.push(`frame.borderColor=${look.borderColor ?? '#000000'}`)\n }\n if (!opts.keepMedia) set.push('frame.backgroundMedia=null')\n if (opts.still) {\n set.push(\n 'zoom=[]',\n 'tilt=[]',\n 'cursor.visible=false',\n 'cursor.clickFx.style=none',\n )\n }\n return set\n}\n\n/** The probe's width: enough to read ink and a hash, cheap to capture. */\nconst PROBE_WIDTH = 640\n\n/**\n * The still moments of a take: candidates from the step timeline, the\n * zoom apexes and the spread (moments.ts), captured ONCE at probe size as\n * the real page (camera released, no chrome), then kept only when\n * populated and distinct. What is dropped is said in `skipped`.\n */\nasync function pickStillTimes(\n browser: Browser,\n dir: string,\n doc: NonNullable<Awaited<ReturnType<typeof loadTake>>['doc']>,\n duration: number,\n opts: DeliverOptions,\n): Promise<{ times: number[]; moments: MomentCandidate[]; notes: string[] }> {\n const { candidates, dropped } = momentCandidates(doc, duration)\n const notes: string[] = []\n if (dropped > 0)\n notes.push(\n `${dropped} of ${doc.zoom.length} zoom apex(es) fall outside the cut`,\n )\n if (!candidates.length) return { times: [], moments: [], notes }\n const meta = doc.source.meta\n const vw = meta.captureWidth ?? meta.width\n const vh = meta.captureHeight ?? meta.height\n const probeDir = await mkdtemp(join(tmpdir(), 'vos-moments-'))\n try {\n const probe = await framesTake(browser, dir, {\n times: candidates.map((c) => c.time),\n width: PROBE_WIDTH,\n height: Math.max(2, Math.round((PROBE_WIDTH * vh) / vw / 2) * 2),\n outDir: probeDir,\n overrides: {\n ...opts.overrides,\n set: [...SCREENSHOT_DEFAULTS, ...(opts.overrides?.set ?? [])],\n },\n })\n // The probe writes its frames in time order; the candidates are in\n // rung order (steps first), which is the order the pick must keep, so\n // measures are joined by TIME, never by index.\n const byTime = new Map<number, { ink: number; hash: string }>()\n for (const frame of probe.frames) {\n const img = decodePng(new Uint8Array(await readFile(frame.file)))\n if (!img) continue\n const whole = { x: 0, y: 0, w: img.w, h: img.h }\n byTime.set(+frame.time.toFixed(3), {\n ink: inkCoverage(img, whole),\n hash: differenceHash(img, whole),\n })\n }\n const measured = []\n for (const c of candidates) {\n const m = byTime.get(+c.time.toFixed(3))\n if (m) measured.push({ time: c.time, ...m })\n }\n const pick = pickMoments(measured)\n const kept = candidates.filter((c) => pick.times.includes(c.time))\n const bySource = (s: MomentCandidate['source']) =>\n candidates.filter((c) => c.source === s).length\n notes.push(\n `${candidates.length} candidate(s): ${bySource('step')} from steps, ${bySource('zoom')} from zoom apexes, ${bySource('spread')} from the spread; ${kept.length} kept`,\n )\n return {\n times: pick.times,\n moments: kept,\n notes: [...notes, ...pick.dropped.map((d) => `moment: ${d}`)],\n }\n } finally {\n await rm(probeDir, { recursive: true, force: true })\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'> & { px?: Destination['px'] },\n opts: Pick<DeliverOptions, 'overrides' | 'composed' | 'look'>,\n video?: { w: number; h: number },\n): DocOverrides | undefined {\n const set: string[] = []\n if (d.genre === 'screenshot' && !opts.composed) {\n if (d.fit === 'cover') set.push('frame.fit=cover')\n set.push(...SCREENSHOT_DEFAULTS)\n } else if (\n d.genre === 'card' &&\n !opts.composed &&\n opts.look &&\n video &&\n d.px\n ) {\n // A card with no poster program is the whole window on the look's\n // ground: centred with room around it, or, on a frame too wide to hold\n // it, given headroom and run off the bottom (the feature-clip grammar).\n set.push(\n ...lookOverrides(opts.look, 'card', d.px, video, {\n still: true,\n keepMedia: opts.overrides?.background !== undefined,\n }),\n )\n } else {\n if (d.fit === 'cover') set.push('frame.fit=cover')\n // No look: a card with no poster program is a cover crop of the real\n // 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 if (d.genre === 'card' && !opts.composed) set.push(...FULL_BLEED)\n }\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 // The output's end: the clips after the footage count, so an end card\n // is inside every cut and the loop's cap reads the whole picture.\n const duration = docOutputDuration(doc)\n const videoSeconds = opts.range\n ? Math.min(opts.range[1], duration) - Math.min(opts.range[0], duration)\n : duration\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 let stillTimes: number[]\n let moments: MomentCandidate[]\n if (opts.times?.length) {\n stillTimes = opts.times\n moments = opts.times.map((time) => ({ time, source: 'times' as const }))\n } else {\n opts.onPhase?.('moments (the step timeline, the zoom apexes, the spread)')\n const picked = await pickStillTimes(browser, dir, doc, duration, opts)\n stillTimes = picked.times\n moments = picked.moments\n for (const n of picked.notes) {\n if (n.startsWith('moment: ')) skipped.push(n)\n else opts.onPhase?.(`note: ${n}`)\n }\n }\n const meta0 = doc.source.meta\n const video = {\n w: meta0.captureWidth ?? meta0.width,\n h: meta0.captureHeight ?? meta0.height,\n }\n /**\n * A video destination rides the look in the hero placement, camera kept,\n * then the destination's MECHANICS (a loop plays no entrance, end card\n * or sound; a silent channel mutes the bed; a 9:16 destination reframes\n * the card), then the user's own sets, which win. The cut's motion\n * (entrance, end card, captions, bed, clicks) is the DOCUMENT's, written\n * by `vos plan`; nothing is composed here.\n */\n const videoOverrides = (d: Destination): DocOverrides | undefined => {\n const set: string[] = []\n if (opts.look) {\n set.push(\n ...lookOverrides(opts.look, 'hero', d.px, video, {\n still: false,\n keepMedia: opts.overrides?.background !== undefined,\n }),\n )\n }\n const mech = destinationMechanics(d, doc)\n set.push(...mech.set)\n if (mech.notes.length) opts.onPhase?.(`${d.id}: ${mech.notes.join(', ')}`)\n set.push(...(opts.overrides?.set ?? []))\n if (!set.length && !mech.unset.length) return opts.overrides\n return { ...opts.overrides, set, unset: mech.unset }\n }\n\n // The poster leg: a CARD destination renders from the POSTER DOCUMENT of\n // its aspect class, found beside the take (poster/<class>/doc.json, or\n // named in LAUNCH.md), at the document's REST (the trailing hold's\n // start), so the still is a frame of the poster's own video by\n // construction. Deliver renders and verifies; the composition is the\n // document's, written by an agent or the studio. A class with no\n // document falls to the take's own frame, said once in words.\n const posters = await findPosterDocs(dir, opts.launchRoles)\n const posterCardIds = new Set<string>()\n const missing = new Set<PosterClass>()\n for (const d of destinations) {\n if (d.kind === 'video' || d.genre !== 'card' || NOT_FROM_FOOTAGE[d.id])\n continue\n const cls = posterClassFor(d.px)\n const ref = posters[cls]\n if (!ref) {\n missing.add(cls)\n continue\n }\n posterCardIds.add(d.id)\n const label = `${d.channel} ${d.asset}`\n const posterDuration = docOutputDuration(ref.doc)\n const time = posterStillTime(ref.doc, posterDuration)\n opts.onPhase?.(\n `${label} (${specWords(d)}) from ${ref.from}${ref.vosId ? ` ${ref.vosId}` : ''}, the rest at ${time.toFixed(2)}s`,\n )\n const shotDir = await mkdtemp(join(tmpdir(), 'vos-poster-'))\n try {\n const captured = await framesTake(browser, ref.takeDir, {\n times: [time],\n width: d.px.w,\n height: d.px.h,\n outDir: shotDir,\n doc: ref.doc,\n overrides: opts.overrides,\n })\n const to = join(outDir, `${d.id}.png`)\n await rename(captured.frames[0].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 const shot = posterShotRect(ref.doc, d.px)\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: time,\n source: 'poster',\n poster: {\n class: cls,\n file: relative(dir, ref.file),\n ...(ref.vosId ? { vosId: ref.vosId } : {}),\n },\n text: posterTextBoxes(ref.doc, d.px, time),\n shot,\n ...(shot.x < 0 && shot.x + shot.w > 1 ? { crop: true } : {}),\n })\n } finally {\n await rm(shotDir, { recursive: true, force: true })\n }\n }\n if (missing.size) {\n const classes = [...missing].sort().join(', ')\n skipped.push(\n `note: no poster document for the ${classes} class${missing.size > 1 ? 'es' : ''} beside the take (poster/<class>/doc.json, or LAUNCH.md poster:), so those cards are the take's own frame`,\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 // A LOOP destination the take outruns takes the take's FIRST seconds\n // up to its cap (a loop is a texture, not a story); a story\n // destination is skipped with the reason, never cut blind.\n let range = opts.range\n let seconds = videoSeconds\n if (d.maxSeconds !== undefined && videoSeconds > d.maxSeconds) {\n if (LOOP_DESTINATIONS.has(d.id) && !opts.range) {\n range = [0, d.maxSeconds]\n seconds = d.maxSeconds\n opts.onPhase?.(\n `note: ${label} takes the first ${d.maxSeconds}s of the ${videoSeconds.toFixed(0)}s take (a loop's cap)`,\n )\n } else {\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 }\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) / seconds) * 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,\n bitrate,\n overrides: videoOverrides(d),\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, video)\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 ...(d.genre === 'screenshot' && opts.composed\n ? { composed: true }\n : {}),\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 look: opts.look?.kind ?? null,\n take: dir,\n produced: new Date().toISOString(),\n specsVerified: CHANNEL_SPECS_VERIFIED,\n moments,\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 // Render-page modes, never stored in the doc: the recording's frames come\n // from the WebCodecs sequential decoder by PTS instead of an element seek\n // and a settle wait per frame, and the page keeps the recording as a Blob\n // so the decoder reads the bytes the element already holds. The lowering\n // fails open at every rung (no VideoDecoder, an undecodable track, a\n // dimension mismatch), so a browser without the path keeps the old one.\n const captureData = {\n ...lowered.data,\n videoDecodeMode: 'webcodecs',\n videoFetchMode: 'blob',\n }\n const animationCode = compileVosConfig(\n { ...lowered.config, data: captureData } 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 * The moment: which instants of a take become its stills. Three rungs, in\n * order, each pure: the STEP timeline (every gesture's end plus a settle,\n * so the frame shows the response and not the travel), the zoom apexes\n * (the camera's own picks), an even spread. Then two guards over what was\n * actually captured: candidates that hash alike collapse to one (a kit of\n * eight crops of one frame is the failure this exists for), and a blank\n * candidate (a wallpaper, an empty canvas, a flat panel) is dropped with\n * the reason in words. No model; the numbers come from the pixels.\n */\nimport { ratedSegments, spanOutputExtent } from '@vosjs/studio-core'\nimport { hammingDistance } from './picture'\nimport type { ProjectDoc, StepSpan } from '@vosjs/studio-core'\n\n/** Seconds after a gesture's end before the frame is read: the response has landed. */\nexport const STEP_SETTLE_SECONDS = 0.4\n\n/** Steps that are not gestures: nothing happened on screen at their end. */\nconst NOT_A_GESTURE = new Set(['wait', 'goto', 'sleep'])\n\nexport interface MomentCandidate {\n /** OUTPUT seconds. */\n time: number\n /** Where it came from. */\n source: 'step' | 'zoom' | 'spread' | 'times'\n /** The step's id (or index) when source is 'step'. */\n step?: string | number\n}\n\n/**\n * Candidate still times for a take, in rung order. Steps first (skipped\n * steps and waits excluded, and a step whose settled instant falls outside\n * the cut drops silently), then zoom apexes, then the spread; duplicates\n * within 0.25 s are merged. `dropped` counts zoom apexes the cut trimmed\n * out, for the phase note.\n */\nexport function momentCandidates(\n doc: ProjectDoc,\n duration: number,\n): { candidates: MomentCandidate[]; dropped: number } {\n const rated = ratedSegments(doc)\n const out: MomentCandidate[] = []\n const push = (c: MomentCandidate) => {\n if (c.time < 0 || c.time > duration) return\n if (out.some((o) => Math.abs(o.time - c.time) < 0.25)) return\n out.push(c)\n }\n const steps = doc.source.meta.steps ?? []\n for (let i = 0; i < steps.length; i++) {\n const s = steps[i]\n if (s.skipped || NOT_A_GESTURE.has(s.do)) continue\n const t = stepOutputTime(rated, s, settleAfter(steps, i))\n if (t === null) continue\n push({ time: t, source: 'step', step: s.id ?? s.step })\n }\n let dropped = 0\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 else dropped++\n }\n for (const t of apexes.sort((a, b) => a - b))\n push({ time: t, source: 'zoom' })\n if (!out.length) {\n for (const p of [0.1, 0.3, 0.5, 0.7, 0.9])\n push({ time: p * duration, source: 'spread' })\n }\n return { candidates: out, dropped }\n}\n\n/**\n * How long after a gesture's end its frame is read. The script's author\n * says it when a `wait` follows the step (a click that navigates, a hover\n * that opens a menu: the wait IS the response landing), so the moment is\n * that wait's end; otherwise the default settle.\n */\nexport function settleAfter(steps: StepSpan[], i: number): number {\n const next = steps[i + 1]\n if (next && next.do === 'wait' && !next.skipped)\n return Math.max(0, next.tEnd - steps[i].tEnd)\n return STEP_SETTLE_SECONDS\n}\n\n/**\n * A step's settled instant in OUTPUT seconds (its gesture end plus the\n * settle, mapped through the cut), or null when the cut trimmed it out.\n */\nexport function stepOutputTime(\n rated: ReturnType<typeof ratedSegments>,\n step: Pick<StepSpan, 'tStart' | 'tEnd'>,\n settle: number,\n): number | null {\n const src = step.tEnd + settle\n const ext = spanOutputExtent(rated, src, src + 0.001)\n if (!ext) return null\n return ext.start\n}\n\n/**\n * Resolve a `--times` entry of the form `step:<id>[+offset|-offset]` (the\n * id from actions.json, or the step's index) against the take's step\n * timeline, in OUTPUT seconds. Null when the entry is not a step form;\n * throws when the step is unknown or trimmed out.\n */\nexport function resolveStepTime(doc: ProjectDoc, entry: string): number | null {\n const m = /^step:([^+-]+)([+-]\\d+(?:\\.\\d+)?)?$/.exec(entry.trim())\n if (!m) return null\n const key = m[1]\n const offset = m[2] ? Number(m[2]) : STEP_SETTLE_SECONDS\n const steps = doc.source.meta.steps ?? []\n const step =\n steps.find((s) => s.id === key) ??\n (/^\\d+$/.test(key) ? steps.find((s) => s.step === Number(key)) : undefined)\n if (!step) {\n const known = steps\n .map((s) => s.id ?? String(s.step))\n .filter((s) => s.length)\n throw new Error(\n `--times ${entry}: no step \"${key}\" in the take's step timeline${known.length ? ` (steps: ${known.join(', ')})` : ' (the take carries none: record it with the current CLI)'}`,\n )\n }\n const t = stepOutputTime(ratedSegments(doc), step, offset)\n if (t === null)\n throw new Error(\n `--times ${entry}: step \"${key}\" (${step.tEnd.toFixed(2)}s in the recording) falls outside the cut`,\n )\n return t\n}\n\nexport interface CandidateMeasure {\n time: number\n /** Ink coverage inside the frame's subject, 0..1. */\n ink: number\n /** Difference hash of the subject. */\n hash: string\n}\n\nexport interface MomentPick {\n /** Times that survive, in candidate order. */\n times: number[]\n /** What was dropped, in words. */\n dropped: string[]\n}\n\n/** Hamming bits under which two candidates are one frame. */\nexport const DUPLICATE_BITS = 6\n\n/**\n * The relative floor's cap: a frame with this much ink is populated no\n * matter how dense the take's other pages are (a gallery grid reads 90%+\n * and must not make a watch page at 30% read as blank).\n */\nexport const POPULATED_INK = 0.12\n\n/**\n * Keep the candidates that are populated and distinct. The blank floor is\n * relative to the take (a fraction of the median ink across candidates,\n * with an absolute floor), so a dense page and a sparse app are each held\n * to their own norm; duplicates collapse to the FIRST of a pair, since\n * candidates arrive in rung order (a step beats an apex beats the spread).\n */\nexport function pickMoments(\n measured: CandidateMeasure[],\n opts: { minInk?: number; relativeInk?: number; duplicateBits?: number } = {},\n): MomentPick {\n const minInk = opts.minInk ?? 0.06\n const relative = opts.relativeInk ?? 0.4\n const bits = opts.duplicateBits ?? DUPLICATE_BITS\n const inks = measured.map((m) => m.ink).sort((a, b) => a - b)\n const median = inks[inks.length >> 1] ?? 0\n const floor = Math.max(minInk, Math.min(POPULATED_INK, median * relative))\n const kept: CandidateMeasure[] = []\n const dropped: string[] = []\n for (const m of measured) {\n if (m.ink < floor) {\n dropped.push(\n `blank at ${m.time.toFixed(2)}s: ${Math.round(m.ink * 100)}% ink (the floor is ${Math.round(floor * 100)}%; the take's median is ${Math.round(median * 100)}%)`,\n )\n continue\n }\n const twin = kept.find((k) => hammingDistance(k.hash, m.hash) <= bits)\n if (twin) {\n dropped.push(\n `${m.time.toFixed(2)}s is the same frame as ${twin.time.toFixed(2)}s`,\n )\n continue\n }\n kept.push(m)\n }\n // Every candidate blank: keep the best one rather than nothing, said.\n if (!kept.length && measured.length) {\n const best = [...measured].sort((a, b) => b.ink - a.ink)[0]\n kept.push(best)\n dropped.push(\n `every candidate is under the blank floor; kept ${best.time.toFixed(2)}s (${Math.round(best.ink * 100)}% ink) as the least empty`,\n )\n }\n return { times: kept.map((k) => k.time), dropped }\n}\n","/**\n * Picture primitives for the kit: what a still LOOKS like, measured from\n * its bytes, no browser and no model. A PNG decoder for the captures this\n * CLI writes (8-bit RGB/RGBA, non-interlaced; anything else reads as\n * unreadable rather than wrong), then the measurements the reference\n * assets were read with: the ground (the median of a border ring), the\n * card (the bounding box of what differs from the ground), the shadow (a\n * gradient band outside the card's bottom edge), ink coverage inside a\n * rect (how much of the card is content), and a difference hash so two\n * stills of one frame can be told apart from two frames.\n */\nimport { inflateSync } from 'node:zlib'\n\nexport interface Rgba {\n w: number\n h: number\n /** RGBA, row-major, 4 bytes per pixel. */\n data: Uint8Array\n}\n\nconst PNG_SIG = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]\n\n/**\n * Decode an 8-bit truecolor (with or without alpha) or greyscale\n * non-interlaced PNG. Returns null for anything else (palette, 16-bit,\n * interlaced): the picture checks then say \"unreadable\", never a wrong\n * number.\n */\nexport function decodePng(bytes: Uint8Array): Rgba | null {\n if (bytes.length < 33) return null\n for (let i = 0; i < 8; i++) if (bytes[i] !== PNG_SIG[i]) return null\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n let pos = 8\n let w = 0\n let h = 0\n let depth = 0\n let colorType = 0\n let interlace = 0\n const idat: Uint8Array[] = []\n while (pos + 8 <= bytes.length) {\n const len = view.getUint32(pos)\n const type = String.fromCharCode(\n bytes[pos + 4],\n bytes[pos + 5],\n bytes[pos + 6],\n bytes[pos + 7],\n )\n const start = pos + 8\n if (type === 'IHDR') {\n w = view.getUint32(start)\n h = view.getUint32(start + 4)\n depth = bytes[start + 8]\n colorType = bytes[start + 9]\n interlace = bytes[start + 12]\n } else if (type === 'IDAT') {\n idat.push(bytes.subarray(start, start + len))\n } else if (type === 'IEND') break\n pos = start + len + 4\n }\n if (!w || !h || depth !== 8 || interlace !== 0) return null\n const channels =\n colorType === 6 ? 4 : colorType === 2 ? 3 : colorType === 4 ? 2 : colorType === 0 ? 1 : 0\n if (!channels) return null\n const total = idat.reduce((n, c) => n + c.length, 0)\n const joined = new Uint8Array(total)\n let off = 0\n for (const c of idat) {\n joined.set(c, off)\n off += c.length\n }\n let raw: Uint8Array\n try {\n raw = new Uint8Array(inflateSync(joined))\n } catch {\n return null\n }\n const stride = w * channels\n if (raw.length < (stride + 1) * h) return null\n const out = new Uint8Array(w * h * 4)\n const prev = new Uint8Array(stride)\n const cur = new Uint8Array(stride)\n for (let y = 0; y < h; y++) {\n const filter = raw[y * (stride + 1)]\n const rowStart = y * (stride + 1) + 1\n for (let i = 0; i < stride; i++) {\n const x = raw[rowStart + i]\n const a = i >= channels ? cur[i - channels] : 0\n const b = prev[i]\n const c = i >= channels ? prev[i - channels] : 0\n let v: number\n switch (filter) {\n case 0:\n v = x\n break\n case 1:\n v = x + a\n break\n case 2:\n v = x + b\n break\n case 3:\n v = x + ((a + b) >> 1)\n break\n case 4: {\n const p = a + b - c\n const pa = Math.abs(p - a)\n const pb = Math.abs(p - b)\n const pc = Math.abs(p - c)\n v = x + (pa <= pb && pa <= pc ? a : pb <= pc ? b : c)\n break\n }\n default:\n return null\n }\n cur[i] = v & 255\n }\n for (let px = 0; px < w; px++) {\n const o = (y * w + px) * 4\n const s = px * channels\n if (channels >= 3) {\n out[o] = cur[s]\n out[o + 1] = cur[s + 1]\n out[o + 2] = cur[s + 2]\n out[o + 3] = channels === 4 ? cur[s + 3] : 255\n } else {\n out[o] = out[o + 1] = out[o + 2] = cur[s]\n out[o + 3] = channels === 2 ? cur[s + 1] : 255\n }\n }\n prev.set(cur)\n }\n return { w, h, data: out }\n}\n\nexport interface Rect {\n x: number\n y: number\n w: number\n h: number\n}\n\nconst at = (img: Rgba, x: number, y: number): [number, number, number] => {\n const o = (y * img.w + x) * 4\n return [img.data[o], img.data[o + 1], img.data[o + 2]]\n}\n\nconst median = (a: number[]) => {\n const s = [...a].sort((x, y) => x - y)\n return s[s.length >> 1] ?? 0\n}\n\n/** The ground: the per-channel median of a 1% border ring, as `#rrggbb`. */\nexport function groundColour(img: Rgba): [number, number, number] {\n const ring = Math.max(1, Math.round(Math.min(img.w, img.h) * 0.01))\n const r: number[] = []\n const g: number[] = []\n const b: number[] = []\n const step = Math.max(1, Math.round(Math.max(img.w, img.h) / 400))\n for (let y = 0; y < img.h; y += step) {\n for (let x = 0; x < img.w; x += step) {\n if (x < ring || y < ring || x >= img.w - ring || y >= img.h - ring) {\n const p = at(img, x, y)\n r.push(p[0])\n g.push(p[1])\n b.push(p[2])\n }\n }\n }\n return [median(r), median(g), median(b)]\n}\n\nexport const hex = (c: [number, number, number]) =>\n '#' + c.map((v) => v.toString(16).padStart(2, '0')).join('')\n\nconst delta = (p: [number, number, number], q: [number, number, number]) =>\n Math.abs(p[0] - q[0]) + Math.abs(p[1] - q[1]) + Math.abs(p[2] - q[2])\n\n/**\n * The card: the bounding box of pixels whose channel-sum delta from the\n * ground exceeds `threshold` (60, the reference measurement). Null when\n * nothing differs (a flat image). Sampled every other pixel.\n */\nexport function cardBounds(\n img: Rgba,\n ground: [number, number, number],\n threshold = 60,\n): Rect | null {\n let x0 = img.w\n let y0 = img.h\n let x1 = -1\n let y1 = -1\n const step = Math.max(1, Math.round(Math.max(img.w, img.h) / 700))\n for (let y = 0; y < img.h; y += step) {\n for (let x = 0; x < img.w; x += step) {\n if (delta(at(img, x, y), ground) > threshold) {\n if (x < x0) x0 = x\n if (y < y0) y0 = y\n if (x > x1) x1 = x\n if (y > y1) y1 = y\n }\n }\n }\n if (x1 < 0) return null\n return { x: x0, y: y0, w: x1 - x0 + 1, h: y1 - y0 + 1 }\n}\n\n/**\n * Shadow presence, read INWARD from the object's faint edge: a soft shadow\n * is a halo whose delta from the ground grows toward the card, so the band\n * nearer the card must read darker than the outer band (a card fill, a\n * hard edge or a flat plate read flat). Sides read are left, right and\n * bottom, wherever the object clears the frame; the reading is the nearer\n * band's delta, else 0. Null when no side has room.\n */\nexport function haloReading(\n img: Rgba,\n ground: [number, number, number],\n card: Rect,\n): number | null {\n const band = Math.max(2, Math.round(Math.min(img.w, img.h) * 0.012))\n const meanRect = (x0: number, y0: number, x1: number, y1: number) => {\n let sum = 0\n let n = 0\n const sx = Math.max(1, Math.round((x1 - x0) / 60))\n const sy = Math.max(1, Math.round((y1 - y0) / 60))\n for (let y = Math.max(0, y0); y < Math.min(img.h, y1); y += sy) {\n for (let x = Math.max(0, x0); x < Math.min(img.w, x1); x += sx) {\n sum += delta(at(img, x, y), ground)\n n++\n }\n }\n return n ? sum / n : 0\n }\n // Two bands, not three: the innermost band would reach the card's own\n // fill, which on a light card is LIGHTER than the halo and breaks the\n // rise. A halo is present when the band nearer the card is darker than\n // the outer one by a clear step and the outer one is not the ground.\n const rise = (bands: [number, number, number]) => {\n const [outer, mid] = bands\n return outer >= 3 && mid - outer >= 1.5 ? mid : 0\n }\n const readings: number[] = []\n const yA = card.y + card.h * 0.2\n const yB = card.y + card.h * 0.8\n if (card.x >= 1 && card.w > band * 4) {\n const x0 = card.x\n readings.push(\n rise([\n meanRect(x0, yA, x0 + band, yB),\n meanRect(x0 + band, yA, x0 + band * 2, yB),\n meanRect(x0 + band * 2, yA, x0 + band * 3, yB),\n ]),\n )\n }\n if (card.x + card.w <= img.w - 1 && card.w > band * 4) {\n const x1 = card.x + card.w\n readings.push(\n rise([\n meanRect(x1 - band, yA, x1, yB),\n meanRect(x1 - band * 2, yA, x1 - band, yB),\n meanRect(x1 - band * 3, yA, x1 - band * 2, yB),\n ]),\n )\n }\n if (card.y + card.h <= img.h - 1 && card.h > band * 4) {\n const y1 = card.y + card.h\n const xA = card.x + card.w * 0.2\n const xB = card.x + card.w * 0.8\n readings.push(\n rise([\n meanRect(xA, y1 - band, xB, y1),\n meanRect(xA, y1 - band * 2, xB, y1 - band),\n meanRect(xA, y1 - band * 3, xB, y1 - band * 2),\n ]),\n )\n }\n return readings.length ? Math.max(...readings) : null\n}\n\n/**\n * A drawn edge at the object's boundary: the strongest single column\n * within the first 24 px inside the faint edge (the halo lies between the\n * faint edge and the card, so the hairline sits a few px in), as the\n * median delta from the ground along its height. A hairline, a browser bar or a dark card reads\n * high; a light fill against a light plate reads its own small tone step.\n */\nexport function edgeContrast(\n img: Rgba,\n ground: [number, number, number],\n card: Rect,\n): number {\n const yA = Math.max(0, Math.round(card.y + card.h * 0.2))\n const yB = Math.min(img.h, Math.round(card.y + card.h * 0.8))\n // The MEDIAN of a column, not its mean: a drawn edge is dark along its\n // whole height, while a column through page content is mostly fill with\n // a few dark rows, which a mean would mistake for an edge.\n const col = (x: number) => {\n if (x < 0 || x >= img.w) return 0\n const ds: number[] = []\n const step = Math.max(1, Math.round((yB - yA) / 80))\n for (let y = yA; y < yB; y += step) ds.push(delta(at(img, x, y), ground))\n return median(ds)\n }\n const depth = Math.min(24, Math.floor(card.w / 8))\n let best = 0\n for (let d = 0; d < depth; d++) {\n best = Math.max(best, col(card.x + d), col(card.x + card.w - 1 - d))\n }\n return best\n}\n\n/**\n * Ink coverage inside a rect: the share of sampled pixels that differ from\n * the rect's own median colour by more than `threshold`. A populated page\n * reads 0.2 and up; a blank canvas, a wallpaper or a flat panel reads\n * under 0.1.\n */\nexport function inkCoverage(img: Rgba, rect: Rect, threshold = 48): number {\n const x0 = Math.max(0, Math.floor(rect.x))\n const y0 = Math.max(0, Math.floor(rect.y))\n const x1 = Math.min(img.w, Math.ceil(rect.x + rect.w))\n const y1 = Math.min(img.h, Math.ceil(rect.y + rect.h))\n if (x1 - x0 < 2 || y1 - y0 < 2) return 0\n const step = Math.max(1, Math.round(Math.max(x1 - x0, y1 - y0) / 300))\n const r: number[] = []\n const g: number[] = []\n const b: number[] = []\n const pts: [number, number, number][] = []\n for (let y = y0; y < y1; y += step) {\n for (let x = x0; x < x1; x += step) {\n const p = at(img, x, y)\n pts.push(p)\n r.push(p[0])\n g.push(p[1])\n b.push(p[2])\n }\n }\n const base: [number, number, number] = [median(r), median(g), median(b)]\n let ink = 0\n for (const p of pts) if (delta(p, base) > threshold) ink++\n return pts.length ? ink / pts.length : 0\n}\n\n/**\n * A 64-bit difference hash: the image reduced to 9x8 luma, each bit \"is\n * this cell brighter than its right neighbour\". Two crops of ONE frame at\n * different aspects still hash within a few bits of each other; two\n * frames of a moving page do not. Returned as a 16-hex string.\n */\nexport function differenceHash(img: Rgba, rect?: Rect): string {\n const r = rect ?? { x: 0, y: 0, w: img.w, h: img.h }\n const cols = 9\n const rows = 8\n const cell: number[] = []\n for (let cy = 0; cy < rows; cy++) {\n for (let cx = 0; cx < cols; cx++) {\n const x0 = Math.floor(r.x + (cx * r.w) / cols)\n const x1 = Math.max(x0 + 1, Math.floor(r.x + ((cx + 1) * r.w) / cols))\n const y0 = Math.floor(r.y + (cy * r.h) / rows)\n const y1 = Math.max(y0 + 1, Math.floor(r.y + ((cy + 1) * r.h) / rows))\n let sum = 0\n let n = 0\n const sx = Math.max(1, Math.floor((x1 - x0) / 8))\n const sy = Math.max(1, Math.floor((y1 - y0) / 8))\n for (let y = y0; y < y1 && y < img.h; y += sy) {\n for (let x = x0; x < x1 && x < img.w; x += sx) {\n const p = at(img, Math.max(0, x), Math.max(0, y))\n sum += 0.299 * p[0] + 0.587 * p[1] + 0.114 * p[2]\n n++\n }\n }\n cell.push(n ? sum / n : 0)\n }\n }\n let bits = ''\n for (let cy = 0; cy < rows; cy++) {\n let byte = 0\n for (let cx = 0; cx < cols - 1; cx++) {\n const l = cell[cy * cols + cx]\n const rr = cell[cy * cols + cx + 1]\n byte = (byte << 1) | (l > rr ? 1 : 0)\n }\n bits += byte.toString(16).padStart(2, '0')\n }\n return bits\n}\n\n/** Bits that differ between two hashes of equal length. */\nexport function hammingDistance(a: string, b: string): number {\n let d = 0\n for (let i = 0; i < Math.min(a.length, b.length); i++) {\n let x = parseInt(a[i], 16) ^ parseInt(b[i], 16)\n while (x) {\n d += x & 1\n x >>= 1\n }\n }\n return d + Math.abs(a.length - b.length) * 4\n}\n\n/** Relative luminance 0..1 of an sRGB triple. */\nexport function luminance(c: [number, number, number]): number {\n const lin = (v: number) => {\n const s = v / 255\n return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)\n }\n return 0.2126 * lin(c[0]) + 0.7152 * lin(c[1]) + 0.0722 * lin(c[2])\n}\n\n/** CIE L* (0..100) of an sRGB triple, for a card-vs-ground separation. */\nexport function lightness(c: [number, number, number]): number {\n const y = luminance(c)\n return y > 0.008856 ? 116 * Math.cbrt(y) - 16 : 903.3 * y\n}\n\n/** The median colour inside a rect (sampled). */\nexport function medianColour(img: Rgba, rect: Rect): [number, number, number] {\n const r: number[] = []\n const g: number[] = []\n const b: number[] = []\n const x0 = Math.max(0, Math.floor(rect.x))\n const y0 = Math.max(0, Math.floor(rect.y))\n const x1 = Math.min(img.w, Math.ceil(rect.x + rect.w))\n const y1 = Math.min(img.h, Math.ceil(rect.y + rect.h))\n const step = Math.max(1, Math.round(Math.max(x1 - x0, y1 - y0) / 200))\n for (let y = y0; y < y1; y += step) {\n for (let x = x0; x < x1; x += step) {\n const p = at(img, x, y)\n r.push(p[0])\n g.push(p[1])\n b.push(p[2])\n }\n }\n return [median(r), median(g), median(b)]\n}\n\n/**\n * Edge energy at a scale: the mean absolute luma step between horizontal\n * neighbours after downscaling the image so its width is `width` cells.\n * The half-size legibility rule compares the energy at full and at half\n * size: a tile that keeps most of its edges when shrunk still reads.\n */\nexport function edgeEnergy(img: Rgba, width: number): number {\n const cols = Math.max(2, Math.min(width, img.w))\n const rows = Math.max(2, Math.round((cols * img.h) / img.w))\n const lum: number[] = []\n for (let cy = 0; cy < rows; cy++) {\n for (let cx = 0; cx < cols; cx++) {\n const x = Math.min(img.w - 1, Math.floor(((cx + 0.5) * img.w) / cols))\n const y = Math.min(img.h - 1, Math.floor(((cy + 0.5) * img.h) / rows))\n const p = at(img, x, y)\n lum.push(0.299 * p[0] + 0.587 * p[1] + 0.114 * p[2])\n }\n }\n let sum = 0\n let n = 0\n for (let cy = 0; cy < rows; cy++) {\n for (let cx = 1; cx < cols; cx++) {\n sum += Math.abs(lum[cy * cols + cx] - lum[cy * cols + cx - 1])\n n++\n }\n }\n return n ? sum / n : 0\n}\n\n/** Measure a still the way the reference assets were measured. */\nexport interface StillMeasure {\n w: number\n h: number\n ground: string\n card: Rect | null\n /** The card's width as a fraction of the frame. */\n widthPct: number | null\n /** Padding on each side as fractions of the frame. */\n pad: { left: number; right: number; top: number; bottom: number } | null\n /** Sides where the card runs to (or past) the frame edge (< 0.5% room). */\n bleed: ('left' | 'right' | 'top' | 'bottom')[]\n /** The shadow halo reading inward from the object's edge; null when no side clears the frame. */\n shadow: number | null\n /** The strongest drawn edge at the boundary (a hairline, a bar, a dark card). */\n edge: number\n /** Ink coverage inside the card (or the whole frame when no card). */\n ink: number\n /** L* difference between the card's median and the ground. */\n separation: number | null\n hash: string\n}\n\nexport function measureStill(img: Rgba): StillMeasure {\n const g = groundColour(img)\n // Two thresholds: the STRONG box is the content (60, the reference\n // measurement); the FAINT box (12) is the object, halo and hairline\n // included, which is what a light card on a light plate needs to be\n // found by at all.\n const strong = cardBounds(img, g, 60)\n const faint = cardBounds(img, g, 12) ?? strong\n const card = faint\n const bleed: StillMeasure['bleed'] = []\n let pad: StillMeasure['pad'] = null\n let widthPct: number | null = null\n let shadow: number | null = null\n let edge = 0\n let separation: number | null = null\n if (card) {\n pad = {\n left: card.x / img.w,\n right: (img.w - card.x - card.w) / img.w,\n top: card.y / img.h,\n bottom: (img.h - card.y - card.h) / img.h,\n }\n for (const side of ['left', 'right', 'top', 'bottom'] as const)\n if (pad[side] < 0.005) bleed.push(side)\n widthPct = card.w / img.w\n shadow = haloReading(img, g, card)\n edge = edgeContrast(img, g, card)\n const body = strong ?? card\n const inner = {\n x: body.x + body.w * 0.1,\n y: body.y + body.h * 0.1,\n w: body.w * 0.8,\n h: body.h * 0.8,\n }\n separation = Math.abs(lightness(medianColour(img, inner)) - lightness(g))\n }\n const inkRect = strong ?? card ?? { x: 0, y: 0, w: img.w, h: img.h }\n return {\n w: img.w,\n h: img.h,\n ground: hex(g),\n card,\n widthPct,\n pad,\n bleed,\n shadow,\n edge,\n ink: inkCoverage(img, inkRect),\n separation,\n hash: differenceHash(img, inkRect),\n }\n}\n","/**\n * The cut's presenting MOTION as planner proposals on the document, and the\n * spec MECHANICS a destination applies at render time. Two halves, drawn\n * once:\n *\n * TASTE lives in the document, in the one vocabulary. `proposeMotion`\n * writes the card's `anim.enter`, lays the templates the recipe names at\n * their anchors (a template is a vos; its clips come stamped `from`), the\n * house end card as clips after the footage plus a card exit, a caption\n * per beat, a music bed and click sounds onto the cut's doc.json (`vos\n * plan`), keyed on the recipe's roles (LAUNCH.md) and never on measured\n * audio, so the studio shows exactly what the kit will render and a\n * human's deletion stays deleted (a re-plan never re-proposes onto a\n * document that already carries a cut).\n *\n * MECHANICS live in the spec. `destinationMechanics` is what a VIDEO\n * destination does to a document at render time and nothing more: a loop\n * drops the card's motion, every clip a template placed and every sound\n * (it must be seamless); a silent channel mutes the bed; a 9:16\n * destination reframes the card (a cover crop that follows the camera,\n * not a letterbox). Pure; the catalog and the words come in as data.\n */\nimport {\n END_CARD_FROM,\n END_CARD_SECONDS,\n applyTemplate,\n docOutputDuration,\n dropTemplate,\n endCardClips,\n migrateMotion,\n ratedSegments,\n sameMedia,\n spanOutputExtent,\n} from '@vosjs/studio-core'\nimport { STEP_SETTLE_SECONDS, stepOutputTime } from './moments'\nimport type {\n Anim,\n AnimKind,\n Destination,\n EndCard,\n Look,\n ProjectDoc,\n TemplateAnchor,\n} from '@vosjs/studio-core'\nimport type { ReleaseWords } from './posterValues'\n\n/** Destinations that play sound (a feed autoplays muted; a demo has a speaker). */\nexport const SOUND_DESTINATIONS = new Set([\n 'x-feed-cut',\n 'youtube-main-demo',\n 'shorts-linkedin-vertical-cut',\n])\n\n/** Destinations that must loop seamlessly: no entrance, no end card, no sound. */\nexport const LOOP_DESTINATIONS = new Set(['github-readme-loop'])\n\nexport interface MusicCatalog {\n tracks: {\n slug: string\n title: string\n mood?: string\n duration: number\n url: string\n }[]\n sfx: { slug: string; title: string; duration: number; url: string }[]\n}\n\n/** The ids the proposals write, so a re-proposal replaces its own work and nothing else. */\nexport const BED_ID = 'bed'\nexport const CLICK_ID_PREFIX = 'click-'\nexport const CAPTION_ID_PREFIX = 'caption-'\n\nexport interface MotionProposalInput {\n words: ReleaseWords\n /** LAUNCH.md roles: music (a slug or mood), entrance, endCard, captions, clicks. */\n launch: Record<string, string>\n /** The end card's ink: the brand's ink over a light ground, white over a dark one. */\n ink?: string | null\n /** The brand's mark for the end card (a take-dir key and its aspect), or none. */\n mark?: { key: string; aspect: number } | null\n /** actions.json steps with their optional captions, by index. */\n captions: { step: number; id?: string; caption: string }[]\n catalog: MusicCatalog | null\n /** The templates the recipe or the flags named, resolved, in order. */\n templates?: MotionTemplate[]\n}\n\nexport interface MotionProposals {\n doc: ProjectDoc\n /** What was proposed, for the phase note. */\n notes: string[]\n /** What could not be proposed, in words. */\n skipped: string[]\n}\n\nconst off = (v: string | undefined) =>\n v !== undefined && /^(none|off|false|no)$/i.test(v.trim())\n\n/** The kinds a boundary moves by. */\nexport type TransitionKind = 'slide' | 'fade' | 'scale'\n\nconst round3 = (v: number): number => Math.round(v * 1000) / 1000\n\n/** A clip on either side of a page change keeps at least this much footage. */\nconst TRANSITION_CLIP_MIN = 1\n\n/**\n * A transition at every page change: a recorded step that navigated (a\n * click, or the wait that let the load land) splits its clip, the outgoing\n * ending on the frame BEFORE the change and the incoming beginning once\n * the page has settled (the load between them is dropped), and the two\n * meet by the kind. A boundary that already sits there is left as it is\n * (a re-plan never doubles a cut); a change too close to a clip's edge is\n * named and skipped. Pure; the primary's steps only.\n */\nexport function proposeTransitions(\n input: ProjectDoc,\n kind: TransitionKind,\n): { doc: ProjectDoc; count: number; skipped: string[] } {\n const doc = structuredClone(input)\n const skipped: string[] = []\n let count = 0\n const steps = doc.source.meta.steps ?? []\n for (const step of steps) {\n if (!step.navigated || step.skipped) continue\n const name = step.id ?? String(step.step)\n const wait = step.do === 'wait'\n const outEnd = round3(wait ? step.tStart : step.tEnd)\n const inStart = round3(wait ? step.tEnd : step.tEnd + STEP_SETTLE_SECONDS)\n const segs = doc.segments\n if (\n segs.some(\n (s) => !s.media && Math.abs(s.out - outEnd) < 0.05 && s !== segs.at(-1),\n )\n )\n continue\n const i = segs.findIndex(\n (s) =>\n !s.media &&\n outEnd >= s.in + TRANSITION_CLIP_MIN &&\n inStart <= s.out - TRANSITION_CLIP_MIN,\n )\n if (i < 0) {\n skipped.push(\n `no transition at step ${name}: the page change sits too close to a clip's edge`,\n )\n continue\n }\n const seg = segs[i]\n const before = { ...seg, out: outEnd, anim: { exit: kind } as Anim }\n const after = { ...seg, in: inStart, anim: { enter: kind } as Anim }\n if (seg.anim?.enter !== undefined) before.anim.enter = seg.anim.enter\n if (seg.anim?.exit !== undefined) after.anim.exit = seg.anim.exit\n doc.segments = [...segs.slice(0, i), before, after, ...segs.slice(i + 1)]\n count++\n }\n return { doc, count, skipped }\n}\n\n/**\n * The bed: LAUNCH.md names a track slug or a mood; a mood picks the first\n * track of that mood. Null when nothing was asked or nothing matched.\n */\nexport function pickTrack(\n catalog: MusicCatalog | null,\n ask: string | undefined,\n): MusicCatalog['tracks'][number] | null {\n if (!catalog || !ask || off(ask)) return null\n const want = ask.trim().toLowerCase()\n return (\n catalog.tracks.find((t) => t.slug.toLowerCase() === want) ??\n catalog.tracks.find((t) => (t.mood ?? '').toLowerCase() === want) ??\n null\n )\n}\n\n/** Click instants of the take in OUTPUT seconds, inside the range. */\nexport function clickTimes(doc: ProjectDoc, range: [number, number]): number[] {\n const rated = ratedSegments(doc)\n const out: number[] = []\n for (const e of doc.source.cursor) {\n if (e.type !== 'down') continue\n const src = e.t / 1000\n const ext = spanOutputExtent(rated, src, src + 0.001)\n if (!ext) continue\n const t = ext.start\n if (t < range[0] || t > range[1]) continue\n if (out.length && t - out[out.length - 1] < 0.12) continue\n out.push(+(t - range[0]).toFixed(3))\n }\n return out\n}\n\nconst outputLength = (doc: ProjectDoc) =>\n ratedSegments(doc).reduce((acc, s) => {\n const rate = s.rate && s.rate > 0 ? s.rate : 1\n return acc + (s.out - s.in) / rate\n }, 0)\n\n/** Where a template lands: the studio-core anchor, or a recorded step's settle. */\nexport type MotionAnchor = TemplateAnchor | { step: string }\n\n/** A template the recipe or a flag named, resolved to its document. */\nexport interface MotionTemplate {\n /** What its clips say they came from (the vos id or the path it was read from). */\n from: string\n doc: ProjectDoc\n at: MotionAnchor\n}\n\n/**\n * The words a template's clips take, by the ids the house templates use:\n * a poster's `stage-*` clips and an end card's `endcard-*` clips. A\n * template with other ids keeps its own words.\n */\nexport function templateWords(words: ReleaseWords): Record<string, string> {\n const headline = (words.headline ?? '').trim()\n const kicker = (words.kicker ?? '').trim()\n const brand = (words.brand ?? '').trim()\n const sub = [brand, (words.release ?? '').trim()].filter(Boolean).join(' ')\n const out: Record<string, string> = {}\n if (headline) {\n out['stage-title'] = headline\n out['endcard-title'] = headline\n }\n if (kicker) out['stage-kicker'] = kicker\n if (brand) {\n out['stage-brand'] = brand\n out['endcard-mark'] = brand\n }\n if (sub && sub !== headline) out['endcard-sub'] = sub\n return out\n}\n\nfunction resolveAnchor(\n doc: ProjectDoc,\n at: MotionAnchor,\n): TemplateAnchor | null {\n if (typeof at !== 'object') return at\n const steps = doc.source.meta.steps ?? []\n const step = steps.find((s) => s.id === at.step || String(s.step) === at.step)\n if (!step || step.skipped) return null\n const t = stepOutputTime(ratedSegments(doc), step, 0.2)\n return t === null ? null : +t.toFixed(3)\n}\n\nconst anchorWord = (at: MotionAnchor): string =>\n typeof at === 'object'\n ? `step ${at.step}`\n : typeof at === 'number'\n ? `${at}s`\n : `the ${at}`\n\nconst onWord = (v: string | undefined) =>\n v === undefined || /^(on|yes|true)$/i.test(v.trim())\n\n/**\n * Propose the cut's motion onto a copy of the document, in the one\n * vocabulary: the card's `anim.enter`, the templates the recipe names\n * laid at their anchors (stamped `from`), the house end card as clips\n * after the footage plus a card exit (`from: 'endcard'`, the migration's\n * shape, until a shelf template replaces it), a caption per beat, a bed\n * and click sounds. Every proposal writes a STABLE id or a `from`, and\n * replaces only its own earlier work, so a maker's clips survive a second\n * pass. A legacy document is read into the vocabulary first.\n */\nexport function proposeMotion(\n input: ProjectDoc,\n opts: MotionProposalInput,\n): MotionProposals {\n let doc = migrateMotion(structuredClone(input))\n const { words, launch, catalog } = opts\n const notes: string[] = []\n const skipped: string[] = []\n const footage = outputLength(doc)\n const range: [number, number] = [0, footage]\n\n // The card's enter: the clip opens on a move.\n const entrance = launch.entrance\n delete doc.frame.entrance\n if (!off(entrance)) {\n const kind =\n entrance && /^(tilt-in|pull-out|rise|fade)$/.test(entrance.trim())\n ? (entrance.trim() as AnimKind)\n : 'tilt-in'\n doc.frame.anim = { ...(doc.frame.anim ?? {}), enter: kind }\n notes.push(`enter ${kind}`)\n } else if (doc.frame.anim?.enter !== undefined) {\n const { enter: _enter, ...rest } = doc.frame.anim\n if (Object.keys(rest).length) doc.frame.anim = rest\n else delete doc.frame.anim\n }\n\n // Page changes: a recorded step that navigated is a cut with a\n // transition at the boundary. LAUNCH.md's `transitions` role picks the\n // kind (slide, the house default; fade; scale; none switches it off).\n const trRole = launch.transitions\n if (!off(trRole)) {\n const trKind =\n trRole && /^(slide|fade|scale)$/.test(trRole.trim())\n ? (trRole.trim() as TransitionKind)\n : 'slide'\n const made = proposeTransitions(doc, trKind)\n doc = made.doc\n if (made.count) notes.push(`${made.count} transition(s) ${trKind}`)\n for (const n of made.skipped) skipped.push(n)\n }\n\n // The end card the recipe names, or the official one the platform holds,\n // arrives as a template stamped `from: 'endcard'` (the house clips below\n // are the offline fallback); a re-plan replaces its earlier work first,\n // and `endCard: none` drops it with the rest.\n const endCardRole = launch.endCard\n doc = dropTemplate(doc, END_CARD_FROM)\n const templates = (opts.templates ?? []).filter(\n (t) => !(t.from === END_CARD_FROM && off(endCardRole)),\n )\n const namedEndCard = templates.some((t) => t.from === END_CARD_FROM)\n\n // The templates the recipe or the flags named, at their anchors: a\n // template is a vos, its clips come stamped with where they came from.\n const tWords = templateWords(words)\n const keys = opts.mark\n ? { 'stage-mark': opts.mark.key, 'endcard-markimg': opts.mark.key }\n : undefined\n for (const t of templates) {\n const at = resolveAnchor(doc, t.at)\n if (at === null) {\n skipped.push(`${t.from}: ${anchorWord(t.at)} was not recorded`)\n continue\n }\n const applied = applyTemplate(t.doc, doc, {\n at,\n from: t.from,\n words: tWords,\n keys,\n })\n doc = applied.doc\n notes.push(`${t.from} at ${anchorWord(t.at)}`)\n for (const n of applied.notes) skipped.push(`${t.from}: ${n}`)\n }\n\n // The end card: on (or absent) with no template in hand is the house\n // shape, a freeze under clips and a card exit; a named or official\n // template took its place above; off drops it.\n if (off(endCardRole)) {\n if (doc.frame.anim?.exit !== undefined) {\n const { exit: _exit, ...rest } = doc.frame.anim\n if (Object.keys(rest).length) doc.frame.anim = rest\n else delete doc.frame.anim\n }\n } else if (onWord(endCardRole) && !namedEndCard) {\n const headline = (words.headline ?? '').trim()\n const brand = (words.brand ?? '').trim()\n const sub = [brand, (words.release ?? '').trim()].filter(Boolean).join(' ')\n if (headline || brand) {\n const card: EndCard = { seconds: END_CARD_SECONDS }\n // Over a light plate the presets' white would vanish: the brand's ink.\n if (opts.ink) card.ink = opts.ink\n if (headline) card.headline = headline\n if (sub && sub !== headline) card.sub = sub\n if (brand) card.wordmark = brand\n if (opts.mark) card.mark = opts.mark\n // The words start where the moving footage ends; the card stays\n // under them as a freeze of its last frame (past its clip the card\n // is gone), receding over the card's seconds.\n const endStart = outputLength(doc)\n const lastSeg = doc.segments.at(-1)\n if (lastSeg) {\n // The last clip may play another media (concat): the freeze\n // names it, or its seconds would land on the primary's footage.\n const atEnd = (f: { at: number; media?: string }) =>\n Math.abs(f.at - lastSeg.out) <= 1e-9 &&\n sameMedia(f.media, lastSeg.media)\n // A freeze the take OWNS at its end survives (its rest, the frame\n // that stands for it) and grows to the card's seconds; only a\n // take with none gets the house freeze, stamped from.\n const kept = (doc.freeze ?? []).find((f) => atEnd(f) && !f.from)\n const own = (doc.freeze ?? []).filter((f) => !atEnd(f))\n const taken = new Set(own.map((f) => f.id))\n let n = 0\n while (taken.has(`f${n}`)) n++\n doc.freeze = [\n ...own,\n kept\n ? { ...kept, seconds: Math.max(kept.seconds, END_CARD_SECONDS) }\n : {\n id: `f${n}`,\n at: lastSeg.out,\n seconds: END_CARD_SECONDS,\n from: END_CARD_FROM,\n ...(lastSeg.media ? { media: lastSeg.media } : {}),\n },\n ].sort((a, b) => a.at - b.at)\n }\n doc.overlays = [\n ...(doc.overlays ?? []),\n ...endCardClips(card, doc, endStart),\n ]\n doc.frame.anim = {\n ...(doc.frame.anim ?? {}),\n exit: { kind: 'recede', seconds: END_CARD_SECONDS },\n }\n notes.push('end card')\n } else {\n skipped.push(\n 'no end card (no headline or wordmark in LAUNCH.md, BRAND.md or the flags)',\n )\n }\n }\n\n // Captions per beat: a step's caption lands at the step's settled moment\n // as a lower-third.\n const kept = (doc.overlays ?? []).filter(\n (o) => !o.id.startsWith(CAPTION_ID_PREFIX),\n )\n const captionClips: NonNullable<ProjectDoc['overlays']> = []\n if (opts.captions.length && !off(launch.captions)) {\n const rated = ratedSegments(doc)\n const steps = doc.source.meta.steps ?? []\n for (const c of opts.captions) {\n const step = steps.find(\n (s) => (c.id !== undefined && s.id === c.id) || s.step === c.step,\n )\n if (!step || step.skipped) continue\n const t = stepOutputTime(rated, step, 0.2)\n if (t === null || t < 0 || t > footage - 1) continue\n captionClips.push({\n id: `${CAPTION_ID_PREFIX}${c.step}`,\n kind: 'text',\n text: c.caption,\n preset: 'caption',\n start: +t.toFixed(3),\n duration: Math.min(3.5, Math.max(2.5, footage - t - 0.2)),\n transform: { x: 0.5, y: 0.86, scale: 1, rotation: 0 },\n anim: { enter: 'rise', exit: 'fade' },\n align: 'center',\n box: { color: 'rgba(17,17,17,0.72)' },\n })\n }\n if (captionClips.length) notes.push(`${captionClips.length} caption(s)`)\n }\n const overlays = [...kept, ...captionClips]\n if (overlays.length) doc.overlays = overlays\n else delete doc.overlays\n\n // Sound: a bed and click sounds. A destination that plays no sound mutes\n // them at render time (`destinationMechanics`); the document carries\n // them, so the studio plays what the demo will. The bed fills the whole\n // OUTPUT, the clips after the footage included.\n const length = docOutputDuration(doc)\n const clips = (doc.audio ?? []).filter(\n (a) => a.id !== BED_ID && !a.id.startsWith(CLICK_ID_PREFIX),\n )\n const track = pickTrack(catalog, launch.music)\n if (track) {\n const hasMic = !!doc.source.micKey\n const fadeOut = Math.min(2.5, length * 0.15)\n clips.push({\n id: BED_ID,\n key: track.url,\n name: track.title,\n start: 0,\n in: 0,\n out: Math.min(track.duration, length),\n duration: track.duration,\n gain: hasMic ? 0.35 : 0.5,\n fadeIn: 0.6,\n fadeOut,\n loop: track.duration < length,\n loopLen:\n track.duration < length ? Math.round(length * 1000) / 1000 : undefined,\n duck: hasMic,\n })\n notes.push(`bed ${track.slug}`)\n } else if (launch.music && !off(launch.music)) {\n skipped.push(\n `music \"${launch.music}\" is not a catalog track or mood${catalog ? '' : ' (the catalog could not be read)'}`,\n )\n }\n const click = catalog?.sfx.find((s) => s.slug === 'sfx-click')\n if (click && !doc.source.micKey && !off(launch.clicks)) {\n const times = clickTimes(doc, range)\n for (const [i, t] of times.entries()) {\n clips.push({\n id: `${CLICK_ID_PREFIX}${i}`,\n key: click.url,\n name: click.title,\n start: t,\n in: 0,\n out: click.duration,\n duration: click.duration,\n gain: 0.4,\n fadeIn: 0,\n fadeOut: 0,\n })\n }\n if (times.length) notes.push(`${times.length} click sound(s)`)\n }\n doc.audio = clips\n\n return { doc, notes, skipped }\n}\n\n/**\n * What a VIDEO destination does to the document at render time, as doc\n * overrides for that one render: the spec's mechanics, never taste.\n */\nexport function destinationMechanics(\n d: Pick<Destination, 'id' | 'kind' | 'px' | 'text'>,\n doc: Pick<ProjectDoc, 'overlays' | 'freeze'>,\n): { set: string[]; unset: string[]; notes: string[] } {\n const set: string[] = []\n const unset: string[] = []\n const notes: string[] = []\n if (d.kind !== 'video') return { set, unset, notes }\n const loop = LOOP_DESTINATIONS.has(d.id)\n const sound = SOUND_DESTINATIONS.has(d.id)\n const portrait = d.px.w / d.px.h < 0.9\n\n if (loop) {\n // Seamless by contract: the card neither arrives nor leaves, nothing a\n // template placed plays, nothing sounds. The two legacy spellings go\n // with it for a document read unmigrated.\n unset.push('frame.anim', 'frame.entrance', 'endCard')\n notes.push('loop: no card motion')\n }\n if (loop || !sound) {\n set.push('audio=[]')\n if (!loop) notes.push('silent channel')\n }\n if (loop || d.text === 'none') {\n // A destination that takes no words drops the beat captions; a loop\n // drops every clip a template placed too. A maker's own titles stay.\n const kept = (doc.overlays ?? []).filter(\n (o) => !o.id.startsWith(CAPTION_ID_PREFIX) && !(loop && o.from),\n )\n if (kept.length !== (doc.overlays ?? []).length) {\n set.push(`overlays=${JSON.stringify(kept)}`)\n notes.push(loop ? 'no template clips, no captions' : 'no captions')\n }\n }\n if (loop) {\n // The freeze a template placed under its clips goes with the clips.\n const keptFreezes = (doc.freeze ?? []).filter((f) => !f.from)\n if (keptFreezes.length !== (doc.freeze ?? []).length)\n set.push(`freeze=${JSON.stringify(keptFreezes)}`)\n }\n if (portrait) {\n // The vertical cut is a reframe, not a letterbox: the card is the tall\n // inset area, the footage cover-fills it, and the crop follows the camera.\n set.push('frame.fit=cover')\n set.push('frame.inset={\"left\":0.06,\"right\":0.06,\"top\":0.17,\"bottom\":0.17}')\n set.push('frame.focusFollow=camera')\n notes.push('vertical reframe follows the camera')\n }\n return { set, unset, notes }\n}\n\n/**\n * The end card's ink: the brand's ink (or near-black) over a light ground,\n * white over a dark one, decided from the look's ground.\n */\nexport function endCardInk(\n look: Look | null | undefined,\n brand: Record<string, string> | null | undefined,\n): string | null {\n if (!look) return null\n const ground = look.ground\n const m = /#([0-9a-f]{6})/i.exec(ground)\n const hex = m ? m[0] : null\n const light =\n look.kind === 'plate' ||\n (hex ? isLightHexGround(hex) : look.kind === 'gradient')\n if (!light) return '#ffffff'\n const ink = brand?.ink\n return ink && /^#[0-9a-f]{6}$/i.test(ink) ? ink : '#111111'\n}\n\nfunction isLightHexGround(hex: string): boolean {\n const n = parseInt(hex.slice(1), 16)\n const r = (n >> 16) & 255\n const g = (n >> 8) & 255\n const b = n & 255\n return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255 >= 0.6\n}\n","/**\n * POSTER DOCUMENTS beside a take. A poster is a plain take document (the\n * card placed by `frame.inset`, leaned by the tilt track, the words and the\n * mark as overlay clips, a trailing hold whose start is the still) that an\n * agent or the studio wrote and pushed; `vos deliver` RENDERS the ones it\n * finds and composes nothing. Found by aspect CLASS beside the take\n * (`poster/<class>/doc.json`, or `poster/doc.json` for every class), or\n * named in LAUNCH.md (`poster: <path>`, `poster-landscape: <path>`, …). A\n * path names a doc.json, or a take directory holding one (a pulled poster\n * take renders over its own footage; a bare doc.json renders over this\n * take's).\n *\n * The picture checks read the text boxes and the shot rect FROM THE\n * DOCUMENT, by the same layout the studio and the render use: the card\n * rect from `computeCardLayout`, the text boxes from `overlayRect` with an\n * estimating measure (no canvas here; the boxes are a fraction wide at\n * worst, which the checks tolerate). Pure except `findPosterDocs`.\n */\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport {\n computeCardLayout,\n docStillTime,\n migrateHostedDoc,\n overlayRect,\n resolveOverlayStyle,\n} from '@vosjs/studio-core'\nimport { readSyncState } from './platform'\nimport type { TextBox } from './kitPicture'\nimport type { ProjectDoc } from '@vosjs/studio-core'\n\nexport type PosterClass = 'landscape' | 'square' | 'portrait' | 'tile'\nexport const POSTER_CLASSES: PosterClass[] = [\n 'landscape',\n 'square',\n 'portrait',\n 'tile',\n]\n\n/** A destination under this long side is a tile: the subject large, few words. */\nexport const TILE_MAX_PX = 700\n\n/** The aspect class a destination's pixels ask for. */\nexport function posterClassFor(px: { w: number; h: number }): PosterClass {\n if (Math.max(px.w, px.h) < TILE_MAX_PX) return 'tile'\n const r = px.w / Math.max(1, px.h)\n if (r < 0.87) return 'portrait'\n if (r <= 1.15) return 'square'\n return 'landscape'\n}\n\nexport interface PosterRef {\n /** The class it serves. */\n cls: PosterClass\n /** The doc.json read. */\n file: string\n /** The take directory whose footage it renders over. */\n takeDir: string\n /** True when the poster is its own take directory (pulled with its footage). */\n ownFootage: boolean\n doc: ProjectDoc\n /** The hosted vos the poster tracks (its vos.json), when it does. */\n vosId?: string\n /** Where the reference came from, for the phase note. */\n from: string\n}\n\nconst ROLE_ALL = 'poster'\nconst roleFor = (cls: PosterClass) => `poster-${cls}`\n\nasync function readPosterAt(\n cls: PosterClass,\n path: string,\n takeDir: string,\n from: string,\n): Promise<PosterRef | null> {\n let file = path\n let docDir = path\n if (existsSync(join(path, 'doc.json'))) {\n file = join(path, 'doc.json')\n } else if (!/\\.json$/i.test(path) || !existsSync(path)) {\n return null\n } else {\n docDir = resolve(path, '..')\n }\n let raw: unknown\n try {\n raw = JSON.parse(await readFile(file, 'utf8'))\n } catch {\n return null\n }\n if (!raw || typeof raw !== 'object') return null\n const source = (raw as { source?: { videoKey?: unknown } }).source\n if (!source || typeof source.videoKey !== 'string') return null\n const doc = migrateHostedDoc(\n raw as Record<string, unknown>,\n ) as unknown as ProjectDoc\n const ownFootage =\n existsSync(join(docDir, 'meta.json')) &&\n existsSync(join(docDir, source.videoKey))\n const sync = readSyncState(docDir)\n return {\n cls,\n file,\n takeDir: ownFootage ? docDir : takeDir,\n ownFootage,\n doc,\n ...(sync?.vosId ? { vosId: sync.vosId } : {}),\n from,\n }\n}\n\n/**\n * The poster document per class, from LAUNCH.md's roles first (a class\n * role over the all-classes role), then the folder convention beside the\n * take. A class with none is absent; the caller says so in words.\n */\nexport async function findPosterDocs(\n takeDir: string,\n launchRoles: Record<string, string> | null | undefined,\n): Promise<Partial<Record<PosterClass, PosterRef>>> {\n const out: Partial<Record<PosterClass, PosterRef>> = {}\n const at = (p: string) => (isAbsolute(p) ? p : resolve(takeDir, p))\n for (const cls of POSTER_CLASSES) {\n const named = launchRoles?.[roleFor(cls)] ?? launchRoles?.[ROLE_ALL]\n const candidates: { path: string; from: string }[] = []\n if (named && !/^(none|off|no|false)$/i.test(named.trim())) {\n const role = launchRoles?.[roleFor(cls)] ? roleFor(cls) : ROLE_ALL\n candidates.push({ path: at(named.trim()), from: `LAUNCH.md ${role}` })\n }\n candidates.push({\n path: join(takeDir, 'poster', cls),\n from: `poster/${cls}`,\n })\n candidates.push({ path: join(takeDir, 'poster'), from: 'poster' })\n for (const c of candidates) {\n const ref = await readPosterAt(cls, c.path, takeDir, c.from)\n if (ref) {\n out[cls] = ref\n break\n }\n }\n }\n return out\n}\n\n/**\n * The still's OUTPUT time: the rest (where the last freeze begins), else\n * the footage's last frame (the last frame the card is on; past its clip\n * the card is gone, so the output's last frame may hold no card at all).\n */\nexport function posterStillTime(doc: ProjectDoc, duration: number): number {\n // One derivation with the shelf's cover and the stills export: the\n // author's still, else the document's own last freeze (the rest), else\n // the hero after the opening has entered.\n return Math.max(0, Math.min(duration, docStillTime(doc)))\n}\n\nconst DESIGN_H = 1080\n\n/** The design frame the document lays out on at the destination's aspect. */\nfunction designFrame(px: { w: number; h: number }) {\n return {\n W: Math.max(2, Math.round((DESIGN_H * px.w) / Math.max(1, px.h))),\n H: DESIGN_H,\n }\n}\n\n/** Where the card sits, as fractions of the asset (a bleed runs past 1 or below 0). */\nexport function posterShotRect(\n doc: ProjectDoc,\n px: { w: number; h: number },\n): { x: number; y: number; w: number; h: number } {\n const { W, H } = designFrame(px)\n const meta = doc.source.meta\n const layout = computeCardLayout(\n doc.frame,\n {\n width: meta.captureWidth ?? meta.width,\n height: meta.captureHeight ?? meta.height,\n },\n W,\n H,\n )\n const r3 = (v: number) => Math.round(v * 1000) / 1000\n return {\n x: r3(layout.cardX / W),\n y: r3(layout.cardY / H),\n w: r3(layout.cardW / W),\n h: r3(layout.cardH / H),\n }\n}\n\n/** An estimating text measure: no canvas here, so a glyph is ~0.55 em. */\nfunction estimateWidth(text: string, font: string, letterSpacingPx = 0) {\n const m = /(\\d+(?:\\.\\d+)?)px/.exec(font)\n const px = m ? Number(m[1]) : 32\n return text.length * (px * 0.55 + letterSpacingPx)\n}\n\n/**\n * The text boxes of the clips on screen at `time`, as fractions of the\n * asset, with the role and colour the contrast check reads.\n */\nexport function posterTextBoxes(\n doc: ProjectDoc,\n px: { w: number; h: number },\n time: number,\n): TextBox[] {\n const { W, H } = designFrame(px)\n const out: TextBox[] = []\n for (const clip of doc.overlays ?? []) {\n if (clip.kind !== 'text') continue\n if (time < clip.start || time > clip.start + clip.duration) continue\n const rect = overlayRect(clip, estimateWidth, W, H)\n const style = resolveOverlayStyle(clip)\n const r3 = (v: number) => Math.round(v * 1000) / 1000\n out.push({\n x: r3((rect.cx - rect.w / 2) / W),\n y: r3((rect.cy - rect.h / 2) / H),\n w: r3(rect.w / W),\n h: r3(rect.h / H),\n role: clip.preset === 'title' ? 'headline' : 'body',\n label: clip.text.split('\\n')[0].slice(0, 40),\n ...(/^#[0-9a-f]{6}$/i.test(style.color) ? { color: style.color } : {}),\n })\n }\n return out\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 brand's MARK as a file: what `vos brand` recorded as `logoUrl` (and\n * its on-dark twin), fetched once into the take's `brand/` folder so the\n * render page can load it from the take server (the site's own URL rarely\n * carries a CORS header, and a cross-origin image taints the canvas), with\n * its aspect read from the bytes. The parsers are pure.\n */\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { isAbsolute, join, resolve } from 'node:path'\n\nexport type MarkExt = 'svg' | 'png' | 'webp' | 'jpg'\n\nexport interface BrandMark {\n /** The key the render page loads: a take-dir path like `/brand/mark.svg`. */\n key: string\n /** Width over height. */\n aspect: number\n}\n\nexport interface BrandMarks {\n /** The mark for light grounds (BRAND.md `logoUrl`). */\n light: BrandMark | null\n /** The mark for dark grounds (BRAND.md `logoOnDarkUrl`). */\n dark: BrandMark | null\n /** What could not be fetched or read, in words. */\n notes: string[]\n}\n\n/** The file kind a mark URL or path names; null for anything else (an .ico, a data URL). */\nexport function markExtension(url: string): MarkExt | null {\n const m = /\\.(svg|png|webp|jpe?g)(?:[?#]|$)/i.exec(url)\n if (!m) return null\n const e = m[1].toLowerCase()\n return e === 'jpeg' ? 'jpg' : (e as MarkExt)\n}\n\n/** Width over height from the bytes: an SVG's viewBox or width/height, a PNG's IHDR, a WebP's VP8/VP8L/VP8X header, a JPEG's SOF. Null when unreadable. */\nexport function imageAspect(bytes: Uint8Array, ext: MarkExt): number | null {\n if (ext === 'svg') {\n const head = new TextDecoder().decode(bytes.subarray(0, 4096))\n const vb =\n /viewBox\\s*=\\s*[\"']\\s*[-\\d.]+[\\s,]+[-\\d.]+[\\s,]+([\\d.]+)[\\s,]+([\\d.]+)/i.exec(\n head,\n )\n if (vb) return ratio(+vb[1], +vb[2])\n const w = /<svg[^>]*\\swidth\\s*=\\s*[\"']([\\d.]+)/i.exec(head)\n const h = /<svg[^>]*\\sheight\\s*=\\s*[\"']([\\d.]+)/i.exec(head)\n if (w && h) return ratio(+w[1], +h[1])\n return null\n }\n const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n if (ext === 'png') {\n if (bytes.length < 24 || bytes[0] !== 0x89 || bytes[1] !== 0x50) return null\n return ratio(dv.getUint32(16), dv.getUint32(20))\n }\n if (ext === 'webp') {\n if (bytes.length < 30) return null\n const tag = String.fromCharCode(...bytes.subarray(12, 16))\n if (tag === 'VP8X')\n return ratio(\n 1 + (dv.getUint32(24, true) & 0xffffff),\n 1 + (dv.getUint32(27, true) & 0xffffff),\n )\n if (tag === 'VP8L') {\n const b = dv.getUint32(21, true)\n return ratio(1 + (b & 0x3fff), 1 + ((b >> 14) & 0x3fff))\n }\n if (tag === 'VP8 ')\n return ratio(\n dv.getUint16(26, true) & 0x3fff,\n dv.getUint16(28, true) & 0x3fff,\n )\n return null\n }\n if (ext === 'jpg') {\n let i = 2\n while (i + 9 < bytes.length) {\n if (bytes[i] !== 0xff) return null\n const marker = bytes[i + 1]\n const len = dv.getUint16(i + 2)\n if (\n marker >= 0xc0 &&\n marker <= 0xcf &&\n marker !== 0xc4 &&\n marker !== 0xc8 &&\n marker !== 0xcc\n ) {\n return ratio(dv.getUint16(i + 7), dv.getUint16(i + 5))\n }\n i += 2 + len\n }\n return null\n }\n return null\n}\n\nfunction ratio(w: number, h: number): number | null {\n return w > 0 && h > 0 ? w / h : null\n}\n\n/**\n * Fetch the brand's marks into `<takeDir>/brand/` and read their aspects.\n * A role may be a URL or a path (relative to the take). Absent roles are\n * absent marks; a failed fetch or an unreadable file is a note, never an\n * error: the kit falls back to the wordmark in words.\n */\nexport async function fetchBrandMarks(\n takeDir: string,\n roles: Record<string, string> | null | undefined,\n): Promise<BrandMarks> {\n const out: BrandMarks = { light: null, dark: null, notes: [] }\n if (!roles) return out\n const one = async (\n role: 'logoUrl' | 'logoOnDarkUrl',\n name: string,\n ): Promise<BrandMark | null> => {\n const src = (roles[role] ?? '').trim()\n if (!src) return null\n const ext = markExtension(src)\n if (!ext) {\n out.notes.push(\n `${role}: ${src} is not an svg, png, webp or jpg; the wordmark stands in`,\n )\n return null\n }\n let bytes: Uint8Array\n try {\n if (/^https?:/i.test(src)) {\n const res = await fetch(src)\n if (!res.ok) throw new Error(`HTTP ${res.status}`)\n bytes = new Uint8Array(await res.arrayBuffer())\n } else {\n const file = isAbsolute(src) ? src : resolve(takeDir, src)\n if (!existsSync(file)) throw new Error('no such file')\n bytes = new Uint8Array(await readFile(file))\n }\n } catch (e) {\n out.notes.push(\n `${role}: ${src} could not be read (${e instanceof Error ? e.message : String(e)}); the wordmark stands in`,\n )\n return null\n }\n const aspect = imageAspect(bytes, ext)\n if (!aspect) {\n out.notes.push(\n `${role}: ${src} has no readable size; the wordmark stands in`,\n )\n return null\n }\n await mkdir(join(takeDir, 'brand'), { recursive: true })\n await writeFile(join(takeDir, 'brand', `${name}.${ext}`), bytes)\n return { key: `/brand/${name}.${ext}`, aspect }\n }\n out.light = await one('logoUrl', 'mark')\n out.dark = await one('logoOnDarkUrl', 'mark-on-dark')\n return out\n}\n","/**\n * The official templates on vos.so, found by TITLE on the official shelf\n * (`GET /api/vos/official`): the platform's `Templates` project, promoted,\n * is the registry, so a template is a document anyone can read and the\n * CLI carries no numbers of its own. A ref that is neither a file nor a\n * vos id resolves here (`--with \"End card\"`, `--style \"Split cover,\n * landscape\"`, `--style split-cover-square`: the match ignores case,\n * spaces and punctuation), and the end card `plan` proposes when the\n * recipe says `on` (or nothing) is the official `End card`; the house\n * clips in `motionPlan.ts` survive as the offline fallback only.\n */\n\n/** The official end card's title. */\nexport const OFFICIAL_END_CARD_TITLE = 'End card'\n\n/** The official split cover's title per aspect class. */\nexport const OFFICIAL_POSTER_TITLES = {\n landscape: 'Split cover, landscape',\n square: 'Split cover, square',\n portrait: 'Split cover, portrait',\n tile: 'Split cover, tile',\n} as const\n\n/** A title or a ref reduced to what identifies it: lowercase, letters and digits only. */\nexport function templateKey(s: string): string {\n return s.toLowerCase().replace(/[^a-z0-9]+/g, '')\n}\n\nexport interface OfficialRow {\n id: string\n title: string\n slug?: string\n}\n\n/**\n * The official vos a ref names, by its title (or its slug), or null. The\n * first match in the shelf's own order wins, so a duplicate title on the\n * gallery resolves to the one the founder sorted first.\n */\nexport function findOfficialByRef(\n rows: readonly OfficialRow[],\n ref: string,\n): OfficialRow | null {\n const key = templateKey(ref)\n if (!key) return null\n for (const row of rows) {\n if (templateKey(row.title) === key) return row\n if (row.slug && templateKey(row.slug) === key) return row\n }\n return null\n}\n","/**\n * The music catalog the platform publishes at `GET /api/music`: the\n * curated CC0 tracks (slug, mood, duration, an absolute URL on the assets\n * host) and the built-in sound effects. Read once per run when a\n * destination plays sound; a failed read is said and the cut stays silent.\n */\nimport type { MusicCatalog } from './motionPlan'\n\nexport async function fetchMusicCatalog(origin: string): Promise<MusicCatalog> {\n const base = origin.replace(/\\/+$/, '')\n const res = await fetch(`${base}/api/music`)\n if (!res.ok) throw new Error(`GET ${base}/api/music answered ${res.status}`)\n const body = (await res.json()) as Partial<MusicCatalog>\n return {\n tracks: Array.isArray(body.tracks) ? body.tracks : [],\n sfx: Array.isArray(body.sfx) ? body.sfx : [],\n }\n}\n","/**\n * `vos judge <kit.json> --against <manifest.json>`: the kit beside its\n * references, composed as sheets an agent (or a person) judges pairwise.\n * No model runs here: for every kit asset that has a reference of its\n * role, the verb writes two sheets (the asset left and right, so order\n * cannot bias the call), a rubric in words, and a verdict slot the judge\n * fills; a summary counts the wins. The reference set is the maker's own\n * (a private fixture folder with a manifest), never redistributed.\n */\nimport { existsSync } from 'node:fs'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { DESTINATIONS } from '@vosjs/studio-core'\nimport { decodePng } from './picture'\nimport { encodePng } from './shotBake'\nimport type { Rgba } from './picture'\nimport type { KitRecord } from './validateKit'\n\nexport interface ReferenceAsset {\n id: string\n file: string\n /** What a kit asset matches on: a template family, a card genre, a video's first frame. */\n role: string\n genre: 'card' | 'video' | 'context' | 'screenshot'\n layout: string\n facts?: Record<string, unknown>\n rule: string\n}\n\nexport interface ReferenceManifest {\n assets: ReferenceAsset[]\n}\n\n/** The rubric every sheet carries: the eight clip rules and the poster layout facts. */\nexport const RUBRIC = [\n 'A plate, and room on it: the subject sits at 74 to 89% of the width with headroom; nobody bleeds a window on all four sides.',\n 'The window is an object: rounded corners and a shadow with weight (a soft wide one on a light plate, a tight glow on a dark one).',\n 'It enters: the first frame is not a static, centred, flat window (a tilt-in, a pull-out, a rise).',\n 'The camera zooms to the affordance, holds through the response, and pulls out to show the consequence.',\n 'Beats are cut at stillness; no wipes.',\n 'Content is staged: real data, a populated state, never an empty canvas or a wallpaper.',\n 'The cursor is a character: visible, smoothed, a press on click, never drifting through dead space.',\n 'The last frame is a poster: a resolved state you could ship as the still.',\n 'The message has its own column or its own frame; the headline is two to six words over up to three lines at about 40% of the height; the wordmark is anchored.',\n 'The poster test: would you post this frame as a still, alone?',\n 'The thumbnail test: does it read at half size?',\n 'Name three ways this asset acknowledges THIS product (its data, its state, its brand), not a generic window.',\n]\n\n/** Which reference roles a kit asset can be judged against. */\nexport function rolesFor(asset: {\n destination?: string\n source?: string\n template?: string\n path: string\n}): string[] {\n if ((asset.source === 'poster' || asset.source === 'stage') && asset.template)\n return [asset.template.replace(/-stage$/, '')]\n const spec = DESTINATIONS.find((d) => d.id === asset.destination)\n if (spec?.kind === 'video') {\n const portrait = spec.px.w < spec.px.h\n return portrait ? ['feature-clip', 'site-walkthrough'] : ['feature-clip', 'site-walkthrough', 'feature-clip-dark']\n }\n if (spec?.genre === 'card') return ['window-in-scene', 'card-on-gradient', 'framed-screenshot']\n if (spec?.genre === 'screenshot') return ['framed-screenshot', 'app-session']\n return []\n}\n\n/** Box-filter resample to `w`×`h` (a clean downscale; upscales bilinearly enough for a sheet). */\nexport function resample(img: Rgba, w: number, h: number): Rgba {\n const out = new Uint8Array(w * h * 4)\n const sx = img.w / w\n const sy = img.h / h\n for (let y = 0; y < h; y++) {\n const y0 = Math.floor(y * sy)\n const y1 = Math.max(y0 + 1, Math.floor((y + 1) * sy))\n for (let x = 0; x < w; x++) {\n const x0 = Math.floor(x * sx)\n const x1 = Math.max(x0 + 1, Math.floor((x + 1) * sx))\n let r = 0\n let g = 0\n let b = 0\n let a = 0\n let n = 0\n for (let yy = y0; yy < y1 && yy < img.h; yy++) {\n for (let xx = x0; xx < x1 && xx < img.w; xx++) {\n const o = (yy * img.w + xx) * 4\n r += img.data[o]\n g += img.data[o + 1]\n b += img.data[o + 2]\n a += img.data[o + 3]\n n++\n }\n }\n const o = (y * w + x) * 4\n out[o] = n ? r / n : 0\n out[o + 1] = n ? g / n : 0\n out[o + 2] = n ? b / n : 0\n out[o + 3] = n ? a / n : 0\n }\n }\n return { w, h, data: out }\n}\n\n/**\n * Two pictures on one sheet at a common height with a gutter, on the\n * plate ground; `left` first. A thin band under each marks its side (a\n * dark band left, a light band right) so the order can be read back\n * without type.\n */\nexport function composeSheet(left: Rgba, right: Rgba, height = 540, gutter = 32): Rgba {\n const lw = Math.max(1, Math.round((left.w * height) / left.h))\n const rw = Math.max(1, Math.round((right.w * height) / right.h))\n const L = resample(left, lw, height)\n const R = resample(right, rw, height)\n const margin = 24\n const band = 8\n const w = margin * 2 + lw + gutter + rw\n const h = margin * 2 + height + band + 6\n const out = new Uint8Array(w * h * 4)\n for (let i = 0; i < w * h; i++) {\n out[i * 4] = 240\n out[i * 4 + 1] = 242\n out[i * 4 + 2] = 244\n out[i * 4 + 3] = 255\n }\n const blit = (src: Rgba, x0: number, y0: number) => {\n for (let y = 0; y < src.h; y++) {\n for (let x = 0; x < src.w; x++) {\n const si = (y * src.w + x) * 4\n const a = src.data[si + 3] / 255\n const o = ((y0 + y) * w + x0 + x) * 4\n for (let c = 0; c < 3; c++) out[o + c] = Math.round(src.data[si + c] * a + out[o + c] * (1 - a))\n }\n }\n }\n blit(L, margin, margin)\n blit(R, margin + lw + gutter, margin)\n const fill = (x0: number, x1: number, y0: number, y1: number, v: number) => {\n for (let y = y0; y < y1; y++)\n for (let x = x0; x < x1; x++) {\n const o = (y * w + x) * 4\n out[o] = v\n out[o + 1] = v\n out[o + 2] = v\n }\n }\n fill(margin, margin + lw, margin + height + 6, margin + height + 6 + band, 40)\n fill(margin + lw + gutter, margin + lw + gutter + rw, margin + height + 6, margin + height + 6 + band, 200)\n return { w, h, data: out }\n}\n\nexport interface JudgeSheet {\n asset: string\n reference: string\n /** The two sheets: A = asset left, B = reference left. */\n sheetA: string\n sheetB: string\n rubric: string\n}\n\nexport interface JudgeResult {\n sheets: JudgeSheet[]\n skipped: string[]\n outDir: string\n verdictFile: string\n}\n\n/**\n * Compose the sheets for a kit against a manifest. For each still asset\n * with a reference of its role, the two orders and the rubric; the verdict\n * file is a JSON skeleton the judge fills (`win: true|false|null` per\n * sheet, with a reason) and `count.mjs` reads.\n */\nexport async function judgeKit(\n kitPath: string,\n manifestPath: string,\n outDir?: string,\n): Promise<JudgeResult> {\n const kit = JSON.parse(await readFile(kitPath, 'utf8')) as KitRecord & {\n assets: (KitRecord['assets'][number] & { template?: string })[]\n }\n const manifest = JSON.parse(await readFile(manifestPath, 'utf8')) as ReferenceManifest\n const manifestDir = dirname(resolve(manifestPath))\n const kitDir = dirname(resolve(kitPath))\n const out = resolve(outDir ?? join(kitDir, 'judge'))\n await mkdir(out, { recursive: true })\n const sheets: JudgeSheet[] = []\n const skipped: string[] = []\n const refCache = new Map<string, Rgba | null>()\n const loadRef = async (file: string) => {\n if (refCache.has(file)) return refCache.get(file) ?? null\n const p = join(manifestDir, file)\n const img = existsSync(p) ? decodePng(new Uint8Array(await readFile(p))) : null\n refCache.set(file, img)\n return img\n }\n for (const a of kit.assets) {\n if (!/\\.png$/i.test(a.path)) continue\n const file = isAbsolute(a.path) && existsSync(a.path) ? a.path : join(kitDir, a.path.split('/').pop() ?? a.path)\n const img = existsSync(file) ? decodePng(new Uint8Array(await readFile(file))) : null\n if (!img) {\n skipped.push(`${a.destination ?? a.path}: unreadable`)\n continue\n }\n const roles = rolesFor({ destination: a.destination, source: a.source, template: a.template, path: a.path })\n const ref = manifest.assets.find((r) => roles.includes(r.role) && r.genre !== 'context')\n if (!ref) {\n skipped.push(`${a.destination ?? a.path}: no reference of role ${roles.join('|') || '(none)'}`)\n continue\n }\n const refImg = await loadRef(ref.file)\n if (!refImg) {\n skipped.push(`${a.destination ?? a.path}: reference ${ref.file} unreadable`)\n continue\n }\n // A still set's members share a destination: the file's own stem is the id.\n const stem = (a.path.split('/').pop() ?? a.path).replace(/\\.png$/i, '')\n const id = stem.replace(/[^A-Za-z0-9_-]+/g, '-') || a.destination || 'asset'\n const nameA = `${id}--A.png`\n const nameB = `${id}--B.png`\n await writeFile(join(out, nameA), encodePng(composeSheet(img, refImg)))\n await writeFile(join(out, nameB), encodePng(composeSheet(refImg, img)))\n const rubric = [\n `# ${id} against ${ref.id} (${ref.file})`,\n '',\n `Sheet A: the kit asset LEFT (dark band), the reference RIGHT (light band). Sheet B: the reverse.`,\n `Judge each sheet on its own, both orders, and write the verdict where the two agree; a disagreement is a tie.`,\n '',\n `## The reference`,\n ref.layout,\n ...(ref.facts ? ['', '```json', JSON.stringify(ref.facts, null, 2), '```'] : []),\n '',\n `Rule: ${ref.rule}`,\n '',\n '## The rubric',\n ...RUBRIC.map((r, i) => `${i + 1}. ${r}`),\n '',\n '## Verdict',\n 'In judge.json: `win` true when the kit asset is at least as good as the reference on the rules that apply to its genre, false when it is worse, null for a tie; `reasons` names the rules by number.',\n '',\n ].join('\\n')\n await writeFile(join(out, `${id}.md`), rubric)\n sheets.push({ asset: id, reference: ref.id, sheetA: nameA, sheetB: nameB, rubric: `${id}.md` })\n }\n const verdictFile = join(out, 'judge.json')\n if (!existsSync(verdictFile)) {\n await writeFile(\n verdictFile,\n JSON.stringify(\n {\n kit: kitPath,\n manifest: manifestPath,\n verdicts: sheets.map((s) => ({ asset: s.asset, reference: s.reference, A: null, B: null, win: null, reasons: [] })),\n },\n null,\n 2,\n ),\n )\n }\n return { sheets, skipped, outDir: out, verdictFile }\n}\n\n/**\n * The win rate: a win counts one, a tie (`win: null` with reasons) counts a\n * half, the pairwise convention; a pair with no reasons was not judged and\n * does not count. Parity with the references is 0.5.\n */\nexport function winRate(\n verdicts: { win: boolean | null; reasons?: number[] }[],\n): { wins: number; ties: number; judged: number; rate: number | null } {\n const judgedList = verdicts.filter((v) => v.win !== null || (v.reasons?.length ?? 0) > 0)\n const wins = judgedList.filter((v) => v.win === true).length\n const ties = judgedList.filter((v) => v.win === null).length\n const judged = judgedList.length\n return { wins, ties, judged, rate: judged ? (wins + ties / 2) / judged : null }\n}\n","/**\n * The shot as an OBJECT: a full-bleed page capture padded with a\n * transparent margin, its corners rounded, a soft shadow under it, encoded\n * back to PNG. The image element the poster family binds carries none of\n * these (an engine ask), so the shot arrives already sitting on whatever\n * ground the template paints. Pure over decoded pixels; the blur is a\n * three-pass box blur (a gaussian to the eye) on the alpha mask.\n */\nimport { deflateSync } from 'node:zlib'\nimport type { Rgba } from './picture'\n\nexport interface BakeOptions {\n /** Transparent margin around the shot, as a fraction of its width (0.06). */\n margin?: number\n /** Corner radius as a fraction of the shot's width (0.014). */\n radius?: number\n /**\n * Shadow strength 0..1 (0.3); 0 = no shadow. Two layers share it: a\n * tight one at the edge and a wide one below, each at a low alpha, so\n * the shot reads as lifted rather than sitting in a dark pool.\n */\n shadow?: number\n /** The wide layer's blur radius as a fraction of the shot's width (0.05). */\n blur?: number\n /** The wide layer's offset downward as a fraction of the shot's width (0.02). */\n offsetY?: number\n /** A hairline around the shot, alpha 0..1 (0 = none), for light shots on light grounds. */\n hairline?: number\n}\n\n/** Box blur one channel of a w×h float plane, radius r, in place; three passes. */\nfunction blurPlane(\n src: Float32Array,\n w: number,\n h: number,\n r: number,\n passes = 3,\n) {\n if (r < 1) return\n const tmp = new Float32Array(src.length)\n for (let p = 0; p < passes; p++) {\n // horizontal\n for (let y = 0; y < h; y++) {\n let acc = 0\n const row = y * w\n for (let x = -r; x <= r; x++)\n acc += src[row + Math.min(w - 1, Math.max(0, x))]\n for (let x = 0; x < w; x++) {\n tmp[row + x] = acc / (2 * r + 1)\n const add = src[row + Math.min(w - 1, x + r + 1)]\n const sub = src[row + Math.max(0, x - r)]\n acc += add - sub\n }\n }\n // vertical\n for (let x = 0; x < w; x++) {\n let acc = 0\n for (let y = -r; y <= r; y++)\n acc += tmp[Math.min(h - 1, Math.max(0, y)) * w + x]\n for (let y = 0; y < h; y++) {\n src[y * w + x] = acc / (2 * r + 1)\n const add = tmp[Math.min(h - 1, y + r + 1) * w + x]\n const sub = tmp[Math.max(0, y - r) * w + x]\n acc += add - sub\n }\n }\n }\n}\n\n/** Coverage of a rounded rect at pixel (x, y) with 2x2 supersampling, 0..1. */\nfunction roundedCoverage(\n x: number,\n y: number,\n rect: { x: number; y: number; w: number; h: number },\n r: number,\n): number {\n let inside = 0\n for (const dy of [0.25, 0.75]) {\n for (const dx of [0.25, 0.75]) {\n const px = x + dx\n const py = y + dy\n if (\n px < rect.x ||\n py < rect.y ||\n px > rect.x + rect.w ||\n py > rect.y + rect.h\n )\n continue\n const cx = Math.min(Math.max(px, rect.x + r), rect.x + rect.w - r)\n const cy = Math.min(Math.max(py, rect.y + r), rect.y + rect.h - r)\n if ((px - cx) ** 2 + (py - cy) ** 2 <= r * r) inside++\n }\n }\n return inside / 4\n}\n\n/** Pad, round and shadow a shot. The output is RGBA with a transparent margin. */\nexport function bakeShot(shot: Rgba, opts: BakeOptions = {}): Rgba {\n const margin = Math.round(shot.w * (opts.margin ?? 0.06))\n const radius = shot.w * (opts.radius ?? 0.014)\n const shadowA = opts.shadow ?? 0.3\n const blur = Math.round(shot.w * (opts.blur ?? 0.05))\n const offsetY = Math.round(shot.w * (opts.offsetY ?? 0.02))\n const hair = opts.hairline ?? 0\n const w = shot.w + margin * 2\n const h = shot.h + margin * 2\n const out = new Uint8Array(w * h * 4)\n const rect = { x: margin, y: margin, w: shot.w, h: shot.h }\n\n if (shadowA > 0) {\n // Two layers: tight at the edge (a quarter of the blur, a fifth of the\n // offset, 0.4 of the strength) and wide below (0.6 of the strength).\n const layers: [number, number, number][] = [\n [Math.max(1, Math.round(blur / 4)), Math.round(offsetY / 5), 0.4],\n [blur, offsetY, 0.6],\n ]\n const acc = new Float32Array(w * h)\n for (const [lb, lo, share] of layers) {\n const mask = new Float32Array(w * h)\n for (let y = 0; y < h; y++)\n for (let x = 0; x < w; x++) {\n const c = roundedCoverage(x, y - lo, rect, radius)\n if (c > 0) mask[y * w + x] = c\n }\n blurPlane(mask, w, h, Math.max(1, Math.round(lb / 2)))\n const a = shadowA * share\n // Layers composite over each other: 1 - (1-a1)(1-a2).\n for (let i = 0; i < w * h; i++)\n acc[i] = 1 - (1 - acc[i]) * (1 - mask[i] * a)\n }\n for (let i = 0; i < w * h; i++) {\n const a = acc[i]\n if (a <= 0.002) continue\n out[i * 4] = 0\n out[i * 4 + 1] = 0\n out[i * 4 + 2] = 0\n out[i * 4 + 3] = Math.round(a * 255)\n }\n }\n\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n const cov = roundedCoverage(x, y, rect, radius)\n if (cov <= 0) continue\n const sx = Math.min(shot.w - 1, Math.max(0, x - margin))\n const sy = Math.min(shot.h - 1, Math.max(0, y - margin))\n const si = (sy * shot.w + sx) * 4\n const o = (y * w + x) * 4\n let r = shot.data[si]\n let g = shot.data[si + 1]\n let b = shot.data[si + 2]\n // A hairline at the edge: the outer 1.5 px darkened.\n if (hair > 0) {\n const edge = Math.min(\n x - rect.x,\n rect.x + rect.w - x,\n y - rect.y,\n rect.y + rect.h - y,\n )\n if (edge < 1.5) {\n r = Math.round(r * (1 - hair))\n g = Math.round(g * (1 - hair))\n b = Math.round(b * (1 - hair))\n }\n }\n // Composite the shot over whatever shadow lies under this pixel.\n const a = cov\n const ba = out[o + 3] / 255\n const outA = a + ba * (1 - a)\n const mix = (fg: number, bg: number) =>\n outA > 0 ? Math.round((fg * a + bg * ba * (1 - a)) / outA) : 0\n out[o] = mix(r, out[o])\n out[o + 1] = mix(g, out[o + 1])\n out[o + 2] = mix(b, out[o + 2])\n out[o + 3] = Math.round(outA * 255)\n }\n }\n return { w, h, data: out }\n}\n\nconst crcTable = (() => {\n const t = new Uint32Array(256)\n for (let n = 0; n < 256; n++) {\n let c = n\n for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1\n t[n] = c >>> 0\n }\n return t\n})()\n\nfunction crc32(buf: Uint8Array): number {\n let c = 0xffffffff\n for (const b of buf) c = crcTable[(c ^ b) & 255] ^ (c >>> 8)\n return (c ^ 0xffffffff) >>> 0\n}\n\nfunction chunk(type: string, body: Uint8Array): Uint8Array {\n const out = new Uint8Array(12 + body.length)\n const dv = new DataView(out.buffer)\n dv.setUint32(0, body.length)\n for (let i = 0; i < 4; i++) out[4 + i] = type.charCodeAt(i)\n out.set(body, 8)\n dv.setUint32(8 + body.length, crc32(out.subarray(4, 8 + body.length)))\n return out\n}\n\n/** Encode RGBA as an 8-bit truecolor-with-alpha PNG (the \"up\" filter per row). */\nexport function encodePng(img: Rgba): Uint8Array {\n const stride = img.w * 4\n const raw = new Uint8Array((stride + 1) * img.h)\n for (let y = 0; y < img.h; y++) {\n raw[y * (stride + 1)] = 2\n for (let i = 0; i < stride; i++) {\n const cur = img.data[y * stride + i]\n const up = y ? img.data[(y - 1) * stride + i] : 0\n raw[y * (stride + 1) + 1 + i] = (cur - up) & 255\n }\n }\n const ihdr = new Uint8Array(13)\n const dv = new DataView(ihdr.buffer)\n dv.setUint32(0, img.w)\n dv.setUint32(4, img.h)\n ihdr[8] = 8\n ihdr[9] = 6\n const parts = [\n new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),\n chunk('IHDR', ihdr),\n chunk('IDAT', new Uint8Array(deflateSync(raw))),\n chunk('IEND', new Uint8Array(0)),\n ]\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0))\n let o = 0\n for (const p of parts) {\n out.set(p, o)\n o += p.length\n }\n return out\n}\n","/**\n * `vos validate <kit.json> --picture`: what each asset LOOKS like, read\n * from its bytes the way the spec pass reads its size. Every finding\n * carries a code, a severity, a message written from the failure it was\n * built on, a fix hint and (where it has one) a box, so an agent can\n * self-check by name before it renders and a reader can find the spot.\n *\n * Checks, and the failure each was written from:\n * blank a card whose subject is under the ink floor (a wallpaper,\n * an empty canvas)\n * duplicate two stills of one frame (a kit of eight crops of one frame)\n * subject the card's width off the band, or a card bled on all four\n * sides where a card was asked for; a screenshot not full bleed\n * separation a light card on a light ground with no shadow and no edge\n * halfsize a tile that loses its edges at half size (the store rule)\n * sliced a text box crossing the frame edge (a headline cut mid-word)\n * safe a text box outside the destination's safe rect\n * contrast a text box under APCA Lc 60 (headline) / 75 (body)\n * firstlast a video whose first or last frame is blank or bled\n *\n * Text boxes come from the manifest (the poster leg records the element\n * layout it rendered), never from OCR: a take frame's page text is\n * unknown, so those three checks run only where the kit says where words\n * are. Pure over decoded pixels; the video frames come through ffmpeg\n * when it is on PATH and are skipped, said, when it is not.\n */\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { readFile } from 'node:fs/promises'\nimport {\n decodePng,\n edgeEnergy,\n hammingDistance,\n inkCoverage,\n measureStill,\n medianColour,\n} from './picture'\nimport type { Rect, Rgba, StillMeasure } from './picture'\nimport type { Destination } from '@vosjs/studio-core'\n\nconst execFileP = promisify(execFile)\n\nexport type PictureCode =\n | 'blank'\n | 'duplicate'\n | 'subject'\n | 'separation'\n | 'halfsize'\n | 'sliced'\n | 'safe'\n | 'contrast'\n | 'firstlast'\n | 'unreadable'\n\nexport interface PictureFinding {\n code: PictureCode\n severity: 'error' | 'warning' | 'info'\n /** The asset's destination id (or ids, for a duplicate group). */\n asset: string\n message: string\n fixHint: string\n /** Where, in pixels of the asset, when the finding has a place. */\n bbox?: Rect\n}\n\n/** A text box the manifest records, as fractions of the asset. */\nexport interface TextBox {\n x: number\n y: number\n w: number\n h: number\n /** `#rrggbb` of the type, for the contrast check. */\n color?: string\n /** 'headline' (Lc 60) or 'body' (Lc 75); absent = headline. */\n role?: 'headline' | 'body'\n /** For the message. */\n label?: string\n}\n\nexport interface PictureAsset {\n destination: string\n path: string\n file: string\n spec?: Pick<Destination, 'genre' | 'kind' | 'text' | 'safe' | 'px'>\n text?: TextBox[]\n seconds?: number | null\n /** The manifest says this screenshot kept the cut's camera and chrome. */\n composed?: boolean\n /**\n * A poster card's shot placement (fractions; a bleed runs past 1): the\n * composition is the template's, so the subject is the SHOT, and the\n * ground is designed rather than a plate to find a card on.\n */\n shot?: { x: number; y: number; w: number; h: number }\n /**\n * A tile: the shot is a close CROP of the page's hero, wider than the\n * frame by design (the subject band does not apply) and mostly the\n * page's own plate (a hero region is half as inky as a populated card).\n */\n crop?: boolean\n}\n\n/** The band the reference assets were measured to. */\nexport const SUBJECT_BAND = { min: 0.6, max: 0.92 }\n/** Ink coverage under which a card's subject is blank. */\nexport const BLANK_INK = 0.12\n/** L* difference under which a card needs a shadow to sit. */\nexport const SEPARATION_L = 8\n/** Shadow halo reading above which a shadow is present. */\nexport const SHADOW_PRESENT = 6\n/** Edge contrast above which a drawn edge (a hairline, a bar) separates the card. */\nexport const EDGE_PRESENT = 40\n/** Hamming bits under which two stills are one frame. */\nexport const DUPLICATE_BITS = 6\n/** Edge energy kept at half size, below which a tile stops reading. */\nexport const HALFSIZE_KEEP = 0.45\n\n/** APCA (W3 0.1.9) lightness contrast of text on a background, |Lc|. */\nexport function apcaContrast(\n text: [number, number, number],\n bg: [number, number, number],\n): number {\n const lum = (c: [number, number, number]) => {\n const ch = (v: number) => Math.pow(v / 255, 2.4)\n let y = 0.2126729 * ch(c[0]) + 0.7151522 * ch(c[1]) + 0.072175 * ch(c[2])\n if (y < 0.022) y += Math.pow(0.022 - y, 1.414)\n return y\n }\n const yt = lum(text)\n const yb = lum(bg)\n if (Math.abs(yb - yt) < 0.0005) return 0\n let sapc: number\n if (yb > yt) {\n sapc = (Math.pow(yb, 0.56) - Math.pow(yt, 0.57)) * 1.14\n return sapc < 0.1 ? 0 : (sapc - 0.027) * 100\n }\n sapc = (Math.pow(yb, 0.65) - Math.pow(yt, 0.62)) * 1.14\n return sapc > -0.1 ? 0 : -(sapc + 0.027) * 100\n}\n\nconst pct = (v: number) => `${Math.round(v * 100)}%`\n\nconst hexToRgb = (h: string): [number, number, number] | null => {\n const m = /^#([0-9a-f]{6})$/i.exec(h.trim())\n if (!m) return null\n const n = parseInt(m[1], 16)\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255]\n}\n\n/** The checks on one still's measurement; pure. */\nexport function stillFindings(\n a: PictureAsset,\n img: Rgba,\n m: StillMeasure,\n): PictureFinding[] {\n const out: PictureFinding[] = []\n const genre = a.spec?.genre\n const bledAll = m.bleed.length === 4\n\n // A poster card: the subject is the shot the template placed. Its width\n // sits in the band (a bleed past the frame is a layout, so the ceiling\n // is loose), and the visible part of it carries ink.\n if (a.shot) {\n const sx = Math.max(0, a.shot.x) * img.w\n const sy = Math.max(0, a.shot.y) * img.h\n const sw = Math.min(1, a.shot.x + a.shot.w) * img.w - sx\n const sh = Math.min(1, a.shot.y + a.shot.h) * img.h - sy\n const rect = { x: sx, y: sy, w: Math.max(1, sw), h: Math.max(1, sh) }\n const ink = inkCoverage(img, rect)\n if (ink < (a.crop ? BLANK_INK / 2 : BLANK_INK)) {\n out.push({\n code: 'blank',\n severity: 'error',\n asset: a.destination,\n message: `${pct(ink)} ink inside the shot: the moment shows a wallpaper, an empty canvas or a flat panel`,\n fixHint:\n 'pick a moment after a gesture landed (--shot-time, or --times step:<id>) and stage the set before recording',\n bbox: rect,\n })\n }\n if (!a.crop && (a.shot.w < 0.5 || a.shot.w > 1.2)) {\n out.push({\n code: 'subject',\n severity: 'error',\n asset: a.destination,\n message: `the shot is ${pct(a.shot.w)} of the width; a card sits at 60 to 92%, a bleed a little past the edge`,\n fixHint:\n 'the template layout places the slot; fix its place for this aspect',\n bbox: rect,\n })\n }\n for (const f of textFindings(a, img)) out.push(f)\n return out\n }\n\n const subject = m.card ?? { x: 0, y: 0, w: img.w, h: img.h }\n if (m.ink < BLANK_INK) {\n out.push({\n code: 'blank',\n severity: 'error',\n asset: a.destination,\n message: `${pct(m.ink)} ink inside the ${m.card ? 'card' : 'frame'}: a wallpaper, an empty canvas or a flat panel, not the product doing something`,\n fixHint:\n 'pick a moment after a gesture landed (--times step:<id>) and stage the set before recording: real data, a populated state',\n bbox: subject,\n })\n }\n\n if (genre === 'card') {\n if (bledAll || m.widthPct === null) {\n out.push({\n code: 'subject',\n severity: 'error',\n asset: a.destination,\n message: bledAll\n ? 'the picture fills the frame on all four sides: a crop, not a card on a ground'\n : 'no card found: the frame is one flat tone',\n fixHint:\n 'present the card in a look (vos deliver reads BRAND.md or --look) or render this destination from a poster template',\n })\n } else if (m.widthPct < SUBJECT_BAND.min || m.widthPct > SUBJECT_BAND.max) {\n out.push({\n code: 'subject',\n severity: 'error',\n asset: a.destination,\n message: `the card is ${pct(m.widthPct)} of the width; the references sit at ${pct(SUBJECT_BAND.min)} to ${pct(SUBJECT_BAND.max)}`,\n fixHint:\n 'the look places the card at 84% (frame.inset); a poster template sets its own placement',\n bbox: m.card ?? undefined,\n })\n }\n if (m.card && !bledAll) {\n const sep = m.separation ?? 0\n const shadow = m.shadow ?? 0\n if (\n sep < SEPARATION_L &&\n shadow < SHADOW_PRESENT &&\n m.edge < EDGE_PRESENT\n ) {\n out.push({\n code: 'separation',\n severity: 'error',\n asset: a.destination,\n message: `the card and the ground are ${sep.toFixed(1)} L* apart with no shadow halo (${shadow.toFixed(1)}) and no drawn edge (${m.edge.toFixed(0)}): the card dissolves into the plate`,\n fixHint:\n 'a contact shadow (frame.shadowContact) plus a hairline (frame.border with borderColor) makes a light card sit on a light ground; the plate look sets both',\n bbox: m.card,\n })\n }\n }\n }\n\n // A page whose own margins are flat reads its content block as the\n // \"card\", and a page's tiles cast halos of their own, so the picture\n // alone cannot prove a screenshot was composed. The manifest can: the\n // deliver verb records `composed` on a screenshot it rendered with the\n // cut's camera and chrome, and that is what this reads.\n if (\n genre === 'screenshot' &&\n a.composed &&\n m.card &&\n (m.widthPct ?? 0) < 0.98\n ) {\n out.push({\n code: 'subject',\n severity: 'error',\n asset: a.destination,\n message: `a store screenshot must be the real page full bleed; this one shows a ${pct(m.widthPct ?? 0)} card on a ground`,\n fixHint:\n 'drop --composed: the screenshot genre renders the page with no chrome and no padding',\n bbox: m.card,\n })\n }\n\n if (img.w <= 500 && (a.spec?.text === 'none' || genre === 'card')) {\n const full = edgeEnergy(img, Math.min(img.w, 400))\n const half = edgeEnergy(img, Math.min(img.w, 400) >> 1)\n const keep = full > 0 ? half / full : 1\n if (keep < HALFSIZE_KEEP) {\n out.push({\n code: 'halfsize',\n severity: 'warning',\n asset: a.destination,\n message: `at half size the tile keeps ${pct(keep)} of its edges: fine text and thin lines vanish where the store shows it small`,\n fixHint:\n 'a tile is the subject large and saturated with no text (the store rule); render it from the card-on-gradient template',\n })\n }\n }\n\n for (const f of textFindings(a, img)) out.push(f)\n return out\n}\n\n/** The word checks: sliced, safe, contrast, and words where none are wanted. */\nfunction textFindings(a: PictureAsset, img: Rgba): PictureFinding[] {\n const out: PictureFinding[] = []\n for (const t of a.text ?? []) {\n const box: Rect = {\n x: t.x * img.w,\n y: t.y * img.h,\n w: t.w * img.w,\n h: t.h * img.h,\n }\n const name = t.label ? `\"${t.label}\"` : 'a text box'\n if (\n box.x < 0 ||\n box.y < 0 ||\n box.x + box.w > img.w + 0.5 ||\n box.y + box.h > img.h + 0.5\n ) {\n out.push({\n code: 'sliced',\n severity: 'error',\n asset: a.destination,\n message: `${name} crosses the frame edge: cut mid-word`,\n fixHint:\n 'shorten the line, or let the template recompose (headline lines at 12 to 14% of the height, inside the safe rect)',\n bbox: box,\n })\n }\n const s = a.spec?.safe\n if (s) {\n const sx = s.x * img.w\n const sy = s.y * img.h\n const sw = s.w * img.w\n const sh = s.h * img.h\n if (\n box.x < sx - 0.5 ||\n box.y < sy - 0.5 ||\n box.x + box.w > sx + sw + 0.5 ||\n box.y + box.h > sy + sh + 0.5\n ) {\n out.push({\n code: 'safe',\n severity: 'warning',\n asset: a.destination,\n message: `${name} sits outside the destination's safe rect (${pct(s.w)}x${pct(s.h)} at ${pct(s.x)},${pct(s.y)}): the platform's chrome or crop covers it`,\n fixHint:\n 'move the text inside the safe rect; the template reads channel-specs safe',\n bbox: box,\n })\n }\n }\n const rgb = t.color ? hexToRgb(t.color) : null\n if (rgb) {\n const ground = medianColour(img, box)\n const lc = apcaContrast(rgb, ground)\n const floor = t.role === 'body' ? 75 : 60\n if (lc < floor) {\n out.push({\n code: 'contrast',\n severity: 'warning',\n asset: a.destination,\n message: `${name} reads APCA Lc ${lc.toFixed(0)} on its ground; ${t.role === 'body' ? 'body' : 'a headline'} wants ${floor}`,\n fixHint:\n 'darken the ink or lighten the ground under the text (BRAND.md ink on bgA/bgB, never on the shot)',\n bbox: box,\n })\n }\n }\n }\n if (a.spec?.text === 'none' && (a.text?.length ?? 0) > 0) {\n out.push({\n code: 'safe',\n severity: 'warning',\n asset: a.destination,\n message:\n 'this destination wants no text (the picture carries it alone) and the kit put words on it',\n fixHint:\n 'render the tile from the card-on-gradient template with no headline',\n })\n }\n return out\n}\n\n/**\n * Duplicate groups across a kit's stills, by difference hash of the\n * subject. Cards are compared with cards (eight covers of one frame is\n * the failure); a screenshot set is compared within its own destination\n * only, because two store galleries of one story legitimately share\n * frames. Two cards on one frame is a warning (X and LinkedIn often take\n * one image); three or more is an error.\n */\nexport function duplicateFindings(\n stills: {\n destination: string\n hash: string\n time: number | null\n genre?: 'screenshot' | 'card'\n /** A poster or stage card: a composition, not a crop. */\n composed?: boolean\n }[],\n): PictureFinding[] {\n const groups: { destination: string; time: number | null }[][] = []\n const seen = new Set<number>()\n const comparable = (\n a: (typeof stills)[number],\n b: (typeof stills)[number],\n ) =>\n a.genre === 'screenshot' || b.genre === 'screenshot'\n ? a.destination === b.destination\n : true\n for (let i = 0; i < stills.length; i++) {\n if (seen.has(i)) continue\n const g = [stills[i]]\n for (let j = i + 1; j < stills.length; j++) {\n if (seen.has(j)) continue\n if (!comparable(stills[i], stills[j])) continue\n if (hammingDistance(stills[i].hash, stills[j].hash) <= DUPLICATE_BITS) {\n g.push(stills[j])\n seen.add(j)\n }\n }\n if (g.length > 1) groups.push(g)\n }\n return groups.map((g) => {\n // Every member composed: one cover on several channels, which a release\n // does on purpose; the failure this check exists for is the CROP of one\n // frame at eight aspects.\n const composed = g.every(\n (s) => stills.find((x) => x.destination === s.destination)?.composed,\n )\n return {\n code: 'duplicate' as const,\n severity: composed\n ? ('info' as const)\n : g.length >= 3\n ? ('error' as const)\n : ('warning' as const),\n asset: g.map((s) => s.destination).join(', '),\n message: composed\n ? `${g.length} channels share one cover: ${g.map((s) => s.destination).join(', ')}`\n : `${g.length} assets share one frame${g[0].time !== null ? ` (${g[0].time.toFixed(2)}s)` : ''}: ${g.map((s) => s.destination).join(', ')}`,\n fixHint:\n 'a kit is many moments: let deliver pick from the step timeline, or pass --times with one step per still; a poster document per class (poster/<class>/doc.json) or per destination (LAUNCH.md poster roles) gives each channel its own cover',\n }\n })\n}\n\n/** One frame of a video through ffmpeg, as decoded pixels; null when unavailable. */\nasync function videoFrame(\n file: string,\n at: number,\n ffmpeg: string,\n): Promise<Rgba | null> {\n try {\n const { stdout } = await execFileP(\n ffmpeg,\n [\n '-v',\n 'error',\n '-ss',\n at.toFixed(3),\n '-i',\n file,\n '-frames:v',\n '1',\n '-f',\n 'image2pipe',\n '-vcodec',\n 'png',\n '-',\n ],\n { encoding: 'buffer', maxBuffer: 64 * 1024 * 1024 },\n )\n return decodePng(new Uint8Array(stdout))\n } catch {\n return null\n }\n}\n\n/** Is a binary on PATH? */\nasync function onPath(bin: string): Promise<boolean> {\n try {\n await execFileP(bin, ['-version'])\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Run the picture checks over a kit's assets. Stills decode from their\n * PNGs; videos read their first and last frame through ffmpeg. Returns the\n * findings and, per asset, what was measured.\n */\nexport async function pictureChecks(assets: PictureAsset[]): Promise<{\n findings: PictureFinding[]\n measured: { destination: string; measure: StillMeasure | null }[]\n}> {\n const findings: PictureFinding[] = []\n const measured: { destination: string; measure: StillMeasure | null }[] = []\n const stills: {\n destination: string\n hash: string\n time: number | null\n genre?: 'screenshot' | 'card'\n composed?: boolean\n }[] = []\n let ffmpeg: boolean | null = null\n\n for (const a of assets) {\n if (/\\.png$/i.test(a.file)) {\n const img = decodePng(new Uint8Array(await readFile(a.file)))\n if (!img) {\n findings.push({\n code: 'unreadable',\n severity: 'info',\n asset: a.destination,\n message: `${a.path} is not an 8-bit non-interlaced PNG; the picture checks cannot read it`,\n fixHint:\n 'render stills through vos deliver or vos frames, which write readable PNGs',\n })\n measured.push({ destination: a.destination, measure: null })\n continue\n }\n const m = measureStill(img)\n measured.push({ destination: a.destination, measure: m })\n findings.push(...stillFindings(a, img, m))\n if (a.spec?.kind !== 'video')\n stills.push({\n destination: a.destination,\n hash: m.hash,\n time: null,\n genre: a.spec?.genre,\n composed: !!a.shot,\n })\n continue\n }\n if (/\\.(mp4|webm|mov)$/i.test(a.file)) {\n if (ffmpeg === null) ffmpeg = await onPath('ffmpeg')\n if (!ffmpeg) {\n findings.push({\n code: 'firstlast',\n severity: 'info',\n asset: a.destination,\n message:\n 'ffmpeg is not on PATH, so the first and last frames were not read',\n fixHint: 'install ffmpeg to have the video checks run',\n })\n measured.push({ destination: a.destination, measure: null })\n continue\n }\n const seconds = a.seconds ?? 0\n const first = await videoFrame(a.file, 0, 'ffmpeg')\n const last = await videoFrame(\n a.file,\n Math.max(0, seconds - 0.1),\n 'ffmpeg',\n )\n for (const [name, img] of [\n ['first', first],\n ['last', last],\n ] as const) {\n if (!img) continue\n const m = measureStill(img)\n if (name === 'first')\n measured.push({ destination: a.destination, measure: m })\n const subject = m.card ?? { x: 0, y: 0, w: img.w, h: img.h }\n const ink = inkCoverage(img, subject)\n if (ink < BLANK_INK) {\n findings.push({\n code: 'firstlast',\n severity: 'error',\n asset: a.destination,\n message: `the ${name} frame is ${pct(ink)} ink: a ${name === 'first' ? 'cold open on nothing' : 'clip that ends on nothing'}`,\n fixHint:\n name === 'first'\n ? 'open on the product (trim the head, or an entrance over a populated frame)'\n : 'end on a resolved state or an end card (the last frame is the poster)',\n })\n }\n if (m.bleed.length === 4 && a.spec?.genre !== 'screenshot') {\n findings.push({\n code: 'firstlast',\n severity: 'warning',\n asset: a.destination,\n message: `the ${name} frame fills the frame on all four sides: no ground, no room`,\n fixHint:\n 'present the cut in a look (vos deliver reads BRAND.md or --look)',\n })\n }\n }\n continue\n }\n }\n findings.push(...duplicateFindings(stills))\n const order: Record<PictureFinding['severity'], number> = {\n error: 0,\n warning: 1,\n info: 2,\n }\n findings.sort((a, b) => order[a.severity] - order[b.severity])\n return { findings, measured }\n}\n\n/** One line per finding, the way the verb prints them. */\nexport function formatFinding(f: PictureFinding): string {\n const where = f.bbox\n ? ` @ ${Math.round(f.bbox.x)},${Math.round(f.bbox.y)} ${Math.round(f.bbox.w)}x${Math.round(f.bbox.h)}`\n : ''\n return `${f.severity} ${f.code} ${f.asset}${where}: ${f.message}\\n fix: ${f.fixHint}`\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 { pictureChecks } from './kitPicture'\nimport type { PictureAsset, PictureFinding, TextBox } from './kitPicture'\nimport type { StillMeasure } from './picture'\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 * Where the words are, as fractions of the asset (the poster leg records\n * the element layout it rendered): what the sliced, safe and contrast\n * checks read. Absent on a take frame, whose page text is unknown.\n */\n text?: TextBox[]\n /** A screenshot rendered with the cut's camera and chrome (--composed). */\n composed?: boolean\n /** A poster card's shot placement, fractions of the asset. */\n shot?: { x: number; y: number; w: number; h: number }\n /** A tile: the shot is a close CROP of the page's hero, past the frame by design. */\n crop?: boolean\n /** The poster document a card rendered from: its class, its file, the vos it tracks. */\n poster?: { class: string; file: string; vosId?: 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 /**\n * The picture checks (`--picture`): every finding with a code, a\n * severity, a message, a fix hint and a box. An `error` finding fails\n * the verdict beside the spec problems; absent when the pass did not run.\n */\n picture?: PictureFinding[]\n /** Per asset, what the picture pass measured (null = unreadable). */\n pictureMeasured?: { destination: string; measure: StillMeasure | null }[]\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(\n kitPath: string,\n opts: { picture?: boolean } = {},\n): 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 const pictureAssets: PictureAsset[] = []\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 pictureAssets.push({\n destination: id,\n path: a.path,\n file,\n spec,\n text: a.text,\n seconds,\n composed: a.composed,\n shot: a.source === 'poster' || a.source === 'stage' ? a.shot : undefined,\n crop: a.crop,\n })\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 if (!opts.picture) {\n return { valid: problems.length === 0, problems, warnings, measured }\n }\n const picture = await pictureChecks(pictureAssets)\n const pictureErrors = picture.findings.filter((f) => f.severity === 'error')\n return {\n valid: problems.length === 0 && pictureErrors.length === 0,\n problems,\n warnings,\n measured,\n picture: picture.findings,\n pictureMeasured: picture.measured,\n }\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 // A step that changes the page's URL (a click that navigates, the\n // wait that lets the load land) is marked: the planner proposes a\n // transition at the page change.\n const urlBefore = page.url()\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 ...(page.url() !== urlBefore ? { navigated: 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.55.7?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 *\n * Two more things a plan writes, both DATA on the document so the studio\n * shows what the kit will render: a LAYOUT copied from a poster document\n * (`--style` carries the seed's card placement, its stage clips by id, its\n * rest lean and its trailing hold, with the release's words patched into\n * the stage clips), and the cut's MOTION as planner proposals (the card's\n * entrance, the end card, a caption per beat, a music bed and click\n * sounds, from LAUNCH.md's roles). Motion is proposed on a FRESH plan and\n * on `--motion`, never on a refresh: a document that carries a cut is the\n * maker's, and a deleted end card stays deleted.\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 copyLayout,\n copyStyle,\n isRejected,\n isStageClip,\n layoutOf,\n planAutoSpeed,\n planAutoZoom,\n projectFromArtifact,\n withBackdrop,\n migrateMotion,\n} from '@vosjs/studio-core'\nimport { RECORDING_NAME, loadTake, writeJson } from './take'\nimport { retimeCut } from './reuse'\nimport { proposeMotion } from './motionPlan'\nimport type { MotionProposalInput } from './motionPlan'\nimport type { ReuseReport } from './reuse'\nimport type { ReleaseWords } from './posterValues'\nimport type {\n Backdrop,\n LayoutParts,\n ProjectDoc,\n RecordingArtifact,\n SpeedSpan,\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 /** The layout the reference carried and what the copy left alone. */\n layout?: LayoutParts & { notes: string[] }\n /** The motion proposed onto the document, and what could not be. */\n motion?: { notes: string[]; skipped: 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 * A reference that is a POSTER carries its layout too: the stage clips\n * by id, the rest lean where this take has no spans, the trailing hold.\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 * The release's words, patched into the stage clips a layout carries\n * (`stage-title` ← headline, `stage-kicker` ← kicker, `stage-brand` ←\n * the wordmark) and read by the end card.\n */\n words?: ReleaseWords\n /** The brand's mark (a take-dir key + aspect): the layout's `stage-mark` and the end card's mark. */\n mark?: { key: string; aspect: number } | null\n /**\n * Propose the cut's motion (the card's enter, the templates the recipe\n * names, the end card, captions, bed, clicks) from these roles. Applied\n * on a fresh plan; `again` re-proposes onto an existing document\n * (replacing only the proposals' own ids and `from`s).\n */\n motion?: MotionProposalInput & { again?: boolean }\n /** The frame that stands for the take (output seconds): --still, LAUNCH.md still:. */\n still?: number | 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\n/**\n * The release's words into the stage clips a layout carries: a headline\n * into `stage-title`, a kicker into `stage-kicker`, the wordmark into\n * `stage-brand`. A word that is absent leaves the clip's own words (the\n * exemplar's placeholder, or what the maker typed). In place.\n */\nexport function patchStageWords(doc: ProjectDoc, words: ReleaseWords): void {\n const map: Record<string, string | null | undefined> = {\n 'stage-title': words.headline,\n 'stage-kicker': words.kicker,\n 'stage-brand': words.brand,\n }\n for (const clip of doc.overlays ?? []) {\n if (clip.kind !== 'text' || !isStageClip(clip)) continue\n const v = map[clip.id]\n if (typeof v === 'string' && v.trim()) clip.text = v.trim()\n }\n}\n\n/** `copyStyle` with the layout, the words and the mark applied. */\nfunction applyStyle(\n seed: ProjectDoc,\n doc: ProjectDoc,\n opts: PlanOptions,\n): { doc: ProjectDoc; layout: PlanSummary['layout'] } {\n const parts = layoutOf(seed)\n const carries = parts.clips.length > 0 || parts.lean || parts.freeze\n if (!carries) return { doc: copyStyle(seed, doc), layout: undefined }\n const keys = opts.mark ? { 'stage-mark': opts.mark.key } : undefined\n const { doc: next, notes } = copyLayout(seed, copyStyle(seed, doc), { keys })\n if (opts.words) patchStageWords(next, opts.words)\n return { doc: next, layout: { ...parts, notes } }\n}\n\n/**\n * The planners over the take's OTHER media (concat): each media's own\n * cursor track, in its own capture space, proposes zoom and speed spans\n * stamped with its id; the manual spans and the rejections of that media\n * hold them off exactly as the primary's do.\n */\nfunction planOtherMedia(\n doc: ProjectDoc,\n activity: Awaited<ReturnType<typeof readDigestActivity>>,\n): { zoom: ZoomSpan[]; speed: SpeedSpan[] } {\n const zoom: ZoomSpan[] = []\n const speed: SpeedSpan[] = []\n for (const m of doc.media ?? []) {\n const manualZoom = doc.zoom.filter(\n (z) => z.media === m.id && z.source === 'manual',\n )\n const rejected = (doc.rejected ?? []).filter((r) => r.media === m.id)\n zoom.push(\n ...planAutoZoom(m.cursor, {\n width: m.meta.width,\n height: m.meta.height,\n style: doc.zoomStyle,\n params: doc.zoomParams,\n })\n .filter((z) => !manualZoom.some((x) => overlaps(z, x)))\n .filter((z) => !isRejected('zoom', z, rejected))\n .map((z) => ({ ...z, id: `${z.id}-${m.id}`, media: m.id })),\n )\n const manualSpeed = (doc.speed ?? []).filter(\n (x) => x.media === m.id && x.source !== 'auto',\n )\n speed.push(\n ...planAutoSpeed(m.cursor, {\n durationMs: m.meta.durationMs,\n params: doc.speedParams,\n activity,\n })\n .filter((x) => !manualSpeed.some((y) => x.in < y.out && x.out > y.in))\n .filter((x) => !isRejected('speed', x, rejected))\n .map((x) => ({ ...x, id: `${x.id}-${m.id}`, media: m.id })),\n )\n }\n return { zoom, speed }\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 let layout: PlanSummary['layout']\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 // The previous cut in the one vocabulary (a legacy end card becomes\n // clips and a card exit, which ride along like the other overlays).\n const prev = migrateMotion(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 freezes survive the re-record, re-timed onto the\n // new footage (the trailing one is the poster's still).\n if (rt.freeze.length) doc.freeze = rt.freeze\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 {\n const others = planOtherMedia(doc, activity)\n doc.zoom = [\n ...doc.zoom.filter((z) => !z.media || z.source === 'manual'),\n ...others.zoom,\n ].sort((a, b) => a.in - b.in)\n doc.speed = [\n ...(doc.speed ?? []).filter((x) => !x.media || x.source !== 'auto'),\n ...others.speed,\n ].sort((a, b) => a.in - b.in)\n }\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 // The frame that stands for the take is an output moment too, and the\n // author's choice: it carries as it is.\n if (prev.still !== undefined) doc.still = prev.still\n if (opts.still != null) doc.still = opts.still\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 if (opts.style) {\n const applied = applyStyle(opts.style.doc, take.doc, opts)\n doc = applied.doc\n layout = applied.layout\n } else {\n doc = take.doc\n }\n fresh = false\n const manual = doc.zoom.filter((z) => z.source === 'manual' && !z.media)\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(\n (s) => s.source !== 'auto' && !s.media,\n )\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 {\n const others = planOtherMedia(doc, activity)\n doc.zoom = [\n ...doc.zoom.filter((z) => !z.media || z.source === 'manual'),\n ...others.zoom,\n ].sort((a, b) => a.in - b.in)\n doc.speed = [\n ...(doc.speed ?? []).filter((x) => !x.media || x.source !== 'auto'),\n ...others.speed,\n ].sort((a, b) => a.in - b.in)\n }\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) {\n const applied = applyStyle(opts.style.doc, doc, opts)\n doc = applied.doc\n layout = applied.layout\n }\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 // The motion proposals ride a fresh document, or an explicit re-ask.\n let motion: PlanSummary['motion']\n if (opts.motion && (fresh || opts.motion.again)) {\n const proposed = proposeMotion(doc, opts.motion)\n doc = proposed.doc\n motion = { notes: proposed.notes, skipped: proposed.skipped }\n }\n\n // The frame that stands for the take: named, never proposed. A plan\n // never moves a still the author set.\n if (opts.still != null) doc.still = opts.still\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 ...(layout ? { layout } : {}),\n ...(motion ? { motion } : {}),\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 { docFreezes } from '@vosjs/studio-core'\nimport type {\n FreezeSpan,\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 /** The previous cut's freezes, re-timed like its manual spans (a legacy hold included). */\n freeze: FreezeSpan[]\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 freeze is a source MOMENT: its anchor or the map re-times the\n // moment, its seconds come along untouched, and one that lands past the\n // new recording is dropped and named.\n const freeze: FreezeSpan[] = []\n for (const f of docFreezes(prev)) {\n let at: number | null = null\n if (f.anchor) {\n at = resolveAnchor(f.anchor, newSteps)\n if (at === null) {\n report.flagged.push(\n `freeze ${f.id}: its anchored step (${String(f.anchor.step)}) is missing or skipped in the new recording — fell back to the step map`,\n )\n } else report.anchored++\n }\n if (at === null) {\n at = stepMap.map(f.at)\n report.mapped++\n }\n if (at < 0 || at > newDuration) {\n report.flagged.push(\n `freeze ${f.id}: lands outside the new recording (${at.toFixed(2)}s) — dropped`,\n )\n continue\n }\n freeze.push({ ...f, at: +at.toFixed(3) })\n }\n freeze.sort((a, b) => a.at - b.at)\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, freeze, 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 {\n docMediaRefs,\n mediaContentType,\n pullMedia,\n takeRelativeFile,\n} 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 // The document's other media, keyed beside the recording (a poster's\n // mark in brand/, a pasted ground): each file rides the same\n // content-addressed door, so a re-push reuses it, and the hosted\n // document keys the asset. A key whose file is missing is said and\n // left as it is (the hosted render will 404 on it, honestly).\n for (const ref of docMediaRefs(docForPush)) {\n const file = join(dir, takeRelativeFile(ref.key))\n if (!existsSync(file)) {\n r.log(` ${ref.where}: ${ref.key} is not in the take — left as is`)\n continue\n }\n const media = await readFile(file)\n const mediaHash = createHash('sha256').update(media).digest('hex')\n const type = mediaContentType(file)\n const put = await api(ctx, '/assets/recording', {\n method: 'POST',\n headers: {\n 'Content-Type': type,\n 'Content-Length': String(media.length),\n 'X-Filename': basename(file),\n 'X-Content-Hash': mediaHash,\n },\n raw: new Uint8Array(media),\n })\n if (put.status !== 201 && put.status !== 200) {\n throw new Error(\n `${ref.where} upload failed (${put.status}): ${String(put.json.error ?? '')}`,\n )\n }\n ref.set(String(put.json.url))\n r.log(\n ` ${ref.where}: ${ref.key} → asset ${String(put.json.id)}${put.json.reused === true ? ' (reused)' : ''}`,\n )\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 /** The base to walk the changelog from; default the tracked version. */\n since?: string\n /** Report what changed and stop: no doc.json, no media, no repoint. */\n check?: boolean\n },\n r: Reporter,\n): Promise<{\n vosId: string\n versionId: string\n versionNumber: number | null\n changed: boolean\n media?: MediaPullResult\n /** --check: the report, nothing written. */\n checked?: boolean\n /** --check: versions between the base and head (null when there is no base to walk from). */\n behind?: number | null\n changes?: unknown[]\n protected?: string[]\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 const base = flags.since ?? state?.versionId ?? null\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 (base === head) {\n r.log(\n flags.since\n ? 'up to date — --since names the head'\n : 'up to date — HEAD is your last push',\n )\n if (flags.check) {\n return {\n vosId,\n versionId: head,\n versionNumber: null,\n changed: false,\n checked: true,\n behind: 0,\n changes: [],\n protected: [],\n }\n }\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 (the\n // tracked version, or --since).\n let walked: { changes: unknown[]; protected: string[] } | null = null\n if (base) {\n const changes = await api(\n ctx,\n `/vos/${vosId}/changes?since=${encodeURIComponent(base)}`,\n )\n if (changes.status === 200) {\n r.log(\n flags.since\n ? `changes since ${base.slice(0, 8)}…:`\n : 'changes since your last push:',\n )\n printChanges(r, changes.json.changes, changes.json.protected)\n walked = {\n changes: Array.isArray(changes.json.changes)\n ? (changes.json.changes as unknown[])\n : [],\n protected: Array.isArray(changes.json.protected)\n ? (changes.json.protected as string[])\n : [],\n }\n if (changes.json.truncated === true) {\n r.log('walk truncated — more versions exist; pull again after syncing')\n }\n } else {\n r.log(\n `changelog unavailable (${changes.status}) — the head is v?; pass --since <versionId> you can read, or pull to sync`,\n )\n }\n } else {\n r.log(\n 'no base to compare from (this take was linked with --vos) — pass --since <versionId> for the changelog',\n )\n }\n\n // --check: the report is the result. Nothing on disk moves.\n if (flags.check) {\n return {\n vosId,\n versionId: head,\n versionNumber: null,\n changed: false,\n checked: true,\n behind: walked ? walked.changes.length : null,\n changes: walked?.changes ?? [],\n protected: walked?.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/** A take-relative media key: neither a URL, a blob, nor a hosted asset path. */\nexport function isTakeRelativeKey(key: string | undefined): key is string {\n // `media:<id>` names a document media (a layer that shows one); the media\n // itself rides the recording door, so the reference is never a file.\n return (\n !!key &&\n !/^(https?:|blob:|data:|media:|\\/\\/)/.test(key) &&\n !key.startsWith('/api/')\n )\n}\n\n/** The file a take-relative key names, under the take directory. */\nexport const takeRelativeFile = (key: string): string => key.replace(/^\\/+/, '')\n\nexport interface DocMediaRef {\n /** Where the key lives, in words (for a log line). */\n where: string\n key: string\n /** Replace the key in the document. */\n set: (next: string) => void\n}\n\n/**\n * Every media key a document carries beside its recording, mic and cam:\n * image and video overlay clips (a poster's mark), the end card's mark, a\n * background image or loop. The recording's own keys are `KEYS` and\n * handled by their own path. A push rehosts these; a pull brings them home.\n */\nexport function docMediaRefs(\n doc: ProjectDoc,\n keep: (key: string | undefined) => boolean = isTakeRelativeKey,\n): DocMediaRef[] {\n const out: DocMediaRef[] = []\n // The take's OTHER media (concat): each recording, and its sidecars,\n // rides the recording door like the primary's; a pull brings them home.\n for (const m of doc.media ?? []) {\n if (keep(m.videoKey))\n out.push({\n where: `media ${m.id}`,\n key: m.videoKey,\n set: (next) => {\n m.videoKey = next\n },\n })\n const mic = m.micKey\n if (mic && keep(mic))\n out.push({\n where: `media ${m.id} mic`,\n key: mic,\n set: (next) => {\n m.micKey = next\n },\n })\n const cam = m.camKey\n if (cam && keep(cam))\n out.push({\n where: `media ${m.id} cam`,\n key: cam,\n set: (next) => {\n m.camKey = next\n },\n })\n }\n for (const clip of doc.overlays ?? []) {\n if (clip.kind === 'text' || !keep(clip.key)) continue\n out.push({\n where: `overlay ${clip.id}`,\n key: clip.key,\n set: (next) => {\n clip.key = next\n },\n })\n }\n const mark = doc.endCard?.mark\n if (mark && keep(mark.key))\n out.push({\n where: 'end card mark',\n key: mark.key,\n set: (next) => {\n mark.key = next\n },\n })\n const bg = doc.frame.backgroundMedia\n if (bg && keep(bg.key))\n out.push({\n where: 'background',\n key: bg.key,\n set: (next) => {\n bg.key = next\n },\n })\n return out\n}\n\n/** The content type a take-relative media file uploads as, by extension. */\nexport function mediaContentType(file: string): string {\n const ext = (/\\.([a-z0-9]+)$/i.exec(file)?.[1] ?? '').toLowerCase()\n const types: Record<string, string> = {\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n gif: 'image/gif',\n avif: 'image/avif',\n webm: 'video/webm',\n mp4: 'video/mp4',\n mov: 'video/quicktime',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n ogg: 'audio/ogg',\n m4a: 'audio/mp4',\n }\n return types[ext] ?? 'application/octet-stream'\n}\n\n/** The extension a downloaded media file takes, from its content type. */\nexport function extensionFor(contentType: string): string {\n const t = contentType.split(';')[0].trim().toLowerCase()\n const exts: Record<string, string> = {\n 'image/svg+xml': '.svg',\n 'image/png': '.png',\n 'image/jpeg': '.jpg',\n 'image/webp': '.webp',\n 'image/gif': '.gif',\n 'image/avif': '.avif',\n 'video/webm': '.webm',\n 'video/mp4': '.mp4',\n 'video/quicktime': '.mov',\n 'audio/mpeg': '.mp3',\n 'audio/wav': '.wav',\n 'audio/ogg': '.ogg',\n 'audio/mp4': '.m4a',\n }\n return exts[t] ?? ''\n}\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 document's other media (a poster's mark, a pasted ground): a hosted\n // asset comes home under media/<assetId>.<ext> and the key re-anchors to\n // it, so the pulled poster renders and re-pushes as a whole.\n for (const ref of docMediaRefs(doc, (k) => assetIdOf(k) !== null)) {\n const assetId = assetIdOf(ref.key)!\n const abs = /^https?:/.test(ref.key) ? ref.key : `${ctx.origin}${ref.key}`\n const existing = existsSync(join(dir, 'media'))\n ? (\n await import('node:fs/promises').then((fs) =>\n fs.readdir(join(dir, 'media')),\n )\n ).find((f) => f.startsWith(`${assetId}.`))\n : undefined\n let file: string\n if (existing) {\n file = `media/${existing}`\n result.kept.push(file)\n } else {\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 ${ref.where} (${ref.key}) failed (${res.status})`,\n )\n }\n const ext = extensionFor(res.headers.get('content-type') ?? '')\n file = `media/${assetId}${ext}`\n const target = join(dir, file)\n await import('node:fs/promises').then((fs) =>\n fs.mkdir(join(dir, 'media'), { recursive: true }),\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(\n ` ${file} ← ${ref.where}, asset ${assetId} (${Math.round(bytes / 1024)} kB)`,\n )\n }\n ref.set(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 } 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 { directoryKind } from '../loadConfig'\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 return directoryKind(target) === 'take'\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 { lookKindForGround } from '@vosjs/studio-core'\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 /** The mark for dark grounds (a design.md asset named on-dark or white), when the site publishes one. */\n logoOnDarkUrl: string | null\n iconUrl: string | null\n ogImage: string | null\n wordmark: string\n designMd: string | null\n llmsTxt: string | null\n /**\n * The look the kit's cards and cuts are presented in, decided from the\n * site's own ground: a paper site is a plate, a dark site is dark,\n * anything else takes the gradient (accent → bgC). The maker overrides\n * it by editing the role; `ground` (absent here) overrides the ground.\n */\n look: 'plate' | 'gradient' | 'dark'\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 // The mark to PLACE: a design.md asset named mark, logo or wordmark that\n // is not an icon (a favicon or app icon carries a tile) and not the\n // on-dark twin, which is recorded beside it.\n const isIcon = (u: string) => /favicon|apple-touch|icon/i.test(u)\n const onDark = (u: string) => /on-dark|white/i.test(u)\n const logoUrl =\n design?.logos.find(\n (u) => /wordmark|logo|mark/i.test(u) && !isIcon(u) && !onDark(u),\n ) ?? null\n const logoOnDarkUrl =\n design?.logos.find(\n (u) => /wordmark|logo|mark/i.test(u) && !isIcon(u) && onDark(u),\n ) ?? 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 logoOnDarkUrl,\n iconUrl,\n ogImage: w.ogImage,\n wordmark,\n designMd: input.designUrl,\n llmsTxt: input.llmsUrl,\n look: lookKindForGround(bgA),\n }\n p.look = `from the body's ground (${bgA}): a paper site is a plate, a dark site is dark, else the gradient`\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 `logoOnDarkUrl: ${q(k.logoOnDarkUrl)}`,\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 `look: ${q(k.look)}`,\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 (placed beside the wordmark on the cards and the end card; \\`logoOnDarkUrl\\` stands in on a dark ground). A site that publishes only a favicon or an app icon gets the icon here, tile and all: publish a bare mark and name it in design.md. 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","END_CARD_FROM","docOutputDuration","migrateHostedDoc","at","isObj","mkdir","readFile","rename","writeFile","existsSync","join","resolve","momentsFromDoc","planForDigest","ratedSegments","spanOutputExtent","existsSync","writeFile","join","resolve","pct","readFile","rm","chunk","readFile","rm","mkdir","readFile","rename","writeFile","existsSync","join","DIGEST_CROP_MAX","DIGEST_FULL_MAX","DIGEST_VERSION","join","mkdir","existsSync","f","rename","writeFile","readFile","out","ratedSegments","spanOutputExtent","resolve","join","mkdir","rename","existsSync","readFile","momentsFromDoc","planForDigest","writeFile","mkdir","rename","rm","writeFile","join","resolve","existsSync","readFile","docOutputDuration","writeFile","compileVosConfig","lowerToComposition","resolveExportSize","VIDEO_TOKEN","resolveExportSize","lowerToComposition","compileVosConfig","writeFile","ratedSegments","spanOutputExtent","off","ratedSegments","spanOutputExtent","relative","median","ratedSegments","spanOutputExtent","ratedSegments","spanOutputExtent","at","kept","hex","existsSync","readFile","join","resolve","docStillTime","readFileSync","join","join","readFileSync","existsSync","join","resolve","readFile","at","docStillTime","join","existsSync","readFile","rm","docOutputDuration","resolve","mkdir","rename","writeFile","mkdir","readFile","writeFile","existsSync","isAbsolute","join","resolve","existsSync","mkdir","readFile","writeFile","isAbsolute","join","resolve","DESTINATIONS","DESTINATIONS","o","readFile","resolve","join","mkdir","existsSync","isAbsolute","writeFile","readFile","DUPLICATE_BITS","at","readFile","existsSync","readFile","stat","dirname","isAbsolute","join","DESTINATIONS","PNG_SIG","readFile","DESTINATIONS","dirname","isAbsolute","existsSync","join","stat","readFileSync","writeFileSync","join","writeFileSync","join","readFileSync","MEDIABUNNY_URL","existsSync","readFile","join","migrateMotion","resolveAnchor","at","join","existsSync","readFile","migrateMotion","existsSync","readFile","join","lowerToComposition","migrateHostedDoc","existsSync","writeFile","join","join","existsSync","writeFile","mkdir","writeFile","join","migrateHostedDoc","mkdir","join","writeFile","migrateHostedDoc","summary","existsSync","readFile","join","lowerToComposition","media","migrateHostedDoc","existsSync","mkdir","readFile","writeFile","createInterface","basename","dirname","join","migrateHostedDoc","sleep","BOOLEAN_FLAGS","join","existsSync","mkdir","writeFile","migrateHostedDoc","dirname","readFile","basename","title","created","watchUrl","studioUrl","createInterface","readFileSync","basename","extname","BOOLEAN_FLAGS","basename","extname","readFileSync","readFileSync","basename","BOOLEAN_FLAGS","basename","cmdPush","readFileSync","res","writeFile","resolve","parseFrontmatter","hex","parseFrontmatter","resolve","writeFile","writeFile","resolve","relative","resolve","readFile","writeFile","BOOLEAN_FLAGS","MULTI_FLAGS","readFile","resolve","existsSync","join","mkdir","cmdCreate","rm","off","at","END_CARD_FROM","docOutputDuration","migrateHostedDoc","problems","warnings","cmdPush","cmdPull"]}
|