camstack 1.2.108 → 1.2.109

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-IaOr7P-z.mjs
14525
+ // ../types/dist/sleep-Cfij6Jj9.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -15693,7 +15693,8 @@ var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
15693
15693
  var RecordingStorageModeSchema = external_exports.enum([
15694
15694
  "off",
15695
15695
  "events",
15696
- "continuous"
15696
+ "continuous",
15697
+ "on-device-decision"
15697
15698
  ]);
15698
15699
  var RecordingObjectTriggerClassSchema = external_exports.enum(FIRST_LEVEL_MACRO_CLASSES);
15699
15700
  var noDuplicates = (values) => new Set(values).size === values.length;
@@ -15730,22 +15731,7 @@ var RecordingTriggersSchema = external_exports.object({
15730
15731
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
15731
15732
  * registrare.
15732
15733
  */
15733
- sensorDeviceIds: external_exports.array(external_exports.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional(),
15734
- /**
15735
- * La camera registra per tutta la durata del SEGNALE che lei stessa
15736
- * pubblica — la cap `recording-signal` (`active: true` mentre il device è in
15737
- * funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
15738
- * resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
15739
- * caduta, così una pulizia di quaranta minuti è UNA clip.
15740
- *
15741
- * Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
15742
- * suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
15743
- * riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
15744
- * segnale mai abbassato (un evento perso) non può tenere aperta una
15745
- * registrazione (D11). Vedi `recorder/addon/band-decision.ts`
15746
- * (`holdTrigger` / `releaseTrigger`).
15747
- */
15748
- deviceSignal: external_exports.boolean().optional()
15734
+ sensorDeviceIds: external_exports.array(external_exports.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
15749
15735
  });
15750
15736
  var RecordingBandModeSchema = external_exports.enum(["continuous", "events"]);
15751
15737
  var RecordingBandTriggersSchema = RecordingTriggersSchema;
@@ -15786,8 +15772,29 @@ var RecordingConfigSchema = external_exports.object({
15786
15772
  * "off" is the absence of a covering band, never a band value.
15787
15773
  */
15788
15774
  bands: external_exports.array(RecordingBandSchema).default([]),
15775
+ /**
15776
+ * THE device-decided intent: record for as long as the camera itself raises
15777
+ * `recording-signal` (`active: true` while the device is in function — a
15778
+ * robot that cleans). AUTHORED, unlike `mode`, and the only authored
15779
+ * recording intent that is not a band.
15780
+ *
15781
+ * It carries NO schedule on purpose. A band is an HOUR, and this feature has
15782
+ * no hour to program: the device decides. What it costs the operator is one
15783
+ * flag — "this camera can record on its own" — and what it buys is the same
15784
+ * hold/release the recorder already implements (D371, `holdTrigger` /
15785
+ * `releaseTrigger`): the window opens on the rise, stays open for the whole
15786
+ * job however long it is, and closes one pad after the fall.
15787
+ *
15788
+ * EXCLUSIVE with `bands` (below): two authorities deciding when the same
15789
+ * camera records is the D62 failure. `off` remains `enabled: false`, so an
15790
+ * operator switching this camera off is REPORTED off, never as broken.
15791
+ */
15792
+ deviceDecision: external_exports.boolean().optional(),
15789
15793
  retention: RecordingRetentionSchema.optional()
15790
- }).strict();
15794
+ }).strict().refine((config2) => config2.deviceDecision !== true || config2.bands.length === 0, {
15795
+ message: "deviceDecision is a whole-config mode and carries no schedule: it cannot be combined with bands",
15796
+ path: ["bands"]
15797
+ });
15791
15798
  var RelocateJobStateSchema = external_exports.enum([
15792
15799
  "queued",
15793
15800
  "running",
@@ -28844,11 +28851,7 @@ var CameraAudioStatusSchema = external_exports.object({
28844
28851
  nodeId: external_exports.string(),
28845
28852
  enabled: external_exports.boolean()
28846
28853
  });
28847
- var CameraRecordingModeSchema = external_exports.enum([
28848
- "off",
28849
- "continuous",
28850
- "events"
28851
- ]);
28854
+ var CameraRecordingModeSchema = RecordingStorageModeSchema;
28852
28855
  var CameraRecordingStatusSchema = external_exports.object({
28853
28856
  mode: CameraRecordingModeSchema,
28854
28857
  active: external_exports.boolean(),
@@ -37153,11 +37156,10 @@ var rebootCapability = {
37153
37156
  var RecordingStatusSchema = external_exports.object({
37154
37157
  deviceId: external_exports.number(),
37155
37158
  enabled: external_exports.boolean(),
37156
- activeMode: external_exports.enum([
37157
- "off",
37158
- "continuous",
37159
- "events"
37160
- ]),
37159
+ /** THE derived storage mode, from the one definition
37160
+ * (`deriveRecordingMode`) — never a second enum. A duplicated list is how
37161
+ * `on-device-decision` could have reached the recorder and not the status. */
37162
+ activeMode: RecordingStorageModeSchema,
37161
37163
  nodeId: external_exports.string(),
37162
37164
  storageBytes: external_exports.number()
37163
37165
  });
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-OLHRHGNY.js";
4
+ } from "./chunk-667FSBVG.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-4UETVHGT.js");
41
+ await import("./launcher-DE3AXTYV.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-4UETVHGT.js");
86
+ await import("./launcher-DE3AXTYV.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-MHBOYSVK.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-UWXU5NPV.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-OLHRHGNY.js";
8
+ } from "./chunk-667FSBVG.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-BNaW68aZ.js
23637
- var require_dist_BNaW68aZ = __commonJS({
23638
- "../system/dist/dist-BNaW68aZ.js"(exports) {
23636
+ // ../system/dist/dist-HAP38XvL.js
23637
+ var require_dist_HAP38XvL = __commonJS({
23638
+ "../system/dist/dist-HAP38XvL.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -26036,21 +26036,21 @@ var require_dist_BNaW68aZ = __commonJS({
26036
26036
  for (const section of sectionsOf(schema)) for (const field of fieldsOf(section)) walkField(field, keys);
26037
26037
  return keys;
26038
26038
  }
26039
- function isRecord$2(value) {
26039
+ function isRecord$3(value) {
26040
26040
  return typeof value === "object" && value !== null && !Array.isArray(value);
26041
26041
  }
26042
26042
  function sectionsOf(schema) {
26043
- if (!isRecord$2(schema)) return [];
26043
+ if (!isRecord$3(schema)) return [];
26044
26044
  const sections = schema["sections"];
26045
26045
  return Array.isArray(sections) ? sections : [];
26046
26046
  }
26047
26047
  function fieldsOf(node) {
26048
- if (!isRecord$2(node)) return [];
26048
+ if (!isRecord$3(node)) return [];
26049
26049
  const fields = node["fields"];
26050
26050
  return Array.isArray(fields) ? fields : [];
26051
26051
  }
26052
26052
  function walkField(field, out) {
26053
- if (!isRecord$2(field)) return;
26053
+ if (!isRecord$3(field)) return;
26054
26054
  const type = field["type"];
26055
26055
  const key = field["key"];
26056
26056
  if ((type === "password" || field["secret"] === true) && typeof key === "string" && key.length > 0) out.add(key);
@@ -26192,7 +26192,8 @@ var require_dist_BNaW68aZ = __commonJS({
26192
26192
  var RecordingStorageModeSchema = zod.z.enum([
26193
26193
  "off",
26194
26194
  "events",
26195
- "continuous"
26195
+ "continuous",
26196
+ "on-device-decision"
26196
26197
  ]);
26197
26198
  var RecordingObjectTriggerClassSchema = zod.z.enum(FIRST_LEVEL_MACRO_CLASSES);
26198
26199
  var noDuplicates = (values) => new Set(values).size === values.length;
@@ -26229,22 +26230,7 @@ var require_dist_BNaW68aZ = __commonJS({
26229
26230
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
26230
26231
  * registrare.
26231
26232
  */
26232
- sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional(),
26233
- /**
26234
- * La camera registra per tutta la durata del SEGNALE che lei stessa
26235
- * pubblica — la cap `recording-signal` (`active: true` mentre il device è in
26236
- * funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
26237
- * resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
26238
- * caduta, così una pulizia di quaranta minuti è UNA clip.
26239
- *
26240
- * Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
26241
- * suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
26242
- * riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
26243
- * segnale mai abbassato (un evento perso) non può tenere aperta una
26244
- * registrazione (D11). Vedi `recorder/addon/band-decision.ts`
26245
- * (`holdTrigger` / `releaseTrigger`).
26246
- */
26247
- deviceSignal: zod.z.boolean().optional()
26233
+ sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
26248
26234
  });
26249
26235
  var RecordingBandModeSchema = zod.z.enum(["continuous", "events"]);
26250
26236
  var RecordingBandTriggersSchema = RecordingTriggersSchema;
@@ -26284,8 +26270,29 @@ var require_dist_BNaW68aZ = __commonJS({
26284
26270
  * "off" is the absence of a covering band, never a band value.
26285
26271
  */
26286
26272
  bands: zod.z.array(RecordingBandSchema).default([]),
26273
+ /**
26274
+ * THE device-decided intent: record for as long as the camera itself raises
26275
+ * `recording-signal` (`active: true` while the device is in function — a
26276
+ * robot that cleans). AUTHORED, unlike `mode`, and the only authored
26277
+ * recording intent that is not a band.
26278
+ *
26279
+ * It carries NO schedule on purpose. A band is an HOUR, and this feature has
26280
+ * no hour to program: the device decides. What it costs the operator is one
26281
+ * flag — "this camera can record on its own" — and what it buys is the same
26282
+ * hold/release the recorder already implements (D371, `holdTrigger` /
26283
+ * `releaseTrigger`): the window opens on the rise, stays open for the whole
26284
+ * job however long it is, and closes one pad after the fall.
26285
+ *
26286
+ * EXCLUSIVE with `bands` (below): two authorities deciding when the same
26287
+ * camera records is the D62 failure. `off` remains `enabled: false`, so an
26288
+ * operator switching this camera off is REPORTED off, never as broken.
26289
+ */
26290
+ deviceDecision: zod.z.boolean().optional(),
26287
26291
  retention: RecordingRetentionSchema.optional()
26288
- }).strict();
26292
+ }).strict().refine((config) => config.deviceDecision !== true || config.bands.length === 0, {
26293
+ message: "deviceDecision is a whole-config mode and carries no schedule: it cannot be combined with bands",
26294
+ path: ["bands"]
26295
+ });
26289
26296
  var RelocateJobStateSchema = zod.z.enum([
26290
26297
  "queued",
26291
26298
  "running",
@@ -39407,11 +39414,7 @@ var require_dist_BNaW68aZ = __commonJS({
39407
39414
  nodeId: zod.z.string(),
39408
39415
  enabled: zod.z.boolean()
39409
39416
  });
39410
- var CameraRecordingModeSchema = zod.z.enum([
39411
- "off",
39412
- "continuous",
39413
- "events"
39414
- ]);
39417
+ var CameraRecordingModeSchema = RecordingStorageModeSchema;
39415
39418
  var CameraRecordingStatusSchema = zod.z.object({
39416
39419
  mode: CameraRecordingModeSchema,
39417
39420
  active: zod.z.boolean(),
@@ -47712,11 +47715,10 @@ var require_dist_BNaW68aZ = __commonJS({
47712
47715
  var RecordingStatusSchema = zod.z.object({
47713
47716
  deviceId: zod.z.number(),
47714
47717
  enabled: zod.z.boolean(),
47715
- activeMode: zod.z.enum([
47716
- "off",
47717
- "continuous",
47718
- "events"
47719
- ]),
47718
+ /** THE derived storage mode, from the one definition
47719
+ * (`deriveRecordingMode`) — never a second enum. A duplicated list is how
47720
+ * `on-device-decision` could have reached the recorder and not the status. */
47721
+ activeMode: RecordingStorageModeSchema,
47720
47722
  nodeId: zod.z.string(),
47721
47723
  storageBytes: zod.z.number()
47722
47724
  });
@@ -60658,7 +60660,7 @@ var require_alerts_addon = __commonJS({
60658
60660
  [Symbol.toStringTag]: { value: "Module" }
60659
60661
  });
60660
60662
  require_chunk_Cek0wNdY();
60661
- var require_dist10 = require_dist_BNaW68aZ();
60663
+ var require_dist10 = require_dist_HAP38XvL();
60662
60664
  function selectExpired(alerts, cutoffMs) {
60663
60665
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60664
60666
  }
@@ -61477,7 +61479,7 @@ var require_console_logging = __commonJS({
61477
61479
  [Symbol.toStringTag]: { value: "Module" }
61478
61480
  });
61479
61481
  require_chunk_Cek0wNdY();
61480
- var require_dist10 = require_dist_BNaW68aZ();
61482
+ var require_dist10 = require_dist_HAP38XvL();
61481
61483
  var require_formatter = require_formatter_DqAKDlvN();
61482
61484
  var LEVEL_RANK = {
61483
61485
  debug: 0,
@@ -61571,7 +61573,7 @@ var require_core_blocks_addon = __commonJS({
61571
61573
  "use strict";
61572
61574
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61573
61575
  var require_chunk = require_chunk_Cek0wNdY();
61574
- var require_dist10 = require_dist_BNaW68aZ();
61576
+ var require_dist10 = require_dist_HAP38XvL();
61575
61577
  var node_crypto = __require("crypto");
61576
61578
  var node_fs_promises = __require("fs/promises");
61577
61579
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -62468,11 +62470,11 @@ var require_core_blocks = __commonJS({
62468
62470
  }
62469
62471
  });
62470
62472
 
62471
- // ../system/dist/retired-settings-keys-FwgzdSHJ.js
62472
- var require_retired_settings_keys_FwgzdSHJ = __commonJS({
62473
- "../system/dist/retired-settings-keys-FwgzdSHJ.js"(exports) {
62473
+ // ../system/dist/retired-settings-keys-BYiTW-q4.js
62474
+ var require_retired_settings_keys_BYiTW_q4 = __commonJS({
62475
+ "../system/dist/retired-settings-keys-BYiTW-q4.js"(exports) {
62474
62476
  "use strict";
62475
- var require_dist10 = require_dist_BNaW68aZ();
62477
+ var require_dist10 = require_dist_HAP38XvL();
62476
62478
  function settingsStoreIsAuthoritativeHere(env) {
62477
62479
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62478
62480
  return raw === "" || raw === "hub";
@@ -64686,8 +64688,8 @@ var require_device_manager_addon = __commonJS({
64686
64688
  [Symbol.toStringTag]: { value: "Module" }
64687
64689
  });
64688
64690
  require_chunk_Cek0wNdY();
64689
- var require_dist10 = require_dist_BNaW68aZ();
64690
- var require_retired_settings_keys = require_retired_settings_keys_FwgzdSHJ();
64691
+ var require_dist10 = require_dist_HAP38XvL();
64692
+ var require_retired_settings_keys = require_retired_settings_keys_BYiTW_q4();
64691
64693
  var node_crypto = __require("crypto");
64692
64694
  var _camstack_types_node = require_node();
64693
64695
  var JOB_HISTORY = 20;
@@ -70312,7 +70314,7 @@ var require_hub_forwarder = __commonJS({
70312
70314
  [Symbol.toStringTag]: { value: "Module" }
70313
70315
  });
70314
70316
  require_chunk_Cek0wNdY();
70315
- var require_dist10 = require_dist_BNaW68aZ();
70317
+ var require_dist10 = require_dist_HAP38XvL();
70316
70318
  var require_formatter = require_formatter_DqAKDlvN();
70317
70319
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
70318
70320
  var HubForwarderDestination = class {
@@ -70449,7 +70451,7 @@ var require_liveness_monitor_addon = __commonJS({
70449
70451
  "use strict";
70450
70452
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
70451
70453
  require_chunk_Cek0wNdY();
70452
- var require_dist10 = require_dist_BNaW68aZ();
70454
+ var require_dist10 = require_dist_HAP38XvL();
70453
70455
  var NO_DEVICES = "liveness:no-devices";
70454
70456
  var ALL_OFFLINE = "liveness:all-devices-offline";
70455
70457
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -70645,7 +70647,7 @@ var require_local_auth_addon = __commonJS({
70645
70647
  [Symbol.toStringTag]: { value: "Module" }
70646
70648
  });
70647
70649
  var require_chunk = require_chunk_Cek0wNdY();
70648
- var require_dist10 = require_dist_BNaW68aZ();
70650
+ var require_dist10 = require_dist_HAP38XvL();
70649
70651
  var node_crypto = __require("crypto");
70650
70652
  node_crypto = require_chunk.__toESM(node_crypto);
70651
70653
  var crypto$1 = __require("crypto");
@@ -78458,7 +78460,7 @@ var require_loki_logging = __commonJS({
78458
78460
  [Symbol.toStringTag]: { value: "Module" }
78459
78461
  });
78460
78462
  require_chunk_Cek0wNdY();
78461
- var require_dist10 = require_dist_BNaW68aZ();
78463
+ var require_dist10 = require_dist_HAP38XvL();
78462
78464
  function sanitizeLabelName(raw) {
78463
78465
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
78464
78466
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79023,7 +79025,7 @@ var require_native_metrics_addon = __commonJS({
79023
79025
  [Symbol.toStringTag]: { value: "Module" }
79024
79026
  });
79025
79027
  var require_chunk = require_chunk_Cek0wNdY();
79026
- var require_dist10 = require_dist_BNaW68aZ();
79028
+ var require_dist10 = require_dist_HAP38XvL();
79027
79029
  var node_fs_promises = __require("fs/promises");
79028
79030
  var node_child_process = __require("child_process");
79029
79031
  var node_util = __require("util");
@@ -81607,7 +81609,7 @@ var require_filesystem_storage_addon = __commonJS({
81607
81609
  [Symbol.toStringTag]: { value: "Module" }
81608
81610
  });
81609
81611
  var require_chunk = require_chunk_Cek0wNdY();
81610
- var require_dist10 = require_dist_BNaW68aZ();
81612
+ var require_dist10 = require_dist_HAP38XvL();
81611
81613
  var node_crypto = __require("crypto");
81612
81614
  var node_fs_promises = __require("fs/promises");
81613
81615
  var node_path = __require("path");
@@ -82723,8 +82725,8 @@ var require_sqlite_settings_addon = __commonJS({
82723
82725
  [Symbol.toStringTag]: { value: "Module" }
82724
82726
  });
82725
82727
  var require_chunk = require_chunk_Cek0wNdY();
82726
- var require_dist10 = require_dist_BNaW68aZ();
82727
- var require_retired_settings_keys = require_retired_settings_keys_FwgzdSHJ();
82728
+ var require_dist10 = require_dist_HAP38XvL();
82729
+ var require_retired_settings_keys = require_retired_settings_keys_BYiTW_q4();
82728
82730
  var node_crypto = __require("crypto");
82729
82731
  var node_fs = __require("fs");
82730
82732
  var node_module = __require("module");
@@ -85214,7 +85216,7 @@ var require_storage_orchestrator_addon = __commonJS({
85214
85216
  [Symbol.toStringTag]: { value: "Module" }
85215
85217
  });
85216
85218
  var require_chunk = require_chunk_Cek0wNdY();
85217
- var require_dist10 = require_dist_BNaW68aZ();
85219
+ var require_dist10 = require_dist_HAP38XvL();
85218
85220
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
85219
85221
  var zod = require_zod();
85220
85222
  var node_crypto = __require("crypto");
@@ -88165,7 +88167,7 @@ var require_system_config_addon = __commonJS({
88165
88167
  [Symbol.toStringTag]: { value: "Module" }
88166
88168
  });
88167
88169
  require_chunk_Cek0wNdY();
88168
- var require_dist10 = require_dist_BNaW68aZ();
88170
+ var require_dist10 = require_dist_HAP38XvL();
88169
88171
  var SECTION_TITLES = {
88170
88172
  server: "Server",
88171
88173
  auth: "Authentication"
@@ -106226,7 +106228,7 @@ var require_winston_logging = __commonJS({
106226
106228
  [Symbol.toStringTag]: { value: "Module" }
106227
106229
  });
106228
106230
  var require_chunk = require_chunk_Cek0wNdY();
106229
- var require_dist10 = require_dist_BNaW68aZ();
106231
+ var require_dist10 = require_dist_HAP38XvL();
106230
106232
  var require_formatter = require_formatter_DqAKDlvN();
106231
106233
  var node_path = __require("path");
106232
106234
  node_path = require_chunk.__toESM(node_path);
@@ -108170,9 +108172,9 @@ var require_event_category_b8kBSOTT = __commonJS({
108170
108172
  }
108171
108173
  });
108172
108174
 
108173
- // ../types/dist/sleep-BGiOgxye.js
108174
- var require_sleep_BGiOgxye = __commonJS({
108175
- "../types/dist/sleep-BGiOgxye.js"(exports) {
108175
+ // ../types/dist/sleep-DDIFZGbc.js
108176
+ var require_sleep_DDIFZGbc = __commonJS({
108177
+ "../types/dist/sleep-DDIFZGbc.js"(exports) {
108176
108178
  "use strict";
108177
108179
  var require_event_category = require_event_category_b8kBSOTT();
108178
108180
  var zod = require_zod();
@@ -111299,6 +111301,7 @@ var require_sleep_BGiOgxye = __commonJS({
111299
111301
  "ptz",
111300
111302
  "ptz-autotrack",
111301
111303
  "reboot",
111304
+ "recording-signal",
111302
111305
  "scene-monitor",
111303
111306
  "script-runner",
111304
111307
  "smoke",
@@ -111903,7 +111906,7 @@ var require_addon = __commonJS({
111903
111906
  "use strict";
111904
111907
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
111905
111908
  var require_event_category = require_event_category_b8kBSOTT();
111906
- var require_sleep = require_sleep_BGiOgxye();
111909
+ var require_sleep = require_sleep_DDIFZGbc();
111907
111910
  var require_err_msg = require_err_msg_COpsHMw2();
111908
111911
  var CAP_INPUT_DEFAULTS = Object.freeze({
111909
111912
  "addons": { "getLogs": { "limit": 100 } },
@@ -130863,7 +130866,7 @@ var require_dist3 = __commonJS({
130863
130866
  "use strict";
130864
130867
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
130865
130868
  var require_chunk = require_chunk_Cek0wNdY();
130866
- var require_dist10 = require_dist_BNaW68aZ();
130869
+ var require_dist10 = require_dist_HAP38XvL();
130867
130870
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
130868
130871
  require_alerts();
130869
130872
  var require_formatter = require_formatter_DqAKDlvN();
@@ -211980,7 +211983,7 @@ var require_dist4 = __commonJS({
211980
211983
  "use strict";
211981
211984
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
211982
211985
  var require_event_category = require_event_category_b8kBSOTT();
211983
- var require_sleep = require_sleep_BGiOgxye();
211986
+ var require_sleep = require_sleep_DDIFZGbc();
211984
211987
  var require_canonical_hash = require_canonical_hash_DNV8S5ET();
211985
211988
  var require_enums2 = require_enums();
211986
211989
  var require_err_msg = require_err_msg_COpsHMw2();
@@ -212705,21 +212708,21 @@ var require_dist4 = __commonJS({
212705
212708
  for (const section of sectionsOf(schema)) if (fieldsOf(section).length > 0) return true;
212706
212709
  return false;
212707
212710
  }
212708
- function isRecord$2(value) {
212711
+ function isRecord$3(value) {
212709
212712
  return typeof value === "object" && value !== null && !Array.isArray(value);
212710
212713
  }
212711
212714
  function sectionsOf(schema) {
212712
- if (!isRecord$2(schema)) return [];
212715
+ if (!isRecord$3(schema)) return [];
212713
212716
  const sections = schema["sections"];
212714
212717
  return Array.isArray(sections) ? sections : [];
212715
212718
  }
212716
212719
  function fieldsOf(node) {
212717
- if (!isRecord$2(node)) return [];
212720
+ if (!isRecord$3(node)) return [];
212718
212721
  const fields = node["fields"];
212719
212722
  return Array.isArray(fields) ? fields : [];
212720
212723
  }
212721
212724
  function walkField(field, out) {
212722
- if (!isRecord$2(field)) return;
212725
+ if (!isRecord$3(field)) return;
212723
212726
  const type = field["type"];
212724
212727
  const key = field["key"];
212725
212728
  if ((type === "password" || field["secret"] === true) && typeof key === "string" && key.length > 0) out.add(key);
@@ -212787,12 +212790,12 @@ var require_dist4 = __commonJS({
212787
212790
  function isString2(v) {
212788
212791
  return typeof v === "string";
212789
212792
  }
212790
- function isRecord$1(v) {
212793
+ function isRecord$2(v) {
212791
212794
  return typeof v === "object" && v !== null && !Array.isArray(v);
212792
212795
  }
212793
212796
  function parseStreamEntry(v) {
212794
212797
  if (isString2(v) && v.trim()) return { url: v };
212795
- if (isRecord$1(v) && isString2(v["url"]) && v["url"].trim()) return {
212798
+ if (isRecord$2(v) && isString2(v["url"]) && v["url"].trim()) return {
212796
212799
  url: v["url"],
212797
212800
  label: isString2(v["label"]) ? v["label"] : void 0
212798
212801
  };
@@ -213197,7 +213200,8 @@ var require_dist4 = __commonJS({
213197
213200
  var RecordingStorageModeSchema = zod.z.enum([
213198
213201
  "off",
213199
213202
  "events",
213200
- "continuous"
213203
+ "continuous",
213204
+ "on-device-decision"
213201
213205
  ]);
213202
213206
  var RecordingObjectTriggerClassSchema = zod.z.enum(FIRST_LEVEL_MACRO_CLASSES);
213203
213207
  var noDuplicates = (values) => new Set(values).size === values.length;
@@ -213235,22 +213239,7 @@ var require_dist4 = __commonJS({
213235
213239
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
213236
213240
  * registrare.
213237
213241
  */
213238
- sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional(),
213239
- /**
213240
- * La camera registra per tutta la durata del SEGNALE che lei stessa
213241
- * pubblica — la cap `recording-signal` (`active: true` mentre il device è in
213242
- * funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
213243
- * resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
213244
- * caduta, così una pulizia di quaranta minuti è UNA clip.
213245
- *
213246
- * Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
213247
- * suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
213248
- * riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
213249
- * segnale mai abbassato (un evento perso) non può tenere aperta una
213250
- * registrazione (D11). Vedi `recorder/addon/band-decision.ts`
213251
- * (`holdTrigger` / `releaseTrigger`).
213252
- */
213253
- deviceSignal: zod.z.boolean().optional()
213242
+ sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
213254
213243
  });
213255
213244
  var RecordingBandModeSchema = zod.z.enum(["continuous", "events"]);
213256
213245
  var RecordingBandTriggersSchema = RecordingTriggersSchema;
@@ -213291,10 +213280,33 @@ var require_dist4 = __commonJS({
213291
213280
  * "off" is the absence of a covering band, never a band value.
213292
213281
  */
213293
213282
  bands: zod.z.array(RecordingBandSchema).default([]),
213283
+ /**
213284
+ * THE device-decided intent: record for as long as the camera itself raises
213285
+ * `recording-signal` (`active: true` while the device is in function — a
213286
+ * robot that cleans). AUTHORED, unlike `mode`, and the only authored
213287
+ * recording intent that is not a band.
213288
+ *
213289
+ * It carries NO schedule on purpose. A band is an HOUR, and this feature has
213290
+ * no hour to program: the device decides. What it costs the operator is one
213291
+ * flag — "this camera can record on its own" — and what it buys is the same
213292
+ * hold/release the recorder already implements (D371, `holdTrigger` /
213293
+ * `releaseTrigger`): the window opens on the rise, stays open for the whole
213294
+ * job however long it is, and closes one pad after the fall.
213295
+ *
213296
+ * EXCLUSIVE with `bands` (below): two authorities deciding when the same
213297
+ * camera records is the D62 failure. `off` remains `enabled: false`, so an
213298
+ * operator switching this camera off is REPORTED off, never as broken.
213299
+ */
213300
+ deviceDecision: zod.z.boolean().optional(),
213294
213301
  retention: RecordingRetentionSchema.optional()
213295
- }).strict();
213302
+ }).strict().refine((config) => config.deviceDecision !== true || config.bands.length === 0, {
213303
+ message: "deviceDecision is a whole-config mode and carries no schedule: it cannot be combined with bands",
213304
+ path: ["bands"]
213305
+ });
213296
213306
  function deriveRecordingMode(config) {
213297
- if (!config.enabled || config.bands.length === 0) return "off";
213307
+ if (!config.enabled) return "off";
213308
+ if (config.deviceDecision === true) return "on-device-decision";
213309
+ if (config.bands.length === 0) return "off";
213298
213310
  if (config.bands.some((band) => band.mode === "continuous")) return "continuous";
213299
213311
  return "events";
213300
213312
  }
@@ -213307,6 +213319,67 @@ var require_dist4 = __commonJS({
213307
213319
  const preferred = assigned.filter((profile) => DEFAULT_RECORDING_PROFILES.includes(profile));
213308
213320
  return preferred.length > 0 ? preferred : [...assigned];
213309
213321
  }
213322
+ var SURVIVING_TRIGGER_KEYS = [
213323
+ "motion",
213324
+ "audioThresholdDbfs",
213325
+ "objectClasses",
213326
+ "sensorDeviceIds"
213327
+ ];
213328
+ function isRecord$1(value) {
213329
+ return typeof value === "object" && value !== null && !Array.isArray(value);
213330
+ }
213331
+ function listensToLegacySignal(band) {
213332
+ return isRecord$1(band) && isRecord$1(band.triggers) && band.triggers.deviceSignal === true;
213333
+ }
213334
+ function hasSurvivingTrigger(band) {
213335
+ const triggers = band.triggers;
213336
+ if (!isRecord$1(triggers)) return false;
213337
+ return SURVIVING_TRIGGER_KEYS.some((key) => triggers[key] !== void 0);
213338
+ }
213339
+ function withoutLegacySignal(band) {
213340
+ const triggers = band.triggers;
213341
+ if (!isRecord$1(triggers)) return band;
213342
+ const { deviceSignal: _retired, ...rest } = triggers;
213343
+ return {
213344
+ ...band,
213345
+ triggers: rest
213346
+ };
213347
+ }
213348
+ function migrateLegacyDeviceSignalConfig(raw) {
213349
+ const unchanged = {
213350
+ value: raw,
213351
+ migrated: false,
213352
+ strippedOnly: false
213353
+ };
213354
+ if (!isRecord$1(raw) || !Array.isArray(raw.bands)) return unchanged;
213355
+ if (!raw.bands.some(listensToLegacySignal)) return unchanged;
213356
+ const kept = [];
213357
+ for (const band of raw.bands) {
213358
+ if (!listensToLegacySignal(band) || !isRecord$1(band)) {
213359
+ kept.push(band);
213360
+ continue;
213361
+ }
213362
+ if (hasSurvivingTrigger(band)) kept.push(withoutLegacySignal(band));
213363
+ }
213364
+ if (kept.length > 0) return {
213365
+ value: {
213366
+ ...raw,
213367
+ bands: kept
213368
+ },
213369
+ migrated: false,
213370
+ strippedOnly: true
213371
+ };
213372
+ const { mode: _derived, ...rest } = raw;
213373
+ return {
213374
+ value: {
213375
+ ...rest,
213376
+ bands: [],
213377
+ deviceDecision: true
213378
+ },
213379
+ migrated: true,
213380
+ strippedOnly: false
213381
+ };
213382
+ }
213310
213383
  var RelocateJobStateSchema = zod.z.enum([
213311
213384
  "queued",
213312
213385
  "running",
@@ -228556,11 +228629,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
228556
228629
  nodeId: zod.z.string(),
228557
228630
  enabled: zod.z.boolean()
228558
228631
  });
228559
- var CameraRecordingModeSchema = zod.z.enum([
228560
- "off",
228561
- "continuous",
228562
- "events"
228563
- ]);
228632
+ var CameraRecordingModeSchema = RecordingStorageModeSchema;
228564
228633
  var CameraRecordingStatusSchema = zod.z.object({
228565
228634
  mode: CameraRecordingModeSchema,
228566
228635
  active: zod.z.boolean(),
@@ -237030,11 +237099,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
237030
237099
  var RecordingStatusSchema = zod.z.object({
237031
237100
  deviceId: zod.z.number(),
237032
237101
  enabled: zod.z.boolean(),
237033
- activeMode: zod.z.enum([
237034
- "off",
237035
- "continuous",
237036
- "events"
237037
- ]),
237102
+ /** THE derived storage mode, from the one definition
237103
+ * (`deriveRecordingMode`) — never a second enum. A duplicated list is how
237104
+ * `on-device-decision` could have reached the recorder and not the status. */
237105
+ activeMode: RecordingStorageModeSchema,
237038
237106
  nodeId: zod.z.string(),
237039
237107
  storageBytes: zod.z.number()
237040
237108
  });
@@ -257320,6 +257388,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257320
257388
  exports.method = require_sleep.method;
257321
257389
  exports.methodAccessForHttpMethod = methodAccessForHttpMethod;
257322
257390
  exports.metricsProviderCapability = metricsProviderCapability;
257391
+ exports.migrateLegacyDeviceSignalConfig = migrateLegacyDeviceSignalConfig;
257323
257392
  exports.modelConvertCapability = modelConvertCapability;
257324
257393
  exports.modelDistributorCapability = modelDistributorCapability;
257325
257394
  exports.modelFormatForRuntime = modelFormatForRuntime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.108",
3
+ "version": "1.2.109",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",