@camstack/system 1.2.98 → 1.2.100

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 (50) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  8. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  9. package/dist/builtins/console-logging/index.js +1 -1
  10. package/dist/builtins/console-logging/index.mjs +1 -1
  11. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  12. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  13. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  14. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  15. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  16. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  17. package/dist/builtins/hub-forwarder/index.js +1 -1
  18. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  19. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  20. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  21. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  22. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  23. package/dist/builtins/local-network/local-network.addon.js +1 -1
  24. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  25. package/dist/builtins/loki-logging/index.js +1 -1
  26. package/dist/builtins/loki-logging/index.mjs +1 -1
  27. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  28. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  29. package/dist/builtins/platform-probe/index.js +1 -1
  30. package/dist/builtins/platform-probe/index.mjs +1 -1
  31. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  32. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  33. package/dist/builtins/snapshot/index.js +84 -4
  34. package/dist/builtins/snapshot/index.mjs +84 -4
  35. package/dist/builtins/snapshot/snapshot.addon.d.ts +23 -0
  36. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  37. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  38. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
  39. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
  40. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  41. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  42. package/dist/builtins/system-config/system-config.addon.js +1 -1
  43. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  44. package/dist/builtins/winston-logging/index.js +1 -1
  45. package/dist/builtins/winston-logging/index.mjs +1 -1
  46. package/dist/{dist-6JUfbDpM.mjs → dist-RbFV8cX7.mjs} +52 -1
  47. package/dist/{dist-uhKRdmyc.js → dist-tMrPAfpF.js} +52 -1
  48. package/dist/index.js +1 -1
  49. package/dist/index.mjs +1 -1
  50. 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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, v as addonPagesCapability, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, v as addonPagesCapability, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, b as addonWidgetsCapability, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, b as addonWidgetsCapability, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  //#region src/builtins/alerts/prune-policy.ts
8
8
  /**
9
9
  * Ids older than `cutoffMs`, oldest first.
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, Mt as createEvent, n as AlertSchema, vt as errMsg, x as alertsCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, Mt as createEvent, n as AlertSchema, vt as errMsg, x as alertsCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  //#region src/builtins/alerts/prune-policy.ts
3
3
  /**
4
4
  * Ids older than `cutoffMs`, oldest first.
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let buffer = require("buffer");
9
9
  let node_fs_promises = require("node:fs/promises");
@@ -1,4 +1,4 @@
1
- import { C as backupCapability, Gt as EventCategory, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { C as backupCapability, Gt as EventCategory, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { randomBytes, randomUUID } from "node:crypto";
3
3
  import { Buffer as Buffer$1 } from "buffer";
4
4
  import * as fsp from "node:fs/promises";
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/console-logging/console-destination.ts
9
9
  var LEVEL_RANK = {
@@ -1,4 +1,4 @@
1
- import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/console-logging/console-destination.ts
4
4
  var LEVEL_RANK = {
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-uhKRdmyc.js");
3
+ const require_dist = require("../../dist-tMrPAfpF.js");
4
4
  let node_crypto = require("node:crypto");
5
5
  let node_fs_promises = require("node:fs/promises");
6
6
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -1,4 +1,4 @@
1
- import { D as coreBlockAddonId, O as coreBlockIdFromAddonId, c as CoreBlockSchema, k as coreBlocksCapability, l as DeclaredDevices, o as CORE_BLOCKS_ADDON_ID, s as CORE_BLOCK_ADDON_PREFIX, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { D as coreBlockAddonId, O as coreBlockIdFromAddonId, c as CoreBlockSchema, k as coreBlocksCapability, l as DeclaredDevices, o as CORE_BLOCKS_ADDON_ID, s as CORE_BLOCK_ADDON_PREFIX, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let _camstack_types_node = require("@camstack/types/node");
9
9
  //#region src/builtins/device-manager/adoption-job-engine.ts
@@ -1,4 +1,4 @@
1
- import { Ct as DeviceFeature, E as buildStreamParamsConfigSchema, F as deviceStatusCapability, Gt as EventCategory, Lt as isDeviceConfigCap, N as deviceManagerCapability, Ot as WELL_KNOWN_TAB_MAP, P as deviceStateCapability, R as enumerateItemArrayFields, Tt as DeviceType, Wt as sleep, a as CAP_NAMES_WITH_STATUS, at as runtimeStatePolicyFor, et as normalizeUnit, nt as parseStreamParamsFormPatch, p as STREAM_PROFILE_META, t as ALL_CAPABILITY_DEFINITIONS, u as DeviceStatusSchema, vt as errMsg, wt as DeviceRole, yt as BaseAddon, z as enumerateSchemaFields } from "../../dist-6JUfbDpM.mjs";
1
+ import { Ct as DeviceFeature, E as buildStreamParamsConfigSchema, F as deviceStatusCapability, Gt as EventCategory, Lt as isDeviceConfigCap, N as deviceManagerCapability, Ot as WELL_KNOWN_TAB_MAP, P as deviceStateCapability, R as enumerateItemArrayFields, Tt as DeviceType, Wt as sleep, a as CAP_NAMES_WITH_STATUS, at as runtimeStatePolicyFor, et as normalizeUnit, nt as parseStreamParamsFormPatch, p as STREAM_PROFILE_META, t as ALL_CAPABILITY_DEFINITIONS, u as DeviceStatusSchema, vt as errMsg, wt as DeviceRole, yt as BaseAddon, z as enumerateSchemaFields } from "../../dist-RbFV8cX7.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
4
4
  //#region src/builtins/device-manager/adoption-job-engine.ts
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  //#region src/builtins/doorbell/trigger-engine.ts
8
8
  /**
9
9
  * Pure trigger logic for the virtual-doorbell builtin — edge detection over
@@ -1,4 +1,4 @@
1
- import { G as isSameAddonId, Gt as EventCategory, I as doorbellCapability, Mt as createEvent, Tt as DeviceType, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { G as isSameAddonId, Gt as EventCategory, I as doorbellCapability, Mt as createEvent, Tt as DeviceType, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  //#region src/builtins/doorbell/trigger-engine.ts
3
3
  /**
4
4
  * Pure trigger logic for the virtual-doorbell builtin — edge detection over
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
9
9
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,4 +1,4 @@
1
- import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
4
4
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-uhKRdmyc.js");
3
+ const require_dist = require("../../dist-tMrPAfpF.js");
4
4
  //#region src/builtins/liveness-monitor/liveness-checks.ts
5
5
  var NO_DEVICES = "liveness:no-devices";
6
6
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, Mt as createEvent, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, Mt as createEvent, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  //#region src/builtins/liveness-monitor/liveness-checks.ts
3
3
  var NO_DEVICES = "liveness:no-devices";
4
4
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_chunk.__toESM(node_crypto);
9
9
  let crypto$1 = require("crypto");
@@ -1,5 +1,5 @@
1
1
  import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
2
- import { S as authProviderCapability, _ as UserRecordSchema, ht as userManagementCapability, m as ScopedTokenSchema, r as ApiKeyRecordSchema, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
2
+ import { S as authProviderCapability, _ as UserRecordSchema, ht as userManagementCapability, m as ScopedTokenSchema, r as ApiKeyRecordSchema, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
3
3
  import * as crypto$2 from "node:crypto";
4
4
  import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
5
5
  import nodeCrypto from "crypto";
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-uhKRdmyc.js");
3
+ const require_dist = require("../../dist-tMrPAfpF.js");
4
4
  let node_os = require("node:os");
5
5
  node_os = require_chunk.__toESM(node_os);
6
6
  //#region src/builtins/local-network/local-network.addon.ts
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, Y as localNetworkCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, Y as localNetworkCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import * as os from "node:os";
3
3
  //#region src/builtins/local-network/local-network.addon.ts
4
4
  /**
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  //#region src/builtins/loki-logging/loki-payload.ts
8
8
  /**
9
9
  * Loki rejects a label name that is not a valid Prometheus label
@@ -1,4 +1,4 @@
1
- import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  //#region src/builtins/loki-logging/loki-payload.ts
3
3
  /**
4
4
  * Loki rejects a label name that is not a valid Prometheus label
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  let node_child_process = require("node:child_process");
8
8
  let node_util = require("node:util");
9
9
  let node_os = require("node:os");
@@ -1,4 +1,4 @@
1
- import { $ as metricsProviderCapability, Gt as EventCategory, Mt as createEvent, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { $ as metricsProviderCapability, Gt as EventCategory, Mt as createEvent, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { execFile, execFileSync } from "node:child_process";
3
3
  import { promisify } from "node:util";
4
4
  import * as os from "node:os";
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  let node_child_process = require("node:child_process");
8
8
  let node_util = require("node:util");
9
9
  let node_os = require("node:os");
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
2
- import { Gt as EventCategory, L as enumerateInferenceDevices, Pt as emitReadiness, ct as scoreRuntimes, rt as platformProbeCapability, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
2
+ import { Gt as EventCategory, L as enumerateInferenceDevices, Pt as emitReadiness, ct as scoreRuntimes, rt as platformProbeCapability, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
5
5
  import * as os from "node:os";
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.js");
7
7
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
8
8
  /**
9
9
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -1,4 +1,4 @@
1
- import { Gt as EventCategory, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Gt as EventCategory, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
3
3
  /**
4
4
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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");
@@ -845,6 +845,9 @@ var DEVICE_META_MEMO_MS = 1e4;
845
845
  /** Wake-on-play's 8 s firmware wait + 20 s broker settle, with scheduling
846
846
  * slack. A lost completion event must not leave a camera "Waking" forever. */
847
847
  var SNAPSHOT_WAKING_TTL_MS = 35e3;
848
+ /** Delay before the single wake-capture retry — covers a camera whose status
849
+ * flips awake a beat before its snapshot endpoint actually answers. */
850
+ var WAKE_CAPTURE_RETRY_MS = 5e3;
848
851
  /** Default cache window for non-battery cams (seconds). Matches the Viewer's
849
852
  * 15 s currency contract (`LINK_CURRENT_MAX_AGE_MS`): a frame younger than
850
853
  * that is presented as current, so re-capturing INSIDE the window bought
@@ -901,6 +904,9 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
901
904
  stateFrames = /* @__PURE__ */ new Map();
902
905
  /** Devices inside the explicit battery wake-in-progress window. */
903
906
  wakingDevices = /* @__PURE__ */ new Map();
907
+ /** Last sleeping flag per battery device, for wake-EDGE detection (the map
908
+ * starts empty; only an observed true→false transition is a wake). */
909
+ lastKnownSleeping = /* @__PURE__ */ new Map();
904
910
  /**
905
911
  * Short-TTL memo for `lookupDeviceMeta` (see {@link DEVICE_META_MEMO_MS}).
906
912
  * The PROMISE is stored (not the resolved value), so a burst of concurrent
@@ -975,7 +981,8 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
975
981
  applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch),
976
982
  getStatus: async (input) => this.getStatus(input.deviceId),
977
983
  getSnapshotOverview: (input) => this.getSnapshotOverview(input),
978
- getSnapshotLinks: (input) => this.getSnapshotLinks(input)
984
+ getSnapshotLinks: (input) => this.getSnapshotLinks(input),
985
+ getDebugState: (input) => this.getSnapshotDebugState(input.deviceId)
979
986
  };
980
987
  this.subscribe({ category: require_dist.EventCategory.DeviceUnregistered }, (event) => {
981
988
  const deviceId = event.data.deviceId;
@@ -997,6 +1004,9 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
997
1004
  });
998
1005
  this.subscribe({ category: require_dist.EventCategory.BatteryOnStatusChanged }, (event) => {
999
1006
  this.wakingDevices.delete(event.data.deviceId);
1007
+ const prevSleeping = this.lastKnownSleeping.get(event.data.deviceId);
1008
+ this.lastKnownSleeping.set(event.data.deviceId, event.data.status.sleeping);
1009
+ if (prevSleeping === true && !event.data.status.sleeping) this.captureOnWake(event.data.deviceId);
1000
1010
  });
1001
1011
  await this.serveMediaDataPlane();
1002
1012
  await this.ensureLinkDataPlane();
@@ -1202,7 +1212,9 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1202
1212
  const refreshes = input.targets.map(async (target) => {
1203
1213
  const state = await this.snapshotStateForLink(target.deviceId);
1204
1214
  stateByDevice.set(target.deviceId, state);
1205
- if (state.reason === void 0) await this.awaitFreshEnough(target.deviceId);
1215
+ if (state.reason !== void 0) return;
1216
+ if (state.isBattery && !await this.hasStreamingBrokerForDevice(target.deviceId)) return;
1217
+ await this.awaitFreshEnough(target.deviceId);
1206
1218
  });
1207
1219
  await raceForResult(Promise.allSettled(refreshes), LINK_BATCH_WAIT_MS);
1208
1220
  const rows = input.targets.map((target) => {
@@ -1226,7 +1238,8 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1226
1238
  width: width ?? null,
1227
1239
  neverCaptured: capturedAt === null,
1228
1240
  sleeping: stateByDevice.get(deviceId)?.reason === "sleeping",
1229
- stateReason: stateByDevice.get(deviceId)?.reason ?? null
1241
+ stateReason: stateByDevice.get(deviceId)?.reason ?? null,
1242
+ battery: stateByDevice.get(deviceId)?.isBattery ?? false
1230
1243
  };
1231
1244
  });
1232
1245
  this.ctx.logger.debug("snapshot: minted links", { meta: {
@@ -1237,6 +1250,36 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1237
1250
  return rows;
1238
1251
  }
1239
1252
  /**
1253
+ * The debug readout's data — the decision chain for one device, cache-only
1254
+ * and capture-free (a debug poll must never wake a battery camera).
1255
+ */
1256
+ async getSnapshotDebugState(deviceId) {
1257
+ const meta = await this.lookupDeviceMeta(deviceId);
1258
+ const state = await this.resolveSnapshotState(deviceId, meta);
1259
+ const hit = this.cache.latest(deviceId);
1260
+ const batterySlice = await this.ctx.api.deviceState.getCapSlice.query({
1261
+ deviceId,
1262
+ capName: require_dist.batteryCapability.name
1263
+ }).catch(() => null);
1264
+ const parsed = require_dist.BatteryStatusSchema.safeParse(batterySlice);
1265
+ return {
1266
+ battery: parsed.success ? {
1267
+ sleeping: parsed.data.sleeping,
1268
+ lastUpdated: parsed.data.lastUpdated,
1269
+ ...parsed.data.lastContactAt !== void 0 ? { lastContactAt: parsed.data.lastContactAt } : {}
1270
+ } : null,
1271
+ state: {
1272
+ isBattery: state.isBattery,
1273
+ reason: state.reason ?? null
1274
+ },
1275
+ frame: {
1276
+ capturedAt: hit?.ts ?? null,
1277
+ ageMs: hit ? Date.now() - hit.ts : null
1278
+ },
1279
+ waking: this.isDeviceWaking(deviceId)
1280
+ };
1281
+ }
1282
+ /**
1240
1283
  * Join the ordinary capture path for one device and wait, bounded, for it.
1241
1284
  *
1242
1285
  * Deliberately `getSnapshot` with `force: false`: the single flight, grab
@@ -1260,6 +1303,42 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1260
1303
  }
1261
1304
  });
1262
1305
  }
1306
+ /**
1307
+ * The one fresh frame an awake battery camera gets outside an active stream:
1308
+ * captured at the WAKE edge, because the link poll deliberately never
1309
+ * recaptures an idle-awake battery camera (every capture is a camera hit
1310
+ * that would keep it out of sleep — the link-mint gate documents the
1311
+ * incident).
1312
+ *
1313
+ * `force: true` is correct here — not a violation of "never wake for a
1314
+ * snapshot": the camera is ALREADY awake (the status edge is what fired),
1315
+ * and the battery 1 h cache default would otherwise answer the wake with
1316
+ * the pre-sleep frame. The single flight coalesces a burst of edges; one
1317
+ * delayed retry covers a camera whose status flipped a beat before its
1318
+ * snapshot endpoint is actually answering (firmware boot lag).
1319
+ */
1320
+ async captureOnWake(deviceId) {
1321
+ for (let attempt = 0; attempt < 2; attempt += 1) {
1322
+ if (attempt > 0) await new Promise((r) => setTimeout(r, WAKE_CAPTURE_RETRY_MS));
1323
+ try {
1324
+ if (await this.getSnapshot({
1325
+ deviceId,
1326
+ force: true
1327
+ }) !== null) {
1328
+ this.ctx.logger.debug("snapshot: wake capture landed", { tags: { deviceId } });
1329
+ return;
1330
+ }
1331
+ } catch (err) {
1332
+ this.ctx.logger.debug("snapshot: wake capture failed", {
1333
+ tags: { deviceId },
1334
+ meta: {
1335
+ error: require_dist.errMsg(err),
1336
+ attempt
1337
+ }
1338
+ });
1339
+ }
1340
+ }
1341
+ }
1263
1342
  /** Resolve the state advertised by a minted link before deciding whether a
1264
1343
  * background capture is allowed. */
1265
1344
  async snapshotStateForLink(deviceId) {
@@ -1393,6 +1472,7 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
1393
1472
  this.variants.clear();
1394
1473
  this.stateFrames.clear();
1395
1474
  this.wakingDevices.clear();
1475
+ this.lastKnownSleeping.clear();
1396
1476
  this.deviceMetaMemo.clear();
1397
1477
  this.captureFlight.clear();
1398
1478
  this.ownerCache = null;
@@ -1,4 +1,4 @@
1
- import { Ct as DeviceFeature, Gt as EventCategory, M as deriveBatteryPresence, Rt as nodePin, T as batteryCapability, Tt as DeviceType, i as BatteryStatusSchema, mt as streamQualityLabel, ut as snapshotCapability, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { Ct as DeviceFeature, Gt as EventCategory, M as deriveBatteryPresence, Rt as nodePin, T as batteryCapability, Tt as DeviceType, i as BatteryStatusSchema, mt as streamQualityLabel, ut as snapshotCapability, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-RbFV8cX7.mjs";
2
2
  import { z } from "zod";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { signExpiringUrl, verifyExpiringUrl } from "@camstack/types/node";
@@ -839,6 +839,9 @@ var DEVICE_META_MEMO_MS = 1e4;
839
839
  /** Wake-on-play's 8 s firmware wait + 20 s broker settle, with scheduling
840
840
  * slack. A lost completion event must not leave a camera "Waking" forever. */
841
841
  var SNAPSHOT_WAKING_TTL_MS = 35e3;
842
+ /** Delay before the single wake-capture retry — covers a camera whose status
843
+ * flips awake a beat before its snapshot endpoint actually answers. */
844
+ var WAKE_CAPTURE_RETRY_MS = 5e3;
842
845
  /** Default cache window for non-battery cams (seconds). Matches the Viewer's
843
846
  * 15 s currency contract (`LINK_CURRENT_MAX_AGE_MS`): a frame younger than
844
847
  * that is presented as current, so re-capturing INSIDE the window bought
@@ -895,6 +898,9 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
895
898
  stateFrames = /* @__PURE__ */ new Map();
896
899
  /** Devices inside the explicit battery wake-in-progress window. */
897
900
  wakingDevices = /* @__PURE__ */ new Map();
901
+ /** Last sleeping flag per battery device, for wake-EDGE detection (the map
902
+ * starts empty; only an observed true→false transition is a wake). */
903
+ lastKnownSleeping = /* @__PURE__ */ new Map();
898
904
  /**
899
905
  * Short-TTL memo for `lookupDeviceMeta` (see {@link DEVICE_META_MEMO_MS}).
900
906
  * The PROMISE is stored (not the resolved value), so a burst of concurrent
@@ -969,7 +975,8 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
969
975
  applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch),
970
976
  getStatus: async (input) => this.getStatus(input.deviceId),
971
977
  getSnapshotOverview: (input) => this.getSnapshotOverview(input),
972
- getSnapshotLinks: (input) => this.getSnapshotLinks(input)
978
+ getSnapshotLinks: (input) => this.getSnapshotLinks(input),
979
+ getDebugState: (input) => this.getSnapshotDebugState(input.deviceId)
973
980
  };
974
981
  this.subscribe({ category: EventCategory.DeviceUnregistered }, (event) => {
975
982
  const deviceId = event.data.deviceId;
@@ -991,6 +998,9 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
991
998
  });
992
999
  this.subscribe({ category: EventCategory.BatteryOnStatusChanged }, (event) => {
993
1000
  this.wakingDevices.delete(event.data.deviceId);
1001
+ const prevSleeping = this.lastKnownSleeping.get(event.data.deviceId);
1002
+ this.lastKnownSleeping.set(event.data.deviceId, event.data.status.sleeping);
1003
+ if (prevSleeping === true && !event.data.status.sleeping) this.captureOnWake(event.data.deviceId);
994
1004
  });
995
1005
  await this.serveMediaDataPlane();
996
1006
  await this.ensureLinkDataPlane();
@@ -1196,7 +1206,9 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1196
1206
  const refreshes = input.targets.map(async (target) => {
1197
1207
  const state = await this.snapshotStateForLink(target.deviceId);
1198
1208
  stateByDevice.set(target.deviceId, state);
1199
- if (state.reason === void 0) await this.awaitFreshEnough(target.deviceId);
1209
+ if (state.reason !== void 0) return;
1210
+ if (state.isBattery && !await this.hasStreamingBrokerForDevice(target.deviceId)) return;
1211
+ await this.awaitFreshEnough(target.deviceId);
1200
1212
  });
1201
1213
  await raceForResult(Promise.allSettled(refreshes), LINK_BATCH_WAIT_MS);
1202
1214
  const rows = input.targets.map((target) => {
@@ -1220,7 +1232,8 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1220
1232
  width: width ?? null,
1221
1233
  neverCaptured: capturedAt === null,
1222
1234
  sleeping: stateByDevice.get(deviceId)?.reason === "sleeping",
1223
- stateReason: stateByDevice.get(deviceId)?.reason ?? null
1235
+ stateReason: stateByDevice.get(deviceId)?.reason ?? null,
1236
+ battery: stateByDevice.get(deviceId)?.isBattery ?? false
1224
1237
  };
1225
1238
  });
1226
1239
  this.ctx.logger.debug("snapshot: minted links", { meta: {
@@ -1231,6 +1244,36 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1231
1244
  return rows;
1232
1245
  }
1233
1246
  /**
1247
+ * The debug readout's data — the decision chain for one device, cache-only
1248
+ * and capture-free (a debug poll must never wake a battery camera).
1249
+ */
1250
+ async getSnapshotDebugState(deviceId) {
1251
+ const meta = await this.lookupDeviceMeta(deviceId);
1252
+ const state = await this.resolveSnapshotState(deviceId, meta);
1253
+ const hit = this.cache.latest(deviceId);
1254
+ const batterySlice = await this.ctx.api.deviceState.getCapSlice.query({
1255
+ deviceId,
1256
+ capName: batteryCapability.name
1257
+ }).catch(() => null);
1258
+ const parsed = BatteryStatusSchema.safeParse(batterySlice);
1259
+ return {
1260
+ battery: parsed.success ? {
1261
+ sleeping: parsed.data.sleeping,
1262
+ lastUpdated: parsed.data.lastUpdated,
1263
+ ...parsed.data.lastContactAt !== void 0 ? { lastContactAt: parsed.data.lastContactAt } : {}
1264
+ } : null,
1265
+ state: {
1266
+ isBattery: state.isBattery,
1267
+ reason: state.reason ?? null
1268
+ },
1269
+ frame: {
1270
+ capturedAt: hit?.ts ?? null,
1271
+ ageMs: hit ? Date.now() - hit.ts : null
1272
+ },
1273
+ waking: this.isDeviceWaking(deviceId)
1274
+ };
1275
+ }
1276
+ /**
1234
1277
  * Join the ordinary capture path for one device and wait, bounded, for it.
1235
1278
  *
1236
1279
  * Deliberately `getSnapshot` with `force: false`: the single flight, grab
@@ -1254,6 +1297,42 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1254
1297
  }
1255
1298
  });
1256
1299
  }
1300
+ /**
1301
+ * The one fresh frame an awake battery camera gets outside an active stream:
1302
+ * captured at the WAKE edge, because the link poll deliberately never
1303
+ * recaptures an idle-awake battery camera (every capture is a camera hit
1304
+ * that would keep it out of sleep — the link-mint gate documents the
1305
+ * incident).
1306
+ *
1307
+ * `force: true` is correct here — not a violation of "never wake for a
1308
+ * snapshot": the camera is ALREADY awake (the status edge is what fired),
1309
+ * and the battery 1 h cache default would otherwise answer the wake with
1310
+ * the pre-sleep frame. The single flight coalesces a burst of edges; one
1311
+ * delayed retry covers a camera whose status flipped a beat before its
1312
+ * snapshot endpoint is actually answering (firmware boot lag).
1313
+ */
1314
+ async captureOnWake(deviceId) {
1315
+ for (let attempt = 0; attempt < 2; attempt += 1) {
1316
+ if (attempt > 0) await new Promise((r) => setTimeout(r, WAKE_CAPTURE_RETRY_MS));
1317
+ try {
1318
+ if (await this.getSnapshot({
1319
+ deviceId,
1320
+ force: true
1321
+ }) !== null) {
1322
+ this.ctx.logger.debug("snapshot: wake capture landed", { tags: { deviceId } });
1323
+ return;
1324
+ }
1325
+ } catch (err) {
1326
+ this.ctx.logger.debug("snapshot: wake capture failed", {
1327
+ tags: { deviceId },
1328
+ meta: {
1329
+ error: errMsg(err),
1330
+ attempt
1331
+ }
1332
+ });
1333
+ }
1334
+ }
1335
+ }
1257
1336
  /** Resolve the state advertised by a minted link before deciding whether a
1258
1337
  * background capture is allowed. */
1259
1338
  async snapshotStateForLink(deviceId) {
@@ -1387,6 +1466,7 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
1387
1466
  this.variants.clear();
1388
1467
  this.stateFrames.clear();
1389
1468
  this.wakingDevices.clear();
1469
+ this.lastKnownSleeping.clear();
1390
1470
  this.deviceMetaMemo.clear();
1391
1471
  this.captureFlight.clear();
1392
1472
  this.ownerCache = null;
@@ -48,6 +48,9 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
48
48
  private readonly stateFrames;
49
49
  /** Devices inside the explicit battery wake-in-progress window. */
50
50
  private readonly wakingDevices;
51
+ /** Last sleeping flag per battery device, for wake-EDGE detection (the map
52
+ * starts empty; only an observed true→false transition is a wake). */
53
+ private readonly lastKnownSleeping;
51
54
  /**
52
55
  * Short-TTL memo for `lookupDeviceMeta` (see {@link DEVICE_META_MEMO_MS}).
53
56
  * The PROMISE is stored (not the resolved value), so a burst of concurrent
@@ -207,6 +210,11 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
207
210
  * forward.
208
211
  */
209
212
  private getSnapshotLinks;
213
+ /**
214
+ * The debug readout's data — the decision chain for one device, cache-only
215
+ * and capture-free (a debug poll must never wake a battery camera).
216
+ */
217
+ private getSnapshotDebugState;
210
218
  /**
211
219
  * Join the ordinary capture path for one device and wait, bounded, for it.
212
220
  *
@@ -215,6 +223,21 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
215
223
  * the Viewer's 15-second currency contract and the link-mint wait bound.
216
224
  */
217
225
  private awaitFreshEnough;
226
+ /**
227
+ * The one fresh frame an awake battery camera gets outside an active stream:
228
+ * captured at the WAKE edge, because the link poll deliberately never
229
+ * recaptures an idle-awake battery camera (every capture is a camera hit
230
+ * that would keep it out of sleep — the link-mint gate documents the
231
+ * incident).
232
+ *
233
+ * `force: true` is correct here — not a violation of "never wake for a
234
+ * snapshot": the camera is ALREADY awake (the status edge is what fired),
235
+ * and the battery 1 h cache default would otherwise answer the wake with
236
+ * the pre-sleep frame. The single flight coalesces a burst of edges; one
237
+ * delayed retry covers a camera whose status flipped a beat before its
238
+ * snapshot endpoint is actually answering (firmware boot lag).
239
+ */
240
+ private captureOnWake;
218
241
  /** Resolve the state advertised by a minted link before deciding whether a
219
242
  * background capture is allowed. */
220
243
  private snapshotStateForLink;
@@ -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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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 { V as filesystemBrowseCapability, pt as storageProviderCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { V as filesystemBrowseCapability, pt as storageProviderCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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 dataStoreProviderCapability, Bt as parseJsonUnknown, _t as vectorStoreCapability, f as RUNTIME_DEFAULTS, gt as vectorDimFromBase64, j as decodeVectorBase64, kt as asJsonObject, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { A as dataStoreProviderCapability, Bt as parseJsonUnknown, _t as vectorStoreCapability, f as RUNTIME_DEFAULTS, gt as vectorDimFromBase64, j as decodeVectorBase64, kt as asJsonObject, vt as errMsg, w as bareAddonId, yt as BaseAddon } from "../../dist-RbFV8cX7.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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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 { dt as storageCapability, ft as storageMigrationCapability, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, lt as settingsStoreCapability, yt as BaseAddon, zt as parseJsonObject } from "../../dist-6JUfbDpM.mjs";
1
+ import { dt as storageCapability, ft as storageMigrationCapability, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, lt as settingsStoreCapability, yt as BaseAddon, zt as parseJsonObject } from "../../dist-RbFV8cX7.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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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 { It as hydrateSchema, vt as errMsg, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { It as hydrateSchema, vt as errMsg, yt as BaseAddon } from "../../dist-RbFV8cX7.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-uhKRdmyc.js");
6
+ const require_dist = require("../../dist-tMrPAfpF.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 { X as logDestinationCapability, yt as BaseAddon } from "../../dist-6JUfbDpM.mjs";
1
+ import { X as logDestinationCapability, yt as BaseAddon } from "../../dist-RbFV8cX7.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";
@@ -18540,6 +18540,39 @@ var snapshotCapability = {
18540
18540
  etag: z.string().nullable()
18541
18541
  }))),
18542
18542
  /**
18543
+ * The full decision chain for ONE device, for the viewer's debug readout —
18544
+ * the answer to "why does this tile show what it shows" in a single poll:
18545
+ * the battery slice the state was derived from, the resolved state + its
18546
+ * reason, the cached frame's identity/age, whether a wake window is open,
18547
+ * and whether a fresh capture is in flight. Cache-only and capture-free:
18548
+ * a debug read must never wake a battery camera.
18549
+ */
18550
+ getDebugState: systemMethod(z.object({ deviceId: z.number() }), z.object({
18551
+ /** The battery slice as read, or null when the device has none. */
18552
+ battery: z.object({
18553
+ sleeping: z.boolean(),
18554
+ lastUpdated: z.number(),
18555
+ lastContactAt: z.number().optional()
18556
+ }).nullable(),
18557
+ /** The resolved snapshot state (what the overlay decision used). */
18558
+ state: z.object({
18559
+ isBattery: z.boolean(),
18560
+ reason: z.enum([
18561
+ "disabled",
18562
+ "sleeping",
18563
+ "unreachable",
18564
+ "waking"
18565
+ ]).nullable()
18566
+ }),
18567
+ /** The cached frame behind the next paint. */
18568
+ frame: z.object({
18569
+ capturedAt: z.number().nullable(),
18570
+ ageMs: z.number().nullable()
18571
+ }),
18572
+ /** A wake window is currently open (the Waking overlay's source). */
18573
+ waking: z.boolean()
18574
+ })),
18575
+ /**
18543
18576
  * Signed, expiring links to a CLIENT-SIZED frame — and the demand signal
18544
18577
  * that makes those frames current.
18545
18578
  *
@@ -18621,7 +18654,14 @@ targets: z.array(z.object({
18621
18654
  "sleeping",
18622
18655
  "unreachable",
18623
18656
  "waking"
18624
- ]).nullable()
18657
+ ]).nullable(),
18658
+ /** A battery camera (whatever its current state). An AWAKE battery
18659
+ * camera is deliberately NOT recaptured on the poll cadence — every
18660
+ * capture is a camera hit that would keep it out of sleep — so its
18661
+ * cached frame legitimately ages past the currency ceiling while
18662
+ * nothing is streaming. A surface must keep painting it (a fresh
18663
+ * frame is captured at each wake), not blank to "unavailable". */
18664
+ battery: z.boolean()
18625
18665
  })))
18626
18666
  },
18627
18667
  status: {
@@ -34375,6 +34415,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34375
34415
  addonId: null,
34376
34416
  access: "view"
34377
34417
  },
34418
+ "snapshot.getDebugState": {
34419
+ capName: "snapshot",
34420
+ capScope: "device",
34421
+ addonId: null,
34422
+ access: "view"
34423
+ },
34378
34424
  "snapshot.getSnapshot": {
34379
34425
  capName: "snapshot",
34380
34426
  capScope: "device",
@@ -36972,6 +37018,11 @@ Object.freeze({
36972
37018
  form: "single",
36973
37019
  optional: false
36974
37020
  }],
37021
+ "snapshot.getDebugState": [{
37022
+ name: "deviceId",
37023
+ form: "single",
37024
+ optional: false
37025
+ }],
36975
37026
  "snapshot.getSnapshot": [{
36976
37027
  name: "deviceId",
36977
37028
  form: "single",
@@ -18540,6 +18540,39 @@ var snapshotCapability = {
18540
18540
  etag: zod.z.string().nullable()
18541
18541
  }))),
18542
18542
  /**
18543
+ * The full decision chain for ONE device, for the viewer's debug readout —
18544
+ * the answer to "why does this tile show what it shows" in a single poll:
18545
+ * the battery slice the state was derived from, the resolved state + its
18546
+ * reason, the cached frame's identity/age, whether a wake window is open,
18547
+ * and whether a fresh capture is in flight. Cache-only and capture-free:
18548
+ * a debug read must never wake a battery camera.
18549
+ */
18550
+ getDebugState: systemMethod(zod.z.object({ deviceId: zod.z.number() }), zod.z.object({
18551
+ /** The battery slice as read, or null when the device has none. */
18552
+ battery: zod.z.object({
18553
+ sleeping: zod.z.boolean(),
18554
+ lastUpdated: zod.z.number(),
18555
+ lastContactAt: zod.z.number().optional()
18556
+ }).nullable(),
18557
+ /** The resolved snapshot state (what the overlay decision used). */
18558
+ state: zod.z.object({
18559
+ isBattery: zod.z.boolean(),
18560
+ reason: zod.z.enum([
18561
+ "disabled",
18562
+ "sleeping",
18563
+ "unreachable",
18564
+ "waking"
18565
+ ]).nullable()
18566
+ }),
18567
+ /** The cached frame behind the next paint. */
18568
+ frame: zod.z.object({
18569
+ capturedAt: zod.z.number().nullable(),
18570
+ ageMs: zod.z.number().nullable()
18571
+ }),
18572
+ /** A wake window is currently open (the Waking overlay's source). */
18573
+ waking: zod.z.boolean()
18574
+ })),
18575
+ /**
18543
18576
  * Signed, expiring links to a CLIENT-SIZED frame — and the demand signal
18544
18577
  * that makes those frames current.
18545
18578
  *
@@ -18621,7 +18654,14 @@ targets: zod.z.array(zod.z.object({
18621
18654
  "sleeping",
18622
18655
  "unreachable",
18623
18656
  "waking"
18624
- ]).nullable()
18657
+ ]).nullable(),
18658
+ /** A battery camera (whatever its current state). An AWAKE battery
18659
+ * camera is deliberately NOT recaptured on the poll cadence — every
18660
+ * capture is a camera hit that would keep it out of sleep — so its
18661
+ * cached frame legitimately ages past the currency ceiling while
18662
+ * nothing is streaming. A surface must keep painting it (a fresh
18663
+ * frame is captured at each wake), not blank to "unavailable". */
18664
+ battery: zod.z.boolean()
18625
18665
  })))
18626
18666
  },
18627
18667
  status: {
@@ -34375,6 +34415,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34375
34415
  addonId: null,
34376
34416
  access: "view"
34377
34417
  },
34418
+ "snapshot.getDebugState": {
34419
+ capName: "snapshot",
34420
+ capScope: "device",
34421
+ addonId: null,
34422
+ access: "view"
34423
+ },
34378
34424
  "snapshot.getSnapshot": {
34379
34425
  capName: "snapshot",
34380
34426
  capScope: "device",
@@ -36972,6 +37018,11 @@ Object.freeze({
36972
37018
  form: "single",
36973
37019
  optional: false
36974
37020
  }],
37021
+ "snapshot.getDebugState": [{
37022
+ name: "deviceId",
37023
+ form: "single",
37024
+ optional: false
37025
+ }],
36975
37026
  "snapshot.getSnapshot": [{
36976
37027
  name: "deviceId",
36977
37028
  form: "single",
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-uhKRdmyc.js");
3
+ const require_dist = require("./dist-tMrPAfpF.js");
4
4
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
5
5
  require("./builtins/alerts/index.js");
6
6
  const require_formatter = require("./formatter-DqAKDlvN.js");
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { At as asNumber, B as extractNestedAddonId, Bt as parseJsonUnknown$1, Dt as ReadinessTimeoutError, Et as ReadinessRegistry, Ft as expandCapMethods, Gt as EventCategory$1, H as isArrayOutputSchema, Ht as resolveCapMount, J as lifecycleJobSchema, K as isVoidInput, Mt as createEvent, Nt as emitDownForOwnedCaps, Q as looseSchema, St as DEVICE_STATUS_METHOD, U as isCollectionArrayMethod, Ut as scopeKey, Vt as readinessKey, W as isObjectInput, Z as logLevelAtMost, bt as DATAPLANE_SECRET_HEADER$1, d as METHOD_ACCESS_MAP, f as RUNTIME_DEFAULTS, it as procedureAuthKey, jt as asString$1, kt as asJsonObject$1, ot as scopesAllowAddon, q as kebabToCamel, st as scopesAllowDeviceCap, t as ALL_CAPABILITY_DEFINITIONS, tt as objectInputDeclaresAddonId, vt as errMsg$1, xt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, y as addonSettingsCapability, zt as parseJsonObject } from "./dist-6JUfbDpM.mjs";
2
+ import { At as asNumber, B as extractNestedAddonId, Bt as parseJsonUnknown$1, Dt as ReadinessTimeoutError, Et as ReadinessRegistry, Ft as expandCapMethods, Gt as EventCategory$1, H as isArrayOutputSchema, Ht as resolveCapMount, J as lifecycleJobSchema, K as isVoidInput, Mt as createEvent, Nt as emitDownForOwnedCaps, Q as looseSchema, St as DEVICE_STATUS_METHOD, U as isCollectionArrayMethod, Ut as scopeKey, Vt as readinessKey, W as isObjectInput, Z as logLevelAtMost, bt as DATAPLANE_SECRET_HEADER$1, d as METHOD_ACCESS_MAP, f as RUNTIME_DEFAULTS, it as procedureAuthKey, jt as asString$1, kt as asJsonObject$1, ot as scopesAllowAddon, q as kebabToCamel, st as scopesAllowDeviceCap, t as ALL_CAPABILITY_DEFINITIONS, tt as objectInputDeclaresAddonId, vt as errMsg$1, xt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, y as addonSettingsCapability, zt as parseJsonObject } from "./dist-RbFV8cX7.mjs";
3
3
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
4
4
  import "./builtins/alerts/index.mjs";
5
5
  import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.98",
3
+ "version": "1.2.100",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",