@vosjs/cli 0.78.0 → 0.80.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 +152 -31
- package/dist/{assetManifest-S6H5F2VE.js → assetManifest-ETT3C7ZA.js} +3 -3
- package/dist/{chunk-JYCW4EOA.js → chunk-B373NVJE.js} +7 -3
- package/dist/chunk-B373NVJE.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-RUDDBHQ7.js → chunk-OWYOJB7K.js} +5 -1
- package/dist/chunk-OWYOJB7K.js.map +1 -0
- package/dist/{chunk-ZSJEISKL.js → chunk-PJ6MEJZV.js} +213 -28
- package/dist/chunk-PJ6MEJZV.js.map +1 -0
- package/dist/{chunk-INRUYQ6J.js → chunk-SP5OHTVB.js} +4285 -1560
- package/dist/chunk-SP5OHTVB.js.map +1 -0
- package/dist/cli.js +17 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.js +5 -5
- package/dist/manifest-VTOIEUHJ.js +8 -0
- package/dist/{run-TIFM3ZHI.js → run-2ELHMPTB.js} +5 -5
- package/dist/{shotList-SCA234OS.js → shotList-MSNWLVDN.js} +63 -9
- package/dist/shotList-MSNWLVDN.js.map +1 -0
- package/package.json +3 -3
- package/schema/actions.schema.json +498 -17
- package/schema/doc.schema.json +46 -5
- package/skills/VERSION +1 -1
- package/skills/launch-kit/SKILL.md +12 -3
- package/skills/product-video/SKILL.md +34 -0
- package/skills/product-video/references/taste.md +7 -3
- package/skills/vos-authoring/SKILL.md +8 -1
- package/skills/vos-create/SKILL.md +5 -0
- package/skills/vos-cut/SKILL.md +25 -2
- package/skills/vos-footage/SKILL.md +4 -0
- package/skills/vos-migrate/SKILL.md +4 -0
- package/dist/chunk-B4U4URE3.js.map +0 -1
- package/dist/chunk-INRUYQ6J.js.map +0 -1
- package/dist/chunk-JYCW4EOA.js.map +0 -1
- package/dist/chunk-RUDDBHQ7.js.map +0 -1
- package/dist/chunk-ZSJEISKL.js.map +0 -1
- package/dist/manifest-6DJSPKVH.js +0 -8
- package/dist/shotList-SCA234OS.js.map +0 -1
- /package/dist/{assetManifest-S6H5F2VE.js.map → assetManifest-ETT3C7ZA.js.map} +0 -0
- /package/dist/{manifest-6DJSPKVH.js.map → manifest-VTOIEUHJ.js.map} +0 -0
- /package/dist/{run-TIFM3ZHI.js.map → run-2ELHMPTB.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,
|
|
@@ -165,16 +190,42 @@
|
|
|
165
190
|
"maxLength": 80,
|
|
166
191
|
"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"
|
|
167
192
|
},
|
|
193
|
+
"zoom": {
|
|
194
|
+
"type": "boolean",
|
|
195
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
196
|
+
},
|
|
168
197
|
"read": {
|
|
169
198
|
"type": "string",
|
|
170
199
|
"minLength": 1,
|
|
171
200
|
"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
201
|
}
|
|
173
|
-
}
|
|
202
|
+
},
|
|
203
|
+
"oneOf": [
|
|
204
|
+
{
|
|
205
|
+
"required": ["selector"],
|
|
206
|
+
"not": {
|
|
207
|
+
"anyOf": [
|
|
208
|
+
{
|
|
209
|
+
"required": ["x"]
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"required": ["y"]
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"required": ["x", "y"],
|
|
219
|
+
"not": {
|
|
220
|
+
"required": ["selector"]
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"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
225
|
},
|
|
175
226
|
{
|
|
176
227
|
"type": "object",
|
|
177
|
-
"required": ["do"
|
|
228
|
+
"required": ["do"],
|
|
178
229
|
"additionalProperties": false,
|
|
179
230
|
"properties": {
|
|
180
231
|
"do": {
|
|
@@ -186,7 +237,42 @@
|
|
|
186
237
|
"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
238
|
},
|
|
188
239
|
"selector": {
|
|
189
|
-
"type": "string"
|
|
240
|
+
"type": "string",
|
|
241
|
+
"description": "the element whose centre the pointer goes to; or x and y instead"
|
|
242
|
+
},
|
|
243
|
+
"x": {
|
|
244
|
+
"type": "number",
|
|
245
|
+
"minimum": 0,
|
|
246
|
+
"description": "with y: a viewport point in CSS px, for a spot no selector names (a place on a canvas); takes no selector"
|
|
247
|
+
},
|
|
248
|
+
"y": {
|
|
249
|
+
"type": "number",
|
|
250
|
+
"minimum": 0
|
|
251
|
+
},
|
|
252
|
+
"count": {
|
|
253
|
+
"type": "integer",
|
|
254
|
+
"enum": [1, 2, 3],
|
|
255
|
+
"default": 1,
|
|
256
|
+
"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"
|
|
257
|
+
},
|
|
258
|
+
"button": {
|
|
259
|
+
"type": "string",
|
|
260
|
+
"enum": ["left", "right", "middle"],
|
|
261
|
+
"default": "left",
|
|
262
|
+
"description": "the button pressed: right opens a context menu"
|
|
263
|
+
},
|
|
264
|
+
"modifiers": {
|
|
265
|
+
"type": "array",
|
|
266
|
+
"uniqueItems": true,
|
|
267
|
+
"items": {
|
|
268
|
+
"type": "string",
|
|
269
|
+
"enum": ["Alt", "Shift", "Meta", "Control", "Mod"]
|
|
270
|
+
},
|
|
271
|
+
"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"
|
|
272
|
+
},
|
|
273
|
+
"settle": {
|
|
274
|
+
"type": "boolean",
|
|
275
|
+
"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
276
|
},
|
|
191
277
|
"id": {
|
|
192
278
|
"type": "string",
|
|
@@ -198,6 +284,10 @@
|
|
|
198
284
|
"maxLength": 80,
|
|
199
285
|
"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"
|
|
200
286
|
},
|
|
287
|
+
"zoom": {
|
|
288
|
+
"type": "boolean",
|
|
289
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
290
|
+
},
|
|
201
291
|
"read": {
|
|
202
292
|
"type": "string",
|
|
203
293
|
"minLength": 1,
|
|
@@ -208,7 +298,28 @@
|
|
|
208
298
|
"enum": ["spend"],
|
|
209
299
|
"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"
|
|
210
300
|
}
|
|
211
|
-
}
|
|
301
|
+
},
|
|
302
|
+
"oneOf": [
|
|
303
|
+
{
|
|
304
|
+
"required": ["selector"],
|
|
305
|
+
"not": {
|
|
306
|
+
"anyOf": [
|
|
307
|
+
{
|
|
308
|
+
"required": ["x"]
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"required": ["y"]
|
|
312
|
+
}
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"required": ["x", "y"],
|
|
318
|
+
"not": {
|
|
319
|
+
"required": ["selector"]
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
]
|
|
212
323
|
},
|
|
213
324
|
{
|
|
214
325
|
"type": "object",
|
|
@@ -240,6 +351,10 @@
|
|
|
240
351
|
"default": true,
|
|
241
352
|
"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."
|
|
242
353
|
},
|
|
354
|
+
"settle": {
|
|
355
|
+
"type": "boolean",
|
|
356
|
+
"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"
|
|
357
|
+
},
|
|
243
358
|
"id": {
|
|
244
359
|
"type": "string",
|
|
245
360
|
"minLength": 1,
|
|
@@ -250,6 +365,10 @@
|
|
|
250
365
|
"maxLength": 80,
|
|
251
366
|
"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"
|
|
252
367
|
},
|
|
368
|
+
"zoom": {
|
|
369
|
+
"type": "boolean",
|
|
370
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
371
|
+
},
|
|
253
372
|
"read": {
|
|
254
373
|
"type": "string",
|
|
255
374
|
"minLength": 1,
|
|
@@ -274,9 +393,9 @@
|
|
|
274
393
|
},
|
|
275
394
|
{
|
|
276
395
|
"type": "object",
|
|
277
|
-
"required": ["do"
|
|
396
|
+
"required": ["do"],
|
|
278
397
|
"additionalProperties": false,
|
|
279
|
-
"description": "
|
|
398
|
+
"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.",
|
|
280
399
|
"properties": {
|
|
281
400
|
"do": {
|
|
282
401
|
"const": "press"
|
|
@@ -300,6 +419,24 @@
|
|
|
300
419
|
"Space"
|
|
301
420
|
]
|
|
302
421
|
},
|
|
422
|
+
"keys": {
|
|
423
|
+
"oneOf": [
|
|
424
|
+
{
|
|
425
|
+
"type": "string",
|
|
426
|
+
"minLength": 1
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"type": "array",
|
|
430
|
+
"minItems": 1,
|
|
431
|
+
"maxItems": 50,
|
|
432
|
+
"items": {
|
|
433
|
+
"type": "string",
|
|
434
|
+
"minLength": 1
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
],
|
|
438
|
+
"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"
|
|
439
|
+
},
|
|
303
440
|
"selector": {
|
|
304
441
|
"type": "string",
|
|
305
442
|
"description": "the element the key is about: the ping and the step's rect are its, with no click"
|
|
@@ -309,6 +446,10 @@
|
|
|
309
446
|
"minimum": 0,
|
|
310
447
|
"description": "the read after the key, ms (default 150), held from the page's last visual change like a click's"
|
|
311
448
|
},
|
|
449
|
+
"settle": {
|
|
450
|
+
"type": "boolean",
|
|
451
|
+
"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"
|
|
452
|
+
},
|
|
312
453
|
"id": {
|
|
313
454
|
"type": "string",
|
|
314
455
|
"minLength": 1,
|
|
@@ -319,6 +460,10 @@
|
|
|
319
460
|
"maxLength": 80,
|
|
320
461
|
"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"
|
|
321
462
|
},
|
|
463
|
+
"zoom": {
|
|
464
|
+
"type": "boolean",
|
|
465
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
466
|
+
},
|
|
322
467
|
"read": {
|
|
323
468
|
"type": "string",
|
|
324
469
|
"minLength": 1,
|
|
@@ -329,7 +474,15 @@
|
|
|
329
474
|
"enum": ["spend"],
|
|
330
475
|
"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"
|
|
331
476
|
}
|
|
332
|
-
}
|
|
477
|
+
},
|
|
478
|
+
"oneOf": [
|
|
479
|
+
{
|
|
480
|
+
"required": ["key"]
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"required": ["keys"]
|
|
484
|
+
}
|
|
485
|
+
]
|
|
333
486
|
},
|
|
334
487
|
{
|
|
335
488
|
"type": "object",
|
|
@@ -347,6 +500,10 @@
|
|
|
347
500
|
"dy": {
|
|
348
501
|
"type": "number"
|
|
349
502
|
},
|
|
503
|
+
"settle": {
|
|
504
|
+
"type": "boolean",
|
|
505
|
+
"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"
|
|
506
|
+
},
|
|
350
507
|
"id": {
|
|
351
508
|
"type": "string",
|
|
352
509
|
"minLength": 1,
|
|
@@ -380,6 +537,10 @@
|
|
|
380
537
|
"type": "number",
|
|
381
538
|
"minimum": 0
|
|
382
539
|
},
|
|
540
|
+
"settle": {
|
|
541
|
+
"type": "boolean",
|
|
542
|
+
"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"
|
|
543
|
+
},
|
|
383
544
|
"id": {
|
|
384
545
|
"type": "string",
|
|
385
546
|
"minLength": 1,
|
|
@@ -399,9 +560,9 @@
|
|
|
399
560
|
},
|
|
400
561
|
{
|
|
401
562
|
"type": "object",
|
|
402
|
-
"required": ["do"
|
|
563
|
+
"required": ["do"],
|
|
403
564
|
"additionalProperties": false,
|
|
404
|
-
"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.",
|
|
565
|
+
"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.",
|
|
405
566
|
"properties": {
|
|
406
567
|
"do": {
|
|
407
568
|
"const": "drag"
|
|
@@ -425,10 +586,42 @@
|
|
|
425
586
|
"type": "number",
|
|
426
587
|
"minimum": 0
|
|
427
588
|
},
|
|
589
|
+
"path": {
|
|
590
|
+
"oneOf": [
|
|
591
|
+
{
|
|
592
|
+
"type": "array",
|
|
593
|
+
"minItems": 2,
|
|
594
|
+
"maxItems": 20000,
|
|
595
|
+
"items": {
|
|
596
|
+
"$ref": "#/$defs/pathPoint"
|
|
597
|
+
}
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"type": "string",
|
|
601
|
+
"pattern": "^(?!\\.)(?!.*\\.\\.)[^/\\\\]+$",
|
|
602
|
+
"description": "a JSON file beside the actions file (a plain name) holding the points, or { \"points\": [...] }"
|
|
603
|
+
}
|
|
604
|
+
],
|
|
605
|
+
"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"
|
|
606
|
+
},
|
|
607
|
+
"modifiers": {
|
|
608
|
+
"type": "array",
|
|
609
|
+
"uniqueItems": true,
|
|
610
|
+
"items": {
|
|
611
|
+
"type": "string",
|
|
612
|
+
"enum": ["Alt", "Shift", "Meta", "Control", "Mod"]
|
|
613
|
+
},
|
|
614
|
+
"description": "held from the press to the release (Alt-drag to duplicate, Shift to constrain); Mod is Meta on macOS, Control elsewhere"
|
|
615
|
+
},
|
|
428
616
|
"ms": {
|
|
429
617
|
"type": "number",
|
|
430
618
|
"minimum": 0,
|
|
431
|
-
"default": 700
|
|
619
|
+
"default": 700,
|
|
620
|
+
"description": "the travel of a straight drag, or of an untimed path (default 700)"
|
|
621
|
+
},
|
|
622
|
+
"settle": {
|
|
623
|
+
"type": "boolean",
|
|
624
|
+
"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"
|
|
432
625
|
},
|
|
433
626
|
"id": {
|
|
434
627
|
"type": "string",
|
|
@@ -440,18 +633,33 @@
|
|
|
440
633
|
"maxLength": 80,
|
|
441
634
|
"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"
|
|
442
635
|
},
|
|
636
|
+
"zoom": {
|
|
637
|
+
"type": "boolean",
|
|
638
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
639
|
+
},
|
|
443
640
|
"read": {
|
|
444
641
|
"type": "string",
|
|
445
642
|
"minLength": 1,
|
|
446
643
|
"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"
|
|
447
644
|
}
|
|
448
|
-
}
|
|
645
|
+
},
|
|
646
|
+
"oneOf": [
|
|
647
|
+
{
|
|
648
|
+
"required": ["tx", "ty"],
|
|
649
|
+
"not": {
|
|
650
|
+
"required": ["path"]
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
"required": ["path"]
|
|
655
|
+
}
|
|
656
|
+
]
|
|
449
657
|
},
|
|
450
658
|
{
|
|
451
659
|
"type": "object",
|
|
452
660
|
"required": ["do"],
|
|
453
661
|
"additionalProperties": false,
|
|
454
|
-
"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)
|
|
662
|
+
"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), gone (no longer visible) or js (an expression evaluated in the page: holds when its value is truthy, or with equals when it equals that value; for state an app keeps in script, such as a canvas's shapes). A condition that never holds is a skip with its reason (a js check names the value it last got), which --strict turns into exit 2. A js check's last value is kept on meta.steps[].value. A hosted take refuses js.",
|
|
455
663
|
"oneOf": [
|
|
456
664
|
{
|
|
457
665
|
"required": ["selector"]
|
|
@@ -461,6 +669,9 @@
|
|
|
461
669
|
},
|
|
462
670
|
{
|
|
463
671
|
"required": ["gone"]
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
"required": ["js"]
|
|
464
675
|
}
|
|
465
676
|
],
|
|
466
677
|
"properties": {
|
|
@@ -483,6 +694,14 @@
|
|
|
483
694
|
"type": "boolean",
|
|
484
695
|
"description": "with selector: wait for the element to be enabled (true) or disabled (false)"
|
|
485
696
|
},
|
|
697
|
+
"js": {
|
|
698
|
+
"type": "string",
|
|
699
|
+
"minLength": 1,
|
|
700
|
+
"description": "a JavaScript expression evaluated in the page (a promise is awaited): the check holds when its value is truthy, or, with equals, when its value equals that one"
|
|
701
|
+
},
|
|
702
|
+
"equals": {
|
|
703
|
+
"description": "with js: the value the expression must answer, compared as JSON"
|
|
704
|
+
},
|
|
486
705
|
"timeout": {
|
|
487
706
|
"type": "number",
|
|
488
707
|
"exclusiveMinimum": 0,
|
|
@@ -518,8 +737,6 @@
|
|
|
518
737
|
"until": {
|
|
519
738
|
"type": "object",
|
|
520
739
|
"additionalProperties": false,
|
|
521
|
-
"minProperties": 1,
|
|
522
|
-
"maxProperties": 1,
|
|
523
740
|
"properties": {
|
|
524
741
|
"selector": {
|
|
525
742
|
"type": "string",
|
|
@@ -532,8 +749,91 @@
|
|
|
532
749
|
"gone": {
|
|
533
750
|
"type": "string",
|
|
534
751
|
"minLength": 1
|
|
752
|
+
},
|
|
753
|
+
"js": {
|
|
754
|
+
"type": "string",
|
|
755
|
+
"minLength": 1,
|
|
756
|
+
"description": "a JavaScript expression evaluated in the page (a promise is awaited): holds when its value is truthy, or, with equals, when its value equals that one. A hosted take refuses it."
|
|
757
|
+
},
|
|
758
|
+
"equals": {
|
|
759
|
+
"description": "with js: the value the expression must answer, compared as JSON"
|
|
535
760
|
}
|
|
536
|
-
}
|
|
761
|
+
},
|
|
762
|
+
"oneOf": [
|
|
763
|
+
{
|
|
764
|
+
"required": ["selector"],
|
|
765
|
+
"not": {
|
|
766
|
+
"anyOf": [
|
|
767
|
+
{
|
|
768
|
+
"required": ["text"]
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"required": ["gone"]
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
"required": ["js"]
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
"required": ["equals"]
|
|
778
|
+
}
|
|
779
|
+
]
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
"required": ["text"],
|
|
784
|
+
"not": {
|
|
785
|
+
"anyOf": [
|
|
786
|
+
{
|
|
787
|
+
"required": ["selector"]
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
"required": ["gone"]
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"required": ["js"]
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"required": ["equals"]
|
|
797
|
+
}
|
|
798
|
+
]
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"required": ["gone"],
|
|
803
|
+
"not": {
|
|
804
|
+
"anyOf": [
|
|
805
|
+
{
|
|
806
|
+
"required": ["selector"]
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
"required": ["text"]
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
"required": ["js"]
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
"required": ["equals"]
|
|
816
|
+
}
|
|
817
|
+
]
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
"required": ["js"],
|
|
822
|
+
"not": {
|
|
823
|
+
"anyOf": [
|
|
824
|
+
{
|
|
825
|
+
"required": ["selector"]
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"required": ["text"]
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
"required": ["gone"]
|
|
832
|
+
}
|
|
833
|
+
]
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
]
|
|
537
837
|
},
|
|
538
838
|
"timeout": {
|
|
539
839
|
"type": "number",
|
|
@@ -623,9 +923,190 @@
|
|
|
623
923
|
"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
924
|
}
|
|
625
925
|
}
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"type": "object",
|
|
929
|
+
"required": ["do"],
|
|
930
|
+
"additionalProperties": false,
|
|
931
|
+
"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.",
|
|
932
|
+
"oneOf": [
|
|
933
|
+
{
|
|
934
|
+
"required": ["text"]
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
"required": ["file"]
|
|
938
|
+
}
|
|
939
|
+
],
|
|
940
|
+
"properties": {
|
|
941
|
+
"do": {
|
|
942
|
+
"const": "paste"
|
|
943
|
+
},
|
|
944
|
+
"selector": {
|
|
945
|
+
"type": "string",
|
|
946
|
+
"minLength": 1,
|
|
947
|
+
"description": "the element to paste into, clicked first"
|
|
948
|
+
},
|
|
949
|
+
"text": {
|
|
950
|
+
"type": "string",
|
|
951
|
+
"description": "the words to paste"
|
|
952
|
+
},
|
|
953
|
+
"file": {
|
|
954
|
+
"type": "string",
|
|
955
|
+
"pattern": "^(?!\\.)(?!.*\\.\\.)[^/\\\\]+\\.(png|jpe?g|webp|gif|svg|txt|md|html?|json|csv)$",
|
|
956
|
+
"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"
|
|
957
|
+
},
|
|
958
|
+
"ms": {
|
|
959
|
+
"type": "number",
|
|
960
|
+
"minimum": 0,
|
|
961
|
+
"description": "the read after the paste, ms (default 150), held from the page's last visual change like a click's"
|
|
962
|
+
},
|
|
963
|
+
"settle": {
|
|
964
|
+
"type": "boolean",
|
|
965
|
+
"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"
|
|
966
|
+
},
|
|
967
|
+
"id": {
|
|
968
|
+
"type": "string",
|
|
969
|
+
"minLength": 1,
|
|
970
|
+
"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."
|
|
971
|
+
},
|
|
972
|
+
"caption": {
|
|
973
|
+
"type": "string",
|
|
974
|
+
"maxLength": 80,
|
|
975
|
+
"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"
|
|
976
|
+
},
|
|
977
|
+
"zoom": {
|
|
978
|
+
"type": "boolean",
|
|
979
|
+
"description": "the cut's camera on this step: true marks it as its beat's payoff (vos plan --zooms per-beat keeps the zoom on it and only it), false means never zoom here (the planner's proposal on it is rejected); the planner still decides level and focus"
|
|
980
|
+
},
|
|
981
|
+
"read": {
|
|
982
|
+
"type": "string",
|
|
983
|
+
"minLength": 1,
|
|
984
|
+
"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"
|
|
985
|
+
}
|
|
986
|
+
}
|
|
626
987
|
}
|
|
627
988
|
]
|
|
628
989
|
}
|
|
990
|
+
},
|
|
991
|
+
"peers": {
|
|
992
|
+
"type": "array",
|
|
993
|
+
"maxItems": 4,
|
|
994
|
+
"description": "Other people on the page, OFF CAMERA: each a browser context of its own (its own storage state, so its own user, or signed out) on the same url, driven by its own steps. Only the take's page is filmed and only the take's steps make the cursor track; what a peer does reaches the footage through the app's own sync (its presence, its remote cursors, the shape it drew). A peer step starts with a take step (`with`, as it starts) or after one (`after`, as it ends), named by id, else right after the peer's previous step (the first, as the camera rolls). The take never waits on a peer: wait for what the peer's work shows with the take's own expect or await. A hosted take refuses peers.",
|
|
995
|
+
"items": {
|
|
996
|
+
"type": "object",
|
|
997
|
+
"required": ["id", "steps"],
|
|
998
|
+
"additionalProperties": false,
|
|
999
|
+
"properties": {
|
|
1000
|
+
"id": {
|
|
1001
|
+
"type": "string",
|
|
1002
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$",
|
|
1003
|
+
"description": "a short word lines and meta.peers name the peer by"
|
|
1004
|
+
},
|
|
1005
|
+
"url": {
|
|
1006
|
+
"type": "string",
|
|
1007
|
+
"description": "the page the peer opens (http or https); absent, the take's url"
|
|
1008
|
+
},
|
|
1009
|
+
"viewport": {
|
|
1010
|
+
"type": "object",
|
|
1011
|
+
"required": ["width", "height"],
|
|
1012
|
+
"properties": {
|
|
1013
|
+
"width": {
|
|
1014
|
+
"type": "number"
|
|
1015
|
+
},
|
|
1016
|
+
"height": {
|
|
1017
|
+
"type": "number"
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
"storageState": {
|
|
1022
|
+
"type": "string",
|
|
1023
|
+
"minLength": 1,
|
|
1024
|
+
"description": "a Playwright storage state file (the second person's sign-in), by a path from the actions file's directory or an absolute one. Opened by the browser only: never copied into the take, never uploaded; a pushed script keeps its file name only. Absent, the peer is signed out. A peer that lands on a sign-in refuses the take."
|
|
1025
|
+
},
|
|
1026
|
+
"steps": {
|
|
1027
|
+
"type": "array",
|
|
1028
|
+
"minItems": 1,
|
|
1029
|
+
"maxItems": 200,
|
|
1030
|
+
"description": "The peer's steps: the take's own step shapes (see steps), for wait, move, hover, click, type, press, scroll, drag (path inline only) and expect, without guard, read, caption or settle, plus when each starts. Every step is bounded like a take step; a miss is a skip listed with the take's (peer set), which --strict fails on.",
|
|
1031
|
+
"items": {
|
|
1032
|
+
"type": "object",
|
|
1033
|
+
"required": ["do"],
|
|
1034
|
+
"properties": {
|
|
1035
|
+
"do": {
|
|
1036
|
+
"enum": [
|
|
1037
|
+
"wait",
|
|
1038
|
+
"move",
|
|
1039
|
+
"hover",
|
|
1040
|
+
"click",
|
|
1041
|
+
"type",
|
|
1042
|
+
"press",
|
|
1043
|
+
"scroll",
|
|
1044
|
+
"drag",
|
|
1045
|
+
"expect"
|
|
1046
|
+
]
|
|
1047
|
+
},
|
|
1048
|
+
"with": {
|
|
1049
|
+
"type": "string",
|
|
1050
|
+
"minLength": 1,
|
|
1051
|
+
"description": "start as the take's step with this id starts: the two run together"
|
|
1052
|
+
},
|
|
1053
|
+
"after": {
|
|
1054
|
+
"type": "string",
|
|
1055
|
+
"minLength": 1,
|
|
1056
|
+
"description": "start once the take's step with this id has ended"
|
|
1057
|
+
},
|
|
1058
|
+
"id": {
|
|
1059
|
+
"type": "string",
|
|
1060
|
+
"minLength": 1
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
"not": {
|
|
1064
|
+
"required": ["with", "after"]
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
},
|
|
1072
|
+
"$defs": {
|
|
1073
|
+
"pathPoint": {
|
|
1074
|
+
"oneOf": [
|
|
1075
|
+
{
|
|
1076
|
+
"type": "array",
|
|
1077
|
+
"minItems": 2,
|
|
1078
|
+
"maxItems": 4,
|
|
1079
|
+
"items": {
|
|
1080
|
+
"type": "number"
|
|
1081
|
+
},
|
|
1082
|
+
"description": "[x, y], [x, y, tMs] or [x, y, tMs, pressure]: every point timed or none"
|
|
1083
|
+
},
|
|
1084
|
+
{
|
|
1085
|
+
"type": "object",
|
|
1086
|
+
"required": ["x", "y"],
|
|
1087
|
+
"additionalProperties": false,
|
|
1088
|
+
"properties": {
|
|
1089
|
+
"x": {
|
|
1090
|
+
"type": "number",
|
|
1091
|
+
"minimum": 0
|
|
1092
|
+
},
|
|
1093
|
+
"y": {
|
|
1094
|
+
"type": "number",
|
|
1095
|
+
"minimum": 0
|
|
1096
|
+
},
|
|
1097
|
+
"t": {
|
|
1098
|
+
"type": "number",
|
|
1099
|
+
"minimum": 0,
|
|
1100
|
+
"description": "ms"
|
|
1101
|
+
},
|
|
1102
|
+
"pressure": {
|
|
1103
|
+
"type": "number",
|
|
1104
|
+
"minimum": 0,
|
|
1105
|
+
"maximum": 1
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
]
|
|
629
1110
|
}
|
|
630
1111
|
}
|
|
631
1112
|
}
|