camstack 1.2.77 → 1.2.79

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.
@@ -15614,7 +15614,8 @@ var OpsLogReasonSchema = external_exports.enum([
15614
15614
  "quota",
15615
15615
  "manual",
15616
15616
  "operator",
15617
- "maintenance"
15617
+ "maintenance",
15618
+ "orphaned-device"
15618
15619
  ]);
15619
15620
  var OpsLogEntrySchema = external_exports.object({
15620
15621
  /** Unique row id. */
@@ -20544,6 +20545,27 @@ var DevicePersistConfigPayloadSchema = external_exports.object({
20544
20545
  deviceId: external_exports.number(),
20545
20546
  data: external_exports.record(external_exports.string(), external_exports.unknown())
20546
20547
  });
20548
+ var MigrateSwitchOutcomeSchema = external_exports.enum([
20549
+ "off",
20550
+ "on",
20551
+ "not-offered",
20552
+ "unreachable"
20553
+ ]);
20554
+ var MigrateSwitchReportSchema = external_exports.object({
20555
+ deviceId: external_exports.number(),
20556
+ switchId: CameraSwitchIdSchema,
20557
+ outcome: MigrateSwitchOutcomeSchema,
20558
+ detail: external_exports.string().optional()
20559
+ });
20560
+ var MigrateDeviceResultSchema = external_exports.object({
20561
+ sourceId: external_exports.number(),
20562
+ targetId: external_exports.number(),
20563
+ switches: external_exports.array(MigrateSwitchReportSchema).readonly(),
20564
+ /** Switches that could NOT be turned off on the source. Empty is the only
20565
+ * value meaning the replaced hardware is quiet. */
20566
+ sourceStillLive: external_exports.array(CameraSwitchIdSchema).readonly(),
20567
+ swapped: external_exports.boolean()
20568
+ });
20547
20569
  var deviceManagerCapability = {
20548
20570
  name: "device-manager",
20549
20571
  scope: "system",
@@ -20558,6 +20580,33 @@ var deviceManagerCapability = {
20558
20580
  addonId: external_exports.string(),
20559
20581
  stableId: external_exports.string()
20560
20582
  }), external_exports.object({ id: external_exports.number() }), { kind: "mutation" }),
20583
+ /**
20584
+ * Replace a camera: the new hardware inherits the number the system knows.
20585
+ *
20586
+ * Everything general about a camera is keyed on the numeric id and nothing
20587
+ * else — the recording path on disk, the hour ledger, the media store, zone
20588
+ * ownership, and all four ecosystem exports. So a replacement moves the
20589
+ * NUMBER rather than the work, and the operator keeps their footage, their
20590
+ * rules and their integrations.
20591
+ *
20592
+ * Both cameras are switched off first, then the identities are exchanged
20593
+ * (children follow their parent), then the target — now answering on the
20594
+ * inherited number — is switched back on.
20595
+ *
20596
+ * **A switch that could not be written is REPORTED, not swallowed.** The
20597
+ * source is characteristically broken, and two of the eight switches write
20598
+ * the camera itself, so on a dead one they cannot be written at all.
20599
+ * `sourceStillLive` names what stayed live; empty is the only value that
20600
+ * means the old hardware is quiet. The migration proceeds either way —
20601
+ * refusing would refuse the case this exists for.
20602
+ */
20603
+ migrateDevice: method(external_exports.object({
20604
+ sourceId: external_exports.number(),
20605
+ targetId: external_exports.number()
20606
+ }), MigrateDeviceResultSchema, {
20607
+ kind: "mutation",
20608
+ auth: "admin"
20609
+ }),
20561
20610
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
20562
20611
  registerDevice: method(DeviceRegisterPayloadSchema, external_exports.void(), { kind: "mutation" }),
20563
20612
  /** Remove a device from the DB + in-memory registry. Called by DeviceManagerApi.remove(). */
@@ -40655,6 +40704,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
40655
40704
  addonId: null,
40656
40705
  access: "view"
40657
40706
  },
40707
+ "deviceManager.migrateDevice": {
40708
+ capName: "device-manager",
40709
+ capScope: "system",
40710
+ addonId: null,
40711
+ access: "create"
40712
+ },
40658
40713
  "deviceManager.persistConfig": {
40659
40714
  capName: "device-manager",
40660
40715
  capScope: "system",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-U3GHKSOG.js";
4
+ } from "./chunk-EDAEBWHA.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-JYQ4AMYP.js");
41
+ await import("./launcher-BA4I4JAU.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-JYQ4AMYP.js");
86
+ await import("./launcher-BA4I4JAU.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-OD7ECRSD.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-HIST37I5.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-U3GHKSOG.js";
8
+ } from "./chunk-EDAEBWHA.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-DsoVfJSR.js
23637
- var require_dist_DsoVfJSR = __commonJS({
23638
- "../system/dist/dist-DsoVfJSR.js"(exports) {
23636
+ // ../system/dist/dist-BzPNEPHo.js
23637
+ var require_dist_BzPNEPHo = __commonJS({
23638
+ "../system/dist/dist-BzPNEPHo.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -25953,6 +25953,16 @@ var require_dist_DsoVfJSR = __commonJS({
25953
25953
  "recording",
25954
25954
  "notifications"
25955
25955
  ]);
25956
+ var CAMERA_SWITCH_ORDER = [
25957
+ "stream-broker",
25958
+ "object-detection",
25959
+ "privacy-mask",
25960
+ "device-audio",
25961
+ "broker-audio",
25962
+ "audio-analysis",
25963
+ "recording",
25964
+ "notifications"
25965
+ ];
25956
25966
  var CameraSwitchAuthoritySchema = zod.z.discriminatedUnion("kind", [
25957
25967
  zod.z.object({ kind: zod.z.literal("device-disabled") }),
25958
25968
  zod.z.object({
@@ -26102,7 +26112,8 @@ var require_dist_DsoVfJSR = __commonJS({
26102
26112
  "quota",
26103
26113
  "manual",
26104
26114
  "operator",
26105
- "maintenance"
26115
+ "maintenance",
26116
+ "orphaned-device"
26106
26117
  ]);
26107
26118
  var OpsLogEntrySchema = zod.z.object({
26108
26119
  /** Unique row id. */
@@ -31247,6 +31258,27 @@ var require_dist_DsoVfJSR = __commonJS({
31247
31258
  deviceId: zod.z.number(),
31248
31259
  data: zod.z.record(zod.z.string(), zod.z.unknown())
31249
31260
  });
31261
+ var MigrateSwitchOutcomeSchema = zod.z.enum([
31262
+ "off",
31263
+ "on",
31264
+ "not-offered",
31265
+ "unreachable"
31266
+ ]);
31267
+ var MigrateSwitchReportSchema = zod.z.object({
31268
+ deviceId: zod.z.number(),
31269
+ switchId: CameraSwitchIdSchema,
31270
+ outcome: MigrateSwitchOutcomeSchema,
31271
+ detail: zod.z.string().optional()
31272
+ });
31273
+ var MigrateDeviceResultSchema = zod.z.object({
31274
+ sourceId: zod.z.number(),
31275
+ targetId: zod.z.number(),
31276
+ switches: zod.z.array(MigrateSwitchReportSchema).readonly(),
31277
+ /** Switches that could NOT be turned off on the source. Empty is the only
31278
+ * value meaning the replaced hardware is quiet. */
31279
+ sourceStillLive: zod.z.array(CameraSwitchIdSchema).readonly(),
31280
+ swapped: zod.z.boolean()
31281
+ });
31250
31282
  var deviceManagerCapability = {
31251
31283
  name: "device-manager",
31252
31284
  scope: "system",
@@ -31261,6 +31293,33 @@ var require_dist_DsoVfJSR = __commonJS({
31261
31293
  addonId: zod.z.string(),
31262
31294
  stableId: zod.z.string()
31263
31295
  }), zod.z.object({ id: zod.z.number() }), { kind: "mutation" }),
31296
+ /**
31297
+ * Replace a camera: the new hardware inherits the number the system knows.
31298
+ *
31299
+ * Everything general about a camera is keyed on the numeric id and nothing
31300
+ * else — the recording path on disk, the hour ledger, the media store, zone
31301
+ * ownership, and all four ecosystem exports. So a replacement moves the
31302
+ * NUMBER rather than the work, and the operator keeps their footage, their
31303
+ * rules and their integrations.
31304
+ *
31305
+ * Both cameras are switched off first, then the identities are exchanged
31306
+ * (children follow their parent), then the target — now answering on the
31307
+ * inherited number — is switched back on.
31308
+ *
31309
+ * **A switch that could not be written is REPORTED, not swallowed.** The
31310
+ * source is characteristically broken, and two of the eight switches write
31311
+ * the camera itself, so on a dead one they cannot be written at all.
31312
+ * `sourceStillLive` names what stayed live; empty is the only value that
31313
+ * means the old hardware is quiet. The migration proceeds either way —
31314
+ * refusing would refuse the case this exists for.
31315
+ */
31316
+ migrateDevice: method(zod.z.object({
31317
+ sourceId: zod.z.number(),
31318
+ targetId: zod.z.number()
31319
+ }), MigrateDeviceResultSchema, {
31320
+ kind: "mutation",
31321
+ auth: "admin"
31322
+ }),
31264
31323
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
31265
31324
  registerDevice: method(DeviceRegisterPayloadSchema, zod.z.void(), { kind: "mutation" }),
31266
31325
  /** Remove a device from the DB + in-memory registry. Called by DeviceManagerApi.remove(). */
@@ -51971,6 +52030,12 @@ var require_dist_DsoVfJSR = __commonJS({
51971
52030
  addonId: null,
51972
52031
  access: "view"
51973
52032
  },
52033
+ "deviceManager.migrateDevice": {
52034
+ capName: "device-manager",
52035
+ capScope: "system",
52036
+ addonId: null,
52037
+ access: "create"
52038
+ },
51974
52039
  "deviceManager.persistConfig": {
51975
52040
  capName: "device-manager",
51976
52041
  capScope: "system",
@@ -59055,6 +59120,12 @@ var require_dist_DsoVfJSR = __commonJS({
59055
59120
  return BatteryStatusSchema;
59056
59121
  }
59057
59122
  });
59123
+ Object.defineProperty(exports, "CAMERA_SWITCH_ORDER", {
59124
+ enumerable: true,
59125
+ get: function() {
59126
+ return CAMERA_SWITCH_ORDER;
59127
+ }
59128
+ });
59058
59129
  Object.defineProperty(exports, "CAP_NAMES_WITH_STATUS", {
59059
59130
  enumerable: true,
59060
59131
  get: function() {
@@ -59715,7 +59786,7 @@ var require_alerts_addon = __commonJS({
59715
59786
  [Symbol.toStringTag]: { value: "Module" }
59716
59787
  });
59717
59788
  require_chunk_Cek0wNdY();
59718
- var require_dist10 = require_dist_DsoVfJSR();
59789
+ var require_dist10 = require_dist_BzPNEPHo();
59719
59790
  function selectExpired(alerts, cutoffMs) {
59720
59791
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
59721
59792
  }
@@ -60534,7 +60605,7 @@ var require_console_logging = __commonJS({
60534
60605
  [Symbol.toStringTag]: { value: "Module" }
60535
60606
  });
60536
60607
  require_chunk_Cek0wNdY();
60537
- var require_dist10 = require_dist_DsoVfJSR();
60608
+ var require_dist10 = require_dist_BzPNEPHo();
60538
60609
  var require_formatter = require_formatter_DqAKDlvN();
60539
60610
  var LEVEL_RANK = {
60540
60611
  debug: 0,
@@ -60628,7 +60699,7 @@ var require_core_blocks_addon = __commonJS({
60628
60699
  "use strict";
60629
60700
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
60630
60701
  var require_chunk = require_chunk_Cek0wNdY();
60631
- var require_dist10 = require_dist_DsoVfJSR();
60702
+ var require_dist10 = require_dist_BzPNEPHo();
60632
60703
  var node_crypto = __require("crypto");
60633
60704
  var node_fs_promises = __require("fs/promises");
60634
60705
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -61525,11 +61596,11 @@ var require_core_blocks = __commonJS({
61525
61596
  }
61526
61597
  });
61527
61598
 
61528
- // ../system/dist/retired-settings-keys-DTE5k4lU.js
61529
- var require_retired_settings_keys_DTE5k4lU = __commonJS({
61530
- "../system/dist/retired-settings-keys-DTE5k4lU.js"(exports) {
61599
+ // ../system/dist/retired-settings-keys-DZmeJ8ja.js
61600
+ var require_retired_settings_keys_DZmeJ8ja = __commonJS({
61601
+ "../system/dist/retired-settings-keys-DZmeJ8ja.js"(exports) {
61531
61602
  "use strict";
61532
- var require_dist10 = require_dist_DsoVfJSR();
61603
+ var require_dist10 = require_dist_BzPNEPHo();
61533
61604
  function settingsStoreIsAuthoritativeHere(env) {
61534
61605
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
61535
61606
  return raw === "" || raw === "hub";
@@ -63743,8 +63814,8 @@ var require_device_manager_addon = __commonJS({
63743
63814
  [Symbol.toStringTag]: { value: "Module" }
63744
63815
  });
63745
63816
  require_chunk_Cek0wNdY();
63746
- var require_dist10 = require_dist_DsoVfJSR();
63747
- var require_retired_settings_keys = require_retired_settings_keys_DTE5k4lU();
63817
+ var require_dist10 = require_dist_BzPNEPHo();
63818
+ var require_retired_settings_keys = require_retired_settings_keys_DZmeJ8ja();
63748
63819
  var node_crypto = __require("crypto");
63749
63820
  var _camstack_types_node = require_node();
63750
63821
  var JOB_HISTORY = 20;
@@ -66226,6 +66297,62 @@ var require_device_manager_addon = __commonJS({
66226
66297
  return chain;
66227
66298
  }
66228
66299
  };
66300
+ function classify(err) {
66301
+ const detail = err instanceof Error ? err.message : String(err);
66302
+ return {
66303
+ outcome: /does not offer|not available|unsupported/i.test(detail) ? "not-offered" : "unreachable",
66304
+ detail
66305
+ };
66306
+ }
66307
+ async function applyAll(deps, deviceId, enabled) {
66308
+ const out = [];
66309
+ for (const switchId of require_dist10.CAMERA_SWITCH_ORDER) try {
66310
+ await deps.setSwitch(deviceId, switchId, enabled);
66311
+ out.push({
66312
+ deviceId,
66313
+ switchId,
66314
+ outcome: enabled ? "on" : "off"
66315
+ });
66316
+ } catch (err) {
66317
+ const { outcome, detail } = classify(err);
66318
+ out.push({
66319
+ deviceId,
66320
+ switchId,
66321
+ outcome,
66322
+ detail
66323
+ });
66324
+ deps.log("camera switch refused", {
66325
+ deviceId,
66326
+ switchId,
66327
+ enabled,
66328
+ outcome,
66329
+ detail
66330
+ });
66331
+ }
66332
+ return out;
66333
+ }
66334
+ async function migrateDevice$1(deps, input) {
66335
+ const { sourceId, targetId } = input;
66336
+ if (sourceId === targetId) throw new Error(`[device-manager] migrateDevice: ${sourceId} is both source and target`);
66337
+ const down = [...await applyAll(deps, sourceId, false), ...await applyAll(deps, targetId, false)];
66338
+ const sourceStillLive = down.filter((r) => r.deviceId === sourceId && r.outcome === "unreachable").map((r) => r.switchId);
66339
+ await deps.swapIds(sourceId, targetId);
66340
+ const up = await applyAll(deps, sourceId, true);
66341
+ await deps.respawnRunners([sourceId, targetId]);
66342
+ deps.log("camera migrated", {
66343
+ sourceId,
66344
+ targetId,
66345
+ sourceStillLive,
66346
+ refusals: [...down, ...up].filter((r) => r.outcome === "unreachable").length
66347
+ });
66348
+ return {
66349
+ sourceId,
66350
+ targetId,
66351
+ switches: [...down, ...up],
66352
+ sourceStillLive,
66353
+ swapped: true
66354
+ };
66355
+ }
66229
66356
  async function stampIntegrationId(metaStore, ctx, deviceId, integrationId) {
66230
66357
  await metaStore.withMetaWriteLock(async () => {
66231
66358
  if (!await metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] stampIntegrationId: unknown device id=${deviceId}`);
@@ -66268,6 +66395,43 @@ var require_device_manager_addon = __commonJS({
66268
66395
  return { id };
66269
66396
  });
66270
66397
  }
66398
+ async function migrateDevice(pctx, input) {
66399
+ const { sourceId, targetId } = input;
66400
+ const ctx = pctx.host.ctx;
66401
+ return await pctx.metaStore.withMetaWriteLock(async () => {
66402
+ for (const id of [sourceId, targetId]) if (await pctx.metaStore.rows.get(id) === null) throw new Error(`[device-manager] migrateDevice: device ${id} does not exist`);
66403
+ const tempId = await pctx.metaStore.allocateNextDeviceId();
66404
+ return await migrateDevice$1({
66405
+ setSwitch: async (deviceId, switchId, enabled) => {
66406
+ await ctx.api.pipelineOrchestrator.setCameraSwitch.mutate({
66407
+ deviceId,
66408
+ switchId,
66409
+ enabled
66410
+ });
66411
+ },
66412
+ swapIds: async (a, b) => {
66413
+ await pctx.metaStore.rows.swapIds(a, b, tempId);
66414
+ },
66415
+ respawnRunners: async (deviceIds) => {
66416
+ const owners = /* @__PURE__ */ new Set();
66417
+ for (const deviceId of deviceIds) {
66418
+ const addonId = pctx.metaStore.idToAddonId.get(deviceId);
66419
+ if (addonId !== void 0) owners.add(addonId);
66420
+ }
66421
+ for (const addonId of owners) await ctx.api.addons.restartAddon.mutate({ addonId });
66422
+ },
66423
+ log: (message, meta) => {
66424
+ ctx.logger.info(message, {
66425
+ tags: { deviceId: sourceId },
66426
+ meta
66427
+ });
66428
+ }
66429
+ }, {
66430
+ sourceId,
66431
+ targetId
66432
+ });
66433
+ });
66434
+ }
66271
66435
  async function registerDevice(pctx, input) {
66272
66436
  const { addonId, stableId, id, type, name, parentDeviceId, features, config } = input;
66273
66437
  const featuresArr = Array.isArray(features) ? [...features] : [];
@@ -68456,6 +68620,7 @@ var require_device_manager_addon = __commonJS({
68456
68620
  resolveDeviceOwnerSync: (deviceId) => resolveDeviceOwnerSync(pctx, deviceId),
68457
68621
  resolveNativeCapOwnerSync: (capName, deviceId) => resolveNativeCapOwnerSync(pctx, capName, deviceId),
68458
68622
  allocateDeviceId: (input) => allocateDeviceId(pctx, input),
68623
+ migrateDevice: (input) => migrateDevice(pctx, input),
68459
68624
  registerDevice: (input) => registerDevice(pctx, input),
68460
68625
  removeDevice: (input) => removeDevice(pctx, input),
68461
68626
  persistConfig: (input) => persistConfig(pctx, input),
@@ -68686,7 +68851,7 @@ var require_hub_forwarder = __commonJS({
68686
68851
  [Symbol.toStringTag]: { value: "Module" }
68687
68852
  });
68688
68853
  require_chunk_Cek0wNdY();
68689
- var require_dist10 = require_dist_DsoVfJSR();
68854
+ var require_dist10 = require_dist_BzPNEPHo();
68690
68855
  var require_formatter = require_formatter_DqAKDlvN();
68691
68856
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
68692
68857
  var HubForwarderDestination = class {
@@ -68823,7 +68988,7 @@ var require_liveness_monitor_addon = __commonJS({
68823
68988
  "use strict";
68824
68989
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
68825
68990
  require_chunk_Cek0wNdY();
68826
- var require_dist10 = require_dist_DsoVfJSR();
68991
+ var require_dist10 = require_dist_BzPNEPHo();
68827
68992
  var NO_DEVICES = "liveness:no-devices";
68828
68993
  var ALL_OFFLINE = "liveness:all-devices-offline";
68829
68994
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -69013,7 +69178,7 @@ var require_local_auth_addon = __commonJS({
69013
69178
  [Symbol.toStringTag]: { value: "Module" }
69014
69179
  });
69015
69180
  var require_chunk = require_chunk_Cek0wNdY();
69016
- var require_dist10 = require_dist_DsoVfJSR();
69181
+ var require_dist10 = require_dist_BzPNEPHo();
69017
69182
  var node_crypto = __require("crypto");
69018
69183
  node_crypto = require_chunk.__toESM(node_crypto);
69019
69184
  var crypto$1 = __require("crypto");
@@ -76826,7 +76991,7 @@ var require_loki_logging = __commonJS({
76826
76991
  [Symbol.toStringTag]: { value: "Module" }
76827
76992
  });
76828
76993
  require_chunk_Cek0wNdY();
76829
- var require_dist10 = require_dist_DsoVfJSR();
76994
+ var require_dist10 = require_dist_BzPNEPHo();
76830
76995
  function sanitizeLabelName(raw) {
76831
76996
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
76832
76997
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -77391,7 +77556,7 @@ var require_native_metrics_addon = __commonJS({
77391
77556
  [Symbol.toStringTag]: { value: "Module" }
77392
77557
  });
77393
77558
  var require_chunk = require_chunk_Cek0wNdY();
77394
- var require_dist10 = require_dist_DsoVfJSR();
77559
+ var require_dist10 = require_dist_BzPNEPHo();
77395
77560
  var node_fs_promises = __require("fs/promises");
77396
77561
  var node_child_process = __require("child_process");
77397
77562
  var node_util = __require("util");
@@ -80013,7 +80178,7 @@ var require_filesystem_storage_addon = __commonJS({
80013
80178
  [Symbol.toStringTag]: { value: "Module" }
80014
80179
  });
80015
80180
  var require_chunk = require_chunk_Cek0wNdY();
80016
- var require_dist10 = require_dist_DsoVfJSR();
80181
+ var require_dist10 = require_dist_BzPNEPHo();
80017
80182
  var node_crypto = __require("crypto");
80018
80183
  var node_fs_promises = __require("fs/promises");
80019
80184
  var node_path = __require("path");
@@ -81129,8 +81294,8 @@ var require_sqlite_settings_addon = __commonJS({
81129
81294
  [Symbol.toStringTag]: { value: "Module" }
81130
81295
  });
81131
81296
  var require_chunk = require_chunk_Cek0wNdY();
81132
- var require_dist10 = require_dist_DsoVfJSR();
81133
- var require_retired_settings_keys = require_retired_settings_keys_DTE5k4lU();
81297
+ var require_dist10 = require_dist_BzPNEPHo();
81298
+ var require_retired_settings_keys = require_retired_settings_keys_DZmeJ8ja();
81134
81299
  var node_crypto = __require("crypto");
81135
81300
  var node_fs = __require("fs");
81136
81301
  var node_module = __require("module");
@@ -83612,7 +83777,7 @@ var require_storage_orchestrator_addon = __commonJS({
83612
83777
  [Symbol.toStringTag]: { value: "Module" }
83613
83778
  });
83614
83779
  var require_chunk = require_chunk_Cek0wNdY();
83615
- var require_dist10 = require_dist_DsoVfJSR();
83780
+ var require_dist10 = require_dist_BzPNEPHo();
83616
83781
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
83617
83782
  var zod = require_zod();
83618
83783
  var node_crypto = __require("crypto");
@@ -86563,7 +86728,7 @@ var require_system_config_addon = __commonJS({
86563
86728
  [Symbol.toStringTag]: { value: "Module" }
86564
86729
  });
86565
86730
  require_chunk_Cek0wNdY();
86566
- var require_dist10 = require_dist_DsoVfJSR();
86731
+ var require_dist10 = require_dist_BzPNEPHo();
86567
86732
  var SECTION_TITLES = {
86568
86733
  server: "Server",
86569
86734
  auth: "Authentication"
@@ -104624,7 +104789,7 @@ var require_winston_logging = __commonJS({
104624
104789
  [Symbol.toStringTag]: { value: "Module" }
104625
104790
  });
104626
104791
  var require_chunk = require_chunk_Cek0wNdY();
104627
- var require_dist10 = require_dist_DsoVfJSR();
104792
+ var require_dist10 = require_dist_BzPNEPHo();
104628
104793
  var require_formatter = require_formatter_DqAKDlvN();
104629
104794
  var node_path = __require("path");
104630
104795
  node_path = require_chunk.__toESM(node_path);
@@ -117124,12 +117289,12 @@ var require_dist2 = __commonJS({
117124
117289
  }
117125
117290
  });
117126
117291
 
117127
- // ../system/dist/manifest-system-deps-ir_XTNpe.js
117128
- var require_manifest_system_deps_ir_XTNpe = __commonJS({
117129
- "../system/dist/manifest-system-deps-ir_XTNpe.js"(exports) {
117292
+ // ../system/dist/manifest-system-deps-B0mzJPmb.js
117293
+ var require_manifest_system_deps_B0mzJPmb = __commonJS({
117294
+ "../system/dist/manifest-system-deps-B0mzJPmb.js"(exports) {
117130
117295
  "use strict";
117131
117296
  var require_chunk = require_chunk_Cek0wNdY();
117132
- require_dist_DsoVfJSR();
117297
+ require_dist_BzPNEPHo();
117133
117298
  require_hub_cap_forward_DmHNjbB0();
117134
117299
  var node_crypto = __require("crypto");
117135
117300
  node_crypto = require_chunk.__toESM(node_crypto);
@@ -129225,7 +129390,7 @@ var require_dist3 = __commonJS({
129225
129390
  "use strict";
129226
129391
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
129227
129392
  var require_chunk = require_chunk_Cek0wNdY();
129228
- var require_dist10 = require_dist_DsoVfJSR();
129393
+ var require_dist10 = require_dist_BzPNEPHo();
129229
129394
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
129230
129395
  require_alerts();
129231
129396
  var require_formatter = require_formatter_DqAKDlvN();
@@ -129252,7 +129417,7 @@ var require_dist3 = __commonJS({
129252
129417
  var require_builtins_winston_logging_index = require_winston_logging();
129253
129418
  var require_file_data_plane = require_file_data_plane_DO8KbxCe();
129254
129419
  var require_tls$1 = require_tls_BxQlomxd();
129255
- var require_manifest_system_deps = require_manifest_system_deps_ir_XTNpe();
129420
+ var require_manifest_system_deps = require_manifest_system_deps_B0mzJPmb();
129256
129421
  var require_resource_monitor = require_resource_monitor_CdnzxBLP();
129257
129422
  var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
129258
129423
  var zod = require_zod();
@@ -211062,7 +211227,8 @@ var require_dist4 = __commonJS({
211062
211227
  "quota",
211063
211228
  "manual",
211064
211229
  "operator",
211065
- "maintenance"
211230
+ "maintenance",
211231
+ "orphaned-device"
211066
211232
  ]);
211067
211233
  var OpsLogEntrySchema = zod.z.object({
211068
211234
  /** Unique row id. */
@@ -217401,6 +217567,27 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
217401
217567
  deviceId: zod.z.number(),
217402
217568
  data: zod.z.record(zod.z.string(), zod.z.unknown())
217403
217569
  });
217570
+ var MigrateSwitchOutcomeSchema = zod.z.enum([
217571
+ "off",
217572
+ "on",
217573
+ "not-offered",
217574
+ "unreachable"
217575
+ ]);
217576
+ var MigrateSwitchReportSchema = zod.z.object({
217577
+ deviceId: zod.z.number(),
217578
+ switchId: CameraSwitchIdSchema,
217579
+ outcome: MigrateSwitchOutcomeSchema,
217580
+ detail: zod.z.string().optional()
217581
+ });
217582
+ var MigrateDeviceResultSchema = zod.z.object({
217583
+ sourceId: zod.z.number(),
217584
+ targetId: zod.z.number(),
217585
+ switches: zod.z.array(MigrateSwitchReportSchema).readonly(),
217586
+ /** Switches that could NOT be turned off on the source. Empty is the only
217587
+ * value meaning the replaced hardware is quiet. */
217588
+ sourceStillLive: zod.z.array(CameraSwitchIdSchema).readonly(),
217589
+ swapped: zod.z.boolean()
217590
+ });
217404
217591
  var deviceManagerCapability = {
217405
217592
  name: "device-manager",
217406
217593
  scope: "system",
@@ -217415,6 +217602,33 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
217415
217602
  addonId: zod.z.string(),
217416
217603
  stableId: zod.z.string()
217417
217604
  }), zod.z.object({ id: zod.z.number() }), { kind: "mutation" }),
217605
+ /**
217606
+ * Replace a camera: the new hardware inherits the number the system knows.
217607
+ *
217608
+ * Everything general about a camera is keyed on the numeric id and nothing
217609
+ * else — the recording path on disk, the hour ledger, the media store, zone
217610
+ * ownership, and all four ecosystem exports. So a replacement moves the
217611
+ * NUMBER rather than the work, and the operator keeps their footage, their
217612
+ * rules and their integrations.
217613
+ *
217614
+ * Both cameras are switched off first, then the identities are exchanged
217615
+ * (children follow their parent), then the target — now answering on the
217616
+ * inherited number — is switched back on.
217617
+ *
217618
+ * **A switch that could not be written is REPORTED, not swallowed.** The
217619
+ * source is characteristically broken, and two of the eight switches write
217620
+ * the camera itself, so on a dead one they cannot be written at all.
217621
+ * `sourceStillLive` names what stayed live; empty is the only value that
217622
+ * means the old hardware is quiet. The migration proceeds either way —
217623
+ * refusing would refuse the case this exists for.
217624
+ */
217625
+ migrateDevice: require_sleep.method(zod.z.object({
217626
+ sourceId: zod.z.number(),
217627
+ targetId: zod.z.number()
217628
+ }), MigrateDeviceResultSchema, {
217629
+ kind: "mutation",
217630
+ auth: "admin"
217631
+ }),
217418
217632
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
217419
217633
  registerDevice: require_sleep.method(DeviceRegisterPayloadSchema, zod.z.void(), { kind: "mutation" }),
217420
217634
  /** Remove a device from the DB + in-memory registry. Called by DeviceManagerApi.remove(). */
@@ -242049,6 +242263,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
242049
242263
  addonId: null,
242050
242264
  access: "view"
242051
242265
  },
242266
+ "deviceManager.migrateDevice": {
242267
+ capName: "device-manager",
242268
+ capScope: "system",
242269
+ addonId: null,
242270
+ access: "create"
242271
+ },
242052
242272
  "deviceManager.persistConfig": {
242053
242273
  capName: "device-manager",
242054
242274
  capScope: "system",
@@ -249355,6 +249575,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
249355
249575
  },
249356
249576
  deviceManager: {
249357
249577
  allocateDeviceId: (input) => dispatch("deviceManager", "allocateDeviceId", "mutation", input),
249578
+ migrateDevice: (input) => dispatch("deviceManager", "migrateDevice", "mutation", input),
249358
249579
  registerDevice: (input) => dispatch("deviceManager", "registerDevice", "mutation", input),
249359
249580
  removeDevice: (input) => dispatch("deviceManager", "removeDevice", "mutation", input),
249360
249581
  persistConfig: (input) => dispatch("deviceManager", "persistConfig", "mutation", input),
@@ -252970,6 +253191,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
252970
253191
  exports.MeshPeerSchema = MeshPeerSchema;
252971
253192
  exports.MeshStatusSchema = MeshStatusSchema;
252972
253193
  exports.MethodAccessSchema = MethodAccessSchema;
253194
+ exports.MigrateDeviceResultSchema = MigrateDeviceResultSchema;
253195
+ exports.MigrateSwitchOutcomeSchema = MigrateSwitchOutcomeSchema;
253196
+ exports.MigrateSwitchReportSchema = MigrateSwitchReportSchema;
252973
253197
  exports.ModelCatalogEntrySchema = ModelCatalogEntrySchema;
252974
253198
  exports.ModelConvertInputSchema = ModelConvertInputSchema;
252975
253199
  exports.ModelConvertMetadataSchema = ModelConvertMetadataSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.77",
3
+ "version": "1.2.79",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",