@camstack/system 1.2.172 → 1.2.174

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/core-blocks.addon.js +1 -1
  14. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.js +200 -2
  16. package/dist/builtins/device-manager/device-manager.addon.mjs +200 -2
  17. package/dist/builtins/device-manager/device-meta-actions.d.ts +13 -0
  18. package/dist/builtins/device-manager/device-row-store.d.ts +41 -0
  19. package/dist/builtins/device-manager/migrate-device.d.ts +44 -0
  20. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  21. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  22. package/dist/builtins/hub-forwarder/index.js +1 -1
  23. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  24. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  25. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  26. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  27. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  28. package/dist/builtins/local-network/local-network.addon.js +1 -1
  29. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  30. package/dist/builtins/loki-logging/index.js +1 -1
  31. package/dist/builtins/loki-logging/index.mjs +1 -1
  32. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  33. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  34. package/dist/builtins/platform-probe/index.js +1 -1
  35. package/dist/builtins/platform-probe/index.mjs +1 -1
  36. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  37. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  38. package/dist/builtins/snapshot/index.js +1 -1
  39. package/dist/builtins/snapshot/index.mjs +1 -1
  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 +0 -0
  43. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  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-1DEQFmTq.mjs → dist-B25PDvaS.mjs} +85 -2
  51. package/dist/{dist-DsoVfJSR.js → dist-BzPNEPHo.js} +90 -1
  52. package/dist/index.js +2 -2
  53. package/dist/index.mjs +2 -2
  54. package/dist/{manifest-system-deps-ir_XTNpe.js → manifest-system-deps-B0mzJPmb.js} +1 -1
  55. package/dist/{manifest-system-deps-Da6sme9C.mjs → manifest-system-deps-Pw8iaY5X.mjs} +1 -1
  56. package/dist/{retired-settings-keys-DTE5k4lU.js → retired-settings-keys-DZmeJ8ja.js} +1 -1
  57. package/dist/{retired-settings-keys-ChS1Q2Kv.mjs → retired-settings-keys-tWdiQpwa.mjs} +1 -1
  58. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ import { CameraSwitchId } from '@camstack/types';
2
+ /** What actually happened to one switch on one device. */
3
+ export type SwitchOutcome = 'off' | 'on' | 'not-offered' | 'unreachable';
4
+ export interface SwitchReport {
5
+ readonly deviceId: number;
6
+ readonly switchId: CameraSwitchId;
7
+ readonly outcome: SwitchOutcome;
8
+ /** The refusal, verbatim, when the outcome is not the requested one. */
9
+ readonly detail?: string;
10
+ }
11
+ export interface MigrateDeviceResult {
12
+ readonly sourceId: number;
13
+ readonly targetId: number;
14
+ /** Every switch write attempted, in order, on both devices. */
15
+ readonly switches: readonly SwitchReport[];
16
+ /**
17
+ * Switches that could NOT be turned off on the source. Empty is the only
18
+ * value that means "the old camera is fully quiet"; a caller that renders
19
+ * only a success flag is not entitled to one.
20
+ */
21
+ readonly sourceStillLive: readonly CameraSwitchId[];
22
+ readonly swapped: boolean;
23
+ }
24
+ export interface MigrateDeviceDeps {
25
+ /** `pipelineOrchestrator.setCameraSwitch`, through `ctx.api`. */
26
+ readonly setSwitch: (deviceId: number, switchId: CameraSwitchId, enabled: boolean) => Promise<void>;
27
+ /** `DeviceRowStore.swapIds`, already under the meta write lock. */
28
+ readonly swapIds: (a: number, b: number) => Promise<void>;
29
+ /** Respawn the runners that hold either number in memory. Disabling stops
30
+ * data PRODUCTION; it does not flush a cache that maps id → addon. */
31
+ readonly respawnRunners: (deviceIds: readonly number[]) => Promise<void>;
32
+ readonly log: (message: string, meta: Record<string, unknown>) => void;
33
+ }
34
+ /**
35
+ * Put both cameras to sleep, exchange their identities, wake the target.
36
+ *
37
+ * Throws only if the swap itself fails — a switch that could not be written is
38
+ * reported, not raised, because refusing to migrate a camera whose old hardware
39
+ * is unreachable would refuse the exact case this exists for.
40
+ */
41
+ export declare function migrateDevice(deps: MigrateDeviceDeps, input: {
42
+ readonly sourceId: number;
43
+ readonly targetId: number;
44
+ }): Promise<MigrateDeviceResult>;
@@ -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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { J as evaluateSensorEdge, Kt as createEvent, Mt as errMsg, Nt as BaseAddon, W as doorbellCapability, _ as SOURCE_DEVICE_TYPES, an as EventCategory, g as SOURCE_CAPS, j as bareAddonId, nt as isSourceCap, tt as isSameAddonId, zt as DeviceType } from "../../dist-1DEQFmTq.mjs";
1
+ import { Bt as DeviceType, G as doorbellCapability, M as bareAddonId, Nt as errMsg, Pt as BaseAddon, Y as evaluateSensorEdge, _ as SOURCE_CAPS, nt as isSameAddonId, on as EventCategory, qt as createEvent, rt as isSourceCap, v as SOURCE_DEVICE_TYPES } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Nt as BaseAddon, st as logDestinationCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Pt as BaseAddon, ct as logDestinationCapability } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
3
+ const require_dist = require("../../dist-BzPNEPHo.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 { Kt as createEvent, Mt as errMsg, Nt as BaseAddon, an as EventCategory } from "../../dist-1DEQFmTq.mjs";
1
+ import { Nt as errMsg, Pt as BaseAddon, on as EventCategory, qt as createEvent } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Nt as BaseAddon, b as ScopedTokenSchema, k as authProviderCapability, kt as userManagementCapability, r as ApiKeyRecordSchema, w as UserRecordSchema } from "../../dist-1DEQFmTq.mjs";
2
+ import { A as authProviderCapability, At as userManagementCapability, Pt as BaseAddon, T as UserRecordSchema, r as ApiKeyRecordSchema, x as ScopedTokenSchema } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
3
+ const require_dist = require("../../dist-BzPNEPHo.js");
4
4
  const require_tls = require("../../tls-BxQlomxd.js");
5
5
  let node_fs_promises = require("node:fs/promises");
6
6
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Nt as BaseAddon, an as EventCategory, ot as localNetworkCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Pt as BaseAddon, on as EventCategory, st as localNetworkCapability } from "../../dist-B25PDvaS.mjs";
2
2
  import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-DOTmtLCW.mjs";
3
3
  import { mkdir, writeFile } from "node:fs/promises";
4
4
  import { join } 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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Nt as BaseAddon, st as logDestinationCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Pt as BaseAddon, ct as logDestinationCapability } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.js");
7
7
  let node_fs_promises = require("node:fs/promises");
8
8
  let node_child_process = require("node:child_process");
9
9
  let node_util = require("node:util");
@@ -1,4 +1,4 @@
1
- import { Kt as createEvent, Mt as errMsg, Nt as BaseAddon, Z as foldSnapshotByFunction, _t as resolveBucketMs, an as EventCategory, gt as reducePoints, ut as metricsProviderCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Nt as errMsg, Pt as BaseAddon, Q as foldSnapshotByFunction, _t as reducePoints, dt as metricsProviderCapability, on as EventCategory, qt as createEvent, vt as resolveBucketMs } from "../../dist-B25PDvaS.mjs";
2
2
  import { readFile, readdir } from "node:fs/promises";
3
3
  import { execFile, execFileSync } from "node:child_process";
4
4
  import { promisify } from "node:util";
@@ -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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.js");
7
7
  let node_child_process = require("node:child_process");
8
8
  let node_util = require("node:util");
9
9
  let node_fs = require("node:fs");
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
2
- import { G as enumerateInferenceDevices, Jt as emitReadiness, Mt as errMsg, Nt as BaseAddon, St as scoreRuntimes, an as EventCategory, mt as platformProbeCapability } from "../../dist-1DEQFmTq.mjs";
2
+ import { Ct as scoreRuntimes, K as enumerateInferenceDevices, Nt as errMsg, Pt as BaseAddon, Yt as emitReadiness, ht as platformProbeCapability, on as EventCategory } from "../../dist-B25PDvaS.mjs";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
5
5
  import * as fs from "node:fs";
@@ -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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Nt as BaseAddon, an as EventCategory } from "../../dist-1DEQFmTq.mjs";
1
+ import { Pt as BaseAddon, on as EventCategory } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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");
@@ -1,4 +1,4 @@
1
- import { B as deriveBatteryPresence, Lt as DeviceFeature, M as batteryCapability, Mt as errMsg, Nt as BaseAddon, Ot as streamQualityLabel, Qt as nodePin, an as EventCategory, i as BatteryStatusSchema, j as bareAddonId, wt as snapshotCapability, zt as DeviceType } from "../../dist-1DEQFmTq.mjs";
1
+ import { $t as nodePin, Bt as DeviceType, M as bareAddonId, N as batteryCapability, Nt as errMsg, Pt as BaseAddon, Rt as DeviceFeature, Tt as snapshotCapability, V as deriveBatteryPresence, i as BatteryStatusSchema, kt as streamQualityLabel, on as EventCategory } from "../../dist-B25PDvaS.mjs";
2
2
  import { z } from "zod";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { signExpiringUrl, verifyExpiringUrl } from "@camstack/types/node";
@@ -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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Dt as storageProviderCapability, Nt as BaseAddon, X as filesystemBrowseCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Ot as storageProviderCapability, Pt as BaseAddon, Z as filesystemBrowseCapability } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.js");
7
7
  const require_hub_cap_forward = require("../../hub-cap-forward-DmHNjbB0.js");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { $t as parseJsonObject, C as StorageMigrationJobSchema, Ct as settingsStoreCapability, Et as storageMigrationCapability, Nt as BaseAddon, P as collectSecretConfigKeys, S as StorageLocationTypeSchema, Tt as storageCapability, m as REDACTED_SECRET, x as StorageCleanupJobSchema } from "../../dist-1DEQFmTq.mjs";
1
+ import { C as StorageLocationTypeSchema, Dt as storageMigrationCapability, Et as storageCapability, F as collectSecretConfigKeys, Pt as BaseAddon, S as StorageCleanupJobSchema, en as parseJsonObject, h as REDACTED_SECRET, w as StorageMigrationJobSchema, wt as settingsStoreCapability } from "../../dist-B25PDvaS.mjs";
2
2
  import { t as HUB_CAP_FWD_ACTION } from "../../hub-cap-forward-BdT320dq.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
@@ -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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Mt as errMsg, Nt as BaseAddon, Xt as hydrateSchema } from "../../dist-1DEQFmTq.mjs";
1
+ import { Nt as errMsg, Pt as BaseAddon, Zt as hydrateSchema } from "../../dist-B25PDvaS.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-DsoVfJSR.js");
6
+ const require_dist = require("../../dist-BzPNEPHo.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 { Nt as BaseAddon, st as logDestinationCapability } from "../../dist-1DEQFmTq.mjs";
1
+ import { Pt as BaseAddon, ct as logDestinationCapability } from "../../dist-B25PDvaS.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";
@@ -3619,6 +3619,32 @@ var CameraSwitchIdSchema = z.enum([
3619
3619
  "notifications"
3620
3620
  ]);
3621
3621
  /**
3622
+ * Stable render order — broadest blast radius first, and a source before the
3623
+ * thing that consumes it. `device-audio` sits ABOVE `audio-analysis` because
3624
+ * turning the microphone off leaves the analyzer with nothing to analyse; the
3625
+ * reverse is not true.
3626
+ *
3627
+ * `privacy-mask` sits directly ABOVE `device-audio` because they are literal
3628
+ * siblings — one cap, one device plane, video then audio — and NOT above
3629
+ * `object-detection` despite feeding it: a mask blanks REGIONS, so its blast
3630
+ * radius is partial, and the "broadest first" rule does not rank a partial
3631
+ * control above a whole-function one.
3632
+ *
3633
+ * `broker-audio` sits directly BELOW `device-audio` by the same source-first
3634
+ * rule: the camera's microphone feeds the broker, so silencing the camera
3635
+ * leaves the broker's mute with nothing to suppress; the reverse is not true.
3636
+ */
3637
+ var CAMERA_SWITCH_ORDER = [
3638
+ "stream-broker",
3639
+ "object-detection",
3640
+ "privacy-mask",
3641
+ "device-audio",
3642
+ "broker-audio",
3643
+ "audio-analysis",
3644
+ "recording",
3645
+ "notifications"
3646
+ ];
3647
+ /**
3622
3648
  * WHERE the switch's state actually lives. A discriminated union rather than a
3623
3649
  * string so both the writer (the orchestrator's `setCameraSwitch`) and any
3624
3650
  * reader can exhaustively narrow — and so "the group added a parallel map" is
@@ -3892,7 +3918,8 @@ var OpsLogReasonSchema = z.enum([
3892
3918
  "quota",
3893
3919
  "manual",
3894
3920
  "operator",
3895
- "maintenance"
3921
+ "maintenance",
3922
+ "orphaned-device"
3896
3923
  ]);
3897
3924
  /** One audit row, shared verbatim by both domains. */
3898
3925
  var OpsLogEntrySchema = z.object({
@@ -10605,6 +10632,29 @@ var DevicePersistConfigPayloadSchema = z.object({
10605
10632
  deviceId: z.number(),
10606
10633
  data: z.record(z.string(), z.unknown())
10607
10634
  });
10635
+ /** What a migration actually did, per switch. `unreachable` is a first-class
10636
+ * answer: a camera that could not be asked is not a camera that was silenced. */
10637
+ var MigrateSwitchOutcomeSchema = z.enum([
10638
+ "off",
10639
+ "on",
10640
+ "not-offered",
10641
+ "unreachable"
10642
+ ]);
10643
+ var MigrateSwitchReportSchema = z.object({
10644
+ deviceId: z.number(),
10645
+ switchId: CameraSwitchIdSchema,
10646
+ outcome: MigrateSwitchOutcomeSchema,
10647
+ detail: z.string().optional()
10648
+ });
10649
+ var MigrateDeviceResultSchema = z.object({
10650
+ sourceId: z.number(),
10651
+ targetId: z.number(),
10652
+ switches: z.array(MigrateSwitchReportSchema).readonly(),
10653
+ /** Switches that could NOT be turned off on the source. Empty is the only
10654
+ * value meaning the replaced hardware is quiet. */
10655
+ sourceStillLive: z.array(CameraSwitchIdSchema).readonly(),
10656
+ swapped: z.boolean()
10657
+ });
10608
10658
  var deviceManagerCapability = {
10609
10659
  name: "device-manager",
10610
10660
  scope: "system",
@@ -10619,6 +10669,33 @@ var deviceManagerCapability = {
10619
10669
  addonId: z.string(),
10620
10670
  stableId: z.string()
10621
10671
  }), z.object({ id: z.number() }), { kind: "mutation" }),
10672
+ /**
10673
+ * Replace a camera: the new hardware inherits the number the system knows.
10674
+ *
10675
+ * Everything general about a camera is keyed on the numeric id and nothing
10676
+ * else — the recording path on disk, the hour ledger, the media store, zone
10677
+ * ownership, and all four ecosystem exports. So a replacement moves the
10678
+ * NUMBER rather than the work, and the operator keeps their footage, their
10679
+ * rules and their integrations.
10680
+ *
10681
+ * Both cameras are switched off first, then the identities are exchanged
10682
+ * (children follow their parent), then the target — now answering on the
10683
+ * inherited number — is switched back on.
10684
+ *
10685
+ * **A switch that could not be written is REPORTED, not swallowed.** The
10686
+ * source is characteristically broken, and two of the eight switches write
10687
+ * the camera itself, so on a dead one they cannot be written at all.
10688
+ * `sourceStillLive` names what stayed live; empty is the only value that
10689
+ * means the old hardware is quiet. The migration proceeds either way —
10690
+ * refusing would refuse the case this exists for.
10691
+ */
10692
+ migrateDevice: method(z.object({
10693
+ sourceId: z.number(),
10694
+ targetId: z.number()
10695
+ }), MigrateDeviceResultSchema, {
10696
+ kind: "mutation",
10697
+ auth: "admin"
10698
+ }),
10622
10699
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
10623
10700
  registerDevice: method(DeviceRegisterPayloadSchema, z.void(), { kind: "mutation" }),
10624
10701
  /** Remove a device from the DB + in-memory registry. Called by DeviceManagerApi.remove(). */
@@ -35679,6 +35756,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
35679
35756
  addonId: null,
35680
35757
  access: "view"
35681
35758
  },
35759
+ "deviceManager.migrateDevice": {
35760
+ capName: "device-manager",
35761
+ capScope: "system",
35762
+ addonId: null,
35763
+ access: "create"
35764
+ },
35682
35765
  "deviceManager.persistConfig": {
35683
35766
  capName: "device-manager",
35684
35767
  capScope: "system",
@@ -42964,4 +43047,4 @@ function enumerateInferenceDevices(hw) {
42964
43047
  return out;
42965
43048
  }
42966
43049
  //#endregion
42967
- export { isCollectionArrayMethod as $, parseJsonObject as $t, backupCapability as A, vectorDimFromBase64 as At, deriveBatteryPresence as B, ReadinessRegistry as Bt, StorageMigrationJobSchema as C, settingsStoreCapability as Ct, addonWidgetsCapability as D, storageProviderCapability as Dt, addonSettingsCapability as E, storageMigrationCapability as Et, coreBlockAddonId as F, DEVICE_SETTINGS_CONTRIBUTION_METHODS as Ft, enumerateInferenceDevices as G, asString as Gt, deviceStateCapability as H, WELL_KNOWN_TAB_MAP as Ht, coreBlockIdFromAddonId as I, DEVICE_STATUS_METHOD as It, evaluateSensorEdge as J, emitReadiness as Jt, enumerateItemArrayFields as K, createEvent as Kt, coreBlocksCapability as L, DeviceFeature as Lt, batteryCapability as M, errMsg as Mt, buildStreamParamsConfigSchema as N, BaseAddon as Nt, alertsCapability as O, streamQualityLabel as Ot, collectSecretConfigKeys as P, DATAPLANE_SECRET_HEADER as Pt, isArrayOutputSchema as Q, nodePin as Qt, dataStoreProviderCapability as R, DeviceRole as Rt, StorageLocationTypeSchema as S, scoreRuntimes as St, addonPagesCapability as T, storageCapability as Tt, deviceStatusCapability as U, asJsonObject as Ut, deviceManagerCapability as V, ReadinessTimeoutError as Vt, doorbellCapability as W, asNumber as Wt, filesystemBrowseCapability as X, hydrateSchema as Xt, extractNestedAddonId as Y, expandCapMethods as Yt, foldSnapshotByFunction as Z, isDeviceConfigCap as Zt, SOURCE_DEVICE_TYPES as _, resolveBucketMs as _t, CAP_NAMES_WITH_STATUS as a, EventCategory as an, lifecycleJobSchema as at, ScopedTokenSchema as b, scopesAllowAddon as bt, CoreBlockSchema as c, logLevelAtMost as ct, DeviceStatusSchema as d, normalizeUnit as dt, parseJsonUnknown as en, isObjectInput as et, LOG_LEVEL_RANK as f, objectInputDeclaresAddonId as ft, SOURCE_CAPS as g, reducePoints as gt, RUNTIME_DEFAULTS as h, procedureAuthKey as ht, BatteryStatusSchema as i, sleep as in, kebabToCamel as it, bareAddonId as j, vectorStoreCapability as jt, authProviderCapability as k, userManagementCapability as kt, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as l, looseSchema as lt, REDACTED_SECRET as m, platformProbeCapability as mt, AlertSchema as n, resolveCapMount as nn, isSourceCap as nt, CORE_BLOCKS_ADDON_ID as o, localNetworkCapability as ot, METHOD_ACCESS_MAP as p, parseStreamParamsFormPatch as pt, enumerateSchemaFields as q, emitDownForOwnedCaps as qt, ApiKeyRecordSchema as r, scopeKey as rn, isVoidInput as rt, CORE_BLOCK_ADDON_PREFIX as s, logDestinationCapability as st, ALL_CAPABILITY_DEFINITIONS as t, readinessKey as tn, isSameAddonId as tt, DeclaredDevices as u, metricsProviderCapability as ut, STORAGE_ACCESS_FALLBACK as v, resolveMethodAuth as vt, UserRecordSchema as w, snapshotCapability as wt, StorageCleanupJobSchema as x, scopesAllowDeviceCap as xt, STREAM_PROFILE_META as y, runtimeStatePolicyFor as yt, decodeVectorBase64 as z, DeviceType as zt };
43050
+ export { isArrayOutputSchema as $, nodePin as $t, authProviderCapability as A, userManagementCapability as At, decodeVectorBase64 as B, DeviceType as Bt, StorageLocationTypeSchema as C, scoreRuntimes as Ct, addonSettingsCapability as D, storageMigrationCapability as Dt, addonPagesCapability as E, storageCapability as Et, collectSecretConfigKeys as F, DATAPLANE_SECRET_HEADER as Ft, doorbellCapability as G, asNumber as Gt, deviceManagerCapability as H, ReadinessTimeoutError as Ht, coreBlockAddonId as I, DEVICE_SETTINGS_CONTRIBUTION_METHODS as It, enumerateSchemaFields as J, emitDownForOwnedCaps as Jt, enumerateInferenceDevices as K, asString as Kt, coreBlockIdFromAddonId as L, DEVICE_STATUS_METHOD as Lt, bareAddonId as M, vectorStoreCapability as Mt, batteryCapability as N, errMsg as Nt, addonWidgetsCapability as O, storageProviderCapability as Ot, buildStreamParamsConfigSchema as P, BaseAddon as Pt, foldSnapshotByFunction as Q, isDeviceConfigCap as Qt, coreBlocksCapability as R, DeviceFeature as Rt, StorageCleanupJobSchema as S, scopesAllowDeviceCap as St, UserRecordSchema as T, snapshotCapability as Tt, deviceStateCapability as U, WELL_KNOWN_TAB_MAP as Ut, deriveBatteryPresence as V, ReadinessRegistry as Vt, deviceStatusCapability as W, asJsonObject as Wt, extractNestedAddonId as X, expandCapMethods as Xt, evaluateSensorEdge as Y, emitReadiness as Yt, filesystemBrowseCapability as Z, hydrateSchema as Zt, SOURCE_CAPS as _, reducePoints as _t, CAMERA_SWITCH_ORDER as a, sleep as an, kebabToCamel as at, STREAM_PROFILE_META as b, runtimeStatePolicyFor as bt, CORE_BLOCK_ADDON_PREFIX as c, logDestinationCapability as ct, DeclaredDevices as d, metricsProviderCapability as dt, parseJsonObject as en, isCollectionArrayMethod as et, DeviceStatusSchema as f, normalizeUnit as ft, RUNTIME_DEFAULTS as g, procedureAuthKey as gt, REDACTED_SECRET as h, platformProbeCapability as ht, BatteryStatusSchema as i, scopeKey as in, isVoidInput as it, backupCapability as j, vectorDimFromBase64 as jt, alertsCapability as k, streamQualityLabel as kt, CoreBlockSchema as l, logLevelAtMost as lt, METHOD_ACCESS_MAP as m, parseStreamParamsFormPatch as mt, AlertSchema as n, readinessKey as nn, isSameAddonId as nt, CAP_NAMES_WITH_STATUS as o, EventCategory as on, lifecycleJobSchema as ot, LOG_LEVEL_RANK as p, objectInputDeclaresAddonId as pt, enumerateItemArrayFields as q, createEvent as qt, ApiKeyRecordSchema as r, resolveCapMount as rn, isSourceCap as rt, CORE_BLOCKS_ADDON_ID as s, localNetworkCapability as st, ALL_CAPABILITY_DEFINITIONS as t, parseJsonUnknown as tn, isObjectInput as tt, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as u, looseSchema as ut, SOURCE_DEVICE_TYPES as v, resolveBucketMs as vt, StorageMigrationJobSchema as w, settingsStoreCapability as wt, ScopedTokenSchema as x, scopesAllowAddon as xt, STORAGE_ACCESS_FALLBACK as y, resolveMethodAuth as yt, dataStoreProviderCapability as z, DeviceRole as zt };
@@ -3619,6 +3619,32 @@ var CameraSwitchIdSchema = zod.z.enum([
3619
3619
  "notifications"
3620
3620
  ]);
3621
3621
  /**
3622
+ * Stable render order — broadest blast radius first, and a source before the
3623
+ * thing that consumes it. `device-audio` sits ABOVE `audio-analysis` because
3624
+ * turning the microphone off leaves the analyzer with nothing to analyse; the
3625
+ * reverse is not true.
3626
+ *
3627
+ * `privacy-mask` sits directly ABOVE `device-audio` because they are literal
3628
+ * siblings — one cap, one device plane, video then audio — and NOT above
3629
+ * `object-detection` despite feeding it: a mask blanks REGIONS, so its blast
3630
+ * radius is partial, and the "broadest first" rule does not rank a partial
3631
+ * control above a whole-function one.
3632
+ *
3633
+ * `broker-audio` sits directly BELOW `device-audio` by the same source-first
3634
+ * rule: the camera's microphone feeds the broker, so silencing the camera
3635
+ * leaves the broker's mute with nothing to suppress; the reverse is not true.
3636
+ */
3637
+ var CAMERA_SWITCH_ORDER = [
3638
+ "stream-broker",
3639
+ "object-detection",
3640
+ "privacy-mask",
3641
+ "device-audio",
3642
+ "broker-audio",
3643
+ "audio-analysis",
3644
+ "recording",
3645
+ "notifications"
3646
+ ];
3647
+ /**
3622
3648
  * WHERE the switch's state actually lives. A discriminated union rather than a
3623
3649
  * string so both the writer (the orchestrator's `setCameraSwitch`) and any
3624
3650
  * reader can exhaustively narrow — and so "the group added a parallel map" is
@@ -3892,7 +3918,8 @@ var OpsLogReasonSchema = zod.z.enum([
3892
3918
  "quota",
3893
3919
  "manual",
3894
3920
  "operator",
3895
- "maintenance"
3921
+ "maintenance",
3922
+ "orphaned-device"
3896
3923
  ]);
3897
3924
  /** One audit row, shared verbatim by both domains. */
3898
3925
  var OpsLogEntrySchema = zod.z.object({
@@ -10605,6 +10632,29 @@ var DevicePersistConfigPayloadSchema = zod.z.object({
10605
10632
  deviceId: zod.z.number(),
10606
10633
  data: zod.z.record(zod.z.string(), zod.z.unknown())
10607
10634
  });
10635
+ /** What a migration actually did, per switch. `unreachable` is a first-class
10636
+ * answer: a camera that could not be asked is not a camera that was silenced. */
10637
+ var MigrateSwitchOutcomeSchema = zod.z.enum([
10638
+ "off",
10639
+ "on",
10640
+ "not-offered",
10641
+ "unreachable"
10642
+ ]);
10643
+ var MigrateSwitchReportSchema = zod.z.object({
10644
+ deviceId: zod.z.number(),
10645
+ switchId: CameraSwitchIdSchema,
10646
+ outcome: MigrateSwitchOutcomeSchema,
10647
+ detail: zod.z.string().optional()
10648
+ });
10649
+ var MigrateDeviceResultSchema = zod.z.object({
10650
+ sourceId: zod.z.number(),
10651
+ targetId: zod.z.number(),
10652
+ switches: zod.z.array(MigrateSwitchReportSchema).readonly(),
10653
+ /** Switches that could NOT be turned off on the source. Empty is the only
10654
+ * value meaning the replaced hardware is quiet. */
10655
+ sourceStillLive: zod.z.array(CameraSwitchIdSchema).readonly(),
10656
+ swapped: zod.z.boolean()
10657
+ });
10608
10658
  var deviceManagerCapability = {
10609
10659
  name: "device-manager",
10610
10660
  scope: "system",
@@ -10619,6 +10669,33 @@ var deviceManagerCapability = {
10619
10669
  addonId: zod.z.string(),
10620
10670
  stableId: zod.z.string()
10621
10671
  }), zod.z.object({ id: zod.z.number() }), { kind: "mutation" }),
10672
+ /**
10673
+ * Replace a camera: the new hardware inherits the number the system knows.
10674
+ *
10675
+ * Everything general about a camera is keyed on the numeric id and nothing
10676
+ * else — the recording path on disk, the hour ledger, the media store, zone
10677
+ * ownership, and all four ecosystem exports. So a replacement moves the
10678
+ * NUMBER rather than the work, and the operator keeps their footage, their
10679
+ * rules and their integrations.
10680
+ *
10681
+ * Both cameras are switched off first, then the identities are exchanged
10682
+ * (children follow their parent), then the target — now answering on the
10683
+ * inherited number — is switched back on.
10684
+ *
10685
+ * **A switch that could not be written is REPORTED, not swallowed.** The
10686
+ * source is characteristically broken, and two of the eight switches write
10687
+ * the camera itself, so on a dead one they cannot be written at all.
10688
+ * `sourceStillLive` names what stayed live; empty is the only value that
10689
+ * means the old hardware is quiet. The migration proceeds either way —
10690
+ * refusing would refuse the case this exists for.
10691
+ */
10692
+ migrateDevice: method(zod.z.object({
10693
+ sourceId: zod.z.number(),
10694
+ targetId: zod.z.number()
10695
+ }), MigrateDeviceResultSchema, {
10696
+ kind: "mutation",
10697
+ auth: "admin"
10698
+ }),
10622
10699
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
10623
10700
  registerDevice: method(DeviceRegisterPayloadSchema, zod.z.void(), { kind: "mutation" }),
10624
10701
  /** Remove a device from the DB + in-memory registry. Called by DeviceManagerApi.remove(). */
@@ -35679,6 +35756,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
35679
35756
  addonId: null,
35680
35757
  access: "view"
35681
35758
  },
35759
+ "deviceManager.migrateDevice": {
35760
+ capName: "device-manager",
35761
+ capScope: "system",
35762
+ addonId: null,
35763
+ access: "create"
35764
+ },
35682
35765
  "deviceManager.persistConfig": {
35683
35766
  capName: "device-manager",
35684
35767
  capScope: "system",
@@ -42994,6 +43077,12 @@ Object.defineProperty(exports, "BatteryStatusSchema", {
42994
43077
  return BatteryStatusSchema;
42995
43078
  }
42996
43079
  });
43080
+ Object.defineProperty(exports, "CAMERA_SWITCH_ORDER", {
43081
+ enumerable: true,
43082
+ get: function() {
43083
+ return CAMERA_SWITCH_ORDER;
43084
+ }
43085
+ });
42997
43086
  Object.defineProperty(exports, "CAP_NAMES_WITH_STATUS", {
42998
43087
  enumerable: true,
42999
43088
  get: function() {
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-DsoVfJSR.js");
3
+ const require_dist = require("./dist-BzPNEPHo.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");
@@ -27,7 +27,7 @@ require("./builtins/system-config/index.js");
27
27
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
28
28
  const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
29
29
  const require_tls$1 = require("./tls-BxQlomxd.js");
30
- const require_manifest_system_deps = require("./manifest-system-deps-ir_XTNpe.js");
30
+ const require_manifest_system_deps = require("./manifest-system-deps-B0mzJPmb.js");
31
31
  const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
32
32
  const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
33
33
  let zod = require("zod");