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 prestream. Waking
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-QT7LGBTP.js";
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-BMA4X5ZT.js");
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-BMA4X5ZT.js");
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-NGNF47ZY.js");
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}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-QT7LGBTP.js";
8
+ } from "./chunk-MXBN3QZ5.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -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-CpXBoZOv.js
23637
- var require_dist_CpXBoZOv = __commonJS({
23638
- "../system/dist/dist-CpXBoZOv.js"(exports) {
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 prestream. Waking
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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-1sEBolVU.js
64671
- var require_retired_settings_keys_1sEBolVU = __commonJS({
64672
- "../system/dist/retired-settings-keys-1sEBolVU.js"(exports) {
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
66912
- var require_retired_settings_keys = require_retired_settings_keys_1sEBolVU();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
85634
- var require_retired_settings_keys = require_retired_settings_keys_1sEBolVU();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 = require_dist_CpXBoZOv();
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 prestream. Waking
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, siblingDistDir = path.resolve(__dirname, "../../addon-agent-ui/dist")) {
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.164",
3
+ "version": "1.2.166",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",