camstack 1.2.138 → 1.2.140

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.
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-B17W9ngu.js
23637
- var require_dist_B17W9ngu = __commonJS({
23638
- "../system/dist/dist-B17W9ngu.js"(exports) {
23636
+ // ../system/dist/dist-0sWJNwme.js
23637
+ var require_dist_0sWJNwme = __commonJS({
23638
+ "../system/dist/dist-0sWJNwme.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -23793,6 +23793,34 @@ var require_dist_B17W9ngu = __commonJS({
23793
23793
  EventCategory2["ModelConvertProgress"] = "model-convert.progress";
23794
23794
  return EventCategory2;
23795
23795
  })({});
23796
+ var AUDIO_CHUNK_FORMATS = [
23797
+ "f32le",
23798
+ "pcmu",
23799
+ "pcma"
23800
+ ];
23801
+ function buildUlawTable() {
23802
+ const table2 = new Float32Array(256);
23803
+ for (let i = 0; i < 256; i++) {
23804
+ const complemented = ~i & 255;
23805
+ const sign = (complemented & 128) !== 0 ? -1 : 1;
23806
+ const exponent = complemented >> 4 & 7;
23807
+ table2[i] = sign * ((8 * (complemented & 15) + 132 << exponent) - 132) / 32768;
23808
+ }
23809
+ return table2;
23810
+ }
23811
+ function buildAlawTable() {
23812
+ const table2 = new Float32Array(256);
23813
+ for (let i = 0; i < 256; i++) {
23814
+ const xored = i ^ 85;
23815
+ const sign = (xored & 128) !== 0 ? 1 : -1;
23816
+ const exponent = xored >> 4 & 7;
23817
+ const mantissa = xored & 15;
23818
+ table2[i] = sign * (exponent === 0 ? 16 * mantissa + 8 : 16 * mantissa + 264 << exponent - 1) / 32768;
23819
+ }
23820
+ return table2;
23821
+ }
23822
+ buildUlawTable();
23823
+ buildAlawTable();
23796
23824
  var WELL_KNOWN_TAB_MAP = Object.fromEntries([
23797
23825
  {
23798
23826
  id: "overview",
@@ -24867,16 +24895,36 @@ var require_dist_B17W9ngu = __commonJS({
24867
24895
  /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
24868
24896
  maxFps: zod.z.number().nonnegative()
24869
24897
  });
24898
+ var AudioChunkFormatSchema = zod.z.enum(AUDIO_CHUNK_FORMATS);
24870
24899
  var DecodedAudioChunkSchema = zod.z.object({
24871
24900
  data: zod.z.instanceof(Uint8Array),
24872
24901
  sampleRate: zod.z.number().int().positive(),
24873
24902
  channels: zod.z.number().int().positive(),
24874
- timestamp: zod.z.number()
24903
+ timestamp: zod.z.number(),
24904
+ /**
24905
+ * Byte format of `data`. ABSENT MEANS `f32le` — today's bytes, byte for
24906
+ * byte, for any peer that never heard of this field. A coded window
24907
+ * (`pcmu` / `pcma`, one byte per sample) is only ever emitted to a
24908
+ * subscription that DECLARED it accepts one, so absence can never mean
24909
+ * "coded bytes a consumer will read as floats" (D455).
24910
+ */
24911
+ format: AudioChunkFormatSchema.optional()
24875
24912
  });
24876
24913
  var SubscribeAudioChunksInputSchema = zod.z.object({
24877
24914
  brokerId: zod.z.string(),
24878
24915
  /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
24879
- tag: zod.z.string().optional()
24916
+ tag: zod.z.string().optional(),
24917
+ /**
24918
+ * Byte formats this subscriber can READ, best first. The broker serves the
24919
+ * chunk's own format when it is in this list and expands to `f32le`
24920
+ * otherwise, so a subscriber is never handed bytes it cannot interpret.
24921
+ *
24922
+ * Absent (or without the source format) means `f32le` — the behaviour every
24923
+ * subscriber had before D455, unchanged. This is the negotiation half of
24924
+ * the source-bytes lever: it is what lets the broker and its consumers
24925
+ * deploy one at a time across three nodes.
24926
+ */
24927
+ accept: zod.z.array(AudioChunkFormatSchema).readonly().optional()
24880
24928
  });
24881
24929
  var SubscribeAudioChunksResultSchema = zod.z.object({
24882
24930
  /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
@@ -28572,6 +28620,37 @@ var require_dist_B17W9ngu = __commonJS({
28572
28620
  minConfidence: zod.z.number().min(0).max(1).default(0.3),
28573
28621
  allowedClasses: zod.z.array(zod.z.string()).default([])
28574
28622
  });
28623
+ var AudioAttachDeviceInputSchema = zod.z.object({
28624
+ deviceId: zod.z.number(),
28625
+ /** Broker id (`<deviceId>/<camStreamId>`) carrying this camera's audio. */
28626
+ brokerId: zod.z.string(),
28627
+ /**
28628
+ * `clusterRoles.ingestNode` — the node whose broker owns the source dial.
28629
+ * Every `streamBroker` call the attachment makes is pinned to it, exactly as
28630
+ * the orchestrator's poller pinned them before the move.
28631
+ */
28632
+ ingestNodeId: zod.z.string(),
28633
+ /**
28634
+ * Resolved once by the orchestrator at attach time, exactly as it was read
28635
+ * once per subscription before D461. The analyzer does NOT re-resolve per
28636
+ * window: a settings change re-attaches, which is what always happened.
28637
+ */
28638
+ settings: AudioAnalysisSettingsSchema
28639
+ });
28640
+ var AudioAttachDeviceResultSchema = zod.z.object({
28641
+ /** False only when the analyzer is shutting down and refused to attach. */
28642
+ attached: zod.z.boolean(),
28643
+ /**
28644
+ * True when the attachment replaced a live one for the same device. An
28645
+ * attach is idempotent by REPLACEMENT — two pollers on one camera would
28646
+ * double the broker's fanout and neither would know about the other.
28647
+ */
28648
+ replaced: zod.z.boolean()
28649
+ });
28650
+ var AudioDetachDeviceResultSchema = zod.z.object({
28651
+ /** False when no attachment existed — detach is idempotent. */
28652
+ detached: zod.z.boolean()
28653
+ });
28575
28654
  var AudioClassificationResultSchema = zod.z.object({
28576
28655
  labels: zod.z.array(AudioClassificationLabelSchema).readonly(),
28577
28656
  rawLabels: zod.z.array(AudioClassificationLabelSchema).readonly().optional(),
@@ -28587,6 +28666,21 @@ var require_dist_B17W9ngu = __commonJS({
28587
28666
  settings: AudioAnalysisSettingsSchema
28588
28667
  }), AudioAnalysisResultSchema.nullable(), { kind: "mutation" }),
28589
28668
  classify: method(AudioChunkInputSchema, AudioClassificationResultSchema, { timeoutMs: 3e4 }),
28669
+ /**
28670
+ * Start pulling this camera's audio from the broker, in THIS process.
28671
+ * Returns as soon as the attachment exists — the first
28672
+ * `subscribeAudioChunks` retries with backoff behind it, because the
28673
+ * broker for a camStream may not be registered yet (that tolerance moved
28674
+ * with the poller, D461). Replaces any live attachment for the device.
28675
+ */
28676
+ attachDevice: method(AudioAttachDeviceInputSchema, AudioAttachDeviceResultSchema, { kind: "mutation" }),
28677
+ /**
28678
+ * Stop pulling this camera's audio and release the broker subscription.
28679
+ * Idempotent. A detach that never arrives is the one failure mode this
28680
+ * split adds, which is why `AudioChunkPlane` reaps a subscription nobody
28681
+ * drains rather than trusting it (D461).
28682
+ */
28683
+ detachDevice: method(zod.z.object({ deviceId: zod.z.number() }), AudioDetachDeviceResultSchema, { kind: "mutation" }),
28590
28684
  isReady: method(zod.z.void(), zod.z.boolean()),
28591
28685
  dispose: method(zod.z.void(), zod.z.void(), { kind: "mutation" }),
28592
28686
  /**
@@ -39036,6 +39130,14 @@ var require_dist_B17W9ngu = __commonJS({
39036
39130
  * set `encodeJpeg: true`; `bytes` is then absent.
39037
39131
  */
39038
39132
  jpeg: zod.z.string().optional(),
39133
+ /**
39134
+ * The SAME compressed JPEG as `jpeg`, as bytes (D462). Present instead of
39135
+ * `jpeg` when the request set `acceptJpegBytes`; a request that did not gets
39136
+ * `jpeg` exactly as before. MsgPack and the mesh leg both carry binary —
39137
+ * `bytes` above has crossed this boundary as a `Uint8Array` all along — so
39138
+ * base64 was buying nothing but a multi-megabyte string in the relay's heap.
39139
+ */
39140
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
39039
39141
  width: zod.z.number().int().positive(),
39040
39142
  height: zod.z.number().int().positive(),
39041
39143
  /**
@@ -39077,7 +39179,14 @@ var require_dist_B17W9ngu = __commonJS({
39077
39179
  detail: zod.z.string().optional()
39078
39180
  })]);
39079
39181
  var ParkedTrackFrameSchema = zod.z.object({
39080
- jpeg: zod.z.string(),
39182
+ /**
39183
+ * Base64 JPEG — the pre-D462 wire. OPTIONAL since D462: a request that set
39184
+ * `acceptJpegBytes` is answered in `jpegBytes` and this is then absent.
39185
+ * Exactly one of the two is present.
39186
+ */
39187
+ jpeg: zod.z.string().optional(),
39188
+ /** The same JPEG as bytes, for a caller that declared it reads them (D462). */
39189
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
39081
39190
  width: zod.z.number().int().positive(),
39082
39191
  height: zod.z.number().int().positive(),
39083
39192
  /** The frame instant the parcel shows (the caller's clock, echoed back). */
@@ -39560,6 +39669,13 @@ var require_dist_B17W9ngu = __commonJS({
39560
39669
  bbox: NativeCropBboxSchema,
39561
39670
  maxWidth: zod.z.number().int().positive().optional(),
39562
39671
  /**
39672
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
39673
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
39674
+ * wire — never assume consent: a pre-D462 caller parses the field as
39675
+ * base64 and bytes would decode to garbage rather than fail.
39676
+ */
39677
+ acceptJpegBytes: zod.z.boolean().optional(),
39678
+ /**
39563
39679
  * When `true`, the runner encodes the resolved crop to JPEG ON THE
39564
39680
  * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
39565
39681
  * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
@@ -39732,7 +39848,14 @@ var require_dist_B17W9ngu = __commonJS({
39732
39848
  getParkedTrackFrame: method(zod.z.object({
39733
39849
  deviceId: zod.z.number(),
39734
39850
  trackId: zod.z.string(),
39735
- kind: ParkedFrameKindSchema
39851
+ kind: ParkedFrameKindSchema,
39852
+ /**
39853
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
39854
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
39855
+ * wire — never assume consent: a pre-D462 caller parses the field as
39856
+ * base64 and bytes would decode to garbage rather than fail.
39857
+ */
39858
+ acceptJpegBytes: zod.z.boolean().optional()
39736
39859
  }), ParkedTrackFrameSchema.nullable()),
39737
39860
  /**
39738
39861
  * Drop every parcel of a track — the hub closed it. Idempotent. A track
@@ -52384,12 +52507,24 @@ var require_dist_B17W9ngu = __commonJS({
52384
52507
  addonId: null,
52385
52508
  access: "create"
52386
52509
  },
52510
+ "audioAnalyzer.attachDevice": {
52511
+ capName: "audio-analyzer",
52512
+ capScope: "system",
52513
+ addonId: null,
52514
+ access: "create"
52515
+ },
52387
52516
  "audioAnalyzer.classify": {
52388
52517
  capName: "audio-analyzer",
52389
52518
  capScope: "system",
52390
52519
  addonId: null,
52391
52520
  access: "view"
52392
52521
  },
52522
+ "audioAnalyzer.detachDevice": {
52523
+ capName: "audio-analyzer",
52524
+ capScope: "system",
52525
+ addonId: null,
52526
+ access: "create"
52527
+ },
52393
52528
  "audioAnalyzer.dispose": {
52394
52529
  capName: "audio-analyzer",
52395
52530
  capScope: "system",
@@ -58233,11 +58368,21 @@ var require_dist_B17W9ngu = __commonJS({
58233
58368
  form: "single",
58234
58369
  optional: false
58235
58370
  }],
58371
+ "audioAnalyzer.attachDevice": [{
58372
+ name: "deviceId",
58373
+ form: "single",
58374
+ optional: false
58375
+ }],
58236
58376
  "audioAnalyzer.classify": [{
58237
58377
  name: "deviceId",
58238
58378
  form: "single",
58239
58379
  optional: true
58240
58380
  }],
58381
+ "audioAnalyzer.detachDevice": [{
58382
+ name: "deviceId",
58383
+ form: "single",
58384
+ optional: false
58385
+ }],
58241
58386
  "audioMetrics.getCurrentSnapshot": [{
58242
58387
  name: "deviceId",
58243
58388
  form: "single",
@@ -60366,6 +60511,14 @@ var require_dist_B17W9ngu = __commonJS({
60366
60511
  durability: "session",
60367
60512
  volatileFields: []
60368
60513
  };
60514
+ var G711_SCALE_CORRECTION_DB = {
60515
+ PCMU: 20 * Math.log10(4),
60516
+ PCMA: 20 * Math.log10(8)
60517
+ };
60518
+ function ituDbfsFromPreEpoch(law, authoredDbfs) {
60519
+ return authoredDbfs + G711_SCALE_CORRECTION_DB[law];
60520
+ }
60521
+ Math.round(ituDbfsFromPreEpoch("PCMU", -55));
60369
60522
  var NC_AUDIO_DEFAULTS = {
60370
60523
  hitPercent: 60,
60371
60524
  samplingSeconds: 10
@@ -61586,7 +61739,7 @@ var require_alerts_addon = __commonJS({
61586
61739
  [Symbol.toStringTag]: { value: "Module" }
61587
61740
  });
61588
61741
  require_chunk_Cek0wNdY();
61589
- var require_dist10 = require_dist_B17W9ngu();
61742
+ var require_dist10 = require_dist_0sWJNwme();
61590
61743
  function selectExpired(alerts, cutoffMs) {
61591
61744
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
61592
61745
  }
@@ -62405,7 +62558,7 @@ var require_console_logging = __commonJS({
62405
62558
  [Symbol.toStringTag]: { value: "Module" }
62406
62559
  });
62407
62560
  require_chunk_Cek0wNdY();
62408
- var require_dist10 = require_dist_B17W9ngu();
62561
+ var require_dist10 = require_dist_0sWJNwme();
62409
62562
  var require_formatter = require_formatter_DqAKDlvN();
62410
62563
  var LEVEL_RANK = {
62411
62564
  debug: 0,
@@ -62499,7 +62652,7 @@ var require_core_blocks_addon = __commonJS({
62499
62652
  "use strict";
62500
62653
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
62501
62654
  var require_chunk = require_chunk_Cek0wNdY();
62502
- var require_dist10 = require_dist_B17W9ngu();
62655
+ var require_dist10 = require_dist_0sWJNwme();
62503
62656
  var node_crypto = __require("crypto");
62504
62657
  var node_fs_promises = __require("fs/promises");
62505
62658
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -63396,11 +63549,11 @@ var require_core_blocks = __commonJS({
63396
63549
  }
63397
63550
  });
63398
63551
 
63399
- // ../system/dist/retired-settings-keys-CjvB7Etx.js
63400
- var require_retired_settings_keys_CjvB7Etx = __commonJS({
63401
- "../system/dist/retired-settings-keys-CjvB7Etx.js"(exports) {
63552
+ // ../system/dist/retired-settings-keys-Dh-XMfFx.js
63553
+ var require_retired_settings_keys_Dh_XMfFx = __commonJS({
63554
+ "../system/dist/retired-settings-keys-Dh-XMfFx.js"(exports) {
63402
63555
  "use strict";
63403
- var require_dist10 = require_dist_B17W9ngu();
63556
+ var require_dist10 = require_dist_0sWJNwme();
63404
63557
  function settingsStoreIsAuthoritativeHere(env) {
63405
63558
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
63406
63559
  return raw === "" || raw === "hub";
@@ -65635,8 +65788,8 @@ var require_device_manager_addon = __commonJS({
65635
65788
  [Symbol.toStringTag]: { value: "Module" }
65636
65789
  });
65637
65790
  require_chunk_Cek0wNdY();
65638
- var require_dist10 = require_dist_B17W9ngu();
65639
- var require_retired_settings_keys = require_retired_settings_keys_CjvB7Etx();
65791
+ var require_dist10 = require_dist_0sWJNwme();
65792
+ var require_retired_settings_keys = require_retired_settings_keys_Dh_XMfFx();
65640
65793
  var node_crypto = __require("crypto");
65641
65794
  var _camstack_types_node = require_node();
65642
65795
  var JOB_HISTORY = 20;
@@ -71261,7 +71414,7 @@ var require_hub_forwarder = __commonJS({
71261
71414
  [Symbol.toStringTag]: { value: "Module" }
71262
71415
  });
71263
71416
  require_chunk_Cek0wNdY();
71264
- var require_dist10 = require_dist_B17W9ngu();
71417
+ var require_dist10 = require_dist_0sWJNwme();
71265
71418
  var require_formatter = require_formatter_DqAKDlvN();
71266
71419
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
71267
71420
  var HubForwarderDestination = class {
@@ -71398,7 +71551,7 @@ var require_liveness_monitor_addon = __commonJS({
71398
71551
  "use strict";
71399
71552
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
71400
71553
  require_chunk_Cek0wNdY();
71401
- var require_dist10 = require_dist_B17W9ngu();
71554
+ var require_dist10 = require_dist_0sWJNwme();
71402
71555
  var NO_DEVICES = "liveness:no-devices";
71403
71556
  var ALL_OFFLINE = "liveness:all-devices-offline";
71404
71557
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -71594,7 +71747,7 @@ var require_local_auth_addon = __commonJS({
71594
71747
  [Symbol.toStringTag]: { value: "Module" }
71595
71748
  });
71596
71749
  var require_chunk = require_chunk_Cek0wNdY();
71597
- var require_dist10 = require_dist_B17W9ngu();
71750
+ var require_dist10 = require_dist_0sWJNwme();
71598
71751
  var node_crypto = __require("crypto");
71599
71752
  node_crypto = require_chunk.__toESM(node_crypto);
71600
71753
  var crypto$1 = __require("crypto");
@@ -79407,7 +79560,7 @@ var require_loki_logging = __commonJS({
79407
79560
  [Symbol.toStringTag]: { value: "Module" }
79408
79561
  });
79409
79562
  require_chunk_Cek0wNdY();
79410
- var require_dist10 = require_dist_B17W9ngu();
79563
+ var require_dist10 = require_dist_0sWJNwme();
79411
79564
  function sanitizeLabelName(raw) {
79412
79565
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
79413
79566
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79994,7 +80147,7 @@ var require_native_metrics_addon = __commonJS({
79994
80147
  [Symbol.toStringTag]: { value: "Module" }
79995
80148
  });
79996
80149
  var require_chunk = require_chunk_Cek0wNdY();
79997
- var require_dist10 = require_dist_B17W9ngu();
80150
+ var require_dist10 = require_dist_0sWJNwme();
79998
80151
  var node_fs_promises = __require("fs/promises");
79999
80152
  var node_fs = __require("fs");
80000
80153
  node_fs = require_chunk.__toESM(node_fs);
@@ -82747,7 +82900,7 @@ var require_filesystem_storage_addon = __commonJS({
82747
82900
  [Symbol.toStringTag]: { value: "Module" }
82748
82901
  });
82749
82902
  var require_chunk = require_chunk_Cek0wNdY();
82750
- var require_dist10 = require_dist_B17W9ngu();
82903
+ var require_dist10 = require_dist_0sWJNwme();
82751
82904
  var node_crypto = __require("crypto");
82752
82905
  var node_fs_promises = __require("fs/promises");
82753
82906
  var node_path = __require("path");
@@ -83974,8 +84127,8 @@ var require_sqlite_settings_addon = __commonJS({
83974
84127
  [Symbol.toStringTag]: { value: "Module" }
83975
84128
  });
83976
84129
  var require_chunk = require_chunk_Cek0wNdY();
83977
- var require_dist10 = require_dist_B17W9ngu();
83978
- var require_retired_settings_keys = require_retired_settings_keys_CjvB7Etx();
84130
+ var require_dist10 = require_dist_0sWJNwme();
84131
+ var require_retired_settings_keys = require_retired_settings_keys_Dh_XMfFx();
83979
84132
  var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
83980
84133
  var node_crypto = __require("crypto");
83981
84134
  var node_path = __require("path");
@@ -86642,7 +86795,7 @@ var require_storage_orchestrator_addon = __commonJS({
86642
86795
  [Symbol.toStringTag]: { value: "Module" }
86643
86796
  });
86644
86797
  var require_chunk = require_chunk_Cek0wNdY();
86645
- var require_dist10 = require_dist_B17W9ngu();
86798
+ var require_dist10 = require_dist_0sWJNwme();
86646
86799
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
86647
86800
  var zod = require_zod();
86648
86801
  var node_crypto = __require("crypto");
@@ -90292,7 +90445,7 @@ var require_system_config_addon = __commonJS({
90292
90445
  [Symbol.toStringTag]: { value: "Module" }
90293
90446
  });
90294
90447
  require_chunk_Cek0wNdY();
90295
- var require_dist10 = require_dist_B17W9ngu();
90448
+ var require_dist10 = require_dist_0sWJNwme();
90296
90449
  var SECTION_TITLES = {
90297
90450
  server: "Server",
90298
90451
  auth: "Authentication"
@@ -108353,7 +108506,7 @@ var require_winston_logging = __commonJS({
108353
108506
  [Symbol.toStringTag]: { value: "Module" }
108354
108507
  });
108355
108508
  var require_chunk = require_chunk_Cek0wNdY();
108356
- var require_dist10 = require_dist_B17W9ngu();
108509
+ var require_dist10 = require_dist_0sWJNwme();
108357
108510
  var require_formatter = require_formatter_DqAKDlvN();
108358
108511
  var node_path = __require("path");
108359
108512
  node_path = require_chunk.__toESM(node_path);
@@ -110390,12 +110543,57 @@ var require_event_category_BNJ9EE5B = __commonJS({
110390
110543
  }
110391
110544
  });
110392
110545
 
110393
- // ../types/dist/sleep-CTHjJilA.js
110394
- var require_sleep_CTHjJilA = __commonJS({
110395
- "../types/dist/sleep-CTHjJilA.js"(exports) {
110546
+ // ../types/dist/sleep-B1ZwxAhh.js
110547
+ var require_sleep_B1ZwxAhh = __commonJS({
110548
+ "../types/dist/sleep-B1ZwxAhh.js"(exports) {
110396
110549
  "use strict";
110397
110550
  var require_event_category = require_event_category_BNJ9EE5B();
110398
110551
  var zod = require_zod();
110552
+ var AUDIO_CHUNK_FORMATS = [
110553
+ "f32le",
110554
+ "pcmu",
110555
+ "pcma"
110556
+ ];
110557
+ function isAudioChunkFormat(value) {
110558
+ return typeof value === "string" && AUDIO_CHUNK_FORMATS.includes(value);
110559
+ }
110560
+ function audioChunkBytesPerSample(format2) {
110561
+ return format2 === "f32le" ? 4 : 1;
110562
+ }
110563
+ function expandAudioChunkToF32le(data, format2) {
110564
+ if (format2 === "f32le") {
110565
+ const copy2 = new Uint8Array(data.byteLength);
110566
+ copy2.set(data);
110567
+ return copy2;
110568
+ }
110569
+ const table = format2 === "pcmu" ? ULAW_TABLE : ALAW_TABLE;
110570
+ const out = new Float32Array(data.length);
110571
+ for (let i = 0; i < data.length; i++) out[i] = table[data[i]];
110572
+ return new Uint8Array(out.buffer);
110573
+ }
110574
+ function buildUlawTable() {
110575
+ const table = new Float32Array(256);
110576
+ for (let i = 0; i < 256; i++) {
110577
+ const complemented = ~i & 255;
110578
+ const sign = (complemented & 128) !== 0 ? -1 : 1;
110579
+ const exponent = complemented >> 4 & 7;
110580
+ table[i] = sign * ((8 * (complemented & 15) + 132 << exponent) - 132) / 32768;
110581
+ }
110582
+ return table;
110583
+ }
110584
+ function buildAlawTable() {
110585
+ const table = new Float32Array(256);
110586
+ for (let i = 0; i < 256; i++) {
110587
+ const xored = i ^ 85;
110588
+ const sign = (xored & 128) !== 0 ? 1 : -1;
110589
+ const exponent = xored >> 4 & 7;
110590
+ const mantissa = xored & 15;
110591
+ table[i] = sign * (exponent === 0 ? 16 * mantissa + 8 : 16 * mantissa + 264 << exponent - 1) / 32768;
110592
+ }
110593
+ return table;
110594
+ }
110595
+ var ULAW_TABLE = buildUlawTable();
110596
+ var ALAW_TABLE = buildAlawTable();
110399
110597
  var WELL_KNOWN_TABS = [
110400
110598
  {
110401
110599
  id: "overview",
@@ -111617,16 +111815,36 @@ var require_sleep_CTHjJilA = __commonJS({
111617
111815
  /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
111618
111816
  maxFps: zod.z.number().nonnegative()
111619
111817
  });
111818
+ var AudioChunkFormatSchema = zod.z.enum(AUDIO_CHUNK_FORMATS);
111620
111819
  var DecodedAudioChunkSchema = zod.z.object({
111621
111820
  data: zod.z.instanceof(Uint8Array),
111622
111821
  sampleRate: zod.z.number().int().positive(),
111623
111822
  channels: zod.z.number().int().positive(),
111624
- timestamp: zod.z.number()
111823
+ timestamp: zod.z.number(),
111824
+ /**
111825
+ * Byte format of `data`. ABSENT MEANS `f32le` — today's bytes, byte for
111826
+ * byte, for any peer that never heard of this field. A coded window
111827
+ * (`pcmu` / `pcma`, one byte per sample) is only ever emitted to a
111828
+ * subscription that DECLARED it accepts one, so absence can never mean
111829
+ * "coded bytes a consumer will read as floats" (D455).
111830
+ */
111831
+ format: AudioChunkFormatSchema.optional()
111625
111832
  });
111626
111833
  var SubscribeAudioChunksInputSchema = zod.z.object({
111627
111834
  brokerId: zod.z.string(),
111628
111835
  /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
111629
- tag: zod.z.string().optional()
111836
+ tag: zod.z.string().optional(),
111837
+ /**
111838
+ * Byte formats this subscriber can READ, best first. The broker serves the
111839
+ * chunk's own format when it is in this list and expands to `f32le`
111840
+ * otherwise, so a subscriber is never handed bytes it cannot interpret.
111841
+ *
111842
+ * Absent (or without the source format) means `f32le` — the behaviour every
111843
+ * subscriber had before D455, unchanged. This is the negotiation half of
111844
+ * the source-bytes lever: it is what lets the broker and its consumers
111845
+ * deploy one at a time across three nodes.
111846
+ */
111847
+ accept: zod.z.array(AudioChunkFormatSchema).readonly().optional()
111630
111848
  });
111631
111849
  var SubscribeAudioChunksResultSchema = zod.z.object({
111632
111850
  /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
@@ -113307,6 +113525,7 @@ var require_sleep_CTHjJilA = __commonJS({
113307
113525
  getDeviceSettings: (input) => dispatchSystem("addonSettings", "getDeviceSettings", "query", input),
113308
113526
  updateDeviceSettings: (input) => dispatchSystem("addonSettings", "updateDeviceSettings", "mutation", input)
113309
113527
  },
113528
+ audioAnalyzer: { detachDevice: (input) => dispatchSystem("audioAnalyzer", "detachDevice", "mutation", input) },
113310
113529
  cameraPipelineConfig: {
113311
113530
  getDeviceSettingsContribution: (input) => dispatchSystem("cameraPipelineConfig", "getDeviceSettingsContribution", "query", input),
113312
113531
  getDeviceLiveContribution: (input) => dispatchSystem("cameraPipelineConfig", "getDeviceLiveContribution", "query", input),
@@ -113610,6 +113829,18 @@ var require_sleep_CTHjJilA = __commonJS({
113610
113829
  signal.addEventListener("abort", onAbort, { once: true });
113611
113830
  });
113612
113831
  }
113832
+ Object.defineProperty(exports, "AUDIO_CHUNK_FORMATS", {
113833
+ enumerable: true,
113834
+ get: function() {
113835
+ return AUDIO_CHUNK_FORMATS;
113836
+ }
113837
+ });
113838
+ Object.defineProperty(exports, "AudioChunkFormatSchema", {
113839
+ enumerable: true,
113840
+ get: function() {
113841
+ return AudioChunkFormatSchema;
113842
+ }
113843
+ });
113613
113844
  Object.defineProperty(exports, "BOOT_RECOVERY_BACKOFF_MS", {
113614
113845
  enumerable: true,
113615
113846
  get: function() {
@@ -113892,6 +114123,12 @@ var require_sleep_CTHjJilA = __commonJS({
113892
114123
  return asString;
113893
114124
  }
113894
114125
  });
114126
+ Object.defineProperty(exports, "audioChunkBytesPerSample", {
114127
+ enumerable: true,
114128
+ get: function() {
114129
+ return audioChunkBytesPerSample;
114130
+ }
114131
+ });
113895
114132
  Object.defineProperty(exports, "collectHydratedFieldEntries", {
113896
114133
  enumerable: true,
113897
114134
  get: function() {
@@ -113970,6 +114207,12 @@ var require_sleep_CTHjJilA = __commonJS({
113970
114207
  return event;
113971
114208
  }
113972
114209
  });
114210
+ Object.defineProperty(exports, "expandAudioChunkToF32le", {
114211
+ enumerable: true,
114212
+ get: function() {
114213
+ return expandAudioChunkToF32le;
114214
+ }
114215
+ });
113973
114216
  Object.defineProperty(exports, "expandCapMethods", {
113974
114217
  enumerable: true,
113975
114218
  get: function() {
@@ -113982,6 +114225,12 @@ var require_sleep_CTHjJilA = __commonJS({
113982
114225
  return hydrateSchema;
113983
114226
  }
113984
114227
  });
114228
+ Object.defineProperty(exports, "isAudioChunkFormat", {
114229
+ enumerable: true,
114230
+ get: function() {
114231
+ return isAudioChunkFormat;
114232
+ }
114233
+ });
113985
114234
  Object.defineProperty(exports, "isDeviceConfigCap", {
113986
114235
  enumerable: true,
113987
114236
  get: function() {
@@ -114128,15 +114377,21 @@ var require_addon = __commonJS({
114128
114377
  "../types/dist/addon.js"(exports) {
114129
114378
  "use strict";
114130
114379
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
114380
+ var require_sleep = require_sleep_B1ZwxAhh();
114131
114381
  var require_event_category = require_event_category_BNJ9EE5B();
114132
- var require_sleep = require_sleep_CTHjJilA();
114133
114382
  var require_err_msg = require_err_msg_COpsHMw2();
114134
114383
  var CAP_INPUT_DEFAULTS = Object.freeze({
114135
114384
  "addons": { "getLogs": { "limit": 100 } },
114136
- "audio-analyzer": { "analyseChunk": { "settings": { "__nested__": {
114137
- "minConfidence": 0.3,
114138
- "allowedClasses": []
114139
- } } } },
114385
+ "audio-analyzer": {
114386
+ "analyseChunk": { "settings": { "__nested__": {
114387
+ "minConfidence": 0.3,
114388
+ "allowedClasses": []
114389
+ } } },
114390
+ "attachDevice": { "settings": { "__nested__": {
114391
+ "minConfidence": 0.3,
114392
+ "allowedClasses": []
114393
+ } } }
114394
+ },
114140
114395
  "audio-codec": {
114141
114396
  "pullEncoded": { "maxCount": 8 },
114142
114397
  "pullPcm": { "maxCount": 8 }
@@ -120987,9 +121242,9 @@ var require_dist2 = __commonJS({
120987
121242
  }
120988
121243
  });
120989
121244
 
120990
- // ../system/dist/manifest-system-deps-g_nK0xsF.js
120991
- var require_manifest_system_deps_g_nK0xsF = __commonJS({
120992
- "../system/dist/manifest-system-deps-g_nK0xsF.js"(exports) {
121245
+ // ../system/dist/manifest-system-deps-DfpwaXkh.js
121246
+ var require_manifest_system_deps_DfpwaXkh = __commonJS({
121247
+ "../system/dist/manifest-system-deps-DfpwaXkh.js"(exports) {
120993
121248
  "use strict";
120994
121249
  var require_chunk = require_chunk_Cek0wNdY();
120995
121250
  require_hub_cap_forward_DmHNjbB0();
@@ -121099,6 +121354,116 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121099
121354
  const top = window2.top.map((d) => `${d.childId}:${d.sent}/${d.suppressed}`).join(",");
121100
121355
  return ` fanoutMode=uds:${window2.udsMode}/cross-node:${window2.crossNodeMode} children=${window2.childrenConnected} childrenUndeclared=${window2.childrenUndeclared} fanoutSent=${window2.fanoutSent} fanoutSuppressed=${window2.fanoutSuppressed} crossNodeDelivered=${window2.crossNodeDelivered} crossNodeSuppressed=${window2.crossNodeSuppressed}` + (top.length === 0 ? "" : ` fanoutTop=${top}`);
121101
121356
  }
121357
+ var EMPTY_CAP_ACTION_READING = /* @__PURE__ */ new Map();
121358
+ var CAP_ACTION_UNLABELLED = "(unlabelled)";
121359
+ var CAP_ACTION_OVERFLOW_LABEL = "(overflow)";
121360
+ var MAX_CAP_ACTIONS_PER_PEER = 64;
121361
+ function capActionLabel(body) {
121362
+ if (typeof body !== "object" || body === null) return null;
121363
+ const env = body;
121364
+ if (env.kind !== "cap-call" && env.kind !== "cap-call-out") return null;
121365
+ if (typeof env.capName !== "string" || typeof env.method !== "string") return null;
121366
+ return `${env.capName}.${env.method}`;
121367
+ }
121368
+ function emptyCounters() {
121369
+ return {
121370
+ calls: 0,
121371
+ reqBytes: 0,
121372
+ resBytes: 0,
121373
+ raw: 0,
121374
+ decoded: 0
121375
+ };
121376
+ }
121377
+ function createCapActionCensus() {
121378
+ const peers = /* @__PURE__ */ new Map();
121379
+ const slot = (peerId, action) => {
121380
+ let byAction = peers.get(peerId);
121381
+ if (byAction === void 0) {
121382
+ byAction = /* @__PURE__ */ new Map();
121383
+ peers.set(peerId, byAction);
121384
+ }
121385
+ const existing = byAction.get(action);
121386
+ if (existing !== void 0) return existing;
121387
+ if (byAction.size >= 64) {
121388
+ let overflow = byAction.get(CAP_ACTION_OVERFLOW_LABEL);
121389
+ if (overflow === void 0) {
121390
+ overflow = emptyCounters();
121391
+ byAction.set(CAP_ACTION_OVERFLOW_LABEL, overflow);
121392
+ }
121393
+ return overflow;
121394
+ }
121395
+ const fresh = emptyCounters();
121396
+ byAction.set(action, fresh);
121397
+ return fresh;
121398
+ };
121399
+ return {
121400
+ record(peerId, action, reqBytes, resBytes) {
121401
+ const c = slot(peerId, action);
121402
+ c.calls += 1;
121403
+ c.reqBytes += reqBytes;
121404
+ c.resBytes += resBytes;
121405
+ },
121406
+ recordForward(peerId, action, kind) {
121407
+ const c = slot(peerId, action);
121408
+ if (kind === "raw") c.raw += 1;
121409
+ else c.decoded += 1;
121410
+ },
121411
+ recordUnlabelled(peerId, bytes) {
121412
+ const c = slot(peerId, CAP_ACTION_UNLABELLED);
121413
+ c.resBytes += bytes;
121414
+ },
121415
+ forget(peerId) {
121416
+ peers.delete(peerId);
121417
+ },
121418
+ read() {
121419
+ const out = /* @__PURE__ */ new Map();
121420
+ for (const [peerId, byAction] of peers) {
121421
+ const copy2 = /* @__PURE__ */ new Map();
121422
+ for (const [action, c] of byAction) copy2.set(action, {
121423
+ calls: c.calls,
121424
+ reqBytes: c.reqBytes,
121425
+ resBytes: c.resBytes,
121426
+ raw: c.raw,
121427
+ decoded: c.decoded
121428
+ });
121429
+ out.set(peerId, copy2);
121430
+ }
121431
+ return out;
121432
+ }
121433
+ };
121434
+ }
121435
+ function sampleOf(reading, peerId, action) {
121436
+ return reading.get(peerId)?.get(action);
121437
+ }
121438
+ function diffCapActionCensus(before, current, topN) {
121439
+ const deltas = [];
121440
+ let labelledBytes = 0;
121441
+ let totalBytes = 0;
121442
+ for (const [peerId, byAction] of current) for (const [action, now] of byAction) {
121443
+ const then = sampleOf(before, peerId, action);
121444
+ const reqBytes = Math.max(0, now.reqBytes - (then?.reqBytes ?? 0));
121445
+ const resBytes = Math.max(0, now.resBytes - (then?.resBytes ?? 0));
121446
+ const bytes = reqBytes + resBytes;
121447
+ totalBytes += bytes;
121448
+ if (action === "(unlabelled)" || action === "(overflow)") continue;
121449
+ labelledBytes += bytes;
121450
+ if (bytes === 0) continue;
121451
+ deltas.push({
121452
+ peerId,
121453
+ action,
121454
+ calls: Math.max(0, now.calls - (then?.calls ?? 0)),
121455
+ reqBytes,
121456
+ resBytes,
121457
+ raw: Math.max(0, now.raw - (then?.raw ?? 0)),
121458
+ decoded: Math.max(0, now.decoded - (then?.decoded ?? 0))
121459
+ });
121460
+ }
121461
+ return {
121462
+ top: deltas.toSorted((a, b) => b.reqBytes + b.resBytes - (a.reqBytes + a.resBytes) || a.peerId.localeCompare(b.peerId) || a.action.localeCompare(b.action)).slice(0, topN),
121463
+ labelledBytes,
121464
+ totalBytes
121465
+ };
121466
+ }
121102
121467
  function createSocketDirectionCounters() {
121103
121468
  return {
121104
121469
  reqMessages: 0,
@@ -121165,10 +121530,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121165
121530
  });
121166
121531
  }
121167
121532
  const forward = registry.readForwardCensus?.();
121533
+ const actions = registry.readActionCensus?.();
121168
121534
  return {
121169
121535
  peers,
121170
121536
  peersConnected: listed.length,
121171
- ...forward === void 0 ? {} : { forward }
121537
+ ...forward === void 0 ? {} : { forward },
121538
+ ...actions === void 0 ? {} : { actions }
121172
121539
  };
121173
121540
  } catch {
121174
121541
  return;
@@ -121249,6 +121616,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121249
121616
  if (peerMessages(delta) > 0) deltas.push(delta);
121250
121617
  }
121251
121618
  const forward = diffForward(current.forward, baseline.forward);
121619
+ const actions = current.actions === void 0 ? void 0 : diffCapActionCensus(baseline.actions ?? EMPTY_CAP_ACTION_READING, current.actions, 5);
121252
121620
  return {
121253
121621
  peersConnected: current.peersConnected,
121254
121622
  peersMeasured: current.peers.length,
@@ -121257,7 +121625,8 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121257
121625
  top: deltas.toSorted((a, b) => peerMessages(b) - peerMessages(a) || a.peerId.localeCompare(b.peerId)).slice(0, topN),
121258
121626
  topBytes: deltas.toSorted((a, b) => peerBytes(b) - peerBytes(a) || a.peerId.localeCompare(b.peerId)).slice(0, topN),
121259
121627
  queued: readSocketQueues(current),
121260
- ...forward === void 0 ? {} : { forward }
121628
+ ...forward === void 0 ? {} : { forward },
121629
+ ...actions === void 0 ? {} : { actions }
121261
121630
  };
121262
121631
  }
121263
121632
  function createSocketPlaneMeter(reader, topN = 5) {
@@ -121268,7 +121637,8 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121268
121637
  const window2 = diffSocketPlane(baseline, current, topN);
121269
121638
  baseline = {
121270
121639
  peers: new Map(current.peers.map((p) => [p.peerId, p])),
121271
- ...current.forward === void 0 ? {} : { forward: current.forward }
121640
+ ...current.forward === void 0 ? {} : { forward: current.forward },
121641
+ ...current.actions === void 0 ? {} : { actions: current.actions }
121272
121642
  };
121273
121643
  return window2;
121274
121644
  } };
@@ -121285,13 +121655,16 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121285
121655
  function formatPeer(delta) {
121286
121656
  return `${delta.peerId}:tx=${delta.tx.reqMessages}/${delta.tx.resMessages}/${delta.tx.evtMessages}:rx=${delta.rx.reqMessages}/${delta.rx.resMessages}/${delta.rx.evtMessages}:txkB=${formatPeerBytes(delta.tx)}:rxkB=${formatPeerBytes(delta.rx)}`;
121287
121657
  }
121658
+ function formatAction(entry) {
121659
+ return `${entry.peerId}!${entry.action}:${kb$1(entry.reqBytes + entry.resBytes)}kB/${entry.calls}:r${entry.raw}/d${entry.decoded}`;
121660
+ }
121288
121661
  function formatSocketPlane(window2) {
121289
121662
  if (window2 === void 0) return "";
121290
121663
  const top = window2.top.map(formatPeer).join(",");
121291
121664
  const named = new Set(window2.top.map((p) => p.peerId));
121292
121665
  const topBytes = window2.topBytes.filter((p) => !named.has(p.peerId)).map(formatPeer).join(",");
121293
121666
  const queuedTop = window2.queued.top.map((p) => `${p.peerId}:${kb$1(p.bytes)}`).join(",");
121294
- return ` socketPeers=${window2.peersMeasured}/${window2.peersConnected} socketTx=${formatDirection(window2.tx)} socketRx=${formatDirection(window2.rx)}` + (top.length === 0 ? "" : ` socketTop=${top}`) + (topBytes.length === 0 ? "" : ` socketTopBytes=${topBytes}`) + ` socketQueued=${kb$1(window2.queued.totalBytes)}kB` + (window2.queued.unmeasured === 0 ? "" : ` socketQueuedUnmeasured=${window2.queued.unmeasured}`) + (queuedTop.length === 0 ? "" : ` socketQueuedTop=${queuedTop}`) + (window2.forward === void 0 ? "" : ` socketFwd=${window2.forward.raw}/${window2.forward.decoded}`);
121667
+ return ` socketPeers=${window2.peersMeasured}/${window2.peersConnected} socketTx=${formatDirection(window2.tx)} socketRx=${formatDirection(window2.rx)}` + (top.length === 0 ? "" : ` socketTop=${top}`) + (topBytes.length === 0 ? "" : ` socketTopBytes=${topBytes}`) + ` socketQueued=${kb$1(window2.queued.totalBytes)}kB` + (window2.queued.unmeasured === 0 ? "" : ` socketQueuedUnmeasured=${window2.queued.unmeasured}`) + (queuedTop.length === 0 ? "" : ` socketQueuedTop=${queuedTop}`) + (window2.forward === void 0 ? "" : ` socketFwd=${window2.forward.raw}/${window2.forward.decoded}`) + (window2.actions === void 0 ? "" : ` socketActions=${kb$1(window2.actions.labelledBytes)}/${kb$1(window2.actions.totalBytes)}kB` + (window2.actions.top.length === 0 ? "" : ` socketTopActions=${window2.actions.top.map(formatAction).join(",")}`));
121295
121668
  }
121296
121669
  function isRecord$1(value) {
121297
121670
  return typeof value === "object" && value !== null;
@@ -121604,6 +121977,95 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121604
121977
  const verdict = live < context.rawMb * 0.5 ? "mostly DEAD buffers awaiting a sweep, not a retention" : "LIVE \u2014 something holds them";
121605
121978
  return `[mem] ${label} arrayBuffer census: live=${live}MB in ${report.count} ArrayBuffers (raw arrayBuffers=${context.rawMb}MB at the trigger \u2192 ${verdict}) top sizes: ${report.topSizes.map(formatExact).join(", ") || "(none)"}; buckets: ${report.buckets.map(formatBucket).join(", ") || "(none)"}; detached=${report.detached} took=${context.tookMs}ms \u2014 cost: ONE forced full GC (the same pause as a reclaim pass), walked in memory, nothing serialised, nothing written; trigger: ${context.reason}`;
121606
121979
  }
121980
+ function countsOf(entries, kinds) {
121981
+ let majors = 0;
121982
+ let minors = 0;
121983
+ let incrementals = 0;
121984
+ let pauseMs = 0;
121985
+ for (const e of entries) {
121986
+ if (e.kind === kinds.major) majors++;
121987
+ else if (e.kind === kinds.minor) minors++;
121988
+ else if (e.kind === kinds.incremental) incrementals++;
121989
+ pauseMs += e.durationMs;
121990
+ }
121991
+ return {
121992
+ majors,
121993
+ minors,
121994
+ incrementals,
121995
+ pauseMs,
121996
+ windowMs: 0
121997
+ };
121998
+ }
121999
+ function createGcCensus(install, kinds, startedAt) {
122000
+ let pending = [];
122001
+ const stopObserving = install((entry) => {
122002
+ pending.push(entry);
122003
+ });
122004
+ if (stopObserving === void 0) return void 0;
122005
+ let windowStart = startedAt;
122006
+ return {
122007
+ read: (at) => {
122008
+ const windowMs = at - windowStart;
122009
+ if (windowMs < 1e3) return null;
122010
+ const taken = pending;
122011
+ pending = [];
122012
+ windowStart = at;
122013
+ return {
122014
+ ...countsOf(taken, kinds),
122015
+ windowMs
122016
+ };
122017
+ },
122018
+ stop: () => {
122019
+ stopObserving();
122020
+ pending = [];
122021
+ }
122022
+ };
122023
+ }
122024
+ function nodeGcObserver() {
122025
+ return {
122026
+ kinds: readKinds({
122027
+ major: 4,
122028
+ minor: 1,
122029
+ incremental: 8
122030
+ }),
122031
+ install: (observe) => {
122032
+ try {
122033
+ const observer = new (process.getBuiltinModule("node:perf_hooks")).PerformanceObserver((list) => {
122034
+ for (const entry of list.getEntries()) {
122035
+ const detail = "detail" in entry ? entry.detail : void 0;
122036
+ observe({
122037
+ kind: typeof detail === "object" && detail !== null && "kind" in detail && typeof detail.kind === "number" ? detail.kind : -1,
122038
+ durationMs: entry.duration
122039
+ });
122040
+ }
122041
+ });
122042
+ observer.observe({ entryTypes: ["gc"] });
122043
+ return () => {
122044
+ observer.disconnect();
122045
+ };
122046
+ } catch {
122047
+ return;
122048
+ }
122049
+ }
122050
+ };
122051
+ }
122052
+ function readKinds(fallback) {
122053
+ try {
122054
+ const c = process.getBuiltinModule("node:perf_hooks").constants;
122055
+ return {
122056
+ major: c.NODE_PERFORMANCE_GC_MAJOR,
122057
+ minor: c.NODE_PERFORMANCE_GC_MINOR,
122058
+ incremental: c.NODE_PERFORMANCE_GC_INCREMENTAL
122059
+ };
122060
+ } catch {
122061
+ return fallback;
122062
+ }
122063
+ }
122064
+ function formatGcCensus(window2) {
122065
+ if (window2 === null || window2 === void 0) return "";
122066
+ const perMin = (n) => window2.windowMs <= 0 ? "?" : (n / (window2.windowMs / 6e4)).toFixed(1);
122067
+ return ` gc=maj${window2.majors}/min${window2.minors}/inc${window2.incrementals}@${Math.round(window2.windowMs / 1e3)}s gcMajPerMin=${perMin(window2.majors)} gcPauseMs=${Math.round(window2.pauseMs)}`;
122068
+ }
121607
122069
  var HUB_MAIN_HEAP_WATCH_LABEL = "hub-main";
121608
122070
  var HEAP_WATCH_INTERVAL_MS = 6e4;
121609
122071
  var HEAP_WATCH_WARN_RATIO = 0.8;
@@ -121772,6 +122234,8 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121772
122234
  const socketPlane = probes?.socketPlane === void 0 ? void 0 : createSocketPlaneMeter(probes.socketPlane);
121773
122235
  const readMemory = reclaimOptions?.readMemory ?? (() => process.memoryUsage());
121774
122236
  const now = reclaimOptions?.now ?? (() => Date.now());
122237
+ const gcObserver = probes?.gcObserver ?? nodeGcObserver();
122238
+ const gcCensus = createGcCensus(gcObserver.install, gcObserver.kinds, now());
121775
122239
  const triggerMb = reclaimOptions?.triggerMb ?? 1024;
121776
122240
  const minIntervalMs = reclaimOptions?.minIntervalMs ?? 12e4;
121777
122241
  const steadyStateIntervalMs = reclaimOptions?.steadyStateIntervalMs ?? 6e5;
@@ -121847,7 +122311,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121847
122311
  const due = at - lastLoggedAt >= intervalMs;
121848
122312
  if (mode === "escalated" || due) {
121849
122313
  lastLoggedAt = at;
121850
- const line = format2(label, sample, loopDelay?.read(), budgetMb, `${formatHeapSpaces(readSpaces())}${formatEventPlane(eventPlane?.read())}` + formatSocketPlane(socketPlane?.read()) + formatMeshQueue(meshQueue?.()));
122314
+ const line = format2(label, sample, loopDelay?.read(), budgetMb, `${formatHeapSpaces(readSpaces())}${formatEventPlane(eventPlane?.read())}` + formatSocketPlane(socketPlane?.read()) + formatMeshQueue(meshQueue?.()) + formatGcCensus(gcCensus?.read(at)));
121851
122315
  if (sample.nearLimit) sink.warn(`${line} \u2014 APPROACHING HEAP LIMIT`);
121852
122316
  else if (mode === "escalated") sink.warn(`${line} \u2014 heap elevated, sampling every ${probeIntervalMs}ms`);
121853
122317
  else sink.info(line);
@@ -121905,6 +122369,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
121905
122369
  stopped = true;
121906
122370
  clearInterval(timer);
121907
122371
  loopDelay?.stop();
122372
+ gcCensus?.stop();
121908
122373
  };
121909
122374
  }
121910
122375
  var RUNNER_HEAP_WATCH_INTERVAL_MS = 3e5;
@@ -125262,6 +125727,8 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125262
125727
  txCounters = createSocketDirectionCounters();
125263
125728
  /** Frames read from the peer, cumulative, split by kind. */
125264
125729
  rxCounters = createSocketDirectionCounters();
125730
+ /** See {@link CapActionChannelObserver}. Absent = no per-action census. */
125731
+ actionObserver = null;
125265
125732
  constructor(socket) {
125266
125733
  this.socket = socket;
125267
125734
  socket.on("data", (chunk) => this.onData(chunk));
@@ -125293,16 +125760,26 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125293
125760
  }, timeoutMs);
125294
125761
  timer.unref?.();
125295
125762
  }
125763
+ const label = this.labelSafely(body);
125296
125764
  this.pending.set(id, {
125297
125765
  resolve,
125298
125766
  reject,
125299
- timer
125767
+ timer,
125768
+ action: null
125300
125769
  });
125301
- this.send({
125770
+ const reqBytes = this.send({
125302
125771
  k: "req",
125303
125772
  id,
125304
125773
  body
125305
125774
  }, opts?.payload);
125775
+ const entry = this.pending.get(id);
125776
+ if (entry !== void 0 && label !== void 0) this.pending.set(id, {
125777
+ ...entry,
125778
+ action: {
125779
+ label,
125780
+ reqBytes
125781
+ }
125782
+ });
125306
125783
  });
125307
125784
  }
125308
125785
  emit(body) {
@@ -125312,6 +125789,37 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125312
125789
  body
125313
125790
  });
125314
125791
  }
125792
+ /**
125793
+ * Wire the per-action census. Only one observer is active at a time; an
125794
+ * unwired channel records nothing at all (never zeros).
125795
+ */
125796
+ observeActions(observer) {
125797
+ this.actionObserver = observer;
125798
+ }
125799
+ /**
125800
+ * The label for one envelope, or `undefined` when there is nothing to
125801
+ * record. Wrapped: a broken labeller must never fail the call it watches —
125802
+ * the same discipline `LocalChildRegistry.recordCapUsage` applies, and for
125803
+ * the same reason.
125804
+ */
125805
+ labelSafely(body) {
125806
+ const obs = this.actionObserver;
125807
+ if (obs === null) return void 0;
125808
+ try {
125809
+ return obs.label(body);
125810
+ } catch {
125811
+ return null;
125812
+ }
125813
+ }
125814
+ /** Settle one request/response pair on the census. Never throws. */
125815
+ recordAction(label, reqBytes, resBytes) {
125816
+ const obs = this.actionObserver;
125817
+ if (obs === null) return;
125818
+ try {
125819
+ obs.record(label, reqBytes, resBytes);
125820
+ } catch {
125821
+ }
125822
+ }
125315
125823
  /** Replace the request handler. Only one handler is active at a time. */
125316
125824
  onRequest(handler) {
125317
125825
  this.requestHandler = handler;
@@ -125359,21 +125867,27 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125359
125867
  * are never copied into the head. A forwarded payload is a view into the
125360
125868
  * frame it arrived on, and that frame's buffer is never mutated, so handing
125361
125869
  * the view to the socket is safe.
125870
+ *
125871
+ * Returns the on-the-wire bytes it charged — the same number the per-kind
125872
+ * counter got, so the per-action census can never disagree with the per-peer
125873
+ * one. `0` when the channel is closed and nothing was written.
125362
125874
  */
125363
125875
  send(frame, payload) {
125364
- if (this.closed) return;
125876
+ if (this.closed) return 0;
125365
125877
  if (payload === void 0) {
125366
125878
  const encoded = encodeFrame(frame);
125367
125879
  recordSocketFrame(this.txCounters, frame.k, encoded.byteLength);
125368
125880
  this.socket.write(encoded);
125369
- return;
125881
+ return encoded.byteLength;
125370
125882
  }
125371
125883
  const head = encodeFrameHead(frame, payload);
125372
- recordSocketFrame(this.txCounters, frame.k, head.byteLength + payload.byteLength);
125884
+ const bytes = head.byteLength + payload.byteLength;
125885
+ recordSocketFrame(this.txCounters, frame.k, bytes);
125373
125886
  this.socket.cork();
125374
125887
  this.socket.write(head);
125375
125888
  this.socket.write(payload);
125376
125889
  this.socket.uncork();
125890
+ return bytes;
125377
125891
  }
125378
125892
  onData(chunk) {
125379
125893
  const frames = this.decoder.push(chunk);
@@ -125392,28 +125906,31 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125392
125906
  async handleFrame(frame, wireBytes) {
125393
125907
  recordSocketFrame(this.rxCounters, frame.k, wireBytes);
125394
125908
  if (frame.k === "req") {
125909
+ const label = this.labelSafely(frame.body);
125910
+ let resBytes = 0;
125395
125911
  try {
125396
125912
  const result = await this.requestHandler(frame.body, frame.pl);
125397
- if (result instanceof PayloadReply) this.send({
125913
+ if (result instanceof PayloadReply) resBytes = this.send({
125398
125914
  k: "res",
125399
125915
  id: frame.id,
125400
125916
  ok: true,
125401
125917
  body: result.body
125402
125918
  }, result.payload);
125403
- else this.send({
125919
+ else resBytes = this.send({
125404
125920
  k: "res",
125405
125921
  id: frame.id,
125406
125922
  ok: true,
125407
125923
  body: result
125408
125924
  });
125409
125925
  } catch (err) {
125410
- this.send({
125926
+ resBytes = this.send({
125411
125927
  k: "res",
125412
125928
  id: frame.id,
125413
125929
  ok: false,
125414
125930
  err: err instanceof Error ? err.message : String(err)
125415
125931
  });
125416
125932
  }
125933
+ if (label !== void 0) this.recordAction(label, wireBytes, resBytes);
125417
125934
  return;
125418
125935
  }
125419
125936
  if (frame.k === "res") {
@@ -125421,6 +125938,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125421
125938
  if (!p) return;
125422
125939
  this.pending.delete(frame.id);
125423
125940
  if (p.timer !== null) clearTimeout(p.timer);
125941
+ if (p.action !== null) this.recordAction(p.action.label, p.action.reqBytes, wireBytes);
125424
125942
  if (!frame.ok) p.reject(new Error(frame.err));
125425
125943
  else if (frame.pl !== void 0) p.resolve(new PayloadReply(frame.body, frame.pl));
125426
125944
  else p.resolve(frame.body);
@@ -125812,6 +126330,42 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125812
126330
  }
125813
126331
  }
125814
126332
  }
126333
+ var DEVICE_KEY_SEPARATOR = "\0";
126334
+ var NO_CANDIDATES = Object.freeze([]);
126335
+ var MapCapChildIndex = class {
126336
+ deviceOwners;
126337
+ singletons;
126338
+ constructor(deviceOwners, singletons) {
126339
+ this.deviceOwners = deviceOwners;
126340
+ this.singletons = singletons;
126341
+ }
126342
+ deviceOwner(capName, deviceId) {
126343
+ return this.deviceOwners.get(`${capName}${DEVICE_KEY_SEPARATOR}${deviceId}`) ?? null;
126344
+ }
126345
+ singletonCandidates(capName) {
126346
+ return this.singletons.get(capName) ?? NO_CANDIDATES;
126347
+ }
126348
+ };
126349
+ function buildCapChildIndex(entries) {
126350
+ const deviceOwners = /* @__PURE__ */ new Map();
126351
+ const singletons = /* @__PURE__ */ new Map();
126352
+ for (const entry of entries) {
126353
+ const namedForThisChild = /* @__PURE__ */ new Set();
126354
+ for (const cap of entry.caps) {
126355
+ if (cap.deviceId === void 0) {
126356
+ if (namedForThisChild.has(cap.capName)) continue;
126357
+ namedForThisChild.add(cap.capName);
126358
+ const candidates = singletons.get(cap.capName);
126359
+ if (candidates === void 0) singletons.set(cap.capName, [entry.childId]);
126360
+ else candidates.push(entry.childId);
126361
+ continue;
126362
+ }
126363
+ const key = `${cap.capName}${DEVICE_KEY_SEPARATOR}${cap.deviceId}`;
126364
+ if (!deviceOwners.has(key)) deviceOwners.set(key, entry.childId);
126365
+ }
126366
+ }
126367
+ return new MapCapChildIndex(deviceOwners, singletons);
126368
+ }
125815
126369
  function liftRoutingHints(args) {
125816
126370
  if (args === null || typeof args !== "object" || Array.isArray(args)) return {};
125817
126371
  const nodeId = Reflect.get(args, "nodeId");
@@ -125851,6 +126405,14 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125851
126405
  /** See {@link ForwardCensus}. Mutable counters on the hot path, by design. */
125852
126406
  forwardedRaw = 0;
125853
126407
  forwardedDecoded = 0;
126408
+ /**
126409
+ * The per-ACTION byte census (D456). `ForwardCensus` above is the same
126410
+ * question asked of the whole plane; this one asks it per `<cap>.<method>`,
126411
+ * beside the bytes that method actually moved. Both are kept: `socketFwd=`
126412
+ * says whether the negotiation is working at all, and a `raw=0` on ONE
126413
+ * method with `raw>0` on its neighbours is a different fault.
126414
+ */
126415
+ actionCensus = createCapActionCensus();
125854
126416
  /** See {@link LocalChildRegistryOptions.capTimeoutMs}. */
125855
126417
  capTimeoutMs;
125856
126418
  /** See {@link LocalChildRegistryOptions.capUsageObserver}. */
@@ -125864,6 +126426,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125864
126426
  /** Last pattern-set string logged per child, to dedup the INFO line. */
125865
126427
  loggedPatternSet = /* @__PURE__ */ new Map();
125866
126428
  /**
126429
+ * Derived `(cap, device?) → child` index over {@link children}, or `null`
126430
+ * when it must be rebuilt. See {@link capIndex} for why it is a cache and
126431
+ * never a registry (D3, D457).
126432
+ */
126433
+ capChildIndex = null;
126434
+ /**
125867
126435
  * Accepts either a plain positional `server` argument (backward-compatible)
125868
126436
  * or a full `LocalChildRegistryOptions` object.
125869
126437
  *
@@ -125944,6 +126512,21 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
125944
126512
  };
125945
126513
  }
125946
126514
  /**
126515
+ * Cumulative per-action byte census: peer → `<cap>.<method>` → bytes, calls
126516
+ * and the raw/decoded split. A COPY (`cap-action-census.ts` explains why it
126517
+ * must be one); the heartbeat subtracts the previous reading.
126518
+ *
126519
+ * This is the instrument D454 closed by asking for. `socketTopBytes=` names
126520
+ * the peer that moves the bytes and `txkB=` says they are responses; neither
126521
+ * can say WHICH method originates them, and after raw-forward the bytes that
126522
+ * cross are no longer the proxy for what hub-main pays — 85.7 % of sibling
126523
+ * calls cross unread. What costs is what hub-main LOOKS at, and that is the
126524
+ * `decoded` half of an entry, next to the bytes it carried.
126525
+ */
126526
+ readActionCensus() {
126527
+ return this.actionCensus.read();
126528
+ }
126529
+ /**
125947
126530
  * The regime the counters above were produced under, read once from
125948
126531
  * `CAMSTACK_UDS_EVENT_FANOUT` at construction.
125949
126532
  *
@@ -126057,11 +126640,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126057
126640
  * compete for the same capName.
126058
126641
  */
126059
126642
  resolveChildId(capName, deviceId) {
126643
+ const index = this.capIndex();
126060
126644
  if (deviceId !== void 0) {
126061
- const deviceOwner = this.findChildId((cap) => cap.capName === capName && cap.deviceId === deviceId);
126645
+ const deviceOwner = index.deviceOwner(capName, deviceId);
126062
126646
  if (deviceOwner !== null) return deviceOwner;
126063
126647
  }
126064
- const candidates = this.findAllChildIds((cap) => cap.capName === capName && cap.deviceId === void 0);
126648
+ const candidates = index.singletonCandidates(capName);
126065
126649
  if (candidates.length === 0) return null;
126066
126650
  if (candidates.length === 1) return candidates[0];
126067
126651
  const preferredAddonId = this.getActiveSingletonAddonId?.(capName) ?? null;
@@ -126095,16 +126679,37 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126095
126679
  } catch {
126096
126680
  }
126097
126681
  }
126098
- /** First child whose cap manifest contains a descriptor matching `predicate`. */
126099
- findChildId(predicate) {
126100
- for (const entry of this.children.values()) if (entry.caps.some(predicate)) return entry.childId;
126101
- return null;
126682
+ /**
126683
+ * The cap index over the CURRENT children, rebuilt on first use after any
126684
+ * mutation of {@link children}.
126685
+ *
126686
+ * This replaced a linear walk of every child's cap manifest per
126687
+ * `cap-call-out`, measured at **7.1 % of hub-main's busy main thread**
126688
+ * across 39 children (D456). Why it did not exist before is the whole
126689
+ * design: what it indexes moves — a runner is replaced on every update, a
126690
+ * crash respawns one, a child re-registers with a replacement manifest after
126691
+ * init — and an index that names a dead child routes work into a socket
126692
+ * nobody is reading, which is strictly worse than a slow scan.
126693
+ *
126694
+ * So it is not maintained; it is DISCARDED. `buildCapChildIndex` is a pure
126695
+ * function of `children.values()`, the only two writers of that map
126696
+ * ({@link invalidateCapIndex}'s call sites) drop the index in the same
126697
+ * statement, and nothing else can construct one. There is no add-on-register
126698
+ * / remove-on-close path that could disagree with the map — i.e. no shadow
126699
+ * registry (D3): the map remains the single authority and this holds no fact
126700
+ * it does not.
126701
+ *
126702
+ * The operator's active-singleton preference is deliberately NOT indexed —
126703
+ * it changes without any child connecting or leaving, so `resolveChildId`
126704
+ * reads it live and the index only supplies the candidate list.
126705
+ */
126706
+ capIndex() {
126707
+ if (this.capChildIndex === null) this.capChildIndex = buildCapChildIndex(this.children.values());
126708
+ return this.capChildIndex;
126102
126709
  }
126103
- /** Every child whose cap manifest contains a descriptor matching `predicate`. */
126104
- findAllChildIds(predicate) {
126105
- const out = [];
126106
- for (const entry of this.children.values()) if (entry.caps.some(predicate)) out.push(entry.childId);
126107
- return out;
126710
+ /** Drop the derived index. MUST follow every write to {@link children}. */
126711
+ invalidateCapIndex() {
126712
+ this.capChildIndex = null;
126108
126713
  }
126109
126714
  /**
126110
126715
  * Does the named child currently provide `(capName, deviceId?)`?
@@ -126300,6 +126905,14 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126300
126905
  onConnection(channel) {
126301
126906
  let childId = null;
126302
126907
  const incarnation = this.nextIncarnation++;
126908
+ channel.observeActions?.({
126909
+ label: capActionLabel,
126910
+ record: (label, reqBytes, resBytes) => {
126911
+ const peerId = childId ?? "(pre-register)";
126912
+ if (label === null) this.actionCensus.recordUnlabelled(peerId, reqBytes + resBytes);
126913
+ else this.actionCensus.record(peerId, label, reqBytes, resBytes);
126914
+ }
126915
+ });
126303
126916
  channel.onEvent((body) => {
126304
126917
  const msg = body;
126305
126918
  if (msg.kind === "event") {
@@ -126342,6 +126955,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126342
126955
  incarnation,
126343
126956
  rawForward: msg.rawForward === true
126344
126957
  });
126958
+ this.invalidateCapIndex();
126345
126959
  this.logPatternSet(msg.childId, eventPatterns);
126346
126960
  this.registeredHandler({
126347
126961
  childId: msg.childId,
@@ -126373,6 +126987,8 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126373
126987
  const addonPinned = pinnedNodeId === void 0 && this.isAddonPinnedCall?.(out.capName, out.method, hints) === true;
126374
126988
  const target = !(out.native === true) && !aggregated && !addonPinned && (pinnedNodeId === void 0 || pinTargetsThisNode) ? this.resolveChildId(out.capName, out.deviceId) : null;
126375
126989
  this.recordCapUsage(childId, target, out.capName, out.method);
126990
+ const actionPeer = childId ?? "(pre-register)";
126991
+ const actionLabel = `${out.capName}.${out.method}`;
126376
126992
  if (target !== null) {
126377
126993
  if (!this.egressRoutedCaps.has(out.capName)) {
126378
126994
  this.egressRoutedCaps.add(out.capName);
@@ -126381,6 +126997,7 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126381
126997
  const entry = this.children.get(target);
126382
126998
  if (payload !== void 0 && entry !== void 0 && entry.rawForward) {
126383
126999
  this.forwardedRaw += 1;
127000
+ this.actionCensus.recordForward(actionPeer, actionLabel, "raw");
126384
127001
  const forward = {
126385
127002
  kind: "cap-call",
126386
127003
  capName: out.capName,
@@ -126395,9 +127012,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126395
127012
  });
126396
127013
  }
126397
127014
  this.forwardedDecoded += 1;
126398
- return this.callCap(buildInput());
127015
+ this.actionCensus.recordForward(actionPeer, actionLabel, "decoded");
127016
+ const input = buildInput();
127017
+ return entry !== void 0 ? this.callCapOnChild(target, input) : this.callCap(input);
126399
127018
  }
126400
127019
  this.forwardedDecoded += 1;
127020
+ this.actionCensus.recordForward(actionPeer, actionLabel, "decoded");
126401
127021
  if (this.onUnownedCall !== void 0) return this.onUnownedCall(buildInput());
126402
127022
  throw new Error(`${UDS_NO_ROUTE_PREFIX}: cap-call-out has no local provider for "${out.capName}" and no fallback`);
126403
127023
  }
@@ -126420,7 +127040,9 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
126420
127040
  return;
126421
127041
  }
126422
127042
  this.children.delete(childId);
127043
+ this.invalidateCapIndex();
126423
127044
  this.childEventStats.delete(childId);
127045
+ this.actionCensus.forget(childId);
126424
127046
  this.loggedPatternSet.delete(childId);
126425
127047
  this.goneHandler(childId, incarnation);
126426
127048
  });
@@ -129074,6 +129696,18 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129074
129696
  return AddonDepsManager;
129075
129697
  }
129076
129698
  });
129699
+ Object.defineProperty(exports, "CAP_ACTION_OVERFLOW_LABEL", {
129700
+ enumerable: true,
129701
+ get: function() {
129702
+ return CAP_ACTION_OVERFLOW_LABEL;
129703
+ }
129704
+ });
129705
+ Object.defineProperty(exports, "CAP_ACTION_UNLABELLED", {
129706
+ enumerable: true,
129707
+ get: function() {
129708
+ return CAP_ACTION_UNLABELLED;
129709
+ }
129710
+ });
129077
129711
  Object.defineProperty(exports, "CapRouteError", {
129078
129712
  enumerable: true,
129079
129713
  get: function() {
@@ -129116,6 +129750,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129116
129750
  return DeviceRegistry;
129117
129751
  }
129118
129752
  });
129753
+ Object.defineProperty(exports, "EMPTY_CAP_ACTION_READING", {
129754
+ enumerable: true,
129755
+ get: function() {
129756
+ return EMPTY_CAP_ACTION_READING;
129757
+ }
129758
+ });
129119
129759
  Object.defineProperty(exports, "EMPTY_SOCKET_DIRECTION", {
129120
129760
  enumerable: true,
129121
129761
  get: function() {
@@ -129212,6 +129852,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129212
129852
  return LocalChildRegistry;
129213
129853
  }
129214
129854
  });
129855
+ Object.defineProperty(exports, "MAX_CAP_ACTIONS_PER_PEER", {
129856
+ enumerable: true,
129857
+ get: function() {
129858
+ return MAX_CAP_ACTIONS_PER_PEER;
129859
+ }
129860
+ });
129215
129861
  Object.defineProperty(exports, "MESH_QUEUE_TOP_N", {
129216
129862
  enumerable: true,
129217
129863
  get: function() {
@@ -129368,6 +130014,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129368
130014
  return callWithServiceDiscovery;
129369
130015
  }
129370
130016
  });
130017
+ Object.defineProperty(exports, "capActionLabel", {
130018
+ enumerable: true,
130019
+ get: function() {
130020
+ return capActionLabel;
130021
+ }
130022
+ });
129371
130023
  Object.defineProperty(exports, "capActionName", {
129372
130024
  enumerable: true,
129373
130025
  get: function() {
@@ -129440,6 +130092,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129440
130092
  return createBrokerDeviceManagerApi;
129441
130093
  }
129442
130094
  });
130095
+ Object.defineProperty(exports, "createCapActionCensus", {
130096
+ enumerable: true,
130097
+ get: function() {
130098
+ return createCapActionCensus;
130099
+ }
130100
+ });
129443
130101
  Object.defineProperty(exports, "createDeferredHeapWatchSink", {
129444
130102
  enumerable: true,
129445
130103
  get: function() {
@@ -129566,6 +130224,12 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129566
130224
  return deserializeTypedArrays;
129567
130225
  }
129568
130226
  });
130227
+ Object.defineProperty(exports, "diffCapActionCensus", {
130228
+ enumerable: true,
130229
+ get: function() {
130230
+ return diffCapActionCensus;
130231
+ }
130232
+ });
129569
130233
  Object.defineProperty(exports, "diffEventPlane", {
129570
130234
  enumerable: true,
129571
130235
  get: function() {
@@ -129905,11 +130569,11 @@ var require_manifest_system_deps_g_nK0xsF = __commonJS({
129905
130569
  }
129906
130570
  });
129907
130571
 
129908
- // ../system/dist/custom-action-registry-DKWhaWL1.js
129909
- var require_custom_action_registry_DKWhaWL1 = __commonJS({
129910
- "../system/dist/custom-action-registry-DKWhaWL1.js"(exports) {
130572
+ // ../system/dist/custom-action-registry-DvVMHLfJ.js
130573
+ var require_custom_action_registry_DvVMHLfJ = __commonJS({
130574
+ "../system/dist/custom-action-registry-DvVMHLfJ.js"(exports) {
129911
130575
  "use strict";
129912
- var require_dist10 = require_dist_B17W9ngu();
130576
+ var require_dist10 = require_dist_0sWJNwme();
129913
130577
  var CustomActionRegistry = class {
129914
130578
  byAddon = /* @__PURE__ */ new Map();
129915
130579
  registerAddon(addonId, catalog, handler) {
@@ -133723,7 +134387,7 @@ var require_dist3 = __commonJS({
133723
134387
  "use strict";
133724
134388
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
133725
134389
  var require_chunk = require_chunk_Cek0wNdY();
133726
- var require_dist10 = require_dist_B17W9ngu();
134390
+ var require_dist10 = require_dist_0sWJNwme();
133727
134391
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
133728
134392
  require_alerts();
133729
134393
  var require_formatter = require_formatter_DqAKDlvN();
@@ -133750,9 +134414,9 @@ var require_dist3 = __commonJS({
133750
134414
  var require_builtins_winston_logging_index = require_winston_logging();
133751
134415
  var require_event_loop_stall_monitor = require_event_loop_stall_monitor_CAsHdMwP();
133752
134416
  var require_tls$1 = require_tls_BFs4PzoW();
133753
- var require_manifest_system_deps = require_manifest_system_deps_g_nK0xsF();
134417
+ var require_manifest_system_deps = require_manifest_system_deps_DfpwaXkh();
133754
134418
  var require_resource_monitor = require_resource_monitor_LVE1BoLs();
133755
- var require_custom_action_registry = require_custom_action_registry_DKWhaWL1();
134419
+ var require_custom_action_registry = require_custom_action_registry_DvVMHLfJ();
133756
134420
  var zod = require_zod();
133757
134421
  var node_crypto = __require("crypto");
133758
134422
  var _camstack_types_node = require_node();
@@ -198409,6 +199073,7 @@ ${originalIndentation}`;
198409
199073
  var require_parser3 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports2, module2) => {
198410
199074
  var Writable = __require("stream").Writable;
198411
199075
  var { resolvePacketType } = require_constants15();
199076
+ var HEADER_BYTES = 6;
198412
199077
  var Parser = class extends Writable {
198413
199078
  /**
198414
199079
  * Create an instance of Parser
@@ -198418,32 +199083,42 @@ ${originalIndentation}`;
198418
199083
  constructor(options, maxPacketSize) {
198419
199084
  super(options);
198420
199085
  this.maxPacketSize = maxPacketSize;
198421
- this.buf = null;
199086
+ this.bufs = [];
199087
+ this.bufLen = 0;
199088
+ }
199089
+ /** The first `HEADER_BYTES` pending bytes, without flattening the rest. */
199090
+ _header() {
199091
+ const first = this.bufs[0];
199092
+ if (first.length >= HEADER_BYTES) return first;
199093
+ const head = Buffer.allocUnsafe(HEADER_BYTES);
199094
+ let written = 0;
199095
+ for (let i = 0; i < this.bufs.length && written < HEADER_BYTES; i++) {
199096
+ const b = this.bufs[i];
199097
+ const take = Math.min(HEADER_BYTES - written, b.length);
199098
+ b.copy(head, written, 0, take);
199099
+ written += take;
199100
+ }
199101
+ return head;
198422
199102
  }
198423
199103
  _write(chunk, encoding, cb) {
198424
- let packet = chunk;
198425
- if (this.buf && this.buf.length > 0) {
198426
- packet = Buffer.concat([this.buf, chunk]);
198427
- this.buf = null;
198428
- }
198429
- while (packet.length > 0) {
198430
- if (packet.length < 6) {
198431
- this.buf = Buffer.from(packet);
198432
- return cb();
198433
- }
198434
- if (this.maxPacketSize && packet.length > this.maxPacketSize) return cb(/* @__PURE__ */ new Error(`Incoming packet is larger than the 'maxPacketSize' limit (${packet.length} > ${this.maxPacketSize})!`));
198435
- const crc = packet[1] ^ packet[2] ^ packet[3] ^ packet[4] ^ packet[5];
198436
- if (crc !== packet[0]) return cb(/* @__PURE__ */ new Error("Invalid packet CRC! " + crc));
198437
- const length = packet.readInt32BE(1);
198438
- if (packet.length >= length) {
198439
- const msg = packet.slice(6, length);
198440
- const type2 = resolvePacketType(packet[5]);
198441
- this.emit("data", type2, msg);
198442
- packet = packet.slice(length);
198443
- } else {
198444
- this.buf = Buffer.from(packet);
198445
- return cb();
198446
- }
199104
+ if (this.bufLen > 0) this.bufs.push(chunk);
199105
+ else this.bufs = [chunk];
199106
+ this.bufLen += chunk.length;
199107
+ while (this.bufLen > 0) {
199108
+ if (this.bufLen < HEADER_BYTES) return cb();
199109
+ if (this.maxPacketSize && this.bufLen > this.maxPacketSize) return cb(/* @__PURE__ */ new Error(`Incoming packet is larger than the 'maxPacketSize' limit (${this.bufLen} > ${this.maxPacketSize})!`));
199110
+ const header = this._header();
199111
+ const crc = header[1] ^ header[2] ^ header[3] ^ header[4] ^ header[5];
199112
+ if (crc !== header[0]) return cb(/* @__PURE__ */ new Error("Invalid packet CRC! " + crc));
199113
+ const length = header.readInt32BE(1);
199114
+ if (this.bufLen < length) return cb();
199115
+ const packet = this.bufs.length === 1 ? this.bufs[0] : Buffer.concat(this.bufs, this.bufLen);
199116
+ const msg = packet.slice(HEADER_BYTES, length);
199117
+ const type2 = resolvePacketType(packet[5]);
199118
+ this.emit("data", type2, msg);
199119
+ const rest = packet.slice(length);
199120
+ this.bufs = rest.length > 0 ? [rest] : [];
199121
+ this.bufLen = rest.length;
198447
199122
  }
198448
199123
  cb();
198449
199124
  }
@@ -214429,6 +215104,8 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214429
215104
  exports.AlertCenterAddon = require_builtins_alerts_alerts_addon.AlertCenterAddon;
214430
215105
  exports.ApiKeyManager = require_builtins_local_auth_local_auth_addon.ApiKeyManager;
214431
215106
  exports.AuthManager = require_builtins_local_auth_local_auth_addon.AuthManager;
215107
+ exports.CAP_ACTION_OVERFLOW_LABEL = require_manifest_system_deps.CAP_ACTION_OVERFLOW_LABEL;
215108
+ exports.CAP_ACTION_UNLABELLED = require_manifest_system_deps.CAP_ACTION_UNLABELLED;
214432
215109
  exports.CA_COMMON_NAME = require_tls$1.CA_COMMON_NAME;
214433
215110
  exports.CA_VALIDITY_DAYS = require_tls$1.CA_VALIDITY_DAYS;
214434
215111
  exports.CLUSTER_SECRET_MISMATCH_TYPE = CLUSTER_SECRET_MISMATCH_TYPE;
@@ -214456,6 +215133,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214456
215133
  exports.DeviceManagerAddon = require_builtins_device_manager_device_manager_addon.DeviceManagerAddon;
214457
215134
  exports.DeviceRegistry = require_manifest_system_deps.DeviceRegistry;
214458
215135
  exports.DeviceStore = require_builtins_sqlite_storage_index.DeviceStore$1;
215136
+ exports.EMPTY_CAP_ACTION_READING = require_manifest_system_deps.EMPTY_CAP_ACTION_READING;
214459
215137
  exports.EMPTY_SOCKET_DIRECTION = require_manifest_system_deps.EMPTY_SOCKET_DIRECTION;
214460
215138
  exports.EMPTY_SOCKET_PLANE_BASELINE = require_manifest_system_deps.EMPTY_SOCKET_PLANE_BASELINE;
214461
215139
  exports.EVENT_PLANE_TOP_N = require_manifest_system_deps.EVENT_PLANE_TOP_N;
@@ -214500,6 +215178,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214500
215178
  exports.LoggingGate = LoggingGate;
214501
215179
  exports.LokiDestination = require_builtins_loki_logging_index.LokiDestination$1;
214502
215180
  exports.LokiLoggingAddon = require_builtins_loki_logging_index.LokiLoggingAddon$1;
215181
+ exports.MAX_CAP_ACTIONS_PER_PEER = require_manifest_system_deps.MAX_CAP_ACTIONS_PER_PEER;
214503
215182
  exports.MAX_LEAF_VALIDITY_DAYS = require_tls$1.MAX_LEAF_VALIDITY_DAYS;
214504
215183
  exports.MESH_QUEUE_TOP_N = require_manifest_system_deps.MESH_QUEUE_TOP_N;
214505
215184
  exports.METHOD_ACCESS_MAP = require_dist10.METHOD_ACCESS_MAP;
@@ -214588,6 +215267,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214588
215267
  exports.callRegisterNodeWithRetry = callRegisterNodeWithRetry;
214589
215268
  exports.callWithServiceDiscovery = require_manifest_system_deps.callWithServiceDiscovery;
214590
215269
  exports.canServeDataPlane = canServeDataPlane;
215270
+ exports.capActionLabel = require_manifest_system_deps.capActionLabel;
214591
215271
  exports.capActionName = require_manifest_system_deps.capActionName;
214592
215272
  exports.capActionSuffix = require_manifest_system_deps.capActionSuffix;
214593
215273
  exports.capBareAction = require_manifest_system_deps.capBareAction;
@@ -214610,6 +215290,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214610
215290
  exports.createAuthenticatedFileServer = require_event_loop_stall_monitor.createAuthenticatedFileServer;
214611
215291
  exports.createBroker = createBroker2;
214612
215292
  exports.createBrokerDeviceManagerApi = require_manifest_system_deps.createBrokerDeviceManagerApi;
215293
+ exports.createCapActionCensus = require_manifest_system_deps.createCapActionCensus;
214613
215294
  exports.createCoreCapService = createCoreCapService;
214614
215295
  exports.createDeferredHeapWatchSink = require_manifest_system_deps.createDeferredHeapWatchSink;
214615
215296
  exports.createDoorSettingsView = createDoorSettingsView;
@@ -214644,6 +215325,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
214644
215325
  exports.describeProviderKindDrift = describeProviderKindDrift;
214645
215326
  exports.describeRss = require_manifest_system_deps.describeRss;
214646
215327
  exports.detectWorkspacePackagesDir = detectWorkspacePackagesDir;
215328
+ exports.diffCapActionCensus = require_manifest_system_deps.diffCapActionCensus;
214647
215329
  exports.diffEventPlane = require_manifest_system_deps.diffEventPlane;
214648
215330
  exports.diffSocketPlane = require_manifest_system_deps.diffSocketPlane;
214649
215331
  Object.defineProperty(exports, "downloadBinary", {
@@ -214841,8 +215523,8 @@ var require_dist4 = __commonJS({
214841
215523
  "../types/dist/index.js"(exports) {
214842
215524
  "use strict";
214843
215525
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
215526
+ var require_sleep = require_sleep_B1ZwxAhh();
214844
215527
  var require_event_category = require_event_category_BNJ9EE5B();
214845
- var require_sleep = require_sleep_CTHjJilA();
214846
215528
  var require_canonical_hash = require_canonical_hash_DNV8S5ET();
214847
215529
  var require_enums2 = require_enums();
214848
215530
  var require_err_msg = require_err_msg_COpsHMw2();
@@ -215990,6 +216672,7 @@ var require_dist4 = __commonJS({
215990
216672
  var RecordingObjectTriggerClassSchema = zod.z.enum(FIRST_LEVEL_MACRO_CLASSES);
215991
216673
  var noDuplicates = (values) => new Set(values).size === values.length;
215992
216674
  var MAX_SENSOR_TRIGGER_DEVICES = 16;
216675
+ var RECORDING_AUDIO_TRIGGER_OFFERED_DBFS = -30;
215993
216676
  var RecordingTriggersSchema = zod.z.object({
215994
216677
  motion: zod.z.boolean().optional(),
215995
216678
  audioThresholdDbfs: zod.z.number().optional(),
@@ -219584,6 +220267,37 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
219584
220267
  minConfidence: zod.z.number().min(0).max(1).default(0.3),
219585
220268
  allowedClasses: zod.z.array(zod.z.string()).default([])
219586
220269
  });
220270
+ var AudioAttachDeviceInputSchema = zod.z.object({
220271
+ deviceId: zod.z.number(),
220272
+ /** Broker id (`<deviceId>/<camStreamId>`) carrying this camera's audio. */
220273
+ brokerId: zod.z.string(),
220274
+ /**
220275
+ * `clusterRoles.ingestNode` — the node whose broker owns the source dial.
220276
+ * Every `streamBroker` call the attachment makes is pinned to it, exactly as
220277
+ * the orchestrator's poller pinned them before the move.
220278
+ */
220279
+ ingestNodeId: zod.z.string(),
220280
+ /**
220281
+ * Resolved once by the orchestrator at attach time, exactly as it was read
220282
+ * once per subscription before D461. The analyzer does NOT re-resolve per
220283
+ * window: a settings change re-attaches, which is what always happened.
220284
+ */
220285
+ settings: AudioAnalysisSettingsSchema
220286
+ });
220287
+ var AudioAttachDeviceResultSchema = zod.z.object({
220288
+ /** False only when the analyzer is shutting down and refused to attach. */
220289
+ attached: zod.z.boolean(),
220290
+ /**
220291
+ * True when the attachment replaced a live one for the same device. An
220292
+ * attach is idempotent by REPLACEMENT — two pollers on one camera would
220293
+ * double the broker's fanout and neither would know about the other.
220294
+ */
220295
+ replaced: zod.z.boolean()
220296
+ });
220297
+ var AudioDetachDeviceResultSchema = zod.z.object({
220298
+ /** False when no attachment existed — detach is idempotent. */
220299
+ detached: zod.z.boolean()
220300
+ });
219587
220301
  var AudioClassificationResultSchema = zod.z.object({
219588
220302
  labels: zod.z.array(AudioClassificationLabelSchema).readonly(),
219589
220303
  rawLabels: zod.z.array(AudioClassificationLabelSchema).readonly().optional(),
@@ -219617,6 +220331,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
219617
220331
  settings: AudioAnalysisSettingsSchema
219618
220332
  }), AudioAnalysisResultSchema.nullable(), { kind: "mutation" }),
219619
220333
  classify: require_sleep.method(AudioChunkInputSchema, AudioClassificationResultSchema, { timeoutMs: 3e4 }),
220334
+ /**
220335
+ * Start pulling this camera's audio from the broker, in THIS process.
220336
+ * Returns as soon as the attachment exists — the first
220337
+ * `subscribeAudioChunks` retries with backoff behind it, because the
220338
+ * broker for a camStream may not be registered yet (that tolerance moved
220339
+ * with the poller, D461). Replaces any live attachment for the device.
220340
+ */
220341
+ attachDevice: require_sleep.method(AudioAttachDeviceInputSchema, AudioAttachDeviceResultSchema, { kind: "mutation" }),
220342
+ /**
220343
+ * Stop pulling this camera's audio and release the broker subscription.
220344
+ * Idempotent. A detach that never arrives is the one failure mode this
220345
+ * split adds, which is why `AudioChunkPlane` reaps a subscription nobody
220346
+ * drains rather than trusting it (D461).
220347
+ */
220348
+ detachDevice: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), AudioDetachDeviceResultSchema, { kind: "mutation" }),
219620
220349
  isReady: require_sleep.method(zod.z.void(), zod.z.boolean()),
219621
220350
  dispose: require_sleep.method(zod.z.void(), zod.z.void(), { kind: "mutation" }),
219622
220351
  /**
@@ -230996,6 +231725,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
230996
231725
  * set `encodeJpeg: true`; `bytes` is then absent.
230997
231726
  */
230998
231727
  jpeg: zod.z.string().optional(),
231728
+ /**
231729
+ * The SAME compressed JPEG as `jpeg`, as bytes (D462). Present instead of
231730
+ * `jpeg` when the request set `acceptJpegBytes`; a request that did not gets
231731
+ * `jpeg` exactly as before. MsgPack and the mesh leg both carry binary —
231732
+ * `bytes` above has crossed this boundary as a `Uint8Array` all along — so
231733
+ * base64 was buying nothing but a multi-megabyte string in the relay's heap.
231734
+ */
231735
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
230999
231736
  width: zod.z.number().int().positive(),
231000
231737
  height: zod.z.number().int().positive(),
231001
231738
  /**
@@ -231037,7 +231774,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
231037
231774
  detail: zod.z.string().optional()
231038
231775
  })]);
231039
231776
  var ParkedTrackFrameSchema = zod.z.object({
231040
- jpeg: zod.z.string(),
231777
+ /**
231778
+ * Base64 JPEG — the pre-D462 wire. OPTIONAL since D462: a request that set
231779
+ * `acceptJpegBytes` is answered in `jpegBytes` and this is then absent.
231780
+ * Exactly one of the two is present.
231781
+ */
231782
+ jpeg: zod.z.string().optional(),
231783
+ /** The same JPEG as bytes, for a caller that declared it reads them (D462). */
231784
+ jpegBytes: zod.z.instanceof(Uint8Array).optional(),
231041
231785
  width: zod.z.number().int().positive(),
231042
231786
  height: zod.z.number().int().positive(),
231043
231787
  /** The frame instant the parcel shows (the caller's clock, echoed back). */
@@ -231693,6 +232437,13 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
231693
232437
  bbox: NativeCropBboxSchema,
231694
232438
  maxWidth: zod.z.number().int().positive().optional(),
231695
232439
  /**
232440
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
232441
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
232442
+ * wire — never assume consent: a pre-D462 caller parses the field as
232443
+ * base64 and bytes would decode to garbage rather than fail.
232444
+ */
232445
+ acceptJpegBytes: zod.z.boolean().optional(),
232446
+ /**
231696
232447
  * When `true`, the runner encodes the resolved crop to JPEG ON THE
231697
232448
  * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
231698
232449
  * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
@@ -231865,7 +232616,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
231865
232616
  getParkedTrackFrame: require_sleep.method(zod.z.object({
231866
232617
  deviceId: zod.z.number(),
231867
232618
  trackId: zod.z.string(),
231868
- kind: ParkedFrameKindSchema
232619
+ kind: ParkedFrameKindSchema,
232620
+ /**
232621
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
232622
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
232623
+ * wire — never assume consent: a pre-D462 caller parses the field as
232624
+ * base64 and bytes would decode to garbage rather than fail.
232625
+ */
232626
+ acceptJpegBytes: zod.z.boolean().optional()
231869
232627
  }), ParkedTrackFrameSchema.nullable()),
231870
232628
  /**
231871
232629
  * Drop every parcel of a track — the hub closed it. Idempotent. A track
@@ -248054,12 +248812,24 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
248054
248812
  addonId: null,
248055
248813
  access: "create"
248056
248814
  },
248815
+ "audioAnalyzer.attachDevice": {
248816
+ capName: "audio-analyzer",
248817
+ capScope: "system",
248818
+ addonId: null,
248819
+ access: "create"
248820
+ },
248057
248821
  "audioAnalyzer.classify": {
248058
248822
  capName: "audio-analyzer",
248059
248823
  capScope: "system",
248060
248824
  addonId: null,
248061
248825
  access: "view"
248062
248826
  },
248827
+ "audioAnalyzer.detachDevice": {
248828
+ capName: "audio-analyzer",
248829
+ capScope: "system",
248830
+ addonId: null,
248831
+ access: "create"
248832
+ },
248063
248833
  "audioAnalyzer.dispose": {
248064
248834
  capName: "audio-analyzer",
248065
248835
  capScope: "system",
@@ -254167,11 +254937,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
254167
254937
  form: "single",
254168
254938
  optional: false
254169
254939
  }],
254940
+ "audioAnalyzer.attachDevice": [{
254941
+ name: "deviceId",
254942
+ form: "single",
254943
+ optional: false
254944
+ }],
254170
254945
  "audioAnalyzer.classify": [{
254171
254946
  name: "deviceId",
254172
254947
  form: "single",
254173
254948
  optional: true
254174
254949
  }],
254950
+ "audioAnalyzer.detachDevice": [{
254951
+ name: "deviceId",
254952
+ form: "single",
254953
+ optional: false
254954
+ }],
254175
254955
  "audioMetrics.getCurrentSnapshot": [{
254176
254956
  name: "deviceId",
254177
254957
  form: "single",
@@ -256017,7 +256797,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256017
256797
  var SYSTEM_SCOPE_DEVICE_METHODS = [
256018
256798
  "addonSettings.getDeviceSettings",
256019
256799
  "addonSettings.updateDeviceSettings",
256800
+ "audioAnalyzer.attachDevice",
256020
256801
  "audioAnalyzer.classify",
256802
+ "audioAnalyzer.detachDevice",
256021
256803
  "decoder.createSession",
256022
256804
  "deviceAdoption.release",
256023
256805
  "deviceAdoption.resync",
@@ -256634,6 +257416,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
256634
257416
  audioAnalyzer: {
256635
257417
  analyseChunk: (input) => dispatch("audioAnalyzer", "analyseChunk", "mutation", input),
256636
257418
  classify: (input) => dispatch("audioAnalyzer", "classify", "query", input),
257419
+ attachDevice: (input) => dispatch("audioAnalyzer", "attachDevice", "mutation", input),
256637
257420
  isReady: (input) => dispatch("audioAnalyzer", "isReady", "query", input),
256638
257421
  dispose: (input) => dispatch("audioAnalyzer", "dispose", "mutation", input),
256639
257422
  reprobeAudioEngine: (input) => dispatch("audioAnalyzer", "reprobeAudioEngine", "mutation", input)
@@ -257206,6 +257989,19 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257206
257989
  }
257207
257990
  };
257208
257991
  }
257992
+ var AUDIO_SCALE_EPOCH_ISO = "2026-09-11T00:00:00.000Z";
257993
+ var AUDIO_SCALE_EPOCH_MS = Date.parse(AUDIO_SCALE_EPOCH_ISO);
257994
+ var G711_SCALE_CORRECTION_DB = {
257995
+ PCMU: 20 * Math.log10(4),
257996
+ PCMA: 20 * Math.log10(8)
257997
+ };
257998
+ function ituDbfsFromPreEpoch(law, authoredDbfs) {
257999
+ return authoredDbfs + G711_SCALE_CORRECTION_DB[law];
258000
+ }
258001
+ function audioScaleEraOf(timestampMs) {
258002
+ if (!Number.isFinite(timestampMs) || timestampMs <= 0) return "unknown";
258003
+ return timestampMs >= AUDIO_SCALE_EPOCH_MS ? "itu" : "pre-itu";
258004
+ }
257209
258005
  var AUDIO_KIND_PREFIX = "audio-";
257210
258006
  function normalizeAudioLabel(value) {
257211
258007
  return value.startsWith(AUDIO_KIND_PREFIX) ? value.slice(6) : value;
@@ -257216,7 +258012,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257216
258012
  var NC_AUDIO_DB_MIN = -96;
257217
258013
  var NC_AUDIO_DB_MAX = 0;
257218
258014
  var NC_AUDIO_DB_STEP = 3;
257219
- var NC_AUDIO_DB_OFFERED = -55;
258015
+ var NC_AUDIO_DB_OFFERED = Math.round(ituDbfsFromPreEpoch("PCMU", -55));
257220
258016
  var NC_AUDIO_HIT_PERCENT_MIN = 1;
257221
258017
  var NC_AUDIO_HIT_PERCENT_MAX = 100;
257222
258018
  var NC_AUDIO_SAMPLING_MIN_SEC = 1;
@@ -257258,7 +258054,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257258
258054
  const hasLabels = wantedLabels !== void 0 && wantedLabels.length > 0;
257259
258055
  const mode = patch.mode ?? (has(patch, "labels") && hasLabels ? "label" : has(patch, "dbThreshold") && wantedDb !== void 0 ? "level" : hasLabels ? "label" : wantedDb !== void 0 ? "level" : null);
257260
258056
  const labels = mode === "label" && hasLabels ? wantedLabels : void 0;
257261
- const dbThreshold = mode !== "level" ? void 0 : wantedDb ?? (patch.mode === "level" ? -55 : void 0);
258057
+ const dbThreshold = mode !== "level" ? void 0 : wantedDb ?? (patch.mode === "level" ? NC_AUDIO_DB_OFFERED : void 0);
257262
258058
  return {
257263
258059
  ...labels !== void 0 ? { labels: [...labels] } : {},
257264
258060
  ...dbThreshold !== void 0 ? { dbThreshold: clampInt(dbThreshold, NC_AUDIO_DB_MIN, 0) } : {},
@@ -257771,7 +258567,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257771
258567
  var NC_AUDIO_SEED = {
257772
258568
  hitPercent: NC_AUDIO_DEFAULTS.hitPercent,
257773
258569
  samplingSeconds: NC_AUDIO_DEFAULTS.samplingSeconds,
257774
- dbThreshold: -55
258570
+ dbThreshold: NC_AUDIO_DB_OFFERED
257775
258571
  };
257776
258572
  function ruleSeedForSection(section) {
257777
258573
  switch (section) {
@@ -259867,8 +260663,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
259867
260663
  exports.ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT = ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT;
259868
260664
  exports.AUDIO_ANALYSIS_CAP_NAME = AUDIO_ANALYSIS_CAP_NAME;
259869
260665
  exports.AUDIO_BACKEND_CHOICES = AUDIO_BACKEND_CHOICES;
260666
+ exports.AUDIO_CHUNK_FORMATS = require_sleep.AUDIO_CHUNK_FORMATS;
259870
260667
  exports.AUDIO_MACRO_LABELS = AUDIO_MACRO_LABELS;
259871
260668
  exports.AUDIO_PRESETS = require_canonical_hash.AUDIO_PRESETS;
260669
+ exports.AUDIO_SCALE_EPOCH_ISO = AUDIO_SCALE_EPOCH_ISO;
260670
+ exports.AUDIO_SCALE_EPOCH_MS = AUDIO_SCALE_EPOCH_MS;
259872
260671
  exports.AccessoriesStatusSchema = AccessoriesStatusSchema;
259873
260672
  exports.AccessoryKind = AccessoryKind;
259874
260673
  exports.AddBrokerInputSchema = AddBrokerInputSchema;
@@ -259908,12 +260707,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
259908
260707
  exports.AttachmentSchema = AttachmentSchema;
259909
260708
  exports.AudioAnalysisResultSchema = AudioAnalysisResultSchema;
259910
260709
  exports.AudioAnalysisSettingsSchema = AudioAnalysisSettingsSchema;
260710
+ exports.AudioAttachDeviceInputSchema = AudioAttachDeviceInputSchema;
260711
+ exports.AudioAttachDeviceResultSchema = AudioAttachDeviceResultSchema;
260712
+ exports.AudioChunkFormatSchema = require_sleep.AudioChunkFormatSchema;
259911
260713
  exports.AudioChunkInputSchema = AudioChunkInputSchema;
259912
260714
  exports.AudioClassSummarySchema = AudioClassSummarySchema;
259913
260715
  exports.AudioClassificationLabelSchema = AudioClassificationLabelSchema;
259914
260716
  exports.AudioClassificationResultSchema = AudioClassificationResultSchema;
259915
260717
  exports.AudioCodecInfoSchema = AudioCodecInfoSchema;
259916
260718
  exports.AudioDecodeSessionConfigSchema = AudioDecodeSessionConfigSchema;
260719
+ exports.AudioDetachDeviceResultSchema = AudioDetachDeviceResultSchema;
259917
260720
  exports.AudioEncodeSchema = AudioEncodeSchema;
259918
260721
  exports.AudioEncodeSessionConfigSchema = AudioEncodeSessionConfigSchema;
259919
260722
  exports.AudioEncodedChunkSchema = AudioEncodedChunkSchema;
@@ -260227,6 +261030,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
260227
261030
  exports.FrameInputSchema = FrameInputSchema;
260228
261031
  exports.FrameLazyCountersSchema = FrameLazyCountersSchema;
260229
261032
  exports.FrameLazyMetricsSchema = FrameLazyMetricsSchema;
261033
+ exports.G711_SCALE_CORRECTION_DB = G711_SCALE_CORRECTION_DB;
260230
261034
  exports.GasStatusSchema = GasStatusSchema;
260231
261035
  exports.GetLoggingSettingsInputSchema = GetLoggingSettingsInputSchema;
260232
261036
  exports.GetStreamWithCodecInputSchema = GetStreamWithCodecInputSchema;
@@ -260615,6 +261419,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
260615
261419
  exports.REACHABILITY_POLL_INTERVAL_MS = REACHABILITY_POLL_INTERVAL_MS;
260616
261420
  exports.REACHABILITY_PROBE_TIMEOUT_MS = REACHABILITY_PROBE_TIMEOUT_MS;
260617
261421
  exports.RECOGNITION_TYPES = RECOGNITION_TYPES;
261422
+ exports.RECORDING_AUDIO_TRIGGER_OFFERED_DBFS = RECORDING_AUDIO_TRIGGER_OFFERED_DBFS;
260618
261423
  exports.RECORDING_EXPORT_MAX_READ_BYTES = RECORDING_EXPORT_MAX_READ_BYTES;
260619
261424
  exports.RECORDING_TIMELINE_BATCH_MAX = RECORDING_TIMELINE_BATCH_MAX;
260620
261425
  exports.REDACTED_SECRET = REDACTED_SECRET;
@@ -260966,6 +261771,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
260966
261771
  exports.assertTimelapseCadences = assertTimelapseCadences;
260967
261772
  exports.audioAnalysisCapability = audioAnalysisCapability;
260968
261773
  exports.audioAnalyzerCapability = audioAnalyzerCapability;
261774
+ exports.audioChunkBytesPerSample = require_sleep.audioChunkBytesPerSample;
260969
261775
  exports.audioCodecCapability = audioCodecCapability;
260970
261776
  exports.audioIsFailClosed = audioIsFailClosed;
260971
261777
  exports.audioKindId = audioKindId;
@@ -260974,6 +261780,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
260974
261780
  exports.audioModeOf = audioModeOf;
260975
261781
  exports.audioOrDefaults = audioOrDefaults;
260976
261782
  exports.audioPlanFromEncodeProfile = require_canonical_hash.audioPlanFromEncodeProfile;
261783
+ exports.audioScaleEraOf = audioScaleEraOf;
260977
261784
  exports.authProviderCapability = authProviderCapability;
260978
261785
  exports.autoAssignProfiles = autoAssignProfiles;
260979
261786
  exports.automationControlCapability = automationControlCapability;
@@ -261101,6 +261908,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
261101
261908
  exports.eventsCapability = eventsCapability;
261102
261909
  exports.evictionPolicyForMode = evictionPolicyForMode;
261103
261910
  exports.evictionPolicyOfLocation = evictionPolicyOfLocation;
261911
+ exports.expandAudioChunkToF32le = require_sleep.expandAudioChunkToF32le;
261104
261912
  exports.expandCapMethods = require_sleep.expandCapMethods;
261105
261913
  exports.extractNestedAddonId = extractNestedAddonId;
261106
261914
  exports.extractSourceInfoFromMetadata = extractSourceInfoFromMetadata;
@@ -261138,6 +261946,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
261138
261946
  exports.invocationFromEncodeProfile = require_canonical_hash.invocationFromEncodeProfile;
261139
261947
  exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
261140
261948
  exports.isArrayOutputSchema = isArrayOutputSchema;
261949
+ exports.isAudioChunkFormat = require_sleep.isAudioChunkFormat;
261141
261950
  exports.isAudioLabelSelected = isAudioLabelSelected;
261142
261951
  exports.isAudioRule = isAudioRule;
261143
261952
  exports.isBaseConditionKey = isBaseConditionKey;
@@ -261164,6 +261973,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
261164
261973
  exports.isStorageLocationMode = isStorageLocationMode;
261165
261974
  exports.isSystemDelivery = isSystemDelivery;
261166
261975
  exports.isVoidInput = isVoidInput;
261976
+ exports.ituDbfsFromPreEpoch = ituDbfsFromPreEpoch;
261167
261977
  exports.jobKindSchema = jobKindSchema;
261168
261978
  exports.kebabToCamel = kebabToCamel;
261169
261979
  exports.knownValues = knownValues;
@@ -356819,6 +357629,7 @@ var require_parser2 = __commonJS({
356819
357629
  "use strict";
356820
357630
  var Writable = __require("stream").Writable;
356821
357631
  var { resolvePacketType } = require_constants9();
357632
+ var HEADER_BYTES = 6;
356822
357633
  var Parser = class extends Writable {
356823
357634
  /**
356824
357635
  * Create an instance of Parser
@@ -356828,40 +357639,57 @@ var require_parser2 = __commonJS({
356828
357639
  constructor(options, maxPacketSize) {
356829
357640
  super(options);
356830
357641
  this.maxPacketSize = maxPacketSize;
356831
- this.buf = null;
357642
+ this.bufs = [];
357643
+ this.bufLen = 0;
357644
+ }
357645
+ /** The first `HEADER_BYTES` pending bytes, without flattening the rest. */
357646
+ _header() {
357647
+ const first = this.bufs[0];
357648
+ if (first.length >= HEADER_BYTES) return first;
357649
+ const head = Buffer.allocUnsafe(HEADER_BYTES);
357650
+ let written = 0;
357651
+ for (let i = 0; i < this.bufs.length && written < HEADER_BYTES; i++) {
357652
+ const b = this.bufs[i];
357653
+ const take = Math.min(HEADER_BYTES - written, b.length);
357654
+ b.copy(head, written, 0, take);
357655
+ written += take;
357656
+ }
357657
+ return head;
356832
357658
  }
356833
357659
  _write(chunk, encoding, cb) {
356834
- let packet = chunk;
356835
- if (this.buf && this.buf.length > 0) {
356836
- packet = Buffer.concat([this.buf, chunk]);
356837
- this.buf = null;
356838
- }
356839
- while (packet.length > 0) {
356840
- if (packet.length < 6) {
356841
- this.buf = Buffer.from(packet);
357660
+ if (this.bufLen > 0) {
357661
+ this.bufs.push(chunk);
357662
+ } else {
357663
+ this.bufs = [chunk];
357664
+ }
357665
+ this.bufLen += chunk.length;
357666
+ while (this.bufLen > 0) {
357667
+ if (this.bufLen < HEADER_BYTES) {
356842
357668
  return cb();
356843
357669
  }
356844
- if (this.maxPacketSize && packet.length > this.maxPacketSize) {
357670
+ if (this.maxPacketSize && this.bufLen > this.maxPacketSize) {
356845
357671
  return cb(
356846
357672
  new Error(
356847
- `Incoming packet is larger than the 'maxPacketSize' limit (${packet.length} > ${this.maxPacketSize})!`
357673
+ `Incoming packet is larger than the 'maxPacketSize' limit (${this.bufLen} > ${this.maxPacketSize})!`
356848
357674
  )
356849
357675
  );
356850
357676
  }
356851
- const crc = packet[1] ^ packet[2] ^ packet[3] ^ packet[4] ^ packet[5];
356852
- if (crc !== packet[0]) {
357677
+ const header = this._header();
357678
+ const crc = header[1] ^ header[2] ^ header[3] ^ header[4] ^ header[5];
357679
+ if (crc !== header[0]) {
356853
357680
  return cb(new Error("Invalid packet CRC! " + crc));
356854
357681
  }
356855
- const length = packet.readInt32BE(1);
356856
- if (packet.length >= length) {
356857
- const msg = packet.slice(6, length);
356858
- const type = resolvePacketType(packet[5]);
356859
- this.emit("data", type, msg);
356860
- packet = packet.slice(length);
356861
- } else {
356862
- this.buf = Buffer.from(packet);
357682
+ const length = header.readInt32BE(1);
357683
+ if (this.bufLen < length) {
356863
357684
  return cb();
356864
357685
  }
357686
+ const packet = this.bufs.length === 1 ? this.bufs[0] : Buffer.concat(this.bufs, this.bufLen);
357687
+ const msg = packet.slice(HEADER_BYTES, length);
357688
+ const type = resolvePacketType(packet[5]);
357689
+ this.emit("data", type, msg);
357690
+ const rest = packet.slice(length);
357691
+ this.bufs = rest.length > 0 ? [rest] : [];
357692
+ this.bufLen = rest.length;
356865
357693
  }
356866
357694
  cb();
356867
357695
  }