camstack 1.2.164 → 1.2.166
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.
|
@@ -19197,7 +19197,7 @@ var streamBrokerCapability = {
|
|
|
19197
19197
|
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
19198
19198
|
* choice — a camera may declare a signal the operator does not want
|
|
19199
19199
|
* waking anything), and
|
|
19200
|
-
* - a consumer is actually attached and waiting on the
|
|
19200
|
+
* - a consumer is actually attached and waiting on the sentry. Waking
|
|
19201
19201
|
* a camera nobody is watching is the one thing a battery camera must
|
|
19202
19202
|
* never do, and a signal arriving with no consumer is exactly that.
|
|
19203
19203
|
*
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDiscover
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MXBN3QZ5.js";
|
|
5
5
|
import "./chunk-LMMQX4CK.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -38,7 +38,7 @@ async function runServe(args) {
|
|
|
38
38
|
...typeof values.data === "string" ? { data: values.data } : {}
|
|
39
39
|
};
|
|
40
40
|
Object.assign(process.env, buildServeEnv(opts));
|
|
41
|
-
await import("./launcher-
|
|
41
|
+
await import("./launcher-F6TAVUCG.js");
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// src/commands/agent.ts
|
|
@@ -83,7 +83,7 @@ async function runAgent(args) {
|
|
|
83
83
|
...typeof values.port === "string" ? { port: values.port } : {}
|
|
84
84
|
};
|
|
85
85
|
Object.assign(process.env, buildAgentEnv(opts));
|
|
86
|
-
await import("./launcher-
|
|
86
|
+
await import("./launcher-F6TAVUCG.js");
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// src/commands/setup.ts
|
|
@@ -1140,7 +1140,7 @@ function isUnknown(_value) {
|
|
|
1140
1140
|
return true;
|
|
1141
1141
|
}
|
|
1142
1142
|
async function resolveServerInteractive(presetNamespace) {
|
|
1143
|
-
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-
|
|
1143
|
+
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-7R72RWAY.js");
|
|
1144
1144
|
if (presetNamespace) {
|
|
1145
1145
|
const spinner4 = clack.spinner();
|
|
1146
1146
|
spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
|
|
@@ -6445,6 +6445,62 @@ var require_first_boot_addon_plan = __commonJS({
|
|
|
6445
6445
|
}
|
|
6446
6446
|
});
|
|
6447
6447
|
|
|
6448
|
+
// ../../server/backend/dist/core/addon/addon-realign-plan.js
|
|
6449
|
+
var require_addon_realign_plan = __commonJS({
|
|
6450
|
+
"../../server/backend/dist/core/addon/addon-realign-plan.js"(exports) {
|
|
6451
|
+
"use strict";
|
|
6452
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6453
|
+
exports.planAddonRealignment = planAddonRealignment;
|
|
6454
|
+
function isStrictlyNewer(a, b) {
|
|
6455
|
+
const pa = a.split(".").map((p) => Number.parseInt(p, 10));
|
|
6456
|
+
const pb = b.split(".").map((p) => Number.parseInt(p, 10));
|
|
6457
|
+
const len = Math.max(pa.length, pb.length);
|
|
6458
|
+
for (let i = 0; i < len; i += 1) {
|
|
6459
|
+
const x = pa[i] ?? 0;
|
|
6460
|
+
const y = pb[i] ?? 0;
|
|
6461
|
+
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
6462
|
+
return false;
|
|
6463
|
+
if (x !== y)
|
|
6464
|
+
return x > y;
|
|
6465
|
+
}
|
|
6466
|
+
return false;
|
|
6467
|
+
}
|
|
6468
|
+
function planAddonRealignment(candidates) {
|
|
6469
|
+
return candidates.map((c) => {
|
|
6470
|
+
if (c.closureVersion === null) {
|
|
6471
|
+
return { pkg: c.pkg, action: "keep", reason: "not carried by this closure" };
|
|
6472
|
+
}
|
|
6473
|
+
if (!isStrictlyNewer(c.closureVersion, c.installedVersion)) {
|
|
6474
|
+
return {
|
|
6475
|
+
pkg: c.pkg,
|
|
6476
|
+
action: "keep",
|
|
6477
|
+
reason: `installed ${c.installedVersion}, closure ${c.closureVersion} \u2014 not strictly newer`
|
|
6478
|
+
};
|
|
6479
|
+
}
|
|
6480
|
+
if (c.installedUpdatedAtMs === null || c.closureLandedAtMs === null) {
|
|
6481
|
+
return {
|
|
6482
|
+
pkg: c.pkg,
|
|
6483
|
+
action: "keep",
|
|
6484
|
+
reason: "cannot date the install or the closure \u2014 an unknown is not evidence of being stale"
|
|
6485
|
+
};
|
|
6486
|
+
}
|
|
6487
|
+
if (c.installedUpdatedAtMs >= c.closureLandedAtMs) {
|
|
6488
|
+
return {
|
|
6489
|
+
pkg: c.pkg,
|
|
6490
|
+
action: "keep",
|
|
6491
|
+
reason: `installed ${c.installedVersion} was deployed AFTER this closure landed \u2014 better informed than ${c.closureVersion}`
|
|
6492
|
+
};
|
|
6493
|
+
}
|
|
6494
|
+
return {
|
|
6495
|
+
pkg: c.pkg,
|
|
6496
|
+
action: "realign",
|
|
6497
|
+
reason: `installed ${c.installedVersion} predates this closure, which carries ${c.closureVersion}`
|
|
6498
|
+
};
|
|
6499
|
+
});
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6502
|
+
});
|
|
6503
|
+
|
|
6448
6504
|
// ../../server/backend/dist/framework-nodepath.js
|
|
6449
6505
|
var require_framework_nodepath = __commonJS({
|
|
6450
6506
|
"../../server/backend/dist/framework-nodepath.js"(exports) {
|
|
@@ -23633,9 +23689,9 @@ var require_zod = __commonJS({
|
|
|
23633
23689
|
}
|
|
23634
23690
|
});
|
|
23635
23691
|
|
|
23636
|
-
// ../system/dist/dist-
|
|
23637
|
-
var
|
|
23638
|
-
"../system/dist/dist-
|
|
23692
|
+
// ../system/dist/dist-DluLUTzR.js
|
|
23693
|
+
var require_dist_DluLUTzR = __commonJS({
|
|
23694
|
+
"../system/dist/dist-DluLUTzR.js"(exports) {
|
|
23639
23695
|
"use strict";
|
|
23640
23696
|
var zod = require_zod();
|
|
23641
23697
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
@@ -29856,7 +29912,7 @@ var require_dist_CpXBoZOv = __commonJS({
|
|
|
29856
29912
|
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
29857
29913
|
* choice — a camera may declare a signal the operator does not want
|
|
29858
29914
|
* waking anything), and
|
|
29859
|
-
* - a consumer is actually attached and waiting on the
|
|
29915
|
+
* - a consumer is actually attached and waiting on the sentry. Waking
|
|
29860
29916
|
* a camera nobody is watching is the one thing a battery camera must
|
|
29861
29917
|
* never do, and a signal arriving with no consumer is exactly that.
|
|
29862
29918
|
*
|
|
@@ -62857,7 +62913,7 @@ var require_alerts_addon = __commonJS({
|
|
|
62857
62913
|
[Symbol.toStringTag]: { value: "Module" }
|
|
62858
62914
|
});
|
|
62859
62915
|
require_chunk_Cek0wNdY();
|
|
62860
|
-
var require_dist10 =
|
|
62916
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
62861
62917
|
function selectExpired(alerts, cutoffMs) {
|
|
62862
62918
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
62863
62919
|
}
|
|
@@ -63676,7 +63732,7 @@ var require_console_logging = __commonJS({
|
|
|
63676
63732
|
[Symbol.toStringTag]: { value: "Module" }
|
|
63677
63733
|
});
|
|
63678
63734
|
require_chunk_Cek0wNdY();
|
|
63679
|
-
var require_dist10 =
|
|
63735
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
63680
63736
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
63681
63737
|
var LEVEL_RANK = {
|
|
63682
63738
|
debug: 0,
|
|
@@ -63770,7 +63826,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
63770
63826
|
"use strict";
|
|
63771
63827
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
63772
63828
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
63773
|
-
var require_dist10 =
|
|
63829
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
63774
63830
|
var node_crypto = __require("crypto");
|
|
63775
63831
|
var node_fs_promises = __require("fs/promises");
|
|
63776
63832
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -64667,11 +64723,11 @@ var require_core_blocks = __commonJS({
|
|
|
64667
64723
|
}
|
|
64668
64724
|
});
|
|
64669
64725
|
|
|
64670
|
-
// ../system/dist/retired-settings-keys-
|
|
64671
|
-
var
|
|
64672
|
-
"../system/dist/retired-settings-keys-
|
|
64726
|
+
// ../system/dist/retired-settings-keys-VcrnwKN0.js
|
|
64727
|
+
var require_retired_settings_keys_VcrnwKN0 = __commonJS({
|
|
64728
|
+
"../system/dist/retired-settings-keys-VcrnwKN0.js"(exports) {
|
|
64673
64729
|
"use strict";
|
|
64674
|
-
var require_dist10 =
|
|
64730
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
64675
64731
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
64676
64732
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
64677
64733
|
return raw === "" || raw === "hub";
|
|
@@ -66908,8 +66964,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
66908
66964
|
[Symbol.toStringTag]: { value: "Module" }
|
|
66909
66965
|
});
|
|
66910
66966
|
require_chunk_Cek0wNdY();
|
|
66911
|
-
var require_dist10 =
|
|
66912
|
-
var require_retired_settings_keys =
|
|
66967
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
66968
|
+
var require_retired_settings_keys = require_retired_settings_keys_VcrnwKN0();
|
|
66913
66969
|
var node_crypto = __require("crypto");
|
|
66914
66970
|
var _camstack_types_node = require_node();
|
|
66915
66971
|
var JOB_HISTORY = 20;
|
|
@@ -72917,7 +72973,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
72917
72973
|
[Symbol.toStringTag]: { value: "Module" }
|
|
72918
72974
|
});
|
|
72919
72975
|
require_chunk_Cek0wNdY();
|
|
72920
|
-
var require_dist10 =
|
|
72976
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
72921
72977
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
72922
72978
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
72923
72979
|
var HubForwarderDestination = class {
|
|
@@ -73054,7 +73110,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
73054
73110
|
"use strict";
|
|
73055
73111
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
73056
73112
|
require_chunk_Cek0wNdY();
|
|
73057
|
-
var require_dist10 =
|
|
73113
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
73058
73114
|
var NO_DEVICES = "liveness:no-devices";
|
|
73059
73115
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
73060
73116
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -73250,7 +73306,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
73250
73306
|
[Symbol.toStringTag]: { value: "Module" }
|
|
73251
73307
|
});
|
|
73252
73308
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
73253
|
-
var require_dist10 =
|
|
73309
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
73254
73310
|
var node_crypto = __require("crypto");
|
|
73255
73311
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
73256
73312
|
var crypto$1 = __require("crypto");
|
|
@@ -81063,7 +81119,7 @@ var require_loki_logging = __commonJS({
|
|
|
81063
81119
|
[Symbol.toStringTag]: { value: "Module" }
|
|
81064
81120
|
});
|
|
81065
81121
|
require_chunk_Cek0wNdY();
|
|
81066
|
-
var require_dist10 =
|
|
81122
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
81067
81123
|
function sanitizeLabelName(raw) {
|
|
81068
81124
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
81069
81125
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -81650,7 +81706,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
81650
81706
|
[Symbol.toStringTag]: { value: "Module" }
|
|
81651
81707
|
});
|
|
81652
81708
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
81653
|
-
var require_dist10 =
|
|
81709
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
81654
81710
|
var node_fs_promises = __require("fs/promises");
|
|
81655
81711
|
var node_fs = __require("fs");
|
|
81656
81712
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -84403,7 +84459,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
84403
84459
|
[Symbol.toStringTag]: { value: "Module" }
|
|
84404
84460
|
});
|
|
84405
84461
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
84406
|
-
var require_dist10 =
|
|
84462
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
84407
84463
|
var node_crypto = __require("crypto");
|
|
84408
84464
|
var node_fs_promises = __require("fs/promises");
|
|
84409
84465
|
var node_path = __require("path");
|
|
@@ -85630,8 +85686,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
85630
85686
|
[Symbol.toStringTag]: { value: "Module" }
|
|
85631
85687
|
});
|
|
85632
85688
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
85633
|
-
var require_dist10 =
|
|
85634
|
-
var require_retired_settings_keys =
|
|
85689
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
85690
|
+
var require_retired_settings_keys = require_retired_settings_keys_VcrnwKN0();
|
|
85635
85691
|
var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
|
|
85636
85692
|
var node_crypto = __require("crypto");
|
|
85637
85693
|
var node_path = __require("path");
|
|
@@ -88418,7 +88474,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
88418
88474
|
[Symbol.toStringTag]: { value: "Module" }
|
|
88419
88475
|
});
|
|
88420
88476
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
88421
|
-
var require_dist10 =
|
|
88477
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
88422
88478
|
var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
|
|
88423
88479
|
var zod = require_zod();
|
|
88424
88480
|
var node_crypto = __require("crypto");
|
|
@@ -92145,7 +92201,7 @@ var require_system_config_addon = __commonJS({
|
|
|
92145
92201
|
[Symbol.toStringTag]: { value: "Module" }
|
|
92146
92202
|
});
|
|
92147
92203
|
require_chunk_Cek0wNdY();
|
|
92148
|
-
var require_dist10 =
|
|
92204
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
92149
92205
|
var SECTION_TITLES = {
|
|
92150
92206
|
server: "Server",
|
|
92151
92207
|
auth: "Authentication"
|
|
@@ -110206,7 +110262,7 @@ var require_winston_logging = __commonJS({
|
|
|
110206
110262
|
[Symbol.toStringTag]: { value: "Module" }
|
|
110207
110263
|
});
|
|
110208
110264
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
110209
|
-
var require_dist10 =
|
|
110265
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
110210
110266
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
110211
110267
|
var node_path = __require("path");
|
|
110212
110268
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -136473,7 +136529,7 @@ var require_dist3 = __commonJS({
|
|
|
136473
136529
|
"use strict";
|
|
136474
136530
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
136475
136531
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
136476
|
-
var require_dist10 =
|
|
136532
|
+
var require_dist10 = require_dist_DluLUTzR();
|
|
136477
136533
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
136478
136534
|
require_alerts();
|
|
136479
136535
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -140227,6 +140283,32 @@ var require_dist3 = __commonJS({
|
|
|
140227
140283
|
* into `addonsDir/<pkg>/`. The Electron bundled-addons path
|
|
140228
140284
|
* uses this so the runtime owns its on-disk copy.
|
|
140229
140285
|
*/
|
|
140286
|
+
/**
|
|
140287
|
+
* Re-install one addon from the running server closure.
|
|
140288
|
+
*
|
|
140289
|
+
* The closure carries a copy of every addon it declares as a dependency, and
|
|
140290
|
+
* NOTHING loads an addon from there — `AddonLoader` reads the addon root and
|
|
140291
|
+
* only the addon root, on every role. So those copies are transport, and
|
|
140292
|
+
* this is the only thing that moves them into the place that runs code.
|
|
140293
|
+
*
|
|
140294
|
+
* Without it a server update advances the closure and changes nothing: six
|
|
140295
|
+
* addons on the hub were behind by up to nineteen versions on 2026-09-17,
|
|
140296
|
+
* each frozen at whenever somebody last ran `camstack deploy`.
|
|
140297
|
+
*
|
|
140298
|
+
* WHICH addons deserve this is not decided here — see `planAddonRealignment`,
|
|
140299
|
+
* which needs two gates because a version comparison alone would overwrite a
|
|
140300
|
+
* deliberate deploy. This only carries out a decision already made.
|
|
140301
|
+
*/
|
|
140302
|
+
async realignFromClosure(packageName, closureDir) {
|
|
140303
|
+
const targetDir = node_path.join(this.addonsDir, packageName);
|
|
140304
|
+
const result = await this.installLocal(packageName, closureDir);
|
|
140305
|
+
await node_fs.promises.writeFile(node_path.join(targetDir, ".install-source"), "closure");
|
|
140306
|
+
this.manifest.upsert(result.name, {
|
|
140307
|
+
version: result.version,
|
|
140308
|
+
source: "closure"
|
|
140309
|
+
});
|
|
140310
|
+
return result;
|
|
140311
|
+
}
|
|
140230
140312
|
async installLocal(packageName, sourceDir) {
|
|
140231
140313
|
const pkgView = readPackageJson(node_path.join(sourceDir, "package.json"));
|
|
140232
140314
|
if (!pkgView) throw new Error(`Invalid package.json at ${sourceDir}`);
|
|
@@ -223733,7 +223815,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
223733
223815
|
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
223734
223816
|
* choice — a camera may declare a signal the operator does not want
|
|
223735
223817
|
* waking anything), and
|
|
223736
|
-
* - a consumer is actually attached and waiting on the
|
|
223818
|
+
* - a consumer is actually attached and waiting on the sentry. Waking
|
|
223737
223819
|
* a camera nobody is watching is the one thing a battery camera must
|
|
223738
223820
|
* never do, and a signal arriving with no consumer is exactly that.
|
|
223739
223821
|
*
|
|
@@ -306439,9 +306521,7 @@ var require_agent_http = __commonJS({
|
|
|
306439
306521
|
}
|
|
306440
306522
|
return installed?.dir ?? bundled?.dir ?? null;
|
|
306441
306523
|
}
|
|
306442
|
-
function resolveUiDistDir(dataDir, bundledAddonsDir
|
|
306443
|
-
if (fs.existsSync(path.join(siblingDistDir, "index.html")))
|
|
306444
|
-
return siblingDistDir;
|
|
306524
|
+
function resolveUiDistDir(dataDir, bundledAddonsDir) {
|
|
306445
306525
|
const installed = readUiDistCandidate(path.join(dataDir, "addons", "@camstack", "addon-agent-ui"));
|
|
306446
306526
|
const bundled = bundledAddonsDir ? readUiDistCandidate(path.join(bundledAddonsDir, "addon-agent-ui")) : null;
|
|
306447
306527
|
const picked = pickUiDist(installed, bundled);
|
|
@@ -439897,6 +439977,7 @@ var require_launcher = __commonJS({
|
|
|
439897
439977
|
var addon_root_inventory_js_1 = require_addon_root_inventory();
|
|
439898
439978
|
var bootstrap_packages_js_1 = require_bootstrap_packages();
|
|
439899
439979
|
var first_boot_addon_plan_js_1 = require_first_boot_addon_plan();
|
|
439980
|
+
var addon_realign_plan_js_1 = require_addon_realign_plan();
|
|
439900
439981
|
var framework_nodepath_js_1 = require_framework_nodepath();
|
|
439901
439982
|
var package_inventory_js_1 = require_package_inventory();
|
|
439902
439983
|
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
@@ -439996,6 +440077,13 @@ var require_launcher = __commonJS({
|
|
|
439996
440077
|
return null;
|
|
439997
440078
|
}
|
|
439998
440079
|
}
|
|
440080
|
+
function readDirTimeMs(dir) {
|
|
440081
|
+
try {
|
|
440082
|
+
return fs.statSync(dir).mtimeMs;
|
|
440083
|
+
} catch {
|
|
440084
|
+
return null;
|
|
440085
|
+
}
|
|
440086
|
+
}
|
|
439999
440087
|
function readInstalledAddonVersions(addonRoot, packages) {
|
|
440000
440088
|
const out = {};
|
|
440001
440089
|
for (const name of packages) {
|
|
@@ -440094,6 +440182,37 @@ var require_launcher = __commonJS({
|
|
|
440094
440182
|
console.warn(`[launcher] first-boot addon plan failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
440095
440183
|
}
|
|
440096
440184
|
await installer.ensureRequiredPackages(bootstrapRequired);
|
|
440185
|
+
try {
|
|
440186
|
+
const closureNodeModules = path.resolve(__dirname, "..", "node_modules");
|
|
440187
|
+
const decisions = (0, addon_realign_plan_js_1.planAddonRealignment)(bootstrapRequired.flatMap((pkg) => {
|
|
440188
|
+
const installedVersion = readInstalledAddonVersions(addonsDir, [pkg])[pkg];
|
|
440189
|
+
if (typeof installedVersion !== "string")
|
|
440190
|
+
return [];
|
|
440191
|
+
return [
|
|
440192
|
+
{
|
|
440193
|
+
pkg,
|
|
440194
|
+
installedVersion,
|
|
440195
|
+
installedUpdatedAtMs: readDirTimeMs(path.join(addonsDir, pkg)),
|
|
440196
|
+
closureVersion: readInstalledAddonVersions(closureNodeModules, [pkg])[pkg] ?? null,
|
|
440197
|
+
closureLandedAtMs: readDirTimeMs(path.join(closureNodeModules, pkg))
|
|
440198
|
+
}
|
|
440199
|
+
];
|
|
440200
|
+
}));
|
|
440201
|
+
for (const d of decisions) {
|
|
440202
|
+
if (d.action !== "realign")
|
|
440203
|
+
continue;
|
|
440204
|
+
try {
|
|
440205
|
+
const done = await installer.realignFromClosure(d.pkg, path.join(closureNodeModules, d.pkg));
|
|
440206
|
+
console.log(`[launcher] re-aligned ${d.pkg} \u2192 ${done.version} \u2014 ${d.reason}`);
|
|
440207
|
+
} catch (err) {
|
|
440208
|
+
console.warn(`[launcher] re-align FAILED for ${d.pkg}: ${err instanceof Error ? err.message : String(err)}`);
|
|
440209
|
+
}
|
|
440210
|
+
}
|
|
440211
|
+
const kept = decisions.filter((d) => d.action === "keep").length;
|
|
440212
|
+
console.log(`[launcher] addon re-alignment: ${decisions.length - kept} re-aligned, ${kept} kept as they are`);
|
|
440213
|
+
} catch (err) {
|
|
440214
|
+
console.warn(`[launcher] addon re-alignment failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
440215
|
+
}
|
|
440097
440216
|
if (typeof installer.ensureAddonRuntimeDeps === "function") {
|
|
440098
440217
|
try {
|
|
440099
440218
|
const depsResult = await installer.ensureAddonRuntimeDeps();
|