@vibeframe/mcp-server 0.57.3 → 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 +552 -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
|
//
|
|
@@ -450501,6 +450498,70 @@ function buildEmptyRootHtml(opts) {
|
|
|
450501
450498
|
</html>
|
|
450502
450499
|
`;
|
|
450503
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
|
+
}
|
|
450504
450565
|
function buildProjectClaudeMd(name) {
|
|
450505
450566
|
return `# ${name} \u2014 Scene Authoring Project
|
|
450506
450567
|
|
|
@@ -450508,6 +450569,16 @@ This project is **bilingual**: it works with both VibeFrame (\`vibe\`) and
|
|
|
450508
450569
|
HeyGen Hyperframes (\`hyperframes\`). You can run either CLI inside this
|
|
450509
450570
|
directory.
|
|
450510
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
|
+
|
|
450511
450582
|
## Skills \u2014 USE THESE FIRST
|
|
450512
450583
|
|
|
450513
450584
|
**Always invoke the relevant skill before authoring scenes.** Skills encode
|
|
@@ -450516,14 +450587,23 @@ semantics, VibeFrame pipeline conventions) that are NOT in generic web docs.
|
|
|
450516
450587
|
|
|
450517
450588
|
| Skill | Command | When to use |
|
|
450518
450589
|
| ----------------- | ---------------- | ------------------------------------------------------------------------------------- |
|
|
450519
|
-
| **
|
|
450520
|
-
| **
|
|
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 |
|
|
450521
450592
|
| **gsap** | \`/gsap\` | GSAP tweens, timelines, easing |
|
|
450522
450593
|
|
|
450523
|
-
|
|
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.
|
|
450524
450603
|
|
|
450525
450604
|
## Project structure
|
|
450526
450605
|
|
|
450606
|
+
- \`DESIGN.md\` \u2014 visual identity contract (palette, type, motion, transitions)
|
|
450527
450607
|
- \`index.html\` \u2014 root composition (timeline)
|
|
450528
450608
|
- \`compositions/scene-*.html\` \u2014 per-scene HTML authored by you or the agent
|
|
450529
450609
|
- \`assets/\` \u2014 shared media (narration audio, images, video)
|
|
@@ -450641,6 +450721,17 @@ async function scaffoldSceneProject(opts) {
|
|
|
450641
450721
|
await writeFile10(claudePath, buildProjectClaudeMd(name), "utf-8");
|
|
450642
450722
|
created.push(claudePath);
|
|
450643
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
|
+
}
|
|
450644
450735
|
const gitignorePath = resolve20(dir, ".gitignore");
|
|
450645
450736
|
if (await pathExists(gitignorePath)) {
|
|
450646
450737
|
skipped.push(gitignorePath);
|
|
@@ -450689,6 +450780,52 @@ function buildTranscriptTweens(transcript, targetSelector) {
|
|
|
450689
450780
|
return `tl.fromTo('${sel}', { opacity: 0, y: 10 }, { opacity: 1, y: 0, duration: 0.18, ease: 'power2.out' }, ${start});`;
|
|
450690
450781
|
}).join("\n ");
|
|
450691
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
|
+
}
|
|
450692
450829
|
function buildPreset(input3) {
|
|
450693
450830
|
const id = input3.id;
|
|
450694
450831
|
const scope = `[data-composition-id="${id}"]`;
|
|
@@ -450725,7 +450862,8 @@ function buildPreset(input3) {
|
|
|
450725
450862
|
const captionInner = useWordSync ? renderTranscriptSpans(transcript) : esc(captionText);
|
|
450726
450863
|
const wordCss = useWordSync ? `
|
|
450727
450864
|
${scope} .caption .word { display: inline-block; opacity: 0; }` : "";
|
|
450728
|
-
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);`;
|
|
450729
450867
|
return {
|
|
450730
450868
|
css: `${scope} {
|
|
450731
450869
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450733,21 +450871,27 @@ function buildPreset(input3) {
|
|
|
450733
450871
|
color: #fff; overflow: hidden; background: #000;
|
|
450734
450872
|
}
|
|
450735
450873
|
${backdrop}
|
|
450874
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450736
450875
|
${scope} .caption {
|
|
450737
450876
|
position: absolute;
|
|
450738
450877
|
left: 8%; right: 8%; bottom: 12%;
|
|
450739
450878
|
text-align: center;
|
|
450740
|
-
font-size:
|
|
450879
|
+
font-size: ${captionFontPx}px;
|
|
450741
450880
|
font-weight: 700;
|
|
450742
450881
|
line-height: 1.2;
|
|
450882
|
+
overflow-wrap: break-word;
|
|
450743
450883
|
text-shadow: 0 4px 20px rgba(0,0,0,0.65);
|
|
450744
450884
|
}${wordCss}`,
|
|
450745
450885
|
body: `${backdropMarkup}
|
|
450746
450886
|
<div class="caption" id="caption">${captionInner}</div>`,
|
|
450747
|
-
timeline
|
|
450887
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
450888
|
+
${kenBurnsTween(scope, dur)}
|
|
450889
|
+
${captionTween}
|
|
450890
|
+
${idleHeroPulse(scope, "#caption", 1, dur)}`
|
|
450748
450891
|
};
|
|
450749
450892
|
}
|
|
450750
450893
|
case "announcement": {
|
|
450894
|
+
const fontSize = fitFontSize(headline, 160, 72, 22);
|
|
450751
450895
|
return {
|
|
450752
450896
|
css: `${scope} {
|
|
450753
450897
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450755,6 +450899,7 @@ function buildPreset(input3) {
|
|
|
450755
450899
|
color: #fff; overflow: hidden; background: #000;
|
|
450756
450900
|
}
|
|
450757
450901
|
${backdrop}
|
|
450902
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450758
450903
|
${scope} .announce {
|
|
450759
450904
|
position: absolute; inset: 0;
|
|
450760
450905
|
display: flex; align-items: center; justify-content: center;
|
|
@@ -450763,10 +450908,11 @@ function buildPreset(input3) {
|
|
|
450763
450908
|
}
|
|
450764
450909
|
${scope} .announce h1 {
|
|
450765
450910
|
margin: 0;
|
|
450766
|
-
font-size:
|
|
450911
|
+
font-size: ${fontSize}px;
|
|
450767
450912
|
font-weight: 900;
|
|
450768
450913
|
letter-spacing: -4px;
|
|
450769
|
-
line-height: 1;
|
|
450914
|
+
line-height: 1.05;
|
|
450915
|
+
overflow-wrap: break-word;
|
|
450770
450916
|
background: linear-gradient(90deg, #8e2de2, #00c9ff);
|
|
450771
450917
|
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
450772
450918
|
text-shadow: 0 8px 40px rgba(142,45,226,0.35);
|
|
@@ -450776,8 +450922,12 @@ function buildPreset(input3) {
|
|
|
450776
450922
|
// Faster, snappier entrance and no tail fade-out — see the
|
|
450777
450923
|
// matching note in the `simple` case above. The headline stays
|
|
450778
450924
|
// on screen until the producer cuts to the next clip; the next
|
|
450779
|
-
// scene's own fade-in handles the visual transition.
|
|
450780
|
-
|
|
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)}`
|
|
450781
450931
|
};
|
|
450782
450932
|
}
|
|
450783
450933
|
case "explainer": {
|
|
@@ -450789,6 +450939,7 @@ function buildPreset(input3) {
|
|
|
450789
450939
|
const wordCss = useWordSync ? `
|
|
450790
450940
|
${scope} #subtitle .word { display: inline-block; opacity: 0; }` : "";
|
|
450791
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);
|
|
450792
450943
|
return {
|
|
450793
450944
|
css: `${scope} {
|
|
450794
450945
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450796,6 +450947,7 @@ function buildPreset(input3) {
|
|
|
450796
450947
|
color: #fff; overflow: hidden; background: #000;
|
|
450797
450948
|
}
|
|
450798
450949
|
${backdrop}
|
|
450950
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450799
450951
|
${scope} .stage {
|
|
450800
450952
|
position: absolute; inset: 0;
|
|
450801
450953
|
display: flex; flex-direction: column; justify-content: center;
|
|
@@ -450806,11 +450958,13 @@ function buildPreset(input3) {
|
|
|
450806
450958
|
color: #00c9ff; font-weight: 600;
|
|
450807
450959
|
}
|
|
450808
450960
|
${scope} .title {
|
|
450809
|
-
font-size:
|
|
450961
|
+
font-size: ${titleFontPx}px; font-weight: 800; letter-spacing: -2px;
|
|
450810
450962
|
line-height: 1.05; margin: 0;
|
|
450963
|
+
overflow-wrap: break-word;
|
|
450811
450964
|
}
|
|
450812
450965
|
${scope} .subtitle {
|
|
450813
450966
|
font-size: 38px; font-weight: 300; color: #c0c0d0; max-width: 80%;
|
|
450967
|
+
overflow-wrap: break-word;
|
|
450814
450968
|
}${wordCss}`,
|
|
450815
450969
|
body: `${backdropMarkup}
|
|
450816
450970
|
<div class="stage">
|
|
@@ -450818,9 +450972,12 @@ function buildPreset(input3) {
|
|
|
450818
450972
|
<h1 class="title" id="title">${esc(headline)}</h1>${sub ? `
|
|
450819
450973
|
<div class="subtitle" id="subtitle">${subtitleInner}</div>` : ""}
|
|
450820
450974
|
</div>`,
|
|
450821
|
-
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);
|
|
450822
450978
|
tl.from('${scope} #title', { opacity: 0, y: 60, duration: 0.7, ease: 'power3.out' }, 0.25);
|
|
450823
|
-
${subtitleTween}
|
|
450979
|
+
${subtitleTween}
|
|
450980
|
+
${idleHeroPulse(scope, "#title", 1.2, dur)}`
|
|
450824
450981
|
};
|
|
450825
450982
|
}
|
|
450826
450983
|
case "kinetic-type": {
|
|
@@ -450836,6 +450993,9 @@ function buildPreset(input3) {
|
|
|
450836
450993
|
const start = (0.05 + i * stagger).toFixed(2);
|
|
450837
450994
|
return `tl.from('${scope} #w-${i}', { opacity: 0, y: 80, scale: 0.8, duration: 0.45, ease: 'back.out(1.8)' }, ${start});`;
|
|
450838
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)));
|
|
450839
450999
|
return {
|
|
450840
451000
|
css: `${scope} {
|
|
450841
451001
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450843,21 +451003,28 @@ function buildPreset(input3) {
|
|
|
450843
451003
|
color: #fff; overflow: hidden; background: #000;
|
|
450844
451004
|
}
|
|
450845
451005
|
${backdrop}
|
|
451006
|
+
${scope} .backdrop { transform-origin: center; }
|
|
450846
451007
|
${scope} .kinetic {
|
|
450847
451008
|
position: absolute; inset: 0;
|
|
450848
451009
|
display: flex; align-items: center; justify-content: center;
|
|
451010
|
+
flex-wrap: wrap; gap: 8px 16px;
|
|
450849
451011
|
text-align: center; padding: 0 6%;
|
|
450850
|
-
font-size:
|
|
451012
|
+
font-size: ${kineticFontPx}px; font-weight: 900; letter-spacing: -6px;
|
|
450851
451013
|
line-height: 1; text-shadow: 0 6px 30px rgba(0,0,0,0.6);
|
|
451014
|
+
overflow-wrap: break-word;
|
|
450852
451015
|
}
|
|
450853
451016
|
${scope} .kinetic .word { display: inline-block; margin: 0 12px; }`,
|
|
450854
451017
|
body: `${backdropMarkup}
|
|
450855
451018
|
<div class="kinetic">${wordSpans}</div>`,
|
|
450856
|
-
timeline:
|
|
451019
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
451020
|
+
${kenBurnsTween(scope, dur)}
|
|
451021
|
+
${tweens}
|
|
451022
|
+
${kineticWordBobs(scope, words.length, idleStart, dur)}`
|
|
450857
451023
|
};
|
|
450858
451024
|
}
|
|
450859
451025
|
case "product-shot": {
|
|
450860
451026
|
const label = kicker || humanise(id);
|
|
451027
|
+
const headlineFontPx = fitFontSize(headline, 72, 40, 50);
|
|
450861
451028
|
return {
|
|
450862
451029
|
css: `${scope} {
|
|
450863
451030
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
@@ -450875,22 +451042,26 @@ function buildPreset(input3) {
|
|
|
450875
451042
|
}
|
|
450876
451043
|
${scope} .product-headline {
|
|
450877
451044
|
position: absolute; left: 8%; right: 8%; bottom: 14%;
|
|
450878
|
-
font-size:
|
|
450879
|
-
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);
|
|
450880
451048
|
}${subhead ? `
|
|
450881
451049
|
${scope} .product-sub {
|
|
450882
451050
|
position: absolute; left: 8%; right: 8%; bottom: 8%;
|
|
450883
451051
|
font-size: 28px; font-weight: 400; color: #d0d0e0;
|
|
451052
|
+
overflow-wrap: break-word;
|
|
450884
451053
|
text-shadow: 0 2px 10px rgba(0,0,0,0.7);
|
|
450885
451054
|
}` : ""}`,
|
|
450886
451055
|
body: `${backdropMarkup}
|
|
450887
451056
|
<div class="label" id="label">${esc(label)}</div>
|
|
450888
451057
|
<div class="product-headline" id="headline">${esc(headline)}</div>${subhead ? `
|
|
450889
451058
|
<div class="product-sub" id="subhead">${esc(subhead)}</div>` : ""}`,
|
|
450890
|
-
timeline:
|
|
451059
|
+
timeline: `${crossfadeTweens(scope, dur)}
|
|
451060
|
+
tl.fromTo('${scope} .backdrop', { scale: 1.0 }, { scale: 1.12, duration: ${dur.toFixed(2)}, ease: 'none' }, 0);
|
|
450891
451061
|
tl.from('${scope} #label', { opacity: 0, x: -30, duration: 0.5, ease: 'power3.out' }, 0.2);
|
|
450892
451062
|
tl.from('${scope} #headline', { opacity: 0, y: 40, duration: 0.6, ease: 'power3.out' }, 0.4);${subhead ? `
|
|
450893
|
-
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)}`
|
|
450894
451065
|
};
|
|
450895
451066
|
}
|
|
450896
451067
|
}
|
|
@@ -450936,7 +451107,7 @@ ${audioBlock}
|
|
|
450936
451107
|
</template>
|
|
450937
451108
|
`;
|
|
450938
451109
|
}
|
|
450939
|
-
function nextSceneStart(rootHtml) {
|
|
451110
|
+
function nextSceneStart(rootHtml, overlap = 0) {
|
|
450940
451111
|
const clipRegex = /<div\s+class="clip"[^>]*?\sdata-start="([\d.]+)"[^>]*?\sdata-duration="([\d.]+)"/gi;
|
|
450941
451112
|
let maxEnd = 0;
|
|
450942
451113
|
let match2;
|
|
@@ -450944,14 +451115,15 @@ function nextSceneStart(rootHtml) {
|
|
|
450944
451115
|
const end = parseFloat(match2[1]) + parseFloat(match2[2]);
|
|
450945
451116
|
if (Number.isFinite(end) && end > maxEnd) maxEnd = end;
|
|
450946
451117
|
}
|
|
450947
|
-
return maxEnd;
|
|
451118
|
+
return Math.max(0, maxEnd - overlap);
|
|
450948
451119
|
}
|
|
450949
451120
|
function buildClipReference(opts) {
|
|
450950
451121
|
const start = Number(opts.start.toFixed(3));
|
|
450951
451122
|
const duration = Number(opts.duration.toFixed(3));
|
|
450952
451123
|
const track = opts.trackIndex ?? 1;
|
|
450953
451124
|
const src = opts.src ?? `compositions/scene-${opts.id}.html`;
|
|
450954
|
-
|
|
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>`;
|
|
450955
451127
|
}
|
|
450956
451128
|
function insertClipIntoRoot(rootHtml, clip) {
|
|
450957
451129
|
const clipDiv = buildClipReference(clip);
|
|
@@ -450984,7 +451156,7 @@ function readRootDims(rootHtml) {
|
|
|
450984
451156
|
if (!widthMatch || !heightMatch) return null;
|
|
450985
451157
|
return { width: parseInt(widthMatch[1], 10), height: parseInt(heightMatch[1], 10) };
|
|
450986
451158
|
}
|
|
450987
|
-
var SCENE_PRESETS, GSAP_CDN;
|
|
451159
|
+
var SCENE_PRESETS, GSAP_CDN, SCENE_OVERLAP_SECONDS;
|
|
450988
451160
|
var init_scene_html_emit = __esm({
|
|
450989
451161
|
"../cli/src/commands/_shared/scene-html-emit.ts"() {
|
|
450990
451162
|
"use strict";
|
|
@@ -450996,6 +451168,7 @@ var init_scene_html_emit = __esm({
|
|
|
450996
451168
|
"product-shot"
|
|
450997
451169
|
];
|
|
450998
451170
|
GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js";
|
|
451171
|
+
SCENE_OVERLAP_SECONDS = 0.4;
|
|
450999
451172
|
}
|
|
451000
451173
|
});
|
|
451001
451174
|
|
|
@@ -451167,7 +451340,12 @@ async function executeSegmentsToScenes(opts) {
|
|
|
451167
451340
|
const dims = aspectToDims(aspect);
|
|
451168
451341
|
const preset = opts.scenePreset ?? DEFAULT_PRESET;
|
|
451169
451342
|
const projectName = opts.projectName ?? basename8(outputDir);
|
|
451170
|
-
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
|
+
})();
|
|
451171
451349
|
const baseError = (error) => ({
|
|
451172
451350
|
success: false,
|
|
451173
451351
|
outputDir,
|
|
@@ -451240,9 +451418,10 @@ async function executeSegmentsToScenes(opts) {
|
|
|
451240
451418
|
id,
|
|
451241
451419
|
start: clipStart,
|
|
451242
451420
|
duration,
|
|
451421
|
+
trackIndex: i % 2 + 1,
|
|
451243
451422
|
src: `compositions/${id}.html`
|
|
451244
451423
|
});
|
|
451245
|
-
clipStart += duration;
|
|
451424
|
+
clipStart += duration - SCENE_OVERLAP_SECONDS;
|
|
451246
451425
|
}
|
|
451247
451426
|
await writeFile12(rootAbs, rootHtml, "utf-8");
|
|
451248
451427
|
let lintResult;
|
|
@@ -464231,6 +464410,176 @@ function parseTtsProviderName(value) {
|
|
|
464231
464410
|
|
|
464232
464411
|
// ../cli/src/commands/scene.ts
|
|
464233
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
|
|
464234
464583
|
init_scene_html_emit();
|
|
464235
464584
|
init_scene_lint();
|
|
464236
464585
|
init_output();
|
|
@@ -464256,6 +464605,18 @@ function validatePreset(value) {
|
|
|
464256
464605
|
}
|
|
464257
464606
|
return value;
|
|
464258
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
|
+
}
|
|
464259
464620
|
var sceneCommand = new Command("scene").description("Author and render per-scene HTML compositions (Hyperframes backend)").addHelpText("after", `
|
|
464260
464621
|
Examples:
|
|
464261
464622
|
$ vibe scene init my-video # Scaffold a new project
|
|
@@ -464273,21 +464634,28 @@ Examples:
|
|
|
464273
464634
|
|
|
464274
464635
|
A scene project is bilingual: it works with both \`vibe\` and \`npx hyperframes\`.
|
|
464275
464636
|
Run 'vibe schema scene.<command>' for structured parameter info.`);
|
|
464276
|
-
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) => {
|
|
464277
464638
|
const aspect = validateAspect(options.ratio);
|
|
464278
464639
|
const duration = validateDuration(options.duration);
|
|
464279
464640
|
const name = options.name ?? basename18(dir.replace(/\/+$/, ""));
|
|
464641
|
+
const visualStyle = options.visualStyle ? validateVisualStyle(options.visualStyle) : void 0;
|
|
464280
464642
|
if (options.dryRun) {
|
|
464281
464643
|
outputResult({
|
|
464282
464644
|
dryRun: true,
|
|
464283
464645
|
command: "scene init",
|
|
464284
|
-
params: {
|
|
464646
|
+
params: {
|
|
464647
|
+
dir,
|
|
464648
|
+
name,
|
|
464649
|
+
aspect,
|
|
464650
|
+
duration,
|
|
464651
|
+
visualStyle: visualStyle?.name ?? null
|
|
464652
|
+
}
|
|
464285
464653
|
});
|
|
464286
464654
|
return;
|
|
464287
464655
|
}
|
|
464288
464656
|
const spinner2 = isJsonMode() ? null : ora(`Scaffolding scene project at ${dir}...`).start();
|
|
464289
464657
|
try {
|
|
464290
|
-
const result = await scaffoldSceneProject({ dir, name, aspect, duration });
|
|
464658
|
+
const result = await scaffoldSceneProject({ dir, name, aspect, duration, visualStyle });
|
|
464291
464659
|
if (isJsonMode()) {
|
|
464292
464660
|
outputResult({
|
|
464293
464661
|
success: true,
|
|
@@ -464296,6 +464664,7 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464296
464664
|
name,
|
|
464297
464665
|
aspect,
|
|
464298
464666
|
duration,
|
|
464667
|
+
visualStyle: visualStyle?.name ?? null,
|
|
464299
464668
|
created: result.created,
|
|
464300
464669
|
merged: result.merged,
|
|
464301
464670
|
skipped: result.skipped
|
|
@@ -464312,7 +464681,13 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464312
464681
|
console.log();
|
|
464313
464682
|
console.log(source_default.bold.cyan("Next steps"));
|
|
464314
464683
|
console.log(source_default.dim("\u2500".repeat(60)));
|
|
464315
|
-
|
|
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")}`);
|
|
464316
464691
|
console.log(` ${source_default.cyan("vibe scene lint")} ${source_default.dim("# validate HTML")}`);
|
|
464317
464692
|
console.log(` ${source_default.cyan("vibe scene render")} ${source_default.dim("# render to MP4")}`);
|
|
464318
464693
|
} catch (error) {
|
|
@@ -464321,6 +464696,69 @@ sceneCommand.command("init").description("Scaffold a new scene project (or safel
|
|
|
464321
464696
|
exitWithError(generalError(`Failed to scaffold: ${msg}`));
|
|
464322
464697
|
}
|
|
464323
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
|
+
});
|
|
464324
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) => {
|
|
464325
464763
|
if (options.style) options.style = validatePreset(options.style);
|
|
464326
464764
|
if (options.duration !== void 0) options.duration = validateDuration(options.duration);
|
|
@@ -464631,7 +465069,20 @@ async function executeSceneAdd(opts) {
|
|
|
464631
465069
|
}
|
|
464632
465070
|
const cfg = await loadVibeProjectConfig(projectDir);
|
|
464633
465071
|
const fallback2 = cfg?.defaultSceneDuration ?? 5;
|
|
464634
|
-
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));
|
|
464635
465086
|
opts.onProgress?.("Emitting scene HTML...");
|
|
464636
465087
|
const sceneHtml = emitSceneHtml({
|
|
464637
465088
|
id,
|
|
@@ -464649,8 +465100,10 @@ async function executeSceneAdd(opts) {
|
|
|
464649
465100
|
await mkdir19(dirname25(scenePath), { recursive: true });
|
|
464650
465101
|
await writeFile25(scenePath, sceneHtml, "utf-8");
|
|
464651
465102
|
opts.onProgress?.("Updating root composition...");
|
|
464652
|
-
const start = nextSceneStart(rootHtmlBefore);
|
|
464653
|
-
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 });
|
|
464654
465107
|
await writeFile25(rootPath, updated, "utf-8");
|
|
464655
465108
|
const transcriptAbsPath = transcriptRelPath ? resolve40(projectDir, transcriptRelPath) : void 0;
|
|
464656
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/
|
|
61
|
-
"@vibeframe/
|
|
60
|
+
"@vibeframe/cli": "0.58.0",
|
|
61
|
+
"@vibeframe/core": "0.58.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=20"
|