@vosjs/cli 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -335,7 +335,7 @@ vos assets ls [--kind <kind>] [--q <text>] [--sort size] | usage | why <id> #
335
335
  vos recipe push <FILE.md> --folder <slug> | --asset <id> # the one recipe write: create, or replace in place
336
336
  ```
337
337
 
338
- `push` is polymorphic by a deterministic sniff, never a flag: a take directory (a `doc.json` carrying `source`) pushes recording and document through the take pipeline; a `config.json` (or a directory holding one) pushes the program, and a `doc.json` beside it that carries `program` (a program document: overlays, objects, audio, speed, tween edits, its own length; `program.config` omitted on disk) rides along, lint-gated. `fetch` and `pull` write a program document back the same way. `pull` takes `--since <versionId>` (walk the changelog from that base instead of the tracked one) and `--check` (print what changed and stop: nothing on disk moves) on both paths. A program push LANDS where `vos.json` says: a directory that tracks a vos iterates it, so the fetch, edit, check, push, pull loop needs no flags, and making something separate from the same config is the explicit `--remix-of` door. Program pushes take `--vos`, `--title`, `--slug`, `--desc`, `--tags`, `--folder`, `--remix-of`, `--base`, `--label`, `--note`, `--override <id>` (repeatable) and `--claimable`; take pushes take `--title`, `--label`, `--note`, `--folder`, `--override`, `--yes` and `--claimable`. Both take `--wait`. A new vos pushed without `--folder` lands unfiled, at the root of the shelf, and the done line says so.
338
+ `push` is polymorphic by a deterministic sniff, never a flag: a take directory (a `doc.json` carrying `source`) pushes recording and document through the take pipeline; a `config.json` (or a directory holding one) pushes the program, and a `doc.json` beside it that carries `program` (a program document: overlays, objects, audio, speed, tween edits, its own length; `program.config` omitted on disk) rides along, lint-gated. `fetch` and `pull` write a program document back the same way. `pull` takes `--since <versionId>` (walk the changelog from that base instead of the tracked one) and `--check` (print what changed and stop: nothing on disk moves) on both paths. A program push LANDS where `vos.json` says: a directory that tracks a vos iterates it, so the fetch, edit, check, push, pull loop needs no flags, and making something separate from the same config is the explicit `--remix-of` door. Program pushes take `--vos`, `--title`, `--slug`, `--desc`, `--tags`, `--folder`, `--remix-of`, `--base`, `--label`, `--note`, `--override <id>` (repeatable) and `--claimable`; take pushes take `--title`, `--label`, `--note`, `--folder`, `--override`, `--yes` and `--claimable`. Both take `--wait`. A new vos pushed without `--folder` lands unfiled, at the root of the shelf, and the done line says so. `--folder` takes a project on your own shelf (its slug or id) or anyone's project by its address, `<handle>/<slug>` as its page on vos.so names it: the server answers where the push lands, CONTINUING that project when the key is its owner's and otherwise STARTING the person's own from it (a private project made once, named after it, with the recipes they may read copied in, never its videos). The push says which.
339
339
 
340
340
  **A program's files are declared, never typed into a function.** `config.json` names each file it uses in `assets` (`"assets": { "logo": { "ref": "./logo.png", "kind": "image" }, "shots": { "ref": ["./shots/1.png", "./shots/2.png"] } }`) and reads `ctx.assets.logo`, or `"$assets.logo"` in an element, object or font. On disk a `ref` is a path in the config's own directory or below, so `vos render`, `vos still` and `vos preview` serve the file to the page from disk. A path that climbs out of that directory (`../`, an absolute path, a link that points away) is not served and not uploaded, and a config loaded from a URL reads no local file: a program's code runs in a page, and what the page is served the program can send anywhere. `vos push` uploads each local file (content-addressed, so a re-push sends nothing: pictures, SVG, video, sound, `.glb` models, fonts and HDR environments) and what it stores names the hosted file as `asset:<id>`, the one spelling the platform resolves for every render; the config on disk keeps its paths. A file an element names as `src` or a font names as `url` is lifted into the manifest on the way (the element then names `"$assets.<name>"`), and a path in `data` that is a file beside the config is uploaded and rewritten to the hosted file's path, so every place a program can name a file crosses. A file typed inside a function cannot be rewritten: `vos push` says so, with the manifest line to write. `vos fetch --media` brings a program's hosted files home under `assets/` and re-points the manifest at them (`assets/.hosted.json` remembers which hosted file each one is, so a later fetch replaces one that changed); without `--media` the manifest keeps `asset:<id>` and a local render reads each file with your key. `vos check` says when a `"$assets.<name>"` names nothing, when a declared path is not a file, and when a function names a hosted file in code instead of the manifest: a file named only in code does not load on a render of a private program and does not follow a remix. A `--claimable` push carries them too, through the claim's own upload session (below).
341
341
 
@@ -6022,6 +6022,38 @@ function resolveFolder(rows, ref) {
6022
6022
  }
6023
6023
  return hit;
6024
6024
  }
6025
+ function projectAddress(ref) {
6026
+ const m = /^@?([A-Za-z0-9_]{1,30})\/([A-Za-z0-9][\w-]{0,99})$/.exec(
6027
+ ref.trim()
6028
+ );
6029
+ return m ? { handle: m[1], slug: m[2].toLowerCase() } : null;
6030
+ }
6031
+ async function resolvePushFolder(origin, key, ref) {
6032
+ const at2 = projectAddress(ref);
6033
+ if (!at2) {
6034
+ return {
6035
+ id: resolveFolder(await listFolders(origin, key), ref).id,
6036
+ note: null
6037
+ };
6038
+ }
6039
+ const r = await apiJson(
6040
+ origin,
6041
+ `/api/folders/public/${encodeURIComponent(at2.handle)}/${encodeURIComponent(at2.slug)}/push-target`,
6042
+ { method: "POST", key }
6043
+ );
6044
+ if (r.status !== 200 && r.status !== 201) {
6045
+ throw new Error(apiError(`find the project ${at2.handle}/${at2.slug}`, r));
6046
+ }
6047
+ const body = r.body;
6048
+ if (!body.folder) {
6049
+ throw new Error(
6050
+ `find the project ${at2.handle}/${at2.slug}: no project in the answer`
6051
+ );
6052
+ }
6053
+ const source = body.source?.name ?? `${at2.handle}/${at2.slug}`;
6054
+ const note = body.target === "continue" ? `continuing ${source}` : body.created ? `starting your own ${source} (${body.folder.slug}), its ${body.recipes ?? 0} recipe${body.recipes === 1 ? "" : "s"} copied in` : `adding to your own ${source} (${body.folder.slug})`;
6055
+ return { id: body.folder.id, note };
6056
+ }
6025
6057
  function printTree(rows) {
6026
6058
  const children = /* @__PURE__ */ new Map();
6027
6059
  for (const f of rows) {
@@ -6404,10 +6436,9 @@ async function pushTake(dir, flags, r) {
6404
6436
  "--folder applies when CREATING a vos \u2014 this take is already pushed; file it with: vos folder move <vosId> --to <folder>"
6405
6437
  );
6406
6438
  }
6407
- folderId = resolveFolder(
6408
- await listFolders(ctx.origin, ctx.key),
6409
- flags.folder
6410
- ).id;
6439
+ const target = await resolvePushFolder(ctx.origin, ctx.key, flags.folder);
6440
+ folderId = target.id;
6441
+ if (target.note) r.log(target.note);
6411
6442
  }
6412
6443
  if (firstPush && !flags.yes) {
6413
6444
  if (!process.stdin.isTTY) {
@@ -7265,7 +7296,7 @@ async function cmdPushProgram(argv) {
7265
7296
  const target = positionals[0];
7266
7297
  if (!target) {
7267
7298
  throw new UsageError(
7268
- 'vos push <config.json|take> [--vos id] [--title t] [--slug s] [--desc d] [--tags a,b] [--folder <id|slug>] [--remix-of id] [--note n] [--label l] [--base versionId] [--override id]... [--prompt "<the prompt that made it>"] [--claimable [--share]]'
7299
+ 'vos push <config.json|take> [--vos id] [--title t] [--slug s] [--desc d] [--tags a,b] [--folder <id|slug|handle/slug>] [--remix-of id] [--note n] [--label l] [--base versionId] [--override id]... [--prompt "<the prompt that made it>"] [--claimable [--share]]'
7269
7300
  );
7270
7301
  }
7271
7302
  const source = resolveConfigPath(target);
@@ -7487,7 +7518,9 @@ ${landedLines(landed2)}` : "")
7487
7518
  const remixOfId = pushTarget.kind === "create" ? pushTarget.remixOfId : void 0;
7488
7519
  const fallbackTitle = state?.title ? `${state.title} remix` : basename3(source).replace(/\.json$/i, "") || "vos remix";
7489
7520
  const title = (strFlag(flags, "title") ?? fallbackTitle).slice(0, 100);
7490
- const folderId = folderRef ? resolveFolder(await listFolders(origin, key), folderRef).id : void 0;
7521
+ const pushFolder = folderRef ? await resolvePushFolder(origin, key, folderRef) : void 0;
7522
+ const folderId = pushFolder?.id;
7523
+ if (pushFolder?.note) r.log(pushFolder.note);
7491
7524
  const created = await createProgramVos({
7492
7525
  origin,
7493
7526
  key,
@@ -7531,6 +7564,7 @@ ${landedLines(landed2)}` : "")
7531
7564
  title,
7532
7565
  visibility: "private",
7533
7566
  folder: folderRef ?? null,
7567
+ ...pushFolder?.note ? { folderNote: pushFolder.note } : {},
7534
7568
  remixOfId: remixOfId ?? null,
7535
7569
  currentVersionId: created.currentVersionId,
7536
7570
  watchUrl,
@@ -7547,7 +7581,7 @@ ${landedLines(landed2)}` : "")
7547
7581
  watch: ${watchUrl}
7548
7582
  studio: ${studioUrl}
7549
7583
  ` + (landed ? `${landedLines(landed)}
7550
- ` : "") + ` shelf: ${folderRef ? `in ${folderRef}` : `unfiled, at the root of your shelf (file it: vos folder move ${created.id} --to <slug>)`}
7584
+ ` : "") + ` shelf: ${folderRef ? `in ${folderRef}${pushFolder?.note ? ` (${pushFolder.note})` : ""}` : `unfiled, at the root of your shelf (file it: vos folder move ${created.id} --to <slug>)`}
7551
7585
  cover: ${typeof programDoc?.still === "number" ? `${String(programDoc.still)}s` : "the platform picks an early frame; choose one with --still <seconds>"}
7552
7586
  ` + (prompt ? ` prompt: shown on the watch page
7553
7587
  ` : ` prompt: none shown; show the one that made it: ${promptHint(source, created.id)}
@@ -14328,4 +14362,4 @@ export {
14328
14362
  verbHelp,
14329
14363
  run
14330
14364
  };
14331
- //# sourceMappingURL=chunk-R4S6V4AC.js.map
14365
+ //# sourceMappingURL=chunk-EYF3WJIC.js.map