@vosjs/cli 0.43.0 → 0.44.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 +2 -0
- package/dist/chunk-RDQYYRWN.js +107 -0
- package/dist/chunk-RDQYYRWN.js.map +1 -0
- package/dist/{chunk-6PJPGBKH.js → chunk-WCSAECM4.js} +30 -93
- package/dist/chunk-WCSAECM4.js.map +1 -0
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -1
- package/dist/{run-ZYROWQ3T.js → run-CRRKT34P.js} +3 -2
- package/dist/shotList-FYDHO5AI.js +111 -0
- package/dist/shotList-FYDHO5AI.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-6PJPGBKH.js.map +0 -1
- /package/dist/{run-ZYROWQ3T.js.map → run-CRRKT34P.js.map} +0 -0
package/README.md
CHANGED
|
@@ -101,6 +101,8 @@ vos plan take --reuse # re-time that cut onto
|
|
|
101
101
|
]
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
**`vos actions script <actions.json>`: the flow as a shot list.** When no rung of the session ladder holds and a person has to record the take themselves (in their own signed-in browser, with the vosso extension), the agent hands over the flow it worked out rather than an apology: numbered beats in plain words with the holds the script asked for, the page to start on and about how long. A step's `caption` leads its beat, a `text=` or `:has-text()` selector is said as its words, and a step's `id` is said as a name (`new-order` reads as "new order"), so give steps ids and captions that a person could follow. `--json` carries the beats beside the text. The take comes back through the ordinary handoff, and the agent cuts it (`vos pull --media`, then the `vos-cut` skill).
|
|
105
|
+
|
|
104
106
|
**`--header name=value`**, repeatable: a request header on every request the recording browser makes, the way past a preview deployment protected by a bypass header alone (`--header x-vercel-protection-bypass=$TOKEN`). The rehearsal's `Next:` line carries it.
|
|
105
107
|
|
|
106
108
|
**What the frame shows.** Getting past a login puts the account's own data in the picture, and asking for a demo account does not hold that line: a person asked to sign in signs in as themselves. So the recorder looks. After the page opens and after every step it reads the text visible in the viewport and reports the KIND of thing it saw and where, never the string: an email address (one on `example.com` or a `.test`, `.example`, `.invalid` or `.localhost` domain is demo data and is not reported), something shaped like an API key or a JWT, a card number that passes the Luhn check, a masked card's visible tail. They land in `meta.exposures[]` (`step`, `kind`, `selector`, `rect`, `seen`), in the `record` and `create` done events, at the end of a rehearsal (before anything is recorded), as warnings in `vos validate <take>`, and in the digest's `take.exposures`. They warn; they do not fail a take, because a product may legitimately show addresses. The `selector` reaches that element and no other, so it can be pasted into a mask.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/plugin/pace.ts
|
|
4
|
+
var POINTER_MS_PER_PX = 0.7;
|
|
5
|
+
var POINTER_MIN_MS = 250;
|
|
6
|
+
var POINTER_MAX_MS = 800;
|
|
7
|
+
var MOTION_TICK_MS = 16;
|
|
8
|
+
var SETTLE_MS = {
|
|
9
|
+
click: 150,
|
|
10
|
+
type: 150,
|
|
11
|
+
scroll: 200,
|
|
12
|
+
drag: 80
|
|
13
|
+
};
|
|
14
|
+
var PRESS_LEAD_MS = 80;
|
|
15
|
+
var PRESS_HOLD_MS = 70;
|
|
16
|
+
var SCROLL_SETTLE_MS = 120;
|
|
17
|
+
var TRAILING_HOLD_MS = 400;
|
|
18
|
+
function pointerTravelMs(dist) {
|
|
19
|
+
return Math.min(
|
|
20
|
+
POINTER_MAX_MS,
|
|
21
|
+
Math.max(POINTER_MIN_MS, Math.round(dist * POINTER_MS_PER_PX))
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
function settleMs(step) {
|
|
25
|
+
if (typeof step.ms === "number" && step.ms >= 0) return step.ms;
|
|
26
|
+
const d = step.do;
|
|
27
|
+
return SETTLE_MS[d] ?? 0;
|
|
28
|
+
}
|
|
29
|
+
var easeInOutCubic = (u) => u < 0.5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2;
|
|
30
|
+
async function clockMotion(dur, at, clock) {
|
|
31
|
+
const start = clock.now();
|
|
32
|
+
let samples = 0;
|
|
33
|
+
for (; ; ) {
|
|
34
|
+
const elapsed = clock.now() - start;
|
|
35
|
+
if (elapsed >= dur) break;
|
|
36
|
+
await at(easeInOutCubic(Math.min(1, elapsed / dur)));
|
|
37
|
+
samples++;
|
|
38
|
+
const next = start + Math.ceil((clock.now() - start) / MOTION_TICK_MS) * MOTION_TICK_MS;
|
|
39
|
+
const wait = Math.min(next, start + dur) - clock.now();
|
|
40
|
+
if (wait > 0) await clock.sleep(wait);
|
|
41
|
+
}
|
|
42
|
+
await at(1);
|
|
43
|
+
return samples + 1;
|
|
44
|
+
}
|
|
45
|
+
async function clockTyping(chars, delay, type, clock) {
|
|
46
|
+
const start = clock.now();
|
|
47
|
+
for (let i = 0; i < chars.length; i++) {
|
|
48
|
+
await type(chars[i], i);
|
|
49
|
+
const due = start + (i + 1) * delay;
|
|
50
|
+
const wait = due - clock.now();
|
|
51
|
+
if (wait > 0 && i < chars.length - 1) await clock.sleep(wait);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function askedMs(step) {
|
|
55
|
+
switch (step.do) {
|
|
56
|
+
case "wait":
|
|
57
|
+
return step.ms ?? 0;
|
|
58
|
+
case "hover":
|
|
59
|
+
return step.ms ?? 700;
|
|
60
|
+
case "drag":
|
|
61
|
+
return step.ms ?? 700;
|
|
62
|
+
case "type":
|
|
63
|
+
return (step.text?.length ?? 0) * (step.delayMs ?? 40);
|
|
64
|
+
default:
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function paceReport(steps) {
|
|
69
|
+
const askedMs2 = steps.reduce((a, s) => a + s.askedMs, 0);
|
|
70
|
+
const gestureMs = steps.reduce((a, s) => a + s.gestureMs, 0);
|
|
71
|
+
const wallMs = steps.reduce((a, s) => a + s.wallMs, 0);
|
|
72
|
+
const overheadMs = Math.max(0, wallMs - askedMs2 - gestureMs);
|
|
73
|
+
const slow = steps.filter((s) => s.wallMs > (s.askedMs + s.gestureMs) * 1.34 + 60).map((s) => ({
|
|
74
|
+
step: s.step,
|
|
75
|
+
do: s.do,
|
|
76
|
+
askedMs: s.askedMs,
|
|
77
|
+
wallMs: s.wallMs
|
|
78
|
+
}));
|
|
79
|
+
return {
|
|
80
|
+
askedMs: askedMs2,
|
|
81
|
+
gestureMs,
|
|
82
|
+
wallMs,
|
|
83
|
+
overheadMs,
|
|
84
|
+
overheadPct: wallMs > 0 ? Math.round(overheadMs / wallMs * 100) : 0,
|
|
85
|
+
slow
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function paceLine(r) {
|
|
89
|
+
const s = (ms) => `${(ms / 1e3).toFixed(1)} s`;
|
|
90
|
+
const slow = r.slow.length ? `; slow: ${r.slow.map((x) => `#${x.step} ${x.do} ${s(x.wallMs)} for ${s(x.askedMs)} asked`).join(", ")}` : "";
|
|
91
|
+
return `pace: the script asked ${s(r.askedMs)}, the gestures added ${s(r.gestureMs)}, the take ran ${s(r.wallMs)} (${r.overheadPct} % overhead${slow})`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
PRESS_LEAD_MS,
|
|
96
|
+
PRESS_HOLD_MS,
|
|
97
|
+
SCROLL_SETTLE_MS,
|
|
98
|
+
TRAILING_HOLD_MS,
|
|
99
|
+
pointerTravelMs,
|
|
100
|
+
settleMs,
|
|
101
|
+
clockMotion,
|
|
102
|
+
clockTyping,
|
|
103
|
+
askedMs,
|
|
104
|
+
paceReport,
|
|
105
|
+
paceLine
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=chunk-RDQYYRWN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin/pace.ts"],"sourcesContent":["/**\n * The recorder's pace — the pure parts.\n *\n * A take of a scripted flow should run as long as the script asks, plus the\n * gestures a person makes between the asks (the pointer's travel, the press,\n * the settle after it) and no more. Measured before this module (§4.5 of\n * the utility-clip retrospective), hovers ran 2× their ask, drags 4.8× and\n * a 25 s script recorded 42 s, for two reasons the numbers here answer:\n *\n * - The motion loops counted STEPS (one per 16 ms of the asked duration)\n * and awaited a `mouse.move` round trip per step, so a page that\n * re-renders per move (a slider) stretched every gesture by the round\n * trip. A gesture is now driven by the CLOCK: its position is a function\n * of the elapsed time, and it ends when the asked duration has elapsed,\n * however many samples the page allowed.\n * - The settles after a gesture were fixed sleeps (500 ms after a click,\n * 250 after every selector lookup). A settle is DATA: `ms` on the step\n * overrides a small default, and the script's own `wait` steps carry\n * the intended pauses.\n */\n\n/** Pointer travel: ms per CSS px, floor and ceiling — a person's hand. */\nexport const POINTER_MS_PER_PX = 0.7\nexport const POINTER_MIN_MS = 250\nexport const POINTER_MAX_MS = 800\n/** The sample cadence a motion loop aims for. */\nexport const MOTION_TICK_MS = 16\n\n/** The settle after a gesture when the step names none, by verb. */\nexport const SETTLE_MS = {\n click: 150,\n type: 150,\n scroll: 200,\n drag: 80,\n} as const\n\n/** The press: the pause before the button goes down, and the hold. */\nexport const PRESS_LEAD_MS = 80\nexport const PRESS_HOLD_MS = 70\n/** The pause between a selector lookup that scrolled the page and the move. */\nexport const SCROLL_SETTLE_MS = 120\n/** The hold after the last step, so the take does not cut on a press. */\nexport const TRAILING_HOLD_MS = 400\n\n/** How long the pointer takes to travel `dist` CSS px. */\nexport function pointerTravelMs(dist: number): number {\n return Math.min(\n POINTER_MAX_MS,\n Math.max(POINTER_MIN_MS, Math.round(dist * POINTER_MS_PER_PX)),\n )\n}\n\n/** The settle after a step: its own `ms` when it names one, else the verb's. */\nexport function settleMs(step: { do: string; ms?: number }): number {\n if (typeof step.ms === 'number' && step.ms >= 0) return step.ms\n const d = step.do as keyof typeof SETTLE_MS\n return SETTLE_MS[d] ?? 0\n}\n\nexport const easeInOutCubic = (u: number): number =>\n u < 0.5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2\n\n/**\n * Drive a motion by the clock: `at(u)` is called with the eased progress\n * for each sample, and the loop ends when `dur` ms have elapsed, with the\n * last call at u = 1 exactly. Between samples it sleeps to the next tick\n * only when the sample came back early; a slow sample (a page busy\n * re-rendering) is followed at once, so the gesture keeps its length and\n * loses samples, never the other way round.\n */\nexport async function clockMotion(\n dur: number,\n at: (u: number) => Promise<void>,\n clock: { now: () => number; sleep: (ms: number) => Promise<void> },\n): Promise<number> {\n const start = clock.now()\n let samples = 0\n for (;;) {\n const elapsed = clock.now() - start\n if (elapsed >= dur) break\n await at(easeInOutCubic(Math.min(1, elapsed / dur)))\n samples++\n const next =\n start + Math.ceil((clock.now() - start) / MOTION_TICK_MS) * MOTION_TICK_MS\n const wait = Math.min(next, start + dur) - clock.now()\n if (wait > 0) await clock.sleep(wait)\n }\n await at(1)\n return samples + 1\n}\n\n/**\n * Typing paced by the clock: the i-th character is due at `start + i·delay`;\n * after each keystroke the loop sleeps to the next due time only if the\n * keystroke came back early. A slow field (an editor re-rendering per key)\n * types as fast as it can and says so in the pace report.\n */\nexport async function clockTyping(\n chars: readonly string[],\n delay: number,\n type: (ch: string, index: number) => Promise<void>,\n clock: { now: () => number; sleep: (ms: number) => Promise<void> },\n): Promise<void> {\n const start = clock.now()\n for (let i = 0; i < chars.length; i++) {\n await type(chars[i], i)\n const due = start + (i + 1) * delay\n const wait = due - clock.now()\n if (wait > 0 && i < chars.length - 1) await clock.sleep(wait)\n }\n}\n\n/** One step's pace: what the script asked for it and what it took. */\nexport interface StepPace {\n step: number\n do: string\n /** The script's own ask: a wait's ms, a hover's dwell, a drag's ms, typing's chars × delay; 0 for a click or a scroll. */\n askedMs: number\n /** The gesture the recorder adds by design: pointer travel, the press, the settle. */\n gestureMs: number\n wallMs: number\n}\n\nexport interface PaceReport {\n askedMs: number\n gestureMs: number\n wallMs: number\n /** Wall time neither asked nor a gesture: what the page and the round trips cost. */\n overheadMs: number\n overheadPct: number\n /** The steps whose wall ran past their ask plus gesture by more than a third. */\n slow: { step: number; do: string; askedMs: number; wallMs: number }[]\n}\n\n/** What a script asks of a step, in ms: the part of its wall time that is the author's. */\nexport function askedMs(step: {\n do: string\n ms?: number\n text?: string\n delayMs?: number\n}): number {\n switch (step.do) {\n case 'wait':\n return step.ms ?? 0\n case 'hover':\n return step.ms ?? 700\n case 'drag':\n return step.ms ?? 700\n case 'type':\n return (step.text?.length ?? 0) * (step.delayMs ?? 40)\n default:\n return 0\n }\n}\n\nexport function paceReport(steps: readonly StepPace[]): PaceReport {\n const askedMs = steps.reduce((a, s) => a + s.askedMs, 0)\n const gestureMs = steps.reduce((a, s) => a + s.gestureMs, 0)\n const wallMs = steps.reduce((a, s) => a + s.wallMs, 0)\n const overheadMs = Math.max(0, wallMs - askedMs - gestureMs)\n const slow = steps\n .filter((s) => s.wallMs > (s.askedMs + s.gestureMs) * 1.34 + 60)\n .map((s) => ({\n step: s.step,\n do: s.do,\n askedMs: s.askedMs,\n wallMs: s.wallMs,\n }))\n return {\n askedMs,\n gestureMs,\n wallMs,\n overheadMs,\n overheadPct: wallMs > 0 ? Math.round((overheadMs / wallMs) * 100) : 0,\n slow,\n }\n}\n\n/** The pace in one line for the log. */\nexport function paceLine(r: PaceReport): string {\n const s = (ms: number) => `${(ms / 1000).toFixed(1)} s`\n const slow = r.slow.length\n ? `; slow: ${r.slow.map((x) => `#${x.step} ${x.do} ${s(x.wallMs)} for ${s(x.askedMs)} asked`).join(', ')}`\n : ''\n return `pace: the script asked ${s(r.askedMs)}, the gestures added ${s(r.gestureMs)}, the take ran ${s(r.wallMs)} (${r.overheadPct} % overhead${slow})`\n}\n"],"mappings":"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","names":["askedMs"]}
|
|
@@ -6,6 +6,19 @@ import {
|
|
|
6
6
|
noteGivenFlag,
|
|
7
7
|
trackFlags
|
|
8
8
|
} from "./chunk-FACYY7VV.js";
|
|
9
|
+
import {
|
|
10
|
+
PRESS_HOLD_MS,
|
|
11
|
+
PRESS_LEAD_MS,
|
|
12
|
+
SCROLL_SETTLE_MS,
|
|
13
|
+
TRAILING_HOLD_MS,
|
|
14
|
+
askedMs,
|
|
15
|
+
clockMotion,
|
|
16
|
+
clockTyping,
|
|
17
|
+
paceLine,
|
|
18
|
+
paceReport,
|
|
19
|
+
pointerTravelMs,
|
|
20
|
+
settleMs
|
|
21
|
+
} from "./chunk-RDQYYRWN.js";
|
|
9
22
|
|
|
10
23
|
// src/plugin/run.ts
|
|
11
24
|
import { mkdir as mkdir10, readFile as readFile15, rm as rm5 } from "fs/promises";
|
|
@@ -6686,97 +6699,6 @@ function cappedLine(capSeconds) {
|
|
|
6686
6699
|
return `stopped at ${formatDurationCap(capSeconds)} (--max-duration ${capSeconds}); the remaining steps did not run`;
|
|
6687
6700
|
}
|
|
6688
6701
|
|
|
6689
|
-
// src/plugin/pace.ts
|
|
6690
|
-
var POINTER_MS_PER_PX = 0.7;
|
|
6691
|
-
var POINTER_MIN_MS = 250;
|
|
6692
|
-
var POINTER_MAX_MS = 800;
|
|
6693
|
-
var MOTION_TICK_MS = 16;
|
|
6694
|
-
var SETTLE_MS = {
|
|
6695
|
-
click: 150,
|
|
6696
|
-
type: 150,
|
|
6697
|
-
scroll: 200,
|
|
6698
|
-
drag: 80
|
|
6699
|
-
};
|
|
6700
|
-
var PRESS_LEAD_MS = 80;
|
|
6701
|
-
var PRESS_HOLD_MS = 70;
|
|
6702
|
-
var SCROLL_SETTLE_MS = 120;
|
|
6703
|
-
var TRAILING_HOLD_MS = 400;
|
|
6704
|
-
function pointerTravelMs(dist) {
|
|
6705
|
-
return Math.min(
|
|
6706
|
-
POINTER_MAX_MS,
|
|
6707
|
-
Math.max(POINTER_MIN_MS, Math.round(dist * POINTER_MS_PER_PX))
|
|
6708
|
-
);
|
|
6709
|
-
}
|
|
6710
|
-
function settleMs(step) {
|
|
6711
|
-
if (typeof step.ms === "number" && step.ms >= 0) return step.ms;
|
|
6712
|
-
const d = step.do;
|
|
6713
|
-
return SETTLE_MS[d] ?? 0;
|
|
6714
|
-
}
|
|
6715
|
-
var easeInOutCubic = (u) => u < 0.5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2;
|
|
6716
|
-
async function clockMotion(dur, at2, clock) {
|
|
6717
|
-
const start = clock.now();
|
|
6718
|
-
let samples = 0;
|
|
6719
|
-
for (; ; ) {
|
|
6720
|
-
const elapsed = clock.now() - start;
|
|
6721
|
-
if (elapsed >= dur) break;
|
|
6722
|
-
await at2(easeInOutCubic(Math.min(1, elapsed / dur)));
|
|
6723
|
-
samples++;
|
|
6724
|
-
const next = start + Math.ceil((clock.now() - start) / MOTION_TICK_MS) * MOTION_TICK_MS;
|
|
6725
|
-
const wait2 = Math.min(next, start + dur) - clock.now();
|
|
6726
|
-
if (wait2 > 0) await clock.sleep(wait2);
|
|
6727
|
-
}
|
|
6728
|
-
await at2(1);
|
|
6729
|
-
return samples + 1;
|
|
6730
|
-
}
|
|
6731
|
-
async function clockTyping(chars, delay, type, clock) {
|
|
6732
|
-
const start = clock.now();
|
|
6733
|
-
for (let i = 0; i < chars.length; i++) {
|
|
6734
|
-
await type(chars[i], i);
|
|
6735
|
-
const due = start + (i + 1) * delay;
|
|
6736
|
-
const wait2 = due - clock.now();
|
|
6737
|
-
if (wait2 > 0 && i < chars.length - 1) await clock.sleep(wait2);
|
|
6738
|
-
}
|
|
6739
|
-
}
|
|
6740
|
-
function askedMs(step) {
|
|
6741
|
-
switch (step.do) {
|
|
6742
|
-
case "wait":
|
|
6743
|
-
return step.ms ?? 0;
|
|
6744
|
-
case "hover":
|
|
6745
|
-
return step.ms ?? 700;
|
|
6746
|
-
case "drag":
|
|
6747
|
-
return step.ms ?? 700;
|
|
6748
|
-
case "type":
|
|
6749
|
-
return (step.text?.length ?? 0) * (step.delayMs ?? 40);
|
|
6750
|
-
default:
|
|
6751
|
-
return 0;
|
|
6752
|
-
}
|
|
6753
|
-
}
|
|
6754
|
-
function paceReport(steps) {
|
|
6755
|
-
const askedMs2 = steps.reduce((a, s) => a + s.askedMs, 0);
|
|
6756
|
-
const gestureMs = steps.reduce((a, s) => a + s.gestureMs, 0);
|
|
6757
|
-
const wallMs = steps.reduce((a, s) => a + s.wallMs, 0);
|
|
6758
|
-
const overheadMs = Math.max(0, wallMs - askedMs2 - gestureMs);
|
|
6759
|
-
const slow = steps.filter((s) => s.wallMs > (s.askedMs + s.gestureMs) * 1.34 + 60).map((s) => ({
|
|
6760
|
-
step: s.step,
|
|
6761
|
-
do: s.do,
|
|
6762
|
-
askedMs: s.askedMs,
|
|
6763
|
-
wallMs: s.wallMs
|
|
6764
|
-
}));
|
|
6765
|
-
return {
|
|
6766
|
-
askedMs: askedMs2,
|
|
6767
|
-
gestureMs,
|
|
6768
|
-
wallMs,
|
|
6769
|
-
overheadMs,
|
|
6770
|
-
overheadPct: wallMs > 0 ? Math.round(overheadMs / wallMs * 100) : 0,
|
|
6771
|
-
slow
|
|
6772
|
-
};
|
|
6773
|
-
}
|
|
6774
|
-
function paceLine(r) {
|
|
6775
|
-
const s = (ms) => `${(ms / 1e3).toFixed(1)} s`;
|
|
6776
|
-
const slow = r.slow.length ? `; slow: ${r.slow.map((x) => `#${x.step} ${x.do} ${s(x.wallMs)} for ${s(x.askedMs)} asked`).join(", ")}` : "";
|
|
6777
|
-
return `pace: the script asked ${s(r.askedMs)}, the gestures added ${s(r.gestureMs)}, the take ran ${s(r.wallMs)} (${r.overheadPct} % overhead${slow})`;
|
|
6778
|
-
}
|
|
6779
|
-
|
|
6780
6702
|
// src/plugin/wall.ts
|
|
6781
6703
|
var IDP_HOSTS = [
|
|
6782
6704
|
"accounts.google.com",
|
|
@@ -10588,9 +10510,10 @@ function convertAgentBrowser(records, opts = {}) {
|
|
|
10588
10510
|
async function cmdActions(argv) {
|
|
10589
10511
|
const { positionals, flags } = parseArgs(argv, /* @__PURE__ */ new Set(["json"]));
|
|
10590
10512
|
const [sub, input] = positionals;
|
|
10513
|
+
if (sub === "script" && input) return cmdActionsScript(input, flags);
|
|
10591
10514
|
if (sub !== "from-agent-browser" || !input) {
|
|
10592
10515
|
throw new UsageError(
|
|
10593
|
-
"vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url <url>] [--viewport WxH] [--json]"
|
|
10516
|
+
"vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url <url>] [--viewport WxH] [--json]\n vos actions script <actions.json> [--json]"
|
|
10594
10517
|
);
|
|
10595
10518
|
}
|
|
10596
10519
|
const r = createReporter(flags.json === true);
|
|
@@ -10638,6 +10561,18 @@ function summary(result) {
|
|
|
10638
10561
|
notes: result.notes
|
|
10639
10562
|
};
|
|
10640
10563
|
}
|
|
10564
|
+
async function cmdActionsScript(input, flags) {
|
|
10565
|
+
const r = createReporter(flags.json === true);
|
|
10566
|
+
const { readFile: readFile16 } = await import("fs/promises");
|
|
10567
|
+
const { shotList, formatShotList } = await import("./shotList-FYDHO5AI.js");
|
|
10568
|
+
const raw = JSON.parse(await readFile16(resolve8(input), "utf8"));
|
|
10569
|
+
const errors = validateActions(raw);
|
|
10570
|
+
if (errors.length) throw new UsageError(`${input}:
|
|
10571
|
+
${errors.join("\n ")}`);
|
|
10572
|
+
const list = shotList(raw);
|
|
10573
|
+
r.done({ ...list, text: formatShotList(list) }, formatShotList(list));
|
|
10574
|
+
return EXIT_OK;
|
|
10575
|
+
}
|
|
10641
10576
|
|
|
10642
10577
|
// src/plugin/run.ts
|
|
10643
10578
|
var BOOLEAN_FLAGS5 = /* @__PURE__ */ new Set([
|
|
@@ -10680,6 +10615,8 @@ Take pipeline
|
|
|
10680
10615
|
vos validate <actions.json|take|kit.json> [--picture] [--json]
|
|
10681
10616
|
vos judge <kit.json> --against <MANIFEST.json> [--out dir] [--json]
|
|
10682
10617
|
vos actions from-agent-browser <steps.jsonl> [--out actions.json] [--url <url>] [--viewport WxH] [--json]
|
|
10618
|
+
vos actions script <actions.json> [--json]
|
|
10619
|
+
the flow as numbered beats in words, for a person recording it by hand
|
|
10683
10620
|
|
|
10684
10621
|
Platform (vos.so) \u2014 fetch, edit, push, pull, repeat
|
|
10685
10622
|
vos login [--key <vos_sk_\u2026>] [--label <name>] [--no-browser]
|
|
@@ -12411,4 +12348,4 @@ export {
|
|
|
12411
12348
|
verbHelp,
|
|
12412
12349
|
run
|
|
12413
12350
|
};
|
|
12414
|
-
//# sourceMappingURL=chunk-
|
|
12351
|
+
//# sourceMappingURL=chunk-WCSAECM4.js.map
|