@vanillaskyai/video 0.6.0 → 0.7.1
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/CHANGELOG.md +164 -0
- package/PUBLIC-API.md +123 -9
- package/README.md +69 -115
- package/dist/{bg-confetti-SHQI7ATB.js → bg-confetti-HITCGLGD.js} +1 -1
- package/dist/{bg-emoji-XYFRA63Q.js → bg-emoji-VU4UZYZN.js} +1 -1
- package/dist/{bg-media-G4XOQEAS.js → bg-media-L34PDQXJ.js} +2 -2
- package/dist/{brand-message-XHONEDNW.js → brand-message-FUJ4STFO.js} +1 -1
- package/dist/{builtin-server-YHEZ2JRF.js → builtin-server-KB7FKF6A.js} +2 -2
- package/dist/{chart-bar-HRHD57ML.js → chart-bar-EGPHJATL.js} +2 -2
- package/dist/{chart-counter-KFPV44RB.js → chart-counter-5FFWQNZO.js} +2 -2
- package/dist/{chart-progress-ring-OR2VOIHV.js → chart-progress-ring-JMXQLMLC.js} +2 -2
- package/dist/{chunk-66MNRUCR.js → chunk-2PYO6VAC.js} +51 -3
- package/dist/{chunk-ZQQQAAKP.js → chunk-2XT4MZ76.js} +33 -2
- package/dist/{chunk-PNS52FL4.js → chunk-5SLENAJW.js} +19 -6
- package/dist/{chunk-EFL34TXF.js → chunk-AITKH6QT.js} +24 -8
- package/dist/{chunk-FZHMQFG3.js → chunk-GAIOHGNR.js} +5 -21
- package/dist/{chunk-3RV4YKB3.js → chunk-JNN3EYVP.js} +51 -26
- package/dist/{chunk-HVCPEAQF.js → chunk-LKBZX7GV.js} +9 -6
- package/dist/{chunk-34O5BY6X.js → chunk-LLPMVDJZ.js} +21 -4
- package/dist/{chunk-G66Z5CWR.js → chunk-MMUXVA47.js} +27 -3
- package/dist/{chunk-7BGAU6C3.js → chunk-MXZSDGZQ.js} +2 -1
- package/dist/{chunk-3OU7HIEB.js → chunk-RE4IMWJR.js} +15 -31
- package/dist/{chunk-FVTMYS6U.js → chunk-RGF452LL.js} +1 -1
- package/dist/chunk-SKRGRKHY.js +142 -0
- package/dist/{chunk-TCEHK2BW.js → chunk-YJJC4N4D.js} +2 -1
- package/dist/cli.js +438 -30
- package/dist/{compose-video-JWIEDTEJ.js → compose-video-PD6LKKRK.js} +4 -4
- package/dist/{cta-logo-JJOGK4UC.js → cta-logo-YR7LYUR5.js} +1 -1
- package/dist/{cta-media-IQ3MAWEH.js → cta-media-DQJBKUO2.js} +2 -2
- package/dist/{events-BBP30j3c.d.ts → events-B6qS1Lsb.d.ts} +2 -2
- package/dist/{incoming-call-KXF67OT2.js → incoming-call-54KQ7O5A.js} +1 -1
- package/dist/index.d.ts +89 -3
- package/dist/index.js +12 -1
- package/dist/{infographic-before-after-2I7YZVDD.js → infographic-before-after-ROS52GOW.js} +1 -1
- package/dist/{infographic-feature-list-QDM4I7XE.js → infographic-feature-list-E7MGUDAN.js} +2 -2
- package/dist/{infographic-problem-solution-FMLJCPG6.js → infographic-problem-solution-3S6NGO5N.js} +2 -2
- package/dist/{infographic-stat-row-VFTIXS5F.js → infographic-stat-row-SYB7AB7H.js} +2 -2
- package/dist/{infographic-steps-L7W24Z35.js → infographic-steps-KCE6JWE2.js} +2 -2
- package/dist/{kit-DEG3fcaL.d.ts → kit-8g46H2RZ.d.ts} +1 -1
- package/dist/{prompt-input-F3CYU2XH.js → prompt-input-MHX4O42G.js} +1 -1
- package/dist/react.d.ts +194 -6
- package/dist/react.js +1849 -40
- package/dist/{reaction-2XCLOJOK.js → reaction-SLEGR3BE.js} +2 -2
- package/dist/server.d.ts +102 -4
- package/dist/server.js +972 -27
- package/dist/{showcase-code-KHSMIPG6.js → showcase-code-2HLAVKBM.js} +2 -2
- package/dist/{showcase-phone-M4CEANIW.js → showcase-phone-Q4HEO4LH.js} +2 -2
- package/dist/{showcase-terminal-26I3DYF7.js → showcase-terminal-DL45LUFG.js} +2 -2
- package/dist/{showcase-web-TY6CZV2Z.js → showcase-web-2QZO73FZ.js} +2 -2
- package/dist/{social-milestone-TF6MX7ET.js → social-milestone-GEFUQSBF.js} +1 -1
- package/dist/{social-notification-2RJDAZSF.js → social-notification-FJ5VHVLK.js} +1 -1
- package/dist/{social-review-stack-2ICKJQG7.js → social-review-stack-KXQCKFRP.js} +1 -1
- package/dist/{social-testimonial-X7OGADA3.js → social-testimonial-JZ7CHC7S.js} +1 -1
- package/dist/{social-tweet-TK7SH2F6.js → social-tweet-UCDXM25F.js} +1 -1
- package/dist/{system-prompt-4I6Z5HK3.js → system-prompt-RRXIWDDD.js} +5 -3
- package/dist/template-catalog.js +1 -1
- package/dist/templates.d.ts +3 -3
- package/dist/test.d.ts +2 -2
- package/dist/test.js +3 -3
- package/dist/{text-stream-J6EDDJP4.js → text-stream-ROTNGSD4.js} +2 -2
- package/dist/{types-BV9IqExh.d.ts → types-2wHBqtg8.d.ts} +29 -1
- package/dist/types-DrABlRa7.d.ts +46 -0
- package/docs/agent-integration.md +49 -25
- package/docs/architecture.md +37 -22
- package/docs/branding-and-personalization.md +1 -1
- package/docs/concepts.md +14 -0
- package/docs/custom-templates.md +9 -9
- package/docs/customization.md +41 -5
- package/docs/getting-started.md +81 -84
- package/docs/media-and-audio.md +103 -166
- package/docs/persistence.md +1 -1
- package/docs/production.md +81 -92
- package/docs/prompt-and-input.md +71 -161
- package/docs/provider-integration.md +91 -49
- package/docs/responsive-orientation.md +1 -1
- package/docs/security.md +6 -5
- package/docs/streaming-protocol.md +1 -1
- package/docs/testing.md +51 -43
- package/examples/custom-template/README.md +1 -1
- package/package.json +20 -22
- package/registry/items/barChart.json +6 -4
- package/registry/items/beforeAfter.json +1 -1
- package/registry/items/bigNumber.json +4 -3
- package/registry/items/brandMessage.json +3 -2
- package/registry/items/cardList.json +6 -4
- package/registry/items/codeEditor.json +4 -3
- package/registry/items/confetti.json +1 -1
- package/registry/items/ctaLogo.json +3 -2
- package/registry/items/ctaMedia.json +4 -3
- package/registry/items/emojiBurst.json +1 -1
- package/registry/items/incomingCall.json +3 -2
- package/registry/items/media.json +4 -3
- package/registry/items/milestone.json +3 -2
- package/registry/items/notification.json +3 -2
- package/registry/items/phoneMockup.json +4 -3
- package/registry/items/problemSolution.json +4 -3
- package/registry/items/progressRing.json +4 -3
- package/registry/items/promptInput.json +3 -2
- package/registry/items/reaction.json +2 -2
- package/registry/items/reviewStack.json +3 -2
- package/registry/items/steps.json +6 -4
- package/registry/items/terminal.json +5 -4
- package/registry/items/testimonial.json +3 -2
- package/registry/items/tripleStats.json +4 -3
- package/registry/items/tweet.json +3 -2
- package/registry/items/webMockup.json +4 -3
- package/starters/video-chat/.env.example +16 -0
- package/starters/video-chat/README.md +63 -0
- package/starters/video-chat/index.html +12 -0
- package/starters/video-chat/package.json +28 -0
- package/starters/video-chat/server.ts +152 -0
- package/starters/video-chat/src/main.tsx +8 -0
- package/starters/video-chat/stock.ts +139 -0
- package/starters/video-chat/tsconfig.json +20 -0
- package/starters/video-chat/vite.config.ts +81 -0
- package/styles/video-chat.css +713 -0
- package/docs/input-and-first-scene.md +0 -64
- package/docs/integrate-nextjs.md +0 -86
- package/docs/live-channels.md +0 -149
- package/docs/use-cases.md +0 -59
- package/examples/nextjs-quickstart/.env.example +0 -2
- package/examples/nextjs-quickstart/README.md +0 -27
- package/examples/nextjs-quickstart/next-env.d.ts +0 -4
- package/examples/nextjs-quickstart/package.json +0 -25
- package/examples/nextjs-quickstart/src/app/api/video/route.ts +0 -33
- package/examples/nextjs-quickstart/src/app/layout.tsx +0 -5
- package/examples/nextjs-quickstart/src/app/page.tsx +0 -31
- package/examples/nextjs-quickstart/tsconfig.json +0 -26
- package/examples/server-integrations/README.md +0 -20
- package/examples/server-integrations/src/ai-sdk-media.ts +0 -90
package/dist/cli.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-3O7OMMMF.js";
|
|
5
|
-
import {
|
|
6
|
-
getBuiltinTemplateMetadata,
|
|
7
|
-
listBuiltinTemplateMetadata
|
|
8
|
-
} from "./chunk-3RV4YKB3.js";
|
|
2
|
+
import "./chunk-AITKH6QT.js";
|
|
3
|
+
import "./chunk-5SLENAJW.js";
|
|
9
4
|
import {
|
|
10
5
|
isTemplatePropertyFormatSupported,
|
|
11
6
|
validateTemplateSchemaValue
|
|
12
7
|
} from "./chunk-352ZZCET.js";
|
|
8
|
+
import {
|
|
9
|
+
getBuiltinTemplateMetadata,
|
|
10
|
+
listBuiltinTemplateMetadata
|
|
11
|
+
} from "./chunk-JNN3EYVP.js";
|
|
12
|
+
import "./chunk-3O7OMMMF.js";
|
|
13
13
|
import {
|
|
14
14
|
assertTemplateTransitionMetadata
|
|
15
15
|
} from "./chunk-2E6T633S.js";
|
|
16
16
|
import {
|
|
17
17
|
BUILTIN_TEMPLATE_MANIFEST
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LKBZX7GV.js";
|
|
19
19
|
import {
|
|
20
20
|
externalVideoBackdropCapabilitySource
|
|
21
21
|
} from "./chunk-WJ6FLKNC.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./chunk-73NTSFFI.js";
|
|
28
28
|
|
|
29
29
|
// src/cli/index.ts
|
|
30
|
-
import { resolve as
|
|
30
|
+
import { resolve as resolve9 } from "path";
|
|
31
31
|
|
|
32
32
|
// src/cli/registry.ts
|
|
33
33
|
import { randomUUID } from "crypto";
|
|
@@ -342,7 +342,7 @@ function minimalEnvironment() {
|
|
|
342
342
|
return Object.fromEntries(names.flatMap((name) => process.env[name] == null ? [] : [[name, process.env[name]]]));
|
|
343
343
|
}
|
|
344
344
|
function delay(milliseconds) {
|
|
345
|
-
return new Promise((
|
|
345
|
+
return new Promise((resolve10) => setTimeout(resolve10, milliseconds));
|
|
346
346
|
}
|
|
347
347
|
function signalProcessGroup(pid, signal) {
|
|
348
348
|
try {
|
|
@@ -373,7 +373,7 @@ async function runTrustedSourceProcess(args, options) {
|
|
|
373
373
|
const operation = options.operation ?? "loading";
|
|
374
374
|
let cleanup;
|
|
375
375
|
let processId;
|
|
376
|
-
const result = new Promise((
|
|
376
|
+
const result = new Promise((resolve10, reject) => {
|
|
377
377
|
const child = spawn(process.execPath, [...args], {
|
|
378
378
|
cwd: options.cwd,
|
|
379
379
|
detached: true,
|
|
@@ -429,7 +429,7 @@ async function runTrustedSourceProcess(args, options) {
|
|
|
429
429
|
));
|
|
430
430
|
return;
|
|
431
431
|
}
|
|
432
|
-
|
|
432
|
+
resolve10(Buffer.concat(protocol).toString("utf8"));
|
|
433
433
|
});
|
|
434
434
|
});
|
|
435
435
|
try {
|
|
@@ -595,7 +595,7 @@ async function discoverProjectTemplates(cwd, options = {}) {
|
|
|
595
595
|
}
|
|
596
596
|
|
|
597
597
|
// src/cli/sync.ts
|
|
598
|
-
var GENERATED_NOTICE = "// Generated by `vanillasky sync`. Do not edit.\n";
|
|
598
|
+
var GENERATED_NOTICE = "// Generated by `vanillasky templates sync`. Do not edit.\n";
|
|
599
599
|
function browserSource(templates) {
|
|
600
600
|
const imports = templates.map(({ exportName, importPath }, index) => exportName === "default" ? `import template${index} from ${JSON.stringify(importPath)};` : `import { ${exportName} as template${index} } from ${JSON.stringify(importPath)};`);
|
|
601
601
|
const names = templates.map((_, index) => `template${index}`);
|
|
@@ -760,7 +760,7 @@ async function syncTemplates(options = {}) {
|
|
|
760
760
|
if (await currentSource(output.path) !== output.source) drifted.push(relative3(cwd, output.path));
|
|
761
761
|
}
|
|
762
762
|
if (options.check && drifted.length > 0) {
|
|
763
|
-
throw new Error(`Generated template files are out of date: ${drifted.join(", ")}. Run \`vanillasky sync\`.`);
|
|
763
|
+
throw new Error(`Generated template files are out of date: ${drifted.join(", ")}. Run \`vanillasky templates sync\`.`);
|
|
764
764
|
}
|
|
765
765
|
if (!options.check && drifted.length > 0) {
|
|
766
766
|
await mkdir(vanillaskyDirectory, { recursive: true });
|
|
@@ -1138,7 +1138,7 @@ async function checkTemplates(options = {}) {
|
|
|
1138
1138
|
}));
|
|
1139
1139
|
const generated = await inspectGeneratedTemplateStatus(cwd, templates);
|
|
1140
1140
|
if (!generated.current) {
|
|
1141
|
-
throw new Error(`Generated template files are out of date: ${generated.stale.join(", ")}. Run \`vanillasky sync\`.`);
|
|
1141
|
+
throw new Error(`Generated template files are out of date: ${generated.stale.join(", ")}. Run \`vanillasky templates sync\`.`);
|
|
1142
1142
|
}
|
|
1143
1143
|
let renders = 0;
|
|
1144
1144
|
for (const item2 of examples) {
|
|
@@ -1435,19 +1435,372 @@ async function findEffectiveTemplate(cwd, id) {
|
|
|
1435
1435
|
return (await effectiveTemplateCatalog(cwd)).find((entry) => entry.id === id);
|
|
1436
1436
|
}
|
|
1437
1437
|
|
|
1438
|
+
// src/cli/init.ts
|
|
1439
|
+
import { spawn as spawn2 } from "child_process";
|
|
1440
|
+
import {
|
|
1441
|
+
existsSync as existsSync3,
|
|
1442
|
+
mkdirSync as mkdirSync2,
|
|
1443
|
+
readFileSync as readFileSync2,
|
|
1444
|
+
renameSync as renameSync2,
|
|
1445
|
+
unlinkSync as unlinkSync2,
|
|
1446
|
+
writeFileSync as writeFileSync2
|
|
1447
|
+
} from "fs";
|
|
1448
|
+
import { basename as basename4, dirname as dirname3, isAbsolute, join as join8, resolve as resolve7 } from "path";
|
|
1449
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1450
|
+
|
|
1451
|
+
// src/cli/gitignore.ts
|
|
1452
|
+
var ROOT_ENVIRONMENT_FILE = ".env.local";
|
|
1453
|
+
function escapeRegex(character) {
|
|
1454
|
+
return /[\\^$.*+?()[\]{}|]/.test(character) ? `\\${character}` : character;
|
|
1455
|
+
}
|
|
1456
|
+
function matchesRootEnvironment(patternInput) {
|
|
1457
|
+
let pattern = patternInput;
|
|
1458
|
+
if (pattern.startsWith("/")) pattern = pattern.slice(1);
|
|
1459
|
+
while (pattern.startsWith("**/")) pattern = pattern.slice(3);
|
|
1460
|
+
if (pattern.endsWith("/") || pattern.includes("/")) return false;
|
|
1461
|
+
let expression = "^";
|
|
1462
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
1463
|
+
const character = pattern[index];
|
|
1464
|
+
if (character === "\\" && index + 1 < pattern.length) {
|
|
1465
|
+
expression += escapeRegex(pattern[index + 1]);
|
|
1466
|
+
index += 1;
|
|
1467
|
+
} else if (character === "*") {
|
|
1468
|
+
while (pattern[index + 1] === "*") index += 1;
|
|
1469
|
+
expression += ".*";
|
|
1470
|
+
} else if (character === "?") {
|
|
1471
|
+
expression += ".";
|
|
1472
|
+
} else if (character === "[") {
|
|
1473
|
+
const closing = pattern.indexOf("]", index + 1);
|
|
1474
|
+
if (closing === -1) expression += "\\[";
|
|
1475
|
+
else {
|
|
1476
|
+
const contents = pattern.slice(index + 1, closing);
|
|
1477
|
+
const negated = contents.startsWith("!") ? `^${contents.slice(1)}` : contents;
|
|
1478
|
+
expression += `[${negated.replaceAll("\\", "\\\\")}]`;
|
|
1479
|
+
index = closing;
|
|
1480
|
+
}
|
|
1481
|
+
} else {
|
|
1482
|
+
expression += escapeRegex(character);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
try {
|
|
1486
|
+
return new RegExp(`${expression}$`).test(ROOT_ENVIRONMENT_FILE);
|
|
1487
|
+
} catch {
|
|
1488
|
+
return false;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
function effectivelyIgnoresLocalEnvironment(source) {
|
|
1492
|
+
let ignored = false;
|
|
1493
|
+
for (const rawLine of source.replaceAll("\r\n", "\n").split("\n")) {
|
|
1494
|
+
let line = rawLine.trim();
|
|
1495
|
+
if (!line || line.startsWith("#")) continue;
|
|
1496
|
+
const negated = line.startsWith("!");
|
|
1497
|
+
if (negated) line = line.slice(1);
|
|
1498
|
+
if (!matchesRootEnvironment(line)) continue;
|
|
1499
|
+
ignored = !negated;
|
|
1500
|
+
}
|
|
1501
|
+
return ignored;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
// src/cli/init.ts
|
|
1505
|
+
var SCAFFOLD_FILES = [
|
|
1506
|
+
".env.example",
|
|
1507
|
+
"README.md",
|
|
1508
|
+
"index.html",
|
|
1509
|
+
"server.ts",
|
|
1510
|
+
"src/main.tsx",
|
|
1511
|
+
"stock.ts",
|
|
1512
|
+
"tsconfig.json",
|
|
1513
|
+
"vite.config.ts"
|
|
1514
|
+
];
|
|
1515
|
+
var DEFAULT_GITIGNORE = ["node_modules", "dist", ".env.local", ""].join("\n");
|
|
1516
|
+
function locateStarterRoot() {
|
|
1517
|
+
const moduleDirectory = dirname3(fileURLToPath2(import.meta.url));
|
|
1518
|
+
const candidates = [
|
|
1519
|
+
resolve7(moduleDirectory, "../../starters/video-chat"),
|
|
1520
|
+
resolve7(moduleDirectory, "../starters/video-chat")
|
|
1521
|
+
];
|
|
1522
|
+
const found = candidates.find((candidate) => existsSync3(join8(candidate, "package.json")));
|
|
1523
|
+
if (!found) throw new Error("The packaged video-chat starter is missing. Reinstall @vanillaskyai/video.");
|
|
1524
|
+
return found;
|
|
1525
|
+
}
|
|
1526
|
+
function readJson(path) {
|
|
1527
|
+
try {
|
|
1528
|
+
const value = JSON.parse(readFileSync2(path, "utf8"));
|
|
1529
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("expected an object");
|
|
1530
|
+
return value;
|
|
1531
|
+
} catch (cause) {
|
|
1532
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
1533
|
+
throw new Error(`Cannot read ${basename4(path)}: ${detail}`);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
function stringMap(value) {
|
|
1537
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
1538
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
1539
|
+
}
|
|
1540
|
+
function resolvedSdkSpec(starterRoot, invokedSpec) {
|
|
1541
|
+
const spec = invokedSpec?.trim();
|
|
1542
|
+
if (!spec) return void 0;
|
|
1543
|
+
if (spec === "@vanillaskyai/video" || spec.startsWith("@vanillaskyai/video@")) {
|
|
1544
|
+
const packageManifest = readJson(resolve7(starterRoot, "../..", "package.json"));
|
|
1545
|
+
return typeof packageManifest.version === "string" ? packageManifest.version : void 0;
|
|
1546
|
+
}
|
|
1547
|
+
if (spec.startsWith("file:")) return spec;
|
|
1548
|
+
return isAbsolute(spec) ? `file:${spec}` : void 0;
|
|
1549
|
+
}
|
|
1550
|
+
function mergedManifest(cwd, starterRoot, invokedSpec) {
|
|
1551
|
+
const destination = join8(cwd, "package.json");
|
|
1552
|
+
const existing = existsSync3(destination) ? readJson(destination) : {};
|
|
1553
|
+
const starter = readJson(join8(starterRoot, "package.json"));
|
|
1554
|
+
const packageName = typeof existing.name === "string" && existing.name.trim() ? existing.name : basename4(cwd).toLowerCase().replace(/[^a-z0-9._-]+/g, "-");
|
|
1555
|
+
const existingDependencies = stringMap(existing.dependencies);
|
|
1556
|
+
const starterDependencies = stringMap(starter.dependencies);
|
|
1557
|
+
const existingScripts = stringMap(existing.scripts);
|
|
1558
|
+
const starterScripts = stringMap(starter.scripts);
|
|
1559
|
+
for (const [name, command] of Object.entries(starterScripts)) {
|
|
1560
|
+
if (Object.prototype.hasOwnProperty.call(existingScripts, name) && existingScripts[name] !== command) {
|
|
1561
|
+
throw new Error(`package.json script ${name} already exists with a different command. Run init in a new npm project.`);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
if (Object.prototype.hasOwnProperty.call(existing, "type") && existing.type !== "module") {
|
|
1565
|
+
throw new Error(`package.json type ${String(existing.type)} is incompatible with the video-chat starter. Run init in a new npm project.`);
|
|
1566
|
+
}
|
|
1567
|
+
const sdkVersion = existingDependencies["@vanillaskyai/video"] ?? resolvedSdkSpec(starterRoot, invokedSpec) ?? starterDependencies["@vanillaskyai/video"];
|
|
1568
|
+
if (!sdkVersion) throw new Error("Install @vanillaskyai/video before running vanillasky init.");
|
|
1569
|
+
const dependencies = {
|
|
1570
|
+
...starterDependencies,
|
|
1571
|
+
...existingDependencies,
|
|
1572
|
+
"@vanillaskyai/video": sdkVersion
|
|
1573
|
+
};
|
|
1574
|
+
const devDependencies = {
|
|
1575
|
+
...stringMap(starter.devDependencies),
|
|
1576
|
+
...stringMap(existing.devDependencies)
|
|
1577
|
+
};
|
|
1578
|
+
const manifest = {
|
|
1579
|
+
...starter,
|
|
1580
|
+
...existing,
|
|
1581
|
+
name: packageName,
|
|
1582
|
+
private: true,
|
|
1583
|
+
type: "module",
|
|
1584
|
+
scripts: { ...existingScripts, ...starterScripts },
|
|
1585
|
+
dependencies,
|
|
1586
|
+
devDependencies
|
|
1587
|
+
};
|
|
1588
|
+
return `${JSON.stringify(manifest, null, 2)}
|
|
1589
|
+
`;
|
|
1590
|
+
}
|
|
1591
|
+
function mergeGitignore(existing) {
|
|
1592
|
+
if (existing == null) return DEFAULT_GITIGNORE;
|
|
1593
|
+
const lines = existing.replaceAll("\r\n", "\n").split("\n");
|
|
1594
|
+
for (const entry of ["node_modules", "dist"]) {
|
|
1595
|
+
if (!lines.includes(entry)) lines.push(entry);
|
|
1596
|
+
}
|
|
1597
|
+
if (!effectivelyIgnoresLocalEnvironment(lines.join("\n"))) lines.push(".env.local");
|
|
1598
|
+
return `${lines.filter((line, index) => line !== "" || index < lines.length - 1).join("\n")}
|
|
1599
|
+
`;
|
|
1600
|
+
}
|
|
1601
|
+
function atomicWrite(path, contents) {
|
|
1602
|
+
mkdirSync2(dirname3(path), { recursive: true });
|
|
1603
|
+
const temporary = `${path}.vanillasky-${process.pid}-${Math.random().toString(16).slice(2)}.tmp`;
|
|
1604
|
+
try {
|
|
1605
|
+
writeFileSync2(temporary, contents, { encoding: "utf8", flag: "wx", mode: 420 });
|
|
1606
|
+
renameSync2(temporary, path);
|
|
1607
|
+
} finally {
|
|
1608
|
+
if (existsSync3(temporary)) unlinkSync2(temporary);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
function defaultInstall(cwd) {
|
|
1612
|
+
return new Promise((resolvePromise, reject) => {
|
|
1613
|
+
const child = spawn2("npm", ["install", "--no-audit", "--no-fund"], {
|
|
1614
|
+
cwd,
|
|
1615
|
+
shell: false,
|
|
1616
|
+
stdio: "inherit"
|
|
1617
|
+
});
|
|
1618
|
+
child.once("error", reject);
|
|
1619
|
+
child.once("exit", (code, signal) => {
|
|
1620
|
+
if (code === 0) resolvePromise();
|
|
1621
|
+
else reject(new Error(`npm install failed${signal ? ` (${signal})` : code == null ? "" : ` with exit code ${code}`}`));
|
|
1622
|
+
});
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
async function initVideoChatApp(options) {
|
|
1626
|
+
const cwd = resolve7(options.cwd);
|
|
1627
|
+
const starterRoot = resolve7(options.starterRoot ?? locateStarterRoot());
|
|
1628
|
+
const planned = /* @__PURE__ */ new Map();
|
|
1629
|
+
for (const path of SCAFFOLD_FILES) {
|
|
1630
|
+
planned.set(path, readFileSync2(join8(starterRoot, path), "utf8"));
|
|
1631
|
+
}
|
|
1632
|
+
planned.set("package.json", mergedManifest(cwd, starterRoot, options.sdkSpec));
|
|
1633
|
+
planned.set(".gitignore", mergeGitignore(
|
|
1634
|
+
existsSync3(join8(cwd, ".gitignore")) ? readFileSync2(join8(cwd, ".gitignore"), "utf8") : void 0
|
|
1635
|
+
));
|
|
1636
|
+
if (!existsSync3(join8(cwd, ".env.local"))) {
|
|
1637
|
+
planned.set(".env.local", planned.get(".env.example"));
|
|
1638
|
+
}
|
|
1639
|
+
let changed = false;
|
|
1640
|
+
for (const [path, contents] of planned) {
|
|
1641
|
+
const destination = safeProjectPath(cwd, path);
|
|
1642
|
+
if (!existsSync3(destination)) {
|
|
1643
|
+
changed = true;
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
const current = readFileSync2(destination, "utf8");
|
|
1647
|
+
if (current === contents) continue;
|
|
1648
|
+
if (path === "package.json" || path === ".gitignore") {
|
|
1649
|
+
changed = true;
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
throw new Error(`${path} already exists with different content. Run init in a new npm project.`);
|
|
1653
|
+
}
|
|
1654
|
+
if (!changed) return { initialized: false, installed: false };
|
|
1655
|
+
for (const [path, contents] of planned) {
|
|
1656
|
+
const destination = safeProjectPath(cwd, path);
|
|
1657
|
+
if (!existsSync3(destination) || readFileSync2(destination, "utf8") !== contents) atomicWrite(destination, contents);
|
|
1658
|
+
}
|
|
1659
|
+
try {
|
|
1660
|
+
await (options.installDependencies ?? defaultInstall)(cwd);
|
|
1661
|
+
} catch (cause) {
|
|
1662
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
1663
|
+
throw new Error(`${detail}. The app files are ready; run npm install to finish setup.`);
|
|
1664
|
+
}
|
|
1665
|
+
return { initialized: true, installed: true };
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
// src/cli/doctor.ts
|
|
1669
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
1670
|
+
import { join as join9, resolve as resolve8 } from "path";
|
|
1671
|
+
var REQUIRED_FILES = [
|
|
1672
|
+
".env.local",
|
|
1673
|
+
"index.html",
|
|
1674
|
+
"server.ts",
|
|
1675
|
+
"src/main.tsx",
|
|
1676
|
+
"stock.ts",
|
|
1677
|
+
"tsconfig.json",
|
|
1678
|
+
"vite.config.ts"
|
|
1679
|
+
];
|
|
1680
|
+
var REQUIRED_DEPENDENCIES = [
|
|
1681
|
+
"@vanillaskyai/video",
|
|
1682
|
+
"@ai-sdk/anthropic",
|
|
1683
|
+
"@ai-sdk/xai",
|
|
1684
|
+
"@fal-ai/client",
|
|
1685
|
+
"ai",
|
|
1686
|
+
"react",
|
|
1687
|
+
"react-dom"
|
|
1688
|
+
];
|
|
1689
|
+
var PROVIDER_KEYS = /* @__PURE__ */ new Set(["ANTHROPIC_API_KEY", "XAI_API_KEY", "FAL_KEY", "PEXELS_API_KEY"]);
|
|
1690
|
+
var CLIENT_ENV_PREFIXES = ["VITE", "NEXT_PUBLIC"].map((prefix) => `${prefix}_`);
|
|
1691
|
+
function parseEnvironment(source) {
|
|
1692
|
+
const result = /* @__PURE__ */ new Map();
|
|
1693
|
+
for (const rawLine of source.replaceAll("\r\n", "\n").split("\n")) {
|
|
1694
|
+
const line = rawLine.trim();
|
|
1695
|
+
if (!line || line.startsWith("#")) continue;
|
|
1696
|
+
const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
|
|
1697
|
+
if (!match) continue;
|
|
1698
|
+
let value = match[2].trim();
|
|
1699
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1700
|
+
value = value.slice(1, -1);
|
|
1701
|
+
} else {
|
|
1702
|
+
value = value.replace(/\s+#.*$/, "").trim();
|
|
1703
|
+
}
|
|
1704
|
+
result.set(match[1], value);
|
|
1705
|
+
}
|
|
1706
|
+
return result;
|
|
1707
|
+
}
|
|
1708
|
+
function stringMap2(value) {
|
|
1709
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
1710
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
1711
|
+
}
|
|
1712
|
+
function isJsonObject(value) {
|
|
1713
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
1714
|
+
}
|
|
1715
|
+
function doctorVideoChatApp(cwdInput) {
|
|
1716
|
+
const cwd = resolve8(cwdInput);
|
|
1717
|
+
const lines = [];
|
|
1718
|
+
let ok = true;
|
|
1719
|
+
for (const path of REQUIRED_FILES) {
|
|
1720
|
+
if (!existsSync4(join9(cwd, path))) {
|
|
1721
|
+
ok = false;
|
|
1722
|
+
lines.push(`MISSING ${path}`);
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
let manifest = {};
|
|
1726
|
+
try {
|
|
1727
|
+
const parsed = JSON.parse(readFileSync3(join9(cwd, "package.json"), "utf8"));
|
|
1728
|
+
if (!isJsonObject(parsed)) throw new Error("expected an object");
|
|
1729
|
+
manifest = parsed;
|
|
1730
|
+
} catch {
|
|
1731
|
+
ok = false;
|
|
1732
|
+
lines.push("MISSING valid package.json");
|
|
1733
|
+
}
|
|
1734
|
+
const dependencies = { ...stringMap2(manifest.dependencies), ...stringMap2(manifest.devDependencies) };
|
|
1735
|
+
const missingDependencies = REQUIRED_DEPENDENCIES.filter((name) => !dependencies[name]);
|
|
1736
|
+
for (const name of missingDependencies) {
|
|
1737
|
+
ok = false;
|
|
1738
|
+
lines.push(`MISSING dependency ${name}`);
|
|
1739
|
+
}
|
|
1740
|
+
const scripts = stringMap2(manifest.scripts);
|
|
1741
|
+
if (scripts.dev !== "vite" || scripts.build !== "tsc && vite build") {
|
|
1742
|
+
ok = false;
|
|
1743
|
+
lines.push("MISSING video-chat dev/build scripts");
|
|
1744
|
+
}
|
|
1745
|
+
const ignore = existsSync4(join9(cwd, ".gitignore")) ? readFileSync3(join9(cwd, ".gitignore"), "utf8") : "";
|
|
1746
|
+
if (!effectivelyIgnoresLocalEnvironment(ignore)) {
|
|
1747
|
+
ok = false;
|
|
1748
|
+
lines.push("UNSAFE .env.local is not ignored");
|
|
1749
|
+
}
|
|
1750
|
+
const environment = existsSync4(join9(cwd, ".env.local")) ? parseEnvironment(readFileSync3(join9(cwd, ".env.local"), "utf8")) : /* @__PURE__ */ new Map();
|
|
1751
|
+
for (const name of environment.keys()) {
|
|
1752
|
+
if (CLIENT_ENV_PREFIXES.some((prefix) => name.startsWith(prefix) && PROVIDER_KEYS.has(name.slice(prefix.length)))) {
|
|
1753
|
+
ok = false;
|
|
1754
|
+
lines.push(`UNSAFE ${name} exposes a provider key to the browser`);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
lines.push("READY templates + browser voice");
|
|
1758
|
+
if (environment.get("ANTHROPIC_API_KEY")) lines.push("READY ANTHROPIC_API_KEY");
|
|
1759
|
+
else {
|
|
1760
|
+
ok = false;
|
|
1761
|
+
lines.push("MISSING ANTHROPIC_API_KEY in .env.local");
|
|
1762
|
+
}
|
|
1763
|
+
lines.push(environment.get("XAI_API_KEY") ? "READY generated speech" : "OPTIONAL generated speech \u2014 add XAI_API_KEY");
|
|
1764
|
+
lines.push(environment.get("FAL_KEY") ? "READY generated video + transcription" : "OPTIONAL generated video + transcription \u2014 add FAL_KEY");
|
|
1765
|
+
lines.push(environment.get("PEXELS_API_KEY") ? "READY stock media" : "OPTIONAL stock media \u2014 add PEXELS_API_KEY");
|
|
1766
|
+
if (existsSync4(join9(cwd, "vanillasky", "templates"))) {
|
|
1767
|
+
lines.push("CHECK custom templates with npx vanillasky templates check");
|
|
1768
|
+
}
|
|
1769
|
+
return { ok, lines };
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1438
1772
|
// src/cli/index.ts
|
|
1439
1773
|
function help() {
|
|
1774
|
+
return [
|
|
1775
|
+
"VanillaSky video chat",
|
|
1776
|
+
"",
|
|
1777
|
+
"Usage:",
|
|
1778
|
+
" vanillasky init",
|
|
1779
|
+
" vanillasky doctor",
|
|
1780
|
+
" vanillasky templates <command>",
|
|
1781
|
+
"",
|
|
1782
|
+
"Template commands:",
|
|
1783
|
+
" vanillasky templates list [--builtin] [--json]",
|
|
1784
|
+
" vanillasky templates describe <template> [--builtin] [--json]",
|
|
1785
|
+
" vanillasky templates add <template...> [--dry-run|--diff] [--overwrite]",
|
|
1786
|
+
" vanillasky templates add --all [--dry-run|--diff] [--overwrite]",
|
|
1787
|
+
" vanillasky templates sync [--check]",
|
|
1788
|
+
" vanillasky templates check",
|
|
1789
|
+
" vanillasky templates create <id>"
|
|
1790
|
+
].join("\n");
|
|
1791
|
+
}
|
|
1792
|
+
function templateHelp() {
|
|
1440
1793
|
return [
|
|
1441
1794
|
"VanillaSky source-owned templates",
|
|
1442
1795
|
"",
|
|
1443
1796
|
"Usage:",
|
|
1444
|
-
" vanillasky list [--builtin] [--json]",
|
|
1445
|
-
" vanillasky describe <template> [--builtin] [--json]",
|
|
1446
|
-
" vanillasky add <template...> [--dry-run|--diff] [--overwrite]",
|
|
1447
|
-
" vanillasky add --all [--dry-run|--diff] [--overwrite]",
|
|
1448
|
-
" vanillasky sync [--check]",
|
|
1449
|
-
" vanillasky check",
|
|
1450
|
-
" vanillasky create <id>"
|
|
1797
|
+
" vanillasky templates list [--builtin] [--json]",
|
|
1798
|
+
" vanillasky templates describe <template> [--builtin] [--json]",
|
|
1799
|
+
" vanillasky templates add <template...> [--dry-run|--diff] [--overwrite]",
|
|
1800
|
+
" vanillasky templates add --all [--dry-run|--diff] [--overwrite]",
|
|
1801
|
+
" vanillasky templates sync [--check]",
|
|
1802
|
+
" vanillasky templates check",
|
|
1803
|
+
" vanillasky templates create <id>"
|
|
1451
1804
|
].join("\n");
|
|
1452
1805
|
}
|
|
1453
1806
|
function unknownOption(command, args, allowed) {
|
|
@@ -1481,21 +1834,76 @@ function sanitizeTerminalOutput(value) {
|
|
|
1481
1834
|
function runVanillaSkyCli(argv, environment = {}) {
|
|
1482
1835
|
const output = environment.write ?? console.log;
|
|
1483
1836
|
const write = (line) => output(sanitizeTerminalOutput(line));
|
|
1484
|
-
const cwd =
|
|
1485
|
-
const [
|
|
1837
|
+
const cwd = resolve9(environment.cwd ?? process.cwd());
|
|
1838
|
+
const [rootCommand, ...rootArgs] = argv;
|
|
1839
|
+
if (rootCommand === "init") {
|
|
1840
|
+
return (async () => {
|
|
1841
|
+
try {
|
|
1842
|
+
const unknown = unknownOption("init", rootArgs, []);
|
|
1843
|
+
if (unknown) throw new Error(unknown);
|
|
1844
|
+
if (rootArgs.length > 0) throw new Error(`Unexpected init argument: ${rootArgs[0]}`);
|
|
1845
|
+
const result = await initVideoChatApp({
|
|
1846
|
+
cwd,
|
|
1847
|
+
starterRoot: environment.starterRoot,
|
|
1848
|
+
sdkSpec: environment.sdkSpec ?? process.env.npm_config_package,
|
|
1849
|
+
installDependencies: environment.installDependencies
|
|
1850
|
+
});
|
|
1851
|
+
if (!result.initialized) {
|
|
1852
|
+
write("Video chat is already initialized.");
|
|
1853
|
+
return 0;
|
|
1854
|
+
}
|
|
1855
|
+
write("Video chat initialized with packaged templates and browser voice.");
|
|
1856
|
+
write("Add ANTHROPIC_API_KEY to .env.local.");
|
|
1857
|
+
write("Then run: npm run dev");
|
|
1858
|
+
write("Check setup: npx vanillasky doctor");
|
|
1859
|
+
return 0;
|
|
1860
|
+
} catch (error) {
|
|
1861
|
+
write(error instanceof Error ? error.message : String(error));
|
|
1862
|
+
return 1;
|
|
1863
|
+
}
|
|
1864
|
+
})();
|
|
1865
|
+
}
|
|
1866
|
+
if (rootCommand === "doctor") {
|
|
1867
|
+
const unknown = unknownOption("doctor", rootArgs, []);
|
|
1868
|
+
if (unknown) {
|
|
1869
|
+
write(unknown);
|
|
1870
|
+
return 1;
|
|
1871
|
+
}
|
|
1872
|
+
if (rootArgs.length > 0) {
|
|
1873
|
+
write(`Unexpected doctor argument: ${rootArgs[0]}`);
|
|
1874
|
+
return 1;
|
|
1875
|
+
}
|
|
1876
|
+
const result = doctorVideoChatApp(cwd);
|
|
1877
|
+
for (const line of result.lines) write(line);
|
|
1878
|
+
return result.ok ? 0 : 1;
|
|
1879
|
+
}
|
|
1880
|
+
if (rootCommand !== "templates") {
|
|
1881
|
+
const removed = /* @__PURE__ */ new Set(["list", "describe", "add", "sync", "check", "create"]);
|
|
1882
|
+
if (rootCommand && removed.has(rootCommand)) {
|
|
1883
|
+
write(`Template commands moved. Use: vanillasky templates ${argv.join(" ")}`);
|
|
1884
|
+
return 1;
|
|
1885
|
+
}
|
|
1886
|
+
write(help());
|
|
1887
|
+
return rootCommand == null || rootCommand === "help" || rootCommand === "--help" || rootCommand === "-h" ? 0 : 1;
|
|
1888
|
+
}
|
|
1889
|
+
const [command, ...args] = rootArgs;
|
|
1890
|
+
if (command == null || command === "help" || command === "--help" || command === "-h") {
|
|
1891
|
+
write(templateHelp());
|
|
1892
|
+
return 0;
|
|
1893
|
+
}
|
|
1486
1894
|
if (command === "create") {
|
|
1487
1895
|
return (async () => {
|
|
1488
1896
|
try {
|
|
1489
1897
|
const unknown = unknownOption("create", args, []);
|
|
1490
1898
|
if (unknown) throw new Error(unknown);
|
|
1491
|
-
if (args.length === 0) throw new Error("Choose one template id. Usage: vanillasky create <id>.");
|
|
1899
|
+
if (args.length === 0) throw new Error("Choose one template id. Usage: vanillasky templates create <id>.");
|
|
1492
1900
|
if (args.length > 1) throw new Error(`Unexpected create argument: ${args[1]}`);
|
|
1493
1901
|
const id = args[0];
|
|
1494
1902
|
const result = await createTemplate({ cwd, id });
|
|
1495
1903
|
write(`Created template: ${result.path}`);
|
|
1496
1904
|
write(`Synced ${result.templates} template${result.templates === 1 ? "" : "s"} to vanillasky/index.ts and vanillasky/server.ts.`);
|
|
1497
1905
|
write(`Source: ${result.path}`);
|
|
1498
|
-
write("Validate templates: vanillasky check");
|
|
1906
|
+
write("Validate templates: vanillasky templates check");
|
|
1499
1907
|
for (const warning of result.warnings ?? []) write(`Warning: ${warning}`);
|
|
1500
1908
|
return 0;
|
|
1501
1909
|
} catch (error) {
|
|
@@ -1593,7 +2001,7 @@ function runVanillaSkyCli(argv, environment = {}) {
|
|
|
1593
2001
|
}
|
|
1594
2002
|
const names = addAll ? listRegistryTemplates().map(({ id }) => id) : positional;
|
|
1595
2003
|
if (names.length === 0) {
|
|
1596
|
-
write("Choose at least one template. Run `vanillasky list` to see the catalog.");
|
|
2004
|
+
write("Choose at least one template. Run `vanillasky templates list` to see the catalog.");
|
|
1597
2005
|
return 1;
|
|
1598
2006
|
}
|
|
1599
2007
|
return (async () => {
|
|
@@ -1649,7 +2057,7 @@ function runVanillaSkyCli(argv, environment = {}) {
|
|
|
1649
2057
|
const name = names[0];
|
|
1650
2058
|
const render = (item2) => {
|
|
1651
2059
|
if (!item2) {
|
|
1652
|
-
write(`Unknown template: ${name ?? ""}. Run \`vanillasky list\` to see the catalog.`);
|
|
2060
|
+
write(`Unknown template: ${name ?? ""}. Run \`vanillasky templates list\` to see the catalog.`);
|
|
1653
2061
|
return 1;
|
|
1654
2062
|
}
|
|
1655
2063
|
if (args.includes("--json")) {
|
|
@@ -1688,8 +2096,8 @@ function runVanillaSkyCli(argv, environment = {}) {
|
|
|
1688
2096
|
return 1;
|
|
1689
2097
|
});
|
|
1690
2098
|
}
|
|
1691
|
-
write(
|
|
1692
|
-
return
|
|
2099
|
+
write(templateHelp());
|
|
2100
|
+
return 1;
|
|
1693
2101
|
}
|
|
1694
2102
|
|
|
1695
2103
|
// src/cli.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createVideo
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RE4IMWJR.js";
|
|
4
4
|
import "./chunk-E7CL7UPB.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-GAIOHGNR.js";
|
|
6
|
+
import "./chunk-MMUXVA47.js";
|
|
7
|
+
import "./chunk-2PYO6VAC.js";
|
|
8
8
|
import "./chunk-AOWSXU2K.js";
|
|
9
9
|
import "./chunk-3O7OMMMF.js";
|
|
10
10
|
import "./chunk-XGRA2MUV.js";
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
SceneBackground,
|
|
7
7
|
getMediaBackgroundProps
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MXZSDGZQ.js";
|
|
9
9
|
import {
|
|
10
10
|
TemplateText
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YJJC4N4D.js";
|
|
12
12
|
import "./chunk-L5BTTCZV.js";
|
|
13
13
|
import "./chunk-FRN6WKHA.js";
|
|
14
14
|
import "./chunk-W3VDIBGR.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { b as VideoOrientation, V as VideoStyle, c as Video, a as VideoCapabilities, d as VideoAudio, e as VideoScene, f as VIDEO_PROTOCOL_VERSION } from './types-
|
|
1
|
+
import { b as VideoOrientation, V as VideoStyle, c as Video, a as VideoCapabilities, d as VideoAudio, e as VideoScene, f as VIDEO_PROTOCOL_VERSION } from './types-2wHBqtg8.js';
|
|
2
2
|
|
|
3
3
|
type VideoWarningCategory = "validation" | "readability" | "grounding" | "provider" | "media" | "protocol";
|
|
4
|
-
type VideoWarningCode = "scene_duration_adjusted" | "scene_omitted_unreadable" | "scene_omitted_for_closer" | "chart_scale_imbalance" | "plan_incomplete" | "plan_missing_closer" | "provider_warning" | "provider_diagnostics_unavailable";
|
|
4
|
+
type VideoWarningCode = "scene_duration_adjusted" | "scene_omitted_unreadable" | "scene_omitted_for_closer" | "scene_variable_clipped" | "chart_scale_imbalance" | "plan_incomplete" | "plan_missing_closer" | "provider_warning" | "provider_diagnostics_unavailable" | "media_budget_reached";
|
|
5
5
|
/** A bounded, client-safe diagnostic that never includes provider payloads. */
|
|
6
6
|
interface VideoWarning {
|
|
7
7
|
code: VideoWarningCode;
|