@camstack/addon-pipeline 1.2.190 → 1.2.191

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.
Files changed (38) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/detection-pipeline/index.js +5 -5
  4. package/dist/detection-pipeline/index.mjs +4 -4
  5. package/dist/{dist-CZkzc0WB.mjs → dist-Cjazw3T-.mjs} +307 -0
  6. package/dist/{dist-C31OZkZP.js → dist-PQArEi7A.js} +307 -0
  7. package/dist/{lazy-sharp-DhHuLuQf.js → lazy-sharp-DfnnPeG5.js} +1 -1
  8. package/dist/{local-frame-registry-B8_L3v0O.mjs → local-frame-registry-CrLITJ5O.mjs} +1 -1
  9. package/dist/{local-frame-registry-CkIaPLcW.js → local-frame-registry-DNVTAOrZ.js} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-kSXNMrbg.mjs → node-KFUZT2L-.mjs} +1 -1
  13. package/dist/{node-CIpenwbm.js → node-wFmd_eR_.js} +1 -1
  14. package/dist/pipeline-runner/index.js +5 -5
  15. package/dist/pipeline-runner/index.mjs +4 -4
  16. package/dist/{process-memory-BQTHtzan.js → process-memory-B4o15Ps9.js} +1 -1
  17. package/dist/{process-memory-CphvVq1H.mjs → process-memory-BgX9_XQ5.mjs} +1 -1
  18. package/dist/recorder/index.js +2 -2
  19. package/dist/recorder/index.mjs +2 -2
  20. package/dist/{segment-demux-js-CYjZAotp.js → segment-demux-js-C36b7S82.js} +1 -1
  21. package/dist/{segment-demux-js-AELUnBau.mjs → segment-demux-js-Cgz-NlSg.mjs} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +44 -6
  23. package/dist/session-decode/decode-worker-child.mjs +43 -5
  24. package/dist/stream-broker/_stub.js +2 -2
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BA9MaopY.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-YWGmRusr.mjs} +3 -3
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D8AK-_F6.mjs +26 -0
  27. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CkCh5TvE.mjs +26 -0
  28. package/dist/stream-broker/demux-worker-child.js +1 -1
  29. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  30. package/dist/stream-broker/{hostInit-0htGr-yV.mjs → hostInit-CuZBoqi0.mjs} +3 -3
  31. package/dist/stream-broker/index.js +3 -3
  32. package/dist/stream-broker/index.mjs +3 -3
  33. package/dist/stream-broker/remoteEntry.js +1 -1
  34. package/dist/{worker-protocol-BSgTKhW7.js → worker-protocol-BulRQMSK.js} +1 -1
  35. package/dist/{worker-protocol-Bcy8Ti5P.mjs → worker-protocol-n4hf2NsC.mjs} +1 -1
  36. package/package.json +1 -1
  37. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CDtnQr69.mjs +0 -26
  38. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BOR2heMq.mjs +0 -26
@@ -29647,6 +29647,203 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
29647
29647
  deviceId: number(),
29648
29648
  status: PtzAutotrackStatusSchema
29649
29649
  });
29650
+ /**
29651
+ * `navigation` — a device-scoped capability that natively expresses the FULL
29652
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
29653
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
29654
+ *
29655
+ * Why a NEW cap rather than overloading `ptz`:
29656
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
29657
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
29658
+ * The two are different physical models: PTZ is absolute-position + presets,
29659
+ * navigation is momentary drive nudges + discrete robot ACTIONS
29660
+ * (dock / spot-clean / follow-pet / go-to-point / …).
29661
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
29662
+ * the reverse:
29663
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
29664
+ * / `getOptions`), and
29665
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
29666
+ * robot camera shows up in the existing PTZ control path without every
29667
+ * PTZ provider learning about robots. The mapping lives in the adapter,
29668
+ * not here (see the addon design note):
29669
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
29670
+ * ptz.stop() → navigation.stop()
29671
+ * ptz.goHome() → navigation.runAction('goHome')
29672
+ * ptz.getPresets() → navigation.listActions() (id→preset)
29673
+ * ptz.goToPreset(id) → navigation.runAction(id)
29674
+ *
29675
+ * ## Continuous drive
29676
+ *
29677
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
29678
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
29679
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
29680
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
29681
+ * coalesce them. The UI owns the cadence.
29682
+ *
29683
+ * ## The action dictionary
29684
+ *
29685
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
29686
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
29687
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
29688
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
29689
+ * vendor-specific list. `kind: 'action'` entries are triggered with
29690
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
29691
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
29692
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
29693
+ *
29694
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
29695
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
29696
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
29697
+ * every device handle. A future nodedreame publish adds a typed
29698
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
29699
+ * provider can then swap the raw calls for the typed methods with no change to
29700
+ * THIS contract.
29701
+ */
29702
+ /**
29703
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
29704
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
29705
+ * halts it.
29706
+ *
29707
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
29708
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
29709
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
29710
+ * vector by it (drivers without proportional drive ignore it).
29711
+ *
29712
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
29713
+ * axis alone; an all-undefined nudge is a no-op.
29714
+ */
29715
+ var NavigationMoveCommandSchema = object({
29716
+ pan: number().min(-1).max(1).optional(),
29717
+ tilt: number().min(-1).max(1).optional(),
29718
+ speed: number().min(0).max(1).optional()
29719
+ });
29720
+ /**
29721
+ * The enumerated discrete actions a navigation-capable robot can perform via
29722
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
29723
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
29724
+ * `playSound` (see the `sound` dictionary entries).
29725
+ */
29726
+ var NavigationActionIdSchema = _enum([
29727
+ "goHome",
29728
+ "locate",
29729
+ "spotClean",
29730
+ "findPet",
29731
+ "personFollow",
29732
+ "stop",
29733
+ "startClean",
29734
+ "pauseClean",
29735
+ "dockWash",
29736
+ "autoEmpty",
29737
+ "flashOn",
29738
+ "flashOff"
29739
+ ]);
29740
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
29741
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
29742
+ /**
29743
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
29744
+ * native panel and the PTZ mimic render as a button.
29745
+ *
29746
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
29747
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
29748
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
29749
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
29750
+ * - `label` — operator-facing English label.
29751
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
29752
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
29753
+ * PTZ render ONLY enabled entries. Data-driven: the provider
29754
+ * flips it from config, never by editing code.
29755
+ */
29756
+ var NavigationActionEntrySchema = object({
29757
+ id: string(),
29758
+ kind: NavigationEntryKindSchema,
29759
+ label: string(),
29760
+ icon: string(),
29761
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
29762
+ soundId: number().int().optional(),
29763
+ /** Per-device feature flag — render this entry only when true. */
29764
+ enabled: boolean()
29765
+ });
29766
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
29767
+ var NavigationPointSchema = object({
29768
+ x: number(),
29769
+ y: number()
29770
+ });
29771
+ /**
29772
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
29773
+ * The cap reports which are enabled so the UI / PTZ render only the controls
29774
+ * that are turned on for THIS device. Data-driven: the provider derives these
29775
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
29776
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
29777
+ * that are not dictionary entries.
29778
+ *
29779
+ * - `move` / `stop` — the momentary drive joystick.
29780
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
29781
+ * map-coordinate plumbing is wired.
29782
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
29783
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
29784
+ * - `light` — the on/off fill-light toggle (works anytime).
29785
+ * - `lightMode` — the auto/manual selector + manual level slider (a
29786
+ * camera-service control; needs an active stream).
29787
+ */
29788
+ var NavigationFeaturesSchema = object({
29789
+ move: boolean(),
29790
+ stop: boolean(),
29791
+ goToPoint: boolean(),
29792
+ runAction: boolean(),
29793
+ playSound: boolean(),
29794
+ light: boolean(),
29795
+ lightMode: boolean()
29796
+ });
29797
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
29798
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
29799
+ /**
29800
+ * Live navigation state so the UI can reflect what the robot is doing:
29801
+ * - `mode` — coarse activity (idle / cleaning / following / …).
29802
+ * - `following` — person/pet follow is currently armed.
29803
+ * - `flash` — the on-camera fill light is on.
29804
+ * - `lightMode` — auto vs manual fill-light mode.
29805
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
29806
+ * `lightMode === 'manual'`.
29807
+ */
29808
+ var NavigationStatusSchema = object({
29809
+ mode: _enum([
29810
+ "idle",
29811
+ "cleaning",
29812
+ "spot",
29813
+ "following",
29814
+ "goto",
29815
+ "returning",
29816
+ "paused",
29817
+ "unknown"
29818
+ ]),
29819
+ following: boolean(),
29820
+ flash: boolean(),
29821
+ lightMode: NavigationLightModeSchema,
29822
+ lightLevel: number().min(40).max(100),
29823
+ /** Ms epoch when the slice was last updated. */
29824
+ lastChangedAt: number()
29825
+ });
29826
+ NavigationStatusSchema.extend({ lastFetchedAt: number() });
29827
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(NavigationActionEntrySchema)), method(object({
29828
+ deviceId: number(),
29829
+ actionId: NavigationActionIdSchema
29830
+ }), _void(), { kind: "mutation" }), method(object({
29831
+ deviceId: number(),
29832
+ soundId: number().int()
29833
+ }), _void(), { kind: "mutation" }), method(object({
29834
+ deviceId: number(),
29835
+ on: boolean()
29836
+ }), _void(), { kind: "mutation" }), method(object({
29837
+ deviceId: number(),
29838
+ mode: NavigationLightModeSchema,
29839
+ level: number().min(40).max(100).optional()
29840
+ }), _void(), { kind: "mutation" }), method(object({
29841
+ deviceId: number(),
29842
+ level: number().min(40).max(100)
29843
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), NavigationFeaturesSchema), object({
29844
+ deviceId: number(),
29845
+ status: NavigationStatusSchema
29846
+ });
29650
29847
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
29651
29848
  kind: "mutation",
29652
29849
  auth: "admin"
@@ -35095,6 +35292,66 @@ Object.freeze({
35095
35292
  addonId: null,
35096
35293
  access: "create"
35097
35294
  },
35295
+ "navigation.getFeatures": {
35296
+ capName: "navigation",
35297
+ capScope: "device",
35298
+ addonId: null,
35299
+ access: "view"
35300
+ },
35301
+ "navigation.goToPoint": {
35302
+ capName: "navigation",
35303
+ capScope: "device",
35304
+ addonId: null,
35305
+ access: "create"
35306
+ },
35307
+ "navigation.listActions": {
35308
+ capName: "navigation",
35309
+ capScope: "device",
35310
+ addonId: null,
35311
+ access: "view"
35312
+ },
35313
+ "navigation.move": {
35314
+ capName: "navigation",
35315
+ capScope: "device",
35316
+ addonId: null,
35317
+ access: "create"
35318
+ },
35319
+ "navigation.playSound": {
35320
+ capName: "navigation",
35321
+ capScope: "device",
35322
+ addonId: null,
35323
+ access: "create"
35324
+ },
35325
+ "navigation.runAction": {
35326
+ capName: "navigation",
35327
+ capScope: "device",
35328
+ addonId: null,
35329
+ access: "create"
35330
+ },
35331
+ "navigation.setLightLevel": {
35332
+ capName: "navigation",
35333
+ capScope: "device",
35334
+ addonId: null,
35335
+ access: "create"
35336
+ },
35337
+ "navigation.setLightMode": {
35338
+ capName: "navigation",
35339
+ capScope: "device",
35340
+ addonId: null,
35341
+ access: "create"
35342
+ },
35343
+ "navigation.setLightOn": {
35344
+ capName: "navigation",
35345
+ capScope: "device",
35346
+ addonId: null,
35347
+ access: "create"
35348
+ },
35349
+ "navigation.stop": {
35350
+ capName: "navigation",
35351
+ capScope: "device",
35352
+ addonId: null,
35353
+ access: "create"
35354
+ },
35098
35355
  "networkAccess.getEndpoint": {
35099
35356
  capName: "network-access",
35100
35357
  capScope: "system",
@@ -39190,6 +39447,56 @@ Object.freeze({
39190
39447
  form: "single",
39191
39448
  optional: false
39192
39449
  }],
39450
+ "navigation.getFeatures": [{
39451
+ name: "deviceId",
39452
+ form: "single",
39453
+ optional: false
39454
+ }],
39455
+ "navigation.goToPoint": [{
39456
+ name: "deviceId",
39457
+ form: "single",
39458
+ optional: false
39459
+ }],
39460
+ "navigation.listActions": [{
39461
+ name: "deviceId",
39462
+ form: "single",
39463
+ optional: false
39464
+ }],
39465
+ "navigation.move": [{
39466
+ name: "deviceId",
39467
+ form: "single",
39468
+ optional: false
39469
+ }],
39470
+ "navigation.playSound": [{
39471
+ name: "deviceId",
39472
+ form: "single",
39473
+ optional: false
39474
+ }],
39475
+ "navigation.runAction": [{
39476
+ name: "deviceId",
39477
+ form: "single",
39478
+ optional: false
39479
+ }],
39480
+ "navigation.setLightLevel": [{
39481
+ name: "deviceId",
39482
+ form: "single",
39483
+ optional: false
39484
+ }],
39485
+ "navigation.setLightMode": [{
39486
+ name: "deviceId",
39487
+ form: "single",
39488
+ optional: false
39489
+ }],
39490
+ "navigation.setLightOn": [{
39491
+ name: "deviceId",
39492
+ form: "single",
39493
+ optional: false
39494
+ }],
39495
+ "navigation.stop": [{
39496
+ name: "deviceId",
39497
+ form: "single",
39498
+ optional: false
39499
+ }],
39193
39500
  "networkQuality.getDeviceStats": [{
39194
39501
  name: "deviceId",
39195
39502
  form: "single",
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C31OZkZP.js");
1
+ const require_dist = require("./dist-PQArEi7A.js");
2
2
  let node_path = require("node:path");
3
3
  node_path = require_dist.__toESM(node_path);
4
4
  let node_url = require("node:url");
@@ -1,4 +1,4 @@
1
- import { M as audioKindId, Z as hfModelUrl, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-CZkzc0WB.mjs";
1
+ import { M as audioKindId, Z as hfModelUrl, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-Cjazw3T-.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C31OZkZP.js");
1
+ const require_dist = require("./dist-PQArEi7A.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-C31OZkZP.js");
6
- const require_lazy_sharp = require("../lazy-sharp-DhHuLuQf.js");
5
+ const require_dist = require("../dist-PQArEi7A.js");
6
+ const require_lazy_sharp = require("../lazy-sharp-DfnnPeG5.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
9
9
  //#region src/motion-wasm/wasm-motion-detector.ts
@@ -1,4 +1,4 @@
1
- import { It as hydrateSchema, Pt as DeviceType, Y as evaluateZoneRules, it as motionDetectionCapability, jt as BaseAddon } from "../dist-CZkzc0WB.mjs";
1
+ import { It as hydrateSchema, Pt as DeviceType, Y as evaluateZoneRules, it as motionDetectionCapability, jt as BaseAddon } from "../dist-Cjazw3T-.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -1,4 +1,4 @@
1
- import { Dt as buildFfmpegArgs, Et as Fmp4BoxSplitter, kt as isSoftwareDecode, wt as errMsg } from "./dist-CZkzc0WB.mjs";
1
+ import { Dt as buildFfmpegArgs, Et as Fmp4BoxSplitter, kt as isSoftwareDecode, wt as errMsg } from "./dist-Cjazw3T-.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import "node:fs";
4
4
  import "node:path";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C31OZkZP.js");
1
+ const require_dist = require("./dist-PQArEi7A.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_dist.__toESM(node_fs, 1);
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-C31OZkZP.js");
6
- const require_node = require("../node-CIpenwbm.js");
7
- const require_local_frame_registry = require("../local-frame-registry-CkIaPLcW.js");
8
- const require_worker_protocol = require("../worker-protocol-BSgTKhW7.js");
5
+ const require_dist = require("../dist-PQArEi7A.js");
6
+ const require_node = require("../node-wFmd_eR_.js");
7
+ const require_local_frame_registry = require("../local-frame-registry-DNVTAOrZ.js");
8
+ const require_worker_protocol = require("../worker-protocol-BulRQMSK.js");
9
9
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
10
- const require_lazy_sharp = require("../lazy-sharp-DhHuLuQf.js");
10
+ const require_lazy_sharp = require("../lazy-sharp-DfnnPeG5.js");
11
11
  const require_restream_intent = require("../restream-intent-Cv9x3jmu.js");
12
12
  const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
13
13
  const require_remote_restream = require("../remote-restream-CO36Sr30.js");
@@ -1,7 +1,7 @@
1
- import { B as defineCustomActions, Bt as nodePin, Ft as createEvent, Gt as _enum, H as deriveDetailCropRect, Kt as array, L as customAction, Qt as object, X as failureContributionCapability, Xt as literal, Yt as lazy, Zt as number, _ as FailureCounters, en as string, et as loadContributionCapability, ft as pipelineRunnerCapability, jt as BaseAddon, lt as pickDetailCropConvention, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, p as DEFAULT_NATIVE_LEASE_SETTINGS, qt as boolean, u as DEFAULT_DETAIL_CROP_CONVENTION, ut as pickNativeLeaseOverride, wt as errMsg } from "../dist-CZkzc0WB.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-kSXNMrbg.mjs";
3
- import { c as getStepDefinition, n as resolveFrameViewGeometry, t as localFrameRegistry } from "../local-frame-registry-B8_L3v0O.mjs";
4
- import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-Bcy8Ti5P.mjs";
1
+ import { B as defineCustomActions, Bt as nodePin, Ft as createEvent, Gt as _enum, H as deriveDetailCropRect, Kt as array, L as customAction, Qt as object, X as failureContributionCapability, Xt as literal, Yt as lazy, Zt as number, _ as FailureCounters, en as string, et as loadContributionCapability, ft as pipelineRunnerCapability, jt as BaseAddon, lt as pickDetailCropConvention, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, p as DEFAULT_NATIVE_LEASE_SETTINGS, qt as boolean, u as DEFAULT_DETAIL_CROP_CONVENTION, ut as pickNativeLeaseOverride, wt as errMsg } from "../dist-Cjazw3T-.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-KFUZT2L-.mjs";
3
+ import { c as getStepDefinition, n as resolveFrameViewGeometry, t as localFrameRegistry } from "../local-frame-registry-CrLITJ5O.mjs";
4
+ import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-n4hf2NsC.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
7
7
  import { n as withDetectionIntent } from "../restream-intent-B4BXZra7.mjs";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C31OZkZP.js");
1
+ const require_dist = require("./dist-PQArEi7A.js");
2
2
  let node_fs = require("node:fs");
3
3
  node_fs = require_dist.__toESM(node_fs);
4
4
  let node_child_process = require("node:child_process");
@@ -1,4 +1,4 @@
1
- import { ot as parseProcStatus } from "./dist-CZkzc0WB.mjs";
1
+ import { ot as parseProcStatus } from "./dist-Cjazw3T-.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  //#region src/shared/node-topology-platform.ts
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-C31OZkZP.js");
6
- const require_node = require("../node-CIpenwbm.js");
5
+ const require_dist = require("../dist-PQArEi7A.js");
6
+ const require_node = require("../node-wFmd_eR_.js");
7
7
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
8
8
  const require_restream_intent = require("../restream-intent-Cv9x3jmu.js");
9
9
  const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
@@ -1,5 +1,5 @@
1
- import { $ as isFirstLevelMacroClass, $t as record, B as defineCustomActions, Bt as nodePin, E as RecordingConfigSchema, Gt as _enum, It as hydrateSchema, J as evaluateSensorEdge, Kt as array, L as customAction, N as batteryCapability, Nt as DeviceFeature, Pt as DeviceType, Qt as object, T as RECORDING_EXPORT_MAX_READ_BYTES, U as deriveRecordingMode, Ut as selectAssignedProfileSlots, V as deriveBatteryPresence, Wt as sleep$1, Zt as number, bt as storageEvictableCapability, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, en as string, et as loadContributionCapability, g as ExportRecordSchema, i as BatteryStatusSchema, jt as BaseAddon, mt as recordingExportCapability, nn as EventCategory, pt as recordingCapability, qt as boolean, vt as resolveRecordingProfiles, wt as errMsg, x as OpsLogEntrySchema } from "../dist-CZkzc0WB.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-kSXNMrbg.mjs";
1
+ import { $ as isFirstLevelMacroClass, $t as record, B as defineCustomActions, Bt as nodePin, E as RecordingConfigSchema, Gt as _enum, It as hydrateSchema, J as evaluateSensorEdge, Kt as array, L as customAction, N as batteryCapability, Nt as DeviceFeature, Pt as DeviceType, Qt as object, T as RECORDING_EXPORT_MAX_READ_BYTES, U as deriveRecordingMode, Ut as selectAssignedProfileSlots, V as deriveBatteryPresence, Wt as sleep$1, Zt as number, bt as storageEvictableCapability, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, en as string, et as loadContributionCapability, g as ExportRecordSchema, i as BatteryStatusSchema, jt as BaseAddon, mt as recordingExportCapability, nn as EventCategory, pt as recordingCapability, qt as boolean, vt as resolveRecordingProfiles, wt as errMsg, x as OpsLogEntrySchema } from "../dist-Cjazw3T-.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-KFUZT2L-.mjs";
3
3
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
4
4
  import { r as withRecordingIntent } from "../restream-intent-B4BXZra7.mjs";
5
5
  import { n as startEventLoopStallMonitor } from "../event-loop-stall-monitor-DXLNBMkY.mjs";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C31OZkZP.js");
1
+ const require_dist = require("./dist-PQArEi7A.js");
2
2
  let node_child_process = require("node:child_process");
3
3
  //#region ../../node_modules/mp4box/dist/mp4box.all.js
4
4
  var require_mp4box_all = /* @__PURE__ */ require_dist.__commonJSMin(((exports) => {
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./chunk-DnnnRqeS.mjs";
2
- import { wt as errMsg } from "./dist-CZkzc0WB.mjs";
2
+ import { wt as errMsg } from "./dist-Cjazw3T-.mjs";
3
3
  import { spawn } from "node:child_process";
4
4
  //#region ../../node_modules/mp4box/dist/mp4box.all.js
5
5
  var require_mp4box_all = /* @__PURE__ */ __commonJSMin(((exports) => {
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_worker_protocol = require("../worker-protocol-BSgTKhW7.js");
3
- const require_lazy_sharp = require("../lazy-sharp-DhHuLuQf.js");
2
+ const require_worker_protocol = require("../worker-protocol-BulRQMSK.js");
3
+ const require_lazy_sharp = require("../lazy-sharp-DfnnPeG5.js");
4
4
  //#region src/session-decode/color-conversion.ts
5
5
  /**
6
6
  * Explicit YUV→RGB colorspace/range resolution for the session-decode worker.
@@ -289,6 +289,10 @@ var FrameSlot = class {
289
289
  markPendingPull() {
290
290
  this.pendingPull = true;
291
291
  }
292
+ /** The id of the frame the last `pull` delivered (the reserved one), or `null`. */
293
+ get reservedFrameId() {
294
+ return this.reserved?.frameId ?? null;
295
+ }
292
296
  /** The reserved frame for `frameId`, or `null` if unknown/stale. */
293
297
  toBuffer(frameId) {
294
298
  if (!this.reserved || this.reserved.frameId !== frameId) return null;
@@ -446,6 +450,10 @@ var LeaseAdmissionLedger = class {
446
450
  get markedSize() {
447
451
  return this.marked.size;
448
452
  }
453
+ /** Whether `frameId` is inside the remembered marked window. */
454
+ isMarked(frameId) {
455
+ return this.marked.has(frameId);
456
+ }
449
457
  /** The runner admitted `frameId` to its detection queue. */
450
458
  mark(frameId) {
451
459
  this.markedTotal++;
@@ -617,7 +625,9 @@ var NativeLeaseStore = class {
617
625
  * has taken what it wanted. Idempotent, and the ORDINARY exit.
618
626
  */
619
627
  release(frameId) {
628
+ const held = this.entries.has(frameId);
620
629
  this.drop(frameId);
630
+ return held;
621
631
  }
622
632
  /** Free + drop every held frame. Idempotent (re-dial + teardown call it). */
623
633
  clear() {
@@ -635,6 +645,20 @@ var NativeLeaseStore = class {
635
645
  }
636
646
  };
637
647
  //#endregion
648
+ //#region src/session-decode/to-buffer-miss.ts
649
+ /** Which rung lost the frame, from what the worker knows at the miss. */
650
+ function toBufferMissRung(facts) {
651
+ if (facts.reservedFrameId !== null && facts.frameId > facts.reservedFrameId) return "not-yet-delivered";
652
+ if (!facts.marked) return "never-leased";
653
+ if (facts.leaseFrames >= facts.holdFrames) return "hold-full";
654
+ return "released";
655
+ }
656
+ /** The error line the runner sees: the rung first, the numbers after it. */
657
+ function describeToBufferMiss(facts) {
658
+ const rung = toBufferMissRung(facts);
659
+ return `decode-worker-child: toBuffer miss for frameId ${facts.frameId} — ${rung} {reserved=${facts.reservedFrameId ?? "none"} marked=${facts.marked} leaseFrames=${facts.leaseFrames}/${facts.holdFrames} holdOverflow=${facts.holdOverflow}}`;
660
+ }
661
+ //#endregion
638
662
  //#region src/session-decode/native-tile-geometry.ts
639
663
  /**
640
664
  * Pure geometry for the **native subject tile** — the compressed, subject-sized
@@ -1859,6 +1883,9 @@ var DecodeWorkerChild = class {
1859
1883
  colorDebug = process.env["CAMSTACK_DECODE_COLOR_DEBUG"] === "1";
1860
1884
  /** Scrypted-style throughput counters (plain integers, no per-frame allocation). */
1861
1885
  framesDecoded = 0;
1886
+ /** Releases that found a held frame / that found nothing to release. */
1887
+ leaseReleased = 0;
1888
+ leaseReleaseMisses = 0;
1862
1889
  /** Child-side skips only (HW-guard drops + probe/degrade frees); slot drops add {@link FrameSlot.droppedCount}. */
1863
1890
  framesSkipped = 0;
1864
1891
  /** Frames actually handed to the parent as a `frame` reply. */
@@ -1943,7 +1970,7 @@ var DecodeWorkerChild = class {
1943
1970
  this.handleCutTiles(message.frameId, message.bboxes);
1944
1971
  return;
1945
1972
  case "releaseNativeLease":
1946
- this.leaseStore.release(message.frameId);
1973
+ this.noteLeaseRelease(this.leaseStore.release(message.frameId));
1947
1974
  return;
1948
1975
  case "markInferred":
1949
1976
  this.admission.mark(message.frameId);
@@ -2007,7 +2034,7 @@ var DecodeWorkerChild = class {
2007
2034
  const skipped = this.framesSkipped + this.frames.droppedCount;
2008
2035
  const rssMb = Math.round(process.memoryUsage().rss / 1048576);
2009
2036
  const ageS = Math.round((now - this.startedAt) / 1e3);
2010
- this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, leaseOffered:${this.admission.offered}, leaseAdmitted:${this.admission.admitted}, leaseMarks:${this.admission.marks}, leaseUnmarkedCrops:${this.admission.unmarkedCrops}, leaseAdmission:${NATIVE_LEASE_KNOBS.values.admission}, leaseMb:${Math.round(this.leaseStore.totalBytes / 1048576)}, leaseFrames:${this.leaseStore.size}, holdOverflow:${this.leaseStore.overflowCount}, tilesCut:${this.tilesCut}, tileHits:${this.tileHits}, tileMisses:${this.tileMisses}, tileCutFailures:${this.tileCutFailures}, tileMb:${Math.round(this.tileStore.totalBytes / 1048576)}, tileFrames:${this.tileStore.frameCount}, scenesCut:${this.scenesCut}, sceneHits:${this.sceneHits}, sceneRefused:${this.sceneRefused}, sceneUnclassified:${this.sceneUnclassified}, sceneEvicted:${this.sceneStore.evictedCount}, sceneMb:${Math.round(this.sceneStore.totalBytes / 1048576)}, sceneFrames:${this.sceneStore.frameCount}, rssMb:${rssMb}, ageS:${ageS}}${final ? " (final)" : ""}\n`);
2037
+ this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, leaseOffered:${this.admission.offered}, leaseAdmitted:${this.admission.admitted}, leaseMarks:${this.admission.marks}, leaseUnmarkedCrops:${this.admission.unmarkedCrops}, leaseAdmission:${NATIVE_LEASE_KNOBS.values.admission}, leaseMb:${Math.round(this.leaseStore.totalBytes / 1048576)}, leaseFrames:${this.leaseStore.size}, holdOverflow:${this.leaseStore.overflowCount}, leaseReleased:${this.leaseReleased}, leaseReleaseMisses:${this.leaseReleaseMisses}, tilesCut:${this.tilesCut}, tileHits:${this.tileHits}, tileMisses:${this.tileMisses}, tileCutFailures:${this.tileCutFailures}, tileMb:${Math.round(this.tileStore.totalBytes / 1048576)}, tileFrames:${this.tileStore.frameCount}, scenesCut:${this.scenesCut}, sceneHits:${this.sceneHits}, sceneRefused:${this.sceneRefused}, sceneUnclassified:${this.sceneUnclassified}, sceneEvicted:${this.sceneStore.evictedCount}, sceneMb:${Math.round(this.sceneStore.totalBytes / 1048576)}, sceneFrames:${this.sceneStore.frameCount}, rssMb:${rssMb}, ageS:${ageS}}${final ? " (final)" : ""}\n`);
2011
2038
  this.lastMetricsAt = now;
2012
2039
  this.lastDeliveredSnapshot = this.framesDelivered;
2013
2040
  if (!this.warnedLarge && rssMb >= WORKER_RSS_WARN_MB) {
@@ -2045,10 +2072,21 @@ var DecodeWorkerChild = class {
2045
2072
  this.pendingPull = true;
2046
2073
  this.frames.markPendingPull();
2047
2074
  }
2075
+ noteLeaseRelease(held) {
2076
+ if (held) this.leaseReleased += 1;
2077
+ else this.leaseReleaseMisses += 1;
2078
+ }
2048
2079
  async handleToBuffer(frameId, opts) {
2049
2080
  const frame = this.leaseStore.get(frameId)?.frame ?? this.frames.toBuffer(frameId);
2050
2081
  if (!frame) {
2051
- this.sendError(`decode-worker-child: toBuffer for unknown or stale frameId ${frameId}`, frameId);
2082
+ this.sendError(describeToBufferMiss({
2083
+ frameId,
2084
+ reservedFrameId: this.frames.reservedFrameId,
2085
+ marked: this.admission.isMarked(frameId),
2086
+ leaseFrames: this.leaseStore.size,
2087
+ holdFrames: NATIVE_LEASE_HOLD_FRAMES,
2088
+ holdOverflow: this.leaseStore.overflowCount
2089
+ }), frameId);
2052
2090
  return;
2053
2091
  }
2054
2092
  try {
@@ -2282,7 +2320,7 @@ var DecodeWorkerChild = class {
2282
2320
  this.sceneStore.put(frameId, [scene]);
2283
2321
  }
2284
2322
  } finally {
2285
- this.leaseStore.release(frameId);
2323
+ this.noteLeaseRelease(this.leaseStore.release(frameId));
2286
2324
  }
2287
2325
  }
2288
2326
  /**