@vibeframe/mcp-server 0.57.2 → 0.58.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/dist/index.js +553 -99
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7126,9 +7126,9 @@ var init_project_builder = __esm({
|
|
|
7126
7126
|
}
|
|
7127
7127
|
});
|
|
7128
7128
|
|
|
7129
|
-
// ../../node_modules/.pnpm/esbuild@0.
|
|
7129
|
+
// ../../node_modules/.pnpm/esbuild@0.27.3/node_modules/esbuild/lib/main.js
|
|
7130
7130
|
var require_main = __commonJS({
|
|
7131
|
-
"../../node_modules/.pnpm/esbuild@0.
|
|
7131
|
+
"../../node_modules/.pnpm/esbuild@0.27.3/node_modules/esbuild/lib/main.js"(exports, module) {
|
|
7132
7132
|
"use strict";
|
|
7133
7133
|
var __defProp3 = Object.defineProperty;
|
|
7134
7134
|
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
|
|
@@ -7333,25 +7333,31 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7333
7333
|
var quote = JSON.stringify;
|
|
7334
7334
|
var buildLogLevelDefault = "warning";
|
|
7335
7335
|
var transformLogLevelDefault = "silent";
|
|
7336
|
-
function
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7336
|
+
function validateAndJoinStringArray(values, what) {
|
|
7337
|
+
const toJoin = [];
|
|
7338
|
+
for (const value of values) {
|
|
7339
|
+
validateStringValue(value, what);
|
|
7340
|
+
if (value.indexOf(",") >= 0) throw new Error(`Invalid ${what}: ${value}`);
|
|
7341
|
+
toJoin.push(value);
|
|
7342
|
+
}
|
|
7343
|
+
return toJoin.join(",");
|
|
7340
7344
|
}
|
|
7341
7345
|
var canBeAnything = () => null;
|
|
7342
7346
|
var mustBeBoolean = (value) => typeof value === "boolean" ? null : "a boolean";
|
|
7343
7347
|
var mustBeString = (value) => typeof value === "string" ? null : "a string";
|
|
7344
7348
|
var mustBeRegExp = (value) => value instanceof RegExp ? null : "a RegExp object";
|
|
7345
7349
|
var mustBeInteger = (value) => typeof value === "number" && value === (value | 0) ? null : "an integer";
|
|
7350
|
+
var mustBeValidPortNumber = (value) => typeof value === "number" && value === (value | 0) && value >= 0 && value <= 65535 ? null : "a valid port number";
|
|
7346
7351
|
var mustBeFunction = (value) => typeof value === "function" ? null : "a function";
|
|
7347
7352
|
var mustBeArray = (value) => Array.isArray(value) ? null : "an array";
|
|
7353
|
+
var mustBeArrayOfStrings = (value) => Array.isArray(value) && value.every((x) => typeof x === "string") ? null : "an array of strings";
|
|
7348
7354
|
var mustBeObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? null : "an object";
|
|
7349
7355
|
var mustBeEntryPoints = (value) => typeof value === "object" && value !== null ? null : "an array or an object";
|
|
7350
7356
|
var mustBeWebAssemblyModule = (value) => value instanceof WebAssembly.Module ? null : "a WebAssembly.Module";
|
|
7351
7357
|
var mustBeObjectOrNull = (value) => typeof value === "object" && !Array.isArray(value) ? null : "an object or null";
|
|
7352
7358
|
var mustBeStringOrBoolean = (value) => typeof value === "string" || typeof value === "boolean" ? null : "a string or a boolean";
|
|
7353
7359
|
var mustBeStringOrObject = (value) => typeof value === "string" || typeof value === "object" && value !== null && !Array.isArray(value) ? null : "a string or an object";
|
|
7354
|
-
var
|
|
7360
|
+
var mustBeStringOrArrayOfStrings = (value) => typeof value === "string" || Array.isArray(value) && value.every((x) => typeof x === "string") ? null : "a string or an array of strings";
|
|
7355
7361
|
var mustBeStringOrUint8Array = (value) => typeof value === "string" || value instanceof Uint8Array ? null : "a string or a Uint8Array";
|
|
7356
7362
|
var mustBeStringOrURL = (value) => typeof value === "string" || value instanceof URL ? null : "a string or a URL";
|
|
7357
7363
|
function getFlag3(object, keys2, key2, mustBeFn) {
|
|
@@ -7415,7 +7421,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7415
7421
|
let legalComments = getFlag3(options, keys2, "legalComments", mustBeString);
|
|
7416
7422
|
let sourceRoot = getFlag3(options, keys2, "sourceRoot", mustBeString);
|
|
7417
7423
|
let sourcesContent = getFlag3(options, keys2, "sourcesContent", mustBeBoolean);
|
|
7418
|
-
let target = getFlag3(options, keys2, "target",
|
|
7424
|
+
let target = getFlag3(options, keys2, "target", mustBeStringOrArrayOfStrings);
|
|
7419
7425
|
let format4 = getFlag3(options, keys2, "format", mustBeString);
|
|
7420
7426
|
let globalName = getFlag3(options, keys2, "globalName", mustBeString);
|
|
7421
7427
|
let mangleProps = getFlag3(options, keys2, "mangleProps", mustBeRegExp);
|
|
@@ -7426,8 +7432,8 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7426
7432
|
let minifyWhitespace = getFlag3(options, keys2, "minifyWhitespace", mustBeBoolean);
|
|
7427
7433
|
let minifyIdentifiers = getFlag3(options, keys2, "minifyIdentifiers", mustBeBoolean);
|
|
7428
7434
|
let lineLimit = getFlag3(options, keys2, "lineLimit", mustBeInteger);
|
|
7429
|
-
let drop = getFlag3(options, keys2, "drop",
|
|
7430
|
-
let dropLabels = getFlag3(options, keys2, "dropLabels",
|
|
7435
|
+
let drop = getFlag3(options, keys2, "drop", mustBeArrayOfStrings);
|
|
7436
|
+
let dropLabels = getFlag3(options, keys2, "dropLabels", mustBeArrayOfStrings);
|
|
7431
7437
|
let charset = getFlag3(options, keys2, "charset", mustBeString);
|
|
7432
7438
|
let treeShaking = getFlag3(options, keys2, "treeShaking", mustBeBoolean);
|
|
7433
7439
|
let ignoreAnnotations = getFlag3(options, keys2, "ignoreAnnotations", mustBeBoolean);
|
|
@@ -7440,17 +7446,15 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7440
7446
|
let define2 = getFlag3(options, keys2, "define", mustBeObject);
|
|
7441
7447
|
let logOverride = getFlag3(options, keys2, "logOverride", mustBeObject);
|
|
7442
7448
|
let supported = getFlag3(options, keys2, "supported", mustBeObject);
|
|
7443
|
-
let pure = getFlag3(options, keys2, "pure",
|
|
7449
|
+
let pure = getFlag3(options, keys2, "pure", mustBeArrayOfStrings);
|
|
7444
7450
|
let keepNames = getFlag3(options, keys2, "keepNames", mustBeBoolean);
|
|
7445
7451
|
let platform = getFlag3(options, keys2, "platform", mustBeString);
|
|
7446
7452
|
let tsconfigRaw = getFlag3(options, keys2, "tsconfigRaw", mustBeStringOrObject);
|
|
7453
|
+
let absPaths = getFlag3(options, keys2, "absPaths", mustBeArrayOfStrings);
|
|
7447
7454
|
if (legalComments) flags.push(`--legal-comments=${legalComments}`);
|
|
7448
7455
|
if (sourceRoot !== void 0) flags.push(`--source-root=${sourceRoot}`);
|
|
7449
7456
|
if (sourcesContent !== void 0) flags.push(`--sources-content=${sourcesContent}`);
|
|
7450
|
-
if (target) {
|
|
7451
|
-
if (Array.isArray(target)) flags.push(`--target=${Array.from(target).map(validateTarget).join(",")}`);
|
|
7452
|
-
else flags.push(`--target=${validateTarget(target)}`);
|
|
7453
|
-
}
|
|
7457
|
+
if (target) flags.push(`--target=${validateAndJoinStringArray(Array.isArray(target) ? target : [target], "target")}`);
|
|
7454
7458
|
if (format4) flags.push(`--format=${format4}`);
|
|
7455
7459
|
if (globalName) flags.push(`--global-name=${globalName}`);
|
|
7456
7460
|
if (platform) flags.push(`--platform=${platform}`);
|
|
@@ -7464,9 +7468,10 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7464
7468
|
if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`);
|
|
7465
7469
|
if (ignoreAnnotations) flags.push(`--ignore-annotations`);
|
|
7466
7470
|
if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, "drop")}`);
|
|
7467
|
-
if (dropLabels) flags.push(`--drop-labels=${
|
|
7468
|
-
if (
|
|
7469
|
-
if (
|
|
7471
|
+
if (dropLabels) flags.push(`--drop-labels=${validateAndJoinStringArray(dropLabels, "drop label")}`);
|
|
7472
|
+
if (absPaths) flags.push(`--abs-paths=${validateAndJoinStringArray(absPaths, "abs paths")}`);
|
|
7473
|
+
if (mangleProps) flags.push(`--mangle-props=${jsRegExpToGoRegExp(mangleProps)}`);
|
|
7474
|
+
if (reserveProps) flags.push(`--reserve-props=${jsRegExpToGoRegExp(reserveProps)}`);
|
|
7470
7475
|
if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`);
|
|
7471
7476
|
if (jsx) flags.push(`--jsx=${jsx}`);
|
|
7472
7477
|
if (jsxFactory) flags.push(`--jsx-factory=${jsxFactory}`);
|
|
@@ -7515,11 +7520,11 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7515
7520
|
let outdir = getFlag3(options, keys2, "outdir", mustBeString);
|
|
7516
7521
|
let outbase = getFlag3(options, keys2, "outbase", mustBeString);
|
|
7517
7522
|
let tsconfig = getFlag3(options, keys2, "tsconfig", mustBeString);
|
|
7518
|
-
let resolveExtensions = getFlag3(options, keys2, "resolveExtensions",
|
|
7519
|
-
let nodePathsInput = getFlag3(options, keys2, "nodePaths",
|
|
7520
|
-
let mainFields = getFlag3(options, keys2, "mainFields",
|
|
7521
|
-
let conditions = getFlag3(options, keys2, "conditions",
|
|
7522
|
-
let external = getFlag3(options, keys2, "external",
|
|
7523
|
+
let resolveExtensions = getFlag3(options, keys2, "resolveExtensions", mustBeArrayOfStrings);
|
|
7524
|
+
let nodePathsInput = getFlag3(options, keys2, "nodePaths", mustBeArrayOfStrings);
|
|
7525
|
+
let mainFields = getFlag3(options, keys2, "mainFields", mustBeArrayOfStrings);
|
|
7526
|
+
let conditions = getFlag3(options, keys2, "conditions", mustBeArrayOfStrings);
|
|
7527
|
+
let external = getFlag3(options, keys2, "external", mustBeArrayOfStrings);
|
|
7523
7528
|
let packages = getFlag3(options, keys2, "packages", mustBeString);
|
|
7524
7529
|
let alias = getFlag3(options, keys2, "alias", mustBeObject);
|
|
7525
7530
|
let loader = getFlag3(options, keys2, "loader", mustBeObject);
|
|
@@ -7528,7 +7533,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7528
7533
|
let entryNames = getFlag3(options, keys2, "entryNames", mustBeString);
|
|
7529
7534
|
let chunkNames = getFlag3(options, keys2, "chunkNames", mustBeString);
|
|
7530
7535
|
let assetNames = getFlag3(options, keys2, "assetNames", mustBeString);
|
|
7531
|
-
let inject = getFlag3(options, keys2, "inject",
|
|
7536
|
+
let inject = getFlag3(options, keys2, "inject", mustBeArrayOfStrings);
|
|
7532
7537
|
let banner = getFlag3(options, keys2, "banner", mustBeObject);
|
|
7533
7538
|
let footer = getFlag3(options, keys2, "footer", mustBeObject);
|
|
7534
7539
|
let entryPoints = getFlag3(options, keys2, "entryPoints", mustBeEntryPoints);
|
|
@@ -7550,37 +7555,13 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7550
7555
|
if (outbase) flags.push(`--outbase=${outbase}`);
|
|
7551
7556
|
if (tsconfig) flags.push(`--tsconfig=${tsconfig}`);
|
|
7552
7557
|
if (packages) flags.push(`--packages=${packages}`);
|
|
7553
|
-
if (resolveExtensions) {
|
|
7554
|
-
let values = [];
|
|
7555
|
-
for (let value of resolveExtensions) {
|
|
7556
|
-
validateStringValue(value, "resolve extension");
|
|
7557
|
-
if (value.indexOf(",") >= 0) throw new Error(`Invalid resolve extension: ${value}`);
|
|
7558
|
-
values.push(value);
|
|
7559
|
-
}
|
|
7560
|
-
flags.push(`--resolve-extensions=${values.join(",")}`);
|
|
7561
|
-
}
|
|
7558
|
+
if (resolveExtensions) flags.push(`--resolve-extensions=${validateAndJoinStringArray(resolveExtensions, "resolve extension")}`);
|
|
7562
7559
|
if (publicPath) flags.push(`--public-path=${publicPath}`);
|
|
7563
7560
|
if (entryNames) flags.push(`--entry-names=${entryNames}`);
|
|
7564
7561
|
if (chunkNames) flags.push(`--chunk-names=${chunkNames}`);
|
|
7565
7562
|
if (assetNames) flags.push(`--asset-names=${assetNames}`);
|
|
7566
|
-
if (mainFields) {
|
|
7567
|
-
|
|
7568
|
-
for (let value of mainFields) {
|
|
7569
|
-
validateStringValue(value, "main field");
|
|
7570
|
-
if (value.indexOf(",") >= 0) throw new Error(`Invalid main field: ${value}`);
|
|
7571
|
-
values.push(value);
|
|
7572
|
-
}
|
|
7573
|
-
flags.push(`--main-fields=${values.join(",")}`);
|
|
7574
|
-
}
|
|
7575
|
-
if (conditions) {
|
|
7576
|
-
let values = [];
|
|
7577
|
-
for (let value of conditions) {
|
|
7578
|
-
validateStringValue(value, "condition");
|
|
7579
|
-
if (value.indexOf(",") >= 0) throw new Error(`Invalid condition: ${value}`);
|
|
7580
|
-
values.push(value);
|
|
7581
|
-
}
|
|
7582
|
-
flags.push(`--conditions=${values.join(",")}`);
|
|
7583
|
-
}
|
|
7563
|
+
if (mainFields) flags.push(`--main-fields=${validateAndJoinStringArray(mainFields, "main field")}`);
|
|
7564
|
+
if (conditions) flags.push(`--conditions=${validateAndJoinStringArray(conditions, "condition")}`);
|
|
7584
7565
|
if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, "external")}`);
|
|
7585
7566
|
if (alias) {
|
|
7586
7567
|
for (let old in alias) {
|
|
@@ -7777,8 +7758,8 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
7777
7758
|
if (isFirstPacket) {
|
|
7778
7759
|
isFirstPacket = false;
|
|
7779
7760
|
let binaryVersion = String.fromCharCode(...bytes);
|
|
7780
|
-
if (binaryVersion !== "0.
|
|
7781
|
-
throw new Error(`Cannot start service: Host version "${"0.
|
|
7761
|
+
if (binaryVersion !== "0.27.3") {
|
|
7762
|
+
throw new Error(`Cannot start service: Host version "${"0.27.3"}" does not match binary version ${quote(binaryVersion)}`);
|
|
7782
7763
|
}
|
|
7783
7764
|
return;
|
|
7784
7765
|
}
|
|
@@ -8120,11 +8101,13 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8120
8101
|
watch: (options2 = {}) => new Promise((resolve44, reject) => {
|
|
8121
8102
|
if (!streamIn.hasFS) throw new Error(`Cannot use the "watch" API in this environment`);
|
|
8122
8103
|
const keys2 = {};
|
|
8104
|
+
const delay = getFlag3(options2, keys2, "delay", mustBeInteger);
|
|
8123
8105
|
checkForInvalidFlags(options2, keys2, `in watch() call`);
|
|
8124
8106
|
const request22 = {
|
|
8125
8107
|
command: "watch",
|
|
8126
8108
|
key: buildKey
|
|
8127
8109
|
};
|
|
8110
|
+
if (delay) request22.delay = delay;
|
|
8128
8111
|
sendRequest(refs3, request22, (error2) => {
|
|
8129
8112
|
if (error2) reject(new Error(error2));
|
|
8130
8113
|
else resolve44(void 0);
|
|
@@ -8133,12 +8116,13 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8133
8116
|
serve: (options2 = {}) => new Promise((resolve44, reject) => {
|
|
8134
8117
|
if (!streamIn.hasFS) throw new Error(`Cannot use the "serve" API in this environment`);
|
|
8135
8118
|
const keys2 = {};
|
|
8136
|
-
const port = getFlag3(options2, keys2, "port",
|
|
8119
|
+
const port = getFlag3(options2, keys2, "port", mustBeValidPortNumber);
|
|
8137
8120
|
const host = getFlag3(options2, keys2, "host", mustBeString);
|
|
8138
8121
|
const servedir = getFlag3(options2, keys2, "servedir", mustBeString);
|
|
8139
8122
|
const keyfile = getFlag3(options2, keys2, "keyfile", mustBeString);
|
|
8140
8123
|
const certfile = getFlag3(options2, keys2, "certfile", mustBeString);
|
|
8141
8124
|
const fallback2 = getFlag3(options2, keys2, "fallback", mustBeString);
|
|
8125
|
+
const cors = getFlag3(options2, keys2, "cors", mustBeObject);
|
|
8142
8126
|
const onRequest = getFlag3(options2, keys2, "onRequest", mustBeFunction);
|
|
8143
8127
|
checkForInvalidFlags(options2, keys2, `in serve() call`);
|
|
8144
8128
|
const request22 = {
|
|
@@ -8152,6 +8136,13 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8152
8136
|
if (keyfile !== void 0) request22.keyfile = keyfile;
|
|
8153
8137
|
if (certfile !== void 0) request22.certfile = certfile;
|
|
8154
8138
|
if (fallback2 !== void 0) request22.fallback = fallback2;
|
|
8139
|
+
if (cors) {
|
|
8140
|
+
const corsKeys = {};
|
|
8141
|
+
const origin = getFlag3(cors, corsKeys, "origin", mustBeStringOrArrayOfStrings);
|
|
8142
|
+
checkForInvalidFlags(cors, corsKeys, `on "cors" object`);
|
|
8143
|
+
if (Array.isArray(origin)) request22.corsOrigin = origin;
|
|
8144
|
+
else if (origin !== void 0) request22.corsOrigin = [origin];
|
|
8145
|
+
}
|
|
8155
8146
|
sendRequest(refs3, request22, (error2, response2) => {
|
|
8156
8147
|
if (error2) return reject(new Error(error2));
|
|
8157
8148
|
if (onRequest) {
|
|
@@ -8287,7 +8278,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8287
8278
|
if (filter4 == null) throw new Error(`onResolve() call is missing a filter`);
|
|
8288
8279
|
let id = nextCallbackID++;
|
|
8289
8280
|
onResolveCallbacks[id] = { name, callback, note: registeredNote };
|
|
8290
|
-
plugin2.onResolve.push({ id, filter: filter4
|
|
8281
|
+
plugin2.onResolve.push({ id, filter: jsRegExpToGoRegExp(filter4), namespace: namespace || "" });
|
|
8291
8282
|
},
|
|
8292
8283
|
onLoad(options, callback) {
|
|
8293
8284
|
let registeredText = `This error came from the "onLoad" callback registered here:`;
|
|
@@ -8299,7 +8290,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8299
8290
|
if (filter4 == null) throw new Error(`onLoad() call is missing a filter`);
|
|
8300
8291
|
let id = nextCallbackID++;
|
|
8301
8292
|
onLoadCallbacks[id] = { name, callback, note: registeredNote };
|
|
8302
|
-
plugin2.onLoad.push({ id, filter: filter4
|
|
8293
|
+
plugin2.onLoad.push({ id, filter: jsRegExpToGoRegExp(filter4), namespace: namespace || "" });
|
|
8303
8294
|
},
|
|
8304
8295
|
onDispose(callback) {
|
|
8305
8296
|
onDisposeCallbacks.push(callback);
|
|
@@ -8359,8 +8350,8 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8359
8350
|
let pluginData = getFlag3(result, keys2, "pluginData", canBeAnything);
|
|
8360
8351
|
let errors = getFlag3(result, keys2, "errors", mustBeArray);
|
|
8361
8352
|
let warnings = getFlag3(result, keys2, "warnings", mustBeArray);
|
|
8362
|
-
let watchFiles = getFlag3(result, keys2, "watchFiles",
|
|
8363
|
-
let watchDirs = getFlag3(result, keys2, "watchDirs",
|
|
8353
|
+
let watchFiles = getFlag3(result, keys2, "watchFiles", mustBeArrayOfStrings);
|
|
8354
|
+
let watchDirs = getFlag3(result, keys2, "watchDirs", mustBeArrayOfStrings);
|
|
8364
8355
|
checkForInvalidFlags(result, keys2, `from onResolve() callback in plugin ${quote(name)}`);
|
|
8365
8356
|
response.id = id2;
|
|
8366
8357
|
if (pluginName != null) response.pluginName = pluginName;
|
|
@@ -8405,8 +8396,8 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
8405
8396
|
let loader = getFlag3(result, keys2, "loader", mustBeString);
|
|
8406
8397
|
let errors = getFlag3(result, keys2, "errors", mustBeArray);
|
|
8407
8398
|
let warnings = getFlag3(result, keys2, "warnings", mustBeArray);
|
|
8408
|
-
let watchFiles = getFlag3(result, keys2, "watchFiles",
|
|
8409
|
-
let watchDirs = getFlag3(result, keys2, "watchDirs",
|
|
8399
|
+
let watchFiles = getFlag3(result, keys2, "watchFiles", mustBeArrayOfStrings);
|
|
8400
|
+
let watchDirs = getFlag3(result, keys2, "watchDirs", mustBeArrayOfStrings);
|
|
8410
8401
|
checkForInvalidFlags(result, keys2, `from onLoad() callback in plugin ${quote(name)}`);
|
|
8411
8402
|
response.id = id2;
|
|
8412
8403
|
if (pluginName != null) response.pluginName = pluginName;
|
|
@@ -8710,6 +8701,11 @@ ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
|
|
|
8710
8701
|
}
|
|
8711
8702
|
};
|
|
8712
8703
|
}
|
|
8704
|
+
function jsRegExpToGoRegExp(regexp) {
|
|
8705
|
+
let result = regexp.source;
|
|
8706
|
+
if (regexp.flags) result = `(?${regexp.flags})${result}`;
|
|
8707
|
+
return result;
|
|
8708
|
+
}
|
|
8713
8709
|
var fs8 = __require("fs");
|
|
8714
8710
|
var os11 = __require("os");
|
|
8715
8711
|
var path14 = __require("path");
|
|
@@ -8746,7 +8742,8 @@ ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
|
|
|
8746
8742
|
};
|
|
8747
8743
|
var knownWebAssemblyFallbackPackages = {
|
|
8748
8744
|
"android arm LE": "@esbuild/android-arm",
|
|
8749
|
-
"android x64 LE": "@esbuild/android-x64"
|
|
8745
|
+
"android x64 LE": "@esbuild/android-x64",
|
|
8746
|
+
"openharmony arm64 LE": "@esbuild/openharmony-arm64"
|
|
8750
8747
|
};
|
|
8751
8748
|
function pkgAndSubpathForCurrentPlatform() {
|
|
8752
8749
|
let pkg;
|
|
@@ -8886,7 +8883,7 @@ for your current platform.`);
|
|
|
8886
8883
|
"node_modules",
|
|
8887
8884
|
".cache",
|
|
8888
8885
|
"esbuild",
|
|
8889
|
-
`pnpapi-${pkg.replace("/", "-")}-${"0.
|
|
8886
|
+
`pnpapi-${pkg.replace("/", "-")}-${"0.27.3"}-${path14.basename(subpath)}`
|
|
8890
8887
|
);
|
|
8891
8888
|
if (!fs8.existsSync(binTargetPath)) {
|
|
8892
8889
|
fs8.mkdirSync(path14.dirname(binTargetPath), { recursive: true });
|
|
@@ -8919,7 +8916,7 @@ for your current platform.`);
|
|
|
8919
8916
|
}
|
|
8920
8917
|
}
|
|
8921
8918
|
var _a7;
|
|
8922
|
-
var isInternalWorkerThread = ((_a7 = worker_threads == null ? void 0 : worker_threads.workerData) == null ? void 0 : _a7.esbuildVersion) === "0.
|
|
8919
|
+
var isInternalWorkerThread = ((_a7 = worker_threads == null ? void 0 : worker_threads.workerData) == null ? void 0 : _a7.esbuildVersion) === "0.27.3";
|
|
8923
8920
|
var esbuildCommandAndArgs = () => {
|
|
8924
8921
|
if ((!ESBUILD_BINARY_PATH || false) && (path23.basename(__filename) !== "main.js" || path23.basename(__dirname) !== "lib")) {
|
|
8925
8922
|
throw new Error(
|
|
@@ -8986,7 +8983,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
8986
8983
|
}
|
|
8987
8984
|
}
|
|
8988
8985
|
};
|
|
8989
|
-
var version = "0.
|
|
8986
|
+
var version = "0.27.3";
|
|
8990
8987
|
var build = (options) => ensureServiceIsRunning().build(options);
|
|
8991
8988
|
var context3 = (buildOptions) => ensureServiceIsRunning().context(buildOptions);
|
|
8992
8989
|
var transform = (input3, options) => ensureServiceIsRunning().transform(input3, options);
|
|
@@ -9089,7 +9086,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
9089
9086
|
var ensureServiceIsRunning = () => {
|
|
9090
9087
|
if (longLivedService) return longLivedService;
|
|
9091
9088
|
let [command3, args] = esbuildCommandAndArgs();
|
|
9092
|
-
let child = child_process.spawn(command3, args.concat(`--service=${"0.
|
|
9089
|
+
let child = child_process.spawn(command3, args.concat(`--service=${"0.27.3"}`, "--ping"), {
|
|
9093
9090
|
windowsHide: true,
|
|
9094
9091
|
stdio: ["pipe", "pipe", "inherit"],
|
|
9095
9092
|
cwd: defaultWD
|
|
@@ -9193,7 +9190,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
9193
9190
|
esbuild: node_exports
|
|
9194
9191
|
});
|
|
9195
9192
|
callback(service);
|
|
9196
|
-
let stdout = child_process.execFileSync(command3, args.concat(`--service=${"0.
|
|
9193
|
+
let stdout = child_process.execFileSync(command3, args.concat(`--service=${"0.27.3"}`), {
|
|
9197
9194
|
cwd: defaultWD,
|
|
9198
9195
|
windowsHide: true,
|
|
9199
9196
|
input: stdin,
|
|
@@ -9213,7 +9210,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
9213
9210
|
var startWorkerThreadService = (worker_threads2) => {
|
|
9214
9211
|
let { port1: mainPort, port2: workerPort } = new worker_threads2.MessageChannel();
|
|
9215
9212
|
let worker = new worker_threads2.Worker(__filename, {
|
|
9216
|
-
workerData: { workerPort, defaultWD, esbuildVersion: "0.
|
|
9213
|
+
workerData: { workerPort, defaultWD, esbuildVersion: "0.27.3" },
|
|
9217
9214
|
transferList: [workerPort],
|
|
9218
9215
|
// From node's documentation: https://nodejs.org/api/worker_threads.html
|
|
9219
9216
|
//
|
|
@@ -446870,6 +446867,7 @@ var init_schema = __esm({
|
|
|
446870
446867
|
elevenlabs: "ELEVENLABS_API_KEY",
|
|
446871
446868
|
runway: "RUNWAY_API_SECRET",
|
|
446872
446869
|
kling: "KLING_API_KEY",
|
|
446870
|
+
fal: "FAL_KEY",
|
|
446873
446871
|
imgbb: "IMGBB_API_KEY",
|
|
446874
446872
|
replicate: "REPLICATE_API_TOKEN",
|
|
446875
446873
|
xai: "XAI_API_KEY",
|
|
@@ -450500,6 +450498,70 @@ function buildEmptyRootHtml(opts) {
|
|
|
450500
450498
|
</html>
|
|
450501
450499
|
`;
|
|
450502
450500
|
}
|
|
450501
|
+
function buildDesignMd(opts) {
|
|
450502
|
+
const { name, style } = opts;
|
|
450503
|
+
const intro = style ? `Visual identity for **${name}**, scaffolded from the **${style.name}** style (after ${style.designer}). Customise freely \u2014 this file is the single source of truth for every scene's palette, typography, and motion.` : `Visual identity for **${name}**. Fill the sections below before authoring any scene HTML or generating any backdrop. Pick a named style with \`vibe scene styles\` if you want a credible starting point.`;
|
|
450504
|
+
const moodLine = style ? `**Mood:** ${style.mood} \xB7 **Best for:** ${style.bestFor}` : `**Mood:** _(one line \u2014 what should the viewer FEEL?)_`;
|
|
450505
|
+
const palette = style ? `${style.palette.map((c) => `- \`${c}\``).join("\n")}
|
|
450506
|
+
|
|
450507
|
+
${style.paletteNotes}` : `- _hex_ \u2014 primary
|
|
450508
|
+
- _hex_ \u2014 accent
|
|
450509
|
+
|
|
450510
|
+
_2\u20133 colours max. Declare explicit hex values; never name colours abstractly._`;
|
|
450511
|
+
const typography = style ? style.typography : `_One family, two weights. State the role of each (headline / label / body)._`;
|
|
450512
|
+
const composition = style ? style.composition : `_Grid? Centered? Layered? How does negative space behave?_`;
|
|
450513
|
+
const motion = style ? `${style.motion}
|
|
450514
|
+
|
|
450515
|
+
**GSAP signature:** ${style.gsapSignature}` : `_How fast? Snappy or fluid? Overshoot or precision?_
|
|
450516
|
+
|
|
450517
|
+
**GSAP signature:** _e.g. \`expo.out\`, \`sine.inOut\`, \`back.out(1.8)\`_`;
|
|
450518
|
+
const transition = style ? style.transition : `_Which Hyperframes shader matches the energy? (Cinematic Zoom, Cross-Warp Morph, Glitch, Domain Warp, \u2026)_`;
|
|
450519
|
+
const avoid = style ? style.avoid.map((a) => `- ${a}`).join("\n") : `- _anti-pattern 1_
|
|
450520
|
+
- _anti-pattern 2_
|
|
450521
|
+
- _anti-pattern 3_`;
|
|
450522
|
+
return `# ${name} \u2014 Design
|
|
450523
|
+
|
|
450524
|
+
> **Hard-gate.** This file defines the visual identity of every scene.
|
|
450525
|
+
> Author it before generating any HTML, backdrop image, or motion.
|
|
450526
|
+
> The Hyperframes \`hyperframes\` skill enforces this: scenes that
|
|
450527
|
+
> contradict DESIGN.md are rejected.
|
|
450528
|
+
|
|
450529
|
+
${intro}
|
|
450530
|
+
|
|
450531
|
+
## Style
|
|
450532
|
+
|
|
450533
|
+
${moodLine}
|
|
450534
|
+
|
|
450535
|
+
## Palette
|
|
450536
|
+
|
|
450537
|
+
${palette}
|
|
450538
|
+
|
|
450539
|
+
## Typography
|
|
450540
|
+
|
|
450541
|
+
${typography}
|
|
450542
|
+
|
|
450543
|
+
## Composition
|
|
450544
|
+
|
|
450545
|
+
${composition}
|
|
450546
|
+
|
|
450547
|
+
## Motion
|
|
450548
|
+
|
|
450549
|
+
${motion}
|
|
450550
|
+
|
|
450551
|
+
## Transition
|
|
450552
|
+
|
|
450553
|
+
${transition}
|
|
450554
|
+
|
|
450555
|
+
## What NOT to do
|
|
450556
|
+
|
|
450557
|
+
${avoid}
|
|
450558
|
+
|
|
450559
|
+
---
|
|
450560
|
+
|
|
450561
|
+
_Browse other named styles: \`vibe scene styles\`_
|
|
450562
|
+
${style ? `_This file was seeded by \`vibe scene init --visual-style "${style.name}"\`._` : `_Seed this file from a named style: \`vibe scene init <dir> --visual-style "<name>"\`._`}
|
|
450563
|
+
`;
|
|
450564
|
+
}
|
|
450503
450565
|
function buildProjectClaudeMd(name) {
|
|
450504
450566
|
return `# ${name} \u2014 Scene Authoring Project
|
|
450505
450567
|
|
|
@@ -450507,6 +450569,16 @@ This project is **bilingual**: it works with both VibeFrame (\`vibe\`) and
|
|
|
450507
450569
|
HeyGen Hyperframes (\`hyperframes\`). You can run either CLI inside this
|
|
450508
450570
|
directory.
|
|
450509
450571
|
|
|
450572
|
+
## Visual identity hard-gate
|
|
450573
|
+
|
|
450574
|
+
**Author \`DESIGN.md\` before any scene HTML.** It defines palette,
|
|
450575
|
+
typography, motion, and transition rules. Both the agent-driven path and
|
|
450576
|
+
the fallback emit reference it; scenes that contradict DESIGN.md are
|
|
450577
|
+
rejected by the Hyperframes \`hyperframes\` skill.
|
|
450578
|
+
|
|
450579
|
+
Browse named styles: \`vibe scene styles\`. Re-seed from one with
|
|
450580
|
+
\`vibe scene init . --visual-style "Swiss Pulse"\` (idempotent).
|
|
450581
|
+
|
|
450510
450582
|
## Skills \u2014 USE THESE FIRST
|
|
450511
450583
|
|
|
450512
450584
|
**Always invoke the relevant skill before authoring scenes.** Skills encode
|
|
@@ -450515,14 +450587,23 @@ semantics, VibeFrame pipeline conventions) that are NOT in generic web docs.
|
|
|
450515
450587
|
|
|
450516
450588
|
| Skill | Command | When to use |
|
|
450517
450589
|
| ----------------- | ---------------- | ------------------------------------------------------------------------------------- |
|
|
450518
|
-
| **
|
|
450519
|
-
| **
|
|
450590
|
+
| **hyperframes** | \`/hyperframes\` | Cinematic-quality composition \u2014 DESIGN.md hard-gate, named styles, motion principles |
|
|
450591
|
+
| **vibe-scene** | \`/vibe-scene\` | VibeFrame's authoring loop, AI assets, lint feedback, pipeline integration |
|
|
450520
450592
|
| **gsap** | \`/gsap\` | GSAP tweens, timelines, easing |
|
|
450521
450593
|
|
|
450522
|
-
|
|
450594
|
+
Install the Hyperframes skills once per machine:
|
|
450595
|
+
|
|
450596
|
+
\`\`\`bash
|
|
450597
|
+
npx skills add heygen-com/hyperframes
|
|
450598
|
+
\`\`\`
|
|
450599
|
+
|
|
450600
|
+
Restart your agent session (or reload the skill list) after installing.
|
|
450601
|
+
If skills aren't available, follow the **Key Rules** below \u2014 they cover
|
|
450602
|
+
the framework-level minimum, not the cinematic craft layer.
|
|
450523
450603
|
|
|
450524
450604
|
## Project structure
|
|
450525
450605
|
|
|
450606
|
+
- \`DESIGN.md\` \u2014 visual identity contract (palette, type, motion, transitions)
|
|
450526
450607
|
- \`index.html\` \u2014 root composition (timeline)
|
|
450527
450608
|
- \`compositions/scene-*.html\` \u2014 per-scene HTML authored by you or the agent
|
|
450528
450609
|
- \`assets/\` \u2014 shared media (narration audio, images, video)
|
|
@@ -450640,6 +450721,17 @@ async function scaffoldSceneProject(opts) {
|
|
|
450640
450721
|
await writeFile10(claudePath, buildProjectClaudeMd(name), "utf-8");
|
|
450641
450722
|
created.push(claudePath);
|
|
450642
450723
|
}
|
|
450724
|
+
const designPath = resolve20(dir, "DESIGN.md");
|
|
450725
|
+
if (await pathExists(designPath)) {
|
|
450726
|
+
skipped.push(designPath);
|
|
450727
|
+
} else {
|
|
450728
|
+
await writeFile10(
|
|
450729
|
+
designPath,
|
|
450730
|
+
buildDesignMd({ name, style: opts.visualStyle }),
|
|
450731
|
+
"utf-8"
|
|
450732
|
+
);
|
|
450733
|
+
created.push(designPath);
|
|
450734
|
+
}
|
|
450643
450735
|
const gitignorePath = resolve20(dir, ".gitignore");
|
|
450644
450736
|
if (await pathExists(gitignorePath)) {
|
|
450645
450737
|
skipped.push(gitignorePath);
|
|
@@ -450688,6 +450780,52 @@ function buildTranscriptTweens(transcript, targetSelector) {
|
|
|
450688
450780
|
return `tl.fromTo('${sel}', { opacity: 0, y: 10 }, { opacity: 1, y: 0, duration: 0.18, ease: 'power2.out' }, ${start});`;
|
|
450689
450781
|
}).join("\n ");
|
|
450690
450782
|
}
|
|
450783
|
+
function crossfadeTweens(scope, dur) {
|
|
450784
|
+
return `tl.from('${scope}', { opacity: 0, duration: ${SCENE_OVERLAP_SECONDS}, ease: 'power2.out' }, 0);
|
|
450785
|
+
tl.to('${scope}', { opacity: 0, duration: ${SCENE_OVERLAP_SECONDS}, ease: 'power2.in' }, ${(dur - SCENE_OVERLAP_SECONDS).toFixed(2)});`;
|
|
450786
|
+
}
|
|
450787
|
+
function fitFontSize(text, baseMaxPx, minPx, comfortableChars) {
|
|
450788
|
+
const charCount = text.length;
|
|
450789
|
+
if (charCount <= comfortableChars) return baseMaxPx;
|
|
450790
|
+
const ratio = comfortableChars / charCount;
|
|
450791
|
+
return Math.max(minPx, Math.round(baseMaxPx * ratio));
|
|
450792
|
+
}
|
|
450793
|
+
function fitKineticFontSize(words) {
|
|
450794
|
+
const totalChars = words.join(" ").length;
|
|
450795
|
+
if (totalChars <= 18) return 180;
|
|
450796
|
+
if (totalChars <= 26) return 140;
|
|
450797
|
+
if (totalChars <= 38) return 110;
|
|
450798
|
+
if (totalChars <= 54) return 90;
|
|
450799
|
+
return 72;
|
|
450800
|
+
}
|
|
450801
|
+
function kenBurnsTween(scope, dur, endScale = 1.08) {
|
|
450802
|
+
return `tl.fromTo('${scope} .backdrop', { scale: 1.0 }, { scale: ${endScale}, duration: ${dur.toFixed(2)}, ease: 'none' }, 0);`;
|
|
450803
|
+
}
|
|
450804
|
+
function idleHeroPulse(scope, selector, idleStart, dur) {
|
|
450805
|
+
const cycleDur = 1.5;
|
|
450806
|
+
const idleEnd = dur - SCENE_OVERLAP_SECONDS;
|
|
450807
|
+
const window3 = idleEnd - idleStart;
|
|
450808
|
+
if (window3 < cycleDur) return "";
|
|
450809
|
+
const plays = Math.max(1, Math.floor(window3 / cycleDur));
|
|
450810
|
+
const repeat = plays - 1;
|
|
450811
|
+
return `tl.to('${scope} ${selector}', { scale: 1.04, y: -8, duration: ${cycleDur}, yoyo: true, repeat: ${repeat}, ease: 'sine.inOut' }, ${idleStart.toFixed(2)});`;
|
|
450812
|
+
}
|
|
450813
|
+
function kineticWordBobs(scope, wordCount, idleStart, dur) {
|
|
450814
|
+
const cycleDur = 1.8;
|
|
450815
|
+
const idleEnd = dur - SCENE_OVERLAP_SECONDS;
|
|
450816
|
+
const window3 = idleEnd - idleStart;
|
|
450817
|
+
if (window3 < cycleDur) return "";
|
|
450818
|
+
const plays = Math.max(1, Math.floor(window3 / cycleDur));
|
|
450819
|
+
const repeat = plays - 1;
|
|
450820
|
+
const lines = [];
|
|
450821
|
+
for (let i = 0; i < wordCount; i++) {
|
|
450822
|
+
const start = (idleStart + i * 0.18).toFixed(2);
|
|
450823
|
+
lines.push(
|
|
450824
|
+
`tl.to('${scope} #w-${i}', { y: -12, duration: ${cycleDur}, yoyo: true, repeat: ${repeat}, ease: 'sine.inOut' }, ${start});`
|
|
450825
|
+
);
|
|
450826
|
+
}
|
|
450827
|
+
return lines.join("\n ");
|
|
450828
|
+
}
|
|
450691
450829
|
function buildPreset(input3) {
|
|
450692
450830
|
const id = input3.id;
|
|
450693
450831
|
const scope = `[data-composition-id="${id}"]`;
|
|
@@ -450724,7 +450862,8 @@ function buildPreset(input3) {
|
|
|
450724
450862
|
const captionInner = useWordSync ? renderTranscriptSpans(transcript) : esc(captionText);
|
|
450725
450863
|
const wordCss = useWordSync ? `
|
|
450726
450864
|
${scope} .caption .word { display: inline-block; opacity: 0; }` : "";
|
|
450727
|
-
const
|
|
450865
|
+
const captionFontPx = fitFontSize(captionText, 56, 28, 60);
|
|
450866
|
+
const captionTween = useWordSync ? buildTranscriptTweens(transcript, `${scope} .caption .word`) : `tl.from('${scope} .caption', { opacity: 0, y: 28, duration: 0.45, ease: 'power3.out' }, 0.05);`;
|
|
450728
450867
|
return {
|
|
450729
450868
|
css: `${scope} {
|
|
450730
450869
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450732,21 +450871,27 @@ function buildPreset(input3) {
|
|
|
450732
450871
|
color: #fff; overflow: hidden; background: #000;
|
|
450733
450872
|
}
|
|
450734
450873
|
${backdrop}
|
|
450874
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450735
450875
|
${scope} .caption {
|
|
450736
450876
|
position: absolute;
|
|
450737
450877
|
left: 8%; right: 8%; bottom: 12%;
|
|
450738
450878
|
text-align: center;
|
|
450739
|
-
font-size:
|
|
450879
|
+
font-size: ${captionFontPx}px;
|
|
450740
450880
|
font-weight: 700;
|
|
450741
450881
|
line-height: 1.2;
|
|
450882
|
+
overflow-wrap: break-word;
|
|
450742
450883
|
text-shadow: 0 4px 20px rgba(0,0,0,0.65);
|
|
450743
450884
|
}${wordCss}`,
|
|
450744
450885
|
body: `${backdropMarkup}
|
|
450745
450886
|
<div class="caption" id="caption">${captionInner}</div>`,
|
|
450746
|
-
timeline
|
|
450887
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
450888
|
+
${kenBurnsTween(scope, dur)}
|
|
450889
|
+
${captionTween}
|
|
450890
|
+
${idleHeroPulse(scope, "#caption", 1, dur)}`
|
|
450747
450891
|
};
|
|
450748
450892
|
}
|
|
450749
450893
|
case "announcement": {
|
|
450894
|
+
const fontSize = fitFontSize(headline, 160, 72, 22);
|
|
450750
450895
|
return {
|
|
450751
450896
|
css: `${scope} {
|
|
450752
450897
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450754,6 +450899,7 @@ function buildPreset(input3) {
|
|
|
450754
450899
|
color: #fff; overflow: hidden; background: #000;
|
|
450755
450900
|
}
|
|
450756
450901
|
${backdrop}
|
|
450902
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450757
450903
|
${scope} .announce {
|
|
450758
450904
|
position: absolute; inset: 0;
|
|
450759
450905
|
display: flex; align-items: center; justify-content: center;
|
|
@@ -450762,10 +450908,11 @@ function buildPreset(input3) {
|
|
|
450762
450908
|
}
|
|
450763
450909
|
${scope} .announce h1 {
|
|
450764
450910
|
margin: 0;
|
|
450765
|
-
font-size:
|
|
450911
|
+
font-size: ${fontSize}px;
|
|
450766
450912
|
font-weight: 900;
|
|
450767
450913
|
letter-spacing: -4px;
|
|
450768
|
-
line-height: 1;
|
|
450914
|
+
line-height: 1.05;
|
|
450915
|
+
overflow-wrap: break-word;
|
|
450769
450916
|
background: linear-gradient(90deg, #8e2de2, #00c9ff);
|
|
450770
450917
|
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
450771
450918
|
text-shadow: 0 8px 40px rgba(142,45,226,0.35);
|
|
@@ -450775,8 +450922,12 @@ function buildPreset(input3) {
|
|
|
450775
450922
|
// Faster, snappier entrance and no tail fade-out — see the
|
|
450776
450923
|
// matching note in the `simple` case above. The headline stays
|
|
450777
450924
|
// on screen until the producer cuts to the next clip; the next
|
|
450778
|
-
// scene's own fade-in handles the visual transition.
|
|
450779
|
-
|
|
450925
|
+
// scene's own fade-in handles the visual transition. Backdrop
|
|
450926
|
+
// Ken-Burns fills what used to be 80% dead static frame.
|
|
450927
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
450928
|
+
${kenBurnsTween(scope, dur)}
|
|
450929
|
+
tl.from('${scope} #headline', { opacity: 0, scale: 0.92, duration: 0.55, ease: 'power3.out' }, 0.05);
|
|
450930
|
+
${idleHeroPulse(scope, "#headline", 1, dur)}`
|
|
450780
450931
|
};
|
|
450781
450932
|
}
|
|
450782
450933
|
case "explainer": {
|
|
@@ -450788,6 +450939,7 @@ function buildPreset(input3) {
|
|
|
450788
450939
|
const wordCss = useWordSync ? `
|
|
450789
450940
|
${scope} #subtitle .word { display: inline-block; opacity: 0; }` : "";
|
|
450790
450941
|
const subtitleTween = useWordSync ? buildTranscriptTweens(transcript, `${scope} #subtitle .word`) : sub ? `tl.from('${scope} #subtitle', { opacity: 0, y: 30, duration: 0.55, ease: 'power3.out' }, 0.55);` : "";
|
|
450942
|
+
const titleFontPx = fitFontSize(headline, 110, 56, 30);
|
|
450791
450943
|
return {
|
|
450792
450944
|
css: `${scope} {
|
|
450793
450945
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450795,6 +450947,7 @@ function buildPreset(input3) {
|
|
|
450795
450947
|
color: #fff; overflow: hidden; background: #000;
|
|
450796
450948
|
}
|
|
450797
450949
|
${backdrop}
|
|
450950
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450798
450951
|
${scope} .stage {
|
|
450799
450952
|
position: absolute; inset: 0;
|
|
450800
450953
|
display: flex; flex-direction: column; justify-content: center;
|
|
@@ -450805,11 +450958,13 @@ function buildPreset(input3) {
|
|
|
450805
450958
|
color: #00c9ff; font-weight: 600;
|
|
450806
450959
|
}
|
|
450807
450960
|
${scope} .title {
|
|
450808
|
-
font-size:
|
|
450961
|
+
font-size: ${titleFontPx}px; font-weight: 800; letter-spacing: -2px;
|
|
450809
450962
|
line-height: 1.05; margin: 0;
|
|
450963
|
+
overflow-wrap: break-word;
|
|
450810
450964
|
}
|
|
450811
450965
|
${scope} .subtitle {
|
|
450812
450966
|
font-size: 38px; font-weight: 300; color: #c0c0d0; max-width: 80%;
|
|
450967
|
+
overflow-wrap: break-word;
|
|
450813
450968
|
}${wordCss}`,
|
|
450814
450969
|
body: `${backdropMarkup}
|
|
450815
450970
|
<div class="stage">
|
|
@@ -450817,9 +450972,12 @@ function buildPreset(input3) {
|
|
|
450817
450972
|
<h1 class="title" id="title">${esc(headline)}</h1>${sub ? `
|
|
450818
450973
|
<div class="subtitle" id="subtitle">${subtitleInner}</div>` : ""}
|
|
450819
450974
|
</div>`,
|
|
450820
|
-
timeline:
|
|
450975
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
450976
|
+
${kenBurnsTween(scope, dur)}
|
|
450977
|
+
tl.from('${scope} #kicker', { opacity: 0, y: 16, duration: 0.4, ease: 'power2.out' }, 0.1);
|
|
450821
450978
|
tl.from('${scope} #title', { opacity: 0, y: 60, duration: 0.7, ease: 'power3.out' }, 0.25);
|
|
450822
|
-
${subtitleTween}
|
|
450979
|
+
${subtitleTween}
|
|
450980
|
+
${idleHeroPulse(scope, "#title", 1.2, dur)}`
|
|
450823
450981
|
};
|
|
450824
450982
|
}
|
|
450825
450983
|
case "kinetic-type": {
|
|
@@ -450835,6 +450993,9 @@ function buildPreset(input3) {
|
|
|
450835
450993
|
const start = (0.05 + i * stagger).toFixed(2);
|
|
450836
450994
|
return `tl.from('${scope} #w-${i}', { opacity: 0, y: 80, scale: 0.8, duration: 0.45, ease: 'back.out(1.8)' }, ${start});`;
|
|
450837
450995
|
}).join("\n ");
|
|
450996
|
+
const kineticFontPx = fitKineticFontSize(words);
|
|
450997
|
+
const lastWordEntryEnd = useWordSync ? Math.max(...transcript.map((w) => w.end + 0.2)) : 0.05 + (words.length - 1) * stagger + 0.45 + 0.2;
|
|
450998
|
+
const idleStart = Math.max(1, Number(lastWordEntryEnd.toFixed(2)));
|
|
450838
450999
|
return {
|
|
450839
451000
|
css: `${scope} {
|
|
450840
451001
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450842,21 +451003,28 @@ function buildPreset(input3) {
|
|
|
450842
451003
|
color: #fff; overflow: hidden; background: #000;
|
|
450843
451004
|
}
|
|
450844
451005
|
${backdrop}
|
|
451006
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450845
451007
|
${scope} .kinetic {
|
|
450846
451008
|
position: absolute; inset: 0;
|
|
450847
451009
|
display: flex; align-items: center; justify-content: center;
|
|
451010
|
+
flex-wrap: wrap; gap: 8px 16px;
|
|
450848
451011
|
text-align: center; padding: 0 6%;
|
|
450849
|
-
font-size:
|
|
451012
|
+
font-size: ${kineticFontPx}px; font-weight: 900; letter-spacing: -6px;
|
|
450850
451013
|
line-height: 1; text-shadow: 0 6px 30px rgba(0,0,0,0.6);
|
|
451014
|
+
overflow-wrap: break-word;
|
|
450851
451015
|
}
|
|
450852
451016
|
${scope} .kinetic .word { display: inline-block; margin: 0 12px; }`,
|
|
450853
451017
|
body: `${backdropMarkup}
|
|
450854
451018
|
<div class="kinetic">${wordSpans}</div>`,
|
|
450855
|
-
timeline:
|
|
451019
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
451020
|
+
${kenBurnsTween(scope, dur)}
|
|
451021
|
+
${tweens}
|
|
451022
|
+
${kineticWordBobs(scope, words.length, idleStart, dur)}`
|
|
450856
451023
|
};
|
|
450857
451024
|
}
|
|
450858
451025
|
case "product-shot": {
|
|
450859
451026
|
const label = kicker || humanise(id);
|
|
451027
|
+
const headlineFontPx = fitFontSize(headline, 72, 40, 50);
|
|
450860
451028
|
return {
|
|
450861
451029
|
css: `${scope} {
|
|
450862
451030
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450874,22 +451042,26 @@ function buildPreset(input3) {
|
|
|
450874
451042
|
}
|
|
450875
451043
|
${scope} .product-headline {
|
|
450876
451044
|
position: absolute; left: 8%; right: 8%; bottom: 14%;
|
|
450877
|
-
font-size:
|
|
450878
|
-
line-height: 1.1;
|
|
451045
|
+
font-size: ${headlineFontPx}px; font-weight: 800; letter-spacing: -1px;
|
|
451046
|
+
line-height: 1.1; overflow-wrap: break-word;
|
|
451047
|
+
text-shadow: 0 4px 20px rgba(0,0,0,0.7);
|
|
450879
451048
|
}${subhead ? `
|
|
450880
451049
|
${scope} .product-sub {
|
|
450881
451050
|
position: absolute; left: 8%; right: 8%; bottom: 8%;
|
|
450882
451051
|
font-size: 28px; font-weight: 400; color: #d0d0e0;
|
|
451052
|
+
overflow-wrap: break-word;
|
|
450883
451053
|
text-shadow: 0 2px 10px rgba(0,0,0,0.7);
|
|
450884
451054
|
}` : ""}`,
|
|
450885
451055
|
body: `${backdropMarkup}
|
|
450886
451056
|
<div class="label" id="label">${esc(label)}</div>
|
|
450887
451057
|
<div class="product-headline" id="headline">${esc(headline)}</div>${subhead ? `
|
|
450888
451058
|
<div class="product-sub" id="subhead">${esc(subhead)}</div>` : ""}`,
|
|
450889
|
-
timeline:
|
|
451059
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
451060
|
+
tl.fromTo('${scope} .backdrop', { scale: 1.0 }, { scale: 1.12, duration: ${dur.toFixed(2)}, ease: 'none' }, 0);
|
|
450890
451061
|
tl.from('${scope} #label', { opacity: 0, x: -30, duration: 0.5, ease: 'power3.out' }, 0.2);
|
|
450891
451062
|
tl.from('${scope} #headline', { opacity: 0, y: 40, duration: 0.6, ease: 'power3.out' }, 0.4);${subhead ? `
|
|
450892
|
-
tl.from('${scope} #subhead', { opacity: 0, y: 20, duration: 0.5, ease: 'power3.out' }, 0.65);` : ""}
|
|
451063
|
+
tl.from('${scope} #subhead', { opacity: 0, y: 20, duration: 0.5, ease: 'power3.out' }, 0.65);` : ""}
|
|
451064
|
+
${idleHeroPulse(scope, "#headline", 1.2, dur)}`
|
|
450893
451065
|
};
|
|
450894
451066
|
}
|
|
450895
451067
|
}
|
|
@@ -450935,7 +451107,7 @@ ${audioBlock}
|
|
|
450935
451107
|
</template>
|
|
450936
451108
|
`;
|
|
450937
451109
|
}
|
|
450938
|
-
function nextSceneStart(rootHtml) {
|
|
451110
|
+
function nextSceneStart(rootHtml, overlap = 0) {
|
|
450939
451111
|
const clipRegex = /<div\s+class="clip"[^>]*?\sdata-start="([\d.]+)"[^>]*?\sdata-duration="([\d.]+)"/gi;
|
|
450940
451112
|
let maxEnd = 0;
|
|
450941
451113
|
let match2;
|
|
@@ -450943,14 +451115,15 @@ function nextSceneStart(rootHtml) {
|
|
|
450943
451115
|
const end = parseFloat(match2[1]) + parseFloat(match2[2]);
|
|
450944
451116
|
if (Number.isFinite(end) && end > maxEnd) maxEnd = end;
|
|
450945
451117
|
}
|
|
450946
|
-
return maxEnd;
|
|
451118
|
+
return Math.max(0, maxEnd - overlap);
|
|
450947
451119
|
}
|
|
450948
451120
|
function buildClipReference(opts) {
|
|
450949
451121
|
const start = Number(opts.start.toFixed(3));
|
|
450950
451122
|
const duration = Number(opts.duration.toFixed(3));
|
|
450951
451123
|
const track = opts.trackIndex ?? 1;
|
|
450952
451124
|
const src = opts.src ?? `compositions/scene-${opts.id}.html`;
|
|
450953
|
-
|
|
451125
|
+
const zIndex = Math.max(1, 1e6 - Math.floor(start * 1e3));
|
|
451126
|
+
return `<div class="clip" data-composition-id="${esc(opts.id)}" data-composition-src="${esc(src)}" data-start="${start}" data-duration="${duration}" data-track-index="${track}" style="z-index: ${zIndex};"></div>`;
|
|
450954
451127
|
}
|
|
450955
451128
|
function insertClipIntoRoot(rootHtml, clip) {
|
|
450956
451129
|
const clipDiv = buildClipReference(clip);
|
|
@@ -450983,7 +451156,7 @@ function readRootDims(rootHtml) {
|
|
|
450983
451156
|
if (!widthMatch || !heightMatch) return null;
|
|
450984
451157
|
return { width: parseInt(widthMatch[1], 10), height: parseInt(heightMatch[1], 10) };
|
|
450985
451158
|
}
|
|
450986
|
-
var SCENE_PRESETS, GSAP_CDN;
|
|
451159
|
+
var SCENE_PRESETS, GSAP_CDN, SCENE_OVERLAP_SECONDS;
|
|
450987
451160
|
var init_scene_html_emit = __esm({
|
|
450988
451161
|
"../cli/src/commands/_shared/scene-html-emit.ts"() {
|
|
450989
451162
|
"use strict";
|
|
@@ -450995,6 +451168,7 @@ var init_scene_html_emit = __esm({
|
|
|
450995
451168
|
"product-shot"
|
|
450996
451169
|
];
|
|
450997
451170
|
GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js";
|
|
451171
|
+
SCENE_OVERLAP_SECONDS = 0.4;
|
|
450998
451172
|
}
|
|
450999
451173
|
});
|
|
451000
451174
|
|
|
@@ -451166,7 +451340,12 @@ async function executeSegmentsToScenes(opts) {
|
|
|
451166
451340
|
const dims = aspectToDims(aspect);
|
|
451167
451341
|
const preset = opts.scenePreset ?? DEFAULT_PRESET;
|
|
451168
451342
|
const projectName = opts.projectName ?? basename8(outputDir);
|
|
451169
|
-
const totalDuration =
|
|
451343
|
+
const totalDuration = (() => {
|
|
451344
|
+
const sum = opts.segments.reduce((acc, s) => acc + (s.duration || 0), 0);
|
|
451345
|
+
if (sum <= 0) return 10;
|
|
451346
|
+
const joins = Math.max(0, opts.segments.length - 1);
|
|
451347
|
+
return Math.max(0.1, sum - joins * SCENE_OVERLAP_SECONDS);
|
|
451348
|
+
})();
|
|
451170
451349
|
const baseError = (error) => ({
|
|
451171
451350
|
success: false,
|
|
451172
451351
|
outputDir,
|
|
@@ -451239,9 +451418,10 @@ async function executeSegmentsToScenes(opts) {
|
|
|
451239
451418
|
id,
|
|
451240
451419
|
start: clipStart,
|
|
451241
451420
|
duration,
|
|
451421
|
+
trackIndex: i % 2 + 1,
|
|
451242
451422
|
src: `compositions/${id}.html`
|
|
451243
451423
|
});
|
|
451244
|
-
clipStart += duration;
|
|
451424
|
+
clipStart += duration - SCENE_OVERLAP_SECONDS;
|
|
451245
451425
|
}
|
|
451246
451426
|
await writeFile12(rootAbs, rootHtml, "utf-8");
|
|
451247
451427
|
let lintResult;
|
|
@@ -464230,6 +464410,176 @@ function parseTtsProviderName(value) {
|
|
|
464230
464410
|
|
|
464231
464411
|
// ../cli/src/commands/scene.ts
|
|
464232
464412
|
init_scene_project();
|
|
464413
|
+
|
|
464414
|
+
// ../cli/src/commands/_shared/visual-styles.ts
|
|
464415
|
+
var STYLES = [
|
|
464416
|
+
{
|
|
464417
|
+
name: "Swiss Pulse",
|
|
464418
|
+
slug: "swiss-pulse",
|
|
464419
|
+
designer: "Josef M\xFCller-Brockmann",
|
|
464420
|
+
mood: "Clinical, precise",
|
|
464421
|
+
bestFor: "SaaS dashboards, developer tools, APIs, metrics",
|
|
464422
|
+
palette: ["#1a1a1a", "#ffffff", "#0066FF"],
|
|
464423
|
+
paletteNotes: "Black, white, ONE accent \u2014 electric blue (#0066FF) or amber (#FFB300). Never both accents at once.",
|
|
464424
|
+
typography: "Helvetica or Inter Bold for headlines, Regular for labels. Numbers dominate at 80\u2013120px.",
|
|
464425
|
+
composition: "Grid-locked. Every element snaps to an invisible 12-column grid. Hard cuts only \u2014 no decorative transitions.",
|
|
464426
|
+
motion: "Animated counters count up from 0. Entries are fast and snap into place. Nothing floats.",
|
|
464427
|
+
transition: "Cinematic Zoom or SDF Iris (precise, geometric)",
|
|
464428
|
+
gsapSignature: "expo.out, power4.out \u2014 fast arrivals, hard stops",
|
|
464429
|
+
avoid: [
|
|
464430
|
+
"Decorative transitions (fades, dissolves) \u2014 use hard cuts",
|
|
464431
|
+
"Two accent colours competing in one frame",
|
|
464432
|
+
"Off-grid placement or floating elements"
|
|
464433
|
+
]
|
|
464434
|
+
},
|
|
464435
|
+
{
|
|
464436
|
+
name: "Velvet Standard",
|
|
464437
|
+
slug: "velvet-standard",
|
|
464438
|
+
designer: "Massimo Vignelli",
|
|
464439
|
+
mood: "Premium, timeless",
|
|
464440
|
+
bestFor: "Luxury products, enterprise software, keynotes, investor decks",
|
|
464441
|
+
palette: ["#000000", "#ffffff", "#1a237e"],
|
|
464442
|
+
paletteNotes: "Black, white, ONE rich accent \u2014 deep navy (#1a237e) or gold (#c9a84c).",
|
|
464443
|
+
typography: "Thin sans-serif, ALL CAPS, wide letter-spacing (0.15em+). Sequential reveals only.",
|
|
464444
|
+
composition: "Generous negative space. Symmetrical, centered, architectural precision. Nothing busy.",
|
|
464445
|
+
motion: "Slow, deliberate. Sequential reveals with long holds. No frantic motion.",
|
|
464446
|
+
transition: "Cross-Warp Morph (elegant, organic flow between scenes)",
|
|
464447
|
+
gsapSignature: "sine.inOut, power1 \u2014 nothing snaps, everything glides",
|
|
464448
|
+
avoid: [
|
|
464449
|
+
"Tight letter-spacing \u2014 kills the premium register",
|
|
464450
|
+
"Bouncy or elastic easings \u2014 too playful",
|
|
464451
|
+
"Multiple elements arriving at once \u2014 break sequence"
|
|
464452
|
+
]
|
|
464453
|
+
},
|
|
464454
|
+
{
|
|
464455
|
+
name: "Deconstructed",
|
|
464456
|
+
slug: "deconstructed",
|
|
464457
|
+
designer: "Neville Brody",
|
|
464458
|
+
mood: "Industrial, raw",
|
|
464459
|
+
bestFor: "Tech news, developer launches, security products, punk-energy reveals",
|
|
464460
|
+
palette: ["#1a1a1a", "#D4501E", "#f0f0f0"],
|
|
464461
|
+
paletteNotes: "Dark grey (#1a1a1a), rust orange (#D4501E), raw white (#f0f0f0).",
|
|
464462
|
+
typography: "Type at angles, overlapping edges, escaping frames. Bold industrial weight.",
|
|
464463
|
+
composition: "Gritty textures \u2014 scan-line effects, glitch artifacts baked into the design.",
|
|
464464
|
+
motion: "Text SLAMS and SHATTERS. Letters scramble then snap to final position.",
|
|
464465
|
+
transition: "Glitch shader or Whip Pan (breaks the rules, feels aggressive)",
|
|
464466
|
+
gsapSignature: "back.out(2.5), steps(8), elastic.out(1.2, 0.4) \u2014 intentional irregularity",
|
|
464467
|
+
avoid: [
|
|
464468
|
+
"Polished, centered compositions \u2014 must feel raw",
|
|
464469
|
+
"Smooth fades \u2014 use glitch / scramble entries",
|
|
464470
|
+
"Soft easings \u2014 every motion lands hard"
|
|
464471
|
+
]
|
|
464472
|
+
},
|
|
464473
|
+
{
|
|
464474
|
+
name: "Maximalist Type",
|
|
464475
|
+
slug: "maximalist-type",
|
|
464476
|
+
designer: "Paula Scher",
|
|
464477
|
+
mood: "Loud, kinetic",
|
|
464478
|
+
bestFor: "Big product launches, milestone announcements, high-energy hype videos",
|
|
464479
|
+
palette: ["#E63946", "#FFD60A", "#000000", "#ffffff"],
|
|
464480
|
+
paletteNotes: "Bold saturated: red (#E63946), yellow (#FFD60A), black, white \u2014 maximum contrast.",
|
|
464481
|
+
typography: "Text IS the visual. Overlapping type layers at different scales and angles, filling 50\u201380% of frame.",
|
|
464482
|
+
composition: "Text layered OVER footage \u2014 never empty backgrounds. 2\u20133 second rapid-fire scenes.",
|
|
464483
|
+
motion: "Everything is kinetic \u2014 slamming, sliding, scaling. No static moments.",
|
|
464484
|
+
transition: "Ridged Burn (explosive, dramatic, impossible to ignore)",
|
|
464485
|
+
gsapSignature: "expo.out, back.out(1.8) \u2014 fast arrivals, hard stops",
|
|
464486
|
+
avoid: [
|
|
464487
|
+
"Static moments \u2014 every frame must move",
|
|
464488
|
+
"Empty backgrounds \u2014 text and footage must layer",
|
|
464489
|
+
"Single typeface at a single size \u2014 must be layered"
|
|
464490
|
+
]
|
|
464491
|
+
},
|
|
464492
|
+
{
|
|
464493
|
+
name: "Data Drift",
|
|
464494
|
+
slug: "data-drift",
|
|
464495
|
+
designer: "Refik Anadol",
|
|
464496
|
+
mood: "Futuristic, immersive",
|
|
464497
|
+
bestFor: "AI products, ML platforms, data companies, speculative tech",
|
|
464498
|
+
palette: ["#0a0a0a", "#7c3aed", "#06b6d4"],
|
|
464499
|
+
paletteNotes: "Iridescent \u2014 deep black (#0a0a0a), electric purple (#7c3aed), cyan (#06b6d4).",
|
|
464500
|
+
typography: "Thin futuristic sans-serif \u2014 floating, weightless, minimal text.",
|
|
464501
|
+
composition: "Fluid morphing compositions. Extreme scale shifts (micro \u2192 macro). Particles coalesce into numbers.",
|
|
464502
|
+
motion: "Light traces data paths through the frame. Smooth, continuous, organic \u2014 nothing hard.",
|
|
464503
|
+
transition: "Gravitational Lens or Domain Warp (otherworldly distortion)",
|
|
464504
|
+
gsapSignature: "sine.inOut, power2.out \u2014 smooth, continuous, organic",
|
|
464505
|
+
avoid: [
|
|
464506
|
+
"Hard cuts \u2014 break the immersion",
|
|
464507
|
+
"Heavy/bold typography \u2014 too grounded",
|
|
464508
|
+
"Static compositions \u2014 must feel like flow"
|
|
464509
|
+
]
|
|
464510
|
+
},
|
|
464511
|
+
{
|
|
464512
|
+
name: "Soft Signal",
|
|
464513
|
+
slug: "soft-signal",
|
|
464514
|
+
designer: "Stefan Sagmeister",
|
|
464515
|
+
mood: "Intimate, warm",
|
|
464516
|
+
bestFor: "Wellness brands, personal stories, lifestyle products, human-centered apps",
|
|
464517
|
+
palette: ["#F5A623", "#FFF8EC", "#C4A3A3", "#8FAF8C"],
|
|
464518
|
+
paletteNotes: "Warm amber (#F5A623), cream (#FFF8EC), dusty rose (#C4A3A3), sage green (#8FAF8C).",
|
|
464519
|
+
typography: "Handwritten-style or humanist serif fonts. Personal, lowercase, delicate.",
|
|
464520
|
+
composition: "Close-up framing feel \u2014 single element fills the frame. Nothing feels corporate.",
|
|
464521
|
+
motion: "Slow drifts and floats, never snaps. Soft organic motion throughout.",
|
|
464522
|
+
transition: "Thermal Distortion (warm, flowing, like heat shimmer)",
|
|
464523
|
+
gsapSignature: "sine.inOut, power1.inOut \u2014 everything breathes",
|
|
464524
|
+
avoid: [
|
|
464525
|
+
"Sharp geometric layouts \u2014 break the warmth",
|
|
464526
|
+
"Hard easings or snaps \u2014 too clinical",
|
|
464527
|
+
"Cool tones (blue/green-blue) without warm balance"
|
|
464528
|
+
]
|
|
464529
|
+
},
|
|
464530
|
+
{
|
|
464531
|
+
name: "Folk Frequency",
|
|
464532
|
+
slug: "folk-frequency",
|
|
464533
|
+
designer: "Eduardo Terrazas",
|
|
464534
|
+
mood: "Cultural, vivid",
|
|
464535
|
+
bestFor: "Consumer apps, food platforms, community products, festive launches",
|
|
464536
|
+
palette: ["#FF1493", "#0047AB", "#FFE000", "#009B77"],
|
|
464537
|
+
paletteNotes: "Vivid folk: hot pink (#FF1493), cobalt blue (#0047AB), sun yellow (#FFE000), emerald (#009B77).",
|
|
464538
|
+
typography: "Bold warm rounded type. Every frame feels handcrafted.",
|
|
464539
|
+
composition: "Pattern and repetition \u2014 folk art rhythm and density. Layered compositions with rich visual texture.",
|
|
464540
|
+
motion: "Colorful motion \u2014 elements bounce, pop, and spin into place with joy.",
|
|
464541
|
+
transition: "Swirl Vortex or Ripple Waves (hypnotic, celebratory)",
|
|
464542
|
+
gsapSignature: "back.out(1.6), elastic.out(1, 0.5) \u2014 overshoots feel intentional",
|
|
464543
|
+
avoid: [
|
|
464544
|
+
"Muted or monochrome palettes \u2014 kill the celebration",
|
|
464545
|
+
"Pure flat / minimal compositions \u2014 must feel layered",
|
|
464546
|
+
"Linear easings \u2014 motion should feel joyful"
|
|
464547
|
+
]
|
|
464548
|
+
},
|
|
464549
|
+
{
|
|
464550
|
+
name: "Shadow Cut",
|
|
464551
|
+
slug: "shadow-cut",
|
|
464552
|
+
designer: "Hans Hillmann",
|
|
464553
|
+
mood: "Dark, cinematic",
|
|
464554
|
+
bestFor: "Security products, dramatic reveals, investigative content, intense launches",
|
|
464555
|
+
palette: ["#0a0a0a", "#3a3a3a", "#ffffff", "#C1121F"],
|
|
464556
|
+
paletteNotes: "Near-monochrome \u2014 deep blacks (#0a0a0a), cold greys (#3a3a3a), stark white + ONE accent (blood red #C1121F or toxic green #39FF14).",
|
|
464557
|
+
typography: "Sharp angular text like film noir title cards. Heavy contrast, no softness.",
|
|
464558
|
+
composition: "Heavy shadow \u2014 elements emerge from darkness. The reveal IS the narrative.",
|
|
464559
|
+
motion: "Slow creeping push-ins, dramatic scale reveals. Silence before the hit matters.",
|
|
464560
|
+
transition: "Domain Warp (dissolves reality before revealing the next scene)",
|
|
464561
|
+
gsapSignature: "power4.in for exits, power3.out for dramatic reveals \u2014 pause before the hit",
|
|
464562
|
+
avoid: [
|
|
464563
|
+
"Bright or saturated palettes \u2014 kill the cinematic mood",
|
|
464564
|
+
"Bouncy easings \u2014 break the tension",
|
|
464565
|
+
"Quick cuts \u2014 let the reveal breathe"
|
|
464566
|
+
]
|
|
464567
|
+
}
|
|
464568
|
+
];
|
|
464569
|
+
function listVisualStyles() {
|
|
464570
|
+
return STYLES;
|
|
464571
|
+
}
|
|
464572
|
+
function getVisualStyle(query2) {
|
|
464573
|
+
const q = query2.trim().toLowerCase();
|
|
464574
|
+
return STYLES.find(
|
|
464575
|
+
(s) => s.name.toLowerCase() === q || s.slug === q
|
|
464576
|
+
);
|
|
464577
|
+
}
|
|
464578
|
+
function visualStyleNames() {
|
|
464579
|
+
return STYLES.map((s) => `"${s.name}"`).join(", ");
|
|
464580
|
+
}
|
|
464581
|
+
|
|
464582
|
+
// ../cli/src/commands/scene.ts
|
|
464233
464583
|
init_scene_html_emit();
|
|
464234
464584
|
init_scene_lint();
|
|
464235
464585
|
init_output();
|
|
@@ -464255,6 +464605,18 @@ function validatePreset(value) {
|
|
|
464255
464605
|
}
|
|
464256
464606
|
return value;
|
|
464257
464607
|
}
|
|
464608
|
+
function validateVisualStyle(value) {
|
|
464609
|
+
const found = getVisualStyle(value);
|
|
464610
|
+
if (!found) {
|
|
464611
|
+
exitWithError(
|
|
464612
|
+
usageError(
|
|
464613
|
+
`Unknown visual style: ${value}`,
|
|
464614
|
+
`Valid: ${visualStyleNames()}. Browse details with \`vibe scene styles\`.`
|
|
464615
|
+
)
|
|
464616
|
+
);
|
|
464617
|
+
}
|
|
464618
|
+
return found;
|
|
464619
|
+
}
|
|
464258
464620
|
var sceneCommand = new Command("scene").description("Author and render per-scene HTML compositions (Hyperframes backend)").addHelpText("after", `
|
|
464259
464621
|
Examples:
|
|
464260
464622
|
$ vibe scene init my-video # Scaffold a new project
|
|
@@ -464272,21 +464634,28 @@ Examples:
|
|
|
464272
464634
|
|
|
464273
464635
|
A scene project is bilingual: it works with both \`vibe\` and \`npx hyperframes\`.
|
|
464274
464636
|
Run 'vibe schema scene.<command>' for structured parameter info.`);
|
|
464275
|
-
sceneCommand.command("init").description("Scaffold a new scene project (or safely augment an existing Hyperframes project)").argument("<dir>", "Project directory (created if it doesn't exist)").option("-n, --name <name>", "Project name (defaults to directory basename)").option("-r, --ratio <ratio>", "Aspect ratio: 16:9, 9:16, 1:1, 4:5", "16:9").option("-d, --duration <sec>", "Default root composition duration (seconds)", "10").option("--dry-run", "Preview parameters without writing files").action(async (dir, options) => {
|
|
464637
|
+
sceneCommand.command("init").description("Scaffold a new scene project (or safely augment an existing Hyperframes project)").argument("<dir>", "Project directory (created if it doesn't exist)").option("-n, --name <name>", "Project name (defaults to directory basename)").option("-r, --ratio <ratio>", "Aspect ratio: 16:9, 9:16, 1:1, 4:5", "16:9").option("-d, --duration <sec>", "Default root composition duration (seconds)", "10").option("--visual-style <name>", `Seed DESIGN.md from a named style (browse via \`vibe scene styles\`). E.g. "Swiss Pulse"`).option("--dry-run", "Preview parameters without writing files").action(async (dir, options) => {
|
|
464276
464638
|
const aspect = validateAspect(options.ratio);
|
|
464277
464639
|
const duration = validateDuration(options.duration);
|
|
464278
464640
|
const name = options.name ?? basename18(dir.replace(/\/+$/, ""));
|
|
464641
|
+
const visualStyle = options.visualStyle ? validateVisualStyle(options.visualStyle) : void 0;
|
|
464279
464642
|
if (options.dryRun) {
|
|
464280
464643
|
outputResult({
|
|
464281
464644
|
dryRun: true,
|
|
464282
464645
|
command: "scene init",
|
|
464283
|
-
params: {
|
|
464646
|
+
params: {
|
|
464647
|
+
dir,
|
|
464648
|
+
name,
|
|
464649
|
+
aspect,
|
|
464650
|
+
duration,
|
|
464651
|
+
visualStyle: visualStyle?.name ?? null
|
|
464652
|
+
}
|
|
464284
464653
|
});
|
|
464285
464654
|
return;
|
|
464286
464655
|
}
|
|
464287
464656
|
const spinner2 = isJsonMode() ? null : ora(`Scaffolding scene project at ${dir}...`).start();
|
|
464288
464657
|
try {
|
|
464289
|
-
const result = await scaffoldSceneProject({ dir, name, aspect, duration });
|
|
464658
|
+
const result = await scaffoldSceneProject({ dir, name, aspect, duration, visualStyle });
|
|
464290
464659
|
if (isJsonMode()) {
|
|
464291
464660
|
outputResult({
|
|
464292
464661
|
success: true,
|
|
@@ -464295,6 +464664,7 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464295
464664
|
name,
|
|
464296
464665
|
aspect,
|
|
464297
464666
|
duration,
|
|
464667
|
+
visualStyle: visualStyle?.name ?? null,
|
|
464298
464668
|
created: result.created,
|
|
464299
464669
|
merged: result.merged,
|
|
464300
464670
|
skipped: result.skipped
|
|
@@ -464311,7 +464681,13 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464311
464681
|
console.log();
|
|
464312
464682
|
console.log(source_default.bold.cyan("Next steps"));
|
|
464313
464683
|
console.log(source_default.dim("\u2500".repeat(60)));
|
|
464314
|
-
|
|
464684
|
+
if (visualStyle) {
|
|
464685
|
+
console.log(` ${source_default.dim("DESIGN.md seeded with")} ${source_default.bold(visualStyle.name)} ${source_default.dim("\u2014 review and customise.")}`);
|
|
464686
|
+
} else {
|
|
464687
|
+
console.log(` ${source_default.cyan("vibe scene styles")} ${source_default.dim("# pick a named style for DESIGN.md")}`);
|
|
464688
|
+
}
|
|
464689
|
+
console.log(` ${source_default.cyan("npx skills add heygen-com/hyperframes")} ${source_default.dim("# load the cinematic-craft skill set")}`);
|
|
464690
|
+
console.log(` ${source_default.cyan("vibe scene add")} <name> ${source_default.dim("# fallback path: 5-preset emit")}`);
|
|
464315
464691
|
console.log(` ${source_default.cyan("vibe scene lint")} ${source_default.dim("# validate HTML")}`);
|
|
464316
464692
|
console.log(` ${source_default.cyan("vibe scene render")} ${source_default.dim("# render to MP4")}`);
|
|
464317
464693
|
} catch (error) {
|
|
@@ -464320,6 +464696,69 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464320
464696
|
exitWithError(generalError(`Failed to scaffold: ${msg}`));
|
|
464321
464697
|
}
|
|
464322
464698
|
});
|
|
464699
|
+
sceneCommand.command("styles").description("List vendored visual styles (or show one) for DESIGN.md seeding").argument("[name]", "Style name to inspect (omit to list all)").action((name) => {
|
|
464700
|
+
if (!name) {
|
|
464701
|
+
const all = listVisualStyles();
|
|
464702
|
+
if (isJsonMode()) {
|
|
464703
|
+
outputResult({
|
|
464704
|
+
success: true,
|
|
464705
|
+
command: "scene styles",
|
|
464706
|
+
count: all.length,
|
|
464707
|
+
styles: all.map((s) => ({
|
|
464708
|
+
name: s.name,
|
|
464709
|
+
slug: s.slug,
|
|
464710
|
+
designer: s.designer,
|
|
464711
|
+
mood: s.mood,
|
|
464712
|
+
bestFor: s.bestFor
|
|
464713
|
+
}))
|
|
464714
|
+
});
|
|
464715
|
+
return;
|
|
464716
|
+
}
|
|
464717
|
+
console.log();
|
|
464718
|
+
console.log(source_default.bold.cyan("Visual styles"));
|
|
464719
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
464720
|
+
for (const s of all) {
|
|
464721
|
+
console.log(
|
|
464722
|
+
` ${source_default.bold(s.name.padEnd(18))} ${source_default.dim(s.mood.padEnd(24))} ${source_default.dim(s.bestFor)}`
|
|
464723
|
+
);
|
|
464724
|
+
}
|
|
464725
|
+
console.log();
|
|
464726
|
+
console.log(source_default.dim("Show details: "), source_default.cyan('vibe scene styles "<name>"'));
|
|
464727
|
+
console.log(source_default.dim("Seed DESIGN.md:"), source_default.cyan('vibe scene init <dir> --visual-style "<name>"'));
|
|
464728
|
+
return;
|
|
464729
|
+
}
|
|
464730
|
+
const style = getVisualStyle(name);
|
|
464731
|
+
if (!style) {
|
|
464732
|
+
exitWithError(
|
|
464733
|
+
usageError(
|
|
464734
|
+
`Unknown visual style: ${name}`,
|
|
464735
|
+
`Valid: ${visualStyleNames()}.`
|
|
464736
|
+
)
|
|
464737
|
+
);
|
|
464738
|
+
return;
|
|
464739
|
+
}
|
|
464740
|
+
if (isJsonMode()) {
|
|
464741
|
+
outputResult({ success: true, command: "scene styles", style });
|
|
464742
|
+
return;
|
|
464743
|
+
}
|
|
464744
|
+
console.log();
|
|
464745
|
+
console.log(source_default.bold.cyan(style.name), source_default.dim(`\u2014 ${style.designer}`));
|
|
464746
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
464747
|
+
console.log(`${source_default.bold("Mood:")} ${style.mood}`);
|
|
464748
|
+
console.log(`${source_default.bold("Best for:")} ${style.bestFor}`);
|
|
464749
|
+
console.log(`${source_default.bold("Palette:")} ${style.palette.join(", ")}`);
|
|
464750
|
+
console.log(source_default.dim(" ") + style.paletteNotes);
|
|
464751
|
+
console.log(`${source_default.bold("Typography:")} ${style.typography}`);
|
|
464752
|
+
console.log(`${source_default.bold("Composition:")} ${style.composition}`);
|
|
464753
|
+
console.log(`${source_default.bold("Motion:")} ${style.motion}`);
|
|
464754
|
+
console.log(`${source_default.bold("GSAP:")} ${style.gsapSignature}`);
|
|
464755
|
+
console.log(`${source_default.bold("Transition:")} ${style.transition}`);
|
|
464756
|
+
console.log();
|
|
464757
|
+
console.log(source_default.bold("Avoid:"));
|
|
464758
|
+
for (const a of style.avoid) console.log(` ${source_default.red("\u2022")} ${a}`);
|
|
464759
|
+
console.log();
|
|
464760
|
+
console.log(source_default.dim("Seed DESIGN.md:"), source_default.cyan(`vibe scene init <dir> --visual-style "${style.name}"`));
|
|
464761
|
+
});
|
|
464323
464762
|
sceneCommand.command("add").description("Add a new scene to a project: AI narration + image + per-scene HTML").argument("<name>", "Scene name (slugified into the composition id)").option("--style <preset>", `Style preset: ${SCENE_PRESETS.join(", ")}`, "simple").option("--narration <text>", "Narration text (or path to a .txt file). Drives TTS + scene duration.").option("--narration-file <path>", "Existing narration audio file (.wav/.mp3). Skips TTS \u2014 useful with hyperframes tts, Mac say, or other external tools.").option("-d, --duration <sec>", "Explicit scene duration in seconds (overrides narration audio)").option("--visuals <prompt>", "Image prompt \u2014 generates assets/scene-<id>.png via the configured image provider").option("--headline <text>", "Visible headline (defaults to the humanised scene name)").option("--kicker <text>", "Small label above the headline (explainer / product-shot)").option("--insert-into <path>", "Root composition file to update", "index.html").option("--project <dir>", "Project directory", ".").option("--image-provider <name>", "Image provider: gemini, openai", "gemini").option("--tts <provider>", "TTS provider: auto, elevenlabs, kokoro (default auto \u2014 picks ElevenLabs when key set, else Kokoro local)", "auto").option("--voice <id>", "Voice id (ElevenLabs name/id, or Kokoro id like af_heart, am_michael)").option("--no-audio", "Skip TTS even when --narration is provided (useful for tests/agent dry runs)").option("--no-image", "Skip image generation even when --visuals is provided").option("--no-transcribe", "Skip Whisper word-level transcribe step (no transcript-<id>.json emitted)").option("--transcribe-language <code>", "BCP-47 language code passed to Whisper (e.g. en, ko)").option("--force", "Overwrite an existing compositions/scene-<id>.html").option("--dry-run", "Preview parameters without writing files or calling APIs").action(async (name, options) => {
|
|
464324
464763
|
if (options.style) options.style = validatePreset(options.style);
|
|
464325
464764
|
if (options.duration !== void 0) options.duration = validateDuration(options.duration);
|
|
@@ -464630,7 +465069,20 @@ async function executeSceneAdd(opts) {
|
|
|
464630
465069
|
}
|
|
464631
465070
|
const cfg = await loadVibeProjectConfig(projectDir);
|
|
464632
465071
|
const fallback2 = cfg?.defaultSceneDuration ?? 5;
|
|
464633
|
-
const
|
|
465072
|
+
const NARRATION_TAIL_BUFFER = 0.5;
|
|
465073
|
+
const userDur = opts.duration;
|
|
465074
|
+
const audioMinDur = narrationDuration !== void 0 ? narrationDuration + SCENE_OVERLAP_SECONDS + NARRATION_TAIL_BUFFER : void 0;
|
|
465075
|
+
let duration;
|
|
465076
|
+
if (userDur !== void 0 && audioMinDur !== void 0) {
|
|
465077
|
+
duration = Math.max(userDur, audioMinDur);
|
|
465078
|
+
} else if (audioMinDur !== void 0) {
|
|
465079
|
+
duration = audioMinDur;
|
|
465080
|
+
} else if (userDur !== void 0) {
|
|
465081
|
+
duration = userDur;
|
|
465082
|
+
} else {
|
|
465083
|
+
duration = fallback2;
|
|
465084
|
+
}
|
|
465085
|
+
duration = Number(duration.toFixed(2));
|
|
464634
465086
|
opts.onProgress?.("Emitting scene HTML...");
|
|
464635
465087
|
const sceneHtml = emitSceneHtml({
|
|
464636
465088
|
id,
|
|
@@ -464648,8 +465100,10 @@ async function executeSceneAdd(opts) {
|
|
|
464648
465100
|
await mkdir19(dirname25(scenePath), { recursive: true });
|
|
464649
465101
|
await writeFile25(scenePath, sceneHtml, "utf-8");
|
|
464650
465102
|
opts.onProgress?.("Updating root composition...");
|
|
464651
|
-
const start = nextSceneStart(rootHtmlBefore);
|
|
464652
|
-
const
|
|
465103
|
+
const start = nextSceneStart(rootHtmlBefore, SCENE_OVERLAP_SECONDS);
|
|
465104
|
+
const existingClipCount = (rootHtmlBefore.match(/<div\s+class="clip"/g) || []).length;
|
|
465105
|
+
const trackIndex = existingClipCount % 2 + 1;
|
|
465106
|
+
const updated = insertClipIntoRoot(rootHtmlBefore, { id, start, duration, trackIndex });
|
|
464653
465107
|
await writeFile25(rootPath, updated, "utf-8");
|
|
464654
465108
|
const transcriptAbsPath = transcriptRelPath ? resolve40(projectDir, transcriptRelPath) : void 0;
|
|
464655
465109
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.58.0",
|
|
4
4
|
"description": "VibeFrame MCP Server - AI-native video editing via Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"tsx": "^4.21.0",
|
|
58
58
|
"typescript": "^5.3.3",
|
|
59
59
|
"vitest": "^1.2.2",
|
|
60
|
-
"@vibeframe/cli": "0.
|
|
61
|
-
"@vibeframe/core": "0.
|
|
60
|
+
"@vibeframe/cli": "0.58.0",
|
|
61
|
+
"@vibeframe/core": "0.58.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=20"
|