@vosjs/cli 0.58.0 → 0.59.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 +5 -2
- package/dist/{chunk-K6PE735V.js → chunk-67L7FPJR.js} +489 -119
- package/dist/chunk-67L7FPJR.js.map +1 -0
- package/dist/{chunk-IH5JJBIB.js → chunk-YC3LY4LW.js} +4 -2
- package/dist/chunk-YC3LY4LW.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{run-O747IZNO.js → run-RJEBQFID.js} +3 -3
- package/package.json +6 -6
- package/schema/doc.schema.json +6 -0
- package/dist/chunk-IH5JJBIB.js.map +0 -1
- package/dist/chunk-K6PE735V.js.map +0 -1
- /package/dist/{run-O747IZNO.js.map → run-RJEBQFID.js.map} +0 -0
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
videoFormat,
|
|
37
37
|
writeCredential,
|
|
38
38
|
writeSyncState
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-YC3LY4LW.js";
|
|
40
40
|
import {
|
|
41
41
|
deadLine,
|
|
42
42
|
deadWarns
|
|
@@ -185,6 +185,37 @@ import {
|
|
|
185
185
|
unionFitLevel
|
|
186
186
|
} from "@vosjs/studio-core";
|
|
187
187
|
import { TYPEFACE_CATALOG, findFontFamily, findTypeface } from "@vosjs/shared";
|
|
188
|
+
var PIN_NEAR_FRACTION = 0.08;
|
|
189
|
+
var PIN_SURFACE_AREA = 0.25;
|
|
190
|
+
var LABEL_STOPWORDS = /* @__PURE__ */ new Set([
|
|
191
|
+
"the",
|
|
192
|
+
"and",
|
|
193
|
+
"for",
|
|
194
|
+
"with",
|
|
195
|
+
"your",
|
|
196
|
+
"you",
|
|
197
|
+
"this",
|
|
198
|
+
"that",
|
|
199
|
+
"from",
|
|
200
|
+
"into",
|
|
201
|
+
"button",
|
|
202
|
+
"link"
|
|
203
|
+
]);
|
|
204
|
+
function wordsOf(text) {
|
|
205
|
+
return text.toLowerCase().split(/[^a-z0-9]+/).filter((x) => x.length >= 3 && !LABEL_STOPWORDS.has(x));
|
|
206
|
+
}
|
|
207
|
+
function layerWords(o) {
|
|
208
|
+
const src = typeof o.html === "string" ? o.html.replace(/<[^>]*>/g, " ") : typeof o.text === "string" ? o.text : "";
|
|
209
|
+
return new Set(wordsOf(src));
|
|
210
|
+
}
|
|
211
|
+
function selectorLabelWords(selector) {
|
|
212
|
+
const out = [];
|
|
213
|
+
const re = /(?:has-text\(|text=|(?:aria-label|title|alt|placeholder|name)\s*[*^$~|]?=\s*)['"]([^'"]+)['"]/g;
|
|
214
|
+
for (let m = re.exec(selector); m; m = re.exec(selector)) {
|
|
215
|
+
out.push(...wordsOf(m[1]));
|
|
216
|
+
}
|
|
217
|
+
return [...new Set(out)];
|
|
218
|
+
}
|
|
188
219
|
var STEP_KINDS_ALL = [
|
|
189
220
|
"none",
|
|
190
221
|
"fade",
|
|
@@ -248,6 +279,20 @@ function lintAnim(name, anim, kinds, problems) {
|
|
|
248
279
|
if (key === "stagger" && (typeof obj.stagger !== "number" || obj.stagger < 0 || obj.stagger > 2))
|
|
249
280
|
problems.push(`${name}.anim.${side}.stagger must be seconds in 0..2`);
|
|
250
281
|
}
|
|
282
|
+
if (obj.at !== void 0) {
|
|
283
|
+
if (!kinds.card || side !== "enter")
|
|
284
|
+
problems.push(
|
|
285
|
+
`${name}.anim.${side}.at is the card's own: frame.anim.enter.at delays the card's entrance; a clip already starts at its own start`
|
|
286
|
+
);
|
|
287
|
+
else if (typeof obj.at !== "number" || !Number.isFinite(obj.at) || obj.at < 0 || obj.at > 30)
|
|
288
|
+
problems.push(
|
|
289
|
+
`${name}.anim.enter.at must be OUTPUT seconds in 0..30 (when the card arrives; the ground plays alone until then)`
|
|
290
|
+
);
|
|
291
|
+
else if (kind === "none")
|
|
292
|
+
problems.push(
|
|
293
|
+
`${name}.anim.enter.at has nothing to delay: the enter is "none", so the card is on screen from the first frame`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
251
296
|
if (obj.side !== void 0) {
|
|
252
297
|
if (kind !== "slide")
|
|
253
298
|
problems.push(`${name}.anim.${side}.side is for a slide`);
|
|
@@ -599,6 +644,7 @@ function lintDoc(docIn) {
|
|
|
599
644
|
}
|
|
600
645
|
const tilt = entries(doc.tilt);
|
|
601
646
|
checkByMedia(tilt, "tilt");
|
|
647
|
+
const dramatic = [];
|
|
602
648
|
for (const t of tilt) {
|
|
603
649
|
const name = spanName("tilt", t);
|
|
604
650
|
for (const ax of ["rx", "ry"]) {
|
|
@@ -611,8 +657,8 @@ function lintDoc(docIn) {
|
|
|
611
657
|
}
|
|
612
658
|
checkTransition(t, name, problems);
|
|
613
659
|
if (isNum(t.rx) && isNum(t.ry) && Math.abs(t.rx) + Math.abs(t.ry) > 25) {
|
|
614
|
-
|
|
615
|
-
`${name}
|
|
660
|
+
dramatic.push(
|
|
661
|
+
`${name} ${(Math.abs(t.rx) + Math.abs(t.ry)).toFixed(0)}\xB0`
|
|
616
662
|
);
|
|
617
663
|
}
|
|
618
664
|
if (t.source !== void 0 && t.source !== "manual" && t.source !== "auto") {
|
|
@@ -624,6 +670,11 @@ function lintDoc(docIn) {
|
|
|
624
670
|
);
|
|
625
671
|
}
|
|
626
672
|
}
|
|
673
|
+
if (dramatic.length) {
|
|
674
|
+
warnings.push(
|
|
675
|
+
`tilt: ${dramatic.length === 1 ? "a span leans" : `${dramatic.length} spans lean`} past 25\xB0 combined (${dramatic.join(", ")}) and read${dramatic.length === 1 ? "s" : ""} dramatic \u2014 the premium band is \xB15..18\xB0 per axis; keep it if the piece means it`
|
|
676
|
+
);
|
|
677
|
+
}
|
|
627
678
|
if (typeof doc.zoomStyle === "string" && doc.zoomStyle in RETIRED_ZOOM_STYLES) {
|
|
628
679
|
const r = RETIRED_ZOOM_STYLES[doc.zoomStyle];
|
|
629
680
|
warnings.push(
|
|
@@ -836,7 +887,8 @@ function lintDoc(docIn) {
|
|
|
836
887
|
enter: CARD_ENTER_KINDS,
|
|
837
888
|
exit: CARD_EXIT_KINDS,
|
|
838
889
|
idle: null,
|
|
839
|
-
words: false
|
|
890
|
+
words: false,
|
|
891
|
+
card: true
|
|
840
892
|
},
|
|
841
893
|
problems
|
|
842
894
|
);
|
|
@@ -930,9 +982,12 @@ function lintDoc(docIn) {
|
|
|
930
982
|
}
|
|
931
983
|
if (footageEnd !== null && footageEnd > 0 && isNum(o.start) && isNum(o.duration)) {
|
|
932
984
|
const over = o.start + o.duration - footageEnd;
|
|
933
|
-
|
|
985
|
+
const frameAnim = isObj(docIn) && isObj(docIn.frame) && isObj(docIn.frame.anim) ? docIn.frame.anim : null;
|
|
986
|
+
const exit = frameAnim ? isObj(frameAnim.exit) ? frameAnim.exit.kind : frameAnim.exit : void 0;
|
|
987
|
+
const cardLeaves = exit !== void 0 && exit !== "none";
|
|
988
|
+
if (over > 0.05 && !cardLeaves) {
|
|
934
989
|
warnings.push(
|
|
935
|
-
o.start >= footageEnd ? `${name} starts at ${o.start.toFixed(2)}s, after the footage ends (${footageEnd.toFixed(2)}s): it plays
|
|
990
|
+
o.start >= footageEnd ? `${name} starts at ${o.start.toFixed(2)}s, after the footage ends (${footageEnd.toFixed(2)}s): it plays over the card's held last frame and lengthens the output by ${over.toFixed(2)}s. A trim moves the footage, never an OUTPUT-anchored layer: re-place it (vos callout with the same --id), put a freeze under it, or, for a closing card on the ground, let the card leave (frame.anim.exit: 'fade')` : `${name} ends ${over.toFixed(2)}s after the footage (${footageEnd.toFixed(2)}s): the card holds its last frame under it. Shorten it, put a freeze under it, or, for a closing card on the ground, let the card leave (frame.anim.exit: 'fade')`
|
|
936
991
|
);
|
|
937
992
|
}
|
|
938
993
|
}
|
|
@@ -1604,13 +1659,67 @@ function framingWarnings(docIn, doc, zoom, overlays, warnings) {
|
|
|
1604
1659
|
if (!tf || !isNum(tf.x) || !isNum(tf.y)) return;
|
|
1605
1660
|
const pinned = pins.get(String(o.id));
|
|
1606
1661
|
if (!pinned && o.pin === void 0 && (o.kind === "html" || o.kind === "image" || o.kind === "video")) {
|
|
1607
|
-
const
|
|
1662
|
+
const words2 = layerWords(o);
|
|
1663
|
+
let layerBox = null;
|
|
1664
|
+
try {
|
|
1665
|
+
const b = pinBox(o, layout);
|
|
1666
|
+
layerBox = {
|
|
1667
|
+
x: tf.x * layout.W - b.w / 2,
|
|
1668
|
+
y: tf.y * layout.H - b.h / 2,
|
|
1669
|
+
w: b.w,
|
|
1670
|
+
h: b.h
|
|
1671
|
+
};
|
|
1672
|
+
} catch {
|
|
1673
|
+
layerBox = null;
|
|
1674
|
+
}
|
|
1675
|
+
const about = [];
|
|
1676
|
+
for (const c of pinCandidates(docIn, {
|
|
1608
1677
|
start: o.start,
|
|
1609
1678
|
duration: o.duration
|
|
1610
|
-
})
|
|
1611
|
-
|
|
1679
|
+
})) {
|
|
1680
|
+
const named = c.selector ? selectorLabelWords(c.selector).filter((x) => words2.has(x)) : [];
|
|
1681
|
+
if (named.length) {
|
|
1682
|
+
about.push({
|
|
1683
|
+
step: String(c.step),
|
|
1684
|
+
why: `its words name ${c.step}'s element ("${named.join(" ")}")`
|
|
1685
|
+
});
|
|
1686
|
+
continue;
|
|
1687
|
+
}
|
|
1688
|
+
if (!layerBox) continue;
|
|
1689
|
+
let ref;
|
|
1690
|
+
try {
|
|
1691
|
+
ref = pinReferent(docIn, { step: c.step });
|
|
1692
|
+
} catch {
|
|
1693
|
+
ref = null;
|
|
1694
|
+
}
|
|
1695
|
+
if (!ref || ref.rect.w * ref.rect.h > PIN_SURFACE_AREA) continue;
|
|
1696
|
+
const target = pinRectOnScreen(
|
|
1697
|
+
ref.rect,
|
|
1698
|
+
c.output.start,
|
|
1699
|
+
layout,
|
|
1700
|
+
camera,
|
|
1701
|
+
zoomTrack
|
|
1702
|
+
);
|
|
1703
|
+
const dx = Math.max(
|
|
1704
|
+
0,
|
|
1705
|
+
target.x - (layerBox.x + layerBox.w),
|
|
1706
|
+
layerBox.x - (target.x + target.w)
|
|
1707
|
+
);
|
|
1708
|
+
const dy = Math.max(
|
|
1709
|
+
0,
|
|
1710
|
+
target.y - (layerBox.y + layerBox.h),
|
|
1711
|
+
layerBox.y - (target.y + target.h)
|
|
1712
|
+
);
|
|
1713
|
+
if (Math.hypot(dx, dy) <= PIN_NEAR_FRACTION * layout.H) {
|
|
1714
|
+
about.push({
|
|
1715
|
+
step: String(c.step),
|
|
1716
|
+
why: `it sits beside ${c.step}'s element`
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
if (about.length) {
|
|
1612
1721
|
warnings.push(
|
|
1613
|
-
`overlays[${i}] is not pinned,
|
|
1722
|
+
`overlays[${i}] is not pinned, but ${about[0].why} \u2014 a callout about it says so, and follows it through the camera: pin: { step: "${about[0].step}" }`
|
|
1614
1723
|
);
|
|
1615
1724
|
}
|
|
1616
1725
|
}
|
|
@@ -1933,6 +2042,60 @@ function isTakeRelativeKey(key) {
|
|
|
1933
2042
|
return !!key && !/^(https?:|blob:|data:|media:|\/\/)/.test(key) && !key.startsWith("/api/");
|
|
1934
2043
|
}
|
|
1935
2044
|
var takeRelativeFile = (key) => key.replace(/^\/+/, "");
|
|
2045
|
+
function sourceSidecarRefs(doc, keep = isTakeRelativeKey) {
|
|
2046
|
+
const out = [];
|
|
2047
|
+
for (const [field, where] of [
|
|
2048
|
+
["micKey", "mic track"],
|
|
2049
|
+
["camKey", "cam track"]
|
|
2050
|
+
]) {
|
|
2051
|
+
const key = doc.source[field];
|
|
2052
|
+
if (!key || !keep(key)) continue;
|
|
2053
|
+
out.push({
|
|
2054
|
+
where,
|
|
2055
|
+
key,
|
|
2056
|
+
set: (next) => {
|
|
2057
|
+
doc.source[field] = next;
|
|
2058
|
+
}
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
return out;
|
|
2062
|
+
}
|
|
2063
|
+
function docObjectRefs(doc, keep = isTakeRelativeKey) {
|
|
2064
|
+
const out = [];
|
|
2065
|
+
for (const clip of doc.objects ?? []) {
|
|
2066
|
+
const asset = clip.asset;
|
|
2067
|
+
if (asset.kind !== "gltf" || !keep(asset.key)) continue;
|
|
2068
|
+
out.push({
|
|
2069
|
+
where: `object ${clip.id}`,
|
|
2070
|
+
key: asset.key,
|
|
2071
|
+
set: (next) => {
|
|
2072
|
+
asset.key = next;
|
|
2073
|
+
}
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
return out;
|
|
2077
|
+
}
|
|
2078
|
+
function docOverlayRefs(doc, keep = isTakeRelativeKey) {
|
|
2079
|
+
const out = [];
|
|
2080
|
+
for (const clip of doc.overlays ?? []) {
|
|
2081
|
+
if (!isKeyedOverlay(clip) || !keep(clip.key)) continue;
|
|
2082
|
+
out.push({
|
|
2083
|
+
where: `overlay ${clip.id}`,
|
|
2084
|
+
key: clip.key,
|
|
2085
|
+
set: (next) => {
|
|
2086
|
+
clip.key = next;
|
|
2087
|
+
}
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
return out;
|
|
2091
|
+
}
|
|
2092
|
+
function docLayerRefs(doc, keep = isTakeRelativeKey) {
|
|
2093
|
+
return [
|
|
2094
|
+
...docOverlayRefs(doc, keep),
|
|
2095
|
+
...docObjectRefs(doc, keep),
|
|
2096
|
+
...docAudioRefs(doc, keep)
|
|
2097
|
+
];
|
|
2098
|
+
}
|
|
1936
2099
|
function docMediaRefs(doc, keep = isTakeRelativeKey) {
|
|
1937
2100
|
const out = [];
|
|
1938
2101
|
for (const m of doc.media ?? []) {
|
|
@@ -1963,16 +2126,8 @@ function docMediaRefs(doc, keep = isTakeRelativeKey) {
|
|
|
1963
2126
|
}
|
|
1964
2127
|
});
|
|
1965
2128
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
out.push({
|
|
1969
|
-
where: `overlay ${clip.id}`,
|
|
1970
|
-
key: clip.key,
|
|
1971
|
-
set: (next) => {
|
|
1972
|
-
clip.key = next;
|
|
1973
|
-
}
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
2129
|
+
out.push(...docOverlayRefs(doc, keep));
|
|
2130
|
+
out.push(...docObjectRefs(doc, keep));
|
|
1976
2131
|
const mark = doc.endCard?.mark;
|
|
1977
2132
|
if (mark && keep(mark.key))
|
|
1978
2133
|
out.push({
|
|
@@ -2579,9 +2734,9 @@ async function renderInPage(opts) {
|
|
|
2579
2734
|
w.__error = String(e instanceof Error && e.stack || e);
|
|
2580
2735
|
}
|
|
2581
2736
|
}
|
|
2582
|
-
async function renderChunk(
|
|
2737
|
+
async function renderChunk(context2, serverBase, chunk2, opts, onChunkProgress) {
|
|
2583
2738
|
const outName = `render-chunk-${chunk2.index}.tmp`;
|
|
2584
|
-
const page = await
|
|
2739
|
+
const page = await context2.newPage();
|
|
2585
2740
|
try {
|
|
2586
2741
|
page.on("console", (m) => {
|
|
2587
2742
|
if (m.type() === "error" || process.env.VOS_RENDER_DEBUG)
|
|
@@ -2646,7 +2801,7 @@ async function renderAnimation(browser, opts) {
|
|
|
2646
2801
|
const server = await startTakeServer(opts.workDir, {
|
|
2647
2802
|
"/render.html": renderPageHtml()
|
|
2648
2803
|
});
|
|
2649
|
-
const
|
|
2804
|
+
const context2 = await browser.newContext({
|
|
2650
2805
|
viewport: { width: opts.width, height: opts.height }
|
|
2651
2806
|
});
|
|
2652
2807
|
try {
|
|
@@ -2660,7 +2815,7 @@ async function renderAnimation(browser, opts) {
|
|
|
2660
2815
|
};
|
|
2661
2816
|
const outNames = await Promise.all(
|
|
2662
2817
|
chunks.map(
|
|
2663
|
-
(chunk2) => renderChunk(
|
|
2818
|
+
(chunk2) => renderChunk(context2, server.base, chunk2, effOpts, (fraction) => {
|
|
2664
2819
|
progress[chunk2.index] = fraction;
|
|
2665
2820
|
reportProgress();
|
|
2666
2821
|
})
|
|
@@ -2684,7 +2839,7 @@ async function renderAnimation(browser, opts) {
|
|
|
2684
2839
|
);
|
|
2685
2840
|
return { bytes, totalFrames, chunks: chunks.length };
|
|
2686
2841
|
} finally {
|
|
2687
|
-
await
|
|
2842
|
+
await context2.close();
|
|
2688
2843
|
server.close();
|
|
2689
2844
|
}
|
|
2690
2845
|
}
|
|
@@ -3188,11 +3343,11 @@ async function digestTake(browser, dir, opts = {}) {
|
|
|
3188
3343
|
const server = await startTakeServer(dir, {
|
|
3189
3344
|
"/digest.html": digestPageHtml()
|
|
3190
3345
|
});
|
|
3191
|
-
const
|
|
3346
|
+
const context2 = await browser.newContext({
|
|
3192
3347
|
viewport: { width: 640, height: 360 }
|
|
3193
3348
|
});
|
|
3194
3349
|
try {
|
|
3195
|
-
const page = await
|
|
3350
|
+
const page = await context2.newPage();
|
|
3196
3351
|
page.on("console", (m) => {
|
|
3197
3352
|
if (m.type() === "error")
|
|
3198
3353
|
process.stderr.write(` [digest page] ${m.text()}
|
|
@@ -3260,7 +3415,7 @@ async function digestTake(browser, dir, opts = {}) {
|
|
|
3260
3415
|
}
|
|
3261
3416
|
if (sizes["sheet.png"]) sheet = "sheet.png";
|
|
3262
3417
|
} finally {
|
|
3263
|
-
await
|
|
3418
|
+
await context2.close();
|
|
3264
3419
|
server.close();
|
|
3265
3420
|
}
|
|
3266
3421
|
} else {
|
|
@@ -3527,11 +3682,11 @@ async function framesTake(browser, dir, opts) {
|
|
|
3527
3682
|
"/render.html": renderPageHtml()
|
|
3528
3683
|
});
|
|
3529
3684
|
const ss = stillSupersample(width, height);
|
|
3530
|
-
const
|
|
3685
|
+
const context2 = await browser.newContext({
|
|
3531
3686
|
viewport: { width: width * ss, height: height * ss }
|
|
3532
3687
|
});
|
|
3533
3688
|
try {
|
|
3534
|
-
const page = await
|
|
3689
|
+
const page = await context2.newPage();
|
|
3535
3690
|
page.on("console", (m) => {
|
|
3536
3691
|
if (m.type() === "error")
|
|
3537
3692
|
process.stderr.write(` [stills page] ${m.text()}
|
|
@@ -3574,7 +3729,7 @@ async function framesTake(browser, dir, opts) {
|
|
|
3574
3729
|
}
|
|
3575
3730
|
return { frames, width, height, duration, outDir };
|
|
3576
3731
|
} finally {
|
|
3577
|
-
await
|
|
3732
|
+
await context2.close();
|
|
3578
3733
|
server.close();
|
|
3579
3734
|
}
|
|
3580
3735
|
}
|
|
@@ -4333,11 +4488,11 @@ var outputLength = (doc) => ratedSegments4(doc).reduce((acc, s) => {
|
|
|
4333
4488
|
const rate = s.rate && s.rate > 0 ? s.rate : 1;
|
|
4334
4489
|
return acc + (s.out - s.in) / rate;
|
|
4335
4490
|
}, 0);
|
|
4336
|
-
function templateWords(
|
|
4337
|
-
const headline = (
|
|
4338
|
-
const kicker = (
|
|
4339
|
-
const brand = (
|
|
4340
|
-
const sub = [brand, (
|
|
4491
|
+
function templateWords(words2) {
|
|
4492
|
+
const headline = (words2.headline ?? "").trim();
|
|
4493
|
+
const kicker = (words2.kicker ?? "").trim();
|
|
4494
|
+
const brand = (words2.brand ?? "").trim();
|
|
4495
|
+
const sub = [brand, (words2.release ?? "").trim()].filter(Boolean).join(" ");
|
|
4341
4496
|
const out = {};
|
|
4342
4497
|
if (headline) {
|
|
4343
4498
|
out["stage-title"] = headline;
|
|
@@ -4363,7 +4518,7 @@ var anchorWord = (at2) => typeof at2 === "object" ? `step ${at2.step}` : typeof
|
|
|
4363
4518
|
var onWord = (v) => v === void 0 || /^(on|yes|true)$/i.test(v.trim());
|
|
4364
4519
|
function proposeMotion(input, opts) {
|
|
4365
4520
|
let doc = migrateMotion(structuredClone(input));
|
|
4366
|
-
const { words, launch, catalog } = opts;
|
|
4521
|
+
const { words: words2, launch, catalog } = opts;
|
|
4367
4522
|
const notes = [];
|
|
4368
4523
|
const skipped = [];
|
|
4369
4524
|
const footage = outputLength(doc);
|
|
@@ -4393,7 +4548,7 @@ function proposeMotion(input, opts) {
|
|
|
4393
4548
|
(t) => !(t.from === END_CARD_FROM && off(endCardRole))
|
|
4394
4549
|
);
|
|
4395
4550
|
const namedEndCard = templates.some((t) => t.from === END_CARD_FROM);
|
|
4396
|
-
const tWords = templateWords(
|
|
4551
|
+
const tWords = templateWords(words2);
|
|
4397
4552
|
const keys = opts.mark ? { "stage-mark": opts.mark.key, "endcard-markimg": opts.mark.key } : void 0;
|
|
4398
4553
|
for (const t of templates) {
|
|
4399
4554
|
const at2 = resolveAnchor(doc, t.at);
|
|
@@ -4418,9 +4573,9 @@ function proposeMotion(input, opts) {
|
|
|
4418
4573
|
else delete doc.frame.anim;
|
|
4419
4574
|
}
|
|
4420
4575
|
} else if (onWord(endCardRole) && !namedEndCard) {
|
|
4421
|
-
const headline = (
|
|
4422
|
-
const brand = (
|
|
4423
|
-
const sub = [brand, (
|
|
4576
|
+
const headline = (words2.headline ?? "").trim();
|
|
4577
|
+
const brand = (words2.brand ?? "").trim();
|
|
4578
|
+
const sub = [brand, (words2.release ?? "").trim()].filter(Boolean).join(" ");
|
|
4424
4579
|
if (headline || brand) {
|
|
4425
4580
|
const card = { seconds: END_CARD_SECONDS };
|
|
4426
4581
|
if (opts.ink) card.ink = opts.ink;
|
|
@@ -6887,11 +7042,11 @@ async function readDigestActivity(dir) {
|
|
|
6887
7042
|
return null;
|
|
6888
7043
|
}
|
|
6889
7044
|
}
|
|
6890
|
-
function patchStageWords(doc,
|
|
7045
|
+
function patchStageWords(doc, words2) {
|
|
6891
7046
|
const map = {
|
|
6892
|
-
"stage-title":
|
|
6893
|
-
"stage-kicker":
|
|
6894
|
-
"stage-brand":
|
|
7047
|
+
"stage-title": words2.headline,
|
|
7048
|
+
"stage-kicker": words2.kicker,
|
|
7049
|
+
"stage-brand": words2.brand
|
|
6895
7050
|
};
|
|
6896
7051
|
for (const clip of doc.overlays ?? []) {
|
|
6897
7052
|
if (clip.kind !== "text" || !isStageClip(clip)) continue;
|
|
@@ -7566,13 +7721,15 @@ async function pushTake(dir, flags, r) {
|
|
|
7566
7721
|
if (upload.reused) r.log(" recording already hosted \u2014 reused");
|
|
7567
7722
|
const docForPush = structuredClone(take.doc);
|
|
7568
7723
|
docForPush.source.videoKey = assetUrl;
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7724
|
+
await uploadDocRefs(sourceSidecarRefs(docForPush), dir, ctx, (l) => r.log(l));
|
|
7725
|
+
for (const field of ["micKey", "camKey"]) {
|
|
7726
|
+
const key = docForPush.source[field];
|
|
7727
|
+
if (key && isTakeRelativeKey(key)) {
|
|
7728
|
+
r.log(
|
|
7729
|
+
` ${field === "micKey" ? "mic" : "cam"} track ${key} is not beside the take \u2014 left out of the push`
|
|
7730
|
+
);
|
|
7731
|
+
delete docForPush.source[field];
|
|
7732
|
+
}
|
|
7576
7733
|
}
|
|
7577
7734
|
await uploadDocRefs(docMediaRefs(docForPush), dir, ctx, (l) => r.log(l));
|
|
7578
7735
|
const lowered = lowerToComposition3(docForPush);
|
|
@@ -8236,7 +8393,7 @@ with their key: vos push ${source} --vos ${String(created2.id ?? "<id>")}`
|
|
|
8236
8393
|
void flags.yes;
|
|
8237
8394
|
if (programDoc) {
|
|
8238
8395
|
await uploadDocRefs(
|
|
8239
|
-
|
|
8396
|
+
docLayerRefs(layersOf(programDoc)),
|
|
8240
8397
|
dir,
|
|
8241
8398
|
{ origin, key },
|
|
8242
8399
|
(l) => r.log(l)
|
|
@@ -8583,6 +8740,13 @@ function isTakeDir(target) {
|
|
|
8583
8740
|
function soundOf(doc) {
|
|
8584
8741
|
return { audio: Array.isArray(doc.audio) ? doc.audio : [] };
|
|
8585
8742
|
}
|
|
8743
|
+
function layersOf(doc) {
|
|
8744
|
+
return {
|
|
8745
|
+
...soundOf(doc),
|
|
8746
|
+
overlays: Array.isArray(doc.overlays) ? doc.overlays : [],
|
|
8747
|
+
objects: Array.isArray(doc.objects) ? doc.objects : []
|
|
8748
|
+
};
|
|
8749
|
+
}
|
|
8586
8750
|
function storedProgramConfig(config, programDoc) {
|
|
8587
8751
|
if (!programDoc) return config;
|
|
8588
8752
|
const doc = { audio: [], ...programDoc };
|
|
@@ -8763,12 +8927,177 @@ async function cmdAsset(argv) {
|
|
|
8763
8927
|
import { existsSync as existsSync16, rmSync as rmSync2, statSync as statSync4 } from "fs";
|
|
8764
8928
|
import { join as join18 } from "path";
|
|
8765
8929
|
import { createInterface as createInterface3 } from "readline/promises";
|
|
8766
|
-
|
|
8767
|
-
|
|
8930
|
+
|
|
8931
|
+
// src/plugin/trash.ts
|
|
8932
|
+
var BOOLEAN_FLAGS4 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
8933
|
+
var MONTHS = [
|
|
8934
|
+
"Jan",
|
|
8935
|
+
"Feb",
|
|
8936
|
+
"Mar",
|
|
8937
|
+
"Apr",
|
|
8938
|
+
"May",
|
|
8939
|
+
"Jun",
|
|
8940
|
+
"Jul",
|
|
8941
|
+
"Aug",
|
|
8942
|
+
"Sep",
|
|
8943
|
+
"Oct",
|
|
8944
|
+
"Nov",
|
|
8945
|
+
"Dec"
|
|
8946
|
+
];
|
|
8947
|
+
function restoreDate(iso, now = /* @__PURE__ */ new Date()) {
|
|
8948
|
+
const d = new Date(iso);
|
|
8949
|
+
if (Number.isNaN(d.getTime())) return iso;
|
|
8950
|
+
const day = `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}`;
|
|
8951
|
+
return d.getUTCFullYear() === now.getUTCFullYear() ? day : `${day} ${d.getUTCFullYear()}`;
|
|
8952
|
+
}
|
|
8953
|
+
function trashedBy(entry) {
|
|
8954
|
+
if (entry.deletedVia === "key") {
|
|
8955
|
+
return entry.deletedClient ?? entry.deletedKeyName ?? "a key";
|
|
8956
|
+
}
|
|
8957
|
+
if (entry.deletedVia === "admin") return "an admin";
|
|
8958
|
+
if (entry.deletedVia === "service") return "vos.so";
|
|
8959
|
+
return "you";
|
|
8960
|
+
}
|
|
8961
|
+
function sinceMoment(value, now = /* @__PURE__ */ new Date()) {
|
|
8962
|
+
const rel = /^(\d+(?:\.\d+)?)(s|m|h|d)$/.exec(value.trim());
|
|
8963
|
+
if (rel) {
|
|
8964
|
+
const unit = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[rel[2]];
|
|
8965
|
+
return new Date(now.getTime() - Number(rel[1]) * unit);
|
|
8966
|
+
}
|
|
8967
|
+
const at2 = new Date(value);
|
|
8968
|
+
return Number.isNaN(at2.getTime()) ? null : at2;
|
|
8969
|
+
}
|
|
8970
|
+
function words(kind) {
|
|
8971
|
+
return kind === "vos" ? "vos" : kind === "folder" ? "project" : "file";
|
|
8972
|
+
}
|
|
8973
|
+
function context(flags) {
|
|
8974
|
+
const origin = platformOrigin({
|
|
8975
|
+
origin: strFlag(flags, "origin"),
|
|
8976
|
+
api: strFlag(flags, "api")
|
|
8977
|
+
}).replace(/\/+$/, "");
|
|
8978
|
+
return { origin, key: requireCredential(strFlag(flags, "key")) };
|
|
8979
|
+
}
|
|
8980
|
+
async function readTrash(ctx) {
|
|
8981
|
+
const res = await apiJson(ctx.origin, "/api/trash", { key: ctx.key });
|
|
8982
|
+
if (res.status !== 200) throw new Error(apiError("read Trash", res));
|
|
8983
|
+
return res.body.entries ?? [];
|
|
8984
|
+
}
|
|
8985
|
+
async function restore(ctx, body) {
|
|
8986
|
+
let restored = [];
|
|
8987
|
+
let missing = [];
|
|
8988
|
+
for (let pass = 0; pass < 100; pass++) {
|
|
8989
|
+
const res = await apiJson(ctx.origin, "/api/trash/restore", {
|
|
8990
|
+
method: "POST",
|
|
8991
|
+
key: ctx.key,
|
|
8992
|
+
body
|
|
8993
|
+
});
|
|
8994
|
+
if (res.status !== 200) throw new Error(apiError("restore", res));
|
|
8995
|
+
if (pass === 0) {
|
|
8996
|
+
restored = res.body.restored ?? [];
|
|
8997
|
+
missing = res.body.missing ?? [];
|
|
8998
|
+
}
|
|
8999
|
+
if (res.body.done !== false) break;
|
|
9000
|
+
}
|
|
9001
|
+
return { restored, missing };
|
|
9002
|
+
}
|
|
9003
|
+
async function cmdTrash(argv) {
|
|
9004
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS4);
|
|
9005
|
+
const r = createReporter(flags.json === true);
|
|
9006
|
+
const ctx = context(flags);
|
|
9007
|
+
if (positionals[0] === "restore") {
|
|
9008
|
+
const raw = strFlag(flags, "since");
|
|
9009
|
+
const since = raw ? sinceMoment(raw) : null;
|
|
9010
|
+
if (!since)
|
|
9011
|
+
throw new UsageError(
|
|
9012
|
+
"vos trash restore --since <30m|1h|2d|ISO time> [--by <key name>] [--json]"
|
|
9013
|
+
);
|
|
9014
|
+
const by = strFlag(flags, "by");
|
|
9015
|
+
let keyId = null;
|
|
9016
|
+
if (by) {
|
|
9017
|
+
const match = (await readTrash(ctx)).find(
|
|
9018
|
+
(e) => e.deletedKeyName === by || e.deletedKeyId?.startsWith(by)
|
|
9019
|
+
);
|
|
9020
|
+
keyId = match?.deletedKeyId ?? null;
|
|
9021
|
+
if (!keyId)
|
|
9022
|
+
throw new Error(`nothing in Trash was moved there by a key named ${by}`);
|
|
9023
|
+
} else {
|
|
9024
|
+
const me = await apiJson(ctx.origin, "/api/user/whoami", {
|
|
9025
|
+
key: ctx.key
|
|
9026
|
+
});
|
|
9027
|
+
keyId = (me.body.key ?? null)?.id ?? null;
|
|
9028
|
+
if (me.status !== 200 || !keyId)
|
|
9029
|
+
throw new Error(
|
|
9030
|
+
"could not tell which key this is: pass --by <key name> (vos trash lists them)"
|
|
9031
|
+
);
|
|
9032
|
+
}
|
|
9033
|
+
const done = await restore(ctx, { keyId, since: since.toISOString() });
|
|
9034
|
+
r.done(
|
|
9035
|
+
{ restored: done.restored, count: done.restored.length },
|
|
9036
|
+
done.restored.length ? `restored ${done.restored.length} item${done.restored.length === 1 ? "" : "s"} moved to Trash since ${since.toISOString()}` : `nothing was moved to Trash by that key since ${since.toISOString()}`
|
|
9037
|
+
);
|
|
9038
|
+
return EXIT_OK;
|
|
9039
|
+
}
|
|
9040
|
+
if (positionals[0])
|
|
9041
|
+
throw new UsageError(
|
|
9042
|
+
`vos trash has no "${positionals[0]}": vos trash, or vos trash restore --since <time>. Trash is emptied by a person, at vos.so/app/trash`
|
|
9043
|
+
);
|
|
9044
|
+
const entries2 = await readTrash(ctx);
|
|
9045
|
+
if (flags.json === true) {
|
|
9046
|
+
r.done({ entries: entries2, count: entries2.length }, "");
|
|
9047
|
+
return EXIT_OK;
|
|
9048
|
+
}
|
|
9049
|
+
if (entries2.length === 0) {
|
|
9050
|
+
r.done({ entries: entries2, count: 0 }, "Trash is empty");
|
|
9051
|
+
return EXIT_OK;
|
|
9052
|
+
}
|
|
9053
|
+
const lines = entries2.map((e) => {
|
|
9054
|
+
const inside = e.members ? ` (${e.members.voses} vos, ${e.members.assets} files)` : "";
|
|
9055
|
+
return ` ${words(e.kind).padEnd(7)} ${e.id} "${e.title}"${inside}: moved by ${trashedBy(e)}, restorable until ${restoreDate(e.restoreUntil)}`;
|
|
9056
|
+
});
|
|
9057
|
+
r.done(
|
|
9058
|
+
{ entries: entries2, count: entries2.length },
|
|
9059
|
+
`${entries2.length} in Trash
|
|
9060
|
+
${lines.join("\n")}
|
|
9061
|
+
restore one: vos restore <id> (emptying Trash is the person's act, at vos.so/app/trash)`
|
|
9062
|
+
);
|
|
9063
|
+
return EXIT_OK;
|
|
9064
|
+
}
|
|
9065
|
+
async function cmdRestore(argv) {
|
|
8768
9066
|
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS4);
|
|
9067
|
+
if (positionals.length === 0)
|
|
9068
|
+
throw new UsageError("vos restore <id|watch-url> [...] [--json]");
|
|
9069
|
+
const r = createReporter(flags.json === true);
|
|
9070
|
+
const ctx = context(flags);
|
|
9071
|
+
const entries2 = await readTrash(ctx);
|
|
9072
|
+
const wanted = positionals.map((p) => parseVosId(p) ?? p);
|
|
9073
|
+
const units = wanted.map((id) => {
|
|
9074
|
+
const entry = entries2.find((e) => e.id === id);
|
|
9075
|
+
if (!entry)
|
|
9076
|
+
throw new Error(
|
|
9077
|
+
`${id} is not in Trash (vos trash lists what is; something inside a trashed project comes back with the project)`
|
|
9078
|
+
);
|
|
9079
|
+
return { kind: entry.kind, id: entry.id, title: entry.title };
|
|
9080
|
+
});
|
|
9081
|
+
const done = await restore(ctx, {
|
|
9082
|
+
ids: units.map(({ kind, id }) => ({ kind, id }))
|
|
9083
|
+
});
|
|
9084
|
+
const names = units.map((u) => `"${u.title}"`).join(", ");
|
|
9085
|
+
r.done(
|
|
9086
|
+
{ restored: done.restored, count: done.restored.length },
|
|
9087
|
+
`restored ${names}`
|
|
9088
|
+
);
|
|
9089
|
+
return EXIT_OK;
|
|
9090
|
+
}
|
|
9091
|
+
|
|
9092
|
+
// src/plugin/remove.ts
|
|
9093
|
+
var BOOLEAN_FLAGS5 = /* @__PURE__ */ new Set(["json", "help", "yes", "dry-run"]);
|
|
9094
|
+
async function cmdDelete(argv) {
|
|
9095
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS5);
|
|
8769
9096
|
const target = positionals[0];
|
|
8770
9097
|
if (!target)
|
|
8771
|
-
throw new UsageError(
|
|
9098
|
+
throw new UsageError(
|
|
9099
|
+
"vos delete <vosId|watch-url|dir> [--yes] [--dry-run] [--json]"
|
|
9100
|
+
);
|
|
8772
9101
|
const r = createReporter(flags.json === true);
|
|
8773
9102
|
const origin = platformOrigin({
|
|
8774
9103
|
origin: strFlag(flags, "origin"),
|
|
@@ -8785,24 +9114,33 @@ async function cmdDelete(argv) {
|
|
|
8785
9114
|
if (meta.status !== 200) throw new Error(apiError(`read ${vosId}`, meta));
|
|
8786
9115
|
const vos = meta.body.vos ?? {};
|
|
8787
9116
|
const title = typeof vos.title === "string" ? vos.title : vosId;
|
|
9117
|
+
if (flags["dry-run"] === true) {
|
|
9118
|
+
r.done(
|
|
9119
|
+
{ id: vosId, title, deleted: false, dryRun: true },
|
|
9120
|
+
`would move "${title}" (${vosId}) to Trash; nothing was changed`
|
|
9121
|
+
);
|
|
9122
|
+
return EXIT_OK;
|
|
9123
|
+
}
|
|
8788
9124
|
if (flags.yes !== true) {
|
|
8789
9125
|
if (!process.stdin.isTTY)
|
|
8790
9126
|
throw new UsageError(
|
|
8791
|
-
`
|
|
9127
|
+
`"${title}" (${vosId}) would move to Trash: re-run with --yes to confirm, or --dry-run to only look`
|
|
8792
9128
|
);
|
|
8793
9129
|
const rl = createInterface3({ input: process.stdin, output: process.stderr });
|
|
8794
9130
|
const answer = await rl.question(
|
|
8795
|
-
`
|
|
9131
|
+
`Move "${title}" (${vosId}) to Trash? It stays restorable there for a while (vos restore ${vosId}). [y/N] `
|
|
8796
9132
|
);
|
|
8797
9133
|
rl.close();
|
|
8798
9134
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
8799
|
-
r.done({ id: vosId, deleted: false }, "kept
|
|
9135
|
+
r.done({ id: vosId, deleted: false }, "kept: nothing was deleted");
|
|
8800
9136
|
return EXIT_OK;
|
|
8801
9137
|
}
|
|
8802
9138
|
}
|
|
8803
9139
|
const res = await apiJson(origin, `/api/vos/${vosId}`, {
|
|
8804
9140
|
method: "DELETE",
|
|
8805
|
-
key
|
|
9141
|
+
key,
|
|
9142
|
+
// Who did it, for the person reading Trash later (display only).
|
|
9143
|
+
headers: { "x-vos-client": clientId() }
|
|
8806
9144
|
});
|
|
8807
9145
|
if (res.status !== 200 && res.status !== 204)
|
|
8808
9146
|
throw new Error(apiError(`delete ${vosId}`, res));
|
|
@@ -8811,9 +9149,23 @@ async function cmdDelete(argv) {
|
|
|
8811
9149
|
rmSync2(join18(dir, SYNC_STATE_NAME), { force: true });
|
|
8812
9150
|
unlinked = true;
|
|
8813
9151
|
}
|
|
9152
|
+
const trashed = res.body.trashed === true;
|
|
9153
|
+
const restoreUntil = typeof res.body.restoreUntil === "string" ? res.body.restoreUntil : null;
|
|
9154
|
+
const tail = unlinked ? `; ${dir} no longer tracks it` : "";
|
|
8814
9155
|
r.done(
|
|
8815
|
-
{
|
|
8816
|
-
|
|
9156
|
+
{
|
|
9157
|
+
id: vosId,
|
|
9158
|
+
title,
|
|
9159
|
+
deleted: true,
|
|
9160
|
+
trashed,
|
|
9161
|
+
...restoreUntil ? { restoreUntil } : {},
|
|
9162
|
+
unlinked
|
|
9163
|
+
},
|
|
9164
|
+
trashed ? `moved "${title}" (${vosId}) to Trash${restoreUntil ? `, restorable until ${restoreDate(restoreUntil)}` : ""}: vos restore ${vosId}${tail}` : (
|
|
9165
|
+
// A vos with no version (a refused hosted take's empty shell) has
|
|
9166
|
+
// nothing to restore, so the platform erases it.
|
|
9167
|
+
`deleted "${title}" (${vosId})${tail}`
|
|
9168
|
+
)
|
|
8817
9169
|
);
|
|
8818
9170
|
return EXIT_OK;
|
|
8819
9171
|
}
|
|
@@ -9013,9 +9365,9 @@ function nonJson(value, path) {
|
|
|
9013
9365
|
}
|
|
9014
9366
|
return null;
|
|
9015
9367
|
}
|
|
9016
|
-
var
|
|
9368
|
+
var BOOLEAN_FLAGS6 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
9017
9369
|
async function cmdBuild(argv) {
|
|
9018
|
-
const { positionals, flags } = parseArgs(argv,
|
|
9370
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS6);
|
|
9019
9371
|
const source = positionals[0];
|
|
9020
9372
|
if (!source)
|
|
9021
9373
|
throw new UsageError("vos build <program.mjs> [--out config.json] [--json]");
|
|
@@ -9057,7 +9409,7 @@ async function cmdBuild(argv) {
|
|
|
9057
9409
|
import { spawnSync } from "child_process";
|
|
9058
9410
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
9059
9411
|
import { join as join20, resolve as resolve8 } from "path";
|
|
9060
|
-
var
|
|
9412
|
+
var BOOLEAN_FLAGS7 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
9061
9413
|
function sampleTimes(duration, every) {
|
|
9062
9414
|
const step = every > 0 ? every : 1;
|
|
9063
9415
|
const out = [];
|
|
@@ -9108,7 +9460,7 @@ function probeSize(video) {
|
|
|
9108
9460
|
return m ? { width: Number(m[1]), height: Number(m[2]) } : null;
|
|
9109
9461
|
}
|
|
9110
9462
|
async function cmdCompare(argv) {
|
|
9111
|
-
const { positionals, flags } = parseArgs(argv,
|
|
9463
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS7);
|
|
9112
9464
|
const source = positionals[0];
|
|
9113
9465
|
const against = strFlag(flags, "against");
|
|
9114
9466
|
if (!source || !against)
|
|
@@ -10253,8 +10605,8 @@ function toHex(css) {
|
|
|
10253
10605
|
return `#${hex2(+m[1])}${hex2(+m[2])}${hex2(+m[3])}${a < 1 ? hex2(a * 255) : ""}`;
|
|
10254
10606
|
}
|
|
10255
10607
|
function keyFor(label, taken, prefix = "t") {
|
|
10256
|
-
const
|
|
10257
|
-
let base =
|
|
10608
|
+
const words2 = label.replace(/[^A-Za-z0-9]+/g, " ").trim().split(" ").filter(Boolean).slice(0, 4);
|
|
10609
|
+
let base = words2.map(
|
|
10258
10610
|
(w, i) => i === 0 ? w.toLowerCase() : w[0].toUpperCase() + w.slice(1).toLowerCase()
|
|
10259
10611
|
).join("");
|
|
10260
10612
|
if (!base || /^[0-9]/.test(base)) base = prefix + (base || "");
|
|
@@ -10315,8 +10667,8 @@ function planScaffold(inv, opts) {
|
|
|
10315
10667
|
for (const t of inv.texts) {
|
|
10316
10668
|
const generic = /^(div|span|p|h[1-6]|li|a|b|i|em|strong)-\d+$/.test(t.id);
|
|
10317
10669
|
const key = keyFor(generic ? t.text : t.id, taken);
|
|
10318
|
-
const
|
|
10319
|
-
data[key] =
|
|
10670
|
+
const words2 = t.font.transform === "uppercase" ? t.text.toUpperCase() : t.font.transform === "lowercase" ? t.text.toLowerCase() : t.text;
|
|
10671
|
+
data[key] = words2;
|
|
10320
10672
|
const family = faceFor(t);
|
|
10321
10673
|
elements.push({
|
|
10322
10674
|
id: key,
|
|
@@ -10335,7 +10687,7 @@ function planScaffold(inv, opts) {
|
|
|
10335
10687
|
} : {}
|
|
10336
10688
|
}
|
|
10337
10689
|
});
|
|
10338
|
-
textKeys.push({ key, size: t.font.size, label:
|
|
10690
|
+
textKeys.push({ key, size: t.font.size, label: words2.slice(0, 40) });
|
|
10339
10691
|
if (t.scene && sceneNames.has(t.scene))
|
|
10340
10692
|
(sceneElements[t.scene] ??= []).push(key);
|
|
10341
10693
|
}
|
|
@@ -10633,7 +10985,7 @@ function reportText(inv, r) {
|
|
|
10633
10985
|
"",
|
|
10634
10986
|
"## Images and video",
|
|
10635
10987
|
"",
|
|
10636
|
-
"Not placed: upload each with `vos asset
|
|
10988
|
+
"Not placed: upload each with `vos asset push` and add an image or video element over its hosted URL.",
|
|
10637
10989
|
"",
|
|
10638
10990
|
...inv.media.filter((m) => m.kind === "image" || m.kind === "video").map((m) => `- ${m.kind} ${m.src ?? "(inline)"}`)
|
|
10639
10991
|
] : [],
|
|
@@ -10667,7 +11019,7 @@ function probeAudioDuration(file) {
|
|
|
10667
11019
|
}
|
|
10668
11020
|
|
|
10669
11021
|
// src/plugin/port.ts
|
|
10670
|
-
var
|
|
11022
|
+
var BOOLEAN_FLAGS8 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
10671
11023
|
async function cmdPort(argv) {
|
|
10672
11024
|
const [sub, ...rest] = argv;
|
|
10673
11025
|
if (sub === "inventory") return await inventory(rest);
|
|
@@ -10677,7 +11029,7 @@ async function cmdPort(argv) {
|
|
|
10677
11029
|
);
|
|
10678
11030
|
}
|
|
10679
11031
|
async function inventory(argv) {
|
|
10680
|
-
const { positionals, flags } = parseArgs(argv,
|
|
11032
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS8);
|
|
10681
11033
|
const source = positionals[0] ?? ".";
|
|
10682
11034
|
const r = createReporter(flags.json === true);
|
|
10683
11035
|
const outDir = resolve11(strFlag(flags, "out") ?? "port");
|
|
@@ -10718,7 +11070,7 @@ function summary(inv) {
|
|
|
10718
11070
|
};
|
|
10719
11071
|
}
|
|
10720
11072
|
async function scaffold(argv) {
|
|
10721
|
-
const { flags } = parseArgs(argv,
|
|
11073
|
+
const { flags } = parseArgs(argv, BOOLEAN_FLAGS8);
|
|
10722
11074
|
const r = createReporter(flags.json === true);
|
|
10723
11075
|
const from = resolve11(strFlag(flags, "from") ?? join24("port", "inventory.json"));
|
|
10724
11076
|
if (!existsSync20(from))
|
|
@@ -10757,7 +11109,7 @@ function scaffoldSourceDir(inv) {
|
|
|
10757
11109
|
// src/plugin/recipe.ts
|
|
10758
11110
|
import { readFileSync as readFileSync8 } from "fs";
|
|
10759
11111
|
import { basename as basename9 } from "path";
|
|
10760
|
-
var
|
|
11112
|
+
var BOOLEAN_FLAGS9 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
10761
11113
|
var USAGE = "vos recipe push <file.md> (--folder <folderId|slug> | --asset <assetId>)";
|
|
10762
11114
|
function recipeFilename(file) {
|
|
10763
11115
|
const name = basename9(file);
|
|
@@ -10767,7 +11119,7 @@ function recipeFilename(file) {
|
|
|
10767
11119
|
return name;
|
|
10768
11120
|
}
|
|
10769
11121
|
async function cmdPush2(argv) {
|
|
10770
|
-
const { positionals, flags } = parseArgs(argv,
|
|
11122
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS9);
|
|
10771
11123
|
const [file] = positionals;
|
|
10772
11124
|
const folderRef = strFlag(flags, "folder");
|
|
10773
11125
|
const assetId = strFlag(flags, "asset");
|
|
@@ -11868,7 +12220,7 @@ import {
|
|
|
11868
12220
|
Output,
|
|
11869
12221
|
WebMOutputFormat
|
|
11870
12222
|
} from "mediabunny";
|
|
11871
|
-
var
|
|
12223
|
+
var BOOLEAN_FLAGS10 = /* @__PURE__ */ new Set(["json", "help"]);
|
|
11872
12224
|
async function probeVideoFile(path) {
|
|
11873
12225
|
const input = new Input({
|
|
11874
12226
|
source: new FilePathSource(path),
|
|
@@ -11959,7 +12311,7 @@ function parseViewport(v) {
|
|
|
11959
12311
|
return { width: Number(m[1]), height: Number(m[2]) };
|
|
11960
12312
|
}
|
|
11961
12313
|
async function cmdIngest(argv) {
|
|
11962
|
-
const { positionals, flags } = parseArgs(argv,
|
|
12314
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS10, MULTI_FLAGS2);
|
|
11963
12315
|
const source = positionals[0];
|
|
11964
12316
|
if (!source)
|
|
11965
12317
|
throw new UsageError(
|
|
@@ -12165,6 +12517,7 @@ var RULES_BODY = `## Product videos (vosso)
|
|
|
12165
12517
|
- Look before you cut: vos frames take --at-zooms; edit take/doc.json and re-render, never re-record
|
|
12166
12518
|
- Hand back: vos open take serves the take into the studio at vos.so, doc.json intact
|
|
12167
12519
|
- Local by default: vos push only when asked for a link, the shelf or a cloud render
|
|
12520
|
+
- Deleting: vos delete moves a vos to Trash and vos restore brings it back; if you deleted by mistake, restore it and say so. Only the person can delete forever, at vos.so/app/trash
|
|
12168
12521
|
- Credentials: VOS_API_KEY, then ~/.config/vos/credentials, then vos login; never print one
|
|
12169
12522
|
- Reference: https://vos.so/llms-full.txt`;
|
|
12170
12523
|
var RULES_BLOCK = `${RULES_BEGIN}
|
|
@@ -12313,7 +12666,7 @@ function bundledSkillsDir(from) {
|
|
|
12313
12666
|
}
|
|
12314
12667
|
|
|
12315
12668
|
// src/plugin/machineCmd.ts
|
|
12316
|
-
var
|
|
12669
|
+
var BOOLEAN_FLAGS11 = /* @__PURE__ */ new Set([
|
|
12317
12670
|
"json",
|
|
12318
12671
|
"help",
|
|
12319
12672
|
"global",
|
|
@@ -12391,7 +12744,7 @@ async function doctorFacts(opts) {
|
|
|
12391
12744
|
};
|
|
12392
12745
|
}
|
|
12393
12746
|
async function cmdSetup(argv) {
|
|
12394
|
-
const { flags } = parseArgs(argv,
|
|
12747
|
+
const { flags } = parseArgs(argv, BOOLEAN_FLAGS11);
|
|
12395
12748
|
const r = reporterFor(flags);
|
|
12396
12749
|
const root = process.cwd();
|
|
12397
12750
|
const global = flags.global === true;
|
|
@@ -12510,7 +12863,7 @@ Next: ${report.next_step}`
|
|
|
12510
12863
|
return report.ok ? EXIT_OK : EXIT_NO_BROWSER;
|
|
12511
12864
|
}
|
|
12512
12865
|
async function cmdDoctor(argv) {
|
|
12513
|
-
const { flags } = parseArgs(argv,
|
|
12866
|
+
const { flags } = parseArgs(argv, BOOLEAN_FLAGS11);
|
|
12514
12867
|
const r = reporterFor(flags);
|
|
12515
12868
|
const root = process.cwd();
|
|
12516
12869
|
const homes = detectAgents(root, { home: homedir2(), global: true });
|
|
@@ -12529,7 +12882,7 @@ Next: ${report.next_step}`
|
|
|
12529
12882
|
return report.ok ? EXIT_OK : EXIT_NO_BROWSER;
|
|
12530
12883
|
}
|
|
12531
12884
|
async function cmdWhoami(argv) {
|
|
12532
|
-
const { flags } = parseArgs(argv,
|
|
12885
|
+
const { flags } = parseArgs(argv, BOOLEAN_FLAGS11);
|
|
12533
12886
|
const r = reporterFor(flags);
|
|
12534
12887
|
const origin = platformOrigin({
|
|
12535
12888
|
origin: strFlag(flags, "origin"),
|
|
@@ -12591,7 +12944,7 @@ async function cmdWhoami(argv) {
|
|
|
12591
12944
|
return EXIT_OK;
|
|
12592
12945
|
}
|
|
12593
12946
|
function cmdLogout(argv) {
|
|
12594
|
-
const { flags } = parseArgs(argv,
|
|
12947
|
+
const { flags } = parseArgs(argv, BOOLEAN_FLAGS11);
|
|
12595
12948
|
const r = reporterFor(flags);
|
|
12596
12949
|
const had = existsSync23(CREDENTIALS_PATH);
|
|
12597
12950
|
rmSync3(CREDENTIALS_PATH, { force: true });
|
|
@@ -12609,7 +12962,7 @@ function cmdLogout(argv) {
|
|
|
12609
12962
|
}
|
|
12610
12963
|
|
|
12611
12964
|
// src/plugin/run.ts
|
|
12612
|
-
var
|
|
12965
|
+
var BOOLEAN_FLAGS12 = /* @__PURE__ */ new Set([
|
|
12613
12966
|
"json",
|
|
12614
12967
|
"help",
|
|
12615
12968
|
"wait",
|
|
@@ -12711,16 +13064,29 @@ Platform (vos.so) \u2014 fetch, edit, push, pull, repeat
|
|
|
12711
13064
|
--override consents to touching
|
|
12712
13065
|
protected (human-edited) nodes, ONLY when the user asked.
|
|
12713
13066
|
Without --folder a new vos lands unfiled, at the root of your
|
|
12714
|
-
shelf. A document's local
|
|
12715
|
-
|
|
13067
|
+
shelf. A document's local files (doc.json: picture and video
|
|
13068
|
+
overlays, 3D props, sound; a take's mic and cam too) upload
|
|
13069
|
+
with the push, each once. --wait stays until the version's still has
|
|
12716
13070
|
rendered and prints absolute still and preview links.
|
|
12717
13071
|
--still <seconds> sets a PROGRAM's cover (doc.json "still", kept
|
|
12718
13072
|
by every later push); without it the platform picks an early
|
|
12719
13073
|
frame. A take's cover is its doc.json "still".
|
|
12720
|
-
vos delete <vosId|watch-url|dir> [--yes] [--json]
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
13074
|
+
vos delete <vosId|watch-url|dir> [--yes] [--dry-run] [--json]
|
|
13075
|
+
move a vos to Trash on vos.so. Nothing is erased: it stays
|
|
13076
|
+
restorable until the date the delete prints (vos restore <id>).
|
|
13077
|
+
Asks on a terminal; headless it needs --yes. --dry-run names
|
|
13078
|
+
what would move and changes nothing. A dir that tracked it is
|
|
13079
|
+
unlinked (its vos.json removed). Needs a key with the delete
|
|
13080
|
+
scope; no key can delete forever, only the person can, on the
|
|
13081
|
+
web
|
|
13082
|
+
vos trash [--json]
|
|
13083
|
+
what is in Trash on vos.so: what, moved by whom, restorable
|
|
13084
|
+
until when
|
|
13085
|
+
vos restore <id|watch-url> [...] [--json]
|
|
13086
|
+
bring those back from Trash, as they were
|
|
13087
|
+
vos trash restore --since <30m|1h|2d|ISO> [--by <key name>] [--json]
|
|
13088
|
+
undo everything this key (or the named one) moved to Trash
|
|
13089
|
+
since then
|
|
12724
13090
|
vos pull [dir|take] [--vos <id>] [--since versionId] [--check] [--media] [--json]
|
|
12725
13091
|
what changed on vos.so since your base; syncs config.json (backup
|
|
12726
13092
|
kept) or the take's doc.json. ALWAYS pull before editing pushed work.
|
|
@@ -13066,7 +13432,7 @@ function wallGate(flags, r, opts) {
|
|
|
13066
13432
|
async function cmdRecord(argv) {
|
|
13067
13433
|
const { positionals, flags, multi } = parseArgs(
|
|
13068
13434
|
argv,
|
|
13069
|
-
|
|
13435
|
+
BOOLEAN_FLAGS12,
|
|
13070
13436
|
MULTI_FLAGS2
|
|
13071
13437
|
);
|
|
13072
13438
|
const actionsPath = strFlag(flags, "actions") ?? positionals[0];
|
|
@@ -13187,10 +13553,10 @@ async function cmdRecord(argv) {
|
|
|
13187
13553
|
const rec = await inSession(
|
|
13188
13554
|
sessionName,
|
|
13189
13555
|
actions,
|
|
13190
|
-
(
|
|
13556
|
+
(context2) => recordTake(browser2, url, actions, takePaths(outDir), r.log, {
|
|
13191
13557
|
storageState,
|
|
13192
13558
|
headers,
|
|
13193
|
-
context,
|
|
13559
|
+
context: context2,
|
|
13194
13560
|
dryRun: true,
|
|
13195
13561
|
// A rehearsal is always strict, and it touches no directory.
|
|
13196
13562
|
onArrival: wallGate(flags, r, { strict: true })
|
|
@@ -13249,11 +13615,11 @@ ${lines.join("\n")}
|
|
|
13249
13615
|
const rec = await inSession(
|
|
13250
13616
|
sessionName,
|
|
13251
13617
|
actions,
|
|
13252
|
-
(
|
|
13618
|
+
(context2) => recordTake(browser, url, actions, paths, r.log, {
|
|
13253
13619
|
maxDurationSeconds,
|
|
13254
13620
|
storageState,
|
|
13255
13621
|
headers,
|
|
13256
|
-
context,
|
|
13622
|
+
context: context2,
|
|
13257
13623
|
onArrival: wallGate(flags, r, {
|
|
13258
13624
|
strict: flags.strict === true,
|
|
13259
13625
|
prepare
|
|
@@ -13308,7 +13674,7 @@ ${lines.join("\n")}
|
|
|
13308
13674
|
async function cmdCreate2(argv) {
|
|
13309
13675
|
const { positionals, flags, multi } = parseArgs(
|
|
13310
13676
|
argv,
|
|
13311
|
-
|
|
13677
|
+
BOOLEAN_FLAGS12,
|
|
13312
13678
|
MULTI_FLAGS2
|
|
13313
13679
|
);
|
|
13314
13680
|
const actionsPath = strFlag(flags, "actions");
|
|
@@ -13353,11 +13719,11 @@ async function cmdCreate2(argv) {
|
|
|
13353
13719
|
const rec = await inSession(
|
|
13354
13720
|
sessionName,
|
|
13355
13721
|
actions,
|
|
13356
|
-
(
|
|
13722
|
+
(context2) => recordTake(browser, url, actions, paths, r.log, {
|
|
13357
13723
|
maxDurationSeconds,
|
|
13358
13724
|
storageState,
|
|
13359
13725
|
headers,
|
|
13360
|
-
context,
|
|
13726
|
+
context: context2,
|
|
13361
13727
|
onArrival: wallGate(flags, r, {
|
|
13362
13728
|
strict: flags.strict === true,
|
|
13363
13729
|
prepare
|
|
@@ -13434,7 +13800,7 @@ async function cmdCreate2(argv) {
|
|
|
13434
13800
|
async function cmdPlan(argv) {
|
|
13435
13801
|
const { positionals, flags, multi } = parseArgs(
|
|
13436
13802
|
argv,
|
|
13437
|
-
|
|
13803
|
+
BOOLEAN_FLAGS12,
|
|
13438
13804
|
/* @__PURE__ */ new Set(["with"])
|
|
13439
13805
|
);
|
|
13440
13806
|
const dir = positionals[0];
|
|
@@ -13535,7 +13901,7 @@ async function releaseInputs(dir, flags, r, withRefs = []) {
|
|
|
13535
13901
|
}
|
|
13536
13902
|
const launch = await readLaunchBesideTake(dir, strFlag(flags, "launch"));
|
|
13537
13903
|
const lines = (v) => v === null || v === void 0 ? null : v.replace(/\\n/g, "\n");
|
|
13538
|
-
const
|
|
13904
|
+
const words2 = {
|
|
13539
13905
|
headline: lines(strFlag(flags, "headline") ?? launch?.roles.headline),
|
|
13540
13906
|
kicker: lines(strFlag(flags, "kicker") ?? launch?.roles.kicker),
|
|
13541
13907
|
brand: strFlag(flags, "brand-name") ?? lookPick.roles?.wordmark ?? null,
|
|
@@ -13620,7 +13986,7 @@ async function releaseInputs(dir, flags, r, withRefs = []) {
|
|
|
13620
13986
|
}
|
|
13621
13987
|
}
|
|
13622
13988
|
return {
|
|
13623
|
-
words,
|
|
13989
|
+
words: words2,
|
|
13624
13990
|
launchRoles,
|
|
13625
13991
|
ink: endCardInk(lookPick.look, lookPick.roles),
|
|
13626
13992
|
mark,
|
|
@@ -13632,7 +13998,7 @@ async function releaseInputs(dir, flags, r, withRefs = []) {
|
|
|
13632
13998
|
async function cmdRender(argv) {
|
|
13633
13999
|
const { positionals, flags, multi } = parseArgs(
|
|
13634
14000
|
argv,
|
|
13635
|
-
|
|
14001
|
+
BOOLEAN_FLAGS12,
|
|
13636
14002
|
MULTI_FLAGS2
|
|
13637
14003
|
);
|
|
13638
14004
|
const dir = positionals[0];
|
|
@@ -13700,7 +14066,7 @@ async function cmdRender(argv) {
|
|
|
13700
14066
|
async function cmdFrames(argv) {
|
|
13701
14067
|
const { positionals, flags, multi } = parseArgs(
|
|
13702
14068
|
argv,
|
|
13703
|
-
|
|
14069
|
+
BOOLEAN_FLAGS12,
|
|
13704
14070
|
MULTI_FLAGS2
|
|
13705
14071
|
);
|
|
13706
14072
|
const dir = positionals[0];
|
|
@@ -13773,7 +14139,7 @@ async function cmdFrames(argv) {
|
|
|
13773
14139
|
async function cmdDeliver(argv) {
|
|
13774
14140
|
const { positionals, flags, multi } = parseArgs(
|
|
13775
14141
|
argv,
|
|
13776
|
-
|
|
14142
|
+
BOOLEAN_FLAGS12,
|
|
13777
14143
|
MULTI_FLAGS2
|
|
13778
14144
|
);
|
|
13779
14145
|
const dir = positionals[0];
|
|
@@ -13939,7 +14305,7 @@ async function officialTemplate(origin, ref) {
|
|
|
13939
14305
|
}
|
|
13940
14306
|
}
|
|
13941
14307
|
async function cmdDigest(argv) {
|
|
13942
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14308
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
13943
14309
|
const dir = positionals[0];
|
|
13944
14310
|
if (!dir)
|
|
13945
14311
|
throw new UsageError(
|
|
@@ -14003,7 +14369,7 @@ async function cmdDigest(argv) {
|
|
|
14003
14369
|
}
|
|
14004
14370
|
}
|
|
14005
14371
|
async function cmdOpen(argv) {
|
|
14006
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14372
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
14007
14373
|
const dir = positionals[0];
|
|
14008
14374
|
if (!dir) throw new UsageError("vos open <take> [--studio <url>]");
|
|
14009
14375
|
const r = createReporter(flags.json === true);
|
|
@@ -14041,7 +14407,7 @@ async function cmdOpen(argv) {
|
|
|
14041
14407
|
return EXIT_OK;
|
|
14042
14408
|
}
|
|
14043
14409
|
async function cmdJudge(argv) {
|
|
14044
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14410
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
14045
14411
|
const target = positionals[0];
|
|
14046
14412
|
const against = strFlag(flags, "against");
|
|
14047
14413
|
if (!target || !against)
|
|
@@ -14070,7 +14436,7 @@ Win rate so far: ${rate.wins} win(s), ${rate.ties} tie(s) of ${rate.judged} judg
|
|
|
14070
14436
|
return EXIT_OK;
|
|
14071
14437
|
}
|
|
14072
14438
|
async function cmdCallout(argv) {
|
|
14073
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14439
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
14074
14440
|
const dir = positionals[0];
|
|
14075
14441
|
const shape = positionals[1];
|
|
14076
14442
|
if (!dir || !shape || !isCalloutShape(shape))
|
|
@@ -14095,19 +14461,19 @@ async function cmdCallout(argv) {
|
|
|
14095
14461
|
);
|
|
14096
14462
|
const codeFile = strFlag(flags, "code-file");
|
|
14097
14463
|
const code = codeFile ? await readFile17(codeFile, "utf8") : strFlag(flags, "code");
|
|
14098
|
-
const
|
|
14464
|
+
const words2 = {
|
|
14099
14465
|
kicker: strFlag(flags, "kicker"),
|
|
14100
14466
|
title: strFlag(flags, "title"),
|
|
14101
14467
|
body: strFlag(flags, "body"),
|
|
14102
14468
|
code: code?.replace(/\\n/g, "\n")
|
|
14103
14469
|
};
|
|
14104
|
-
if (shape === "code" && !
|
|
14470
|
+
if (shape === "code" && !words2.code)
|
|
14105
14471
|
throw new UsageError(
|
|
14106
14472
|
'a code callout needs --code "\u2026" or --code-file <file>'
|
|
14107
14473
|
);
|
|
14108
|
-
if (shape === "note" && !
|
|
14474
|
+
if (shape === "note" && !words2.title)
|
|
14109
14475
|
throw new UsageError('a note needs --title "\u2026"');
|
|
14110
|
-
if (shape === "tag" && !
|
|
14476
|
+
if (shape === "tag" && !words2.kicker && !words2.title)
|
|
14111
14477
|
throw new UsageError('a tag needs --kicker "\u2026"');
|
|
14112
14478
|
const stepRaw = strFlag(flags, "step");
|
|
14113
14479
|
const atRaw = strFlag(flags, "at");
|
|
@@ -14118,7 +14484,7 @@ async function cmdCallout(argv) {
|
|
|
14118
14484
|
try {
|
|
14119
14485
|
composed = composeCallout(take.doc, register, {
|
|
14120
14486
|
shape,
|
|
14121
|
-
words,
|
|
14487
|
+
words: words2,
|
|
14122
14488
|
id: strFlag(flags, "id"),
|
|
14123
14489
|
step: stepRaw !== void 0 ? /^\d+$/.test(stepRaw) ? Number(stepRaw) : stepRaw : void 0,
|
|
14124
14490
|
at: atRaw !== void 0 ? Number(atRaw) : void 0,
|
|
@@ -14169,7 +14535,7 @@ async function cmdCallout(argv) {
|
|
|
14169
14535
|
return EXIT_OK;
|
|
14170
14536
|
}
|
|
14171
14537
|
async function cmdValidate(argv) {
|
|
14172
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14538
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
14173
14539
|
const target = positionals[0];
|
|
14174
14540
|
if (!target) throw new UsageError("vos validate <actions.json|take>");
|
|
14175
14541
|
const r = createReporter(flags.json === true);
|
|
@@ -14331,7 +14697,7 @@ async function cmdValidate(argv) {
|
|
|
14331
14697
|
async function cmdPush3(argv) {
|
|
14332
14698
|
const { positionals, flags, multi } = parseArgs(
|
|
14333
14699
|
argv,
|
|
14334
|
-
|
|
14700
|
+
BOOLEAN_FLAGS12,
|
|
14335
14701
|
MULTI_FLAGS2
|
|
14336
14702
|
);
|
|
14337
14703
|
const dir = positionals[0];
|
|
@@ -14395,7 +14761,7 @@ ${landedLines(landed)}` : "")
|
|
|
14395
14761
|
return EXIT_OK;
|
|
14396
14762
|
}
|
|
14397
14763
|
async function cmdPull2(argv) {
|
|
14398
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14764
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12, MULTI_FLAGS2);
|
|
14399
14765
|
const dir = positionals[0] ?? ".";
|
|
14400
14766
|
const r = createReporter(flags.json === true);
|
|
14401
14767
|
const result = await pullTake(
|
|
@@ -14508,6 +14874,10 @@ async function run(argv) {
|
|
|
14508
14874
|
}
|
|
14509
14875
|
case "delete":
|
|
14510
14876
|
return await cmdDelete(rest);
|
|
14877
|
+
case "trash":
|
|
14878
|
+
return await cmdTrash(rest);
|
|
14879
|
+
case "restore":
|
|
14880
|
+
return await cmdRestore(rest);
|
|
14511
14881
|
case "build":
|
|
14512
14882
|
return await cmdBuild(rest);
|
|
14513
14883
|
case "compare":
|
|
@@ -14560,7 +14930,7 @@ async function run(argv) {
|
|
|
14560
14930
|
}
|
|
14561
14931
|
}
|
|
14562
14932
|
async function cmdSession(argv) {
|
|
14563
|
-
const { positionals, flags } = parseArgs(argv,
|
|
14933
|
+
const { positionals, flags } = parseArgs(argv, BOOLEAN_FLAGS12);
|
|
14564
14934
|
const [sub, arg] = positionals;
|
|
14565
14935
|
const r = createReporter(flags.json === true);
|
|
14566
14936
|
const usage = "vos session open <url> --name <app> | check <name> [--url <url>] | list | rm <name>";
|
|
@@ -14700,4 +15070,4 @@ export {
|
|
|
14700
15070
|
verbHelp,
|
|
14701
15071
|
run
|
|
14702
15072
|
};
|
|
14703
|
-
//# sourceMappingURL=chunk-
|
|
15073
|
+
//# sourceMappingURL=chunk-67L7FPJR.js.map
|