@vosjs/cli 0.76.0 → 0.77.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.
@@ -9,7 +9,7 @@ import {
9
9
  reencodeStill,
10
10
  renderStill,
11
11
  videoFormat
12
- } from "./chunk-YZAM4W7B.js";
12
+ } from "./chunk-KDIRW72G.js";
13
13
  import {
14
14
  PREV_DOC_NAME,
15
15
  RECORDING_NAME,
@@ -28,6 +28,7 @@ import {
28
28
  readJson,
29
29
  readMediaHead,
30
30
  recordHostedMedia,
31
+ safePathName,
31
32
  sourceSidecarRefs,
32
33
  takeMediaFile,
33
34
  takePaths,
@@ -36,7 +37,7 @@ import {
36
37
  uploadDocRefs,
37
38
  uploadManifest,
38
39
  writeJson
39
- } from "./chunk-M3QIN457.js";
40
+ } from "./chunk-UY2N42P2.js";
40
41
  import {
41
42
  CREDENTIALS_PATH,
42
43
  MEDIA_HEAD_BYTES,
@@ -68,8 +69,9 @@ import {
68
69
  sniffMediaType,
69
70
  strFlag,
70
71
  writeCredential,
72
+ writeFileSafe,
71
73
  writeSyncState
72
- } from "./chunk-FL3E27WE.js";
74
+ } from "./chunk-B4U4URE3.js";
73
75
  import {
74
76
  deadLine,
75
77
  deadWarns
@@ -366,10 +368,13 @@ var EPS = 1e-3;
366
368
  var isNum = (v) => typeof v === "number" && Number.isFinite(v);
367
369
  var isObj = (v) => typeof v === "object" && v !== null;
368
370
  function htmlFontUrlProblem(url) {
369
- if (/^https?:\/\//.test(url)) return null;
371
+ if (/^https:\/\/assets\.vos\.so\//.test(url)) return null;
370
372
  if (/^\/api\/assets\/[^/]+\/file$/.test(url)) return null;
373
+ if (/^https?:\/\//i.test(url)) {
374
+ return `names ${url}: a face is fetched from https://assets.vos.so (the host a layer's images are held to), a hosted file (/api/assets/<id>/file) or a .woff2 beside the document, never another host`;
375
+ }
371
376
  if (/^(data:|blob:)/.test(url) || url.startsWith("/")) {
372
- return `must be an https URL, a hosted file (/api/assets/<id>/file) or a .woff2 beside the document (got ${url})`;
377
+ return `must be an https://assets.vos.so URL, a hosted file (/api/assets/<id>/file) or a .woff2 beside the document (got ${url})`;
373
378
  }
374
379
  if (url.split(/[\\/]/).includes("..")) {
375
380
  return `names ${url}, outside the document's directory: copy the font beside doc.json`;
@@ -6205,7 +6210,7 @@ async function writeScriptBeside(dir, doc) {
6205
6210
  }
6206
6211
 
6207
6212
  // src/plugin/folder.ts
6208
- import { mkdir as mkdir5, writeFile as writeFile8 } from "fs/promises";
6213
+ import { mkdir as mkdir5 } from "fs/promises";
6209
6214
  import { join as join12 } from "path";
6210
6215
  import { recipeHints } from "@vosjs/shared/frontmatter";
6211
6216
  import { migrateHostedDoc } from "@vosjs/studio-core";
@@ -6394,7 +6399,6 @@ function recipeLine(filename, body) {
6394
6399
  ].filter(Boolean);
6395
6400
  return `${filename}${facts.length ? ` (${facts.join(" \xB7 ")})` : ""}`;
6396
6401
  }
6397
- var safeName = (v) => v.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "file";
6398
6402
  async function cmdPull(argv) {
6399
6403
  const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS);
6400
6404
  const ref = positionals[0];
@@ -6413,26 +6417,27 @@ async function cmdPull(argv) {
6413
6417
  if (res.status !== 200)
6414
6418
  throw new Error(apiError(`pull folder ${folder.slug}`, res));
6415
6419
  const payload = res.body;
6416
- const out = strFlag(flags, "out") ?? folder.slug;
6420
+ const safeName = (v, id) => safePathName((v ?? "").toLowerCase(), id);
6421
+ const out = strFlag(flags, "out") ?? safeName(folder.slug, folder.id);
6417
6422
  await mkdir5(join12(out, "recipes"), { recursive: true });
6418
6423
  const lines = [];
6419
6424
  const recipes = [];
6420
6425
  for (const rec of payload.recipes) {
6421
- const path = join12(out, "recipes", safeName(rec.filename));
6422
- await writeFile8(path, rec.body ?? "");
6426
+ const path = join12(out, "recipes", safeName(rec.filename, rec.id));
6427
+ await writeFileSafe(path, rec.body ?? "");
6423
6428
  recipes.push({ path, line: recipeLine(rec.filename, rec.body ?? "") });
6424
6429
  }
6425
6430
  for (const rec of payload.inheritedRecipes) {
6426
- const from = safeName(rec.folderSlug ?? "inherited");
6431
+ const from = safeName(rec.folderSlug ?? "inherited", "inherited");
6427
6432
  await mkdir5(join12(out, "recipes", "_inherited", from), { recursive: true });
6428
6433
  const path = join12(
6429
6434
  out,
6430
6435
  "recipes",
6431
6436
  "_inherited",
6432
6437
  from,
6433
- safeName(rec.filename)
6438
+ safeName(rec.filename, rec.id)
6434
6439
  );
6435
- await writeFile8(path, rec.body ?? "");
6440
+ await writeFileSafe(path, rec.body ?? "");
6436
6441
  recipes.push({
6437
6442
  path,
6438
6443
  line: `${recipeLine(rec.filename, rec.body ?? "")} [inherited from ${rec.folderName ?? from}]`
@@ -6440,14 +6445,14 @@ async function cmdPull(argv) {
6440
6445
  }
6441
6446
  const members = [];
6442
6447
  for (const v of payload.voses) {
6443
- const dir = join12(out, "members", safeName(v.slug || v.title || v.id));
6448
+ const dir = join12(out, "members", safeName(v.slug || v.title, v.id));
6444
6449
  await mkdir5(dir, { recursive: true });
6445
6450
  const cfg = await apiJson(origin, `/api/vos/${v.id}/config`, { key });
6446
6451
  if (cfg.status !== 200) {
6447
6452
  lines.push(`skipped ${v.title}: ${apiError("fetch config", cfg)}`);
6448
6453
  continue;
6449
6454
  }
6450
- await writeFile8(
6455
+ await writeFileSafe(
6451
6456
  join12(dir, "config.json"),
6452
6457
  JSON.stringify(cfg.body.config, null, 2)
6453
6458
  );
@@ -6459,7 +6464,7 @@ async function cmdPull(argv) {
6459
6464
  { key }
6460
6465
  );
6461
6466
  if (doc.status === 200) {
6462
- await writeFile8(
6467
+ await writeFileSafe(
6463
6468
  join12(dir, "doc.json"),
6464
6469
  JSON.stringify(doc.body, null, 2)
6465
6470
  );
@@ -6991,7 +6996,7 @@ async function pushTakeClaimable(dir, flags, r) {
6991
6996
 
6992
6997
  // src/plugin/program.ts
6993
6998
  import { existsSync as existsSync13 } from "fs";
6994
- import { mkdir as mkdir6, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
6999
+ import { mkdir as mkdir6, readFile as readFile11 } from "fs/promises";
6995
7000
  import { createInterface as createInterface2 } from "readline/promises";
6996
7001
  import { basename as basename3, dirname as dirname2, join as join14 } from "path";
6997
7002
  import {
@@ -7209,9 +7214,9 @@ async function cmdFetch(argv) {
7209
7214
  if (cfg.status !== 200)
7210
7215
  throw new Error(apiError(`fetch config for ${vosId}`, cfg));
7211
7216
  const slug = typeof vosMeta.slug === "string" && vosMeta.slug ? vosMeta.slug : vosId;
7212
- const out = strFlag(flags, "out") ?? slug;
7217
+ const out = strFlag(flags, "out") ?? safePathName(slug, vosId);
7213
7218
  await mkdir6(out, { recursive: true });
7214
- await writeFile9(
7219
+ await writeFileSafe(
7215
7220
  join14(out, "config.json"),
7216
7221
  JSON.stringify(cfg.body.config, null, 2)
7217
7222
  );
@@ -7237,12 +7242,18 @@ async function cmdFetch(argv) {
7237
7242
  const hosted = migrateHostedDoc3(doc.body);
7238
7243
  const { config: own } = await writeProgramDoc(out, hosted);
7239
7244
  if (own) {
7240
- await writeFile9(join14(out, "config.json"), JSON.stringify(own, null, 2));
7245
+ await writeFileSafe(
7246
+ join14(out, "config.json"),
7247
+ JSON.stringify(own, null, 2)
7248
+ );
7241
7249
  }
7242
7250
  } else if (doc.status === 200) {
7243
7251
  take = true;
7244
7252
  const hosted = migrateHostedDoc3(doc.body);
7245
- await writeFile9(join14(out, "doc.json"), JSON.stringify(hosted, null, 2));
7253
+ await writeFileSafe(
7254
+ join14(out, "doc.json"),
7255
+ JSON.stringify(hosted, null, 2)
7256
+ );
7246
7257
  if (flags.media === true) {
7247
7258
  const media = await pullMedia({ origin, key }, out, hosted, r.log);
7248
7259
  await recordHostedMedia(out, vosId, media);
@@ -7263,7 +7274,7 @@ async function cmdFetch(argv) {
7263
7274
  if (hostedCount && flags.media === true) {
7264
7275
  const pulled = await pullManifest({ origin, key }, out, written, r.log);
7265
7276
  if (pulled) {
7266
- await writeFile9(
7277
+ await writeFileSafe(
7267
7278
  configPath,
7268
7279
  JSON.stringify({ ...written, assets: pulled.assets }, null, 2)
7269
7280
  );
@@ -7737,7 +7748,10 @@ async function cmdPullProgram(argv) {
7737
7748
  const configPath = join14(dir, "config.json");
7738
7749
  let backedUp = false;
7739
7750
  if (existsSync13(configPath)) {
7740
- await writeFile9(join14(dir, "config.backup.json"), await readFile11(configPath));
7751
+ await writeFileSafe(
7752
+ join14(dir, "config.backup.json"),
7753
+ await readFile11(configPath)
7754
+ );
7741
7755
  backedUp = true;
7742
7756
  }
7743
7757
  let headConfig = cfg.body.config;
@@ -7756,7 +7770,7 @@ async function cmdPullProgram(argv) {
7756
7770
  if (own) headConfig = own;
7757
7771
  }
7758
7772
  }
7759
- await writeFile9(configPath, JSON.stringify(headConfig, null, 2));
7773
+ await writeFileSafe(configPath, JSON.stringify(headConfig, null, 2));
7760
7774
  writeSyncState(dir, {
7761
7775
  vosId,
7762
7776
  versionId: typeof head.id === "string" ? head.id : since
@@ -7898,13 +7912,16 @@ async function setProgramStill(dir, t) {
7898
7912
  );
7899
7913
  doc = parsed;
7900
7914
  }
7901
- await writeFile9(docPath, JSON.stringify({ ...doc, still: t }, null, 2) + "\n");
7915
+ await writeFileSafe(
7916
+ docPath,
7917
+ JSON.stringify({ ...doc, still: t }, null, 2) + "\n"
7918
+ );
7902
7919
  }
7903
7920
  async function writeProgramDoc(dir, hosted) {
7904
7921
  const program = hosted.program && typeof hosted.program === "object" ? hosted.program : {};
7905
7922
  const { config, ...rest } = program;
7906
7923
  const onDisk = { ...hosted, program: rest };
7907
- await writeFile9(join14(dir, "doc.json"), JSON.stringify(onDisk, null, 2));
7924
+ await writeFileSafe(join14(dir, "doc.json"), JSON.stringify(onDisk, null, 2));
7908
7925
  return {
7909
7926
  config: config && typeof config === "object" ? config : null
7910
7927
  };
@@ -8013,6 +8030,130 @@ function nameFromUrl(url) {
8013
8030
  }
8014
8031
  }
8015
8032
 
8033
+ // src/plugin/netAddress.ts
8034
+ function privateHostReason(hostname2) {
8035
+ const host = hostname2.replace(/^\[|\]$/g, "").toLowerCase();
8036
+ if (host === "localhost" || host.endsWith(".localhost"))
8037
+ return "is this machine";
8038
+ const v4 = parseIPv4(host);
8039
+ if (v4) return privateIPv4Reason(v4);
8040
+ const v6 = expandIPv6(host);
8041
+ if (!v6) return null;
8042
+ const carried = carriedIPv4(v6);
8043
+ if (carried) return privateIPv4Reason(carried);
8044
+ if (v6.every((w) => w === 0)) return "is an unspecified address";
8045
+ if (v6.slice(0, 7).every((w) => w === 0) && v6[7] === 1)
8046
+ return "is this machine";
8047
+ if ((v6[0] & 65024) === 64512) return "is a private network address";
8048
+ if ((v6[0] & 65472) === 65152) return "is a link-local address";
8049
+ return null;
8050
+ }
8051
+ function privateIPv4Reason([a, b]) {
8052
+ if (a === 0) return "is an unspecified address";
8053
+ if (a === 127) return "is this machine";
8054
+ if (a === 10) return "is a private network address";
8055
+ if (a === 172 && b >= 16 && b <= 31) return "is a private network address";
8056
+ if (a === 192 && b === 168) return "is a private network address";
8057
+ if (a === 100 && b >= 64 && b <= 127) return "is a private network address";
8058
+ if (a === 169 && b === 254) return "is a link-local address";
8059
+ return null;
8060
+ }
8061
+ function parseIPv4(host) {
8062
+ if (!/^[0-9a-fx.]+$/i.test(host)) return null;
8063
+ const parts = host.split(".");
8064
+ if (parts.length > 4 || parts.some((p) => p === "")) return null;
8065
+ const nums = [];
8066
+ for (const p of parts) {
8067
+ let n;
8068
+ if (/^0x[0-9a-f]+$/i.test(p)) n = parseInt(p.slice(2), 16);
8069
+ else if (/^0[0-7]+$/.test(p)) n = parseInt(p, 8);
8070
+ else if (/^[0-9]+$/.test(p)) n = parseInt(p, 10);
8071
+ else return null;
8072
+ nums.push(n);
8073
+ }
8074
+ const last = nums[nums.length - 1];
8075
+ const lead = nums.slice(0, -1);
8076
+ if (lead.some((n) => n > 255)) return null;
8077
+ const fill = 4 - lead.length;
8078
+ if (last >= 256 ** fill) return null;
8079
+ const tail = [];
8080
+ let rest = last;
8081
+ for (let i = 0; i < fill; i++) {
8082
+ tail.unshift(rest % 256);
8083
+ rest = Math.floor(rest / 256);
8084
+ }
8085
+ return [...lead, ...tail];
8086
+ }
8087
+ function expandIPv6(host) {
8088
+ if (!host.includes(":")) return null;
8089
+ const zone = host.indexOf("%");
8090
+ const addr = zone >= 0 ? host.slice(0, zone) : host;
8091
+ if (!/^[0-9a-f:.]+$/i.test(addr)) return null;
8092
+ const halves = addr.split("::");
8093
+ if (halves.length > 2) return null;
8094
+ const words2 = (part) => {
8095
+ if (part === "") return [];
8096
+ const out = [];
8097
+ const groups = part.split(":");
8098
+ for (let i = 0; i < groups.length; i++) {
8099
+ const g = groups[i];
8100
+ if (g.includes(".")) {
8101
+ if (i !== groups.length - 1) return null;
8102
+ const v4 = parseIPv4(g);
8103
+ if (!v4) return null;
8104
+ out.push(v4[0] << 8 | v4[1], v4[2] << 8 | v4[3]);
8105
+ continue;
8106
+ }
8107
+ if (!/^[0-9a-f]{1,4}$/i.test(g)) return null;
8108
+ out.push(parseInt(g, 16));
8109
+ }
8110
+ return out;
8111
+ };
8112
+ const head = words2(halves[0]);
8113
+ const tail = halves.length === 2 ? words2(halves[1]) : [];
8114
+ if (!head || !tail) return null;
8115
+ if (halves.length === 1) return head.length === 8 ? head : null;
8116
+ const gap = 8 - head.length - tail.length;
8117
+ if (gap < 1) return null;
8118
+ return [...head, ...new Array(gap).fill(0), ...tail];
8119
+ }
8120
+ function carriedIPv4(v6) {
8121
+ const zeroLead = v6.slice(0, 5).every((w) => w === 0);
8122
+ const mapped = zeroLead && v6[5] === 65535;
8123
+ const compatible = zeroLead && v6[5] === 0 && (v6[6] !== 0 || v6[7] > 1);
8124
+ const nat64 = v6[0] === 100 && v6[1] === 65435;
8125
+ if (!mapped && !compatible && !nat64) return null;
8126
+ return [v6[6] >> 8, v6[6] & 255, v6[7] >> 8, v6[7] & 255];
8127
+ }
8128
+ function fetchRefusal(url) {
8129
+ let u;
8130
+ try {
8131
+ u = new URL(url);
8132
+ } catch {
8133
+ return `${url} is not a URL`;
8134
+ }
8135
+ if (u.protocol !== "http:" && u.protocol !== "https:")
8136
+ return `${url} is not an http(s) address, and the CLI fetches nothing else`;
8137
+ const reason = privateHostReason(u.hostname);
8138
+ if (reason)
8139
+ return `${u.hostname} ${reason}, and the CLI fetches only from the public internet`;
8140
+ return null;
8141
+ }
8142
+ var MAX_HOPS = 5;
8143
+ async function fetchPublic(url, init = {}, fetchImpl = fetch) {
8144
+ let at2 = url;
8145
+ for (let hop = 0; ; hop++) {
8146
+ const refused = fetchRefusal(at2);
8147
+ if (refused) throw new Error(refused);
8148
+ const res = await fetchImpl(at2, { ...init, redirect: "manual" });
8149
+ const location = res.headers.get("location");
8150
+ if (res.status < 300 || res.status > 399 || !location) return res;
8151
+ if (hop >= MAX_HOPS)
8152
+ throw new Error(`${url} redirected more than ${MAX_HOPS} times`);
8153
+ at2 = new URL(location, at2).href;
8154
+ }
8155
+ }
8156
+
8016
8157
  // src/plugin/asset.ts
8017
8158
  var BOOLEAN_FLAGS3 = /* @__PURE__ */ new Set(["json", "help"]);
8018
8159
  async function cmdRename(argv) {
@@ -8133,8 +8274,10 @@ async function cmdImport(argv) {
8133
8274
  const key = requireCredential(strFlag(flags, "key"));
8134
8275
  const folderRef = strFlag(flags, "folder");
8135
8276
  const folder = folderRef ? resolveFolder(await listFolders(origin, key), folderRef) : null;
8277
+ const refused = fetchRefusal(url);
8278
+ if (refused) throw new UsageError(`import: ${refused}`);
8136
8279
  r.log(`fetching ${url}`);
8137
- const res = await fetch(url, { redirect: "follow" });
8280
+ const res = await fetchPublic(url);
8138
8281
  if (!res.ok)
8139
8282
  throw new Error(`import ${url}: the address answered ${res.status}`);
8140
8283
  const declared = Number(res.headers.get("content-length") ?? 0);
@@ -10608,7 +10751,7 @@ async function cmdRecipe(argv) {
10608
10751
  }
10609
10752
 
10610
10753
  // src/plugin/brand.ts
10611
- import { writeFile as writeFile10 } from "fs/promises";
10754
+ import { writeFile as writeFile8 } from "fs/promises";
10612
10755
  import { resolve as resolve11 } from "path";
10613
10756
  import { parseFrontmatter as parseFrontmatter2 } from "@vosjs/shared/frontmatter";
10614
10757
  import { lookKindForGround } from "@vosjs/studio-core";
@@ -10907,7 +11050,7 @@ function renderBrandMd(c, claim) {
10907
11050
  }
10908
11051
  async function fetchText(url) {
10909
11052
  try {
10910
- const res = await fetch(url, { redirect: "follow" });
11053
+ const res = await fetchPublic(url);
10911
11054
  if (!res.ok) return null;
10912
11055
  const type = res.headers.get("content-type") ?? "";
10913
11056
  if (/text\/html/i.test(type)) return null;
@@ -10927,6 +11070,8 @@ async function cmdBrand(argv) {
10927
11070
  } catch {
10928
11071
  throw new UsageError(`not a URL: ${raw}`);
10929
11072
  }
11073
+ const refused = fetchRefusal(url);
11074
+ if (refused) throw new UsageError(refused);
10930
11075
  const r = createReporter(flags.json === true);
10931
11076
  const out = resolve11(strFlag(flags, "out") ?? "BRAND.md");
10932
11077
  r.log(`reading ${origin}/design.md and /llms.txt\u2026`);
@@ -10962,7 +11107,7 @@ async function cmdBrand(argv) {
10962
11107
  composition,
10963
11108
  llms?.claim ?? design?.description ?? null
10964
11109
  );
10965
- await writeFile10(out, md);
11110
+ await writeFile8(out, md);
10966
11111
  const k = composition.kit;
10967
11112
  r.done(
10968
11113
  {
@@ -10993,6 +11138,20 @@ function hostedEnv(actions, shell) {
10993
11138
  }
10994
11139
  return { env, missing };
10995
11140
  }
11141
+ function envNamesNotice(actions) {
11142
+ const names = setupEnvNames2(actions.setup);
11143
+ if (names.length === 0) return null;
11144
+ return {
11145
+ names,
11146
+ line: `the setup reads ${names.length === 1 ? "this environment variable" : "these environment variables"} from this shell: ${names.join(", ")} (names only; a value is never printed or stored)`
11147
+ };
11148
+ }
11149
+ function announceEnvNames(actions, r) {
11150
+ const notice = envNamesNotice(actions);
11151
+ if (!notice) return;
11152
+ r.log(notice.line);
11153
+ r.event({ event: "env", names: notice.names });
11154
+ }
10996
11155
  function isWallError(error) {
10997
11156
  return !!error && /^(\[\w+\] )?The page is behind a sign-in/.test(error);
10998
11157
  }
@@ -11076,8 +11235,11 @@ async function recordHosted(input) {
11076
11235
  };
11077
11236
  }
11078
11237
 
11238
+ // src/plugin/run.ts
11239
+ import { urlSchemeProblem } from "@vosjs/render-core/record";
11240
+
11079
11241
  // src/plugin/agentBrowser.ts
11080
- import { writeFile as writeFile11 } from "fs/promises";
11242
+ import { writeFile as writeFile9 } from "fs/promises";
11081
11243
  import { resolve as resolve12 } from "path";
11082
11244
  function parseAgentBrowserLog(text) {
11083
11245
  const records = [];
@@ -11575,7 +11737,7 @@ async function cmdActions(argv) {
11575
11737
  );
11576
11738
  return EXIT_ERROR;
11577
11739
  }
11578
- await writeFile11(out, `${JSON.stringify(result.actions, null, 2)}
11740
+ await writeFile9(out, `${JSON.stringify(result.actions, null, 2)}
11579
11741
  `);
11580
11742
  r.done(
11581
11743
  { ok: true, out, url: result.actions.url ?? null, ...summary2(result) },
@@ -11610,7 +11772,43 @@ async function cmdActionsScript(input, flags) {
11610
11772
  import { existsSync as existsSync20 } from "fs";
11611
11773
  import { copyFile, mkdir as mkdir7, readFile as readFile12, stat as stat2 } from "fs/promises";
11612
11774
  import { basename as basename9, join as join22, resolve as resolve13 } from "path";
11775
+
11776
+ // src/plugin/traceInflate.ts
11613
11777
  import { inflateRawSync } from "zlib";
11778
+ var TRACE_ENTRY_MAX_BYTES = 64 * 1024 * 1024;
11779
+ var TRACE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
11780
+ function traceBudget(caps = {}) {
11781
+ return {
11782
+ entry: caps.entry ?? TRACE_ENTRY_MAX_BYTES,
11783
+ total: caps.total ?? TRACE_TOTAL_MAX_BYTES,
11784
+ used: 0
11785
+ };
11786
+ }
11787
+ var mib = (n) => `${(n / (1024 * 1024)).toFixed(n < 10 * 1024 * 1024 ? 1 : 0)} MiB`;
11788
+ function inflateEntry(raw, entry, budget) {
11789
+ const room = Math.min(budget.entry, budget.total - budget.used);
11790
+ const over = (bytes) => new Error(
11791
+ `${entry.name} inflates to ${bytes}, past the ${mib(budget.entry)} an entry may take (${mib(budget.total)} for the whole trace); this is not a trace the recorder reads`
11792
+ );
11793
+ if (entry.size > room) throw over(mib(entry.size));
11794
+ let out;
11795
+ if (entry.method === 8) {
11796
+ try {
11797
+ out = new Uint8Array(inflateRawSync(raw, { maxOutputLength: room + 1 }));
11798
+ } catch (e) {
11799
+ if (e.code === "ERR_BUFFER_TOO_LARGE")
11800
+ throw over(`more than ${mib(room)}`);
11801
+ throw e;
11802
+ }
11803
+ } else {
11804
+ out = raw;
11805
+ }
11806
+ if (out.length > room) throw over(mib(out.length));
11807
+ budget.used += out.length;
11808
+ return out;
11809
+ }
11810
+
11811
+ // src/plugin/ingest.ts
11614
11812
  import {
11615
11813
  cursorFromPlaywrightTrace,
11616
11814
  cursorFromTrace,
@@ -11706,7 +11904,7 @@ async function readTraceFile(path, offsetMs) {
11706
11904
  }
11707
11905
  const raw = zipEntryBytes(bytes, entry);
11708
11906
  const text2 = new TextDecoder().decode(
11709
- entry.method === 8 ? new Uint8Array(inflateRawSync(raw)) : raw
11907
+ inflateEntry(raw, entry, traceBudget())
11710
11908
  );
11711
11909
  return cursorFromPlaywrightTrace(text2, { offsetMs });
11712
11910
  }
@@ -12867,6 +13065,9 @@ async function cmdRecord(argv) {
12867
13065
  const url = strFlag(flags, "url") ?? actions.url;
12868
13066
  if (!url)
12869
13067
  throw new UsageError('no URL \u2014 set "url" in the actions file or pass --url');
13068
+ const scheme = urlSchemeProblem(url);
13069
+ if (scheme) throw new UsageError(scheme);
13070
+ announceEnvNames(actions, r);
12870
13071
  const outDir = resolve14(strFlag(flags, "out") ?? "take");
12871
13072
  const storageState = takeStorageState(flags);
12872
13073
  const sessionName = takeSessionName(flags, storageState);
@@ -13112,6 +13313,9 @@ async function cmdCreate2(argv) {
13112
13313
  const url = strFlag(flags, "url") ?? actions.url;
13113
13314
  if (!url)
13114
13315
  throw new UsageError('no URL \u2014 set "url" in the actions file or pass --url');
13316
+ const scheme = urlSchemeProblem(url);
13317
+ if (scheme) throw new UsageError(scheme);
13318
+ announceEnvNames(actions, r);
13115
13319
  const outDir = resolve14(strFlag(flags, "out") ?? "take");
13116
13320
  const format = videoFormat(strFlag(flags, "format"), positionals[0]);
13117
13321
  const out = positionals[0] ?? join25(outDir, `out.${format}`);
@@ -14475,4 +14679,4 @@ export {
14475
14679
  verbHelp,
14476
14680
  run
14477
14681
  };
14478
- //# sourceMappingURL=chunk-OJ3ZCPYS.js.map
14682
+ //# sourceMappingURL=chunk-SB622PZM.js.map