@vosjs/cli 0.53.3 → 0.53.5
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vosjs/cli",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.5",
|
|
4
4
|
"description": "The vos CLI: record the real product from a scripted browser flow, auto-zoom from the cursor track, cut as data in doc.json, render deterministic video and stills, deliver a release's media per destination spec, and sync with vos.so. One binary, every verb, MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"mediabunny": "^1.55.7",
|
|
51
51
|
"playwright": "^1.49.0",
|
|
52
|
-
"@vosjs/core": "^0.25.2",
|
|
53
52
|
"@vosjs/editor": "^1.4.0",
|
|
54
|
-
"@vosjs/elements": "^0.
|
|
55
|
-
"@vosjs/render-core": "^0.3.
|
|
53
|
+
"@vosjs/elements": "^0.9.0",
|
|
54
|
+
"@vosjs/render-core": "^0.3.9",
|
|
55
|
+
"@vosjs/core": "^0.25.3",
|
|
56
56
|
"@vosjs/shared": "^0.5.0",
|
|
57
57
|
"@vosjs/studio-core": "^0.33.1",
|
|
58
58
|
"@vosjs/timeline": "^0.4.1",
|
package/skills/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10.0
|
package/skills/vos-port/SKILL.md
CHANGED
|
@@ -43,10 +43,15 @@ not in `node_modules`.
|
|
|
43
43
|
`font.family` and `font.color` take `{ "$data": "<key>" }` (they
|
|
44
44
|
re-raster live on a data edit). Logos and shapes are `svg` or `image`
|
|
45
45
|
elements, footage a `video` element. Elements are what the studio selects
|
|
46
|
-
and moves.
|
|
46
|
+
and moves. **Every visible word is a bound element**, whatever animates
|
|
47
|
+
it: a word whose letters rise one by one is ONE `split` element bound to
|
|
48
|
+
its key, never a pool of per-letter elements filled from `onFrame` (a
|
|
49
|
+
person can retype the first in the studio and not the second).
|
|
47
50
|
4. **Motion is the timeline.** `createTimeline` holds the tweens, on
|
|
48
51
|
`ctx.elements.get(id).props` (whole) or `.segments` (`split: { type:
|
|
49
|
-
'chars' | 'words' | 'lines' }` units), in the GSAP dialect.
|
|
52
|
+
'chars' | 'words' | 'lines' }` units), in the GSAP dialect. Read
|
|
53
|
+
`el.segments` inside `createTimeline` and nowhere else: a data edit to a
|
|
54
|
+
bound split word rebuilds its units and the timeline over them. Keep curves
|
|
50
55
|
exact: Remotion's `Easing.bezier(a, b, c, d)` is `ease: 'css-bezier(a, b,
|
|
51
56
|
c, d)'`; GSAP eases keep their names.
|
|
52
57
|
5. **Scenes are labels.** One `tl.addLabel('<scene>', t)` per scene or
|
|
@@ -185,7 +190,7 @@ stated approximation:
|
|
|
185
190
|
|
|
186
191
|
| Source | In vos today |
|
|
187
192
|
| --- | --- |
|
|
188
|
-
| `overflow: hidden` masks, `clip-path` reveals | no element masks: approximate with opacity
|
|
193
|
+
| `overflow: hidden` masks, `clip-path` reveals | no element masks: approximate a masked WORD with opacity (it stays a bound element); paint only a shape |
|
|
189
194
|
| a colour per split unit (`charStyle` making one letter red) | segments carry x/y/opacity/scale/rotation only: a separate element, or paint it |
|
|
190
195
|
| `mixBlendMode` | no blend modes on elements: paint it |
|
|
191
196
|
| a shape's colour as a knob | an svg's colours are compiled in (static `colors`): paint the shape if its colour must change live |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Generated by scripts/build-element-reference.mjs from @vosjs/core 0.25.
|
|
1
|
+
<!-- Generated by scripts/build-element-reference.mjs from @vosjs/core 0.25.3, @vosjs/elements 0.9.0, @vosjs/timeline 0.4.1 and @vosjs/shared 0.5.0. Do not edit by hand: re-run the script. -->
|
|
2
2
|
|
|
3
3
|
# Elements, the context and eases: the declarations
|
|
4
4
|
|
|
@@ -117,7 +117,16 @@ interface VosConfigJson {
|
|
|
117
117
|
|
|
118
118
|
`content`, `font.family` and `font.color` of a text element are the three
|
|
119
119
|
fields that take a `{ "$data": "<key>" }` binding, and the only ones that
|
|
120
|
-
re-resolve on a data edit; every other field is read once at build.
|
|
120
|
+
re-resolve on a data edit; every other field is read once at build. The key
|
|
121
|
+
names a TOP-LEVEL key of `config.data` (no dotted path, no array index), so
|
|
122
|
+
a list of words that each need binding is one key per word; `content`
|
|
123
|
+
takes the value as a string. A bound `split` element follows a data edit
|
|
124
|
+
too: its units are rebuilt from the new words and the timeline is rebuilt
|
|
125
|
+
over them (`@vosjs/elements` 0.9.0 with core 0.25.3; before that the
|
|
126
|
+
studio reloaded the program for such a knob and other hosts kept the old
|
|
127
|
+
word). So a per-letter word that is a knob is ONE bound `split` element,
|
|
128
|
+
never a pool of per-letter elements written from `onFrame`: a person can
|
|
129
|
+
retype a bound element in the studio, and cannot retype a pool.
|
|
121
130
|
`font.size`, `letterSpacing`, `transform.translateX/Y`, `stroke.width`
|
|
122
131
|
and `shadow.blur` are design pixels (a 1080-high frame). There is no
|
|
123
132
|
`mask`, `clip`, `blend` or group field on any element: SKILL.md's
|
|
@@ -318,9 +327,14 @@ The tween dialect animates numbers only: tween `fontSize` and
|
|
|
318
327
|
|
|
319
328
|
Every such write queues a re-raster, even of an unchanged value, so guard
|
|
320
329
|
a per-frame write: `if (el.props.content !== next) el.props.content = next`.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
330
|
+
These writes do nothing on a `split` element (its units are structure):
|
|
331
|
+
change a split element's words through its binding, never its props.
|
|
332
|
+
|
|
333
|
+
A text raster never fails for being long: its density drops until the
|
|
334
|
+
longest side fits the GPU's largest texture (4096 px when the GPU does
|
|
335
|
+
not say), so a line past about 4096 design px at 1080p, or half that at
|
|
336
|
+
2160p, renders softer. Only then is a long marquee worth cutting into
|
|
337
|
+
elements, and each piece stays bound.
|
|
324
338
|
|
|
325
339
|
```ts
|
|
326
340
|
/**
|
|
@@ -381,9 +395,14 @@ interface ElementInstance {
|
|
|
381
395
|
props: ElementProps;
|
|
382
396
|
/**
|
|
383
397
|
* Split text segments (only available when split config is defined).
|
|
384
|
-
* Each segment has its own ElementProps for individual animation.
|
|
398
|
+
* Each segment has its own ElementProps for individual animation. A data
|
|
399
|
+
* edit to a BOUND split text rebuilds them from the new words: the array
|
|
400
|
+
* and its objects are replaced (and the host rebuilds the timeline), so
|
|
401
|
+
* read `el.segments` inside createTimeline, never cache it elsewhere.
|
|
385
402
|
*/
|
|
386
403
|
segments?: ElementProps[];
|
|
404
|
+
/** Set when a data edit rebuilt this element's units; the host clears it. */
|
|
405
|
+
structural?: boolean;
|
|
387
406
|
/** Update element content (text or image src) */
|
|
388
407
|
setContent: (content: string) => void;
|
|
389
408
|
/**
|
|
@@ -409,6 +428,83 @@ interface ElementInstance {
|
|
|
409
428
|
}
|
|
410
429
|
```
|
|
411
430
|
|
|
431
|
+
## Knobs (`config.params` and `config.presets`)
|
|
432
|
+
|
|
433
|
+
A knob is a `ParamSpec` over one top-level `data` key, and a Look a named
|
|
434
|
+
set of values. vos.so keeps at most 12 knobs and 8 Looks, the first valid
|
|
435
|
+
ones, and `vos check` names every one it would drop before a push. Every
|
|
436
|
+
bound word stays a `data` key whether or not it has a knob: the studio's
|
|
437
|
+
element panel retypes a bound element directly, so the 12 knobs go to what
|
|
438
|
+
a person reaches for first (the palette, the headline), not to every word.
|
|
439
|
+
A `text` knob with `multiline: true` suits a list a painter draws line by
|
|
440
|
+
line; a list of elements is one key per element.
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
/**
|
|
444
|
+
* Config params: `config.params`
|
|
445
|
+
* declares the `ctx.data` keys a program reads as its creative knobs — key,
|
|
446
|
+
* kind, range, default. THE one params module, shared by the web Remix
|
|
447
|
+
* panel, the API, and scripts (the knob honesty lint): edits commit by
|
|
448
|
+
* baking BOTH `params[i].default` and `data[key]` into the config, so
|
|
449
|
+
* saves/exports/server renders pick the values up through the existing
|
|
450
|
+
* `config.data` machinery with zero new plumbing.
|
|
451
|
+
*
|
|
452
|
+
* The engine schema does not know `params` yet (upstream addition pending) —
|
|
453
|
+
* `vosConfigJsonSchema` STRIPS unknown fields on parse, so the API re-attaches
|
|
454
|
+
* validated params at the storage boundary (the platform's server-side copy;
|
|
455
|
+
* change both together) and
|
|
456
|
+
* this module validates defensively.
|
|
457
|
+
*/
|
|
458
|
+
type ParamValue = number | string | boolean;
|
|
459
|
+
|
|
460
|
+
interface ParamSpec {
|
|
461
|
+
/** The ctx.data key the program reads. */
|
|
462
|
+
key: string;
|
|
463
|
+
/** Human label; falls back to the key. */
|
|
464
|
+
label?: string;
|
|
465
|
+
/** One sentence on what the knob changes (U3b — knobs carry meaning). */
|
|
466
|
+
hint?: string;
|
|
467
|
+
/** Unit shown inside the number field: px, %, s, ×, °. */
|
|
468
|
+
unit?: string;
|
|
469
|
+
/** Optional card grouping; ungrouped knobs land on the Remix card. */
|
|
470
|
+
group?: string;
|
|
471
|
+
/** Sort order within a group (falls back to declaration order). */
|
|
472
|
+
order?: number;
|
|
473
|
+
kind: 'number' | 'color' | 'select' | 'toggle' | 'text' | 'font';
|
|
474
|
+
/** number kind */
|
|
475
|
+
min?: number;
|
|
476
|
+
max?: number;
|
|
477
|
+
step?: number;
|
|
478
|
+
/**
|
|
479
|
+
* select kind: the enumerated choices (REQUIRED, ≥2). font kind: an
|
|
480
|
+
* OPTIONAL curation — the families the knob offers; absent = the whole
|
|
481
|
+
* hosted catalog. Faces travel with the value: `applyParamValue` writes
|
|
482
|
+
* the chosen family's hosted faces into `data.fonts`, which the engine
|
|
483
|
+
* (core ≥0.17) registers at boot and on SET_DATA — no `config.fonts`
|
|
484
|
+
* declaration needed, no recompile.
|
|
485
|
+
*/
|
|
486
|
+
options?: string[];
|
|
487
|
+
/** text kind: render a multiline editor (content knobs, e.g. a headline). */
|
|
488
|
+
multiline?: boolean;
|
|
489
|
+
default: ParamValue;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* A Look (U3b): a named set of param values — the feel-the-range layer.
|
|
494
|
+
* Tap a look, then fine-tune; applying is ONE undoable multi-value commit.
|
|
495
|
+
*/
|
|
496
|
+
interface LookPreset {
|
|
497
|
+
name: string;
|
|
498
|
+
values: Record<string, ParamValue>;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Text params carry URLs (modelUrl knobs) and bound content
|
|
503
|
+
* (headline knobs) — longer than other string kinds.
|
|
504
|
+
*/
|
|
505
|
+
const TEXT_PARAM_MAX = 280;
|
|
506
|
+
```
|
|
507
|
+
|
|
412
508
|
## The context (`ctx`)
|
|
413
509
|
|
|
414
510
|
`setup(ctx)` gets a `SetupContext` and may return assets;
|
|
@@ -24,7 +24,7 @@ units (render pixels, y down, degrees counter-clockwise).
|
|
|
24
24
|
| a CSS `cubic-bezier(a, b, c, d)` timing | `ease: 'css-bezier(a, b, c, d)'` (exact; spelled `cubic-bezier` it plays linear) |
|
|
25
25
|
| CSS `--chrome` set by the timeline | a `data` value read in `onFrame`, or a tween on the element that shows it |
|
|
26
26
|
| faces resolved by the runtime from CSS families | `fonts: [{ family, weight, url }]` from the catalog |
|
|
27
|
-
| `mix-blend-mode`, `clip-path`, `overflow: hidden` reveals | GAPS:
|
|
27
|
+
| `mix-blend-mode`, `clip-path`, `overflow: hidden` reveals | GAPS: a revealed word keeps its bound element with an opacity approximation; the painter only for a shape; said in the push note |
|
|
28
28
|
|
|
29
29
|
Two traps specific to HyperFrames sources:
|
|
30
30
|
|