hyperframes 0.7.103 → 0.7.105
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/cli.js +1438 -653
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/skills/hyperframes-cli/SKILL.md +13 -7
- package/dist/studio/assets/{hyperframes-player-DUB-xtR5.js → hyperframes-player-Jx07OQgw.js} +1 -1
- package/dist/studio/assets/{index-DHc-xHLb.js → index-CryZ0PGi.js} +1 -1
- package/dist/studio/assets/{index-Cez_yvk5.js → index-Dqi2GmOp.js} +1 -1
- package/dist/studio/assets/{index-CxC2vn2-.js → index-DuxKGsHZ.js} +214 -214
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +779 -294
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.7.
|
|
53
|
+
VERSION = true ? "0.7.105" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -4819,7 +4819,7 @@ var require_util = __commonJS({
|
|
|
4819
4819
|
return url;
|
|
4820
4820
|
}
|
|
4821
4821
|
exports.urlGenerate = urlGenerate;
|
|
4822
|
-
function
|
|
4822
|
+
function normalize3(aPath) {
|
|
4823
4823
|
var path2 = aPath;
|
|
4824
4824
|
var url = urlParse(aPath);
|
|
4825
4825
|
if (url) {
|
|
@@ -4856,8 +4856,8 @@ var require_util = __commonJS({
|
|
|
4856
4856
|
}
|
|
4857
4857
|
return path2;
|
|
4858
4858
|
}
|
|
4859
|
-
exports.normalize =
|
|
4860
|
-
function
|
|
4859
|
+
exports.normalize = normalize3;
|
|
4860
|
+
function join140(aRoot, aPath) {
|
|
4861
4861
|
if (aRoot === "") {
|
|
4862
4862
|
aRoot = ".";
|
|
4863
4863
|
}
|
|
@@ -4882,14 +4882,14 @@ var require_util = __commonJS({
|
|
|
4882
4882
|
aRootUrl.host = aPath;
|
|
4883
4883
|
return urlGenerate(aRootUrl);
|
|
4884
4884
|
}
|
|
4885
|
-
var joined = aPath.charAt(0) === "/" ? aPath :
|
|
4885
|
+
var joined = aPath.charAt(0) === "/" ? aPath : normalize3(aRoot.replace(/\/+$/, "") + "/" + aPath);
|
|
4886
4886
|
if (aRootUrl) {
|
|
4887
4887
|
aRootUrl.path = joined;
|
|
4888
4888
|
return urlGenerate(aRootUrl);
|
|
4889
4889
|
}
|
|
4890
4890
|
return joined;
|
|
4891
4891
|
}
|
|
4892
|
-
exports.join =
|
|
4892
|
+
exports.join = join140;
|
|
4893
4893
|
exports.isAbsolute = function(aPath) {
|
|
4894
4894
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
4895
4895
|
};
|
|
@@ -5062,9 +5062,9 @@ var require_util = __commonJS({
|
|
|
5062
5062
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
5063
5063
|
}
|
|
5064
5064
|
}
|
|
5065
|
-
sourceURL =
|
|
5065
|
+
sourceURL = join140(urlGenerate(parsed), sourceURL);
|
|
5066
5066
|
}
|
|
5067
|
-
return
|
|
5067
|
+
return normalize3(sourceURL);
|
|
5068
5068
|
}
|
|
5069
5069
|
exports.computeSourceURL = computeSourceURL;
|
|
5070
5070
|
}
|
|
@@ -6815,7 +6815,7 @@ var require_esprima2 = __commonJS({
|
|
|
6815
6815
|
return parse9(code, parsingOptions, delegate);
|
|
6816
6816
|
}
|
|
6817
6817
|
exports2.parseScript = parseScript2;
|
|
6818
|
-
function
|
|
6818
|
+
function tokenize2(code, options, delegate) {
|
|
6819
6819
|
var tokenizer2 = new tokenizer_1.Tokenizer(code, options);
|
|
6820
6820
|
var tokens;
|
|
6821
6821
|
tokens = [];
|
|
@@ -6838,7 +6838,7 @@ var require_esprima2 = __commonJS({
|
|
|
6838
6838
|
}
|
|
6839
6839
|
return tokens;
|
|
6840
6840
|
}
|
|
6841
|
-
exports2.tokenize =
|
|
6841
|
+
exports2.tokenize = tokenize2;
|
|
6842
6842
|
var syntax_1 = __webpack_require__(2);
|
|
6843
6843
|
exports2.Syntax = syntax_1.Syntax;
|
|
6844
6844
|
exports2.version = "4.0.1";
|
|
@@ -13003,7 +13003,7 @@ var require_options = __commonJS({
|
|
|
13003
13003
|
tokens: true
|
|
13004
13004
|
};
|
|
13005
13005
|
var hasOwn4 = defaults.hasOwnProperty;
|
|
13006
|
-
function
|
|
13006
|
+
function normalize3(opts) {
|
|
13007
13007
|
var options = opts || defaults;
|
|
13008
13008
|
function get(key2) {
|
|
13009
13009
|
return hasOwn4.call(options, key2) ? options[key2] : defaults[key2];
|
|
@@ -13030,7 +13030,7 @@ var require_options = __commonJS({
|
|
|
13030
13030
|
tokens: !!get("tokens")
|
|
13031
13031
|
};
|
|
13032
13032
|
}
|
|
13033
|
-
exports.normalize =
|
|
13033
|
+
exports.normalize = normalize3;
|
|
13034
13034
|
}
|
|
13035
13035
|
});
|
|
13036
13036
|
|
|
@@ -21731,7 +21731,7 @@ var require_lib = __commonJS({
|
|
|
21731
21731
|
}
|
|
21732
21732
|
var skipWhiteSpace2 = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
|
|
21733
21733
|
var skipWhiteSpaceInLine = /(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/g;
|
|
21734
|
-
function
|
|
21734
|
+
function isWhitespace4(code2) {
|
|
21735
21735
|
switch (code2) {
|
|
21736
21736
|
case 9:
|
|
21737
21737
|
case 11:
|
|
@@ -23238,7 +23238,7 @@ var require_lib = __commonJS({
|
|
|
23238
23238
|
}
|
|
23239
23239
|
break;
|
|
23240
23240
|
default:
|
|
23241
|
-
if (
|
|
23241
|
+
if (isWhitespace4(ch)) {
|
|
23242
23242
|
++this.state.pos;
|
|
23243
23243
|
} else if (ch === 45 && !this.inModule && this.optionFlags & 8192) {
|
|
23244
23244
|
const pos = this.state.pos;
|
|
@@ -40807,7 +40807,7 @@ function formatAttributes(attributes2, opts) {
|
|
|
40807
40807
|
var _a4;
|
|
40808
40808
|
if (!attributes2)
|
|
40809
40809
|
return;
|
|
40810
|
-
const
|
|
40810
|
+
const encode3 = ((_a4 = opts.encodeEntities) !== null && _a4 !== void 0 ? _a4 : opts.decodeEntities) === false ? replaceQuotes : opts.xmlMode || opts.encodeEntities !== "utf8" ? encodeXML : escapeAttribute;
|
|
40811
40811
|
return Object.keys(attributes2).map((key2) => {
|
|
40812
40812
|
var _a5, _b;
|
|
40813
40813
|
const value = (_a5 = attributes2[key2]) !== null && _a5 !== void 0 ? _a5 : "";
|
|
@@ -40817,7 +40817,7 @@ function formatAttributes(attributes2, opts) {
|
|
|
40817
40817
|
if (!opts.emptyAttrs && !opts.xmlMode && value === "") {
|
|
40818
40818
|
return key2;
|
|
40819
40819
|
}
|
|
40820
|
-
return `${key2}="${
|
|
40820
|
+
return `${key2}="${encode3(value)}"`;
|
|
40821
40821
|
}).join(" ");
|
|
40822
40822
|
}
|
|
40823
40823
|
function render(node, options = {}) {
|
|
@@ -62930,7 +62930,10 @@ function passthroughFields(parsed) {
|
|
|
62930
62930
|
skillsUpdateAvailable: parsed.skillsUpdateAvailable,
|
|
62931
62931
|
skillsOutdatedCount: parsed.skillsOutdatedCount,
|
|
62932
62932
|
skillsMissingCount: parsed.skillsMissingCount,
|
|
62933
|
-
skillsRemovedCount: parsed.skillsRemovedCount
|
|
62933
|
+
skillsRemovedCount: parsed.skillsRemovedCount,
|
|
62934
|
+
// Consent, so it survives the run that recorded it. Undefined stays
|
|
62935
|
+
// undefined on purpose: it means never asked, which is not the same as no.
|
|
62936
|
+
localEmbeddingEnabled: parsed.localEmbeddingEnabled
|
|
62934
62937
|
};
|
|
62935
62938
|
}
|
|
62936
62939
|
function guardedFields(parsed) {
|
|
@@ -63465,6 +63468,12 @@ function resolveDefaultDrawElement(args) {
|
|
|
63465
63468
|
if (!isDrawElementPlatform(args.platform) || args.browserGpuMode === "software") return false;
|
|
63466
63469
|
return args.workerEncode;
|
|
63467
63470
|
}
|
|
63471
|
+
function explainDrawElementDisabled(args) {
|
|
63472
|
+
if (!isDrawElementPlatform(args.platform)) return "unsupported_platform";
|
|
63473
|
+
if (args.browserGpuMode === "software") return "software_gpu";
|
|
63474
|
+
if (!args.workerEncode) return "worker_encode_off";
|
|
63475
|
+
return "disabled";
|
|
63476
|
+
}
|
|
63468
63477
|
function resolveConfig(overrides) {
|
|
63469
63478
|
const env = (key2) => process.env[key2];
|
|
63470
63479
|
const envNum = (key2, fallback) => {
|
|
@@ -74478,7 +74487,7 @@ var require_tokenize = __commonJS({
|
|
|
74478
74487
|
var _b;
|
|
74479
74488
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
74480
74489
|
exports.FIELDS = void 0;
|
|
74481
|
-
exports.default =
|
|
74490
|
+
exports.default = tokenize2;
|
|
74482
74491
|
var t2 = __importStar2(require_tokenTypes());
|
|
74483
74492
|
var unescapable = (_a4 = {}, _a4[t2.tab] = true, _a4[t2.newline] = true, _a4[t2.cr] = true, _a4[t2.feed] = true, _a4);
|
|
74484
74493
|
var wordDelimiters = (_b = {}, _b[t2.space] = true, _b[t2.tab] = true, _b[t2.newline] = true, _b[t2.cr] = true, _b[t2.feed] = true, _b[t2.ampersand] = true, _b[t2.asterisk] = true, _b[t2.bang] = true, _b[t2.comma] = true, _b[t2.colon] = true, _b[t2.semicolon] = true, _b[t2.openParenthesis] = true, _b[t2.closeParenthesis] = true, _b[t2.openSquare] = true, _b[t2.closeSquare] = true, _b[t2.singleQuote] = true, _b[t2.doubleQuote] = true, _b[t2.plus] = true, _b[t2.pipe] = true, _b[t2.tilde] = true, _b[t2.greaterThan] = true, _b[t2.equals] = true, _b[t2.dollar] = true, _b[t2.caret] = true, _b[t2.slash] = true, _b);
|
|
@@ -74531,7 +74540,7 @@ var require_tokenize = __commonJS({
|
|
|
74531
74540
|
START_POS: 5,
|
|
74532
74541
|
END_POS: 6
|
|
74533
74542
|
};
|
|
74534
|
-
function
|
|
74543
|
+
function tokenize2(input2) {
|
|
74535
74544
|
var tokens = [];
|
|
74536
74545
|
var css = input2.css.valueOf();
|
|
74537
74546
|
var length = css.length;
|
|
@@ -90278,6 +90287,7 @@ __export(src_exports, {
|
|
|
90278
90287
|
encodeFramesChunkedConcat: () => encodeFramesChunkedConcat,
|
|
90279
90288
|
encodeFramesFromDir: () => encodeFramesFromDir,
|
|
90280
90289
|
executeParallelCapture: () => executeParallelCapture,
|
|
90290
|
+
explainDrawElementDisabled: () => explainDrawElementDisabled,
|
|
90281
90291
|
extractAllVideoFrames: () => extractAllVideoFrames,
|
|
90282
90292
|
extractAudioMetadata: () => extractAudioMetadata,
|
|
90283
90293
|
extractFinalVideoFrameTimestamp: () => extractFinalVideoFrameTimestamp,
|
|
@@ -94442,49 +94452,88 @@ var init_ffmpeg = __esm({
|
|
|
94442
94452
|
});
|
|
94443
94453
|
|
|
94444
94454
|
// src/utils/download.ts
|
|
94455
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
94445
94456
|
import { createWriteStream as createWriteStream2, renameSync as renameSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
94446
94457
|
import { get as httpsGet } from "https";
|
|
94458
|
+
import { Transform as Transform2 } from "stream";
|
|
94447
94459
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
94460
|
+
function redirectTarget(location, from) {
|
|
94461
|
+
return new URL(location, from).toString();
|
|
94462
|
+
}
|
|
94448
94463
|
function removePartialFile(path2) {
|
|
94449
94464
|
try {
|
|
94450
94465
|
unlinkSync2(path2);
|
|
94451
94466
|
} catch {
|
|
94452
94467
|
}
|
|
94453
94468
|
}
|
|
94469
|
+
function enforceByteLimit(maxBytes) {
|
|
94470
|
+
let received = 0;
|
|
94471
|
+
return new Transform2({
|
|
94472
|
+
transform(chunk, _encoding, callback) {
|
|
94473
|
+
received += chunk.byteLength;
|
|
94474
|
+
callback(
|
|
94475
|
+
received > maxBytes ? new Error(`Download exceeded ${maxBytes} bytes`) : null,
|
|
94476
|
+
chunk
|
|
94477
|
+
);
|
|
94478
|
+
}
|
|
94479
|
+
});
|
|
94480
|
+
}
|
|
94454
94481
|
function downloadFile(url, dest, options = {}) {
|
|
94455
|
-
const tmp = `${dest}.tmp`;
|
|
94482
|
+
const tmp = `${dest}.${process.pid}.${randomUUID6()}.tmp`;
|
|
94456
94483
|
const timeoutMs = options.timeoutMs ?? DEFAULT_DOWNLOAD_TIMEOUT_MS;
|
|
94484
|
+
const maxBytes = options.maxBytes;
|
|
94457
94485
|
return new Promise((resolve77, reject) => {
|
|
94458
|
-
const follow = (u) => {
|
|
94486
|
+
const follow = (u, hops = 0) => {
|
|
94459
94487
|
let activeResponse;
|
|
94460
94488
|
let responsePipelineStarted = false;
|
|
94461
94489
|
let requestError;
|
|
94462
|
-
|
|
94463
|
-
|
|
94464
|
-
|
|
94465
|
-
|
|
94466
|
-
if (
|
|
94490
|
+
let request;
|
|
94491
|
+
try {
|
|
94492
|
+
request = httpsGet(u, (res) => {
|
|
94493
|
+
activeResponse = res;
|
|
94494
|
+
if (res.statusCode && REDIRECT_CODES.has(res.statusCode)) {
|
|
94495
|
+
const location = res.headers.location;
|
|
94496
|
+
if (location) {
|
|
94497
|
+
if (hops >= MAX_REDIRECTS2) {
|
|
94498
|
+
res.resume();
|
|
94499
|
+
removePartialFile(tmp);
|
|
94500
|
+
reject(
|
|
94501
|
+
new Error(`Download failed: more than ${MAX_REDIRECTS2} redirects from ${url}`)
|
|
94502
|
+
);
|
|
94503
|
+
return;
|
|
94504
|
+
}
|
|
94505
|
+
res.resume();
|
|
94506
|
+
try {
|
|
94507
|
+
follow(redirectTarget(location, u), hops + 1);
|
|
94508
|
+
} catch (error) {
|
|
94509
|
+
removePartialFile(tmp);
|
|
94510
|
+
reject(error);
|
|
94511
|
+
}
|
|
94512
|
+
return;
|
|
94513
|
+
}
|
|
94514
|
+
}
|
|
94515
|
+
if (res.statusCode !== 200) {
|
|
94467
94516
|
res.resume();
|
|
94468
|
-
|
|
94517
|
+
removePartialFile(tmp);
|
|
94518
|
+
reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
94469
94519
|
return;
|
|
94470
94520
|
}
|
|
94471
|
-
|
|
94472
|
-
|
|
94473
|
-
res
|
|
94474
|
-
|
|
94475
|
-
|
|
94476
|
-
|
|
94477
|
-
|
|
94478
|
-
|
|
94479
|
-
|
|
94480
|
-
|
|
94481
|
-
renameSync4(tmp, dest);
|
|
94482
|
-
resolve77();
|
|
94483
|
-
}).catch((err) => {
|
|
94484
|
-
removePartialFile(tmp);
|
|
94485
|
-
reject(requestError ?? err);
|
|
94521
|
+
const file = createWriteStream2(tmp);
|
|
94522
|
+
responsePipelineStarted = true;
|
|
94523
|
+
const transfer = maxBytes === void 0 ? pipeline2(res, file) : pipeline2(res, enforceByteLimit(maxBytes), file);
|
|
94524
|
+
transfer.then(() => {
|
|
94525
|
+
renameSync4(tmp, dest);
|
|
94526
|
+
resolve77();
|
|
94527
|
+
}).catch((err) => {
|
|
94528
|
+
removePartialFile(tmp);
|
|
94529
|
+
reject(requestError ?? err);
|
|
94530
|
+
});
|
|
94486
94531
|
});
|
|
94487
|
-
})
|
|
94532
|
+
} catch (error) {
|
|
94533
|
+
removePartialFile(tmp);
|
|
94534
|
+
reject(error);
|
|
94535
|
+
return;
|
|
94536
|
+
}
|
|
94488
94537
|
request.setTimeout(timeoutMs, () => {
|
|
94489
94538
|
request.destroy(new Error(`Download timed out after ${timeoutMs}ms`));
|
|
94490
94539
|
});
|
|
@@ -94501,11 +94550,13 @@ function downloadFile(url, dest, options = {}) {
|
|
|
94501
94550
|
follow(url);
|
|
94502
94551
|
});
|
|
94503
94552
|
}
|
|
94504
|
-
var DEFAULT_DOWNLOAD_TIMEOUT_MS;
|
|
94553
|
+
var DEFAULT_DOWNLOAD_TIMEOUT_MS, REDIRECT_CODES, MAX_REDIRECTS2;
|
|
94505
94554
|
var init_download = __esm({
|
|
94506
94555
|
"src/utils/download.ts"() {
|
|
94507
94556
|
"use strict";
|
|
94508
94557
|
DEFAULT_DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
94558
|
+
REDIRECT_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
94559
|
+
MAX_REDIRECTS2 = 10;
|
|
94509
94560
|
}
|
|
94510
94561
|
});
|
|
94511
94562
|
|
|
@@ -94714,7 +94765,7 @@ import { execFileSync as execFileSync5 } from "child_process";
|
|
|
94714
94765
|
import { existsSync as existsSync25, readFileSync as readFileSync14, mkdirSync as mkdirSync12, unlinkSync as unlinkSync3 } from "fs";
|
|
94715
94766
|
import { join as join21, extname as extname5 } from "path";
|
|
94716
94767
|
import { tmpdir as tmpdir3 } from "os";
|
|
94717
|
-
import { randomUUID as
|
|
94768
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
94718
94769
|
function detectLanguage(whisperPath, modelPath2, wavPath) {
|
|
94719
94770
|
try {
|
|
94720
94771
|
const output = execFileSync5(whisperPath, ["--model", modelPath2, "--detect-language", wavPath], {
|
|
@@ -94856,7 +94907,7 @@ function isVideoFile(filePath) {
|
|
|
94856
94907
|
return VIDEO_EXTENSIONS.has(extname5(filePath).toLowerCase());
|
|
94857
94908
|
}
|
|
94858
94909
|
function tempWavPath() {
|
|
94859
|
-
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${
|
|
94910
|
+
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${randomUUID7()}.wav`);
|
|
94860
94911
|
}
|
|
94861
94912
|
function extractAudio(videoPath) {
|
|
94862
94913
|
const ffmpegPath = findFFmpeg();
|
|
@@ -97313,8 +97364,8 @@ function detectHyperframesServer(port, normalizedProjectDir, expectedServerBuild
|
|
|
97313
97364
|
if (json.isHyperframes !== true) {
|
|
97314
97365
|
return resolveResult({ type: "not-hyperframes" });
|
|
97315
97366
|
}
|
|
97316
|
-
const
|
|
97317
|
-
if (
|
|
97367
|
+
const normalize3 = (p2) => resolve14(p2).replace(/\\/g, "/").toLowerCase();
|
|
97368
|
+
if (normalize3(json.projectDir) === normalizedProjectDir) {
|
|
97318
97369
|
if (expectedServerBuildSignature !== null && json.serverBuildSignature !== expectedServerBuildSignature) {
|
|
97319
97370
|
return resolveResult({ type: "mismatch", projectName: json.projectName });
|
|
97320
97371
|
}
|
|
@@ -98075,6 +98126,7 @@ function shouldWatchProjectFile(filename) {
|
|
|
98075
98126
|
}
|
|
98076
98127
|
function createProjectWatcher(projectDir) {
|
|
98077
98128
|
const listeners = /* @__PURE__ */ new Set();
|
|
98129
|
+
const pendingPaths = /* @__PURE__ */ new Set();
|
|
98078
98130
|
let debounceTimer = null;
|
|
98079
98131
|
let watcher = null;
|
|
98080
98132
|
try {
|
|
@@ -98082,10 +98134,16 @@ function createProjectWatcher(projectDir) {
|
|
|
98082
98134
|
if (!filename) return;
|
|
98083
98135
|
const relativePath = filename.toString();
|
|
98084
98136
|
if (!shouldWatchProjectFile(relativePath)) return;
|
|
98137
|
+
pendingPaths.add(relativePath);
|
|
98085
98138
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
98086
98139
|
debounceTimer = setTimeout(() => {
|
|
98087
|
-
|
|
98088
|
-
|
|
98140
|
+
const changedPaths = [...pendingPaths];
|
|
98141
|
+
pendingPaths.clear();
|
|
98142
|
+
debounceTimer = null;
|
|
98143
|
+
for (const changedPath of changedPaths) {
|
|
98144
|
+
for (const fn of listeners) {
|
|
98145
|
+
fn(changedPath);
|
|
98146
|
+
}
|
|
98089
98147
|
}
|
|
98090
98148
|
}, DEBOUNCE_MS);
|
|
98091
98149
|
});
|
|
@@ -98104,6 +98162,7 @@ function createProjectWatcher(projectDir) {
|
|
|
98104
98162
|
},
|
|
98105
98163
|
close() {
|
|
98106
98164
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
98165
|
+
pendingPaths.clear();
|
|
98107
98166
|
watcher?.close();
|
|
98108
98167
|
listeners.clear();
|
|
98109
98168
|
}
|
|
@@ -99464,7 +99523,7 @@ var init_chunk_6H3V3WGJ = __esm({
|
|
|
99464
99523
|
|
|
99465
99524
|
// ../studio-server/dist/chunk-ZPI6QXJH.js
|
|
99466
99525
|
import { spawn as spawn8 } from "child_process";
|
|
99467
|
-
import { createHash as createHash7, randomUUID as
|
|
99526
|
+
import { createHash as createHash7, randomUUID as randomUUID8 } from "crypto";
|
|
99468
99527
|
import {
|
|
99469
99528
|
existsSync as existsSync210,
|
|
99470
99529
|
mkdirSync as mkdirSync15,
|
|
@@ -99788,7 +99847,7 @@ async function transcodeToCache(absoluteSourcePath, cachePath2, variant) {
|
|
|
99788
99847
|
if (existsSync210(cachePath2)) return cachePath2;
|
|
99789
99848
|
const cacheDir = dirname14(cachePath2);
|
|
99790
99849
|
mkdirSync15(cacheDir, { recursive: true });
|
|
99791
|
-
const tempPath = join29(cacheDir, `.tmp-${
|
|
99850
|
+
const tempPath = join29(cacheDir, `.tmp-${randomUUID8()}-${basename4(cachePath2)}`);
|
|
99792
99851
|
try {
|
|
99793
99852
|
await runFfmpeg2(absoluteSourcePath, tempPath, variant);
|
|
99794
99853
|
renameSync6(tempPath, cachePath2);
|
|
@@ -106705,7 +106764,7 @@ import { basename as basename5, join as join42 } from "path";
|
|
|
106705
106764
|
import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as readFileSync32, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "fs";
|
|
106706
106765
|
import { Buffer as Buffer2 } from "buffer";
|
|
106707
106766
|
import { join as join52, relative as relative22 } from "path";
|
|
106708
|
-
import { createHash as createHash22, randomUUID as
|
|
106767
|
+
import { createHash as createHash22, randomUUID as randomUUID9 } from "crypto";
|
|
106709
106768
|
import { existsSync as existsSync37, readFileSync as readFileSync42, realpathSync as realpathSync6 } from "fs";
|
|
106710
106769
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
106711
106770
|
import { dirname as dirname15, relative as relative32, resolve as resolve24, sep as sep7 } from "path";
|
|
@@ -107168,7 +107227,7 @@ function fileContentVersion(content) {
|
|
|
107168
107227
|
}
|
|
107169
107228
|
function createWriteToken(requestToken) {
|
|
107170
107229
|
const token = requestToken?.trim();
|
|
107171
|
-
return token && token.length <= 200 ? token :
|
|
107230
|
+
return token && token.length <= 200 ? token : randomUUID9();
|
|
107172
107231
|
}
|
|
107173
107232
|
function recordFileWriteReceipt(absPath, receipt) {
|
|
107174
107233
|
const now = Date.now();
|
|
@@ -107178,12 +107237,13 @@ function recordFileWriteReceipt(absPath, receipt) {
|
|
|
107178
107237
|
current2.push({ ...receipt, recordedAt: now });
|
|
107179
107238
|
receipts.set(absPath, current2);
|
|
107180
107239
|
}
|
|
107181
|
-
function consumeFileWriteReceipt(absPath) {
|
|
107240
|
+
function consumeFileWriteReceipt(absPath, expectedVersion) {
|
|
107182
107241
|
const now = Date.now();
|
|
107183
107242
|
const current2 = (receipts.get(absPath) ?? []).filter(
|
|
107184
107243
|
(entry) => now - entry.recordedAt < RECEIPT_TTL_MS
|
|
107185
107244
|
);
|
|
107186
|
-
const
|
|
107245
|
+
const receiptIndex = current2.findIndex((entry) => entry.version === expectedVersion);
|
|
107246
|
+
const receipt = receiptIndex === -1 ? null : current2.splice(receiptIndex, 1)[0] ?? null;
|
|
107187
107247
|
if (current2.length > 0) receipts.set(absPath, current2);
|
|
107188
107248
|
else receipts.delete(absPath);
|
|
107189
107249
|
if (!receipt) return null;
|
|
@@ -107524,19 +107584,44 @@ function commitElementPatchBatches(projectDir, batches, writeFile4 = writeFileSy
|
|
|
107524
107584
|
}
|
|
107525
107585
|
return { durable: true, files };
|
|
107526
107586
|
}
|
|
107587
|
+
function commitElementPatchBatchesWithReceipts(c3, projectDir, batches) {
|
|
107588
|
+
const result = commitElementPatchBatches(projectDir, batches);
|
|
107589
|
+
if ("error" in result || !result.durable) return result;
|
|
107590
|
+
for (const file of result.files) {
|
|
107591
|
+
if (!file.changed) continue;
|
|
107592
|
+
const absPath = resolveWithinProject(projectDir, file.sourceFile);
|
|
107593
|
+
if (!absPath) throw new Error(`Committed element patch escaped project: ${file.sourceFile}`);
|
|
107594
|
+
recordMutationReceipt(c3, file.sourceFile, absPath, file.after);
|
|
107595
|
+
}
|
|
107596
|
+
return result;
|
|
107597
|
+
}
|
|
107598
|
+
function recordMutationReceipt(c3, filePath, absPath, html) {
|
|
107599
|
+
const version2 = fileContentVersion(html);
|
|
107600
|
+
const writeToken = createWriteToken(c3.req.header("X-Hyperframes-Write-Token"));
|
|
107601
|
+
recordFileWriteReceipt(absPath, { path: filePath, version: version2, writeToken });
|
|
107602
|
+
return { version: version2, writeToken };
|
|
107603
|
+
}
|
|
107604
|
+
function writeFileWithReceipt(c3, filePath, absPath, html) {
|
|
107605
|
+
writeFileSync42(absPath, html, "utf-8");
|
|
107606
|
+
return recordMutationReceipt(c3, filePath, absPath, html);
|
|
107607
|
+
}
|
|
107608
|
+
function writeMutationResult(c3, projectDir, filePath, absPath, html) {
|
|
107609
|
+
const backup = snapshotBeforeWrite(projectDir, absPath);
|
|
107610
|
+
if (backup.error) console.warn(`Failed to create backup for ${filePath}: ${backup.error}`);
|
|
107611
|
+
const { version: version2 } = writeFileWithReceipt(c3, filePath, absPath, html);
|
|
107612
|
+
return { backupPath: backupPathForResponse(projectDir, backup.backupPath), version: version2 };
|
|
107613
|
+
}
|
|
107527
107614
|
function writeIfChanged(c3, projectDir, filePath, absPath, original, next) {
|
|
107528
107615
|
if (next === original) {
|
|
107529
107616
|
return c3.json({ ok: true, changed: false, content: original, path: filePath });
|
|
107530
107617
|
}
|
|
107531
|
-
const
|
|
107532
|
-
if (backup.error) console.warn(`Failed to create backup for ${filePath}: ${backup.error}`);
|
|
107533
|
-
writeFileSync42(absPath, next, "utf-8");
|
|
107618
|
+
const { backupPath } = writeMutationResult(c3, projectDir, filePath, absPath, next);
|
|
107534
107619
|
return c3.json({
|
|
107535
107620
|
ok: true,
|
|
107536
107621
|
changed: true,
|
|
107537
107622
|
content: next,
|
|
107538
107623
|
path: filePath,
|
|
107539
|
-
backupPath
|
|
107624
|
+
backupPath
|
|
107540
107625
|
});
|
|
107541
107626
|
}
|
|
107542
107627
|
function rejectUnsafeMutationValues(c3, unsafeFields) {
|
|
@@ -107904,10 +107989,13 @@ async function applyGsapMutations(c3, res, mutations) {
|
|
|
107904
107989
|
return c3.json({ error: "file changed during GSAP mutation", conflict: true }, 409);
|
|
107905
107990
|
}
|
|
107906
107991
|
if (changed) {
|
|
107907
|
-
|
|
107908
|
-
|
|
107909
|
-
|
|
107910
|
-
|
|
107992
|
+
backupPath = writeMutationResult(
|
|
107993
|
+
c3,
|
|
107994
|
+
res.project.dir,
|
|
107995
|
+
res.filePath,
|
|
107996
|
+
res.absPath,
|
|
107997
|
+
newHtml
|
|
107998
|
+
).backupPath;
|
|
107911
107999
|
}
|
|
107912
108000
|
const responsePayload = {
|
|
107913
108001
|
ok: true,
|
|
@@ -108864,10 +108952,12 @@ function registerFileRoutes(api, adapter2) {
|
|
|
108864
108952
|
}
|
|
108865
108953
|
const backup = snapshotBeforeWrite(ctx.project.dir, ctx.absPath);
|
|
108866
108954
|
if (backup.error) return c3.json({ error: `backup failed: ${backup.error}` }, 500);
|
|
108867
|
-
|
|
108868
|
-
|
|
108869
|
-
|
|
108870
|
-
|
|
108955
|
+
const { version: version2, writeToken } = writeFileWithReceipt(
|
|
108956
|
+
c3,
|
|
108957
|
+
ctx.filePath,
|
|
108958
|
+
ctx.absPath,
|
|
108959
|
+
insertion.html
|
|
108960
|
+
);
|
|
108871
108961
|
c3.header("ETag", version2);
|
|
108872
108962
|
return c3.json({
|
|
108873
108963
|
ok: true,
|
|
@@ -109065,10 +109155,13 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109065
109155
|
version: version22
|
|
109066
109156
|
});
|
|
109067
109157
|
}
|
|
109068
|
-
const
|
|
109069
|
-
|
|
109070
|
-
|
|
109071
|
-
|
|
109158
|
+
const { version: version2, backupPath } = writeMutationResult(
|
|
109159
|
+
c3,
|
|
109160
|
+
ctx.project.dir,
|
|
109161
|
+
ctx.filePath,
|
|
109162
|
+
ctx.absPath,
|
|
109163
|
+
result.html
|
|
109164
|
+
);
|
|
109072
109165
|
c3.header("ETag", version2);
|
|
109073
109166
|
return c3.json({
|
|
109074
109167
|
ok: true,
|
|
@@ -109077,7 +109170,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109077
109170
|
newId: result.newId,
|
|
109078
109171
|
path: ctx.filePath,
|
|
109079
109172
|
version: version2,
|
|
109080
|
-
backupPath
|
|
109173
|
+
backupPath
|
|
109081
109174
|
});
|
|
109082
109175
|
});
|
|
109083
109176
|
api.post("/projects/:id/file-mutations/patch-element/*", async (c3) => {
|
|
@@ -109112,16 +109205,20 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109112
109205
|
path: ctx.filePath
|
|
109113
109206
|
});
|
|
109114
109207
|
}
|
|
109115
|
-
const
|
|
109116
|
-
|
|
109117
|
-
|
|
109208
|
+
const { backupPath } = writeMutationResult(
|
|
109209
|
+
c3,
|
|
109210
|
+
ctx.project.dir,
|
|
109211
|
+
ctx.filePath,
|
|
109212
|
+
ctx.absPath,
|
|
109213
|
+
patched
|
|
109214
|
+
);
|
|
109118
109215
|
return c3.json({
|
|
109119
109216
|
ok: true,
|
|
109120
109217
|
changed: true,
|
|
109121
109218
|
matched,
|
|
109122
109219
|
content: patched,
|
|
109123
109220
|
path: ctx.filePath,
|
|
109124
|
-
backupPath
|
|
109221
|
+
backupPath
|
|
109125
109222
|
});
|
|
109126
109223
|
});
|
|
109127
109224
|
api.post("/projects/:id/file-mutations/patch-element-batches", async (c3) => {
|
|
@@ -109133,7 +109230,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109133
109230
|
}
|
|
109134
109231
|
const unsafeFields = findUnsafeElementPatchBatchValues(body.batches);
|
|
109135
109232
|
if (unsafeFields.length > 0) return rejectUnsafeMutationValues(c3, unsafeFields);
|
|
109136
|
-
const result =
|
|
109233
|
+
const result = commitElementPatchBatchesWithReceipts(c3, project.dir, body.batches);
|
|
109137
109234
|
if ("error" in result) {
|
|
109138
109235
|
return elementPatchBatchCommitErrorResponse(c3, result.error, result.sourceFile);
|
|
109139
109236
|
}
|
|
@@ -109151,7 +109248,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109151
109248
|
if (unsafeFields.length > 0) {
|
|
109152
109249
|
return rejectUnsafeMutationValues(c3, unsafeFields);
|
|
109153
109250
|
}
|
|
109154
|
-
const result =
|
|
109251
|
+
const result = commitElementPatchBatchesWithReceipts(c3, ctx.project.dir, [batch]);
|
|
109155
109252
|
if ("error" in result) {
|
|
109156
109253
|
return elementPatchBatchCommitErrorResponse(c3, result.error, result.sourceFile);
|
|
109157
109254
|
}
|
|
@@ -109207,16 +109304,20 @@ function registerFileRoutes(api, adapter2) {
|
|
|
109207
109304
|
result.error === "grouped elements must share a single parent" ? 422 : 400
|
|
109208
109305
|
);
|
|
109209
109306
|
}
|
|
109210
|
-
const
|
|
109211
|
-
|
|
109212
|
-
|
|
109307
|
+
const { backupPath } = writeMutationResult(
|
|
109308
|
+
c3,
|
|
109309
|
+
ctx.project.dir,
|
|
109310
|
+
ctx.filePath,
|
|
109311
|
+
ctx.absPath,
|
|
109312
|
+
result.html
|
|
109313
|
+
);
|
|
109213
109314
|
return c3.json({
|
|
109214
109315
|
ok: true,
|
|
109215
109316
|
changed: true,
|
|
109216
109317
|
groupId: result.groupId,
|
|
109217
109318
|
content: result.html,
|
|
109218
109319
|
path: ctx.filePath,
|
|
109219
|
-
backupPath
|
|
109320
|
+
backupPath
|
|
109220
109321
|
});
|
|
109221
109322
|
});
|
|
109222
109323
|
api.post("/projects/:id/file-mutations/unwrap-elements/*", async (c3) => {
|
|
@@ -125332,7 +125433,7 @@ import {
|
|
|
125332
125433
|
import { tmpdir as tmpdir8 } from "os";
|
|
125333
125434
|
import { join as join60, dirname as dirname25, resolve as resolve33 } from "path";
|
|
125334
125435
|
import { totalmem as totalmem2 } from "os";
|
|
125335
|
-
import { randomUUID as
|
|
125436
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
125336
125437
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
125337
125438
|
function sampleDirectoryBytes(dir) {
|
|
125338
125439
|
let total = 0;
|
|
@@ -125504,6 +125605,18 @@ function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, ran
|
|
|
125504
125605
|
}
|
|
125505
125606
|
return batches;
|
|
125506
125607
|
}
|
|
125608
|
+
function resolveObservedCaptureMode(forceScreenshot, platform10 = process.platform) {
|
|
125609
|
+
return forceScreenshot || platform10 !== "linux" ? "screenshot" : "beginframe";
|
|
125610
|
+
}
|
|
125611
|
+
function createCaptureObservabilityUpdater(observability, platform10 = process.platform) {
|
|
125612
|
+
return (patch) => {
|
|
125613
|
+
Object.assign(observability, patch);
|
|
125614
|
+
observability.captureMode = resolveObservedCaptureMode(
|
|
125615
|
+
Boolean(observability.forceScreenshot),
|
|
125616
|
+
platform10
|
|
125617
|
+
);
|
|
125618
|
+
};
|
|
125619
|
+
}
|
|
125507
125620
|
function getNextRetryWorkerCount(currentWorkers) {
|
|
125508
125621
|
return Math.max(1, Math.floor(currentWorkers / 2));
|
|
125509
125622
|
}
|
|
@@ -125691,7 +125804,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
125691
125804
|
}
|
|
125692
125805
|
function createRenderJob(config) {
|
|
125693
125806
|
return {
|
|
125694
|
-
id:
|
|
125807
|
+
id: randomUUID10(),
|
|
125695
125808
|
config: {
|
|
125696
125809
|
...config,
|
|
125697
125810
|
fps: toFps(config.fps),
|
|
@@ -125975,7 +126088,7 @@ async function executeRenderPipeline(input2) {
|
|
|
125975
126088
|
const chunkedEncodeSize = cfg.chunkSizeFrames;
|
|
125976
126089
|
const captureObservability = {
|
|
125977
126090
|
forceScreenshot: Boolean(cfg.forceScreenshot),
|
|
125978
|
-
captureMode: cfg.forceScreenshot
|
|
126091
|
+
captureMode: resolveObservedCaptureMode(Boolean(cfg.forceScreenshot)),
|
|
125979
126092
|
browserGpuMode: cfg.browserGpuMode,
|
|
125980
126093
|
protocolTimeoutMs: cfg.protocolTimeout,
|
|
125981
126094
|
pageNavigationTimeoutMs: cfg.pageNavigationTimeout,
|
|
@@ -125983,10 +126096,7 @@ async function executeRenderPipeline(input2) {
|
|
|
125983
126096
|
};
|
|
125984
126097
|
let extractionObservability;
|
|
125985
126098
|
let compositionHash;
|
|
125986
|
-
const updateCaptureObservability = (
|
|
125987
|
-
Object.assign(captureObservability, patch);
|
|
125988
|
-
captureObservability.captureMode = captureObservability.forceScreenshot ? "screenshot" : "beginframe";
|
|
125989
|
-
};
|
|
126099
|
+
const updateCaptureObservability = createCaptureObservabilityUpdater(captureObservability);
|
|
125990
126100
|
const captureAttempts = [];
|
|
125991
126101
|
const dedupPerfs = [];
|
|
125992
126102
|
const layeredCaptureWarnings = [];
|
|
@@ -126109,7 +126219,11 @@ async function executeRenderPipeline(input2) {
|
|
|
126109
126219
|
perfStages.compileOnlyMs = compileResult.compileOnlyMs;
|
|
126110
126220
|
let captureForceScreenshot = compileResult.forceScreenshot;
|
|
126111
126221
|
const deCompileGate = compileResult.deCompileGate;
|
|
126112
|
-
let deClampReason
|
|
126222
|
+
let deClampReason = cfg.useDrawElement ? void 0 : explainDrawElementDisabled({
|
|
126223
|
+
platform: process.platform,
|
|
126224
|
+
browserGpuMode: cfg.browserGpuMode,
|
|
126225
|
+
workerEncode: cfg.enableDrawElementWorkerEncode
|
|
126226
|
+
});
|
|
126113
126227
|
let deWorkerInversion;
|
|
126114
126228
|
let deParallelStreamForced = false;
|
|
126115
126229
|
let captureParallelStreamForced = false;
|
|
@@ -126617,7 +126731,7 @@ async function executeRenderPipeline(input2) {
|
|
|
126617
126731
|
});
|
|
126618
126732
|
if (captureParallelStreamEligible) {
|
|
126619
126733
|
captureParallelStreamForced = true;
|
|
126620
|
-
const captureParallelStream =
|
|
126734
|
+
const captureParallelStream = resolveObservedCaptureMode(captureForceScreenshot);
|
|
126621
126735
|
log2.info(
|
|
126622
126736
|
`[Render] Parallel ${captureParallelStream} capture will stream to the encoder (interleaved, ${workerCount} workers) instead of the disk path. Set HF_CAPTURE_PARALLEL_STREAM=false to disable.`
|
|
126623
126737
|
);
|
|
@@ -132975,7 +133089,13 @@ function createStudioServer(options) {
|
|
|
132975
133089
|
app.get("/api/events", (c3) => {
|
|
132976
133090
|
return streamSSE4(c3, async (stream) => {
|
|
132977
133091
|
const listener = (path2) => {
|
|
132978
|
-
const
|
|
133092
|
+
const absPath = resolve38(projectDir, path2);
|
|
133093
|
+
let version2 = null;
|
|
133094
|
+
try {
|
|
133095
|
+
version2 = fileContentVersion(readFileSync40(absPath, "utf-8"));
|
|
133096
|
+
} catch {
|
|
133097
|
+
}
|
|
133098
|
+
const receipt = version2 ? consumeFileWriteReceipt(absPath, version2) : null;
|
|
132979
133099
|
stream.writeSSE({ event: "file-change", data: JSON.stringify(receipt ?? { path: path2 }) }).catch(() => {
|
|
132980
133100
|
});
|
|
132981
133101
|
};
|
|
@@ -135260,24 +135380,583 @@ var init_add = __esm({
|
|
|
135260
135380
|
}
|
|
135261
135381
|
});
|
|
135262
135382
|
|
|
135383
|
+
// src/registry/localSearch.ts
|
|
135384
|
+
function tokenize(text2) {
|
|
135385
|
+
const words = text2.toLowerCase().match(/[a-z]+/g) ?? [];
|
|
135386
|
+
return words.filter((word) => word.length > 2 && !STOP.has(word));
|
|
135387
|
+
}
|
|
135388
|
+
function rankByWords(query2, items, textOf) {
|
|
135389
|
+
const want = new Set(tokenize(query2));
|
|
135390
|
+
if (want.size === 0) return items.map((item) => ({ item, score: 0 }));
|
|
135391
|
+
return items.map((item) => {
|
|
135392
|
+
const have = new Set(tokenize(textOf(item)));
|
|
135393
|
+
let shared = 0;
|
|
135394
|
+
for (const token of want) if (have.has(token)) shared += 1;
|
|
135395
|
+
return { item, score: shared / (Math.sqrt(have.size) || 1) };
|
|
135396
|
+
}).sort((a, b2) => b2.score - a.score || nameOf(b2.item).localeCompare(nameOf(a.item)));
|
|
135397
|
+
}
|
|
135398
|
+
function searchByWords(query2, items, textOf) {
|
|
135399
|
+
return rankByWords(query2, items, textOf).filter((scored) => scored.score > 0).map((scored) => scored.item);
|
|
135400
|
+
}
|
|
135401
|
+
function nameOf(item) {
|
|
135402
|
+
const named = item;
|
|
135403
|
+
return typeof named?.name === "string" ? named.name : "";
|
|
135404
|
+
}
|
|
135405
|
+
var STOP;
|
|
135406
|
+
var init_localSearch = __esm({
|
|
135407
|
+
"src/registry/localSearch.ts"() {
|
|
135408
|
+
"use strict";
|
|
135409
|
+
STOP = new Set(
|
|
135410
|
+
"the a an and or of to in on at is are be it its for with that this as by from into one two must not no all over under across while when where which who whom whose they them their we our you your he she his her but if then than so such can may might will would should each other another same both few more most some any every".split(" ")
|
|
135411
|
+
);
|
|
135412
|
+
}
|
|
135413
|
+
});
|
|
135414
|
+
|
|
135415
|
+
// src/registry/localModel.ts
|
|
135416
|
+
import { createHash as createHash18 } from "crypto";
|
|
135417
|
+
import { existsSync as existsSync71, mkdirSync as mkdirSync39, readFileSync as readFileSync44, unlinkSync as unlinkSync8 } from "fs";
|
|
135418
|
+
import { homedir as homedir15 } from "os";
|
|
135419
|
+
import { join as join81 } from "path";
|
|
135420
|
+
function localModelConsent() {
|
|
135421
|
+
return readConfig().localEmbeddingEnabled;
|
|
135422
|
+
}
|
|
135423
|
+
function recordLocalModelConsent(enabled) {
|
|
135424
|
+
writeConfig({ ...readConfig(), localEmbeddingEnabled: enabled });
|
|
135425
|
+
}
|
|
135426
|
+
function localModelPath() {
|
|
135427
|
+
return join81(MODELS_DIR3, `${LOCAL_MODEL_ID}.onnx`);
|
|
135428
|
+
}
|
|
135429
|
+
function localTokenizerPath() {
|
|
135430
|
+
return join81(MODELS_DIR3, `${LOCAL_MODEL_ID}.tokenizer.json`);
|
|
135431
|
+
}
|
|
135432
|
+
function modelFileIsValid(file) {
|
|
135433
|
+
const path2 = file.dest();
|
|
135434
|
+
if (!existsSync71(path2)) return false;
|
|
135435
|
+
try {
|
|
135436
|
+
return createHash18("sha256").update(readFileSync44(path2)).digest("hex") === file.sha256;
|
|
135437
|
+
} catch {
|
|
135438
|
+
return false;
|
|
135439
|
+
}
|
|
135440
|
+
}
|
|
135441
|
+
function isLocalModelReady() {
|
|
135442
|
+
return LOCAL_MODEL_ARTIFACTS.every(modelFileIsValid);
|
|
135443
|
+
}
|
|
135444
|
+
function localModelStatus() {
|
|
135445
|
+
const consent = localModelConsent();
|
|
135446
|
+
if (consent === false) return { status: "declined" };
|
|
135447
|
+
if (isLocalModelReady()) return { status: "ready" };
|
|
135448
|
+
if (consent === void 0) return { status: "not-asked" };
|
|
135449
|
+
return { status: "unavailable", reason: "model not downloaded yet" };
|
|
135450
|
+
}
|
|
135451
|
+
async function ensureLocalModel() {
|
|
135452
|
+
if (isLocalModelReady()) return true;
|
|
135453
|
+
try {
|
|
135454
|
+
mkdirSync39(MODELS_DIR3, { recursive: true });
|
|
135455
|
+
for (const file of LOCAL_MODEL_ARTIFACTS) {
|
|
135456
|
+
if (modelFileIsValid(file)) continue;
|
|
135457
|
+
const dest = file.dest();
|
|
135458
|
+
await downloadFile(file.url, dest, { maxBytes: file.bytes });
|
|
135459
|
+
if (!modelFileIsValid(file)) {
|
|
135460
|
+
unlinkSync8(dest);
|
|
135461
|
+
return false;
|
|
135462
|
+
}
|
|
135463
|
+
}
|
|
135464
|
+
return isLocalModelReady();
|
|
135465
|
+
} catch {
|
|
135466
|
+
return false;
|
|
135467
|
+
}
|
|
135468
|
+
}
|
|
135469
|
+
function nonInteractiveConsentMessage() {
|
|
135470
|
+
return `On-device search needs a one-time ${LOCAL_MODEL_SIZE_MB} MB download that stays on this machine. Nothing is sent anywhere. Ask the person you are working for, and pass --on-device --yes once they agree.`;
|
|
135471
|
+
}
|
|
135472
|
+
function downloadOfferMessage(matchCount) {
|
|
135473
|
+
const found = matchCount === void 0 ? "Use on-device meaning search." : matchCount === 0 ? "No matches from word search." : `Only ${matchCount} match${matchCount === 1 ? "" : "es"} from word search.`;
|
|
135474
|
+
return `${found} Download a ${LOCAL_MODEL_SIZE_MB} MB search model for better offline results? It stays on your machine and nothing is sent.`;
|
|
135475
|
+
}
|
|
135476
|
+
var LOCAL_MODEL_ID, LOCAL_MODEL_DIMENSIONS, LOCAL_MODEL_SIZE_MB, QUERY_INSTRUCTION, MODELS_DIR3, MODEL_REPO, LOCAL_MODEL_REVISION, LOCAL_MODEL_ARTIFACTS;
|
|
135477
|
+
var init_localModel = __esm({
|
|
135478
|
+
"src/registry/localModel.ts"() {
|
|
135479
|
+
"use strict";
|
|
135480
|
+
init_download();
|
|
135481
|
+
init_config();
|
|
135482
|
+
LOCAL_MODEL_ID = "bge-small-en-v1.5";
|
|
135483
|
+
LOCAL_MODEL_DIMENSIONS = 384;
|
|
135484
|
+
LOCAL_MODEL_SIZE_MB = 33;
|
|
135485
|
+
QUERY_INSTRUCTION = "Represent this sentence for searching relevant passages: ";
|
|
135486
|
+
MODELS_DIR3 = join81(homedir15(), ".hyperframes", "models");
|
|
135487
|
+
MODEL_REPO = "Xenova/bge-small-en-v1.5";
|
|
135488
|
+
LOCAL_MODEL_REVISION = "ea104dacec62c0de699686887e3f920caeb4f3e3";
|
|
135489
|
+
LOCAL_MODEL_ARTIFACTS = [
|
|
135490
|
+
{
|
|
135491
|
+
url: `https://huggingface.co/${MODEL_REPO}/resolve/${LOCAL_MODEL_REVISION}/onnx/model_quantized.onnx`,
|
|
135492
|
+
dest: () => localModelPath(),
|
|
135493
|
+
bytes: 34014426,
|
|
135494
|
+
sha256: "6c9c6101a956d62dfb5e7190c538226c0c5bb9cb27b651234b6df063ee7dbfe4"
|
|
135495
|
+
},
|
|
135496
|
+
{
|
|
135497
|
+
url: `https://huggingface.co/${MODEL_REPO}/resolve/${LOCAL_MODEL_REVISION}/tokenizer.json`,
|
|
135498
|
+
dest: () => localTokenizerPath(),
|
|
135499
|
+
bytes: 711396,
|
|
135500
|
+
sha256: "d241a60d5e8f04cc1b2b3e9ef7a4921b27bf526d9f6050ab90f9267a1f9e5c66"
|
|
135501
|
+
}
|
|
135502
|
+
];
|
|
135503
|
+
}
|
|
135504
|
+
});
|
|
135505
|
+
|
|
135506
|
+
// src/registry/wordpiece.ts
|
|
135507
|
+
function configFromTokenizerJson(raw) {
|
|
135508
|
+
const parsed = JSON.parse(raw);
|
|
135509
|
+
const model = parsed.model;
|
|
135510
|
+
if (!model?.vocab) throw new Error("tokenizer.json has no WordPiece vocab");
|
|
135511
|
+
return {
|
|
135512
|
+
vocab: model.vocab,
|
|
135513
|
+
unkToken: model.unk_token ?? "[UNK]",
|
|
135514
|
+
continuingSubwordPrefix: model.continuing_subword_prefix ?? "##",
|
|
135515
|
+
maxInputCharsPerWord: model.max_input_chars_per_word ?? 100,
|
|
135516
|
+
clsToken: "[CLS]",
|
|
135517
|
+
sepToken: "[SEP]"
|
|
135518
|
+
};
|
|
135519
|
+
}
|
|
135520
|
+
function normalize(text2) {
|
|
135521
|
+
let out = "";
|
|
135522
|
+
for (const char of text2) {
|
|
135523
|
+
const code = char.codePointAt(0);
|
|
135524
|
+
if (code === 0 || code === 65533) continue;
|
|
135525
|
+
if (isControl(char, code)) continue;
|
|
135526
|
+
if (isWhitespace3(char, code)) {
|
|
135527
|
+
out += " ";
|
|
135528
|
+
continue;
|
|
135529
|
+
}
|
|
135530
|
+
out += isChinese(code) ? ` ${char} ` : char;
|
|
135531
|
+
}
|
|
135532
|
+
return out.toLowerCase().normalize("NFD").replace(new RegExp("\\p{Mn}", "gu"), "");
|
|
135533
|
+
}
|
|
135534
|
+
function preTokenize(normalized2) {
|
|
135535
|
+
const words = [];
|
|
135536
|
+
for (const chunk of normalized2.split(/\s+/)) {
|
|
135537
|
+
if (!chunk) continue;
|
|
135538
|
+
let current2 = "";
|
|
135539
|
+
for (const char of chunk) {
|
|
135540
|
+
if (isPunctuation(char)) {
|
|
135541
|
+
if (current2) words.push(current2);
|
|
135542
|
+
words.push(char);
|
|
135543
|
+
current2 = "";
|
|
135544
|
+
} else {
|
|
135545
|
+
current2 += char;
|
|
135546
|
+
}
|
|
135547
|
+
}
|
|
135548
|
+
if (current2) words.push(current2);
|
|
135549
|
+
}
|
|
135550
|
+
return words;
|
|
135551
|
+
}
|
|
135552
|
+
function wordPiece(word, config) {
|
|
135553
|
+
if ([...word].length > config.maxInputCharsPerWord) return [config.unkToken];
|
|
135554
|
+
const pieces = [];
|
|
135555
|
+
let start = 0;
|
|
135556
|
+
while (start < word.length) {
|
|
135557
|
+
let end = word.length;
|
|
135558
|
+
let match = null;
|
|
135559
|
+
while (start < end) {
|
|
135560
|
+
const candidate = start === 0 ? word.slice(start, end) : config.continuingSubwordPrefix + word.slice(start, end);
|
|
135561
|
+
if (candidate in config.vocab) {
|
|
135562
|
+
match = candidate;
|
|
135563
|
+
break;
|
|
135564
|
+
}
|
|
135565
|
+
end -= 1;
|
|
135566
|
+
}
|
|
135567
|
+
if (match === null) return [config.unkToken];
|
|
135568
|
+
pieces.push(match);
|
|
135569
|
+
start = end;
|
|
135570
|
+
}
|
|
135571
|
+
return pieces;
|
|
135572
|
+
}
|
|
135573
|
+
function encode2(text2, config) {
|
|
135574
|
+
const tokens = [config.clsToken];
|
|
135575
|
+
for (const word of preTokenize(normalize(text2))) tokens.push(...wordPiece(word, config));
|
|
135576
|
+
tokens.push(config.sepToken);
|
|
135577
|
+
const unk = config.vocab[config.unkToken];
|
|
135578
|
+
const ids = tokens.map((token) => config.vocab[token] ?? unk);
|
|
135579
|
+
return {
|
|
135580
|
+
ids,
|
|
135581
|
+
attentionMask: ids.map(() => 1),
|
|
135582
|
+
tokenTypeIds: ids.map(() => 0)
|
|
135583
|
+
};
|
|
135584
|
+
}
|
|
135585
|
+
function isControl(char, code) {
|
|
135586
|
+
if (char === " " || char === "\n" || char === "\r") return false;
|
|
135587
|
+
return code < 32 || code === 127 || new RegExp("\\p{Cc}|\\p{Cf}", "u").test(char);
|
|
135588
|
+
}
|
|
135589
|
+
function isWhitespace3(char, code) {
|
|
135590
|
+
return char === " " || char === " " || char === "\n" || char === "\r" || code === 11 || code === 12 || new RegExp("\\p{Zs}", "u").test(char);
|
|
135591
|
+
}
|
|
135592
|
+
function isPunctuation(char) {
|
|
135593
|
+
const code = char.codePointAt(0);
|
|
135594
|
+
const asciiSymbol = code >= 33 && code <= 47 || code >= 58 && code <= 64 || code >= 91 && code <= 96 || code >= 123 && code <= 126;
|
|
135595
|
+
return asciiSymbol || new RegExp("\\p{P}", "u").test(char);
|
|
135596
|
+
}
|
|
135597
|
+
function isChinese(code) {
|
|
135598
|
+
return code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 131072 && code <= 173791 || code >= 173824 && code <= 177983 || code >= 177984 && code <= 178207 || code >= 178208 && code <= 183983 || code >= 63744 && code <= 64255 || code >= 194560 && code <= 195103;
|
|
135599
|
+
}
|
|
135600
|
+
var init_wordpiece = __esm({
|
|
135601
|
+
"src/registry/wordpiece.ts"() {
|
|
135602
|
+
"use strict";
|
|
135603
|
+
}
|
|
135604
|
+
});
|
|
135605
|
+
|
|
135606
|
+
// src/registry/localEmbedder.ts
|
|
135607
|
+
import { readFileSync as readFileSync45 } from "fs";
|
|
135608
|
+
async function localRuntimeAvailable() {
|
|
135609
|
+
try {
|
|
135610
|
+
await import("onnxruntime-node");
|
|
135611
|
+
return true;
|
|
135612
|
+
} catch {
|
|
135613
|
+
return false;
|
|
135614
|
+
}
|
|
135615
|
+
}
|
|
135616
|
+
async function loadLocalEmbedder() {
|
|
135617
|
+
const ort = await import("onnxruntime-node");
|
|
135618
|
+
const config = configFromTokenizerJson(readFileSync45(localTokenizerPath(), "utf-8"));
|
|
135619
|
+
const session = await ort.InferenceSession.create(localModelPath());
|
|
135620
|
+
return {
|
|
135621
|
+
async embed(texts, options) {
|
|
135622
|
+
if (texts.length === 0) return [];
|
|
135623
|
+
const prefix = options?.isQuery ? QUERY_INSTRUCTION : "";
|
|
135624
|
+
const encodings = texts.map((text2) => truncate(encode2(prefix + text2, config)));
|
|
135625
|
+
const width = Math.max(...encodings.map((e3) => e3.ids.length));
|
|
135626
|
+
const batch = encodings.length;
|
|
135627
|
+
const ids = new BigInt64Array(batch * width);
|
|
135628
|
+
const mask = new BigInt64Array(batch * width);
|
|
135629
|
+
const types5 = new BigInt64Array(batch * width);
|
|
135630
|
+
encodings.forEach((encoding, row) => {
|
|
135631
|
+
encoding.ids.forEach((id, column) => {
|
|
135632
|
+
const at4 = row * width + column;
|
|
135633
|
+
ids[at4] = BigInt(id);
|
|
135634
|
+
mask[at4] = 1n;
|
|
135635
|
+
types5[at4] = 0n;
|
|
135636
|
+
});
|
|
135637
|
+
});
|
|
135638
|
+
const dims = [batch, width];
|
|
135639
|
+
const output = await session.run({
|
|
135640
|
+
input_ids: new ort.Tensor("int64", ids, dims),
|
|
135641
|
+
attention_mask: new ort.Tensor("int64", mask, dims),
|
|
135642
|
+
token_type_ids: new ort.Tensor("int64", types5, dims)
|
|
135643
|
+
});
|
|
135644
|
+
const hidden = output["last_hidden_state"];
|
|
135645
|
+
if (!hidden) throw new Error("model returned no last_hidden_state");
|
|
135646
|
+
const data2 = hidden.data;
|
|
135647
|
+
const hiddenSize = hidden.dims[2];
|
|
135648
|
+
if (hiddenSize !== LOCAL_MODEL_DIMENSIONS) {
|
|
135649
|
+
throw new Error(
|
|
135650
|
+
`model produced ${hiddenSize} dimensions, expected ${LOCAL_MODEL_DIMENSIONS}`
|
|
135651
|
+
);
|
|
135652
|
+
}
|
|
135653
|
+
return encodings.map((_, row) => {
|
|
135654
|
+
const start = row * width * hiddenSize;
|
|
135655
|
+
return normalize2(Array.from(data2.subarray(start, start + hiddenSize)));
|
|
135656
|
+
});
|
|
135657
|
+
}
|
|
135658
|
+
};
|
|
135659
|
+
}
|
|
135660
|
+
function truncate(encoding) {
|
|
135661
|
+
if (encoding.ids.length <= MAX_TOKENS) return encoding;
|
|
135662
|
+
const ids = [
|
|
135663
|
+
...encoding.ids.slice(0, MAX_TOKENS - 1),
|
|
135664
|
+
encoding.ids[encoding.ids.length - 1]
|
|
135665
|
+
];
|
|
135666
|
+
return { ids, attentionMask: ids.map(() => 1), tokenTypeIds: ids.map(() => 0) };
|
|
135667
|
+
}
|
|
135668
|
+
function normalize2(vector) {
|
|
135669
|
+
const norm = Math.sqrt(vector.reduce((sum, value) => sum + value * value, 0));
|
|
135670
|
+
return norm === 0 ? vector : vector.map((value) => value / norm);
|
|
135671
|
+
}
|
|
135672
|
+
function cosine(a, b2) {
|
|
135673
|
+
let sum = 0;
|
|
135674
|
+
for (let i2 = 0; i2 < a.length; i2 += 1) sum += a[i2] * b2[i2];
|
|
135675
|
+
return sum;
|
|
135676
|
+
}
|
|
135677
|
+
var MAX_TOKENS;
|
|
135678
|
+
var init_localEmbedder = __esm({
|
|
135679
|
+
"src/registry/localEmbedder.ts"() {
|
|
135680
|
+
"use strict";
|
|
135681
|
+
init_localModel();
|
|
135682
|
+
init_wordpiece();
|
|
135683
|
+
MAX_TOKENS = 512;
|
|
135684
|
+
}
|
|
135685
|
+
});
|
|
135686
|
+
|
|
135687
|
+
// src/registry/localSemantic.ts
|
|
135688
|
+
import { existsSync as existsSync73, mkdirSync as mkdirSync40, readFileSync as readFileSync46, writeFileSync as writeFileSync28 } from "fs";
|
|
135689
|
+
import { homedir as homedir16 } from "os";
|
|
135690
|
+
import { join as join83 } from "path";
|
|
135691
|
+
function localVectorDirectory() {
|
|
135692
|
+
return process.env["HYPERFRAMES_CATALOG_ARTIFACT_DIR"] ?? join83(homedir16(), ".hyperframes", "catalog");
|
|
135693
|
+
}
|
|
135694
|
+
function vectorPairAgrees(fetched) {
|
|
135695
|
+
const meta = fetched.find(([file]) => file === "local-vectors.json")?.[1];
|
|
135696
|
+
const bin = fetched.find(([file]) => file === "local-vectors.bin")?.[1];
|
|
135697
|
+
if (!meta || !bin) return false;
|
|
135698
|
+
try {
|
|
135699
|
+
const parsed = JSON.parse(meta.toString("utf-8"));
|
|
135700
|
+
if (parsed.dimensions !== LOCAL_MODEL_DIMENSIONS) return false;
|
|
135701
|
+
return bin.byteLength === (parsed.names?.length ?? -1) * LOCAL_MODEL_DIMENSIONS * 4;
|
|
135702
|
+
} catch {
|
|
135703
|
+
return false;
|
|
135704
|
+
}
|
|
135705
|
+
}
|
|
135706
|
+
function vectorRevisionAgrees(fetched, expectedRevision) {
|
|
135707
|
+
if (expectedRevision === void 0) return true;
|
|
135708
|
+
const meta = fetched.find(([file]) => file === "local-vectors.json")?.[1];
|
|
135709
|
+
if (!meta) return false;
|
|
135710
|
+
try {
|
|
135711
|
+
const parsed = JSON.parse(meta.toString("utf-8"));
|
|
135712
|
+
return parsed.revision === expectedRevision;
|
|
135713
|
+
} catch {
|
|
135714
|
+
return false;
|
|
135715
|
+
}
|
|
135716
|
+
}
|
|
135717
|
+
async function fetchLocalVectors(registryBaseUrl, options = {}) {
|
|
135718
|
+
const directory = options.directory ?? localVectorDirectory();
|
|
135719
|
+
const base2 = registryBaseUrl.replace(/\/+$/, "");
|
|
135720
|
+
try {
|
|
135721
|
+
mkdirSync40(directory, { recursive: true, mode: 448 });
|
|
135722
|
+
const fetched = [];
|
|
135723
|
+
for (const file of ["local-vectors.json", "local-vectors.bin"]) {
|
|
135724
|
+
const response = await fetch(`${base2}/catalog-artifact/${file}`, {
|
|
135725
|
+
signal: AbortSignal.timeout(CATALOG_ARTIFACT_TIMEOUT_MS)
|
|
135726
|
+
});
|
|
135727
|
+
if (!response.ok) return false;
|
|
135728
|
+
fetched.push([file, Buffer.from(await response.arrayBuffer())]);
|
|
135729
|
+
}
|
|
135730
|
+
if (!vectorPairAgrees(fetched) || !vectorRevisionAgrees(fetched, options.expectedRevision)) {
|
|
135731
|
+
return false;
|
|
135732
|
+
}
|
|
135733
|
+
for (const [file, bytes] of fetched) {
|
|
135734
|
+
writeFileSync28(join83(directory, file), bytes, { mode: 384 });
|
|
135735
|
+
}
|
|
135736
|
+
return hasLocalVectors(directory);
|
|
135737
|
+
} catch {
|
|
135738
|
+
return false;
|
|
135739
|
+
}
|
|
135740
|
+
}
|
|
135741
|
+
function hasLocalVectors(directory = localVectorDirectory()) {
|
|
135742
|
+
return existsSync73(join83(directory, "local-vectors.bin")) && existsSync73(join83(directory, "local-vectors.json"));
|
|
135743
|
+
}
|
|
135744
|
+
function loadLocalVectors(directory = localVectorDirectory()) {
|
|
135745
|
+
const meta = JSON.parse(
|
|
135746
|
+
readFileSync46(join83(directory, "local-vectors.json"), "utf-8")
|
|
135747
|
+
);
|
|
135748
|
+
const buffer = readFileSync46(join83(directory, "local-vectors.bin"));
|
|
135749
|
+
const vectors = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4);
|
|
135750
|
+
const expected = meta.names.length * meta.dimensions;
|
|
135751
|
+
if (vectors.length !== expected) {
|
|
135752
|
+
throw new Error(`local vectors hold ${vectors.length} floats, expected ${expected}`);
|
|
135753
|
+
}
|
|
135754
|
+
if (meta.dimensions !== LOCAL_MODEL_DIMENSIONS) {
|
|
135755
|
+
throw new Error(
|
|
135756
|
+
`local vectors are ${meta.dimensions}-dimension, model produces ${LOCAL_MODEL_DIMENSIONS}`
|
|
135757
|
+
);
|
|
135758
|
+
}
|
|
135759
|
+
return { names: meta.names, dimensions: meta.dimensions, vectors };
|
|
135760
|
+
}
|
|
135761
|
+
function localVectorNames(directory = localVectorDirectory()) {
|
|
135762
|
+
if (!hasLocalVectors(directory)) return [];
|
|
135763
|
+
try {
|
|
135764
|
+
const meta = JSON.parse(readFileSync46(join83(directory, "local-vectors.json"), "utf-8"));
|
|
135765
|
+
return meta.names ?? [];
|
|
135766
|
+
} catch {
|
|
135767
|
+
return [];
|
|
135768
|
+
}
|
|
135769
|
+
}
|
|
135770
|
+
function cachedLocalVectorRevision(directory = localVectorDirectory()) {
|
|
135771
|
+
if (!hasLocalVectors(directory)) return void 0;
|
|
135772
|
+
try {
|
|
135773
|
+
const meta = JSON.parse(readFileSync46(join83(directory, "local-vectors.json"), "utf-8"));
|
|
135774
|
+
return typeof meta.revision === "string" ? meta.revision : void 0;
|
|
135775
|
+
} catch {
|
|
135776
|
+
return void 0;
|
|
135777
|
+
}
|
|
135778
|
+
}
|
|
135779
|
+
async function localSemanticRanking(query2, directory = localVectorDirectory()) {
|
|
135780
|
+
if (!isLocalModelReady() || !hasLocalVectors(directory)) return null;
|
|
135781
|
+
const set = loadLocalVectors(directory);
|
|
135782
|
+
const embedder = await loadLocalEmbedder();
|
|
135783
|
+
const [queryVector] = await embedder.embed([query2], { isQuery: true });
|
|
135784
|
+
if (!queryVector) return null;
|
|
135785
|
+
const scored = set.names.map((name, row) => {
|
|
135786
|
+
const start = row * set.dimensions;
|
|
135787
|
+
return {
|
|
135788
|
+
name,
|
|
135789
|
+
score: cosine(queryVector, Array.from(set.vectors.subarray(start, start + set.dimensions)))
|
|
135790
|
+
};
|
|
135791
|
+
});
|
|
135792
|
+
scored.sort((a, b2) => b2.score - a.score || b2.name.localeCompare(a.name));
|
|
135793
|
+
return scored;
|
|
135794
|
+
}
|
|
135795
|
+
var CATALOG_ARTIFACT_TIMEOUT_MS;
|
|
135796
|
+
var init_localSemantic = __esm({
|
|
135797
|
+
"src/registry/localSemantic.ts"() {
|
|
135798
|
+
"use strict";
|
|
135799
|
+
init_localEmbedder();
|
|
135800
|
+
init_localModel();
|
|
135801
|
+
CATALOG_ARTIFACT_TIMEOUT_MS = 3e4;
|
|
135802
|
+
}
|
|
135803
|
+
});
|
|
135804
|
+
|
|
135263
135805
|
// src/commands/catalog.ts
|
|
135264
135806
|
var catalog_exports = {};
|
|
135265
135807
|
__export(catalog_exports, {
|
|
135808
|
+
countUnindexed: () => countUnindexed,
|
|
135266
135809
|
default: () => catalog_default,
|
|
135267
|
-
examples: () => examples5
|
|
135810
|
+
examples: () => examples5,
|
|
135811
|
+
pickByName: () => pickByName
|
|
135268
135812
|
});
|
|
135269
135813
|
import { resolve as resolve43 } from "path";
|
|
135814
|
+
async function prepareOnDeviceTier(opts) {
|
|
135815
|
+
const warnings = [];
|
|
135816
|
+
const warn = (message) => {
|
|
135817
|
+
warnings.push(message);
|
|
135818
|
+
console.error(message);
|
|
135819
|
+
};
|
|
135820
|
+
const status = opts.status;
|
|
135821
|
+
if (!opts.assumedYes && status.status === "declined") {
|
|
135822
|
+
warn(
|
|
135823
|
+
"on-device search skipped: the model download was previously declined. Re-run with --yes to consent."
|
|
135824
|
+
);
|
|
135825
|
+
return warnings;
|
|
135826
|
+
}
|
|
135827
|
+
if (!opts.assumedYes && status.status === "not-asked" && !opts.canPrompt) {
|
|
135828
|
+
warn(nonInteractiveConsentMessage());
|
|
135829
|
+
return warnings;
|
|
135830
|
+
}
|
|
135831
|
+
if (!opts.assumedYes && status.status === "not-asked") {
|
|
135832
|
+
const answer = await ue({
|
|
135833
|
+
message: downloadOfferMessage(),
|
|
135834
|
+
initialValue: true
|
|
135835
|
+
});
|
|
135836
|
+
if (q(answer) || answer !== true) {
|
|
135837
|
+
recordLocalModelConsent(false);
|
|
135838
|
+
warn("on-device search skipped: the download was declined.");
|
|
135839
|
+
return warnings;
|
|
135840
|
+
}
|
|
135841
|
+
}
|
|
135842
|
+
if (!await localRuntimeAvailable()) {
|
|
135843
|
+
warn(
|
|
135844
|
+
"on-device search needs the native ONNX runtime, which a single-file build cannot load. Install the CLI normally (npm i -g hyperframes) to use this tier."
|
|
135845
|
+
);
|
|
135846
|
+
return warnings;
|
|
135847
|
+
}
|
|
135848
|
+
if (status.status === "declined" || status.status === "not-asked") {
|
|
135849
|
+
recordLocalModelConsent(true);
|
|
135850
|
+
}
|
|
135851
|
+
const model = await ensureLocalModel();
|
|
135852
|
+
const revisionStale = opts.artifactRevision !== void 0 && cachedLocalVectorRevision() !== opts.artifactRevision;
|
|
135853
|
+
if (!hasLocalVectors() || revisionStale || countUnindexed(opts.registryNames, localVectorNames()) > 0) {
|
|
135854
|
+
await fetchLocalVectors(opts.registry, { expectedRevision: opts.artifactRevision });
|
|
135855
|
+
}
|
|
135856
|
+
const vectors = hasLocalVectors();
|
|
135857
|
+
if (!model || !vectors) {
|
|
135858
|
+
warn(
|
|
135859
|
+
`on-device search unavailable: ${!model ? "model" : "catalog vectors"} could not be fetched`
|
|
135860
|
+
);
|
|
135861
|
+
} else if (opts.artifactRevision !== void 0 && cachedLocalVectorRevision() !== opts.artifactRevision) {
|
|
135862
|
+
warn("on-device search is using the previous catalog vectors because the update failed");
|
|
135863
|
+
}
|
|
135864
|
+
return warnings;
|
|
135865
|
+
}
|
|
135866
|
+
function pickByName(items, names, registryNames) {
|
|
135867
|
+
const byName = new Map(items.map((item) => [item.name, item]));
|
|
135868
|
+
const ranked = names.map((name) => byName.get(name)).filter((item) => item !== void 0);
|
|
135869
|
+
return { ranked, missing: names.filter((name) => !registryNames.has(name)).length };
|
|
135870
|
+
}
|
|
135871
|
+
function countUnindexed(registryNames, indexedNames) {
|
|
135872
|
+
const indexed = new Set(indexedNames);
|
|
135873
|
+
let count = 0;
|
|
135874
|
+
for (const name of registryNames) {
|
|
135875
|
+
if (!indexed.has(name)) count += 1;
|
|
135876
|
+
}
|
|
135877
|
+
return count;
|
|
135878
|
+
}
|
|
135879
|
+
async function applySearch(items, query2, registryNames, status) {
|
|
135880
|
+
const warnings = [];
|
|
135881
|
+
if (status.status === "ready") {
|
|
135882
|
+
try {
|
|
135883
|
+
const ranking = await localSemanticRanking(query2);
|
|
135884
|
+
if (ranking) {
|
|
135885
|
+
const { ranked, missing } = pickByName(
|
|
135886
|
+
items,
|
|
135887
|
+
ranking.map((entry) => entry.name),
|
|
135888
|
+
registryNames
|
|
135889
|
+
);
|
|
135890
|
+
const best = ranked[0];
|
|
135891
|
+
if (best) {
|
|
135892
|
+
const scoreByName = new Map(ranking.map((entry) => [entry.name, entry.score]));
|
|
135893
|
+
return {
|
|
135894
|
+
items: ranked.slice(0, 25),
|
|
135895
|
+
localMode: "local-model",
|
|
135896
|
+
warnings,
|
|
135897
|
+
missing,
|
|
135898
|
+
unindexed: countUnindexed(registryNames, localVectorNames()),
|
|
135899
|
+
topScore: scoreByName.get(best.name) ?? null
|
|
135900
|
+
};
|
|
135901
|
+
}
|
|
135902
|
+
}
|
|
135903
|
+
} catch (error) {
|
|
135904
|
+
const warning = `on-device search did not run: ${error instanceof Error ? error.message : "unknown error"}`;
|
|
135905
|
+
warnings.push(warning);
|
|
135906
|
+
console.error(warning);
|
|
135907
|
+
}
|
|
135908
|
+
}
|
|
135909
|
+
const words = searchByWords(
|
|
135910
|
+
query2,
|
|
135911
|
+
items,
|
|
135912
|
+
(item) => `${item.name} ${item.title} ${item.description} ${(item.tags ?? []).join(" ")}`
|
|
135913
|
+
);
|
|
135914
|
+
return { items: words, localMode: "words", warnings, missing: 0, unindexed: 0, topScore: null };
|
|
135915
|
+
}
|
|
135916
|
+
function tierToken(searched) {
|
|
135917
|
+
return searched?.localMode === "local-model" ? "on-device" : "words";
|
|
135918
|
+
}
|
|
135919
|
+
function tierDetail(searched) {
|
|
135920
|
+
return searched?.localMode === "local-model" ? "on-device meaning search" : "local word match";
|
|
135921
|
+
}
|
|
135922
|
+
function reportLocalModelOption(json) {
|
|
135923
|
+
if (!json && process.stdout.isTTY) return;
|
|
135924
|
+
if (localModelStatus().status !== "not-asked") return;
|
|
135925
|
+
console.error(nonInteractiveConsentMessage());
|
|
135926
|
+
}
|
|
135927
|
+
async function offerLocalModel(matchCount, json, registryBaseUrl, artifactRevision) {
|
|
135928
|
+
if (json || !process.stdout.isTTY) return;
|
|
135929
|
+
if (localModelStatus().status !== "not-asked") return;
|
|
135930
|
+
const answer = await ue({
|
|
135931
|
+
message: downloadOfferMessage(matchCount),
|
|
135932
|
+
initialValue: true
|
|
135933
|
+
});
|
|
135934
|
+
if (q(answer)) return;
|
|
135935
|
+
recordLocalModelConsent(answer === true);
|
|
135936
|
+
if (answer !== true) return;
|
|
135937
|
+
const vectors = hasLocalVectors() || await fetchLocalVectors(registryBaseUrl, { expectedRevision: artifactRevision });
|
|
135938
|
+
console.log(
|
|
135939
|
+
c.dim(
|
|
135940
|
+
vectors ? " Run the search again to download the model and rank by meaning." : " Could not fetch the catalog vectors; offline ranking stays off until they are available."
|
|
135941
|
+
)
|
|
135942
|
+
);
|
|
135943
|
+
}
|
|
135270
135944
|
var examples5, catalog_default;
|
|
135271
135945
|
var init_catalog = __esm({
|
|
135272
135946
|
"src/commands/catalog.ts"() {
|
|
135273
135947
|
"use strict";
|
|
135274
|
-
init_commandResult();
|
|
135275
135948
|
init_dist();
|
|
135276
135949
|
init_dist8();
|
|
135277
135950
|
init_colors();
|
|
135278
135951
|
init_resolver();
|
|
135952
|
+
init_remote();
|
|
135279
135953
|
init_projectConfig();
|
|
135954
|
+
init_commandResult();
|
|
135280
135955
|
init_add();
|
|
135956
|
+
init_localSearch();
|
|
135957
|
+
init_localModel();
|
|
135958
|
+
init_localEmbedder();
|
|
135959
|
+
init_localSemantic();
|
|
135281
135960
|
examples5 = [
|
|
135282
135961
|
["List all blocks and components", "hyperframes catalog"],
|
|
135283
135962
|
["List blocks only", "hyperframes catalog --type block"],
|
|
@@ -135306,8 +135985,26 @@ var init_catalog = __esm({
|
|
|
135306
135985
|
"human-friendly": {
|
|
135307
135986
|
type: "boolean",
|
|
135308
135987
|
description: "Interactive picker \u2014 select an item to install"
|
|
135988
|
+
},
|
|
135989
|
+
query: {
|
|
135990
|
+
type: "string",
|
|
135991
|
+
description: "Search by meaning when the on-device model is on, otherwise by name, title, description and tags"
|
|
135992
|
+
},
|
|
135993
|
+
yes: {
|
|
135994
|
+
type: "boolean",
|
|
135995
|
+
alias: "y",
|
|
135996
|
+
description: "Assume yes for prompts this run, including the on-device model download"
|
|
135997
|
+
},
|
|
135998
|
+
"on-device": {
|
|
135999
|
+
type: "boolean",
|
|
136000
|
+
// Consent for the model download is otherwise only reachable through a
|
|
136001
|
+
// prompt that fires on a TTY, which leaves every agent and CI run unable
|
|
136002
|
+
// to opt in at all.
|
|
136003
|
+
description: "Use on-device meaning search; pass --yes to approve a first non-interactive download"
|
|
135309
136004
|
}
|
|
135310
136005
|
},
|
|
136006
|
+
// one flag-parsing entry point feeding three output paths (json, interactive, table); splitting those is its own change
|
|
136007
|
+
// fallow-ignore-next-line complexity
|
|
135311
136008
|
async run({ args }) {
|
|
135312
136009
|
const json = args.json === true;
|
|
135313
136010
|
const interactive = args["human-friendly"] === true;
|
|
@@ -135318,12 +136015,14 @@ var init_catalog = __esm({
|
|
|
135318
136015
|
else if (args.type === "component") typeFilter = "hyperframes:component";
|
|
135319
136016
|
else if (args.type) {
|
|
135320
136017
|
console.error(`Invalid --type: "${args.type}". Use "block" or "component".`);
|
|
135321
|
-
|
|
135322
|
-
}
|
|
135323
|
-
const
|
|
135324
|
-
|
|
135325
|
-
|
|
135326
|
-
const
|
|
136018
|
+
finishCommand(1);
|
|
136019
|
+
}
|
|
136020
|
+
const manifest = await fetchRegistryManifest(config.registry);
|
|
136021
|
+
const entries2 = manifest?.items ?? [];
|
|
136022
|
+
const artifactRevision = manifest?.catalogArtifact?.revision;
|
|
136023
|
+
const catalog = entries2.filter((e3) => e3.type !== "hyperframes:example");
|
|
136024
|
+
const registryNames = new Set(catalog.map((e3) => e3.name));
|
|
136025
|
+
const filtered = typeFilter ? catalog.filter((e3) => e3.type === typeFilter) : catalog;
|
|
135327
136026
|
if (filtered.length === 0) {
|
|
135328
136027
|
if (json) console.log("[]");
|
|
135329
136028
|
else console.log("No items found in registry.");
|
|
@@ -135331,10 +136030,56 @@ var init_catalog = __esm({
|
|
|
135331
136030
|
}
|
|
135332
136031
|
const items = await loadAllItems(filtered, { baseUrl: config.registry });
|
|
135333
136032
|
const tagFilter = args.tag?.toLowerCase();
|
|
135334
|
-
const
|
|
136033
|
+
const tagged = tagFilter ? items.filter((item) => item.tags?.some((t2) => t2.toLowerCase() === tagFilter)) : items;
|
|
136034
|
+
const query2 = typeof args.query === "string" ? args.query.trim() : "";
|
|
136035
|
+
const searchContext = query2 ? { status: localModelStatus() } : null;
|
|
136036
|
+
const routineUpdate = searchContext?.status.status === "unavailable" || searchContext?.status.status === "ready" && artifactRevision !== void 0 && cachedLocalVectorRevision() !== artifactRevision;
|
|
136037
|
+
const shouldPrepare = args["on-device"] === true || routineUpdate;
|
|
136038
|
+
let warnings = [];
|
|
136039
|
+
let effectiveStatus = searchContext?.status;
|
|
136040
|
+
if (searchContext && shouldPrepare) {
|
|
136041
|
+
warnings = await prepareOnDeviceTier({
|
|
136042
|
+
assumedYes: args.yes === true,
|
|
136043
|
+
artifactRevision,
|
|
136044
|
+
canPrompt: process.stdout.isTTY === true && !json,
|
|
136045
|
+
registry: config.registry,
|
|
136046
|
+
registryNames,
|
|
136047
|
+
status: searchContext.status
|
|
136048
|
+
});
|
|
136049
|
+
effectiveStatus = localModelStatus();
|
|
136050
|
+
}
|
|
136051
|
+
const searched = effectiveStatus ? await applySearch(tagged, query2, registryNames, effectiveStatus) : null;
|
|
136052
|
+
if (searched) warnings.push(...searched.warnings);
|
|
136053
|
+
const matching = searched ? searched.items : tagged;
|
|
135335
136054
|
if (matching.length === 0) {
|
|
135336
|
-
if (json)
|
|
135337
|
-
|
|
136055
|
+
if (json && query2) {
|
|
136056
|
+
console.log(
|
|
136057
|
+
JSON.stringify(
|
|
136058
|
+
{
|
|
136059
|
+
query: query2,
|
|
136060
|
+
tier: tierToken(searched),
|
|
136061
|
+
tier_detail: tierDetail(searched),
|
|
136062
|
+
dropped: searched?.missing ?? 0,
|
|
136063
|
+
unindexed: searched?.unindexed ?? 0,
|
|
136064
|
+
...searched?.topScore != null ? { top_score: searched.topScore } : {},
|
|
136065
|
+
shown: 0,
|
|
136066
|
+
total: tagged.length,
|
|
136067
|
+
...warnings.length ? { warnings } : {},
|
|
136068
|
+
results: []
|
|
136069
|
+
},
|
|
136070
|
+
null,
|
|
136071
|
+
2
|
|
136072
|
+
)
|
|
136073
|
+
);
|
|
136074
|
+
} else if (json) console.log("[]");
|
|
136075
|
+
else {
|
|
136076
|
+
const criteria = [
|
|
136077
|
+
query2 ? `query "${query2}"` : null,
|
|
136078
|
+
args.tag ? `tag "${args.tag}"` : null
|
|
136079
|
+
].filter(Boolean);
|
|
136080
|
+
console.log(`No items match ${criteria.join(" and ")}.`);
|
|
136081
|
+
}
|
|
136082
|
+
if (query2) await offerLocalModel(0, json, config.registry, artifactRevision);
|
|
135338
136083
|
return;
|
|
135339
136084
|
}
|
|
135340
136085
|
if (json) {
|
|
@@ -135347,9 +136092,49 @@ var init_catalog = __esm({
|
|
|
135347
136092
|
..."dimensions" in item && item.dimensions ? { dimensions: item.dimensions } : {},
|
|
135348
136093
|
..."duration" in item && item.duration ? { duration: item.duration } : {}
|
|
135349
136094
|
}));
|
|
135350
|
-
|
|
136095
|
+
if (!query2) {
|
|
136096
|
+
console.log(JSON.stringify(output, null, 2));
|
|
136097
|
+
return;
|
|
136098
|
+
}
|
|
136099
|
+
console.log(
|
|
136100
|
+
JSON.stringify(
|
|
136101
|
+
{
|
|
136102
|
+
query: query2,
|
|
136103
|
+
tier: tierToken(searched),
|
|
136104
|
+
tier_detail: tierDetail(searched),
|
|
136105
|
+
dropped: searched?.missing ?? 0,
|
|
136106
|
+
unindexed: searched?.unindexed ?? 0,
|
|
136107
|
+
...searched?.topScore != null ? { top_score: searched.topScore } : {},
|
|
136108
|
+
shown: output.length,
|
|
136109
|
+
total: tagged.length,
|
|
136110
|
+
...warnings.length ? { warnings } : {},
|
|
136111
|
+
results: output
|
|
136112
|
+
},
|
|
136113
|
+
null,
|
|
136114
|
+
2
|
|
136115
|
+
)
|
|
136116
|
+
);
|
|
135351
136117
|
return;
|
|
135352
136118
|
}
|
|
136119
|
+
if (searched) {
|
|
136120
|
+
const how = tierDetail(searched);
|
|
136121
|
+
const unshowable = searched.missing > 0 ? ` \xB7 ${searched.missing} ranked ${searched.missing === 1 ? "move" : "moves"} not in this registry` : "";
|
|
136122
|
+
console.log(c.dim(` ${matching.length} of ${tagged.length} moves \xB7 ${how}${unshowable}`));
|
|
136123
|
+
if (searched.unindexed > 0) {
|
|
136124
|
+
const remedy = args["on-device"] === true ? "The published index is behind this registry." : "Re-run with --on-device to refresh it.";
|
|
136125
|
+
console.log(
|
|
136126
|
+
c.warn(
|
|
136127
|
+
` ${searched.unindexed} of ${registryNames.size} moves are missing from the on-device index, so meaning search cannot return them. ${remedy}`
|
|
136128
|
+
)
|
|
136129
|
+
);
|
|
136130
|
+
}
|
|
136131
|
+
if (searched.localMode === "words") {
|
|
136132
|
+
if (warnings.length === 0) {
|
|
136133
|
+
reportLocalModelOption(json);
|
|
136134
|
+
await offerLocalModel(matching.length, json, config.registry, artifactRevision);
|
|
136135
|
+
}
|
|
136136
|
+
}
|
|
136137
|
+
}
|
|
135353
136138
|
if (interactive) {
|
|
135354
136139
|
const options = matching.map((item) => ({
|
|
135355
136140
|
value: item.name,
|
|
@@ -135416,7 +136201,7 @@ var init_mediaProxyPreview = __esm({
|
|
|
135416
136201
|
});
|
|
135417
136202
|
|
|
135418
136203
|
// src/utils/compositionServer.ts
|
|
135419
|
-
import { createReadStream as createReadStream6, existsSync as
|
|
136204
|
+
import { createReadStream as createReadStream6, existsSync as existsSync74, statSync as statSync26 } from "fs";
|
|
135420
136205
|
import { resolve as resolve44, dirname as dirname35 } from "path";
|
|
135421
136206
|
import { Readable as Readable3 } from "stream";
|
|
135422
136207
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
@@ -135431,7 +136216,7 @@ function resolveRuntimePath2() {
|
|
|
135431
136216
|
// Monorepo dev: src/<dir>/ → src/ → cli/ → packages/ then into core/dist/
|
|
135432
136217
|
resolve44(d2, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
|
|
135433
136218
|
];
|
|
135434
|
-
return candidates.find((p2) =>
|
|
136219
|
+
return candidates.find((p2) => existsSync74(p2)) ?? null;
|
|
135435
136220
|
}
|
|
135436
136221
|
function resolvePlayerPath() {
|
|
135437
136222
|
const d2 = helperDir();
|
|
@@ -135440,7 +136225,7 @@ function resolvePlayerPath() {
|
|
|
135440
136225
|
resolve44(d2, "hyperframes-player.global.js"),
|
|
135441
136226
|
resolve44(d2, "..", "hyperframes-player.global.js")
|
|
135442
136227
|
];
|
|
135443
|
-
return candidates.find((p2) =>
|
|
136228
|
+
return candidates.find((p2) => existsSync74(p2)) ?? null;
|
|
135444
136229
|
}
|
|
135445
136230
|
function resolveSlideshowPath() {
|
|
135446
136231
|
const d2 = helperDir();
|
|
@@ -135449,7 +136234,7 @@ function resolveSlideshowPath() {
|
|
|
135449
136234
|
resolve44(d2, "hyperframes-slideshow.global.js"),
|
|
135450
136235
|
resolve44(d2, "..", "hyperframes-slideshow.global.js")
|
|
135451
136236
|
];
|
|
135452
|
-
return candidates.find((p2) =>
|
|
136237
|
+
return candidates.find((p2) => existsSync74(p2)) ?? null;
|
|
135453
136238
|
}
|
|
135454
136239
|
function injectRuntime(html) {
|
|
135455
136240
|
return injectTagsAtHeadStart(html, `<script src="/runtime.js"></script>`);
|
|
@@ -135577,7 +136362,7 @@ __export(play_exports, {
|
|
|
135577
136362
|
examples: () => examples6,
|
|
135578
136363
|
registerCompositionRoute: () => registerCompositionRoute
|
|
135579
136364
|
});
|
|
135580
|
-
import { existsSync as
|
|
136365
|
+
import { existsSync as existsSync75, readFileSync as readFileSync47 } from "fs";
|
|
135581
136366
|
import { resolve as resolve45 } from "path";
|
|
135582
136367
|
async function registerCompositionRoute(app, project, autoProxy) {
|
|
135583
136368
|
const { isSafePath: isSafePath2 } = await Promise.resolve().then(() => (init_studio_api(), studio_api_exports));
|
|
@@ -135585,9 +136370,9 @@ async function registerCompositionRoute(app, project, autoProxy) {
|
|
|
135585
136370
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
135586
136371
|
const filePath = resolve45(project.dir, reqPath);
|
|
135587
136372
|
if (!isSafePath2(project.dir, filePath)) return ctx.text("Forbidden", 403);
|
|
135588
|
-
if (!
|
|
136373
|
+
if (!existsSync75(filePath)) return ctx.text("Not found", 404);
|
|
135589
136374
|
if (filePath.endsWith(".html")) {
|
|
135590
|
-
let html = injectRuntime(
|
|
136375
|
+
let html = injectRuntime(readFileSync47(filePath, "utf-8"));
|
|
135591
136376
|
if (autoProxy) {
|
|
135592
136377
|
html = await injectMediaCodecMapIntoHtml(html, project.dir, [{ html, compSrcPath: reqPath }]);
|
|
135593
136378
|
}
|
|
@@ -135768,13 +136553,13 @@ var init_play = __esm({
|
|
|
135768
136553
|
const { createAdaptorServer } = await import("@hono/node-server");
|
|
135769
136554
|
const app = new Hono6();
|
|
135770
136555
|
app.get("/player.js", (ctx) => {
|
|
135771
|
-
return ctx.body(
|
|
136556
|
+
return ctx.body(readFileSync47(playerPath, "utf-8"), 200, {
|
|
135772
136557
|
"Content-Type": "application/javascript",
|
|
135773
136558
|
"Cache-Control": "no-cache"
|
|
135774
136559
|
});
|
|
135775
136560
|
});
|
|
135776
136561
|
app.get("/runtime.js", (ctx) => {
|
|
135777
|
-
return ctx.body(
|
|
136562
|
+
return ctx.body(readFileSync47(runtimePath, "utf-8"), 200, {
|
|
135778
136563
|
"Content-Type": "application/javascript",
|
|
135779
136564
|
"Cache-Control": "no-cache"
|
|
135780
136565
|
});
|
|
@@ -135820,7 +136605,7 @@ __export(present_exports, {
|
|
|
135820
136605
|
default: () => present_default,
|
|
135821
136606
|
examples: () => examples7
|
|
135822
136607
|
});
|
|
135823
|
-
import { existsSync as
|
|
136608
|
+
import { existsSync as existsSync76, readFileSync as readFileSync48 } from "fs";
|
|
135824
136609
|
import { resolve as resolve46 } from "path";
|
|
135825
136610
|
function buildPresentPage(projectName, islandJson) {
|
|
135826
136611
|
return `<!doctype html>
|
|
@@ -136012,7 +136797,7 @@ var init_present = __esm({
|
|
|
136012
136797
|
setCommandExitCode(1);
|
|
136013
136798
|
return;
|
|
136014
136799
|
}
|
|
136015
|
-
const indexHtml =
|
|
136800
|
+
const indexHtml = readFileSync48(project.indexPath, "utf-8");
|
|
136016
136801
|
const { slideshowIslandRegex: slideshowIslandRegex2 } = await Promise.resolve().then(() => (init_slideshow2(), slideshow_exports));
|
|
136017
136802
|
const islandMatch = slideshowIslandRegex2("i").exec(indexHtml);
|
|
136018
136803
|
if (!islandMatch?.[1]) {
|
|
@@ -136038,14 +136823,14 @@ var init_present = __esm({
|
|
|
136038
136823
|
const app = new Hono6();
|
|
136039
136824
|
app.get(
|
|
136040
136825
|
"/player.js",
|
|
136041
|
-
(ctx) => ctx.body(
|
|
136826
|
+
(ctx) => ctx.body(readFileSync48(playerPath, "utf-8"), 200, {
|
|
136042
136827
|
"Content-Type": "application/javascript",
|
|
136043
136828
|
"Cache-Control": "no-cache"
|
|
136044
136829
|
})
|
|
136045
136830
|
);
|
|
136046
136831
|
app.get(
|
|
136047
136832
|
"/slideshow.js",
|
|
136048
|
-
(ctx) => ctx.body(
|
|
136833
|
+
(ctx) => ctx.body(readFileSync48(slideshowPath, "utf-8"), 200, {
|
|
136049
136834
|
"Content-Type": "application/javascript",
|
|
136050
136835
|
"Cache-Control": "no-cache"
|
|
136051
136836
|
})
|
|
@@ -136054,9 +136839,9 @@ var init_present = __esm({
|
|
|
136054
136839
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
136055
136840
|
const filePath = resolve46(project.dir, reqPath);
|
|
136056
136841
|
if (!isSafePath2(project.dir, filePath)) return ctx.text("Forbidden", 403);
|
|
136057
|
-
if (!
|
|
136058
|
-
if (filePath.endsWith(".html")) return ctx.html(
|
|
136059
|
-
return ctx.body(
|
|
136842
|
+
if (!existsSync76(filePath)) return ctx.text("Not found", 404);
|
|
136843
|
+
if (filePath.endsWith(".html")) return ctx.html(readFileSync48(filePath, "utf-8"));
|
|
136844
|
+
return ctx.body(readFileSync48(filePath), 200, { "Content-Type": assetContentType(filePath) });
|
|
136060
136845
|
});
|
|
136061
136846
|
app.get("/", (ctx) => ctx.html(buildPresentPage(project.name, islandJson)));
|
|
136062
136847
|
ge(c.bold("hyperframes present"));
|
|
@@ -136300,15 +137085,15 @@ var init_client2 = __esm({
|
|
|
136300
137085
|
});
|
|
136301
137086
|
|
|
136302
137087
|
// src/auth/paths.ts
|
|
136303
|
-
import { homedir as
|
|
136304
|
-
import { join as
|
|
137088
|
+
import { homedir as homedir17 } from "os";
|
|
137089
|
+
import { join as join84 } from "path";
|
|
136305
137090
|
function configDir() {
|
|
136306
137091
|
const override = process.env["HEYGEN_CONFIG_DIR"];
|
|
136307
137092
|
if (override && override.length > 0) return override;
|
|
136308
|
-
return
|
|
137093
|
+
return join84(homedir17(), ".heygen");
|
|
136309
137094
|
}
|
|
136310
137095
|
function credentialPath() {
|
|
136311
|
-
return
|
|
137096
|
+
return join84(configDir(), CREDENTIAL_FILENAME);
|
|
136312
137097
|
}
|
|
136313
137098
|
var CREDENTIAL_FILENAME;
|
|
136314
137099
|
var init_paths2 = __esm({
|
|
@@ -136672,10 +137457,10 @@ var init_resolver2 = __esm({
|
|
|
136672
137457
|
});
|
|
136673
137458
|
|
|
136674
137459
|
// src/auth/pkce.ts
|
|
136675
|
-
import { createHash as
|
|
137460
|
+
import { createHash as createHash19, randomBytes as randomBytes3 } from "crypto";
|
|
136676
137461
|
function generatePkcePair() {
|
|
136677
137462
|
const verifier = base64UrlEncode(randomBytes3(VERIFIER_BYTES));
|
|
136678
|
-
const challenge = base64UrlEncode(
|
|
137463
|
+
const challenge = base64UrlEncode(createHash19("sha256").update(verifier).digest());
|
|
136679
137464
|
return { verifier, challenge, method: "S256" };
|
|
136680
137465
|
}
|
|
136681
137466
|
function generateState() {
|
|
@@ -137393,14 +138178,14 @@ var init_auth = __esm({
|
|
|
137393
138178
|
});
|
|
137394
138179
|
|
|
137395
138180
|
// src/utils/projectLink.ts
|
|
137396
|
-
import { randomUUID as
|
|
137397
|
-
import { existsSync as
|
|
137398
|
-
import { homedir as
|
|
137399
|
-
import { join as
|
|
138181
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
138182
|
+
import { existsSync as existsSync77, mkdirSync as mkdirSync41, readFileSync as readFileSync49, writeFileSync as writeFileSync29 } from "fs";
|
|
138183
|
+
import { homedir as homedir18 } from "os";
|
|
138184
|
+
import { join as join85, resolve as resolve47 } from "path";
|
|
137400
138185
|
function readJsonRecord(path2) {
|
|
137401
138186
|
try {
|
|
137402
|
-
if (!
|
|
137403
|
-
const parsed = JSON.parse(
|
|
138187
|
+
if (!existsSync77(path2)) return null;
|
|
138188
|
+
const parsed = JSON.parse(readFileSync49(path2, "utf-8"));
|
|
137404
138189
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
|
|
137405
138190
|
return parsed;
|
|
137406
138191
|
} catch {
|
|
@@ -137425,8 +138210,8 @@ function readProjectLinks() {
|
|
|
137425
138210
|
}
|
|
137426
138211
|
function writeProjectLinks(links) {
|
|
137427
138212
|
try {
|
|
137428
|
-
|
|
137429
|
-
|
|
138213
|
+
mkdirSync41(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
138214
|
+
writeFileSync29(PROJECTS_FILE, `${JSON.stringify(links, null, 2)}
|
|
137430
138215
|
`, { mode: 384 });
|
|
137431
138216
|
} catch {
|
|
137432
138217
|
}
|
|
@@ -137444,13 +138229,13 @@ function ensureProjectId(absDir) {
|
|
|
137444
138229
|
const path2 = resolve47(absDir);
|
|
137445
138230
|
const existing = links[path2];
|
|
137446
138231
|
if (existing) return existing.projectId;
|
|
137447
|
-
const projectId =
|
|
138232
|
+
const projectId = randomUUID11();
|
|
137448
138233
|
links[path2] = { projectId, url: "" };
|
|
137449
138234
|
writeProjectLinks(links);
|
|
137450
138235
|
return projectId;
|
|
137451
138236
|
}
|
|
137452
138237
|
function teamProjectPath(projectDir) {
|
|
137453
|
-
return
|
|
138238
|
+
return join85(resolve47(projectDir), TEAM_PROJECT_DIR, TEAM_PROJECT_FILE);
|
|
137454
138239
|
}
|
|
137455
138240
|
function readTeamProject(projectDir) {
|
|
137456
138241
|
const record = readJsonRecord(teamProjectPath(projectDir));
|
|
@@ -137464,8 +138249,8 @@ function writeTeamProject(projectDir, team) {
|
|
|
137464
138249
|
projectId: team.projectId,
|
|
137465
138250
|
...team.spaceId ? { spaceId: team.spaceId } : {}
|
|
137466
138251
|
};
|
|
137467
|
-
|
|
137468
|
-
|
|
138252
|
+
mkdirSync41(join85(resolve47(projectDir), TEAM_PROJECT_DIR), { recursive: true });
|
|
138253
|
+
writeFileSync29(file, `${JSON.stringify(body, null, 2)}
|
|
137469
138254
|
`);
|
|
137470
138255
|
return file;
|
|
137471
138256
|
}
|
|
@@ -137473,16 +138258,16 @@ var CONFIG_DIR2, PROJECTS_FILE, TEAM_PROJECT_DIR, TEAM_PROJECT_FILE;
|
|
|
137473
138258
|
var init_projectLink = __esm({
|
|
137474
138259
|
"src/utils/projectLink.ts"() {
|
|
137475
138260
|
"use strict";
|
|
137476
|
-
CONFIG_DIR2 =
|
|
137477
|
-
PROJECTS_FILE =
|
|
138261
|
+
CONFIG_DIR2 = join85(homedir18(), ".hyperframes");
|
|
138262
|
+
PROJECTS_FILE = join85(CONFIG_DIR2, "projects.json");
|
|
137478
138263
|
TEAM_PROJECT_DIR = ".hyperframes";
|
|
137479
138264
|
TEAM_PROJECT_FILE = "project.json";
|
|
137480
138265
|
}
|
|
137481
138266
|
});
|
|
137482
138267
|
|
|
137483
138268
|
// src/utils/publishProject.ts
|
|
137484
|
-
import { basename as basename14, dirname as dirname37, join as
|
|
137485
|
-
import { existsSync as
|
|
138269
|
+
import { basename as basename14, dirname as dirname37, join as join86, posix as posix5, relative as relative18, resolve as resolve48 } from "path";
|
|
138270
|
+
import { existsSync as existsSync78, readdirSync as readdirSync27, readFileSync as readFileSync50, statSync as statSync27 } from "fs";
|
|
137486
138271
|
import AdmZip from "adm-zip";
|
|
137487
138272
|
import ignore2 from "ignore";
|
|
137488
138273
|
function isRecord8(value) {
|
|
@@ -137644,16 +138429,16 @@ function shouldIgnoreSegment(segment) {
|
|
|
137644
138429
|
}
|
|
137645
138430
|
function createProjectIgnore(rootDir) {
|
|
137646
138431
|
const matcher = ignore2().add(DEFAULT_PROJECT_IGNORE);
|
|
137647
|
-
const ignorePath =
|
|
137648
|
-
if (
|
|
137649
|
-
matcher.add(
|
|
138432
|
+
const ignorePath = join86(rootDir, HYPERFRAMES_IGNORE_FILE);
|
|
138433
|
+
if (existsSync78(ignorePath)) {
|
|
138434
|
+
matcher.add(readFileSync50(ignorePath, "utf-8"));
|
|
137650
138435
|
}
|
|
137651
138436
|
return matcher;
|
|
137652
138437
|
}
|
|
137653
138438
|
function collectProjectFiles(rootDir, currentDir, paths, matcher) {
|
|
137654
138439
|
for (const entry of readdirSync27(currentDir, { withFileTypes: true })) {
|
|
137655
138440
|
if (shouldIgnoreSegment(entry.name)) continue;
|
|
137656
|
-
const absolutePath =
|
|
138441
|
+
const absolutePath = join86(currentDir, entry.name);
|
|
137657
138442
|
const relativePath = relative18(rootDir, absolutePath).replaceAll("\\", "/");
|
|
137658
138443
|
if (!relativePath) continue;
|
|
137659
138444
|
if (entry.isDirectory()) {
|
|
@@ -137679,7 +138464,7 @@ function addExternalAsset(ctx, absPath) {
|
|
|
137679
138464
|
while (ctx.usedArchivePaths.has(`${base2}_${i2}${ext}`)) i2++;
|
|
137680
138465
|
archivePath = `${base2}_${i2}${ext}`;
|
|
137681
138466
|
}
|
|
137682
|
-
ctx.fileContents.set(archivePath,
|
|
138467
|
+
ctx.fileContents.set(archivePath, readFileSync50(absPath));
|
|
137683
138468
|
ctx.externalMap.set(absPath, archivePath);
|
|
137684
138469
|
ctx.usedArchivePaths.add(archivePath);
|
|
137685
138470
|
return archivePath;
|
|
@@ -137689,7 +138474,7 @@ function tryResolveExternal(ctx, rawPath, referrerAbsDir) {
|
|
|
137689
138474
|
const absPath = resolve48(referrerAbsDir, rawPath);
|
|
137690
138475
|
if (isPathInside(absPath, ctx.absProjectDir)) return null;
|
|
137691
138476
|
try {
|
|
137692
|
-
if (!
|
|
138477
|
+
if (!existsSync78(absPath) || !statSync27(absPath).isFile()) return null;
|
|
137693
138478
|
} catch {
|
|
137694
138479
|
return null;
|
|
137695
138480
|
}
|
|
@@ -137794,7 +138579,7 @@ function buildPublishFileMap(projectDir) {
|
|
|
137794
138579
|
}
|
|
137795
138580
|
const fileContents = /* @__PURE__ */ new Map();
|
|
137796
138581
|
for (const filePath of filePaths) {
|
|
137797
|
-
fileContents.set(filePath,
|
|
138582
|
+
fileContents.set(filePath, readFileSync50(join86(absProjectDir, filePath)));
|
|
137798
138583
|
}
|
|
137799
138584
|
localizeExternalAssets(absProjectDir, fileContents);
|
|
137800
138585
|
return fileContents;
|
|
@@ -137980,7 +138765,7 @@ var init_publishProject = __esm({
|
|
|
137980
138765
|
});
|
|
137981
138766
|
|
|
137982
138767
|
// src/utils/publishProxyBake.ts
|
|
137983
|
-
import { existsSync as
|
|
138768
|
+
import { existsSync as existsSync79 } from "fs";
|
|
137984
138769
|
import { readFile as readFile4 } from "fs/promises";
|
|
137985
138770
|
import { basename as basename15, dirname as dirname38, resolve as resolve49 } from "path";
|
|
137986
138771
|
function emptyManifest() {
|
|
@@ -138038,7 +138823,7 @@ async function bakeMediaProxies(projectDir, fileContents) {
|
|
|
138038
138823
|
const rootRelativeSrc = rewriteAssetPath(
|
|
138039
138824
|
entryPath,
|
|
138040
138825
|
cleaned,
|
|
138041
|
-
(path2) =>
|
|
138826
|
+
(path2) => existsSync79(resolve49(absProjectDir, path2))
|
|
138042
138827
|
);
|
|
138043
138828
|
for (const candidate of resolveLocalAssetCandidates(absProjectDir, rootRelativeSrc)) {
|
|
138044
138829
|
const archivePath = proxyByAbsolutePath.get(candidate);
|
|
@@ -138082,8 +138867,8 @@ __export(publish_exports, {
|
|
|
138082
138867
|
examples: () => examples8,
|
|
138083
138868
|
parseUpdateTarget: () => parseUpdateTarget
|
|
138084
138869
|
});
|
|
138085
|
-
import { join as
|
|
138086
|
-
import { existsSync as
|
|
138870
|
+
import { join as join87, relative as relative19, resolve as resolve50 } from "path";
|
|
138871
|
+
import { existsSync as existsSync80 } from "fs";
|
|
138087
138872
|
function parseUpdateTarget(value) {
|
|
138088
138873
|
const trimmed = value.trim();
|
|
138089
138874
|
const pathMatch = trimmed.match(/\/p\/([^/?#]+)/);
|
|
@@ -138153,8 +138938,8 @@ var init_publish = __esm({
|
|
|
138153
138938
|
async run({ args }) {
|
|
138154
138939
|
const rawArg = args.dir;
|
|
138155
138940
|
const dir = resolve50(rawArg ?? ".");
|
|
138156
|
-
const indexPath2 =
|
|
138157
|
-
if (
|
|
138941
|
+
const indexPath2 = join87(dir, "index.html");
|
|
138942
|
+
if (existsSync80(indexPath2)) {
|
|
138158
138943
|
const lintResult = await lintProject(dir);
|
|
138159
138944
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
138160
138945
|
console.log();
|
|
@@ -138295,7 +139080,7 @@ var init_publish = __esm({
|
|
|
138295
139080
|
|
|
138296
139081
|
// src/commands/render/plan.ts
|
|
138297
139082
|
import { statSync as statSync28 } from "fs";
|
|
138298
|
-
import { dirname as dirname39, join as
|
|
139083
|
+
import { dirname as dirname39, join as join88, resolve as resolve51 } from "path";
|
|
138299
139084
|
function formatFpsParseError(input2, reason) {
|
|
138300
139085
|
switch (reason) {
|
|
138301
139086
|
case "empty":
|
|
@@ -138465,8 +139250,8 @@ function createRenderPlan(args, now = /* @__PURE__ */ new Date()) {
|
|
|
138465
139250
|
const rendersDir = resolve51("renders");
|
|
138466
139251
|
const ext = FORMAT_EXT[format];
|
|
138467
139252
|
const timestamp = formatRenderOutputTimestamp(now);
|
|
138468
|
-
const batchOutputTemplate = args.output ? args.output :
|
|
138469
|
-
const outputPath = args.output ? resolve51(args.output) :
|
|
139253
|
+
const batchOutputTemplate = args.output ? args.output : join88(rendersDir, `${project.name}_${timestamp}_{index}${ext}`);
|
|
139254
|
+
const outputPath = args.output ? resolve51(args.output) : join88(rendersDir, `${project.name}_${timestamp}${ext}`);
|
|
138470
139255
|
const useDocker = args.docker ?? false;
|
|
138471
139256
|
const useGpu = args.gpu ?? false;
|
|
138472
139257
|
const browserGpuMode = resolveBrowserGpuForCli(useDocker, args["browser-gpu"]);
|
|
@@ -138597,7 +139382,7 @@ var init_plan2 = __esm({
|
|
|
138597
139382
|
|
|
138598
139383
|
// src/commands/render/present.ts
|
|
138599
139384
|
import { cpus as cpus4 } from "os";
|
|
138600
|
-
import { readFileSync as
|
|
139385
|
+
import { readFileSync as readFileSync51 } from "fs";
|
|
138601
139386
|
async function presentRenderPlan(plan2) {
|
|
138602
139387
|
await presentRenderWarnings(plan2);
|
|
138603
139388
|
if (plan2.effectiveQuiet || plan2.batchPath) return;
|
|
@@ -138640,7 +139425,7 @@ function presentRenderSummary(plan2) {
|
|
|
138640
139425
|
async function warnForSlideshow(plan2) {
|
|
138641
139426
|
try {
|
|
138642
139427
|
const { slideshowIslandRegex: slideshowIslandRegex2 } = await Promise.resolve().then(() => (init_slideshow2(), slideshow_exports));
|
|
138643
|
-
if (!slideshowIslandRegex2("i").test(
|
|
139428
|
+
if (!slideshowIslandRegex2("i").test(readFileSync51(plan2.renderTarget, "utf8"))) return;
|
|
138644
139429
|
console.log(
|
|
138645
139430
|
c.warn("\u26A0") + " This composition carries a slideshow island \u2014 `render` captures only the first scene, so the MP4 will be truncated to slide 1. Use " + c.accent("hyperframes present") + " for the deck; a linear main-line MP4 export is not yet available."
|
|
138646
139431
|
);
|
|
@@ -138657,9 +139442,9 @@ var init_present2 = __esm({
|
|
|
138657
139442
|
});
|
|
138658
139443
|
|
|
138659
139444
|
// src/utils/variables.ts
|
|
138660
|
-
import { readFileSync as
|
|
139445
|
+
import { readFileSync as readFileSync53 } from "fs";
|
|
138661
139446
|
import { resolve as resolve52 } from "path";
|
|
138662
|
-
function parseVariablesArg(inline, filePath, readFile5 = (p2) =>
|
|
139447
|
+
function parseVariablesArg(inline, filePath, readFile5 = (p2) => readFileSync53(resolve52(p2), "utf8")) {
|
|
138663
139448
|
if (inline != null && filePath != null) {
|
|
138664
139449
|
return { ok: false, error: { kind: "conflict" } };
|
|
138665
139450
|
}
|
|
@@ -138742,7 +139527,7 @@ function validateVariablesAgainstProject(indexPath2, values) {
|
|
|
138742
139527
|
function loadProjectVariableSchema(indexPath2) {
|
|
138743
139528
|
let html;
|
|
138744
139529
|
try {
|
|
138745
|
-
html =
|
|
139530
|
+
html = readFileSync53(indexPath2, "utf8");
|
|
138746
139531
|
} catch {
|
|
138747
139532
|
return [];
|
|
138748
139533
|
}
|
|
@@ -138797,8 +139582,8 @@ __export(batchRender_exports, {
|
|
|
138797
139582
|
resolveOutputTemplate: () => resolveOutputTemplate,
|
|
138798
139583
|
runBatchRender: () => runBatchRender
|
|
138799
139584
|
});
|
|
138800
|
-
import { mkdirSync as
|
|
138801
|
-
import { dirname as dirname40, join as
|
|
139585
|
+
import { mkdirSync as mkdirSync43, readFileSync as readFileSync54, writeFileSync as writeFileSync30 } from "fs";
|
|
139586
|
+
import { dirname as dirname40, join as join89, resolve as resolve53, sep as sep12 } from "path";
|
|
138802
139587
|
function isRecord9(value) {
|
|
138803
139588
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
138804
139589
|
}
|
|
@@ -138923,7 +139708,7 @@ function reportBatchVariableIssues(row, index, schema, quiet, json) {
|
|
|
138923
139708
|
}
|
|
138924
139709
|
function prepareBatchRender(options) {
|
|
138925
139710
|
const batchPath = resolve53(options.batchPath);
|
|
138926
|
-
const read = options.readFile ?? ((path2) =>
|
|
139711
|
+
const read = options.readFile ?? ((path2) => readFileSync54(path2, "utf8"));
|
|
138927
139712
|
let raw;
|
|
138928
139713
|
try {
|
|
138929
139714
|
raw = read(batchPath);
|
|
@@ -138939,7 +139724,7 @@ function prepareBatchRender(options) {
|
|
|
138939
139724
|
variables,
|
|
138940
139725
|
outputPath: resolve53(resolveOutputTemplate(options.outputTemplate, variables, index))
|
|
138941
139726
|
}));
|
|
138942
|
-
const manifestPath2 =
|
|
139727
|
+
const manifestPath2 = join89(
|
|
138943
139728
|
commonOutputDirectory(rows.map((row) => row.outputPath)),
|
|
138944
139729
|
"manifest.json"
|
|
138945
139730
|
);
|
|
@@ -138987,8 +139772,8 @@ function summarizeManifest(manifest) {
|
|
|
138987
139772
|
}
|
|
138988
139773
|
function writeManifest(manifest) {
|
|
138989
139774
|
summarizeManifest(manifest);
|
|
138990
|
-
|
|
138991
|
-
|
|
139775
|
+
mkdirSync43(dirname40(manifest.manifestPath), { recursive: true });
|
|
139776
|
+
writeFileSync30(manifest.manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf8");
|
|
138992
139777
|
}
|
|
138993
139778
|
async function renderBatchRow(row, manifest, options) {
|
|
138994
139779
|
const manifestRow = manifest.rows[row.index];
|
|
@@ -139002,7 +139787,7 @@ async function renderBatchRow(row, manifest, options) {
|
|
|
139002
139787
|
console.log(c.dim(`Batch row ${row.index}: ${row.outputPath}`));
|
|
139003
139788
|
}
|
|
139004
139789
|
try {
|
|
139005
|
-
|
|
139790
|
+
mkdirSync43(dirname40(row.outputPath), { recursive: true });
|
|
139006
139791
|
const result = await options.renderOne(row);
|
|
139007
139792
|
manifestRow.status = "completed";
|
|
139008
139793
|
manifestRow.durationMs = result.durationMs ?? null;
|
|
@@ -139119,13 +139904,13 @@ var init_batchRender = __esm({
|
|
|
139119
139904
|
});
|
|
139120
139905
|
|
|
139121
139906
|
// src/commands/render/execute.ts
|
|
139122
|
-
import { mkdirSync as
|
|
139907
|
+
import { mkdirSync as mkdirSync44, readFileSync as readFileSync55 } from "fs";
|
|
139123
139908
|
function renderLintContinuationHint(strictErrors) {
|
|
139124
139909
|
return strictErrors ? " Continuing render despite lint warnings. Use --strict-all to block warnings." : " Continuing render despite lint issues. Use --strict to block errors.";
|
|
139125
139910
|
}
|
|
139126
139911
|
async function executeRenderPlan(plan2, dependencies) {
|
|
139127
139912
|
applyRenderEnvironment(plan2);
|
|
139128
|
-
if (!plan2.batchPath)
|
|
139913
|
+
if (!plan2.batchPath) mkdirSync44(renderOutputDirectory(plan2), { recursive: true });
|
|
139129
139914
|
let batchModule;
|
|
139130
139915
|
let preparedBatch;
|
|
139131
139916
|
if (plan2.batchPath) {
|
|
@@ -139260,7 +140045,7 @@ async function runResolutionPreflight(plan2, checkResolution) {
|
|
|
139260
140045
|
if (!plan2.outputResolution) return;
|
|
139261
140046
|
let issue;
|
|
139262
140047
|
try {
|
|
139263
|
-
issue = await checkResolution(
|
|
140048
|
+
issue = await checkResolution(readFileSync55(plan2.renderTarget, "utf8"), plan2.outputResolution, {
|
|
139264
140049
|
alphaRequested: plan2.format === "webm" || plan2.format === "mov" || plan2.format === "png-sequence",
|
|
139265
140050
|
hdrRequested: plan2.hdrMode === "force-hdr",
|
|
139266
140051
|
aspectAgnostic: plan2.outputResolutionAspectAgnostic
|
|
@@ -139659,7 +140444,7 @@ var init_dockerRunArgs = __esm({
|
|
|
139659
140444
|
|
|
139660
140445
|
// src/browser/preflight.ts
|
|
139661
140446
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
139662
|
-
import { existsSync as
|
|
140447
|
+
import { existsSync as existsSync81 } from "fs";
|
|
139663
140448
|
import { platform as platform8 } from "os";
|
|
139664
140449
|
function parseToolVersion(raw) {
|
|
139665
140450
|
const m2 = raw.match(/(ffmpeg|ffprobe)\s+version\s+([\d][\d.\-\w]*)/i);
|
|
@@ -139667,7 +140452,7 @@ function parseToolVersion(raw) {
|
|
|
139667
140452
|
}
|
|
139668
140453
|
function configuredMissingDetail(envName) {
|
|
139669
140454
|
const configured = process.env[envName]?.trim();
|
|
139670
|
-
if (!configured ||
|
|
140455
|
+
if (!configured || existsSync81(configured)) return void 0;
|
|
139671
140456
|
return `Configured path does not exist: ${envName}="${configured}"`;
|
|
139672
140457
|
}
|
|
139673
140458
|
function readToolVersion(binaryPath) {
|
|
@@ -139764,7 +140549,7 @@ function chromeSharedLibOutcome(executablePath, found) {
|
|
|
139764
140549
|
}
|
|
139765
140550
|
async function checkChrome(browserPath) {
|
|
139766
140551
|
if (browserPath) {
|
|
139767
|
-
if (
|
|
140552
|
+
if (existsSync81(browserPath)) {
|
|
139768
140553
|
return chromeSharedLibOutcome(browserPath, {
|
|
139769
140554
|
name: "Chrome",
|
|
139770
140555
|
ok: true,
|
|
@@ -139922,9 +140707,9 @@ __export(render_exports, {
|
|
|
139922
140707
|
renderLocal: () => renderLocal,
|
|
139923
140708
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
139924
140709
|
});
|
|
139925
|
-
import { mkdtempSync as mkdtempSync12, readdirSync as readdirSync28, readFileSync as
|
|
140710
|
+
import { mkdtempSync as mkdtempSync12, readdirSync as readdirSync28, readFileSync as readFileSync56, statSync as statSync29, writeFileSync as writeFileSync31, rmSync as rmSync27 } from "fs";
|
|
139926
140711
|
import { freemem as freemem5, tmpdir as tmpdir12 } from "os";
|
|
139927
|
-
import { resolve as resolve54, dirname as dirname41, join as
|
|
140712
|
+
import { resolve as resolve54, dirname as dirname41, join as join90, basename as basename16 } from "path";
|
|
139928
140713
|
import { execFileSync as execFileSync11, spawn as spawn15 } from "child_process";
|
|
139929
140714
|
async function readCompositionDimensions(compositionHtml) {
|
|
139930
140715
|
try {
|
|
@@ -139990,8 +140775,8 @@ function ensureDockerImage(version2, platform10, quiet) {
|
|
|
139990
140775
|
}
|
|
139991
140776
|
if (!quiet) console.log(c.dim(` Building Docker image: ${tag} (${platform10})...`));
|
|
139992
140777
|
const dockerfilePath = resolveDockerfilePath();
|
|
139993
|
-
const tmpDir = mkdtempSync12(
|
|
139994
|
-
|
|
140778
|
+
const tmpDir = mkdtempSync12(join90(tmpdir12(), "hyperframes-docker-"));
|
|
140779
|
+
writeFileSync31(join90(tmpDir, "Dockerfile"), readFileSync56(dockerfilePath));
|
|
139995
140780
|
const targetArch = platform10 === "linux/arm64" ? "arm64" : "amd64";
|
|
139996
140781
|
try {
|
|
139997
140782
|
execFileSync11(
|
|
@@ -140617,7 +141402,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds
|
|
|
140617
141402
|
for (const entry of readdirSync28(outputPath, { withFileTypes: true })) {
|
|
140618
141403
|
if (!entry.isFile()) continue;
|
|
140619
141404
|
try {
|
|
140620
|
-
total += statSync29(
|
|
141405
|
+
total += statSync29(join90(outputPath, entry.name)).size;
|
|
140621
141406
|
} catch {
|
|
140622
141407
|
}
|
|
140623
141408
|
}
|
|
@@ -141029,7 +141814,7 @@ __export(staticProjectServer_exports, {
|
|
|
141029
141814
|
serveStaticProjectHtml: () => serveStaticProjectHtml
|
|
141030
141815
|
});
|
|
141031
141816
|
import { createServer as createServer2 } from "http";
|
|
141032
|
-
import { createReadStream as createReadStream7, existsSync as
|
|
141817
|
+
import { createReadStream as createReadStream7, existsSync as existsSync83, statSync as statSync30 } from "fs";
|
|
141033
141818
|
import { isAbsolute as isAbsolute14, relative as relative20, resolve as resolve55 } from "path";
|
|
141034
141819
|
function serveFileWithRange(filePath, rangeHeader, res, contentType = getMimeType(filePath)) {
|
|
141035
141820
|
const size = statSync30(filePath).size;
|
|
@@ -141133,7 +141918,7 @@ async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Fail
|
|
|
141133
141918
|
const filePath = resolve55(root, requestPath);
|
|
141134
141919
|
const rel = relative20(root, filePath);
|
|
141135
141920
|
if (rel.startsWith("..") || isAbsolute14(rel)) continue;
|
|
141136
|
-
if (
|
|
141921
|
+
if (existsSync83(filePath)) {
|
|
141137
141922
|
if (proxyRequest) {
|
|
141138
141923
|
void serveProxyRequest(
|
|
141139
141924
|
projectDir,
|
|
@@ -141597,8 +142382,8 @@ var init_motionAudit = __esm({
|
|
|
141597
142382
|
});
|
|
141598
142383
|
|
|
141599
142384
|
// src/utils/motionSpec.ts
|
|
141600
|
-
import { existsSync as
|
|
141601
|
-
import { basename as basename17, join as
|
|
142385
|
+
import { existsSync as existsSync84, readFileSync as readFileSync57, readdirSync as readdirSync29 } from "fs";
|
|
142386
|
+
import { basename as basename17, join as join91 } from "path";
|
|
141602
142387
|
function isObject2(value) {
|
|
141603
142388
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
141604
142389
|
}
|
|
@@ -141640,11 +142425,11 @@ function parseMotionSpec(raw) {
|
|
|
141640
142425
|
return { ok: true, spec };
|
|
141641
142426
|
}
|
|
141642
142427
|
function findMotionSpec(projectDir) {
|
|
141643
|
-
if (!
|
|
142428
|
+
if (!existsSync84(projectDir)) return null;
|
|
141644
142429
|
const entries2 = readdirSync29(projectDir);
|
|
141645
142430
|
const sidecars = entries2.filter((name) => name.endsWith(".motion.json")).sort();
|
|
141646
142431
|
if (!sidecars[0]) return null;
|
|
141647
|
-
if (sidecars.length === 1) return
|
|
142432
|
+
if (sidecars.length === 1) return join91(projectDir, sidecars[0]);
|
|
141648
142433
|
const htmlBases = new Set(
|
|
141649
142434
|
entries2.filter((name) => name.endsWith(".html")).map((name) => basename17(name, ".html"))
|
|
141650
142435
|
);
|
|
@@ -141654,12 +142439,12 @@ function findMotionSpec(projectDir) {
|
|
|
141654
142439
|
`ambiguous motion sidecars in ${projectDir}: ${matched.join(", ")} each match a composition \u2014 remove the sidecars you do not need, or use one composition per project`
|
|
141655
142440
|
);
|
|
141656
142441
|
}
|
|
141657
|
-
return
|
|
142442
|
+
return join91(projectDir, matched[0] ?? sidecars[0]);
|
|
141658
142443
|
}
|
|
141659
142444
|
function readMotionSpec(path2) {
|
|
141660
142445
|
let raw;
|
|
141661
142446
|
try {
|
|
141662
|
-
raw = JSON.parse(
|
|
142447
|
+
raw = JSON.parse(readFileSync57(path2, "utf-8"));
|
|
141663
142448
|
} catch (err) {
|
|
141664
142449
|
return { ok: false, errors: [`could not read ${basename17(path2)}: ${err.message}`] };
|
|
141665
142450
|
}
|
|
@@ -141712,8 +142497,8 @@ __export(layout_exports, {
|
|
|
141712
142497
|
loadBrowserScript: () => loadBrowserScript,
|
|
141713
142498
|
parseAt: () => parseAt
|
|
141714
142499
|
});
|
|
141715
|
-
import { existsSync as
|
|
141716
|
-
import { dirname as dirname42, join as
|
|
142500
|
+
import { existsSync as existsSync85, readFileSync as readFileSync58 } from "fs";
|
|
142501
|
+
import { dirname as dirname42, join as join93 } from "path";
|
|
141717
142502
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
141718
142503
|
function buildMotionSampleTimes(duration) {
|
|
141719
142504
|
if (!Number.isFinite(duration) || duration <= 0) return [];
|
|
@@ -141871,9 +142656,9 @@ async function runLayoutAudit(projectDir, opts) {
|
|
|
141871
142656
|
}
|
|
141872
142657
|
}
|
|
141873
142658
|
function loadBrowserScript(name) {
|
|
141874
|
-
const candidates = [
|
|
142659
|
+
const candidates = [join93(__dirname2, name), join93(__dirname2, "commands", name)];
|
|
141875
142660
|
for (const candidate of candidates) {
|
|
141876
|
-
if (
|
|
142661
|
+
if (existsSync85(candidate)) return readFileSync58(candidate, "utf-8");
|
|
141877
142662
|
}
|
|
141878
142663
|
throw new Error(`Missing browser script ${name}`);
|
|
141879
142664
|
}
|
|
@@ -142270,9 +143055,9 @@ __export(validate_exports, {
|
|
|
142270
143055
|
resolveNavigationTimeoutMs: () => resolveNavigationTimeoutMs,
|
|
142271
143056
|
shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
|
|
142272
143057
|
});
|
|
142273
|
-
import { existsSync as
|
|
143058
|
+
import { existsSync as existsSync86, mkdtempSync as mkdtempSync13, readFileSync as readFileSync59, rmSync as rmSync28 } from "fs";
|
|
142274
143059
|
import { tmpdir as tmpdir13 } from "os";
|
|
142275
|
-
import { join as
|
|
143060
|
+
import { join as join94, dirname as dirname43 } from "path";
|
|
142276
143061
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
142277
143062
|
function resolveNavigationTimeoutMs(optTimeout) {
|
|
142278
143063
|
return Math.max(NAV_TIMEOUT_FLOOR_MS, optTimeout ?? 0);
|
|
@@ -142421,11 +143206,11 @@ async function runContrastAudit(page) {
|
|
|
142421
143206
|
}
|
|
142422
143207
|
function loadContrastAuditScript() {
|
|
142423
143208
|
const candidates = [
|
|
142424
|
-
|
|
142425
|
-
|
|
143209
|
+
join94(__dirname3, "contrast-audit.browser.js"),
|
|
143210
|
+
join94(__dirname3, "commands", "contrast-audit.browser.js")
|
|
142426
143211
|
];
|
|
142427
143212
|
for (const candidate of candidates) {
|
|
142428
|
-
if (
|
|
143213
|
+
if (existsSync86(candidate)) return readFileSync59(candidate, "utf-8");
|
|
142429
143214
|
}
|
|
142430
143215
|
throw new Error("Missing contrast audit browser script");
|
|
142431
143216
|
}
|
|
@@ -142437,7 +143222,7 @@ async function localizeRemoteAssets(html) {
|
|
|
142437
143222
|
try {
|
|
142438
143223
|
const { loadProducer: loadProducer2 } = await Promise.resolve().then(() => (init_producer(), producer_exports));
|
|
142439
143224
|
const { localizeRemoteMediaSources: localizeRemoteMediaSources2, localizeRemoteImageSources: localizeRemoteImageSources2, localizeRemoteFontFaces: localizeRemoteFontFaces2 } = await loadProducer2();
|
|
142440
|
-
dir = mkdtempSync13(
|
|
143225
|
+
dir = mkdtempSync13(join94(tmpdir13(), "hf-validate-assets-"));
|
|
142441
143226
|
const assetDir = dir;
|
|
142442
143227
|
const media = await localizeRemoteMediaSources2(html, assetDir);
|
|
142443
143228
|
const images = await localizeRemoteImageSources2(media.html, assetDir);
|
|
@@ -142755,8 +143540,8 @@ __export(checkBrowser_exports, {
|
|
|
142755
143540
|
preResolveHostileMediaProxies: () => preResolveHostileMediaProxies,
|
|
142756
143541
|
runBrowserCheck: () => runBrowserCheck
|
|
142757
143542
|
});
|
|
142758
|
-
import { mkdirSync as
|
|
142759
|
-
import { join as
|
|
143543
|
+
import { mkdirSync as mkdirSync45, writeFileSync as writeFileSync33 } from "fs";
|
|
143544
|
+
import { join as join95, resolve as resolve56 } from "path";
|
|
142760
143545
|
async function preResolveHostileMediaProxies(projectDir, html, autoProxyOverride) {
|
|
142761
143546
|
if (!resolveAutoProxy(projectDir, autoProxyOverride)) return;
|
|
142762
143547
|
let codecMap;
|
|
@@ -142856,8 +143641,8 @@ async function captureFindingCrops(project, options, requests) {
|
|
|
142856
143641
|
chromeBrowser = session.browser;
|
|
142857
143642
|
const page = session.page;
|
|
142858
143643
|
await waitForPreferredSeekTarget(page);
|
|
142859
|
-
const snapshotDir =
|
|
142860
|
-
|
|
143644
|
+
const snapshotDir = join95(project.dir, "snapshots");
|
|
143645
|
+
mkdirSync45(snapshotDir, { recursive: true });
|
|
142861
143646
|
for (const request of requests) {
|
|
142862
143647
|
await seekCompositionTimeline(page, request.time, AUDIT_SEEK_OPTIONS);
|
|
142863
143648
|
const canvas = await page.evaluate(() => ({
|
|
@@ -142866,8 +143651,8 @@ async function captureFindingCrops(project, options, requests) {
|
|
|
142866
143651
|
}));
|
|
142867
143652
|
const region = padCropRegion(request.bbox, canvas, DEFAULT_ZOOM_PADDING_PX);
|
|
142868
143653
|
const buffer = await captureRegionCrop(page, region, DEFAULT_ZOOM_SCALE);
|
|
142869
|
-
|
|
142870
|
-
written.push(
|
|
143654
|
+
writeFileSync33(join95(snapshotDir, request.filename), buffer);
|
|
143655
|
+
written.push(join95("snapshots", request.filename));
|
|
142871
143656
|
}
|
|
142872
143657
|
return written;
|
|
142873
143658
|
} finally {
|
|
@@ -143673,8 +144458,8 @@ var init_checkBrowser = __esm({
|
|
|
143673
144458
|
});
|
|
143674
144459
|
|
|
143675
144460
|
// src/utils/checkPipeline.ts
|
|
143676
|
-
import { mkdirSync as
|
|
143677
|
-
import { join as
|
|
144461
|
+
import { mkdirSync as mkdirSync46, writeFileSync as writeFileSync34 } from "fs";
|
|
144462
|
+
import { join as join96, relative as relative21 } from "path";
|
|
143678
144463
|
function selectContrastTimes(grid) {
|
|
143679
144464
|
if (grid.length <= 5) return [...grid];
|
|
143680
144465
|
return Array.from({ length: 5 }, (_, index) => {
|
|
@@ -144619,12 +145404,12 @@ async function runBrowserCheck2(project, options, motion) {
|
|
|
144619
145404
|
return module.runBrowserCheck(project, options, motion, runAuditGrid);
|
|
144620
145405
|
}
|
|
144621
145406
|
async function writeSnapshot(projectDir, index, time, pngBase64) {
|
|
144622
|
-
const snapshotDir =
|
|
144623
|
-
|
|
145407
|
+
const snapshotDir = join96(projectDir, "snapshots");
|
|
145408
|
+
mkdirSync46(snapshotDir, { recursive: true });
|
|
144624
145409
|
const filename = `frame-${String(index).padStart(2, "0")}-at-${time.toFixed(1)}s.png`;
|
|
144625
|
-
const path2 =
|
|
144626
|
-
|
|
144627
|
-
return
|
|
145410
|
+
const path2 = join96(snapshotDir, filename);
|
|
145411
|
+
writeFileSync34(path2, Buffer.from(pngBase64, "base64"));
|
|
145412
|
+
return join96("snapshots", filename);
|
|
144628
145413
|
}
|
|
144629
145414
|
async function captureFindingCrops2(project, options, requests) {
|
|
144630
145415
|
const module = await Promise.resolve().then(() => (init_checkBrowser(), checkBrowser_exports));
|
|
@@ -145219,28 +146004,28 @@ var init_beats = __esm({
|
|
|
145219
146004
|
});
|
|
145220
146005
|
|
|
145221
146006
|
// src/beats/headlessAnalyzer.ts
|
|
145222
|
-
import { existsSync as
|
|
146007
|
+
import { existsSync as existsSync87, readFileSync as readFileSync60 } from "fs";
|
|
145223
146008
|
import { createRequire as createRequire3 } from "module";
|
|
145224
|
-
import { dirname as dirname44, join as
|
|
146009
|
+
import { dirname as dirname44, join as join97 } from "path";
|
|
145225
146010
|
import { fileURLToPath as fileURLToPath13 } from "url";
|
|
145226
146011
|
function findPrebuiltBundle() {
|
|
145227
146012
|
const here = dirname44(fileURLToPath13(import.meta.url));
|
|
145228
146013
|
const candidates = [
|
|
145229
|
-
|
|
146014
|
+
join97(here, "beat-analyzer.global.js"),
|
|
145230
146015
|
// dist root (tsup-bundled cli)
|
|
145231
|
-
|
|
146016
|
+
join97(here, "../beat-analyzer.global.js"),
|
|
145232
146017
|
// dist/beats → dist
|
|
145233
|
-
|
|
146018
|
+
join97(here, "../dist/beat-analyzer.global.js")
|
|
145234
146019
|
];
|
|
145235
146020
|
for (const p2 of candidates) {
|
|
145236
|
-
if (
|
|
146021
|
+
if (existsSync87(p2)) return p2;
|
|
145237
146022
|
}
|
|
145238
146023
|
return null;
|
|
145239
146024
|
}
|
|
145240
146025
|
async function buildFromCoreSource() {
|
|
145241
146026
|
const esbuild = await import("esbuild");
|
|
145242
146027
|
const coreRoot = dirname44(require2.resolve("@hyperframes/core/package.json"));
|
|
145243
|
-
const entry =
|
|
146028
|
+
const entry = join97(coreRoot, "src/beats/beatDetection.ts");
|
|
145244
146029
|
const result = await esbuild.build({
|
|
145245
146030
|
stdin: {
|
|
145246
146031
|
contents: `import { analyzeMusicFromBuffer } from ${JSON.stringify(entry)};
|
|
@@ -145262,7 +146047,7 @@ function buildAnalyzerBundle() {
|
|
|
145262
146047
|
if (bundlePromise) return bundlePromise;
|
|
145263
146048
|
bundlePromise = (async () => {
|
|
145264
146049
|
const prebuilt = findPrebuiltBundle();
|
|
145265
|
-
if (prebuilt) return
|
|
146050
|
+
if (prebuilt) return readFileSync60(prebuilt, "utf8");
|
|
145266
146051
|
return buildFromCoreSource();
|
|
145267
146052
|
})().catch((err) => {
|
|
145268
146053
|
bundlePromise = null;
|
|
@@ -145340,14 +146125,14 @@ __export(beats_exports, {
|
|
|
145340
146125
|
default: () => beats_default,
|
|
145341
146126
|
examples: () => examples13
|
|
145342
146127
|
});
|
|
145343
|
-
import { existsSync as
|
|
145344
|
-
import { resolve as resolve57, join as
|
|
146128
|
+
import { existsSync as existsSync88, readFileSync as readFileSync61, mkdirSync as mkdirSync47, writeFileSync as writeFileSync35 } from "fs";
|
|
146129
|
+
import { resolve as resolve57, join as join98, dirname as dirname45 } from "path";
|
|
145345
146130
|
function fail(message) {
|
|
145346
146131
|
console.error(c.error(message));
|
|
145347
146132
|
failCommand();
|
|
145348
146133
|
}
|
|
145349
146134
|
function resolveMusicTarget(project) {
|
|
145350
|
-
const src = findMusicAudioSrc(
|
|
146135
|
+
const src = findMusicAudioSrc(readFileSync61(project.indexPath, "utf-8"));
|
|
145351
146136
|
if (!src) {
|
|
145352
146137
|
fail(
|
|
145353
146138
|
'No music track found. Add data-timeline-role="music" to the <audio> element (or give it an id like music/bgm/soundtrack).'
|
|
@@ -145356,12 +146141,12 @@ function resolveMusicTarget(project) {
|
|
|
145356
146141
|
const rel = audioRelPathForSrc(src);
|
|
145357
146142
|
if (!rel) fail(`Cannot derive a beat-file path for music src: ${src}`);
|
|
145358
146143
|
const audioPath = resolve57(project.dir, rel);
|
|
145359
|
-
if (!
|
|
146144
|
+
if (!existsSync88(audioPath)) fail(`Audio file not found: ${rel}`);
|
|
145360
146145
|
return { rel, audioPath };
|
|
145361
146146
|
}
|
|
145362
146147
|
async function detect(audioPath) {
|
|
145363
146148
|
try {
|
|
145364
|
-
return await analyzeBeatsHeadless(
|
|
146149
|
+
return await analyzeBeatsHeadless(readFileSync61(audioPath));
|
|
145365
146150
|
} catch (err) {
|
|
145366
146151
|
const msg = err instanceof Error ? err.message : String(err);
|
|
145367
146152
|
const hint2 = /chrome|executable|browser|ENOENT/i.test(msg) ? "\nRun: npx hyperframes browser ensure" : "";
|
|
@@ -145412,9 +146197,9 @@ var init_beats2 = __esm({
|
|
|
145412
146197
|
if (result.beatTimes.length === 0) {
|
|
145413
146198
|
fail(`No beats detected in ${rel} \u2014 nothing written. (Track may be silent/ambient.)`);
|
|
145414
146199
|
}
|
|
145415
|
-
const outPath =
|
|
145416
|
-
|
|
145417
|
-
|
|
146200
|
+
const outPath = join98(project.dir, "beats", `${rel}.json`);
|
|
146201
|
+
mkdirSync47(dirname45(outPath), { recursive: true });
|
|
146202
|
+
writeFileSync35(outPath, serializeBeats(result.beatTimes, result.beatStrengths, rel));
|
|
145418
146203
|
report(`beats/${rel}.json`, result, Boolean(args.json));
|
|
145419
146204
|
}
|
|
145420
146205
|
});
|
|
@@ -147369,10 +148154,10 @@ __export(motionShot_exports, {
|
|
|
147369
148154
|
ensureShotOutputDir: () => ensureShotOutputDir,
|
|
147370
148155
|
seekAllAdaptersInBrowser: () => seekAllAdaptersInBrowser
|
|
147371
148156
|
});
|
|
147372
|
-
import { mkdirSync as
|
|
148157
|
+
import { mkdirSync as mkdirSync48, writeFileSync as writeFileSync36 } from "fs";
|
|
147373
148158
|
import { dirname as dirname46 } from "path";
|
|
147374
148159
|
function ensureShotOutputDir(outPath) {
|
|
147375
|
-
|
|
148160
|
+
mkdirSync48(dirname46(outPath), { recursive: true });
|
|
147376
148161
|
}
|
|
147377
148162
|
function applyOrbitCamera(selectors, cam) {
|
|
147378
148163
|
const first = document.querySelector(selectors[0] ?? "");
|
|
@@ -147693,7 +148478,7 @@ async function captureGhostOnionSkin(page, requests, times, size, camera, outPat
|
|
|
147693
148478
|
);
|
|
147694
148479
|
const b64 = String(dataUrl).replace(/^data:image\/png;base64,/, "");
|
|
147695
148480
|
if (!b64) throw new Error("ghost composite returned no data");
|
|
147696
|
-
|
|
148481
|
+
writeFileSync36(outPath, Buffer.from(b64, "base64"));
|
|
147697
148482
|
return outPath;
|
|
147698
148483
|
}
|
|
147699
148484
|
async function captureMarkerOnionSkin(page, requests, times, size, camera, frame, outPath) {
|
|
@@ -147763,7 +148548,7 @@ async function captureMarkerOnionSkin(page, requests, times, size, camera, frame
|
|
|
147763
148548
|
await new Promise((r2) => setTimeout(r2, 60));
|
|
147764
148549
|
const buf = await page.screenshot({ type: "png" });
|
|
147765
148550
|
if (!buf) throw new Error("screenshot returned no data");
|
|
147766
|
-
|
|
148551
|
+
writeFileSync36(outPath, buf);
|
|
147767
148552
|
return outPath;
|
|
147768
148553
|
}
|
|
147769
148554
|
async function captureMotionPathShot(projectDir, requestsIn, outPath, opts = {}) {
|
|
@@ -147835,8 +148620,8 @@ __export(keyframes_exports, {
|
|
|
147835
148620
|
resolveScope: () => resolveScope,
|
|
147836
148621
|
surfaceComposition: () => surfaceComposition
|
|
147837
148622
|
});
|
|
147838
|
-
import { existsSync as
|
|
147839
|
-
import { resolve as resolve58, dirname as dirname47, basename as basename18, join as
|
|
148623
|
+
import { existsSync as existsSync89, readFileSync as readFileSync63, statSync as statSync31 } from "fs";
|
|
148624
|
+
import { resolve as resolve58, dirname as dirname47, basename as basename18, join as join99, relative as relative23, sep as sep13 } from "path";
|
|
147840
148625
|
function queryIncludingTemplates(html, selector) {
|
|
147841
148626
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
147842
148627
|
const roots = [doc];
|
|
@@ -148197,7 +148982,7 @@ function groupTraces(tweens) {
|
|
|
148197
148982
|
return traces;
|
|
148198
148983
|
}
|
|
148199
148984
|
function collectCompositions(indexPath2) {
|
|
148200
|
-
const html =
|
|
148985
|
+
const html = readFileSync63(indexPath2, "utf-8");
|
|
148201
148986
|
const baseDir = dirname47(indexPath2);
|
|
148202
148987
|
const out = [
|
|
148203
148988
|
surfaceComposition(html, basename18(indexPath2), basename18(indexPath2))
|
|
@@ -148207,9 +148992,9 @@ function collectCompositions(indexPath2) {
|
|
|
148207
148992
|
const src = div.getAttribute("data-composition-src");
|
|
148208
148993
|
if (!src) continue;
|
|
148209
148994
|
const subPath = resolve58(baseDir, src);
|
|
148210
|
-
if (!
|
|
148995
|
+
if (!existsSync89(subPath)) continue;
|
|
148211
148996
|
const id = div.getAttribute("data-composition-id") ?? src;
|
|
148212
|
-
out.push(surfaceComposition(
|
|
148997
|
+
out.push(surfaceComposition(readFileSync63(subPath, "utf-8"), id, src));
|
|
148213
148998
|
}
|
|
148214
148999
|
return out;
|
|
148215
149000
|
}
|
|
@@ -148326,9 +149111,9 @@ function resolveScope(args) {
|
|
|
148326
149111
|
let projectName;
|
|
148327
149112
|
let projectDir;
|
|
148328
149113
|
let entryFile;
|
|
148329
|
-
if (raw && raw.endsWith(".html") &&
|
|
149114
|
+
if (raw && raw.endsWith(".html") && existsSync89(raw) && statSync31(raw).isFile()) {
|
|
148330
149115
|
const entryPath = resolve58(raw);
|
|
148331
|
-
comps = [surfaceComposition(
|
|
149116
|
+
comps = [surfaceComposition(readFileSync63(entryPath, "utf-8"), basename18(entryPath), entryPath)];
|
|
148332
149117
|
projectName = basename18(entryPath);
|
|
148333
149118
|
projectDir = findProjectRoot(entryPath);
|
|
148334
149119
|
entryFile = relative23(projectDir, entryPath).split(sep13).join("/");
|
|
@@ -148358,8 +149143,8 @@ function findProjectRoot(entryPath) {
|
|
|
148358
149143
|
const entryDir = dirname47(entryPath);
|
|
148359
149144
|
let candidate = entryDir;
|
|
148360
149145
|
for (; ; ) {
|
|
148361
|
-
if (
|
|
148362
|
-
if (
|
|
149146
|
+
if (existsSync89(join99(candidate, "index.html"))) return candidate;
|
|
149147
|
+
if (existsSync89(join99(candidate, ".git"))) return entryDir;
|
|
148363
149148
|
const parent = dirname47(candidate);
|
|
148364
149149
|
if (parent === candidate) return entryDir;
|
|
148365
149150
|
candidate = parent;
|
|
@@ -148549,8 +149334,8 @@ __export(info_exports, {
|
|
|
148549
149334
|
examples: () => examples16,
|
|
148550
149335
|
orientation: () => orientation
|
|
148551
149336
|
});
|
|
148552
|
-
import { readFileSync as
|
|
148553
|
-
import { join as
|
|
149337
|
+
import { readFileSync as readFileSync64, readdirSync as readdirSync30, statSync as statSync33 } from "fs";
|
|
149338
|
+
import { join as join100 } from "path";
|
|
148554
149339
|
function orientation(width, height) {
|
|
148555
149340
|
if (width > height) return "landscape";
|
|
148556
149341
|
if (height > width) return "portrait";
|
|
@@ -148564,7 +149349,7 @@ function durationFromHtml(html, fallback) {
|
|
|
148564
149349
|
function totalSize(dir) {
|
|
148565
149350
|
let total = 0;
|
|
148566
149351
|
for (const entry of readdirSync30(dir, { withFileTypes: true })) {
|
|
148567
|
-
const path2 =
|
|
149352
|
+
const path2 = join100(dir, entry.name);
|
|
148568
149353
|
if (entry.isDirectory()) {
|
|
148569
149354
|
total += totalSize(path2);
|
|
148570
149355
|
} else {
|
|
@@ -148596,7 +149381,7 @@ var init_info = __esm({
|
|
|
148596
149381
|
},
|
|
148597
149382
|
async run({ args }) {
|
|
148598
149383
|
const project = resolveProject(args.dir);
|
|
148599
|
-
const html =
|
|
149384
|
+
const html = readFileSync64(project.indexPath, "utf-8");
|
|
148600
149385
|
ensureDOMParser();
|
|
148601
149386
|
const parsed = parseHtml(html);
|
|
148602
149387
|
const tracks = new Set(parsed.elements.map((el) => el.zIndex));
|
|
@@ -148656,7 +149441,7 @@ __export(compositions_exports, {
|
|
|
148656
149441
|
parseCompositions: () => parseCompositions,
|
|
148657
149442
|
parseSubComposition: () => parseSubComposition
|
|
148658
149443
|
});
|
|
148659
|
-
import { existsSync as
|
|
149444
|
+
import { existsSync as existsSync90, readFileSync as readFileSync65 } from "fs";
|
|
148660
149445
|
import { resolve as resolve59, dirname as dirname48 } from "path";
|
|
148661
149446
|
function countRenderableDescendants(root) {
|
|
148662
149447
|
return Array.from(root.querySelectorAll("*")).filter(
|
|
@@ -148736,8 +149521,8 @@ function parseCompositions(html, baseDir) {
|
|
|
148736
149521
|
const compositionSrc = div.getAttribute("data-composition-src");
|
|
148737
149522
|
if (compositionSrc) {
|
|
148738
149523
|
const subPath = resolve59(baseDir, compositionSrc);
|
|
148739
|
-
if (
|
|
148740
|
-
const subHtml =
|
|
149524
|
+
if (existsSync90(subPath)) {
|
|
149525
|
+
const subHtml = readFileSync65(subPath, "utf-8");
|
|
148741
149526
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
148742
149527
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
148743
149528
|
return;
|
|
@@ -148843,7 +149628,7 @@ var init_compositions = __esm({
|
|
|
148843
149628
|
},
|
|
148844
149629
|
async run({ args }) {
|
|
148845
149630
|
const project = resolveProject(args.dir);
|
|
148846
|
-
const html =
|
|
149631
|
+
const html = readFileSync65(project.indexPath, "utf-8");
|
|
148847
149632
|
ensureDOMParser();
|
|
148848
149633
|
const compositions = parseCompositions(html, dirname48(project.indexPath));
|
|
148849
149634
|
if (args.json) {
|
|
@@ -148881,8 +149666,8 @@ __export(benchmark_exports, {
|
|
|
148881
149666
|
default: () => benchmark_default,
|
|
148882
149667
|
examples: () => examples18
|
|
148883
149668
|
});
|
|
148884
|
-
import { existsSync as
|
|
148885
|
-
import { resolve as resolve60, join as
|
|
149669
|
+
import { existsSync as existsSync91, statSync as statSync34 } from "fs";
|
|
149670
|
+
import { resolve as resolve60, join as join101 } from "path";
|
|
148886
149671
|
var examples18, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
|
|
148887
149672
|
var init_benchmark = __esm({
|
|
148888
149673
|
"src/commands/benchmark.ts"() {
|
|
@@ -148961,7 +149746,7 @@ var init_benchmark = __esm({
|
|
|
148961
149746
|
s2?.start(`Benchmarking ${config.label}...`);
|
|
148962
149747
|
for (let i2 = 0; i2 < runsPerConfig; i2++) {
|
|
148963
149748
|
s2?.message(`${config.label} \u2014 run ${i2 + 1}/${runsPerConfig}`);
|
|
148964
|
-
const outputPath =
|
|
149749
|
+
const outputPath = join101(
|
|
148965
149750
|
benchDir,
|
|
148966
149751
|
`${config.label.replace(/[^a-zA-Z0-9]/g, "_")}_run${i2}.mp4`
|
|
148967
149752
|
);
|
|
@@ -148975,7 +149760,7 @@ var init_benchmark = __esm({
|
|
|
148975
149760
|
await producer.executeRenderJob(job, project.dir, outputPath);
|
|
148976
149761
|
const elapsedMs = Date.now() - startTime;
|
|
148977
149762
|
let fileSize = null;
|
|
148978
|
-
if (
|
|
149763
|
+
if (existsSync91(outputPath)) {
|
|
148979
149764
|
const stat3 = statSync34(outputPath);
|
|
148980
149765
|
fileSize = stat3.size;
|
|
148981
149766
|
}
|
|
@@ -149250,12 +150035,12 @@ __export(remove_background_exports, {
|
|
|
149250
150035
|
examples: () => examples20
|
|
149251
150036
|
});
|
|
149252
150037
|
import { resolve as resolve61 } from "path";
|
|
149253
|
-
import { existsSync as
|
|
150038
|
+
import { existsSync as existsSync93 } from "fs";
|
|
149254
150039
|
async function showInfo(json) {
|
|
149255
150040
|
const { selectProviders: selectProviders2, listAvailableProviders: listAvailableProviders2, DEFAULT_MODEL: DEFAULT_MODEL5, MODEL_MEMORY_MB: MODEL_MEMORY_MB2, modelPath: modelPath2 } = await Promise.resolve().then(() => (init_manager3(), manager_exports3));
|
|
149256
150041
|
const providers = listAvailableProviders2();
|
|
149257
150042
|
const auto = selectProviders2("auto");
|
|
149258
|
-
const cached2 =
|
|
150043
|
+
const cached2 = existsSync93(modelPath2());
|
|
149259
150044
|
if (json) {
|
|
149260
150045
|
console.log(
|
|
149261
150046
|
JSON.stringify({
|
|
@@ -149461,9 +150246,9 @@ var init_remove_background = __esm({
|
|
|
149461
150246
|
|
|
149462
150247
|
// src/whisper/parakeet.ts
|
|
149463
150248
|
import { execFileSync as execFileSync12 } from "child_process";
|
|
149464
|
-
import { existsSync as
|
|
149465
|
-
import { homedir as
|
|
149466
|
-
import { basename as basename19, extname as extname16, join as
|
|
150249
|
+
import { existsSync as existsSync94, mkdtempSync as mkdtempSync14, readFileSync as readFileSync66, rmSync as rmSync29, writeFileSync as writeFileSync37 } from "fs";
|
|
150250
|
+
import { homedir as homedir19, tmpdir as tmpdir14 } from "os";
|
|
150251
|
+
import { basename as basename19, extname as extname16, join as join103 } from "path";
|
|
149467
150252
|
function isRunnable(bin) {
|
|
149468
150253
|
try {
|
|
149469
150254
|
execFileSync12(bin, ["--help"], { stdio: ["ignore", "ignore", "ignore"], timeout: 1e4 });
|
|
@@ -149475,10 +150260,10 @@ function isRunnable(bin) {
|
|
|
149475
150260
|
function findParakeet() {
|
|
149476
150261
|
const candidates = [
|
|
149477
150262
|
process.env.HYPERFRAMES_PARAKEET,
|
|
149478
|
-
|
|
150263
|
+
join103(homedir19(), ".venvs", "parakeet", "bin", "parakeet-mlx")
|
|
149479
150264
|
].filter((p2) => Boolean(p2));
|
|
149480
150265
|
for (const path2 of candidates) {
|
|
149481
|
-
if (
|
|
150266
|
+
if (existsSync94(path2) && isRunnable(path2)) return path2;
|
|
149482
150267
|
}
|
|
149483
150268
|
try {
|
|
149484
150269
|
const which = process.platform === "win32" ? "where" : "which";
|
|
@@ -149488,7 +150273,7 @@ function findParakeet() {
|
|
|
149488
150273
|
timeout: 5e3
|
|
149489
150274
|
});
|
|
149490
150275
|
const first = out.split(/\r?\n/).map((s2) => s2.trim()).find(Boolean);
|
|
149491
|
-
if (first &&
|
|
150276
|
+
if (first && existsSync94(first)) return first;
|
|
149492
150277
|
} catch {
|
|
149493
150278
|
}
|
|
149494
150279
|
return void 0;
|
|
@@ -149525,22 +150310,22 @@ function transcribeWithParakeet(inputPath, dir, options) {
|
|
|
149525
150310
|
);
|
|
149526
150311
|
}
|
|
149527
150312
|
const model = options?.model ?? DEFAULT_MODEL3;
|
|
149528
|
-
const cached2 =
|
|
149529
|
-
|
|
150313
|
+
const cached2 = existsSync94(
|
|
150314
|
+
join103(homedir19(), ".cache", "huggingface", "hub", `models--${model.replace(/\//g, "--")}`)
|
|
149530
150315
|
);
|
|
149531
150316
|
options?.onProgress?.(
|
|
149532
150317
|
cached2 ? "Transcribing with Parakeet..." : "Downloading Parakeet model (first run, ~600MB)..."
|
|
149533
150318
|
);
|
|
149534
|
-
const workDir = mkdtempSync14(
|
|
150319
|
+
const workDir = mkdtempSync14(join103(tmpdir14(), "hyperframes-parakeet-"));
|
|
149535
150320
|
try {
|
|
149536
150321
|
const argv2 = [inputPath, "--model", model, "--output-format", "json", "--output-dir", workDir];
|
|
149537
150322
|
if (options?.language) argv2.push("--language", options.language);
|
|
149538
150323
|
execFileSync12(runner, argv2, { stdio: ["ignore", "pipe", "pipe"], timeout: 18e5 });
|
|
149539
|
-
const produced =
|
|
149540
|
-
if (!
|
|
149541
|
-
const words = mergeTokensToWords(JSON.parse(
|
|
149542
|
-
const transcriptPath =
|
|
149543
|
-
|
|
150324
|
+
const produced = join103(workDir, `${basename19(inputPath, extname16(inputPath))}.json`);
|
|
150325
|
+
if (!existsSync94(produced)) throw new Error("Parakeet did not produce output.");
|
|
150326
|
+
const words = mergeTokensToWords(JSON.parse(readFileSync66(produced, "utf-8")));
|
|
150327
|
+
const transcriptPath = join103(dir, "transcript.json");
|
|
150328
|
+
writeFileSync37(transcriptPath, JSON.stringify(words, null, 2));
|
|
149544
150329
|
const durationSeconds = words.length > 0 ? words[words.length - 1].end : 0;
|
|
149545
150330
|
return { transcriptPath, wordCount: words.length, durationSeconds, speechOnsetSeconds: null };
|
|
149546
150331
|
} finally {
|
|
@@ -149562,8 +150347,8 @@ __export(transcribe_exports2, {
|
|
|
149562
150347
|
default: () => transcribe_default,
|
|
149563
150348
|
examples: () => examples21
|
|
149564
150349
|
});
|
|
149565
|
-
import { existsSync as
|
|
149566
|
-
import { resolve as resolve62, join as
|
|
150350
|
+
import { existsSync as existsSync95, writeFileSync as writeFileSync38 } from "fs";
|
|
150351
|
+
import { resolve as resolve62, join as join104, extname as extname17, dirname as dirname49 } from "path";
|
|
149567
150352
|
function parseTimeoutMs(raw, json) {
|
|
149568
150353
|
const source = raw ?? process.env["HYPERFRAMES_TRANSCRIBE_TIMEOUT_MS"];
|
|
149569
150354
|
if (source == null || source === "") return void 0;
|
|
@@ -149599,8 +150384,8 @@ async function importTranscript(inputPath, dir, json) {
|
|
|
149599
150384
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
149600
150385
|
const { words, format } = loadTranscript2(inputPath);
|
|
149601
150386
|
if (words.length === 0) exitNoWords(json);
|
|
149602
|
-
const outPath =
|
|
149603
|
-
|
|
150387
|
+
const outPath = join104(dir, "transcript.json");
|
|
150388
|
+
writeFileSync38(outPath, JSON.stringify(words, null, 2));
|
|
149604
150389
|
patchCaptionHtml2(dir, words);
|
|
149605
150390
|
if (json) {
|
|
149606
150391
|
console.log(
|
|
@@ -149617,9 +150402,9 @@ async function exportTranscript(inputPath, dir, to, output, json, preserveCues)
|
|
|
149617
150402
|
const { words, format } = loadTranscript2(inputPath);
|
|
149618
150403
|
if (words.length === 0) exitNoWords(json);
|
|
149619
150404
|
const preGrouped = preserveCues || format === "srt" || format === "vtt" || void 0;
|
|
149620
|
-
const outPath = resolve62(output ??
|
|
150405
|
+
const outPath = resolve62(output ?? join104(dir, `transcript.${to}`));
|
|
149621
150406
|
const content = to === "srt" ? formatSrt2(words, { preGrouped }) : formatVtt2(words, { preGrouped });
|
|
149622
|
-
|
|
150407
|
+
writeFileSync38(outPath, content);
|
|
149623
150408
|
if (json) {
|
|
149624
150409
|
console.log(
|
|
149625
150410
|
JSON.stringify({ ok: true, format: to, wordCount: words.length, outputPath: outPath })
|
|
@@ -149668,7 +150453,7 @@ async function transcribeAudio(inputPath, dir, opts) {
|
|
|
149668
150453
|
);
|
|
149669
150454
|
}
|
|
149670
150455
|
}
|
|
149671
|
-
|
|
150456
|
+
writeFileSync38(result.transcriptPath, JSON.stringify(words, null, 2));
|
|
149672
150457
|
patchCaptionHtml2(dir, words);
|
|
149673
150458
|
if (opts.json) {
|
|
149674
150459
|
console.log(
|
|
@@ -149801,7 +150586,7 @@ var init_transcribe2 = __esm({
|
|
|
149801
150586
|
},
|
|
149802
150587
|
async run({ args }) {
|
|
149803
150588
|
const inputPath = resolve62(args.input);
|
|
149804
|
-
if (!
|
|
150589
|
+
if (!existsSync95(inputPath)) {
|
|
149805
150590
|
const message = `File not found: ${args.input}`;
|
|
149806
150591
|
trackCommandFailure("transcribe", message);
|
|
149807
150592
|
console.error(c.error(message));
|
|
@@ -149838,9 +150623,9 @@ var init_transcribe2 = __esm({
|
|
|
149838
150623
|
});
|
|
149839
150624
|
|
|
149840
150625
|
// src/tts/manager.ts
|
|
149841
|
-
import { existsSync as
|
|
149842
|
-
import { homedir as
|
|
149843
|
-
import { join as
|
|
150626
|
+
import { existsSync as existsSync96, mkdirSync as mkdirSync49 } from "fs";
|
|
150627
|
+
import { homedir as homedir20 } from "os";
|
|
150628
|
+
import { join as join105 } from "path";
|
|
149844
150629
|
function inferLangFromVoiceId(voiceId) {
|
|
149845
150630
|
const first = voiceId.charAt(0).toLowerCase();
|
|
149846
150631
|
return VOICE_PREFIX_LANG[first] ?? "en-us";
|
|
@@ -149849,41 +150634,41 @@ function isSupportedLang(value) {
|
|
|
149849
150634
|
return SUPPORTED_LANGS.includes(value);
|
|
149850
150635
|
}
|
|
149851
150636
|
async function ensureModel3(model = DEFAULT_MODEL4, options) {
|
|
149852
|
-
const modelPath2 =
|
|
149853
|
-
if (
|
|
150637
|
+
const modelPath2 = join105(MODELS_DIR4, `${model}.onnx`);
|
|
150638
|
+
if (existsSync96(modelPath2)) return modelPath2;
|
|
149854
150639
|
const url = MODEL_URLS2[model];
|
|
149855
150640
|
if (!url) {
|
|
149856
150641
|
throw new Error(
|
|
149857
150642
|
`Unknown TTS model: ${model}. Available: ${Object.keys(MODEL_URLS2).join(", ")}`
|
|
149858
150643
|
);
|
|
149859
150644
|
}
|
|
149860
|
-
|
|
150645
|
+
mkdirSync49(MODELS_DIR4, { recursive: true });
|
|
149861
150646
|
options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
|
|
149862
150647
|
await downloadFile(url, modelPath2);
|
|
149863
|
-
if (!
|
|
150648
|
+
if (!existsSync96(modelPath2)) {
|
|
149864
150649
|
throw new Error(`Model download failed: ${model}`);
|
|
149865
150650
|
}
|
|
149866
150651
|
return modelPath2;
|
|
149867
150652
|
}
|
|
149868
150653
|
async function ensureVoices(options) {
|
|
149869
|
-
const voicesPath =
|
|
149870
|
-
if (
|
|
149871
|
-
|
|
150654
|
+
const voicesPath = join105(VOICES_DIR, "voices-v1.0.bin");
|
|
150655
|
+
if (existsSync96(voicesPath)) return voicesPath;
|
|
150656
|
+
mkdirSync49(VOICES_DIR, { recursive: true });
|
|
149872
150657
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
149873
150658
|
await downloadFile(VOICES_URL, voicesPath);
|
|
149874
|
-
if (!
|
|
150659
|
+
if (!existsSync96(voicesPath)) {
|
|
149875
150660
|
throw new Error("Voice data download failed");
|
|
149876
150661
|
}
|
|
149877
150662
|
return voicesPath;
|
|
149878
150663
|
}
|
|
149879
|
-
var CACHE_DIR3,
|
|
150664
|
+
var CACHE_DIR3, MODELS_DIR4, VOICES_DIR, DEFAULT_MODEL4, MODEL_URLS2, VOICES_URL, SUPPORTED_LANGS, VOICE_PREFIX_LANG, BUNDLED_VOICES, DEFAULT_VOICE;
|
|
149880
150665
|
var init_manager4 = __esm({
|
|
149881
150666
|
"src/tts/manager.ts"() {
|
|
149882
150667
|
"use strict";
|
|
149883
150668
|
init_download();
|
|
149884
|
-
CACHE_DIR3 =
|
|
149885
|
-
|
|
149886
|
-
VOICES_DIR =
|
|
150669
|
+
CACHE_DIR3 = join105(homedir20(), ".cache", "hyperframes", "tts");
|
|
150670
|
+
MODELS_DIR4 = join105(CACHE_DIR3, "models");
|
|
150671
|
+
VOICES_DIR = join105(CACHE_DIR3, "voices");
|
|
149887
150672
|
DEFAULT_MODEL4 = "kokoro-v1.0";
|
|
149888
150673
|
MODEL_URLS2 = {
|
|
149889
150674
|
"kokoro-v1.0": "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx"
|
|
@@ -150012,19 +150797,19 @@ __export(synthesize_exports, {
|
|
|
150012
150797
|
synthesize: () => synthesize
|
|
150013
150798
|
});
|
|
150014
150799
|
import { execFileSync as execFileSync14 } from "child_process";
|
|
150015
|
-
import { existsSync as
|
|
150016
|
-
import { join as
|
|
150017
|
-
import { homedir as
|
|
150800
|
+
import { existsSync as existsSync97, writeFileSync as writeFileSync39, mkdirSync as mkdirSync50, readdirSync as readdirSync31, unlinkSync as unlinkSync9 } from "fs";
|
|
150801
|
+
import { join as join106, dirname as dirname50, basename as basename20 } from "path";
|
|
150802
|
+
import { homedir as homedir21 } from "os";
|
|
150018
150803
|
function ensureSynthScript() {
|
|
150019
|
-
if (!
|
|
150020
|
-
|
|
150021
|
-
|
|
150804
|
+
if (!existsSync97(SCRIPT_PATH)) {
|
|
150805
|
+
mkdirSync50(SCRIPT_DIR, { recursive: true });
|
|
150806
|
+
writeFileSync39(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
150022
150807
|
const currentName = basename20(SCRIPT_PATH);
|
|
150023
150808
|
try {
|
|
150024
150809
|
for (const entry of readdirSync31(SCRIPT_DIR)) {
|
|
150025
150810
|
if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
|
|
150026
150811
|
try {
|
|
150027
|
-
|
|
150812
|
+
unlinkSync9(join106(SCRIPT_DIR, entry));
|
|
150028
150813
|
} catch {
|
|
150029
150814
|
}
|
|
150030
150815
|
}
|
|
@@ -150058,7 +150843,7 @@ async function synthesize(text2, outputPath, options) {
|
|
|
150058
150843
|
ensureVoices({ onProgress: options?.onProgress })
|
|
150059
150844
|
]);
|
|
150060
150845
|
const scriptPath = ensureSynthScript();
|
|
150061
|
-
|
|
150846
|
+
mkdirSync50(dirname50(outputPath), { recursive: true });
|
|
150062
150847
|
options?.onProgress?.(`Generating speech with voice ${voice} (${lang})...`);
|
|
150063
150848
|
try {
|
|
150064
150849
|
const espeakLang = ESPEAK_LANG_OVERRIDES[lang] ?? lang;
|
|
@@ -150071,7 +150856,7 @@ async function synthesize(text2, outputPath, options) {
|
|
|
150071
150856
|
stdio: ["pipe", "pipe", "pipe"]
|
|
150072
150857
|
}
|
|
150073
150858
|
);
|
|
150074
|
-
if (!
|
|
150859
|
+
if (!existsSync97(outputPath)) {
|
|
150075
150860
|
throw new Error("Synthesis completed but no output file was created");
|
|
150076
150861
|
}
|
|
150077
150862
|
const lines = stdout2.trim().split("\n");
|
|
@@ -150084,7 +150869,7 @@ async function synthesize(text2, outputPath, options) {
|
|
|
150084
150869
|
langApplied: result.langApplied
|
|
150085
150870
|
};
|
|
150086
150871
|
} catch (err) {
|
|
150087
|
-
if (err instanceof SyntaxError &&
|
|
150872
|
+
if (err instanceof SyntaxError && existsSync97(outputPath)) {
|
|
150088
150873
|
throw new Error(
|
|
150089
150874
|
"Speech was generated but metadata could not be read. Check the output file manually."
|
|
150090
150875
|
);
|
|
@@ -150139,8 +150924,8 @@ print(json.dumps({
|
|
|
150139
150924
|
ESPEAK_LANG_OVERRIDES = {
|
|
150140
150925
|
zh: "cmn"
|
|
150141
150926
|
};
|
|
150142
|
-
SCRIPT_DIR =
|
|
150143
|
-
SCRIPT_PATH =
|
|
150927
|
+
SCRIPT_DIR = join106(homedir21(), ".cache", "hyperframes", "tts");
|
|
150928
|
+
SCRIPT_PATH = join106(SCRIPT_DIR, "synth-v2.py");
|
|
150144
150929
|
}
|
|
150145
150930
|
});
|
|
150146
150931
|
|
|
@@ -150150,7 +150935,7 @@ __export(tts_exports, {
|
|
|
150150
150935
|
default: () => tts_default,
|
|
150151
150936
|
examples: () => examples22
|
|
150152
150937
|
});
|
|
150153
|
-
import { existsSync as
|
|
150938
|
+
import { existsSync as existsSync98, readFileSync as readFileSync67 } from "fs";
|
|
150154
150939
|
import { resolve as resolve63, extname as extname18 } from "path";
|
|
150155
150940
|
function listVoices(json) {
|
|
150156
150941
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -150267,8 +151052,8 @@ var init_tts = __esm({
|
|
|
150267
151052
|
}
|
|
150268
151053
|
let text2;
|
|
150269
151054
|
const maybeFile = resolve63(input2);
|
|
150270
|
-
if (
|
|
150271
|
-
text2 =
|
|
151055
|
+
if (existsSync98(maybeFile) && extname18(maybeFile).toLowerCase() === ".txt") {
|
|
151056
|
+
text2 = readFileSync67(maybeFile, "utf-8").trim();
|
|
150272
151057
|
if (!text2) {
|
|
150273
151058
|
console.error(c.error("File is empty."));
|
|
150274
151059
|
failCommand();
|
|
@@ -150360,15 +151145,15 @@ __export(docs_exports, {
|
|
|
150360
151145
|
default: () => docs_default,
|
|
150361
151146
|
examples: () => examples23
|
|
150362
151147
|
});
|
|
150363
|
-
import { readFileSync as
|
|
150364
|
-
import { resolve as resolve64, dirname as dirname51, join as
|
|
151148
|
+
import { readFileSync as readFileSync68, existsSync as existsSync99 } from "fs";
|
|
151149
|
+
import { resolve as resolve64, dirname as dirname51, join as join107 } from "path";
|
|
150365
151150
|
import { fileURLToPath as fileURLToPath14 } from "url";
|
|
150366
151151
|
function docsDir() {
|
|
150367
151152
|
const thisFile = fileURLToPath14(import.meta.url);
|
|
150368
151153
|
const dir = dirname51(thisFile);
|
|
150369
151154
|
const devPath = resolve64(dir, "..", "docs");
|
|
150370
151155
|
const builtPath = resolve64(dir, "docs");
|
|
150371
|
-
return
|
|
151156
|
+
return existsSync99(devPath) ? devPath : builtPath;
|
|
150372
151157
|
}
|
|
150373
151158
|
function formatInlineCode(line2) {
|
|
150374
151159
|
return line2.replace(/`([^`]+)`/g, (_match, code) => c.accent(code));
|
|
@@ -150466,12 +151251,12 @@ var init_docs = __esm({
|
|
|
150466
151251
|
}
|
|
150467
151252
|
failCommand();
|
|
150468
151253
|
}
|
|
150469
|
-
const filePath =
|
|
150470
|
-
if (!
|
|
151254
|
+
const filePath = join107(docsDir(), entry.file);
|
|
151255
|
+
if (!existsSync99(filePath)) {
|
|
150471
151256
|
console.error(c.error(`Doc file not found: ${filePath}`));
|
|
150472
151257
|
failCommand();
|
|
150473
151258
|
}
|
|
150474
|
-
const content =
|
|
151259
|
+
const content = readFileSync68(filePath, "utf-8");
|
|
150475
151260
|
console.log();
|
|
150476
151261
|
renderMarkdown(content);
|
|
150477
151262
|
}
|
|
@@ -150545,7 +151330,7 @@ __export(doctor_exports, {
|
|
|
150545
151330
|
redactHome: () => redactHome
|
|
150546
151331
|
});
|
|
150547
151332
|
import { execFileSync as execFileSync15, execSync as execSync5 } from "child_process";
|
|
150548
|
-
import { existsSync as
|
|
151333
|
+
import { existsSync as existsSync100 } from "fs";
|
|
150549
151334
|
import { platform as platform9 } from "os";
|
|
150550
151335
|
import { dirname as dirname52 } from "path";
|
|
150551
151336
|
function checkDocker() {
|
|
@@ -150635,7 +151420,7 @@ function checkDisk2() {
|
|
|
150635
151420
|
}
|
|
150636
151421
|
return { ok: true, detail: `${freeGb} GB free` };
|
|
150637
151422
|
}
|
|
150638
|
-
function checkFramesCache(env = process.env, freeDiskMb = getFreeDiskMb, fileExists =
|
|
151423
|
+
function checkFramesCache(env = process.env, freeDiskMb = getFreeDiskMb, fileExists = existsSync100) {
|
|
150639
151424
|
const resolution = resolveExtractCacheDir(env);
|
|
150640
151425
|
if (resolution.disabled) {
|
|
150641
151426
|
return {
|
|
@@ -150869,7 +151654,7 @@ __export(upgrade_exports, {
|
|
|
150869
151654
|
upgradeProjectPins: () => upgradeProjectPins
|
|
150870
151655
|
});
|
|
150871
151656
|
import { execFileSync as execFileSync16 } from "child_process";
|
|
150872
|
-
import { existsSync as
|
|
151657
|
+
import { existsSync as existsSync101, readFileSync as readFileSync69, writeFileSync as writeFileSync40, renameSync as renameSync14 } from "fs";
|
|
150873
151658
|
import { resolve as resolve65 } from "path";
|
|
150874
151659
|
async function confirmUpgrade() {
|
|
150875
151660
|
const shouldUpgrade = await ue({ message: "Upgrade now?" });
|
|
@@ -150929,10 +151714,10 @@ function resolveProjectArgs(project, opts) {
|
|
|
150929
151714
|
}
|
|
150930
151715
|
async function upgradeProjectPins(dir, opts) {
|
|
150931
151716
|
const pkgPath = resolve65(dir, "package.json");
|
|
150932
|
-
if (!
|
|
151717
|
+
if (!existsSync101(pkgPath)) {
|
|
150933
151718
|
return { changed: false, from: [], to: "", path: pkgPath };
|
|
150934
151719
|
}
|
|
150935
|
-
const raw = JSON.parse(
|
|
151720
|
+
const raw = JSON.parse(readFileSync69(pkgPath, "utf-8"));
|
|
150936
151721
|
const scripts = raw.scripts ?? {};
|
|
150937
151722
|
const { latest } = await checkForUpdate(true);
|
|
150938
151723
|
if (!isSafeVersion(latest)) return { changed: false, from: [], to: latest, path: pkgPath };
|
|
@@ -150940,14 +151725,14 @@ async function upgradeProjectPins(dir, opts) {
|
|
|
150940
151725
|
if (rewrite.changed && !opts.check) {
|
|
150941
151726
|
raw.scripts = rewrite.scripts;
|
|
150942
151727
|
const tmp = `${pkgPath}.tmp`;
|
|
150943
|
-
|
|
151728
|
+
writeFileSync40(tmp, `${JSON.stringify(raw, null, 2)}
|
|
150944
151729
|
`, "utf-8");
|
|
150945
151730
|
renameSync14(tmp, pkgPath);
|
|
150946
151731
|
}
|
|
150947
151732
|
return { changed: rewrite.changed, from: rewrite.fromVersions, to: latest, path: pkgPath };
|
|
150948
151733
|
}
|
|
150949
151734
|
function printProjectPinResult(res, checkOnly) {
|
|
150950
|
-
if (!
|
|
151735
|
+
if (!existsSync101(res.path)) {
|
|
150951
151736
|
console.log(` ${c.dim("No package.json found \u2014 nothing to upgrade.")}`);
|
|
150952
151737
|
return;
|
|
150953
151738
|
}
|
|
@@ -151095,13 +151880,13 @@ function normalizeRepoUrl(repoUrl) {
|
|
|
151095
151880
|
const trimmed = repoUrl.trim().replace(/\/$/, "").replace(/\.git$/, "");
|
|
151096
151881
|
return trimmed || HYPERFRAMES_REPO_URL;
|
|
151097
151882
|
}
|
|
151098
|
-
function
|
|
151883
|
+
function truncate2(value, max) {
|
|
151099
151884
|
return value.length > max ? `${value.slice(0, max - 1)}\u2026` : value;
|
|
151100
151885
|
}
|
|
151101
151886
|
function buildIssueTitle(rating, comment) {
|
|
151102
151887
|
const firstLine = comment?.split("\n")[0]?.trim();
|
|
151103
151888
|
if (!firstLine) return `Render feedback (rating ${rating}/${FEEDBACK_RATING_SCALE})`;
|
|
151104
|
-
return `[feedback] ${
|
|
151889
|
+
return `[feedback] ${truncate2(firstLine, TITLE_MAX)}`;
|
|
151105
151890
|
}
|
|
151106
151891
|
function buildIssueBody(input2) {
|
|
151107
151892
|
const comment = input2.comment?.trim();
|
|
@@ -151110,7 +151895,7 @@ function buildIssueBody(input2) {
|
|
|
151110
151895
|
`**Rating:** ${input2.rating}/${FEEDBACK_RATING_SCALE}`,
|
|
151111
151896
|
"",
|
|
151112
151897
|
"## Comment",
|
|
151113
|
-
comment ?
|
|
151898
|
+
comment ? truncate2(comment, COMMENT_MAX) : "_No comment provided._",
|
|
151114
151899
|
"",
|
|
151115
151900
|
"## Minimal repro",
|
|
151116
151901
|
repro,
|
|
@@ -151209,7 +151994,7 @@ __export(feedback_exports, {
|
|
|
151209
151994
|
default: () => feedback_default,
|
|
151210
151995
|
examples: () => examples26
|
|
151211
151996
|
});
|
|
151212
|
-
import { randomUUID as
|
|
151997
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
151213
151998
|
import { resolve as resolve66 } from "path";
|
|
151214
151999
|
import open from "open";
|
|
151215
152000
|
function normalizeComment(raw) {
|
|
@@ -151362,7 +152147,7 @@ var init_feedback2 = __esm({
|
|
|
151362
152147
|
}
|
|
151363
152148
|
const comment = normalizeComment(args.comment);
|
|
151364
152149
|
const doctorSummary = await getDoctorSummary();
|
|
151365
|
-
const feedbackId =
|
|
152150
|
+
const feedbackId = randomUUID12();
|
|
151366
152151
|
const config = readConfig();
|
|
151367
152152
|
const joinKeys = buildTelemetryJoinKeys({
|
|
151368
152153
|
feedbackId,
|
|
@@ -151587,8 +152372,8 @@ __export(contactSheet_exports, {
|
|
|
151587
152372
|
createSvgContactSheet: () => createSvgContactSheet
|
|
151588
152373
|
});
|
|
151589
152374
|
import sharp from "sharp";
|
|
151590
|
-
import { readdirSync as readdirSync33, readFileSync as
|
|
151591
|
-
import { join as
|
|
152375
|
+
import { readdirSync as readdirSync33, readFileSync as readFileSync70, writeFileSync as writeFileSync41, unlinkSync as unlinkSync10, existsSync as existsSync103 } from "fs";
|
|
152376
|
+
import { join as join108, extname as extname19, basename as basename21, dirname as dirname53 } from "path";
|
|
151592
152377
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
151593
152378
|
const {
|
|
151594
152379
|
cols = 3,
|
|
@@ -151674,10 +152459,10 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
151674
152459
|
return results;
|
|
151675
152460
|
}
|
|
151676
152461
|
async function createScrollContactSheet(screenshotsDir, outputPath, budget = {}) {
|
|
151677
|
-
if (!
|
|
152462
|
+
if (!existsSync103(screenshotsDir)) return [];
|
|
151678
152463
|
const scrollFiles = readdirSync33(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
151679
152464
|
if (scrollFiles.length === 0) return [];
|
|
151680
|
-
const paths = scrollFiles.map((f3) =>
|
|
152465
|
+
const paths = scrollFiles.map((f3) => join108(screenshotsDir, f3));
|
|
151681
152466
|
const labels = scrollFiles.map((f3) => {
|
|
151682
152467
|
const m2 = f3.match(/scroll-(\d+)\.png/);
|
|
151683
152468
|
return m2 ? `${m2[1]}% scroll` : f3;
|
|
@@ -151691,10 +152476,10 @@ async function createScrollContactSheet(screenshotsDir, outputPath, budget = {})
|
|
|
151691
152476
|
);
|
|
151692
152477
|
}
|
|
151693
152478
|
async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {}) {
|
|
151694
|
-
if (!
|
|
152479
|
+
if (!existsSync103(snapshotsDir)) return [];
|
|
151695
152480
|
const snapshotFiles = readdirSync33(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
151696
152481
|
if (snapshotFiles.length === 0) return [];
|
|
151697
|
-
const paths = snapshotFiles.map((f3) =>
|
|
152482
|
+
const paths = snapshotFiles.map((f3) => join108(snapshotsDir, f3));
|
|
151698
152483
|
const labels = snapshotFiles.map((f3) => {
|
|
151699
152484
|
const m2 = f3.match(/at-([\d.]+)s/);
|
|
151700
152485
|
return m2 ? `${m2[1]}s` : f3;
|
|
@@ -151708,11 +152493,11 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {})
|
|
|
151708
152493
|
);
|
|
151709
152494
|
}
|
|
151710
152495
|
async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
151711
|
-
if (!
|
|
152496
|
+
if (!existsSync103(assetsDir)) return [];
|
|
151712
152497
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
151713
152498
|
const assetFiles = readdirSync33(assetsDir).filter((f3) => imageExts.has(extname19(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
151714
152499
|
if (assetFiles.length === 0) return [];
|
|
151715
|
-
const paths = assetFiles.map((f3) =>
|
|
152500
|
+
const paths = assetFiles.map((f3) => join108(assetsDir, f3));
|
|
151716
152501
|
return createContactSheetPages(paths, outputPath, {
|
|
151717
152502
|
cols: 4,
|
|
151718
152503
|
cellWidth: 480,
|
|
@@ -151723,7 +152508,7 @@ async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
|
151723
152508
|
}
|
|
151724
152509
|
async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget = {}) {
|
|
151725
152510
|
const dirsToScan = [svgsDir, assetsRootDir].filter(
|
|
151726
|
-
(d2) => d2 !== void 0 &&
|
|
152511
|
+
(d2) => d2 !== void 0 && existsSync103(d2)
|
|
151727
152512
|
);
|
|
151728
152513
|
if (dirsToScan.length === 0) return [];
|
|
151729
152514
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -151732,7 +152517,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
151732
152517
|
for (const f3 of readdirSync33(dir).filter((f4) => f4.endsWith(".svg")).sort()) {
|
|
151733
152518
|
if (!seen.has(f3)) {
|
|
151734
152519
|
seen.add(f3);
|
|
151735
|
-
svgPaths.push(
|
|
152520
|
+
svgPaths.push(join108(dir, f3));
|
|
151736
152521
|
}
|
|
151737
152522
|
}
|
|
151738
152523
|
}
|
|
@@ -151745,14 +152530,14 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
151745
152530
|
for (let i2 = 0; i2 < svgPaths.length; i2++) {
|
|
151746
152531
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
151747
152532
|
const svgPath = svgPaths[i2];
|
|
151748
|
-
const tmpPath =
|
|
152533
|
+
const tmpPath = join108(tmpDir, `.thumb-${i2}.png`);
|
|
151749
152534
|
try {
|
|
151750
|
-
const svgBuf =
|
|
152535
|
+
const svgBuf = readFileSync70(svgPath);
|
|
151751
152536
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
151752
152537
|
fit: "contain",
|
|
151753
152538
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
151754
152539
|
}).flatten({ background: { r: 245, g: 245, b: 245 } }).png().toBuffer();
|
|
151755
|
-
|
|
152540
|
+
writeFileSync41(tmpPath, thumb);
|
|
151756
152541
|
tmpPaths.push(tmpPath);
|
|
151757
152542
|
labels.push(svgFileNames[i2].replace(".svg", ""));
|
|
151758
152543
|
} catch {
|
|
@@ -151776,7 +152561,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
151776
152561
|
} finally {
|
|
151777
152562
|
for (const tmp of tmpPaths) {
|
|
151778
152563
|
try {
|
|
151779
|
-
|
|
152564
|
+
unlinkSync10(tmp);
|
|
151780
152565
|
} catch {
|
|
151781
152566
|
}
|
|
151782
152567
|
}
|
|
@@ -159667,7 +160452,7 @@ var require_gaxios = __commonJS({
|
|
|
159667
160452
|
var retry_js_1 = require_retry3();
|
|
159668
160453
|
var stream_1 = __require("stream");
|
|
159669
160454
|
var interceptor_js_1 = require_interceptor();
|
|
159670
|
-
var
|
|
160455
|
+
var randomUUID13 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
159671
160456
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
159672
160457
|
var Gaxios = class {
|
|
159673
160458
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -159940,7 +160725,7 @@ var require_gaxios = __commonJS({
|
|
|
159940
160725
|
*/
|
|
159941
160726
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
159942
160727
|
if (opts.multipart?.length) {
|
|
159943
|
-
const boundary = await
|
|
160728
|
+
const boundary = await randomUUID13();
|
|
159944
160729
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
159945
160730
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
159946
160731
|
} else if (shouldDirectlyPassData) {
|
|
@@ -171752,7 +172537,7 @@ var require_websocket = __commonJS({
|
|
|
171752
172537
|
var http4 = __require("http");
|
|
171753
172538
|
var net2 = __require("net");
|
|
171754
172539
|
var tls = __require("tls");
|
|
171755
|
-
var { randomBytes: randomBytes4, createHash:
|
|
172540
|
+
var { randomBytes: randomBytes4, createHash: createHash23 } = __require("crypto");
|
|
171756
172541
|
var { Duplex, Readable: Readable5 } = __require("stream");
|
|
171757
172542
|
var { URL: URL2 } = __require("url");
|
|
171758
172543
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -172412,7 +173197,7 @@ var require_websocket = __commonJS({
|
|
|
172412
173197
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
172413
173198
|
return;
|
|
172414
173199
|
}
|
|
172415
|
-
const digest =
|
|
173200
|
+
const digest = createHash23("sha1").update(key2 + GUID).digest("base64");
|
|
172416
173201
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
172417
173202
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
172418
173203
|
return;
|
|
@@ -172779,7 +173564,7 @@ var require_websocket_server = __commonJS({
|
|
|
172779
173564
|
var EventEmitter = __require("events");
|
|
172780
173565
|
var http4 = __require("http");
|
|
172781
173566
|
var { Duplex } = __require("stream");
|
|
172782
|
-
var { createHash:
|
|
173567
|
+
var { createHash: createHash23 } = __require("crypto");
|
|
172783
173568
|
var extension2 = require_extension();
|
|
172784
173569
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
172785
173570
|
var subprotocol2 = require_subprotocol();
|
|
@@ -173080,7 +173865,7 @@ var require_websocket_server = __commonJS({
|
|
|
173080
173865
|
);
|
|
173081
173866
|
}
|
|
173082
173867
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
173083
|
-
const digest =
|
|
173868
|
+
const digest = createHash23("sha1").update(key2 + GUID).digest("base64");
|
|
173084
173869
|
const headers = [
|
|
173085
173870
|
"HTTP/1.1 101 Switching Protocols",
|
|
173086
173871
|
"Upgrade: websocket",
|
|
@@ -191532,9 +192317,9 @@ __export(snapshot_exports, {
|
|
|
191532
192317
|
resolveSnapshotVideoFrameTime: () => resolveSnapshotVideoFrameTime,
|
|
191533
192318
|
tailFrameTime: () => tailFrameTime
|
|
191534
192319
|
});
|
|
191535
|
-
import { existsSync as
|
|
192320
|
+
import { existsSync as existsSync104, mkdtempSync as mkdtempSync15, readFileSync as readFileSync71, mkdirSync as mkdirSync51, rmSync as rmSync30, writeFileSync as writeFileSync43 } from "fs";
|
|
191536
192321
|
import { tmpdir as tmpdir15 } from "os";
|
|
191537
|
-
import { resolve as resolve67, join as
|
|
192322
|
+
import { resolve as resolve67, join as join109, relative as relative24, isAbsolute as isAbsolute15, basename as basename25 } from "path";
|
|
191538
192323
|
function orbitStageSource() {
|
|
191539
192324
|
return `function(cam) {
|
|
191540
192325
|
var root = document.querySelector("[data-composition-id]")
|
|
@@ -191580,8 +192365,8 @@ function requireSnapshotFfmpeg(ffmpegPath) {
|
|
|
191580
192365
|
);
|
|
191581
192366
|
}
|
|
191582
192367
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
191583
|
-
const tmp = mkdtempSync15(
|
|
191584
|
-
const outPath =
|
|
192368
|
+
const tmp = mkdtempSync15(join109(tmpdir15(), "hf-snapshot-frame-"));
|
|
192369
|
+
const outPath = join109(tmp, "frame.png");
|
|
191585
192370
|
try {
|
|
191586
192371
|
const ffmpegPath = requireSnapshotFfmpeg(findFFmpeg());
|
|
191587
192372
|
const args = ["-hide_banner", "-loglevel", "error"];
|
|
@@ -191601,8 +192386,8 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
191601
192386
|
outPath
|
|
191602
192387
|
);
|
|
191603
192388
|
const result = await runFfmpegOnce(ffmpegPath, args, FFMPEG_EXTRACT_TIMEOUT_MS);
|
|
191604
|
-
if (result.code !== 0 || result.timedOut || !
|
|
191605
|
-
return
|
|
192389
|
+
if (result.code !== 0 || result.timedOut || !existsSync104(outPath)) return null;
|
|
192390
|
+
return readFileSync71(outPath);
|
|
191606
192391
|
} finally {
|
|
191607
192392
|
try {
|
|
191608
192393
|
rmSync30(tmp, { recursive: true, force: true });
|
|
@@ -191694,13 +192479,13 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
191694
192479
|
);
|
|
191695
192480
|
}
|
|
191696
192481
|
const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
|
|
191697
|
-
const snapshotDir = opts.outputDir ??
|
|
191698
|
-
|
|
192482
|
+
const snapshotDir = opts.outputDir ?? join109(projectDir, "snapshots");
|
|
192483
|
+
mkdirSync51(snapshotDir, { recursive: true });
|
|
191699
192484
|
try {
|
|
191700
192485
|
const { readdirSync: readdirSync39 } = await import("fs");
|
|
191701
192486
|
for (const file of readdirSync39(snapshotDir)) {
|
|
191702
192487
|
if (/\.(png|jpg|jpeg)$/i.test(file)) {
|
|
191703
|
-
rmSync30(
|
|
192488
|
+
rmSync30(join109(snapshotDir, file), { force: true });
|
|
191704
192489
|
}
|
|
191705
192490
|
}
|
|
191706
192491
|
} catch {
|
|
@@ -191786,7 +192571,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
191786
192571
|
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
|
191787
192572
|
const candidate = resolve67(projectDir, decodedPath);
|
|
191788
192573
|
const rel2 = relative24(projectDir, candidate);
|
|
191789
|
-
if (!rel2.startsWith("..") && !isAbsolute15(rel2) &&
|
|
192574
|
+
if (!rel2.startsWith("..") && !isAbsolute15(rel2) && existsSync104(candidate)) {
|
|
191790
192575
|
ffmpegInput = candidate;
|
|
191791
192576
|
inputIsLocal = true;
|
|
191792
192577
|
} else if (url.protocol === "http:" || url.protocol === "https:") {
|
|
@@ -191829,7 +192614,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
191829
192614
|
}
|
|
191830
192615
|
const timeLabel = formatSnapshotTimestamp(time);
|
|
191831
192616
|
const filename = `frame-${String(i2).padStart(2, "0")}-at-${timeLabel}.png`;
|
|
191832
|
-
const framePath =
|
|
192617
|
+
const framePath = join109(snapshotDir, filename);
|
|
191833
192618
|
if (opts.zoom) {
|
|
191834
192619
|
const canvas = await page.evaluate(() => ({
|
|
191835
192620
|
width: window.innerWidth,
|
|
@@ -191847,7 +192632,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
191847
192632
|
region,
|
|
191848
192633
|
opts.zoomScale ?? DEFAULT_ZOOM_SCALE
|
|
191849
192634
|
);
|
|
191850
|
-
|
|
192635
|
+
writeFileSync43(framePath, buffer);
|
|
191851
192636
|
} else {
|
|
191852
192637
|
await page.screenshot({ path: framePath, type: "png", omitBackground: true });
|
|
191853
192638
|
}
|
|
@@ -191963,7 +192748,7 @@ var init_snapshot = __esm({
|
|
|
191963
192748
|
const angleLabel = camera && (camera.yaw !== 0 || camera.pitch !== 0) ? ` ${c.dim(`(angle yaw ${camera.yaw}\xB0 pitch ${camera.pitch}\xB0)`)}` : "";
|
|
191964
192749
|
console.log(`${c.accent("\u25C6")} Capturing ${label2} from ${c.accent(project.name)}${angleLabel}`);
|
|
191965
192750
|
try {
|
|
191966
|
-
const snapshotDir = args.output ? resolve67(String(args.output)) :
|
|
192751
|
+
const snapshotDir = args.output ? resolve67(String(args.output)) : join109(project.dir, "snapshots");
|
|
191967
192752
|
const paths = await captureSnapshots(project.dir, {
|
|
191968
192753
|
frames,
|
|
191969
192754
|
timeout,
|
|
@@ -191994,7 +192779,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
191994
192779
|
const { createSnapshotContactSheet: createSnapshotContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
191995
192780
|
const sheets = await createSnapshotContactSheet2(
|
|
191996
192781
|
snapshotDir,
|
|
191997
|
-
|
|
192782
|
+
join109(snapshotDir, "contact-sheet.jpg")
|
|
191998
192783
|
);
|
|
191999
192784
|
if (sheets.length > 0) {
|
|
192000
192785
|
const label3 = sheets.length === 1 ? "contact-sheet.jpg" : `contact-sheet-1..${sheets.length}.jpg`;
|
|
@@ -192030,9 +192815,9 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
192030
192815
|
const results = await Promise.allSettled(
|
|
192031
192816
|
paths.map(async (p2) => {
|
|
192032
192817
|
const filename = basename25(p2);
|
|
192033
|
-
const filePath =
|
|
192034
|
-
if (!
|
|
192035
|
-
const raw =
|
|
192818
|
+
const filePath = join109(snapshotDir, filename);
|
|
192819
|
+
if (!existsSync104(filePath)) return { filename, desc: "file not found" };
|
|
192820
|
+
const raw = readFileSync71(filePath);
|
|
192036
192821
|
let imageData;
|
|
192037
192822
|
let mimeType = "image/png";
|
|
192038
192823
|
if (sharpFn) {
|
|
@@ -192068,8 +192853,8 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
192068
192853
|
descriptions.push(`## (error)`, `Gemini call failed: ${errMsg.slice(0, 120)}`, ``);
|
|
192069
192854
|
}
|
|
192070
192855
|
}
|
|
192071
|
-
const descPath =
|
|
192072
|
-
|
|
192856
|
+
const descPath = join109(snapshotDir, "descriptions.md");
|
|
192857
|
+
writeFileSync43(descPath, descriptions.join("\n"));
|
|
192073
192858
|
console.log(` ${c.dim("descriptions.md")} (Gemini frame analysis)`);
|
|
192074
192859
|
}
|
|
192075
192860
|
} catch (descErr) {
|
|
@@ -192401,8 +193186,8 @@ __export(media_treatment_exports, {
|
|
|
192401
193186
|
mediaTreatmentCommand: () => mediaTreatmentCommand,
|
|
192402
193187
|
resolveMediaTreatmentSource: () => resolveMediaTreatmentSource
|
|
192403
193188
|
});
|
|
192404
|
-
import { existsSync as
|
|
192405
|
-
import { join as
|
|
193189
|
+
import { existsSync as existsSync105, readFileSync as readFileSync73, writeFileSync as writeFileSync44 } from "fs";
|
|
193190
|
+
import { join as join110, relative as relative26, resolve as resolve69 } from "path";
|
|
192406
193191
|
function getMediaTreatmentCapabilityOverview() {
|
|
192407
193192
|
const capabilities = getHfColorGradingCapabilities();
|
|
192408
193193
|
const family = (id, label2, description) => ({
|
|
@@ -192780,7 +193565,7 @@ function resolveMediaTreatmentSource(projectDir, compositionFile, source) {
|
|
|
192780
193565
|
}
|
|
192781
193566
|
const cleanSource = cleanAssetUrl(sourceUrl);
|
|
192782
193567
|
if (!cleanSource) throw new Error("Selected media has no analyzable local src");
|
|
192783
|
-
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path2) =>
|
|
193568
|
+
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path2) => existsSync105(join110(projectDir, path2)));
|
|
192784
193569
|
const asset = resolveExistingLocalAsset(projectDir, projectRelative);
|
|
192785
193570
|
if (!asset) throw new Error(`Media file not found: ${source}`);
|
|
192786
193571
|
return asset.resolved;
|
|
@@ -192833,7 +193618,7 @@ function resolveMutationFile(args) {
|
|
|
192833
193618
|
if (!isPathInside(filePath, project.dir) || !filePath.toLowerCase().endsWith(".html")) {
|
|
192834
193619
|
throw new Error("--file must be an HTML file inside the project");
|
|
192835
193620
|
}
|
|
192836
|
-
if (!
|
|
193621
|
+
if (!existsSync105(filePath)) throw new Error(`Composition file not found: ${fileArg}`);
|
|
192837
193622
|
return { project, filePath };
|
|
192838
193623
|
}
|
|
192839
193624
|
function analyzeTarget(args) {
|
|
@@ -192845,7 +193630,7 @@ function analyzeTarget(args) {
|
|
|
192845
193630
|
}
|
|
192846
193631
|
const selectorIndex = parseSelectorIndex(readOptionalString(args["selector-index"]));
|
|
192847
193632
|
const { element, tag } = selectMediaElement(
|
|
192848
|
-
|
|
193633
|
+
readFileSync73(filePath, "utf8"),
|
|
192849
193634
|
selector,
|
|
192850
193635
|
selectorIndex
|
|
192851
193636
|
);
|
|
@@ -192870,14 +193655,14 @@ function prepareMutation(args) {
|
|
|
192870
193655
|
const clear = args.clear === true;
|
|
192871
193656
|
const apply = args.apply === true;
|
|
192872
193657
|
const selectorIndex = parseSelectorIndex(readOptionalString(args["selector-index"]));
|
|
192873
|
-
const result = applyMediaTreatmentToHtml(
|
|
193658
|
+
const result = applyMediaTreatmentToHtml(readFileSync73(filePath, "utf8"), {
|
|
192874
193659
|
selector,
|
|
192875
193660
|
selectorIndex,
|
|
192876
193661
|
grading: parseGrading(readOptionalString(args.grading), apply, clear),
|
|
192877
193662
|
clear
|
|
192878
193663
|
});
|
|
192879
193664
|
const dryRun = args["dry-run"] === true;
|
|
192880
|
-
if (result.changed && !dryRun)
|
|
193665
|
+
if (result.changed && !dryRun) writeFileSync44(filePath, result.html);
|
|
192881
193666
|
const action = result.value === null ? "clear" : "apply";
|
|
192882
193667
|
return {
|
|
192883
193668
|
action,
|
|
@@ -193056,15 +193841,15 @@ __export(grade_compare_exports, {
|
|
|
193056
193841
|
});
|
|
193057
193842
|
import {
|
|
193058
193843
|
copyFileSync as copyFileSync10,
|
|
193059
|
-
existsSync as
|
|
193060
|
-
mkdirSync as
|
|
193844
|
+
existsSync as existsSync106,
|
|
193845
|
+
mkdirSync as mkdirSync53,
|
|
193061
193846
|
mkdtempSync as mkdtempSync16,
|
|
193062
|
-
readFileSync as
|
|
193847
|
+
readFileSync as readFileSync74,
|
|
193063
193848
|
rmSync as rmSync31,
|
|
193064
|
-
writeFileSync as
|
|
193849
|
+
writeFileSync as writeFileSync45
|
|
193065
193850
|
} from "fs";
|
|
193066
193851
|
import { tmpdir as tmpdir16 } from "os";
|
|
193067
|
-
import { basename as basename27, dirname as dirname54, extname as extname21, join as
|
|
193852
|
+
import { basename as basename27, dirname as dirname54, extname as extname21, join as join111, resolve as resolve70 } from "path";
|
|
193068
193853
|
import sharp2 from "sharp";
|
|
193069
193854
|
function isRecord13(value) {
|
|
193070
193855
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -193150,12 +193935,12 @@ function rewriteGradingLutSrc(grading, src) {
|
|
|
193150
193935
|
return next;
|
|
193151
193936
|
}
|
|
193152
193937
|
function parseGradesFile(filePath) {
|
|
193153
|
-
if (!
|
|
193938
|
+
if (!existsSync106(filePath)) {
|
|
193154
193939
|
throw new Error(`Grades file not found: ${filePath}`);
|
|
193155
193940
|
}
|
|
193156
193941
|
let parsed;
|
|
193157
193942
|
try {
|
|
193158
|
-
parsed = JSON.parse(
|
|
193943
|
+
parsed = JSON.parse(readFileSync74(filePath, "utf-8"));
|
|
193159
193944
|
} catch (err) {
|
|
193160
193945
|
throw new Error(`Could not parse grades JSON: ${normalizeErrorMessage(err)}`);
|
|
193161
193946
|
}
|
|
@@ -193320,19 +194105,19 @@ function frameFileNameForPath(framePath) {
|
|
|
193320
194105
|
return "frame.png";
|
|
193321
194106
|
}
|
|
193322
194107
|
async function prepareGradeCompareTempProject(opts) {
|
|
193323
|
-
const tempDir = mkdtempSync16(
|
|
194108
|
+
const tempDir = mkdtempSync16(join111(tmpdir16(), "hf-grade-compare-"));
|
|
193324
194109
|
try {
|
|
193325
194110
|
const frameFileName2 = opts.frameFileName ?? frameFileNameForPath(opts.framePath);
|
|
193326
|
-
|
|
194111
|
+
writeFileSync45(join111(tempDir, frameFileName2), opts.frameBuffer);
|
|
193327
194112
|
let lutIndex = 0;
|
|
193328
194113
|
const stagedCells = opts.cells.map((cell) => {
|
|
193329
194114
|
const lutSrc = lutSrcFromGrading(cell.grading);
|
|
193330
194115
|
if (!lutSrc) return cell;
|
|
193331
194116
|
const sourcePath = resolveFromBase(opts.projectDir, lutSrc);
|
|
193332
|
-
if (!
|
|
194117
|
+
if (!existsSync106(sourcePath)) {
|
|
193333
194118
|
throw new Error(`LUT file not found for "${cell.label}": ${sourcePath}`);
|
|
193334
194119
|
}
|
|
193335
|
-
const lutText =
|
|
194120
|
+
const lutText = readFileSync74(sourcePath, "utf-8");
|
|
193336
194121
|
try {
|
|
193337
194122
|
parseCubeLut(lutText, { maxSize: 64 });
|
|
193338
194123
|
} catch (err) {
|
|
@@ -193343,7 +194128,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
193343
194128
|
const lutExt = extname21(sourcePath) || ".cube";
|
|
193344
194129
|
const stagedName = `lut-${lutIndex}${lutExt}`;
|
|
193345
194130
|
lutIndex += 1;
|
|
193346
|
-
copyFileSync10(sourcePath,
|
|
194131
|
+
copyFileSync10(sourcePath, join111(tempDir, stagedName));
|
|
193347
194132
|
return {
|
|
193348
194133
|
label: cell.label,
|
|
193349
194134
|
grading: rewriteGradingLutSrc(cell.grading, stagedName)
|
|
@@ -193355,7 +194140,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
193355
194140
|
frameWidth: opts.frameWidth,
|
|
193356
194141
|
frameHeight: opts.frameHeight
|
|
193357
194142
|
});
|
|
193358
|
-
|
|
194143
|
+
writeFileSync45(join111(tempDir, "index.html"), html);
|
|
193359
194144
|
return { tempDir, html, cells: stagedCells };
|
|
193360
194145
|
} catch (err) {
|
|
193361
194146
|
rmSync31(tempDir, { recursive: true, force: true });
|
|
@@ -193367,8 +194152,8 @@ function isVideoPath2(filePath) {
|
|
|
193367
194152
|
return [".mp4", ".mov", ".m4v", ".webm", ".mkv", ".avi", ".mpeg", ".mpg", ".ogv"].includes(ext);
|
|
193368
194153
|
}
|
|
193369
194154
|
async function extractVideoFrameToBuffer2(videoPath) {
|
|
193370
|
-
const tmp = mkdtempSync16(
|
|
193371
|
-
const outPath =
|
|
194155
|
+
const tmp = mkdtempSync16(join111(tmpdir16(), "hf-grade-compare-frame-"));
|
|
194156
|
+
const outPath = join111(tmp, "frame.png");
|
|
193372
194157
|
try {
|
|
193373
194158
|
const ffmpegPath = findFFmpeg();
|
|
193374
194159
|
if (!ffmpegPath) return null;
|
|
@@ -193391,20 +194176,20 @@ async function extractVideoFrameToBuffer2(videoPath) {
|
|
|
193391
194176
|
if (result.timedOut) {
|
|
193392
194177
|
throw new Error(`ffmpeg timed out extracting first frame from ${videoPath}`);
|
|
193393
194178
|
}
|
|
193394
|
-
if (result.code !== 0 || !
|
|
194179
|
+
if (result.code !== 0 || !existsSync106(outPath)) {
|
|
193395
194180
|
const detail = result.stderr.trim() ? `: ${result.stderr.trim()}` : "";
|
|
193396
194181
|
throw new Error(`ffmpeg could not extract first frame from ${videoPath}${detail}`);
|
|
193397
194182
|
}
|
|
193398
|
-
return
|
|
194183
|
+
return readFileSync74(outPath);
|
|
193399
194184
|
} finally {
|
|
193400
194185
|
rmSync31(tmp, { recursive: true, force: true });
|
|
193401
194186
|
}
|
|
193402
194187
|
}
|
|
193403
194188
|
async function loadReferenceFrame(framePath) {
|
|
193404
|
-
if (!
|
|
194189
|
+
if (!existsSync106(framePath)) {
|
|
193405
194190
|
throw new Error(`Reference frame not found: ${framePath}`);
|
|
193406
194191
|
}
|
|
193407
|
-
const buffer = isVideoPath2(framePath) ? await extractVideoFrameToBuffer2(framePath) :
|
|
194192
|
+
const buffer = isVideoPath2(framePath) ? await extractVideoFrameToBuffer2(framePath) : readFileSync74(framePath);
|
|
193408
194193
|
if (!buffer) {
|
|
193409
194194
|
throw new Error(`Could not extract a frame from video: ${framePath}`);
|
|
193410
194195
|
}
|
|
@@ -193423,7 +194208,7 @@ async function captureGradeCompareSheet(projectDir, timeoutMs) {
|
|
|
193423
194208
|
const { bundleToSingleHtml: bundleToSingleHtml2 } = await Promise.resolve().then(() => (init_compiler(), compiler_exports));
|
|
193424
194209
|
const html = await bundleToSingleHtml2(projectDir);
|
|
193425
194210
|
const server = await serveStaticProjectHtml(projectDir, html);
|
|
193426
|
-
const sheetPath =
|
|
194211
|
+
const sheetPath = join111(projectDir, "grade-compare.png");
|
|
193427
194212
|
try {
|
|
193428
194213
|
const {
|
|
193429
194214
|
browser: chromeBrowser,
|
|
@@ -193564,7 +194349,7 @@ var init_grade_compare = __esm({
|
|
|
193564
194349
|
prepared.tempDir,
|
|
193565
194350
|
parsed.timeoutMs
|
|
193566
194351
|
);
|
|
193567
|
-
|
|
194352
|
+
mkdirSync53(dirname54(parsed.outPath), { recursive: true });
|
|
193568
194353
|
copyFileSync10(tempSheet, parsed.outPath);
|
|
193569
194354
|
trackCompareSheet({
|
|
193570
194355
|
command: "grade-compare",
|
|
@@ -193609,9 +194394,9 @@ __export(compare_exports, {
|
|
|
193609
194394
|
parseCompareArgs: () => parseCompareArgs,
|
|
193610
194395
|
prepareCompareVariantProjects: () => prepareCompareVariantProjects
|
|
193611
194396
|
});
|
|
193612
|
-
import { cpSync as cpSync6, existsSync as
|
|
194397
|
+
import { cpSync as cpSync6, existsSync as existsSync107, mkdirSync as mkdirSync54, mkdtempSync as mkdtempSync17, renameSync as renameSync15, rmSync as rmSync33, statSync as statSync36 } from "fs";
|
|
193613
194398
|
import { tmpdir as tmpdir17 } from "os";
|
|
193614
|
-
import { basename as basename28, dirname as dirname55, extname as extname23, join as
|
|
194399
|
+
import { basename as basename28, dirname as dirname55, extname as extname23, join as join113 } from "path";
|
|
193615
194400
|
function defaultLabelForPath(input2) {
|
|
193616
194401
|
const name = basename28(input2);
|
|
193617
194402
|
return extname23(name).toLowerCase() === ".html" ? basename28(name, extname23(name)) : name;
|
|
@@ -193710,7 +194495,7 @@ function inputError(variant) {
|
|
|
193710
194495
|
);
|
|
193711
194496
|
}
|
|
193712
194497
|
function stageHtmlVariant(variant) {
|
|
193713
|
-
const stagedDir = mkdtempSync17(
|
|
194498
|
+
const stagedDir = mkdtempSync17(join113(tmpdir17(), "hf-compare-variant-"));
|
|
193714
194499
|
try {
|
|
193715
194500
|
cpSync6(dirname55(variant.inputPath), stagedDir, {
|
|
193716
194501
|
recursive: true,
|
|
@@ -193721,7 +194506,7 @@ function stageHtmlVariant(variant) {
|
|
|
193721
194506
|
});
|
|
193722
194507
|
const sourceName = basename28(variant.inputPath);
|
|
193723
194508
|
if (sourceName !== "index.html") {
|
|
193724
|
-
renameSync15(
|
|
194509
|
+
renameSync15(join113(stagedDir, sourceName), join113(stagedDir, "index.html"));
|
|
193725
194510
|
}
|
|
193726
194511
|
return {
|
|
193727
194512
|
...variant,
|
|
@@ -193737,11 +194522,11 @@ function prepareCompareVariantProjects(variants) {
|
|
|
193737
194522
|
const prepared = [];
|
|
193738
194523
|
try {
|
|
193739
194524
|
for (const variant of variants) {
|
|
193740
|
-
if (!
|
|
194525
|
+
if (!existsSync107(variant.inputPath)) {
|
|
193741
194526
|
throw inputError(variant);
|
|
193742
194527
|
}
|
|
193743
194528
|
const stat3 = statSync36(variant.inputPath);
|
|
193744
|
-
if (stat3.isDirectory() &&
|
|
194529
|
+
if (stat3.isDirectory() && existsSync107(join113(variant.inputPath, "index.html"))) {
|
|
193745
194530
|
prepared.push({
|
|
193746
194531
|
...variant,
|
|
193747
194532
|
projectDir: variant.inputPath
|
|
@@ -193807,13 +194592,13 @@ async function renderCompareSheet(parsed) {
|
|
|
193807
194592
|
const capResult = capCompareVariants(parsed.variants);
|
|
193808
194593
|
const variants = capResult.variants;
|
|
193809
194594
|
const prepared = prepareCompareVariantProjects(variants);
|
|
193810
|
-
const frameDir = mkdtempSync17(
|
|
194595
|
+
const frameDir = mkdtempSync17(join113(tmpdir17(), "hf-compare-frames-"));
|
|
193811
194596
|
const framePaths = [];
|
|
193812
194597
|
try {
|
|
193813
194598
|
let renderReadyTimedOut = false;
|
|
193814
194599
|
for (let i2 = 0; i2 < prepared.length; i2++) {
|
|
193815
194600
|
const variant = prepared[i2];
|
|
193816
|
-
const framePath =
|
|
194601
|
+
const framePath = join113(frameDir, `variant-${String(i2 + 1).padStart(2, "0")}.png`);
|
|
193817
194602
|
const rendered = await renderCompareVariant(variant, {
|
|
193818
194603
|
atSeconds: parsed.atSeconds,
|
|
193819
194604
|
framePath,
|
|
@@ -193822,7 +194607,7 @@ async function renderCompareSheet(parsed) {
|
|
|
193822
194607
|
framePaths.push(rendered.framePath);
|
|
193823
194608
|
renderReadyTimedOut = renderReadyTimedOut || rendered.renderReadyTimedOut;
|
|
193824
194609
|
}
|
|
193825
|
-
|
|
194610
|
+
mkdirSync54(dirname55(parsed.outPath), { recursive: true });
|
|
193826
194611
|
await createContactSheet(framePaths, parsed.outPath, {
|
|
193827
194612
|
cols: parsed.cols ?? defaultCompareCols(framePaths.length),
|
|
193828
194613
|
maxImages: framePaths.length,
|
|
@@ -193941,11 +194726,11 @@ ${c.error("\u2717")} Compare failed: ${message}`);
|
|
|
193941
194726
|
});
|
|
193942
194727
|
|
|
193943
194728
|
// src/capture/assetDownloader.ts
|
|
193944
|
-
import { writeFileSync as
|
|
193945
|
-
import { join as
|
|
193946
|
-
import { createHash as
|
|
194729
|
+
import { writeFileSync as writeFileSync46, mkdirSync as mkdirSync55 } from "fs";
|
|
194730
|
+
import { join as join114, extname as extname24 } from "path";
|
|
194731
|
+
import { createHash as createHash20 } from "crypto";
|
|
193947
194732
|
function svgContentHashSlug(svgSource, isLogo) {
|
|
193948
|
-
const hash2 =
|
|
194733
|
+
const hash2 = createHash20("sha1").update(svgSource).digest("hex").slice(0, 8);
|
|
193949
194734
|
return isLogo ? `logo-${hash2}` : `svg-${hash2}`;
|
|
193950
194735
|
}
|
|
193951
194736
|
function toStandaloneSvg(outerHTML) {
|
|
@@ -193963,11 +194748,11 @@ function toStandaloneSvg(outerHTML) {
|
|
|
193963
194748
|
return outerHTML.replace(original, tag);
|
|
193964
194749
|
}
|
|
193965
194750
|
async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks, options = {}) {
|
|
193966
|
-
const assetsDir =
|
|
193967
|
-
|
|
194751
|
+
const assetsDir = join114(outputDir, "assets");
|
|
194752
|
+
mkdirSync55(assetsDir, { recursive: true });
|
|
193968
194753
|
const assets = [];
|
|
193969
194754
|
const downloadedUrls = /* @__PURE__ */ new Set();
|
|
193970
|
-
|
|
194755
|
+
mkdirSync55(join114(outputDir, "assets", "svgs"), { recursive: true });
|
|
193971
194756
|
const usedSvgNames = /* @__PURE__ */ new Set();
|
|
193972
194757
|
for (let i2 = 0; i2 < tokens.svgs.length && i2 < 30; i2++) {
|
|
193973
194758
|
const svg = tokens.svgs[i2];
|
|
@@ -193984,7 +194769,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
193984
194769
|
const name = `${finalSlug}.svg`;
|
|
193985
194770
|
const localPath = `assets/svgs/${name}`;
|
|
193986
194771
|
try {
|
|
193987
|
-
|
|
194772
|
+
writeFileSync46(join114(outputDir, localPath), svgFile, "utf-8");
|
|
193988
194773
|
assets.push({ url: "", localPath, type: "svg" });
|
|
193989
194774
|
} catch {
|
|
193990
194775
|
}
|
|
@@ -193999,7 +194784,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
193999
194784
|
const localPath = `assets/${name}`;
|
|
194000
194785
|
const buffer = await fetchBuffer(icon.href, Math.min(1e4, remainingMs));
|
|
194001
194786
|
if (buffer) {
|
|
194002
|
-
|
|
194787
|
+
writeFileSync46(join114(outputDir, localPath), buffer);
|
|
194003
194788
|
assets.push({ url: icon.href, localPath, type: "favicon" });
|
|
194004
194789
|
break;
|
|
194005
194790
|
}
|
|
@@ -194066,7 +194851,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
194066
194851
|
const name = `${slug}${ext}`;
|
|
194067
194852
|
usedNames.add(slug);
|
|
194068
194853
|
const localPath = `assets/${name}`;
|
|
194069
|
-
|
|
194854
|
+
writeFileSync46(join114(outputDir, localPath), buffer);
|
|
194070
194855
|
assets.push({ url, localPath, type: "image" });
|
|
194071
194856
|
imgIdx++;
|
|
194072
194857
|
} catch {
|
|
@@ -194080,7 +194865,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
194080
194865
|
const localPath = `assets/og-image${ext}`;
|
|
194081
194866
|
const buffer = remainingMs > 0 ? await fetchBuffer(tokens.ogImage, Math.min(1e4, remainingMs)) : null;
|
|
194082
194867
|
if (buffer && buffer.length > 5e3) {
|
|
194083
|
-
|
|
194868
|
+
writeFileSync46(join114(outputDir, localPath), buffer);
|
|
194084
194869
|
assets.push({ url: tokens.ogImage, localPath, type: "image" });
|
|
194085
194870
|
}
|
|
194086
194871
|
} catch {
|
|
@@ -194103,8 +194888,8 @@ function normalizeUrl(u) {
|
|
|
194103
194888
|
}
|
|
194104
194889
|
}
|
|
194105
194890
|
async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
194106
|
-
const assetsDir =
|
|
194107
|
-
|
|
194891
|
+
const assetsDir = join114(outputDir, "assets", "fonts");
|
|
194892
|
+
mkdirSync55(assetsDir, { recursive: true });
|
|
194108
194893
|
const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
|
|
194109
194894
|
const fontUrls = /* @__PURE__ */ new Set();
|
|
194110
194895
|
let match;
|
|
@@ -194143,11 +194928,11 @@ async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
|
194143
194928
|
try {
|
|
194144
194929
|
const urlObj = new URL(fontUrl);
|
|
194145
194930
|
const filename = urlObj.pathname.split("/").pop() || `font-${count}.woff2`;
|
|
194146
|
-
const localPath =
|
|
194931
|
+
const localPath = join114(assetsDir, filename);
|
|
194147
194932
|
const relativePath = `assets/fonts/${filename}`;
|
|
194148
194933
|
const buffer = await fetchBuffer(fontUrl, Math.min(1e4, remainingMs));
|
|
194149
194934
|
if (buffer) {
|
|
194150
|
-
|
|
194935
|
+
writeFileSync46(localPath, buffer);
|
|
194151
194936
|
rewritten = rewritten.split(fontUrl).join(relativePath);
|
|
194152
194937
|
}
|
|
194153
194938
|
} catch {
|
|
@@ -194299,8 +195084,8 @@ __export(video_exports, {
|
|
|
194299
195084
|
runVideoMode: () => runVideoMode,
|
|
194300
195085
|
safeFilename: () => safeFilename
|
|
194301
195086
|
});
|
|
194302
|
-
import { createWriteStream as createWriteStream4, existsSync as
|
|
194303
|
-
import { resolve as resolve71, join as
|
|
195087
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync108, mkdirSync as mkdirSync56, readFileSync as readFileSync75, unlinkSync as unlinkSync11 } from "fs";
|
|
195088
|
+
import { resolve as resolve71, join as join115, basename as basename29 } from "path";
|
|
194304
195089
|
async function streamToFile(url, destPath) {
|
|
194305
195090
|
const r2 = await safeFetch(url, {
|
|
194306
195091
|
signal: AbortSignal.timeout(12e4),
|
|
@@ -194362,7 +195147,7 @@ async function streamToFile(url, destPath) {
|
|
|
194362
195147
|
file.destroy();
|
|
194363
195148
|
if (e3.code !== "EEXIST") {
|
|
194364
195149
|
try {
|
|
194365
|
-
|
|
195150
|
+
unlinkSync11(destPath);
|
|
194366
195151
|
} catch {
|
|
194367
195152
|
}
|
|
194368
195153
|
}
|
|
@@ -194419,11 +195204,11 @@ function pickManifestEntry(manifest, args) {
|
|
|
194419
195204
|
}
|
|
194420
195205
|
async function runVideoMode(args) {
|
|
194421
195206
|
const projectDir = resolve71(args.project);
|
|
194422
|
-
const directPath =
|
|
194423
|
-
const w2hPath =
|
|
194424
|
-
const manifestPath2 =
|
|
195207
|
+
const directPath = join115(projectDir, "extracted", "video-manifest.json");
|
|
195208
|
+
const w2hPath = join115(projectDir, "capture", "extracted", "video-manifest.json");
|
|
195209
|
+
const manifestPath2 = existsSync108(directPath) ? directPath : w2hPath;
|
|
194425
195210
|
const isW2hLayout = manifestPath2 === w2hPath;
|
|
194426
|
-
if (!
|
|
195211
|
+
if (!existsSync108(manifestPath2)) {
|
|
194427
195212
|
console.error(
|
|
194428
195213
|
`${c.error("\u2717")} no video-manifest.json at ${directPath} or ${w2hPath}
|
|
194429
195214
|
Was this directory produced by \`hyperframes capture\`?`
|
|
@@ -194433,7 +195218,7 @@ async function runVideoMode(args) {
|
|
|
194433
195218
|
}
|
|
194434
195219
|
let manifest;
|
|
194435
195220
|
try {
|
|
194436
|
-
manifest = JSON.parse(
|
|
195221
|
+
manifest = JSON.parse(readFileSync75(manifestPath2, "utf-8"));
|
|
194437
195222
|
} catch (e3) {
|
|
194438
195223
|
console.error(`${c.error("\u2717")} video-manifest.json is malformed: ${e3.message}`);
|
|
194439
195224
|
setCommandExitCode(1);
|
|
@@ -194474,10 +195259,10 @@ async function runVideoMode(args) {
|
|
|
194474
195259
|
setCommandExitCode(1);
|
|
194475
195260
|
return;
|
|
194476
195261
|
}
|
|
194477
|
-
const outDir = isW2hLayout ?
|
|
194478
|
-
|
|
195262
|
+
const outDir = isW2hLayout ? join115(projectDir, "capture", "assets", "videos") : join115(projectDir, "assets", "videos");
|
|
195263
|
+
mkdirSync56(outDir, { recursive: true });
|
|
194479
195264
|
const fname = safeFilename(entry.filename || basename29(entry.url));
|
|
194480
|
-
const outPath =
|
|
195265
|
+
const outPath = join115(outDir, fname);
|
|
194481
195266
|
const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
|
|
194482
195267
|
console.log(
|
|
194483
195268
|
`${c.accent("\u25B8")} downloading [${entry.index}] ${entry.filename} (${entry.sourceWidth || entry.width}\xD7${entry.sourceHeight || entry.height})`
|
|
@@ -195721,8 +196506,8 @@ var init_designStyleExtractor = __esm({
|
|
|
195721
196506
|
});
|
|
195722
196507
|
|
|
195723
196508
|
// src/capture/fontMetadataExtractor.ts
|
|
195724
|
-
import { readdirSync as readdirSync34, readFileSync as
|
|
195725
|
-
import { join as
|
|
196509
|
+
import { readdirSync as readdirSync34, readFileSync as readFileSync76, writeFileSync as writeFileSync47, existsSync as existsSync109 } from "fs";
|
|
196510
|
+
import { join as join116 } from "path";
|
|
195726
196511
|
import * as fontkit from "fontkit";
|
|
195727
196512
|
function isFontCollection(value) {
|
|
195728
196513
|
return value.type === "TTC" || value.type === "DFont";
|
|
@@ -195730,10 +196515,10 @@ function isFontCollection(value) {
|
|
|
195730
196515
|
function extractFontMetadata(fontsDir, outputPath) {
|
|
195731
196516
|
const files = [];
|
|
195732
196517
|
const unidentified = [];
|
|
195733
|
-
if (
|
|
196518
|
+
if (existsSync109(fontsDir)) {
|
|
195734
196519
|
const fontFiles = readdirSync34(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
195735
196520
|
for (const filename of fontFiles) {
|
|
195736
|
-
const fullPath =
|
|
196521
|
+
const fullPath = join116(fontsDir, filename);
|
|
195737
196522
|
const meta = readSingleFont(fullPath, filename);
|
|
195738
196523
|
if (meta.identified) {
|
|
195739
196524
|
files.push(meta);
|
|
@@ -195755,7 +196540,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
195755
196540
|
tool: "fontkit"
|
|
195756
196541
|
}
|
|
195757
196542
|
};
|
|
195758
|
-
|
|
196543
|
+
writeFileSync47(outputPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
195759
196544
|
return manifest;
|
|
195760
196545
|
}
|
|
195761
196546
|
function readSingleFont(fullPath, filename) {
|
|
@@ -195772,7 +196557,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
195772
196557
|
isIcon: false
|
|
195773
196558
|
};
|
|
195774
196559
|
try {
|
|
195775
|
-
const buf =
|
|
196560
|
+
const buf = readFileSync76(fullPath);
|
|
195776
196561
|
const created = fontkit.create(buf);
|
|
195777
196562
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
195778
196563
|
if (!font) return empty2;
|
|
@@ -196044,8 +196829,8 @@ var init_animationCataloger = __esm({
|
|
|
196044
196829
|
});
|
|
196045
196830
|
|
|
196046
196831
|
// src/capture/mediaCapture.ts
|
|
196047
|
-
import { mkdirSync as
|
|
196048
|
-
import { join as
|
|
196832
|
+
import { mkdirSync as mkdirSync57, writeFileSync as writeFileSync48, readdirSync as readdirSync35, readFileSync as readFileSync77, statSync as statSync37 } from "fs";
|
|
196833
|
+
import { join as join117, extname as extname25 } from "path";
|
|
196049
196834
|
function liveRemainingMs(budget, fallbackMs) {
|
|
196050
196835
|
return budget.remainingMs?.() ?? fallbackMs;
|
|
196051
196836
|
}
|
|
@@ -196083,7 +196868,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
196083
196868
|
const hash2 = buf.toString("base64").slice(0, 100);
|
|
196084
196869
|
if (savedHashes.has(hash2)) continue;
|
|
196085
196870
|
savedHashes.add(hash2);
|
|
196086
|
-
|
|
196871
|
+
writeFileSync48(join117(lottieDir, `animation-${savedCount}.lottie`), buf);
|
|
196087
196872
|
savedCount++;
|
|
196088
196873
|
continue;
|
|
196089
196874
|
}
|
|
@@ -196101,7 +196886,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
196101
196886
|
} catch {
|
|
196102
196887
|
continue;
|
|
196103
196888
|
}
|
|
196104
|
-
|
|
196889
|
+
writeFileSync48(join117(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
|
|
196105
196890
|
savedCount++;
|
|
196106
196891
|
}
|
|
196107
196892
|
} catch {
|
|
@@ -196111,18 +196896,18 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
196111
196896
|
}
|
|
196112
196897
|
async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget = {}) {
|
|
196113
196898
|
const manifest = [];
|
|
196114
|
-
const previewDir =
|
|
196115
|
-
|
|
196899
|
+
const previewDir = join117(lottieDir, "previews");
|
|
196900
|
+
mkdirSync57(previewDir, { recursive: true });
|
|
196116
196901
|
for (const file of readdirSync35(lottieDir)) {
|
|
196117
196902
|
if (!file.endsWith(".json")) continue;
|
|
196118
196903
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
196119
196904
|
try {
|
|
196120
|
-
const raw = JSON.parse(
|
|
196905
|
+
const raw = JSON.parse(readFileSync77(join117(lottieDir, file), "utf-8"));
|
|
196121
196906
|
const fr = raw.fr || 30;
|
|
196122
196907
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
196123
196908
|
const previewName = file.replace(".json", "-preview.png");
|
|
196124
196909
|
let preview;
|
|
196125
|
-
const fileSize = statSync37(
|
|
196910
|
+
const fileSize = statSync37(join117(lottieDir, file)).size;
|
|
196126
196911
|
if (fileSize > 2e6) continue;
|
|
196127
196912
|
let previewPage;
|
|
196128
196913
|
try {
|
|
@@ -196130,7 +196915,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
196130
196915
|
previewPage = await chromeBrowser.newPage();
|
|
196131
196916
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
196132
196917
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
196133
|
-
const animData = JSON.parse(
|
|
196918
|
+
const animData = JSON.parse(readFileSync77(join117(lottieDir, file), "utf-8"));
|
|
196134
196919
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
196135
196920
|
await previewPage.setContent(
|
|
196136
196921
|
`<!DOCTYPE html>
|
|
@@ -196161,7 +196946,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
196161
196946
|
});
|
|
196162
196947
|
if (liveRemainingMs(budget, 1) > 0) {
|
|
196163
196948
|
await previewPage.screenshot({
|
|
196164
|
-
path:
|
|
196949
|
+
path: join117(previewDir, previewName),
|
|
196165
196950
|
type: "png",
|
|
196166
196951
|
omitBackground: true
|
|
196167
196952
|
});
|
|
@@ -196186,8 +196971,8 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
196186
196971
|
}
|
|
196187
196972
|
}
|
|
196188
196973
|
if (manifest.length > 0) {
|
|
196189
|
-
|
|
196190
|
-
|
|
196974
|
+
writeFileSync48(
|
|
196975
|
+
join117(outputDir, "extracted", "lottie-manifest.json"),
|
|
196191
196976
|
JSON.stringify(manifest, null, 2),
|
|
196192
196977
|
"utf-8"
|
|
196193
196978
|
);
|
|
@@ -196225,7 +197010,7 @@ async function downloadVideoBody(srcUrl, filename, videosDir, timeoutMs) {
|
|
|
196225
197010
|
}
|
|
196226
197011
|
if (total < 1024) return null;
|
|
196227
197012
|
const safe = /\.[a-z0-9]+$/i.test(filename) ? filename.replace(/[^\w.-]/g, "_") : `video${ext}`;
|
|
196228
|
-
|
|
197013
|
+
writeFileSync48(join117(videosDir, safe), Buffer.concat(chunks));
|
|
196229
197014
|
return `assets/videos/${safe}`;
|
|
196230
197015
|
} catch {
|
|
196231
197016
|
return null;
|
|
@@ -196292,10 +197077,10 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
196292
197077
|
}
|
|
196293
197078
|
const merged = [...byKey.values()];
|
|
196294
197079
|
if (merged.length === 0) return;
|
|
196295
|
-
const videoManifestDir =
|
|
196296
|
-
|
|
196297
|
-
const previewDir =
|
|
196298
|
-
|
|
197080
|
+
const videoManifestDir = join117(outputDir, "assets", "videos");
|
|
197081
|
+
mkdirSync57(videoManifestDir, { recursive: true });
|
|
197082
|
+
const previewDir = join117(videoManifestDir, "previews");
|
|
197083
|
+
mkdirSync57(previewDir, { recursive: true });
|
|
196299
197084
|
const videoManifest = [];
|
|
196300
197085
|
const dlStart = Date.now();
|
|
196301
197086
|
for (let vi = 0; vi < merged.length && vi < 20; vi++) {
|
|
@@ -196323,7 +197108,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
196323
197108
|
await new Promise((r2) => setTimeout(r2, 200));
|
|
196324
197109
|
if (liveRemainingMs(opts ?? {}, 1) > 0) {
|
|
196325
197110
|
await page.screenshot({
|
|
196326
|
-
path:
|
|
197111
|
+
path: join117(previewDir, previewName),
|
|
196327
197112
|
clip: {
|
|
196328
197113
|
x: Math.max(0, rect.x),
|
|
196329
197114
|
y: Math.max(0, rect.y),
|
|
@@ -196359,8 +197144,8 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
196359
197144
|
});
|
|
196360
197145
|
}
|
|
196361
197146
|
if (videoManifest.length > 0) {
|
|
196362
|
-
|
|
196363
|
-
|
|
197147
|
+
writeFileSync48(
|
|
197148
|
+
join117(outputDir, "extracted", "video-manifest.json"),
|
|
196364
197149
|
JSON.stringify(videoManifest, null, 2),
|
|
196365
197150
|
"utf-8"
|
|
196366
197151
|
);
|
|
@@ -196429,8 +197214,8 @@ var init_mediaCapture = __esm({
|
|
|
196429
197214
|
});
|
|
196430
197215
|
|
|
196431
197216
|
// src/capture/contentExtractor.ts
|
|
196432
|
-
import { existsSync as
|
|
196433
|
-
import { basename as basename30, join as
|
|
197217
|
+
import { existsSync as existsSync110, readdirSync as readdirSync36, statSync as statSync38, readFileSync as readFileSync78 } from "fs";
|
|
197218
|
+
import { basename as basename30, join as join118 } from "path";
|
|
196434
197219
|
function resolveVisionPhaseCompletion(outcome, remainingMs) {
|
|
196435
197220
|
if (outcome.budgetExhausted || remainingMs <= 0) {
|
|
196436
197221
|
return { status: "degraded", reason: "budget-exhausted" };
|
|
@@ -196668,7 +197453,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
196668
197453
|
return response.text?.trim() || "";
|
|
196669
197454
|
};
|
|
196670
197455
|
}
|
|
196671
|
-
const imageFiles = readdirSync36(
|
|
197456
|
+
const imageFiles = readdirSync36(join118(outputDir, "assets")).filter(
|
|
196672
197457
|
(f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
|
|
196673
197458
|
);
|
|
196674
197459
|
const BATCH_SIZE = 20;
|
|
@@ -196696,10 +197481,10 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
196696
197481
|
const batch = imageFiles.slice(i2, i2 + BATCH_SIZE);
|
|
196697
197482
|
const results = await Promise.allSettled(
|
|
196698
197483
|
batch.map(async (file) => {
|
|
196699
|
-
const filePath =
|
|
197484
|
+
const filePath = join118(outputDir, "assets", file);
|
|
196700
197485
|
const stat3 = statSync38(filePath);
|
|
196701
197486
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
196702
|
-
const buffer =
|
|
197487
|
+
const buffer = readFileSync78(filePath);
|
|
196703
197488
|
const base64 = buffer.toString("base64");
|
|
196704
197489
|
const ext = file.split(".").pop()?.toLowerCase() || "png";
|
|
196705
197490
|
const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -196729,12 +197514,12 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
196729
197514
|
`${Object.keys(geminiCaptions).length} images captioned with ${providerName}`
|
|
196730
197515
|
);
|
|
196731
197516
|
const svgFiles = [];
|
|
196732
|
-
const assetsDir =
|
|
197517
|
+
const assetsDir = join118(outputDir, "assets");
|
|
196733
197518
|
for (const f3 of readdirSync36(assetsDir)) {
|
|
196734
197519
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
196735
197520
|
}
|
|
196736
|
-
const svgsSubdir =
|
|
196737
|
-
if (
|
|
197521
|
+
const svgsSubdir = join118(assetsDir, "svgs");
|
|
197522
|
+
if (existsSync110(svgsSubdir)) {
|
|
196738
197523
|
for (const f3 of readdirSync36(svgsSubdir)) {
|
|
196739
197524
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
196740
197525
|
}
|
|
@@ -196764,10 +197549,10 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
196764
197549
|
const batch = svgFiles.slice(i2, i2 + SVG_BATCH);
|
|
196765
197550
|
const results = await Promise.allSettled(
|
|
196766
197551
|
batch.map(async ({ relPath }) => {
|
|
196767
|
-
const filePath =
|
|
197552
|
+
const filePath = join118(assetsDir, relPath);
|
|
196768
197553
|
let pngBase64;
|
|
196769
197554
|
try {
|
|
196770
|
-
const svgSource =
|
|
197555
|
+
const svgSource = readFileSync78(filePath, "utf-8");
|
|
196771
197556
|
const lightFillHits = (svgSource.match(/fill\s*=\s*["'](#fff(fff)?|white|#[ef][ef][ef]|#[ef]{6})["']/gi) || []).length;
|
|
196772
197557
|
const darkFillHits = (svgSource.match(/fill\s*=\s*["'](#000(000)?|black|#[0-3]{6}|#[0-3]{3})["']/gi) || []).length;
|
|
196773
197558
|
const bg = lightFillHits > darkFillHits ? { r: 32, g: 32, b: 32 } : { r: 255, g: 255, b: 255 };
|
|
@@ -196833,11 +197618,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
196833
197618
|
const uncaptionedLines = [];
|
|
196834
197619
|
const svgLines = [];
|
|
196835
197620
|
const fontLines = [];
|
|
196836
|
-
const assetsPath =
|
|
197621
|
+
const assetsPath = join118(outputDir, "assets");
|
|
196837
197622
|
try {
|
|
196838
197623
|
for (const file of readdirSync36(assetsPath)) {
|
|
196839
197624
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
196840
|
-
const filePath =
|
|
197625
|
+
const filePath = join118(assetsPath, file);
|
|
196841
197626
|
const stat3 = statSync38(filePath);
|
|
196842
197627
|
if (!stat3.isFile()) continue;
|
|
196843
197628
|
const sizeKb = Math.round(stat3.size / 1024);
|
|
@@ -196866,7 +197651,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
196866
197651
|
} catch {
|
|
196867
197652
|
}
|
|
196868
197653
|
try {
|
|
196869
|
-
const svgsPath =
|
|
197654
|
+
const svgsPath = join118(assetsPath, "svgs");
|
|
196870
197655
|
for (const file of readdirSync36(svgsPath)) {
|
|
196871
197656
|
if (!file.endsWith(".svg")) continue;
|
|
196872
197657
|
const svgMatch = tokens.svgs.find(
|
|
@@ -196885,7 +197670,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
196885
197670
|
} catch {
|
|
196886
197671
|
}
|
|
196887
197672
|
try {
|
|
196888
|
-
const fontsPath =
|
|
197673
|
+
const fontsPath = join118(assetsPath, "fonts");
|
|
196889
197674
|
for (const file of readdirSync36(fontsPath)) {
|
|
196890
197675
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
196891
197676
|
}
|
|
@@ -196894,7 +197679,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
196894
197679
|
const videoLines = [];
|
|
196895
197680
|
try {
|
|
196896
197681
|
const manifest = JSON.parse(
|
|
196897
|
-
|
|
197682
|
+
readFileSync78(join118(outputDir, "extracted", "video-manifest.json"), "utf-8")
|
|
196898
197683
|
);
|
|
196899
197684
|
for (const v2 of manifest) {
|
|
196900
197685
|
if (!v2.localPath) continue;
|
|
@@ -196929,8 +197714,8 @@ var agentPromptGenerator_exports = {};
|
|
|
196929
197714
|
__export(agentPromptGenerator_exports, {
|
|
196930
197715
|
generateAgentPrompt: () => generateAgentPrompt
|
|
196931
197716
|
});
|
|
196932
|
-
import { writeFileSync as
|
|
196933
|
-
import { join as
|
|
197717
|
+
import { writeFileSync as writeFileSync49, readdirSync as readdirSync37, existsSync as existsSync111 } from "fs";
|
|
197718
|
+
import { join as join119 } from "path";
|
|
196934
197719
|
function inferColorRole(hex) {
|
|
196935
197720
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
196936
197721
|
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
@@ -196949,9 +197734,9 @@ function inferColorRole(hex) {
|
|
|
196949
197734
|
}
|
|
196950
197735
|
function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
|
|
196951
197736
|
const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
|
|
196952
|
-
|
|
196953
|
-
|
|
196954
|
-
|
|
197737
|
+
writeFileSync49(join119(outputDir, "AGENTS.md"), prompt, "utf-8");
|
|
197738
|
+
writeFileSync49(join119(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
|
197739
|
+
writeFileSync49(join119(outputDir, ".cursorrules"), prompt, "utf-8");
|
|
196955
197740
|
}
|
|
196956
197741
|
function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
|
|
196957
197742
|
const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -196960,8 +197745,8 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
196960
197745
|
(f3) => f3.family + (f3.variable && f3.weightRange ? ` (${f3.weightRange[0]}-${f3.weightRange[1]} variable)` : f3.weights.length > 0 ? ` (${f3.weights.join(",")})` : "")
|
|
196961
197746
|
).join(", ") || "none detected";
|
|
196962
197747
|
function contactSheetRows(dir, baseFile, label2) {
|
|
196963
|
-
const fullDir =
|
|
196964
|
-
if (!
|
|
197748
|
+
const fullDir = join119(outputDir, dir);
|
|
197749
|
+
if (!existsSync111(fullDir)) return [];
|
|
196965
197750
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
196966
197751
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
196967
197752
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
@@ -196993,7 +197778,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
196993
197778
|
tableRows.push(
|
|
196994
197779
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
196995
197780
|
);
|
|
196996
|
-
if (
|
|
197781
|
+
if (existsSync111(join119(outputDir, "extracted", "design-styles.json"))) {
|
|
196997
197782
|
tableRows.push(
|
|
196998
197783
|
"| `extracted/design-styles.json` | Computed styles from live DOM: typography hierarchy, button/card/nav styles, spacing scale, border-radius, box shadows. Primary data source for DESIGN.md. |"
|
|
196999
197784
|
);
|
|
@@ -197064,15 +197849,15 @@ var init_agentPromptGenerator = __esm({
|
|
|
197064
197849
|
});
|
|
197065
197850
|
|
|
197066
197851
|
// src/capture/scaffolding.ts
|
|
197067
|
-
import { existsSync as
|
|
197068
|
-
import { join as
|
|
197852
|
+
import { existsSync as existsSync113, writeFileSync as writeFileSync50, readFileSync as readFileSync79 } from "fs";
|
|
197853
|
+
import { join as join120, resolve as resolve72 } from "path";
|
|
197069
197854
|
function loadEnvFile(startDir) {
|
|
197070
197855
|
try {
|
|
197071
197856
|
let dir = resolve72(startDir);
|
|
197072
197857
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
197073
197858
|
const envPath = resolve72(dir, ".env");
|
|
197074
197859
|
try {
|
|
197075
|
-
const envContent =
|
|
197860
|
+
const envContent = readFileSync79(envPath, "utf-8");
|
|
197076
197861
|
for (const line2 of envContent.split("\n")) {
|
|
197077
197862
|
const trimmed = line2.trim();
|
|
197078
197863
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -197091,10 +197876,10 @@ function loadEnvFile(startDir) {
|
|
|
197091
197876
|
}
|
|
197092
197877
|
}
|
|
197093
197878
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
197094
|
-
const metaPath =
|
|
197095
|
-
if (!
|
|
197879
|
+
const metaPath = join120(outputDir, "meta.json");
|
|
197880
|
+
if (!existsSync113(metaPath)) {
|
|
197096
197881
|
const hostname2 = new URL(url).hostname.replace(/^www\./, "");
|
|
197097
|
-
|
|
197882
|
+
writeFileSync50(
|
|
197098
197883
|
metaPath,
|
|
197099
197884
|
JSON.stringify({ id: hostname2 + "-video", name: tokens.title || hostname2 }, null, 2),
|
|
197100
197885
|
"utf-8"
|
|
@@ -197151,8 +197936,8 @@ __export(screenshotCapture_exports, {
|
|
|
197151
197936
|
captureScrollScreenshots: () => captureScrollScreenshots,
|
|
197152
197937
|
pngHeight: () => pngHeight
|
|
197153
197938
|
});
|
|
197154
|
-
import { writeFileSync as
|
|
197155
|
-
import { join as
|
|
197939
|
+
import { writeFileSync as writeFileSync51, mkdirSync as mkdirSync58 } from "fs";
|
|
197940
|
+
import { join as join121 } from "path";
|
|
197156
197941
|
function pngHeight(buf) {
|
|
197157
197942
|
if (buf.length < 24) return null;
|
|
197158
197943
|
if (buf[12] !== 73 || buf[13] !== 72 || buf[14] !== 68 || buf[15] !== 82) return null;
|
|
@@ -197177,7 +197962,7 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
197177
197962
|
const buffer = await page.screenshot({ type: "png", fullPage: true });
|
|
197178
197963
|
const produced = pngHeight(buffer);
|
|
197179
197964
|
if (produced != null && produced > MAX_PLATE_HEIGHT_PX) return null;
|
|
197180
|
-
|
|
197965
|
+
writeFileSync51(join121(screenshotsDir, "full-page.png"), buffer);
|
|
197181
197966
|
return "screenshots/full-page.png";
|
|
197182
197967
|
} finally {
|
|
197183
197968
|
try {
|
|
@@ -197192,8 +197977,8 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
197192
197977
|
}
|
|
197193
197978
|
}
|
|
197194
197979
|
async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
197195
|
-
const screenshotsDir =
|
|
197196
|
-
|
|
197980
|
+
const screenshotsDir = join121(outputDir, "screenshots");
|
|
197981
|
+
mkdirSync58(screenshotsDir, { recursive: true });
|
|
197197
197982
|
const MAX_SCREENSHOTS = 20;
|
|
197198
197983
|
const filePaths = [];
|
|
197199
197984
|
if ((budget.remainingMs?.() ?? 1) <= 0) return filePaths;
|
|
@@ -197286,10 +198071,10 @@ async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
|
197286
198071
|
finalPositions[i2] / Math.max(1, scrollHeight - viewportHeight) * 100
|
|
197287
198072
|
);
|
|
197288
198073
|
const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
|
|
197289
|
-
const filePath =
|
|
198074
|
+
const filePath = join121(screenshotsDir, filename);
|
|
197290
198075
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
197291
198076
|
const buffer = await page.screenshot({ type: "png" });
|
|
197292
|
-
|
|
198077
|
+
writeFileSync51(filePath, buffer);
|
|
197293
198078
|
filePaths.push(`screenshots/${filename}`);
|
|
197294
198079
|
}
|
|
197295
198080
|
await page.evaluate(`window.scrollTo(0, 0)`);
|
|
@@ -197642,8 +198427,8 @@ var capture_exports = {};
|
|
|
197642
198427
|
__export(capture_exports, {
|
|
197643
198428
|
captureWebsite: () => captureWebsite
|
|
197644
198429
|
});
|
|
197645
|
-
import { mkdirSync as
|
|
197646
|
-
import { join as
|
|
198430
|
+
import { mkdirSync as mkdirSync59, writeFileSync as writeFileSync53, existsSync as existsSync114 } from "fs";
|
|
198431
|
+
import { join as join123 } from "path";
|
|
197647
198432
|
async function captureWebsite(opts, onProgress) {
|
|
197648
198433
|
const {
|
|
197649
198434
|
url,
|
|
@@ -197684,9 +198469,9 @@ async function captureWebsite(opts, onProgress) {
|
|
|
197684
198469
|
};
|
|
197685
198470
|
phase("browser", "started");
|
|
197686
198471
|
loadEnvFile(outputDir);
|
|
197687
|
-
|
|
197688
|
-
|
|
197689
|
-
|
|
198472
|
+
mkdirSync59(join123(outputDir, "extracted"), { recursive: true });
|
|
198473
|
+
mkdirSync59(join123(outputDir, "screenshots"), { recursive: true });
|
|
198474
|
+
mkdirSync59(join123(outputDir, "assets"), { recursive: true });
|
|
197690
198475
|
progress("browser", "Launching headless Chrome...");
|
|
197691
198476
|
const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
|
|
197692
198477
|
const browser = await ensureBrowser2();
|
|
@@ -197862,8 +198647,8 @@ async function captureWebsite(opts, onProgress) {
|
|
|
197862
198647
|
} catch {
|
|
197863
198648
|
}
|
|
197864
198649
|
if (discoveredLotties.length > 0 && remainingMs() > 0) {
|
|
197865
|
-
const lottieDir =
|
|
197866
|
-
|
|
198650
|
+
const lottieDir = join123(outputDir, "assets", "lottie");
|
|
198651
|
+
mkdirSync59(lottieDir, { recursive: true });
|
|
197867
198652
|
const lottieBudget = { remainingMs };
|
|
197868
198653
|
const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir, lottieBudget);
|
|
197869
198654
|
if (savedCount > 0 && remainingMs() > 0) {
|
|
@@ -197882,8 +198667,8 @@ async function captureWebsite(opts, onProgress) {
|
|
|
197882
198667
|
return true;
|
|
197883
198668
|
});
|
|
197884
198669
|
capturedShaders = unique;
|
|
197885
|
-
|
|
197886
|
-
|
|
198670
|
+
writeFileSync53(
|
|
198671
|
+
join123(outputDir, "extracted", "shaders.json"),
|
|
197887
198672
|
JSON.stringify(unique, null, 2),
|
|
197888
198673
|
"utf-8"
|
|
197889
198674
|
);
|
|
@@ -197897,16 +198682,16 @@ async function captureWebsite(opts, onProgress) {
|
|
|
197897
198682
|
...tokens,
|
|
197898
198683
|
svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
|
|
197899
198684
|
};
|
|
197900
|
-
|
|
197901
|
-
|
|
198685
|
+
writeFileSync53(
|
|
198686
|
+
join123(outputDir, "extracted", "tokens.json"),
|
|
197902
198687
|
JSON.stringify(tokensForDisk, null, 2),
|
|
197903
198688
|
"utf-8"
|
|
197904
198689
|
);
|
|
197905
198690
|
progress("style", "Extracting design styles...");
|
|
197906
198691
|
try {
|
|
197907
198692
|
const designStyles = await extractDesignStyles(page1);
|
|
197908
|
-
|
|
197909
|
-
|
|
198693
|
+
writeFileSync53(
|
|
198694
|
+
join123(outputDir, "extracted", "design-styles.json"),
|
|
197910
198695
|
JSON.stringify(designStyles, null, 2),
|
|
197911
198696
|
"utf-8"
|
|
197912
198697
|
);
|
|
@@ -198006,8 +198791,8 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
198006
198791
|
}
|
|
198007
198792
|
try {
|
|
198008
198793
|
const fontsManifest = extractFontMetadata(
|
|
198009
|
-
|
|
198010
|
-
|
|
198794
|
+
join123(outputDir, "assets", "fonts"),
|
|
198795
|
+
join123(outputDir, "extracted", "fonts-manifest.json")
|
|
198011
198796
|
);
|
|
198012
198797
|
if (fontsManifest.families.length > 0) {
|
|
198013
198798
|
const summary = fontsManifest.families.map((f3) => `${f3.family}${f3.variable ? " (variable)" : ""} \xD7 ${f3.fileCount}`).join(", ");
|
|
@@ -198033,8 +198818,8 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
198033
198818
|
scrollTriggeredElements: (animationCatalog.scrollTargets || []).length,
|
|
198034
198819
|
representativeAnimations: representativeAnims
|
|
198035
198820
|
};
|
|
198036
|
-
|
|
198037
|
-
|
|
198821
|
+
writeFileSync53(
|
|
198822
|
+
join123(outputDir, "extracted", "animations.json"),
|
|
198038
198823
|
JSON.stringify(leanCatalog, null, 2),
|
|
198039
198824
|
"utf-8"
|
|
198040
198825
|
);
|
|
@@ -198079,8 +198864,8 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
198079
198864
|
...tokens,
|
|
198080
198865
|
svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
|
|
198081
198866
|
};
|
|
198082
|
-
|
|
198083
|
-
|
|
198867
|
+
writeFileSync53(
|
|
198868
|
+
join123(outputDir, "extracted", "tokens.json"),
|
|
198084
198869
|
JSON.stringify(tokensForDisk2, null, 2),
|
|
198085
198870
|
"utf-8"
|
|
198086
198871
|
);
|
|
@@ -198096,12 +198881,12 @@ ${extracted.bodyHtml}
|
|
|
198096
198881
|
</body>
|
|
198097
198882
|
</html>
|
|
198098
198883
|
`;
|
|
198099
|
-
|
|
198884
|
+
writeFileSync53(join123(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
|
|
198100
198885
|
} catch (err) {
|
|
198101
198886
|
warnings.push(`page.html write failed: ${err}`);
|
|
198102
198887
|
}
|
|
198103
198888
|
if (visibleTextContent) {
|
|
198104
|
-
|
|
198889
|
+
writeFileSync53(join123(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
|
|
198105
198890
|
}
|
|
198106
198891
|
let geminiCaptions = {};
|
|
198107
198892
|
if (skipVision) {
|
|
@@ -198137,8 +198922,8 @@ ${extracted.bodyHtml}
|
|
|
198137
198922
|
if (lines.length > 0) {
|
|
198138
198923
|
const hasVisionKey = !!(!skipVision && (process.env.OPENROUTER_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY));
|
|
198139
198924
|
const header = hasVisionKey ? "# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\nTo find a specific brand or icon, **grep this file for the brand name in the description text** (e.g. `grep -i 'autodesk' asset-descriptions.md`). The Gemini Vision captions identify what's actually in each file \u2014 that's the agent's selector.\n\nThe `logo-<hash>.svg` filename prefix is a cheap structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). It is NOT a content claim \u2014 many `logo-*` files are nav icons or decorative shapes. Trust the captions, not the filename prefix.\n\n" : "# Asset Descriptions\n\n\u26A0\uFE0F GEMINI_API_KEY not set \u2014 descriptions below are catalog-derived (alt text, headings, section context, filename) instead of Vision-generated. To get richer Vision descriptions on the next capture, set GEMINI_API_KEY (or GOOGLE_API_KEY) and re-run.\n\nThe `logo-<hash>.svg` filename prefix is a structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). To pick the actual brand logo without Vision, open the `logo-*` candidates in a previewer or rasterize them with `sharp` before referencing \u2014 composing a fake logo ships off-brand in the final video.\n\n";
|
|
198140
|
-
|
|
198141
|
-
|
|
198925
|
+
writeFileSync53(
|
|
198926
|
+
join123(outputDir, "extracted", "asset-descriptions.md"),
|
|
198142
198927
|
header + lines.map((l) => "- " + l).join("\n") + "\n",
|
|
198143
198928
|
"utf-8"
|
|
198144
198929
|
);
|
|
@@ -198156,8 +198941,8 @@ ${extracted.bodyHtml}
|
|
|
198156
198941
|
const { createScrollContactSheet: createScrollContactSheet2, createAssetContactSheet: createAssetContactSheet2, createSvgContactSheet: createSvgContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
198157
198942
|
const contactSheetBudget = { remainingMs };
|
|
198158
198943
|
const scrollSheets = await createScrollContactSheet2(
|
|
198159
|
-
|
|
198160
|
-
|
|
198944
|
+
join123(outputDir, "screenshots"),
|
|
198945
|
+
join123(outputDir, "screenshots", "contact-sheet.jpg"),
|
|
198161
198946
|
contactSheetBudget
|
|
198162
198947
|
);
|
|
198163
198948
|
if (scrollSheets.length > 0)
|
|
@@ -198165,11 +198950,11 @@ ${extracted.bodyHtml}
|
|
|
198165
198950
|
"design",
|
|
198166
198951
|
`Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
|
|
198167
198952
|
);
|
|
198168
|
-
const assetsImgDir =
|
|
198169
|
-
if (
|
|
198953
|
+
const assetsImgDir = join123(outputDir, "assets");
|
|
198954
|
+
if (existsSync114(assetsImgDir)) {
|
|
198170
198955
|
const assetSheets = await createAssetContactSheet2(
|
|
198171
198956
|
assetsImgDir,
|
|
198172
|
-
|
|
198957
|
+
join123(outputDir, "assets", "contact-sheet.jpg"),
|
|
198173
198958
|
contactSheetBudget
|
|
198174
198959
|
);
|
|
198175
198960
|
if (assetSheets.length > 0)
|
|
@@ -198178,9 +198963,9 @@ ${extracted.bodyHtml}
|
|
|
198178
198963
|
`Asset contact sheet generated (${assetSheets.length} page${assetSheets.length > 1 ? "s" : ""})`
|
|
198179
198964
|
);
|
|
198180
198965
|
}
|
|
198181
|
-
const svgsDir =
|
|
198182
|
-
const assetsRootDir =
|
|
198183
|
-
const svgOutputPath =
|
|
198966
|
+
const svgsDir = join123(outputDir, "assets", "svgs");
|
|
198967
|
+
const assetsRootDir = join123(outputDir, "assets");
|
|
198968
|
+
const svgOutputPath = existsSync114(svgsDir) ? join123(outputDir, "assets", "svgs", "contact-sheet.jpg") : join123(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
198184
198969
|
const svgSheets = await createSvgContactSheet2(
|
|
198185
198970
|
svgsDir,
|
|
198186
198971
|
svgOutputPath,
|
|
@@ -198213,7 +198998,7 @@ ${extracted.bodyHtml}
|
|
|
198213
198998
|
animationCatalog,
|
|
198214
198999
|
screenshots.length > 0,
|
|
198215
199000
|
discoveredLotties.length > 0,
|
|
198216
|
-
|
|
199001
|
+
existsSync114(join123(outputDir, "extracted", "shaders.json")),
|
|
198217
199002
|
catalogedAssets,
|
|
198218
199003
|
progress,
|
|
198219
199004
|
warnings,
|
|
@@ -198391,14 +199176,14 @@ var init_capture2 = __esm({
|
|
|
198391
199176
|
let outputName = args.output ?? "capture";
|
|
198392
199177
|
let outputDir = resolve73(outputName);
|
|
198393
199178
|
if (isDefaultOutput) {
|
|
198394
|
-
const { existsSync:
|
|
199179
|
+
const { existsSync: existsSync128 } = await import("fs");
|
|
198395
199180
|
let n2 = 2;
|
|
198396
|
-
while (
|
|
199181
|
+
while (existsSync128(outputDir) && n2 < 100) {
|
|
198397
199182
|
outputName = `capture-${n2}`;
|
|
198398
199183
|
outputDir = resolve73(outputName);
|
|
198399
199184
|
n2++;
|
|
198400
199185
|
}
|
|
198401
|
-
if (
|
|
199186
|
+
if (existsSync128(outputDir)) {
|
|
198402
199187
|
console.error(`./capture-{2..99} are all taken. Pass -o <name> to pick a directory.`);
|
|
198403
199188
|
failCommand();
|
|
198404
199189
|
}
|
|
@@ -198487,11 +199272,11 @@ var init_capture2 = __esm({
|
|
|
198487
199272
|
} catch (err) {
|
|
198488
199273
|
const errMsg = normalizeErrorMessage(err);
|
|
198489
199274
|
try {
|
|
198490
|
-
const { mkdirSync:
|
|
198491
|
-
|
|
199275
|
+
const { mkdirSync: mkdirSync70, writeFileSync: writeFileSync63 } = await import("fs");
|
|
199276
|
+
mkdirSync70(outputDir, { recursive: true });
|
|
198492
199277
|
const isTimeout = /timeout|timed out/i.test(errMsg);
|
|
198493
199278
|
const reason = isTimeout ? "Page navigation timed out \u2014 the site may be blocking headless browsers or requires authentication." : `Capture failed: ${errMsg}`;
|
|
198494
|
-
|
|
199279
|
+
writeFileSync63(
|
|
198495
199280
|
`${outputDir}/BLOCKED.md`,
|
|
198496
199281
|
`# Capture Failed
|
|
198497
199282
|
|
|
@@ -198555,33 +199340,33 @@ __export(state_exports, {
|
|
|
198555
199340
|
stateFilePath: () => stateFilePath,
|
|
198556
199341
|
writeStackOutputs: () => writeStackOutputs
|
|
198557
199342
|
});
|
|
198558
|
-
import { existsSync as
|
|
198559
|
-
import { dirname as dirname56, join as
|
|
199343
|
+
import { existsSync as existsSync115, mkdirSync as mkdirSync60, readdirSync as readdirSync38, readFileSync as readFileSync80, rmSync as rmSync34, writeFileSync as writeFileSync54 } from "fs";
|
|
199344
|
+
import { dirname as dirname56, join as join124 } from "path";
|
|
198560
199345
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
198561
|
-
return
|
|
199346
|
+
return join124(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
198562
199347
|
}
|
|
198563
199348
|
function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
198564
199349
|
const path2 = stateFilePath(outputs.stackName, cwd);
|
|
198565
|
-
|
|
198566
|
-
|
|
199350
|
+
mkdirSync60(dirname56(path2), { recursive: true });
|
|
199351
|
+
writeFileSync54(path2, JSON.stringify(outputs, null, 2) + "\n");
|
|
198567
199352
|
return path2;
|
|
198568
199353
|
}
|
|
198569
199354
|
function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
198570
199355
|
const path2 = stateFilePath(stackName, cwd);
|
|
198571
|
-
if (!
|
|
199356
|
+
if (!existsSync115(path2)) return null;
|
|
198572
199357
|
try {
|
|
198573
|
-
return JSON.parse(
|
|
199358
|
+
return JSON.parse(readFileSync80(path2, "utf-8"));
|
|
198574
199359
|
} catch {
|
|
198575
199360
|
return null;
|
|
198576
199361
|
}
|
|
198577
199362
|
}
|
|
198578
199363
|
function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
198579
199364
|
const path2 = stateFilePath(stackName, cwd);
|
|
198580
|
-
if (
|
|
199365
|
+
if (existsSync115(path2)) rmSync34(path2);
|
|
198581
199366
|
}
|
|
198582
199367
|
function listStackNames(cwd = process.cwd()) {
|
|
198583
|
-
const dir =
|
|
198584
|
-
if (!
|
|
199368
|
+
const dir = join124(cwd, STATE_DIR_NAME);
|
|
199369
|
+
if (!existsSync115(dir)) return [];
|
|
198585
199370
|
return readdirSync38(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
198586
199371
|
}
|
|
198587
199372
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
@@ -198612,8 +199397,8 @@ var init_state = __esm({
|
|
|
198612
199397
|
|
|
198613
199398
|
// src/commands/lambda/sam.ts
|
|
198614
199399
|
import { execFileSync as execFileSync18, spawnSync as spawnSync4 } from "child_process";
|
|
198615
|
-
import { existsSync as
|
|
198616
|
-
import { join as
|
|
199400
|
+
import { existsSync as existsSync116 } from "fs";
|
|
199401
|
+
import { join as join125 } from "path";
|
|
198617
199402
|
function assertSamAvailable() {
|
|
198618
199403
|
try {
|
|
198619
199404
|
execFileSync18("sam", ["--version"], { stdio: "ignore" });
|
|
@@ -198633,8 +199418,8 @@ function assertAwsCliAvailable() {
|
|
|
198633
199418
|
}
|
|
198634
199419
|
}
|
|
198635
199420
|
function locateSamTemplate(repoRoot2) {
|
|
198636
|
-
const candidate =
|
|
198637
|
-
if (!
|
|
199421
|
+
const candidate = join125(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
199422
|
+
if (!existsSync116(candidate)) {
|
|
198638
199423
|
throw new Error(
|
|
198639
199424
|
`[lambda] SAM template not found at ${candidate}. If you're running from an installed package, point --sam-template at your local copy of examples/aws-lambda/template.yaml.`
|
|
198640
199425
|
);
|
|
@@ -198667,7 +199452,7 @@ function samDeploy(opts) {
|
|
|
198667
199452
|
if (opts.awsProfile) {
|
|
198668
199453
|
args.push("--profile", opts.awsProfile);
|
|
198669
199454
|
}
|
|
198670
|
-
const samDir =
|
|
199455
|
+
const samDir = join125(opts.repoRoot, "examples", "aws-lambda");
|
|
198671
199456
|
const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
198672
199457
|
if (result.status !== 0) {
|
|
198673
199458
|
throw new Error(
|
|
@@ -198685,7 +199470,7 @@ function samDelete(opts) {
|
|
|
198685
199470
|
if (opts.awsProfile) {
|
|
198686
199471
|
args.push("--profile", opts.awsProfile);
|
|
198687
199472
|
}
|
|
198688
|
-
const samDir =
|
|
199473
|
+
const samDir = join125(opts.repoRoot, "examples", "aws-lambda");
|
|
198689
199474
|
const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
198690
199475
|
if (result.status !== 0) {
|
|
198691
199476
|
throw new Error(`[lambda] sam delete exited with code ${result.status ?? "unknown"}`);
|
|
@@ -198735,17 +199520,17 @@ var init_sam = __esm({
|
|
|
198735
199520
|
});
|
|
198736
199521
|
|
|
198737
199522
|
// src/commands/lambda/repoRoot.ts
|
|
198738
|
-
import { existsSync as
|
|
199523
|
+
import { existsSync as existsSync117 } from "fs";
|
|
198739
199524
|
import { dirname as dirname57, resolve as resolve74 } from "path";
|
|
198740
199525
|
import { fileURLToPath as fileURLToPath15 } from "url";
|
|
198741
199526
|
function repoRoot() {
|
|
198742
199527
|
const override = process.env.HYPERFRAMES_REPO_ROOT;
|
|
198743
|
-
if (override &&
|
|
199528
|
+
if (override && existsSync117(resolve74(override, "packages", "aws-lambda", "package.json"))) {
|
|
198744
199529
|
return override;
|
|
198745
199530
|
}
|
|
198746
199531
|
let dir = dirname57(fileURLToPath15(import.meta.url));
|
|
198747
199532
|
for (let depth = 0; depth < 12; depth++) {
|
|
198748
|
-
if (
|
|
199533
|
+
if (existsSync117(resolve74(dir, "packages", "aws-lambda", "package.json"))) {
|
|
198749
199534
|
return dir;
|
|
198750
199535
|
}
|
|
198751
199536
|
const parent = dirname57(dir);
|
|
@@ -198768,8 +199553,8 @@ __export(deploy_exports, {
|
|
|
198768
199553
|
runDeploy: () => runDeploy
|
|
198769
199554
|
});
|
|
198770
199555
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
198771
|
-
import { existsSync as
|
|
198772
|
-
import { join as
|
|
199556
|
+
import { existsSync as existsSync118 } from "fs";
|
|
199557
|
+
import { join as join126, resolve as resolve75 } from "path";
|
|
198773
199558
|
async function runDeploy(args = {}) {
|
|
198774
199559
|
const resolved2 = {
|
|
198775
199560
|
stackName: args.stackName ?? DEFAULT_STACK_NAME,
|
|
@@ -198786,8 +199571,8 @@ async function runDeploy(args = {}) {
|
|
|
198786
199571
|
console.log(c.dim("\u2192 Building handler ZIP"));
|
|
198787
199572
|
buildHandlerZip(root);
|
|
198788
199573
|
} else {
|
|
198789
|
-
const zip =
|
|
198790
|
-
if (!
|
|
199574
|
+
const zip = join126(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
199575
|
+
if (!existsSync118(zip)) {
|
|
198791
199576
|
throw new Error(
|
|
198792
199577
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
198793
199578
|
);
|
|
@@ -198830,7 +199615,7 @@ async function runDeploy(args = {}) {
|
|
|
198830
199615
|
function buildHandlerZip(root) {
|
|
198831
199616
|
const result = spawnSync5(
|
|
198832
199617
|
"bun",
|
|
198833
|
-
["run", "--cwd",
|
|
199618
|
+
["run", "--cwd", join126(root, "packages", "aws-lambda"), "build:zip"],
|
|
198834
199619
|
{ stdio: "inherit" }
|
|
198835
199620
|
);
|
|
198836
199621
|
if (result.status !== 0) {
|
|
@@ -198899,14 +199684,14 @@ var init_sites = __esm({
|
|
|
198899
199684
|
});
|
|
198900
199685
|
|
|
198901
199686
|
// src/commands/lambda/_dimensions.ts
|
|
198902
|
-
import { readFileSync as
|
|
198903
|
-
import { join as
|
|
199687
|
+
import { readFileSync as readFileSync81 } from "fs";
|
|
199688
|
+
import { join as join127 } from "path";
|
|
198904
199689
|
function warnOnDimensionMismatch(args) {
|
|
198905
199690
|
if (args.quiet) return;
|
|
198906
199691
|
if (args.outputResolution) return;
|
|
198907
199692
|
let html;
|
|
198908
199693
|
try {
|
|
198909
|
-
html =
|
|
199694
|
+
html = readFileSync81(join127(args.projectDir, "index.html"), "utf-8");
|
|
198910
199695
|
} catch {
|
|
198911
199696
|
return;
|
|
198912
199697
|
}
|
|
@@ -198935,8 +199720,8 @@ __export(render_exports2, {
|
|
|
198935
199720
|
buildLambdaRenderConfig: () => buildLambdaRenderConfig,
|
|
198936
199721
|
runRender: () => runRender
|
|
198937
199722
|
});
|
|
198938
|
-
import { existsSync as
|
|
198939
|
-
import { join as
|
|
199723
|
+
import { existsSync as existsSync119 } from "fs";
|
|
199724
|
+
import { join as join128, resolve as resolvePath2 } from "path";
|
|
198940
199725
|
async function loadSDK2() {
|
|
198941
199726
|
return import("@hyperframes/aws-lambda/sdk");
|
|
198942
199727
|
}
|
|
@@ -198952,8 +199737,8 @@ async function runRender(args) {
|
|
|
198952
199737
|
});
|
|
198953
199738
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
198954
199739
|
if (variables && Object.keys(variables).length > 0) {
|
|
198955
|
-
const indexPath2 =
|
|
198956
|
-
if (
|
|
199740
|
+
const indexPath2 = join128(projectDir, "index.html");
|
|
199741
|
+
if (existsSync119(indexPath2)) {
|
|
198957
199742
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
198958
199743
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
198959
199744
|
} else if (args.strictVariables && !args.json) {
|
|
@@ -199086,8 +199871,8 @@ __export(render_batch_exports, {
|
|
|
199086
199871
|
runRenderBatch: () => runRenderBatch,
|
|
199087
199872
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
199088
199873
|
});
|
|
199089
|
-
import { existsSync as
|
|
199090
|
-
import { join as
|
|
199874
|
+
import { existsSync as existsSync120, readFileSync as readFileSync83 } from "fs";
|
|
199875
|
+
import { join as join129, resolve as resolvePath3 } from "path";
|
|
199091
199876
|
async function loadSDK3() {
|
|
199092
199877
|
return import("@hyperframes/aws-lambda/sdk");
|
|
199093
199878
|
}
|
|
@@ -199095,7 +199880,7 @@ async function runRenderBatch(args) {
|
|
|
199095
199880
|
const projectDir = resolvePath3(args.projectDir);
|
|
199096
199881
|
const stack = requireStack(args.stackName);
|
|
199097
199882
|
const batchPath = resolvePath3(args.batch);
|
|
199098
|
-
if (!
|
|
199883
|
+
if (!existsSync120(batchPath)) {
|
|
199099
199884
|
errorBox("Batch file not found", `No such file: ${batchPath}`);
|
|
199100
199885
|
failCommand();
|
|
199101
199886
|
}
|
|
@@ -199111,7 +199896,7 @@ async function runRenderBatch(args) {
|
|
|
199111
199896
|
outputResolution: args.outputResolution,
|
|
199112
199897
|
quiet: args.json
|
|
199113
199898
|
});
|
|
199114
|
-
const schema = loadProjectVariableSchema(
|
|
199899
|
+
const schema = loadProjectVariableSchema(join129(projectDir, "index.html"));
|
|
199115
199900
|
const strict = args.strictVariables ?? false;
|
|
199116
199901
|
let hadStrictIssue = false;
|
|
199117
199902
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -199246,7 +200031,7 @@ function buildLambdaBatchRenderConfig(args) {
|
|
|
199246
200031
|
return config;
|
|
199247
200032
|
}
|
|
199248
200033
|
function parseBatchFile(path2) {
|
|
199249
|
-
const raw =
|
|
200034
|
+
const raw = readFileSync83(path2, "utf8");
|
|
199250
200035
|
const lines = raw.split(/\r?\n/);
|
|
199251
200036
|
const out = [];
|
|
199252
200037
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
@@ -199440,7 +200225,7 @@ __export(policies_exports, {
|
|
|
199440
200225
|
runPolicies: () => runPolicies,
|
|
199441
200226
|
validatePolicy: () => validatePolicy
|
|
199442
200227
|
});
|
|
199443
|
-
import { readFileSync as
|
|
200228
|
+
import { readFileSync as readFileSync84 } from "fs";
|
|
199444
200229
|
function allRequiredActions() {
|
|
199445
200230
|
const set = /* @__PURE__ */ new Set();
|
|
199446
200231
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -199546,7 +200331,7 @@ async function runPolicies(args) {
|
|
|
199546
200331
|
}
|
|
199547
200332
|
}
|
|
199548
200333
|
function validatePolicy(policyPath) {
|
|
199549
|
-
const raw =
|
|
200334
|
+
const raw = readFileSync84(policyPath, "utf-8");
|
|
199550
200335
|
const parsed = JSON.parse(raw);
|
|
199551
200336
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
199552
200337
|
parsed.Statement
|
|
@@ -200157,9 +200942,9 @@ __export(cloudrun_exports, {
|
|
|
200157
200942
|
missingCloudRunAdapterMessage: () => missingCloudRunAdapterMessage
|
|
200158
200943
|
});
|
|
200159
200944
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
200160
|
-
import { existsSync as
|
|
200161
|
-
import { homedir as
|
|
200162
|
-
import { join as
|
|
200945
|
+
import { existsSync as existsSync121, mkdirSync as mkdirSync61, readFileSync as readFileSync85, writeFileSync as writeFileSync55 } from "fs";
|
|
200946
|
+
import { homedir as homedir22 } from "os";
|
|
200947
|
+
import { join as join130, resolve as resolve76 } from "path";
|
|
200163
200948
|
function loadCloudRunAdapter() {
|
|
200164
200949
|
cloudRunAdapterPromise ??= Promise.all([
|
|
200165
200950
|
import("@hyperframes/gcp-cloud-run/sdk"),
|
|
@@ -200178,14 +200963,14 @@ Or, for an opt-in project setup:
|
|
|
200178
200963
|
${c.accent("npm install @hyperframes/gcp-cloud-run")}`;
|
|
200179
200964
|
}
|
|
200180
200965
|
function stateDir() {
|
|
200181
|
-
return
|
|
200966
|
+
return join130(homedir22(), ".hyperframes");
|
|
200182
200967
|
}
|
|
200183
200968
|
function statePath() {
|
|
200184
|
-
return
|
|
200969
|
+
return join130(stateDir(), "cloudrun-state.json");
|
|
200185
200970
|
}
|
|
200186
200971
|
function writeState(state) {
|
|
200187
|
-
|
|
200188
|
-
|
|
200972
|
+
mkdirSync61(stateDir(), { recursive: true });
|
|
200973
|
+
writeFileSync55(statePath(), JSON.stringify(state, null, 2));
|
|
200189
200974
|
}
|
|
200190
200975
|
function readState(args) {
|
|
200191
200976
|
const overrides = {
|
|
@@ -200193,9 +200978,9 @@ function readState(args) {
|
|
|
200193
200978
|
region: args.region
|
|
200194
200979
|
};
|
|
200195
200980
|
let base2 = {};
|
|
200196
|
-
if (
|
|
200981
|
+
if (existsSync121(statePath())) {
|
|
200197
200982
|
try {
|
|
200198
|
-
base2 = JSON.parse(
|
|
200983
|
+
base2 = JSON.parse(readFileSync85(statePath(), "utf8"));
|
|
200199
200984
|
} catch {
|
|
200200
200985
|
}
|
|
200201
200986
|
}
|
|
@@ -200338,13 +201123,13 @@ function machineVars(args, project, region, image) {
|
|
|
200338
201123
|
}
|
|
200339
201124
|
function findRepoRoot(tfDir) {
|
|
200340
201125
|
const candidate = resolve76(tfDir, "..", "..", "..");
|
|
200341
|
-
if (
|
|
201126
|
+
if (existsSync121(join130(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
|
|
200342
201127
|
return null;
|
|
200343
201128
|
}
|
|
200344
201129
|
function writeCloudBuildConfig(image) {
|
|
200345
|
-
const cfgPath =
|
|
200346
|
-
|
|
200347
|
-
|
|
201130
|
+
const cfgPath = join130(stateDir(), "cloudrun-cloudbuild.yaml");
|
|
201131
|
+
mkdirSync61(stateDir(), { recursive: true });
|
|
201132
|
+
writeFileSync55(
|
|
200348
201133
|
cfgPath,
|
|
200349
201134
|
[
|
|
200350
201135
|
"steps:",
|
|
@@ -200487,7 +201272,7 @@ async function runRenderBatch2(args) {
|
|
|
200487
201272
|
failCommand();
|
|
200488
201273
|
}
|
|
200489
201274
|
const fps = resolveCloudRunFps(args, projectDir, "render-batch");
|
|
200490
|
-
if (!
|
|
201275
|
+
if (!existsSync121(resolve76(batchPath))) {
|
|
200491
201276
|
console.error(`[cloudrun render-batch] batch file not found: ${batchPath}`);
|
|
200492
201277
|
failCommand();
|
|
200493
201278
|
}
|
|
@@ -200554,7 +201339,7 @@ async function runRenderBatch2(args) {
|
|
|
200554
201339
|
if (failed.length > 0) failCommand();
|
|
200555
201340
|
}
|
|
200556
201341
|
function parseBatchFile2(path2) {
|
|
200557
|
-
const lines =
|
|
201342
|
+
const lines = readFileSync85(path2, "utf8").split(/\r?\n/);
|
|
200558
201343
|
const entries2 = [];
|
|
200559
201344
|
lines.forEach((line2, idx) => {
|
|
200560
201345
|
const trimmed = line2.trim();
|
|
@@ -200579,7 +201364,7 @@ function parseBatchFile2(path2) {
|
|
|
200579
201364
|
async function runDestroy2(args) {
|
|
200580
201365
|
const { getTerraformModuleDir } = await loadCloudRunAdapter();
|
|
200581
201366
|
const tfDir = getTerraformModuleDir();
|
|
200582
|
-
const state =
|
|
201367
|
+
const state = existsSync121(statePath()) ? JSON.parse(readFileSync85(statePath(), "utf8")) : {};
|
|
200583
201368
|
const project = args.project ?? state.projectId;
|
|
200584
201369
|
const region = args.region ?? state.region ?? "us-central1";
|
|
200585
201370
|
const image = args.image ?? "unused:latest";
|
|
@@ -200634,8 +201419,8 @@ function resolveAndValidateVariables(args, projectDir) {
|
|
|
200634
201419
|
args["variables-file"]
|
|
200635
201420
|
);
|
|
200636
201421
|
if (variables && Object.keys(variables).length > 0) {
|
|
200637
|
-
const indexPath2 =
|
|
200638
|
-
if (
|
|
201422
|
+
const indexPath2 = join130(projectDir, "index.html");
|
|
201423
|
+
if (existsSync121(indexPath2)) {
|
|
200639
201424
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
200640
201425
|
reportVariableIssues(issues, {
|
|
200641
201426
|
strict: Boolean(args["strict-variables"]),
|
|
@@ -200881,7 +201666,7 @@ ${HELP2}`);
|
|
|
200881
201666
|
});
|
|
200882
201667
|
|
|
200883
201668
|
// src/cloud/detectAspectRatio.ts
|
|
200884
|
-
import { readFileSync as
|
|
201669
|
+
import { readFileSync as readFileSync86 } from "fs";
|
|
200885
201670
|
function extractAttributeNumber(tag, re2) {
|
|
200886
201671
|
const match = tag.match(re2);
|
|
200887
201672
|
if (!match) return null;
|
|
@@ -200893,7 +201678,7 @@ function extractAttributeNumber(tag, re2) {
|
|
|
200893
201678
|
function detectAspectRatioFromHtml(entryHtmlPath) {
|
|
200894
201679
|
let html;
|
|
200895
201680
|
try {
|
|
200896
|
-
html =
|
|
201681
|
+
html = readFileSync86(entryHtmlPath, "utf-8");
|
|
200897
201682
|
} catch (err) {
|
|
200898
201683
|
return { kind: "read-error", error: normalizeErrorMessage(err) };
|
|
200899
201684
|
}
|
|
@@ -200996,7 +201781,7 @@ var init_poll = __esm({
|
|
|
200996
201781
|
});
|
|
200997
201782
|
|
|
200998
201783
|
// src/cloud/download.ts
|
|
200999
|
-
import { createWriteStream as createWriteStream5, mkdirSync as
|
|
201784
|
+
import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync63, unlinkSync as unlinkSync12 } from "fs";
|
|
201000
201785
|
import { dirname as dirname58 } from "path";
|
|
201001
201786
|
async function downloadToFile(url, destPath, options = {}) {
|
|
201002
201787
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -201007,7 +201792,7 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
201007
201792
|
if (!res.body) {
|
|
201008
201793
|
throw new Error(`Failed to download ${url}: empty response body`);
|
|
201009
201794
|
}
|
|
201010
|
-
|
|
201795
|
+
mkdirSync63(dirname58(destPath), { recursive: true });
|
|
201011
201796
|
const totalHeader = res.headers.get("content-length");
|
|
201012
201797
|
const total = totalHeader ? Number.parseInt(totalHeader, 10) : void 0;
|
|
201013
201798
|
const totalOpt = total !== void 0 && Number.isFinite(total) ? total : void 0;
|
|
@@ -201037,7 +201822,7 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
201037
201822
|
await closeFile(file);
|
|
201038
201823
|
if (errored) {
|
|
201039
201824
|
try {
|
|
201040
|
-
|
|
201825
|
+
unlinkSync12(destPath);
|
|
201041
201826
|
} catch {
|
|
201042
201827
|
}
|
|
201043
201828
|
}
|
|
@@ -201487,9 +202272,9 @@ var init_parsing = __esm({
|
|
|
201487
202272
|
});
|
|
201488
202273
|
|
|
201489
202274
|
// src/cloud/upload.ts
|
|
201490
|
-
import { createHash as
|
|
202275
|
+
import { createHash as createHash21 } from "crypto";
|
|
201491
202276
|
function sha256Hex2(bytes) {
|
|
201492
|
-
return
|
|
202277
|
+
return createHash21("sha256").update(bytes).digest("hex");
|
|
201493
202278
|
}
|
|
201494
202279
|
function sleep4(ms) {
|
|
201495
202280
|
return new Promise((r2) => setTimeout(r2, ms));
|
|
@@ -201601,7 +202386,7 @@ __export(render_exports3, {
|
|
|
201601
202386
|
validateResolutionFormatCombo: () => validateResolutionFormatCombo
|
|
201602
202387
|
});
|
|
201603
202388
|
import { isAbsolute as isAbsolute17, relative as relative27, resolve as resolvePath4 } from "path";
|
|
201604
|
-
import { existsSync as
|
|
202389
|
+
import { existsSync as existsSync122 } from "fs";
|
|
201605
202390
|
function parsePollIntervalMs(raw) {
|
|
201606
202391
|
const n2 = parseNumericFlag(raw, { flag: "--poll-interval", min: 1 });
|
|
201607
202392
|
return n2 === void 0 ? DEFAULT_POLL_INTERVAL_MS : Math.round(n2 * 1e3);
|
|
@@ -201651,7 +202436,7 @@ function resolveAspectRatioForSubmit(project, compositionArg, explicit, asJson)
|
|
|
201651
202436
|
const dir = project.dir ?? ".";
|
|
201652
202437
|
const entryRelative = compositionArg ?? "index.html";
|
|
201653
202438
|
const entryPath = resolvePath4(dir, entryRelative);
|
|
201654
|
-
if (!
|
|
202439
|
+
if (!existsSync122(entryPath)) {
|
|
201655
202440
|
errorBox(
|
|
201656
202441
|
"Composition not found",
|
|
201657
202442
|
`Entry file "${entryRelative}" does not exist in ${dir}.`,
|
|
@@ -203682,7 +204467,7 @@ var init_parseFigmaRef = __esm({
|
|
|
203682
204467
|
});
|
|
203683
204468
|
|
|
203684
204469
|
// ../core/dist/figma/freeze.js
|
|
203685
|
-
import { copyFileSync as copyFileSync11, mkdirSync as
|
|
204470
|
+
import { copyFileSync as copyFileSync11, mkdirSync as mkdirSync64, rmSync as rmSync35, statSync as statSync39, writeFileSync as writeFileSync56 } from "fs";
|
|
203686
204471
|
import { dirname as dirname59 } from "path";
|
|
203687
204472
|
function exceedsFreezeCap(byteLength) {
|
|
203688
204473
|
return byteLength > MAX_FREEZE_BYTES;
|
|
@@ -203692,14 +204477,14 @@ function freezeBytes(bytes, destPath) {
|
|
|
203692
204477
|
throw new Error("freeze failed: empty bytes");
|
|
203693
204478
|
if (exceedsFreezeCap(bytes.length))
|
|
203694
204479
|
throw new Error(`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap`);
|
|
203695
|
-
|
|
204480
|
+
mkdirSync64(dirname59(destPath), { recursive: true });
|
|
203696
204481
|
try {
|
|
203697
|
-
|
|
204482
|
+
writeFileSync56(destPath, bytes, { flag: "wx" });
|
|
203698
204483
|
} catch (err) {
|
|
203699
204484
|
if (err.code !== "EEXIST")
|
|
203700
204485
|
throw err;
|
|
203701
204486
|
rmSync35(destPath);
|
|
203702
|
-
|
|
204487
|
+
writeFileSync56(destPath, bytes, { flag: "wx" });
|
|
203703
204488
|
}
|
|
203704
204489
|
return bytes.length;
|
|
203705
204490
|
}
|
|
@@ -203712,12 +204497,12 @@ var init_freeze = __esm({
|
|
|
203712
204497
|
});
|
|
203713
204498
|
|
|
203714
204499
|
// ../core/dist/figma/jsonl.js
|
|
203715
|
-
import { existsSync as
|
|
204500
|
+
import { existsSync as existsSync123, readFileSync as readFileSync87 } from "fs";
|
|
203716
204501
|
function readJsonlValues(path2) {
|
|
203717
|
-
if (!
|
|
204502
|
+
if (!existsSync123(path2))
|
|
203718
204503
|
return [];
|
|
203719
204504
|
const out = [];
|
|
203720
|
-
for (const line2 of
|
|
204505
|
+
for (const line2 of readFileSync87(path2, "utf8").split(/\r?\n/)) {
|
|
203721
204506
|
const trimmed = line2.trim();
|
|
203722
204507
|
if (trimmed.length === 0)
|
|
203723
204508
|
continue;
|
|
@@ -203736,16 +204521,16 @@ var init_jsonl = __esm({
|
|
|
203736
204521
|
});
|
|
203737
204522
|
|
|
203738
204523
|
// ../core/dist/figma/manifest.js
|
|
203739
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
203740
|
-
import { join as
|
|
204524
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync124, mkdirSync as mkdirSync65, readFileSync as readFileSync88, writeFileSync as writeFileSync57 } from "fs";
|
|
204525
|
+
import { join as join131 } from "path";
|
|
203741
204526
|
function mediaDir(projectDir) {
|
|
203742
|
-
return
|
|
204527
|
+
return join131(projectDir, ".media");
|
|
203743
204528
|
}
|
|
203744
204529
|
function manifestPath(projectDir) {
|
|
203745
|
-
return
|
|
204530
|
+
return join131(mediaDir(projectDir), MANIFEST_FILE2);
|
|
203746
204531
|
}
|
|
203747
204532
|
function typeDirPath(projectDir, type) {
|
|
203748
|
-
return
|
|
204533
|
+
return join131(mediaDir(projectDir), TYPE_DIRS[type]);
|
|
203749
204534
|
}
|
|
203750
204535
|
function isFigmaManifestRecord(value) {
|
|
203751
204536
|
if (typeof value !== "object" || value === null)
|
|
@@ -203769,7 +204554,7 @@ function readManifest(projectDir) {
|
|
|
203769
204554
|
return readJsonlValues(manifestPath(projectDir)).filter(isFigmaManifestRecord);
|
|
203770
204555
|
}
|
|
203771
204556
|
function appendRecord(projectDir, record) {
|
|
203772
|
-
|
|
204557
|
+
mkdirSync65(typeDirPath(projectDir, record.type), { recursive: true });
|
|
203773
204558
|
appendFileSync2(manifestPath(projectDir), JSON.stringify(record) + "\n");
|
|
203774
204559
|
}
|
|
203775
204560
|
function findAllByFigmaNode(projectDir, fileKey, nodeId) {
|
|
@@ -203777,7 +204562,7 @@ function findAllByFigmaNode(projectDir, fileKey, nodeId) {
|
|
|
203777
204562
|
}
|
|
203778
204563
|
function updateRecord(projectDir, record) {
|
|
203779
204564
|
const p2 = manifestPath(projectDir);
|
|
203780
|
-
const lines =
|
|
204565
|
+
const lines = readFileSync88(p2, "utf8").split(/\r?\n/);
|
|
203781
204566
|
const out = lines.map((line2) => {
|
|
203782
204567
|
const trimmed = line2.trim();
|
|
203783
204568
|
if (trimmed.length === 0)
|
|
@@ -203790,15 +204575,15 @@ function updateRecord(projectDir, record) {
|
|
|
203790
204575
|
}
|
|
203791
204576
|
return line2;
|
|
203792
204577
|
});
|
|
203793
|
-
|
|
204578
|
+
writeFileSync57(p2, out.join("\n"));
|
|
203794
204579
|
}
|
|
203795
204580
|
function nextId(projectDir, type) {
|
|
203796
204581
|
const re2 = new RegExp(`^${type}_(\\d+)$`);
|
|
203797
204582
|
let max = 0;
|
|
203798
204583
|
const p2 = manifestPath(projectDir);
|
|
203799
|
-
if (!
|
|
204584
|
+
if (!existsSync124(p2))
|
|
203800
204585
|
return `${type}_001`;
|
|
203801
|
-
for (const line2 of
|
|
204586
|
+
for (const line2 of readFileSync88(p2, "utf8").split(/\r?\n/)) {
|
|
203802
204587
|
const trimmed = line2.trim();
|
|
203803
204588
|
if (trimmed.length === 0)
|
|
203804
204589
|
continue;
|
|
@@ -203831,13 +204616,13 @@ var init_manifest = __esm({
|
|
|
203831
204616
|
});
|
|
203832
204617
|
|
|
203833
204618
|
// ../core/dist/figma/mediaIndex.js
|
|
203834
|
-
import { mkdirSync as
|
|
203835
|
-
import { dirname as dirname60, join as
|
|
204619
|
+
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58 } from "fs";
|
|
204620
|
+
import { dirname as dirname60, join as join133 } from "path";
|
|
203836
204621
|
function isRow(value) {
|
|
203837
204622
|
return typeof value === "object" && value !== null;
|
|
203838
204623
|
}
|
|
203839
204624
|
function indexPath(projectDir) {
|
|
203840
|
-
return
|
|
204625
|
+
return join133(mediaDir(projectDir), "index.md");
|
|
203841
204626
|
}
|
|
203842
204627
|
function pad(str, len2) {
|
|
203843
204628
|
return String(str ?? "").padEnd(len2);
|
|
@@ -203882,8 +204667,8 @@ function regenerateIndex(projectDir) {
|
|
|
203882
204667
|
const records = readJsonlValues(manifestPath(projectDir)).filter(isRow);
|
|
203883
204668
|
const content = generateIndexContent(records);
|
|
203884
204669
|
const p2 = indexPath(projectDir);
|
|
203885
|
-
|
|
203886
|
-
|
|
204670
|
+
mkdirSync66(dirname60(p2), { recursive: true });
|
|
204671
|
+
writeFileSync58(p2, content);
|
|
203887
204672
|
return content;
|
|
203888
204673
|
}
|
|
203889
204674
|
var init_mediaIndex = __esm({
|
|
@@ -203948,10 +204733,10 @@ var init_sanitizeSvg = __esm({
|
|
|
203948
204733
|
});
|
|
203949
204734
|
|
|
203950
204735
|
// ../core/dist/figma/bindings.js
|
|
203951
|
-
import { appendFileSync as appendFileSync3, mkdirSync as
|
|
203952
|
-
import { join as
|
|
204736
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync67, writeFileSync as writeFileSync59 } from "fs";
|
|
204737
|
+
import { join as join134 } from "path";
|
|
203953
204738
|
function bindingsPath(projectDir) {
|
|
203954
|
-
return
|
|
204739
|
+
return join134(mediaDir(projectDir), BINDINGS_FILE);
|
|
203955
204740
|
}
|
|
203956
204741
|
function isRecord15(value) {
|
|
203957
204742
|
return typeof value === "object" && value !== null;
|
|
@@ -203968,9 +204753,9 @@ function readBindings(projectDir) {
|
|
|
203968
204753
|
function upsertBindings(projectDir, records) {
|
|
203969
204754
|
const incoming = new Set(records.map((r2) => r2.figmaId));
|
|
203970
204755
|
const survivors = readLines(projectDir).filter((line2) => !(isBindingRecord(line2) && incoming.has(line2.figmaId)));
|
|
203971
|
-
|
|
204756
|
+
mkdirSync67(mediaDir(projectDir), { recursive: true });
|
|
203972
204757
|
const lines = [...survivors, ...records].map((r2) => JSON.stringify(r2)).join("\n");
|
|
203973
|
-
|
|
204758
|
+
writeFileSync59(bindingsPath(projectDir), lines.length > 0 ? lines + "\n" : "");
|
|
203974
204759
|
}
|
|
203975
204760
|
var BINDINGS_FILE;
|
|
203976
204761
|
var init_bindings = __esm({
|
|
@@ -204551,8 +205336,8 @@ __export(asset_exports, {
|
|
|
204551
205336
|
runAssetImport: () => runAssetImport,
|
|
204552
205337
|
runAssetImportMany: () => runAssetImportMany
|
|
204553
205338
|
});
|
|
204554
|
-
import { existsSync as
|
|
204555
|
-
import { join as
|
|
205339
|
+
import { existsSync as existsSync125 } from "fs";
|
|
205340
|
+
import { join as join135, relative as relative28 } from "path";
|
|
204556
205341
|
function gatherAssetRefs(positionals) {
|
|
204557
205342
|
return positionals.flatMap((r2) => /^https?:/i.test(r2.trim()) ? [r2] : r2.split(",")).map((r2) => r2.trim()).filter((r2) => r2.length > 0);
|
|
204558
205343
|
}
|
|
@@ -204566,7 +205351,7 @@ function requireNodeRef(refInput) {
|
|
|
204566
205351
|
}
|
|
204567
205352
|
function reuseExisting(fileKey, nodeId, opts, version2, deps, description, entity) {
|
|
204568
205353
|
const existing = findAllByFigmaNode(deps.projectDir, fileKey, nodeId).find(
|
|
204569
|
-
(r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 &&
|
|
205354
|
+
(r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 && existsSync125(join135(deps.projectDir, r2.path))
|
|
204570
205355
|
);
|
|
204571
205356
|
if (!existing) return null;
|
|
204572
205357
|
let record = existing;
|
|
@@ -204589,7 +205374,7 @@ async function freezeAndRecord(fileKey, nodeId, url, ext, opts, version2, deps,
|
|
|
204589
205374
|
bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
|
|
204590
205375
|
}
|
|
204591
205376
|
const id = nextId(deps.projectDir, "image");
|
|
204592
|
-
const destAbs =
|
|
205377
|
+
const destAbs = join135(typeDirPath(deps.projectDir, "image"), `${id}.${ext}`);
|
|
204593
205378
|
freezeBytes(bytes, destAbs);
|
|
204594
205379
|
const record = {
|
|
204595
205380
|
id,
|
|
@@ -204758,12 +205543,12 @@ __export(tokens_exports, {
|
|
|
204758
205543
|
default: () => tokens_default,
|
|
204759
205544
|
runTokensImport: () => runTokensImport
|
|
204760
205545
|
});
|
|
204761
|
-
import { writeFileSync as
|
|
204762
|
-
import { join as
|
|
205546
|
+
import { writeFileSync as writeFileSync60 } from "fs";
|
|
205547
|
+
import { join as join136 } from "path";
|
|
204763
205548
|
async function runTokensImport(refInput, deps) {
|
|
204764
205549
|
const { fileKey } = parseFigmaRef(refInput);
|
|
204765
205550
|
const { version: version2 } = await deps.client.fileVersion(fileKey);
|
|
204766
|
-
const sidecarPath =
|
|
205551
|
+
const sidecarPath = join136(deps.projectDir, "figma-tokens.json");
|
|
204767
205552
|
let vars = null;
|
|
204768
205553
|
try {
|
|
204769
205554
|
vars = await deps.client.variables(fileKey);
|
|
@@ -204773,7 +205558,7 @@ async function runTokensImport(refInput, deps) {
|
|
|
204773
205558
|
if (vars !== null) {
|
|
204774
205559
|
const out = tokensToVariables(vars, { fileKey, version: version2 });
|
|
204775
205560
|
upsertBindings(deps.projectDir, out.bindings);
|
|
204776
|
-
|
|
205561
|
+
writeFileSync60(sidecarPath, JSON.stringify(out.sidecar, null, 2) + "\n");
|
|
204777
205562
|
return { mode: "variables", entries: out.entries, sidecarPath };
|
|
204778
205563
|
}
|
|
204779
205564
|
const styles = await deps.client.styles(fileKey);
|
|
@@ -204787,7 +205572,7 @@ async function runTokensImport(refInput, deps) {
|
|
|
204787
205572
|
value: null
|
|
204788
205573
|
}))
|
|
204789
205574
|
};
|
|
204790
|
-
|
|
205575
|
+
writeFileSync60(sidecarPath, JSON.stringify(sidecar, null, 2) + "\n");
|
|
204791
205576
|
return { mode: "styles", entries: [], sidecarPath, styleCount: styles.length };
|
|
204792
205577
|
}
|
|
204793
205578
|
var tokens_default;
|
|
@@ -204837,8 +205622,8 @@ __export(component_exports, {
|
|
|
204837
205622
|
default: () => component_default,
|
|
204838
205623
|
runComponentImport: () => runComponentImport
|
|
204839
205624
|
});
|
|
204840
|
-
import { existsSync as
|
|
204841
|
-
import { join as
|
|
205625
|
+
import { existsSync as existsSync126, mkdirSync as mkdirSync68, writeFileSync as writeFileSync61 } from "fs";
|
|
205626
|
+
import { join as join137, relative as relative29 } from "path";
|
|
204842
205627
|
function escapeAttr2(value) {
|
|
204843
205628
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
204844
205629
|
}
|
|
@@ -204849,20 +205634,20 @@ async function runComponentImport(refInput, deps) {
|
|
|
204849
205634
|
const bindings = resolveBindings(tree, readBindings(deps.projectDir));
|
|
204850
205635
|
const mapped = nodeToHtml(tree, bindings, { rootName: deps.name });
|
|
204851
205636
|
const name = slugify(deps.name ?? tree.name);
|
|
204852
|
-
const componentDir =
|
|
204853
|
-
if (
|
|
205637
|
+
const componentDir = join137(deps.projectDir, "compositions", "components", name);
|
|
205638
|
+
if (existsSync126(componentDir))
|
|
204854
205639
|
console.warn(
|
|
204855
205640
|
`component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
|
|
204856
205641
|
);
|
|
204857
|
-
|
|
205642
|
+
mkdirSync68(componentDir, { recursive: true });
|
|
204858
205643
|
const { html, frozenAssets, failedRasterize } = await rasterizeFallback(
|
|
204859
205644
|
mapped,
|
|
204860
205645
|
ref2.fileKey,
|
|
204861
205646
|
componentDir,
|
|
204862
205647
|
deps
|
|
204863
205648
|
);
|
|
204864
|
-
const htmlFile =
|
|
204865
|
-
|
|
205649
|
+
const htmlFile = join137(componentDir, `${name}.html`);
|
|
205650
|
+
writeFileSync61(htmlFile, html + "\n");
|
|
204866
205651
|
const registryItem = {
|
|
204867
205652
|
name,
|
|
204868
205653
|
type: "hyperframes:component",
|
|
@@ -204882,8 +205667,8 @@ async function runComponentImport(refInput, deps) {
|
|
|
204882
205667
|
}))
|
|
204883
205668
|
]
|
|
204884
205669
|
};
|
|
204885
|
-
|
|
204886
|
-
|
|
205670
|
+
writeFileSync61(
|
|
205671
|
+
join137(componentDir, "registry-item.json"),
|
|
204887
205672
|
JSON.stringify(registryItem, null, 2) + "\n"
|
|
204888
205673
|
);
|
|
204889
205674
|
return {
|
|
@@ -204908,7 +205693,7 @@ async function rasterizeFallback(mapped, fileKey, componentDir, deps) {
|
|
|
204908
205693
|
continue;
|
|
204909
205694
|
}
|
|
204910
205695
|
frozenAssets.push(asset.record.path);
|
|
204911
|
-
const srcRel = relative29(componentDir,
|
|
205696
|
+
const srcRel = relative29(componentDir, join137(deps.projectDir, asset.record.path)).replaceAll(
|
|
204912
205697
|
"\\",
|
|
204913
205698
|
"/"
|
|
204914
205699
|
);
|
|
@@ -205055,9 +205840,9 @@ __export(autoUpdate_exports, {
|
|
|
205055
205840
|
scheduleBackgroundInstall: () => scheduleBackgroundInstall
|
|
205056
205841
|
});
|
|
205057
205842
|
import { spawn as spawn16 } from "child_process";
|
|
205058
|
-
import { appendFileSync as appendFileSync4, mkdirSync as
|
|
205059
|
-
import { homedir as
|
|
205060
|
-
import { join as
|
|
205843
|
+
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync69, openSync as openSync8 } from "fs";
|
|
205844
|
+
import { homedir as homedir23 } from "os";
|
|
205845
|
+
import { join as join138 } from "path";
|
|
205061
205846
|
import { compareVersions as compareVersions3 } from "compare-versions";
|
|
205062
205847
|
function isAutoInstallDisabled() {
|
|
205063
205848
|
if (isDevMode()) return true;
|
|
@@ -205072,15 +205857,15 @@ function majorOf(version2) {
|
|
|
205072
205857
|
}
|
|
205073
205858
|
function log(line2) {
|
|
205074
205859
|
try {
|
|
205075
|
-
|
|
205860
|
+
mkdirSync69(CONFIG_DIR3, { recursive: true, mode: 448 });
|
|
205076
205861
|
appendFileSync4(LOG_FILE, `${(/* @__PURE__ */ new Date()).toISOString()} ${line2}
|
|
205077
205862
|
`, { mode: 384 });
|
|
205078
205863
|
} catch {
|
|
205079
205864
|
}
|
|
205080
205865
|
}
|
|
205081
205866
|
function launchDetachedInstall(invocation, displayCommand, version2) {
|
|
205082
|
-
|
|
205083
|
-
const configFile =
|
|
205867
|
+
mkdirSync69(CONFIG_DIR3, { recursive: true, mode: 448 });
|
|
205868
|
+
const configFile = join138(CONFIG_DIR3, "config.json");
|
|
205084
205869
|
const nodeScript = `
|
|
205085
205870
|
const { execFile } = require("node:child_process");
|
|
205086
205871
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -205201,8 +205986,8 @@ var init_autoUpdate = __esm({
|
|
|
205201
205986
|
init_config();
|
|
205202
205987
|
init_env();
|
|
205203
205988
|
init_installerDetection();
|
|
205204
|
-
CONFIG_DIR3 =
|
|
205205
|
-
LOG_FILE =
|
|
205989
|
+
CONFIG_DIR3 = join138(homedir23(), ".hyperframes");
|
|
205990
|
+
LOG_FILE = join138(CONFIG_DIR3, "auto-update.log");
|
|
205206
205991
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
205207
205992
|
}
|
|
205208
205993
|
});
|
|
@@ -205393,9 +206178,9 @@ var init_help = __esm({
|
|
|
205393
206178
|
init_version();
|
|
205394
206179
|
init_dist();
|
|
205395
206180
|
init_runId();
|
|
205396
|
-
import { dirname as dirname61, join as
|
|
206181
|
+
import { dirname as dirname61, join as join139 } from "path";
|
|
205397
206182
|
import { fileURLToPath as fileURLToPath16 } from "url";
|
|
205398
|
-
import { existsSync as
|
|
206183
|
+
import { existsSync as existsSync127 } from "fs";
|
|
205399
206184
|
|
|
205400
206185
|
// src/utils/reject-unknown-flags.ts
|
|
205401
206186
|
var ALWAYS_KNOWN = /* @__PURE__ */ new Set(["help", "h", "version", "v", "json"]);
|
|
@@ -205512,8 +206297,8 @@ for (const stream of [process.stdout, process.stderr]) {
|
|
|
205512
206297
|
}
|
|
205513
206298
|
(() => {
|
|
205514
206299
|
const here = dirname61(fileURLToPath16(import.meta.url));
|
|
205515
|
-
const shader =
|
|
205516
|
-
if (!process.env.HF_SHADER_WORKER_ENTRY &&
|
|
206300
|
+
const shader = join139(here, "shaderTransitionWorker.js");
|
|
206301
|
+
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync127(shader)) {
|
|
205517
206302
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
205518
206303
|
}
|
|
205519
206304
|
})();
|
|
@@ -205525,10 +206310,10 @@ if (rootVersionRequested) {
|
|
|
205525
206310
|
process.exit(0);
|
|
205526
206311
|
}
|
|
205527
206312
|
try {
|
|
205528
|
-
const { readFileSync:
|
|
206313
|
+
const { readFileSync: readFileSync89 } = await import("fs");
|
|
205529
206314
|
const { resolve: resolve77 } = await import("path");
|
|
205530
206315
|
const envPath = resolve77(process.cwd(), ".env");
|
|
205531
|
-
const envContent =
|
|
206316
|
+
const envContent = readFileSync89(envPath, "utf-8");
|
|
205532
206317
|
for (const rawLine of envContent.split("\n")) {
|
|
205533
206318
|
let line2 = rawLine.trim();
|
|
205534
206319
|
if (!line2 || line2.startsWith("#")) continue;
|