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.
@@ -14522,7 +14522,35 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-ox21Ig4I.mjs
14525
+ // ../types/dist/sleep-BnujYGPe.mjs
14526
+ var AUDIO_CHUNK_FORMATS = [
14527
+ "f32le",
14528
+ "pcmu",
14529
+ "pcma"
14530
+ ];
14531
+ function buildUlawTable() {
14532
+ const table2 = new Float32Array(256);
14533
+ for (let i = 0; i < 256; i++) {
14534
+ const complemented = ~i & 255;
14535
+ const sign = (complemented & 128) !== 0 ? -1 : 1;
14536
+ const exponent = complemented >> 4 & 7;
14537
+ table2[i] = sign * ((8 * (complemented & 15) + 132 << exponent) - 132) / 32768;
14538
+ }
14539
+ return table2;
14540
+ }
14541
+ function buildAlawTable() {
14542
+ const table2 = new Float32Array(256);
14543
+ for (let i = 0; i < 256; i++) {
14544
+ const xored = i ^ 85;
14545
+ const sign = (xored & 128) !== 0 ? 1 : -1;
14546
+ const exponent = xored >> 4 & 7;
14547
+ const mantissa = xored & 15;
14548
+ table2[i] = sign * (exponent === 0 ? 16 * mantissa + 8 : 16 * mantissa + 264 << exponent - 1) / 32768;
14549
+ }
14550
+ return table2;
14551
+ }
14552
+ var ULAW_TABLE = buildUlawTable();
14553
+ var ALAW_TABLE = buildAlawTable();
14526
14554
  var WELL_KNOWN_TABS = [
14527
14555
  {
14528
14556
  id: "overview",
@@ -14877,16 +14905,36 @@ var SubscribeFramesResultSchema = external_exports.object({
14877
14905
  /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
14878
14906
  maxFps: external_exports.number().nonnegative()
14879
14907
  });
14908
+ var AudioChunkFormatSchema = external_exports.enum(AUDIO_CHUNK_FORMATS);
14880
14909
  var DecodedAudioChunkSchema = external_exports.object({
14881
14910
  data: external_exports.instanceof(Uint8Array),
14882
14911
  sampleRate: external_exports.number().int().positive(),
14883
14912
  channels: external_exports.number().int().positive(),
14884
- timestamp: external_exports.number()
14913
+ timestamp: external_exports.number(),
14914
+ /**
14915
+ * Byte format of `data`. ABSENT MEANS `f32le` — today's bytes, byte for
14916
+ * byte, for any peer that never heard of this field. A coded window
14917
+ * (`pcmu` / `pcma`, one byte per sample) is only ever emitted to a
14918
+ * subscription that DECLARED it accepts one, so absence can never mean
14919
+ * "coded bytes a consumer will read as floats" (D455).
14920
+ */
14921
+ format: AudioChunkFormatSchema.optional()
14885
14922
  });
14886
14923
  var SubscribeAudioChunksInputSchema = external_exports.object({
14887
14924
  brokerId: external_exports.string(),
14888
14925
  /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
14889
- tag: external_exports.string().optional()
14926
+ tag: external_exports.string().optional(),
14927
+ /**
14928
+ * Byte formats this subscriber can READ, best first. The broker serves the
14929
+ * chunk's own format when it is in this list and expands to `f32le`
14930
+ * otherwise, so a subscriber is never handed bytes it cannot interpret.
14931
+ *
14932
+ * Absent (or without the source format) means `f32le` — the behaviour every
14933
+ * subscriber had before D455, unchanged. This is the negotiation half of
14934
+ * the source-bytes lever: it is what lets the broker and its consumers
14935
+ * deploy one at a time across three nodes.
14936
+ */
14937
+ accept: external_exports.array(AudioChunkFormatSchema).readonly().optional()
14890
14938
  });
14891
14939
  var SubscribeAudioChunksResultSchema = external_exports.object({
14892
14940
  /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
@@ -17896,6 +17944,37 @@ var AudioAnalysisSettingsSchema = external_exports.object({
17896
17944
  minConfidence: external_exports.number().min(0).max(1).default(0.3),
17897
17945
  allowedClasses: external_exports.array(external_exports.string()).default([])
17898
17946
  });
17947
+ var AudioAttachDeviceInputSchema = external_exports.object({
17948
+ deviceId: external_exports.number(),
17949
+ /** Broker id (`<deviceId>/<camStreamId>`) carrying this camera's audio. */
17950
+ brokerId: external_exports.string(),
17951
+ /**
17952
+ * `clusterRoles.ingestNode` — the node whose broker owns the source dial.
17953
+ * Every `streamBroker` call the attachment makes is pinned to it, exactly as
17954
+ * the orchestrator's poller pinned them before the move.
17955
+ */
17956
+ ingestNodeId: external_exports.string(),
17957
+ /**
17958
+ * Resolved once by the orchestrator at attach time, exactly as it was read
17959
+ * once per subscription before D461. The analyzer does NOT re-resolve per
17960
+ * window: a settings change re-attaches, which is what always happened.
17961
+ */
17962
+ settings: AudioAnalysisSettingsSchema
17963
+ });
17964
+ var AudioAttachDeviceResultSchema = external_exports.object({
17965
+ /** False only when the analyzer is shutting down and refused to attach. */
17966
+ attached: external_exports.boolean(),
17967
+ /**
17968
+ * True when the attachment replaced a live one for the same device. An
17969
+ * attach is idempotent by REPLACEMENT — two pollers on one camera would
17970
+ * double the broker's fanout and neither would know about the other.
17971
+ */
17972
+ replaced: external_exports.boolean()
17973
+ });
17974
+ var AudioDetachDeviceResultSchema = external_exports.object({
17975
+ /** False when no attachment existed — detach is idempotent. */
17976
+ detached: external_exports.boolean()
17977
+ });
17899
17978
  var AudioClassificationResultSchema = external_exports.object({
17900
17979
  labels: external_exports.array(AudioClassificationLabelSchema).readonly(),
17901
17980
  rawLabels: external_exports.array(AudioClassificationLabelSchema).readonly().optional(),
@@ -17911,6 +17990,21 @@ var audioAnalyzerCapability = {
17911
17990
  settings: AudioAnalysisSettingsSchema
17912
17991
  }), AudioAnalysisResultSchema.nullable(), { kind: "mutation" }),
17913
17992
  classify: method(AudioChunkInputSchema, AudioClassificationResultSchema, { timeoutMs: 3e4 }),
17993
+ /**
17994
+ * Start pulling this camera's audio from the broker, in THIS process.
17995
+ * Returns as soon as the attachment exists — the first
17996
+ * `subscribeAudioChunks` retries with backoff behind it, because the
17997
+ * broker for a camStream may not be registered yet (that tolerance moved
17998
+ * with the poller, D461). Replaces any live attachment for the device.
17999
+ */
18000
+ attachDevice: method(AudioAttachDeviceInputSchema, AudioAttachDeviceResultSchema, { kind: "mutation" }),
18001
+ /**
18002
+ * Stop pulling this camera's audio and release the broker subscription.
18003
+ * Idempotent. A detach that never arrives is the one failure mode this
18004
+ * split adds, which is why `AudioChunkPlane` reaps a subscription nobody
18005
+ * drains rather than trusting it (D461).
18006
+ */
18007
+ detachDevice: method(external_exports.object({ deviceId: external_exports.number() }), AudioDetachDeviceResultSchema, { kind: "mutation" }),
17914
18008
  isReady: method(external_exports.void(), external_exports.boolean()),
17915
18009
  dispose: method(external_exports.void(), external_exports.void(), { kind: "mutation" }),
17916
18010
  /**
@@ -28258,6 +28352,14 @@ var NativeCropResultSchema = external_exports.object({
28258
28352
  * set `encodeJpeg: true`; `bytes` is then absent.
28259
28353
  */
28260
28354
  jpeg: external_exports.string().optional(),
28355
+ /**
28356
+ * The SAME compressed JPEG as `jpeg`, as bytes (D462). Present instead of
28357
+ * `jpeg` when the request set `acceptJpegBytes`; a request that did not gets
28358
+ * `jpeg` exactly as before. MsgPack and the mesh leg both carry binary —
28359
+ * `bytes` above has crossed this boundary as a `Uint8Array` all along — so
28360
+ * base64 was buying nothing but a multi-megabyte string in the relay's heap.
28361
+ */
28362
+ jpegBytes: external_exports.instanceof(Uint8Array).optional(),
28261
28363
  width: external_exports.number().int().positive(),
28262
28364
  height: external_exports.number().int().positive(),
28263
28365
  /**
@@ -28299,7 +28401,14 @@ var ParkTrackFrameResultSchema = external_exports.discriminatedUnion("parked", [
28299
28401
  detail: external_exports.string().optional()
28300
28402
  })]);
28301
28403
  var ParkedTrackFrameSchema = external_exports.object({
28302
- jpeg: external_exports.string(),
28404
+ /**
28405
+ * Base64 JPEG — the pre-D462 wire. OPTIONAL since D462: a request that set
28406
+ * `acceptJpegBytes` is answered in `jpegBytes` and this is then absent.
28407
+ * Exactly one of the two is present.
28408
+ */
28409
+ jpeg: external_exports.string().optional(),
28410
+ /** The same JPEG as bytes, for a caller that declared it reads them (D462). */
28411
+ jpegBytes: external_exports.instanceof(Uint8Array).optional(),
28303
28412
  width: external_exports.number().int().positive(),
28304
28413
  height: external_exports.number().int().positive(),
28305
28414
  /** The frame instant the parcel shows (the caller's clock, echoed back). */
@@ -28955,6 +29064,13 @@ var pipelineRunnerCapability = {
28955
29064
  bbox: NativeCropBboxSchema,
28956
29065
  maxWidth: external_exports.number().int().positive().optional(),
28957
29066
  /**
29067
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
29068
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
29069
+ * wire — never assume consent: a pre-D462 caller parses the field as
29070
+ * base64 and bytes would decode to garbage rather than fail.
29071
+ */
29072
+ acceptJpegBytes: external_exports.boolean().optional(),
29073
+ /**
28958
29074
  * When `true`, the runner encodes the resolved crop to JPEG ON THE
28959
29075
  * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
28960
29076
  * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
@@ -29127,7 +29243,14 @@ var pipelineRunnerCapability = {
29127
29243
  getParkedTrackFrame: method(external_exports.object({
29128
29244
  deviceId: external_exports.number(),
29129
29245
  trackId: external_exports.string(),
29130
- kind: ParkedFrameKindSchema
29246
+ kind: ParkedFrameKindSchema,
29247
+ /**
29248
+ * The caller reads a `Uint8Array` (D462). When set, a JPEG answer comes
29249
+ * back in `jpegBytes` instead of base64 `jpeg`. Absent means the old
29250
+ * wire — never assume consent: a pre-D462 caller parses the field as
29251
+ * base64 and bytes would decode to garbage rather than fail.
29252
+ */
29253
+ acceptJpegBytes: external_exports.boolean().optional()
29131
29254
  }), ParkedTrackFrameSchema.nullable()),
29132
29255
  /**
29133
29256
  * Drop every parcel of a track — the hub closed it. Idempotent. A track
@@ -40954,12 +41077,24 @@ var METHOD_ACCESS_MAP = Object.freeze({
40954
41077
  addonId: null,
40955
41078
  access: "create"
40956
41079
  },
41080
+ "audioAnalyzer.attachDevice": {
41081
+ capName: "audio-analyzer",
41082
+ capScope: "system",
41083
+ addonId: null,
41084
+ access: "create"
41085
+ },
40957
41086
  "audioAnalyzer.classify": {
40958
41087
  capName: "audio-analyzer",
40959
41088
  capScope: "system",
40960
41089
  addonId: null,
40961
41090
  access: "view"
40962
41091
  },
41092
+ "audioAnalyzer.detachDevice": {
41093
+ capName: "audio-analyzer",
41094
+ capScope: "system",
41095
+ addonId: null,
41096
+ access: "create"
41097
+ },
40963
41098
  "audioAnalyzer.dispose": {
40964
41099
  capName: "audio-analyzer",
40965
41100
  capScope: "system",
@@ -46803,11 +46938,21 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
46803
46938
  form: "single",
46804
46939
  optional: false
46805
46940
  }],
46941
+ "audioAnalyzer.attachDevice": [{
46942
+ name: "deviceId",
46943
+ form: "single",
46944
+ optional: false
46945
+ }],
46806
46946
  "audioAnalyzer.classify": [{
46807
46947
  name: "deviceId",
46808
46948
  form: "single",
46809
46949
  optional: true
46810
46950
  }],
46951
+ "audioAnalyzer.detachDevice": [{
46952
+ name: "deviceId",
46953
+ form: "single",
46954
+ optional: false
46955
+ }],
46811
46956
  "audioMetrics.getCurrentSnapshot": [{
46812
46957
  name: "deviceId",
46813
46958
  form: "single",
@@ -48659,6 +48804,16 @@ var CAP_PROVIDER_KIND_MAP = Object.freeze({
48659
48804
  "network-access": "ingress",
48660
48805
  "smtp-provider": "email"
48661
48806
  });
48807
+ var AUDIO_SCALE_EPOCH_ISO = "2026-09-11T00:00:00.000Z";
48808
+ var AUDIO_SCALE_EPOCH_MS = Date.parse(AUDIO_SCALE_EPOCH_ISO);
48809
+ var G711_SCALE_CORRECTION_DB = {
48810
+ PCMU: 20 * Math.log10(4),
48811
+ PCMA: 20 * Math.log10(8)
48812
+ };
48813
+ function ituDbfsFromPreEpoch(law, authoredDbfs) {
48814
+ return authoredDbfs + G711_SCALE_CORRECTION_DB[law];
48815
+ }
48816
+ var NC_AUDIO_DB_OFFERED = Math.round(ituDbfsFromPreEpoch("PCMU", -55));
48662
48817
  var NC_AUDIO_DEFAULTS = {
48663
48818
  hitPercent: 60,
48664
48819
  samplingSeconds: 10
@@ -48668,7 +48823,7 @@ var BASE_CONDITION_SET = new Set(NC_BASE_CONDITION_KEYS);
48668
48823
  var NC_AUDIO_SEED = {
48669
48824
  hitPercent: NC_AUDIO_DEFAULTS.hitPercent,
48670
48825
  samplingSeconds: NC_AUDIO_DEFAULTS.samplingSeconds,
48671
- dbThreshold: -55
48826
+ dbThreshold: NC_AUDIO_DB_OFFERED
48672
48827
  };
48673
48828
  var TimelapseTemplateSchema = external_exports.object({
48674
48829
  title: external_exports.string().max(500).optional(),
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-6RH3QFQD.js";
4
+ } from "./chunk-I7QELQM5.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-JISZUXK5.js");
41
+ await import("./launcher-TQKCEWPV.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-JISZUXK5.js");
86
+ await import("./launcher-TQKCEWPV.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-2BZHPBNB.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-ELE6KHU4.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-6RH3QFQD.js";
8
+ } from "./chunk-I7QELQM5.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,