@telepath-computer/television 0.1.215 → 1.3.2
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/THIRD-PARTY-NOTICES.txt +336 -0
- package/dist/canonical/v1/frozen.json +6 -0
- package/dist/canonical/v1/styles.css +7 -2
- package/dist/canonical/v2/components.js +1 -0
- package/dist/canonical/v2/fonts/Hind-Variable.933e9900.woff2 +0 -0
- package/dist/canonical/v2/styles.css +1153 -0
- package/dist/cli.cjs +1820 -775
- package/dist/onboarding/README.md +16 -14
- package/dist/onboarding/business-ops/about.html +4 -3
- package/dist/onboarding/business-ops/retention-vs-releases.html +25 -32
- package/dist/onboarding/business-ops/revenue-vs-goals.html +26 -31
- package/dist/onboarding/productivity/about.html +4 -3
- package/dist/onboarding/productivity/company-todos/THIRD-PARTY-NOTICES.txt +29 -0
- package/dist/onboarding/productivity/company-todos/index.html +20 -20
- package/dist/onboarding/productivity/company-todos/task.css +4 -5
- package/dist/onboarding/productivity/company-todos/task.js +1 -1
- package/dist/onboarding/productivity/meeting-prep.html +12 -12
- package/dist/onboarding/productivity/priorities-today.html +10 -10
- package/dist/onboarding/productivity/todays-calendar/calendar.css +1 -1
- package/dist/onboarding/productivity/todays-calendar/index.html +12 -14
- package/dist/onboarding/research/about.html +4 -3
- package/dist/onboarding/research/open-model-research.html +35 -35
- package/dist/onboarding/research/todays-news.html +72 -72
- package/dist/onboarding/tv-guide/welcome.html +178 -0
- package/dist/skills/television/SKILL.md +122 -67
- package/dist/skills/television/theming.md +1087 -0
- package/dist/skills/tv-calendar/SKILL.md +3 -1
- package/dist/skills/tv-calendar/calendar.css +1 -1
- package/dist/skills/tv-table/SKILL.md +5 -2
- package/dist/skills/tv-tasks/SKILL.md +19 -15
- package/dist/skills/tv-tasks/task.css +4 -26
- package/dist/skills/tv-tasks/task.js +1 -1
- package/dist/themes/README.md +5 -0
- package/dist/themes/aquarium/README.md +48 -0
- package/dist/themes/aquarium/iframe-background.js +137 -0
- package/dist/themes/aquarium/manifest.json +7 -0
- package/dist/themes/aquarium/theme.css +46 -0
- package/dist/themes/blueprint/README.md +31 -0
- package/dist/themes/blueprint/manifest.json +6 -0
- package/dist/themes/blueprint/theme.css +115 -0
- package/dist/themes/clouds/README.md +15 -0
- package/dist/themes/clouds/THIRD-PARTY-NOTICES.txt +81 -0
- package/dist/themes/clouds/manifest.json +6 -0
- package/dist/themes/clouds/theme.css +62 -0
- package/dist/themes/clouds/wallpaper-dark.webp +0 -0
- package/dist/themes/clouds/wallpaper.webp +0 -0
- package/dist/themes/crt-phosphor/README.md +31 -0
- package/dist/themes/crt-phosphor/manifest.json +6 -0
- package/dist/themes/crt-phosphor/theme.css +105 -0
- package/dist/themes/nord/README.md +9 -0
- package/dist/themes/nord/THIRD-PARTY-NOTICES.txt +29 -0
- package/dist/themes/nord/manifest.json +5 -0
- package/dist/themes/nord/theme.css +28 -0
- package/dist/themes/swiss/README.md +5 -0
- package/dist/themes/swiss/manifest.json +5 -0
- package/dist/themes/swiss/theme.css +34 -0
- package/dist/themes/tokyo-night/README.md +17 -0
- package/dist/themes/tokyo-night/THIRD-PARTY-NOTICES.txt +235 -0
- package/dist/themes/tokyo-night/manifest.json +5 -0
- package/dist/themes/tokyo-night/theme.css +31 -0
- package/dist/themes/tokyo-night/wallpaper.webp +0 -0
- package/dist/views/artifact-missing/index.html +40 -68
- package/dist/views/markdown/THIRD-PARTY-NOTICES.txt +26 -0
- package/dist/views/markdown/index.html +49 -23
- package/dist/web/THIRD-PARTY-NOTICES.txt +26 -0
- package/dist/web/assets/artifact-bridge-BEUWXKq7.js +1 -0
- package/dist/web/assets/{artifactMissing-9rcTXhkH.js → artifactMissing-CUs1ZwDx.js} +1 -1
- package/dist/web/assets/main-3UimTRLK.css +1 -0
- package/dist/web/assets/main-CSSzbG7q.js +704 -0
- package/dist/web/assets/{urlUnsupported-kgq7Zh2V.js → urlUnsupported-powR79PT.js} +1 -1
- package/dist/web/index.html +40 -5
- package/dist/web/views/artifact-missing/index.html +40 -68
- package/dist/web/views/url-unsupported/index.html +40 -68
- package/package.json +1 -1
- package/dist/onboarding/tv-guide/welcome/assets/television.svg +0 -71
- package/dist/onboarding/tv-guide/welcome/index.html +0 -203
- package/dist/skills/tv-theme/SKILL.md +0 -449
- package/dist/web/assets/artifact-bridge-BXDhGuL-.js +0 -1
- package/dist/web/assets/clouds-CAYIArXj.jpg +0 -0
- package/dist/web/assets/main-Blg8fuaV.css +0 -1
- package/dist/web/assets/main-Z-io-D9l.js +0 -596
package/dist/cli.cjs
CHANGED
|
@@ -1194,7 +1194,7 @@ var require_command = __commonJS({
|
|
|
1194
1194
|
"../../node_modules/commander/lib/command.js"(exports2) {
|
|
1195
1195
|
var EventEmitter2 = require("node:events").EventEmitter;
|
|
1196
1196
|
var childProcess = require("node:child_process");
|
|
1197
|
-
var
|
|
1197
|
+
var path19 = require("node:path");
|
|
1198
1198
|
var fs4 = require("node:fs");
|
|
1199
1199
|
var process3 = require("node:process");
|
|
1200
1200
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -2207,9 +2207,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2207
2207
|
let launchWithNode = false;
|
|
2208
2208
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2209
2209
|
function findFile(baseDir, baseName) {
|
|
2210
|
-
const localBin =
|
|
2210
|
+
const localBin = path19.resolve(baseDir, baseName);
|
|
2211
2211
|
if (fs4.existsSync(localBin)) return localBin;
|
|
2212
|
-
if (sourceExt.includes(
|
|
2212
|
+
if (sourceExt.includes(path19.extname(baseName))) return void 0;
|
|
2213
2213
|
const foundExt = sourceExt.find(
|
|
2214
2214
|
(ext) => fs4.existsSync(`${localBin}${ext}`)
|
|
2215
2215
|
);
|
|
@@ -2227,17 +2227,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2227
2227
|
} catch {
|
|
2228
2228
|
resolvedScriptPath = this._scriptPath;
|
|
2229
2229
|
}
|
|
2230
|
-
executableDir =
|
|
2231
|
-
|
|
2230
|
+
executableDir = path19.resolve(
|
|
2231
|
+
path19.dirname(resolvedScriptPath),
|
|
2232
2232
|
executableDir
|
|
2233
2233
|
);
|
|
2234
2234
|
}
|
|
2235
2235
|
if (executableDir) {
|
|
2236
2236
|
let localFile = findFile(executableDir, executableFile);
|
|
2237
2237
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2238
|
-
const legacyName =
|
|
2238
|
+
const legacyName = path19.basename(
|
|
2239
2239
|
this._scriptPath,
|
|
2240
|
-
|
|
2240
|
+
path19.extname(this._scriptPath)
|
|
2241
2241
|
);
|
|
2242
2242
|
if (legacyName !== this._name) {
|
|
2243
2243
|
localFile = findFile(
|
|
@@ -2248,7 +2248,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2248
2248
|
}
|
|
2249
2249
|
executableFile = localFile || executableFile;
|
|
2250
2250
|
}
|
|
2251
|
-
launchWithNode = sourceExt.includes(
|
|
2251
|
+
launchWithNode = sourceExt.includes(path19.extname(executableFile));
|
|
2252
2252
|
let proc;
|
|
2253
2253
|
if (process3.platform !== "win32") {
|
|
2254
2254
|
if (launchWithNode) {
|
|
@@ -3163,7 +3163,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3163
3163
|
* @return {Command}
|
|
3164
3164
|
*/
|
|
3165
3165
|
nameFromFilename(filename) {
|
|
3166
|
-
this._name =
|
|
3166
|
+
this._name = path19.basename(filename, path19.extname(filename));
|
|
3167
3167
|
return this;
|
|
3168
3168
|
}
|
|
3169
3169
|
/**
|
|
@@ -3177,9 +3177,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3177
3177
|
* @param {string} [path]
|
|
3178
3178
|
* @return {(string|null|Command)}
|
|
3179
3179
|
*/
|
|
3180
|
-
executableDir(
|
|
3181
|
-
if (
|
|
3182
|
-
this._executableDir =
|
|
3180
|
+
executableDir(path20) {
|
|
3181
|
+
if (path20 === void 0) return this._executableDir;
|
|
3182
|
+
this._executableDir = path20;
|
|
3183
3183
|
return this;
|
|
3184
3184
|
}
|
|
3185
3185
|
/**
|
|
@@ -21480,11 +21480,11 @@ var require_mime_types = __commonJS({
|
|
|
21480
21480
|
}
|
|
21481
21481
|
return exts[0];
|
|
21482
21482
|
}
|
|
21483
|
-
function lookup(
|
|
21484
|
-
if (!
|
|
21483
|
+
function lookup(path19) {
|
|
21484
|
+
if (!path19 || typeof path19 !== "string") {
|
|
21485
21485
|
return false;
|
|
21486
21486
|
}
|
|
21487
|
-
var extension3 = extname("x." +
|
|
21487
|
+
var extension3 = extname("x." + path19).toLowerCase().substr(1);
|
|
21488
21488
|
if (!extension3) {
|
|
21489
21489
|
return false;
|
|
21490
21490
|
}
|
|
@@ -24307,7 +24307,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
24307
24307
|
"../../node_modules/path-to-regexp/index.js"(exports2, module2) {
|
|
24308
24308
|
module2.exports = pathToRegexp;
|
|
24309
24309
|
var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
|
|
24310
|
-
function pathToRegexp(
|
|
24310
|
+
function pathToRegexp(path19, keys, options) {
|
|
24311
24311
|
options = options || {};
|
|
24312
24312
|
keys = keys || [];
|
|
24313
24313
|
var strict = options.strict;
|
|
@@ -24321,8 +24321,8 @@ var require_path_to_regexp = __commonJS({
|
|
|
24321
24321
|
var pos = 0;
|
|
24322
24322
|
var backtrack = "";
|
|
24323
24323
|
var m2;
|
|
24324
|
-
if (
|
|
24325
|
-
while (m2 = MATCHING_GROUP_REGEXP.exec(
|
|
24324
|
+
if (path19 instanceof RegExp) {
|
|
24325
|
+
while (m2 = MATCHING_GROUP_REGEXP.exec(path19.source)) {
|
|
24326
24326
|
if (m2[0][0] === "\\") continue;
|
|
24327
24327
|
keys.push({
|
|
24328
24328
|
name: m2[1] || name++,
|
|
@@ -24330,18 +24330,18 @@ var require_path_to_regexp = __commonJS({
|
|
|
24330
24330
|
offset: m2.index
|
|
24331
24331
|
});
|
|
24332
24332
|
}
|
|
24333
|
-
return
|
|
24333
|
+
return path19;
|
|
24334
24334
|
}
|
|
24335
|
-
if (Array.isArray(
|
|
24336
|
-
|
|
24335
|
+
if (Array.isArray(path19)) {
|
|
24336
|
+
path19 = path19.map(function(value) {
|
|
24337
24337
|
return pathToRegexp(value, keys, options).source;
|
|
24338
24338
|
});
|
|
24339
|
-
return new RegExp(
|
|
24339
|
+
return new RegExp(path19.join("|"), flags);
|
|
24340
24340
|
}
|
|
24341
|
-
if (typeof
|
|
24341
|
+
if (typeof path19 !== "string") {
|
|
24342
24342
|
throw new TypeError("path must be a string, array of strings, or regular expression");
|
|
24343
24343
|
}
|
|
24344
|
-
|
|
24344
|
+
path19 = path19.replace(
|
|
24345
24345
|
/\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
|
|
24346
24346
|
function(match, slash, format, key, capture2, star, optional2, offset) {
|
|
24347
24347
|
if (match[0] === "\\") {
|
|
@@ -24358,7 +24358,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
24358
24358
|
if (slash || format) {
|
|
24359
24359
|
backtrack = "";
|
|
24360
24360
|
} else {
|
|
24361
|
-
backtrack +=
|
|
24361
|
+
backtrack += path19.slice(pos, offset);
|
|
24362
24362
|
}
|
|
24363
24363
|
pos = offset + match.length;
|
|
24364
24364
|
if (match === "*") {
|
|
@@ -24388,7 +24388,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
24388
24388
|
return result;
|
|
24389
24389
|
}
|
|
24390
24390
|
);
|
|
24391
|
-
while (m2 = MATCHING_GROUP_REGEXP.exec(
|
|
24391
|
+
while (m2 = MATCHING_GROUP_REGEXP.exec(path19)) {
|
|
24392
24392
|
if (m2[0][0] === "\\") continue;
|
|
24393
24393
|
if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m2.index) {
|
|
24394
24394
|
keys.splice(keysOffset + i, 0, {
|
|
@@ -24400,13 +24400,13 @@ var require_path_to_regexp = __commonJS({
|
|
|
24400
24400
|
}
|
|
24401
24401
|
i++;
|
|
24402
24402
|
}
|
|
24403
|
-
|
|
24403
|
+
path19 += strict ? "" : path19[path19.length - 1] === "/" ? "?" : "/?";
|
|
24404
24404
|
if (end) {
|
|
24405
|
-
|
|
24406
|
-
} else if (
|
|
24407
|
-
|
|
24405
|
+
path19 += "$";
|
|
24406
|
+
} else if (path19[path19.length - 1] !== "/") {
|
|
24407
|
+
path19 += lookahead ? "(?=/|$)" : "(?:/|$)";
|
|
24408
24408
|
}
|
|
24409
|
-
return new RegExp("^" +
|
|
24409
|
+
return new RegExp("^" + path19, flags);
|
|
24410
24410
|
}
|
|
24411
24411
|
}
|
|
24412
24412
|
});
|
|
@@ -24419,19 +24419,19 @@ var require_layer = __commonJS({
|
|
|
24419
24419
|
var debug = require_src3()("express:router:layer");
|
|
24420
24420
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
24421
24421
|
module2.exports = Layer;
|
|
24422
|
-
function Layer(
|
|
24422
|
+
function Layer(path19, options, fn) {
|
|
24423
24423
|
if (!(this instanceof Layer)) {
|
|
24424
|
-
return new Layer(
|
|
24424
|
+
return new Layer(path19, options, fn);
|
|
24425
24425
|
}
|
|
24426
|
-
debug("new %o",
|
|
24426
|
+
debug("new %o", path19);
|
|
24427
24427
|
var opts = options || {};
|
|
24428
24428
|
this.handle = fn;
|
|
24429
24429
|
this.name = fn.name || "<anonymous>";
|
|
24430
24430
|
this.params = void 0;
|
|
24431
24431
|
this.path = void 0;
|
|
24432
|
-
this.regexp = pathRegexp(
|
|
24433
|
-
this.regexp.fast_star =
|
|
24434
|
-
this.regexp.fast_slash =
|
|
24432
|
+
this.regexp = pathRegexp(path19, this.keys = [], opts);
|
|
24433
|
+
this.regexp.fast_star = path19 === "*";
|
|
24434
|
+
this.regexp.fast_slash = path19 === "/" && opts.end === false;
|
|
24435
24435
|
}
|
|
24436
24436
|
Layer.prototype.handle_error = function handle_error(error48, req, res, next) {
|
|
24437
24437
|
var fn = this.handle;
|
|
@@ -24455,20 +24455,20 @@ var require_layer = __commonJS({
|
|
|
24455
24455
|
next(err);
|
|
24456
24456
|
}
|
|
24457
24457
|
};
|
|
24458
|
-
Layer.prototype.match = function match(
|
|
24458
|
+
Layer.prototype.match = function match(path19) {
|
|
24459
24459
|
var match2;
|
|
24460
|
-
if (
|
|
24460
|
+
if (path19 != null) {
|
|
24461
24461
|
if (this.regexp.fast_slash) {
|
|
24462
24462
|
this.params = {};
|
|
24463
24463
|
this.path = "";
|
|
24464
24464
|
return true;
|
|
24465
24465
|
}
|
|
24466
24466
|
if (this.regexp.fast_star) {
|
|
24467
|
-
this.params = { "0": decode_param(
|
|
24468
|
-
this.path =
|
|
24467
|
+
this.params = { "0": decode_param(path19) };
|
|
24468
|
+
this.path = path19;
|
|
24469
24469
|
return true;
|
|
24470
24470
|
}
|
|
24471
|
-
match2 = this.regexp.exec(
|
|
24471
|
+
match2 = this.regexp.exec(path19);
|
|
24472
24472
|
}
|
|
24473
24473
|
if (!match2) {
|
|
24474
24474
|
this.params = void 0;
|
|
@@ -24561,10 +24561,10 @@ var require_route = __commonJS({
|
|
|
24561
24561
|
var slice = Array.prototype.slice;
|
|
24562
24562
|
var toString = Object.prototype.toString;
|
|
24563
24563
|
module2.exports = Route;
|
|
24564
|
-
function Route(
|
|
24565
|
-
this.path =
|
|
24564
|
+
function Route(path19) {
|
|
24565
|
+
this.path = path19;
|
|
24566
24566
|
this.stack = [];
|
|
24567
|
-
debug("new %o",
|
|
24567
|
+
debug("new %o", path19);
|
|
24568
24568
|
this.methods = {};
|
|
24569
24569
|
}
|
|
24570
24570
|
Route.prototype._handles_method = function _handles_method(method) {
|
|
@@ -24776,8 +24776,8 @@ var require_router = __commonJS({
|
|
|
24776
24776
|
if (++sync > 100) {
|
|
24777
24777
|
return setImmediate(next, err);
|
|
24778
24778
|
}
|
|
24779
|
-
var
|
|
24780
|
-
if (
|
|
24779
|
+
var path19 = getPathname(req);
|
|
24780
|
+
if (path19 == null) {
|
|
24781
24781
|
return done(layerError);
|
|
24782
24782
|
}
|
|
24783
24783
|
var layer;
|
|
@@ -24785,7 +24785,7 @@ var require_router = __commonJS({
|
|
|
24785
24785
|
var route;
|
|
24786
24786
|
while (match !== true && idx < stack.length) {
|
|
24787
24787
|
layer = stack[idx++];
|
|
24788
|
-
match = matchLayer(layer,
|
|
24788
|
+
match = matchLayer(layer, path19);
|
|
24789
24789
|
route = layer.route;
|
|
24790
24790
|
if (typeof match !== "boolean") {
|
|
24791
24791
|
layerError = layerError || match;
|
|
@@ -24823,18 +24823,18 @@ var require_router = __commonJS({
|
|
|
24823
24823
|
} else if (route) {
|
|
24824
24824
|
layer.handle_request(req, res, next);
|
|
24825
24825
|
} else {
|
|
24826
|
-
trim_prefix(layer, layerError, layerPath,
|
|
24826
|
+
trim_prefix(layer, layerError, layerPath, path19);
|
|
24827
24827
|
}
|
|
24828
24828
|
sync = 0;
|
|
24829
24829
|
});
|
|
24830
24830
|
}
|
|
24831
|
-
function trim_prefix(layer, layerError, layerPath,
|
|
24831
|
+
function trim_prefix(layer, layerError, layerPath, path19) {
|
|
24832
24832
|
if (layerPath.length !== 0) {
|
|
24833
|
-
if (layerPath !==
|
|
24833
|
+
if (layerPath !== path19.slice(0, layerPath.length)) {
|
|
24834
24834
|
next(layerError);
|
|
24835
24835
|
return;
|
|
24836
24836
|
}
|
|
24837
|
-
var c =
|
|
24837
|
+
var c = path19[layerPath.length];
|
|
24838
24838
|
if (c && c !== "/" && c !== ".") return next(layerError);
|
|
24839
24839
|
debug("trim prefix (%s) from url %s", layerPath, req.url);
|
|
24840
24840
|
removed = layerPath;
|
|
@@ -24912,7 +24912,7 @@ var require_router = __commonJS({
|
|
|
24912
24912
|
};
|
|
24913
24913
|
proto.use = function use(fn) {
|
|
24914
24914
|
var offset = 0;
|
|
24915
|
-
var
|
|
24915
|
+
var path19 = "/";
|
|
24916
24916
|
if (typeof fn !== "function") {
|
|
24917
24917
|
var arg = fn;
|
|
24918
24918
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -24920,7 +24920,7 @@ var require_router = __commonJS({
|
|
|
24920
24920
|
}
|
|
24921
24921
|
if (typeof arg !== "function") {
|
|
24922
24922
|
offset = 1;
|
|
24923
|
-
|
|
24923
|
+
path19 = fn;
|
|
24924
24924
|
}
|
|
24925
24925
|
}
|
|
24926
24926
|
var callbacks = flatten(slice.call(arguments, offset));
|
|
@@ -24932,8 +24932,8 @@ var require_router = __commonJS({
|
|
|
24932
24932
|
if (typeof fn !== "function") {
|
|
24933
24933
|
throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
|
|
24934
24934
|
}
|
|
24935
|
-
debug("use %o %s",
|
|
24936
|
-
var layer = new Layer(
|
|
24935
|
+
debug("use %o %s", path19, fn.name || "<anonymous>");
|
|
24936
|
+
var layer = new Layer(path19, {
|
|
24937
24937
|
sensitive: this.caseSensitive,
|
|
24938
24938
|
strict: false,
|
|
24939
24939
|
end: false
|
|
@@ -24943,9 +24943,9 @@ var require_router = __commonJS({
|
|
|
24943
24943
|
}
|
|
24944
24944
|
return this;
|
|
24945
24945
|
};
|
|
24946
|
-
proto.route = function route(
|
|
24947
|
-
var route2 = new Route(
|
|
24948
|
-
var layer = new Layer(
|
|
24946
|
+
proto.route = function route(path19) {
|
|
24947
|
+
var route2 = new Route(path19);
|
|
24948
|
+
var layer = new Layer(path19, {
|
|
24949
24949
|
sensitive: this.caseSensitive,
|
|
24950
24950
|
strict: this.strict,
|
|
24951
24951
|
end: true
|
|
@@ -24955,8 +24955,8 @@ var require_router = __commonJS({
|
|
|
24955
24955
|
return route2;
|
|
24956
24956
|
};
|
|
24957
24957
|
methods.concat("all").forEach(function(method) {
|
|
24958
|
-
proto[method] = function(
|
|
24959
|
-
var route = this.route(
|
|
24958
|
+
proto[method] = function(path19) {
|
|
24959
|
+
var route = this.route(path19);
|
|
24960
24960
|
route[method].apply(route, slice.call(arguments, 1));
|
|
24961
24961
|
return this;
|
|
24962
24962
|
};
|
|
@@ -24992,9 +24992,9 @@ var require_router = __commonJS({
|
|
|
24992
24992
|
}
|
|
24993
24993
|
return toString.call(obj).replace(objectRegExp, "$1");
|
|
24994
24994
|
}
|
|
24995
|
-
function matchLayer(layer,
|
|
24995
|
+
function matchLayer(layer, path19) {
|
|
24996
24996
|
try {
|
|
24997
|
-
return layer.match(
|
|
24997
|
+
return layer.match(path19);
|
|
24998
24998
|
} catch (err) {
|
|
24999
24999
|
return err;
|
|
25000
25000
|
}
|
|
@@ -25995,13 +25995,13 @@ var require_view = __commonJS({
|
|
|
25995
25995
|
"../../node_modules/express/lib/view.js"(exports2, module2) {
|
|
25996
25996
|
"use strict";
|
|
25997
25997
|
var debug = require_src3()("express:view");
|
|
25998
|
-
var
|
|
25998
|
+
var path19 = require("path");
|
|
25999
25999
|
var fs4 = require("fs");
|
|
26000
|
-
var dirname =
|
|
26001
|
-
var basename =
|
|
26002
|
-
var extname =
|
|
26003
|
-
var join2 =
|
|
26004
|
-
var resolve =
|
|
26000
|
+
var dirname = path19.dirname;
|
|
26001
|
+
var basename = path19.basename;
|
|
26002
|
+
var extname = path19.extname;
|
|
26003
|
+
var join2 = path19.join;
|
|
26004
|
+
var resolve = path19.resolve;
|
|
26005
26005
|
module2.exports = View;
|
|
26006
26006
|
function View(name, options) {
|
|
26007
26007
|
var opts = options || {};
|
|
@@ -26030,17 +26030,17 @@ var require_view = __commonJS({
|
|
|
26030
26030
|
this.path = this.lookup(fileName);
|
|
26031
26031
|
}
|
|
26032
26032
|
View.prototype.lookup = function lookup(name) {
|
|
26033
|
-
var
|
|
26033
|
+
var path20;
|
|
26034
26034
|
var roots = [].concat(this.root);
|
|
26035
26035
|
debug('lookup "%s"', name);
|
|
26036
|
-
for (var i = 0; i < roots.length && !
|
|
26036
|
+
for (var i = 0; i < roots.length && !path20; i++) {
|
|
26037
26037
|
var root = roots[i];
|
|
26038
26038
|
var loc = resolve(root, name);
|
|
26039
26039
|
var dir = dirname(loc);
|
|
26040
26040
|
var file2 = basename(loc);
|
|
26041
|
-
|
|
26041
|
+
path20 = this.resolve(dir, file2);
|
|
26042
26042
|
}
|
|
26043
|
-
return
|
|
26043
|
+
return path20;
|
|
26044
26044
|
};
|
|
26045
26045
|
View.prototype.render = function render(options, callback) {
|
|
26046
26046
|
debug('render "%s"', this.path);
|
|
@@ -26048,21 +26048,21 @@ var require_view = __commonJS({
|
|
|
26048
26048
|
};
|
|
26049
26049
|
View.prototype.resolve = function resolve2(dir, file2) {
|
|
26050
26050
|
var ext = this.ext;
|
|
26051
|
-
var
|
|
26052
|
-
var stat = tryStat(
|
|
26051
|
+
var path20 = join2(dir, file2);
|
|
26052
|
+
var stat = tryStat(path20);
|
|
26053
26053
|
if (stat && stat.isFile()) {
|
|
26054
|
-
return
|
|
26054
|
+
return path20;
|
|
26055
26055
|
}
|
|
26056
|
-
|
|
26057
|
-
stat = tryStat(
|
|
26056
|
+
path20 = join2(dir, basename(file2, ext), "index" + ext);
|
|
26057
|
+
stat = tryStat(path20);
|
|
26058
26058
|
if (stat && stat.isFile()) {
|
|
26059
|
-
return
|
|
26059
|
+
return path20;
|
|
26060
26060
|
}
|
|
26061
26061
|
};
|
|
26062
|
-
function tryStat(
|
|
26063
|
-
debug('stat "%s"',
|
|
26062
|
+
function tryStat(path20) {
|
|
26063
|
+
debug('stat "%s"', path20);
|
|
26064
26064
|
try {
|
|
26065
|
-
return fs4.statSync(
|
|
26065
|
+
return fs4.statSync(path20);
|
|
26066
26066
|
} catch (e) {
|
|
26067
26067
|
return void 0;
|
|
26068
26068
|
}
|
|
@@ -26840,7 +26840,7 @@ var require_types = __commonJS({
|
|
|
26840
26840
|
// ../../node_modules/mime/mime.js
|
|
26841
26841
|
var require_mime = __commonJS({
|
|
26842
26842
|
"../../node_modules/mime/mime.js"(exports2, module2) {
|
|
26843
|
-
var
|
|
26843
|
+
var path19 = require("path");
|
|
26844
26844
|
var fs4 = require("fs");
|
|
26845
26845
|
function Mime() {
|
|
26846
26846
|
this.types = /* @__PURE__ */ Object.create(null);
|
|
@@ -26870,8 +26870,8 @@ var require_mime = __commonJS({
|
|
|
26870
26870
|
this.define(map2);
|
|
26871
26871
|
this._loading = null;
|
|
26872
26872
|
};
|
|
26873
|
-
Mime.prototype.lookup = function(
|
|
26874
|
-
var ext =
|
|
26873
|
+
Mime.prototype.lookup = function(path20, fallback) {
|
|
26874
|
+
var ext = path20.replace(/^.*[\.\/\\]/, "").toLowerCase();
|
|
26875
26875
|
return this.types[ext] || fallback || this.default_type;
|
|
26876
26876
|
};
|
|
26877
26877
|
Mime.prototype.extension = function(mimeType) {
|
|
@@ -27105,28 +27105,28 @@ var require_send = __commonJS({
|
|
|
27105
27105
|
var ms = require_ms5();
|
|
27106
27106
|
var onFinished = require_on_finished();
|
|
27107
27107
|
var parseRange = require_range_parser();
|
|
27108
|
-
var
|
|
27108
|
+
var path19 = require("path");
|
|
27109
27109
|
var statuses = require_statuses();
|
|
27110
27110
|
var Stream = require("stream");
|
|
27111
27111
|
var util = require("util");
|
|
27112
|
-
var extname =
|
|
27113
|
-
var join2 =
|
|
27114
|
-
var normalize =
|
|
27115
|
-
var resolve =
|
|
27116
|
-
var sep =
|
|
27112
|
+
var extname = path19.extname;
|
|
27113
|
+
var join2 = path19.join;
|
|
27114
|
+
var normalize = path19.normalize;
|
|
27115
|
+
var resolve = path19.resolve;
|
|
27116
|
+
var sep = path19.sep;
|
|
27117
27117
|
var BYTES_RANGE_REGEXP = /^ *bytes=/;
|
|
27118
27118
|
var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
|
|
27119
27119
|
var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
|
27120
27120
|
module2.exports = send2;
|
|
27121
27121
|
module2.exports.mime = mime;
|
|
27122
|
-
function send2(req,
|
|
27123
|
-
return new SendStream(req,
|
|
27122
|
+
function send2(req, path20, options) {
|
|
27123
|
+
return new SendStream(req, path20, options);
|
|
27124
27124
|
}
|
|
27125
|
-
function SendStream(req,
|
|
27125
|
+
function SendStream(req, path20, options) {
|
|
27126
27126
|
Stream.call(this);
|
|
27127
27127
|
var opts = options || {};
|
|
27128
27128
|
this.options = opts;
|
|
27129
|
-
this.path =
|
|
27129
|
+
this.path = path20;
|
|
27130
27130
|
this.req = req;
|
|
27131
27131
|
this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
|
|
27132
27132
|
this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
|
|
@@ -27172,8 +27172,8 @@ var require_send = __commonJS({
|
|
|
27172
27172
|
this._index = index2;
|
|
27173
27173
|
return this;
|
|
27174
27174
|
}, "send.index: pass index as option");
|
|
27175
|
-
SendStream.prototype.root = function root(
|
|
27176
|
-
this._root = resolve(String(
|
|
27175
|
+
SendStream.prototype.root = function root(path20) {
|
|
27176
|
+
this._root = resolve(String(path20));
|
|
27177
27177
|
debug("root %s", this._root);
|
|
27178
27178
|
return this;
|
|
27179
27179
|
};
|
|
@@ -27286,10 +27286,10 @@ var require_send = __commonJS({
|
|
|
27286
27286
|
var lastModified = this.res.getHeader("Last-Modified");
|
|
27287
27287
|
return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
|
|
27288
27288
|
};
|
|
27289
|
-
SendStream.prototype.redirect = function redirect(
|
|
27289
|
+
SendStream.prototype.redirect = function redirect(path20) {
|
|
27290
27290
|
var res = this.res;
|
|
27291
27291
|
if (hasListeners(this, "directory")) {
|
|
27292
|
-
this.emit("directory", res,
|
|
27292
|
+
this.emit("directory", res, path20);
|
|
27293
27293
|
return;
|
|
27294
27294
|
}
|
|
27295
27295
|
if (this.hasTrailingSlash()) {
|
|
@@ -27309,42 +27309,42 @@ var require_send = __commonJS({
|
|
|
27309
27309
|
SendStream.prototype.pipe = function pipe2(res) {
|
|
27310
27310
|
var root = this._root;
|
|
27311
27311
|
this.res = res;
|
|
27312
|
-
var
|
|
27313
|
-
if (
|
|
27312
|
+
var path20 = decode3(this.path);
|
|
27313
|
+
if (path20 === -1) {
|
|
27314
27314
|
this.error(400);
|
|
27315
27315
|
return res;
|
|
27316
27316
|
}
|
|
27317
|
-
if (~
|
|
27317
|
+
if (~path20.indexOf("\0")) {
|
|
27318
27318
|
this.error(400);
|
|
27319
27319
|
return res;
|
|
27320
27320
|
}
|
|
27321
27321
|
var parts;
|
|
27322
27322
|
if (root !== null) {
|
|
27323
|
-
if (
|
|
27324
|
-
|
|
27323
|
+
if (path20) {
|
|
27324
|
+
path20 = normalize("." + sep + path20);
|
|
27325
27325
|
}
|
|
27326
|
-
if (UP_PATH_REGEXP.test(
|
|
27327
|
-
debug('malicious path "%s"',
|
|
27326
|
+
if (UP_PATH_REGEXP.test(path20)) {
|
|
27327
|
+
debug('malicious path "%s"', path20);
|
|
27328
27328
|
this.error(403);
|
|
27329
27329
|
return res;
|
|
27330
27330
|
}
|
|
27331
|
-
parts =
|
|
27332
|
-
|
|
27331
|
+
parts = path20.split(sep);
|
|
27332
|
+
path20 = normalize(join2(root, path20));
|
|
27333
27333
|
} else {
|
|
27334
|
-
if (UP_PATH_REGEXP.test(
|
|
27335
|
-
debug('malicious path "%s"',
|
|
27334
|
+
if (UP_PATH_REGEXP.test(path20)) {
|
|
27335
|
+
debug('malicious path "%s"', path20);
|
|
27336
27336
|
this.error(403);
|
|
27337
27337
|
return res;
|
|
27338
27338
|
}
|
|
27339
|
-
parts = normalize(
|
|
27340
|
-
|
|
27339
|
+
parts = normalize(path20).split(sep);
|
|
27340
|
+
path20 = resolve(path20);
|
|
27341
27341
|
}
|
|
27342
27342
|
if (containsDotFile(parts)) {
|
|
27343
27343
|
var access2 = this._dotfiles;
|
|
27344
27344
|
if (access2 === void 0) {
|
|
27345
27345
|
access2 = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
|
|
27346
27346
|
}
|
|
27347
|
-
debug('%s dotfile "%s"', access2,
|
|
27347
|
+
debug('%s dotfile "%s"', access2, path20);
|
|
27348
27348
|
switch (access2) {
|
|
27349
27349
|
case "allow":
|
|
27350
27350
|
break;
|
|
@@ -27358,13 +27358,13 @@ var require_send = __commonJS({
|
|
|
27358
27358
|
}
|
|
27359
27359
|
}
|
|
27360
27360
|
if (this._index.length && this.hasTrailingSlash()) {
|
|
27361
|
-
this.sendIndex(
|
|
27361
|
+
this.sendIndex(path20);
|
|
27362
27362
|
return res;
|
|
27363
27363
|
}
|
|
27364
|
-
this.sendFile(
|
|
27364
|
+
this.sendFile(path20);
|
|
27365
27365
|
return res;
|
|
27366
27366
|
};
|
|
27367
|
-
SendStream.prototype.send = function send3(
|
|
27367
|
+
SendStream.prototype.send = function send3(path20, stat) {
|
|
27368
27368
|
var len = stat.size;
|
|
27369
27369
|
var options = this.options;
|
|
27370
27370
|
var opts = {};
|
|
@@ -27376,9 +27376,9 @@ var require_send = __commonJS({
|
|
|
27376
27376
|
this.headersAlreadySent();
|
|
27377
27377
|
return;
|
|
27378
27378
|
}
|
|
27379
|
-
debug('pipe "%s"',
|
|
27380
|
-
this.setHeader(
|
|
27381
|
-
this.type(
|
|
27379
|
+
debug('pipe "%s"', path20);
|
|
27380
|
+
this.setHeader(path20, stat);
|
|
27381
|
+
this.type(path20);
|
|
27382
27382
|
if (this.isConditionalGET()) {
|
|
27383
27383
|
if (this.isPreconditionFailure()) {
|
|
27384
27384
|
this.error(412);
|
|
@@ -27427,26 +27427,26 @@ var require_send = __commonJS({
|
|
|
27427
27427
|
res.end();
|
|
27428
27428
|
return;
|
|
27429
27429
|
}
|
|
27430
|
-
this.stream(
|
|
27430
|
+
this.stream(path20, opts);
|
|
27431
27431
|
};
|
|
27432
|
-
SendStream.prototype.sendFile = function sendFile(
|
|
27432
|
+
SendStream.prototype.sendFile = function sendFile(path20) {
|
|
27433
27433
|
var i = 0;
|
|
27434
27434
|
var self2 = this;
|
|
27435
|
-
debug('stat "%s"',
|
|
27436
|
-
fs4.stat(
|
|
27437
|
-
if (err && err.code === "ENOENT" && !extname(
|
|
27435
|
+
debug('stat "%s"', path20);
|
|
27436
|
+
fs4.stat(path20, function onstat(err, stat) {
|
|
27437
|
+
if (err && err.code === "ENOENT" && !extname(path20) && path20[path20.length - 1] !== sep) {
|
|
27438
27438
|
return next(err);
|
|
27439
27439
|
}
|
|
27440
27440
|
if (err) return self2.onStatError(err);
|
|
27441
|
-
if (stat.isDirectory()) return self2.redirect(
|
|
27442
|
-
self2.emit("file",
|
|
27443
|
-
self2.send(
|
|
27441
|
+
if (stat.isDirectory()) return self2.redirect(path20);
|
|
27442
|
+
self2.emit("file", path20, stat);
|
|
27443
|
+
self2.send(path20, stat);
|
|
27444
27444
|
});
|
|
27445
27445
|
function next(err) {
|
|
27446
27446
|
if (self2._extensions.length <= i) {
|
|
27447
27447
|
return err ? self2.onStatError(err) : self2.error(404);
|
|
27448
27448
|
}
|
|
27449
|
-
var p =
|
|
27449
|
+
var p = path20 + "." + self2._extensions[i++];
|
|
27450
27450
|
debug('stat "%s"', p);
|
|
27451
27451
|
fs4.stat(p, function(err2, stat) {
|
|
27452
27452
|
if (err2) return next(err2);
|
|
@@ -27456,7 +27456,7 @@ var require_send = __commonJS({
|
|
|
27456
27456
|
});
|
|
27457
27457
|
}
|
|
27458
27458
|
};
|
|
27459
|
-
SendStream.prototype.sendIndex = function sendIndex(
|
|
27459
|
+
SendStream.prototype.sendIndex = function sendIndex(path20) {
|
|
27460
27460
|
var i = -1;
|
|
27461
27461
|
var self2 = this;
|
|
27462
27462
|
function next(err) {
|
|
@@ -27464,7 +27464,7 @@ var require_send = __commonJS({
|
|
|
27464
27464
|
if (err) return self2.onStatError(err);
|
|
27465
27465
|
return self2.error(404);
|
|
27466
27466
|
}
|
|
27467
|
-
var p = join2(
|
|
27467
|
+
var p = join2(path20, self2._index[i]);
|
|
27468
27468
|
debug('stat "%s"', p);
|
|
27469
27469
|
fs4.stat(p, function(err2, stat) {
|
|
27470
27470
|
if (err2) return next(err2);
|
|
@@ -27475,10 +27475,10 @@ var require_send = __commonJS({
|
|
|
27475
27475
|
}
|
|
27476
27476
|
next();
|
|
27477
27477
|
};
|
|
27478
|
-
SendStream.prototype.stream = function stream(
|
|
27478
|
+
SendStream.prototype.stream = function stream(path20, options) {
|
|
27479
27479
|
var self2 = this;
|
|
27480
27480
|
var res = this.res;
|
|
27481
|
-
var stream2 = fs4.createReadStream(
|
|
27481
|
+
var stream2 = fs4.createReadStream(path20, options);
|
|
27482
27482
|
this.emit("stream", stream2);
|
|
27483
27483
|
stream2.pipe(res);
|
|
27484
27484
|
function cleanup() {
|
|
@@ -27493,10 +27493,10 @@ var require_send = __commonJS({
|
|
|
27493
27493
|
self2.emit("end");
|
|
27494
27494
|
});
|
|
27495
27495
|
};
|
|
27496
|
-
SendStream.prototype.type = function type(
|
|
27496
|
+
SendStream.prototype.type = function type(path20) {
|
|
27497
27497
|
var res = this.res;
|
|
27498
27498
|
if (res.getHeader("Content-Type")) return;
|
|
27499
|
-
var type2 = mime.lookup(
|
|
27499
|
+
var type2 = mime.lookup(path20);
|
|
27500
27500
|
if (!type2) {
|
|
27501
27501
|
debug("no content-type");
|
|
27502
27502
|
return;
|
|
@@ -27505,9 +27505,9 @@ var require_send = __commonJS({
|
|
|
27505
27505
|
debug("content-type %s", type2);
|
|
27506
27506
|
res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
|
|
27507
27507
|
};
|
|
27508
|
-
SendStream.prototype.setHeader = function setHeader(
|
|
27508
|
+
SendStream.prototype.setHeader = function setHeader(path20, stat) {
|
|
27509
27509
|
var res = this.res;
|
|
27510
|
-
this.emit("headers", res,
|
|
27510
|
+
this.emit("headers", res, path20, stat);
|
|
27511
27511
|
if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
|
|
27512
27512
|
debug("accept ranges");
|
|
27513
27513
|
res.setHeader("Accept-Ranges", "bytes");
|
|
@@ -27566,9 +27566,9 @@ var require_send = __commonJS({
|
|
|
27566
27566
|
}
|
|
27567
27567
|
return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
|
|
27568
27568
|
}
|
|
27569
|
-
function decode3(
|
|
27569
|
+
function decode3(path20) {
|
|
27570
27570
|
try {
|
|
27571
|
-
return decodeURIComponent(
|
|
27571
|
+
return decodeURIComponent(path20);
|
|
27572
27572
|
} catch (err) {
|
|
27573
27573
|
return -1;
|
|
27574
27574
|
}
|
|
@@ -28477,10 +28477,10 @@ var require_utils3 = __commonJS({
|
|
|
28477
28477
|
var querystring = require("querystring");
|
|
28478
28478
|
exports2.etag = createETagGenerator({ weak: false });
|
|
28479
28479
|
exports2.wetag = createETagGenerator({ weak: true });
|
|
28480
|
-
exports2.isAbsolute = function(
|
|
28481
|
-
if ("/" ===
|
|
28482
|
-
if (":" ===
|
|
28483
|
-
if ("\\\\" ===
|
|
28480
|
+
exports2.isAbsolute = function(path19) {
|
|
28481
|
+
if ("/" === path19[0]) return true;
|
|
28482
|
+
if (":" === path19[1] && ("\\" === path19[2] || "/" === path19[2])) return true;
|
|
28483
|
+
if ("\\\\" === path19.substring(0, 2)) return true;
|
|
28484
28484
|
};
|
|
28485
28485
|
exports2.flatten = deprecate.function(
|
|
28486
28486
|
flatten,
|
|
@@ -28691,7 +28691,7 @@ var require_application = __commonJS({
|
|
|
28691
28691
|
};
|
|
28692
28692
|
app.use = function use(fn) {
|
|
28693
28693
|
var offset = 0;
|
|
28694
|
-
var
|
|
28694
|
+
var path19 = "/";
|
|
28695
28695
|
if (typeof fn !== "function") {
|
|
28696
28696
|
var arg = fn;
|
|
28697
28697
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -28699,7 +28699,7 @@ var require_application = __commonJS({
|
|
|
28699
28699
|
}
|
|
28700
28700
|
if (typeof arg !== "function") {
|
|
28701
28701
|
offset = 1;
|
|
28702
|
-
|
|
28702
|
+
path19 = fn;
|
|
28703
28703
|
}
|
|
28704
28704
|
}
|
|
28705
28705
|
var fns = flatten(slice.call(arguments, offset));
|
|
@@ -28710,12 +28710,12 @@ var require_application = __commonJS({
|
|
|
28710
28710
|
var router = this._router;
|
|
28711
28711
|
fns.forEach(function(fn2) {
|
|
28712
28712
|
if (!fn2 || !fn2.handle || !fn2.set) {
|
|
28713
|
-
return router.use(
|
|
28713
|
+
return router.use(path19, fn2);
|
|
28714
28714
|
}
|
|
28715
|
-
debug(".use app under %s",
|
|
28716
|
-
fn2.mountpath =
|
|
28715
|
+
debug(".use app under %s", path19);
|
|
28716
|
+
fn2.mountpath = path19;
|
|
28717
28717
|
fn2.parent = this;
|
|
28718
|
-
router.use(
|
|
28718
|
+
router.use(path19, function mounted_app(req, res, next) {
|
|
28719
28719
|
var orig = req.app;
|
|
28720
28720
|
fn2.handle(req, res, function(err) {
|
|
28721
28721
|
setPrototypeOf(req, orig.request);
|
|
@@ -28727,9 +28727,9 @@ var require_application = __commonJS({
|
|
|
28727
28727
|
}, this);
|
|
28728
28728
|
return this;
|
|
28729
28729
|
};
|
|
28730
|
-
app.route = function route(
|
|
28730
|
+
app.route = function route(path19) {
|
|
28731
28731
|
this.lazyrouter();
|
|
28732
|
-
return this._router.route(
|
|
28732
|
+
return this._router.route(path19);
|
|
28733
28733
|
};
|
|
28734
28734
|
app.engine = function engine(ext, fn) {
|
|
28735
28735
|
if (typeof fn !== "function") {
|
|
@@ -28780,7 +28780,7 @@ var require_application = __commonJS({
|
|
|
28780
28780
|
}
|
|
28781
28781
|
return this;
|
|
28782
28782
|
};
|
|
28783
|
-
app.path = function
|
|
28783
|
+
app.path = function path19() {
|
|
28784
28784
|
return this.parent ? this.parent.path() + this.mountpath : "";
|
|
28785
28785
|
};
|
|
28786
28786
|
app.enabled = function enabled(setting) {
|
|
@@ -28796,19 +28796,19 @@ var require_application = __commonJS({
|
|
|
28796
28796
|
return this.set(setting, false);
|
|
28797
28797
|
};
|
|
28798
28798
|
methods.forEach(function(method) {
|
|
28799
|
-
app[method] = function(
|
|
28799
|
+
app[method] = function(path19) {
|
|
28800
28800
|
if (method === "get" && arguments.length === 1) {
|
|
28801
|
-
return this.set(
|
|
28801
|
+
return this.set(path19);
|
|
28802
28802
|
}
|
|
28803
28803
|
this.lazyrouter();
|
|
28804
|
-
var route = this._router.route(
|
|
28804
|
+
var route = this._router.route(path19);
|
|
28805
28805
|
route[method].apply(route, slice.call(arguments, 1));
|
|
28806
28806
|
return this;
|
|
28807
28807
|
};
|
|
28808
28808
|
});
|
|
28809
|
-
app.all = function all(
|
|
28809
|
+
app.all = function all(path19) {
|
|
28810
28810
|
this.lazyrouter();
|
|
28811
|
-
var route = this._router.route(
|
|
28811
|
+
var route = this._router.route(path19);
|
|
28812
28812
|
var args = slice.call(arguments, 1);
|
|
28813
28813
|
for (var i = 0; i < methods.length; i++) {
|
|
28814
28814
|
route[methods[i]].apply(route, args);
|
|
@@ -29567,7 +29567,7 @@ var require_request = __commonJS({
|
|
|
29567
29567
|
var subdomains2 = !isIP2(hostname3) ? hostname3.split(".").reverse() : [hostname3];
|
|
29568
29568
|
return subdomains2.slice(offset);
|
|
29569
29569
|
});
|
|
29570
|
-
defineGetter(req, "path", function
|
|
29570
|
+
defineGetter(req, "path", function path19() {
|
|
29571
29571
|
return parse3(this).pathname;
|
|
29572
29572
|
});
|
|
29573
29573
|
defineGetter(req, "hostname", function hostname3() {
|
|
@@ -29889,7 +29889,7 @@ var require_response = __commonJS({
|
|
|
29889
29889
|
var http2 = require("http");
|
|
29890
29890
|
var isAbsolute = require_utils3().isAbsolute;
|
|
29891
29891
|
var onFinished = require_on_finished();
|
|
29892
|
-
var
|
|
29892
|
+
var path19 = require("path");
|
|
29893
29893
|
var statuses = require_statuses();
|
|
29894
29894
|
var merge2 = require_utils_merge();
|
|
29895
29895
|
var sign = require_cookie_signature().sign;
|
|
@@ -29898,9 +29898,9 @@ var require_response = __commonJS({
|
|
|
29898
29898
|
var setCharset = require_utils3().setCharset;
|
|
29899
29899
|
var cookie = require_cookie();
|
|
29900
29900
|
var send2 = require_send();
|
|
29901
|
-
var extname =
|
|
29901
|
+
var extname = path19.extname;
|
|
29902
29902
|
var mime = send2.mime;
|
|
29903
|
-
var resolve =
|
|
29903
|
+
var resolve = path19.resolve;
|
|
29904
29904
|
var vary = require_vary();
|
|
29905
29905
|
var res = Object.create(http2.ServerResponse.prototype);
|
|
29906
29906
|
module2.exports = res;
|
|
@@ -30077,26 +30077,26 @@ var require_response = __commonJS({
|
|
|
30077
30077
|
this.type("txt");
|
|
30078
30078
|
return this.send(body);
|
|
30079
30079
|
};
|
|
30080
|
-
res.sendFile = function sendFile(
|
|
30080
|
+
res.sendFile = function sendFile(path20, options, callback) {
|
|
30081
30081
|
var done = callback;
|
|
30082
30082
|
var req = this.req;
|
|
30083
30083
|
var res2 = this;
|
|
30084
30084
|
var next = req.next;
|
|
30085
30085
|
var opts = options || {};
|
|
30086
|
-
if (!
|
|
30086
|
+
if (!path20) {
|
|
30087
30087
|
throw new TypeError("path argument is required to res.sendFile");
|
|
30088
30088
|
}
|
|
30089
|
-
if (typeof
|
|
30089
|
+
if (typeof path20 !== "string") {
|
|
30090
30090
|
throw new TypeError("path must be a string to res.sendFile");
|
|
30091
30091
|
}
|
|
30092
30092
|
if (typeof options === "function") {
|
|
30093
30093
|
done = options;
|
|
30094
30094
|
opts = {};
|
|
30095
30095
|
}
|
|
30096
|
-
if (!opts.root && !isAbsolute(
|
|
30096
|
+
if (!opts.root && !isAbsolute(path20)) {
|
|
30097
30097
|
throw new TypeError("path must be absolute or specify root to res.sendFile");
|
|
30098
30098
|
}
|
|
30099
|
-
var pathname = encodeURI(
|
|
30099
|
+
var pathname = encodeURI(path20);
|
|
30100
30100
|
var file2 = send2(req, pathname, opts);
|
|
30101
30101
|
sendfile(res2, file2, opts, function(err) {
|
|
30102
30102
|
if (done) return done(err);
|
|
@@ -30106,7 +30106,7 @@ var require_response = __commonJS({
|
|
|
30106
30106
|
}
|
|
30107
30107
|
});
|
|
30108
30108
|
};
|
|
30109
|
-
res.sendfile = function(
|
|
30109
|
+
res.sendfile = function(path20, options, callback) {
|
|
30110
30110
|
var done = callback;
|
|
30111
30111
|
var req = this.req;
|
|
30112
30112
|
var res2 = this;
|
|
@@ -30116,7 +30116,7 @@ var require_response = __commonJS({
|
|
|
30116
30116
|
done = options;
|
|
30117
30117
|
opts = {};
|
|
30118
30118
|
}
|
|
30119
|
-
var file2 = send2(req,
|
|
30119
|
+
var file2 = send2(req, path20, opts);
|
|
30120
30120
|
sendfile(res2, file2, opts, function(err) {
|
|
30121
30121
|
if (done) return done(err);
|
|
30122
30122
|
if (err && err.code === "EISDIR") return next();
|
|
@@ -30129,7 +30129,7 @@ var require_response = __commonJS({
|
|
|
30129
30129
|
res.sendfile,
|
|
30130
30130
|
"res.sendfile: Use res.sendFile instead"
|
|
30131
30131
|
);
|
|
30132
|
-
res.download = function download(
|
|
30132
|
+
res.download = function download(path20, filename, options, callback) {
|
|
30133
30133
|
var done = callback;
|
|
30134
30134
|
var name = filename;
|
|
30135
30135
|
var opts = options || null;
|
|
@@ -30146,7 +30146,7 @@ var require_response = __commonJS({
|
|
|
30146
30146
|
opts = filename;
|
|
30147
30147
|
}
|
|
30148
30148
|
var headers = {
|
|
30149
|
-
"Content-Disposition": contentDisposition(name ||
|
|
30149
|
+
"Content-Disposition": contentDisposition(name || path20)
|
|
30150
30150
|
};
|
|
30151
30151
|
if (opts && opts.headers) {
|
|
30152
30152
|
var keys = Object.keys(opts.headers);
|
|
@@ -30159,7 +30159,7 @@ var require_response = __commonJS({
|
|
|
30159
30159
|
}
|
|
30160
30160
|
opts = Object.create(opts);
|
|
30161
30161
|
opts.headers = headers;
|
|
30162
|
-
var fullPath = !opts.root ? resolve(
|
|
30162
|
+
var fullPath = !opts.root ? resolve(path20) : path20;
|
|
30163
30163
|
return this.sendFile(fullPath, opts, done);
|
|
30164
30164
|
};
|
|
30165
30165
|
res.contentType = res.type = function contentType(type) {
|
|
@@ -30460,11 +30460,11 @@ var require_serve_static = __commonJS({
|
|
|
30460
30460
|
}
|
|
30461
30461
|
var forwardError = !fallthrough;
|
|
30462
30462
|
var originalUrl = parseUrl.original(req);
|
|
30463
|
-
var
|
|
30464
|
-
if (
|
|
30465
|
-
|
|
30463
|
+
var path19 = parseUrl(req).pathname;
|
|
30464
|
+
if (path19 === "/" && originalUrl.pathname.substr(-1) !== "/") {
|
|
30465
|
+
path19 = "";
|
|
30466
30466
|
}
|
|
30467
|
-
var stream = send2(req,
|
|
30467
|
+
var stream = send2(req, path19, opts);
|
|
30468
30468
|
stream.on("directory", onDirectory);
|
|
30469
30469
|
if (setHeaders) {
|
|
30470
30470
|
stream.on("headers", setHeaders);
|
|
@@ -32803,7 +32803,7 @@ var require_websocket = __commonJS({
|
|
|
32803
32803
|
var http2 = require("http");
|
|
32804
32804
|
var net = require("net");
|
|
32805
32805
|
var tls = require("tls");
|
|
32806
|
-
var { randomBytes: randomBytes3, createHash:
|
|
32806
|
+
var { randomBytes: randomBytes3, createHash: createHash4 } = require("crypto");
|
|
32807
32807
|
var { Duplex, Readable } = require("stream");
|
|
32808
32808
|
var { URL: URL2 } = require("url");
|
|
32809
32809
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -33463,7 +33463,7 @@ var require_websocket = __commonJS({
|
|
|
33463
33463
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
33464
33464
|
return;
|
|
33465
33465
|
}
|
|
33466
|
-
const digest =
|
|
33466
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
33467
33467
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
33468
33468
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
33469
33469
|
return;
|
|
@@ -33830,7 +33830,7 @@ var require_websocket_server = __commonJS({
|
|
|
33830
33830
|
var EventEmitter2 = require("events");
|
|
33831
33831
|
var http2 = require("http");
|
|
33832
33832
|
var { Duplex } = require("stream");
|
|
33833
|
-
var { createHash:
|
|
33833
|
+
var { createHash: createHash4 } = require("crypto");
|
|
33834
33834
|
var extension2 = require_extension();
|
|
33835
33835
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
33836
33836
|
var subprotocol2 = require_subprotocol();
|
|
@@ -34131,7 +34131,7 @@ var require_websocket_server = __commonJS({
|
|
|
34131
34131
|
);
|
|
34132
34132
|
}
|
|
34133
34133
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
34134
|
-
const digest =
|
|
34134
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
34135
34135
|
const headers = [
|
|
34136
34136
|
"HTTP/1.1 101 Switching Protocols",
|
|
34137
34137
|
"Upgrade: websocket",
|
|
@@ -34223,6 +34223,7 @@ __export(index_exports, {
|
|
|
34223
34223
|
inspectTelemetryBuildConfig: () => inspectTelemetryBuildConfig,
|
|
34224
34224
|
listVisibleCLICommandNames: () => listVisibleCLICommandNames,
|
|
34225
34225
|
resolveBundledSkillsRoot: () => resolveBundledSkillsRoot,
|
|
34226
|
+
resolveBundledThemesPath: () => resolveBundledThemesPath,
|
|
34226
34227
|
resolveBundledViewsPath: () => resolveBundledViewsPath,
|
|
34227
34228
|
resolveCanonicalDir: () => resolveCanonicalDir,
|
|
34228
34229
|
resolveOnboardingContentPath: () => resolveOnboardingContentPath,
|
|
@@ -34231,9 +34232,9 @@ __export(index_exports, {
|
|
|
34231
34232
|
});
|
|
34232
34233
|
module.exports = __toCommonJS(index_exports);
|
|
34233
34234
|
var import_node_child_process3 = require("node:child_process");
|
|
34234
|
-
var
|
|
34235
|
+
var import_node_fs17 = require("node:fs");
|
|
34235
34236
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
34236
|
-
var
|
|
34237
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
34237
34238
|
var import_node_module = require("node:module");
|
|
34238
34239
|
var import_node_url2 = require("node:url");
|
|
34239
34240
|
|
|
@@ -34386,22 +34387,22 @@ var Daemon = class {
|
|
|
34386
34387
|
}
|
|
34387
34388
|
async install() {
|
|
34388
34389
|
if (this.platform === "darwin") {
|
|
34389
|
-
const
|
|
34390
|
-
if ((0, import_node_fs.existsSync)(
|
|
34391
|
-
await this.exec("launchctl", ["unload", "-w",
|
|
34390
|
+
const path19 = plistPath(this.home, this.name);
|
|
34391
|
+
if ((0, import_node_fs.existsSync)(path19)) {
|
|
34392
|
+
await this.exec("launchctl", ["unload", "-w", path19]).catch(() => void 0);
|
|
34392
34393
|
}
|
|
34393
34394
|
await (0, import_promises.mkdir)((0, import_node_path.join)(this.home, "Library", "LaunchAgents"), { recursive: true });
|
|
34394
|
-
await (0, import_promises.writeFile)(
|
|
34395
|
-
await this.exec("launchctl", ["load", "-w",
|
|
34395
|
+
await (0, import_promises.writeFile)(path19, renderPlist(this.name, this.programArgs, this.env), "utf8");
|
|
34396
|
+
await this.exec("launchctl", ["load", "-w", path19]);
|
|
34396
34397
|
return;
|
|
34397
34398
|
}
|
|
34398
34399
|
if (this.platform === "linux") {
|
|
34399
|
-
const
|
|
34400
|
-
if ((0, import_node_fs.existsSync)(
|
|
34400
|
+
const path19 = unitPath(this.home, this.name);
|
|
34401
|
+
if ((0, import_node_fs.existsSync)(path19)) {
|
|
34401
34402
|
await this.exec("systemctl", ["--user", "disable", "--now", `${this.name}.service`]).catch(() => void 0);
|
|
34402
34403
|
}
|
|
34403
34404
|
await (0, import_promises.mkdir)((0, import_node_path.join)(this.home, ".config", "systemd", "user"), { recursive: true });
|
|
34404
|
-
await (0, import_promises.writeFile)(
|
|
34405
|
+
await (0, import_promises.writeFile)(path19, renderUnit(this.description, this.programArgs, this.env), "utf8");
|
|
34405
34406
|
await this.exec("systemctl", ["--user", "daemon-reload"]);
|
|
34406
34407
|
await this.exec("systemctl", ["--user", "enable", "--now", `${this.name}.service`]);
|
|
34407
34408
|
return;
|
|
@@ -34410,17 +34411,17 @@ var Daemon = class {
|
|
|
34410
34411
|
}
|
|
34411
34412
|
async uninstall() {
|
|
34412
34413
|
if (this.platform === "darwin") {
|
|
34413
|
-
const
|
|
34414
|
-
if ((0, import_node_fs.existsSync)(
|
|
34415
|
-
await this.exec("launchctl", ["unload", "-w",
|
|
34416
|
-
await (0, import_promises.rm)(
|
|
34414
|
+
const path19 = plistPath(this.home, this.name);
|
|
34415
|
+
if ((0, import_node_fs.existsSync)(path19)) {
|
|
34416
|
+
await this.exec("launchctl", ["unload", "-w", path19]).catch(() => void 0);
|
|
34417
|
+
await (0, import_promises.rm)(path19, { force: true });
|
|
34417
34418
|
}
|
|
34418
34419
|
return;
|
|
34419
34420
|
}
|
|
34420
34421
|
if (this.platform === "linux") {
|
|
34421
|
-
const
|
|
34422
|
+
const path19 = unitPath(this.home, this.name);
|
|
34422
34423
|
await this.exec("systemctl", ["--user", "disable", "--now", `${this.name}.service`]).catch(() => void 0);
|
|
34423
|
-
await (0, import_promises.rm)(
|
|
34424
|
+
await (0, import_promises.rm)(path19, { force: true });
|
|
34424
34425
|
await this.exec("systemctl", ["--user", "daemon-reload"]);
|
|
34425
34426
|
return;
|
|
34426
34427
|
}
|
|
@@ -34428,8 +34429,8 @@ var Daemon = class {
|
|
|
34428
34429
|
}
|
|
34429
34430
|
async status() {
|
|
34430
34431
|
if (this.platform === "darwin") {
|
|
34431
|
-
const
|
|
34432
|
-
if (!(0, import_node_fs.existsSync)(
|
|
34432
|
+
const path19 = plistPath(this.home, this.name);
|
|
34433
|
+
if (!(0, import_node_fs.existsSync)(path19))
|
|
34433
34434
|
return { installed: false, running: false };
|
|
34434
34435
|
try {
|
|
34435
34436
|
await this.exec("launchctl", ["list", this.name]);
|
|
@@ -34439,8 +34440,8 @@ var Daemon = class {
|
|
|
34439
34440
|
}
|
|
34440
34441
|
}
|
|
34441
34442
|
if (this.platform === "linux") {
|
|
34442
|
-
const
|
|
34443
|
-
if (!(0, import_node_fs.existsSync)(
|
|
34443
|
+
const path19 = unitPath(this.home, this.name);
|
|
34444
|
+
if (!(0, import_node_fs.existsSync)(path19))
|
|
34444
34445
|
return { installed: false, running: false };
|
|
34445
34446
|
try {
|
|
34446
34447
|
const result = await this.exec("systemctl", [
|
|
@@ -34464,9 +34465,9 @@ require_shim7()();
|
|
|
34464
34465
|
|
|
34465
34466
|
// ../server/src/server.ts
|
|
34466
34467
|
var import_express2 = __toESM(require_express2(), 1);
|
|
34467
|
-
var
|
|
34468
|
+
var import_node_fs10 = require("node:fs");
|
|
34468
34469
|
var import_node_http = __toESM(require("node:http"), 1);
|
|
34469
|
-
var
|
|
34470
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
34470
34471
|
var import_node_url = require("node:url");
|
|
34471
34472
|
|
|
34472
34473
|
// ../server/src/config.ts
|
|
@@ -35361,10 +35362,10 @@ function mergeDefs(...defs) {
|
|
|
35361
35362
|
function cloneDef(schema) {
|
|
35362
35363
|
return mergeDefs(schema._zod.def);
|
|
35363
35364
|
}
|
|
35364
|
-
function getElementAtPath(obj,
|
|
35365
|
-
if (!
|
|
35365
|
+
function getElementAtPath(obj, path19) {
|
|
35366
|
+
if (!path19)
|
|
35366
35367
|
return obj;
|
|
35367
|
-
return
|
|
35368
|
+
return path19.reduce((acc, key) => acc?.[key], obj);
|
|
35368
35369
|
}
|
|
35369
35370
|
function promiseAllObject(promisesObj) {
|
|
35370
35371
|
const keys = Object.keys(promisesObj);
|
|
@@ -35747,11 +35748,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
35747
35748
|
}
|
|
35748
35749
|
return false;
|
|
35749
35750
|
}
|
|
35750
|
-
function prefixIssues(
|
|
35751
|
+
function prefixIssues(path19, issues) {
|
|
35751
35752
|
return issues.map((iss) => {
|
|
35752
35753
|
var _a2;
|
|
35753
35754
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
35754
|
-
iss.path.unshift(
|
|
35755
|
+
iss.path.unshift(path19);
|
|
35755
35756
|
return iss;
|
|
35756
35757
|
});
|
|
35757
35758
|
}
|
|
@@ -35934,7 +35935,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
35934
35935
|
}
|
|
35935
35936
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
35936
35937
|
const result = { errors: [] };
|
|
35937
|
-
const processError = (error49,
|
|
35938
|
+
const processError = (error49, path19 = []) => {
|
|
35938
35939
|
var _a2, _b;
|
|
35939
35940
|
for (const issue2 of error49.issues) {
|
|
35940
35941
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -35944,7 +35945,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
35944
35945
|
} else if (issue2.code === "invalid_element") {
|
|
35945
35946
|
processError({ issues: issue2.issues }, issue2.path);
|
|
35946
35947
|
} else {
|
|
35947
|
-
const fullpath = [...
|
|
35948
|
+
const fullpath = [...path19, ...issue2.path];
|
|
35948
35949
|
if (fullpath.length === 0) {
|
|
35949
35950
|
result.errors.push(mapper(issue2));
|
|
35950
35951
|
continue;
|
|
@@ -35976,8 +35977,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
35976
35977
|
}
|
|
35977
35978
|
function toDotPath(_path) {
|
|
35978
35979
|
const segs = [];
|
|
35979
|
-
const
|
|
35980
|
-
for (const seg of
|
|
35980
|
+
const path19 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
35981
|
+
for (const seg of path19) {
|
|
35981
35982
|
if (typeof seg === "number")
|
|
35982
35983
|
segs.push(`[${seg}]`);
|
|
35983
35984
|
else if (typeof seg === "symbol")
|
|
@@ -47954,13 +47955,13 @@ function resolveRef(ref, ctx) {
|
|
|
47954
47955
|
if (!ref.startsWith("#")) {
|
|
47955
47956
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
47956
47957
|
}
|
|
47957
|
-
const
|
|
47958
|
-
if (
|
|
47958
|
+
const path19 = ref.slice(1).split("/").filter(Boolean);
|
|
47959
|
+
if (path19.length === 0) {
|
|
47959
47960
|
return ctx.rootSchema;
|
|
47960
47961
|
}
|
|
47961
47962
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
47962
|
-
if (
|
|
47963
|
-
const key =
|
|
47963
|
+
if (path19[0] === defsKey) {
|
|
47964
|
+
const key = path19[1];
|
|
47964
47965
|
if (!key || !ctx.defs[key]) {
|
|
47965
47966
|
throw new Error(`Reference not found: ${ref}`);
|
|
47966
47967
|
}
|
|
@@ -48546,6 +48547,7 @@ var ChannelChangedEvent = defineEvent();
|
|
|
48546
48547
|
var PinnedChannelsChangedEvent = defineEvent();
|
|
48547
48548
|
var ArtifactFocusEvent = defineEvent();
|
|
48548
48549
|
var ThemeChangedEvent = defineEvent();
|
|
48550
|
+
var AppearanceChangedEvent = defineEvent();
|
|
48549
48551
|
|
|
48550
48552
|
// ../shared/src/errors.ts
|
|
48551
48553
|
function defineError(name) {
|
|
@@ -48817,6 +48819,18 @@ var ArtifactClient = class {
|
|
|
48817
48819
|
);
|
|
48818
48820
|
}
|
|
48819
48821
|
};
|
|
48822
|
+
var ThemeClient = class {
|
|
48823
|
+
#http;
|
|
48824
|
+
constructor(http2) {
|
|
48825
|
+
this.#http = http2;
|
|
48826
|
+
}
|
|
48827
|
+
list() {
|
|
48828
|
+
return this.#http.requestJSON("GET", "/themes");
|
|
48829
|
+
}
|
|
48830
|
+
refresh() {
|
|
48831
|
+
return this.#http.requestJSON("POST", "/themes/refresh");
|
|
48832
|
+
}
|
|
48833
|
+
};
|
|
48820
48834
|
var MarkdownClient = class {
|
|
48821
48835
|
#http;
|
|
48822
48836
|
constructor(http2) {
|
|
@@ -48861,6 +48875,10 @@ var DisplayClient = class {
|
|
|
48861
48875
|
if (input.focusedChannelId !== void 0) body.focusedChannelId = input.focusedChannelId;
|
|
48862
48876
|
if (input.pinnedChannelIds !== void 0) body.pinnedChannelIds = input.pinnedChannelIds;
|
|
48863
48877
|
if (input.activeThemeName !== void 0) body.activeThemeName = input.activeThemeName;
|
|
48878
|
+
if (input.appearanceMode !== void 0) body.appearanceMode = input.appearanceMode;
|
|
48879
|
+
if (input.themeJavaScriptConsentIds !== void 0) {
|
|
48880
|
+
body.themeJavaScriptConsentIds = input.themeJavaScriptConsentIds;
|
|
48881
|
+
}
|
|
48864
48882
|
return this.#http.requestVoid("PATCH", "/display", body);
|
|
48865
48883
|
}
|
|
48866
48884
|
focus(input) {
|
|
@@ -48871,6 +48889,7 @@ var TelevisionClient = class {
|
|
|
48871
48889
|
channels;
|
|
48872
48890
|
artifacts;
|
|
48873
48891
|
display;
|
|
48892
|
+
themes;
|
|
48874
48893
|
markdown;
|
|
48875
48894
|
telemetry;
|
|
48876
48895
|
#http;
|
|
@@ -48879,6 +48898,7 @@ var TelevisionClient = class {
|
|
|
48879
48898
|
this.channels = new ChannelClient(this.#http);
|
|
48880
48899
|
this.artifacts = new ArtifactClient(this.#http);
|
|
48881
48900
|
this.display = new DisplayClient(this.#http);
|
|
48901
|
+
this.themes = new ThemeClient(this.#http);
|
|
48882
48902
|
this.markdown = new MarkdownClient(this.#http);
|
|
48883
48903
|
this.telemetry = new TelemetryControlClient(this.#http);
|
|
48884
48904
|
}
|
|
@@ -49085,11 +49105,654 @@ function createArtifact(input) {
|
|
|
49085
49105
|
return ArtifactSchema.parse({ id: input.id ?? ulid3(), ...input });
|
|
49086
49106
|
}
|
|
49087
49107
|
|
|
49108
|
+
// ../server/src/bundled-theme-ids.ts
|
|
49109
|
+
var BUNDLED_THEMES = [{ "id": "aquarium", "minimumVersion": "1.0.2" }, { "id": "blueprint", "minimumVersion": "1.0.0" }, { "id": "crt-phosphor", "minimumVersion": "1.0.0" }, { "id": "clouds", "minimumVersion": "2.1.0" }, { "id": "nord", "minimumVersion": "1.1.0" }, { "id": "swiss", "minimumVersion": "1.1.0" }, { "id": "tokyo-night", "minimumVersion": "1.1.0" }];
|
|
49110
|
+
var BUNDLED_THEME_IDS = BUNDLED_THEMES.map(({ id }) => id);
|
|
49111
|
+
|
|
49112
|
+
// ../server/src/bundled-theme-installer.ts
|
|
49113
|
+
var import_node_fs4 = require("node:fs");
|
|
49114
|
+
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
49115
|
+
|
|
49116
|
+
// ../server/src/artifact-paths.ts
|
|
49117
|
+
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
49118
|
+
function getStateDir(storagePath) {
|
|
49119
|
+
return import_node_path3.default.join(storagePath, "state");
|
|
49120
|
+
}
|
|
49121
|
+
function getChannelsDir(storagePath) {
|
|
49122
|
+
return import_node_path3.default.join(getStateDir(storagePath), "channels");
|
|
49123
|
+
}
|
|
49124
|
+
function getLegacyScreensDir(storagePath) {
|
|
49125
|
+
return import_node_path3.default.join(getStateDir(storagePath), "screens");
|
|
49126
|
+
}
|
|
49127
|
+
function getArtifactsMetadataDir(storagePath) {
|
|
49128
|
+
return import_node_path3.default.join(getStateDir(storagePath), "artifacts");
|
|
49129
|
+
}
|
|
49130
|
+
function getDisplayStatePath(storagePath) {
|
|
49131
|
+
return import_node_path3.default.join(getStateDir(storagePath), "display.json");
|
|
49132
|
+
}
|
|
49133
|
+
function getDisplayMigrationTempPath(storagePath) {
|
|
49134
|
+
return import_node_path3.default.join(getStateDir(storagePath), ".display.json.screen-to-channel.tmp");
|
|
49135
|
+
}
|
|
49136
|
+
function getTelemetryStatePath(storagePath) {
|
|
49137
|
+
return import_node_path3.default.join(getStateDir(storagePath), "telemetry.json");
|
|
49138
|
+
}
|
|
49139
|
+
function getTokenPath(storagePath) {
|
|
49140
|
+
return import_node_path3.default.join(getStateDir(storagePath), "token");
|
|
49141
|
+
}
|
|
49142
|
+
function getOnboardingStatePath(storagePath) {
|
|
49143
|
+
return import_node_path3.default.join(getStateDir(storagePath), "onboarding.json");
|
|
49144
|
+
}
|
|
49145
|
+
function getBundledThemesStatePath(storagePath) {
|
|
49146
|
+
return import_node_path3.default.join(getStateDir(storagePath), "bundled-themes.json");
|
|
49147
|
+
}
|
|
49148
|
+
function getOnboardingArtifactSentinelPath(storagePath) {
|
|
49149
|
+
return import_node_path3.default.join(getStateDir(storagePath), "onboarding-artifact.json");
|
|
49150
|
+
}
|
|
49151
|
+
function getAgentArtifactsDir(storagePath) {
|
|
49152
|
+
return import_node_path3.default.join(...[storagePath, "artifacts"]);
|
|
49153
|
+
}
|
|
49154
|
+
function getArtifactLiveMetadataPath(storagePath, artifactID) {
|
|
49155
|
+
return import_node_path3.default.join(getArtifactsMetadataDir(storagePath), `${artifactID}.json`);
|
|
49156
|
+
}
|
|
49157
|
+
|
|
49158
|
+
// ../server/src/themes.ts
|
|
49159
|
+
var import_node_crypto2 = require("node:crypto");
|
|
49160
|
+
var import_node_fs3 = require("node:fs");
|
|
49161
|
+
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
49162
|
+
var ETAG_DIGEST_LENGTH = 16;
|
|
49163
|
+
var HTTP_NO_CONTENT_STATUS = 204;
|
|
49164
|
+
var HTTP_NOT_FOUND_STATUS = 404;
|
|
49165
|
+
var HTTP_NOT_MODIFIED_STATUS = 304;
|
|
49166
|
+
var THEME_MANIFEST_FILE = "manifest.json";
|
|
49167
|
+
var THEME_ENTRY_FILE = "theme.css";
|
|
49168
|
+
var THEME_SCRIPT_ENTRIES = [
|
|
49169
|
+
{ declaration: "enableMainJS", filename: "main.js", requiresConsent: true },
|
|
49170
|
+
{
|
|
49171
|
+
declaration: "enableIframeBackgroundJS",
|
|
49172
|
+
filename: "iframe-background.js",
|
|
49173
|
+
requiresConsent: false
|
|
49174
|
+
},
|
|
49175
|
+
{
|
|
49176
|
+
declaration: "enableIframeOverlayJS",
|
|
49177
|
+
filename: "iframe-overlay.js",
|
|
49178
|
+
requiresConsent: false
|
|
49179
|
+
}
|
|
49180
|
+
];
|
|
49181
|
+
var THEME_AUTHORING_CONTEXT_FILE = "README.md";
|
|
49182
|
+
var SEMVER_NUMERIC_IDENTIFIER = "(?:0|[1-9]\\d*)";
|
|
49183
|
+
var SEMVER_NON_NUMERIC_IDENTIFIER = "(?:\\d*[A-Za-z-][0-9A-Za-z-]*)";
|
|
49184
|
+
var SEMVER_PRERELEASE_IDENTIFIER = `(?:${SEMVER_NUMERIC_IDENTIFIER}|${SEMVER_NON_NUMERIC_IDENTIFIER})`;
|
|
49185
|
+
var SEMVER_BUILD_IDENTIFIER = "[0-9A-Za-z-]+";
|
|
49186
|
+
var SEMVER_PATTERN = new RegExp(
|
|
49187
|
+
`^${SEMVER_NUMERIC_IDENTIFIER}\\.${SEMVER_NUMERIC_IDENTIFIER}\\.${SEMVER_NUMERIC_IDENTIFIER}(?:-${SEMVER_PRERELEASE_IDENTIFIER}(?:\\.${SEMVER_PRERELEASE_IDENTIFIER})*)?(?:\\+${SEMVER_BUILD_IDENTIFIER}(?:\\.${SEMVER_BUILD_IDENTIFIER})*)?$`
|
|
49188
|
+
);
|
|
49189
|
+
function isSemanticVersion(value) {
|
|
49190
|
+
return SEMVER_PATTERN.test(value);
|
|
49191
|
+
}
|
|
49192
|
+
function compareSemanticVersions(left, right) {
|
|
49193
|
+
const leftVersion = parseSemanticVersion(left);
|
|
49194
|
+
const rightVersion = parseSemanticVersion(right);
|
|
49195
|
+
if (leftVersion === null || rightVersion === null) {
|
|
49196
|
+
throw new Error("Semantic Version comparison requires two valid versions");
|
|
49197
|
+
}
|
|
49198
|
+
for (let index = 0; index < leftVersion.core.length; index += 1) {
|
|
49199
|
+
const leftPart = leftVersion.core[index];
|
|
49200
|
+
const rightPart = rightVersion.core[index];
|
|
49201
|
+
if (leftPart < rightPart) return -1;
|
|
49202
|
+
if (leftPart > rightPart) return 1;
|
|
49203
|
+
}
|
|
49204
|
+
if (leftVersion.prerelease === null) return rightVersion.prerelease === null ? 0 : 1;
|
|
49205
|
+
if (rightVersion.prerelease === null) return -1;
|
|
49206
|
+
const identifierCount = Math.max(
|
|
49207
|
+
leftVersion.prerelease.length,
|
|
49208
|
+
rightVersion.prerelease.length
|
|
49209
|
+
);
|
|
49210
|
+
for (let index = 0; index < identifierCount; index += 1) {
|
|
49211
|
+
const leftIdentifier = leftVersion.prerelease[index];
|
|
49212
|
+
const rightIdentifier = rightVersion.prerelease[index];
|
|
49213
|
+
if (leftIdentifier === void 0) return -1;
|
|
49214
|
+
if (rightIdentifier === void 0) return 1;
|
|
49215
|
+
if (leftIdentifier === rightIdentifier) continue;
|
|
49216
|
+
const leftNumeric = /^\d+$/.test(leftIdentifier);
|
|
49217
|
+
const rightNumeric = /^\d+$/.test(rightIdentifier);
|
|
49218
|
+
if (leftNumeric && rightNumeric) {
|
|
49219
|
+
return BigInt(leftIdentifier) < BigInt(rightIdentifier) ? -1 : 1;
|
|
49220
|
+
}
|
|
49221
|
+
if (leftNumeric) return -1;
|
|
49222
|
+
if (rightNumeric) return 1;
|
|
49223
|
+
return leftIdentifier < rightIdentifier ? -1 : 1;
|
|
49224
|
+
}
|
|
49225
|
+
return 0;
|
|
49226
|
+
}
|
|
49227
|
+
function parseSemanticVersion(value) {
|
|
49228
|
+
if (!isSemanticVersion(value)) return null;
|
|
49229
|
+
const withoutBuild = value.split("+", 1)[0];
|
|
49230
|
+
const prereleaseSeparator = withoutBuild.indexOf("-");
|
|
49231
|
+
const coreText = prereleaseSeparator === -1 ? withoutBuild : withoutBuild.slice(0, prereleaseSeparator);
|
|
49232
|
+
const prerelease = prereleaseSeparator === -1 ? null : withoutBuild.slice(prereleaseSeparator + 1).split(".");
|
|
49233
|
+
const [major, minor, patch] = coreText.split(".").map((part) => BigInt(part));
|
|
49234
|
+
return {
|
|
49235
|
+
core: [major, minor, patch],
|
|
49236
|
+
prerelease
|
|
49237
|
+
};
|
|
49238
|
+
}
|
|
49239
|
+
function getThemesDir(storagePath) {
|
|
49240
|
+
return import_node_path4.default.join(storagePath, "themes");
|
|
49241
|
+
}
|
|
49242
|
+
function getThemeDir(storagePath, themeID) {
|
|
49243
|
+
return import_node_path4.default.join(getThemesDir(storagePath), themeID);
|
|
49244
|
+
}
|
|
49245
|
+
function normalizeThemeColorScheme(value) {
|
|
49246
|
+
if (typeof value !== "string") return null;
|
|
49247
|
+
const words = new Set(value.trim().toLowerCase().split(/\s+/));
|
|
49248
|
+
if (words.size === 1 && words.has("light")) return "light";
|
|
49249
|
+
if (words.size === 1 && words.has("dark")) return "dark";
|
|
49250
|
+
if (words.size === 2 && words.has("light") && words.has("dark")) {
|
|
49251
|
+
return "light dark";
|
|
49252
|
+
}
|
|
49253
|
+
return null;
|
|
49254
|
+
}
|
|
49255
|
+
function validateThemePackage(themeDir, themeID) {
|
|
49256
|
+
const errors = [];
|
|
49257
|
+
let manifest;
|
|
49258
|
+
let parsed;
|
|
49259
|
+
try {
|
|
49260
|
+
const raw = (0, import_node_fs3.readFileSync)(import_node_path4.default.join(themeDir, THEME_MANIFEST_FILE), "utf8");
|
|
49261
|
+
try {
|
|
49262
|
+
parsed = JSON.parse(raw);
|
|
49263
|
+
} catch {
|
|
49264
|
+
errors.push(`cannot parse ${THEME_MANIFEST_FILE}`);
|
|
49265
|
+
}
|
|
49266
|
+
} catch {
|
|
49267
|
+
errors.push(`cannot read ${THEME_MANIFEST_FILE}`);
|
|
49268
|
+
}
|
|
49269
|
+
if (parsed !== void 0) {
|
|
49270
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
49271
|
+
errors.push(`${THEME_MANIFEST_FILE} must contain a JSON object`);
|
|
49272
|
+
} else {
|
|
49273
|
+
const candidate = parsed;
|
|
49274
|
+
const nameValid = typeof candidate.name === "string" && candidate.name.trim().length > 0;
|
|
49275
|
+
if (!nameValid) {
|
|
49276
|
+
errors.push("manifest must have a non-empty name");
|
|
49277
|
+
}
|
|
49278
|
+
const versionValid = typeof candidate.version === "string" && isSemanticVersion(candidate.version);
|
|
49279
|
+
if (!versionValid) {
|
|
49280
|
+
errors.push("manifest version must be a valid Semantic Version");
|
|
49281
|
+
}
|
|
49282
|
+
const colorScheme = normalizeThemeColorScheme(candidate.colorScheme);
|
|
49283
|
+
if (colorScheme === null) {
|
|
49284
|
+
errors.push(
|
|
49285
|
+
"manifest colorScheme must be one of: light, dark, light dark"
|
|
49286
|
+
);
|
|
49287
|
+
}
|
|
49288
|
+
const authoredForAppVersion = typeof candidate.authoredForAppVersion === "string" && isSemanticVersion(candidate.authoredForAppVersion) ? candidate.authoredForAppVersion : void 0;
|
|
49289
|
+
const javascriptDeclarations = {};
|
|
49290
|
+
let javascriptDeclarationsValid = true;
|
|
49291
|
+
for (const { declaration, filename } of THEME_SCRIPT_ENTRIES) {
|
|
49292
|
+
if (!Object.hasOwn(candidate, declaration)) continue;
|
|
49293
|
+
if (typeof candidate[declaration] !== "boolean") {
|
|
49294
|
+
errors.push(`manifest ${declaration} must be a boolean`);
|
|
49295
|
+
javascriptDeclarationsValid = false;
|
|
49296
|
+
continue;
|
|
49297
|
+
}
|
|
49298
|
+
javascriptDeclarations[declaration] = candidate[declaration];
|
|
49299
|
+
validateReadableRegularFile(themeDir, filename, errors);
|
|
49300
|
+
}
|
|
49301
|
+
if (nameValid && versionValid && colorScheme !== null && javascriptDeclarationsValid) {
|
|
49302
|
+
manifest = {
|
|
49303
|
+
name: candidate.name,
|
|
49304
|
+
version: candidate.version,
|
|
49305
|
+
colorScheme,
|
|
49306
|
+
...authoredForAppVersion === void 0 ? {} : { authoredForAppVersion },
|
|
49307
|
+
...javascriptDeclarations
|
|
49308
|
+
};
|
|
49309
|
+
}
|
|
49310
|
+
}
|
|
49311
|
+
}
|
|
49312
|
+
validateReadableRegularFile(themeDir, THEME_ENTRY_FILE, errors);
|
|
49313
|
+
return errors.length === 0 && manifest !== void 0 ? { theme: { id: themeID, ...manifest }, errors: [] } : { errors };
|
|
49314
|
+
}
|
|
49315
|
+
function validateReadableRegularFile(themeDir, filename, errors) {
|
|
49316
|
+
try {
|
|
49317
|
+
const entryPath = import_node_path4.default.join(themeDir, filename);
|
|
49318
|
+
if (!(0, import_node_fs3.statSync)(entryPath).isFile()) {
|
|
49319
|
+
errors.push(`${filename} must be a readable regular file`);
|
|
49320
|
+
} else {
|
|
49321
|
+
(0, import_node_fs3.accessSync)(entryPath, import_node_fs3.constants.R_OK);
|
|
49322
|
+
}
|
|
49323
|
+
} catch {
|
|
49324
|
+
errors.push(`${filename} must be a readable regular file`);
|
|
49325
|
+
}
|
|
49326
|
+
}
|
|
49327
|
+
function scanThemesDirectory(themesDir) {
|
|
49328
|
+
let entries;
|
|
49329
|
+
try {
|
|
49330
|
+
entries = (0, import_node_fs3.readdirSync)(themesDir, { withFileTypes: true });
|
|
49331
|
+
} catch {
|
|
49332
|
+
return {
|
|
49333
|
+
themes: [],
|
|
49334
|
+
errors: [{ folder: null, error: "cannot read themes directory" }]
|
|
49335
|
+
};
|
|
49336
|
+
}
|
|
49337
|
+
const themes = [];
|
|
49338
|
+
const errors = [];
|
|
49339
|
+
for (const entry of entries) {
|
|
49340
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) {
|
|
49341
|
+
continue;
|
|
49342
|
+
}
|
|
49343
|
+
const result = validateThemePackage(import_node_path4.default.join(themesDir, entry.name), entry.name);
|
|
49344
|
+
if (result.theme !== void 0) {
|
|
49345
|
+
themes.push(result.theme);
|
|
49346
|
+
} else {
|
|
49347
|
+
errors.push({ folder: entry.name, error: result.errors.join("; ") });
|
|
49348
|
+
}
|
|
49349
|
+
}
|
|
49350
|
+
themes.sort(
|
|
49351
|
+
(left, right) => left.name.localeCompare(right.name, "en") || left.id.localeCompare(right.id, "en")
|
|
49352
|
+
);
|
|
49353
|
+
errors.sort((left, right) => (left.folder ?? "").localeCompare(right.folder ?? "", "en"));
|
|
49354
|
+
return { themes, errors };
|
|
49355
|
+
}
|
|
49356
|
+
function serveActiveTheme(store) {
|
|
49357
|
+
return (req, res, next) => {
|
|
49358
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
49359
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS");
|
|
49360
|
+
if (req.method === "OPTIONS") {
|
|
49361
|
+
res.status(HTTP_NO_CONTENT_STATUS).end();
|
|
49362
|
+
return;
|
|
49363
|
+
}
|
|
49364
|
+
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
49365
|
+
next();
|
|
49366
|
+
return;
|
|
49367
|
+
}
|
|
49368
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
49369
|
+
const relativePath = requestedThemePath(req.path);
|
|
49370
|
+
if (relativePath === null) {
|
|
49371
|
+
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
49372
|
+
return;
|
|
49373
|
+
}
|
|
49374
|
+
const activeThemeID = store.getActiveThemeName();
|
|
49375
|
+
const theme = activeThemeID === null ? void 0 : store.getThemeRegistry().themes.find((candidate) => candidate.id === activeThemeID);
|
|
49376
|
+
if (theme === void 0) {
|
|
49377
|
+
sendMissingThemeResponse(relativePath, res);
|
|
49378
|
+
return;
|
|
49379
|
+
}
|
|
49380
|
+
const scriptEntry = getThemeScriptEntry(relativePath);
|
|
49381
|
+
if (scriptEntry !== void 0 && (theme[scriptEntry.declaration] !== true || scriptEntry.requiresConsent && !store.hasThemeJavaScriptConsent(theme.id))) {
|
|
49382
|
+
sendEmptyThemeEntryResponse(scriptEntry.filename, theme, res);
|
|
49383
|
+
return;
|
|
49384
|
+
}
|
|
49385
|
+
try {
|
|
49386
|
+
const themesRoot = (0, import_node_fs3.realpathSync)(getThemesDir(store.storagePath));
|
|
49387
|
+
const packageRoot = (0, import_node_fs3.realpathSync)(getThemeDir(store.storagePath, theme.id));
|
|
49388
|
+
if (!isContainedPath(themesRoot, packageRoot)) {
|
|
49389
|
+
sendMissingThemeResponse(relativePath, res, theme);
|
|
49390
|
+
return;
|
|
49391
|
+
}
|
|
49392
|
+
if (scriptEntry === void 0) {
|
|
49393
|
+
const entryPath = (0, import_node_fs3.realpathSync)(import_node_path4.default.join(packageRoot, THEME_ENTRY_FILE));
|
|
49394
|
+
if (!isContainedPath(packageRoot, entryPath) || !(0, import_node_fs3.statSync)(entryPath).isFile()) {
|
|
49395
|
+
sendMissingThemeResponse(relativePath, res, theme);
|
|
49396
|
+
return;
|
|
49397
|
+
}
|
|
49398
|
+
}
|
|
49399
|
+
const candidate = import_node_path4.default.resolve(packageRoot, relativePath);
|
|
49400
|
+
if (!isContainedPath(packageRoot, candidate) || isThemeAuthoringContextPath(packageRoot, candidate)) {
|
|
49401
|
+
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
49402
|
+
return;
|
|
49403
|
+
}
|
|
49404
|
+
const realCandidate = (0, import_node_fs3.realpathSync)(candidate);
|
|
49405
|
+
if (!isContainedPath(packageRoot, realCandidate)) {
|
|
49406
|
+
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
49407
|
+
return;
|
|
49408
|
+
}
|
|
49409
|
+
if (!(0, import_node_fs3.statSync)(realCandidate).isFile()) {
|
|
49410
|
+
sendMissingThemeResponse(relativePath, res, theme);
|
|
49411
|
+
return;
|
|
49412
|
+
}
|
|
49413
|
+
const bytes = (0, import_node_fs3.readFileSync)(realCandidate);
|
|
49414
|
+
const etag = themeETag(theme.id, theme.version, bytes);
|
|
49415
|
+
res.type(import_node_path4.default.extname(relativePath));
|
|
49416
|
+
res.setHeader("ETag", etag);
|
|
49417
|
+
if (matchesIfNoneMatch(req.headers["if-none-match"], etag)) {
|
|
49418
|
+
res.status(HTTP_NOT_MODIFIED_STATUS).end();
|
|
49419
|
+
return;
|
|
49420
|
+
}
|
|
49421
|
+
res.send(bytes);
|
|
49422
|
+
} catch {
|
|
49423
|
+
sendMissingThemeResponse(relativePath, res, theme);
|
|
49424
|
+
}
|
|
49425
|
+
};
|
|
49426
|
+
}
|
|
49427
|
+
function requestedThemePath(requestPath) {
|
|
49428
|
+
try {
|
|
49429
|
+
const decoded = decodeURIComponent(requestPath).replace(/^\/+/, "");
|
|
49430
|
+
if (decoded === "" || decoded.includes("\0") || import_node_path4.default.isAbsolute(decoded)) {
|
|
49431
|
+
return null;
|
|
49432
|
+
}
|
|
49433
|
+
return decoded;
|
|
49434
|
+
} catch {
|
|
49435
|
+
return null;
|
|
49436
|
+
}
|
|
49437
|
+
}
|
|
49438
|
+
function isContainedPath(root, candidate) {
|
|
49439
|
+
return candidate === root || candidate.startsWith(`${root}${import_node_path4.default.sep}`);
|
|
49440
|
+
}
|
|
49441
|
+
function isThemeAuthoringContextPath(packageRoot, candidate) {
|
|
49442
|
+
return import_node_path4.default.relative(packageRoot, candidate).toLowerCase() === THEME_AUTHORING_CONTEXT_FILE.toLowerCase();
|
|
49443
|
+
}
|
|
49444
|
+
function isThemeEntryPath(relativePath, filename) {
|
|
49445
|
+
return import_node_path4.default.normalize(relativePath) === filename;
|
|
49446
|
+
}
|
|
49447
|
+
function getThemeScriptEntry(relativePath) {
|
|
49448
|
+
return THEME_SCRIPT_ENTRIES.find(
|
|
49449
|
+
({ filename }) => isThemeEntryPath(relativePath, filename)
|
|
49450
|
+
);
|
|
49451
|
+
}
|
|
49452
|
+
function sendMissingThemeResponse(relativePath, res, theme) {
|
|
49453
|
+
if (isThemeEntryPath(relativePath, THEME_ENTRY_FILE)) {
|
|
49454
|
+
sendEmptyThemeEntryResponse(THEME_ENTRY_FILE, theme, res);
|
|
49455
|
+
return;
|
|
49456
|
+
}
|
|
49457
|
+
const scriptEntry = getThemeScriptEntry(relativePath);
|
|
49458
|
+
if (scriptEntry !== void 0) {
|
|
49459
|
+
sendEmptyThemeEntryResponse(scriptEntry.filename, theme, res);
|
|
49460
|
+
return;
|
|
49461
|
+
}
|
|
49462
|
+
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
49463
|
+
}
|
|
49464
|
+
function sendEmptyThemeEntryResponse(filename, theme, res) {
|
|
49465
|
+
const bytes = Buffer.alloc(0);
|
|
49466
|
+
const etag = themeETag(theme?.id ?? "default", theme?.version ?? "internal", bytes);
|
|
49467
|
+
res.type(filename === THEME_ENTRY_FILE ? "text/css" : "text/javascript");
|
|
49468
|
+
res.setHeader("ETag", etag);
|
|
49469
|
+
res.send(bytes);
|
|
49470
|
+
}
|
|
49471
|
+
function themeETag(themeID, version2, bytes) {
|
|
49472
|
+
const digest = (0, import_node_crypto2.createHash)("sha256").update(themeID).update("\0").update(version2).update("\0").update(bytes).digest("hex").slice(0, ETAG_DIGEST_LENGTH);
|
|
49473
|
+
return `W/"theme-${digest}"`;
|
|
49474
|
+
}
|
|
49475
|
+
function matchesIfNoneMatch(header, etag) {
|
|
49476
|
+
if (header === void 0) return false;
|
|
49477
|
+
const values = Array.isArray(header) ? header : [header];
|
|
49478
|
+
return values.some(
|
|
49479
|
+
(value) => value.split(",").map((candidate) => candidate.trim()).some((candidate) => candidate === "*" || candidate === etag)
|
|
49480
|
+
);
|
|
49481
|
+
}
|
|
49482
|
+
|
|
49483
|
+
// ../server/src/bundled-theme-installer.ts
|
|
49484
|
+
var JSON_INDENT_SPACES = 2;
|
|
49485
|
+
var BACKUP_TIMESTAMP_LENGTH = 19;
|
|
49486
|
+
var BUNDLED_THEME_STATE_VERSION = 2;
|
|
49487
|
+
var DEFAULT_BUNDLED_THEME_ID = "clouds";
|
|
49488
|
+
function getBundledThemeStateTempPath(storagePath) {
|
|
49489
|
+
const statePath = getBundledThemesStatePath(storagePath);
|
|
49490
|
+
return import_node_path5.default.join(import_node_path5.default.dirname(statePath), `.${import_node_path5.default.basename(statePath)}.tmp-${process.pid}`);
|
|
49491
|
+
}
|
|
49492
|
+
function getBundledThemeCopyTempPath(storagePath, themeID) {
|
|
49493
|
+
return import_node_path5.default.join(getThemesDir(storagePath), `.${themeID}.bundled-theme.tmp-${process.pid}`);
|
|
49494
|
+
}
|
|
49495
|
+
function getBundledThemeBackupTempPath(storagePath, themeID) {
|
|
49496
|
+
return import_node_path5.default.join(getThemesDir(storagePath), `.${themeID}.bundled-theme.backup-tmp-${process.pid}`);
|
|
49497
|
+
}
|
|
49498
|
+
function getBundledThemePreviousPath(storagePath, themeID) {
|
|
49499
|
+
return import_node_path5.default.join(getThemesDir(storagePath), `.${themeID}.bundled-theme.previous-${process.pid}`);
|
|
49500
|
+
}
|
|
49501
|
+
function readBundledThemeStateFile(storagePath) {
|
|
49502
|
+
const statePath = getBundledThemesStatePath(storagePath);
|
|
49503
|
+
if (!(0, import_node_fs4.existsSync)(statePath)) return { status: "absent" };
|
|
49504
|
+
let parsed;
|
|
49505
|
+
try {
|
|
49506
|
+
parsed = JSON.parse((0, import_node_fs4.readFileSync)(statePath, "utf8"));
|
|
49507
|
+
} catch (error48) {
|
|
49508
|
+
return { status: "invalid", error: describeError(error48) };
|
|
49509
|
+
}
|
|
49510
|
+
if (isBundledThemeState(parsed)) return { status: "ok", state: parsed };
|
|
49511
|
+
return {
|
|
49512
|
+
status: "invalid",
|
|
49513
|
+
error: "expected version 2 bundled-theme state with unique sorted theme IDs"
|
|
49514
|
+
};
|
|
49515
|
+
}
|
|
49516
|
+
function writeBundledThemeStateFile(storagePath, state) {
|
|
49517
|
+
const statePath = getBundledThemesStatePath(storagePath);
|
|
49518
|
+
const tempPath = getBundledThemeStateTempPath(storagePath);
|
|
49519
|
+
try {
|
|
49520
|
+
(0, import_node_fs4.writeFileSync)(tempPath, `${JSON.stringify(state, null, JSON_INDENT_SPACES)}
|
|
49521
|
+
`);
|
|
49522
|
+
(0, import_node_fs4.renameSync)(tempPath, statePath);
|
|
49523
|
+
} catch (error48) {
|
|
49524
|
+
try {
|
|
49525
|
+
(0, import_node_fs4.rmSync)(tempPath, { recursive: true, force: true });
|
|
49526
|
+
} catch {
|
|
49527
|
+
}
|
|
49528
|
+
throw error48;
|
|
49529
|
+
}
|
|
49530
|
+
}
|
|
49531
|
+
function runBundledThemeInstallation(storagePath, bundledThemesPath) {
|
|
49532
|
+
if (bundledThemesPath === void 0) return null;
|
|
49533
|
+
const stateRead = readBundledThemeStateFile(storagePath);
|
|
49534
|
+
if (stateRead.status === "invalid") {
|
|
49535
|
+
console.warn(
|
|
49536
|
+
"Bundled theme state is invalid; skipping bundled theme installation for this boot.",
|
|
49537
|
+
stateRead.error
|
|
49538
|
+
);
|
|
49539
|
+
return null;
|
|
49540
|
+
}
|
|
49541
|
+
let state = stateRead.status === "ok" ? stateRead.state : {
|
|
49542
|
+
version: BUNDLED_THEME_STATE_VERSION,
|
|
49543
|
+
installedThemeIDs: [],
|
|
49544
|
+
initialThemeSelectionComplete: false
|
|
49545
|
+
};
|
|
49546
|
+
const recoveryFailures = recoverInterruptedReplacements(storagePath);
|
|
49547
|
+
for (const { id, minimumVersion } of BUNDLED_THEMES) {
|
|
49548
|
+
if (recoveryFailures.has(id)) continue;
|
|
49549
|
+
const destinationPath = getThemeDir(storagePath, id);
|
|
49550
|
+
let handled = false;
|
|
49551
|
+
if (!pathExists(destinationPath)) {
|
|
49552
|
+
if (state.installedThemeIDs.includes(id)) continue;
|
|
49553
|
+
handled = installBundledTheme(storagePath, bundledThemesPath, id);
|
|
49554
|
+
} else if (installedThemeMeetsMinimum(destinationPath, id, minimumVersion)) {
|
|
49555
|
+
handled = true;
|
|
49556
|
+
} else {
|
|
49557
|
+
handled = replaceBundledTheme(storagePath, bundledThemesPath, id);
|
|
49558
|
+
}
|
|
49559
|
+
if (!handled || state.installedThemeIDs.includes(id)) continue;
|
|
49560
|
+
const nextState = {
|
|
49561
|
+
...state,
|
|
49562
|
+
installedThemeIDs: [...state.installedThemeIDs, id].sort((left, right) => left.localeCompare(right, "en"))
|
|
49563
|
+
};
|
|
49564
|
+
try {
|
|
49565
|
+
writeBundledThemeStateFile(storagePath, nextState);
|
|
49566
|
+
state = nextState;
|
|
49567
|
+
} catch (error48) {
|
|
49568
|
+
console.warn(
|
|
49569
|
+
`Failed to record bundled theme ${JSON.stringify(id)}; it will retry on the next boot.`,
|
|
49570
|
+
error48
|
|
49571
|
+
);
|
|
49572
|
+
}
|
|
49573
|
+
}
|
|
49574
|
+
return state;
|
|
49575
|
+
}
|
|
49576
|
+
function installedThemeMeetsMinimum(destinationPath, themeID, minimumVersion) {
|
|
49577
|
+
try {
|
|
49578
|
+
if (!(0, import_node_fs4.lstatSync)(destinationPath).isDirectory()) return false;
|
|
49579
|
+
} catch {
|
|
49580
|
+
return false;
|
|
49581
|
+
}
|
|
49582
|
+
const result = validateThemePackage(destinationPath, themeID);
|
|
49583
|
+
return result.theme !== void 0 && compareSemanticVersions(result.theme.version, minimumVersion) >= 0;
|
|
49584
|
+
}
|
|
49585
|
+
function installBundledTheme(storagePath, bundledThemesPath, themeID) {
|
|
49586
|
+
const destinationPath = getThemeDir(storagePath, themeID);
|
|
49587
|
+
const tempPath = getBundledThemeCopyTempPath(storagePath, themeID);
|
|
49588
|
+
try {
|
|
49589
|
+
copyFresh(import_node_path5.default.join(bundledThemesPath, themeID), tempPath);
|
|
49590
|
+
if (pathExists(destinationPath)) {
|
|
49591
|
+
(0, import_node_fs4.rmSync)(tempPath, { recursive: true, force: true });
|
|
49592
|
+
return false;
|
|
49593
|
+
}
|
|
49594
|
+
(0, import_node_fs4.renameSync)(tempPath, destinationPath);
|
|
49595
|
+
return true;
|
|
49596
|
+
} catch (error48) {
|
|
49597
|
+
removeAfterFailure(tempPath);
|
|
49598
|
+
console.warn(
|
|
49599
|
+
`Failed to install bundled theme ${JSON.stringify(themeID)}; it will retry on the next boot.`,
|
|
49600
|
+
error48
|
|
49601
|
+
);
|
|
49602
|
+
return false;
|
|
49603
|
+
}
|
|
49604
|
+
}
|
|
49605
|
+
function replaceBundledTheme(storagePath, bundledThemesPath, themeID) {
|
|
49606
|
+
const destinationPath = getThemeDir(storagePath, themeID);
|
|
49607
|
+
const backupTempPath = getBundledThemeBackupTempPath(storagePath, themeID);
|
|
49608
|
+
try {
|
|
49609
|
+
copyFresh(destinationPath, backupTempPath);
|
|
49610
|
+
(0, import_node_fs4.renameSync)(backupTempPath, unusedBackupPath(storagePath, themeID));
|
|
49611
|
+
} catch (error48) {
|
|
49612
|
+
removeAfterFailure(backupTempPath);
|
|
49613
|
+
console.warn(
|
|
49614
|
+
`Failed to back up bundled theme ${JSON.stringify(themeID)}; it will retry on the next boot.`,
|
|
49615
|
+
error48
|
|
49616
|
+
);
|
|
49617
|
+
return false;
|
|
49618
|
+
}
|
|
49619
|
+
const replacementTempPath = getBundledThemeCopyTempPath(storagePath, themeID);
|
|
49620
|
+
const previousPath = getBundledThemePreviousPath(storagePath, themeID);
|
|
49621
|
+
let previousMoved = false;
|
|
49622
|
+
let replacementInstalled = false;
|
|
49623
|
+
try {
|
|
49624
|
+
copyFresh(import_node_path5.default.join(bundledThemesPath, themeID), replacementTempPath);
|
|
49625
|
+
(0, import_node_fs4.renameSync)(destinationPath, previousPath);
|
|
49626
|
+
previousMoved = true;
|
|
49627
|
+
(0, import_node_fs4.renameSync)(replacementTempPath, destinationPath);
|
|
49628
|
+
replacementInstalled = true;
|
|
49629
|
+
} catch (error48) {
|
|
49630
|
+
removeAfterFailure(replacementTempPath);
|
|
49631
|
+
if (previousMoved && !replacementInstalled && !pathExists(destinationPath)) {
|
|
49632
|
+
try {
|
|
49633
|
+
(0, import_node_fs4.renameSync)(previousPath, destinationPath);
|
|
49634
|
+
} catch (rollbackError) {
|
|
49635
|
+
console.warn(
|
|
49636
|
+
`Failed to restore bundled theme ${JSON.stringify(themeID)} after replacement failed.`,
|
|
49637
|
+
rollbackError
|
|
49638
|
+
);
|
|
49639
|
+
}
|
|
49640
|
+
}
|
|
49641
|
+
console.warn(
|
|
49642
|
+
`Failed to replace bundled theme ${JSON.stringify(themeID)}; it will retry on the next boot.`,
|
|
49643
|
+
error48
|
|
49644
|
+
);
|
|
49645
|
+
return false;
|
|
49646
|
+
}
|
|
49647
|
+
try {
|
|
49648
|
+
(0, import_node_fs4.rmSync)(previousPath, { recursive: true, force: true });
|
|
49649
|
+
} catch (error48) {
|
|
49650
|
+
console.warn(
|
|
49651
|
+
`Bundled theme ${JSON.stringify(themeID)} was replaced, but its hidden prior copy could not be removed.`,
|
|
49652
|
+
error48
|
|
49653
|
+
);
|
|
49654
|
+
}
|
|
49655
|
+
return true;
|
|
49656
|
+
}
|
|
49657
|
+
function copyFresh(sourcePath, destinationPath) {
|
|
49658
|
+
(0, import_node_fs4.cpSync)(sourcePath, destinationPath, {
|
|
49659
|
+
recursive: true,
|
|
49660
|
+
errorOnExist: true,
|
|
49661
|
+
force: false,
|
|
49662
|
+
verbatimSymlinks: true
|
|
49663
|
+
});
|
|
49664
|
+
}
|
|
49665
|
+
function unusedBackupPath(storagePath, themeID) {
|
|
49666
|
+
const initialTime = Date.now();
|
|
49667
|
+
for (let offsetSeconds = 0; ; offsetSeconds += 1) {
|
|
49668
|
+
const timestamp = new Date(initialTime + offsetSeconds * 1e3).toISOString().slice(0, BACKUP_TIMESTAMP_LENGTH).replace("T", "-").replaceAll(":", "-");
|
|
49669
|
+
const candidate = import_node_path5.default.join(getThemesDir(storagePath), `.${themeID}.backup.${timestamp}`);
|
|
49670
|
+
if (!pathExists(candidate)) return candidate;
|
|
49671
|
+
}
|
|
49672
|
+
}
|
|
49673
|
+
function recoverInterruptedReplacements(storagePath) {
|
|
49674
|
+
const failed = /* @__PURE__ */ new Set();
|
|
49675
|
+
const themesPath = getThemesDir(storagePath);
|
|
49676
|
+
const entries = (0, import_node_fs4.readdirSync)(themesPath, { withFileTypes: true });
|
|
49677
|
+
for (const { id } of BUNDLED_THEMES) {
|
|
49678
|
+
const previousPrefix = `.${id}.bundled-theme.previous-`;
|
|
49679
|
+
const previousNames = entries.map(({ name }) => name).filter((name) => name.startsWith(previousPrefix) && /^\d+$/.test(name.slice(previousPrefix.length))).sort();
|
|
49680
|
+
const destinationPath = getThemeDir(storagePath, id);
|
|
49681
|
+
if (!pathExists(destinationPath) && previousNames.length > 0) {
|
|
49682
|
+
const previousPath = import_node_path5.default.join(themesPath, previousNames[0]);
|
|
49683
|
+
try {
|
|
49684
|
+
(0, import_node_fs4.renameSync)(previousPath, destinationPath);
|
|
49685
|
+
} catch (error48) {
|
|
49686
|
+
failed.add(id);
|
|
49687
|
+
console.warn(
|
|
49688
|
+
`Failed to recover interrupted replacement of bundled theme ${JSON.stringify(id)}; it will retry on the next boot.`,
|
|
49689
|
+
error48
|
|
49690
|
+
);
|
|
49691
|
+
}
|
|
49692
|
+
}
|
|
49693
|
+
if (pathExists(destinationPath)) {
|
|
49694
|
+
for (const previousName of previousNames) {
|
|
49695
|
+
const previousPath = import_node_path5.default.join(themesPath, previousName);
|
|
49696
|
+
if (!pathExists(previousPath)) continue;
|
|
49697
|
+
try {
|
|
49698
|
+
(0, import_node_fs4.rmSync)(previousPath, { recursive: true, force: true });
|
|
49699
|
+
} catch (error48) {
|
|
49700
|
+
console.warn(
|
|
49701
|
+
`Failed to remove an interrupted replacement copy for bundled theme ${JSON.stringify(id)}.`,
|
|
49702
|
+
error48
|
|
49703
|
+
);
|
|
49704
|
+
}
|
|
49705
|
+
}
|
|
49706
|
+
}
|
|
49707
|
+
}
|
|
49708
|
+
for (const entry of entries) {
|
|
49709
|
+
const match = /^\.(.+)\.bundled-theme\.(?:tmp|backup-tmp)-(\d+)$/.exec(entry.name);
|
|
49710
|
+
if (match === null || !BUNDLED_THEME_IDS.includes(match[1])) continue;
|
|
49711
|
+
if (Number(match[2]) === process.pid && !entry.isDirectory()) continue;
|
|
49712
|
+
try {
|
|
49713
|
+
(0, import_node_fs4.rmSync)(import_node_path5.default.join(themesPath, entry.name), { recursive: true, force: true });
|
|
49714
|
+
} catch (error48) {
|
|
49715
|
+
console.warn(`Failed to remove bundled theme copy temporary ${JSON.stringify(entry.name)}.`, error48);
|
|
49716
|
+
}
|
|
49717
|
+
}
|
|
49718
|
+
return failed;
|
|
49719
|
+
}
|
|
49720
|
+
function removeAfterFailure(candidatePath) {
|
|
49721
|
+
try {
|
|
49722
|
+
(0, import_node_fs4.rmSync)(candidatePath, { recursive: true, force: true });
|
|
49723
|
+
} catch {
|
|
49724
|
+
}
|
|
49725
|
+
}
|
|
49726
|
+
function pathExists(candidatePath) {
|
|
49727
|
+
try {
|
|
49728
|
+
(0, import_node_fs4.lstatSync)(candidatePath);
|
|
49729
|
+
return true;
|
|
49730
|
+
} catch {
|
|
49731
|
+
return false;
|
|
49732
|
+
}
|
|
49733
|
+
}
|
|
49734
|
+
function hasValidThemeIDs(value) {
|
|
49735
|
+
if (!Array.isArray(value) || !value.every((themeID) => typeof themeID === "string")) {
|
|
49736
|
+
return false;
|
|
49737
|
+
}
|
|
49738
|
+
const sorted = [...value].sort((left, right) => left.localeCompare(right, "en"));
|
|
49739
|
+
return sorted.length === new Set(sorted).size && sorted.every((themeID, index) => themeID === value[index]);
|
|
49740
|
+
}
|
|
49741
|
+
function isBundledThemeState(value) {
|
|
49742
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
49743
|
+
const candidate = value;
|
|
49744
|
+
return Object.keys(candidate).sort().join(",") === "initialThemeSelectionComplete,installedThemeIDs,version" && candidate.version === BUNDLED_THEME_STATE_VERSION && typeof candidate.initialThemeSelectionComplete === "boolean" && hasValidThemeIDs(candidate.installedThemeIDs);
|
|
49745
|
+
}
|
|
49746
|
+
function describeError(error48) {
|
|
49747
|
+
return error48 instanceof Error ? error48.message : String(error48);
|
|
49748
|
+
}
|
|
49749
|
+
|
|
49088
49750
|
// ../server/src/telemetry/types.ts
|
|
49089
49751
|
var telemetryVersionBrand = Symbol("telemetryVersion");
|
|
49090
49752
|
function telemetryVersion(value) {
|
|
49091
49753
|
return value;
|
|
49092
49754
|
}
|
|
49755
|
+
var THEME_STATES = ["none", ...BUNDLED_THEME_IDS, "custom"];
|
|
49093
49756
|
var AGENT_TYPES = [
|
|
49094
49757
|
"pi",
|
|
49095
49758
|
"opencode",
|
|
@@ -49121,12 +49784,30 @@ function deriveArtifactProperties(artifact) {
|
|
|
49121
49784
|
url_is_artifact_proxy: isTvArtifact(artifact.url)
|
|
49122
49785
|
};
|
|
49123
49786
|
}
|
|
49787
|
+
var BUNDLED_THEME_ID_SET = new Set(BUNDLED_THEME_IDS);
|
|
49788
|
+
function classifyThemeState(activeThemeName) {
|
|
49789
|
+
if (activeThemeName === null) return "none";
|
|
49790
|
+
if (BUNDLED_THEME_ID_SET.has(activeThemeName)) return activeThemeName;
|
|
49791
|
+
return "custom";
|
|
49792
|
+
}
|
|
49124
49793
|
function deriveThemeProperties(input) {
|
|
49125
49794
|
return {
|
|
49126
|
-
theme_state: input.activeThemeName
|
|
49795
|
+
theme_state: classifyThemeState(input.activeThemeName),
|
|
49127
49796
|
theme_count: input.themeCount
|
|
49128
49797
|
};
|
|
49129
49798
|
}
|
|
49799
|
+
function deriveThemeSettingsProperties(input) {
|
|
49800
|
+
const theme = input.themes.find((candidate) => candidate.id === input.activeThemeName);
|
|
49801
|
+
const mainDeclared = theme?.enableMainJS === true;
|
|
49802
|
+
return {
|
|
49803
|
+
theme_state: classifyThemeState(input.activeThemeName),
|
|
49804
|
+
theme_main_js_declared: mainDeclared,
|
|
49805
|
+
theme_main_js_enabled: mainDeclared && input.activeThemeName !== null && input.themeJavaScriptConsentIds.includes(input.activeThemeName),
|
|
49806
|
+
theme_iframe_background_enabled: theme?.enableIframeBackgroundJS === true,
|
|
49807
|
+
theme_iframe_overlay_enabled: theme?.enableIframeOverlayJS === true,
|
|
49808
|
+
appearance_mode: input.appearanceMode
|
|
49809
|
+
};
|
|
49810
|
+
}
|
|
49130
49811
|
var KNOWN_AGENT_TYPES = AGENT_TYPES.filter((agentType) => agentType !== "dot-agents" && agentType !== "interactive-install" && agentType !== "other");
|
|
49131
49812
|
var IPV4_VERSION = 4;
|
|
49132
49813
|
var TAILNET_FIRST_OCTET = 100;
|
|
@@ -49305,10 +49986,10 @@ function telemetryContextFromMeta(value) {
|
|
|
49305
49986
|
}
|
|
49306
49987
|
|
|
49307
49988
|
// ../server/src/artifact-proxy.ts
|
|
49308
|
-
var
|
|
49989
|
+
var import_node_crypto3 = require("node:crypto");
|
|
49309
49990
|
var import_promises2 = require("node:fs/promises");
|
|
49310
|
-
var
|
|
49311
|
-
var
|
|
49991
|
+
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
49992
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
49312
49993
|
var import_send = __toESM(require_send(), 1);
|
|
49313
49994
|
|
|
49314
49995
|
// ../../node_modules/marked/lib/marked.esm.js
|
|
@@ -50519,6 +51200,35 @@ var Kt = g.parseInline;
|
|
|
50519
51200
|
var Xt = b.parse;
|
|
50520
51201
|
var Jt = x.lex;
|
|
50521
51202
|
|
|
51203
|
+
// ../artifact/src/browser/appearance-resolver.ts
|
|
51204
|
+
function installAppearanceResolver(initialPreference, targetWindow = window) {
|
|
51205
|
+
const existing = targetWindow.__televisionAppearanceResolver;
|
|
51206
|
+
if (existing !== void 0) return existing;
|
|
51207
|
+
const query = targetWindow.matchMedia("(prefers-color-scheme: dark)");
|
|
51208
|
+
let preference = initialPreference;
|
|
51209
|
+
const isPreference = (value) => value === "system" || value === "light" || value === "dark";
|
|
51210
|
+
const apply = () => {
|
|
51211
|
+
const effective = preference === "system" ? query.matches ? "dark" : "light" : preference;
|
|
51212
|
+
targetWindow.document.documentElement.dataset.theme = effective;
|
|
51213
|
+
};
|
|
51214
|
+
const controller = {
|
|
51215
|
+
setPreference(nextPreference) {
|
|
51216
|
+
if (!isPreference(nextPreference)) return;
|
|
51217
|
+
preference = nextPreference;
|
|
51218
|
+
apply();
|
|
51219
|
+
}
|
|
51220
|
+
};
|
|
51221
|
+
targetWindow.__televisionAppearanceResolver = controller;
|
|
51222
|
+
query.addEventListener("change", () => {
|
|
51223
|
+
if (preference === "system") apply();
|
|
51224
|
+
});
|
|
51225
|
+
apply();
|
|
51226
|
+
return controller;
|
|
51227
|
+
}
|
|
51228
|
+
function appearanceResolverScriptSource(preferenceExpression) {
|
|
51229
|
+
return `(${installAppearanceResolver.toString()})(${preferenceExpression});`;
|
|
51230
|
+
}
|
|
51231
|
+
|
|
50522
51232
|
// ../utils/src/disposable.ts
|
|
50523
51233
|
function wrapDispose(target, isDisposed, setDisposed) {
|
|
50524
51234
|
const disposeImpl = target.dispose.bind(target);
|
|
@@ -50606,6 +51316,27 @@ function installBridge(win = window, options = {}) {
|
|
|
50606
51316
|
keyboard.preventDefault();
|
|
50607
51317
|
win.parent.postMessage({ type: "navigation-key", key: keyboard.key }, "*");
|
|
50608
51318
|
}, true);
|
|
51319
|
+
const pointerEventTypes = [
|
|
51320
|
+
"pointermove",
|
|
51321
|
+
"pointerdown",
|
|
51322
|
+
"pointerup",
|
|
51323
|
+
"pointercancel",
|
|
51324
|
+
"click"
|
|
51325
|
+
];
|
|
51326
|
+
for (const eventType of pointerEventTypes) {
|
|
51327
|
+
win.addEventListener(eventType, (event) => {
|
|
51328
|
+
const pointer = event;
|
|
51329
|
+
if (!pointer.isTrusted) return;
|
|
51330
|
+
win.parent.postMessage({
|
|
51331
|
+
type: "artifact-pointer",
|
|
51332
|
+
eventType,
|
|
51333
|
+
clientX: pointer.clientX,
|
|
51334
|
+
clientY: pointer.clientY,
|
|
51335
|
+
button: pointer.button,
|
|
51336
|
+
buttons: pointer.buttons
|
|
51337
|
+
}, "*");
|
|
51338
|
+
}, true);
|
|
51339
|
+
}
|
|
50609
51340
|
const capturedURL = win.location.href;
|
|
50610
51341
|
const isTvArtifactURL = (url2) => {
|
|
50611
51342
|
try {
|
|
@@ -50691,6 +51422,53 @@ function installBridge(win = window, options = {}) {
|
|
|
50691
51422
|
startPollLoop();
|
|
50692
51423
|
}
|
|
50693
51424
|
if (options.reportNavigation !== false) {
|
|
51425
|
+
const browserLocalProtocols = /* @__PURE__ */ new Set([
|
|
51426
|
+
"about:",
|
|
51427
|
+
"blob:",
|
|
51428
|
+
"chrome-extension:",
|
|
51429
|
+
"chrome:",
|
|
51430
|
+
"data:",
|
|
51431
|
+
"devtools:",
|
|
51432
|
+
"file:",
|
|
51433
|
+
"filesystem:",
|
|
51434
|
+
"javascript:",
|
|
51435
|
+
"view-source:"
|
|
51436
|
+
]);
|
|
51437
|
+
const applicationNavigationURL = (value, baseURL) => {
|
|
51438
|
+
try {
|
|
51439
|
+
const parsed = new URL(value, baseURL);
|
|
51440
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:") return null;
|
|
51441
|
+
return browserLocalProtocols.has(parsed.protocol) ? null : parsed;
|
|
51442
|
+
} catch {
|
|
51443
|
+
return null;
|
|
51444
|
+
}
|
|
51445
|
+
};
|
|
51446
|
+
const webNavigationURL = (value, baseURL) => {
|
|
51447
|
+
try {
|
|
51448
|
+
const parsed = new URL(value, baseURL);
|
|
51449
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:" ? parsed : null;
|
|
51450
|
+
} catch {
|
|
51451
|
+
return null;
|
|
51452
|
+
}
|
|
51453
|
+
};
|
|
51454
|
+
const handleApplicationAnchorActivation = (event) => {
|
|
51455
|
+
const leftClick = event.type === "click" && event.button === 0;
|
|
51456
|
+
const middleClick = event.type === "auxclick" && event.button === 1;
|
|
51457
|
+
if (!leftClick && !middleClick) return;
|
|
51458
|
+
const elementConstructor = win.document.defaultView?.Element;
|
|
51459
|
+
if (!elementConstructor || !(event.target instanceof elementConstructor)) return;
|
|
51460
|
+
const anchor = event.target.closest("a[href]");
|
|
51461
|
+
if (!anchor) return;
|
|
51462
|
+
const url2 = applicationNavigationURL(anchor.href, win.document.baseURI);
|
|
51463
|
+
if (!url2) return;
|
|
51464
|
+
const target = anchor.target.toLowerCase();
|
|
51465
|
+
const requestsAnotherContext = middleClick || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || target !== "" && target !== "_self";
|
|
51466
|
+
if (!requestsAnotherContext && !anchor.hasAttribute("download")) return;
|
|
51467
|
+
event.preventDefault();
|
|
51468
|
+
win.location.href = url2.href;
|
|
51469
|
+
};
|
|
51470
|
+
win.document.addEventListener("click", handleApplicationAnchorActivation, true);
|
|
51471
|
+
win.document.addEventListener("auxclick", handleApplicationAnchorActivation, true);
|
|
50694
51472
|
const postNavigationRequest = (message) => {
|
|
50695
51473
|
win.parent.postMessage({ type: "navigation-request", ...message }, "*");
|
|
50696
51474
|
};
|
|
@@ -50701,6 +51479,8 @@ function installBridge(win = window, options = {}) {
|
|
|
50701
51479
|
const navigateEvent = event;
|
|
50702
51480
|
const url2 = navigateEvent.destination?.url;
|
|
50703
51481
|
if (typeof url2 !== "string") return;
|
|
51482
|
+
const parsedURL = webNavigationURL(url2, win.location.href);
|
|
51483
|
+
if (!parsedURL) return;
|
|
50704
51484
|
const sameDocument = navigateEvent.destination?.sameDocument === true;
|
|
50705
51485
|
const message = {
|
|
50706
51486
|
url: url2,
|
|
@@ -50711,12 +51491,9 @@ function installBridge(win = window, options = {}) {
|
|
|
50711
51491
|
postNavigationRequest(message);
|
|
50712
51492
|
return;
|
|
50713
51493
|
}
|
|
50714
|
-
|
|
50715
|
-
|
|
50716
|
-
|
|
50717
|
-
return;
|
|
50718
|
-
}
|
|
50719
|
-
} catch {
|
|
51494
|
+
if (parsedURL.origin === win.location.origin) {
|
|
51495
|
+
postNavigationRequest({ ...message, native: true });
|
|
51496
|
+
return;
|
|
50720
51497
|
}
|
|
50721
51498
|
const canIntercept = navigateEvent.canIntercept;
|
|
50722
51499
|
if (canIntercept !== false) {
|
|
@@ -50737,13 +51514,9 @@ function installBridge(win = window, options = {}) {
|
|
|
50737
51514
|
if (anchor.target && anchor.target.toLowerCase() !== "_self") return;
|
|
50738
51515
|
if (anchor.hasAttribute("download")) return;
|
|
50739
51516
|
const href = anchor.getAttribute("href");
|
|
50740
|
-
if (!href
|
|
50741
|
-
|
|
50742
|
-
|
|
50743
|
-
url2 = new URL(anchor.href, win.document.baseURI);
|
|
50744
|
-
} catch {
|
|
50745
|
-
return;
|
|
50746
|
-
}
|
|
51517
|
+
if (!href) return;
|
|
51518
|
+
const url2 = webNavigationURL(anchor.href, win.document.baseURI);
|
|
51519
|
+
if (!url2) return;
|
|
50747
51520
|
if (url2.origin === win.location.origin && url2.pathname === win.location.pathname && url2.search === win.location.search && url2.hash !== "") {
|
|
50748
51521
|
postNavigationRequest({ url: url2.href, sameDocument: true });
|
|
50749
51522
|
return;
|
|
@@ -50777,9 +51550,10 @@ function installBridge(win = window, options = {}) {
|
|
|
50777
51550
|
const formConstructor = win.document.defaultView?.HTMLFormElement;
|
|
50778
51551
|
if (!formConstructor || !(form instanceof formConstructor)) return;
|
|
50779
51552
|
if (form.target && form.target.toLowerCase() !== "_self") return;
|
|
51553
|
+
const action = webNavigationURL(form.action || win.location.href, win.document.baseURI);
|
|
51554
|
+
if (!action) return;
|
|
50780
51555
|
submit.preventDefault();
|
|
50781
51556
|
const method = form.method.toLowerCase();
|
|
50782
|
-
const action = new URL(form.action || win.location.href, win.document.baseURI);
|
|
50783
51557
|
if (method === "get") {
|
|
50784
51558
|
const formDataConstructor = win.document.defaultView?.FormData;
|
|
50785
51559
|
if (!formDataConstructor) return;
|
|
@@ -50798,7 +51572,7 @@ function installBridge(win = window, options = {}) {
|
|
|
50798
51572
|
postBridgeReady();
|
|
50799
51573
|
}
|
|
50800
51574
|
function bridgeScriptSource(options = {}) {
|
|
50801
|
-
return `(function(){const __name=(target)=>target;(${installBridge.toString()})(window,${JSON.stringify(options)});})();`;
|
|
51575
|
+
return `(function(){const __name=(target)=>target;(${installAppearanceResolver.toString()})("system",window);(${installBridge.toString()})(window,${JSON.stringify(options)});})();`;
|
|
50802
51576
|
}
|
|
50803
51577
|
|
|
50804
51578
|
// ../server/src/markdown-doc-style.ts
|
|
@@ -50895,7 +51669,7 @@ li::before {
|
|
|
50895
51669
|
width: var(--md-gutter);
|
|
50896
51670
|
margin-left: calc(-1 * var(--md-gutter));
|
|
50897
51671
|
text-align: center;
|
|
50898
|
-
color:
|
|
51672
|
+
color: var(--color-text-muted);
|
|
50899
51673
|
}
|
|
50900
51674
|
|
|
50901
51675
|
ol > li {
|
|
@@ -50947,8 +51721,8 @@ pre code {
|
|
|
50947
51721
|
|
|
50948
51722
|
/* Blockquote: editor's grey border + muted text, with its indent. */
|
|
50949
51723
|
blockquote {
|
|
50950
|
-
border-left: 3px solid
|
|
50951
|
-
color:
|
|
51724
|
+
border-left: 3px solid var(--color-border);
|
|
51725
|
+
color: var(--color-text-muted);
|
|
50952
51726
|
padding-left: 1rem;
|
|
50953
51727
|
margin-left: 0.25rem;
|
|
50954
51728
|
}
|
|
@@ -51033,7 +51807,7 @@ function sendArtifactNotFound(req, res, store) {
|
|
|
51033
51807
|
return;
|
|
51034
51808
|
}
|
|
51035
51809
|
try {
|
|
51036
|
-
const body = await (0, import_promises2.readFile)(
|
|
51810
|
+
const body = await (0, import_promises2.readFile)(import_node_path6.default.join(viewPath, "index.html"));
|
|
51037
51811
|
applyProxyHeaders(res);
|
|
51038
51812
|
res.status(HTTP_NOT_FOUND).type("text/html; charset=utf-8");
|
|
51039
51813
|
res.setHeader("Content-Length", String(body.byteLength));
|
|
@@ -51057,30 +51831,68 @@ function isHTMLResponse(res) {
|
|
|
51057
51831
|
const value = Array.isArray(contentType) ? contentType.join("; ") : String(contentType ?? "");
|
|
51058
51832
|
return value.toLowerCase().startsWith("text/html");
|
|
51059
51833
|
}
|
|
51060
|
-
function injectedETag(stat, body, bridgeSource) {
|
|
51061
|
-
const hash2 = (0,
|
|
51834
|
+
function injectedETag(stat, body, bridgeSource, appearanceSource = "") {
|
|
51835
|
+
const hash2 = (0, import_node_crypto3.createHash)("sha256");
|
|
51062
51836
|
hash2.update(String(stat.size));
|
|
51063
51837
|
hash2.update("\0");
|
|
51064
51838
|
hash2.update(String(stat.mtimeMs));
|
|
51065
51839
|
hash2.update("\0");
|
|
51066
51840
|
hash2.update(bridgeSource);
|
|
51067
51841
|
hash2.update("\0");
|
|
51842
|
+
hash2.update(appearanceSource);
|
|
51843
|
+
hash2.update("\0");
|
|
51068
51844
|
hash2.update(body);
|
|
51069
51845
|
return `"${hash2.digest("base64url")}"`;
|
|
51070
51846
|
}
|
|
51071
|
-
function
|
|
51072
|
-
return
|
|
51847
|
+
function appearanceScript(source) {
|
|
51848
|
+
return `<script>
|
|
51849
|
+
${source}
|
|
51850
|
+
</script>`;
|
|
51851
|
+
}
|
|
51852
|
+
function injectAppearance(source, appearanceSource) {
|
|
51853
|
+
const script = appearanceScript(appearanceSource);
|
|
51854
|
+
const head = /<head\b[^>]*>/i.exec(source);
|
|
51855
|
+
if (head) {
|
|
51856
|
+
const afterHead = source.slice(head.index + head[0].length);
|
|
51857
|
+
const headEnd = /<\/head\s*>/i.exec(afterHead);
|
|
51858
|
+
const searchEnd2 = headEnd === null ? source.length : head.index + head[0].length + headEnd.index;
|
|
51859
|
+
const headContent = source.slice(head.index + head[0].length, searchEnd2);
|
|
51860
|
+
let insertion2 = head.index + head[0].length;
|
|
51861
|
+
for (const match of headContent.matchAll(/<meta\b[^>]*>/gi)) {
|
|
51862
|
+
if (/\bhttp-equiv\s*=\s*["']?Content-Security-Policy["']?/i.test(match[0])) {
|
|
51863
|
+
insertion2 = head.index + head[0].length + match.index + match[0].length;
|
|
51864
|
+
}
|
|
51865
|
+
}
|
|
51866
|
+
return `${source.slice(0, insertion2)}
|
|
51867
|
+
${script}${source.slice(insertion2)}`;
|
|
51868
|
+
}
|
|
51869
|
+
const firstStyleOrBody = /<(?:link\b[^>]*rel\s*=\s*["']?stylesheet|style\b|body\b)/i.exec(source);
|
|
51870
|
+
const searchEnd = firstStyleOrBody?.index ?? source.length;
|
|
51871
|
+
const prefix = source.slice(0, searchEnd);
|
|
51872
|
+
const doctype = /<!doctype\b[^>]*>/i.exec(prefix);
|
|
51873
|
+
let insertion = doctype === null ? 0 : doctype.index + doctype[0].length;
|
|
51874
|
+
for (const match of prefix.matchAll(/<meta\b[^>]*>/gi)) {
|
|
51875
|
+
if (/\bhttp-equiv\s*=\s*["']?Content-Security-Policy["']?/i.test(match[0])) {
|
|
51876
|
+
insertion = match.index + match[0].length;
|
|
51877
|
+
}
|
|
51878
|
+
}
|
|
51879
|
+
return `${source.slice(0, insertion)}
|
|
51880
|
+
${script}${source.slice(insertion)}`;
|
|
51881
|
+
}
|
|
51882
|
+
function injectDocument(body, appearanceSource, bridgeSource) {
|
|
51883
|
+
const early = injectAppearance(body.toString("utf8"), appearanceSource);
|
|
51884
|
+
return Buffer.from(`${early}
|
|
51073
51885
|
<script>
|
|
51074
51886
|
${bridgeSource}
|
|
51075
51887
|
</script>
|
|
51076
|
-
`)
|
|
51888
|
+
`);
|
|
51077
51889
|
}
|
|
51078
|
-
function sendInjectedHTML(req, res, stream, resolvedPath, stat, bridgeSource) {
|
|
51890
|
+
function sendInjectedHTML(req, res, stream, resolvedPath, stat, appearanceSource, bridgeSource) {
|
|
51079
51891
|
void (async () => {
|
|
51080
51892
|
try {
|
|
51081
51893
|
const source = await (0, import_promises2.readFile)(resolvedPath);
|
|
51082
|
-
const body =
|
|
51083
|
-
const etag = injectedETag(stat, body, bridgeSource);
|
|
51894
|
+
const body = injectDocument(source, appearanceSource, bridgeSource);
|
|
51895
|
+
const etag = injectedETag(stat, body, bridgeSource, appearanceSource);
|
|
51084
51896
|
stream.setHeader(resolvedPath, stat);
|
|
51085
51897
|
stream.type(resolvedPath);
|
|
51086
51898
|
res.setHeader("Cache-Control", HTML_CACHE_CONTROL);
|
|
@@ -51106,7 +51918,7 @@ function markdownDocument(renderedHTML) {
|
|
|
51106
51918
|
<head>
|
|
51107
51919
|
<meta charset="utf-8">
|
|
51108
51920
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
51109
|
-
<link rel="stylesheet" href="/canonical/
|
|
51921
|
+
<link rel="stylesheet" href="/canonical/v2/styles.css">
|
|
51110
51922
|
<style>${MARKDOWN_DOC_CSS}</style>
|
|
51111
51923
|
</head>
|
|
51112
51924
|
<body>
|
|
@@ -51114,11 +51926,16 @@ ${renderedHTML}
|
|
|
51114
51926
|
</body>
|
|
51115
51927
|
</html>`;
|
|
51116
51928
|
}
|
|
51117
|
-
function sendRenderedMarkdown(req, res, resolvedPath, stat, bridgeSource) {
|
|
51929
|
+
function sendRenderedMarkdown(req, res, resolvedPath, stat, appearanceSource, bridgeSource) {
|
|
51118
51930
|
void (async () => {
|
|
51119
51931
|
try {
|
|
51120
51932
|
const source = await (0, import_promises2.readFile)(resolvedPath, "utf8");
|
|
51121
|
-
const etag = injectedETag(
|
|
51933
|
+
const etag = injectedETag(
|
|
51934
|
+
stat,
|
|
51935
|
+
Buffer.from(source + markdownDocument("")),
|
|
51936
|
+
bridgeSource,
|
|
51937
|
+
appearanceSource
|
|
51938
|
+
);
|
|
51122
51939
|
applyProxyHeaders(res);
|
|
51123
51940
|
res.status(HTTP_OK2).type("text/html; charset=utf-8");
|
|
51124
51941
|
res.setHeader("Cache-Control", HTML_CACHE_CONTROL);
|
|
@@ -51132,7 +51949,11 @@ function sendRenderedMarkdown(req, res, resolvedPath, stat, bridgeSource) {
|
|
|
51132
51949
|
return;
|
|
51133
51950
|
}
|
|
51134
51951
|
const rendered = g.parse(source, { async: false });
|
|
51135
|
-
const body =
|
|
51952
|
+
const body = injectDocument(
|
|
51953
|
+
Buffer.from(markdownDocument(rendered)),
|
|
51954
|
+
appearanceSource,
|
|
51955
|
+
bridgeSource
|
|
51956
|
+
);
|
|
51136
51957
|
res.setHeader("Content-Length", String(body.byteLength));
|
|
51137
51958
|
res.end(body);
|
|
51138
51959
|
} catch {
|
|
@@ -51140,7 +51961,7 @@ function sendRenderedMarkdown(req, res, resolvedPath, stat, bridgeSource) {
|
|
|
51140
51961
|
}
|
|
51141
51962
|
})();
|
|
51142
51963
|
}
|
|
51143
|
-
function pipeWithInjection(req, res, subpath, options, bridgeSource, notFound) {
|
|
51964
|
+
function pipeWithInjection(req, res, subpath, options, appearanceSource, bridgeSource, notFound) {
|
|
51144
51965
|
applyProxyHeaders(res);
|
|
51145
51966
|
const stream = (0, import_send.default)(req, subpath, { ...options, etag: true });
|
|
51146
51967
|
const sendOriginal = stream.send.bind(stream);
|
|
@@ -51157,7 +51978,7 @@ function pipeWithInjection(req, res, subpath, options, bridgeSource, notFound) {
|
|
|
51157
51978
|
return;
|
|
51158
51979
|
}
|
|
51159
51980
|
res.removeHeader("ETag");
|
|
51160
|
-
sendInjectedHTML(req, res, stream, resolvedPath, stat, bridgeSource);
|
|
51981
|
+
sendInjectedHTML(req, res, stream, resolvedPath, stat, appearanceSource, bridgeSource);
|
|
51161
51982
|
};
|
|
51162
51983
|
stream.on("error", (error48) => {
|
|
51163
51984
|
if ((error48.status ?? HTTP_NOT_FOUND) === HTTP_NOT_FOUND && notFound) {
|
|
@@ -51169,18 +51990,18 @@ function pipeWithInjection(req, res, subpath, options, bridgeSource, notFound) {
|
|
|
51169
51990
|
});
|
|
51170
51991
|
stream.pipe(res);
|
|
51171
51992
|
}
|
|
51172
|
-
function serveDirectoryArtifact(req, res, store, artifact, subpath, bridgeSource) {
|
|
51993
|
+
function serveDirectoryArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource) {
|
|
51173
51994
|
if (subpath === "") {
|
|
51174
51995
|
applyProxyHeaders(res);
|
|
51175
51996
|
res.redirect(HTTP_MOVED_PERMANENTLY, `${proxyMountPath(artifact.id)}/`);
|
|
51176
51997
|
return;
|
|
51177
51998
|
}
|
|
51178
|
-
pipeWithInjection(req, res, subpath, { root: artifact.path, index: ["index.html", "index.htm"], dotfiles: "allow" }, bridgeSource, subpath === "/" ? () => sendArtifactNotFound(req, res, store) : void 0);
|
|
51999
|
+
pipeWithInjection(req, res, subpath, { root: artifact.path, index: ["index.html", "index.htm"], dotfiles: "allow" }, appearanceSource, bridgeSource, subpath === "/" ? () => sendArtifactNotFound(req, res, store) : void 0);
|
|
51179
52000
|
}
|
|
51180
|
-
function serveFileArtifact(req, res, store, artifact, subpath, bridgeSource) {
|
|
52001
|
+
function serveFileArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource) {
|
|
51181
52002
|
let stat;
|
|
51182
52003
|
try {
|
|
51183
|
-
stat =
|
|
52004
|
+
stat = import_node_fs5.default.statSync(artifact.path);
|
|
51184
52005
|
} catch {
|
|
51185
52006
|
const basename2 = artifactBasename(artifact.path);
|
|
51186
52007
|
if (subpath === `/${encodeURIComponent(basename2)}`) sendArtifactNotFound(req, res, store);
|
|
@@ -51203,14 +52024,14 @@ function serveFileArtifact(req, res, store, artifact, subpath, bridgeSource) {
|
|
|
51203
52024
|
sendNotFound(res);
|
|
51204
52025
|
return;
|
|
51205
52026
|
}
|
|
51206
|
-
pipeWithInjection(req, res, subpath, { root:
|
|
52027
|
+
pipeWithInjection(req, res, subpath, { root: import_node_path6.default.dirname(artifact.path), index: false, dotfiles: "allow" }, appearanceSource, bridgeSource, () => sendArtifactNotFound(req, res, store));
|
|
51207
52028
|
}
|
|
51208
|
-
function serveMarkdownArtifact(req, res, store, artifact, subpath, bridgeSource) {
|
|
52029
|
+
function serveMarkdownArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource) {
|
|
51209
52030
|
const basename = artifactBasename(artifact.path);
|
|
51210
52031
|
const canonical = proxyFilePath(artifact.id, basename);
|
|
51211
52032
|
let stat;
|
|
51212
52033
|
try {
|
|
51213
|
-
stat =
|
|
52034
|
+
stat = import_node_fs5.default.statSync(artifact.path);
|
|
51214
52035
|
} catch {
|
|
51215
52036
|
if (subpath === `/${encodeURIComponent(basename)}`) sendArtifactNotFound(req, res, store);
|
|
51216
52037
|
else sendNotFound(res);
|
|
@@ -51230,9 +52051,10 @@ function serveMarkdownArtifact(req, res, store, artifact, subpath, bridgeSource)
|
|
|
51230
52051
|
sendNotFound(res);
|
|
51231
52052
|
return;
|
|
51232
52053
|
}
|
|
51233
|
-
sendRenderedMarkdown(req, res, artifact.path, stat, bridgeSource);
|
|
52054
|
+
sendRenderedMarkdown(req, res, artifact.path, stat, appearanceSource, bridgeSource);
|
|
51234
52055
|
}
|
|
51235
52056
|
function serveArtifactProxy(store, options = {}) {
|
|
52057
|
+
const appearanceSource = appearanceResolverScriptSource('"system"');
|
|
51236
52058
|
const bridgeSource = bridgeScriptSource({ pollCadence: options.pollCadence });
|
|
51237
52059
|
return (req, res) => {
|
|
51238
52060
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
@@ -51250,15 +52072,15 @@ function serveArtifactProxy(store, options = {}) {
|
|
|
51250
52072
|
sendNotFound(res);
|
|
51251
52073
|
return;
|
|
51252
52074
|
}
|
|
51253
|
-
if (isMarkdownPath(artifact.path)) serveMarkdownArtifact(req, res, store, artifact, subpath, bridgeSource);
|
|
51254
|
-
else if (hasTrailingSeparator(artifact.path)) serveDirectoryArtifact(req, res, store, artifact, subpath, bridgeSource);
|
|
51255
|
-
else serveFileArtifact(req, res, store, artifact, subpath, bridgeSource);
|
|
52075
|
+
if (isMarkdownPath(artifact.path)) serveMarkdownArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource);
|
|
52076
|
+
else if (hasTrailingSeparator(artifact.path)) serveDirectoryArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource);
|
|
52077
|
+
else serveFileArtifact(req, res, store, artifact, subpath, appearanceSource, bridgeSource);
|
|
51256
52078
|
};
|
|
51257
52079
|
}
|
|
51258
52080
|
|
|
51259
52081
|
// ../server/src/markdown.ts
|
|
51260
52082
|
var fs2 = __toESM(require("node:fs/promises"), 1);
|
|
51261
|
-
var
|
|
52083
|
+
var import_node_fs6 = require("node:fs");
|
|
51262
52084
|
var import_express = __toESM(require_express2(), 1);
|
|
51263
52085
|
var HTTP_NO_CONTENT = 204;
|
|
51264
52086
|
var HTTP_NOT_FOUND2 = 404;
|
|
@@ -51304,7 +52126,7 @@ function serveMarkdownContent(store) {
|
|
|
51304
52126
|
}
|
|
51305
52127
|
const content = typeof req.body === "string" ? req.body : "";
|
|
51306
52128
|
try {
|
|
51307
|
-
await fs2.access(artifact.path,
|
|
52129
|
+
await fs2.access(artifact.path, import_node_fs6.constants.F_OK);
|
|
51308
52130
|
await fs2.writeFile(artifact.path, content, "utf8");
|
|
51309
52131
|
res.status(HTTP_NO_CONTENT).end();
|
|
51310
52132
|
} catch (error48) {
|
|
@@ -51324,83 +52146,6 @@ function serveMarkdownContent(store) {
|
|
|
51324
52146
|
};
|
|
51325
52147
|
}
|
|
51326
52148
|
|
|
51327
|
-
// ../server/src/themes.ts
|
|
51328
|
-
var import_node_fs5 = require("node:fs");
|
|
51329
|
-
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
51330
|
-
var HTTP_NOT_FOUND_STATUS = 404;
|
|
51331
|
-
var THEME_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
51332
|
-
var THEME_ENTRY_FILE = "theme.css";
|
|
51333
|
-
var URL_RE = /url\(\s*(["']?)([^"')\s]+)\1\s*\)/g;
|
|
51334
|
-
function isValidThemeName(name) {
|
|
51335
|
-
return THEME_NAME_PATTERN.test(name);
|
|
51336
|
-
}
|
|
51337
|
-
function assertValidThemeName(name) {
|
|
51338
|
-
if (!isValidThemeName(name)) {
|
|
51339
|
-
throw new Error(`Invalid theme name: ${name}`);
|
|
51340
|
-
}
|
|
51341
|
-
}
|
|
51342
|
-
function getThemesDir(storagePath) {
|
|
51343
|
-
return import_node_path4.default.join(storagePath, "themes");
|
|
51344
|
-
}
|
|
51345
|
-
function getThemeDir(storagePath, name) {
|
|
51346
|
-
assertValidThemeName(name);
|
|
51347
|
-
return import_node_path4.default.join(getThemesDir(storagePath), name);
|
|
51348
|
-
}
|
|
51349
|
-
function getThemeEntryPath(storagePath, name) {
|
|
51350
|
-
return import_node_path4.default.join(getThemeDir(storagePath, name), THEME_ENTRY_FILE);
|
|
51351
|
-
}
|
|
51352
|
-
function themeExists(storagePath, name) {
|
|
51353
|
-
if (!isValidThemeName(name)) {
|
|
51354
|
-
return false;
|
|
51355
|
-
}
|
|
51356
|
-
try {
|
|
51357
|
-
return (0, import_node_fs5.statSync)(getThemeEntryPath(storagePath, name)).isFile();
|
|
51358
|
-
} catch {
|
|
51359
|
-
return false;
|
|
51360
|
-
}
|
|
51361
|
-
}
|
|
51362
|
-
function listThemeNames(storagePath) {
|
|
51363
|
-
const themesDir = getThemesDir(storagePath);
|
|
51364
|
-
if (!(0, import_node_fs5.existsSync)(themesDir)) {
|
|
51365
|
-
return [];
|
|
51366
|
-
}
|
|
51367
|
-
let entries;
|
|
51368
|
-
try {
|
|
51369
|
-
entries = (0, import_node_fs5.readdirSync)(themesDir);
|
|
51370
|
-
} catch {
|
|
51371
|
-
return [];
|
|
51372
|
-
}
|
|
51373
|
-
return entries.filter((name) => themeExists(storagePath, name)).sort((left, right) => left.localeCompare(right));
|
|
51374
|
-
}
|
|
51375
|
-
function rewriteThemeURLs(css, themeName) {
|
|
51376
|
-
return css.replace(URL_RE, (whole, quote, url2) => {
|
|
51377
|
-
if (/^(data:|https?:)/.test(url2) || url2.startsWith("/")) {
|
|
51378
|
-
return whole;
|
|
51379
|
-
}
|
|
51380
|
-
const rewritten = `/themes/${themeName}/${url2}`;
|
|
51381
|
-
return `url(${quote}${rewritten}${quote})`;
|
|
51382
|
-
});
|
|
51383
|
-
}
|
|
51384
|
-
function serveThemeCSS(storagePath) {
|
|
51385
|
-
return (req, res, next) => {
|
|
51386
|
-
const { name } = req.params;
|
|
51387
|
-
if (!isValidThemeName(name) || !themeExists(storagePath, name)) {
|
|
51388
|
-
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
51389
|
-
return;
|
|
51390
|
-
}
|
|
51391
|
-
try {
|
|
51392
|
-
const css = (0, import_node_fs5.readFileSync)(getThemeEntryPath(storagePath, name), "utf8");
|
|
51393
|
-
res.type("text/css").setHeader("Cache-Control", "no-cache").send(rewriteThemeURLs(css, name));
|
|
51394
|
-
} catch (error48) {
|
|
51395
|
-
if (error48.code === "ENOENT") {
|
|
51396
|
-
res.sendStatus(HTTP_NOT_FOUND_STATUS);
|
|
51397
|
-
return;
|
|
51398
|
-
}
|
|
51399
|
-
next(error48);
|
|
51400
|
-
}
|
|
51401
|
-
};
|
|
51402
|
-
}
|
|
51403
|
-
|
|
51404
52149
|
// ../server/src/routes.ts
|
|
51405
52150
|
var patchChannelSchema = external_exports.object({
|
|
51406
52151
|
name: external_exports.string().optional(),
|
|
@@ -51442,7 +52187,11 @@ var patchArtifactSchema = external_exports.object({
|
|
|
51442
52187
|
var patchDisplaySchema = external_exports.object({
|
|
51443
52188
|
focusedChannelId: external_exports.string().nullable().optional(),
|
|
51444
52189
|
pinnedChannelIds: external_exports.array(external_exports.string()).optional(),
|
|
51445
|
-
activeThemeName: external_exports.string().
|
|
52190
|
+
activeThemeName: external_exports.string().nullable().optional(),
|
|
52191
|
+
appearanceMode: external_exports.enum(["system", "light", "dark"]).optional(),
|
|
52192
|
+
themeJavaScriptConsentIds: external_exports.array(external_exports.string().min(1)).refine((ids) => new Set(ids).size === ids.length, {
|
|
52193
|
+
message: "themeJavaScriptConsentIds must not contain duplicate theme ids"
|
|
52194
|
+
}).optional()
|
|
51446
52195
|
}).strict();
|
|
51447
52196
|
var focusSchema = external_exports.object({
|
|
51448
52197
|
artifactID: external_exports.string()
|
|
@@ -51520,8 +52269,8 @@ function registerRoutes(app, store, options) {
|
|
|
51520
52269
|
app.options("/artifacts/:id", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51521
52270
|
app.options("/display", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51522
52271
|
app.options("/display/focus", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51523
|
-
app.options("/themes
|
|
51524
|
-
app.options("/themes
|
|
52272
|
+
app.options("/themes", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
52273
|
+
app.options("/themes/refresh", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51525
52274
|
app.options("/markdown/:id", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51526
52275
|
app.options("/telemetry", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
51527
52276
|
app.options("/telemetry/enable", (_req, res) => res.status(HTTP_NO_CONTENT2).end());
|
|
@@ -51535,6 +52284,12 @@ function registerRoutes(app, store, options) {
|
|
|
51535
52284
|
app.post("/telemetry/disable", ...auth, async (_req, res) => {
|
|
51536
52285
|
res.json(await options.disableTelemetry?.() ?? { state: "unavailable", reason: null, guidPresent: false, region: "us" });
|
|
51537
52286
|
});
|
|
52287
|
+
app.get("/themes", ...auth, (_req, res) => {
|
|
52288
|
+
res.json(store.getThemeRegistry());
|
|
52289
|
+
});
|
|
52290
|
+
app.post("/themes/refresh", ...auth, (req, res) => {
|
|
52291
|
+
res.json(store.refreshThemeRegistry(telemetryContext(req)));
|
|
52292
|
+
});
|
|
51538
52293
|
app.get("/channels", ...auth, (_req, res) => {
|
|
51539
52294
|
res.json({ channels: store.listChannels() });
|
|
51540
52295
|
});
|
|
@@ -51699,11 +52454,11 @@ var import_websocket = __toESM(require_websocket(), 1);
|
|
|
51699
52454
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
51700
52455
|
|
|
51701
52456
|
// ../server/src/auth.ts
|
|
51702
|
-
var
|
|
52457
|
+
var import_node_crypto4 = require("node:crypto");
|
|
51703
52458
|
var AUTH_TOKEN_BYTES = 32;
|
|
51704
52459
|
var AUTH_PARSE_BASE_URL = "http://localhost";
|
|
51705
52460
|
function createToken() {
|
|
51706
|
-
return (0,
|
|
52461
|
+
return (0, import_node_crypto4.randomBytes)(AUTH_TOKEN_BYTES).toString("hex");
|
|
51707
52462
|
}
|
|
51708
52463
|
function isAuthorizedBearer(authorizationHeader, expectedToken) {
|
|
51709
52464
|
if (typeof authorizationHeader !== "string" || !authorizationHeader.startsWith("Bearer ")) {
|
|
@@ -51865,7 +52620,15 @@ var EventStreamServer = class extends withDisposable(class {
|
|
|
51865
52620
|
this.broadcast({ type: "pinned-channels-changed", pinnedChannelIds: event.pinnedChannelIds });
|
|
51866
52621
|
};
|
|
51867
52622
|
const onThemeChanged = (event) => {
|
|
51868
|
-
this.broadcast({
|
|
52623
|
+
this.broadcast({
|
|
52624
|
+
type: "theme-changed",
|
|
52625
|
+
themeName: event.themeName,
|
|
52626
|
+
activeThemeColorScheme: event.activeThemeColorScheme,
|
|
52627
|
+
themeJavaScriptConsentIds: [...event.themeJavaScriptConsentIds]
|
|
52628
|
+
});
|
|
52629
|
+
};
|
|
52630
|
+
const onAppearanceChanged = (event) => {
|
|
52631
|
+
this.broadcast({ type: "appearance-changed", appearanceMode: event.appearanceMode });
|
|
51869
52632
|
};
|
|
51870
52633
|
const onArtifactFocus = (event) => {
|
|
51871
52634
|
this.broadcast({ type: "artifact-focus", channelID: event.channelID, artifactID: event.artifactID });
|
|
@@ -51880,6 +52643,7 @@ var EventStreamServer = class extends withDisposable(class {
|
|
|
51880
52643
|
this.store.addEventListener("channel-changed", onChannelChanged);
|
|
51881
52644
|
this.store.addEventListener("pinned-channels-changed", onPinnedChannelsChanged);
|
|
51882
52645
|
this.store.addEventListener("theme-changed", onThemeChanged);
|
|
52646
|
+
this.store.addEventListener("appearance-changed", onAppearanceChanged);
|
|
51883
52647
|
this.store.addEventListener("artifact-focus", onArtifactFocus);
|
|
51884
52648
|
this.unsubscribe.push(
|
|
51885
52649
|
() => this.store.removeEventListener("artifact-created", onArtifactCreated),
|
|
@@ -51892,6 +52656,7 @@ var EventStreamServer = class extends withDisposable(class {
|
|
|
51892
52656
|
() => this.store.removeEventListener("channel-changed", onChannelChanged),
|
|
51893
52657
|
() => this.store.removeEventListener("pinned-channels-changed", onPinnedChannelsChanged),
|
|
51894
52658
|
() => this.store.removeEventListener("theme-changed", onThemeChanged),
|
|
52659
|
+
() => this.store.removeEventListener("appearance-changed", onAppearanceChanged),
|
|
51895
52660
|
() => this.store.removeEventListener("artifact-focus", onArtifactFocus)
|
|
51896
52661
|
);
|
|
51897
52662
|
}
|
|
@@ -51921,7 +52686,7 @@ function isTelemetryActivityMessage(parsed, expectedClientId) {
|
|
|
51921
52686
|
var import_node_child_process2 = require("node:child_process");
|
|
51922
52687
|
var import_promises3 = require("node:fs/promises");
|
|
51923
52688
|
var import_node_os3 = require("node:os");
|
|
51924
|
-
var
|
|
52689
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
51925
52690
|
var launchACPProcess = (command, args, options) => {
|
|
51926
52691
|
const child = (0, import_node_child_process2.spawn)(command, args, options);
|
|
51927
52692
|
const directKill = child.kill.bind(child);
|
|
@@ -51964,7 +52729,7 @@ function trackChild(child) {
|
|
|
51964
52729
|
child.once("exit", untrack);
|
|
51965
52730
|
child.once("error", untrack);
|
|
51966
52731
|
}
|
|
51967
|
-
var ACP_STUB_CWD =
|
|
52732
|
+
var ACP_STUB_CWD = import_node_path7.default.join((0, import_node_os3.homedir)(), ".television", "acp");
|
|
51968
52733
|
var ACPBridge = class extends withDisposable(class {
|
|
51969
52734
|
}) {
|
|
51970
52735
|
child = null;
|
|
@@ -51981,7 +52746,7 @@ var ACPBridge = class extends withDisposable(class {
|
|
|
51981
52746
|
this.send = options.send;
|
|
51982
52747
|
this.profile = options.profile;
|
|
51983
52748
|
this.launchProcess = options.launchProcess ?? launchACPProcess;
|
|
51984
|
-
this.sessionCwd =
|
|
52749
|
+
this.sessionCwd = import_node_path7.default.resolve(process.cwd());
|
|
51985
52750
|
}
|
|
51986
52751
|
handleClientMessage(message) {
|
|
51987
52752
|
switch (message.type) {
|
|
@@ -52217,87 +52982,63 @@ function splitListenValues(values) {
|
|
|
52217
52982
|
}
|
|
52218
52983
|
|
|
52219
52984
|
// ../server/src/canonical.ts
|
|
52220
|
-
var
|
|
52221
|
-
var
|
|
52222
|
-
var
|
|
52985
|
+
var import_node_crypto5 = require("node:crypto");
|
|
52986
|
+
var import_node_fs7 = require("node:fs");
|
|
52987
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
52223
52988
|
var CACHE_CONTROL_NO_CACHE = "no-cache";
|
|
52224
|
-
var
|
|
52225
|
-
var
|
|
52226
|
-
var NO_THEME_HASH = "none";
|
|
52989
|
+
var ETAG_DIGEST_LENGTH2 = 16;
|
|
52990
|
+
var HTTP_NOT_MODIFIED_STATUS2 = 304;
|
|
52227
52991
|
var CANONICAL_STYLESHEET = "styles.css";
|
|
52228
|
-
function
|
|
52229
|
-
const
|
|
52230
|
-
|
|
52231
|
-
|
|
52232
|
-
|
|
52233
|
-
|
|
52234
|
-
|
|
52235
|
-
|
|
52236
|
-
|
|
52237
|
-
|
|
52238
|
-
|
|
52239
|
-
|
|
52240
|
-
|
|
52241
|
-
|
|
52242
|
-
|
|
52992
|
+
function canonicalWrapper(version2, frozen = false, querySuffix = "") {
|
|
52993
|
+
const baseImport = `@import url("/canonical/${version2}/base.css${querySuffix}");
|
|
52994
|
+
`;
|
|
52995
|
+
if (frozen) return baseImport;
|
|
52996
|
+
return `${baseImport}@import url("/theme/theme.css${querySuffix}");
|
|
52997
|
+
`;
|
|
52998
|
+
}
|
|
52999
|
+
function serveCanonicalBase(canonicalDir) {
|
|
53000
|
+
const body = (0, import_node_fs7.readFileSync)(import_node_path8.default.join(canonicalDir, CANONICAL_STYLESHEET));
|
|
53001
|
+
const digest = (0, import_node_crypto5.createHash)("sha256").update(body).digest("hex").slice(0, ETAG_DIGEST_LENGTH2);
|
|
53002
|
+
const etag = `W/"canonical-base-${digest}"`;
|
|
53003
|
+
return (req, res) => {
|
|
53004
|
+
res.type("text/css");
|
|
53005
|
+
res.setHeader("Cache-Control", CACHE_CONTROL_NO_CACHE);
|
|
53006
|
+
res.setHeader("ETag", etag);
|
|
53007
|
+
if (matchesIfNoneMatch2(req.headers["if-none-match"], etag)) {
|
|
53008
|
+
res.status(HTTP_NOT_MODIFIED_STATUS2).end();
|
|
53009
|
+
return;
|
|
52243
53010
|
}
|
|
53011
|
+
res.send(body);
|
|
52244
53012
|
};
|
|
52245
53013
|
}
|
|
52246
|
-
function
|
|
52247
|
-
|
|
52248
|
-
|
|
52249
|
-
|
|
52250
|
-
|
|
52251
|
-
|
|
52252
|
-
|
|
52253
|
-
|
|
52254
|
-
|
|
52255
|
-
|
|
52256
|
-
|
|
52257
|
-
|
|
52258
|
-
|
|
52259
|
-
try {
|
|
52260
|
-
const themeCSS = (0, import_node_fs6.readFileSync)(getThemeEntryPath(store.storagePath, activeThemeName), "utf8");
|
|
52261
|
-
return {
|
|
52262
|
-
body: `${bundle.css}
|
|
52263
|
-
|
|
52264
|
-
/* active theme: ${activeThemeName} */
|
|
52265
|
-
${rewriteThemeURLs(themeCSS, activeThemeName)}`,
|
|
52266
|
-
etag: buildETag(bundle.hash, hashContent(themeCSS))
|
|
52267
|
-
};
|
|
52268
|
-
} catch (error48) {
|
|
52269
|
-
if (error48.code === "ENOENT") {
|
|
52270
|
-
logMissingActiveTheme(store.storagePath, activeThemeName);
|
|
52271
|
-
return { body: bundle.css, etag: buildETag(bundle.hash, NO_THEME_HASH) };
|
|
53014
|
+
function serveCanonicalStyles(version2, frozen = false) {
|
|
53015
|
+
return (req, res) => {
|
|
53016
|
+
const queryIndex = req.originalUrl.indexOf("?");
|
|
53017
|
+
const querySuffix = queryIndex === -1 ? "" : req.originalUrl.slice(queryIndex);
|
|
53018
|
+
const body = canonicalWrapper(version2, frozen, querySuffix);
|
|
53019
|
+
const digest = (0, import_node_crypto5.createHash)("sha256").update(body).digest("hex").slice(0, ETAG_DIGEST_LENGTH2);
|
|
53020
|
+
const etag = `W/"canonical-${version2}-${digest}"`;
|
|
53021
|
+
res.type("text/css");
|
|
53022
|
+
res.setHeader("Cache-Control", CACHE_CONTROL_NO_CACHE);
|
|
53023
|
+
res.setHeader("ETag", etag);
|
|
53024
|
+
if (matchesIfNoneMatch2(req.headers["if-none-match"], etag)) {
|
|
53025
|
+
res.status(HTTP_NOT_MODIFIED_STATUS2).end();
|
|
53026
|
+
return;
|
|
52272
53027
|
}
|
|
52273
|
-
|
|
52274
|
-
}
|
|
52275
|
-
}
|
|
52276
|
-
function buildETag(bundleHash, themeHash) {
|
|
52277
|
-
return `W/"v1-${bundleHash}-${themeHash}"`;
|
|
52278
|
-
}
|
|
52279
|
-
function hashContent(content) {
|
|
52280
|
-
return (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, HASH_HEX_LENGTH);
|
|
52281
|
-
}
|
|
52282
|
-
function matchesIfNoneMatch(header, etag) {
|
|
52283
|
-
if (!header) {
|
|
52284
|
-
return false;
|
|
52285
|
-
}
|
|
52286
|
-
const rawValues = Array.isArray(header) ? header : [header];
|
|
52287
|
-
return rawValues.some(
|
|
52288
|
-
(rawValue) => rawValue.split(",").map((value) => value.trim()).some((value) => value === "*" || value === etag)
|
|
52289
|
-
);
|
|
53028
|
+
res.send(body);
|
|
53029
|
+
};
|
|
52290
53030
|
}
|
|
52291
|
-
function
|
|
52292
|
-
|
|
52293
|
-
|
|
52294
|
-
|
|
53031
|
+
function matchesIfNoneMatch2(header, etag) {
|
|
53032
|
+
if (header === void 0) return false;
|
|
53033
|
+
const values = Array.isArray(header) ? header : [header];
|
|
53034
|
+
return values.some(
|
|
53035
|
+
(value) => value.split(",").map((candidate) => candidate.trim()).some((candidate) => candidate === "*" || candidate === etag)
|
|
52295
53036
|
);
|
|
52296
53037
|
}
|
|
52297
53038
|
|
|
52298
53039
|
// ../server/src/logger.ts
|
|
52299
|
-
var
|
|
52300
|
-
var
|
|
53040
|
+
var import_node_fs8 = require("node:fs");
|
|
53041
|
+
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
52301
53042
|
var LOG_DIR_NAME = "logs";
|
|
52302
53043
|
var ACTIVE_LOG_FILE = "tv.log";
|
|
52303
53044
|
var LOG_RETENTION_DAYS = 14;
|
|
@@ -52313,9 +53054,9 @@ var ROTATION_LOCK_TIMEOUT_MS = 5e3;
|
|
|
52313
53054
|
var INT32_BYTES = 4;
|
|
52314
53055
|
function log(storagePath, msg, data) {
|
|
52315
53056
|
try {
|
|
52316
|
-
const logsDir =
|
|
52317
|
-
(0,
|
|
52318
|
-
const logPath =
|
|
53057
|
+
const logsDir = import_node_path9.default.join(storagePath, LOG_DIR_NAME);
|
|
53058
|
+
(0, import_node_fs8.mkdirSync)(logsDir, { recursive: true });
|
|
53059
|
+
const logPath = import_node_path9.default.join(logsDir, ACTIVE_LOG_FILE);
|
|
52319
53060
|
rotateIfStale(logsDir, logPath);
|
|
52320
53061
|
const record2 = {
|
|
52321
53062
|
ts: localTimestamp(/* @__PURE__ */ new Date()),
|
|
@@ -52323,7 +53064,7 @@ function log(storagePath, msg, data) {
|
|
|
52323
53064
|
msg,
|
|
52324
53065
|
...serializeData(data)
|
|
52325
53066
|
};
|
|
52326
|
-
(0,
|
|
53067
|
+
(0, import_node_fs8.appendFileSync)(logPath, `${JSON.stringify(record2)}
|
|
52327
53068
|
`, { encoding: "utf8" });
|
|
52328
53069
|
} catch (error48) {
|
|
52329
53070
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
@@ -52346,21 +53087,21 @@ function serializeError(error48) {
|
|
|
52346
53087
|
return { name: "NonError", message: String(error48) };
|
|
52347
53088
|
}
|
|
52348
53089
|
function rotateIfStale(logsDir, logPath) {
|
|
52349
|
-
const lockPath =
|
|
53090
|
+
const lockPath = import_node_path9.default.join(logsDir, ROTATION_LOCK_DIR);
|
|
52350
53091
|
if (!acquireRotationLock(lockPath)) return;
|
|
52351
53092
|
try {
|
|
52352
53093
|
let stats;
|
|
52353
53094
|
try {
|
|
52354
|
-
stats = (0,
|
|
53095
|
+
stats = (0, import_node_fs8.statSync)(logPath);
|
|
52355
53096
|
} catch (error48) {
|
|
52356
53097
|
if (error48.code === "ENOENT") return;
|
|
52357
53098
|
throw error48;
|
|
52358
53099
|
}
|
|
52359
53100
|
if (!isPreviousLocalCalendarDay(stats.mtime, /* @__PURE__ */ new Date())) return;
|
|
52360
53101
|
const archiveDate = localDateString(stats.mtime);
|
|
52361
|
-
const archivePath = uniqueArchivePath(
|
|
53102
|
+
const archivePath = uniqueArchivePath(import_node_path9.default.join(logsDir, `${ACTIVE_LOG_FILE}.${archiveDate}`));
|
|
52362
53103
|
try {
|
|
52363
|
-
(0,
|
|
53104
|
+
(0, import_node_fs8.renameSync)(logPath, archivePath);
|
|
52364
53105
|
} catch (error48) {
|
|
52365
53106
|
if (error48.code === "ENOENT") return;
|
|
52366
53107
|
throw error48;
|
|
@@ -52374,7 +53115,7 @@ function acquireRotationLock(lockPath) {
|
|
|
52374
53115
|
const deadline = Date.now() + ROTATION_LOCK_TIMEOUT_MS;
|
|
52375
53116
|
while (true) {
|
|
52376
53117
|
try {
|
|
52377
|
-
(0,
|
|
53118
|
+
(0, import_node_fs8.mkdirSync)(lockPath);
|
|
52378
53119
|
return true;
|
|
52379
53120
|
} catch (error48) {
|
|
52380
53121
|
if (error48.code !== "EEXIST") throw error48;
|
|
@@ -52385,7 +53126,7 @@ function acquireRotationLock(lockPath) {
|
|
|
52385
53126
|
}
|
|
52386
53127
|
function releaseRotationLock(lockPath) {
|
|
52387
53128
|
try {
|
|
52388
|
-
(0,
|
|
53129
|
+
(0, import_node_fs8.rmdirSync)(lockPath);
|
|
52389
53130
|
} catch {
|
|
52390
53131
|
}
|
|
52391
53132
|
}
|
|
@@ -52393,21 +53134,21 @@ function sleepSync(ms) {
|
|
|
52393
53134
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(INT32_BYTES)), 0, 0, ms);
|
|
52394
53135
|
}
|
|
52395
53136
|
function uniqueArchivePath(basePath) {
|
|
52396
|
-
if (!(0,
|
|
53137
|
+
if (!(0, import_node_fs8.existsSync)(basePath)) return basePath;
|
|
52397
53138
|
for (let index = 1; ; index += 1) {
|
|
52398
53139
|
const candidate = `${basePath}-${index}`;
|
|
52399
|
-
if (!(0,
|
|
53140
|
+
if (!(0, import_node_fs8.existsSync)(candidate)) return candidate;
|
|
52400
53141
|
}
|
|
52401
53142
|
}
|
|
52402
53143
|
function removeExpiredArchives(logsDir, retainedArchivePath) {
|
|
52403
53144
|
const cutoff = Date.now() - LOG_RETENTION_DAYS * MS_PER_DAY;
|
|
52404
|
-
for (const entry of (0,
|
|
53145
|
+
for (const entry of (0, import_node_fs8.readdirSync)(logsDir, { withFileTypes: true })) {
|
|
52405
53146
|
if (!entry.isFile() || !entry.name.startsWith(`${ACTIVE_LOG_FILE}.`)) continue;
|
|
52406
|
-
const fullPath =
|
|
53147
|
+
const fullPath = import_node_path9.default.join(logsDir, entry.name);
|
|
52407
53148
|
if (fullPath === retainedArchivePath) continue;
|
|
52408
53149
|
try {
|
|
52409
|
-
if ((0,
|
|
52410
|
-
(0,
|
|
53150
|
+
if ((0, import_node_fs8.statSync)(fullPath).mtime.getTime() < cutoff) {
|
|
53151
|
+
(0, import_node_fs8.rmSync)(fullPath, { force: true });
|
|
52411
53152
|
}
|
|
52412
53153
|
} catch {
|
|
52413
53154
|
}
|
|
@@ -52581,14 +53322,23 @@ function createServerStoreTelemetryHooks(store, capture2) {
|
|
|
52581
53322
|
}
|
|
52582
53323
|
});
|
|
52583
53324
|
},
|
|
52584
|
-
|
|
53325
|
+
appearanceModeChanged(appearanceMode, clientContext) {
|
|
53326
|
+
safeEmit(() => capture2({
|
|
53327
|
+
name: "appearance_mode_changed",
|
|
53328
|
+
properties: { appearance_mode: appearanceMode }
|
|
53329
|
+
}, clientContext));
|
|
53330
|
+
},
|
|
53331
|
+
themeChanged(reason, clientContext) {
|
|
52585
53332
|
safeEmit(() => {
|
|
52586
53333
|
capture2({
|
|
52587
53334
|
name: "theme_changed",
|
|
52588
|
-
properties:
|
|
52589
|
-
|
|
52590
|
-
|
|
52591
|
-
|
|
53335
|
+
properties: {
|
|
53336
|
+
...deriveThemeProperties({
|
|
53337
|
+
activeThemeName: store.getActiveThemeName(),
|
|
53338
|
+
themeCount: store.getThemeRegistry().themes.length
|
|
53339
|
+
}),
|
|
53340
|
+
theme_change_reason: reason
|
|
53341
|
+
}
|
|
52592
53342
|
}, clientContext);
|
|
52593
53343
|
});
|
|
52594
53344
|
}
|
|
@@ -52650,50 +53400,9 @@ function safeEmit(callback) {
|
|
|
52650
53400
|
}
|
|
52651
53401
|
|
|
52652
53402
|
// ../server/src/telemetry/identity.ts
|
|
52653
|
-
var
|
|
53403
|
+
var import_node_crypto6 = require("node:crypto");
|
|
52654
53404
|
var import_promises4 = require("node:fs/promises");
|
|
52655
|
-
var
|
|
52656
|
-
|
|
52657
|
-
// ../server/src/artifact-paths.ts
|
|
52658
|
-
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
52659
|
-
function getStateDir(storagePath) {
|
|
52660
|
-
return import_node_path8.default.join(storagePath, "state");
|
|
52661
|
-
}
|
|
52662
|
-
function getChannelsDir(storagePath) {
|
|
52663
|
-
return import_node_path8.default.join(getStateDir(storagePath), "channels");
|
|
52664
|
-
}
|
|
52665
|
-
function getLegacyScreensDir(storagePath) {
|
|
52666
|
-
return import_node_path8.default.join(getStateDir(storagePath), "screens");
|
|
52667
|
-
}
|
|
52668
|
-
function getArtifactsMetadataDir(storagePath) {
|
|
52669
|
-
return import_node_path8.default.join(getStateDir(storagePath), "artifacts");
|
|
52670
|
-
}
|
|
52671
|
-
function getDisplayStatePath(storagePath) {
|
|
52672
|
-
return import_node_path8.default.join(getStateDir(storagePath), "display.json");
|
|
52673
|
-
}
|
|
52674
|
-
function getDisplayMigrationTempPath(storagePath) {
|
|
52675
|
-
return import_node_path8.default.join(getStateDir(storagePath), ".display.json.screen-to-channel.tmp");
|
|
52676
|
-
}
|
|
52677
|
-
function getTelemetryStatePath(storagePath) {
|
|
52678
|
-
return import_node_path8.default.join(getStateDir(storagePath), "telemetry.json");
|
|
52679
|
-
}
|
|
52680
|
-
function getTokenPath(storagePath) {
|
|
52681
|
-
return import_node_path8.default.join(getStateDir(storagePath), "token");
|
|
52682
|
-
}
|
|
52683
|
-
function getOnboardingStatePath(storagePath) {
|
|
52684
|
-
return import_node_path8.default.join(getStateDir(storagePath), "onboarding.json");
|
|
52685
|
-
}
|
|
52686
|
-
function getOnboardingArtifactSentinelPath(storagePath) {
|
|
52687
|
-
return import_node_path8.default.join(getStateDir(storagePath), "onboarding-artifact.json");
|
|
52688
|
-
}
|
|
52689
|
-
function getAgentArtifactsDir(storagePath) {
|
|
52690
|
-
return import_node_path8.default.join(...[storagePath, "artifacts"]);
|
|
52691
|
-
}
|
|
52692
|
-
function getArtifactLiveMetadataPath(storagePath, artifactID) {
|
|
52693
|
-
return import_node_path8.default.join(getArtifactsMetadataDir(storagePath), `${artifactID}.json`);
|
|
52694
|
-
}
|
|
52695
|
-
|
|
52696
|
-
// ../server/src/telemetry/identity.ts
|
|
53405
|
+
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
52697
53406
|
var TELEMETRY_STATE_SCHEMA_VERSION = 1;
|
|
52698
53407
|
var SEMVER_MAJOR_CAPTURE_INDEX = 1;
|
|
52699
53408
|
var SEMVER_MINOR_CAPTURE_INDEX = 2;
|
|
@@ -52710,7 +53419,7 @@ async function readTelemetryState(storagePath) {
|
|
|
52710
53419
|
}
|
|
52711
53420
|
async function writeTelemetryState(storagePath, state) {
|
|
52712
53421
|
const statePath = getTelemetryStatePath(storagePath);
|
|
52713
|
-
await (0, import_promises4.mkdir)(
|
|
53422
|
+
await (0, import_promises4.mkdir)(import_node_path10.default.dirname(statePath), { recursive: true });
|
|
52714
53423
|
const tempPath = `${statePath}.${process.pid}.${Date.now()}.tmp`;
|
|
52715
53424
|
await (0, import_promises4.writeFile)(tempPath, `${JSON.stringify(state, null, 2)}
|
|
52716
53425
|
`, "utf8");
|
|
@@ -52721,7 +53430,7 @@ async function loadOrMintTelemetryState(storagePath, options = {}) {
|
|
|
52721
53430
|
if (existing) return { state: existing, created: false };
|
|
52722
53431
|
const state = {
|
|
52723
53432
|
schemaVersion: TELEMETRY_STATE_SCHEMA_VERSION,
|
|
52724
|
-
userId: options.userIdFactory?.() ?? (0,
|
|
53433
|
+
userId: options.userIdFactory?.() ?? (0, import_node_crypto6.randomUUID)(),
|
|
52725
53434
|
optedOut: false,
|
|
52726
53435
|
lastVersion: options.lastVersion ?? ""
|
|
52727
53436
|
};
|
|
@@ -52799,12 +53508,12 @@ function isProductionTelemetryBuild(env) {
|
|
|
52799
53508
|
return telemetryBuildMarker(env) === "production";
|
|
52800
53509
|
}
|
|
52801
53510
|
function isTelemetryVersionOlder(previousVersion, runningVersion) {
|
|
52802
|
-
const previous =
|
|
52803
|
-
const running =
|
|
53511
|
+
const previous = parseSemanticVersion2(previousVersion);
|
|
53512
|
+
const running = parseSemanticVersion2(runningVersion);
|
|
52804
53513
|
if (!previous || !running) return false;
|
|
52805
|
-
return
|
|
53514
|
+
return compareSemanticVersions2(previous, running) < 0;
|
|
52806
53515
|
}
|
|
52807
|
-
function
|
|
53516
|
+
function parseSemanticVersion2(value) {
|
|
52808
53517
|
const match = value.trim().match(/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/);
|
|
52809
53518
|
if (!match) return null;
|
|
52810
53519
|
return {
|
|
@@ -52814,7 +53523,7 @@ function parseSemanticVersion(value) {
|
|
|
52814
53523
|
prerelease: match[SEMVER_PRERELEASE_CAPTURE_INDEX]?.split(".") ?? []
|
|
52815
53524
|
};
|
|
52816
53525
|
}
|
|
52817
|
-
function
|
|
53526
|
+
function compareSemanticVersions2(left, right) {
|
|
52818
53527
|
const core = compareNumbers(left.major, right.major) || compareNumbers(left.minor, right.minor) || compareNumbers(left.patch, right.patch);
|
|
52819
53528
|
if (core !== 0) return core;
|
|
52820
53529
|
return comparePrerelease(left.prerelease, right.prerelease);
|
|
@@ -52894,9 +53603,9 @@ function buildTelemetryEvent(event, context) {
|
|
|
52894
53603
|
}
|
|
52895
53604
|
|
|
52896
53605
|
// ../server/src/telemetry/posthog-config.ts
|
|
52897
|
-
var
|
|
53606
|
+
var import_node_fs9 = require("node:fs");
|
|
52898
53607
|
var import_node_os4 = __toESM(require("node:os"), 1);
|
|
52899
|
-
var
|
|
53608
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
52900
53609
|
var POSTHOG_US_INGESTION_HOST = "https://us.i.posthog.com";
|
|
52901
53610
|
var POSTHOG_US_API_HOST = "https://us.posthog.com";
|
|
52902
53611
|
var POSTHOG_PRODUCTION_PROJECT_ID = 482022;
|
|
@@ -52924,14 +53633,14 @@ function resolveTelemetryDeveloperHome(env = process.env) {
|
|
|
52924
53633
|
}
|
|
52925
53634
|
function detectTelemetryDeveloperHost(homeDir = import_node_os4.default.homedir()) {
|
|
52926
53635
|
try {
|
|
52927
|
-
return (0,
|
|
53636
|
+
return (0, import_node_fs9.existsSync)(import_node_path11.default.join(homeDir, ".tv-developer"));
|
|
52928
53637
|
} catch {
|
|
52929
53638
|
return false;
|
|
52930
53639
|
}
|
|
52931
53640
|
}
|
|
52932
53641
|
|
|
52933
53642
|
// ../server/src/telemetry/sessions.ts
|
|
52934
|
-
var
|
|
53643
|
+
var import_node_crypto7 = require("node:crypto");
|
|
52935
53644
|
var IDLE_TIMEOUT_MINUTES = 30;
|
|
52936
53645
|
var MAX_SESSION_HOURS = 24;
|
|
52937
53646
|
var SECONDS_PER_MINUTE2 = 60;
|
|
@@ -52958,7 +53667,7 @@ function createTelemetrySessionManager() {
|
|
|
52958
53667
|
return new InMemoryTelemetrySessionManager();
|
|
52959
53668
|
}
|
|
52960
53669
|
function createUUIDv7(timestampMs) {
|
|
52961
|
-
const bytes = (0,
|
|
53670
|
+
const bytes = (0, import_node_crypto7.randomBytes)(UUID_BYTE_COUNT);
|
|
52962
53671
|
writeTimestamp(bytes, timestampMs);
|
|
52963
53672
|
bytes[UUID_VERSION_BYTE_INDEX] = UUID_VERSION_7_HIGH_BITS | bytes[UUID_VERSION_BYTE_INDEX] & UUID_VERSION_LOW_MASK;
|
|
52964
53673
|
bytes[UUID_VARIANT_BYTE_INDEX] = UUID_VARIANT_RFC_9562_HIGH_BITS | bytes[UUID_VARIANT_BYTE_INDEX] & UUID_VARIANT_LOW_MASK;
|
|
@@ -53163,10 +53872,20 @@ async function createTelemetryRuntime(options) {
|
|
|
53163
53872
|
const sessionIdFor = (clientContext) => {
|
|
53164
53873
|
return sessions.sessionIdFor(clientContext?.clientId ?? null, nowMs());
|
|
53165
53874
|
};
|
|
53166
|
-
const
|
|
53167
|
-
|
|
53168
|
-
|
|
53169
|
-
|
|
53875
|
+
const captureWithCurrentProperties = (event, sessionId) => {
|
|
53876
|
+
if (!telemetryEnabled(env, currentState)) return;
|
|
53877
|
+
try {
|
|
53878
|
+
const settings = options.readThemeSettings();
|
|
53879
|
+
const { appearance_mode, ...themeSettings } = settings;
|
|
53880
|
+
const settingsForEvent = event.name === "session_activity" ? settings : event.name === "theme_changed" ? themeSettings : event.name === "appearance_mode_changed" ? { appearance_mode } : {};
|
|
53881
|
+
capture({
|
|
53882
|
+
...event,
|
|
53883
|
+
properties: { ...event.properties, ...settingsForEvent },
|
|
53884
|
+
personProperties: { ...pendingPersonProperties, ...event.personProperties, ...settings }
|
|
53885
|
+
}, { state: currentState, env, sink, sessionId });
|
|
53886
|
+
pendingPersonProperties = null;
|
|
53887
|
+
} catch {
|
|
53888
|
+
}
|
|
53170
53889
|
};
|
|
53171
53890
|
return {
|
|
53172
53891
|
boot,
|
|
@@ -53179,10 +53898,10 @@ async function createTelemetryRuntime(options) {
|
|
|
53179
53898
|
},
|
|
53180
53899
|
async disable() {
|
|
53181
53900
|
if (!currentState.optedOut) {
|
|
53182
|
-
|
|
53901
|
+
captureWithCurrentProperties({
|
|
53183
53902
|
name: "telemetry_opted_out",
|
|
53184
53903
|
personProperties: { telemetry_opted_out: true }
|
|
53185
|
-
}
|
|
53904
|
+
});
|
|
53186
53905
|
currentState = await setTelemetryOptedOut(options.storagePath, currentState, true);
|
|
53187
53906
|
}
|
|
53188
53907
|
return telemetryStatus(env, currentState);
|
|
@@ -53195,7 +53914,7 @@ async function createTelemetryRuntime(options) {
|
|
|
53195
53914
|
return telemetryStatus(env, currentState);
|
|
53196
53915
|
},
|
|
53197
53916
|
capture(event, clientContext) {
|
|
53198
|
-
|
|
53917
|
+
captureWithCurrentProperties(event, sessionIdFor(clientContext));
|
|
53199
53918
|
},
|
|
53200
53919
|
observeClientRequest(clientContext) {
|
|
53201
53920
|
return sessionIdFor(clientContext);
|
|
@@ -53204,7 +53923,7 @@ async function createTelemetryRuntime(options) {
|
|
|
53204
53923
|
if (!clientContext) return;
|
|
53205
53924
|
const sessionId = sessionIdFor(clientContext);
|
|
53206
53925
|
if (!sessionId) return;
|
|
53207
|
-
|
|
53926
|
+
captureWithCurrentProperties({
|
|
53208
53927
|
name: "session_activity",
|
|
53209
53928
|
properties: {
|
|
53210
53929
|
server_version: options.version,
|
|
@@ -53251,7 +53970,7 @@ function disabledTelemetryRuntime() {
|
|
|
53251
53970
|
|
|
53252
53971
|
// ../server/src/updates/version.ts
|
|
53253
53972
|
function readVersionStamp() {
|
|
53254
|
-
if ("
|
|
53973
|
+
if ("1.3.2".length > 0) return "1.3.2";
|
|
53255
53974
|
return void 0;
|
|
53256
53975
|
}
|
|
53257
53976
|
function resolveUpdateReleaseVersion(env = process.env, stamp = readVersionStamp()) {
|
|
@@ -53268,7 +53987,7 @@ function resolveRequiredDesktopVersion(baked, env = process.env, stamp = readVer
|
|
|
53268
53987
|
}
|
|
53269
53988
|
|
|
53270
53989
|
// ../server/src/required-desktop-version.ts
|
|
53271
|
-
var REQUIRED_DESKTOP_VERSION = "
|
|
53990
|
+
var REQUIRED_DESKTOP_VERSION = "1.3.1";
|
|
53272
53991
|
|
|
53273
53992
|
// ../server/src/updates/server-status.ts
|
|
53274
53993
|
function buildServerStatus(env = process.env, stamp = readVersionStamp(), baked = REQUIRED_DESKTOP_VERSION, update = null) {
|
|
@@ -53418,6 +54137,28 @@ function parseIntervalOverride(value) {
|
|
|
53418
54137
|
var import_meta = {};
|
|
53419
54138
|
var HTTP_UNAUTHORIZED_STATUS = 401;
|
|
53420
54139
|
var LOOPBACK_IPV4 = "127.0.0.1";
|
|
54140
|
+
var CANONICAL_VERSION_DIRECTORY_PATTERN = /^v\d+(?:\.\d+)?$/;
|
|
54141
|
+
function resolveCanonicalVersionDirectories(canonicalDir) {
|
|
54142
|
+
const canonicalRoot = import_node_path12.default.resolve(canonicalDir);
|
|
54143
|
+
const versions = (0, import_node_fs10.readdirSync)(canonicalRoot, { withFileTypes: true }).filter(
|
|
54144
|
+
(entry) => entry.isDirectory() && CANONICAL_VERSION_DIRECTORY_PATTERN.test(entry.name)
|
|
54145
|
+
).map((entry) => {
|
|
54146
|
+
const directory = import_node_path12.default.join(canonicalRoot, entry.name);
|
|
54147
|
+
return {
|
|
54148
|
+
version: entry.name,
|
|
54149
|
+
directory,
|
|
54150
|
+
frozen: (0, import_node_fs10.existsSync)(import_node_path12.default.join(directory, "frozen.json"))
|
|
54151
|
+
};
|
|
54152
|
+
}).sort(
|
|
54153
|
+
(left, right) => left.version.localeCompare(right.version, void 0, { numeric: true })
|
|
54154
|
+
);
|
|
54155
|
+
if (versions.length === 0) {
|
|
54156
|
+
throw new Error(
|
|
54157
|
+
`canonical root ${canonicalRoot} contains no version directories matching v<n>`
|
|
54158
|
+
);
|
|
54159
|
+
}
|
|
54160
|
+
return versions;
|
|
54161
|
+
}
|
|
53421
54162
|
var Server = class {
|
|
53422
54163
|
app;
|
|
53423
54164
|
httpServer;
|
|
@@ -53493,31 +54234,39 @@ var Server = class {
|
|
|
53493
54234
|
testArtifactPollCadence: options.testArtifactPollCadence
|
|
53494
54235
|
});
|
|
53495
54236
|
if (options.canonicalDir) {
|
|
53496
|
-
const
|
|
53497
|
-
|
|
53498
|
-
|
|
53499
|
-
|
|
53500
|
-
|
|
53501
|
-
|
|
53502
|
-
|
|
53503
|
-
|
|
53504
|
-
|
|
53505
|
-
|
|
53506
|
-
|
|
53507
|
-
|
|
53508
|
-
|
|
53509
|
-
|
|
53510
|
-
|
|
53511
|
-
|
|
53512
|
-
|
|
53513
|
-
|
|
53514
|
-
|
|
53515
|
-
|
|
53516
|
-
|
|
54237
|
+
for (const { version: version2, directory, frozen } of resolveCanonicalVersionDirectories(
|
|
54238
|
+
options.canonicalDir
|
|
54239
|
+
)) {
|
|
54240
|
+
const mountPath = `/canonical/${version2}`;
|
|
54241
|
+
this.app.use(mountPath, (_req, res, next) => {
|
|
54242
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
54243
|
+
next();
|
|
54244
|
+
});
|
|
54245
|
+
this.app.get(
|
|
54246
|
+
`${mountPath}/styles.css`,
|
|
54247
|
+
serveCanonicalStyles(version2, frozen)
|
|
54248
|
+
);
|
|
54249
|
+
this.app.get(`${mountPath}/base.css`, serveCanonicalBase(directory));
|
|
54250
|
+
this.app.use(
|
|
54251
|
+
mountPath,
|
|
54252
|
+
import_express2.default.static(directory, {
|
|
54253
|
+
setHeaders: (res, filePath) => {
|
|
54254
|
+
if (filePath.startsWith(
|
|
54255
|
+
`${import_node_path12.default.resolve(directory, "fonts")}${import_node_path12.default.sep}`
|
|
54256
|
+
)) {
|
|
54257
|
+
res.setHeader(
|
|
54258
|
+
"Cache-Control",
|
|
54259
|
+
"public, max-age=31536000, immutable"
|
|
54260
|
+
);
|
|
54261
|
+
} else {
|
|
54262
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
54263
|
+
}
|
|
54264
|
+
}
|
|
54265
|
+
})
|
|
54266
|
+
);
|
|
54267
|
+
}
|
|
53517
54268
|
}
|
|
53518
|
-
|
|
53519
|
-
this.app.get("/themes/:name/theme.css", serveThemeCSS(this.store.storagePath));
|
|
53520
|
-
this.app.use("/themes", import_express2.default.static(themesDir));
|
|
54269
|
+
this.app.use("/theme", serveActiveTheme(this.store));
|
|
53521
54270
|
for (const viewID of ["artifact-missing", "markdown"]) {
|
|
53522
54271
|
const viewPath = this.store.getViewPath(viewID);
|
|
53523
54272
|
if (viewPath) {
|
|
@@ -53530,7 +54279,7 @@ var Server = class {
|
|
|
53530
54279
|
if (filePath.endsWith(".html") || filePath.endsWith(".htm")) {
|
|
53531
54280
|
res.setHeader("Referrer-Policy", "no-referrer");
|
|
53532
54281
|
res.setHeader("Cache-Control", "no-cache");
|
|
53533
|
-
} else if (filePath.includes(`${
|
|
54282
|
+
} else if (filePath.includes(`${import_node_path12.default.sep}assets${import_node_path12.default.sep}`)) {
|
|
53534
54283
|
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
53535
54284
|
}
|
|
53536
54285
|
}
|
|
@@ -53696,6 +54445,10 @@ var Server = class {
|
|
|
53696
54445
|
storagePath: this.store.storagePath,
|
|
53697
54446
|
version: version2,
|
|
53698
54447
|
dataDirCreated: this.store.dataDirCreated,
|
|
54448
|
+
readThemeSettings: () => deriveThemeSettingsProperties({
|
|
54449
|
+
...this.store.getDisplayState(),
|
|
54450
|
+
themes: this.store.getThemeRegistry().themes
|
|
54451
|
+
}),
|
|
53699
54452
|
...this.telemetryOptions.env === void 0 ? {} : { env: this.telemetryOptions.env },
|
|
53700
54453
|
...this.telemetryOptions.sink === void 0 ? {} : { sink: this.telemetryOptions.sink },
|
|
53701
54454
|
...this.telemetryOptions.developerHost === void 0 ? {} : { developerHost: this.telemetryOptions.developerHost },
|
|
@@ -53763,43 +54516,46 @@ var Server = class {
|
|
|
53763
54516
|
};
|
|
53764
54517
|
};
|
|
53765
54518
|
function readServerPackageVersion() {
|
|
53766
|
-
if ("
|
|
53767
|
-
return telemetryVersion("
|
|
54519
|
+
if ("1.3.2".length > 0) {
|
|
54520
|
+
return telemetryVersion("1.3.2");
|
|
53768
54521
|
}
|
|
53769
|
-
const packageJsonPath =
|
|
53770
|
-
if (!(0,
|
|
53771
|
-
return telemetryVersion(JSON.parse((0,
|
|
54522
|
+
const packageJsonPath = import_node_path12.default.resolve(import_node_path12.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)), "..", "package.json");
|
|
54523
|
+
if (!(0, import_node_fs10.existsSync)(packageJsonPath)) return telemetryVersion("0.0.0");
|
|
54524
|
+
return telemetryVersion(JSON.parse((0, import_node_fs10.readFileSync)(packageJsonPath, "utf8")).version);
|
|
53772
54525
|
}
|
|
53773
54526
|
|
|
53774
54527
|
// ../server/src/server-store.ts
|
|
53775
|
-
var
|
|
53776
|
-
var
|
|
54528
|
+
var import_node_fs16 = require("node:fs");
|
|
54529
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
53777
54530
|
|
|
53778
54531
|
// ../server/src/file-watcher.ts
|
|
53779
54532
|
var import_node_events = require("node:events");
|
|
53780
54533
|
var fs3 = __toESM(require("node:fs"), 1);
|
|
53781
|
-
var
|
|
54534
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
53782
54535
|
var DEFAULT_REARM_INTERVAL_MS = 250;
|
|
53783
54536
|
function isMissingWatchRootError(error48) {
|
|
53784
54537
|
return typeof error48 === "object" && error48 !== null && "code" in error48 && error48.code === "ENOENT";
|
|
53785
54538
|
}
|
|
53786
54539
|
var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
53787
54540
|
#dir;
|
|
53788
|
-
#
|
|
54541
|
+
#watchedBasename;
|
|
53789
54542
|
#watchRootBasename;
|
|
53790
54543
|
#onChange;
|
|
53791
54544
|
#options;
|
|
54545
|
+
#recursive;
|
|
53792
54546
|
#watcher = null;
|
|
53793
54547
|
#ancestorWatchers = [];
|
|
53794
54548
|
#closed = false;
|
|
53795
54549
|
#dead = false;
|
|
53796
54550
|
#rearmTimer = null;
|
|
53797
54551
|
#rootEventImmediate = null;
|
|
53798
|
-
|
|
54552
|
+
#recursiveRefreshImmediate = null;
|
|
54553
|
+
constructor(contentPath, onChange, options = {}) {
|
|
53799
54554
|
super();
|
|
53800
|
-
this.#
|
|
53801
|
-
this.#
|
|
53802
|
-
this.#
|
|
54555
|
+
this.#recursive = options.recursive === true;
|
|
54556
|
+
this.#dir = this.#recursive ? contentPath : import_node_path13.default.dirname(contentPath);
|
|
54557
|
+
this.#watchedBasename = import_node_path13.default.basename(contentPath);
|
|
54558
|
+
this.#watchRootBasename = import_node_path13.default.basename(import_node_path13.default.normalize(this.#dir));
|
|
53803
54559
|
this.#onChange = onChange;
|
|
53804
54560
|
this.#options = options;
|
|
53805
54561
|
try {
|
|
@@ -53821,16 +54577,30 @@ var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
|
53821
54577
|
clearImmediate(this.#rootEventImmediate);
|
|
53822
54578
|
this.#rootEventImmediate = null;
|
|
53823
54579
|
}
|
|
54580
|
+
if (this.#recursiveRefreshImmediate) {
|
|
54581
|
+
clearImmediate(this.#recursiveRefreshImmediate);
|
|
54582
|
+
this.#recursiveRefreshImmediate = null;
|
|
54583
|
+
}
|
|
53824
54584
|
this.#closeActiveWatchers();
|
|
53825
54585
|
}
|
|
53826
54586
|
#attach() {
|
|
53827
|
-
const watcher = fs3.watch(this.#dir, (_event, filename) => {
|
|
53828
|
-
const
|
|
53829
|
-
|
|
54587
|
+
const watcher = fs3.watch(this.#dir, { recursive: this.#recursive }, (_event, filename) => {
|
|
54588
|
+
const relativePath = filename?.toString();
|
|
54589
|
+
const isWatchRootEvent = relativePath === void 0 || relativePath === "" || relativePath === this.#watchRootBasename;
|
|
54590
|
+
if (this.#recursive) {
|
|
54591
|
+
if (isWatchRootEvent) {
|
|
54592
|
+
this.#handleWatchRootEvent();
|
|
54593
|
+
} else {
|
|
54594
|
+
this.#onChange();
|
|
54595
|
+
this.#scheduleRecursiveRefresh();
|
|
54596
|
+
}
|
|
54597
|
+
return;
|
|
54598
|
+
}
|
|
54599
|
+
if (relativePath === this.#watchedBasename) {
|
|
53830
54600
|
this.#onChange();
|
|
53831
54601
|
return;
|
|
53832
54602
|
}
|
|
53833
|
-
if (
|
|
54603
|
+
if (isWatchRootEvent) {
|
|
53834
54604
|
this.#handleWatchRootEvent();
|
|
53835
54605
|
}
|
|
53836
54606
|
});
|
|
@@ -53843,7 +54613,7 @@ var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
|
53843
54613
|
});
|
|
53844
54614
|
const ancestorWatchers = [];
|
|
53845
54615
|
for (const ancestorDir of this.#ancestorDirs()) {
|
|
53846
|
-
const ancestorBasename =
|
|
54616
|
+
const ancestorBasename = import_node_path13.default.basename(import_node_path13.default.normalize(ancestorDir));
|
|
53847
54617
|
try {
|
|
53848
54618
|
const ancestorWatcher = fs3.watch(ancestorDir, (_event, filename) => {
|
|
53849
54619
|
const basename = filename?.toString();
|
|
@@ -53866,6 +54636,27 @@ var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
|
53866
54636
|
this.#ancestorWatchers = ancestorWatchers;
|
|
53867
54637
|
this.#dead = false;
|
|
53868
54638
|
}
|
|
54639
|
+
#scheduleRecursiveRefresh() {
|
|
54640
|
+
if (this.#recursiveRefreshImmediate) return;
|
|
54641
|
+
this.#recursiveRefreshImmediate = setImmediate(() => {
|
|
54642
|
+
this.#recursiveRefreshImmediate = null;
|
|
54643
|
+
if (this.#closed) return;
|
|
54644
|
+
if (!this.#isWatchRootPresent()) {
|
|
54645
|
+
this.#markDead();
|
|
54646
|
+
return;
|
|
54647
|
+
}
|
|
54648
|
+
this.#closeActiveWatchers();
|
|
54649
|
+
try {
|
|
54650
|
+
this.#attach();
|
|
54651
|
+
} catch (error48) {
|
|
54652
|
+
if (this.#isWatchRootPresent()) {
|
|
54653
|
+
this.emit("error", error48);
|
|
54654
|
+
return;
|
|
54655
|
+
}
|
|
54656
|
+
this.#markDead();
|
|
54657
|
+
}
|
|
54658
|
+
});
|
|
54659
|
+
}
|
|
53869
54660
|
#handleWatchRootEvent() {
|
|
53870
54661
|
if (this.#rootEventImmediate) return;
|
|
53871
54662
|
this.#rootEventImmediate = setImmediate(() => {
|
|
@@ -53889,10 +54680,10 @@ var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
|
53889
54680
|
}
|
|
53890
54681
|
#ancestorDirs() {
|
|
53891
54682
|
const ancestors = [];
|
|
53892
|
-
let current =
|
|
53893
|
-
while (current !==
|
|
54683
|
+
let current = import_node_path13.default.dirname(this.#dir);
|
|
54684
|
+
while (current !== import_node_path13.default.dirname(current)) {
|
|
53894
54685
|
ancestors.push(current);
|
|
53895
|
-
current =
|
|
54686
|
+
current = import_node_path13.default.dirname(current);
|
|
53896
54687
|
}
|
|
53897
54688
|
return ancestors;
|
|
53898
54689
|
}
|
|
@@ -53944,13 +54735,13 @@ var ReArmingContentWatcher = class extends import_node_events.EventEmitter {
|
|
|
53944
54735
|
}
|
|
53945
54736
|
}
|
|
53946
54737
|
};
|
|
53947
|
-
var defaultWatchContentFile = (
|
|
53948
|
-
return new ReArmingContentWatcher(
|
|
54738
|
+
var defaultWatchContentFile = (contentPath, onChange, options) => {
|
|
54739
|
+
return new ReArmingContentWatcher(contentPath, onChange, options);
|
|
53949
54740
|
};
|
|
53950
54741
|
|
|
53951
54742
|
// ../server/src/redesign-storage-migration.ts
|
|
53952
|
-
var
|
|
53953
|
-
var
|
|
54743
|
+
var import_node_fs12 = require("node:fs");
|
|
54744
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
53954
54745
|
|
|
53955
54746
|
// ../server/src/redesign-record-migration.ts
|
|
53956
54747
|
function convertStoredChannelRecord(record2) {
|
|
@@ -54025,8 +54816,8 @@ function newestChannelId(channelIds) {
|
|
|
54025
54816
|
}
|
|
54026
54817
|
|
|
54027
54818
|
// ../server/src/storage-name-migration.ts
|
|
54028
|
-
var
|
|
54029
|
-
var
|
|
54819
|
+
var import_node_fs11 = require("node:fs");
|
|
54820
|
+
var JSON_INDENT_SPACES2 = 2;
|
|
54030
54821
|
function isActiveID(value) {
|
|
54031
54822
|
return typeof value === "string" || value === null;
|
|
54032
54823
|
}
|
|
@@ -54036,23 +54827,23 @@ function isThemeName(value) {
|
|
|
54036
54827
|
function migrateChannelMetadataDirectory(storagePath) {
|
|
54037
54828
|
const legacyDir = getLegacyScreensDir(storagePath);
|
|
54038
54829
|
const currentDir = getChannelsDir(storagePath);
|
|
54039
|
-
const legacyExists = (0,
|
|
54040
|
-
const currentExists = (0,
|
|
54830
|
+
const legacyExists = (0, import_node_fs11.existsSync)(legacyDir);
|
|
54831
|
+
const currentExists = (0, import_node_fs11.existsSync)(currentDir);
|
|
54041
54832
|
if (!legacyExists) {
|
|
54042
54833
|
return;
|
|
54043
54834
|
}
|
|
54044
54835
|
if (!currentExists) {
|
|
54045
|
-
(0,
|
|
54836
|
+
(0, import_node_fs11.renameSync)(legacyDir, currentDir);
|
|
54046
54837
|
return;
|
|
54047
54838
|
}
|
|
54048
|
-
const legacyEntries = (0,
|
|
54049
|
-
const currentEntries = (0,
|
|
54839
|
+
const legacyEntries = (0, import_node_fs11.readdirSync)(legacyDir);
|
|
54840
|
+
const currentEntries = (0, import_node_fs11.readdirSync)(currentDir);
|
|
54050
54841
|
if (legacyEntries.length === 0) {
|
|
54051
|
-
(0,
|
|
54842
|
+
(0, import_node_fs11.rmdirSync)(legacyDir);
|
|
54052
54843
|
return;
|
|
54053
54844
|
}
|
|
54054
54845
|
if (currentEntries.length === 0) {
|
|
54055
|
-
(0,
|
|
54846
|
+
(0, import_node_fs11.renameSync)(legacyDir, currentDir);
|
|
54056
54847
|
return;
|
|
54057
54848
|
}
|
|
54058
54849
|
throw new Error(
|
|
@@ -54061,12 +54852,12 @@ function migrateChannelMetadataDirectory(storagePath) {
|
|
|
54061
54852
|
}
|
|
54062
54853
|
function migrateDisplayStateField(storagePath) {
|
|
54063
54854
|
const displayPath = getDisplayStatePath(storagePath);
|
|
54064
|
-
if (!(0,
|
|
54855
|
+
if (!(0, import_node_fs11.existsSync)(displayPath)) {
|
|
54065
54856
|
return;
|
|
54066
54857
|
}
|
|
54067
54858
|
let parsed;
|
|
54068
54859
|
try {
|
|
54069
|
-
parsed = JSON.parse((0,
|
|
54860
|
+
parsed = JSON.parse((0, import_node_fs11.readFileSync)(displayPath, "utf8"));
|
|
54070
54861
|
} catch {
|
|
54071
54862
|
return;
|
|
54072
54863
|
}
|
|
@@ -54107,12 +54898,12 @@ function migrateDisplayStateField(storagePath) {
|
|
|
54107
54898
|
next[key] = value;
|
|
54108
54899
|
}
|
|
54109
54900
|
const temporaryPath = getDisplayMigrationTempPath(storagePath);
|
|
54110
|
-
(0,
|
|
54111
|
-
(0,
|
|
54901
|
+
(0, import_node_fs11.writeFileSync)(temporaryPath, JSON.stringify(next, null, JSON_INDENT_SPACES2));
|
|
54902
|
+
(0, import_node_fs11.renameSync)(temporaryPath, displayPath);
|
|
54112
54903
|
}
|
|
54113
54904
|
|
|
54114
54905
|
// ../server/src/redesign-storage-migration.ts
|
|
54115
|
-
var
|
|
54906
|
+
var JSON_INDENT_SPACES3 = 2;
|
|
54116
54907
|
var JSON_FILE_SUFFIX = ".json";
|
|
54117
54908
|
function runRedesignStorageMigration(storagePath) {
|
|
54118
54909
|
migrateChannelMetadataDirectory(storagePath);
|
|
@@ -54120,19 +54911,20 @@ function runRedesignStorageMigration(storagePath) {
|
|
|
54120
54911
|
const channelIds = migrateChannelRecords(storagePath);
|
|
54121
54912
|
migrateDisplayRecord(storagePath, channelIds);
|
|
54122
54913
|
backfillChannelPageSizes(storagePath);
|
|
54914
|
+
migrateDisplayAppearanceMode(storagePath);
|
|
54123
54915
|
}
|
|
54124
54916
|
function getRedesignRecordMigrationTempPath(recordPath) {
|
|
54125
|
-
return
|
|
54917
|
+
return import_node_path14.default.join(import_node_path14.default.dirname(recordPath), `.${import_node_path14.default.basename(recordPath)}.redesign.tmp`);
|
|
54126
54918
|
}
|
|
54127
54919
|
function migrateChannelRecords(storagePath) {
|
|
54128
54920
|
const channelsDir = getChannelsDir(storagePath);
|
|
54129
|
-
if (!(0,
|
|
54921
|
+
if (!(0, import_node_fs12.existsSync)(channelsDir)) {
|
|
54130
54922
|
return [];
|
|
54131
54923
|
}
|
|
54132
54924
|
const channelIds = [];
|
|
54133
|
-
for (const file2 of (0,
|
|
54925
|
+
for (const file2 of (0, import_node_fs12.readdirSync)(channelsDir).sort()) {
|
|
54134
54926
|
if (!file2.endsWith(JSON_FILE_SUFFIX)) continue;
|
|
54135
|
-
const recordPath =
|
|
54927
|
+
const recordPath = import_node_path14.default.join(channelsDir, file2);
|
|
54136
54928
|
const parsed = readJSON(recordPath);
|
|
54137
54929
|
const inspected = inspectChannelRecord(parsed);
|
|
54138
54930
|
if (inspected === null) continue;
|
|
@@ -54148,7 +54940,7 @@ function migrateChannelRecords(storagePath) {
|
|
|
54148
54940
|
}
|
|
54149
54941
|
function migrateDisplayRecord(storagePath, channelIds) {
|
|
54150
54942
|
const displayPath = getDisplayStatePath(storagePath);
|
|
54151
|
-
if (!(0,
|
|
54943
|
+
if (!(0, import_node_fs12.existsSync)(displayPath)) return;
|
|
54152
54944
|
const parsed = readJSON(displayPath);
|
|
54153
54945
|
const record2 = parseConvertibleDisplayRecord(parsed);
|
|
54154
54946
|
if (record2 === null) return;
|
|
@@ -54159,10 +54951,10 @@ function migrateDisplayRecord(storagePath, channelIds) {
|
|
|
54159
54951
|
}
|
|
54160
54952
|
function backfillChannelPageSizes(storagePath) {
|
|
54161
54953
|
const channelsDir = getChannelsDir(storagePath);
|
|
54162
|
-
if (!(0,
|
|
54163
|
-
for (const file2 of (0,
|
|
54954
|
+
if (!(0, import_node_fs12.existsSync)(channelsDir)) return;
|
|
54955
|
+
for (const file2 of (0, import_node_fs12.readdirSync)(channelsDir).sort()) {
|
|
54164
54956
|
if (!file2.endsWith(JSON_FILE_SUFFIX)) continue;
|
|
54165
|
-
const recordPath =
|
|
54957
|
+
const recordPath = import_node_path14.default.join(channelsDir, file2);
|
|
54166
54958
|
const record2 = inspectPageSizeBackfillRecord(readJSON(recordPath));
|
|
54167
54959
|
if (record2 === null) continue;
|
|
54168
54960
|
const backfilled = backfillStoredChannelPageSizes(record2);
|
|
@@ -54171,13 +54963,23 @@ function backfillChannelPageSizes(storagePath) {
|
|
|
54171
54963
|
}
|
|
54172
54964
|
}
|
|
54173
54965
|
}
|
|
54966
|
+
function migrateDisplayAppearanceMode(storagePath) {
|
|
54967
|
+
const displayPath = getDisplayStatePath(storagePath);
|
|
54968
|
+
if (!(0, import_node_fs12.existsSync)(displayPath)) return;
|
|
54969
|
+
const record2 = readJSON(displayPath);
|
|
54970
|
+
if (!isRecord2(record2) || Object.hasOwn(record2, "appearanceMode")) return;
|
|
54971
|
+
if (!isNullableString(record2.focusedChannelId) || !Array.isArray(record2.pinnedChannelIds) || !record2.pinnedChannelIds.every((id) => typeof id === "string") || !isThemeName2(record2.activeThemeName)) {
|
|
54972
|
+
return;
|
|
54973
|
+
}
|
|
54974
|
+
writeAtomicJSON(displayPath, { ...record2, appearanceMode: "system" });
|
|
54975
|
+
}
|
|
54174
54976
|
function writeAtomicJSON(recordPath, value) {
|
|
54175
54977
|
const temporaryPath = getRedesignRecordMigrationTempPath(recordPath);
|
|
54176
|
-
(0,
|
|
54177
|
-
(0,
|
|
54978
|
+
(0, import_node_fs12.writeFileSync)(temporaryPath, JSON.stringify(value, null, JSON_INDENT_SPACES3));
|
|
54979
|
+
(0, import_node_fs12.renameSync)(temporaryPath, recordPath);
|
|
54178
54980
|
}
|
|
54179
54981
|
function readJSON(recordPath) {
|
|
54180
|
-
const bytes = (0,
|
|
54982
|
+
const bytes = (0, import_node_fs12.readFileSync)(recordPath, "utf8");
|
|
54181
54983
|
try {
|
|
54182
54984
|
return JSON.parse(bytes);
|
|
54183
54985
|
} catch {
|
|
@@ -54270,12 +55072,12 @@ function isRecord2(value) {
|
|
|
54270
55072
|
}
|
|
54271
55073
|
|
|
54272
55074
|
// ../server/src/onboarding-installer.ts
|
|
54273
|
-
var
|
|
54274
|
-
var
|
|
55075
|
+
var import_node_fs15 = require("node:fs");
|
|
55076
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
54275
55077
|
|
|
54276
55078
|
// ../server/src/onboarding-content.ts
|
|
54277
|
-
var
|
|
54278
|
-
var
|
|
55079
|
+
var import_node_fs13 = require("node:fs");
|
|
55080
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
54279
55081
|
var ONBOARDING_CONFIG_FILENAME = "onboarding-channels.json";
|
|
54280
55082
|
var ONBOARDING_CONFIG_VERSION = 3;
|
|
54281
55083
|
var ONBOARDING_ARTIFACT_ID_PREFIX = "television-onboarding";
|
|
@@ -54287,18 +55089,18 @@ function isValidOnboardingSlug(slug) {
|
|
|
54287
55089
|
return ONBOARDING_SLUG_PATTERN.test(slug) && !slug.includes("--");
|
|
54288
55090
|
}
|
|
54289
55091
|
function loadOnboardingConfig(contentRoot) {
|
|
54290
|
-
const configPath =
|
|
55092
|
+
const configPath = import_node_path15.default.join(contentRoot, ONBOARDING_CONFIG_FILENAME);
|
|
54291
55093
|
let raw;
|
|
54292
55094
|
try {
|
|
54293
|
-
raw = (0,
|
|
55095
|
+
raw = (0, import_node_fs13.readFileSync)(configPath, "utf8");
|
|
54294
55096
|
} catch (error48) {
|
|
54295
|
-
return { errors: [`cannot read ${ONBOARDING_CONFIG_FILENAME}: ${
|
|
55097
|
+
return { errors: [`cannot read ${ONBOARDING_CONFIG_FILENAME}: ${describeError2(error48)}`] };
|
|
54296
55098
|
}
|
|
54297
55099
|
let parsed;
|
|
54298
55100
|
try {
|
|
54299
55101
|
parsed = JSON.parse(raw);
|
|
54300
55102
|
} catch (error48) {
|
|
54301
|
-
return { errors: [`failed to parse ${ONBOARDING_CONFIG_FILENAME}: ${
|
|
55103
|
+
return { errors: [`failed to parse ${ONBOARDING_CONFIG_FILENAME}: ${describeError2(error48)}`] };
|
|
54302
55104
|
}
|
|
54303
55105
|
const errors = validateConfigSchema(parsed);
|
|
54304
55106
|
if (errors.length > 0) {
|
|
@@ -54308,15 +55110,15 @@ function loadOnboardingConfig(contentRoot) {
|
|
|
54308
55110
|
}
|
|
54309
55111
|
function resolveOnboardingArtifactSource(contentRoot, channelSlug, artifactSlug) {
|
|
54310
55112
|
const label = `artifact "${artifactSlug}" in channel "${channelSlug}"`;
|
|
54311
|
-
const channelDir =
|
|
55113
|
+
const channelDir = import_node_path15.default.join(contentRoot, channelSlug);
|
|
54312
55114
|
const shapes = [];
|
|
54313
55115
|
for (const extension2 of [".html", ".md"]) {
|
|
54314
|
-
const candidate =
|
|
55116
|
+
const candidate = import_node_path15.default.join(channelDir, `${artifactSlug}${extension2}`);
|
|
54315
55117
|
if (isFile(candidate)) {
|
|
54316
55118
|
shapes.push({ kind: "file", path: candidate, display: `${artifactSlug}${extension2}` });
|
|
54317
55119
|
}
|
|
54318
55120
|
}
|
|
54319
|
-
const dirPath =
|
|
55121
|
+
const dirPath = import_node_path15.default.join(channelDir, artifactSlug);
|
|
54320
55122
|
if (isDirectory(dirPath)) {
|
|
54321
55123
|
shapes.push({ kind: "directory", path: dirPath, display: `${artifactSlug}/` });
|
|
54322
55124
|
}
|
|
@@ -54333,7 +55135,7 @@ function resolveOnboardingArtifactSource(contentRoot, channelSlug, artifactSlug)
|
|
|
54333
55135
|
error: `${label} has no source: expected ${artifactSlug}.html, ${artifactSlug}.md, or ${artifactSlug}/`
|
|
54334
55136
|
};
|
|
54335
55137
|
}
|
|
54336
|
-
if (shape.kind === "directory" && !isFile(
|
|
55138
|
+
if (shape.kind === "directory" && !isFile(import_node_path15.default.join(shape.path, "index.html"))) {
|
|
54337
55139
|
return { ok: false, error: `${label} is a directory artifact missing index.html at its root` };
|
|
54338
55140
|
}
|
|
54339
55141
|
return { ok: true, source: { kind: shape.kind, path: shape.path } };
|
|
@@ -54432,28 +55234,28 @@ function validateArtifactSchema(rawArtifact, channelLabel, index, artifactSlugs)
|
|
|
54432
55234
|
return errors;
|
|
54433
55235
|
}
|
|
54434
55236
|
function isFile(candidate) {
|
|
54435
|
-
return (0,
|
|
55237
|
+
return (0, import_node_fs13.existsSync)(candidate) && (0, import_node_fs13.statSync)(candidate).isFile();
|
|
54436
55238
|
}
|
|
54437
55239
|
function isDirectory(candidate) {
|
|
54438
|
-
return (0,
|
|
55240
|
+
return (0, import_node_fs13.existsSync)(candidate) && (0, import_node_fs13.statSync)(candidate).isDirectory();
|
|
54439
55241
|
}
|
|
54440
|
-
function
|
|
55242
|
+
function describeError2(error48) {
|
|
54441
55243
|
return error48 instanceof Error ? error48.message : String(error48);
|
|
54442
55244
|
}
|
|
54443
55245
|
|
|
54444
55246
|
// ../server/src/onboarding-state.ts
|
|
54445
|
-
var
|
|
54446
|
-
var
|
|
55247
|
+
var import_node_fs14 = require("node:fs");
|
|
55248
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
54447
55249
|
|
|
54448
55250
|
// ../server/src/onboarding.ts
|
|
54449
55251
|
var ONBOARDING_ARTIFACT_ID = "television-onboarding";
|
|
54450
55252
|
|
|
54451
55253
|
// ../server/src/onboarding-state.ts
|
|
54452
|
-
var
|
|
55254
|
+
var JSON_INDENT_SPACES4 = 2;
|
|
54453
55255
|
var ONBOARDING_STATE_VERSION = 3;
|
|
54454
55256
|
function readOnboardingStateFile(storagePath) {
|
|
54455
55257
|
const statePath = getOnboardingStatePath(storagePath);
|
|
54456
|
-
if (!(0,
|
|
55258
|
+
if (!(0, import_node_fs14.existsSync)(statePath)) {
|
|
54457
55259
|
return { status: "absent" };
|
|
54458
55260
|
}
|
|
54459
55261
|
const parsed = parseJSONFile(statePath);
|
|
@@ -54469,7 +55271,7 @@ function readOnboardingStateFile(storagePath) {
|
|
|
54469
55271
|
}
|
|
54470
55272
|
function readLegacyOnboardingFile(storagePath) {
|
|
54471
55273
|
const legacyPath = getOnboardingArtifactSentinelPath(storagePath);
|
|
54472
|
-
if (!(0,
|
|
55274
|
+
if (!(0, import_node_fs14.existsSync)(legacyPath)) {
|
|
54473
55275
|
return { status: "absent" };
|
|
54474
55276
|
}
|
|
54475
55277
|
const parsed = parseJSONFile(legacyPath);
|
|
@@ -54495,17 +55297,17 @@ function readLegacyOnboardingFile(storagePath) {
|
|
|
54495
55297
|
}
|
|
54496
55298
|
function getOnboardingStateTempPath(storagePath) {
|
|
54497
55299
|
const statePath = getOnboardingStatePath(storagePath);
|
|
54498
|
-
return
|
|
55300
|
+
return import_node_path16.default.join(import_node_path16.default.dirname(statePath), `.${import_node_path16.default.basename(statePath)}.tmp-${process.pid}`);
|
|
54499
55301
|
}
|
|
54500
55302
|
function writeOnboardingStateFile(storagePath, state) {
|
|
54501
55303
|
const statePath = getOnboardingStatePath(storagePath);
|
|
54502
55304
|
const tempPath = getOnboardingStateTempPath(storagePath);
|
|
54503
55305
|
try {
|
|
54504
|
-
(0,
|
|
54505
|
-
(0,
|
|
55306
|
+
(0, import_node_fs14.writeFileSync)(tempPath, JSON.stringify(state, null, JSON_INDENT_SPACES4));
|
|
55307
|
+
(0, import_node_fs14.renameSync)(tempPath, statePath);
|
|
54506
55308
|
} catch (error48) {
|
|
54507
55309
|
try {
|
|
54508
|
-
(0,
|
|
55310
|
+
(0, import_node_fs14.rmSync)(tempPath, { force: true });
|
|
54509
55311
|
} catch {
|
|
54510
55312
|
}
|
|
54511
55313
|
throw error48;
|
|
@@ -54514,14 +55316,14 @@ function writeOnboardingStateFile(storagePath, state) {
|
|
|
54514
55316
|
function parseJSONFile(filePath) {
|
|
54515
55317
|
let raw;
|
|
54516
55318
|
try {
|
|
54517
|
-
raw = (0,
|
|
55319
|
+
raw = (0, import_node_fs14.readFileSync)(filePath, "utf8");
|
|
54518
55320
|
} catch (error48) {
|
|
54519
|
-
return { ok: false, error: `cannot read ${filePath}: ${
|
|
55321
|
+
return { ok: false, error: `cannot read ${filePath}: ${describeError3(error48)}` };
|
|
54520
55322
|
}
|
|
54521
55323
|
try {
|
|
54522
55324
|
return { ok: true, value: JSON.parse(raw) };
|
|
54523
55325
|
} catch (error48) {
|
|
54524
|
-
return { ok: false, error: `cannot parse ${filePath}: ${
|
|
55326
|
+
return { ok: false, error: `cannot parse ${filePath}: ${describeError3(error48)}` };
|
|
54525
55327
|
}
|
|
54526
55328
|
}
|
|
54527
55329
|
function parseV3State(value) {
|
|
@@ -54565,7 +55367,7 @@ function parseInstallRecords(value) {
|
|
|
54565
55367
|
function isUsableTimestamp(value) {
|
|
54566
55368
|
return typeof value === "string" && !Number.isNaN(Date.parse(value));
|
|
54567
55369
|
}
|
|
54568
|
-
function
|
|
55370
|
+
function describeError3(error48) {
|
|
54569
55371
|
return error48 instanceof Error ? error48.message : String(error48);
|
|
54570
55372
|
}
|
|
54571
55373
|
|
|
@@ -54689,17 +55491,17 @@ function installChannel(target, contentPath, channelConfig) {
|
|
|
54689
55491
|
const artifactID = onboardingArtifactID(channelConfig.slug, artifactConfig.slug);
|
|
54690
55492
|
const artifactsDir = getAgentArtifactsDir(target.storagePath);
|
|
54691
55493
|
if (resolved.source.kind === "file") {
|
|
54692
|
-
const destination =
|
|
54693
|
-
(0,
|
|
54694
|
-
(0,
|
|
55494
|
+
const destination = import_node_path17.default.join(artifactsDir, `${artifactID}${import_node_path17.default.extname(resolved.source.path)}`);
|
|
55495
|
+
(0, import_node_fs15.rmSync)(destination, { recursive: true, force: true });
|
|
55496
|
+
(0, import_node_fs15.cpSync)(resolved.source.path, destination);
|
|
54695
55497
|
copies.push({ artifactConfig, artifactID, destination });
|
|
54696
55498
|
} else {
|
|
54697
|
-
const destinationDir =
|
|
54698
|
-
if ((0,
|
|
54699
|
-
(0,
|
|
55499
|
+
const destinationDir = import_node_path17.default.join(artifactsDir, artifactID);
|
|
55500
|
+
if ((0, import_node_fs15.existsSync)(destinationDir)) {
|
|
55501
|
+
(0, import_node_fs15.rmSync)(destinationDir, { recursive: true, force: true });
|
|
54700
55502
|
}
|
|
54701
|
-
(0,
|
|
54702
|
-
copies.push({ artifactConfig, artifactID, destination: destinationDir +
|
|
55503
|
+
(0, import_node_fs15.cpSync)(resolved.source.path, destinationDir, { recursive: true });
|
|
55504
|
+
copies.push({ artifactConfig, artifactID, destination: destinationDir + import_node_path17.default.sep });
|
|
54703
55505
|
}
|
|
54704
55506
|
}
|
|
54705
55507
|
for (const { artifactConfig, artifactID, destination } of copies) {
|
|
@@ -54726,7 +55528,7 @@ function installChannel(target, contentPath, channelConfig) {
|
|
|
54726
55528
|
}
|
|
54727
55529
|
|
|
54728
55530
|
// ../server/src/server-store.ts
|
|
54729
|
-
var
|
|
55531
|
+
var JSON_INDENT_SPACES5 = 2;
|
|
54730
55532
|
var LAYOUT_VERSION = 2;
|
|
54731
55533
|
var CONTENT_WATCH_DEBOUNCE_MS = 100;
|
|
54732
55534
|
var JSON_FILE_SUFFIX2 = ".json";
|
|
@@ -54738,14 +55540,28 @@ function isBundledViewID(id) {
|
|
|
54738
55540
|
function sameIds(left, right) {
|
|
54739
55541
|
return left.length === right.length && left.every((id, index) => id === right[index]);
|
|
54740
55542
|
}
|
|
55543
|
+
function sameIdMembership(left, right) {
|
|
55544
|
+
if (left.length !== right.length) return false;
|
|
55545
|
+
const rightIds = new Set(right);
|
|
55546
|
+
return left.every((id) => rightIds.has(id));
|
|
55547
|
+
}
|
|
55548
|
+
function sameThemeJavaScriptDeclarations(left, right) {
|
|
55549
|
+
return left.every((value, index) => value === right[index]);
|
|
55550
|
+
}
|
|
55551
|
+
function isAppearanceMode(value) {
|
|
55552
|
+
return value === "system" || value === "light" || value === "dark";
|
|
55553
|
+
}
|
|
55554
|
+
function isThemeJavaScriptConsentIds(value) {
|
|
55555
|
+
return Array.isArray(value) && value.every((id) => typeof id === "string" && id.length > 0) && new Set(value).size === value.length;
|
|
55556
|
+
}
|
|
54741
55557
|
function hasSameArtifactMetadata(left, right) {
|
|
54742
55558
|
if (left.kind !== right.kind || left.title !== right.title) return false;
|
|
54743
55559
|
return left.kind === "path" && right.kind === "path" ? left.path === right.path : left.kind === "url" && right.kind === "url" && left.url === right.url;
|
|
54744
55560
|
}
|
|
54745
55561
|
function hasExistingTelevisionDataStructure(storagePath) {
|
|
54746
|
-
if ((0,
|
|
54747
|
-
if ((0,
|
|
54748
|
-
if ((0,
|
|
55562
|
+
if ((0, import_node_fs16.existsSync)(getDisplayStatePath(storagePath))) return true;
|
|
55563
|
+
if ((0, import_node_fs16.existsSync)(getOnboardingStatePath(storagePath))) return true;
|
|
55564
|
+
if ((0, import_node_fs16.existsSync)(getOnboardingArtifactSentinelPath(storagePath))) return true;
|
|
54749
55565
|
if (directoryIsNonEmpty(getChannelsDir(storagePath))) return true;
|
|
54750
55566
|
if (directoryIsNonEmpty(getLegacyScreensDir(storagePath))) return true;
|
|
54751
55567
|
if (directoryIsNonEmpty(getArtifactsMetadataDir(storagePath))) return true;
|
|
@@ -54755,7 +55571,7 @@ function hasExistingTelevisionDataStructure(storagePath) {
|
|
|
54755
55571
|
}
|
|
54756
55572
|
function directoryIsNonEmpty(dir) {
|
|
54757
55573
|
try {
|
|
54758
|
-
return (0,
|
|
55574
|
+
return (0, import_node_fs16.readdirSync)(dir).length > 0;
|
|
54759
55575
|
} catch {
|
|
54760
55576
|
return false;
|
|
54761
55577
|
}
|
|
@@ -54765,10 +55581,10 @@ function artifactWatchTarget(artifact) {
|
|
|
54765
55581
|
return null;
|
|
54766
55582
|
}
|
|
54767
55583
|
if (hasTrailingSeparator(artifact.path)) {
|
|
54768
|
-
return { watchPath: artifact.path,
|
|
55584
|
+
return { watchPath: artifact.path, recursive: true };
|
|
54769
55585
|
}
|
|
54770
55586
|
if (isMarkdownPath(artifact.path) || isHtmlPath(artifact.path)) {
|
|
54771
|
-
return { watchPath: artifact.path };
|
|
55587
|
+
return { watchPath: artifact.path, recursive: false };
|
|
54772
55588
|
}
|
|
54773
55589
|
return null;
|
|
54774
55590
|
}
|
|
@@ -54780,6 +55596,9 @@ var ServerStore = class extends EventTarget {
|
|
|
54780
55596
|
focusedChannelId = null;
|
|
54781
55597
|
pinnedChannelIds = [];
|
|
54782
55598
|
activeThemeName = null;
|
|
55599
|
+
appearanceMode = "system";
|
|
55600
|
+
themeJavaScriptConsentIds = [];
|
|
55601
|
+
themeRegistry = { themes: [], errors: [] };
|
|
54783
55602
|
displayStateReady = false;
|
|
54784
55603
|
_artifacts = /* @__PURE__ */ new Map();
|
|
54785
55604
|
artifactChannels = /* @__PURE__ */ new Map();
|
|
@@ -54791,22 +55610,24 @@ var ServerStore = class extends EventTarget {
|
|
|
54791
55610
|
watchContentFile;
|
|
54792
55611
|
bundledViewsPath;
|
|
54793
55612
|
onboardingContentPath;
|
|
55613
|
+
bundledThemesPath;
|
|
54794
55614
|
serving;
|
|
54795
55615
|
// True only while the constructor's install phase runs: content watchers
|
|
54796
55616
|
// must not start before the final bootstrap step
|
|
54797
|
-
// (specs/arch/onboarding/installer.md#^bootstrap-sequence step
|
|
55617
|
+
// (specs/arch/onboarding/installer.md#^bootstrap-sequence step 8).
|
|
54798
55618
|
inBootstrapInstall = false;
|
|
54799
55619
|
telemetryHooks = null;
|
|
54800
55620
|
// The serving bootstrap sequence and the token-only cutoff are spec'd:
|
|
54801
55621
|
// specs/arch/onboarding/installer.md#^bootstrap-sequence, #^token-only-boot.
|
|
54802
55622
|
constructor(options) {
|
|
54803
55623
|
super();
|
|
54804
|
-
this.storagePath =
|
|
55624
|
+
this.storagePath = import_node_path18.default.resolve(options.storagePath);
|
|
54805
55625
|
this.serving = options.installOnboardingChannels === true;
|
|
54806
55626
|
this.dataDirCreated = !hasExistingTelevisionDataStructure(this.storagePath);
|
|
54807
55627
|
this.watchContentFile = options.watchContentFile ?? defaultWatchContentFile;
|
|
54808
55628
|
this.bundledViewsPath = options.bundledViewsPath;
|
|
54809
55629
|
this.onboardingContentPath = options.onboardingContentPath;
|
|
55630
|
+
this.bundledThemesPath = options.bundledThemesPath === void 0 ? void 0 : import_node_path18.default.resolve(options.bundledThemesPath);
|
|
54810
55631
|
if (this.serving) {
|
|
54811
55632
|
runRedesignStorageMigration(this.storagePath);
|
|
54812
55633
|
}
|
|
@@ -54834,10 +55655,17 @@ var ServerStore = class extends EventTarget {
|
|
|
54834
55655
|
if (this.channels.size === 0) {
|
|
54835
55656
|
this.createChannel({ name: "Default" });
|
|
54836
55657
|
}
|
|
55658
|
+
const bundledThemeState = runBundledThemeInstallation(
|
|
55659
|
+
this.storagePath,
|
|
55660
|
+
this.bundledThemesPath
|
|
55661
|
+
);
|
|
55662
|
+
this.refreshThemeRegistry();
|
|
54837
55663
|
if (!this.loadDisplayState()) {
|
|
54838
55664
|
this.initializeDisplayState();
|
|
54839
55665
|
}
|
|
55666
|
+
this.completeDefaultThemeSelection(bundledThemeState);
|
|
54840
55667
|
this.displayStateReady = true;
|
|
55668
|
+
this.clearUnregisteredActiveTheme();
|
|
54841
55669
|
if (noContentAtBoot && onboarding.focusChannelID !== void 0 && this.channels.has(onboarding.focusChannelID)) {
|
|
54842
55670
|
this.patchDisplay({ focusedChannelId: onboarding.focusChannelID });
|
|
54843
55671
|
}
|
|
@@ -54856,8 +55684,8 @@ var ServerStore = class extends EventTarget {
|
|
|
54856
55684
|
if (!isBundledViewID(id) || this.bundledViewsPath === void 0) {
|
|
54857
55685
|
return null;
|
|
54858
55686
|
}
|
|
54859
|
-
const viewPath =
|
|
54860
|
-
return (0,
|
|
55687
|
+
const viewPath = import_node_path18.default.join(this.bundledViewsPath, id);
|
|
55688
|
+
return (0, import_node_fs16.existsSync)(import_node_path18.default.join(viewPath, "index.html")) ? viewPath : null;
|
|
54861
55689
|
}
|
|
54862
55690
|
getChannel(id) {
|
|
54863
55691
|
const channel = this.channels.get(id);
|
|
@@ -54896,7 +55724,7 @@ var ServerStore = class extends EventTarget {
|
|
|
54896
55724
|
this.persistChannel(channel);
|
|
54897
55725
|
} catch (error48) {
|
|
54898
55726
|
channel.layout = previousLayout;
|
|
54899
|
-
(0,
|
|
55727
|
+
(0, import_node_fs16.rmSync)(getArtifactLiveMetadataPath(this.storagePath, artifact.id), { force: true });
|
|
54900
55728
|
throw error48;
|
|
54901
55729
|
}
|
|
54902
55730
|
this._artifacts.set(artifact.id, artifact);
|
|
@@ -54944,7 +55772,10 @@ var ServerStore = class extends EventTarget {
|
|
|
54944
55772
|
this._artifacts.set(input.artifactID, updated);
|
|
54945
55773
|
if (pointerChanged) {
|
|
54946
55774
|
this.startWatchingArtifactContent(updated);
|
|
54947
|
-
this.
|
|
55775
|
+
const watcher = this.contentWatchers.get(updated.id);
|
|
55776
|
+
if (watcher) {
|
|
55777
|
+
this.scheduleArtifactContentChangedEvent(updated.id, watcher);
|
|
55778
|
+
}
|
|
54948
55779
|
}
|
|
54949
55780
|
this.dispatchEvent(new ArtifactUpdatedEvent("artifact-updated", { artifact: updated }));
|
|
54950
55781
|
if (metadataChanged) {
|
|
@@ -54981,7 +55812,7 @@ var ServerStore = class extends EventTarget {
|
|
|
54981
55812
|
}
|
|
54982
55813
|
this.stopWatchingArtifactContent(artifactID);
|
|
54983
55814
|
this._artifacts.delete(artifactID);
|
|
54984
|
-
(0,
|
|
55815
|
+
(0, import_node_fs16.rmSync)(getArtifactLiveMetadataPath(this.storagePath, artifactID), { force: true });
|
|
54985
55816
|
if (channelID !== void 0) {
|
|
54986
55817
|
this.dispatchEvent(new ArtifactRemovedEvent("artifact-removed", { artifactID, channelID }));
|
|
54987
55818
|
}
|
|
@@ -55006,7 +55837,9 @@ var ServerStore = class extends EventTarget {
|
|
|
55006
55837
|
this.persistDisplayState({
|
|
55007
55838
|
focusedChannelId: channel.id,
|
|
55008
55839
|
pinnedChannelIds: this.pinnedChannelIds,
|
|
55009
|
-
activeThemeName: this.activeThemeName
|
|
55840
|
+
activeThemeName: this.activeThemeName,
|
|
55841
|
+
appearanceMode: this.appearanceMode,
|
|
55842
|
+
themeJavaScriptConsentIds: [...this.themeJavaScriptConsentIds]
|
|
55010
55843
|
});
|
|
55011
55844
|
this.focusedChannelId = channel.id;
|
|
55012
55845
|
}
|
|
@@ -55068,19 +55901,52 @@ var ServerStore = class extends EventTarget {
|
|
|
55068
55901
|
getActiveThemeName() {
|
|
55069
55902
|
return this.activeThemeName;
|
|
55070
55903
|
}
|
|
55904
|
+
hasThemeJavaScriptConsent(themeID) {
|
|
55905
|
+
return this.themeJavaScriptConsentIds.includes(themeID);
|
|
55906
|
+
}
|
|
55907
|
+
getThemeRegistry() {
|
|
55908
|
+
return {
|
|
55909
|
+
themes: this.themeRegistry.themes.map((theme) => ({ ...theme })),
|
|
55910
|
+
errors: this.themeRegistry.errors.map((error48) => ({ ...error48 }))
|
|
55911
|
+
};
|
|
55912
|
+
}
|
|
55913
|
+
refreshThemeRegistry(telemetryContext) {
|
|
55914
|
+
const selectedThemeID = this.activeThemeName;
|
|
55915
|
+
const previousColorScheme = this.getActiveThemeColorScheme();
|
|
55916
|
+
const previousJavaScriptDeclarations = selectedThemeID === null ? null : this.registeredThemeJavaScriptDeclarations(selectedThemeID);
|
|
55917
|
+
this.themeRegistry = scanThemesDirectory(getThemesDir(this.storagePath));
|
|
55918
|
+
if (this.displayStateReady) {
|
|
55919
|
+
this.clearUnregisteredActiveTheme(telemetryContext);
|
|
55920
|
+
if (selectedThemeID !== null && this.activeThemeName === selectedThemeID && previousJavaScriptDeclarations !== null && (previousColorScheme !== this.getActiveThemeColorScheme() || !sameThemeJavaScriptDeclarations(
|
|
55921
|
+
previousJavaScriptDeclarations,
|
|
55922
|
+
this.registeredThemeJavaScriptDeclarations(selectedThemeID)
|
|
55923
|
+
))) {
|
|
55924
|
+
this.dispatchThemeChanged(selectedThemeID);
|
|
55925
|
+
}
|
|
55926
|
+
}
|
|
55927
|
+
return this.getThemeRegistry();
|
|
55928
|
+
}
|
|
55071
55929
|
getDisplayState() {
|
|
55072
55930
|
return {
|
|
55073
55931
|
focusedChannelId: this.getFocusedChannelId(),
|
|
55074
55932
|
pinnedChannelIds: [...this.pinnedChannelIds],
|
|
55075
|
-
activeThemeName: this.activeThemeName
|
|
55933
|
+
activeThemeName: this.activeThemeName,
|
|
55934
|
+
activeThemeColorScheme: this.getActiveThemeColorScheme(),
|
|
55935
|
+
appearanceMode: this.appearanceMode,
|
|
55936
|
+
themeJavaScriptConsentIds: [...this.themeJavaScriptConsentIds]
|
|
55076
55937
|
};
|
|
55077
55938
|
}
|
|
55078
55939
|
patchDisplay(input, telemetryContext) {
|
|
55940
|
+
this.applyDisplayPatch(input, "selection", telemetryContext);
|
|
55941
|
+
}
|
|
55942
|
+
applyDisplayPatch(input, themeChangeReason, telemetryContext) {
|
|
55079
55943
|
const currentFocusedChannelId = this.getFocusedChannelId();
|
|
55080
55944
|
const previousPinnedChannelIds = this.pinnedChannelIds;
|
|
55081
55945
|
let nextFocusedChannelId = this.focusedChannelId;
|
|
55082
55946
|
let nextPinnedChannelIds = this.pinnedChannelIds;
|
|
55083
55947
|
let nextActiveThemeName = this.activeThemeName;
|
|
55948
|
+
let nextAppearanceMode = this.appearanceMode;
|
|
55949
|
+
let nextThemeJavaScriptConsentIds = this.themeJavaScriptConsentIds;
|
|
55084
55950
|
if (input.focusedChannelId !== void 0) {
|
|
55085
55951
|
if (input.focusedChannelId === null) {
|
|
55086
55952
|
if (this.channels.size !== 0) {
|
|
@@ -55101,33 +55967,51 @@ var ServerStore = class extends EventTarget {
|
|
|
55101
55967
|
nextPinnedChannelIds = [...input.pinnedChannelIds];
|
|
55102
55968
|
}
|
|
55103
55969
|
if (input.activeThemeName !== void 0) {
|
|
55104
|
-
if (input.activeThemeName !== null) {
|
|
55105
|
-
|
|
55106
|
-
|
|
55107
|
-
|
|
55108
|
-
|
|
55109
|
-
throw new NotFoundError(`Theme not found: ${input.activeThemeName}`, {
|
|
55110
|
-
entityType: "theme",
|
|
55111
|
-
entityID: input.activeThemeName
|
|
55112
|
-
});
|
|
55113
|
-
}
|
|
55970
|
+
if (input.activeThemeName !== null && !this.isThemeRegistered(input.activeThemeName)) {
|
|
55971
|
+
throw new NotFoundError(`Theme not found: ${input.activeThemeName}`, {
|
|
55972
|
+
entityType: "theme",
|
|
55973
|
+
entityID: input.activeThemeName
|
|
55974
|
+
});
|
|
55114
55975
|
}
|
|
55115
55976
|
nextActiveThemeName = input.activeThemeName;
|
|
55116
55977
|
}
|
|
55978
|
+
if (input.appearanceMode !== void 0) {
|
|
55979
|
+
if (!isAppearanceMode(input.appearanceMode)) {
|
|
55980
|
+
throw new InvalidRequestError(`Invalid appearance mode: ${String(input.appearanceMode)}`);
|
|
55981
|
+
}
|
|
55982
|
+
nextAppearanceMode = input.appearanceMode;
|
|
55983
|
+
}
|
|
55984
|
+
if (input.themeJavaScriptConsentIds !== void 0) {
|
|
55985
|
+
if (input.themeJavaScriptConsentIds.some((id) => typeof id !== "string" || id.length === 0) || new Set(input.themeJavaScriptConsentIds).size !== input.themeJavaScriptConsentIds.length) {
|
|
55986
|
+
throw new InvalidRequestError(
|
|
55987
|
+
"themeJavaScriptConsentIds must contain unique non-empty theme ids"
|
|
55988
|
+
);
|
|
55989
|
+
}
|
|
55990
|
+
nextThemeJavaScriptConsentIds = [...input.themeJavaScriptConsentIds];
|
|
55991
|
+
}
|
|
55117
55992
|
const focusedChannelChanged = nextFocusedChannelId !== this.focusedChannelId;
|
|
55118
55993
|
const pinnedChannelsChanged = !sameIds(nextPinnedChannelIds, this.pinnedChannelIds);
|
|
55119
55994
|
const themeChanged = nextActiveThemeName !== this.activeThemeName;
|
|
55120
|
-
|
|
55995
|
+
const appearanceChanged = nextAppearanceMode !== this.appearanceMode;
|
|
55996
|
+
const themeJavaScriptConsentChanged = !sameIdMembership(
|
|
55997
|
+
nextThemeJavaScriptConsentIds,
|
|
55998
|
+
this.themeJavaScriptConsentIds
|
|
55999
|
+
);
|
|
56000
|
+
if (!focusedChannelChanged && !pinnedChannelsChanged && !themeChanged && !appearanceChanged && !themeJavaScriptConsentChanged) {
|
|
55121
56001
|
return;
|
|
55122
56002
|
}
|
|
55123
56003
|
this.persistDisplayState({
|
|
55124
56004
|
focusedChannelId: this.resolveFocusedChannelId(nextFocusedChannelId),
|
|
55125
56005
|
pinnedChannelIds: nextPinnedChannelIds,
|
|
55126
|
-
activeThemeName: nextActiveThemeName
|
|
56006
|
+
activeThemeName: nextActiveThemeName,
|
|
56007
|
+
appearanceMode: nextAppearanceMode,
|
|
56008
|
+
themeJavaScriptConsentIds: nextThemeJavaScriptConsentIds
|
|
55127
56009
|
});
|
|
55128
56010
|
this.focusedChannelId = nextFocusedChannelId;
|
|
55129
56011
|
this.pinnedChannelIds = nextPinnedChannelIds;
|
|
55130
56012
|
this.activeThemeName = nextActiveThemeName;
|
|
56013
|
+
this.appearanceMode = nextAppearanceMode;
|
|
56014
|
+
this.themeJavaScriptConsentIds = nextThemeJavaScriptConsentIds;
|
|
55131
56015
|
if (themeChanged) {
|
|
55132
56016
|
this.startWatchingActiveTheme();
|
|
55133
56017
|
}
|
|
@@ -55151,11 +56035,19 @@ var ServerStore = class extends EventTarget {
|
|
|
55151
56035
|
)
|
|
55152
56036
|
);
|
|
55153
56037
|
}
|
|
56038
|
+
if (themeChanged || themeJavaScriptConsentChanged) {
|
|
56039
|
+
this.dispatchThemeChanged();
|
|
56040
|
+
}
|
|
55154
56041
|
if (themeChanged) {
|
|
56042
|
+
this.emitTelemetry((hooks) => hooks.themeChanged(themeChangeReason, telemetryContext));
|
|
56043
|
+
}
|
|
56044
|
+
if (appearanceChanged) {
|
|
56045
|
+
this.emitTelemetry((hooks) => hooks.appearanceModeChanged(this.appearanceMode, telemetryContext));
|
|
55155
56046
|
this.dispatchEvent(
|
|
55156
|
-
new
|
|
56047
|
+
new AppearanceChangedEvent("appearance-changed", {
|
|
56048
|
+
appearanceMode: this.appearanceMode
|
|
56049
|
+
})
|
|
55157
56050
|
);
|
|
55158
|
-
this.emitTelemetry((hooks) => hooks.themeChanged(telemetryContext));
|
|
55159
56051
|
}
|
|
55160
56052
|
}
|
|
55161
56053
|
/**
|
|
@@ -55193,8 +56085,8 @@ var ServerStore = class extends EventTarget {
|
|
|
55193
56085
|
const artifactResults = artifactIDs.map(
|
|
55194
56086
|
(artifactID) => this.deleteArtifactWithCause(artifactID, "channel_deleted", telemetryContext)
|
|
55195
56087
|
);
|
|
55196
|
-
const metadataPath =
|
|
55197
|
-
(0,
|
|
56088
|
+
const metadataPath = import_node_path18.default.join(this.channelsDir, `${channel.id}.json`);
|
|
56089
|
+
(0, import_node_fs16.rmSync)(metadataPath, { force: true });
|
|
55198
56090
|
this.channels.delete(channel.id);
|
|
55199
56091
|
const nextFocusedChannelId = previousFocusedChannelId === channel.id ? this.pickDeletionSuccessorChannelID(nextPinnedChannelIds) : previousFocusedChannelId;
|
|
55200
56092
|
const pinnedChannelsChanged = !sameIds(nextPinnedChannelIds, this.pinnedChannelIds);
|
|
@@ -55203,7 +56095,9 @@ var ServerStore = class extends EventTarget {
|
|
|
55203
56095
|
this.persistDisplayState({
|
|
55204
56096
|
focusedChannelId: nextFocusedChannelId,
|
|
55205
56097
|
pinnedChannelIds: nextPinnedChannelIds,
|
|
55206
|
-
activeThemeName: this.activeThemeName
|
|
56098
|
+
activeThemeName: this.activeThemeName,
|
|
56099
|
+
appearanceMode: this.appearanceMode,
|
|
56100
|
+
themeJavaScriptConsentIds: [...this.themeJavaScriptConsentIds]
|
|
55207
56101
|
});
|
|
55208
56102
|
this.pinnedChannelIds = nextPinnedChannelIds;
|
|
55209
56103
|
this.focusedChannelId = nextFocusedChannelId;
|
|
@@ -55239,13 +56133,13 @@ var ServerStore = class extends EventTarget {
|
|
|
55239
56133
|
}
|
|
55240
56134
|
}
|
|
55241
56135
|
load() {
|
|
55242
|
-
if ((0,
|
|
55243
|
-
for (const file2 of (0,
|
|
56136
|
+
if ((0, import_node_fs16.existsSync)(this.channelsDir)) {
|
|
56137
|
+
for (const file2 of (0, import_node_fs16.readdirSync)(this.channelsDir)) {
|
|
55244
56138
|
if (!file2.endsWith(JSON_FILE_SUFFIX2)) continue;
|
|
55245
|
-
const filePath =
|
|
56139
|
+
const filePath = import_node_path18.default.join(this.channelsDir, file2);
|
|
55246
56140
|
let raw;
|
|
55247
56141
|
try {
|
|
55248
|
-
raw = JSON.parse((0,
|
|
56142
|
+
raw = JSON.parse((0, import_node_fs16.readFileSync)(filePath, "utf8"));
|
|
55249
56143
|
} catch (error48) {
|
|
55250
56144
|
console.warn(`Skipping malformed JSON file: ${filePath}`, error48);
|
|
55251
56145
|
continue;
|
|
@@ -55263,15 +56157,15 @@ var ServerStore = class extends EventTarget {
|
|
|
55263
56157
|
});
|
|
55264
56158
|
}
|
|
55265
56159
|
}
|
|
55266
|
-
if (!(0,
|
|
56160
|
+
if (!(0, import_node_fs16.existsSync)(this.artifactsDir)) {
|
|
55267
56161
|
return;
|
|
55268
56162
|
}
|
|
55269
|
-
for (const file2 of (0,
|
|
56163
|
+
for (const file2 of (0, import_node_fs16.readdirSync)(this.artifactsDir)) {
|
|
55270
56164
|
if (!file2.endsWith(JSON_FILE_SUFFIX2)) {
|
|
55271
56165
|
continue;
|
|
55272
56166
|
}
|
|
55273
56167
|
const id = file2.slice(0, -JSON_FILE_SUFFIX2.length);
|
|
55274
|
-
const metadataPath =
|
|
56168
|
+
const metadataPath = import_node_path18.default.join(this.artifactsDir, file2);
|
|
55275
56169
|
const metadata = this.readArtifactFile(metadataPath, id);
|
|
55276
56170
|
this._artifacts.set(id, metadata);
|
|
55277
56171
|
}
|
|
@@ -55285,27 +56179,38 @@ var ServerStore = class extends EventTarget {
|
|
|
55285
56179
|
if (target === null) {
|
|
55286
56180
|
return;
|
|
55287
56181
|
}
|
|
56182
|
+
let watcher;
|
|
56183
|
+
let watcherOwned = false;
|
|
56184
|
+
let pendingChange = false;
|
|
56185
|
+
const scheduleChange = () => {
|
|
56186
|
+
if (!watcher || !watcherOwned) {
|
|
56187
|
+
pendingChange = true;
|
|
56188
|
+
return;
|
|
56189
|
+
}
|
|
56190
|
+
this.scheduleArtifactContentChangedEvent(artifact.id, watcher);
|
|
56191
|
+
};
|
|
55288
56192
|
try {
|
|
55289
|
-
|
|
55290
|
-
|
|
55291
|
-
|
|
55292
|
-
|
|
55293
|
-
this.scheduleArtifactContentChangedEvent(artifact.id);
|
|
55294
|
-
},
|
|
55295
|
-
onWatcherRearmed: () => {
|
|
55296
|
-
this.scheduleArtifactContentChangedEvent(artifact.id);
|
|
55297
|
-
}
|
|
56193
|
+
watcher = this.watchContentFile(target.watchPath, scheduleChange, {
|
|
56194
|
+
recursive: target.recursive,
|
|
56195
|
+
onWatcherDead: scheduleChange,
|
|
56196
|
+
onWatcherRearmed: scheduleChange
|
|
55298
56197
|
});
|
|
55299
56198
|
watcher.on("error", (error48) => {
|
|
56199
|
+
if (this.contentWatchers.get(artifact.id) !== watcher) {
|
|
56200
|
+
return;
|
|
56201
|
+
}
|
|
55300
56202
|
console.warn(
|
|
55301
56203
|
`Watcher error for artifact ${artifact.id}: ${target.watchPath}`,
|
|
55302
56204
|
error48
|
|
55303
56205
|
);
|
|
55304
|
-
|
|
55305
|
-
this.stopWatchingArtifactContent(artifact.id);
|
|
55306
|
-
}
|
|
56206
|
+
this.stopWatchingArtifactContent(artifact.id);
|
|
55307
56207
|
});
|
|
55308
56208
|
this.contentWatchers.set(artifact.id, watcher);
|
|
56209
|
+
watcherOwned = true;
|
|
56210
|
+
if (pendingChange) {
|
|
56211
|
+
pendingChange = false;
|
|
56212
|
+
scheduleChange();
|
|
56213
|
+
}
|
|
55309
56214
|
} catch (error48) {
|
|
55310
56215
|
console.warn(
|
|
55311
56216
|
`Failed to watch artifact content path for ${artifact.id}: ${target.watchPath}`,
|
|
@@ -55332,26 +56237,44 @@ var ServerStore = class extends EventTarget {
|
|
|
55332
56237
|
}
|
|
55333
56238
|
startWatchingActiveTheme() {
|
|
55334
56239
|
this.stopWatchingActiveTheme();
|
|
55335
|
-
if (this.activeThemeName === null || !
|
|
56240
|
+
if (this.activeThemeName === null || !this.isThemeRegistered(this.activeThemeName)) {
|
|
55336
56241
|
return;
|
|
55337
56242
|
}
|
|
55338
56243
|
const themeName = this.activeThemeName;
|
|
55339
|
-
const themePath =
|
|
56244
|
+
const themePath = getThemeDir(this.storagePath, themeName);
|
|
56245
|
+
let watcher;
|
|
56246
|
+
let watcherOwned = false;
|
|
56247
|
+
let pendingChange = false;
|
|
56248
|
+
const scheduleChange = () => {
|
|
56249
|
+
if (!watcher || !watcherOwned) {
|
|
56250
|
+
pendingChange = true;
|
|
56251
|
+
return;
|
|
56252
|
+
}
|
|
56253
|
+
this.scheduleThemeChangedEvent(themeName, watcher);
|
|
56254
|
+
};
|
|
55340
56255
|
try {
|
|
55341
|
-
|
|
55342
|
-
|
|
56256
|
+
watcher = this.watchContentFile(themePath, scheduleChange, {
|
|
56257
|
+
recursive: true,
|
|
56258
|
+
onWatcherDead: scheduleChange,
|
|
56259
|
+
onWatcherRearmed: scheduleChange
|
|
55343
56260
|
});
|
|
55344
56261
|
watcher.on("error", (error48) => {
|
|
56262
|
+
if (this.themeWatcher !== watcher) {
|
|
56263
|
+
return;
|
|
56264
|
+
}
|
|
55345
56265
|
console.warn(
|
|
55346
56266
|
`Watcher error for active theme ${themeName}: ${themePath}`,
|
|
55347
56267
|
error48
|
|
55348
56268
|
);
|
|
55349
|
-
|
|
55350
|
-
this.stopWatchingActiveTheme();
|
|
55351
|
-
}
|
|
56269
|
+
this.stopWatchingActiveTheme();
|
|
55352
56270
|
});
|
|
55353
56271
|
this.themeWatcher = watcher;
|
|
55354
56272
|
this.themeWatcherFor = themeName;
|
|
56273
|
+
watcherOwned = true;
|
|
56274
|
+
if (pendingChange) {
|
|
56275
|
+
pendingChange = false;
|
|
56276
|
+
scheduleChange();
|
|
56277
|
+
}
|
|
55355
56278
|
} catch (error48) {
|
|
55356
56279
|
console.warn(
|
|
55357
56280
|
`Failed to watch active theme path for ${themeName}: ${themePath}`,
|
|
@@ -55368,29 +56291,39 @@ var ServerStore = class extends EventTarget {
|
|
|
55368
56291
|
this.themeWatchDebounceTimer = null;
|
|
55369
56292
|
}
|
|
55370
56293
|
}
|
|
55371
|
-
scheduleThemeChangedEvent(themeName) {
|
|
56294
|
+
scheduleThemeChangedEvent(themeName, sourceWatcher) {
|
|
56295
|
+
if (this.themeWatcher !== sourceWatcher || this.themeWatcherFor !== themeName || this.activeThemeName !== themeName) {
|
|
56296
|
+
return;
|
|
56297
|
+
}
|
|
55372
56298
|
if (this.themeWatchDebounceTimer) {
|
|
55373
56299
|
clearTimeout(this.themeWatchDebounceTimer);
|
|
55374
56300
|
}
|
|
55375
|
-
|
|
55376
|
-
this.themeWatchDebounceTimer
|
|
55377
|
-
if (this.themeWatcher === null) {
|
|
56301
|
+
const timer = setTimeout(() => {
|
|
56302
|
+
if (this.themeWatchDebounceTimer !== timer) {
|
|
55378
56303
|
return;
|
|
55379
56304
|
}
|
|
55380
|
-
|
|
56305
|
+
this.themeWatchDebounceTimer = null;
|
|
56306
|
+
if (this.themeWatcher !== sourceWatcher || this.themeWatcherFor !== themeName || this.activeThemeName !== themeName) {
|
|
55381
56307
|
return;
|
|
55382
56308
|
}
|
|
55383
|
-
this.
|
|
56309
|
+
this.dispatchThemeChanged(themeName);
|
|
55384
56310
|
}, CONTENT_WATCH_DEBOUNCE_MS);
|
|
56311
|
+
this.themeWatchDebounceTimer = timer;
|
|
55385
56312
|
}
|
|
55386
|
-
scheduleArtifactContentChangedEvent(artifactID) {
|
|
56313
|
+
scheduleArtifactContentChangedEvent(artifactID, sourceWatcher) {
|
|
56314
|
+
if (this.contentWatchers.get(artifactID) !== sourceWatcher || !this._artifacts.has(artifactID)) {
|
|
56315
|
+
return;
|
|
56316
|
+
}
|
|
55387
56317
|
const existingTimer = this.contentWatchDebounceTimers.get(artifactID);
|
|
55388
56318
|
if (existingTimer) {
|
|
55389
56319
|
clearTimeout(existingTimer);
|
|
55390
56320
|
}
|
|
55391
56321
|
const timer = setTimeout(() => {
|
|
56322
|
+
if (this.contentWatchDebounceTimers.get(artifactID) !== timer) {
|
|
56323
|
+
return;
|
|
56324
|
+
}
|
|
55392
56325
|
this.contentWatchDebounceTimers.delete(artifactID);
|
|
55393
|
-
if (
|
|
56326
|
+
if (this.contentWatchers.get(artifactID) !== sourceWatcher || !this._artifacts.has(artifactID)) {
|
|
55394
56327
|
return;
|
|
55395
56328
|
}
|
|
55396
56329
|
this.dispatchEvent(
|
|
@@ -55442,20 +56375,20 @@ var ServerStore = class extends EventTarget {
|
|
|
55442
56375
|
* without statting.
|
|
55443
56376
|
*/
|
|
55444
56377
|
normalizeArtifactPath(artifactPath) {
|
|
55445
|
-
if (!
|
|
56378
|
+
if (!import_node_path18.default.isAbsolute(artifactPath)) {
|
|
55446
56379
|
throw new InvalidRequestError("path must be absolute");
|
|
55447
56380
|
}
|
|
55448
56381
|
const stripped = stripTrailingSeparators(artifactPath);
|
|
55449
56382
|
let stat;
|
|
55450
56383
|
try {
|
|
55451
|
-
(0,
|
|
55452
|
-
stat = (0,
|
|
56384
|
+
(0, import_node_fs16.accessSync)(stripped, import_node_fs16.constants.R_OK);
|
|
56385
|
+
stat = (0, import_node_fs16.statSync)(stripped);
|
|
55453
56386
|
} catch {
|
|
55454
56387
|
throw new InvalidRequestError(`path does not exist or is not readable: ${artifactPath}`);
|
|
55455
56388
|
}
|
|
55456
56389
|
if (stat.isDirectory()) {
|
|
55457
|
-
const canonical = hasTrailingSeparator(stripped) ? stripped : `${stripped}${
|
|
55458
|
-
if (!DIRECTORY_INDEX_BASENAMES.some((basename) => (0,
|
|
56390
|
+
const canonical = hasTrailingSeparator(stripped) ? stripped : `${stripped}${import_node_path18.default.sep}`;
|
|
56391
|
+
if (!DIRECTORY_INDEX_BASENAMES.some((basename) => (0, import_node_fs16.existsSync)(import_node_path18.default.join(canonical, basename)))) {
|
|
55459
56392
|
throw new InvalidRequestError(`directory artifact must contain index.html or index.htm: ${canonical}`);
|
|
55460
56393
|
}
|
|
55461
56394
|
return canonical;
|
|
@@ -55483,14 +56416,60 @@ var ServerStore = class extends EventTarget {
|
|
|
55483
56416
|
this.focusedChannelId = this.pickPreferredChannelID();
|
|
55484
56417
|
this.pinnedChannelIds = [];
|
|
55485
56418
|
this.activeThemeName = null;
|
|
56419
|
+
this.appearanceMode = "system";
|
|
56420
|
+
this.themeJavaScriptConsentIds = [];
|
|
55486
56421
|
this.persistDisplayState();
|
|
55487
56422
|
}
|
|
56423
|
+
completeDefaultThemeSelection(state) {
|
|
56424
|
+
if (state === null || state.initialThemeSelectionComplete || !state.installedThemeIDs.includes(DEFAULT_BUNDLED_THEME_ID)) {
|
|
56425
|
+
return;
|
|
56426
|
+
}
|
|
56427
|
+
if (this.activeThemeName === null && this.isThemeRegistered(DEFAULT_BUNDLED_THEME_ID)) {
|
|
56428
|
+
this.persistDisplayState({
|
|
56429
|
+
...this.getDisplayState(),
|
|
56430
|
+
activeThemeName: DEFAULT_BUNDLED_THEME_ID
|
|
56431
|
+
});
|
|
56432
|
+
this.activeThemeName = DEFAULT_BUNDLED_THEME_ID;
|
|
56433
|
+
}
|
|
56434
|
+
writeBundledThemeStateFile(this.storagePath, {
|
|
56435
|
+
version: BUNDLED_THEME_STATE_VERSION,
|
|
56436
|
+
installedThemeIDs: state.installedThemeIDs,
|
|
56437
|
+
initialThemeSelectionComplete: true
|
|
56438
|
+
});
|
|
56439
|
+
}
|
|
56440
|
+
dispatchThemeChanged(themeName = this.activeThemeName) {
|
|
56441
|
+
this.dispatchEvent(new ThemeChangedEvent("theme-changed", {
|
|
56442
|
+
themeName,
|
|
56443
|
+
activeThemeColorScheme: this.getActiveThemeColorScheme(themeName),
|
|
56444
|
+
themeJavaScriptConsentIds: [...this.themeJavaScriptConsentIds]
|
|
56445
|
+
}));
|
|
56446
|
+
}
|
|
56447
|
+
getActiveThemeColorScheme(themeName = this.activeThemeName) {
|
|
56448
|
+
if (themeName === null) return null;
|
|
56449
|
+
return this.themeRegistry.themes.find((theme) => theme.id === themeName)?.colorScheme ?? null;
|
|
56450
|
+
}
|
|
56451
|
+
isThemeRegistered(themeID) {
|
|
56452
|
+
return this.themeRegistry.themes.some((theme) => theme.id === themeID);
|
|
56453
|
+
}
|
|
56454
|
+
registeredThemeJavaScriptDeclarations(themeID) {
|
|
56455
|
+
const theme = this.themeRegistry.themes.find((candidate) => candidate.id === themeID);
|
|
56456
|
+
return [
|
|
56457
|
+
theme?.enableMainJS,
|
|
56458
|
+
theme?.enableIframeBackgroundJS,
|
|
56459
|
+
theme?.enableIframeOverlayJS
|
|
56460
|
+
];
|
|
56461
|
+
}
|
|
56462
|
+
clearUnregisteredActiveTheme(telemetryContext) {
|
|
56463
|
+
if (this.activeThemeName !== null && !this.isThemeRegistered(this.activeThemeName)) {
|
|
56464
|
+
this.applyDisplayPatch({ activeThemeName: null }, "fallback", telemetryContext);
|
|
56465
|
+
}
|
|
56466
|
+
}
|
|
55488
56467
|
ensureDirectories() {
|
|
55489
|
-
(0,
|
|
55490
|
-
(0,
|
|
55491
|
-
(0,
|
|
55492
|
-
(0,
|
|
55493
|
-
(0,
|
|
56468
|
+
(0, import_node_fs16.mkdirSync)(import_node_path18.default.join(this.storagePath, "state"), { recursive: true });
|
|
56469
|
+
(0, import_node_fs16.mkdirSync)(this.channelsDir, { recursive: true });
|
|
56470
|
+
(0, import_node_fs16.mkdirSync)(this.artifactsDir, { recursive: true });
|
|
56471
|
+
(0, import_node_fs16.mkdirSync)(getThemesDir(this.storagePath), { recursive: true });
|
|
56472
|
+
(0, import_node_fs16.mkdirSync)(getAgentArtifactsDir(this.storagePath), { recursive: true });
|
|
55494
56473
|
}
|
|
55495
56474
|
rebuildArtifactChannels() {
|
|
55496
56475
|
this.artifactChannels.clear();
|
|
@@ -55509,12 +56488,12 @@ var ServerStore = class extends EventTarget {
|
|
|
55509
56488
|
}
|
|
55510
56489
|
}
|
|
55511
56490
|
loadDisplayState() {
|
|
55512
|
-
if (!(0,
|
|
56491
|
+
if (!(0, import_node_fs16.existsSync)(this.displayStatePath)) {
|
|
55513
56492
|
return false;
|
|
55514
56493
|
}
|
|
55515
56494
|
let raw;
|
|
55516
56495
|
try {
|
|
55517
|
-
raw = (0,
|
|
56496
|
+
raw = (0, import_node_fs16.readFileSync)(this.displayStatePath, "utf8");
|
|
55518
56497
|
} catch {
|
|
55519
56498
|
return false;
|
|
55520
56499
|
}
|
|
@@ -55524,18 +56503,34 @@ var ServerStore = class extends EventTarget {
|
|
|
55524
56503
|
} catch {
|
|
55525
56504
|
return false;
|
|
55526
56505
|
}
|
|
55527
|
-
if (parsed && typeof parsed === "object" && "focusedChannelId" in parsed && (typeof parsed.focusedChannelId === "string" || parsed.focusedChannelId === null) && "pinnedChannelIds" in parsed && Array.isArray(parsed.pinnedChannelIds) && parsed.pinnedChannelIds.every((id) => typeof id === "string") && "activeThemeName" in parsed && (typeof parsed.activeThemeName === "string" || parsed.activeThemeName === null))
|
|
56506
|
+
if (parsed && typeof parsed === "object" && "focusedChannelId" in parsed && (typeof parsed.focusedChannelId === "string" || parsed.focusedChannelId === null) && "pinnedChannelIds" in parsed && Array.isArray(parsed.pinnedChannelIds) && parsed.pinnedChannelIds.every((id) => typeof id === "string") && "activeThemeName" in parsed && (typeof parsed.activeThemeName === "string" || parsed.activeThemeName === null) && "appearanceMode" in parsed && isAppearanceMode(parsed.appearanceMode) && (!("themeJavaScriptConsentIds" in parsed) || isThemeJavaScriptConsentIds(
|
|
56507
|
+
parsed.themeJavaScriptConsentIds
|
|
56508
|
+
))) {
|
|
55528
56509
|
this.focusedChannelId = parsed.focusedChannelId;
|
|
55529
56510
|
this.pinnedChannelIds = [...parsed.pinnedChannelIds];
|
|
55530
56511
|
this.activeThemeName = parsed.activeThemeName;
|
|
56512
|
+
this.appearanceMode = parsed.appearanceMode;
|
|
56513
|
+
this.themeJavaScriptConsentIds = "themeJavaScriptConsentIds" in parsed ? [...parsed.themeJavaScriptConsentIds] : [];
|
|
55531
56514
|
return true;
|
|
55532
56515
|
}
|
|
55533
56516
|
return false;
|
|
55534
56517
|
}
|
|
55535
|
-
persistDisplayState(state =
|
|
55536
|
-
|
|
56518
|
+
persistDisplayState(state = {
|
|
56519
|
+
focusedChannelId: this.getFocusedChannelId(),
|
|
56520
|
+
pinnedChannelIds: [...this.pinnedChannelIds],
|
|
56521
|
+
activeThemeName: this.activeThemeName,
|
|
56522
|
+
appearanceMode: this.appearanceMode,
|
|
56523
|
+
themeJavaScriptConsentIds: [...this.themeJavaScriptConsentIds]
|
|
56524
|
+
}) {
|
|
56525
|
+
(0, import_node_fs16.writeFileSync)(
|
|
55537
56526
|
this.displayStatePath,
|
|
55538
|
-
JSON.stringify(
|
|
56527
|
+
JSON.stringify({
|
|
56528
|
+
focusedChannelId: state.focusedChannelId,
|
|
56529
|
+
pinnedChannelIds: state.pinnedChannelIds,
|
|
56530
|
+
activeThemeName: state.activeThemeName,
|
|
56531
|
+
appearanceMode: state.appearanceMode,
|
|
56532
|
+
themeJavaScriptConsentIds: state.themeJavaScriptConsentIds
|
|
56533
|
+
}, null, JSON_INDENT_SPACES5)
|
|
55539
56534
|
);
|
|
55540
56535
|
}
|
|
55541
56536
|
get displayStatePath() {
|
|
@@ -55569,11 +56564,11 @@ var ServerStore = class extends EventTarget {
|
|
|
55569
56564
|
return newestChannelID;
|
|
55570
56565
|
}
|
|
55571
56566
|
loadOrCreateAuthToken() {
|
|
55572
|
-
if ((0,
|
|
55573
|
-
return (0,
|
|
56567
|
+
if ((0, import_node_fs16.existsSync)(this.tokenPath)) {
|
|
56568
|
+
return (0, import_node_fs16.readFileSync)(this.tokenPath, "utf8").trim();
|
|
55574
56569
|
}
|
|
55575
56570
|
const token = createToken();
|
|
55576
|
-
(0,
|
|
56571
|
+
(0, import_node_fs16.writeFileSync)(this.tokenPath, `${token}
|
|
55577
56572
|
`);
|
|
55578
56573
|
return token;
|
|
55579
56574
|
}
|
|
@@ -55588,15 +56583,15 @@ var ServerStore = class extends EventTarget {
|
|
|
55588
56583
|
layout: channel.layout,
|
|
55589
56584
|
...channel.onboarding ? { onboarding: channel.onboarding } : {}
|
|
55590
56585
|
};
|
|
55591
|
-
(0,
|
|
55592
|
-
|
|
55593
|
-
JSON.stringify(stored, null,
|
|
56586
|
+
(0, import_node_fs16.writeFileSync)(
|
|
56587
|
+
import_node_path18.default.join(this.channelsDir, `${channel.id}.json`),
|
|
56588
|
+
JSON.stringify(stored, null, JSON_INDENT_SPACES5)
|
|
55594
56589
|
);
|
|
55595
56590
|
}
|
|
55596
56591
|
readArtifactFile(filePath, expectedID) {
|
|
55597
56592
|
let raw;
|
|
55598
56593
|
try {
|
|
55599
|
-
raw = (0,
|
|
56594
|
+
raw = (0, import_node_fs16.readFileSync)(filePath, "utf8");
|
|
55600
56595
|
} catch (error48) {
|
|
55601
56596
|
throw this.invalidMetadataFile(filePath, "unreadable", error48);
|
|
55602
56597
|
}
|
|
@@ -55618,24 +56613,19 @@ var ServerStore = class extends EventTarget {
|
|
|
55618
56613
|
`id ${result.data.id} does not match filename ${expectedID}`
|
|
55619
56614
|
);
|
|
55620
56615
|
}
|
|
55621
|
-
if (result.data.kind === "path" && !
|
|
56616
|
+
if (result.data.kind === "path" && !import_node_path18.default.isAbsolute(result.data.path)) {
|
|
55622
56617
|
throw this.invalidMetadataFile(filePath, "path must be absolute");
|
|
55623
56618
|
}
|
|
55624
56619
|
return result.data;
|
|
55625
56620
|
}
|
|
55626
|
-
/**
|
|
55627
|
-
* Build a descriptive error for a malformed artifact metadata file. The
|
|
55628
|
-
* message points at `docs/storage.md` so the user can reconcile the file
|
|
55629
|
-
* (edit to match the schema, or delete to remove the artifact) without
|
|
55630
|
-
* having to hunt for the schema definition.
|
|
55631
|
-
*/
|
|
56621
|
+
/** Explain the invalid metadata and recovery without relying on repository docs. */
|
|
55632
56622
|
invalidMetadataFile(filePath, reason, cause) {
|
|
55633
56623
|
const message = `Invalid artifact metadata file ${filePath}: ${reason}
|
|
55634
|
-
|
|
56624
|
+
Correct this metadata file and restart Television, or delete only this metadata file to unregister the artifact; its artifact content will remain untouched.`;
|
|
55635
56625
|
return cause !== void 0 ? new Error(message, { cause }) : new Error(message);
|
|
55636
56626
|
}
|
|
55637
56627
|
writeArtifact(artifact) {
|
|
55638
|
-
(0,
|
|
56628
|
+
(0, import_node_fs16.writeFileSync)(getArtifactLiveMetadataPath(this.storagePath, artifact.id), JSON.stringify(artifact, null, JSON_INDENT_SPACES5));
|
|
55639
56629
|
}
|
|
55640
56630
|
get channelsDir() {
|
|
55641
56631
|
return getChannelsDir(this.storagePath);
|
|
@@ -55673,7 +56663,7 @@ var SKILL_INSTALL_TELEMETRY_TIMEOUT_MS2 = 1e3;
|
|
|
55673
56663
|
var MAX_PORT2 = 65535;
|
|
55674
56664
|
var MAX_PROCESS_EXIT_STATUS = 255;
|
|
55675
56665
|
var HTTP_UNAUTHORIZED_STATUS2 = 401;
|
|
55676
|
-
var HELP_POINTER = "Television ships bundled skills. The main skill is `television` \u2014 keep its guidance available for channels, lifecycle, the `tv` CLI,
|
|
56666
|
+
var HELP_POINTER = "Television ships bundled skills. The main skill is `television` \u2014 keep its guidance available for channels, lifecycle, the `tv` CLI, artifact workflow, and theming. Re-read it only if it is not already in context or you know the installed skill changed. Additional `tv-*` skills cover specialized artifact types. Install all bundled skills with `tv skills install <path>` (e.g. ~/.openclaw/skills) or `tv skills install -i`.";
|
|
55677
56667
|
var PORT_ZERO_WARNING = "WARNING: --port 0 can make Television hard for later agent CLI commands to rediscover. Use a stable port and export TELEVISION_PORT in the user's environment when agents need to find the server later.";
|
|
55678
56668
|
var SAFE_ARG_PATTERN = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
55679
56669
|
var CLIDirectiveError = class extends Error {
|
|
@@ -55723,24 +56713,31 @@ function createDirectiveError(message) {
|
|
|
55723
56713
|
return new CLIDirectiveError(ensureHelpPointer(message));
|
|
55724
56714
|
}
|
|
55725
56715
|
function getDevPackageDir() {
|
|
55726
|
-
return
|
|
56716
|
+
return import_node_path19.default.resolve(import_node_path19.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "..");
|
|
55727
56717
|
}
|
|
55728
56718
|
function resolveVercelSkillsInstallerBin() {
|
|
55729
56719
|
if (typeof require === "function" && typeof require.resolve === "function") {
|
|
55730
56720
|
return require.resolve("skills/bin/cli.mjs");
|
|
55731
56721
|
}
|
|
55732
|
-
const localRequire = (0, import_node_module.createRequire)(
|
|
56722
|
+
const localRequire = (0, import_node_module.createRequire)(import_node_path19.default.join(getDevPackageDir(), "package.json"));
|
|
55733
56723
|
return localRequire.resolve("skills/bin/cli.mjs");
|
|
55734
56724
|
}
|
|
55735
56725
|
function readCLIVersion() {
|
|
55736
|
-
if ("
|
|
55737
|
-
return "
|
|
56726
|
+
if ("1.3.2".length > 0) {
|
|
56727
|
+
return "1.3.2";
|
|
55738
56728
|
}
|
|
55739
|
-
const devPackageJsonPath =
|
|
55740
|
-
if (!(0,
|
|
56729
|
+
const devPackageJsonPath = import_node_path19.default.join(getDevPackageDir(), "package.json");
|
|
56730
|
+
if (!(0, import_node_fs17.existsSync)(devPackageJsonPath)) {
|
|
55741
56731
|
throw new Error("Could not resolve package.json for repo-local CLI version.");
|
|
55742
56732
|
}
|
|
55743
|
-
return JSON.parse((0,
|
|
56733
|
+
return JSON.parse((0, import_node_fs17.readFileSync)(devPackageJsonPath, "utf8")).version;
|
|
56734
|
+
}
|
|
56735
|
+
function readCLIVersionOutput(resolveHomeDir) {
|
|
56736
|
+
const releaseVersion = readCLIVersion();
|
|
56737
|
+
if (false) {
|
|
56738
|
+
return `${releaseVersion} (commit ${void 0})`;
|
|
56739
|
+
}
|
|
56740
|
+
return releaseVersion;
|
|
55744
56741
|
}
|
|
55745
56742
|
function inspectTelemetryBuildConfig(env = {}, options = {}) {
|
|
55746
56743
|
const project = resolvePostHogProject(env, options);
|
|
@@ -55760,9 +56757,9 @@ function buildAgentHelpNote() {
|
|
|
55760
56757
|
return [
|
|
55761
56758
|
"",
|
|
55762
56759
|
"Agent workflow note:",
|
|
55763
|
-
" The main skill is `television` \u2014 keep its guidance available for channels, lifecycle, the `tv` CLI,
|
|
56760
|
+
" The main skill is `television` \u2014 keep its guidance available for channels, lifecycle, the `tv` CLI, artifact workflow, and theming.",
|
|
55764
56761
|
" Re-read it only if it is not already in context or you know the installed skill changed.",
|
|
55765
|
-
" Additional `tv-*` skills cover specialized artifact types
|
|
56762
|
+
" Additional `tv-*` skills cover specialized artifact types.",
|
|
55766
56763
|
" Install all bundled skills: `tv skills install <path>` (e.g. ~/.openclaw/skills) or `tv skills install -i`."
|
|
55767
56764
|
].join("\n");
|
|
55768
56765
|
}
|
|
@@ -55770,11 +56767,11 @@ function buildArtifactWorkflowHelpNote(includeHTMLNote) {
|
|
|
55770
56767
|
const lines = [
|
|
55771
56768
|
"",
|
|
55772
56769
|
"Agent note:",
|
|
55773
|
-
" The main skill is `television` \u2014 keep its guidance available for channels, lifecycle,
|
|
56770
|
+
" The main skill is `television` \u2014 keep its guidance available for channels, lifecycle, the `tv` CLI, artifact workflow, and theming.",
|
|
55774
56771
|
" Re-read it only if it is not already in context or you know the installed skill changed."
|
|
55775
56772
|
];
|
|
55776
56773
|
if (includeHTMLNote) {
|
|
55777
|
-
lines.push(" Additional `tv-*` skills cover specialized artifact types
|
|
56774
|
+
lines.push(" Additional `tv-*` skills cover specialized artifact types.");
|
|
55778
56775
|
lines.push(" Install all bundled skills: `tv skills install <path>` (e.g. ~/.openclaw/skills) or `tv skills install -i`.");
|
|
55779
56776
|
}
|
|
55780
56777
|
return lines.join("\n");
|
|
@@ -55818,7 +56815,7 @@ function formatCLIError(error48, argv = []) {
|
|
|
55818
56815
|
const status = typeof error48.status === "number" ? Number(error48.status) : void 0;
|
|
55819
56816
|
if (status === HTTP_UNAUTHORIZED_STATUS2) {
|
|
55820
56817
|
return ensureHelpPointer(
|
|
55821
|
-
`Television server at ${serverURL} rejected the request as unauthorized. Check the token in ${
|
|
56818
|
+
`Television server at ${serverURL} rejected the request as unauthorized. Check the token in ${import_node_path19.default.join(storagePathFromArgv(argv) ?? getTelevisionStoragePath(), "state", "token")}.`
|
|
55822
56819
|
);
|
|
55823
56820
|
}
|
|
55824
56821
|
if (status !== void 0) {
|
|
@@ -55869,66 +56866,76 @@ function resolveServeAuth(argv, hasListen) {
|
|
|
55869
56866
|
}
|
|
55870
56867
|
function resolveStaticDir() {
|
|
55871
56868
|
if (process.argv[1]) {
|
|
55872
|
-
const entryDir =
|
|
55873
|
-
const resolved =
|
|
55874
|
-
return (0,
|
|
56869
|
+
const entryDir = import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1]));
|
|
56870
|
+
const resolved = import_node_path19.default.resolve(entryDir, "./web");
|
|
56871
|
+
return (0, import_node_fs17.existsSync)(import_node_path19.default.join(resolved, "index.html")) ? resolved : void 0;
|
|
55875
56872
|
}
|
|
55876
|
-
const devStaticPath =
|
|
55877
|
-
return (0,
|
|
56873
|
+
const devStaticPath = import_node_path19.default.resolve(getDevPackageDir(), "../web/dist");
|
|
56874
|
+
return (0, import_node_fs17.existsSync)(import_node_path19.default.join(devStaticPath, "index.html")) ? devStaticPath : void 0;
|
|
55878
56875
|
}
|
|
55879
56876
|
function resolveBundledViewsPath() {
|
|
55880
56877
|
if (process.argv[1]) {
|
|
55881
|
-
const entryDir =
|
|
55882
|
-
const resolved =
|
|
55883
|
-
return (0,
|
|
56878
|
+
const entryDir = import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1]));
|
|
56879
|
+
const resolved = import_node_path19.default.resolve(entryDir, "./views");
|
|
56880
|
+
return (0, import_node_fs17.existsSync)(resolved) ? resolved : void 0;
|
|
55884
56881
|
}
|
|
55885
|
-
const devViewsPath =
|
|
55886
|
-
return (0,
|
|
56882
|
+
const devViewsPath = import_node_path19.default.join(getDevPackageDir(), "dist/views");
|
|
56883
|
+
return (0, import_node_fs17.existsSync)(devViewsPath) ? devViewsPath : void 0;
|
|
55887
56884
|
}
|
|
55888
56885
|
function resolveCanonicalDir() {
|
|
55889
56886
|
if (process.argv[1]) {
|
|
55890
|
-
const entryDir =
|
|
55891
|
-
const resolved =
|
|
55892
|
-
return (0,
|
|
56887
|
+
const entryDir = import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1]));
|
|
56888
|
+
const resolved = import_node_path19.default.resolve(entryDir, "./canonical");
|
|
56889
|
+
return (0, import_node_fs17.existsSync)(resolved) ? resolved : void 0;
|
|
55893
56890
|
}
|
|
55894
|
-
const devCanonicalPath =
|
|
56891
|
+
const devCanonicalPath = import_node_path19.default.resolve(
|
|
55895
56892
|
getDevPackageDir(),
|
|
55896
|
-
"../server/dist/canonical
|
|
56893
|
+
"../server/dist/canonical"
|
|
55897
56894
|
);
|
|
55898
|
-
return (0,
|
|
56895
|
+
return (0, import_node_fs17.existsSync)(devCanonicalPath) ? devCanonicalPath : void 0;
|
|
55899
56896
|
}
|
|
55900
56897
|
function resolveOnboardingContentPath() {
|
|
55901
56898
|
if (process.argv[1]) {
|
|
55902
|
-
const entryDir =
|
|
55903
|
-
const resolved =
|
|
55904
|
-
return (0,
|
|
56899
|
+
const entryDir = import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1]));
|
|
56900
|
+
const resolved = import_node_path19.default.resolve(entryDir, "./onboarding");
|
|
56901
|
+
return (0, import_node_fs17.existsSync)(resolved) ? resolved : void 0;
|
|
55905
56902
|
}
|
|
55906
|
-
const devPath =
|
|
56903
|
+
const devPath = import_node_path19.default.resolve(
|
|
55907
56904
|
getDevPackageDir(),
|
|
55908
56905
|
"../server/assets/onboarding-channels"
|
|
55909
56906
|
);
|
|
55910
|
-
return (0,
|
|
56907
|
+
return (0, import_node_fs17.existsSync)(devPath) ? devPath : void 0;
|
|
56908
|
+
}
|
|
56909
|
+
function resolveBundledThemesPath() {
|
|
56910
|
+
if (process.argv[1]) {
|
|
56911
|
+
const entryDir = import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1]));
|
|
56912
|
+
const resolved = import_node_path19.default.resolve(entryDir, "./themes");
|
|
56913
|
+
return (0, import_node_fs17.existsSync)(resolved) ? resolved : void 0;
|
|
56914
|
+
}
|
|
56915
|
+
const devPath = import_node_path19.default.resolve(getDevPackageDir(), "../server/assets/themes");
|
|
56916
|
+
return (0, import_node_fs17.existsSync)(devPath) ? devPath : void 0;
|
|
55911
56917
|
}
|
|
55912
56918
|
function resolveBundledSkillsRoot() {
|
|
55913
|
-
const builtPath = typeof process.argv[1] === "string" ?
|
|
55914
|
-
if (builtPath && (0,
|
|
56919
|
+
const builtPath = typeof process.argv[1] === "string" ? import_node_path19.default.resolve(import_node_path19.default.dirname((0, import_node_fs17.realpathSync)(process.argv[1])), "./skills") : void 0;
|
|
56920
|
+
if (builtPath && (0, import_node_fs17.existsSync)(builtPath)) {
|
|
55915
56921
|
return builtPath;
|
|
55916
56922
|
}
|
|
55917
|
-
const devPath =
|
|
55918
|
-
return (0,
|
|
56923
|
+
const devPath = import_node_path19.default.resolve(getDevPackageDir(), "../skills/dist");
|
|
56924
|
+
return (0, import_node_fs17.existsSync)(devPath) ? devPath : void 0;
|
|
55919
56925
|
}
|
|
55920
56926
|
function copyBundledSkillsToDestination(bundledSkillsRoot, destinationRoot) {
|
|
55921
|
-
if ((0,
|
|
56927
|
+
if ((0, import_node_fs17.existsSync)(destinationRoot) && !(0, import_node_fs17.statSync)(destinationRoot).isDirectory()) {
|
|
55922
56928
|
throw new Error(`Skills destination is not a directory: ${destinationRoot}`);
|
|
55923
56929
|
}
|
|
55924
|
-
(0,
|
|
56930
|
+
(0, import_node_fs17.mkdirSync)(destinationRoot, { recursive: true });
|
|
56931
|
+
(0, import_node_fs17.rmSync)(import_node_path19.default.join(destinationRoot, "tv-theme"), { recursive: true, force: true });
|
|
55925
56932
|
const copied = [];
|
|
55926
|
-
const entries = (0,
|
|
56933
|
+
const entries = (0, import_node_fs17.readdirSync)(bundledSkillsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).sort((a, b2) => a.name.localeCompare(b2.name));
|
|
55927
56934
|
for (const entry of entries) {
|
|
55928
|
-
const sourcePath =
|
|
55929
|
-
const destinationPath =
|
|
55930
|
-
(0,
|
|
55931
|
-
(0,
|
|
56935
|
+
const sourcePath = import_node_path19.default.join(bundledSkillsRoot, entry.name);
|
|
56936
|
+
const destinationPath = import_node_path19.default.join(destinationRoot, entry.name);
|
|
56937
|
+
(0, import_node_fs17.rmSync)(destinationPath, { recursive: true, force: true });
|
|
56938
|
+
(0, import_node_fs17.cpSync)(sourcePath, destinationPath, { recursive: true });
|
|
55932
56939
|
copied.push({ name: entry.name, sourcePath, destinationPath });
|
|
55933
56940
|
}
|
|
55934
56941
|
return copied;
|
|
@@ -56011,11 +57018,11 @@ function formatCommanderError(argv, error48) {
|
|
|
56011
57018
|
return null;
|
|
56012
57019
|
}
|
|
56013
57020
|
function readAuthToken(storagePath) {
|
|
56014
|
-
const tokenPath =
|
|
56015
|
-
if (!(0,
|
|
57021
|
+
const tokenPath = import_node_path19.default.join(storagePath, "state", "token");
|
|
57022
|
+
if (!(0, import_node_fs17.existsSync)(tokenPath)) {
|
|
56016
57023
|
return void 0;
|
|
56017
57024
|
}
|
|
56018
|
-
const token = (0,
|
|
57025
|
+
const token = (0, import_node_fs17.readFileSync)(tokenPath, "utf8").trim();
|
|
56019
57026
|
return token.length > 0 ? token : void 0;
|
|
56020
57027
|
}
|
|
56021
57028
|
function readOrCreateAuthToken(storagePath) {
|
|
@@ -56061,6 +57068,7 @@ function createEnvironment(environment) {
|
|
|
56061
57068
|
storagePath: options.storagePath ?? getTelevisionStoragePath(),
|
|
56062
57069
|
...options.bundledViewsPath ? { bundledViewsPath: options.bundledViewsPath } : {},
|
|
56063
57070
|
...options.onboardingContentPath ? { onboardingContentPath: options.onboardingContentPath } : {},
|
|
57071
|
+
...options.bundledThemesPath ? { bundledThemesPath: options.bundledThemesPath } : {},
|
|
56064
57072
|
installOnboardingChannels: true
|
|
56065
57073
|
}),
|
|
56066
57074
|
listen: options.listen,
|
|
@@ -56091,6 +57099,7 @@ function createEnvironment(environment) {
|
|
|
56091
57099
|
resolveCanonicalDir: environment.resolveCanonicalDir ?? (() => resolveCanonicalDir()),
|
|
56092
57100
|
resolveBundledViewsPath: environment.resolveBundledViewsPath ?? (() => resolveBundledViewsPath()),
|
|
56093
57101
|
resolveOnboardingContentPath: environment.resolveOnboardingContentPath ?? (() => resolveOnboardingContentPath()),
|
|
57102
|
+
resolveBundledThemesPath: environment.resolveBundledThemesPath ?? (() => resolveBundledThemesPath()),
|
|
56094
57103
|
resolveBundledSkillsRoot: environment.resolveBundledSkillsRoot ?? (() => resolveBundledSkillsRoot()),
|
|
56095
57104
|
resolveHomeDir: environment.resolveHomeDir ?? (() => import_node_os5.default.homedir()),
|
|
56096
57105
|
runSkillsInstaller: environment.runSkillsInstaller ?? (async (args) => {
|
|
@@ -56143,7 +57152,7 @@ function createProgram(env, argv = []) {
|
|
|
56143
57152
|
log(storagePath, "persisted service uninstalled", { daemonName: DAEMON_NAME, outcome });
|
|
56144
57153
|
writeJSON(env.stdout, { status: "stopped" });
|
|
56145
57154
|
};
|
|
56146
|
-
program2.name("tv").description("Television \u2014 virtual display for agents").version(
|
|
57155
|
+
program2.name("tv").description("Television \u2014 virtual display for agents").version(readCLIVersionOutput(env.resolveHomeDir)).option("-v", "Output the version number").showSuggestionAfterError(false).addHelpText("after", buildAgentHelpNote()).configureOutput({
|
|
56147
57156
|
writeOut: (str) => env.stdout.write(str),
|
|
56148
57157
|
writeErr: (str) => env.stderr.write(str),
|
|
56149
57158
|
outputError: () => {
|
|
@@ -56173,7 +57182,7 @@ function createProgram(env, argv = []) {
|
|
|
56173
57182
|
);
|
|
56174
57183
|
}
|
|
56175
57184
|
const clientPort = resolveClientPort(opts.port);
|
|
56176
|
-
const storagePath =
|
|
57185
|
+
const storagePath = import_node_path19.default.resolve(opts.storagePath ?? getTelevisionStoragePath());
|
|
56177
57186
|
const profile2 = resolveACPAgentProfile(process.env);
|
|
56178
57187
|
const daemonEnv = buildPersistedACPEnvironment(process.env, { developerHome: env.resolveHomeDir() });
|
|
56179
57188
|
if (process.env.TELEVISION_PORT !== void 0 && process.env.TELEVISION_PORT !== "") {
|
|
@@ -56239,6 +57248,7 @@ function createProgram(env, argv = []) {
|
|
|
56239
57248
|
throw error48;
|
|
56240
57249
|
}
|
|
56241
57250
|
const onboardingContentPath = env.resolveOnboardingContentPath();
|
|
57251
|
+
const bundledThemesPath = env.resolveBundledThemesPath();
|
|
56242
57252
|
const server = env.createServer({
|
|
56243
57253
|
listen: opts.listen,
|
|
56244
57254
|
auth,
|
|
@@ -56248,6 +57258,7 @@ function createProgram(env, argv = []) {
|
|
|
56248
57258
|
canonicalDir: env.resolveCanonicalDir(),
|
|
56249
57259
|
bundledViewsPath: env.resolveBundledViewsPath(),
|
|
56250
57260
|
...onboardingContentPath !== void 0 ? { onboardingContentPath } : {},
|
|
57261
|
+
...bundledThemesPath !== void 0 ? { bundledThemesPath } : {},
|
|
56251
57262
|
launchMode: resolveTelemetryLaunchMode(process.env),
|
|
56252
57263
|
...opts.installedByAgent === void 0 ? {} : { installedByAgent: opts.installedByAgent },
|
|
56253
57264
|
...profile ? { acpProfile: profile } : {}
|
|
@@ -56366,6 +57377,14 @@ function createProgram(env, argv = []) {
|
|
|
56366
57377
|
}
|
|
56367
57378
|
writeLine(env.stdout, `Channel created: ${channel.id} (${channel.name})`);
|
|
56368
57379
|
});
|
|
57380
|
+
program2.command("update-channel").description("Rename a channel in place").requiredOption("--channel <id>", "Channel ID").requiredOption("--name <name>", "New channel name").option("--port <number>", "Server port", parsePortOption).option("--storage-path <path>", "Directory containing the Television token").action(async (opts) => {
|
|
57381
|
+
const client = createAuthenticatedClient(opts);
|
|
57382
|
+
const { channel } = await client.channels.update({
|
|
57383
|
+
channelID: opts.channel,
|
|
57384
|
+
name: opts.name
|
|
57385
|
+
});
|
|
57386
|
+
writeLine(env.stdout, `Channel updated: ${channel.id} (${channel.name})`);
|
|
57387
|
+
});
|
|
56369
57388
|
program2.command("remove-channel").description(
|
|
56370
57389
|
"Delete a channel. Artifacts on the channel are permanently deleted from the Television registry; their pointed-to path or URL targets are not touched."
|
|
56371
57390
|
).requiredOption("--channel <id>", "Channel ID").option("--port <number>", "Server port", parsePortOption).option("--storage-path <path>", "Directory containing the Television token").action(async (opts) => {
|
|
@@ -56386,7 +57405,7 @@ function createProgram(env, argv = []) {
|
|
|
56386
57405
|
writeJSON(env.stdout, await client.channels.get({ channelID: opts.channel }));
|
|
56387
57406
|
});
|
|
56388
57407
|
program2.command("focus-status").description(
|
|
56389
|
-
"Print display state as JSON: the active (persistently focused) channel ID and the active theme
|
|
57408
|
+
"Print display state as JSON: the active (persistently focused) channel ID and the active theme ID."
|
|
56390
57409
|
).option("--port <number>", "Server port", parsePortOption).option("--storage-path <path>", "Directory containing the Television token").action(async (opts) => {
|
|
56391
57410
|
const client = createAuthenticatedClient(opts);
|
|
56392
57411
|
const display = await client.display.get();
|
|
@@ -56404,19 +57423,44 @@ function createProgram(env, argv = []) {
|
|
|
56404
57423
|
writeLine(env.stdout, `Focused channel ${opts.channel}.`);
|
|
56405
57424
|
});
|
|
56406
57425
|
program2.command("set-theme").description(
|
|
56407
|
-
|
|
56408
|
-
).argument("<theme>", "
|
|
57426
|
+
"Activate an installed display theme by its exact theme ID, or use `none` to run without a theme."
|
|
57427
|
+
).argument("<theme>", "Exact theme ID to activate, or `none` to use no theme").option("--port <number>", "Server port", parsePortOption).option("--storage-path <path>", "Directory containing the Television token").addHelpText("after", [
|
|
56409
57428
|
"",
|
|
56410
57429
|
"Examples:",
|
|
56411
57430
|
" tv set-theme paperlike Activate the `paperlike` theme.",
|
|
56412
|
-
" tv set-theme
|
|
57431
|
+
" tv set-theme none Use no theme (case-insensitive).",
|
|
56413
57432
|
"",
|
|
56414
57433
|
"Note:",
|
|
56415
|
-
" `
|
|
56416
|
-
' To activate a user-authored theme literally named `default`, call `PATCH /display { activeThemeName: "default" }` directly.'
|
|
57434
|
+
" `none` means no theme."
|
|
56417
57435
|
].join("\n")).action(async (theme, opts) => {
|
|
56418
57436
|
const client = createAuthenticatedClient(opts);
|
|
56419
|
-
|
|
57437
|
+
let previousSelection = null;
|
|
57438
|
+
let previousSelectionAvailable = false;
|
|
57439
|
+
try {
|
|
57440
|
+
previousSelection = (await client.display.get()).activeThemeName;
|
|
57441
|
+
previousSelectionAvailable = true;
|
|
57442
|
+
} catch {
|
|
57443
|
+
}
|
|
57444
|
+
const nextSelection = theme.toLowerCase() === "none" ? null : theme;
|
|
57445
|
+
if (nextSelection !== null) {
|
|
57446
|
+
const registry2 = await client.themes.refresh();
|
|
57447
|
+
const validationError = registry2.errors.find((entry) => entry.folder === theme);
|
|
57448
|
+
if (validationError !== void 0) {
|
|
57449
|
+
throw new ValidationError(`Theme folder ${theme} is invalid: ${validationError.error}`);
|
|
57450
|
+
}
|
|
57451
|
+
}
|
|
57452
|
+
await client.display.patch({ activeThemeName: nextSelection });
|
|
57453
|
+
const nextLabel = nextSelection ?? "None";
|
|
57454
|
+
if (!previousSelectionAvailable) {
|
|
57455
|
+
writeLine(env.stdout, `Active theme: '${nextLabel}'.`);
|
|
57456
|
+
return;
|
|
57457
|
+
}
|
|
57458
|
+
const previousLabel = previousSelection ?? "None";
|
|
57459
|
+
if (previousSelection === nextSelection) {
|
|
57460
|
+
writeLine(env.stdout, `Active theme unchanged: '${nextLabel}'.`);
|
|
57461
|
+
return;
|
|
57462
|
+
}
|
|
57463
|
+
writeLine(env.stdout, `Active theme changed from '${previousLabel}' to '${nextLabel}'.`);
|
|
56420
57464
|
});
|
|
56421
57465
|
program2.command("focus-artifact").description(
|
|
56422
57466
|
"Send a transient focus nudge for a specific artifact. Connected clients select the artifact's tab page and switch to its channel when needed. This is NOT persisted as state \u2014 there is no concept of a 'focused artifact' that survives reconnects (the focused channel is persistent, but artifact focus is a one-shot event)."
|
|
@@ -56457,7 +57501,7 @@ function createProgram(env, argv = []) {
|
|
|
56457
57501
|
if (!bundledTelevisionSkillsCollectionRoot) {
|
|
56458
57502
|
throw new Error("Could not resolve the bundled Television skills root.");
|
|
56459
57503
|
}
|
|
56460
|
-
const destinationRoot =
|
|
57504
|
+
const destinationRoot = import_node_path19.default.resolve(inputPath);
|
|
56461
57505
|
const copied = copyBundledSkillsToDestination(bundledTelevisionSkillsCollectionRoot, destinationRoot);
|
|
56462
57506
|
writeLine(env.stdout, `Copied ${copied.length} bundled Television skill(s):`);
|
|
56463
57507
|
for (const skill of copied) {
|
|
@@ -56492,7 +57536,7 @@ function createProgram(env, argv = []) {
|
|
|
56492
57536
|
const client = createAuthenticatedClient(opts);
|
|
56493
57537
|
const health = await client.health();
|
|
56494
57538
|
result.healthy = true;
|
|
56495
|
-
|
|
57539
|
+
if (health.version !== void 0) result.version = health.version;
|
|
56496
57540
|
result.bindAddresses = health.bindAddresses;
|
|
56497
57541
|
result.port = health.port;
|
|
56498
57542
|
result.telemetry = await client.telemetry.status();
|
|
@@ -56516,7 +57560,7 @@ async function runCLI(argv, environment = {}) {
|
|
|
56516
57560
|
const env = createEnvironment(environment);
|
|
56517
57561
|
try {
|
|
56518
57562
|
if (argv.length === 1 && argv[0] === "-v") {
|
|
56519
|
-
writeLine(env.stdout,
|
|
57563
|
+
writeLine(env.stdout, readCLIVersionOutput(env.resolveHomeDir));
|
|
56520
57564
|
return 0;
|
|
56521
57565
|
}
|
|
56522
57566
|
const program2 = createProgram(env, argv);
|
|
@@ -56555,6 +57599,7 @@ if (!isVitestRuntime()) {
|
|
|
56555
57599
|
inspectTelemetryBuildConfig,
|
|
56556
57600
|
listVisibleCLICommandNames,
|
|
56557
57601
|
resolveBundledSkillsRoot,
|
|
57602
|
+
resolveBundledThemesPath,
|
|
56558
57603
|
resolveBundledViewsPath,
|
|
56559
57604
|
resolveCanonicalDir,
|
|
56560
57605
|
resolveOnboardingContentPath,
|