@osmo.inc/cli 0.1.18-preview.1 → 0.1.18-preview.2
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/dist/osmo.js +111 -39
- package/package.json +1 -1
- package/release.json +15 -15
- package/studio/src/app.css +1 -1
- package/studio/src/app.js +138 -138
- package/vendor/osmo-lite +0 -0
- package/vendor/platform.json +1 -1
package/dist/osmo.js
CHANGED
|
@@ -404,6 +404,42 @@ var init_comments = __esm({
|
|
|
404
404
|
}
|
|
405
405
|
});
|
|
406
406
|
|
|
407
|
+
// ../studio/src/lib/export-settings.ts
|
|
408
|
+
function validateExportSettings(input, meta) {
|
|
409
|
+
const format2 = input.format ?? "h264";
|
|
410
|
+
const scale = input.scale ?? 1;
|
|
411
|
+
const quality = input.quality ?? "high";
|
|
412
|
+
const startFrame = input.startFrame ?? 0;
|
|
413
|
+
const endFrame = input.endFrame ?? meta.totalFrames - 1;
|
|
414
|
+
if (format2 !== "h264" && format2 !== "vp8" && format2 !== "prores")
|
|
415
|
+
throw new Error("Choose a supported export format");
|
|
416
|
+
if (typeof scale !== "number" || !exportScales.some((value) => value === scale))
|
|
417
|
+
throw new Error("Output scale must be 1, 1.5, 2 or 3");
|
|
418
|
+
if (quality !== "medium" && quality !== "high" && quality !== "max")
|
|
419
|
+
throw new Error("Choose a supported quality");
|
|
420
|
+
if (typeof startFrame !== "number" || typeof endFrame !== "number" || !Number.isInteger(startFrame) || !Number.isInteger(endFrame) || startFrame < 0 || endFrame < startFrame || endFrame >= meta.totalFrames)
|
|
421
|
+
throw new Error(
|
|
422
|
+
`Choose a frame range between 0 and ${meta.totalFrames - 1}`
|
|
423
|
+
);
|
|
424
|
+
return { format: format2, scale, quality, startFrame, endFrame };
|
|
425
|
+
}
|
|
426
|
+
var exportFormats, exportScales;
|
|
427
|
+
var init_export_settings = __esm({
|
|
428
|
+
"../studio/src/lib/export-settings.ts"() {
|
|
429
|
+
"use strict";
|
|
430
|
+
exportFormats = {
|
|
431
|
+
h264: { label: "MP4 (H.264)", extension: "mp4", mime: "video/mp4" },
|
|
432
|
+
vp8: { label: "WebM (VP8)", extension: "webm", mime: "video/webm" },
|
|
433
|
+
prores: {
|
|
434
|
+
label: "ProRes 4444 (MOV)",
|
|
435
|
+
extension: "mov",
|
|
436
|
+
mime: "video/quicktime"
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
exportScales = [1, 1.5, 2, 3];
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
|
|
407
443
|
// src/worker.ts
|
|
408
444
|
import { spawn as spawn2 } from "node:child_process";
|
|
409
445
|
var Renderer;
|
|
@@ -1551,7 +1587,7 @@ async function listProjectResources(root) {
|
|
|
1551
1587
|
throw new Error("Manifest exceeds 1 MB");
|
|
1552
1588
|
const meta = JSON.parse(await fs4.readFile(manifestFile, "utf8"));
|
|
1553
1589
|
const entry = `resources/${item.name}/${meta.entry}`, file = await resourceFile(root, entry);
|
|
1554
|
-
const kind = meta.kind ?? meta.category ?? kinds[path15.extname(file).toLowerCase()];
|
|
1590
|
+
const kind = meta.kind ?? (meta.category === "3d" ? "model" : meta.category) ?? kinds[path15.extname(file).toLowerCase()];
|
|
1555
1591
|
if (!["shader", "image", "video", "model", "scene"].includes(kind) || kinds[path15.extname(file).toLowerCase()] !== kind)
|
|
1556
1592
|
throw new Error("Unsupported resource type");
|
|
1557
1593
|
let effect;
|
|
@@ -2762,12 +2798,12 @@ function applyTimelineCommand(text2, command, {
|
|
|
2762
2798
|
let tag = existing?.importClause.name.text;
|
|
2763
2799
|
if (!tag) {
|
|
2764
2800
|
let n = 1;
|
|
2765
|
-
const
|
|
2801
|
+
const names = new Set(
|
|
2766
2802
|
[...text2.matchAll(/\b[A-Za-z_$][\w$]*\b/g)].map((m) => m[0])
|
|
2767
2803
|
);
|
|
2768
2804
|
do {
|
|
2769
2805
|
tag = `Animation${n++}`;
|
|
2770
|
-
} while (
|
|
2806
|
+
} while (names.has(tag));
|
|
2771
2807
|
}
|
|
2772
2808
|
id = fresh();
|
|
2773
2809
|
const element = `<${tag} id={${JSON.stringify(id)}} track={${track}} start={${start}} duration={${duration}} width={${card.width}} height={${card.height}}${Object.keys(card.values).length ? ` values={${JSON.stringify(card.values)}}` : ""} />`;
|
|
@@ -2874,8 +2910,8 @@ var init_timeline = __esm({
|
|
|
2874
2910
|
}
|
|
2875
2911
|
}
|
|
2876
2912
|
};
|
|
2877
|
-
pick = (
|
|
2878
|
-
|
|
2913
|
+
pick = (names, extras = {}) => Object.fromEntries(
|
|
2914
|
+
names.map((name) => [name, propertySpecs[name]]).concat(Object.entries(extras))
|
|
2879
2915
|
);
|
|
2880
2916
|
transformNames = [
|
|
2881
2917
|
"position",
|
|
@@ -2908,7 +2944,7 @@ var init_timeline = __esm({
|
|
|
2908
2944
|
|
|
2909
2945
|
// ../editor/src/resource-source.ts
|
|
2910
2946
|
import ts9 from "typescript";
|
|
2911
|
-
function addImports(text2,
|
|
2947
|
+
function addImports(text2, names, declaration = "") {
|
|
2912
2948
|
const ast = ts9.createSourceFile(
|
|
2913
2949
|
"scene.tsx",
|
|
2914
2950
|
text2,
|
|
@@ -2921,7 +2957,7 @@ function addImports(text2, names2, declaration = "") {
|
|
|
2921
2957
|
);
|
|
2922
2958
|
const bindings = existing?.importClause?.namedBindings;
|
|
2923
2959
|
if (bindings && ts9.isNamedImports(bindings)) {
|
|
2924
|
-
const missing =
|
|
2960
|
+
const missing = names.filter(
|
|
2925
2961
|
(name) => !bindings.elements.some((e) => e.name.text === name)
|
|
2926
2962
|
);
|
|
2927
2963
|
if (missing.length)
|
|
@@ -2932,7 +2968,7 @@ function addImports(text2, names2, declaration = "") {
|
|
|
2932
2968
|
text: `${bindings.elements.length ? ", " : ""}${missing.join(", ")} `
|
|
2933
2969
|
}
|
|
2934
2970
|
]);
|
|
2935
|
-
} else text2 = `import {${
|
|
2971
|
+
} else text2 = `import {${names.join(", ")}} from '@osmo/scene';
|
|
2936
2972
|
${text2}`;
|
|
2937
2973
|
if (declaration) {
|
|
2938
2974
|
const next = ts9.createSourceFile(
|
|
@@ -3059,11 +3095,11 @@ ${text2}`;
|
|
|
3059
3095
|
text2 = addImports(text2, [plan.tag]);
|
|
3060
3096
|
} else {
|
|
3061
3097
|
const effect = plan.resource.effect;
|
|
3062
|
-
const
|
|
3098
|
+
const names = new Set(
|
|
3063
3099
|
[...text2.matchAll(/\b[A-Za-z_$][\w$]*\b/g)].map((m) => m[0])
|
|
3064
3100
|
);
|
|
3065
3101
|
let name = "resourceEffect", i = 1;
|
|
3066
|
-
while (
|
|
3102
|
+
while (names.has(name)) name = `resourceEffect${i++}`;
|
|
3067
3103
|
const attrs = attributes2(node), attr = attrs.get("effects"), array = unwrap2(attr?.initializer);
|
|
3068
3104
|
const call2 = `${name}(${JSON.stringify(effect.values ?? {})})`;
|
|
3069
3105
|
if (attr) {
|
|
@@ -3700,7 +3736,7 @@ import http from "node:http";
|
|
|
3700
3736
|
import fs6 from "node:fs";
|
|
3701
3737
|
import { readFile as readFile11, stat as stat3, realpath as realpath2, readdir as readdir3 } from "node:fs/promises";
|
|
3702
3738
|
import path19 from "node:path";
|
|
3703
|
-
import { createHash as createHash8 } from "node:crypto";
|
|
3739
|
+
import { createHash as createHash8, randomUUID as randomUUID7 } from "node:crypto";
|
|
3704
3740
|
import { spawn as spawn3 } from "node:child_process";
|
|
3705
3741
|
async function revision(paths) {
|
|
3706
3742
|
const hash3 = createHash8("sha256");
|
|
@@ -4383,9 +4419,12 @@ async function startStudio({
|
|
|
4383
4419
|
{ status: 409 }
|
|
4384
4420
|
);
|
|
4385
4421
|
const snapshot = project;
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4422
|
+
if (!state.meta) throw new Error("Load a scene before exporting");
|
|
4423
|
+
const settings2 = validateExportSettings(input, state.meta);
|
|
4424
|
+
const format2 = exportFormats[settings2.format];
|
|
4425
|
+
const filename2 = input.filename ?? `${path19.basename(scene, ".tsx")}-${Date.now()}.${format2.extension}`;
|
|
4426
|
+
if (typeof filename2 !== "string" || !/^[\w .-]+$/.test(filename2) || !filename2.toLowerCase().endsWith(`.${format2.extension}`) || filename2.startsWith("."))
|
|
4427
|
+
throw new Error(`Use a filename ending in .${format2.extension}`);
|
|
4389
4428
|
const folder = path19.join(root, "exports");
|
|
4390
4429
|
await fs6.promises.mkdir(folder, { recursive: true });
|
|
4391
4430
|
const canonicalFolder = await realpath2(folder);
|
|
@@ -4398,6 +4437,7 @@ async function startStudio({
|
|
|
4398
4437
|
{ status: 409 }
|
|
4399
4438
|
);
|
|
4400
4439
|
const job = state.export = {
|
|
4440
|
+
id: randomUUID7(),
|
|
4401
4441
|
status: "rendering",
|
|
4402
4442
|
phase: "preparing",
|
|
4403
4443
|
filename: filename2,
|
|
@@ -4422,7 +4462,7 @@ async function startStudio({
|
|
|
4422
4462
|
job.phase = "rendering";
|
|
4423
4463
|
await worker.request(
|
|
4424
4464
|
"export",
|
|
4425
|
-
{ destination, supersample: 2 },
|
|
4465
|
+
{ destination, supersample: 2, settings: settings2 },
|
|
4426
4466
|
({ done, total }) => {
|
|
4427
4467
|
job.progress = done / total;
|
|
4428
4468
|
}
|
|
@@ -4443,10 +4483,10 @@ async function startStudio({
|
|
|
4443
4483
|
exportStarting = false;
|
|
4444
4484
|
}
|
|
4445
4485
|
}
|
|
4446
|
-
if (req.method === "GET" && url2.pathname === "/api/export/download" && state.export?.status === "complete") {
|
|
4486
|
+
if (req.method === "GET" && url2.pathname === "/api/export/download" && state.export?.status === "complete" && (!url2.searchParams.has("id") || url2.searchParams.get("id") === state.export.id)) {
|
|
4447
4487
|
const bytes3 = await readFile11(state.export.path);
|
|
4448
4488
|
res.writeHead(200, {
|
|
4449
|
-
"Content-Type": "video/mp4",
|
|
4489
|
+
"Content-Type": state.export.filename.toLowerCase().endsWith(".webm") ? "video/webm" : state.export.filename.toLowerCase().endsWith(".mov") ? "video/quicktime" : "video/mp4",
|
|
4450
4490
|
"Content-Disposition": `attachment; filename="${state.export.filename}"`
|
|
4451
4491
|
});
|
|
4452
4492
|
return res.end(bytes3);
|
|
@@ -4645,6 +4685,7 @@ var studioStamp, studioDigest;
|
|
|
4645
4685
|
var init_server = __esm({
|
|
4646
4686
|
"src/server.ts"() {
|
|
4647
4687
|
"use strict";
|
|
4688
|
+
init_export_settings();
|
|
4648
4689
|
init_storyboard2();
|
|
4649
4690
|
init_timeline_editor();
|
|
4650
4691
|
init_project_resources();
|
|
@@ -5363,10 +5404,12 @@ var COST = {
|
|
|
5363
5404
|
image: "is the same for each image",
|
|
5364
5405
|
character: "grows with characters of text"
|
|
5365
5406
|
};
|
|
5366
|
-
var
|
|
5407
|
+
var packageFiles = (primitive) => primitive === "Model" ? ["model.glb", "resource.json"] : ["resource.json", "shader.d.ts", "shader.wgsl"];
|
|
5367
5408
|
var LOCK = ".osmo-get.lock";
|
|
5368
5409
|
var maxFile = 1024 * 1024;
|
|
5369
5410
|
var maxResponse = 4 * maxFile;
|
|
5411
|
+
var maxModel = 64 * maxFile;
|
|
5412
|
+
var fileLimit = (name) => name.endsWith(".glb") ? maxModel : maxFile;
|
|
5370
5413
|
var ownerPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
5371
5414
|
var namePattern = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
|
|
5372
5415
|
var versionPattern = /^\d+\.\d+\.\d+$/;
|
|
@@ -5418,7 +5461,7 @@ async function bytes(response, limit = maxResponse) {
|
|
|
5418
5461
|
}
|
|
5419
5462
|
return Buffer.concat(chunks);
|
|
5420
5463
|
}
|
|
5421
|
-
async function responseBody(response, json2 = true) {
|
|
5464
|
+
async function responseBody(response, json2 = true, limit) {
|
|
5422
5465
|
if (!response.ok) {
|
|
5423
5466
|
const body3 = await response.json().catch(() => ({}));
|
|
5424
5467
|
if (response.status === 401)
|
|
@@ -5444,7 +5487,7 @@ async function responseBody(response, json2 = true) {
|
|
|
5444
5487
|
`Osmo resource request failed (${response.status}). Retry later.`
|
|
5445
5488
|
);
|
|
5446
5489
|
}
|
|
5447
|
-
const body2 = await bytes(response);
|
|
5490
|
+
const body2 = await bytes(response, limit);
|
|
5448
5491
|
if (!json2) return body2;
|
|
5449
5492
|
try {
|
|
5450
5493
|
return JSON.parse(String(body2));
|
|
@@ -5472,12 +5515,12 @@ function validItem(item) {
|
|
|
5472
5515
|
return !!item && text(item.id) && text(item.title) && typeof item.summary === "string" && (item.use === "run" || item.use === "get") && text(item.kind) && strings(item.tags) && (item.tasks === void 0 || strings(item.tasks));
|
|
5473
5516
|
}
|
|
5474
5517
|
function compatibility(pkg) {
|
|
5475
|
-
const supported = pkg.primitive === "Shader" && pkg.compatibility?.scene === sceneVersion;
|
|
5518
|
+
const supported = (pkg.primitive === "Shader" || pkg.primitive === "Model") && pkg.compatibility?.scene === sceneVersion;
|
|
5476
5519
|
return {
|
|
5477
5520
|
supported,
|
|
5478
5521
|
scene: pkg.compatibility?.scene,
|
|
5479
5522
|
cliVersion: version,
|
|
5480
|
-
note: supported ? "Supported by this CLI
|
|
5523
|
+
note: !supported ? "This CLI cannot use this resource. Update the CLI before downloading it." : pkg.primitive === "Model" ? "Supported by this CLI: the Model primitive renders it, with scene content on its surfaces." : "Supported by this CLI in Strict mode using Shader.src and explicit uniforms."
|
|
5481
5524
|
};
|
|
5482
5525
|
}
|
|
5483
5526
|
async function catalogDetail(ref) {
|
|
@@ -5496,7 +5539,9 @@ async function catalogDetail(ref) {
|
|
|
5496
5539
|
const pkg = entry.package;
|
|
5497
5540
|
if (!pkg || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(pkg.folder ?? "") || !versionPattern.test(pkg.version ?? "") || ref.version && pkg.version !== ref.version || !Array.isArray(pkg.presets) || !pkg.presets.length || !pkg.presets.every((p) => text(p.id) && text(p.title)) || !pkg.presets.some((p) => p.id === pkg.defaultPreset) || !Array.isArray(pkg.previews) || !pkg.previews.every(
|
|
5498
5541
|
(p) => text(p.url) && ["image", "video"].includes(p.type)
|
|
5499
|
-
))
|
|
5542
|
+
) || pkg.primitive === "Model" && !(Array.isArray(pkg.surfaces) && pkg.surfaces.every(
|
|
5543
|
+
(s) => text(s.id) && text(s.title) && strings(s.nodes) && Number.isInteger(s.width) && Number.isInteger(s.height)
|
|
5544
|
+
) && Array.isArray(pkg.animations) && pkg.animations.every((a) => text(a.name))))
|
|
5500
5545
|
invalid();
|
|
5501
5546
|
return entry;
|
|
5502
5547
|
}
|
|
@@ -5541,18 +5586,23 @@ async function show(ref) {
|
|
|
5541
5586
|
next: `osmo resources get ${detail.id}${ref.version ? `@${ref.version}` : ""}`
|
|
5542
5587
|
};
|
|
5543
5588
|
}
|
|
5544
|
-
function
|
|
5589
|
+
function checkFiles(pkg) {
|
|
5590
|
+
const names = packageFiles(pkg.primitive);
|
|
5545
5591
|
if (!Array.isArray(pkg.files) || pkg.files.length !== names.length || [...pkg.files.map((f) => f.path)].sort().join(",") !== names.join(","))
|
|
5546
5592
|
invalid();
|
|
5547
5593
|
for (const file of pkg.files)
|
|
5548
|
-
if (!Number.isInteger(file.bytes) || file.bytes < 1 || file.bytes >
|
|
5594
|
+
if (!Number.isInteger(file.bytes) || file.bytes < 1 || file.bytes > fileLimit(file.path) || !/^[a-f0-9]{64}$/.test(file.sha256 ?? ""))
|
|
5549
5595
|
invalid();
|
|
5596
|
+
return names;
|
|
5597
|
+
}
|
|
5598
|
+
function unpack(zip, pkg) {
|
|
5599
|
+
const names = checkFiles(pkg);
|
|
5550
5600
|
const prefix = `resources/${pkg.folder}/`, seen = /* @__PURE__ */ new Set();
|
|
5551
5601
|
let extracted;
|
|
5552
5602
|
try {
|
|
5553
5603
|
extracted = unzipSync(zip, {
|
|
5554
5604
|
filter: (file) => {
|
|
5555
|
-
if (!names.some((name) => file.name === prefix + name) || seen.has(file.name) || file.originalSize >
|
|
5605
|
+
if (!names.some((name) => file.name === prefix + name) || seen.has(file.name) || file.originalSize > fileLimit(file.name))
|
|
5556
5606
|
invalid();
|
|
5557
5607
|
seen.add(file.name);
|
|
5558
5608
|
return true;
|
|
@@ -5578,9 +5628,9 @@ function unpack(zip, pkg) {
|
|
|
5578
5628
|
} catch {
|
|
5579
5629
|
invalid();
|
|
5580
5630
|
}
|
|
5581
|
-
if (manifest2.id !== pkg.folder || manifest2.version !== pkg.version || manifest2.entry !== "
|
|
5631
|
+
if (manifest2.id !== pkg.folder || manifest2.version !== pkg.version || manifest2.primitive !== pkg.primitive || (pkg.primitive === "Model" ? manifest2.entry !== "model.glb" : manifest2.entry !== "shader.wgsl" || manifest2.types !== "shader.d.ts") || !Array.isArray(manifest2.presets) || !manifest2.presets.some((p) => p.id === pkg.defaultPreset) || !manifest2.presets.every((p) => text(manifest2.usage?.[p.id])))
|
|
5582
5632
|
invalid();
|
|
5583
|
-
return { files, manifest: manifest2 };
|
|
5633
|
+
return { files, manifest: manifest2, names };
|
|
5584
5634
|
}
|
|
5585
5635
|
async function stat(file) {
|
|
5586
5636
|
try {
|
|
@@ -5590,7 +5640,7 @@ async function stat(file) {
|
|
|
5590
5640
|
throw error;
|
|
5591
5641
|
}
|
|
5592
5642
|
}
|
|
5593
|
-
async function save(destination, shown, files) {
|
|
5643
|
+
async function save(destination, shown, files, names) {
|
|
5594
5644
|
const parent = path3.dirname(destination), base = path3.basename(destination);
|
|
5595
5645
|
const inside2 = (await stat(destination))?.isDirectory() ?? false;
|
|
5596
5646
|
if (!inside2) await mkdir2(parent, { recursive: true });
|
|
@@ -5676,14 +5726,17 @@ async function get(ref, flags) {
|
|
|
5676
5726
|
const compat = compatibility(pkg);
|
|
5677
5727
|
if (!compat.supported) fail("incompatible_resource", compat.note);
|
|
5678
5728
|
const destination = path3.resolve(flags.out ?? pkg.folder);
|
|
5729
|
+
checkFiles(pkg);
|
|
5730
|
+
const declared = pkg.files.reduce((sum, file) => sum + file.bytes, 0);
|
|
5679
5731
|
const zip = await responseBody(
|
|
5680
5732
|
await authenticatedGet(
|
|
5681
5733
|
`/api/resources/${ref.owner}/${ref.name}/versions/${pkg.version}/download`
|
|
5682
5734
|
),
|
|
5683
|
-
false
|
|
5735
|
+
false,
|
|
5736
|
+
Math.max(maxResponse, declared + maxFile)
|
|
5684
5737
|
);
|
|
5685
|
-
const { files, manifest: manifest2 } = unpack(zip, pkg);
|
|
5686
|
-
const status = await save(destination, flags.out ?? pkg.folder, files);
|
|
5738
|
+
const { files, manifest: manifest2, names } = unpack(zip, pkg);
|
|
5739
|
+
const status = await save(destination, flags.out ?? pkg.folder, files, names);
|
|
5687
5740
|
const relative = path3.relative(await realpath(process.cwd()), await realpath(destination)).split(path3.sep).join("/");
|
|
5688
5741
|
const folder = relative === "" ? "." : relative;
|
|
5689
5742
|
const src = path3.isAbsolute(folder) || folder.startsWith("../") || folder === "." ? folder : `./${folder}`;
|
|
@@ -5705,9 +5758,10 @@ async function get(ref, flags) {
|
|
|
5705
5758
|
)
|
|
5706
5759
|
])
|
|
5707
5760
|
),
|
|
5761
|
+
...pkg.primitive === "Model" ? { surfaces: pkg.surfaces, animations: pkg.animations } : {},
|
|
5708
5762
|
notes: manifest2.notes,
|
|
5709
5763
|
compatibility: compat,
|
|
5710
|
-
next: `Read ${folder}/shader.d.ts for what each uniform does, then use a usage snippet.`
|
|
5764
|
+
next: pkg.primitive === "Model" ? "Use a usage snippet, and put your scene content inside its Surface." : `Read ${folder}/shader.d.ts for what each uniform does, then use a usage snippet.`
|
|
5711
5765
|
};
|
|
5712
5766
|
}
|
|
5713
5767
|
async function resourcesCommand(verb, args, flags = {}) {
|
|
@@ -5777,7 +5831,7 @@ function formatResources(result) {
|
|
|
5777
5831
|
if ("usage" in r) {
|
|
5778
5832
|
const usage = Object.entries(r.usage).map(
|
|
5779
5833
|
([preset, snippet]) => `${preset}:
|
|
5780
|
-
${snippet}`
|
|
5834
|
+
${snippet.replaceAll("\n", "\n ")}`
|
|
5781
5835
|
);
|
|
5782
5836
|
return [
|
|
5783
5837
|
`${r.id}@${r.version} ${r.status === "downloaded" ? "downloaded to" : "is already in"} ${r.folder}/`,
|
|
@@ -5816,10 +5870,28 @@ function formatResources(result) {
|
|
|
5816
5870
|
return lines.join("\n");
|
|
5817
5871
|
}
|
|
5818
5872
|
const pkg = r.package;
|
|
5873
|
+
if (pkg.surfaces?.length)
|
|
5874
|
+
lines.push(
|
|
5875
|
+
"Surfaces (scene content goes here):",
|
|
5876
|
+
table(
|
|
5877
|
+
pkg.surfaces.map((s) => [
|
|
5878
|
+
` ${s.id}`,
|
|
5879
|
+
`${s.width} x ${s.height}`,
|
|
5880
|
+
s.inset ? `${s.description} Keep text clear of ${s.inset.top} px at the top, ${s.inset.bottom} at the bottom, ${s.inset.left} at the left, ${s.inset.right} at the right.` : s.description
|
|
5881
|
+
])
|
|
5882
|
+
),
|
|
5883
|
+
""
|
|
5884
|
+
);
|
|
5885
|
+
if (pkg.animations?.length)
|
|
5886
|
+
lines.push(
|
|
5887
|
+
"Animations (each takes 0 to 1):",
|
|
5888
|
+
table(pkg.animations.map((a) => [` ${a.name}`, a.description])),
|
|
5889
|
+
""
|
|
5890
|
+
);
|
|
5819
5891
|
lines.push(
|
|
5820
5892
|
`Presets: ${pkg.presets.map((p) => p.id === pkg.defaultPreset ? `${p.id} (default)` : p.id).join(", ")}`,
|
|
5821
5893
|
...pkg.previews.map((p) => `${p.caption ?? p.type}: ${p.url}`),
|
|
5822
|
-
pkg.pageUrl,
|
|
5894
|
+
...pkg.pageUrl ? [pkg.pageUrl] : [],
|
|
5823
5895
|
r.compatibility?.note ?? "",
|
|
5824
5896
|
"",
|
|
5825
5897
|
`Next: ${r.next}`
|
|
@@ -8476,7 +8548,7 @@ them like any other asset.
|
|
|
8476
8548
|
| Vector curves, icons, cutouts or illustrations | Path with SVG d, fill and stroke; evenodd for holes |
|
|
8477
8549
|
| Images, footage, soundtrack | Image, Video, Audio with local asset paths |
|
|
8478
8550
|
| Parallax and solid cards | Camera, z and Group.depth |
|
|
8479
|
-
| Content on a 3D model |
|
|
8551
|
+
| Content on a 3D model | osmo resources list --type 3d; a usage snippet names its surfaces. Own GLBs: inspect selectors first |
|
|
8480
8552
|
| Procedural backgrounds or liquid glass | Check resources; Shader with local src and explicit uniforms; glass samples backdrop |
|
|
8481
8553
|
| Softness or texture | effects={[blur({ radius: 5 }), grain({ amount: 0.04 })]} |
|
|
8482
8554
|
|
|
@@ -9497,10 +9569,10 @@ function commandHelp(command) {
|
|
|
9497
9569
|
const flags = Object.entries({ ...command.flags, ...GLOBAL_FLAGS }).filter(
|
|
9498
9570
|
([, flag]) => !flag.hidden
|
|
9499
9571
|
);
|
|
9500
|
-
const
|
|
9572
|
+
const names = flags.map(
|
|
9501
9573
|
([name, flag]) => `--${name}${flag.value ? ` ${flag.value}` : ""}`
|
|
9502
9574
|
);
|
|
9503
|
-
const width = Math.max(...
|
|
9575
|
+
const width = Math.max(...names.map((name) => name.length));
|
|
9504
9576
|
const aliases = (command.aliases ?? []).map(
|
|
9505
9577
|
(path22) => `osmo ${path22.join(" ")}`
|
|
9506
9578
|
);
|
|
@@ -9510,7 +9582,7 @@ function commandHelp(command) {
|
|
|
9510
9582
|
typeof command.about === "function" ? command.about() : command.about,
|
|
9511
9583
|
...aliases.length ? ["", `Also: ${aliases.join(", ")}`] : [],
|
|
9512
9584
|
"",
|
|
9513
|
-
...flags.map(([, flag], i) => ` ${
|
|
9585
|
+
...flags.map(([, flag], i) => ` ${names[i].padEnd(width)} ${flag.help}`),
|
|
9514
9586
|
...command.example ? ["", "Example:", ` ${command.example}`] : []
|
|
9515
9587
|
].join("\n");
|
|
9516
9588
|
}
|
package/package.json
CHANGED
package/release.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.18-preview.
|
|
2
|
+
"version": "0.1.18-preview.2",
|
|
3
3
|
"platform": "darwin-arm64",
|
|
4
4
|
"channel": "preview",
|
|
5
5
|
"defaultCloudOrigin": "https://studio.osmo.inc",
|
|
6
|
-
"sourceCommit": "
|
|
6
|
+
"sourceCommit": "6ebe16917fb110278936b537afa7e8c25482dbd3",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"signing": "ad-hoc",
|
|
9
9
|
"licenseFileIncluded": false,
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"contents": {
|
|
19
|
-
"totalBytes":
|
|
19
|
+
"totalBytes": 59229777,
|
|
20
20
|
"fileCount": 947,
|
|
21
21
|
"groups": {
|
|
22
|
-
"vendor":
|
|
23
|
-
"studio":
|
|
22
|
+
"vendor": 17015285,
|
|
23
|
+
"studio": 15991440,
|
|
24
24
|
"node_modules/@esbuild/darwin-arm64": 10385745,
|
|
25
25
|
"node_modules/typescript": 9913238,
|
|
26
26
|
"third-party": 4800129,
|
|
27
27
|
"src": 375601,
|
|
28
|
-
"dist":
|
|
28
|
+
"dist": 362102,
|
|
29
29
|
"node_modules/esbuild": 143795,
|
|
30
30
|
"runtime": 137478,
|
|
31
31
|
"node_modules/fflate": 96377,
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"largestFiles": [
|
|
40
40
|
{
|
|
41
41
|
"path": "vendor/osmo-lite",
|
|
42
|
-
"bytes":
|
|
42
|
+
"bytes": 16979520
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"path": "studio/src/engine_bg.wasm",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"path": "studio/src/app.js",
|
|
58
|
-
"bytes":
|
|
58
|
+
"bytes": 4694683
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"path": "node_modules/typescript/lib/lib.dom.d.ts",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"path": "dist/osmo.js",
|
|
74
|
-
"bytes":
|
|
74
|
+
"bytes": 362102
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
77
|
"path": "third-party/rust-standard-library/COPYRIGHT-library.html",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
"path": "studio/src/app.css",
|
|
114
|
-
"bytes":
|
|
114
|
+
"bytes": 87341
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
117
|
"path": "third-party/npm/mediabunny@1.52.2/source/src/media-sink.ts",
|
|
@@ -120,15 +120,15 @@
|
|
|
120
120
|
]
|
|
121
121
|
},
|
|
122
122
|
"hashes": {
|
|
123
|
-
"dist/osmo.js": "
|
|
124
|
-
"vendor/osmo-lite": "
|
|
123
|
+
"dist/osmo.js": "0deba9fd346683e2e03a3c90060c91643fcda0a86ac6ef091489e05c88af2d89",
|
|
124
|
+
"vendor/osmo-lite": "d5ea0634df51a6ed0bfbb07ee1ae261eb1dce75745c31837f3ce810eb847f11d",
|
|
125
125
|
"studio/src/engine_bg.wasm": "2077f7d96e556bfd35a34fc6ed2efaf0b1dddb98e2d48e9b373a8fe0a8e3d681",
|
|
126
|
-
"studio/src/app.js": "
|
|
127
|
-
"studio/src/app.css": "
|
|
126
|
+
"studio/src/app.js": "6171912dcd36886bb75edd7eed412e7775bb727b8d09f62e2fe0104da5f64082",
|
|
127
|
+
"studio/src/app.css": "ac8d0d5c169da134d2ad7457aab63b10e0fcd4dbb3668406b33ed7dea05469d7",
|
|
128
128
|
"third-party/inventory.json": "6ff4e90c6583a67ca8bfe95b3f4399cfcdc080d39585dce1314a8dd91ee6fecb"
|
|
129
129
|
},
|
|
130
130
|
"lockfiles": {
|
|
131
|
-
"package-lock.json": "
|
|
131
|
+
"package-lock.json": "0f47b7cbe9ca6d998f74ec04ac5a33c507099035f89e3bd63b26eb39e532b652",
|
|
132
132
|
"apps/native/Cargo.lock": "cf31d67cf167c5f32438abfeb42159eb50da61d36e4e482bae50ed3d71241373",
|
|
133
133
|
"packages/render-engine/Cargo.lock": "a1a68051e1eea30ef0fa46bf17cd0685bb2c6a327defed0405e0d63dd61017a7"
|
|
134
134
|
}
|