@vosjs/cli 0.74.0 → 0.75.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.
@@ -36,7 +36,7 @@ import {
36
36
  uploadDocRefs,
37
37
  uploadManifest,
38
38
  writeJson
39
- } from "./chunk-Y5E672GT.js";
39
+ } from "./chunk-M3QIN457.js";
40
40
  import {
41
41
  CREDENTIALS_PATH,
42
42
  MEDIA_HEAD_BYTES,
@@ -133,7 +133,7 @@ function landedLines(l) {
133
133
  // src/plugin/run.ts
134
134
  import { mkdir as mkdir8, readFile as readFile13, rm as rm2 } from "fs/promises";
135
135
  import { existsSync as existsSync23 } from "fs";
136
- import { join as join25, resolve as resolve13 } from "path";
136
+ import { join as join25, resolve as resolve14 } from "path";
137
137
  import {
138
138
  END_CARD_FROM as END_CARD_FROM2,
139
139
  docOutputDuration as docOutputDuration3,
@@ -2014,7 +2014,7 @@ function mediaProbeLints(results) {
2014
2014
  // src/plugin/framesTake.ts
2015
2015
  import { mkdir as mkdir2, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
2016
2016
  import { existsSync as existsSync3 } from "fs";
2017
- import { join as join3, resolve as resolve2 } from "path";
2017
+ import { join as join3, resolve as resolve3 } from "path";
2018
2018
  import { compileVosConfig } from "@vosjs/core";
2019
2019
  import {
2020
2020
  docStillTime,
@@ -2028,9 +2028,10 @@ import {
2028
2028
 
2029
2029
  // src/plugin/server.ts
2030
2030
  import { createServer } from "http";
2031
- import { existsSync, readFileSync, statSync } from "fs";
2031
+ import { randomBytes } from "crypto";
2032
+ import { existsSync, readFileSync, realpathSync, statSync } from "fs";
2032
2033
  import { writeFile } from "fs/promises";
2033
- import { extname, join } from "path";
2034
+ import { extname, join, resolve, sep } from "path";
2034
2035
  var MIME = {
2035
2036
  ".html": "text/html",
2036
2037
  ".js": "text/javascript",
@@ -2052,9 +2053,46 @@ var MIME = {
2052
2053
  ".m4a": "audio/mp4",
2053
2054
  ".ogg": "audio/ogg"
2054
2055
  };
2056
+ var SAVE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
2057
+ var SAVE_NEVER = /* @__PURE__ */ new Set([
2058
+ "doc.json",
2059
+ "actions.json",
2060
+ "vos.json",
2061
+ "meta.json",
2062
+ "cursor.json"
2063
+ ]);
2064
+ function saveNameOk(name) {
2065
+ return SAVE_NAME.test(name) && !name.includes("..") && !SAVE_NEVER.has(name);
2066
+ }
2067
+ function fileInRoot(rootDir, pathname) {
2068
+ let decoded;
2069
+ try {
2070
+ decoded = decodeURIComponent(pathname);
2071
+ } catch {
2072
+ return null;
2073
+ }
2074
+ const file = resolve(rootDir, `.${decoded}`);
2075
+ if (!existsSync(file) || !statSync(file).isFile()) return null;
2076
+ const root = realpathSync(rootDir);
2077
+ const real = realpathSync(file);
2078
+ return real.startsWith(root + sep) ? real : null;
2079
+ }
2080
+ function ownReader(req) {
2081
+ const site = req.headers["sec-fetch-site"];
2082
+ return site === void 0 || site === "same-origin" || site === "none";
2083
+ }
2055
2084
  function startTakeServer(rootDir, pages) {
2085
+ const token = randomBytes(16).toString("hex");
2086
+ const prefix = `/t/${token}`;
2056
2087
  const server = createServer((req, res) => {
2057
- const url = new URL(req.url ?? "/", "http://x");
2088
+ const raw = new URL(req.url ?? "/", "http://x");
2089
+ const tokened = raw.pathname === prefix || raw.pathname.startsWith(`${prefix}/`);
2090
+ if (!tokened && req.method !== "OPTIONS" && !ownReader(req)) {
2091
+ res.writeHead(404).end();
2092
+ return;
2093
+ }
2094
+ const url = tokened ? new URL(raw.pathname.slice(prefix.length) || "/", "http://x") : raw;
2095
+ url.search = raw.search;
2058
2096
  res.setHeader("access-control-allow-origin", "*");
2059
2097
  res.setHeader("access-control-allow-private-network", "true");
2060
2098
  if (req.method === "OPTIONS") {
@@ -2067,10 +2105,11 @@ function startTakeServer(rootDir, pages) {
2067
2105
  return;
2068
2106
  }
2069
2107
  if (req.method === "POST" && url.pathname === "/save") {
2070
- const name = (url.searchParams.get("name") ?? "out.bin").replace(
2071
- /[^\w.-]/g,
2072
- ""
2073
- );
2108
+ const name = url.searchParams.get("name") ?? "out.bin";
2109
+ if (tokened || !ownReader(req) || !saveNameOk(name)) {
2110
+ res.writeHead(404).end();
2111
+ return;
2112
+ }
2074
2113
  const chunks = [];
2075
2114
  req.on("data", (c) => chunks.push(c));
2076
2115
  req.on("end", () => {
@@ -2086,8 +2125,8 @@ function startTakeServer(rootDir, pages) {
2086
2125
  res.end(pages[url.pathname]);
2087
2126
  return;
2088
2127
  }
2089
- const file = join(rootDir, decodeURIComponent(url.pathname));
2090
- if (existsSync(file) && statSync(file).isFile()) {
2128
+ const file = fileInRoot(rootDir, url.pathname);
2129
+ if (file) {
2091
2130
  const size = statSync(file).size;
2092
2131
  const buf = readFileSync(file);
2093
2132
  const type = sniffMediaType(buf.subarray(0, MEDIA_HEAD_BYTES)) ?? MIME[extname(file)] ?? "application/octet-stream";
@@ -2120,10 +2159,13 @@ function startTakeServer(rootDir, pages) {
2120
2159
  res.writeHead(404).end();
2121
2160
  });
2122
2161
  return new Promise(
2123
- (resolve14) => server.listen(0, () => {
2162
+ (done) => server.listen(0, "127.0.0.1", () => {
2124
2163
  const addr = server.address();
2125
2164
  const port = typeof addr === "object" && addr ? addr.port : 0;
2126
- resolve14({ base: `http://localhost:${port}`, close: () => server.close() });
2165
+ done({
2166
+ base: `http://127.0.0.1:${port}${prefix}`,
2167
+ close: () => server.close()
2168
+ });
2127
2169
  })
2128
2170
  );
2129
2171
  }
@@ -2708,7 +2750,7 @@ function applyAndValidate(doc, o) {
2708
2750
  // src/plugin/digestTake.ts
2709
2751
  import { mkdir, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
2710
2752
  import { existsSync as existsSync2 } from "fs";
2711
- import { join as join2, resolve } from "path";
2753
+ import { join as join2, resolve as resolve2 } from "path";
2712
2754
  import {
2713
2755
  CHANGE_GRID,
2714
2756
  CHANGE_LEAD,
@@ -2969,7 +3011,7 @@ async function digestTake(browser, dir, opts = {}) {
2969
3011
  const meta = doc.source.meta;
2970
3012
  let plan = planForDigest(doc);
2971
3013
  const transcript = opts.transcript ?? await discoverTranscript(dir);
2972
- const outDir = resolve(opts.outDir ?? join2(dir, DIGEST_DIR));
3014
+ const outDir = resolve2(opts.outDir ?? join2(dir, DIGEST_DIR));
2973
3015
  await mkdir(outDir, { recursive: true });
2974
3016
  const fullMax = opts.full ?? DIGEST_FULL_MAX;
2975
3017
  const cropMax = opts.crop ?? DIGEST_CROP_MAX;
@@ -3380,7 +3422,7 @@ async function framesTake(browser, dir, opts) {
3380
3422
  throw new Error(
3381
3423
  "no frame times \u2014 pass --times/--frame, --at-zooms, --at-moments or --at-still"
3382
3424
  );
3383
- const outDir = resolve2(opts.outDir ?? join3(dir, "stills"));
3425
+ const outDir = resolve3(opts.outDir ?? join3(dir, "stills"));
3384
3426
  await mkdir2(outDir, { recursive: true });
3385
3427
  const named = shots.map((s, i) => ({
3386
3428
  ...s,
@@ -3484,7 +3526,7 @@ async function writeIndexJson(result) {
3484
3526
 
3485
3527
  // src/plugin/deliver.ts
3486
3528
  import { mkdir as mkdir3, writeFile as writeFile5 } from "fs/promises";
3487
- import { join as join4, relative, resolve as resolve3 } from "path";
3529
+ import { join as join4, relative, resolve as resolve4 } from "path";
3488
3530
  import { existsSync as existsSync4 } from "fs";
3489
3531
  import { readFile as readFile4 } from "fs/promises";
3490
3532
  import { parseFrontmatter } from "@vosjs/shared/frontmatter";
@@ -4062,7 +4104,7 @@ async function deliverTake(browser, dir, opts) {
4062
4104
  const doc = take.doc;
4063
4105
  const duration = docOutputDuration2(doc);
4064
4106
  const videoSeconds = opts.range ? Math.min(opts.range[1], duration) - Math.min(opts.range[0], duration) : duration;
4065
- const outDir = resolve3(opts.outDir ?? join4(dir, "kit"));
4107
+ const outDir = resolve4(opts.outDir ?? join4(dir, "kit"));
4066
4108
  await mkdir3(outDir, { recursive: true });
4067
4109
  const destinations = opts.channels.flatMap((c) => destinationsForChannel(c));
4068
4110
  const assets = [];
@@ -4156,10 +4198,147 @@ async function deliverTake(browser, dir, opts) {
4156
4198
  return { kit, kitFile, outDir };
4157
4199
  }
4158
4200
 
4201
+ // src/plugin/login.ts
4202
+ import { hostname } from "os";
4203
+ var LoginUnsupportedError = class extends Error {
4204
+ constructor() {
4205
+ super("this origin does not support browser login");
4206
+ }
4207
+ };
4208
+ var MAX_TRANSIENT_FAILURES = 5;
4209
+ var MAX_INTERVAL_MS = 3e4;
4210
+ async function launchDefaultBrowser(url) {
4211
+ const { spawn: spawn2 } = await import("child_process");
4212
+ const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
4213
+ try {
4214
+ const child = spawn2(cmd, args, { detached: true, stdio: "ignore" });
4215
+ child.on("error", () => {
4216
+ });
4217
+ child.unref();
4218
+ } catch {
4219
+ }
4220
+ }
4221
+ function verifyUrlOk(verifyUrl, origin) {
4222
+ try {
4223
+ return new URL(verifyUrl).origin === new URL(origin).origin;
4224
+ } catch {
4225
+ return false;
4226
+ }
4227
+ }
4228
+ async function browserLogin(origin, r, opts) {
4229
+ const create = await apiJson(origin, "/api/cli/login", {
4230
+ method: "POST",
4231
+ body: {
4232
+ hostname: hostname().slice(0, 64),
4233
+ ...opts.label ? { label: opts.label.slice(0, 64) } : {}
4234
+ }
4235
+ });
4236
+ if (create.status === 404) throw new LoginUnsupportedError();
4237
+ if (create.status !== 201) throw new Error(apiError("start login", create));
4238
+ const code = create.body.code;
4239
+ const secret = create.body.secret;
4240
+ const verifyUrl = create.body.verifyUrl;
4241
+ const expiresAt = Date.parse(String(create.body.expiresAt ?? ""));
4242
+ const baseIntervalMs = (typeof create.body.interval === "number" ? create.body.interval : 3) * 1e3;
4243
+ if (!code || !secret || !verifyUrl || Number.isNaN(expiresAt)) {
4244
+ throw new Error("start login \u2192 malformed response from the platform");
4245
+ }
4246
+ r.event({ event: "login_await", url: verifyUrl, code, expiresAt });
4247
+ r.log(`Confirm this code in the browser: ${code}`);
4248
+ r.log(`Sign in at ${verifyUrl}`);
4249
+ if (opts.openBrowser && verifyUrlOk(verifyUrl, origin))
4250
+ void launchDefaultBrowser(verifyUrl);
4251
+ r.log("Waiting for approval\u2026 (Ctrl-C to cancel)");
4252
+ const sleep = opts.sleep ?? ((ms) => new Promise((res) => setTimeout(res, ms)));
4253
+ let intervalMs = baseIntervalMs;
4254
+ let failures = 0;
4255
+ let capNoted = false;
4256
+ while (Date.now() < expiresAt) {
4257
+ await sleep(intervalMs);
4258
+ let res;
4259
+ try {
4260
+ res = await apiJson(origin, "/api/cli/login/poll", {
4261
+ method: "POST",
4262
+ body: { secret }
4263
+ });
4264
+ failures = 0;
4265
+ } catch (e) {
4266
+ if (++failures >= MAX_TRANSIENT_FAILURES) {
4267
+ throw new Error(
4268
+ `lost the connection while waiting (${e instanceof Error ? e.message : String(e)}) \u2014 run \`vos login\` again`
4269
+ );
4270
+ }
4271
+ continue;
4272
+ }
4273
+ const status = res.body.status;
4274
+ if (res.status === 200 && status === "pending") {
4275
+ intervalMs = baseIntervalMs;
4276
+ continue;
4277
+ }
4278
+ if (res.status === 200 && status === "ok") {
4279
+ const path = (opts.store ?? writeCredential)(res.body.key);
4280
+ const user = typeof res.body.user === "object" && res.body.user !== null ? res.body.user.name ?? "" : "";
4281
+ return { path, user };
4282
+ }
4283
+ if (res.status === 429) {
4284
+ if (status === "key_limit" && !capNoted) {
4285
+ capNoted = true;
4286
+ r.log(`${res.body.error} \u2014 ${res.body.hint}`);
4287
+ }
4288
+ intervalMs = Math.min(intervalMs * 2, MAX_INTERVAL_MS);
4289
+ continue;
4290
+ }
4291
+ if (res.status === 403 && status === "denied") {
4292
+ throw new Error("the sign-in was denied in the browser");
4293
+ }
4294
+ throw new Error(
4295
+ typeof res.body.error === "string" ? res.body.error : apiError("poll login", res)
4296
+ );
4297
+ }
4298
+ throw new Error(
4299
+ "no approval within 15 minutes \u2014 run `vos login` again, or mint a key at https://vos.so/app/api and pass --key"
4300
+ );
4301
+ }
4302
+ var HANDOFF_URL = /^(https?:\/\/[^/]+)\/h\/(vos_ho_[A-Za-z0-9_-]+)$/;
4303
+ function parseHandoffUrl(url) {
4304
+ const m = HANDOFF_URL.exec(url.trim());
4305
+ return m ? { origin: m[1], token: m[2] } : null;
4306
+ }
4307
+ async function handoffLogin(url, r, opts = {}) {
4308
+ const parsed = parseHandoffUrl(url);
4309
+ if (!parsed)
4310
+ throw new Error(
4311
+ "--handoff wants the link a person copied from vos.so, https://vos.so/h/vos_ho_\u2026"
4312
+ );
4313
+ r.log(`exchanging the setup link at ${parsed.origin}\u2026`);
4314
+ const res = await apiJson(parsed.origin, "/api/cli/login/exchange", {
4315
+ method: "POST",
4316
+ body: { token: parsed.token, hostname: hostname().slice(0, 64) }
4317
+ });
4318
+ if (res.status === 200 && res.body.status === "ok") {
4319
+ const path = (opts.store ?? writeCredential)(res.body.key);
4320
+ const user = typeof res.body.user === "object" && res.body.user !== null ? res.body.user.name ?? "" : "";
4321
+ return {
4322
+ path,
4323
+ user,
4324
+ keyName: String(res.body.keyName ?? ""),
4325
+ origin: parsed.origin
4326
+ };
4327
+ }
4328
+ if (res.status === 404 && !res.body.status) {
4329
+ throw new Error(
4330
+ `${parsed.origin} does not support setup links yet \u2014 run \`vos login\` instead`
4331
+ );
4332
+ }
4333
+ const said = typeof res.body.error === "string" ? res.body.error : apiError("exchange", res);
4334
+ const hint = typeof res.body.hint === "string" ? ` ${res.body.hint}` : "";
4335
+ throw new Error(`${said}${hint}`);
4336
+ }
4337
+
4159
4338
  // src/plugin/markAsset.ts
4160
4339
  import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
4161
4340
  import { existsSync as existsSync5 } from "fs";
4162
- import { isAbsolute, join as join5, resolve as resolve4 } from "path";
4341
+ import { isAbsolute, join as join5, resolve as resolve5 } from "path";
4163
4342
  function markExtension(url) {
4164
4343
  const m = /\.(svg|png|webp|jpe?g)(?:[?#]|$)/i.exec(url);
4165
4344
  if (!m) return null;
@@ -4240,7 +4419,7 @@ async function fetchBrandMarks(takeDir, roles) {
4240
4419
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
4241
4420
  bytes = new Uint8Array(await res.arrayBuffer());
4242
4421
  } else {
4243
- const file = isAbsolute(src) ? src : resolve4(takeDir, src);
4422
+ const file = isAbsolute(src) ? src : resolve5(takeDir, src);
4244
4423
  if (!existsSync5(file)) throw new Error("no such file");
4245
4424
  bytes = new Uint8Array(await readFile5(file));
4246
4425
  }
@@ -5269,10 +5448,10 @@ async function openSession(name, url, opts = { log: () => {
5269
5448
  opts.log(
5270
5449
  `a Chrome window opened on session "${name}": sign in to ${new URL(url).host}, ${leave}`
5271
5450
  );
5272
- return new Promise((resolve14, reject) => {
5451
+ return new Promise((resolve15, reject) => {
5273
5452
  const child = spawn(exe, args, { stdio: "ignore" });
5274
5453
  child.on("error", reject);
5275
- child.on("exit", (code) => resolve14({ code }));
5454
+ child.on("exit", (code) => resolve15({ code }));
5276
5455
  });
5277
5456
  }
5278
5457
  async function withSession(name, fn, opts = {}) {
@@ -5989,11 +6168,33 @@ function scriptToWrite(doc, hasLocal) {
5989
6168
  return `${JSON.stringify(script, null, 2)}
5990
6169
  `;
5991
6170
  }
6171
+ function publicScript(script) {
6172
+ const setup = script.setup;
6173
+ if (!Array.isArray(setup)) return script;
6174
+ return {
6175
+ ...script,
6176
+ setup: setup.map((step) => {
6177
+ if (!step || typeof step !== "object") return step;
6178
+ const s = step;
6179
+ if (s.do === "type" && typeof s.text === "string")
6180
+ return { ...s, text: "[typed value not stored]" };
6181
+ if (s.do === "goto" && typeof s.url === "string") {
6182
+ try {
6183
+ const u = new URL(s.url);
6184
+ return { ...s, url: `${u.origin}${u.pathname}` };
6185
+ } catch {
6186
+ return s;
6187
+ }
6188
+ }
6189
+ return s;
6190
+ })
6191
+ };
6192
+ }
5992
6193
  function embedScript(doc, dir) {
5993
6194
  const path = join11(dir, "actions.json");
5994
6195
  if (!existsSync10(path)) return;
5995
6196
  const script = scriptFromText(readFileSync2(path, "utf8"));
5996
- if (script) doc.source.script = script;
6197
+ if (script) doc.source.script = publicScript(script);
5997
6198
  }
5998
6199
  async function writeScriptBeside(dir, doc) {
5999
6200
  const path = join11(dir, "actions.json");
@@ -6800,133 +7001,9 @@ import {
6800
7001
  } from "@vosjs/core";
6801
7002
  import { lowerProgramDoc, migrateHostedDoc as migrateHostedDoc3 } from "@vosjs/studio-core";
6802
7003
 
6803
- // src/plugin/login.ts
6804
- import { hostname } from "os";
6805
- var LoginUnsupportedError = class extends Error {
6806
- constructor() {
6807
- super("this origin does not support browser login");
6808
- }
6809
- };
6810
- var MAX_TRANSIENT_FAILURES = 5;
6811
- var MAX_INTERVAL_MS = 3e4;
6812
- async function launchDefaultBrowser(url) {
6813
- const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
6814
- const { exec } = await import("child_process");
6815
- exec(`${opener} ${JSON.stringify(url)}`, () => {
6816
- });
6817
- }
6818
- async function browserLogin(origin, r, opts) {
6819
- const create = await apiJson(origin, "/api/cli/login", {
6820
- method: "POST",
6821
- body: {
6822
- hostname: hostname().slice(0, 64),
6823
- ...opts.label ? { label: opts.label.slice(0, 64) } : {}
6824
- }
6825
- });
6826
- if (create.status === 404) throw new LoginUnsupportedError();
6827
- if (create.status !== 201) throw new Error(apiError("start login", create));
6828
- const code = create.body.code;
6829
- const secret = create.body.secret;
6830
- const verifyUrl = create.body.verifyUrl;
6831
- const expiresAt = Date.parse(String(create.body.expiresAt ?? ""));
6832
- const baseIntervalMs = (typeof create.body.interval === "number" ? create.body.interval : 3) * 1e3;
6833
- if (!code || !secret || !verifyUrl || Number.isNaN(expiresAt)) {
6834
- throw new Error("start login \u2192 malformed response from the platform");
6835
- }
6836
- r.event({ event: "login_await", url: verifyUrl, code, expiresAt });
6837
- r.log(`Confirm this code in the browser: ${code}`);
6838
- r.log(`Sign in at ${verifyUrl}`);
6839
- if (opts.openBrowser) void launchDefaultBrowser(verifyUrl);
6840
- r.log("Waiting for approval\u2026 (Ctrl-C to cancel)");
6841
- const sleep = opts.sleep ?? ((ms) => new Promise((res) => setTimeout(res, ms)));
6842
- let intervalMs = baseIntervalMs;
6843
- let failures = 0;
6844
- let capNoted = false;
6845
- while (Date.now() < expiresAt) {
6846
- await sleep(intervalMs);
6847
- let res;
6848
- try {
6849
- res = await apiJson(origin, "/api/cli/login/poll", {
6850
- method: "POST",
6851
- body: { secret }
6852
- });
6853
- failures = 0;
6854
- } catch (e) {
6855
- if (++failures >= MAX_TRANSIENT_FAILURES) {
6856
- throw new Error(
6857
- `lost the connection while waiting (${e instanceof Error ? e.message : String(e)}) \u2014 run \`vos login\` again`
6858
- );
6859
- }
6860
- continue;
6861
- }
6862
- const status = res.body.status;
6863
- if (res.status === 200 && status === "pending") {
6864
- intervalMs = baseIntervalMs;
6865
- continue;
6866
- }
6867
- if (res.status === 200 && status === "ok") {
6868
- const path = (opts.store ?? writeCredential)(res.body.key);
6869
- const user = typeof res.body.user === "object" && res.body.user !== null ? res.body.user.name ?? "" : "";
6870
- return { path, user };
6871
- }
6872
- if (res.status === 429) {
6873
- if (status === "key_limit" && !capNoted) {
6874
- capNoted = true;
6875
- r.log(`${res.body.error} \u2014 ${res.body.hint}`);
6876
- }
6877
- intervalMs = Math.min(intervalMs * 2, MAX_INTERVAL_MS);
6878
- continue;
6879
- }
6880
- if (res.status === 403 && status === "denied") {
6881
- throw new Error("the sign-in was denied in the browser");
6882
- }
6883
- throw new Error(
6884
- typeof res.body.error === "string" ? res.body.error : apiError("poll login", res)
6885
- );
6886
- }
6887
- throw new Error(
6888
- "no approval within 15 minutes \u2014 run `vos login` again, or mint a key at https://vos.so/app/api and pass --key"
6889
- );
6890
- }
6891
- var HANDOFF_URL = /^(https?:\/\/[^/]+)\/h\/(vos_ho_[A-Za-z0-9_-]+)$/;
6892
- function parseHandoffUrl(url) {
6893
- const m = HANDOFF_URL.exec(url.trim());
6894
- return m ? { origin: m[1], token: m[2] } : null;
6895
- }
6896
- async function handoffLogin(url, r, opts = {}) {
6897
- const parsed = parseHandoffUrl(url);
6898
- if (!parsed)
6899
- throw new Error(
6900
- "--handoff wants the link a person copied from vos.so, https://vos.so/h/vos_ho_\u2026"
6901
- );
6902
- r.log(`exchanging the setup link at ${parsed.origin}\u2026`);
6903
- const res = await apiJson(parsed.origin, "/api/cli/login/exchange", {
6904
- method: "POST",
6905
- body: { token: parsed.token, hostname: hostname().slice(0, 64) }
6906
- });
6907
- if (res.status === 200 && res.body.status === "ok") {
6908
- const path = (opts.store ?? writeCredential)(res.body.key);
6909
- const user = typeof res.body.user === "object" && res.body.user !== null ? res.body.user.name ?? "" : "";
6910
- return {
6911
- path,
6912
- user,
6913
- keyName: String(res.body.keyName ?? ""),
6914
- origin: parsed.origin
6915
- };
6916
- }
6917
- if (res.status === 404 && !res.body.status) {
6918
- throw new Error(
6919
- `${parsed.origin} does not support setup links yet \u2014 run \`vos login\` instead`
6920
- );
6921
- }
6922
- const said = typeof res.body.error === "string" ? res.body.error : apiError("exchange", res);
6923
- const hint = typeof res.body.hint === "string" ? ` ${res.body.hint}` : "";
6924
- throw new Error(`${said}${hint}`);
6925
- }
6926
-
6927
7004
  // src/plugin/programFiles.ts
6928
7005
  import { basename as basename2, extname as extname2, relative as relative2 } from "path";
6929
- import { existsSync as existsSync12, realpathSync } from "fs";
7006
+ import { existsSync as existsSync12, realpathSync as realpathSync2 } from "fs";
6930
7007
  function isLocalName(value) {
6931
7008
  if (/^(https?:|data:|blob:|asset:|media:)/.test(value)) return false;
6932
7009
  if (value.startsWith("$")) return false;
@@ -6978,7 +7055,7 @@ function liftNamedFiles(config, dir) {
6978
7055
  }
6979
7056
  function localDataRefs(config, dir) {
6980
7057
  const refs = [];
6981
- const root = realpathSync(dir);
7058
+ const root = realpathSync2(dir);
6982
7059
  const walk = (value, where, set) => {
6983
7060
  if (typeof value === "string") {
6984
7061
  if (!isLocalName(value) || !FILE_EXT.test(value)) return;
@@ -8493,7 +8570,7 @@ function trackingCwd(vosId) {
8493
8570
 
8494
8571
  // src/plugin/buildProgram.ts
8495
8572
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
8496
- import { basename as basename5, dirname as dirname3, join as join16, resolve as resolve5 } from "path";
8573
+ import { basename as basename5, dirname as dirname3, join as join16, resolve as resolve6 } from "path";
8497
8574
  import { pathToFileURL } from "url";
8498
8575
  import { parse } from "acorn";
8499
8576
  import { fullAncestor } from "acorn-walk";
@@ -8693,7 +8770,7 @@ async function cmdBuild(argv) {
8693
8770
  if (!source)
8694
8771
  throw new UsageError("vos build <program.mjs> [--out config.json] [--json]");
8695
8772
  const r = createReporter(flags.json === true);
8696
- const file = resolve5(source);
8773
+ const file = resolve6(source);
8697
8774
  const text = readFileSync5(file, "utf8");
8698
8775
  const mod = await import(`${pathToFileURL(file).href}?t=${Date.now()}`);
8699
8776
  const program = mod.default ?? mod.program;
@@ -8710,7 +8787,7 @@ async function cmdBuild(argv) {
8710
8787
  );
8711
8788
  return EXIT_ERROR;
8712
8789
  }
8713
- const out = resolve5(
8790
+ const out = resolve6(
8714
8791
  strFlag(flags, "out") ?? join16(dirname3(file), "config.json")
8715
8792
  );
8716
8793
  writeFileSync2(out, JSON.stringify(built.config, null, 2) + "\n");
@@ -8729,7 +8806,7 @@ async function cmdBuild(argv) {
8729
8806
  // src/plugin/compare.ts
8730
8807
  import { spawnSync } from "child_process";
8731
8808
  import { existsSync as existsSync15, mkdirSync as mkdirSync2, statSync as statSync4, writeFileSync as writeFileSync3 } from "fs";
8732
- import { dirname as dirname4, join as join17, resolve as resolve6 } from "path";
8809
+ import { dirname as dirname4, join as join17, resolve as resolve7 } from "path";
8733
8810
  var BOOLEAN_FLAGS7 = /* @__PURE__ */ new Set(["json", "help"]);
8734
8811
  function sampleTimes(duration, every) {
8735
8812
  const step = every > 0 ? every : 1;
@@ -8790,7 +8867,7 @@ async function cmdCompare(argv) {
8790
8867
  );
8791
8868
  requireFfmpeg();
8792
8869
  const r = createReporter(flags.json === true);
8793
- const ref = resolve6(against);
8870
+ const ref = resolve7(against);
8794
8871
  const loaded = await loadVosConfig(source);
8795
8872
  for (const w of loaded.warnings) r.log(`note: ${w}`);
8796
8873
  const config = loaded.config;
@@ -8812,7 +8889,7 @@ async function cmdCompare(argv) {
8812
8889
  const threshold = Number(strFlag(flags, "threshold") ?? 0.95);
8813
8890
  const timesRaw = strFlag(flags, "times");
8814
8891
  const times = timesRaw ? parseTimes(timesRaw, duration) : sampleTimes(duration, Number(strFlag(flags, "every") ?? 1));
8815
- const outDir = resolve6(strFlag(flags, "out") ?? "compare");
8892
+ const outDir = resolve7(strFlag(flags, "out") ?? "compare");
8816
8893
  mkdirSync2(outDir, { recursive: true });
8817
8894
  const browser = await launchBrowser();
8818
8895
  const scores = [];
@@ -8916,7 +8993,7 @@ async function cmdCompare(argv) {
8916
8993
 
8917
8994
  // src/plugin/port.ts
8918
8995
  import { existsSync as existsSync19, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
8919
- import { dirname as dirname7, join as join21, resolve as resolve9 } from "path";
8996
+ import { dirname as dirname7, join as join21, resolve as resolve10 } from "path";
8920
8997
  import { pathToFileURL as pathToFileURL3 } from "url";
8921
8998
 
8922
8999
  // src/plugin/portInventory.ts
@@ -8928,7 +9005,7 @@ import {
8928
9005
  readdirSync as readdirSync4,
8929
9006
  statSync as statSync6
8930
9007
  } from "fs";
8931
- import { dirname as dirname5, join as join19, relative as relative3, resolve as resolve7 } from "path";
9008
+ import { dirname as dirname5, join as join19, relative as relative3, resolve as resolve8 } from "path";
8932
9009
  import { pathToFileURL as pathToFileURL2 } from "url";
8933
9010
  import { findFontFamily as findFontFamily3 } from "@vosjs/shared";
8934
9011
 
@@ -9551,7 +9628,7 @@ var SEEK_AND_READ = `((args) => {
9551
9628
  return out
9552
9629
  })`;
9553
9630
  async function readInventory(source, opts) {
9554
- const abs = resolve7(source);
9631
+ const abs = resolve8(source);
9555
9632
  const dir = existsSync17(abs) && statSync6(abs).isDirectory() ? abs : dirname5(abs);
9556
9633
  const engine = detectEngine(dir);
9557
9634
  const page = sourcePage(abs);
@@ -9719,7 +9796,7 @@ async function readInventory(source, opts) {
9719
9796
  // src/plugin/portScaffold.ts
9720
9797
  import { spawnSync as spawnSync3 } from "child_process";
9721
9798
  import { copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
9722
- import { basename as basename7, dirname as dirname6, join as join20, resolve as resolve8 } from "path";
9799
+ import { basename as basename7, dirname as dirname6, join as join20, resolve as resolve9 } from "path";
9723
9800
  import { findFontFamily as findFontFamily4, fontFaceUrl, nearestFontWeight } from "@vosjs/shared";
9724
9801
 
9725
9802
  // src/plugin/painterLib.ts
@@ -10128,7 +10205,7 @@ function planScaffold(inv, opts) {
10128
10205
  const audio = [];
10129
10206
  const copies = [];
10130
10207
  inv.media.filter((m) => m.kind === "audio" && m.src).forEach((m, i) => {
10131
- const from = resolve8(opts.sourceDir, m.src);
10208
+ const from = resolve9(opts.sourceDir, m.src);
10132
10209
  const name = basename7(from);
10133
10210
  if (!existsSync18(from)) {
10134
10211
  report.push(
@@ -10181,9 +10258,18 @@ function planScaffold(inv, opts) {
10181
10258
  }
10182
10259
  function programSource(p) {
10183
10260
  const j = (v) => JSON.stringify(v, null, 2).replace(/\n/g, "\n ");
10184
- const sceneTodos = p.scenes.length ? p.scenes.map(
10185
- (s) => ` // TODO scene "${s.name}" (${s.start}s${s.duration ? ` to ${s.start + s.duration}s` : ""}): translate its motion onto ctx.elements.get(id).props / .segments here`
10186
- ).join("\n") : " // TODO: translate the source's motion here, one block per scene (tl.addLabel above names them)";
10261
+ const word = (v) => JSON.stringify(
10262
+ Array.from(String(v), (ch) => {
10263
+ const code = ch.charCodeAt(0);
10264
+ return code < 32 || code === 8232 || code === 8233 ? " " : ch;
10265
+ }).join("")
10266
+ );
10267
+ const secs = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
10268
+ const sceneTodos = p.scenes.length ? p.scenes.map((s) => {
10269
+ const start = secs(s.start) ?? 0;
10270
+ const duration = secs(s.duration);
10271
+ return ` // TODO scene ${word(s.name)} (${start}s${duration ? ` to ${start + duration}s` : ""}): translate its motion onto ctx.elements.get(id).props / .segments here`;
10272
+ }).join("\n") : " // TODO: translate the source's motion here, one block per scene (tl.addLabel above names them)";
10187
10273
  const springHint = p.uses.includes("spring") ? `
10188
10274
  // The source springs. Put a spring ON THE TIMELINE with the spring ease:
10189
10275
  // tl.to(p, { y: 0, ease: 'spring(200)', duration: content.refs.lib.springSeconds({ damping: 200 }) }, at)
@@ -10360,11 +10446,11 @@ async function inventory(argv) {
10360
10446
  const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS8);
10361
10447
  const source = positionals[0] ?? ".";
10362
10448
  const r = createReporter(flags.json === true);
10363
- const outDir = resolve9(strFlag(flags, "out") ?? "port");
10449
+ const outDir = resolve10(strFlag(flags, "out") ?? "port");
10364
10450
  mkdirSync5(outDir, { recursive: true });
10365
10451
  const renderFlag = strFlag(flags, "render");
10366
10452
  const inv = await readInventory(source, {
10367
- render: renderFlag === void 0 ? void 0 : resolve9(renderFlag),
10453
+ render: renderFlag === void 0 ? void 0 : resolve10(renderFlag),
10368
10454
  outDir,
10369
10455
  log: (l) => r.log(`note: ${l}`)
10370
10456
  });
@@ -10400,13 +10486,13 @@ function summary(inv) {
10400
10486
  async function scaffold(argv) {
10401
10487
  const { flags } = parseArgs(argv, BOOLEAN_FLAGS8);
10402
10488
  const r = createReporter(flags.json === true);
10403
- const from = resolve9(strFlag(flags, "from") ?? join21("port", "inventory.json"));
10489
+ const from = resolve10(strFlag(flags, "from") ?? join21("port", "inventory.json"));
10404
10490
  if (!existsSync19(from))
10405
10491
  throw new UsageError(
10406
10492
  `no inventory at ${from}: run npx vos port inventory <source> first`
10407
10493
  );
10408
10494
  const inv = JSON.parse(readFileSync8(from, "utf8"));
10409
- const outDir = resolve9(
10495
+ const outDir = resolve10(
10410
10496
  strFlag(flags, "out") ?? join21(dirname7(from), "program")
10411
10497
  );
10412
10498
  const plan = planScaffold(inv, {
@@ -10431,7 +10517,7 @@ async function scaffold(argv) {
10431
10517
  }
10432
10518
  function scaffoldSourceDir(inv) {
10433
10519
  if (inv.root) return inv.root;
10434
- return inv.source.endsWith(".html") ? dirname7(resolve9(inv.source)) : resolve9(inv.source);
10520
+ return inv.source.endsWith(".html") ? dirname7(resolve10(inv.source)) : resolve10(inv.source);
10435
10521
  }
10436
10522
 
10437
10523
  // src/plugin/recipe.ts
@@ -10523,7 +10609,7 @@ async function cmdRecipe(argv) {
10523
10609
 
10524
10610
  // src/plugin/brand.ts
10525
10611
  import { writeFile as writeFile10 } from "fs/promises";
10526
- import { resolve as resolve10 } from "path";
10612
+ import { resolve as resolve11 } from "path";
10527
10613
  import { parseFrontmatter as parseFrontmatter2 } from "@vosjs/shared/frontmatter";
10528
10614
  import { lookKindForGround } from "@vosjs/studio-core";
10529
10615
  var HEX_RE = /#(?:[0-9a-f]{6}|[0-9a-f]{3})\b/gi;
@@ -10842,7 +10928,7 @@ async function cmdBrand(argv) {
10842
10928
  throw new UsageError(`not a URL: ${raw}`);
10843
10929
  }
10844
10930
  const r = createReporter(flags.json === true);
10845
- const out = resolve10(strFlag(flags, "out") ?? "BRAND.md");
10931
+ const out = resolve11(strFlag(flags, "out") ?? "BRAND.md");
10846
10932
  r.log(`reading ${origin}/design.md and /llms.txt\u2026`);
10847
10933
  const [designText, llmsText] = await Promise.all([
10848
10934
  fetchText(`${origin}/design.md`),
@@ -10992,7 +11078,7 @@ async function recordHosted(input) {
10992
11078
 
10993
11079
  // src/plugin/agentBrowser.ts
10994
11080
  import { writeFile as writeFile11 } from "fs/promises";
10995
- import { resolve as resolve11 } from "path";
11081
+ import { resolve as resolve12 } from "path";
10996
11082
  function parseAgentBrowserLog(text) {
10997
11083
  const records = [];
10998
11084
  const problems = [];
@@ -11463,7 +11549,7 @@ async function cmdActions(argv) {
11463
11549
  );
11464
11550
  }
11465
11551
  const r = createReporter(flags.json === true);
11466
- const out = resolve11(strFlag(flags, "out") ?? "actions.json");
11552
+ const out = resolve12(strFlag(flags, "out") ?? "actions.json");
11467
11553
  const viewportFlag = strFlag(flags, "viewport");
11468
11554
  let viewport;
11469
11555
  if (viewportFlag) {
@@ -11472,7 +11558,7 @@ async function cmdActions(argv) {
11472
11558
  viewport = { width: Number(m[1]), height: Number(m[2]) };
11473
11559
  }
11474
11560
  const { readFile: readFile14 } = await import("fs/promises");
11475
- const text = await readFile14(resolve11(input), "utf8");
11561
+ const text = await readFile14(resolve12(input), "utf8");
11476
11562
  const { records, problems } = parseAgentBrowserLog(text);
11477
11563
  for (const p of problems) r.log(` ${p}`);
11478
11564
  const result = convertAgentBrowser(records, {
@@ -11511,7 +11597,7 @@ async function cmdActionsScript(input, flags) {
11511
11597
  const r = createReporter(flags.json === true);
11512
11598
  const { readFile: readFile14 } = await import("fs/promises");
11513
11599
  const { shotList, formatShotList } = await import("./shotList-MAQVLZBY.js");
11514
- const raw = JSON.parse(await readFile14(resolve11(input), "utf8"));
11600
+ const raw = JSON.parse(await readFile14(resolve12(input), "utf8"));
11515
11601
  const errors = validateActions(raw);
11516
11602
  if (errors.length) throw new UsageError(`${input}:
11517
11603
  ${errors.join("\n ")}`);
@@ -11523,7 +11609,7 @@ async function cmdActionsScript(input, flags) {
11523
11609
  // src/plugin/ingest.ts
11524
11610
  import { existsSync as existsSync20 } from "fs";
11525
11611
  import { copyFile, mkdir as mkdir7, readFile as readFile12, stat as stat2 } from "fs/promises";
11526
- import { basename as basename9, join as join22, resolve as resolve12 } from "path";
11612
+ import { basename as basename9, join as join22, resolve as resolve13 } from "path";
11527
11613
  import { inflateRawSync } from "zlib";
11528
11614
  import {
11529
11615
  cursorFromPlaywrightTrace,
@@ -11640,10 +11726,10 @@ async function cmdIngest(argv) {
11640
11726
  throw new UsageError(
11641
11727
  "vos ingest <video.webm|mp4> [--cursor <trace.zip|steps.jsonl|cursor.csv>] [--as footage|take] [--out take] [--offset <ms>] [--viewport WxH] [--background <slug|url|none>] [--json]"
11642
11728
  );
11643
- const videoPath = resolve12(source);
11729
+ const videoPath = resolve13(source);
11644
11730
  if (!existsSync20(videoPath)) throw new UsageError(`${source}: no such file`);
11645
11731
  const r = createReporter(flags.json === true);
11646
- const outDir = resolve12(strFlag(flags, "out") ?? "take");
11732
+ const outDir = resolve13(strFlag(flags, "out") ?? "take");
11647
11733
  const offsetMs = numFlag(flags, "offset", 0);
11648
11734
  const viewportFlag = parseViewport(strFlag(flags, "viewport"));
11649
11735
  const cursorPath = strFlag(flags, "cursor");
@@ -11665,7 +11751,7 @@ async function cmdIngest(argv) {
11665
11751
  }
11666
11752
  let trace = null;
11667
11753
  if (cursorPath) {
11668
- trace = await readTraceFile(resolve12(cursorPath), offsetMs);
11754
+ trace = await readTraceFile(resolve13(cursorPath), offsetMs);
11669
11755
  for (const n of trace.notes) r.log(`note: ${n}`);
11670
11756
  }
11671
11757
  if (existsSync20(join22(outDir, "meta.json"))) {
@@ -12670,7 +12756,7 @@ function takeBrowserArgs(multi) {
12670
12756
  function takeStorageState(flags) {
12671
12757
  const raw = strFlag(flags, "storage-state");
12672
12758
  if (!raw) return void 0;
12673
- const path = resolve13(raw);
12759
+ const path = resolve14(raw);
12674
12760
  if (!existsSync23(path))
12675
12761
  throw new UsageError(`--storage-state: no such file: ${path}`);
12676
12762
  return path;
@@ -12753,7 +12839,7 @@ async function cmdRecord(argv) {
12753
12839
  const url = strFlag(flags, "url") ?? actions.url;
12754
12840
  if (!url)
12755
12841
  throw new UsageError('no URL \u2014 set "url" in the actions file or pass --url');
12756
- const outDir = resolve13(strFlag(flags, "out") ?? "take");
12842
+ const outDir = resolve14(strFlag(flags, "out") ?? "take");
12757
12843
  const storageState = takeStorageState(flags);
12758
12844
  const sessionName = takeSessionName(flags, storageState);
12759
12845
  const browserArgs = takeBrowserArgs(multi);
@@ -12880,7 +12966,9 @@ async function cmdRecord(argv) {
12880
12966
  const carried = [
12881
12967
  ...strFlag(flags, "storage-state") ? [`--storage-state ${strFlag(flags, "storage-state")}`] : [],
12882
12968
  ...browserArgs.map((a) => `--browser-arg=${a}`),
12883
- ...Object.entries(headers).map(([k, v]) => `--header ${k}=${v}`),
12969
+ // A header value is a bypass token more often than not: named, never
12970
+ // printed.
12971
+ ...Object.keys(headers).map((k) => `--header ${k}=\u2026`),
12884
12972
  ...sessionName ? [`--session ${sessionName}`] : [],
12885
12973
  ...flags["allow-wall"] === true ? ["--allow-wall"] : []
12886
12974
  ].join(" ");
@@ -12996,7 +13084,7 @@ async function cmdCreate2(argv) {
12996
13084
  const url = strFlag(flags, "url") ?? actions.url;
12997
13085
  if (!url)
12998
13086
  throw new UsageError('no URL \u2014 set "url" in the actions file or pass --url');
12999
- const outDir = resolve13(strFlag(flags, "out") ?? "take");
13087
+ const outDir = resolve14(strFlag(flags, "out") ?? "take");
13000
13088
  const format = videoFormat(strFlag(flags, "format"), positionals[0]);
13001
13089
  const out = positionals[0] ?? join25(outDir, `out.${format}`);
13002
13090
  const parallel = numFlag(flags, "parallel", 1);
@@ -13123,7 +13211,7 @@ async function cmdPlan(argv) {
13123
13211
  }
13124
13212
  let reuse;
13125
13213
  if (flags.reuse === true) {
13126
- const from = resolve13(strFlag(flags, "from") ?? join25(dir, PREV_DOC_NAME));
13214
+ const from = resolve14(strFlag(flags, "from") ?? join25(dir, PREV_DOC_NAME));
13127
13215
  if (!existsSync23(from)) {
13128
13216
  throw new UsageError(
13129
13217
  `--reuse: ${from} does not exist \u2014 a re-record into this take writes doc.prev.json, or pass --from <doc.json>`
@@ -13181,7 +13269,7 @@ async function cmdPlan(argv) {
13181
13269
  ${s.reuse.flagged.join("\n ")}` : "") : "";
13182
13270
  r.done(
13183
13271
  {
13184
- take: resolve13(dir),
13272
+ take: resolve14(dir),
13185
13273
  fresh: s.fresh,
13186
13274
  cursorKept: s.cursorKept,
13187
13275
  zoomAuto: s.zoomAuto,
@@ -13547,7 +13635,7 @@ async function resolveStyleRef(flags) {
13547
13635
  }
13548
13636
  async function resolveDocRef(ref, flags, what) {
13549
13637
  const styleRef = ref;
13550
- const file = existsSync23(styleRef) ? resolve13(
13638
+ const file = existsSync23(styleRef) ? resolve14(
13551
13639
  styleRef,
13552
13640
  existsSync23(join25(styleRef, "doc.json")) ? "doc.json" : ""
13553
13641
  ) : null;
@@ -13673,7 +13761,7 @@ async function cmdOpen(argv) {
13673
13761
  /\/+$/,
13674
13762
  ""
13675
13763
  );
13676
- const server = await startTakeServer(resolve13(dir), {});
13764
+ const server = await startTakeServer(resolve14(dir), {});
13677
13765
  const url = `${studio}/studio?take=${encodeURIComponent(server.base)}`;
13678
13766
  r.event({ event: "open", server: server.base, url });
13679
13767
  r.log(`take served at ${server.base}`);
@@ -13681,10 +13769,7 @@ async function cmdOpen(argv) {
13681
13769
  `);
13682
13770
  if (flags.print !== true) {
13683
13771
  r.log("opening the studio\u2026 (Ctrl-C to stop serving)");
13684
- const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
13685
- const { exec } = await import("child_process");
13686
- exec(`${opener} ${JSON.stringify(url)}`, () => {
13687
- });
13772
+ await launchDefaultBrowser(url);
13688
13773
  } else {
13689
13774
  r.log("serving (\u2014 --print: not launching a browser; Ctrl-C to stop)");
13690
13775
  }
@@ -13970,7 +14055,7 @@ async function cmdPush3(argv) {
13970
14055
  );
13971
14056
  const refusal = takePushRefusal({
13972
14057
  vos: strFlag(flags, "vos"),
13973
- trackedVosId: readSyncState(resolve13(dir))?.vosId ?? null,
14058
+ trackedVosId: readSyncState(resolve14(dir))?.vosId ?? null,
13974
14059
  programOnly: ["slug", "desc", "tags", "base", "remix-of", "still"].filter(
13975
14060
  (name) => hasFlag(flags, name)
13976
14061
  )
@@ -13986,7 +14071,7 @@ async function cmdPush3(argv) {
13986
14071
  `--claimable creates a NEW claimable vos; ${iterating.map((f) => `--${f}`).join(", ")} ${iterating.length > 1 ? "apply" : "applies"} to a keyed push`
13987
14072
  );
13988
14073
  const claim = await pushTakeClaimable(
13989
- resolve13(dir),
14074
+ resolve14(dir),
13990
14075
  {
13991
14076
  api: strFlag(flags, "api"),
13992
14077
  origin: strFlag(flags, "origin"),
@@ -14008,7 +14093,7 @@ reference and the only credential.`
14008
14093
  }
14009
14094
  const overrides = multi.override;
14010
14095
  const result = await pushTake(
14011
- resolve13(dir),
14096
+ resolve14(dir),
14012
14097
  {
14013
14098
  key: strFlag(flags, "key"),
14014
14099
  api: strFlag(flags, "api"),
@@ -14062,7 +14147,7 @@ async function cmdPull2(argv) {
14062
14147
  const dir = positionals[0] ?? ".";
14063
14148
  const r = createReporter(flags.json === true);
14064
14149
  const result = await pullTake(
14065
- resolve13(dir),
14150
+ resolve14(dir),
14066
14151
  {
14067
14152
  key: strFlag(flags, "key"),
14068
14153
  api: strFlag(flags, "api"),
@@ -14362,4 +14447,4 @@ export {
14362
14447
  verbHelp,
14363
14448
  run
14364
14449
  };
14365
- //# sourceMappingURL=chunk-EYF3WJIC.js.map
14450
+ //# sourceMappingURL=chunk-X6NQNBDF.js.map