@vosjs/cli 0.68.0 → 0.69.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @vosjs/cli
2
2
 
3
- > The `vos` binary. Render vos configs to video and stills, record the real product from a scripted browser flow, plan zooms and pacing from the cursor track, cut as data, deliver a release's media per channel spec, and sync with vos.so. One package, every verb, MIT.
3
+ > The `vos` binary. Render vos configs to video and stills, record the real product from a scripted browser flow, plan zooms and pacing from the cursor track, cut as data, deliver a release's video cuts per channel spec, and sync with vos.so. One package, every verb, MIT.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@vosjs/cli)](https://www.npmjs.com/package/@vosjs/cli)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/vosjs/vos/blob/main/LICENSE)
@@ -79,7 +79,7 @@ vos digest take # SEE the recording befo
79
79
  vos frames take --at-zooms --at-moments # PNG stills: contact sheet, every zoom apex, every moment
80
80
  vos render take check.webm --range 4..8 --draft # spot-check an edit in seconds (half res, low bitrate)
81
81
  vos render take out.webm # the polished render
82
- vos frames take --frame 2.5 --size 1280x800 # an exact-size still: posters, OG cards, store screenshots
82
+ vos frames take --frame 2.5 --size 1280x800 # one frame at an exact size, to check a moment
83
83
  vos open take # hand the take to the studio; a human drags every span
84
84
  ```
85
85
 
@@ -177,7 +177,7 @@ A session never enters a take directory and never reaches vos.so: `vos push` ref
177
177
 
178
178
  **A series shares its look by data.** `vos plan <take> --style <seed doc.json | vosId>` copies the seed's `zoomStyle`, `zoomParams`, `speedParams`, `tiltStyle`, `frame`, `cursor`, `cam` and `export` onto a new take (never its spans, overlays or audio) and re-plans the automatic spans under them. A seed that is a POSTER carries its layout too: its card placement, its `stage-*` clips by id (with the release's words from LAUNCH.md's `headline` and `kicker` roles, BRAND.md's `wordmark`, or `--headline` and `--kicker` patched in; the brand's mark from BRAND.md `logoUrl` fetched into `<take>/brand/` for `stage-mark`), its rest lean, its trailing freeze. What could not follow is said in words.
179
179
 
180
- **The cut's motion is the document's, in one vocabulary.** Every visual thing carries `anim` (`enter`, `exit`, `idle`; a kind, or a step with its seconds and, for words, `unit`, `direction`, `stagger`): the card (`frame.anim`, entering by `tilt-in`, `pull-out`, `rise`, `fade` or `slide` and leaving by `recede` or `fade`), a text, image or video clip, a prop, and a FOOTAGE clip at its boundaries (`segments[].anim`: `exit` is how it leaves at the boundary after it, `enter` how it arrives at the one before, by `slide`, `fade` or `scale`; a slide names its `side`, a step its `seconds`, never longer than half the shorter clip). An exit and the next clip's enter at one boundary run together as a push: the incoming clip plays live while the outgoing, frozen on its last frame, moves away, the camera rests through the window, and one cursor dot crosses from the outgoing card's last point to the incoming's. A page change inside one recording is the same primitive: two clips of one media, the load between them cut. The output lasts until the last clip ends; the card is on screen exactly while its clip runs (the footage, freezes included) and leaves at its end, so its `exit` plays over the clip's last seconds like every clip's; past the footage the clips play over the ground alone. A FREEZE (`freeze: [{id, at, seconds}]`, a source moment held for output seconds, beside the speed spans on the retime lane) freezes the footage anywhere, the middle of the take included; a segment's older `hold` is read as a freeze at its end. **The frame that STANDS for a take** is `still` (output seconds; `vos plan --still <t>`, LAUNCH.md `still:`), else the take's own last freeze (a poster's rest; a template's freezes, stamped `from`, never count), else the hero moment after the card and the opening clips have entered: the shelf's cover, the kit's card stills and `vos frames --at-still` all read that one derivation, and a plan never moves a still the author set. There is no end-card field and no entrance field. A COMPONENT is a TEMPLATE: a plain take on a shelf whose clips carry stable ids, laid onto a take at an anchor and stamped `from` with where its clips came from. A fresh `vos plan` proposes the card's enter, the templates the recipe names (`LAUNCH.md` `with: <ref>[@end|@start|@step:<id>|@<seconds>], …` or `--with`, repeatable; `endCard: <ref>` names one at the end), the END CARD when `endCard` is on or absent: the official `End card` template on vos.so (the platform's `Templates` project, promoted; any official template resolves by its title, `--with "End card"`, `--style "Split cover, landscape"`), laid at the end with the release's words and BRAND.md's mark, stamped `from: endcard`; offline, the house clips stand in (a freeze of the last frame for the card's seconds, the card receding over it, the headline, the release line, the wordmark and the mark as clips over the freeze), a caption per `actions.json` step, a music bed and click sounds, a transition at every page change the recorder marked (`meta.steps[].navigated`: the outgoing clip ends on the frame before the change, the incoming begins once the page has settled; `transitions: slide|fade|scale|none`, slide by default), from LAUNCH.md's `entrance`, `transitions`, `endCard`, `with`, `captions`, `music` and `clicks` roles (or the flags), as data in doc.json with stable ids (`bed`, `click-<n>`, `caption-<step>`), so the studio shows what the kit will render; a refresh never re-proposes (a deleted clip stays deleted) and `--motion` re-proposes on purpose, replacing only its own work. A document written in the older spellings (`frame.entrance`, `endCard`, a clip's `enter`/`exit`/`fx`, a prop's `animation`) is read into the vocabulary and `vos validate` says so.
180
+ **The cut's motion is the document's, in one vocabulary.** Every visual thing carries `anim` (`enter`, `exit`, `idle`; a kind, or a step with its seconds and, for words, `unit`, `direction`, `stagger`): the card (`frame.anim`, entering by `tilt-in`, `pull-out`, `rise`, `fade` or `slide` and leaving by `recede` or `fade`), a text, image or video clip, a prop, and a FOOTAGE clip at its boundaries (`segments[].anim`: `exit` is how it leaves at the boundary after it, `enter` how it arrives at the one before, by `slide`, `fade` or `scale`; a slide names its `side`, a step its `seconds`, never longer than half the shorter clip). An exit and the next clip's enter at one boundary run together as a push: the incoming clip plays live while the outgoing, frozen on its last frame, moves away, the camera rests through the window, and one cursor dot crosses from the outgoing card's last point to the incoming's. A page change inside one recording is the same primitive: two clips of one media, the load between them cut. The output lasts until the last clip ends; the card is on screen exactly while its clip runs (the footage, freezes included) and leaves at its end, so its `exit` plays over the clip's last seconds like every clip's; past the footage the clips play over the ground alone. A FREEZE (`freeze: [{id, at, seconds}]`, a source moment held for output seconds, beside the speed spans on the retime lane) freezes the footage anywhere, the middle of the take included; a segment's older `hold` is read as a freeze at its end. **The frame that STANDS for a take** is `still` (output seconds; `vos plan --still <t>`, LAUNCH.md `still:`), else the take's own last freeze (a poster's rest; a template's freezes, stamped `from`, never count), else the hero moment after the card and the opening clips have entered: the shelf's cover and `vos frames --at-still` both read that one derivation, and a plan never moves a still the author set. There is no end-card field and no entrance field. A COMPONENT is a TEMPLATE: a plain take on a shelf whose clips carry stable ids, laid onto a take at an anchor and stamped `from` with where its clips came from. A fresh `vos plan` proposes the card's enter, the templates the recipe names (`LAUNCH.md` `with: <ref>[@end|@start|@step:<id>|@<seconds>], …` or `--with`, repeatable; `endCard: <ref>` names one at the end), the END CARD when `endCard` is on or absent: the official `End card` template on vos.so (the platform's `Templates` project, promoted; any official template resolves by its title, `--with "End card"`, `--style "Split cover, landscape"`), laid at the end with the release's words and BRAND.md's mark, stamped `from: endcard`; offline, the house clips stand in (a freeze of the last frame for the card's seconds, the card receding over it, the headline, the release line, the wordmark and the mark as clips over the freeze), a caption per `actions.json` step, a music bed and click sounds, a transition at every page change the recorder marked (`meta.steps[].navigated`: the outgoing clip ends on the frame before the change, the incoming begins once the page has settled; `transitions: slide|fade|scale|none`, slide by default), from LAUNCH.md's `entrance`, `transitions`, `endCard`, `with`, `captions`, `music` and `clicks` roles (or the flags), as data in doc.json with stable ids (`bed`, `click-<n>`, `caption-<step>`), so the studio shows what the kit will render; a refresh never re-proposes (a deleted clip stays deleted) and `--motion` re-proposes on purpose, replacing only its own work. A document written in the older spellings (`frame.entrance`, `endCard`, a clip's `enter`/`exit`/`fx`, a prop's `animation`) is read into the vocabulary and `vos validate` says so.
181
181
 
182
182
  **A fresh take opens on a backdrop.** `create`, `record` and `plan` put the first ready loop from `GET /api/backdrops` behind the card (its ground colour as `frame.background`); `--background <slug|url|none>` overrides it, and offline the frame stays bare with a note.
183
183
 
@@ -214,7 +214,7 @@ take/
214
214
  vos.json hosted tracking (vos id + base version), written by push, fetch and pull
215
215
  stills/ `vos frames` output + stills.json
216
216
  digest/ `vos digest` output: digest.json, <id>.full.png, <id>.crop.png, sheet.png
217
- kit/ `vos deliver` output: kit.json + the assets
217
+ kit/ `vos deliver` output: kit.json + the cuts
218
218
  mic.webm, cam.webm sidecar tracks, present on takes pulled from vos.so with --media
219
219
  ```
220
220
 
@@ -292,15 +292,12 @@ So `vos frames take --frame 2.0 --set frame.browserBar.kind=mac-light --set tilt
292
292
  ## Delivering a release
293
293
 
294
294
  ```bash
295
- vos deliver take --to cws,producthunt,og --release v2.1 # stills at each spec's pixels, video cuts, everything verified into kit.json
296
- vos plan take/poster/landscape --style <poster vosId> --headline "Ship it" # a poster is a take: copy a shelf poster's layout, type the words
297
- vos validate take/kit/kit.json # re-measure every asset from its bytes against the channel specs
295
+ vos deliver take --to youtube,x,shorts,github --release v2.1 # a video cut per destination at its spec's pixels, verified into kit.json
296
+ vos validate take/kit/kit.json # re-measure every cut from its bytes against the channel specs
298
297
  vos brand https://your.app --out BRAND.md # the brand kit, witnessed: /design.md, /llms.txt, then the page
299
298
  ```
300
299
 
301
- [`schema/channel-specs.json`](./schema/channel-specs.json) holds per-channel launch-asset specs: dimensions, byte and duration ceilings, and a genre per image destination (`screenshot` is the real page from the take, full bleed; `card` is a composed cover). Channels: `cws`, `producthunt` (`ph`), `x`, `linkedin` (`li`), `og`, `github` (`gh`), `youtube` (`yt`), `shorts-linkedin` (`shorts`), or `all`. `vos deliver <take> --to <channels>` loops them in one pass and writes `kit.json`, the manifest the `launch-kit` skill builds the rest of the release around; an asset that misses its spec lands in `skipped[]` with the reason, and the verb exits 1 when nothing was produced. Flags: `--release <tag>`, `--out <take>/kit`, `--times`, `--range`, `--parallel`, `--launch LAUNCH.md`, `--look`, `--brand`, `--composed` (keep the cut's camera and chrome on screenshot stills instead of the full-bleed page), `--set`, `--background`. `vos validate` reads a kit back from its bytes (a `.png` that is WebP, a lying size or duration, a set under its count, a byte ceiling).
302
-
303
- **A poster is a document, and deliver renders it.** A card-genre destination (OG, LinkedIn, X, the YouTube thumbnail, the CWS tile and marquee, the GitHub social preview) renders from the poster document of its aspect class (`landscape`, `square`, `portrait`, `tile`), found beside the take as `poster/<class>/doc.json` (`poster/doc.json` serves every class) or named in LAUNCH.md (`poster: <path>`, `poster-<class>: <path>`, a path to a doc.json or to a pulled poster take), at the document's REST (where its last freeze begins, the composed frame before nothing moves). The poster is a plain take document: the card placed by `frame.inset`, leaned by the tilt track, the words and the mark as `stage-*` clips, a trailing freeze; an agent writes it with `vos plan --style <poster>` from a poster on a shelf, or by hand, and pushes it like any take. `kit.json` records `source: "poster"`, the class, the file, the vos it tracks, the shot rect and the text boxes read from the document. A class with no document is the take's own frame, said once. Deliver composes nothing; it applies each video destination's mechanics (the README loop drops the card's motion, every clip a template placed, the captions and the sound; a channel that autoplays muted drops the bed; the 9:16 cut reframes and follows the camera) and verifies.
300
+ [`schema/channel-specs.json`](./schema/channel-specs.json) holds the per-channel video specs: dimensions, byte and duration ceilings, and a word policy. Channels: `youtube` (`yt`, the 16:9 demo), `x` (the feed cut), `shorts-linkedin` (`shorts`, the 9:16 cut), `github` (`gh`, the README loop), or `all`; any other channel is refused in words. `vos deliver <take> --to <channels>` loops them in one pass and writes `kit.json` beside the cuts; a cut that misses its spec (a duration floor the take cannot fill, a byte ceiling) lands in `skipped[]` with the reason, and the verb exits 1 when nothing was produced. Flags: `--release <tag>`, `--out <take>/kit`, `--range`, `--parallel`, `--look`, `--brand`, `--set`, `--background`. Deliver composes nothing: the cut's motion is the document's, written by `vos plan` (`--style <doc.json|vosId>` copies a signed-off take's layout and stage clips, with the release's words from `--headline` and `--kicker` or LAUNCH.md). It presents the card in the look (`--look`, else the BRAND.md beside the take, else the house gradient), applies each destination's mechanics (the README loop drops the card's motion, every clip a template placed, the captions and the sound; a channel that autoplays muted drops the bed; the 9:16 cut reframes and follows the camera), and verifies. `vos validate` reads a kit back from its bytes (a lying size, duration or byte count, a spec miss); `--picture` also reads each cut's first and last frames through ffmpeg (a blank open or close, a frame bled on all four sides).
304
301
 
305
302
  `vos brand <url>` reads the site's `/design.md` first (the convention beside `/llms.txt`), then `/llms.txt`, then witnesses one page, and writes `BRAND.md`: the palette, faces, marks and the avoid list, with the provenance of every value, so a brand is resolved before any asset is authored.
306
303
 
@@ -27,7 +27,7 @@ var manifest = {
27
27
  },
28
28
  {
29
29
  name: "deliver",
30
- summary: "render a take to release destinations (CWS, Product Hunt, X, LinkedIn, OG\u2026) + verified kit.json"
30
+ summary: "render a take to release video destinations (YouTube, X, Shorts/LinkedIn, GitHub) + verified kit.json"
31
31
  },
32
32
  {
33
33
  name: "digest",
@@ -113,4 +113,4 @@ var manifest = {
113
113
  export {
114
114
  manifest
115
115
  };
116
- //# sourceMappingURL=chunk-AUFY3M22.js.map
116
+ //# sourceMappingURL=chunk-2KEQ3LKH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin/manifest.ts"],"sourcesContent":["/**\n * The verb manifest of the take pipeline and the vos.so verbs — what\n * `vos help` lists under the engine verbs. It kept the shape a separately\n * installed plugin once handed the host (name + host range), so a script\n * reading it keeps working.\n */\nexport interface PluginVerb {\n name: string\n summary: string\n}\n\nexport interface PluginManifest {\n name: string\n /** Host versions this plugin speaks the run(argv) contract with. */\n hostRange: string\n verbs: PluginVerb[]\n}\n\nexport const manifest: PluginManifest = {\n name: '@vosjs/cli',\n hostRange: '>=0.9.0',\n verbs: [\n {\n name: 'create',\n summary: 'record + auto-plan + render, one command (--strict)',\n },\n {\n name: 'record',\n summary: 'drive actions.json into a take (screencast + cursor track)',\n },\n {\n name: 'plan',\n summary:\n 'plan zoom/cursor effects into doc.json (wand contract); --reuse re-times a previous cut onto a re-recording',\n },\n {\n name: 'render',\n summary: 'render a take directory (engine configs render in the host)',\n },\n {\n name: 'frames',\n summary:\n 'PNG stills at output times / zoom apexes / moments / exact sizes',\n },\n {\n name: 'deliver',\n summary:\n 'render a take to release video destinations (YouTube, X, Shorts/LinkedIn, GitHub) + verified kit.json',\n },\n {\n name: 'digest',\n summary:\n 'see a recording before cutting it: moments (clicks, typing, scrolls, idle, scenes) + footage frames + crops, in doc units',\n },\n { name: 'open', summary: 'serve the take into the vos.so studio' },\n {\n name: 'validate',\n summary:\n 'lint actions.json, a take dir (doc.json semantics), or re-measure a kit.json against the channel specs',\n },\n {\n name: 'actions',\n summary:\n 'from-agent-browser: turn an agent-browser walk (steps.jsonl) into actions.json; what cannot follow is named',\n },\n {\n name: 'ingest',\n summary:\n 'a take from a recording someone else made, with its cursor track from a trace beside it (Playwright trace.zip, stamped records, CSV); without one nothing is planned',\n },\n {\n name: 'port',\n summary:\n 'bring a page, a HyperFrames or a Remotion piece: inventory (its words, colours, faces, media, scenes) then scaffold (a data-first program.mjs to translate the motion into)',\n },\n {\n name: 'build',\n summary:\n 'program.mjs (real functions) → config.json, refusing what cannot run on its own (module-scope reads, syntax the page cannot parse, non-JSON data)',\n },\n {\n name: 'compare',\n summary:\n \"a program against the source's own render: per-frame SSIM and source | vos | difference sheets; exits 1 when any frame is under the threshold\",\n },\n {\n name: 'brand',\n summary:\n \"write a product's BRAND.md, witnessed: /design.md, /llms.txt, then the page (palette, faces, marks, the avoid list)\",\n },\n {\n name: 'fetch',\n summary: 'download a hosted program: config.json + vos.json tracking',\n },\n {\n name: 'push',\n summary: 'push a config.json or take to vos.so (private; versioned)',\n },\n {\n name: 'duplicate',\n summary:\n 'a private sibling of your OWN vos (someone else\\u2019s is remixed: fetch + push --remix-of)',\n },\n {\n name: 'pull',\n summary:\n 'sync what changed on vos.so since your base (--media brings a take’s footage home)',\n },\n {\n name: 'folder',\n summary:\n 'list/create/pull folders, move voses and assets into them (pull = the context package on disk)',\n },\n {\n name: 'asset',\n summary:\n 'your files: push or import one, list them (assets ls), see storage (assets usage) and what uses a file (assets why)',\n },\n {\n name: 'recipe',\n summary:\n 'push a recipe .md into a folder, or replace one in place (prior body kept)',\n },\n {\n name: 'login',\n summary: 'sign in via the browser (or --key); stores a content key',\n },\n {\n name: 'setup',\n summary:\n 'ready this machine: the vos skills into your agent, a browser, one rules block, then doctor',\n },\n {\n name: 'doctor',\n summary:\n 'what is ready, in words: node, browser, ffmpeg, skills, a credential (never printed), the dev server',\n },\n {\n name: 'whoami',\n summary: 'the key’s name and the account it belongs to, never the key',\n },\n { name: 'logout', summary: 'remove ~/.config/vos/credentials' },\n ],\n}\n"],"mappings":";;;AAkBO,IAAM,WAA2B;AAAA,EACtC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA,EAAE,MAAM,QAAQ,SAAS,wCAAwC;AAAA,IACjE;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,EAAE,MAAM,UAAU,SAAS,mCAAmC;AAAA,EAChE;AACF;","names":[]}