@osmo.inc/cli 0.1.22 → 0.1.23

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
@@ -36,7 +36,11 @@ not required. Other CLI commands remain available on platforms without Studio.
36
36
  When you want a review link for this project, run `osmo login`, then
37
37
  `osmo studio deploy`. This uploads the source and video to one project review
38
38
  page. Use `osmo studio clone PROJECT` to copy an accessible project for local
39
- editing. Cloud operations require login and retain existing source permissions.
39
+ editing. Old web-editor projects download into `legacy-<id>/` with `README.md`,
40
+ `project.json`, `animations/`, and `assets.json`. These are conversion materials,
41
+ not runnable local projects: media remains as URLs, and no Git history or cloud
42
+ sync connection is created. Pass a folder argument to override the destination.
43
+ Cloud operations require login and retain existing source permissions.
40
44
 
41
45
  ## Share a video and collect feedback
42
46
 
package/dist/osmo.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/commands.ts
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
- import path6 from "node:path";
4
+ import path7 from "node:path";
5
5
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
6
6
  import { parseArgs } from "node:util";
7
7
 
@@ -500,8 +500,8 @@ async function revoke(origin, state, save3) {
500
500
  await save3();
501
501
  return signedIn;
502
502
  }
503
- async function authCommand(args, flags = {}) {
504
- const origin = authOrigin();
503
+ async function authCommand(args, flags = {}, requestedOrigin = authOrigin()) {
504
+ const origin = authOrigin({ OSMO_BASE_URL: requestedOrigin });
505
505
  const scope = [
506
506
  ...IDENTITY_SCOPES,
507
507
  ...PERMISSIONS.filter(
@@ -1259,13 +1259,43 @@ function formatResources(result) {
1259
1259
  }
1260
1260
 
1261
1261
  // src/run.ts
1262
+ import { spawnSync as spawnSync2 } from "node:child_process";
1262
1263
  import { randomUUID as randomUUID2 } from "node:crypto";
1263
- import { createWriteStream, openAsBlob, rmSync } from "node:fs";
1264
- import { mkdir as mkdir3, readFile as readFile3, rename as rename3, rm as rm3, stat as stat2 } from "node:fs/promises";
1265
- import path4 from "node:path";
1264
+ import { createWriteStream, existsSync as existsSync2, openAsBlob, rmSync as rmSync2 } from "node:fs";
1265
+ import { mkdir as mkdir3, readFile as readFile3, rename as rename3, rm as rm3, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
1266
+ import path5 from "node:path";
1266
1267
  import { Readable } from "node:stream";
1267
1268
  import { pipeline } from "node:stream/promises";
1268
1269
 
1270
+ // src/cloud-pointer.ts
1271
+ import { spawnSync } from "node:child_process";
1272
+
1273
+ // src/git.ts
1274
+ import {
1275
+ existsSync,
1276
+ mkdirSync,
1277
+ readFileSync,
1278
+ renameSync,
1279
+ rmSync,
1280
+ writeFileSync
1281
+ } from "node:fs";
1282
+ import path4 from "node:path";
1283
+ var hasRepo = (root) => existsSync(path4.join(root, ".git"));
1284
+
1285
+ // src/cloud-pointer.ts
1286
+ var PROJECT_ID = /^[a-z0-9]{10,40}$/;
1287
+ function pointerFromGit(root) {
1288
+ const read = (key) => {
1289
+ const r = spawnSync("git", ["-C", root, "config", "--get", key], {
1290
+ encoding: "utf8"
1291
+ });
1292
+ return r.status === 0 ? r.stdout.trim() : "";
1293
+ };
1294
+ const origin = read("osmo.cloud.origin"), id = read("osmo.cloud.id");
1295
+ return origin && id ? { origin, id } : null;
1296
+ }
1297
+ var cloudPointer = (root) => hasRepo(root) ? pointerFromGit(root) : null;
1298
+
1269
1299
  // src/cloud-request.ts
1270
1300
  var PERMISSION_DOES = {
1271
1301
  "projects:write": "change projects",
@@ -1318,12 +1348,17 @@ var UPLOAD_MAX_BYTES = 100 * 1024 * 1024;
1318
1348
  var TRANSFER_MS = 15 * 6e4;
1319
1349
  var EXTENSIONS = {
1320
1350
  "video/mp4": "mp4",
1351
+ "video/quicktime": "mov",
1352
+ "video/webm": "webm",
1321
1353
  "image/png": "png",
1322
1354
  "image/jpeg": "jpg",
1323
1355
  "image/webp": "webp",
1356
+ "image/gif": "gif",
1324
1357
  "image/svg+xml": "svg",
1325
1358
  "audio/mpeg": "mp3",
1326
- "audio/wav": "wav"
1359
+ "audio/wav": "wav",
1360
+ "audio/mp4": "m4a",
1361
+ "audio/ogg": "ogg"
1327
1362
  };
1328
1363
  var jobPattern = /^run_[a-z0-9]{8,40}$/;
1329
1364
  var invalidInput = (detail, issues) => new OsmoError(
@@ -1569,7 +1604,7 @@ function fileSource(value) {
1569
1604
  return { kind: "local", file: value };
1570
1605
  }
1571
1606
  function uploadType(name) {
1572
- return UPLOAD_TYPES[path4.extname(name).slice(1).toLowerCase()];
1607
+ return UPLOAD_TYPES[path5.extname(name).slice(1).toLowerCase()];
1573
1608
  }
1574
1609
  var megabytes = (n) => n < 1048576 ? `${Math.max(1, Math.round(n / 1024))} KB` : `${(n / 1048576).toFixed(1)} MB`;
1575
1610
  async function resolveFiles(schema, input, issues, io) {
@@ -1605,12 +1640,12 @@ async function resolveFiles(schema, input, issues, io) {
1605
1640
  else if (!uploadType(job.source.file))
1606
1641
  issues.push({
1607
1642
  path: job.path,
1608
- message: `${path4.basename(job.source.file)} isn't a type runs take (${Object.keys(UPLOAD_TYPES).join(", ")})`
1643
+ message: `${path5.basename(job.source.file)} isn't a type runs take (${Object.keys(UPLOAD_TYPES).join(", ")})`
1609
1644
  });
1610
1645
  else if (info.size > UPLOAD_MAX_BYTES || info.size === 0)
1611
1646
  issues.push({
1612
1647
  path: job.path,
1613
- message: `${path4.basename(job.source.file)} must be 1 byte to ${megabytes(UPLOAD_MAX_BYTES)}`
1648
+ message: `${path5.basename(job.source.file)} must be 1 byte to ${megabytes(UPLOAD_MAX_BYTES)}`
1614
1649
  });
1615
1650
  }
1616
1651
  return async () => {
@@ -1619,7 +1654,7 @@ async function resolveFiles(schema, input, issues, io) {
1619
1654
  const { file } = job.source;
1620
1655
  const type = uploadType(file);
1621
1656
  const blob = await openAsBlob(file, { type });
1622
- io.log(`uploading ${path4.basename(file)} (${megabytes(blob.size)})`);
1657
+ io.log(`uploading ${path5.basename(file)} (${megabytes(blob.size)})`);
1623
1658
  job.set(await upload(blob, type));
1624
1659
  } else if (job.source.kind === "web") {
1625
1660
  io.log(`fetching ${job.source.url}`);
@@ -1807,34 +1842,71 @@ Next: ${next}`
1807
1842
  stop();
1808
1843
  }
1809
1844
  }
1845
+ function projectFolder(start = process.cwd()) {
1846
+ for (let dir = path5.resolve(start); ; dir = path5.dirname(dir)) {
1847
+ if (existsSync2(path5.join(dir, ".osmo/project.json"))) return dir;
1848
+ if (path5.dirname(dir) === dir) return null;
1849
+ }
1850
+ }
1851
+ function here() {
1852
+ const root = projectFolder();
1853
+ if (!root) return null;
1854
+ const pointer = cloudPointer(root);
1855
+ let same = false;
1856
+ try {
1857
+ same = !!pointer && PROJECT_ID.test(pointer.id) && new URL(pointer.origin).origin === new URL(authOrigin()).origin;
1858
+ } catch {
1859
+ }
1860
+ return same && pointer ? { root, project: pointer.id } : { root };
1861
+ }
1862
+ async function generationsFolder(root) {
1863
+ const ours = path5.join(root, "generations");
1864
+ const listed = hasRepo(root) ? spawnSync2("git", ["-C", root, "ls-files", "--", "generations"], {
1865
+ encoding: "utf8"
1866
+ }) : null;
1867
+ const tracked = listed?.status === 0 && listed.stdout.trim() !== "";
1868
+ const theirs = tracked || existsSync2(ours) && !existsSync2(path5.join(ours, ".gitignore"));
1869
+ const folder = theirs ? path5.join(root, "osmo-generations") : ours;
1870
+ await mkdir3(folder, { recursive: true });
1871
+ const ignore = path5.join(folder, ".gitignore");
1872
+ if (!existsSync2(ignore)) await writeFile3(ignore, "*\n");
1873
+ return folder;
1874
+ }
1810
1875
  async function targets(run, out2) {
1811
1876
  const model = (run.model.split("/").pop() ?? "").replace(/[^A-Za-z0-9.-]/g, "-").replace(/^[.-]+/, "") || "output";
1812
1877
  const name = `${model}-${run.job.slice(4, 12)}`;
1813
1878
  const extension = (o) => {
1814
- const fromUrl = path4.extname(new URL(o.url).pathname).slice(1);
1879
+ const fromUrl = path5.extname(new URL(o.url).pathname).slice(1);
1815
1880
  return EXTENSIONS[o.mime] ?? (/^[A-Za-z0-9]{1,5}$/.test(fromUrl) ? fromUrl : "bin");
1816
1881
  };
1817
1882
  const several = run.outputs.length > 1;
1818
1883
  const named = run.outputs.map(
1819
1884
  (o, i) => `${name}${several ? `-${i + 1}` : ""}.${extension(o)}`
1820
1885
  );
1821
- if (out2 === void 0) return named;
1822
- const folder = /[/\\]$/.test(out2) || (await stat2(out2).catch(() => null))?.isDirectory() || several && !path4.extname(out2);
1886
+ if (out2 === void 0) {
1887
+ const project = here();
1888
+ if (!project) return named;
1889
+ const folder2 = await generationsFolder(project.root);
1890
+ return named.map(
1891
+ (n) => path5.relative(process.cwd(), path5.join(folder2, n)) || n
1892
+ );
1893
+ }
1894
+ const folder = /[/\\]$/.test(out2) || (await stat2(out2).catch(() => null))?.isDirectory() || several && !path5.extname(out2);
1823
1895
  if (!folder) {
1824
1896
  if (!several)
1825
1897
  return run.outputs.map(
1826
- (o) => path4.extname(out2) ? out2 : `${out2}.${extension(o)}`
1898
+ (o) => path5.extname(out2) ? out2 : `${out2}.${extension(o)}`
1827
1899
  );
1828
- const stem = out2.slice(0, -path4.extname(out2).length);
1900
+ const stem = out2.slice(0, -path5.extname(out2).length);
1829
1901
  return run.outputs.map((o, i) => `${stem}-${i + 1}.${extension(o)}`);
1830
1902
  }
1831
1903
  await mkdir3(out2, { recursive: true });
1832
- return named.map((file) => path4.join(out2, file));
1904
+ return named.map((file) => path5.join(out2, file));
1833
1905
  }
1834
1906
  async function save2(run, out2, io) {
1835
1907
  let partial;
1836
1908
  const stop = onInterrupt(() => {
1837
- if (partial) rmSync(partial, { force: true });
1909
+ if (partial) rmSync2(partial, { force: true });
1838
1910
  writeNow(
1839
1911
  io.json ? 1 : 2,
1840
1912
  io.json ? JSON.stringify({
@@ -1863,7 +1935,7 @@ Next: ${pickUp(run.job, out2)}`
1863
1935
  gone ? `${run.job}'s outputs are no longer kept. Outputs last 30 days.` : `Couldn't download ${run.job}'s output${response ? ` (${response.status})` : ""}.`,
1864
1936
  gone ? void 0 : pickUp(run.job, out2)
1865
1937
  );
1866
- await mkdir3(path4.dirname(path4.resolve(file)), { recursive: true });
1938
+ await mkdir3(path5.dirname(path5.resolve(file)), { recursive: true });
1867
1939
  partial = `${file}.part-${process.pid}`;
1868
1940
  try {
1869
1941
  await pipeline(
@@ -1880,7 +1952,7 @@ Next: ${pickUp(run.job, out2)}`
1880
1952
  partial = void 0;
1881
1953
  }
1882
1954
  const bytes2 = (await stat2(file)).size;
1883
- const said = path4.extname(file).slice(1).toLowerCase();
1955
+ const said = path5.extname(file).slice(1).toLowerCase();
1884
1956
  const made = EXTENSIONS[output.mime];
1885
1957
  if (out2 !== void 0 && said && made && (said === "jpeg" ? "jpg" : said) !== made)
1886
1958
  io.log(`${file} holds ${output.mime}, which its name doesn't say.`);
@@ -1969,7 +2041,7 @@ async function runCommand(id, flags, io) {
1969
2041
  const schema = detail.run.inputSchema;
1970
2042
  const base = flags.inputs ? await readInputsFile(flags.inputs) : {};
1971
2043
  const { input, issues } = buildInputs(schema, flags.input ?? [], base);
1972
- const wanted = path4.extname(flags.out ?? "").slice(1).toLowerCase();
2044
+ const wanted = path5.extname(flags.out ?? "").slice(1).toLowerCase();
1973
2045
  const formats = schema.properties?.format?.enum;
1974
2046
  if (wanted && formats && input.format === void 0 && !issues.length) {
1975
2047
  const format = wanted === "jpeg" ? "jpg" : wanted;
@@ -2003,6 +2075,7 @@ Next: ${error.next}`
2003
2075
  );
2004
2076
  });
2005
2077
  const key = randomUUID2();
2078
+ const linked = here()?.project;
2006
2079
  const refusedFirst = (code) => ["runs_disabled", "model_unavailable"].includes(code ?? "");
2007
2080
  let started;
2008
2081
  try {
@@ -2014,7 +2087,9 @@ Next: ${error.next}`
2014
2087
  body: {
2015
2088
  model: detail.id,
2016
2089
  inputs: input,
2017
- ...flags.workspace ? { workspace: flags.workspace } : {}
2090
+ ...flags.workspace ? { workspace: flags.workspace } : {},
2091
+ // The linked project this runs in: the run is listed with it.
2092
+ ...linked ? { project: linked } : {}
2018
2093
  },
2019
2094
  wait: 0,
2020
2095
  headers: { "Idempotency-Key": key }
@@ -2074,6 +2149,8 @@ async function jobsCommand(job, flags, io) {
2074
2149
  if (job === void 0) {
2075
2150
  const params = new URLSearchParams({ limit: flags.limit ?? "20" });
2076
2151
  if (flags.cursor) params.set("cursor", flags.cursor);
2152
+ const project = flags.all ? void 0 : here()?.project;
2153
+ if (project) params.set("project", project);
2077
2154
  const page = await api(`/api/runs?${params}`);
2078
2155
  if (page.status === 400 && page.data.error === "invalid_cursor")
2079
2156
  throw new UsageError(
@@ -2091,7 +2168,9 @@ async function jobsCommand(job, flags, io) {
2091
2168
  status: "ok",
2092
2169
  runs: page.data.runs,
2093
2170
  nextCursor: page.data.nextCursor ?? null,
2094
- next: page.data.runs.length ? "osmo jobs JOB" : "osmo resources list --type model"
2171
+ ...project ? { inProject: true } : {},
2172
+ ...flags.all ? { all: true } : {},
2173
+ next: page.data.runs.length ? "osmo jobs JOB" : project ? "osmo jobs --all" : "osmo resources list --type model"
2095
2174
  };
2096
2175
  }
2097
2176
  if (!jobPattern.test(job))
@@ -2175,7 +2254,9 @@ Next: ${r.next}`;
2175
2254
  }
2176
2255
  function formatJobs(result) {
2177
2256
  const r = result;
2178
- if (!r.runs.length) return `No runs yet.
2257
+ if (!r.runs.length)
2258
+ return r.inProject ? `No runs in this project yet. osmo jobs --all lists all of yours.
2259
+ Next: ${r.next}` : `No runs yet.
2179
2260
  Next: ${r.next}`;
2180
2261
  const when = (iso) => {
2181
2262
  const d = new Date(iso);
@@ -2194,7 +2275,9 @@ Next: ${r.next}`;
2194
2275
  ...rows.map(
2195
2276
  (row) => row.map((cell, i) => i < 3 ? cell.padEnd(widths[i]) : cell).join(" ")
2196
2277
  ),
2197
- ...r.nextCursor ? [`\u2026 and older runs. Continue with: osmo jobs --cursor ${r.nextCursor}`] : [],
2278
+ ...r.nextCursor ? [
2279
+ `\u2026 and older runs. Continue with: osmo jobs --cursor ${r.nextCursor}${r.all ? " --all" : ""}`
2280
+ ] : [],
2198
2281
  "",
2199
2282
  `Next: ${r.next}`
2200
2283
  ].join("\n");
@@ -2344,24 +2427,27 @@ async function deleteShare(value, yes = false) {
2344
2427
  async function unshare(value) {
2345
2428
  const share = await resolveShare(value);
2346
2429
  const origin = authOrigin();
2430
+ await unshareProject(share.id, origin);
2431
+ const restore = newVersion(share);
2432
+ return {
2433
+ status: "unshared",
2434
+ share: share.id,
2435
+ ...restore ? { restore } : {}
2436
+ };
2437
+ }
2438
+ async function unshareProject(projectId, origin) {
2347
2439
  const done = await call(
2348
2440
  origin,
2349
- `/api/projects/${share.id}/share`,
2441
+ `/api/projects/${projectId}/share`,
2350
2442
  { method: "DELETE", allow: [403] }
2351
2443
  );
2352
2444
  if (done.error === "scope_required") throw scopeRequired(origin, done.scope);
2353
2445
  if (done.error)
2354
2446
  throw new OsmoError(
2355
2447
  "forbidden",
2356
- `Only an owner of share ${share.id} can unshare it.`,
2448
+ `Only an owner of share ${projectId} can unshare it.`,
2357
2449
  "osmo shares"
2358
2450
  );
2359
- const restore = newVersion(share);
2360
- return {
2361
- status: "unshared",
2362
- share: share.id,
2363
- ...restore ? { restore } : {}
2364
- };
2365
2451
  }
2366
2452
  async function shareComments(value, {
2367
2453
  open = false,
@@ -2597,7 +2683,7 @@ function formatUsage(result, now = Date.now()) {
2597
2683
  // src/video-deploy.ts
2598
2684
  import { execFile } from "node:child_process";
2599
2685
  import { stat as stat3 } from "node:fs/promises";
2600
- import path5 from "node:path";
2686
+ import path6 from "node:path";
2601
2687
  import { promisify } from "node:util";
2602
2688
 
2603
2689
  // src/upload-render.ts
@@ -2766,9 +2852,9 @@ async function shareVideo(file, {
2766
2852
  if (to !== void 0) parseShare(to, origin);
2767
2853
  if (name !== void 0 && (!name.trim() || name.trim().length > 200))
2768
2854
  throw new Error("--name takes 1 to 200 characters.");
2769
- const source = path5.resolve(file), metadata = await probeVideo(source);
2855
+ const source = path6.resolve(file), metadata = await probeVideo(source);
2770
2856
  await currentAccount(origin);
2771
- const title = name?.trim() ?? path5.basename(source).slice(0, 200);
2857
+ const title = name?.trim() ?? path6.basename(source).slice(0, 200);
2772
2858
  const target = to === void 0 ? void 0 : await resolveShare(to);
2773
2859
  if (target?.kind === "repo")
2774
2860
  throw new OsmoError(
@@ -2811,14 +2897,14 @@ Retry with --to ${share} to add it to the same share.`,
2811
2897
  }
2812
2898
 
2813
2899
  // src/commands.ts
2814
- var auth = (path7, usage, about, args, flags) => ({
2815
- path: path7,
2900
+ var auth = (path8, usage, about, args, flags) => ({
2901
+ path: path8,
2816
2902
  group: "Account",
2817
2903
  usage,
2818
2904
  about,
2819
2905
  args,
2820
2906
  flags,
2821
- run: (rest, flags2) => authCommand([...path7, ...rest], flags2),
2907
+ run: (rest, flags2) => authCommand([...path8, ...rest], flags2),
2822
2908
  text: (result) => formatAuth(result),
2823
2909
  failed: (result) => ["denied", "expired"].includes(result.status)
2824
2910
  });
@@ -3044,7 +3130,7 @@ var COMMANDS = [
3044
3130
  },
3045
3131
  out: out(
3046
3132
  "PATH",
3047
- "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT here."
3133
+ "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT in the project's generations/ (kept out of its versions), or here outside a project."
3048
3134
  ),
3049
3135
  "no-wait": {
3050
3136
  type: "boolean",
@@ -3065,13 +3151,13 @@ var COMMANDS = [
3065
3151
  {
3066
3152
  path: ["jobs"],
3067
3153
  group: "Resources and models",
3068
- usage: "jobs [JOB] [--out PATH] [--limit N]",
3069
- about: "Lists your recent runs, newest first. With a JOB, waits for it and saves its outputs, which are kept for 30 days.",
3154
+ usage: "jobs [JOB] [--out PATH] [--limit N] [--all]",
3155
+ about: "Lists your recent runs, newest first: in a project linked to the cloud, that project's. With a JOB, waits for it and saves its outputs, which are kept for 30 days.",
3070
3156
  args: [0, 1],
3071
3157
  flags: {
3072
3158
  out: out(
3073
3159
  "PATH",
3074
- "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT here."
3160
+ "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT in the project's generations/ (kept out of its versions), or here outside a project."
3075
3161
  ),
3076
3162
  limit: {
3077
3163
  type: "string",
@@ -3082,6 +3168,10 @@ var COMMANDS = [
3082
3168
  type: "string",
3083
3169
  value: "CURSOR",
3084
3170
  help: "Continue a cut-off list from its nextCursor."
3171
+ },
3172
+ all: {
3173
+ type: "boolean",
3174
+ help: "List all your runs, not only this project's."
3085
3175
  }
3086
3176
  },
3087
3177
  example: "osmo jobs run_abc12345",
@@ -3096,6 +3186,11 @@ var COMMANDS = [
3096
3186
  "--out needs a job: osmo jobs JOB --out PATH.",
3097
3187
  "osmo jobs --help"
3098
3188
  );
3189
+ if (args.length && flags.all)
3190
+ throw new UsageError(
3191
+ "--all widens the list, which osmo jobs prints without a JOB.",
3192
+ "osmo jobs --help"
3193
+ );
3099
3194
  if (args.length && (flags.limit !== void 0 || flags.cursor !== void 0))
3100
3195
  throw new UsageError(
3101
3196
  "--limit and --cursor page the list, which osmo jobs prints without a JOB.",
@@ -3289,7 +3384,7 @@ Version: ${r.versionLink}`;
3289
3384
  studio(
3290
3385
  "clone",
3291
3386
  "PROJECT [FOLDER]",
3292
- "Copies a project from the cloud into a new folder, with its history. PROJECT is the project's ID, or the link to its page or its review. FOLDER defaults to the project's name. Needs osmo login and access to the project.",
3387
+ "Copies a cloud project and its history into a new folder. Legacy web-editor projects download as text exports with asset URLs and require conversion before local editing. PROJECT is an ID or project/review link. FOLDER defaults to the project name, or legacy-<id> for legacy exports. Needs osmo login and source access.",
3293
3388
  [1, 2],
3294
3389
  { example: "osmo studio clone https://studio.osmo.inc/app/projects/ID" }
3295
3390
  ),
@@ -3490,9 +3585,9 @@ var GLOBAL_FLAGS = {
3490
3585
  function findCommand(words2) {
3491
3586
  let found;
3492
3587
  for (const command of COMMANDS)
3493
- for (const path7 of [command.path, ...command.aliases ?? []])
3494
- if (path7.length <= words2.length && path7.every((word, i) => words2[i] === word) && path7.length > (found?.length ?? 0))
3495
- found = { command, length: path7.length };
3588
+ for (const path8 of [command.path, ...command.aliases ?? []])
3589
+ if (path8.length <= words2.length && path8.every((word, i) => words2[i] === word) && path8.length > (found?.length ?? 0))
3590
+ found = { command, length: path8.length };
3496
3591
  return found && { command: found.command, rest: words2.slice(found.length) };
3497
3592
  }
3498
3593
  function commandHelp(command) {
@@ -3504,7 +3599,7 @@ function commandHelp(command) {
3504
3599
  );
3505
3600
  const width = Math.max(...names.map((name) => name.length));
3506
3601
  const aliases = (command.aliases ?? []).map(
3507
- (path7) => `osmo ${path7.join(" ")}`
3602
+ (path8) => `osmo ${path8.join(" ")}`
3508
3603
  );
3509
3604
  return [
3510
3605
  `osmo ${command.usage}`,
@@ -3684,17 +3779,17 @@ async function loadStudio() {
3684
3779
  manifest2 = createRequire(import.meta.url).resolve(
3685
3780
  `@osmo.inc/cli-${platform}/package.json`
3686
3781
  );
3687
- entry = path6.join(path6.dirname(manifest2), "dist/studio.js");
3782
+ entry = path7.join(path7.dirname(manifest2), "dist/studio.js");
3688
3783
  } catch {
3689
3784
  }
3690
- if (!existsSync(entry))
3785
+ if (!existsSync3(entry))
3691
3786
  throw new OsmoError(
3692
3787
  "studio_unavailable",
3693
3788
  PLATFORMS.includes(platform) ? `Osmo Studio and its renderer aren't installed: @osmo.inc/cli-${platform} is missing. Reinstall @osmo.inc/cli with optional dependencies; if that doesn't add it, this release has no package for ${platform}.` : `Osmo Studio's renderer isn't available for ${platform} yet. It runs on ${PLATFORMS.join(", ")}.`,
3694
3789
  PLATFORMS.includes(platform) ? "npm install -g @osmo.inc/cli" : void 0
3695
3790
  );
3696
3791
  if (manifest2) {
3697
- const installed = JSON.parse(readFileSync(manifest2, "utf8")).version;
3792
+ const installed = JSON.parse(readFileSync2(manifest2, "utf8")).version;
3698
3793
  if (installed !== version)
3699
3794
  throw new OsmoError(
3700
3795
  "studio_mismatch",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osmo.inc/cli",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -33,8 +33,8 @@
33
33
  "fflate"
34
34
  ],
35
35
  "optionalDependencies": {
36
- "@osmo.inc/cli-darwin-arm64": "0.1.22",
37
- "@osmo.inc/cli-linux-x64": "0.1.22",
38
- "@osmo.inc/cli-linux-arm64": "0.1.22"
36
+ "@osmo.inc/cli-darwin-arm64": "0.1.23",
37
+ "@osmo.inc/cli-linux-x64": "0.1.23",
38
+ "@osmo.inc/cli-linux-arm64": "0.1.23"
39
39
  }
40
40
  }
package/release.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
- "version": "0.1.22",
2
+ "version": "0.1.23",
3
3
  "package": "@osmo.inc/cli",
4
4
  "platform": "any",
5
5
  "channel": "latest",
6
6
  "defaultCloudOrigin": "https://studio.osmo.inc",
7
- "sourceCommit": "dc5a0ab0dc8f153ac47f88ec6f5207d38e1408a0",
7
+ "sourceCommit": "e865c900aafb496ce6520ab1308f911087337ccf",
8
8
  "sourceDirty": false,
9
9
  "licenseFileIncluded": false,
10
10
  "dependencyCount": 1,
@@ -19,14 +19,14 @@
19
19
  }
20
20
  },
21
21
  "contents": {
22
- "totalBytes": 254101,
22
+ "totalBytes": 258185,
23
23
  "fileCount": 13,
24
24
  "groups": {
25
- "dist": 137666,
25
+ "dist": 141437,
26
26
  "node_modules/fflate": 96377,
27
27
  "DEPLOY.md": 6514,
28
28
  "third-party": 4850,
29
- "README.md": 3657,
29
+ "README.md": 3970,
30
30
  "SETUP.md": 2893,
31
31
  "bin": 1001,
32
32
  "package.json": 788,
@@ -35,7 +35,7 @@
35
35
  "largestFiles": [
36
36
  {
37
37
  "path": "dist/osmo.js",
38
- "bytes": 137666
38
+ "bytes": 141437
39
39
  },
40
40
  {
41
41
  "path": "node_modules/fflate/esm/index.mjs",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  {
49
49
  "path": "README.md",
50
- "bytes": 3657
50
+ "bytes": 3970
51
51
  },
52
52
  {
53
53
  "path": "third-party/npm/fflate@0.8.3/package.json",
@@ -88,11 +88,11 @@
88
88
  ]
89
89
  },
90
90
  "hashes": {
91
- "dist/osmo.js": "3d0da716a65c0f85d00da766f0981c633ea121f3943e72c3fbd4c5c70a069799",
91
+ "dist/osmo.js": "049c78e40164dbf2c1f0b6edbb42f3367ee53f30349b2256e7745472278bf985",
92
92
  "third-party/inventory.json": "3927f7452a7e60b86aa376f17c549311f4d55327a33f5ac2a82d337a14b38f0b"
93
93
  },
94
94
  "lockfiles": {
95
- "package-lock.json": "50769688a12227eb1bafbaf2f7e4e995013cdb0d8b4277ef79ef3a6e5c6856d2",
95
+ "package-lock.json": "2d0f9f1a32d5196c97f3a6cc4116390870c667686cf562ba17f5addb83ed6a01",
96
96
  "apps/native/Cargo.lock": "cf31d67cf167c5f32438abfeb42159eb50da61d36e4e482bae50ed3d71241373",
97
97
  "packages/render-engine/Cargo.lock": "a1a68051e1eea30ef0fa46bf17cd0685bb2c6a327defed0405e0d63dd61017a7"
98
98
  }