@vosjs/cli 0.77.1 → 0.79.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 +163 -21
- package/dist/{assetManifest-MQ7HO7RZ.js → assetManifest-U25FJER6.js} +3 -3
- package/dist/{chunk-UY2N42P2.js → chunk-4ZUHEXUX.js} +13 -4
- package/dist/chunk-4ZUHEXUX.js.map +1 -0
- package/dist/{chunk-B4U4URE3.js → chunk-J3KHIZCH.js} +466 -412
- package/dist/chunk-J3KHIZCH.js.map +1 -0
- package/dist/{chunk-2KEQ3LKH.js → chunk-OWYOJB7K.js} +22 -2
- package/dist/chunk-OWYOJB7K.js.map +1 -0
- package/dist/{chunk-IJZ3C435.js → chunk-TWAP4BKR.js} +4372 -587
- package/dist/chunk-TWAP4BKR.js.map +1 -0
- package/dist/{chunk-KDIRW72G.js → chunk-Z6TLHRFQ.js} +7 -4
- package/dist/chunk-Z6TLHRFQ.js.map +1 -0
- package/dist/cli.js +9 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +41 -29
- package/dist/index.js +5 -5
- package/dist/manifest-VTOIEUHJ.js +8 -0
- package/dist/{run-UNOXIGZ3.js → run-UKWKAGDK.js} +7 -5
- package/dist/{shotList-MAQVLZBY.js → shotList-EE3S5LVF.js} +52 -7
- package/dist/shotList-EE3S5LVF.js.map +1 -0
- package/package.json +4 -4
- package/schema/actions.schema.json +489 -12
- package/schema/doc.schema.json +63 -3
- package/skills/VERSION +1 -1
- package/skills/launch-kit/SKILL.md +6 -1
- package/skills/product-video/SKILL.md +7 -0
- package/skills/vos-authoring/SKILL.md +8 -1
- package/skills/vos-create/SKILL.md +5 -0
- package/skills/vos-cut/SKILL.md +8 -0
- package/skills/vos-footage/SKILL.md +4 -0
- package/skills/vos-migrate/SKILL.md +4 -0
- package/dist/chunk-2KEQ3LKH.js.map +0 -1
- package/dist/chunk-B4U4URE3.js.map +0 -1
- package/dist/chunk-IJZ3C435.js.map +0 -1
- package/dist/chunk-KDIRW72G.js.map +0 -1
- package/dist/chunk-UY2N42P2.js.map +0 -1
- package/dist/manifest-QLQKVSML.js +0 -8
- package/dist/shotList-MAQVLZBY.js.map +0 -1
- /package/dist/{assetManifest-MQ7HO7RZ.js.map → assetManifest-U25FJER6.js.map} +0 -0
- /package/dist/{manifest-QLQKVSML.js.map → manifest-VTOIEUHJ.js.map} +0 -0
- /package/dist/{run-UNOXIGZ3.js.map → run-UKWKAGDK.js.map} +0 -0
|
@@ -80,6 +80,12 @@
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
|
+
"ready": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"enum": ["dom", "networkidle"],
|
|
86
|
+
"default": "dom",
|
|
87
|
+
"description": "When the first page counts as ready for step 1. dom: after load, once the page has made no DOM change for 800 ms, at most 8 s. networkidle: once the network has gone quiet, at most 45 s, which a page holding a socket open or an analytics beacon never does. The same mode opens a setup goto, the page after a setup, and an await's reload. `--ready` overrides. The done event's `ready` says how the first load settled ({ mode, ms, capped }); `navTimeout` is true only when networkidle was asked for and never came."
|
|
88
|
+
},
|
|
83
89
|
"mask": {
|
|
84
90
|
"type": "array",
|
|
85
91
|
"description": "Hidden BEFORE the first frame is captured and kept hidden across navigations and re-renders: what a signed-in account shows that must not ship. The real value is never in a frame, never in the recording, never pushed. `vos record` reports what it still sees afterwards (meta.exposures), and a mask whose selector reached nothing fails --strict.",
|
|
@@ -104,6 +110,11 @@
|
|
|
104
110
|
}
|
|
105
111
|
}
|
|
106
112
|
},
|
|
113
|
+
"settle": {
|
|
114
|
+
"type": "boolean",
|
|
115
|
+
"default": false,
|
|
116
|
+
"description": "every gesture step waits on the app after it (a step's own settle overrides): a canvas that falls behind under load finishes the last stroke before the next one starts"
|
|
117
|
+
},
|
|
107
118
|
"steps": {
|
|
108
119
|
"type": "array",
|
|
109
120
|
"minItems": 1,
|
|
@@ -140,14 +151,24 @@
|
|
|
140
151
|
},
|
|
141
152
|
{
|
|
142
153
|
"type": "object",
|
|
143
|
-
"required": ["do"
|
|
154
|
+
"required": ["do"],
|
|
144
155
|
"additionalProperties": false,
|
|
145
156
|
"properties": {
|
|
146
157
|
"do": {
|
|
147
158
|
"const": "hover"
|
|
148
159
|
},
|
|
149
160
|
"selector": {
|
|
150
|
-
"type": "string"
|
|
161
|
+
"type": "string",
|
|
162
|
+
"description": "the element whose centre the pointer goes to; or x and y instead"
|
|
163
|
+
},
|
|
164
|
+
"x": {
|
|
165
|
+
"type": "number",
|
|
166
|
+
"minimum": 0,
|
|
167
|
+
"description": "with y: a viewport point in CSS px, for a spot no selector names (a place on a canvas); takes no selector"
|
|
168
|
+
},
|
|
169
|
+
"y": {
|
|
170
|
+
"type": "number",
|
|
171
|
+
"minimum": 0
|
|
151
172
|
},
|
|
152
173
|
"ms": {
|
|
153
174
|
"type": "number",
|
|
@@ -155,6 +176,10 @@
|
|
|
155
176
|
"default": 700,
|
|
156
177
|
"description": "Dwell — parked cursor becomes a zoom signal."
|
|
157
178
|
},
|
|
179
|
+
"settle": {
|
|
180
|
+
"type": "boolean",
|
|
181
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
182
|
+
},
|
|
158
183
|
"id": {
|
|
159
184
|
"type": "string",
|
|
160
185
|
"minLength": 1,
|
|
@@ -170,11 +195,33 @@
|
|
|
170
195
|
"minLength": 1,
|
|
171
196
|
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
172
197
|
}
|
|
173
|
-
}
|
|
198
|
+
},
|
|
199
|
+
"oneOf": [
|
|
200
|
+
{
|
|
201
|
+
"required": ["selector"],
|
|
202
|
+
"not": {
|
|
203
|
+
"anyOf": [
|
|
204
|
+
{
|
|
205
|
+
"required": ["x"]
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"required": ["y"]
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"required": ["x", "y"],
|
|
215
|
+
"not": {
|
|
216
|
+
"required": ["selector"]
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"description": "Rest the pointer on an element's centre (selector) or on a viewport point (x, y); ms is the dwell, a zoom signal."
|
|
174
221
|
},
|
|
175
222
|
{
|
|
176
223
|
"type": "object",
|
|
177
|
-
"required": ["do"
|
|
224
|
+
"required": ["do"],
|
|
178
225
|
"additionalProperties": false,
|
|
179
226
|
"properties": {
|
|
180
227
|
"do": {
|
|
@@ -186,7 +233,42 @@
|
|
|
186
233
|
"description": "the read after the press, ms (default 150), held from the page's last visual change: the recorder watches the screencast and pays the settle itself (a change within 400 ms says the page is answering, 250 ms of quiet says it settled, 1.2 s bounds a page that never stops), so the same ms reads the same on every run. Size it as a reading beat, about 1000 after a navigation and 600 after a control, never padded for a slow page."
|
|
187
234
|
},
|
|
188
235
|
"selector": {
|
|
189
|
-
"type": "string"
|
|
236
|
+
"type": "string",
|
|
237
|
+
"description": "the element whose centre the pointer goes to; or x and y instead"
|
|
238
|
+
},
|
|
239
|
+
"x": {
|
|
240
|
+
"type": "number",
|
|
241
|
+
"minimum": 0,
|
|
242
|
+
"description": "with y: a viewport point in CSS px, for a spot no selector names (a place on a canvas); takes no selector"
|
|
243
|
+
},
|
|
244
|
+
"y": {
|
|
245
|
+
"type": "number",
|
|
246
|
+
"minimum": 0
|
|
247
|
+
},
|
|
248
|
+
"count": {
|
|
249
|
+
"type": "integer",
|
|
250
|
+
"enum": [1, 2, 3],
|
|
251
|
+
"default": 1,
|
|
252
|
+
"description": "2 is a real double click, 3 a triple click: that many presses inside the platform's double-click interval, each carrying its click count; every press is a down and an up on the cursor track"
|
|
253
|
+
},
|
|
254
|
+
"button": {
|
|
255
|
+
"type": "string",
|
|
256
|
+
"enum": ["left", "right", "middle"],
|
|
257
|
+
"default": "left",
|
|
258
|
+
"description": "the button pressed: right opens a context menu"
|
|
259
|
+
},
|
|
260
|
+
"modifiers": {
|
|
261
|
+
"type": "array",
|
|
262
|
+
"uniqueItems": true,
|
|
263
|
+
"items": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"enum": ["Alt", "Shift", "Meta", "Control", "Mod"]
|
|
266
|
+
},
|
|
267
|
+
"description": "held for the press (a Shift-click adds to the selection) and released after it, whatever happens; Mod is Meta on macOS, Control elsewhere"
|
|
268
|
+
},
|
|
269
|
+
"settle": {
|
|
270
|
+
"type": "boolean",
|
|
271
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
190
272
|
},
|
|
191
273
|
"id": {
|
|
192
274
|
"type": "string",
|
|
@@ -202,8 +284,34 @@
|
|
|
202
284
|
"type": "string",
|
|
203
285
|
"minLength": 1,
|
|
204
286
|
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
287
|
+
},
|
|
288
|
+
"guard": {
|
|
289
|
+
"type": "string",
|
|
290
|
+
"enum": ["spend"],
|
|
291
|
+
"description": "the step costs something real (credits, a purchase, a message sent): `vos record --dry-run` hovers it and never presses it, and `vos record` presses it only with `--confirm <id>`, refusing before any capture otherwise. Needs an id. A hosted take refuses a guarded step"
|
|
205
292
|
}
|
|
206
|
-
}
|
|
293
|
+
},
|
|
294
|
+
"oneOf": [
|
|
295
|
+
{
|
|
296
|
+
"required": ["selector"],
|
|
297
|
+
"not": {
|
|
298
|
+
"anyOf": [
|
|
299
|
+
{
|
|
300
|
+
"required": ["x"]
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"required": ["y"]
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"required": ["x", "y"],
|
|
310
|
+
"not": {
|
|
311
|
+
"required": ["selector"]
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
]
|
|
207
315
|
},
|
|
208
316
|
{
|
|
209
317
|
"type": "object",
|
|
@@ -235,6 +343,10 @@
|
|
|
235
343
|
"default": true,
|
|
236
344
|
"description": "The recorder clicks the field before typing, and that click is what opens the typing zoom on it. false types into the field as it is already focused: for a keystroke that finishes earlier typing (a submitting Enter) rather than starting it, where a second click rings a click effect on empty space beside the text."
|
|
237
345
|
},
|
|
346
|
+
"settle": {
|
|
347
|
+
"type": "boolean",
|
|
348
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
349
|
+
},
|
|
238
350
|
"id": {
|
|
239
351
|
"type": "string",
|
|
240
352
|
"minLength": 1,
|
|
@@ -259,14 +371,19 @@
|
|
|
259
371
|
"type": "string",
|
|
260
372
|
"enum": ["end", "start"],
|
|
261
373
|
"description": "where the caret goes after the focusing click, before the first character: a click lands it where the pointer hit, and a code editor line is typed at its end"
|
|
374
|
+
},
|
|
375
|
+
"guard": {
|
|
376
|
+
"type": "string",
|
|
377
|
+
"enum": ["spend"],
|
|
378
|
+
"description": "the step costs something real (credits, a purchase, a message sent): `vos record --dry-run` hovers it and never presses it, and `vos record` presses it only with `--confirm <id>`, refusing before any capture otherwise. Needs an id. A hosted take refuses a guarded step"
|
|
262
379
|
}
|
|
263
380
|
}
|
|
264
381
|
},
|
|
265
382
|
{
|
|
266
383
|
"type": "object",
|
|
267
|
-
"required": ["do"
|
|
384
|
+
"required": ["do"],
|
|
268
385
|
"additionalProperties": false,
|
|
269
|
-
"description": "
|
|
386
|
+
"description": "A key, a chord or a sequence, each recorded as a typing ping where the pointer is (or on selector when given, with no click), never as the key itself. key names one control key (Escape closes what a click opened, Enter submits what was typed); keys names a chord (\"Shift+D\", \"Mod+Z\", Mod being Meta on macOS and Control elsewhere), a plain key (\"r\", a tool's shortcut) or a sequence ([\"v\", \"Escape\"]), 150 ms apart. Words are typed with type.",
|
|
270
387
|
"properties": {
|
|
271
388
|
"do": {
|
|
272
389
|
"const": "press"
|
|
@@ -290,6 +407,24 @@
|
|
|
290
407
|
"Space"
|
|
291
408
|
]
|
|
292
409
|
},
|
|
410
|
+
"keys": {
|
|
411
|
+
"oneOf": [
|
|
412
|
+
{
|
|
413
|
+
"type": "string",
|
|
414
|
+
"minLength": 1
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"type": "array",
|
|
418
|
+
"minItems": 1,
|
|
419
|
+
"maxItems": 50,
|
|
420
|
+
"items": {
|
|
421
|
+
"type": "string",
|
|
422
|
+
"minLength": 1
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
],
|
|
426
|
+
"description": "a key name or chord (modifiers Shift, Control, Alt, Meta, Mod, ControlOrMeta joined with + before the key; a key is a single character, a named key like Escape or ArrowLeft, F1 to F24, or a code like KeyA or Digit1), or a list of them pressed in order"
|
|
427
|
+
},
|
|
293
428
|
"selector": {
|
|
294
429
|
"type": "string",
|
|
295
430
|
"description": "the element the key is about: the ping and the step's rect are its, with no click"
|
|
@@ -299,6 +434,10 @@
|
|
|
299
434
|
"minimum": 0,
|
|
300
435
|
"description": "the read after the key, ms (default 150), held from the page's last visual change like a click's"
|
|
301
436
|
},
|
|
437
|
+
"settle": {
|
|
438
|
+
"type": "boolean",
|
|
439
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
440
|
+
},
|
|
302
441
|
"id": {
|
|
303
442
|
"type": "string",
|
|
304
443
|
"minLength": 1,
|
|
@@ -313,8 +452,21 @@
|
|
|
313
452
|
"type": "string",
|
|
314
453
|
"minLength": 1,
|
|
315
454
|
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
455
|
+
},
|
|
456
|
+
"guard": {
|
|
457
|
+
"type": "string",
|
|
458
|
+
"enum": ["spend"],
|
|
459
|
+
"description": "the step costs something real (credits, a purchase, a message sent): `vos record --dry-run` hovers it and never presses it, and `vos record` presses it only with `--confirm <id>`, refusing before any capture otherwise. Needs an id. A hosted take refuses a guarded step"
|
|
316
460
|
}
|
|
317
|
-
}
|
|
461
|
+
},
|
|
462
|
+
"oneOf": [
|
|
463
|
+
{
|
|
464
|
+
"required": ["key"]
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
"required": ["keys"]
|
|
468
|
+
}
|
|
469
|
+
]
|
|
318
470
|
},
|
|
319
471
|
{
|
|
320
472
|
"type": "object",
|
|
@@ -332,6 +484,10 @@
|
|
|
332
484
|
"dy": {
|
|
333
485
|
"type": "number"
|
|
334
486
|
},
|
|
487
|
+
"settle": {
|
|
488
|
+
"type": "boolean",
|
|
489
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
490
|
+
},
|
|
335
491
|
"id": {
|
|
336
492
|
"type": "string",
|
|
337
493
|
"minLength": 1,
|
|
@@ -365,6 +521,10 @@
|
|
|
365
521
|
"type": "number",
|
|
366
522
|
"minimum": 0
|
|
367
523
|
},
|
|
524
|
+
"settle": {
|
|
525
|
+
"type": "boolean",
|
|
526
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
527
|
+
},
|
|
368
528
|
"id": {
|
|
369
529
|
"type": "string",
|
|
370
530
|
"minLength": 1,
|
|
@@ -384,9 +544,9 @@
|
|
|
384
544
|
},
|
|
385
545
|
{
|
|
386
546
|
"type": "object",
|
|
387
|
-
"required": ["do"
|
|
547
|
+
"required": ["do"],
|
|
388
548
|
"additionalProperties": false,
|
|
389
|
-
"description": "Press-move-release: drag an element, slide a range input, move a clip. Start = selector center when given, else (x, y); end = (tx, ty), eased over ms.",
|
|
549
|
+
"description": "Press-move-release: drag an element, slide a range input, move a clip. Start = selector center when given, else (x, y); end = (tx, ty), eased over ms. With path, the drag DRAWS: the press at the path's first point, a move at every later point in order (never dropped, so a page that answers slowly makes the stroke late, reported as meta.steps[].overrunMs, never a different stroke), the release at its last. modifiers are held from the press to the release.",
|
|
390
550
|
"properties": {
|
|
391
551
|
"do": {
|
|
392
552
|
"const": "drag"
|
|
@@ -410,10 +570,287 @@
|
|
|
410
570
|
"type": "number",
|
|
411
571
|
"minimum": 0
|
|
412
572
|
},
|
|
573
|
+
"path": {
|
|
574
|
+
"oneOf": [
|
|
575
|
+
{
|
|
576
|
+
"type": "array",
|
|
577
|
+
"minItems": 2,
|
|
578
|
+
"maxItems": 20000,
|
|
579
|
+
"items": {
|
|
580
|
+
"$ref": "#/$defs/pathPoint"
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
"type": "string",
|
|
585
|
+
"pattern": "^(?!\\.)(?!.*\\.\\.)[^/\\\\]+$",
|
|
586
|
+
"description": "a JSON file beside the actions file (a plain name) holding the points, or { \"points\": [...] }"
|
|
587
|
+
}
|
|
588
|
+
],
|
|
589
|
+
"description": "viewport points to draw through, replayed by their own times (tMs from the first point) or, untimed, evenly over ms. A point that carries pressure draws the whole path with a pen (pointer events with that pressure); without, the mouse draws it. A path takes no selector, x, y, tx or ty"
|
|
590
|
+
},
|
|
591
|
+
"modifiers": {
|
|
592
|
+
"type": "array",
|
|
593
|
+
"uniqueItems": true,
|
|
594
|
+
"items": {
|
|
595
|
+
"type": "string",
|
|
596
|
+
"enum": ["Alt", "Shift", "Meta", "Control", "Mod"]
|
|
597
|
+
},
|
|
598
|
+
"description": "held from the press to the release (Alt-drag to duplicate, Shift to constrain); Mod is Meta on macOS, Control elsewhere"
|
|
599
|
+
},
|
|
413
600
|
"ms": {
|
|
414
601
|
"type": "number",
|
|
415
602
|
"minimum": 0,
|
|
416
|
-
"default": 700
|
|
603
|
+
"default": 700,
|
|
604
|
+
"description": "the travel of a straight drag, or of an untimed path (default 700)"
|
|
605
|
+
},
|
|
606
|
+
"settle": {
|
|
607
|
+
"type": "boolean",
|
|
608
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
609
|
+
},
|
|
610
|
+
"id": {
|
|
611
|
+
"type": "string",
|
|
612
|
+
"minLength": 1,
|
|
613
|
+
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
614
|
+
},
|
|
615
|
+
"caption": {
|
|
616
|
+
"type": "string",
|
|
617
|
+
"maxLength": 80,
|
|
618
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on a loop"
|
|
619
|
+
},
|
|
620
|
+
"read": {
|
|
621
|
+
"type": "string",
|
|
622
|
+
"minLength": 1,
|
|
623
|
+
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
"oneOf": [
|
|
627
|
+
{
|
|
628
|
+
"required": ["tx", "ty"],
|
|
629
|
+
"not": {
|
|
630
|
+
"required": ["path"]
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
"required": ["path"]
|
|
635
|
+
}
|
|
636
|
+
]
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
"type": "object",
|
|
640
|
+
"required": ["do"],
|
|
641
|
+
"additionalProperties": false,
|
|
642
|
+
"description": "Check the page is as the flow expects, on camera, with no cursor move: exactly one of selector (visible; with enabled, enabled or disabled), text (some visible text contains it) or gone (no longer visible). A condition that never holds is a skip with its reason, which --strict turns into exit 2.",
|
|
643
|
+
"oneOf": [
|
|
644
|
+
{
|
|
645
|
+
"required": ["selector"]
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
"required": ["text"]
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
"required": ["gone"]
|
|
652
|
+
}
|
|
653
|
+
],
|
|
654
|
+
"properties": {
|
|
655
|
+
"do": {
|
|
656
|
+
"const": "expect"
|
|
657
|
+
},
|
|
658
|
+
"selector": {
|
|
659
|
+
"type": "string",
|
|
660
|
+
"minLength": 1
|
|
661
|
+
},
|
|
662
|
+
"text": {
|
|
663
|
+
"type": "string",
|
|
664
|
+
"minLength": 1
|
|
665
|
+
},
|
|
666
|
+
"gone": {
|
|
667
|
+
"type": "string",
|
|
668
|
+
"minLength": 1
|
|
669
|
+
},
|
|
670
|
+
"enabled": {
|
|
671
|
+
"type": "boolean",
|
|
672
|
+
"description": "with selector: wait for the element to be enabled (true) or disabled (false)"
|
|
673
|
+
},
|
|
674
|
+
"timeout": {
|
|
675
|
+
"type": "number",
|
|
676
|
+
"exclusiveMinimum": 0,
|
|
677
|
+
"default": 5,
|
|
678
|
+
"description": "seconds to wait for the condition"
|
|
679
|
+
},
|
|
680
|
+
"id": {
|
|
681
|
+
"type": "string",
|
|
682
|
+
"minLength": 1,
|
|
683
|
+
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
684
|
+
},
|
|
685
|
+
"caption": {
|
|
686
|
+
"type": "string",
|
|
687
|
+
"maxLength": 80,
|
|
688
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on a loop"
|
|
689
|
+
},
|
|
690
|
+
"read": {
|
|
691
|
+
"type": "string",
|
|
692
|
+
"minLength": 1,
|
|
693
|
+
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
"type": "object",
|
|
699
|
+
"required": ["do", "until"],
|
|
700
|
+
"additionalProperties": false,
|
|
701
|
+
"description": "Wait OFF CAMERA for something slow (a render, a generated result): the capture stops, the condition is polled, and the capture resumes when it holds, so the footage has no gap and no frozen stretch. The cut lands in meta.skips[] ({ step, id, at, ms }) and becomes a segment boundary in the planned doc.json. A rehearsal waits for real and prints the time.",
|
|
702
|
+
"properties": {
|
|
703
|
+
"do": {
|
|
704
|
+
"const": "await"
|
|
705
|
+
},
|
|
706
|
+
"until": {
|
|
707
|
+
"type": "object",
|
|
708
|
+
"additionalProperties": false,
|
|
709
|
+
"minProperties": 1,
|
|
710
|
+
"maxProperties": 1,
|
|
711
|
+
"properties": {
|
|
712
|
+
"selector": {
|
|
713
|
+
"type": "string",
|
|
714
|
+
"minLength": 1
|
|
715
|
+
},
|
|
716
|
+
"text": {
|
|
717
|
+
"type": "string",
|
|
718
|
+
"minLength": 1
|
|
719
|
+
},
|
|
720
|
+
"gone": {
|
|
721
|
+
"type": "string",
|
|
722
|
+
"minLength": 1
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
"timeout": {
|
|
727
|
+
"type": "number",
|
|
728
|
+
"exclusiveMinimum": 0,
|
|
729
|
+
"default": 600,
|
|
730
|
+
"description": "the most seconds to wait"
|
|
731
|
+
},
|
|
732
|
+
"poll": {
|
|
733
|
+
"type": "number",
|
|
734
|
+
"exclusiveMinimum": 0,
|
|
735
|
+
"default": 2,
|
|
736
|
+
"description": "seconds between looks"
|
|
737
|
+
},
|
|
738
|
+
"reload": {
|
|
739
|
+
"type": "boolean",
|
|
740
|
+
"default": false,
|
|
741
|
+
"description": "reload the page between looks"
|
|
742
|
+
},
|
|
743
|
+
"onTimeout": {
|
|
744
|
+
"type": "string",
|
|
745
|
+
"enum": ["fail", "continue"],
|
|
746
|
+
"default": "fail",
|
|
747
|
+
"description": "fail: the take stops there, exit 1; continue: the capture resumes and the skip records timedOut"
|
|
748
|
+
},
|
|
749
|
+
"id": {
|
|
750
|
+
"type": "string",
|
|
751
|
+
"minLength": 1,
|
|
752
|
+
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
753
|
+
},
|
|
754
|
+
"caption": {
|
|
755
|
+
"type": "string",
|
|
756
|
+
"maxLength": 80,
|
|
757
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on a loop"
|
|
758
|
+
},
|
|
759
|
+
"read": {
|
|
760
|
+
"type": "string",
|
|
761
|
+
"minLength": 1,
|
|
762
|
+
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"type": "object",
|
|
768
|
+
"required": ["do"],
|
|
769
|
+
"additionalProperties": false,
|
|
770
|
+
"description": "Keep a file the page makes, in the take's outputs/: selector clicks a control and waits up to 30 s for the browser's download; src fetches the currentSrc of a video, audio or img element with the page's own cookies. Listed in meta.outputs[] ({ step, id, name, bytes, contentType }). A download that never arrives is a skip with its reason. A hosted take refuses a download.",
|
|
771
|
+
"oneOf": [
|
|
772
|
+
{
|
|
773
|
+
"required": ["selector"]
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
"required": ["src"]
|
|
777
|
+
}
|
|
778
|
+
],
|
|
779
|
+
"properties": {
|
|
780
|
+
"do": {
|
|
781
|
+
"const": "download"
|
|
782
|
+
},
|
|
783
|
+
"selector": {
|
|
784
|
+
"type": "string",
|
|
785
|
+
"minLength": 1
|
|
786
|
+
},
|
|
787
|
+
"src": {
|
|
788
|
+
"type": "string",
|
|
789
|
+
"minLength": 1,
|
|
790
|
+
"description": "a selector (the same grammar as every other step) of a video, audio or img element"
|
|
791
|
+
},
|
|
792
|
+
"as": {
|
|
793
|
+
"type": "string",
|
|
794
|
+
"minLength": 1,
|
|
795
|
+
"pattern": "^(?!\\.)(?!.*\\.\\.)[^/\\\\]+$",
|
|
796
|
+
"description": "the file name inside outputs/ (a plain name: no path separator, no \"..\"); absent, the name the page suggested"
|
|
797
|
+
},
|
|
798
|
+
"id": {
|
|
799
|
+
"type": "string",
|
|
800
|
+
"minLength": 1,
|
|
801
|
+
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
802
|
+
},
|
|
803
|
+
"caption": {
|
|
804
|
+
"type": "string",
|
|
805
|
+
"maxLength": 80,
|
|
806
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on a loop"
|
|
807
|
+
},
|
|
808
|
+
"read": {
|
|
809
|
+
"type": "string",
|
|
810
|
+
"minLength": 1,
|
|
811
|
+
"description": "a selector whose words the recorder keeps once the step has settled (meta.steps[].text, trimmed, at most 2 KB): the take's own payload, which a layer quotes instead of a replay; on a click, what the click opened"
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"type": "object",
|
|
817
|
+
"required": ["do"],
|
|
818
|
+
"additionalProperties": false,
|
|
819
|
+
"description": "Put words or a file on the clipboard and paste it the way a person's ⌘V does: the browser's own clipboard and a trusted paste chord, so the page gets a trusted keydown and paste event and navigator.clipboard.read() sees the item; when the browser refuses the item, a paste event dispatched in the page (untrusted, said in the log). Into selector (clicked first) or where the focus is. Recorded as a typing ping, never its contents. A hosted take refuses a paste.",
|
|
820
|
+
"oneOf": [
|
|
821
|
+
{
|
|
822
|
+
"required": ["text"]
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
"required": ["file"]
|
|
826
|
+
}
|
|
827
|
+
],
|
|
828
|
+
"properties": {
|
|
829
|
+
"do": {
|
|
830
|
+
"const": "paste"
|
|
831
|
+
},
|
|
832
|
+
"selector": {
|
|
833
|
+
"type": "string",
|
|
834
|
+
"minLength": 1,
|
|
835
|
+
"description": "the element to paste into, clicked first"
|
|
836
|
+
},
|
|
837
|
+
"text": {
|
|
838
|
+
"type": "string",
|
|
839
|
+
"description": "the words to paste"
|
|
840
|
+
},
|
|
841
|
+
"file": {
|
|
842
|
+
"type": "string",
|
|
843
|
+
"pattern": "^(?!\\.)(?!.*\\.\\.)[^/\\\\]+\\.(png|jpe?g|webp|gif|svg|txt|md|html?|json|csv)$",
|
|
844
|
+
"description": "a file beside the actions file, by a plain name, at most 10 MB: an image (a picture other than PNG is pasted as PNG), an SVG (also as its markup), or text"
|
|
845
|
+
},
|
|
846
|
+
"ms": {
|
|
847
|
+
"type": "number",
|
|
848
|
+
"minimum": 0,
|
|
849
|
+
"description": "the read after the paste, ms (default 150), held from the page's last visual change like a click's"
|
|
850
|
+
},
|
|
851
|
+
"settle": {
|
|
852
|
+
"type": "boolean",
|
|
853
|
+
"description": "after the gesture, wait until the page has made no DOM change and painted no new frame for 300 ms (at most 4 s), so an app that fell behind catches up before the next step; meta.steps[].settleMs says how long it waited. Absent: the script's top-level settle"
|
|
417
854
|
},
|
|
418
855
|
"id": {
|
|
419
856
|
"type": "string",
|
|
@@ -435,5 +872,45 @@
|
|
|
435
872
|
]
|
|
436
873
|
}
|
|
437
874
|
}
|
|
875
|
+
},
|
|
876
|
+
"$defs": {
|
|
877
|
+
"pathPoint": {
|
|
878
|
+
"oneOf": [
|
|
879
|
+
{
|
|
880
|
+
"type": "array",
|
|
881
|
+
"minItems": 2,
|
|
882
|
+
"maxItems": 4,
|
|
883
|
+
"items": {
|
|
884
|
+
"type": "number"
|
|
885
|
+
},
|
|
886
|
+
"description": "[x, y], [x, y, tMs] or [x, y, tMs, pressure]: every point timed or none"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
"type": "object",
|
|
890
|
+
"required": ["x", "y"],
|
|
891
|
+
"additionalProperties": false,
|
|
892
|
+
"properties": {
|
|
893
|
+
"x": {
|
|
894
|
+
"type": "number",
|
|
895
|
+
"minimum": 0
|
|
896
|
+
},
|
|
897
|
+
"y": {
|
|
898
|
+
"type": "number",
|
|
899
|
+
"minimum": 0
|
|
900
|
+
},
|
|
901
|
+
"t": {
|
|
902
|
+
"type": "number",
|
|
903
|
+
"minimum": 0,
|
|
904
|
+
"description": "ms"
|
|
905
|
+
},
|
|
906
|
+
"pressure": {
|
|
907
|
+
"type": "number",
|
|
908
|
+
"minimum": 0,
|
|
909
|
+
"maximum": 1
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
]
|
|
914
|
+
}
|
|
438
915
|
}
|
|
439
916
|
}
|