@vosjs/cli 0.65.3 → 0.66.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 +1 -1
- package/dist/{assetManifest-RQYJYQ7Q.js → assetManifest-RDHHKAAM.js} +3 -3
- package/dist/{chunk-7CIAU4QP.js → chunk-63KINQOJ.js} +2 -2
- package/dist/{chunk-CODEEH2Z.js → chunk-SFU4U3GM.js} +89 -38
- package/dist/chunk-SFU4U3GM.js.map +1 -0
- package/dist/{chunk-DU3ANWU4.js → chunk-TYGDQEEI.js} +2 -2
- package/dist/{chunk-WVQAZTYU.js → chunk-UQLC4BEZ.js} +13 -2
- package/dist/{chunk-WVQAZTYU.js.map → chunk-UQLC4BEZ.js.map} +1 -1
- package/dist/cli.js +6 -6
- package/dist/index.d.ts +6 -1
- package/dist/index.js +4 -4
- package/dist/{run-GYCIE77C.js → run-OY6B5AFZ.js} +5 -5
- package/package.json +5 -5
- package/schema/doc.schema.json +39 -3
- package/skills/vos-authoring/references/schema-reference.md +1 -1
- package/skills/vos-port/references/elements-and-context.md +7 -4
- package/dist/chunk-CODEEH2Z.js.map +0 -1
- /package/dist/{assetManifest-RQYJYQ7Q.js.map → assetManifest-RDHHKAAM.js.map} +0 -0
- /package/dist/{chunk-7CIAU4QP.js.map → chunk-63KINQOJ.js.map} +0 -0
- /package/dist/{chunk-DU3ANWU4.js.map → chunk-TYGDQEEI.js.map} +0 -0
- /package/dist/{run-GYCIE77C.js.map → run-OY6B5AFZ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -263,7 +263,7 @@ Verified the flow in agent-browser already? `vos actions from-agent-browser step
|
|
|
263
263
|
|
|
264
264
|
**Tilt.** `doc.tilt`: source-anchored, non-overlapping spans where the card leans to a pose and returns to rest: `[{ "id": "u0", "in": 4, "out": 8, "rx": 6, "ry": -9, "source": "manual" }]`. `rx`/`ry` are degrees (±45 hard limit; ±5..18 reads well); `+rx` brings the top edge toward the camera, `+ry` the left edge, so a lean toward a right-side focus is a negative `ry`. Rest is flat. `doc.tiltStyle` (`off`, `subtle`, `medium`, `strong`) is the intensity the planner derives automatic spans from.
|
|
265
265
|
|
|
266
|
-
**Text overlays.** `doc.overlays`: screen-space clips above the card, outside the zoom, output-anchored. `{ "id": "t0", "kind": "text", "start": 1, "duration": 3, "text": "Ship it", "preset": "title", "transform": { "x": 0.5, "y": 0.82, "scale": 1, "rotation": 0 }, "enter": "rise", "exit": "fade" }`. Presets `title`, `caption`, `label`, overridable with `size` (12..200 design px) and `color`; `\n` breaks lines; a caption (a layer with no referent) is a lower third at `y` ≈ 0.82. Enter and exit: `rise`, `fade`, `none`. Fonts load at render start, fail-open to system stacks.
|
|
266
|
+
**Text overlays.** `doc.overlays`: screen-space clips above the card, outside the zoom, output-anchored. `{ "id": "t0", "kind": "text", "start": 1, "duration": 3, "text": "Ship it", "preset": "title", "transform": { "x": 0.5, "y": 0.82, "scale": 1, "rotation": 0 }, "enter": "rise", "exit": "fade" }`. Presets `title`, `caption`, `label`, overridable with `size` (12..200 design px) and `color`; `\n` breaks lines; a caption (a layer with no referent) is a lower third at `y` ≈ 0.82. Enter and exit: `rise`, `fade`, `none`. Fonts load at render start, fail-open to system stacks. **Styled words are runs.** `text` is a string, or a list of runs when parts of it are set differently: `"text": [{ "text": "Ship " }, { "text": "faster", "weight": 700, "underline": true }]`. A run is a piece of text plus the fields in which it departs from the layer: `weight` (700 is bold; snapped to what the family hosts), `italic`, `color`, `underline`, `strike`, `highlight` (a colour behind it). There is no markup in the words (an asterisk is an asterisk), a style may start and end anywhere, a run may hold `\n`, and a per-word or per-character entrance keeps every unit in its own style. `vos validate` names a run field it does not know and prints the runs to write for a layer still using the retired `emphasis`.
|
|
267
267
|
|
|
268
268
|
**Callouts in the grammar.** `vos callout <take> note --step copy --kicker "index.css" --title "Every token you tuned, as CSS variables." --mark ring` writes a callout in the house grammar (three shapes a viewer learns once: `note`, a kicker, a title and a line; `tag`, one label on the accent; `code`, the payload block) from the product's REGISTER: `BRAND.md` beside the take (`bgA` the ground, `accent`, `fontBody`; a kit whose accent is RESERVED, a recorder's red that marks time and nothing else, names a `callout` role and the notes speak in that hue instead) or `--ground #hex --accent #hex --font "…"`. The card inverts the app's value in the product's hue (a light app gets a dark card, a dark app a light one), keeps the accent for the kicker, sets its title at 1.35× the app's body AS SEEN ON SCREEN at the layer's start (the camera's level is read from the document; `--body-px <n>` instead sets the body size on the DELIVERED frame and is never rescaled, which is the flag a rich capture needs, since a 2560-wide take on a padded frame sits near scale 0.6 and lands every default on the grammar's floor; the verb prints the three sizes and the scale it measured), lifts on a real shadow and a hairline, rises in and fades out, opens a beat after the step's press lands and closes before the next scroll or navigation, and is pinned to the step (`--side`, `--mark`, `--leader`, `--color` refine the pin; `--color` paints the mark and the leader, never the kicker, which is the accent). `--at <s> --seconds <n>` places one without a step; `--print` prints the clip instead of writing it. `vos validate <take> --picture` renders the footage under every html layer at its start and reports the ΔE between the card's ground and what it covers: under 8 is a problem (the card reads as one more panel), under 16 a warning. An unpinned html or media layer whose window holds a step with an element gets the pin named in a warning.
|
|
269
269
|
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
localManifestRefs,
|
|
5
5
|
pullManifest,
|
|
6
6
|
uploadManifest
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-63KINQOJ.js";
|
|
8
|
+
import "./chunk-UQLC4BEZ.js";
|
|
9
9
|
export {
|
|
10
10
|
hostedLiteralWarnings,
|
|
11
11
|
localManifestRefs,
|
|
12
12
|
pullManifest,
|
|
13
13
|
uploadManifest
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=assetManifest-
|
|
15
|
+
//# sourceMappingURL=assetManifest-RDHHKAAM.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
manifestRefs,
|
|
10
10
|
nameForType,
|
|
11
11
|
resolveMediaType
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UQLC4BEZ.js";
|
|
13
13
|
|
|
14
14
|
// src/plugin/assetManifest.ts
|
|
15
15
|
import {
|
|
@@ -700,4 +700,4 @@ export {
|
|
|
700
700
|
pullManifest,
|
|
701
701
|
hostedLiteralWarnings
|
|
702
702
|
};
|
|
703
|
-
//# sourceMappingURL=chunk-
|
|
703
|
+
//# sourceMappingURL=chunk-63KINQOJ.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
reencodeStill,
|
|
10
10
|
renderStill,
|
|
11
11
|
videoFormat
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TYGDQEEI.js";
|
|
13
13
|
import {
|
|
14
14
|
PREV_DOC_NAME,
|
|
15
15
|
RECORDING_NAME,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
uploadDocRefs,
|
|
34
34
|
uploadManifest,
|
|
35
35
|
writeJson
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-63KINQOJ.js";
|
|
37
37
|
import {
|
|
38
38
|
CREDENTIALS_PATH,
|
|
39
39
|
MEDIA_HEAD_BYTES,
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
clientId,
|
|
45
45
|
containerMismatch,
|
|
46
46
|
deriveSlug,
|
|
47
|
+
detailLine,
|
|
47
48
|
formatChanges,
|
|
48
49
|
hasFlag,
|
|
49
50
|
hostedAssetId,
|
|
@@ -64,7 +65,7 @@ import {
|
|
|
64
65
|
strFlag,
|
|
65
66
|
writeCredential,
|
|
66
67
|
writeSyncState
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-UQLC4BEZ.js";
|
|
68
69
|
import {
|
|
69
70
|
deadLine,
|
|
70
71
|
deadWarns
|
|
@@ -213,7 +214,12 @@ import {
|
|
|
213
214
|
pinCandidates,
|
|
214
215
|
pinRectOnScreen,
|
|
215
216
|
pinReferent,
|
|
216
|
-
|
|
217
|
+
marksEmphasis,
|
|
218
|
+
migrateTextClip,
|
|
219
|
+
plainText,
|
|
220
|
+
resolveOverlayStyle,
|
|
221
|
+
snapRunWeight,
|
|
222
|
+
RUN_STYLE_KEYS,
|
|
217
223
|
ratedSegments,
|
|
218
224
|
recommendedExportResolution,
|
|
219
225
|
resolvePins,
|
|
@@ -243,7 +249,7 @@ function wordsOf(text) {
|
|
|
243
249
|
return text.toLowerCase().split(/[^a-z0-9]+/).filter((x) => x.length >= 3 && !LABEL_STOPWORDS.has(x));
|
|
244
250
|
}
|
|
245
251
|
function layerWords(o) {
|
|
246
|
-
const src = typeof o.html === "string" ? o.html.replace(/<[^>]*>/g, " ") : typeof o.text === "string" ? o.text : "";
|
|
252
|
+
const src = typeof o.html === "string" ? o.html.replace(/<[^>]*>/g, " ") : typeof o.text === "string" || Array.isArray(o.text) ? plainText(o.text) : "";
|
|
247
253
|
return new Set(wordsOf(src));
|
|
248
254
|
}
|
|
249
255
|
function selectorLabelWords(selector) {
|
|
@@ -1062,28 +1068,75 @@ function lintDoc(docIn) {
|
|
|
1062
1068
|
}
|
|
1063
1069
|
checkPin(o, name, docIn, recording, problems, warnings);
|
|
1064
1070
|
if (o.kind === "text") {
|
|
1065
|
-
if (
|
|
1066
|
-
|
|
1071
|
+
if (Array.isArray(o.text)) {
|
|
1072
|
+
const HINTS = {
|
|
1073
|
+
bold: "weight: 700",
|
|
1074
|
+
fontWeight: "weight",
|
|
1075
|
+
strikethrough: "strike: true",
|
|
1076
|
+
background: "highlight",
|
|
1077
|
+
colour: "color"
|
|
1078
|
+
};
|
|
1079
|
+
o.text.forEach((run2, ri) => {
|
|
1080
|
+
const at2 = `${name}.text[${ri}]`;
|
|
1081
|
+
if (!run2 || typeof run2 !== "object" || Array.isArray(run2)) {
|
|
1082
|
+
problems.push(
|
|
1083
|
+
`${at2} must be a run: { text, weight?, italic?, color?, underline?, strike?, highlight? }`
|
|
1084
|
+
);
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
const r = run2;
|
|
1088
|
+
if (typeof r.text !== "string")
|
|
1089
|
+
problems.push(`${at2}.text must be a string`);
|
|
1090
|
+
else if (!r.text)
|
|
1091
|
+
warnings.push(`${at2} has no text and paints nothing; drop it`);
|
|
1092
|
+
for (const k of Object.keys(r)) {
|
|
1093
|
+
if (k === "text" || RUN_STYLE_KEYS.includes(k))
|
|
1094
|
+
continue;
|
|
1095
|
+
problems.push(
|
|
1096
|
+
`${at2}.${k} is not a run field (${RUN_STYLE_KEYS.join(", ")})${HINTS[k] ? `: write ${HINTS[k]}` : ""}`
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
if (r.weight !== void 0 && (!isNum(r.weight) || r.weight < 100 || r.weight > 900))
|
|
1100
|
+
problems.push(`${at2}.weight must be 100..900`);
|
|
1101
|
+
for (const k of ["italic", "underline", "strike"]) {
|
|
1102
|
+
if (r[k] !== void 0 && typeof r[k] !== "boolean")
|
|
1103
|
+
problems.push(`${at2}.${k} must be true or false`);
|
|
1104
|
+
}
|
|
1105
|
+
for (const k of ["color", "highlight"]) {
|
|
1106
|
+
if (r[k] !== void 0 && typeof r[k] !== "string")
|
|
1107
|
+
problems.push(`${at2}.${k} must be a CSS colour`);
|
|
1108
|
+
}
|
|
1109
|
+
if (isNum(r.weight) && r.weight >= 100 && r.weight <= 900) {
|
|
1110
|
+
const layer = o;
|
|
1111
|
+
const own = resolveOverlayStyle({ ...layer, text: "" }).weight;
|
|
1112
|
+
if (r.weight !== own && snapRunWeight(layer, r.weight) === own)
|
|
1113
|
+
warnings.push(
|
|
1114
|
+
`${at2}.weight ${r.weight} paints no differently: the layer's family hosts no weight nearer to it than the layer's own ${own}`
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
} else if (typeof o.text !== "string") {
|
|
1119
|
+
problems.push(
|
|
1120
|
+
`${name}.text must be a string, or a list of runs ([{ text, weight?, italic?, color?, underline?, strike?, highlight? }])`
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1067
1123
|
if (typeof o.preset === "string" && !PRESETS.includes(o.preset)) {
|
|
1068
1124
|
warnings.push(
|
|
1069
1125
|
`${name}.preset "${String(o.preset)}" is not a known preset (${PRESETS.join("|")}) \u2014 falls back to "title"`
|
|
1070
1126
|
);
|
|
1071
1127
|
}
|
|
1072
|
-
if (o.emphasis !== void 0) {
|
|
1073
|
-
const
|
|
1074
|
-
if (!em || typeof em !== "object" || Array.isArray(em)) {
|
|
1075
|
-
problems.push(
|
|
1076
|
-
`${name}.emphasis must be { weight?, color? } ({} turns *markers* on)`
|
|
1077
|
-
);
|
|
1078
|
-
} else {
|
|
1079
|
-
if (em.weight !== void 0 && (!isNum(em.weight) || em.weight < 100 || em.weight > 900))
|
|
1080
|
-
problems.push(`${name}.emphasis.weight must be 100..900`);
|
|
1081
|
-
if (em.color !== void 0 && typeof em.color !== "string")
|
|
1082
|
-
problems.push(`${name}.emphasis.color must be a CSS colour`);
|
|
1083
|
-
}
|
|
1084
|
-
} else if (typeof o.text === "string" && parseEmphasis(o.text) !== null) {
|
|
1128
|
+
if (o.emphasis !== void 0 && typeof o.text === "string") {
|
|
1129
|
+
const runs = migrateTextClip(o).text;
|
|
1085
1130
|
warnings.push(
|
|
1086
|
-
`${name}.
|
|
1131
|
+
`${name}.emphasis is retired (styled words are runs now, with no markers in the text). It is still read, but write it as: "text": ${JSON.stringify(runs)} and drop "emphasis"`
|
|
1132
|
+
);
|
|
1133
|
+
} else if (typeof o.text === "string" && marksEmphasis(o.text)) {
|
|
1134
|
+
const runs = migrateTextClip({
|
|
1135
|
+
...o,
|
|
1136
|
+
emphasis: {}
|
|
1137
|
+
}).text;
|
|
1138
|
+
warnings.push(
|
|
1139
|
+
`${name}.text has words between asterisks, which show as typed. To set them bold write runs: "text": ${JSON.stringify(runs)}`
|
|
1087
1140
|
);
|
|
1088
1141
|
}
|
|
1089
1142
|
if (o.size !== void 0 && (!isNum(o.size) || o.size < 12 || o.size > 200)) {
|
|
@@ -4332,8 +4385,9 @@ import {
|
|
|
4332
4385
|
computeCardLayout,
|
|
4333
4386
|
docStillTime as docStillTime2,
|
|
4334
4387
|
migrateHostedDoc,
|
|
4388
|
+
overlayPlainText,
|
|
4335
4389
|
overlayRect,
|
|
4336
|
-
resolveOverlayStyle
|
|
4390
|
+
resolveOverlayStyle as resolveOverlayStyle2
|
|
4337
4391
|
} from "@vosjs/studio-core";
|
|
4338
4392
|
var POSTER_CLASSES = [
|
|
4339
4393
|
"landscape",
|
|
@@ -4452,7 +4506,7 @@ function posterTextBoxes(doc, px, time) {
|
|
|
4452
4506
|
if (clip.kind !== "text") continue;
|
|
4453
4507
|
if (time < clip.start || time > clip.start + clip.duration) continue;
|
|
4454
4508
|
const rect = overlayRect(clip, estimateWidth, W, H);
|
|
4455
|
-
const style =
|
|
4509
|
+
const style = resolveOverlayStyle2(clip);
|
|
4456
4510
|
const r3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
4457
4511
|
out.push({
|
|
4458
4512
|
x: r3((rect.cx - rect.w / 2) / W),
|
|
@@ -4460,7 +4514,7 @@ function posterTextBoxes(doc, px, time) {
|
|
|
4460
4514
|
w: r3(rect.w / W),
|
|
4461
4515
|
h: r3(rect.h / H),
|
|
4462
4516
|
role: clip.preset === "title" ? "headline" : "body",
|
|
4463
|
-
label: clip.
|
|
4517
|
+
label: overlayPlainText(clip).split("\n")[0].slice(0, 40),
|
|
4464
4518
|
.../^#[0-9a-f]{6}$/i.test(style.color) ? { color: style.color } : {}
|
|
4465
4519
|
});
|
|
4466
4520
|
}
|
|
@@ -7128,16 +7182,6 @@ async function api(ctx, path, init) {
|
|
|
7128
7182
|
const r = await apiJson(ctx.origin, `/api${path}`, { ...init, key: ctx.key });
|
|
7129
7183
|
return { status: r.status, json: r.body };
|
|
7130
7184
|
}
|
|
7131
|
-
function detailLine(body) {
|
|
7132
|
-
const details = body.details;
|
|
7133
|
-
if (!Array.isArray(details) || !details.length) return "";
|
|
7134
|
-
const lines = details.map((d) => {
|
|
7135
|
-
const path = Array.isArray(d.path) ? d.path.join(".") : "";
|
|
7136
|
-
return `${path ? `${path}: ` : ""}${String(d.message ?? JSON.stringify(d))}`;
|
|
7137
|
-
});
|
|
7138
|
-
return `
|
|
7139
|
-
${lines.join("\n ")}`;
|
|
7140
|
-
}
|
|
7141
7185
|
function printChanges(r, changes, protectedIds) {
|
|
7142
7186
|
if (Array.isArray(changes)) {
|
|
7143
7187
|
for (const entry of changes) {
|
|
@@ -7641,6 +7685,7 @@ import { existsSync as existsSync13, realpathSync } from "fs";
|
|
|
7641
7685
|
function isLocalName(value) {
|
|
7642
7686
|
if (/^(https?:|data:|blob:|asset:|media:)/.test(value)) return false;
|
|
7643
7687
|
if (value.startsWith("$")) return false;
|
|
7688
|
+
if (value.startsWith("<svg") || value.startsWith("<?xml")) return false;
|
|
7644
7689
|
if (value.startsWith("/")) return existsSync13(value);
|
|
7645
7690
|
return true;
|
|
7646
7691
|
}
|
|
@@ -9154,14 +9199,15 @@ async function cmdDelete(argv) {
|
|
|
9154
9199
|
});
|
|
9155
9200
|
if (res.status !== 200 && res.status !== 204)
|
|
9156
9201
|
throw new Error(apiError(`delete ${vosId}`, res));
|
|
9202
|
+
const tracking = dir ?? trackingCwd(vosId);
|
|
9157
9203
|
let unlinked = false;
|
|
9158
|
-
if (
|
|
9159
|
-
rmSync2(join16(
|
|
9204
|
+
if (tracking) {
|
|
9205
|
+
rmSync2(join16(tracking, SYNC_STATE_NAME), { force: true });
|
|
9160
9206
|
unlinked = true;
|
|
9161
9207
|
}
|
|
9162
9208
|
const trashed = res.body.trashed === true;
|
|
9163
9209
|
const restoreUntil = typeof res.body.restoreUntil === "string" ? res.body.restoreUntil : null;
|
|
9164
|
-
const tail = unlinked ? `; ${dir} no longer tracks it` : "";
|
|
9210
|
+
const tail = unlinked ? `; ${dir ?? "this directory"} no longer tracks it` : "";
|
|
9165
9211
|
r.done(
|
|
9166
9212
|
{
|
|
9167
9213
|
id: vosId,
|
|
@@ -9179,6 +9225,11 @@ async function cmdDelete(argv) {
|
|
|
9179
9225
|
);
|
|
9180
9226
|
return EXIT_OK;
|
|
9181
9227
|
}
|
|
9228
|
+
function trackingCwd(vosId) {
|
|
9229
|
+
const cwd = process.cwd();
|
|
9230
|
+
if (!existsSync15(join16(cwd, SYNC_STATE_NAME))) return null;
|
|
9231
|
+
return readSyncState(cwd)?.vosId === vosId ? cwd : null;
|
|
9232
|
+
}
|
|
9182
9233
|
|
|
9183
9234
|
// src/plugin/buildProgram.ts
|
|
9184
9235
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -15095,4 +15146,4 @@ export {
|
|
|
15095
15146
|
verbHelp,
|
|
15096
15147
|
run
|
|
15097
15148
|
};
|
|
15098
|
-
//# sourceMappingURL=chunk-
|
|
15149
|
+
//# sourceMappingURL=chunk-SFU4U3GM.js.map
|