@camstack/system 1.2.91 → 1.2.93

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.
Files changed (58) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/console-logging/index.js +1 -1
  12. package/dist/builtins/console-logging/index.mjs +1 -1
  13. package/dist/builtins/core-blocks/blocks-integration.d.ts +34 -1
  14. package/dist/builtins/core-blocks/core-blocks.addon.js +69 -22
  15. package/dist/builtins/core-blocks/core-blocks.addon.mjs +69 -22
  16. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  17. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  18. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  19. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  20. package/dist/builtins/hub-forwarder/index.js +1 -1
  21. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  22. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  23. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  24. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  25. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  26. package/dist/builtins/local-network/local-network.addon.js +1 -1
  27. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  28. package/dist/builtins/loki-logging/index.js +1 -1
  29. package/dist/builtins/loki-logging/index.mjs +1 -1
  30. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  31. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  32. package/dist/builtins/platform-probe/index.js +1 -1
  33. package/dist/builtins/platform-probe/index.mjs +1 -1
  34. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  35. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  36. package/dist/builtins/snapshot/index.js +27 -6
  37. package/dist/builtins/snapshot/index.mjs +27 -6
  38. package/dist/builtins/snapshot/snapshot-courtesy.d.ts +12 -2
  39. package/dist/builtins/snapshot/snapshot.addon.d.ts +11 -0
  40. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  41. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  42. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
  43. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
  44. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  45. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  46. package/dist/builtins/system-config/system-config.addon.js +1 -1
  47. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  48. package/dist/builtins/winston-logging/index.js +1 -1
  49. package/dist/builtins/winston-logging/index.mjs +1 -1
  50. package/dist/{dist-9Gfk4KOk.js → dist-BMus2E5R.js} +351 -7
  51. package/dist/{dist-DhrTd8LL.mjs → dist-F1XDQDE1.mjs} +346 -8
  52. package/dist/index.js +41 -6
  53. package/dist/index.mjs +41 -6
  54. package/dist/kernel/addon-health-monitor.d.ts +10 -1
  55. package/dist/logging/log-manager.d.ts +28 -0
  56. package/dist/{manifest-python-deps-C0zkl1Ae.js → manifest-python-deps-BZO_eMn-.js} +1 -7
  57. package/dist/{manifest-python-deps-fWzdEasI.mjs → manifest-python-deps-D3hP9W8D.mjs} +2 -8
  58. package/package.json +1 -1
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  let zod = require("zod");
8
8
  let node_crypto = require("node:crypto");
9
9
  let _camstack_types_node = require("@camstack/types/node");
@@ -299,6 +299,7 @@ function courtesyLabel(reason) {
299
299
  case "disabled": return "Disabled";
300
300
  case "offline": return "Offline";
301
301
  case "sleeping": return "Sleeping";
302
+ case "unreachable": return "Unreachable";
302
303
  }
303
304
  }
304
305
  /**
@@ -310,6 +311,7 @@ function courtesyBackground(reason) {
310
311
  case "disabled": return "#2b2b31";
311
312
  case "offline": return "#3a2b2b";
312
313
  case "sleeping": return "#232b3a";
314
+ case "unreachable": return "#3a2b2b";
313
315
  }
314
316
  }
315
317
  /** XML escaping for text placed inside an SVG `<text>` node. */
@@ -1355,16 +1357,18 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1355
1357
  });
1356
1358
  return hit ? hit.data : null;
1357
1359
  }
1358
- if (!force && isBatteryDevice && await this.isDeviceSleeping(deviceId)) {
1359
- log.debug("snapshot: sleeping battery cam and no force serving cache, not capturing", {
1360
+ const presence = isBatteryDevice ? await this.readBatteryPresence(deviceId) : "awake";
1361
+ if (!force && presence !== "awake") {
1362
+ log.debug("snapshot: battery cam not awake and no force — serving cache, not capturing", {
1360
1363
  tags: { deviceId },
1361
1364
  meta: {
1365
+ presence,
1362
1366
  hasCache: hit !== void 0,
1363
1367
  ageMs: hit ? now - hit.ts : null
1364
1368
  }
1365
1369
  });
1366
1370
  if (hit) return hit.data;
1367
- return await this.courtesyImage(deviceId, "sleeping", deviceName);
1371
+ return await this.courtesyImage(deviceId, presence, deviceName);
1368
1372
  }
1369
1373
  const flightKey = `${deviceId}:${effectiveStreamId ?? "auto"}`;
1370
1374
  const flight = this.captureFlight.run(flightKey, () => this.captureFresh({
@@ -1727,18 +1731,35 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1727
1731
  * cache hit returns before we get here.
1728
1732
  */
1729
1733
  async isDeviceSleeping(deviceId) {
1734
+ return await this.readBatteryPresence(deviceId) !== "awake";
1735
+ }
1736
+ /**
1737
+ * The device's three-valued battery presence (D173) — `awake`, `sleeping`,
1738
+ * or `unreachable`. Same mirror read as the sleep gate, one derivation
1739
+ * (`deriveBatteryPresence`) so this layer cannot disagree with the badge or
1740
+ * the stream error about what a camera is doing.
1741
+ *
1742
+ * A failed read answers `awake`: unknown must never become a fault badge,
1743
+ * and "assume awake" is the pre-existing, deliberately conservative failure
1744
+ * direction of the gate this replaces.
1745
+ */
1746
+ async readBatteryPresence(deviceId) {
1730
1747
  try {
1731
1748
  const handle = (await this.ctx.fetchDevice(deviceId)).state.battery;
1732
1749
  await handle.refresh();
1733
1750
  const raw = handle.value;
1734
1751
  const parsed = require_dist.BatteryStatusSchema.safeParse(raw);
1735
- return parsed.success && parsed.data.sleeping;
1752
+ if (!parsed.success) return "awake";
1753
+ return require_dist.deriveBatteryPresence({
1754
+ status: parsed.data,
1755
+ nowMs: Date.now()
1756
+ });
1736
1757
  } catch (err) {
1737
1758
  this.ctx.logger.warn("snapshot: battery mirror read failed — assuming awake", {
1738
1759
  tags: { deviceId },
1739
1760
  meta: { error: require_dist.errMsg(err) }
1740
1761
  });
1741
- return false;
1762
+ return "awake";
1742
1763
  }
1743
1764
  }
1744
1765
  /**
@@ -1,4 +1,4 @@
1
- import { Ct as DeviceType, It as nodePin, Ut as EventCategory, _t as BaseAddon, ct as snapshotCapability, ft as streamQualityLabel, gt as errMsg, i as BatteryStatusSchema, w as bareAddonId, xt as DeviceFeature } from "../../dist-DhrTd8LL.mjs";
1
+ import { Lt as nodePin, St as DeviceFeature, Wt as EventCategory, _t as errMsg, i as BatteryStatusSchema, j as deriveBatteryPresence, lt as snapshotCapability, pt as streamQualityLabel, vt as BaseAddon, w as bareAddonId, wt as DeviceType } from "../../dist-F1XDQDE1.mjs";
2
2
  import { z } from "zod";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { signExpiringUrl, verifyExpiringUrl } from "@camstack/types/node";
@@ -293,6 +293,7 @@ function courtesyLabel(reason) {
293
293
  case "disabled": return "Disabled";
294
294
  case "offline": return "Offline";
295
295
  case "sleeping": return "Sleeping";
296
+ case "unreachable": return "Unreachable";
296
297
  }
297
298
  }
298
299
  /**
@@ -304,6 +305,7 @@ function courtesyBackground(reason) {
304
305
  case "disabled": return "#2b2b31";
305
306
  case "offline": return "#3a2b2b";
306
307
  case "sleeping": return "#232b3a";
308
+ case "unreachable": return "#3a2b2b";
307
309
  }
308
310
  }
309
311
  /** XML escaping for text placed inside an SVG `<text>` node. */
@@ -1349,16 +1351,18 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1349
1351
  });
1350
1352
  return hit ? hit.data : null;
1351
1353
  }
1352
- if (!force && isBatteryDevice && await this.isDeviceSleeping(deviceId)) {
1353
- log.debug("snapshot: sleeping battery cam and no force serving cache, not capturing", {
1354
+ const presence = isBatteryDevice ? await this.readBatteryPresence(deviceId) : "awake";
1355
+ if (!force && presence !== "awake") {
1356
+ log.debug("snapshot: battery cam not awake and no force — serving cache, not capturing", {
1354
1357
  tags: { deviceId },
1355
1358
  meta: {
1359
+ presence,
1356
1360
  hasCache: hit !== void 0,
1357
1361
  ageMs: hit ? now - hit.ts : null
1358
1362
  }
1359
1363
  });
1360
1364
  if (hit) return hit.data;
1361
- return await this.courtesyImage(deviceId, "sleeping", deviceName);
1365
+ return await this.courtesyImage(deviceId, presence, deviceName);
1362
1366
  }
1363
1367
  const flightKey = `${deviceId}:${effectiveStreamId ?? "auto"}`;
1364
1368
  const flight = this.captureFlight.run(flightKey, () => this.captureFresh({
@@ -1721,18 +1725,35 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1721
1725
  * cache hit returns before we get here.
1722
1726
  */
1723
1727
  async isDeviceSleeping(deviceId) {
1728
+ return await this.readBatteryPresence(deviceId) !== "awake";
1729
+ }
1730
+ /**
1731
+ * The device's three-valued battery presence (D173) — `awake`, `sleeping`,
1732
+ * or `unreachable`. Same mirror read as the sleep gate, one derivation
1733
+ * (`deriveBatteryPresence`) so this layer cannot disagree with the badge or
1734
+ * the stream error about what a camera is doing.
1735
+ *
1736
+ * A failed read answers `awake`: unknown must never become a fault badge,
1737
+ * and "assume awake" is the pre-existing, deliberately conservative failure
1738
+ * direction of the gate this replaces.
1739
+ */
1740
+ async readBatteryPresence(deviceId) {
1724
1741
  try {
1725
1742
  const handle = (await this.ctx.fetchDevice(deviceId)).state.battery;
1726
1743
  await handle.refresh();
1727
1744
  const raw = handle.value;
1728
1745
  const parsed = BatteryStatusSchema.safeParse(raw);
1729
- return parsed.success && parsed.data.sleeping;
1746
+ if (!parsed.success) return "awake";
1747
+ return deriveBatteryPresence({
1748
+ status: parsed.data,
1749
+ nowMs: Date.now()
1750
+ });
1730
1751
  } catch (err) {
1731
1752
  this.ctx.logger.warn("snapshot: battery mirror read failed — assuming awake", {
1732
1753
  tags: { deviceId },
1733
1754
  meta: { error: errMsg(err) }
1734
1755
  });
1735
- return false;
1756
+ return "awake";
1736
1757
  }
1737
1758
  }
1738
1759
  /**
@@ -1,5 +1,15 @@
1
- /** Why a camera cannot produce a frame right now. */
2
- export type CourtesyReason = 'disabled' | 'offline' | 'sleeping';
1
+ /**
2
+ * Why a camera cannot produce a frame right now.
3
+ *
4
+ * `sleeping` and `unreachable` are deliberately two reasons and not one. A
5
+ * battery camera in low-power mode is WORKING — that tile must not read as a
6
+ * fault, which is D62's rule in the third state — while a battery camera
7
+ * nothing has been heard from for hours is a genuine fault the operator has to
8
+ * see (a flat battery, or a camera off the LAN). Painting the second as the
9
+ * first is how a dead camera stayed green for 30 hours. The two are separated
10
+ * by `deriveBatteryPresence`, never by a caller's own guess.
11
+ */
12
+ export type CourtesyReason = 'disabled' | 'offline' | 'sleeping' | 'unreachable';
3
13
  /** Default tile size when the caller asks for no particular width. */
4
14
  export declare const COURTESY_DEFAULT_WIDTH = 640;
5
15
  /** The word the frame carries. Deliberately the operator's vocabulary. */
@@ -374,6 +374,17 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
374
374
  * cache hit returns before we get here.
375
375
  */
376
376
  private isDeviceSleeping;
377
+ /**
378
+ * The device's three-valued battery presence (D173) — `awake`, `sleeping`,
379
+ * or `unreachable`. Same mirror read as the sleep gate, one derivation
380
+ * (`deriveBatteryPresence`) so this layer cannot disagree with the badge or
381
+ * the stream error about what a camera is doing.
382
+ *
383
+ * A failed read answers `awake`: unknown must never become a fault badge,
384
+ * and "assume awake" is the pre-existing, deliberately conservative failure
385
+ * direction of the gate this replaces.
386
+ */
387
+ private readBatteryPresence;
377
388
  /**
378
389
  * True when at least one of the device's brokers is actively
379
390
  * streaming (status === 'streaming'). Used by the battery-cam guard
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let node_fs_promises = require("node:fs/promises");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { _t as BaseAddon, dt as storageProviderCapability, z as filesystemBrowseCapability } from "../../dist-DhrTd8LL.mjs";
1
+ import { B as filesystemBrowseCapability, ft as storageProviderCapability, vt as BaseAddon } from "../../dist-F1XDQDE1.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let node_fs = require("node:fs");
9
9
  let node_module = require("node:module");
@@ -1,4 +1,4 @@
1
- import { A as decodeVectorBase64, Dt as asJsonObject, Rt as parseJsonUnknown, _t as BaseAddon, f as RUNTIME_DEFAULTS, gt as errMsg, ht as vectorStoreCapability, k as dataStoreProviderCapability, mt as vectorDimFromBase64, w as bareAddonId } from "../../dist-DhrTd8LL.mjs";
1
+ import { A as decodeVectorBase64, Ot as asJsonObject, _t as errMsg, f as RUNTIME_DEFAULTS, gt as vectorStoreCapability, ht as vectorDimFromBase64, k as dataStoreProviderCapability, vt as BaseAddon, w as bareAddonId, zt as parseJsonUnknown } from "../../dist-F1XDQDE1.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { statSync } from "node:fs";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let node_fs_promises = require("node:fs/promises");
9
9
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -1,4 +1,4 @@
1
- import { Lt as parseJsonObject, _t as BaseAddon, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, lt as storageCapability, st as settingsStoreCapability, ut as storageMigrationCapability } from "../../dist-DhrTd8LL.mjs";
1
+ import { Rt as parseJsonObject, ct as settingsStoreCapability, dt as storageMigrationCapability, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, ut as storageCapability, vt as BaseAddon } from "../../dist-F1XDQDE1.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import * as fs from "node:fs/promises";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  //#region src/builtins/system-config/system-config.addon.ts
8
8
  /**
9
9
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -1,4 +1,4 @@
1
- import { Pt as hydrateSchema, _t as BaseAddon, gt as errMsg } from "../../dist-DhrTd8LL.mjs";
1
+ import { Ft as hydrateSchema, _t as errMsg, vt as BaseAddon } from "../../dist-F1XDQDE1.mjs";
2
2
  //#region src/builtins/system-config/system-config.addon.ts
3
3
  /**
4
4
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-9Gfk4KOk.js");
6
+ const require_dist = require("../../dist-BMus2E5R.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { J as logDestinationCapability, _t as BaseAddon } from "../../dist-DhrTd8LL.mjs";
1
+ import { Y as logDestinationCapability, vt as BaseAddon } from "../../dist-F1XDQDE1.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  import * as path$1 from "node:path";
4
4
  import path from "node:path";