@vosjs/cli 0.65.0 → 0.65.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/package.json +4 -4
- package/skills/VERSION +1 -1
- package/skills/vos-authoring/SKILL.md +3 -0
- package/skills/vos-authoring/references/schema-reference.md +1 -1
- package/skills/vos-port/references/elements-and-context.md +58 -4
- package/skills/vos-remix/references/3d-recipe.md +3 -1
- package/skills/vos-remix/references/params-knobs.md +36 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vosjs/cli",
|
|
3
|
-
"version": "0.65.
|
|
3
|
+
"version": "0.65.1",
|
|
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",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"mediabunny": "^1.55.7",
|
|
53
53
|
"playwright": "^1.49.0",
|
|
54
54
|
"@vosjs/core": "^0.27.0",
|
|
55
|
-
"@vosjs/editor": "^1.4.0",
|
|
56
55
|
"@vosjs/elements": "^0.10.2",
|
|
56
|
+
"@vosjs/studio-core": "^0.35.3",
|
|
57
57
|
"@vosjs/render-core": "^0.3.17",
|
|
58
|
-
"@vosjs/
|
|
58
|
+
"@vosjs/editor": "^1.4.0",
|
|
59
59
|
"@vosjs/timeline": "^0.5.0",
|
|
60
|
-
"@vosjs/
|
|
60
|
+
"@vosjs/shared": "^0.7.0",
|
|
61
61
|
"@vosjs/tween": "^0.8.3"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
package/skills/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.21.0
|
|
@@ -159,6 +159,9 @@ documents a `ctx.data` key the program reads:
|
|
|
159
159
|
```
|
|
160
160
|
|
|
161
161
|
- kinds: `number` (min/max/step) | `color` | `select` (options) | `toggle`
|
|
162
|
+
| `text` | `font` | `asset` (a FILE knob: its `key` is a name in
|
|
163
|
+
`config.assets`, it has no `default`, and the person swaps the declared
|
|
164
|
+
file from the editor; see the vos-remix skill's `params-knobs.md`)
|
|
162
165
|
- `hint`: ONE sentence on what visibly changes — write it
|
|
163
166
|
- the program reads it where it animates:
|
|
164
167
|
`const d = ctx.data || {}; if (typeof d.hue === 'number') u.uHue.value = d.hue`
|
|
@@ -268,7 +268,7 @@ A file the program uses (a picture, a video, a model, a font file) is named in `
|
|
|
268
268
|
|
|
269
269
|
**Never type a file's URL or path inside a function string.** It renders on your machine and then fails where it matters: a server render of a private vos cannot fetch it, and a remix does not bring it along. `vos check` reports a `"$assets.<name>"` that names nothing, a declared path that is not a file, and a hosted file typed in code.
|
|
270
270
|
|
|
271
|
-
A file a
|
|
271
|
+
A file a person should be able to swap is still declared here, with a FILE KNOB over its name: `"params": [{ "key": "cover", "label": "Cover", "kind": "asset" }]` (`@vosjs/cli` 0.65 or later). The knob's value is the declared file's `ref`, so it has no `default` and nothing in `data`; `accept` lists the kinds it takes and defaults to the file's own `kind`. Older programs spell this as a text knob holding a URL in `data` (a `modelUrl` param); that still plays, but write new ones with a file knob.
|
|
272
272
|
|
|
273
273
|
---
|
|
274
274
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Generated by scripts/build-element-reference.mjs from @vosjs/core 0.
|
|
1
|
+
<!-- Generated by scripts/build-element-reference.mjs from @vosjs/core 0.27.0, @vosjs/elements 0.10.2, @vosjs/timeline 0.5.0 and @vosjs/shared 0.7.0. Do not edit by hand: re-run the script. -->
|
|
2
2
|
|
|
3
3
|
# Elements, the context and eases: the declarations
|
|
4
4
|
|
|
@@ -46,6 +46,16 @@ interface VosConfigJson {
|
|
|
46
46
|
* Total duration of one animation cycle in seconds.
|
|
47
47
|
*/
|
|
48
48
|
duration: number;
|
|
49
|
+
/**
|
|
50
|
+
* The canvas the program is designed for, in pixels. Its ratio is the
|
|
51
|
+
* program's aspect (any shape: 1080x1920, 1080x1080, 2560x1080); its pixels
|
|
52
|
+
* are the default output size of a render or still. Absent, a host picks
|
|
53
|
+
* (16:9 by convention). Design units stay 1080-high at every size.
|
|
54
|
+
*/
|
|
55
|
+
size?: {
|
|
56
|
+
width: number;
|
|
57
|
+
height: number;
|
|
58
|
+
};
|
|
49
59
|
/** Scene configuration (background, fog) */
|
|
50
60
|
scene?: SceneConfig;
|
|
51
61
|
/** Camera configuration */
|
|
@@ -77,6 +87,25 @@ interface VosConfigJson {
|
|
|
77
87
|
* @example { cursor: [{ t: 0, x: 10, y: 20, type: 'down' }] }
|
|
78
88
|
*/
|
|
79
89
|
data?: Record<string, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* The files this program uses, declared by name: its manifest.
|
|
92
|
+
*
|
|
93
|
+
* A program reads `ctx.assets.<name>` and gets a URL (or an array of
|
|
94
|
+
* them) that the HOST resolved for the surface it is running on. An
|
|
95
|
+
* element, object or font may name one as the string `"$assets.<name>"`
|
|
96
|
+
* (or `"$assets.<name>[2]"`), which is replaced the same way.
|
|
97
|
+
*
|
|
98
|
+
* Declaring a file here instead of typing its URL inside a function is
|
|
99
|
+
* what lets a host see it: it can serve a private file to a render page,
|
|
100
|
+
* bring it along when the program is copied, and refuse to collect it
|
|
101
|
+
* while the program still plays.
|
|
102
|
+
*
|
|
103
|
+
* A `ref` is whatever the host understands: a URL or path is used as it
|
|
104
|
+
* is; any other scheme is mapped by the compile option `resolveAssetRef`
|
|
105
|
+
* and, per surface, by `deps.assets`.
|
|
106
|
+
* @example { logo: { ref: './logo.png', kind: 'image' } }
|
|
107
|
+
*/
|
|
108
|
+
assets?: Record<string, AssetDecl>;
|
|
80
109
|
/**
|
|
81
110
|
* Async setup hook as a string.
|
|
82
111
|
* @example "(ctx) => { const loader = new ctx.loaders.FontLoader(); ... }"
|
|
@@ -434,8 +463,13 @@ interface ElementProps {
|
|
|
434
463
|
interface ElementInstance {
|
|
435
464
|
/** Original configuration */
|
|
436
465
|
config: ElementConfig;
|
|
437
|
-
/** Three.js mesh (textured plane) */
|
|
466
|
+
/** Three.js mesh (textured plane); a split text's FIRST unit only */
|
|
438
467
|
mesh: THREE.Mesh;
|
|
468
|
+
/**
|
|
469
|
+
* Every mesh the element draws (a split text's units), for picking and
|
|
470
|
+
* the editor's box. Absent on instances from @vosjs/elements < 0.10.1.
|
|
471
|
+
*/
|
|
472
|
+
meshes?: () => THREE.Mesh[];
|
|
439
473
|
/** DOM node for SplitText (text elements only) - typed as unknown for portability */
|
|
440
474
|
node: unknown;
|
|
441
475
|
/** GSAP-animatable properties */
|
|
@@ -477,7 +511,8 @@ interface ElementInstance {
|
|
|
477
511
|
|
|
478
512
|
## Knobs (`config.params` and `config.presets`)
|
|
479
513
|
|
|
480
|
-
A knob is a `ParamSpec` over one top-level `data` key
|
|
514
|
+
A knob is a `ParamSpec` over one top-level `data` key (a file knob, kind
|
|
515
|
+
`asset`, is over a name in `assets` instead), and a Look a named
|
|
481
516
|
set of values. vos.so keeps at most 12 knobs and 8 Looks, the first valid
|
|
482
517
|
ones, and `vos check` names every one it would drop before a push. Every
|
|
483
518
|
bound word stays a `data` key whether or not it has a knob: the studio's
|
|
@@ -501,9 +536,22 @@ line; a list of elements is one key per element.
|
|
|
501
536
|
* validated params at the storage boundary (the platform's server-side copy;
|
|
502
537
|
* change both together) and
|
|
503
538
|
* this module validates defensively.
|
|
539
|
+
*
|
|
540
|
+
* ONE kind is not a `ctx.data` key. An `asset` knob swaps a FILE, and a
|
|
541
|
+
* program's files live in `config.assets`, declared by name and read as
|
|
542
|
+
* `ctx.assets.<name>` or `"$assets.<name>"`. So an asset knob's `key` is a
|
|
543
|
+
* manifest name, its value is that entry's `ref`, and a commit writes the
|
|
544
|
+
* manifest, never `data`. That is what lets a swapped file get everything
|
|
545
|
+
* a declared file gets (a local path served by the CLI, uploaded by a push,
|
|
546
|
+
* resolved for every surface) instead of being a URL typed into data that
|
|
547
|
+
* nothing downstream knows is a file.
|
|
504
548
|
*/
|
|
505
549
|
type ParamValue = number | string | boolean;
|
|
506
550
|
|
|
551
|
+
const ASSET_PARAM_KINDS: readonly ["image", "video", "audio", "model", "font", "hdr"];
|
|
552
|
+
|
|
553
|
+
type AssetParamKind = (typeof ASSET_PARAM_KINDS)[number];
|
|
554
|
+
|
|
507
555
|
interface ParamSpec {
|
|
508
556
|
/** The ctx.data key the program reads. */
|
|
509
557
|
key: string;
|
|
@@ -517,7 +565,13 @@ interface ParamSpec {
|
|
|
517
565
|
group?: string;
|
|
518
566
|
/** Sort order within a group (falls back to declaration order). */
|
|
519
567
|
order?: number;
|
|
520
|
-
kind: 'number' | 'color' | 'select' | 'toggle' | 'text' | 'font';
|
|
568
|
+
kind: 'number' | 'color' | 'select' | 'toggle' | 'text' | 'font' | 'asset';
|
|
569
|
+
/**
|
|
570
|
+
* asset kind: the kinds of file the knob takes (a picker offers only
|
|
571
|
+
* these). Absent = the declared file's own `kind` hint, and when that is
|
|
572
|
+
* absent too, any file.
|
|
573
|
+
*/
|
|
574
|
+
accept?: AssetParamKind[];
|
|
521
575
|
/** number kind */
|
|
522
576
|
min?: number;
|
|
523
577
|
max?: number;
|
|
@@ -18,7 +18,9 @@ Reveal: https://vos.so/gallery?tag=3d) are built to take a model swap.
|
|
|
18
18
|
POINT** in these programs — with the loaded `setupData.model`,
|
|
19
19
|
bbox-normalized to ~1.7 units and grounded at `y = 0` (the templates
|
|
20
20
|
ship the normalization snippet; keep it so `scale` knobs stay
|
|
21
|
-
model-independent).
|
|
21
|
+
model-independent). To let the person swap the model later from the
|
|
22
|
+
editor, add a file knob over it (`params-knobs.md`, File knobs):
|
|
23
|
+
`{ "key": "product", "label": "Model", "kind": "asset" }`.
|
|
22
24
|
- Or keep the template's own product and only retune params.
|
|
23
25
|
3. **Never type the model's URL or path inside a function string.**
|
|
24
26
|
`vos render` and `vos preview` serve the declared file to the page;
|
|
@@ -17,6 +17,7 @@ just an artifact.**
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
- kinds: `number` (min/max/step) | `color` | `select` (options) | `toggle`
|
|
20
|
+
| `text` | `font` | `asset` (a file knob, below)
|
|
20
21
|
- `hint`: ONE sentence on what visibly changes — always write it
|
|
21
22
|
- `unit` shows inside the number field (`px` `%` `s` `×` `°`);
|
|
22
23
|
`group`/`order` cluster related knobs into their own panel card
|
|
@@ -38,6 +39,41 @@ Values must reference declared param keys with matching types (anything
|
|
|
38
39
|
else is dropped on save; max 8 Looks, names ≤24 chars). Ship 2–3 Looks
|
|
39
40
|
whenever the program has 4+ params.
|
|
40
41
|
|
|
42
|
+
## File knobs
|
|
43
|
+
|
|
44
|
+
A file a person should be able to swap (the logo, the product shot, the
|
|
45
|
+
model) is a knob of kind `asset` over a DECLARED file. Its `key` is the
|
|
46
|
+
file's name in `config.assets`; it has no `default` and nothing in `data`,
|
|
47
|
+
because its value is that file's `ref`. Needs `@vosjs/cli` 0.65 or later.
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
"assets": { "logo": { "ref": "./logo.png", "kind": "image" } },
|
|
51
|
+
"params": [{ "key": "logo", "label": "Logo", "kind": "asset",
|
|
52
|
+
"hint": "The mark in the corner" }]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- The program reads it like any declared file: `ctx.assets.logo`, or
|
|
56
|
+
`"src": "$assets.logo"` on an element. No `onFrame` read is needed: a
|
|
57
|
+
swap recompiles the program once, it is never a live data edit.
|
|
58
|
+
- `accept` lists the kinds it takes (`image`, `video`, `audio`, `model`,
|
|
59
|
+
`font`, `hdr`), e.g. `"accept": ["image", "video"]`. Without it the knob
|
|
60
|
+
takes the declared file's own `kind`, so write `kind` on the file.
|
|
61
|
+
- One knob, one file: a name declared as a list cannot be a file knob.
|
|
62
|
+
- In the editor the person sees the file with a **Replace** control and
|
|
63
|
+
picks from their own files or their device. The swap rewrites the
|
|
64
|
+
manifest entry, so the new file is declared like the old one: `vos push`
|
|
65
|
+
uploads it, and a server render of a private vos can fetch it.
|
|
66
|
+
- To swap it yourself, change the file's `ref` in `assets` and push. A
|
|
67
|
+
Look can swap it too: `"values": { "logo": "asset:<id>" }`.
|
|
68
|
+
- `vos check` warns when a file knob would do nothing: the name is not
|
|
69
|
+
declared, it is a list, nothing reads `ctx.assets.<name>`, or no kind is
|
|
70
|
+
said anywhere.
|
|
71
|
+
|
|
72
|
+
A `text` knob holding a URL in `data` (a `modelUrl` param) is the older
|
|
73
|
+
spelling. It still plays, but the person gets a box to paste an address
|
|
74
|
+
into, and `vos push` does not upload a local file named there. Write new
|
|
75
|
+
programs with a file knob.
|
|
76
|
+
|
|
41
77
|
## The five rules
|
|
42
78
|
|
|
43
79
|
1. **The knob budget is a negotiation, not an accumulation.** Curate 2–4
|