camstack 1.2.160 → 1.2.162

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.
@@ -19746,7 +19746,23 @@ var PickStreamRequirementsSchema = external_exports.object({
19746
19746
  * This is what lets one picker serve both the bypass and the full source
19747
19747
  * choice, instead of a consumer scoring privately when the bypass misses.
19748
19748
  */
19749
- allowTranscode: external_exports.boolean().optional()
19749
+ allowTranscode: external_exports.boolean().optional(),
19750
+ /**
19751
+ * Consider ONLY streams the broker has bound to a profile slot.
19752
+ *
19753
+ * A consumer that dials the broker — which is every exporter, since none
19754
+ * of them may open the camera's own URL — can do nothing with a source
19755
+ * that has no slot: there is no restream to dial. Without this the picker
19756
+ * can name such a stream, and each consumer discovers the dead end for
19757
+ * itself: Alexa's `profileForCamStream` returns `null` and it quietly
19758
+ * falls back, and HomeKit would have had to grow the same function again.
19759
+ *
19760
+ * Default `false`, and deliberately so: the BROKER itself picks through
19761
+ * here when it decides which source to BIND to a slot
19762
+ * (`computeInitialAssignment`), and it must see the unbound ones or it
19763
+ * could never bind them.
19764
+ */
19765
+ requireProfileBound: external_exports.boolean().optional()
19750
19766
  }).readonly();
19751
19767
  var PickStreamPreferencesSchema = external_exports.object({
19752
19768
  /**
@@ -19787,7 +19803,43 @@ var PickedCamStreamSchema = external_exports.object({
19787
19803
  */
19788
19804
  transcodes: external_exports.boolean(),
19789
19805
  /** One-line explanation of why this stream won — for logs / debug UI. */
19790
- reason: external_exports.string()
19806
+ reason: external_exports.string(),
19807
+ /**
19808
+ * The broker profile slot this source is bound to, when it is bound.
19809
+ *
19810
+ * Answered HERE because every consumer needs it and none of them can get it
19811
+ * from the `camStreamId` alone. Alexa wrote `profileForCamStream` for it —
19812
+ * a second cap read plus a `null` branch — and HomeKit was about to write
19813
+ * the same function a second time.
19814
+ *
19815
+ * Absent when the source has no slot, which a caller passing
19816
+ * `requireProfileBound` can never see.
19817
+ */
19818
+ profile: CamProfileSchema.optional(),
19819
+ /** The broker id of that slot, for logs that must name what was dialled. */
19820
+ brokerId: external_exports.string().optional(),
19821
+ /**
19822
+ * The broker restream URL to dial for this stream.
19823
+ *
19824
+ * An exporter must never open the camera's own URL — the broker is the one
19825
+ * that dials the camera, and every consumer goes through its restream. So
19826
+ * the picker answers with the thing a consumer may actually use, instead of
19827
+ * naming a source and leaving each caller to look the URL up.
19828
+ */
19829
+ url: external_exports.string().optional(),
19830
+ /**
19831
+ * Frames per second this stream really delivers, and where the number came
19832
+ * from.
19833
+ *
19834
+ * It is here because getting it wrong is expensive and silent: a HomeKit
19835
+ * accessory advertised 720p at 24 fps while the slot serving it ran at 9,
19836
+ * and the controller rendered nothing at all. The source is carried with the
19837
+ * value for the same reason the bitrate evidence is: `published` is what the
19838
+ * publisher declares and `measured` is what the broker observed, and they
19839
+ * are not interchangeable.
19840
+ */
19841
+ fps: external_exports.number().positive().optional(),
19842
+ fpsSource: external_exports.enum(["published", "measured"]).optional()
19791
19843
  });
19792
19844
  var cameraStreamsCapability = {
19793
19845
  name: "camera-streams",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-VJIT6AOW.js";
4
+ } from "./chunk-QT7LGBTP.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-HOXPTYJH.js");
41
+ await import("./launcher-3GIYBFMQ.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-HOXPTYJH.js");
86
+ await import("./launcher-3GIYBFMQ.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1140,7 +1140,7 @@ function isUnknown(_value) {
1140
1140
  return true;
1141
1141
  }
1142
1142
  async function resolveServerInteractive(presetNamespace) {
1143
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-N63N6OOD.js");
1143
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-NGNF47ZY.js");
1144
1144
  if (presetNamespace) {
1145
1145
  const spinner4 = clack.spinner();
1146
1146
  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-VJIT6AOW.js";
8
+ } from "./chunk-QT7LGBTP.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-Cz6h6Nc3.js
23637
- var require_dist_Cz6h6Nc3 = __commonJS({
23638
- "../system/dist/dist-Cz6h6Nc3.js"(exports) {
23636
+ // ../system/dist/dist-CpXBoZOv.js
23637
+ var require_dist_CpXBoZOv = __commonJS({
23638
+ "../system/dist/dist-CpXBoZOv.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -30405,7 +30405,23 @@ var require_dist_Cz6h6Nc3 = __commonJS({
30405
30405
  * This is what lets one picker serve both the bypass and the full source
30406
30406
  * choice, instead of a consumer scoring privately when the bypass misses.
30407
30407
  */
30408
- allowTranscode: zod.z.boolean().optional()
30408
+ allowTranscode: zod.z.boolean().optional(),
30409
+ /**
30410
+ * Consider ONLY streams the broker has bound to a profile slot.
30411
+ *
30412
+ * A consumer that dials the broker — which is every exporter, since none
30413
+ * of them may open the camera's own URL — can do nothing with a source
30414
+ * that has no slot: there is no restream to dial. Without this the picker
30415
+ * can name such a stream, and each consumer discovers the dead end for
30416
+ * itself: Alexa's `profileForCamStream` returns `null` and it quietly
30417
+ * falls back, and HomeKit would have had to grow the same function again.
30418
+ *
30419
+ * Default `false`, and deliberately so: the BROKER itself picks through
30420
+ * here when it decides which source to BIND to a slot
30421
+ * (`computeInitialAssignment`), and it must see the unbound ones or it
30422
+ * could never bind them.
30423
+ */
30424
+ requireProfileBound: zod.z.boolean().optional()
30409
30425
  }).readonly();
30410
30426
  var PickStreamPreferencesSchema = zod.z.object({
30411
30427
  /**
@@ -30446,7 +30462,43 @@ var require_dist_Cz6h6Nc3 = __commonJS({
30446
30462
  */
30447
30463
  transcodes: zod.z.boolean(),
30448
30464
  /** One-line explanation of why this stream won — for logs / debug UI. */
30449
- reason: zod.z.string()
30465
+ reason: zod.z.string(),
30466
+ /**
30467
+ * The broker profile slot this source is bound to, when it is bound.
30468
+ *
30469
+ * Answered HERE because every consumer needs it and none of them can get it
30470
+ * from the `camStreamId` alone. Alexa wrote `profileForCamStream` for it —
30471
+ * a second cap read plus a `null` branch — and HomeKit was about to write
30472
+ * the same function a second time.
30473
+ *
30474
+ * Absent when the source has no slot, which a caller passing
30475
+ * `requireProfileBound` can never see.
30476
+ */
30477
+ profile: CamProfileSchema.optional(),
30478
+ /** The broker id of that slot, for logs that must name what was dialled. */
30479
+ brokerId: zod.z.string().optional(),
30480
+ /**
30481
+ * The broker restream URL to dial for this stream.
30482
+ *
30483
+ * An exporter must never open the camera's own URL — the broker is the one
30484
+ * that dials the camera, and every consumer goes through its restream. So
30485
+ * the picker answers with the thing a consumer may actually use, instead of
30486
+ * naming a source and leaving each caller to look the URL up.
30487
+ */
30488
+ url: zod.z.string().optional(),
30489
+ /**
30490
+ * Frames per second this stream really delivers, and where the number came
30491
+ * from.
30492
+ *
30493
+ * It is here because getting it wrong is expensive and silent: a HomeKit
30494
+ * accessory advertised 720p at 24 fps while the slot serving it ran at 9,
30495
+ * and the controller rendered nothing at all. The source is carried with the
30496
+ * value for the same reason the bitrate evidence is: `published` is what the
30497
+ * publisher declares and `measured` is what the broker observed, and they
30498
+ * are not interchangeable.
30499
+ */
30500
+ fps: zod.z.number().positive().optional(),
30501
+ fpsSource: zod.z.enum(["published", "measured"]).optional()
30450
30502
  });
30451
30503
  var cameraStreamsCapability = {
30452
30504
  name: "camera-streams",
@@ -62805,7 +62857,7 @@ var require_alerts_addon = __commonJS({
62805
62857
  [Symbol.toStringTag]: { value: "Module" }
62806
62858
  });
62807
62859
  require_chunk_Cek0wNdY();
62808
- var require_dist10 = require_dist_Cz6h6Nc3();
62860
+ var require_dist10 = require_dist_CpXBoZOv();
62809
62861
  function selectExpired(alerts, cutoffMs) {
62810
62862
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
62811
62863
  }
@@ -63624,7 +63676,7 @@ var require_console_logging = __commonJS({
63624
63676
  [Symbol.toStringTag]: { value: "Module" }
63625
63677
  });
63626
63678
  require_chunk_Cek0wNdY();
63627
- var require_dist10 = require_dist_Cz6h6Nc3();
63679
+ var require_dist10 = require_dist_CpXBoZOv();
63628
63680
  var require_formatter = require_formatter_DqAKDlvN();
63629
63681
  var LEVEL_RANK = {
63630
63682
  debug: 0,
@@ -63718,7 +63770,7 @@ var require_core_blocks_addon = __commonJS({
63718
63770
  "use strict";
63719
63771
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
63720
63772
  var require_chunk = require_chunk_Cek0wNdY();
63721
- var require_dist10 = require_dist_Cz6h6Nc3();
63773
+ var require_dist10 = require_dist_CpXBoZOv();
63722
63774
  var node_crypto = __require("crypto");
63723
63775
  var node_fs_promises = __require("fs/promises");
63724
63776
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -64615,11 +64667,11 @@ var require_core_blocks = __commonJS({
64615
64667
  }
64616
64668
  });
64617
64669
 
64618
- // ../system/dist/retired-settings-keys-DBrIdOQp.js
64619
- var require_retired_settings_keys_DBrIdOQp = __commonJS({
64620
- "../system/dist/retired-settings-keys-DBrIdOQp.js"(exports) {
64670
+ // ../system/dist/retired-settings-keys-1sEBolVU.js
64671
+ var require_retired_settings_keys_1sEBolVU = __commonJS({
64672
+ "../system/dist/retired-settings-keys-1sEBolVU.js"(exports) {
64621
64673
  "use strict";
64622
- var require_dist10 = require_dist_Cz6h6Nc3();
64674
+ var require_dist10 = require_dist_CpXBoZOv();
64623
64675
  function settingsStoreIsAuthoritativeHere(env) {
64624
64676
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
64625
64677
  return raw === "" || raw === "hub";
@@ -66856,8 +66908,8 @@ var require_device_manager_addon = __commonJS({
66856
66908
  [Symbol.toStringTag]: { value: "Module" }
66857
66909
  });
66858
66910
  require_chunk_Cek0wNdY();
66859
- var require_dist10 = require_dist_Cz6h6Nc3();
66860
- var require_retired_settings_keys = require_retired_settings_keys_DBrIdOQp();
66911
+ var require_dist10 = require_dist_CpXBoZOv();
66912
+ var require_retired_settings_keys = require_retired_settings_keys_1sEBolVU();
66861
66913
  var node_crypto = __require("crypto");
66862
66914
  var _camstack_types_node = require_node();
66863
66915
  var JOB_HISTORY = 20;
@@ -72865,7 +72917,7 @@ var require_hub_forwarder = __commonJS({
72865
72917
  [Symbol.toStringTag]: { value: "Module" }
72866
72918
  });
72867
72919
  require_chunk_Cek0wNdY();
72868
- var require_dist10 = require_dist_Cz6h6Nc3();
72920
+ var require_dist10 = require_dist_CpXBoZOv();
72869
72921
  var require_formatter = require_formatter_DqAKDlvN();
72870
72922
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
72871
72923
  var HubForwarderDestination = class {
@@ -73002,7 +73054,7 @@ var require_liveness_monitor_addon = __commonJS({
73002
73054
  "use strict";
73003
73055
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
73004
73056
  require_chunk_Cek0wNdY();
73005
- var require_dist10 = require_dist_Cz6h6Nc3();
73057
+ var require_dist10 = require_dist_CpXBoZOv();
73006
73058
  var NO_DEVICES = "liveness:no-devices";
73007
73059
  var ALL_OFFLINE = "liveness:all-devices-offline";
73008
73060
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -73198,7 +73250,7 @@ var require_local_auth_addon = __commonJS({
73198
73250
  [Symbol.toStringTag]: { value: "Module" }
73199
73251
  });
73200
73252
  var require_chunk = require_chunk_Cek0wNdY();
73201
- var require_dist10 = require_dist_Cz6h6Nc3();
73253
+ var require_dist10 = require_dist_CpXBoZOv();
73202
73254
  var node_crypto = __require("crypto");
73203
73255
  node_crypto = require_chunk.__toESM(node_crypto);
73204
73256
  var crypto$1 = __require("crypto");
@@ -81011,7 +81063,7 @@ var require_loki_logging = __commonJS({
81011
81063
  [Symbol.toStringTag]: { value: "Module" }
81012
81064
  });
81013
81065
  require_chunk_Cek0wNdY();
81014
- var require_dist10 = require_dist_Cz6h6Nc3();
81066
+ var require_dist10 = require_dist_CpXBoZOv();
81015
81067
  function sanitizeLabelName(raw) {
81016
81068
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
81017
81069
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -81598,7 +81650,7 @@ var require_native_metrics_addon = __commonJS({
81598
81650
  [Symbol.toStringTag]: { value: "Module" }
81599
81651
  });
81600
81652
  var require_chunk = require_chunk_Cek0wNdY();
81601
- var require_dist10 = require_dist_Cz6h6Nc3();
81653
+ var require_dist10 = require_dist_CpXBoZOv();
81602
81654
  var node_fs_promises = __require("fs/promises");
81603
81655
  var node_fs = __require("fs");
81604
81656
  node_fs = require_chunk.__toESM(node_fs);
@@ -84351,7 +84403,7 @@ var require_filesystem_storage_addon = __commonJS({
84351
84403
  [Symbol.toStringTag]: { value: "Module" }
84352
84404
  });
84353
84405
  var require_chunk = require_chunk_Cek0wNdY();
84354
- var require_dist10 = require_dist_Cz6h6Nc3();
84406
+ var require_dist10 = require_dist_CpXBoZOv();
84355
84407
  var node_crypto = __require("crypto");
84356
84408
  var node_fs_promises = __require("fs/promises");
84357
84409
  var node_path = __require("path");
@@ -85578,8 +85630,8 @@ var require_sqlite_settings_addon = __commonJS({
85578
85630
  [Symbol.toStringTag]: { value: "Module" }
85579
85631
  });
85580
85632
  var require_chunk = require_chunk_Cek0wNdY();
85581
- var require_dist10 = require_dist_Cz6h6Nc3();
85582
- var require_retired_settings_keys = require_retired_settings_keys_DBrIdOQp();
85633
+ var require_dist10 = require_dist_CpXBoZOv();
85634
+ var require_retired_settings_keys = require_retired_settings_keys_1sEBolVU();
85583
85635
  var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
85584
85636
  var node_crypto = __require("crypto");
85585
85637
  var node_path = __require("path");
@@ -88366,7 +88418,7 @@ var require_storage_orchestrator_addon = __commonJS({
88366
88418
  [Symbol.toStringTag]: { value: "Module" }
88367
88419
  });
88368
88420
  var require_chunk = require_chunk_Cek0wNdY();
88369
- var require_dist10 = require_dist_Cz6h6Nc3();
88421
+ var require_dist10 = require_dist_CpXBoZOv();
88370
88422
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
88371
88423
  var zod = require_zod();
88372
88424
  var node_crypto = __require("crypto");
@@ -92093,7 +92145,7 @@ var require_system_config_addon = __commonJS({
92093
92145
  [Symbol.toStringTag]: { value: "Module" }
92094
92146
  });
92095
92147
  require_chunk_Cek0wNdY();
92096
- var require_dist10 = require_dist_Cz6h6Nc3();
92148
+ var require_dist10 = require_dist_CpXBoZOv();
92097
92149
  var SECTION_TITLES = {
92098
92150
  server: "Server",
92099
92151
  auth: "Authentication"
@@ -110154,7 +110206,7 @@ var require_winston_logging = __commonJS({
110154
110206
  [Symbol.toStringTag]: { value: "Module" }
110155
110207
  });
110156
110208
  var require_chunk = require_chunk_Cek0wNdY();
110157
- var require_dist10 = require_dist_Cz6h6Nc3();
110209
+ var require_dist10 = require_dist_CpXBoZOv();
110158
110210
  var require_formatter = require_formatter_DqAKDlvN();
110159
110211
  var node_path = __require("path");
110160
110212
  node_path = require_chunk.__toESM(node_path);
@@ -136421,7 +136473,7 @@ var require_dist3 = __commonJS({
136421
136473
  "use strict";
136422
136474
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
136423
136475
  var require_chunk = require_chunk_Cek0wNdY();
136424
- var require_dist10 = require_dist_Cz6h6Nc3();
136476
+ var require_dist10 = require_dist_CpXBoZOv();
136425
136477
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
136426
136478
  require_alerts();
136427
136479
  var require_formatter = require_formatter_DqAKDlvN();
@@ -224230,7 +224282,23 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
224230
224282
  * This is what lets one picker serve both the bypass and the full source
224231
224283
  * choice, instead of a consumer scoring privately when the bypass misses.
224232
224284
  */
224233
- allowTranscode: zod.z.boolean().optional()
224285
+ allowTranscode: zod.z.boolean().optional(),
224286
+ /**
224287
+ * Consider ONLY streams the broker has bound to a profile slot.
224288
+ *
224289
+ * A consumer that dials the broker — which is every exporter, since none
224290
+ * of them may open the camera's own URL — can do nothing with a source
224291
+ * that has no slot: there is no restream to dial. Without this the picker
224292
+ * can name such a stream, and each consumer discovers the dead end for
224293
+ * itself: Alexa's `profileForCamStream` returns `null` and it quietly
224294
+ * falls back, and HomeKit would have had to grow the same function again.
224295
+ *
224296
+ * Default `false`, and deliberately so: the BROKER itself picks through
224297
+ * here when it decides which source to BIND to a slot
224298
+ * (`computeInitialAssignment`), and it must see the unbound ones or it
224299
+ * could never bind them.
224300
+ */
224301
+ requireProfileBound: zod.z.boolean().optional()
224234
224302
  }).readonly();
224235
224303
  var PickStreamPreferencesSchema = zod.z.object({
224236
224304
  /**
@@ -224271,7 +224339,43 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
224271
224339
  */
224272
224340
  transcodes: zod.z.boolean(),
224273
224341
  /** One-line explanation of why this stream won — for logs / debug UI. */
224274
- reason: zod.z.string()
224342
+ reason: zod.z.string(),
224343
+ /**
224344
+ * The broker profile slot this source is bound to, when it is bound.
224345
+ *
224346
+ * Answered HERE because every consumer needs it and none of them can get it
224347
+ * from the `camStreamId` alone. Alexa wrote `profileForCamStream` for it —
224348
+ * a second cap read plus a `null` branch — and HomeKit was about to write
224349
+ * the same function a second time.
224350
+ *
224351
+ * Absent when the source has no slot, which a caller passing
224352
+ * `requireProfileBound` can never see.
224353
+ */
224354
+ profile: require_sleep.CamProfileSchema.optional(),
224355
+ /** The broker id of that slot, for logs that must name what was dialled. */
224356
+ brokerId: zod.z.string().optional(),
224357
+ /**
224358
+ * The broker restream URL to dial for this stream.
224359
+ *
224360
+ * An exporter must never open the camera's own URL — the broker is the one
224361
+ * that dials the camera, and every consumer goes through its restream. So
224362
+ * the picker answers with the thing a consumer may actually use, instead of
224363
+ * naming a source and leaving each caller to look the URL up.
224364
+ */
224365
+ url: zod.z.string().optional(),
224366
+ /**
224367
+ * Frames per second this stream really delivers, and where the number came
224368
+ * from.
224369
+ *
224370
+ * It is here because getting it wrong is expensive and silent: a HomeKit
224371
+ * accessory advertised 720p at 24 fps while the slot serving it ran at 9,
224372
+ * and the controller rendered nothing at all. The source is carried with the
224373
+ * value for the same reason the bitrate evidence is: `published` is what the
224374
+ * publisher declares and `measured` is what the broker observed, and they
224375
+ * are not interchangeable.
224376
+ */
224377
+ fps: zod.z.number().positive().optional(),
224378
+ fpsSource: zod.z.enum(["published", "measured"]).optional()
224275
224379
  });
224276
224380
  var cameraStreamsCapability = {
224277
224381
  name: "camera-streams",
@@ -425770,7 +425874,23 @@ var require_share_token_service = __commonJS({
425770
425874
  exports.SHARE_TOKEN_MAX_DEVICES = 64;
425771
425875
  exports.ShareTokenScopeSchema = zod_1.z.object({
425772
425876
  kind: zod_1.z.enum(types_1.SHARE_VIEW_KINDS),
425773
- deviceIds: zod_1.z.array(zod_1.z.number().int().nonnegative()).min(1).max(exports.SHARE_TOKEN_MAX_DEVICES)
425877
+ deviceIds: zod_1.z.array(zod_1.z.number().int().nonnegative()).min(1).max(exports.SHARE_TOKEN_MAX_DEVICES),
425878
+ /**
425879
+ * TALK-BACK, opt-in at mint time. Absent means OFF, and that is the whole
425880
+ * point: a share link is handed to third parties, so the difference between
425881
+ * "can watch the kitchen" and "can speak into the kitchen" must be a choice
425882
+ * somebody made for THAT link, on the day they made it.
425883
+ *
425884
+ * It rides on the scope rather than widening the grid enumeration because
425885
+ * the enumeration is retroactive: a method added there is granted to every
425886
+ * token ever minted, including the one handed to a neighbour last week.
425887
+ * `share-view-access.ts` says so about event history; the same rule with
425888
+ * actuation into the home on the other end of it is not a smaller matter.
425889
+ *
425890
+ * It widens WHAT may be called, never WHICH cameras — `deviceIds` still
425891
+ * gates every talk call.
425892
+ */
425893
+ talk: zod_1.z.boolean().optional()
425774
425894
  });
425775
425895
  exports.ShareTokenRecordSchema = zod_1.z.object({
425776
425896
  id: zod_1.z.string(),
@@ -427374,6 +427494,11 @@ var require_share_view_access = __commonJS({
427374
427494
  "turnProvider.getTurnServers",
427375
427495
  "live.onEvent"
427376
427496
  ]);
427497
+ var GRID_VIEW_TALK_METHODS = /* @__PURE__ */ new Set([
427498
+ "intercom.startSession",
427499
+ "intercom.handleAnswer",
427500
+ "intercom.stopSession"
427501
+ ]);
427377
427502
  var GRID_VIEW_DEVICE_METHODS = /* @__PURE__ */ new Set([
427378
427503
  "snapshot.getSnapshot",
427379
427504
  "pipelineOrchestrator.getCameraMetrics",
@@ -427448,7 +427573,12 @@ var require_share_view_access = __commonJS({
427448
427573
  if (GRID_VIEW_OPEN_METHODS.has(path)) {
427449
427574
  return { ok: true };
427450
427575
  }
427451
- if (GRID_VIEW_DEVICE_METHODS.has(path)) {
427576
+ if (GRID_VIEW_TALK_METHODS.has(path)) {
427577
+ if (scope.talk !== true) {
427578
+ return { ok: false, reason: `'${path}' needs a share link minted with talk-back` };
427579
+ }
427580
+ }
427581
+ if (GRID_VIEW_TALK_METHODS.has(path) || GRID_VIEW_DEVICE_METHODS.has(path)) {
427452
427582
  const deviceId = extractDeviceId(input);
427453
427583
  if (deviceId === null) {
427454
427584
  return { ok: false, reason: `'${path}' requires a numeric deviceId for share-view access` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.160",
3
+ "version": "1.2.162",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",