@vosjs/cli 0.41.0 → 0.41.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/README.md CHANGED
@@ -90,7 +90,7 @@ vos plan take --reuse # re-time that cut onto
90
90
 
91
91
  **The wall check.** Once the first navigation settles, and before a frame is captured, `record`, `create` and `--dry-run` ask whether the recorder landed where it was sent. A take that met a sign-in instead is refused with exit 4 and a sentence (`asked for /dashboard, landed on /login: no session for app.acme.com`): the asked URL answered 401 or 403, the recorder was sent to an identity provider or a sign-in path, or the page is a sign-in form (one password field, or a one-time-code field) rendered in place. A redirect somewhere else with no sign-in in sight, which is what a site that shows strangers a public page looks like, is refused under `--strict` and in a rehearsal, and said as a warning otherwise. The check runs before a re-record clears anything, so a session that expired since the last take never costs the footage it failed to replace. The way past a wall is a session: `--storage-state <file>`, minted from the test auth the project already has wherever that exists. `--allow-wall` records the page anyway (a video OF a sign-in page is a legitimate take), and the take's `meta.wall` and its digest then say so.
92
92
 
93
- **Rehearse before you record.** `vos record … --dry-run` runs every step against the real page, in order, because a later selector usually exists only after an earlier click. Nothing is captured and nothing is written: the pointer lands instead of travelling, every pause is cut to a beat, and the take directory beside it keeps its footage, its cut and its script exactly as they were (a real re-record moves `doc.json` aside; a rehearsal does not). Selector lookups keep their whole timeout, so a miss here is a miss in the take. It prints each step with the rect it resolved, in capture px, which are the rects a pin or `vos callout --step` reads, and exits 2 on any miss or a first load that never settled. Add `--dry-run` to the exact command you were about to run; `--storage-state` and `--browser-arg=` apply to it too.
93
+ **Rehearse before you record.** `vos record … --dry-run` runs every step against the real page, in order, because a later selector usually exists only after an earlier click. Nothing is captured and nothing is written: the pointer lands instead of travelling, every pause is cut to a beat, and the take directory beside it keeps its footage, its cut and its script exactly as they were (a real re-record moves `doc.json` aside; a rehearsal does not). Selector lookups keep their whole timeout, so a miss here is a miss in the take. It prints each step with the rect it resolved, in capture px, which are the rects a pin or `vos callout --step` reads, and exits 2 on any miss or a first load that never settled. Add `--dry-run` to the exact command you were about to run; `--storage-state` and `--browser-arg=` apply to it too, and the `Next:` line it prints carries them, so the command it hands you records what it rehearsed.
94
94
 
95
95
  **Digest first.** `vos digest <take>` is how an agent sees a recording without reading the video. It writes `digest/digest.json`: one moment per thing the cursor track says mattered (click clusters, typing sessions, scroll runs, dwells, idle gaps, head, tail, and frame-diff scene changes), each with source and output extents, a normalized `focus` and `rect` you can copy into a zoom span, per-second `activity`, and the planners' `proposed` span ids; plus one footage frame and a crop around the target per moment, and `sheet.png`, the contact sheet. Read the JSON, then the sheet, then a crop only where you must decide. `vos validate` then warns when a zoom does not contain what was clicked under it, and `vos frames --at-moments` renders the composed output at every moment so a still and its footage crop share an id.
96
96
 
@@ -256,6 +256,7 @@ vos push /tmp/take --label "$TAG launch" --yes --json # VOS_API_KEY as a r
256
256
  ## For scripts and agents
257
257
 
258
258
  - **Output.** Logs on stderr, results on stdout. `--json` turns every verb into NDJSON events ending with `{"event":"done",…}`.
259
+ - **`vos <verb> --help`** prints that verb's usage lines and exits 0 (it used to be a usage error).
259
260
  - **Exit codes.** 0 ok, 1 error, 2 usage (including `--strict` failures), 3 no browser found, 4 the recorder met a wall (a sign-in, or under `--strict` a redirect away from the asked page) and nothing was recorded or cleared. `--json` carries the verdict as a `wall` event (`kind`, `level`, `asked`, `landed`, `refused`).
260
261
  - **`--strict`** on `record` and `create` (agents: always): a skipped selector, a page that never reaches network idle, or a take that hit `--max-duration` exits 2 and lists `skipped[]` (and `capped`) in the done event. The default is lenient (exit 0, `skipped[]` still reported) for exploratory runs.
261
262
  - **`--max-duration <s>`** on `record` and `create` defaults to the hosted recording cap, read live from `GET /api/limits` (2 s, fail-open to 30 min when the origin is unreachable): the capture stops there and the done event says so. Cut the flow rather than raising the cap; the platform refuses a longer take.
@@ -6687,7 +6687,7 @@ function redirectedAway(asked, landed) {
6687
6687
  if (l.endsWith(a)) return false;
6688
6688
  return true;
6689
6689
  }
6690
- var LADDER = 'Walk the session ladder (mint a session from the test auth the project already has, or pass --storage-state): https://vos.so/llms-full.txt, "Sessions". A take OF this page is --allow-wall.';
6690
+ var LADDER = 'This is a missing or expired session, not a script bug. Ways past, cheapest first: mint a session from the test auth the project already has; script the sign-in off camera and save the storage state; or have a person sign in once (npx playwright open --channel chrome --save-storage=<file> <url>). Then pass --storage-state <file>. The ladder: https://vos.so/llms-full.txt, "Sessions". A take OF this page is --allow-wall.';
6691
6691
  function wallVerdict(a) {
6692
6692
  const asked = parse(a.askedUrl);
6693
6693
  const landed = parse(a.landedUrl);
@@ -10675,6 +10675,12 @@ async function cmdRecord(argv) {
10675
10675
  return ` ${s.skipped ? "\u2717" : "\u2713"} #${s.step}${s.id ? ` (${s.id})` : ""} ${s.do}${what}${s.skipped ? " NOT FOUND" : rect}${s.navigated ? " \u2192 navigated" : ""}`;
10676
10676
  });
10677
10677
  const failed2 = rec.skipped.length > 0 || rec.navTimeout;
10678
+ const carried = [
10679
+ ...strFlag(flags, "storage-state") ? [`--storage-state ${strFlag(flags, "storage-state")}`] : [],
10680
+ ...browserArgs.map((a) => `--browser-arg=${a}`),
10681
+ ...flags["allow-wall"] === true ? ["--allow-wall"] : []
10682
+ ].join(" ");
10683
+ const nextOut = strFlag(flags, "out") ?? "take";
10678
10684
  r.done(
10679
10685
  {
10680
10686
  dryRun: true,
@@ -10686,7 +10692,7 @@ async function cmdRecord(argv) {
10686
10692
  },
10687
10693
  `${failed2 ? "REHEARSAL FAILED" : "Rehearsal passed"}: ${steps.length - rec.skipped.length}/${steps.length} steps resolved in ${((Date.now() - started) / 1e3).toFixed(1)}s${rec.navTimeout ? " (the first load never reached networkidle)" : ""}
10688
10694
  ${lines.join("\n")}
10689
- ${failed2 ? "Fix the script, rehearse again, then record." : `Rects are capture px (the step rects a pin or a callout reads). Next: vos record --actions ${actionsPath} --out ${outDir} --strict`}`
10695
+ ${failed2 ? "Fix the script, rehearse again, then record." : `Rects are capture px (the step rects a pin or a callout reads). Next: vos record --actions ${actionsPath} --out ${nextOut}${carried ? ` ${carried}` : ""} --strict`}`
10690
10696
  );
10691
10697
  return failed2 ? EXIT_USAGE : EXIT_OK;
10692
10698
  } finally {
@@ -11842,6 +11848,23 @@ async function cmdPull2(argv) {
11842
11848
  );
11843
11849
  return EXIT_OK;
11844
11850
  }
11851
+ function verbHelp(verb) {
11852
+ const lines = HELP.split("\n");
11853
+ const out = [];
11854
+ let taking = false;
11855
+ for (const line of lines) {
11856
+ if (/^ {2}vos /.test(line)) taking = line.startsWith(` vos ${verb} `);
11857
+ else if (taking && !/^ {3,}\S/.test(line)) taking = false;
11858
+ if (taking) out.push(line);
11859
+ }
11860
+ if (out.length === 0) return `vos ${verb}: no such verb here. Run: vos help
11861
+ `;
11862
+ return `${out.join("\n")}
11863
+
11864
+ The whole reference, with every flag explained: https://vos.so/llms-full.txt
11865
+ Exit codes: 0 ok, 1 error, 2 usage or --strict failure, 3 no browser, 4 the recorder met a sign-in instead of the page.
11866
+ `;
11867
+ }
11845
11868
  async function run(argv) {
11846
11869
  const [cmd, ...rest] = argv;
11847
11870
  try {
@@ -11849,6 +11872,10 @@ async function run(argv) {
11849
11872
  process.stdout.write(HELP);
11850
11873
  return cmd ? EXIT_OK : EXIT_USAGE;
11851
11874
  }
11875
+ if (rest.includes("--help") || rest.includes("-h")) {
11876
+ process.stdout.write(verbHelp(cmd));
11877
+ return EXIT_OK;
11878
+ }
11852
11879
  switch (cmd) {
11853
11880
  case "create":
11854
11881
  return await cmdCreate2(rest);
@@ -11959,6 +11986,7 @@ export {
11959
11986
  MULTI_FLAGS2 as MULTI_FLAGS,
11960
11987
  HELP,
11961
11988
  takeBrowserArgs,
11989
+ verbHelp,
11962
11990
  run
11963
11991
  };
11964
- //# sourceMappingURL=chunk-BD4FXBUO.js.map
11992
+ //# sourceMappingURL=chunk-4QVEV3HX.js.map