@camstack/addon-tailscale 1.2.117 → 1.2.119

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.
@@ -1,5 +1,7 @@
1
- require("node:crypto");
2
- //#region ../types/dist/event-category-BGmz_oxW.mjs
1
+ import * as fs from "node:fs/promises";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ //#region ../types/dist/event-category-B_0XEcLF.mjs
3
5
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
6
  EventCategory["SystemBoot"] = "system.boot";
5
7
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -500,15 +502,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
500
502
  EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
501
503
  EventCategory["AgentBackupActivated"] = "agent.backup.activated";
502
504
  EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
503
- /**
504
- * Per-agent hwaccel preference changed (user override set, cleared, or
505
- * re-probed). Observability event — decoders pull the current pref at
506
- * `createSession`, so running sessions keep their current backend until
507
- * they rotate naturally (camera add/remove, stream restart). Future
508
- * work can wire a listener in stream-broker that force-rotates live
509
- * sessions; for now this event powers logs + admin-UI toast feedback.
510
- */
511
- EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
512
505
  EventCategory["MotionAnalysis"] = "detection.motion-analysis";
513
506
  /** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
514
507
  EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
@@ -5379,7 +5372,7 @@ var ZodIssueCode = {
5379
5372
  var ZodFirstPartyTypeKind;
5380
5373
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5381
5374
  //#endregion
5382
- //#region ../types/dist/sleep-DXKLNFvA.mjs
5375
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5383
5376
  /**
5384
5377
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5385
5378
  * window to float samples (D455).
@@ -6745,32 +6738,12 @@ object({
6745
6738
  audioCodec: string().optional(),
6746
6739
  metadata: record(string(), unknown()).readonly().optional()
6747
6740
  });
6748
- var EncodedPacketSchema = object({
6749
- type: _enum(["video", "audio"]),
6750
- data: _instanceof(Uint8Array),
6751
- pts: number(),
6752
- dts: number(),
6753
- keyframe: boolean(),
6754
- codec: string()
6755
- });
6756
- var DecodedFrameSchema = object({
6757
- data: _instanceof(Uint8Array),
6758
- width: number(),
6759
- height: number(),
6760
- format: _enum([
6761
- "jpeg",
6762
- "rgb",
6763
- "bgr",
6764
- "yuv420",
6765
- "gray"
6766
- ]),
6767
- timestamp: number()
6768
- });
6769
6741
  /**
6770
6742
  * Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
6771
6743
  * frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
6772
- * interface in `interfaces/frame-handle.ts` field-for-field so a decoder cap
6773
- * method (`pullHandles`) can carry handles over tRPC / Moleculer.
6744
+ * interface in `interfaces/frame-handle.ts` field-for-field so a cap method
6745
+ * (the runner's native-crop and pipeline-executor inputs) can carry handles
6746
+ * over tRPC / Moleculer.
6774
6747
  *
6775
6748
  * The `satisfies` assertion below pins this schema to the interface: if a
6776
6749
  * field is added to / removed from `FrameHandle` without a matching schema
@@ -6796,50 +6769,6 @@ var FrameHandleSchema = object({
6796
6769
  slotCount: number().int().positive()
6797
6770
  });
6798
6771
  /**
6799
- * Pixel format a frame-handle subscriber can request from the broker
6800
- * (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
6801
- * `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
6802
- * `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
6803
- * payload, and no decoded-frame consumer requests it over the shm plane.
6804
- */
6805
- var FrameHandleFormatSchema = _enum([
6806
- "rgb",
6807
- "bgr",
6808
- "yuv420",
6809
- "gray"
6810
- ]);
6811
- /**
6812
- * Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
6813
- * broker for a `FrameHandle` stream of one `format`; the broker maintains one
6814
- * shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
6815
- * subscriber (motion) and an `rgb` subscriber (detection) each read the format
6816
- * they asked for with no broker-side conversion.
6817
- */
6818
- var SubscribeFramesInputSchema = object({
6819
- brokerId: string(),
6820
- format: FrameHandleFormatSchema,
6821
- /**
6822
- * Optional reader-side cadence hint in frames per second. The broker does
6823
- * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
6824
- * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
6825
- * the consumer can pace its own `pullFrameHandles` polling.
6826
- */
6827
- maxFps: number().positive().optional(),
6828
- /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
6829
- tag: string().optional()
6830
- });
6831
- /**
6832
- * Result of `stream-broker.subscribeFrames`. The consumer then polls
6833
- * `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
6834
- * `FrameHandle` to a `FrameRingReader`.
6835
- */
6836
- var SubscribeFramesResultSchema = object({
6837
- /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
6838
- subscriptionId: string(),
6839
- /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
6840
- maxFps: number().nonnegative()
6841
- });
6842
- /**
6843
6772
  * Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
6844
6773
  * `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
6845
6774
  * sample bytes plus the track parameters a consumer needs to interpret them.
@@ -6847,8 +6776,8 @@ var SubscribeFramesResultSchema = object({
6847
6776
  * Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
6848
6777
  * Float32 PCM), so unlike video frames they ship their bytes INLINE over
6849
6778
  * tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
6850
- * (the wire-serialisable supertype of `Buffer`) to match `DecodedFrameSchema`
6851
- * / `EncodedPacketSchema`'s precedent; a `Buffer` is assignable to it.
6779
+ * (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
6780
+ * it.
6852
6781
  */
6853
6782
  var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
6854
6783
  var DecodedAudioChunkSchema = object({
@@ -6866,11 +6795,10 @@ var DecodedAudioChunkSchema = object({
6866
6795
  format: AudioChunkFormatSchema.optional()
6867
6796
  });
6868
6797
  /**
6869
- * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). The
6870
- * handle-free, ship-bytes-inline analogue of `subscribeFrames`: a consumer
6871
- * asks the broker for the decoded audio-chunk stream of one broker; the
6872
- * broker keeps a per-subscription bounded FIFO queue the consumer drains via
6873
- * `pullAudioChunks`.
6798
+ * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
6799
+ * its bytes inline: a consumer asks the broker for the decoded audio-chunk
6800
+ * stream of one broker; the broker keeps a per-subscription bounded FIFO queue
6801
+ * the consumer drains via `pullAudioChunks`.
6874
6802
  */
6875
6803
  var SubscribeAudioChunksInputSchema = object({
6876
6804
  brokerId: string(),
@@ -6901,9 +6829,7 @@ var BrokerStatsSchema = object({
6901
6829
  "stopped"
6902
6830
  ]),
6903
6831
  inputFps: number(),
6904
- decodeFps: number(),
6905
6832
  encodedSubscribers: number(),
6906
- decodedSubscribers: number(),
6907
6833
  uptimeMs: number(),
6908
6834
  bitrateKbps: number(),
6909
6835
  idrIntervalMs: number(),
@@ -6916,14 +6842,6 @@ var BrokerStatsSchema = object({
6916
6842
  preBufferMs: number(),
6917
6843
  preBufferPackets: number(),
6918
6844
  /**
6919
- * Moleculer node id of the decoder provider currently servicing this
6920
- * stream's decoded subscribers. `null` until the deferred decoder is
6921
- * created (no decoded clients yet, or codec not detected). Surfaces the
6922
- * runtime decoder placement so the UI can show "Decoder: <agent>" without
6923
- * a separate cap call per broker.
6924
- */
6925
- decoderNodeId: string().nullable(),
6926
- /**
6927
6845
  * Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
6928
6846
  * when the stream has no audio track or the broker is in cold start.
6929
6847
  * `supported = false` means the codec was detected but the local
@@ -10279,70 +10197,6 @@ var StorageLocationDeclarationSchema = object({
10279
10197
  "backup"
10280
10198
  ]).optional()
10281
10199
  });
10282
- var DecoderStatsSchema = object({
10283
- inputFps: number(),
10284
- outputFps: number(),
10285
- avgDecodeTimeMs: number(),
10286
- droppedFrames: number(),
10287
- /**
10288
- * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
10289
- * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
10290
- * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
10291
- * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
10292
- */
10293
- lagMs: number().optional(),
10294
- effectiveFps: number().optional(),
10295
- adaptiveFps: number().optional()
10296
- });
10297
- var DecoderSessionConfigSchema = object({
10298
- codec: string(),
10299
- maxFps: number().default(0),
10300
- outputFormat: _enum([
10301
- "jpeg",
10302
- "rgb",
10303
- "bgr",
10304
- "yuv420",
10305
- "gray"
10306
- ]).default("jpeg"),
10307
- scale: number().default(1),
10308
- width: number().optional(),
10309
- height: number().optional(),
10310
- /**
10311
- * Identifier of the camera this decoder session serves. Optional
10312
- * because the cap is generic (any caller could request decode), but
10313
- * stream-broker passes it so decoder logs include `deviceId` for
10314
- * per-camera filtering when diagnosing failures (e.g. node-av
10315
- * sendPacket errors on a single hung camera).
10316
- */
10317
- deviceId: number().int().nonnegative().optional(),
10318
- /**
10319
- * Free-form tag for log scoping. Stream-broker uses
10320
- * `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
10321
- * on every line so `grep tag=broker:5/high` filters one camera
10322
- * profile cleanly.
10323
- */
10324
- tag: string().optional(),
10325
- /**
10326
- * Where the session delivers decoded frames (Phase 5 / D9):
10327
- *
10328
- * - `'callback'` (default) — the legacy pixel path: decoded frames are
10329
- * buffered as `DecodedFrame`s and drained via `pullFrames`.
10330
- * - `'shm'` — the shared-memory frame plane: decoded frames are written
10331
- * into an OS shared-memory ring and drained as zero-pixel
10332
- * `FrameHandle`s via `pullHandles`. A session is one mode or the
10333
- * other — `pullFrames` returns nothing for an `'shm'` session and
10334
- * `pullHandles` returns nothing for a `'callback'` session.
10335
- */
10336
- frameSink: _enum(["callback", "shm"]).default("callback"),
10337
- /**
10338
- * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
10339
- * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
10340
- * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
10341
- * stream-broker's `streamingDebug` gate — off by default so production logs
10342
- * stay quiet and the emit path pays zero per-frame cost when disabled.
10343
- */
10344
- debug: boolean().optional()
10345
- });
10346
10200
  /**
10347
10201
  * Per-component log CHANNELS — the gate a hot path consults, and the registry
10348
10202
  * an addon declares its channels in.
@@ -10485,6 +10339,26 @@ var ClipSearchStrictnessSchema = _enum([
10485
10339
  "balanced",
10486
10340
  "strict"
10487
10341
  ]);
10342
+ /** Steps whose effect a root label can BE. */
10343
+ var LABEL_SUPPLY_STEP_IDS = [
10344
+ "animal-classifier",
10345
+ "vehicle-classifier",
10346
+ "package-detection"
10347
+ ];
10348
+ /** Steps whose box a root detection can BE. */
10349
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10350
+ /**
10351
+ * Steps whose per-detection MASK a root detection can carry (D737). The live
10352
+ * mask step is `segmentation` — a frame-plane refiner that runs its own model
10353
+ * once per detection crop. (`instance-segmentation` is a dormant step id that
10354
+ * no camera tree carries.)
10355
+ */
10356
+ var MASK_SUPPLY_STEP_IDS = ["segmentation"];
10357
+ [
10358
+ ...LABEL_SUPPLY_STEP_IDS,
10359
+ ...CROP_SUPPLY_STEP_IDS,
10360
+ ...MASK_SUPPLY_STEP_IDS
10361
+ ];
10488
10362
  var MODEL_FORMATS = [
10489
10363
  "onnx",
10490
10364
  "coreml",
@@ -10513,7 +10387,53 @@ var ModelFormatEntrySchema = object({
10513
10387
  /** Multi-file payload (directory members or sibling files). */
10514
10388
  files: array(string()).readonly().optional(),
10515
10389
  /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
10516
- runtimes: array(_enum(["python"])).readonly().optional()
10390
+ runtimes: array(_enum(["python"])).readonly().optional(),
10391
+ /**
10392
+ * Content revision of the artefact, for one hosted OFF the CamStack mirror.
10393
+ * A format on the mirror leaves it unset: its revision (the sha256 of its
10394
+ * weight file) comes from the downloader's generated table, kept in step
10395
+ * with the mirror by `scripts/check-hosted-model-revisions.ts` (D744). A
10396
+ * node records the revision it downloaded next to the file
10397
+ * (`<file>.revision`); a copy with no record or a different one is stale
10398
+ * unless its weight file hashes to the revision, and a stale copy is
10399
+ * downloaded again, the old one serving until the new one is complete. No
10400
+ * revision at all ⇒ a file on disk is current, whatever it holds (D743).
10401
+ */
10402
+ revision: string().min(1).optional()
10403
+ });
10404
+ /**
10405
+ * What a node holds for one (model, format) (D746). `current` is a complete
10406
+ * copy at its catalog revision — exactly what `downloaded: true` means.
10407
+ * `stale` is bytes on disk that are not (yet) proven current under D743/D744:
10408
+ * no or a different revision record, or a missing sibling. `missing` is no
10409
+ * copy. `downloaded` alone folds `stale` into "not downloaded", which hid
10410
+ * reclaimable bytes and a copy about to be replaced.
10411
+ */
10412
+ var ModelOnDiskStateSchema = _enum([
10413
+ "current",
10414
+ "stale",
10415
+ "missing"
10416
+ ]);
10417
+ /**
10418
+ * The numeric precision of one format's BUILD (D746) — reported only when the
10419
+ * build states it (file-name token, an INT8 variant, an EdgeTPU compile, a
10420
+ * CamStack Core ML export). Absent means "not stated", never "fp32".
10421
+ */
10422
+ var ModelFormatPrecisionSchema = _enum([
10423
+ "fp32",
10424
+ "fp16",
10425
+ "int8"
10426
+ ]);
10427
+ /**
10428
+ * One format of one model as a node's `pipelineExecutor.getSchema` reports it.
10429
+ * `onDisk` / `precision` are optional for version skew: a runner that predates
10430
+ * them omits them, and a reader falls back to `downloaded`.
10431
+ */
10432
+ var PipelineModelFormatStatusSchema = object({
10433
+ downloaded: boolean(),
10434
+ sizeMB: number(),
10435
+ onDisk: ModelOnDiskStateSchema.optional(),
10436
+ precision: ModelFormatPrecisionSchema.optional()
10517
10437
  });
10518
10438
  /**
10519
10439
  * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
@@ -10554,11 +10474,11 @@ var ModelVariantGroupSchema = object({
10554
10474
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10555
10475
  precision: _enum(["fp32", "int8"]).optional(),
10556
10476
  /**
10557
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10558
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10559
- * future performance variants plug into.
10477
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10478
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10479
+ * label is "Test".
10560
10480
  */
10561
- optimization: _enum(["standard", "fast"]).optional(),
10481
+ optimization: _enum(["standard", "test"]).optional(),
10562
10482
  /**
10563
10483
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10564
10484
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10581,9 +10501,10 @@ var ModelProviderIdSchema = _enum([
10581
10501
  * are per upstream. A persisted custom-model row written when this field was a
10582
10502
  * string still parses — the string is lifted into `{ weights }`.
10583
10503
  *
10584
- * Every licence surface (the admin "Models and licenses" page,
10585
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10586
- * these records by `scripts/gen-model-licenses.ts` (D661).
10504
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10505
+ * model table) is GENERATED from these records by
10506
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10507
+ * `camstack/docs` → `/docs/detection/models`.
10587
10508
  */
10588
10509
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10589
10510
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -10616,6 +10537,46 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10616
10537
  /** True when the weights or their data forbid commercial use. */
10617
10538
  nonCommercial: boolean().optional()
10618
10539
  }));
10540
+ /**
10541
+ * One step a ROOT detector can supply from its own output (D730) — see
10542
+ * `ModelCatalogEntry.suppliesSteps`.
10543
+ *
10544
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10545
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10546
+ * the root cannot produce (shown as unavailable, never a blocker).
10547
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10548
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10549
+ * child of the `parentMacro` detection that contains it — never a track.
10550
+ * - `mask`: the root's decode emits an instance mask with every detection (a
10551
+ * YOLO26-seg root, D737) — the `segmentation` step's result, carried on the
10552
+ * detection in the shape that step produces. Derived from the model's
10553
+ * postprocessor on read, never stored by an import.
10554
+ */
10555
+ var RootStepSupplySchema = discriminatedUnion("kind", [
10556
+ object({
10557
+ kind: literal("label"),
10558
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10559
+ labelToEffect: record(string(), string()),
10560
+ uncovered: array(string()).readonly()
10561
+ }),
10562
+ object({
10563
+ kind: literal("crop"),
10564
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10565
+ rootLabels: array(string()).readonly(),
10566
+ parentMacro: _enum(["vehicle", "person"]),
10567
+ childClass: _enum(["plate", "face"]),
10568
+ /**
10569
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10570
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10571
+ * stored by an import.
10572
+ */
10573
+ rootInputPx: number().int().positive().optional()
10574
+ }),
10575
+ object({
10576
+ kind: literal("mask"),
10577
+ stepId: _enum(MASK_SUPPLY_STEP_IDS)
10578
+ })
10579
+ ]);
10619
10580
  var ModelCatalogEntrySchema = object({
10620
10581
  id: string(),
10621
10582
  name: string(),
@@ -10681,6 +10642,35 @@ var ModelCatalogEntrySchema = object({
10681
10642
  */
10682
10643
  defaultConfidence: number().min(0).max(1).optional(),
10683
10644
  /**
10645
+ * Per-MODEL default of the per-class confidence floors (`minConfidence<Macro>`
10646
+ * on a detector step), keyed by macro class: `{ person: 0.45 }`. A class
10647
+ * absent here runs at the step slider's global default. The same row shape
10648
+ * the floor measurement produces (`model-floors.json`: modelId → floors), so
10649
+ * a measured table is copied in as-is. An operator override is bound to the
10650
+ * model it was made for and does not survive a model change (D738). A custom
10651
+ * / imported model may declare it; without it, the global defaults apply.
10652
+ */
10653
+ defaultClassFloors: record(string(), number().min(0).max(1)).optional(),
10654
+ /**
10655
+ * The inference precision this model's OpenVINO IR needs on an Intel GPU.
10656
+ * Absent ⇒ the device default (f16 on a GPU). Set to `'f32'` for an FP32 IR
10657
+ * that produces invalid output at f16 — measured 2026-10-07 for YOLO26
10658
+ * base IRs (`yolo26s`: 0 true / 146 false positives; `yolo26m*`: NaN
10659
+ * scores) on the Core Ultra iGPU and the N100. Threaded to the pool as
10660
+ * `PoolModelConfig.gpuInferencePrecision`; the pool sets
10661
+ * INFERENCE_PRECISION_HINT on a GPU only. Costs ~60% latency on the GPU.
10662
+ */
10663
+ gpuInferencePrecision: _enum(["f32", "f16"]).optional(),
10664
+ /**
10665
+ * ROOT detectors only: per supplied step (`animal-classifier`, …), the
10666
+ * minimum DETECTION score from which this root's own fine label (species,
10667
+ * vehicle type — D736 root supply) is taken (D741). Below it the detection
10668
+ * keeps its macro class without the fine label. `1` = never take it from
10669
+ * this root. Absent ⇒ no floor beyond the macro floor. The supplied step's
10670
+ * `minConfidence` slider, bound to the ROOT model, overrides it.
10671
+ */
10672
+ suppliedLabelFloors: record(string(), number().min(0).max(1)).optional(),
10673
+ /**
10684
10674
  * When true, the executor produces a landmark-aligned crop (similarity warp
10685
10675
  * onto the canonical template) before this step runs, instead of a plain
10686
10676
  * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
@@ -10742,6 +10732,16 @@ var ModelCatalogEntrySchema = object({
10742
10732
  */
10743
10733
  classMap: DetectionCatalogClassMapSchema.optional(),
10744
10734
  /**
10735
+ * The pipeline steps this ROOT detector can supply from its own output
10736
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
10737
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
10738
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
10739
+ * by hand and never assumed per family; a row without it is derived on read
10740
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
10741
+ * `useRootModel` flag (`resolveRootSupply`).
10742
+ */
10743
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
10744
+ /**
10745
10745
  * The model's CLIP feature-space contract (text encoder, dimension, vector
10746
10746
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
10747
10747
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -12343,13 +12343,6 @@ var BrokerRtspClientSchema = object({
12343
12343
  lastRtpAt: number(),
12344
12344
  bytesSent: number()
12345
12345
  });
12346
- var BrokerDecodedClientSchema = object({
12347
- tag: string(),
12348
- subscribedAt: number(),
12349
- maxFps: number(),
12350
- framesDelivered: number(),
12351
- framesDropped: number()
12352
- });
12353
12346
  var BrokerAudioClientSchema = object({
12354
12347
  tag: string(),
12355
12348
  subscribedAt: number(),
@@ -12441,7 +12434,6 @@ var BrokerEncodedClientSchema = object({
12441
12434
  });
12442
12435
  var BrokerClientsSchema = object({
12443
12436
  rtsp: array(BrokerRtspClientSchema).readonly(),
12444
- decoded: array(BrokerDecodedClientSchema).readonly(),
12445
12437
  audio: array(BrokerAudioClientSchema).readonly(),
12446
12438
  encoded: array(BrokerEncodedClientSchema).readonly(),
12447
12439
  pipeClients: number(),
@@ -12810,11 +12802,7 @@ method(object({
12810
12802
  auth: "admin"
12811
12803
  }), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
12812
12804
  brokerId: string(),
12813
- channel: _enum([
12814
- "rtsp",
12815
- "decoded",
12816
- "audio"
12817
- ]),
12805
+ channel: _enum(["rtsp", "audio"]),
12818
12806
  handle: string()
12819
12807
  }), object({ killed: boolean() }), {
12820
12808
  kind: "mutation",
@@ -12849,10 +12837,7 @@ method(object({
12849
12837
  }), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
12850
12838
  subscriptionId: string(),
12851
12839
  maxCount: number().int().positive().default(8)
12852
- }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(SubscribeFramesInputSchema, SubscribeFramesResultSchema, { kind: "mutation" }), method(object({
12853
- subscriptionId: string(),
12854
- maxCount: number().int().positive().default(4)
12855
- }), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
12840
+ }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
12856
12841
  brokerId: string(),
12857
12842
  seconds: number().min(0).max(30)
12858
12843
  }), _void(), {
@@ -14009,54 +13994,12 @@ id: union([string(), number()]) }), {
14009
13994
  kind: "mutation",
14010
13995
  auth: "admin"
14011
13996
  });
14012
- /**
14013
- * shm ring usage stats for a `frameSink: 'shm'` decoder session —
14014
- * exposed via `decoder.getShmStats` so downstream consumers can
14015
- * observe ring pressure (slot count, byte budget, hit/miss ratio).
14016
- */
14017
- var ShmRingStatsSchema = object({
14018
- sessionId: string(),
14019
- slotCount: number().int(),
14020
- slotByteLength: number().int(),
14021
- segmentBytes: number().int(),
14022
- budgetMb: number().int(),
14023
- framesWritten: number().int(),
14024
- getFrameHits: number().int(),
14025
- getFrameMisses: number().int()
14026
- });
14027
- method(object({ codec: string() }), boolean()), method(_void(), object({
13997
+ method(_void(), object({
14028
13998
  id: string(),
14029
13999
  name: string(),
14030
- isPullMode: boolean().optional(),
14031
- priority: number().optional(),
14032
14000
  hwaccel: string().optional(),
14033
14001
  probedBestHwaccel: string().optional()
14034
- })), method(DecoderSessionConfigSchema, object({
14035
- sessionId: string(),
14036
- nodeId: string()
14037
- })), method(object({ sessionId: string() }), _void()), method(object({
14038
- sessionId: string(),
14039
- packet: EncodedPacketSchema
14040
- }), _void()), method(object({
14041
- sessionId: string(),
14042
- url: string()
14043
- }), _void()), method(object({
14044
- sessionId: string(),
14045
- maxCount: number().default(1),
14046
- waitMs: number().optional()
14047
- }), array(DecodedFrameSchema)), method(object({
14048
- sessionId: string(),
14049
- maxCount: number().default(1),
14050
- waitMs: number().optional()
14051
- }), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
14052
- sessionId: string(),
14053
- config: DecoderSessionConfigSchema.partial()
14054
- }), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
14055
- sessionId: string(),
14056
- codec: string(),
14057
- outputFormat: string(),
14058
- createdAtMs: number()
14059
- })).readonly()), method(_void(), object({ backend: string() }), {
14002
+ })), method(_void(), object({ backend: string() }), {
14060
14003
  kind: "mutation",
14061
14004
  auth: "admin"
14062
14005
  });
@@ -14112,7 +14055,7 @@ DeviceType.Camera;
14112
14055
  * This matters here more than anywhere else in the repo, because every provider
14113
14056
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14114
14057
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14115
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14058
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14116
14059
  * camera's own page will ask for its own login. That is correct, and pre-
14117
14060
  * filling it is the operator's business, not ours.
14118
14061
  *
@@ -14868,6 +14811,10 @@ var DeviceInfoSchema = object({
14868
14811
  isCamera: boolean(),
14869
14812
  /** Current config values — serializable snapshot */
14870
14813
  config: record(string(), unknown()),
14814
+ /** Paths inside `config` the device's schema declares secret (D783) —
14815
+ * what the non-admin redaction withholds. Paths, never values. Absent
14816
+ * when the owning runner has not reported them. */
14817
+ secretConfigPaths: array(string()).optional(),
14871
14818
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
14872
14819
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
14873
14820
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15073,7 +15020,13 @@ var DeviceRegisterPayloadSchema = object({
15073
15020
  * call (workers re-register on init), so probe-driven updates
15074
15021
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15075
15022
  features: array(string()).optional(),
15076
- config: record(string(), unknown())
15023
+ config: record(string(), unknown()),
15024
+ /** Config paths the device's own schema DECLARES secret
15025
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15026
+ * `connection.password`). Re-published on every register; the non-admin
15027
+ * redaction withholds them at any depth (D783). Optional: an older runner
15028
+ * omits it and the keyword backstop applies. */
15029
+ secretConfigPaths: array(string()).optional()
15077
15030
  });
15078
15031
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15079
15032
  var DevicePersistConfigPayloadSchema = object({
@@ -15900,6 +15853,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
15900
15853
  kind: "mutation",
15901
15854
  auth: "admin"
15902
15855
  });
15856
+ var HUB_ADDRESS_ROLES = [
15857
+ "appConnections",
15858
+ "notificationTaps",
15859
+ "internal",
15860
+ "publicEndpoint"
15861
+ ];
15903
15862
  /**
15904
15863
  * Transport bounds for AI capability methods.
15905
15864
  *
@@ -16726,7 +16685,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
16726
16685
  icon: string().optional(),
16727
16686
  /** Addon-owned HTTP route the button navigates to (GET). */
16728
16687
  startUrl: string(),
16729
- stage: LoginStageEnum
16688
+ stage: LoginStageEnum,
16689
+ /**
16690
+ * The provider names an external identity a signed-in user can link to
16691
+ * their own account (D782): `auth.listLinkableProviders` /
16692
+ * `beginExternalLink` offer exactly the redirect methods that set this,
16693
+ * whatever their id. Absent / false — a login button only (magic-link).
16694
+ */
16695
+ linkable: boolean().optional()
16730
16696
  }),
16731
16697
  object({
16732
16698
  kind: literal("widget"),
@@ -17096,7 +17062,7 @@ method(object({
17096
17062
  timeoutMs: 6e5
17097
17063
  });
17098
17064
  method(object({
17099
- nodeId: string(),
17065
+ targetNodeId: string(),
17100
17066
  modelId: string(),
17101
17067
  format: _enum(MODEL_FORMATS),
17102
17068
  entry: ModelCatalogEntrySchema
@@ -18481,6 +18447,8 @@ var NcSystemEventKindSchema = _enum([
18481
18447
  "stream-offline",
18482
18448
  "node-online",
18483
18449
  "node-offline",
18450
+ "node-restarting",
18451
+ "node-updating",
18484
18452
  "node-inference-unavailable",
18485
18453
  "detection-blind",
18486
18454
  "addon-crash-loop",
@@ -19579,8 +19547,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19579
19547
  disabledTargetIds: array(string()).default([])
19580
19548
  });
19581
19549
  /**
19582
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19583
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19550
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19551
+ * report a still-true state. `addons` is the crash-looped addons only and
19552
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19584
19553
  * job is not an open state, and the alarm stays instant.
19585
19554
  */
19586
19555
  var NcStateSummarySectionIdSchema = _enum([
@@ -19592,6 +19561,7 @@ var NcStateSummarySectionIdSchema = _enum([
19592
19561
  "detection-blind",
19593
19562
  "nodes",
19594
19563
  "addons",
19564
+ "addon-updates",
19595
19565
  "updates"
19596
19566
  ]);
19597
19567
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20072,7 +20042,25 @@ var NcAlarmModeDelaysListSchema = array(object({
20072
20042
  * When this mode may be armed. Absent / null = always allowed (same as a
20073
20043
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20074
20044
  */
20075
- schedule: NcScheduleSchema.optional()
20045
+ schedule: NcScheduleSchema.optional(),
20046
+ /**
20047
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20048
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20049
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20050
+ */
20051
+ notifyDuringEntryDelay: boolean().optional(),
20052
+ /**
20053
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20054
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20055
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20056
+ */
20057
+ notifySensorRewatched: boolean().optional(),
20058
+ /**
20059
+ * D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
20060
+ * change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
20061
+ * re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
20062
+ */
20063
+ notifySensorIgnored: boolean().optional()
20076
20064
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20077
20065
  var NcAlarmModeDelaysEditListSchema = array(object({
20078
20066
  mode: AlarmArmModeSchema,
@@ -20081,7 +20069,13 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20081
20069
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20082
20070
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20083
20071
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20084
- schedule: NcScheduleSchema.nullable().optional()
20072
+ schedule: NcScheduleSchema.nullable().optional(),
20073
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20074
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20075
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20076
+ notifySensorRewatched: boolean().nullable().optional(),
20077
+ /** D735: set the switch, or `null` to clear it (back to the default, false). */
20078
+ notifySensorIgnored: boolean().nullable().optional()
20085
20079
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20086
20080
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20087
20081
  var NcAlarmNonBlockingEditSchema = object({
@@ -21042,45 +21036,25 @@ Object.freeze(Object.fromEntries([{
21042
21036
  label: "Face recognition model",
21043
21037
  defaultModelId: "auraface-r100",
21044
21038
  indexName: "the enrolled face gallery",
21045
- options: [
21046
- {
21047
- id: "auraface-r100",
21048
- label: "AuraFace R100"
21049
- },
21050
- {
21051
- id: "arcface-r100",
21052
- label: "ArcFace (ResNet34)"
21053
- },
21054
- {
21055
- id: "inception-resnet-v1",
21056
- label: "Inception ResNet V1"
21057
- }
21058
- ]
21039
+ options: [{
21040
+ id: "auraface-r100",
21041
+ label: "AuraFace R100"
21042
+ }]
21059
21043
  }, {
21060
21044
  stepId: "clip-embedding",
21061
21045
  label: "Semantic search model",
21062
- defaultModelId: "mobileclip-s1",
21046
+ defaultModelId: "siglip2-b16-224",
21063
21047
  indexName: "the object semantic-search index",
21064
- options: [
21065
- {
21066
- id: "mobileclip-s1",
21067
- label: "MobileCLIP S1"
21068
- },
21069
- {
21070
- id: "mobileclip-s2",
21071
- label: "MobileCLIP S2"
21072
- },
21073
- {
21074
- id: "siglip2-b16-224",
21075
- label: "SigLIP2 B/16 (Apache-2.0)"
21076
- }
21077
- ]
21048
+ options: [{
21049
+ id: "siglip2-b16-224",
21050
+ label: "SigLIP2 B/16 (Apache-2.0)"
21051
+ }]
21078
21052
  }].map((s) => [s.stepId, s.defaultModelId])));
21079
21053
  var CLUSTER_STEP_SETTING_FIELDS = [{
21080
21054
  stepId: "face-embedding",
21081
21055
  key: "minLandmarkFaceSize",
21082
- label: "Min face size for recognition (detection px)",
21083
- description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
21056
+ label: "Min face size to embed (detection-frame px)",
21057
+ description: "Faces smaller than this in the small frame the detector sees are not embedded, so they can never be recognised. Below it the face cannot be aligned reliably and a bad embedding matches everyone. Same value on every node. 0 = no limit.",
21084
21058
  type: "slider",
21085
21059
  min: 0,
21086
21060
  max: 64,
@@ -22132,7 +22106,13 @@ var RetrainFrameSchema = object({
22132
22106
  sizeBytes: number().int(),
22133
22107
  width: number().int(),
22134
22108
  height: number().int(),
22135
- copiedAt: number()
22109
+ copiedAt: number(),
22110
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22111
+ capturedAt: number().optional(),
22112
+ /** The operator's "every subject in this frame is boxed". Detector
22113
+ * evaluation keeps only complete frames: an unboxed subject would count as
22114
+ * a false positive. */
22115
+ complete: boolean()
22136
22116
  });
22137
22117
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22138
22118
  var RetrainCopyRefusalSchema = _enum([
@@ -22153,6 +22133,51 @@ var RetrainFrameListSchema = object({
22153
22133
  /** What the page pre-selects — the native key frame when one survives. */
22154
22134
  autoPickMediaId: number().int().optional()
22155
22135
  });
22136
+ /**
22137
+ * Which frames an annotated export carries. Every field narrows; an empty
22138
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22139
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22140
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22141
+ * export carried (`exportedInBatch`).
22142
+ */
22143
+ var RetrainExportFilterSchema = object({
22144
+ deviceIds: array(number()).optional(),
22145
+ frameIds: array(string()).max(2e4).optional(),
22146
+ batchId: string().optional(),
22147
+ /** Only frames the operator marked complete (all subjects boxed). */
22148
+ completeOnly: boolean().optional()
22149
+ });
22150
+ /**
22151
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22152
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22153
+ * convention — the classifier layout.
22154
+ */
22155
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22156
+ /**
22157
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22158
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22159
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22160
+ * logged.
22161
+ */
22162
+ var RetrainArchiveTargetSchema = object({
22163
+ kind: literal("http"),
22164
+ method: _enum(["PUT", "POST"]),
22165
+ url: string().url(),
22166
+ headers: record(string(), string()).optional()
22167
+ });
22168
+ var RetrainArchiveResultSchema = object({
22169
+ batchId: string(),
22170
+ frames: number().int(),
22171
+ crops: number().int(),
22172
+ annotations: number().int(),
22173
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22174
+ missing: number().int(),
22175
+ bytes: number().int(),
22176
+ /** sha256 of the exact bytes sent. */
22177
+ sha256: string(),
22178
+ /** The target's HTTP status. */
22179
+ status: number().int()
22180
+ });
22156
22181
  /** What the operator asked the assist to look for. */
22157
22182
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22158
22183
  kind: literal("package"),
@@ -22947,9 +22972,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
22947
22972
  }), RetrainTransitionResultSchema, {
22948
22973
  kind: "mutation",
22949
22974
  auth: "admin"
22950
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
22975
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
22951
22976
  kind: "query",
22952
22977
  auth: "admin"
22978
+ }), method(object({
22979
+ deviceId: number(),
22980
+ trackId: string(),
22981
+ frameId: string(),
22982
+ complete: boolean()
22983
+ }), RetrainFrameSchema, {
22984
+ kind: "mutation",
22985
+ auth: "admin"
22986
+ }), method(object({
22987
+ filter: RetrainExportFilterSchema,
22988
+ layout: RetrainExportLayoutSchema,
22989
+ target: RetrainArchiveTargetSchema
22990
+ }), RetrainArchiveResultSchema, {
22991
+ kind: "mutation",
22992
+ auth: "admin",
22993
+ timeoutMs: 60 * 6e4
22953
22994
  }), method(object({
22954
22995
  /** Which of the three event tables owns the row. */
22955
22996
  ownerType: EventOwnerTypeSchema,
@@ -23000,6 +23041,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23000
23041
  timestamp: number()
23001
23042
  });
23002
23043
  /**
23044
+ * A root model's boxes standing in for one crop-kind step's own inference
23045
+ * (D730) — see `runPipeline.suppliedRoot`.
23046
+ */
23047
+ var SuppliedRootOutputSchema = object({
23048
+ stepId: string(),
23049
+ /** The root model that drew the boxes — stamped on the result. */
23050
+ modelId: string(),
23051
+ detections: array(object({
23052
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23053
+ bbox: tuple([
23054
+ number(),
23055
+ number(),
23056
+ number(),
23057
+ number()
23058
+ ]),
23059
+ score: number(),
23060
+ /**
23061
+ * Five facial landmarks in the same pixels — a face the step's own
23062
+ * detector already re-found inside a root face box (D730), so its
23063
+ * embedder child aligns it exactly as it aligns any detected face.
23064
+ */
23065
+ landmarks: array(object({
23066
+ x: number(),
23067
+ y: number()
23068
+ })).optional()
23069
+ })).min(1)
23070
+ });
23071
+ /**
23003
23072
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
23004
23073
  * within the frame, so the executor can re-cut a leaf child ROI at native
23005
23074
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23047,7 +23116,7 @@ var FrameRefSchema = object({
23047
23116
  timestamp: number(),
23048
23117
  capturedAt: number().optional()
23049
23118
  });
23050
- var ModelFormatSchema$1 = _enum([
23119
+ var ModelFormatSchema$2 = _enum([
23051
23120
  "onnx",
23052
23121
  "coreml",
23053
23122
  "openvino",
@@ -23065,7 +23134,7 @@ var PipelineSlotSchema = _enum([
23065
23134
  var PipelineEngineChoiceSchema = object({
23066
23135
  runtime: literal("python"),
23067
23136
  backend: string(),
23068
- format: ModelFormatSchema$1,
23137
+ format: ModelFormatSchema$2,
23069
23138
  device: string().optional()
23070
23139
  });
23071
23140
  /**
@@ -23104,32 +23173,15 @@ var PipelineDefaultStepSchema = lazy(() => object({
23104
23173
  group: string().optional(),
23105
23174
  settings: record(string(), unknown()).optional()
23106
23175
  }));
23107
- var PipelineTemplateStepSchema = lazy(() => object({
23108
- addonId: string(),
23109
- enabled: boolean(),
23110
- modelId: string(),
23111
- children: array(PipelineTemplateStepSchema).readonly(),
23112
- settings: record(string(), unknown()).optional()
23113
- }));
23114
- var PipelineTemplateSchema$1 = object({
23115
- id: string(),
23116
- name: string(),
23117
- createdAt: string(),
23118
- updatedAt: string(),
23119
- engine: PipelineEngineChoiceSchema,
23120
- steps: array(PipelineTemplateStepSchema).readonly()
23121
- });
23122
23176
  var PipelineModelOptionSchema = object({
23123
23177
  id: string(),
23124
23178
  name: string(),
23125
- formats: record(string(), object({
23126
- downloaded: boolean(),
23127
- sizeMB: number()
23128
- })),
23179
+ formats: record(string(), PipelineModelFormatStatusSchema),
23129
23180
  group: ModelVariantGroupSchema.optional(),
23130
23181
  legacy: boolean().optional(),
23131
23182
  provider: ModelProviderIdSchema.optional(),
23132
- defaultConfidence: number().optional()
23183
+ defaultConfidence: number().optional(),
23184
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23133
23185
  });
23134
23186
  var ConfigFieldBridge = custom();
23135
23187
  var PipelineAddonSchemaSchema = object({
@@ -23291,6 +23343,22 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23291
23343
  }), {
23292
23344
  kind: "mutation",
23293
23345
  auth: "admin"
23346
+ }), method(object({
23347
+ nodeId: string(),
23348
+ deviceIds: array(number()).readonly().optional(),
23349
+ dryRun: boolean()
23350
+ }), object({
23351
+ entries: array(object({
23352
+ deviceId: number(),
23353
+ keys: array(string()).readonly()
23354
+ })).readonly(),
23355
+ refused: array(object({
23356
+ deviceId: number(),
23357
+ reason: string()
23358
+ })).readonly()
23359
+ }), {
23360
+ kind: "mutation",
23361
+ auth: "admin"
23294
23362
  }), method(object({ nodeId: string() }), object({ unhealthy: array(object({
23295
23363
  /** `<backend>:<device>`, e.g. `openvino:gpu`. */
23296
23364
  deviceKey: string(),
@@ -23316,22 +23384,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23316
23384
  }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
23317
23385
  steps: array(PipelineStepInputSchema),
23318
23386
  deviceKey: string().optional()
23319
- }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
23320
- name: string(),
23321
- steps: array(PipelineTemplateStepSchema).readonly(),
23322
- engine: PipelineEngineChoiceSchema
23323
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
23324
- id: string(),
23325
- name: string().optional(),
23326
- steps: array(PipelineTemplateStepSchema).readonly().optional()
23327
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
23387
+ }), PipelineValidationResultSchema), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
23328
23388
  addonId: string(),
23329
23389
  modelId: string(),
23330
- format: ModelFormatSchema$1
23390
+ format: ModelFormatSchema$2
23331
23391
  }), DownloadModelResultSchema, { kind: "mutation" }), method(object({
23332
23392
  addonId: string(),
23333
23393
  modelId: string(),
23334
- format: ModelFormatSchema$1
23394
+ format: ModelFormatSchema$2
23335
23395
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
23336
23396
  steps: array(PipelineStepInputSchema).min(1),
23337
23397
  frame: FrameInputSchema.optional(),
@@ -23397,7 +23457,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23397
23457
  * `device-not-servable`), and nothing reaches the camera's live
23398
23458
  * trace stream. Absent ⇒ unchanged behaviour.
23399
23459
  */
23400
- replay: literal(true).optional()
23460
+ replay: literal(true).optional(),
23461
+ /**
23462
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
23463
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
23464
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
23465
+ * NOT inferred, these boxes are its output, and its children (the plate
23466
+ * reader) run on them through their own crop policy. Boxes are in the
23467
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
23468
+ */
23469
+ suppliedRoot: SuppliedRootOutputSchema.optional()
23401
23470
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
23402
23471
  steps: array(PipelineStepInputSchema).min(1),
23403
23472
  frames: array(FrameInputSchema).min(1).max(255),
@@ -23479,6 +23548,375 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23479
23548
  filename: string().optional(),
23480
23549
  settings: record(string(), unknown()).optional()
23481
23550
  }), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
23551
+ /**
23552
+ * The wire shapes of the Auto tune plan and apply (D745), used by the
23553
+ * `pipeline-orchestrator` cap. The recommender's own types
23554
+ * (`recommend.ts`) are the TS face of the same data; these
23555
+ * schemas are what crosses the cap boundary.
23556
+ */
23557
+ var ModelFormatSchema$1 = _enum(MODEL_FORMATS);
23558
+ /** The operator's range for it. */
23559
+ var MIN_SESSIONS_PER_DEVICE_RANGE = {
23560
+ min: 1,
23561
+ max: 8
23562
+ };
23563
+ var HardwareClassIdSchema = _enum([
23564
+ "intel-core-ultra",
23565
+ "intel-n-series",
23566
+ "apple-m-base",
23567
+ "apple-m-pro",
23568
+ "unknown"
23569
+ ]);
23570
+ var AcceleratorKindSchema = _enum([
23571
+ "intel-npu",
23572
+ "intel-igpu",
23573
+ "x86-cpu",
23574
+ "arm-cpu",
23575
+ "apple-ane",
23576
+ "coral"
23577
+ ]);
23578
+ var RecommendationReasonSchema = discriminatedUnion("kind", [
23579
+ object({
23580
+ kind: literal("capacity"),
23581
+ sessions: number(),
23582
+ minSessions: number()
23583
+ }),
23584
+ object({
23585
+ kind: literal("tie-faster"),
23586
+ over: string(),
23587
+ recallDelta: number()
23588
+ }),
23589
+ object({
23590
+ kind: literal("stepped-down"),
23591
+ from: string(),
23592
+ to: string(),
23593
+ limitedBy: string()
23594
+ }),
23595
+ object({
23596
+ kind: literal("no-fit-lightest"),
23597
+ sessions: number(),
23598
+ minSessions: number()
23599
+ }),
23600
+ object({
23601
+ kind: literal("derived-latency"),
23602
+ modelId: string()
23603
+ }),
23604
+ object({ kind: literal("cpu-device") }),
23605
+ object({ kind: literal("coral-untouched") }),
23606
+ object({ kind: literal("device-disabled") }),
23607
+ object({ kind: literal("device-unavailable") }),
23608
+ object({ kind: literal("node-offline") }),
23609
+ object({ kind: literal("no-hardware-facts") }),
23610
+ object({
23611
+ kind: literal("no-measured-data"),
23612
+ hardwareClass: HardwareClassIdSchema
23613
+ }),
23614
+ object({
23615
+ kind: literal("no-family-build"),
23616
+ format: ModelFormatSchema$1
23617
+ })
23618
+ ]);
23619
+ var DeviceModelChoiceSchema = object({
23620
+ modelId: string(),
23621
+ p50Ms: number(),
23622
+ fps: number(),
23623
+ measured: boolean(),
23624
+ /** Parallel sessions at the camera rate with the headroom kept free: ⌊fps × (1 − headroom) / camera fps⌋. */
23625
+ capacitySessions: number(),
23626
+ personRecall: number()
23627
+ });
23628
+ var DeviceRecommendationSchema = object({
23629
+ deviceKey: string(),
23630
+ accelerator: AcceleratorKindSchema.nullable(),
23631
+ enabled: boolean(),
23632
+ available: boolean(),
23633
+ chosen: DeviceModelChoiceSchema.nullable(),
23634
+ reasons: array(RecommendationReasonSchema).readonly()
23635
+ });
23636
+ var NodeRecommendationSchema = object({
23637
+ nodeId: string(),
23638
+ reachable: boolean(),
23639
+ hardwareClass: HardwareClassIdSchema.nullable(),
23640
+ cpuModel: string().nullable(),
23641
+ skipped: boolean(),
23642
+ acceleratorModelId: string().nullable(),
23643
+ devices: array(DeviceRecommendationSchema).readonly(),
23644
+ reasons: array(RecommendationReasonSchema).readonly()
23645
+ });
23646
+ var ModelPinChangeSchema = object({
23647
+ stepId: string(),
23648
+ before: string().nullable(),
23649
+ after: string().nullable()
23650
+ });
23651
+ var NodeDeviceChangeSchema = object({
23652
+ nodeId: string(),
23653
+ deviceKey: string(),
23654
+ madeExplicit: boolean(),
23655
+ modelPins: array(ModelPinChangeSchema).readonly(),
23656
+ thresholds: array(object({
23657
+ stepId: string(),
23658
+ keys: array(string()).readonly()
23659
+ })).readonly()
23660
+ });
23661
+ var CameraOverrideClearSchema = object({
23662
+ deviceId: number(),
23663
+ source: _enum(["step-override", "wholesale"]),
23664
+ nodeId: string(),
23665
+ deviceKey: string().nullable(),
23666
+ stepId: string(),
23667
+ modelIdBefore: string().nullable(),
23668
+ keys: array(string()).readonly()
23669
+ });
23670
+ var DetectorStoreClearSchema = object({
23671
+ deviceId: number(),
23672
+ keys: array(string()).readonly()
23673
+ });
23674
+ var AutoTuneWarningSchema = discriminatedUnion("kind", [
23675
+ object({
23676
+ kind: literal("detector-store-cluster-wide"),
23677
+ skippedNodes: array(string()).readonly()
23678
+ }),
23679
+ object({
23680
+ kind: literal("detector-store-unreadable"),
23681
+ error: string()
23682
+ }),
23683
+ object({
23684
+ kind: literal("coral-enabled"),
23685
+ nodeId: string(),
23686
+ deviceKey: string()
23687
+ })
23688
+ ]);
23689
+ var AutoTuneOptionsSchema = object({
23690
+ /** Share of each accelerator's throughput kept free (0.3–0.5). */
23691
+ headroom: number().min(.3).max(.5).default(.4),
23692
+ /**
23693
+ * The least number of parallel sessions every device must sustain at the
23694
+ * camera rate with the headroom kept free (D755). The most accurate model
23695
+ * that reaches it wins.
23696
+ */
23697
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
23698
+ });
23699
+ var AutoTunePlanSchema = object({
23700
+ /** Hash of everything the apply will write — the apply refuses a different one. */
23701
+ planHash: string(),
23702
+ family: literal("yolov9"),
23703
+ headroom: number(),
23704
+ minSessionsPerDevice: number(),
23705
+ /** The detection rate a session is counted at (the fastest camera running the pipeline root). */
23706
+ cameraFps: number(),
23707
+ generatedAt: number(),
23708
+ nodes: array(NodeRecommendationSchema).readonly(),
23709
+ nodeChanges: array(NodeDeviceChangeSchema).readonly(),
23710
+ cameraClears: array(CameraOverrideClearSchema).readonly(),
23711
+ detectorStoreClears: array(DetectorStoreClearSchema).readonly(),
23712
+ warnings: array(AutoTuneWarningSchema).readonly()
23713
+ });
23714
+ var AutoTuneApplyInputSchema = object({
23715
+ planHash: string(),
23716
+ headroom: number().min(.3).max(.5).default(.4),
23717
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
23718
+ });
23719
+ var AutoTunePhaseResultSchema = object({
23720
+ phase: _enum([
23721
+ "download",
23722
+ "camera-overrides",
23723
+ "detector-thresholds",
23724
+ "node-models",
23725
+ "redispatch"
23726
+ ]),
23727
+ ok: boolean(),
23728
+ detail: string()
23729
+ });
23730
+ var AutoTuneApplyResultSchema = discriminatedUnion("kind", [
23731
+ object({
23732
+ kind: literal("applied"),
23733
+ planHash: string(),
23734
+ phases: array(AutoTunePhaseResultSchema).readonly()
23735
+ }),
23736
+ object({
23737
+ kind: literal("aborted"),
23738
+ phases: array(AutoTunePhaseResultSchema).readonly()
23739
+ }),
23740
+ object({
23741
+ kind: literal("stale"),
23742
+ plan: AutoTunePlanSchema
23743
+ }),
23744
+ object({
23745
+ kind: literal("refused"),
23746
+ reason: _enum(["apply-in-progress"])
23747
+ })
23748
+ ]);
23749
+ /**
23750
+ * Wire shapes of the Load balancing surface (D748): the session placement
23751
+ * policy, the atomic share write, the observed placement statistics, the
23752
+ * hardware share suggestion and the stale device pins.
23753
+ */
23754
+ /**
23755
+ * How a new detection session picks its node and device.
23756
+ * - `least-loaded` — the historical rule: lowest `attached / weight`, a
23757
+ * constant node order at a tie (D37). An idle node always ties at 0, so a
23758
+ * weight only bites once a node already holds a session.
23759
+ * - `share` — the share of PARALLEL sessions is held to the weights, and a
23760
+ * full or drowning node yields to a free one (D748).
23761
+ */
23762
+ var SessionPlacementPolicySchema = _enum(["least-loaded", "share"]);
23763
+ var LoadBalancingSharesInputSchema = object({
23764
+ /** nodeId → share (> 0). A node left out keeps its weight. */
23765
+ nodes: record(string(), number().positive()).default({}),
23766
+ /** nodeId → deviceKey → share (> 0). A device left out keeps its weight. */
23767
+ devices: record(string(), record(string(), number().positive())).default({})
23768
+ });
23769
+ var PlacementStatsInputSchema = object({
23770
+ /** Window the observed shares are averaged over (default 1 h, max 24 h). */
23771
+ windowMs: number().int().min(6e4).max(1440 * 60 * 1e3).default(3600 * 1e3) });
23772
+ var PlacementDeviceStatsSchema = object({
23773
+ deviceKey: string(),
23774
+ /** Sessions running on this device now. */
23775
+ sessionsNow: number(),
23776
+ /** Sessions started on this device inside the window. */
23777
+ sessionsStarted: number(),
23778
+ /** Time-weighted share of the node's parallel sessions over the window (0–1); null = no session ran. */
23779
+ observedShare: number().nullable()
23780
+ });
23781
+ var PlacementNodeStatsSchema = object({
23782
+ nodeId: string(),
23783
+ sessionsNow: number(),
23784
+ sessionsStarted: number(),
23785
+ /** Time-weighted share of the cluster's parallel sessions over the window (0–1); null = none ran. */
23786
+ observedShare: number().nullable(),
23787
+ /** Most sessions this node ran at once inside the window. */
23788
+ peakSessions: number(),
23789
+ /** Sessions a share election handed elsewhere because this node was full or drowning. */
23790
+ yieldsAway: number(),
23791
+ devices: array(PlacementDeviceStatsSchema).readonly()
23792
+ });
23793
+ /** A camera's device pin that the session path cannot honour. */
23794
+ var StaleDevicePinSchema = object({
23795
+ deviceId: number(),
23796
+ deviceKey: string(),
23797
+ /** `disabled` — the key exists on some node but is not enabled anywhere; `absent` — no node has it. */
23798
+ reason: _enum(["disabled", "absent"])
23799
+ });
23800
+ var PlacementStatsSchema = object({
23801
+ policy: SessionPlacementPolicySchema,
23802
+ windowMs: number(),
23803
+ /** How much of the window was actually observed (the hub keeps it in memory). */
23804
+ observedForMs: number(),
23805
+ sessionsNow: number(),
23806
+ /** Most parallel sessions across the cluster inside the window. */
23807
+ clusterPeakSessions: number(),
23808
+ nodes: array(PlacementNodeStatsSchema).readonly(),
23809
+ stalePins: array(StaleDevicePinSchema).readonly()
23810
+ });
23811
+ /**
23812
+ * Where an automatic share's capacity comes from (D755).
23813
+ * - `hardware` — the static capacity of each device at its Auto tune model:
23814
+ * the measured latency table for the node's hardware class.
23815
+ * - `benchmark` — the node's own measured capacity (node benchmark results).
23816
+ * A node with no results falls back to `hardware`, and says so.
23817
+ */
23818
+ var CapacitySourceSchema = _enum(["hardware", "benchmark"]);
23819
+ /** Why a node under the `benchmark` source was sized from hardware instead. */
23820
+ var CapacityFallbackSchema = _enum(["no-benchmark-results", "partial-benchmark-results"]);
23821
+ var SuggestSharesInputSchema = object({
23822
+ headroom: number().min(.3).max(.5).default(.4),
23823
+ /** Default `hardware`. */
23824
+ source: CapacitySourceSchema.default("hardware")
23825
+ });
23826
+ var SuggestedDeviceShareSchema = object({
23827
+ deviceKey: string(),
23828
+ /** Share of the node (0–100, rounded). */
23829
+ share: number(),
23830
+ modelId: string().nullable(),
23831
+ /** Inferences per second at that model, from the measured table; null when sized by a benchmark. */
23832
+ fps: number().nullable(),
23833
+ /** False for a table cell derived from another chip; true for a measured cell or a benchmark. */
23834
+ measured: boolean(),
23835
+ /**
23836
+ * Advisory session cap: ⌊fps × (1 − headroom) / camera fps⌋ from the table,
23837
+ * or the benchmark's measured max sessions. Never enforced.
23838
+ */
23839
+ suggestedMaxSessions: number().nullable()
23840
+ });
23841
+ var SuggestedNodeShareSchema = object({
23842
+ nodeId: string(),
23843
+ /** Share of the cluster (0–100, rounded); null = node skipped (offline, unknown hardware). */
23844
+ share: number().nullable(),
23845
+ /** Parallel sessions the node sustains at the suggested models with the headroom kept free. */
23846
+ capacitySessions: number(),
23847
+ devices: array(SuggestedDeviceShareSchema).readonly(),
23848
+ skippedReason: string().nullable(),
23849
+ /** What this node's capacity was read from; null when the node is skipped. */
23850
+ capacitySource: CapacitySourceSchema.nullable(),
23851
+ /** Set when the `benchmark` source was asked for and this node used `hardware`. */
23852
+ capacityFallback: CapacityFallbackSchema.nullable()
23853
+ });
23854
+ var SuggestSharesResultSchema = object({
23855
+ headroom: number(),
23856
+ /** The source asked for; each node says what it actually used. */
23857
+ source: CapacitySourceSchema,
23858
+ /** Camera detection rate the capacity is counted in (the fastest camera's fps). */
23859
+ cameraFps: number(),
23860
+ /** The Auto tune capacity floor the models were picked at. */
23861
+ minSessionsPerDevice: number(),
23862
+ nodes: array(SuggestedNodeShareSchema).readonly()
23863
+ });
23864
+ /**
23865
+ * Where the node and device shares come from (D750, D755).
23866
+ * - `hardware` (default) — computed by the system from each node's static
23867
+ * capacity (its accelerators at their Auto tune models, from the measured
23868
+ * latency table), recomputed whenever a node or device joins, leaves, is
23869
+ * switched on or off, or changes model. No load input.
23870
+ * - `benchmark` — the same, from each node's measured capacity (node
23871
+ * benchmark results); a node without results falls back to `hardware`.
23872
+ * - `manual` — the operator's stored sliders.
23873
+ * Either way a node or device that cannot take sessions gives its share to
23874
+ * the others in proportion; the stored values are never rewritten for that.
23875
+ */
23876
+ var ShareSourceSchema = _enum([
23877
+ "hardware",
23878
+ "benchmark",
23879
+ "manual"
23880
+ ]);
23881
+ var SetShareSourceInputSchema = object({ source: ShareSourceSchema });
23882
+ object({
23883
+ nodes: record(string(), number()),
23884
+ devices: record(string(), record(string(), number()))
23885
+ });
23886
+ var EffectiveDeviceShareSchema = object({
23887
+ deviceKey: string(),
23888
+ /** Can take sessions now (enabled, available, can run the root). */
23889
+ eligible: boolean(),
23890
+ /** The share the source assigns, as a percentage of the node's devices. */
23891
+ configuredPct: number(),
23892
+ /** The share actually used, after an ineligible device's share went to the others. */
23893
+ effectivePct: number()
23894
+ });
23895
+ var EffectiveNodeShareSchema = object({
23896
+ nodeId: string(),
23897
+ eligible: boolean(),
23898
+ configuredPct: number(),
23899
+ effectivePct: number(),
23900
+ /** Automatic sources: what this node's share was computed from; null under `manual` or before the first answer. */
23901
+ capacitySource: CapacitySourceSchema.nullable(),
23902
+ /** Automatic `benchmark`: why this node used `hardware` instead. */
23903
+ capacityFallback: CapacityFallbackSchema.nullable(),
23904
+ devices: array(EffectiveDeviceShareSchema).readonly()
23905
+ });
23906
+ var EffectiveSharesSchema = object({
23907
+ source: ShareSourceSchema,
23908
+ policy: SessionPlacementPolicySchema,
23909
+ /** An automatic source with no computed answer yet: the stored sliders are used meanwhile. */
23910
+ autoPending: boolean(),
23911
+ /** When the automatic shares were last computed (ms epoch); null = never. */
23912
+ computedAt: number().nullable(),
23913
+ /** What made the system recompute them last. */
23914
+ trigger: string().nullable(),
23915
+ nodes: array(EffectiveNodeShareSchema).readonly(),
23916
+ /** The relative weights the election reads (before eligibility). */
23917
+ nodeWeights: record(string(), number()),
23918
+ deviceWeights: record(string(), record(string(), number()))
23919
+ });
23482
23920
  object({
23483
23921
  activeCameras: number(),
23484
23922
  throttledCameras: number(),
@@ -23922,6 +24360,22 @@ var MotionSourceEnum = _enum([
23922
24360
  "device-activity"
23923
24361
  ]);
23924
24362
  /**
24363
+ * What opened an on-motion detection SESSION: the motion source that passed the
24364
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24365
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24366
+ * device name as the orchestrator's camera-sensors resolution last read it;
24367
+ * absent when unknown or when the camera itself triggered.
24368
+ *
24369
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24370
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24371
+ * runner never decides anything on it.
24372
+ */
24373
+ var SessionTriggerSchema = object({
24374
+ source: MotionSourceEnum,
24375
+ triggeredBy: MotionTriggeredBySchema,
24376
+ sensorName: string().optional()
24377
+ });
24378
+ /**
23925
24379
  * List of motion sources active on a camera. Empty array is valid:
23926
24380
  * "no source" — happens for battery cams without firmware motion when
23927
24381
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24173,6 +24627,14 @@ var RunnerCameraConfigSchema = object({
24173
24627
  */
24174
24628
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24175
24629
  /**
24630
+ * What opened this attach, on a SESSION attach only (see
24631
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24632
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24633
+ * behind it, and every attach from an orchestrator older than the field — the
24634
+ * runner then names no source on the phase event.
24635
+ */
24636
+ sessionTrigger: SessionTriggerSchema.optional(),
24637
+ /**
24176
24638
  * WHICH root detector runs for this camera. The detection counterpart of
24177
24639
  * {@link motionSources}, same shape and same discipline: a per-camera list
24178
24640
  * of sources the system understands, vendor-agnostic, owned here.
@@ -24332,14 +24794,15 @@ var RunnerLocalLoadSchema = object({
24332
24794
  * Per-inference-device live load (multi-device C4). One entry per deviceKey
24333
24795
  * this runner currently has attached cameras on, so the orchestrator's second
24334
24796
  * `balance()` pass (over a node's devices) weights on real per-pool session
24335
- * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
24336
- * per device is 0 until the pool backlog gets a public accessor (follow-up).
24797
+ * counts. Empty on single-device / pre-multi-device runners. There is no
24798
+ * per-device queue depth: the inference pool's backlog has no accessor, and
24799
+ * a field that always read 0 was removed rather than shown as a measurement
24800
+ * (D762).
24337
24801
  */
24338
24802
  devices: array(object({
24339
24803
  deviceKey: string(),
24340
24804
  backend: string(),
24341
- attachedCameras: number(),
24342
- queueDepthTotal: number()
24805
+ attachedCameras: number()
24343
24806
  })).default([]),
24344
24807
  /** Hardware capability flags reported by this node. */
24345
24808
  hardware: object({
@@ -24475,7 +24938,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
24475
24938
  */
24476
24939
  cropJpeg: string().optional(),
24477
24940
  parent: DetailParentSchema,
24478
- steps: array(string()).optional()
24941
+ steps: array(string()).optional(),
24942
+ /**
24943
+ * The camera's root model already drew this step's boxes (D730): a
24944
+ * `license_plate` inside the parent vehicle. The named step is NOT
24945
+ * inferred — these FRAME-space boxes are its output — and its
24946
+ * requested children (the plate reader) run on them. Absent ⇒ every
24947
+ * requested step infers as before.
24948
+ */
24949
+ supplied: object({
24950
+ stepId: string(),
24951
+ modelId: string(),
24952
+ boxes: array(object({
24953
+ bbox: NativeCropBboxSchema,
24954
+ score: number()
24955
+ })).min(1)
24956
+ }).optional()
24479
24957
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
24480
24958
  /** Catalog step id, e.g. `clip-embedding`. */
24481
24959
  stepId: string(),
@@ -24538,14 +25016,6 @@ var CameraPipelineConfigSchema = object({
24538
25016
  settings: record(string(), unknown()).readonly().optional()
24539
25017
  }).nullable().optional()
24540
25018
  });
24541
- var PipelineTemplateSchema = object({
24542
- id: string(),
24543
- name: string(),
24544
- description: string().optional(),
24545
- config: CameraPipelineConfigSchema,
24546
- createdAt: string(),
24547
- updatedAt: string()
24548
- });
24549
25019
  var DeviceStepConfigSchema = object({
24550
25020
  modelId: string().optional(),
24551
25021
  settings: record(string(), unknown()).optional(),
@@ -24619,9 +25089,10 @@ var CameraStepOverridePatchSchema = object({
24619
25089
  modelId: string().optional(),
24620
25090
  settings: record(string(), unknown()).readonly().optional()
24621
25091
  });
25092
+ var CameraStepSettingsSchema = record(string(), record(string(), unknown()).readonly());
24622
25093
  var CameraPipelineSettingsSchema = object({
24623
- pinnedAgentNodeId: string().optional(),
24624
25094
  stepToggles: record(string(), boolean()).optional(),
25095
+ stepSettings: CameraStepSettingsSchema.optional(),
24625
25096
  stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
24626
25097
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
24627
25098
  });
@@ -24654,7 +25125,10 @@ var PipelineAssignmentSchema = object({
24654
25125
  });
24655
25126
  /**
24656
25127
  * Per-agent load summary surfaced to the load balancer + dashboards.
24657
- * Aggregated from each runner's `getLocalLoad` cap call.
25128
+ * Aggregated from each runner's `getLocalLoad` cap call. In the
25129
+ * `getAgentLoad` report, a single-device node's default-pool sessions (no
25130
+ * `deviceKey`) are credited to its one eligible device in `load.devices` —
25131
+ * the default pool IS that device (D745); the balancer's census stays raw.
24658
25132
  */
24659
25133
  var AgentLoadSummarySchema = object({
24660
25134
  nodeId: string(),
@@ -24743,26 +25217,27 @@ var CameraBrokerStatusSchema = object({
24743
25217
  width: number(),
24744
25218
  height: number(),
24745
25219
  subscribers: number(),
24746
- inFps: number(),
24747
- outFps: number()
25220
+ /**
25221
+ * Encoded packets/s the broker receives from the camera. null when the
25222
+ * broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
25223
+ * There is no output rate: decoding runs in the session decode workers, not
25224
+ * in the broker, so the broker's own decoded-frame rate is 0 on every live
25225
+ * camera and is not served (D758).
25226
+ */
25227
+ inFps: number().nullable()
24748
25228
  })).readonly(),
24749
25229
  webrtcSessions: number(),
24750
25230
  rtspRestream: boolean()
24751
25231
  });
24752
- /** Shared-memory ring statistics within the decoder block. */
24753
- var CameraDecoderShmSchema = object({
24754
- framesWritten: number(),
24755
- getFrameHits: number(),
24756
- getFrameMisses: number(),
24757
- budgetMb: number()
24758
- });
24759
- /** Decoder block — null when the decoder stage is unreachable or inactive. */
24760
- var CameraDecoderStatusSchema = object({
24761
- nodeId: string(),
24762
- formats: array(string()).readonly(),
24763
- sessionCount: number(),
24764
- shm: CameraDecoderShmSchema
24765
- });
25232
+ /**
25233
+ * Decoder block — WHERE decode runs (co-located with the detection node by
25234
+ * construction); null when the camera has no detection node. It carries no
25235
+ * frame counter: the shared-memory plane whose counters it used to serve is
25236
+ * gone, and those fields read 0 forever. Whether frames actually flow is read
25237
+ * from `detection.actualFps` (frames delivered to and processed by the
25238
+ * detector), never from a counter nothing feeds.
25239
+ */
25240
+ var CameraDecoderStatusSchema = object({ nodeId: string() });
24766
25241
  /** Motion block — null when motion detection is not active for this device. */
24767
25242
  var CameraMotionStatusSchema = object({
24768
25243
  enabled: boolean(),
@@ -25119,12 +25594,6 @@ method(object({
25119
25594
  }), object({ success: literal(true) }), {
25120
25595
  kind: "mutation",
25121
25596
  auth: "admin"
25122
- }), method(object({
25123
- agentNodeId: string(),
25124
- detectWeight: number().positive().nullable()
25125
- }), object({ success: literal(true) }), {
25126
- kind: "mutation",
25127
- auth: "admin"
25128
25597
  }), method(object({
25129
25598
  agentNodeId: string(),
25130
25599
  detect: boolean().nullable().optional(),
@@ -25166,6 +25635,15 @@ method(object({
25166
25635
  }), {
25167
25636
  kind: "mutation",
25168
25637
  auth: "admin"
25638
+ }), method(AutoTuneOptionsSchema, AutoTunePlanSchema, { auth: "admin" }), method(AutoTuneApplyInputSchema, AutoTuneApplyResultSchema, {
25639
+ kind: "mutation",
25640
+ auth: "admin"
25641
+ }), method(LoadBalancingSharesInputSchema, object({ success: literal(true) }), {
25642
+ kind: "mutation",
25643
+ auth: "admin"
25644
+ }), method(PlacementStatsInputSchema, PlacementStatsSchema, { auth: "admin" }), method(SuggestSharesInputSchema, SuggestSharesResultSchema, { auth: "admin" }), method(_void(), EffectiveSharesSchema, { auth: "admin" }), method(SetShareSourceInputSchema, object({ success: literal(true) }), {
25645
+ kind: "mutation",
25646
+ auth: "admin"
25169
25647
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
25170
25648
  deviceId: number(),
25171
25649
  addonId: string(),
@@ -25182,6 +25660,13 @@ method(object({
25182
25660
  }), object({ success: literal(true) }), {
25183
25661
  kind: "mutation",
25184
25662
  auth: "admin"
25663
+ }), method(object({
25664
+ deviceId: number(),
25665
+ addonId: string(),
25666
+ settings: record(string(), unknown()).nullable()
25667
+ }), object({ success: literal(true) }), {
25668
+ kind: "mutation",
25669
+ auth: "admin"
25185
25670
  }), method(object({
25186
25671
  deviceId: number(),
25187
25672
  agentNodeId: string(),
@@ -25205,25 +25690,7 @@ method(object({
25205
25690
  }), method(_void(), DiskReconcileJobSchema, {
25206
25691
  kind: "mutation",
25207
25692
  auth: "admin"
25208
- }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
25209
- name: string(),
25210
- description: string().optional(),
25211
- config: CameraPipelineConfigSchema
25212
- }), PipelineTemplateSchema, {
25213
- kind: "mutation",
25214
- auth: "admin"
25215
- }), method(object({
25216
- id: string(),
25217
- name: string().optional(),
25218
- description: string().optional(),
25219
- config: CameraPipelineConfigSchema.optional()
25220
- }), PipelineTemplateSchema, {
25221
- kind: "mutation",
25222
- auth: "admin"
25223
- }), method(object({ id: string() }), object({ success: literal(true) }), {
25224
- kind: "mutation",
25225
- auth: "admin"
25226
- });
25693
+ }), method(_void(), DiskReconcileJobSchema, { auth: "admin" });
25227
25694
  /**
25228
25695
  * Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
25229
25696
  * `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
@@ -25813,7 +26280,19 @@ var SsoBridgeClaimsSchema = object({
25813
26280
  * editing a descriptor must not retroactively extend or shorten a link the
25814
26281
  * operator already consented to.
25815
26282
  */
25816
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26283
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26284
+ /**
26285
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26286
+ * that was started from a signed-in user's "Link" button: the finish then
26287
+ * links this identity to the intent's user instead of signing anyone in.
26288
+ * The handle carries no user id — the hub resolves it, single-use.
26289
+ */
26290
+ linkIntent: string().optional(),
26291
+ /**
26292
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26293
+ * subject is unique only per issuer, so a link is bound to it.
26294
+ */
26295
+ issuer: string().optional()
25817
26296
  });
25818
26297
  method(object({
25819
26298
  claims: SsoBridgeClaimsSchema,
@@ -27443,8 +27922,6 @@ var WebrtcStreamChoiceSchema = object({
27443
27922
  ]).nullable(),
27444
27923
  /** Input FPS from the camera (null for adaptive). */
27445
27924
  inputFps: number().nullable(),
27446
- /** Decoded FPS (null for adaptive). */
27447
- decodeFps: number().nullable(),
27448
27925
  /** Bitrate in kbps (null for adaptive). */
27449
27926
  bitrateKbps: number().nullable()
27450
27927
  });
@@ -27721,7 +28198,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
27721
28198
  * field their hints were silently stripped by the schema and the
27722
28199
  * adaptive ladder started blind on the client's display size.
27723
28200
  */
27724
- hints: webrtcClientHintsSchema.optional()
28201
+ hints: webrtcClientHintsSchema.optional(),
28202
+ /**
28203
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28204
+ * through the `intercom` cap's push-talk triple. When `true` and the
28205
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28206
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28207
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28208
+ *
28209
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28210
+ * with `intercom`, when the linked user may control that camera. The
28211
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28212
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28213
+ * intercom cap's own surface (share tokens gate it there), and this
28214
+ * flag must not become a second door to the camera's speaker.
28215
+ */
28216
+ talkback: boolean().optional()
27725
28217
  }), object({
27726
28218
  sessionId: string(),
27727
28219
  sdpAnswer: string()
@@ -27776,6 +28268,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
27776
28268
  */
27777
28269
  alive: boolean()
27778
28270
  })), method(object({
28271
+ deviceId: number().int().nonnegative(),
28272
+ sessionId: string(),
28273
+ downlinkMbps: number().nonnegative()
28274
+ }), object({
28275
+ outcome: _enum(["switching", "held"]),
28276
+ tier: CamProfileSchema.nullable(),
28277
+ reason: string()
28278
+ }), { kind: "mutation" }), method(object({
27779
28279
  deviceId: number().int().nonnegative(),
27780
28280
  sessionId: string()
27781
28281
  }), WebrtcSessionDebugSchema, { kind: "query" });
@@ -28015,6 +28515,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28015
28515
  var RestartAddonResultSchema = unknown();
28016
28516
  var InstallPackageResultSchema = unknown();
28017
28517
  var ReloadPackagesResultSchema = unknown();
28518
+ /**
28519
+ * What an uninstall did on ONE node.
28520
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
28521
+ * - `not-installed` — the node did not have it (nothing to do).
28522
+ * - `refused` — protected / bootstrap package; nothing touched.
28523
+ * - `failed` — attempted and did not complete; `error` says why.
28524
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
28525
+ * back-fill never returns the package, and the stale-addon sweep removes the
28526
+ * copy when the node registers again (only once the hub no longer has it).
28527
+ */
28528
+ var UninstallNodeOutcomeSchema = _enum([
28529
+ "uninstalled",
28530
+ "not-installed",
28531
+ "refused",
28532
+ "failed",
28533
+ "pending-reconnect"
28534
+ ]);
28535
+ var UninstallNodeResultSchema = object({
28536
+ nodeId: string(),
28537
+ outcome: UninstallNodeOutcomeSchema,
28538
+ error: string().optional(),
28539
+ addonIds: array(string()).readonly(),
28540
+ runnersStopped: array(string()).readonly(),
28541
+ warnings: array(string()).readonly()
28542
+ });
28543
+ var UninstallPackageResultSchema = object({
28544
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
28545
+ success: boolean(),
28546
+ packageName: string(),
28547
+ results: array(UninstallNodeResultSchema).readonly()
28548
+ });
28549
+ /**
28550
+ * `unreachable` lists online agents whose status read FAILED — absence from
28551
+ * `installations` is only "not installed" for a node that answered (D315).
28552
+ */
28553
+ var PackageInstallationsSchema = object({
28554
+ installations: array(object({
28555
+ packageName: string(),
28556
+ nodeId: string(),
28557
+ nodeName: string(),
28558
+ isHub: boolean(),
28559
+ isOnline: boolean(),
28560
+ version: string().nullable(),
28561
+ addonIds: array(string()).readonly(),
28562
+ source: _enum(["live", "recorded"]),
28563
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
28564
+ onHub: boolean()
28565
+ })).readonly(),
28566
+ unreachable: array(object({
28567
+ nodeId: string(),
28568
+ error: string()
28569
+ })).readonly()
28570
+ });
28018
28571
  var BulkUpdateItemStatusSchema = _enum([
28019
28572
  "queued",
28020
28573
  "updating",
@@ -28097,10 +28650,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
28097
28650
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
28098
28651
  kind: "mutation",
28099
28652
  auth: "admin"
28100
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
28653
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
28654
+ packageName: string().min(1),
28655
+ nodeId: string().optional(),
28656
+ everywhere: boolean().optional()
28657
+ }), UninstallPackageResultSchema, {
28101
28658
  kind: "mutation",
28102
28659
  auth: "admin"
28103
- }), method(_void(), ReloadPackagesResultSchema, {
28660
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
28104
28661
  kind: "mutation",
28105
28662
  auth: "admin"
28106
28663
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -30396,7 +30953,7 @@ var LocalInterfaceSchema = object({
30396
30953
  name: string(),
30397
30954
  family: _enum(["IPv4", "IPv6"]),
30398
30955
  address: string(),
30399
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
30956
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
30400
30957
  cidr: string(),
30401
30958
  /** OS netmask. Stable across calls so the SDK can hash on it. */
30402
30959
  netmask: string(),
@@ -30450,7 +31007,9 @@ var ConnectionEndpointSchema = object({
30450
31007
  "lan-ipv4",
30451
31008
  "lan-ipv6",
30452
31009
  "public",
30453
- "loopback"
31010
+ "loopback",
31011
+ "app-link",
31012
+ "custom"
30454
31013
  ]),
30455
31014
  /**
30456
31015
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -30519,15 +31078,27 @@ var GetConnectionEndpointsResultSchema = object({
30519
31078
  localPort: AdvertisedLocalPortSchema
30520
31079
  });
30521
31080
  /**
30522
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
30523
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
30524
- * what AUTO currently picks, so the UI can show the effective value either way.
31081
+ * The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
31082
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
31083
+ * so the UI can show it either way.
30525
31084
  */
30526
31085
  var NotificationEndpointSchema = object({
30527
31086
  /** The operator's explicit choice, or null for AUTO. */
30528
31087
  baseUrl: string().nullable(),
30529
- /** What the ranking currently resolves to (null when nothing is reachable). */
30530
- resolved: string().nullable()
31088
+ /**
31089
+ * The effective flagged address: the explicit choice, else (AUTO) the
31090
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
31091
+ * answered the public tunnel / mesh here, or null.
31092
+ */
31093
+ resolved: string().nullable(),
31094
+ /**
31095
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
31096
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
31097
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
31098
+ * hub advertises neither; the app link is then minted without `hub=`.
31099
+ * Absent on a pre-D709 hub.
31100
+ */
31101
+ appLinkHub: string().nullable()
30531
31102
  });
30532
31103
  /**
30533
31104
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -30540,6 +31111,72 @@ var ViewerEndpointsSchema = object({
30540
31111
  /** What the ranking currently resolves to (may be empty if nothing is up). */
30541
31112
  resolved: array(string()).readonly()
30542
31113
  });
31114
+ /**
31115
+ * DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
31116
+ * for addons built against it): `cluster` is the `internal` role, `browser`
31117
+ * the `publicEndpoint` role; `override` is the flagged address.
31118
+ */
31119
+ var HubAddressSnapshotSchema = object({
31120
+ override: string().nullable(),
31121
+ resolved: string().nullable(),
31122
+ source: _enum([
31123
+ "override",
31124
+ "auto",
31125
+ "none"
31126
+ ])
31127
+ });
31128
+ var HubAddressesSchema = object({
31129
+ cluster: HubAddressSnapshotSchema,
31130
+ browser: HubAddressSnapshotSchema
31131
+ });
31132
+ /**
31133
+ * What an address is used for (`hub-address.ts`, D734). `appConnections` is
31134
+ * many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
31135
+ * by at most one address.
31136
+ */
31137
+ var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
31138
+ var RoleSourceSchema = _enum([
31139
+ "flagged",
31140
+ "auto",
31141
+ "none"
31142
+ ]);
31143
+ /** One single-valued role: the flagged address, the one in use, and why. */
31144
+ var HubAddressRoleResolutionSchema = object({
31145
+ /** The address carrying the flag, or null = automatic. */
31146
+ flagged: string().nullable(),
31147
+ /** The address in use, or null when nothing qualifies (never loopback). */
31148
+ resolved: string().nullable(),
31149
+ source: RoleSourceSchema
31150
+ });
31151
+ var HubAppConnectionsResolutionSchema = object({
31152
+ /** The addresses flagged `appConnections`, or empty = automatic. */
31153
+ flagged: array(string()).readonly(),
31154
+ /** What the apps race right now. */
31155
+ resolved: array(string()).readonly(),
31156
+ source: RoleSourceSchema
31157
+ });
31158
+ var HubAddressBookSchema = object({
31159
+ rows: array(ConnectionEndpointSchema.extend({
31160
+ /** In the hub's detected palette right now. */
31161
+ detected: boolean(),
31162
+ /** Entered by the operator (removable). */
31163
+ custom: boolean(),
31164
+ /** The roles explicitly flagged on this address. */
31165
+ flags: array(HubAddressRoleSchema).readonly(),
31166
+ /** The roles this address serves right now — flagged or automatic. */
31167
+ inUse: array(HubAddressRoleSchema).readonly(),
31168
+ /** The roles this address may be flagged with. */
31169
+ eligible: array(HubAddressRoleSchema).readonly()
31170
+ })).readonly(),
31171
+ roles: object({
31172
+ appConnections: HubAppConnectionsResolutionSchema,
31173
+ notificationTaps: HubAddressRoleResolutionSchema,
31174
+ internal: HubAddressRoleResolutionSchema,
31175
+ publicEndpoint: HubAddressRoleResolutionSchema
31176
+ }),
31177
+ /** The `hub=` an app link carries (D709), or null. */
31178
+ appLinkHub: string().nullable()
31179
+ });
30543
31180
  var AllowedAddressesSchema = object({
30544
31181
  /**
30545
31182
  * Allowlist of interface addresses operators have explicitly opted
@@ -30581,8 +31218,29 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
30581
31218
  * Pass `'https'` when the caller is itself loaded over HTTPS
30582
31219
  * to avoid mixed-content blocks in the browser. The public
30583
31220
  * tunnel always emits `https://` regardless. */
30584
- scheme: _enum(["http", "https"]).optional()
30585
- }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
31221
+ scheme: _enum(["http", "https"]).optional(),
31222
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
31223
+ * an address notification taps can be flagged with, not a hub
31224
+ * route. Default `false`: racers and rankers never see it. */
31225
+ includeAppLink: boolean().optional()
31226
+ }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(object({ scheme: _enum(["http", "https"]).optional() }).optional(), HubAddressBookSchema), method(object({
31227
+ baseUrl: string(),
31228
+ label: string().max(80)
31229
+ }), HubAddressBookSchema, {
31230
+ kind: "mutation",
31231
+ auth: "admin"
31232
+ }), method(object({ baseUrl: string() }), HubAddressBookSchema, {
31233
+ kind: "mutation",
31234
+ auth: "admin"
31235
+ }), method(object({
31236
+ role: HubAddressRoleSchema,
31237
+ baseUrl: string().nullable(),
31238
+ enabled: boolean(),
31239
+ acceptInsecureHttp: boolean().optional()
31240
+ }), HubAddressBookSchema, {
31241
+ kind: "mutation",
31242
+ auth: "admin"
31243
+ }), method(_void(), HubAddressesSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
30586
31244
  kind: "mutation",
30587
31245
  auth: "admin"
30588
31246
  }), method(object({
@@ -30842,7 +31500,7 @@ var MeshPeerSchema = object({
30842
31500
  tags: array(string()).readonly(),
30843
31501
  /** True when the peer advertises itself as an exit-node candidate. */
30844
31502
  exitNodeOption: boolean(),
30845
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
31503
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
30846
31504
  advertisedRoutes: array(string()).readonly(),
30847
31505
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
30848
31506
  userLogin: string().nullable(),
@@ -31033,7 +31691,8 @@ object({
31033
31691
  * writes this slice (not even a boot seed), and neither does the runner's
31034
31692
  * phase machine: its phase is "a session is attached" for every on-motion
31035
31693
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
31036
- * A provider's `isDetected` answers from the hub's slice.
31694
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
31695
+ * (`hubMotionNativeProvider`).
31037
31696
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
31038
31697
  * imports) — the provider pushes both edges itself, from the upstream
31039
31698
  * system's own state change. That is the sensor's own fact.
@@ -31847,7 +32506,13 @@ var OsdStatusSchema = object({ overlays: array(object({
31847
32506
  */
31848
32507
  availablePositions: array(OsdPositionEnum).readonly(),
31849
32508
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
31850
- readOnly: boolean().optional()
32509
+ readOnly: boolean().optional(),
32510
+ /**
32511
+ * Firmware text ceiling for this overlay. Absent = no known limit.
32512
+ * The OSD manager truncates here on every write — never stores its own
32513
+ * copy on the binding.
32514
+ */
32515
+ maxCharacters: number().int().positive().optional()
31851
32516
  })).readonly() });
31852
32517
  var OsdOverlayPatchSchema = object({
31853
32518
  enabled: boolean().optional(),
@@ -31898,7 +32563,9 @@ var OsdTemplateBindingSchema = object({
31898
32563
  valuePath: string().min(1).max(64),
31899
32564
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
31900
32565
  displayUnit: string().max(16).optional(),
31901
- maxDecimals: number().int().min(0).max(4).default(1)
32566
+ maxDecimals: number().int().min(0).max(4).default(1),
32567
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
32568
+ valueMap: record(string(), string()).optional()
31902
32569
  });
31903
32570
  /**
31904
32571
  * A named template: bindings (alias → leaf field) + a parser that
@@ -31948,18 +32615,11 @@ var OsdSlotBindingSchema = object({
31948
32615
  source: OsdSourceSchema,
31949
32616
  /** `${value}` and `${unit}` are substituted; every occurrence. */
31950
32617
  template: string().max(96).default("${value}"),
31951
- /** Truncate with an ellipsis past this length. Absent = no limit. */
31952
- maxCharacters: number().int().min(4).max(64).optional(),
31953
32618
  /**
31954
32619
  * Decimal places for a numeric value. `0` yields an integer — the
31955
32620
  * documented workaround for firmwares that reject `.` in overlay text.
31956
32621
  */
31957
32622
  maxDecimals: number().int().min(0).max(4).default(1),
31958
- /**
31959
- * Appended via `${unit}` when no unit conversion produces a label.
31960
- * Prefer `source.displayUnit` for converted device-state values.
31961
- */
31962
- unitLabel: string().max(8).optional(),
31963
32623
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
31964
32624
  valueMap: record(string(), string()).optional(),
31965
32625
  /** Time windows in which the slot is shown. Absent = always. */
@@ -31968,9 +32628,7 @@ var OsdSlotBindingSchema = object({
31968
32628
  * Display gate, in the notification centre's condition vocabulary.
31969
32629
  * Only the keys reported by `getConditionSupport` are accepted.
31970
32630
  */
31971
- conditions: NcConditionsSchema.optional(),
31972
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
31973
- fallbackText: string().max(64).default("")
32631
+ conditions: NcConditionsSchema.optional()
31974
32632
  });
31975
32633
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
31976
32634
  var OsdSlotViewSchema = object({
@@ -35660,6 +36318,32 @@ var TotpStatusSchema = object({
35660
36318
  /** Null when no row exists OR the row is still pending confirmation. */
35661
36319
  confirmedAt: number().nullable()
35662
36320
  });
36321
+ /**
36322
+ * user-management — singleton capability for user accounts, API keys,
36323
+ * and scoped tokens.
36324
+ *
36325
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
36326
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
36327
+ * because non-admins never reach these. If/when we open non-admin
36328
+ * delegation, structural caller-scope subset check goes inside the
36329
+ * provider.
36330
+ */
36331
+ var ExternalIdentitySchema = object({
36332
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
36333
+ provider: string(),
36334
+ /** The IdP's stable subject (`sub`) for this account. */
36335
+ subject: string(),
36336
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
36337
+ issuer: string(),
36338
+ userId: string(),
36339
+ /** What the IdP called the account at link time (username / email) — display only. */
36340
+ label: string().optional(),
36341
+ linkedAt: number()
36342
+ });
36343
+ var ExternalIdentityKeySchema = object({
36344
+ provider: string().min(1),
36345
+ subject: string().min(1)
36346
+ });
35663
36347
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
35664
36348
  kind: "mutation",
35665
36349
  auth: "admin",
@@ -35773,7 +36457,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
35773
36457
  userId: string(),
35774
36458
  username: string(),
35775
36459
  scopes: array(TokenScopeSchema)
35776
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
36460
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
36461
+ userId: string(),
36462
+ issuer: string()
36463
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
36464
+ userId: string(),
36465
+ issuer: string().min(1),
36466
+ label: string().optional()
36467
+ }), object({ success: literal(true) }), {
36468
+ kind: "mutation",
36469
+ auth: "admin",
36470
+ access: "create"
36471
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
36472
+ kind: "mutation",
36473
+ auth: "admin",
36474
+ access: "delete"
36475
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
35777
36476
  kind: "mutation",
35778
36477
  auth: "admin",
35779
36478
  access: "delete"
@@ -36165,6 +36864,16 @@ DeviceType.Camera, method(object({
36165
36864
  package: array(ZoneRuleSchema).readonly()
36166
36865
  });
36167
36866
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
36867
+ Object.freeze({
36868
+ person: .5,
36869
+ vehicle: .5,
36870
+ animal: .5
36871
+ });
36872
+ Object.freeze({
36873
+ person: .65,
36874
+ vehicle: .65,
36875
+ animal: .65
36876
+ });
36168
36877
  /**
36169
36878
  * Accessory device helpers — shared across drivers.
36170
36879
  *
@@ -36339,6 +37048,12 @@ Object.freeze({
36339
37048
  addonId: null,
36340
37049
  access: "view"
36341
37050
  },
37051
+ "addons.listInstallations": {
37052
+ capName: "addons",
37053
+ capScope: "system",
37054
+ addonId: null,
37055
+ access: "view"
37056
+ },
36342
37057
  "addons.listJobs": {
36343
37058
  capName: "addons",
36344
37059
  capScope: "system",
@@ -37521,90 +38236,18 @@ Object.freeze({
37521
38236
  addonId: null,
37522
38237
  access: "create"
37523
38238
  },
37524
- "decoder.createSession": {
37525
- capName: "decoder",
37526
- capScope: "system",
37527
- addonId: null,
37528
- access: "view"
37529
- },
37530
- "decoder.destroySession": {
37531
- capName: "decoder",
37532
- capScope: "system",
37533
- addonId: null,
37534
- access: "delete"
37535
- },
37536
- "decoder.getFrame": {
37537
- capName: "decoder",
37538
- capScope: "system",
37539
- addonId: null,
37540
- access: "view"
37541
- },
37542
38239
  "decoder.getInfo": {
37543
38240
  capName: "decoder",
37544
38241
  capScope: "system",
37545
38242
  addonId: null,
37546
38243
  access: "view"
37547
38244
  },
37548
- "decoder.getShmStats": {
37549
- capName: "decoder",
37550
- capScope: "system",
37551
- addonId: null,
37552
- access: "view"
37553
- },
37554
- "decoder.getStats": {
37555
- capName: "decoder",
37556
- capScope: "system",
37557
- addonId: null,
37558
- access: "view"
37559
- },
37560
- "decoder.listActiveSessions": {
37561
- capName: "decoder",
37562
- capScope: "system",
37563
- addonId: null,
37564
- access: "view"
37565
- },
37566
- "decoder.openStream": {
37567
- capName: "decoder",
37568
- capScope: "system",
37569
- addonId: null,
37570
- access: "view"
37571
- },
37572
- "decoder.pullFrames": {
37573
- capName: "decoder",
37574
- capScope: "system",
37575
- addonId: null,
37576
- access: "view"
37577
- },
37578
- "decoder.pullHandles": {
37579
- capName: "decoder",
37580
- capScope: "system",
37581
- addonId: null,
37582
- access: "view"
37583
- },
37584
- "decoder.pushPacket": {
37585
- capName: "decoder",
37586
- capScope: "system",
37587
- addonId: null,
37588
- access: "view"
37589
- },
37590
38245
  "decoder.reprobeHwaccel": {
37591
38246
  capName: "decoder",
37592
38247
  capScope: "system",
37593
38248
  addonId: null,
37594
38249
  access: "create"
37595
38250
  },
37596
- "decoder.supportsCodec": {
37597
- capName: "decoder",
37598
- capScope: "system",
37599
- addonId: null,
37600
- access: "view"
37601
- },
37602
- "decoder.updateConfig": {
37603
- capName: "decoder",
37604
- capScope: "system",
37605
- addonId: null,
37606
- access: "view"
37607
- },
37608
38251
  "detectionPipeline.applyDeviceSettingsPatch": {
37609
38252
  capName: "detection-pipeline",
37610
38253
  capScope: "device",
@@ -39093,12 +39736,24 @@ Object.freeze({
39093
39736
  addonId: null,
39094
39737
  access: "view"
39095
39738
  },
39739
+ "localNetwork.addCustomAddress": {
39740
+ capName: "local-network",
39741
+ capScope: "system",
39742
+ addonId: null,
39743
+ access: "create"
39744
+ },
39096
39745
  "localNetwork.downloadCa": {
39097
39746
  capName: "local-network",
39098
39747
  capScope: "system",
39099
39748
  addonId: null,
39100
39749
  access: "view"
39101
39750
  },
39751
+ "localNetwork.getAddresses": {
39752
+ capName: "local-network",
39753
+ capScope: "system",
39754
+ addonId: null,
39755
+ access: "view"
39756
+ },
39102
39757
  "localNetwork.getAllowedAddresses": {
39103
39758
  capName: "local-network",
39104
39759
  capScope: "system",
@@ -39111,6 +39766,12 @@ Object.freeze({
39111
39766
  addonId: null,
39112
39767
  access: "view"
39113
39768
  },
39769
+ "localNetwork.getHubAddresses": {
39770
+ capName: "local-network",
39771
+ capScope: "system",
39772
+ addonId: null,
39773
+ access: "view"
39774
+ },
39114
39775
  "localNetwork.getNotificationEndpoint": {
39115
39776
  capName: "local-network",
39116
39777
  capScope: "system",
@@ -39147,6 +39808,12 @@ Object.freeze({
39147
39808
  addonId: null,
39148
39809
  access: "create"
39149
39810
  },
39811
+ "localNetwork.removeCustomAddress": {
39812
+ capName: "local-network",
39813
+ capScope: "system",
39814
+ addonId: null,
39815
+ access: "delete"
39816
+ },
39150
39817
  "localNetwork.resetAllowlistToBestMatch": {
39151
39818
  capName: "local-network",
39152
39819
  capScope: "system",
@@ -39159,6 +39826,12 @@ Object.freeze({
39159
39826
  addonId: null,
39160
39827
  access: "create"
39161
39828
  },
39829
+ "localNetwork.setAddressRole": {
39830
+ capName: "local-network",
39831
+ capScope: "system",
39832
+ addonId: null,
39833
+ access: "create"
39834
+ },
39162
39835
  "localNetwork.setAllowedAddresses": {
39163
39836
  capName: "local-network",
39164
39837
  capScope: "system",
@@ -40605,6 +41278,12 @@ Object.freeze({
40605
41278
  addonId: null,
40606
41279
  access: "create"
40607
41280
  },
41281
+ "pipelineAnalytics.setRetrainFrameComplete": {
41282
+ capName: "pipeline-analytics",
41283
+ capScope: "device",
41284
+ addonId: null,
41285
+ access: "create"
41286
+ },
40608
41287
  "pipelineAnalytics.setTrackFlags": {
40609
41288
  capName: "pipeline-analytics",
40610
41289
  capScope: "device",
@@ -40641,6 +41320,12 @@ Object.freeze({
40641
41320
  addonId: null,
40642
41321
  access: "delete"
40643
41322
  },
41323
+ "pipelineAnalytics.writeRetrainArchive": {
41324
+ capName: "pipeline-analytics",
41325
+ capScope: "device",
41326
+ addonId: null,
41327
+ access: "create"
41328
+ },
40644
41329
  "pipelineExecutor.cacheFrameInPool": {
40645
41330
  capName: "pipeline-executor",
40646
41331
  capScope: "system",
@@ -40653,13 +41338,13 @@ Object.freeze({
40653
41338
  addonId: null,
40654
41339
  access: "delete"
40655
41340
  },
40656
- "pipelineExecutor.deleteModel": {
41341
+ "pipelineExecutor.clearModelBoundDeviceOverrides": {
40657
41342
  capName: "pipeline-executor",
40658
41343
  capScope: "system",
40659
41344
  addonId: null,
40660
41345
  access: "delete"
40661
41346
  },
40662
- "pipelineExecutor.deleteTemplate": {
41347
+ "pipelineExecutor.deleteModel": {
40663
41348
  capName: "pipeline-executor",
40664
41349
  capScope: "system",
40665
41350
  addonId: null,
@@ -40803,12 +41488,6 @@ Object.freeze({
40803
41488
  addonId: null,
40804
41489
  access: "view"
40805
41490
  },
40806
- "pipelineExecutor.listTemplates": {
40807
- capName: "pipeline-executor",
40808
- capScope: "system",
40809
- addonId: null,
40810
- access: "view"
40811
- },
40812
41491
  "pipelineExecutor.rearmInferenceDevice": {
40813
41492
  capName: "pipeline-executor",
40814
41493
  capScope: "system",
@@ -40833,12 +41512,6 @@ Object.freeze({
40833
41512
  addonId: null,
40834
41513
  access: "create"
40835
41514
  },
40836
- "pipelineExecutor.saveTemplate": {
40837
- capName: "pipeline-executor",
40838
- capScope: "system",
40839
- addonId: null,
40840
- access: "create"
40841
- },
40842
41515
  "pipelineExecutor.setVideoPipelineSteps": {
40843
41516
  capName: "pipeline-executor",
40844
41517
  capScope: "system",
@@ -40857,41 +41530,35 @@ Object.freeze({
40857
41530
  addonId: null,
40858
41531
  access: "create"
40859
41532
  },
40860
- "pipelineExecutor.updateTemplate": {
40861
- capName: "pipeline-executor",
40862
- capScope: "system",
40863
- addonId: null,
40864
- access: "create"
40865
- },
40866
41533
  "pipelineExecutor.validatePipeline": {
40867
41534
  capName: "pipeline-executor",
40868
41535
  capScope: "system",
40869
41536
  addonId: null,
40870
41537
  access: "view"
40871
41538
  },
40872
- "pipelineOrchestrator.applyDeviceSettingsPatch": {
41539
+ "pipelineOrchestrator.applyAutoTune": {
40873
41540
  capName: "pipeline-orchestrator",
40874
41541
  capScope: "system",
40875
41542
  addonId: null,
40876
41543
  access: "create"
40877
41544
  },
40878
- "pipelineOrchestrator.assignAudio": {
41545
+ "pipelineOrchestrator.applyDeviceSettingsPatch": {
40879
41546
  capName: "pipeline-orchestrator",
40880
41547
  capScope: "system",
40881
41548
  addonId: null,
40882
41549
  access: "create"
40883
41550
  },
40884
- "pipelineOrchestrator.assignPipeline": {
41551
+ "pipelineOrchestrator.assignAudio": {
40885
41552
  capName: "pipeline-orchestrator",
40886
41553
  capScope: "system",
40887
41554
  addonId: null,
40888
41555
  access: "create"
40889
41556
  },
40890
- "pipelineOrchestrator.deleteTemplate": {
41557
+ "pipelineOrchestrator.assignPipeline": {
40891
41558
  capName: "pipeline-orchestrator",
40892
41559
  capScope: "system",
40893
41560
  addonId: null,
40894
- access: "delete"
41561
+ access: "create"
40895
41562
  },
40896
41563
  "pipelineOrchestrator.getAgentLoad": {
40897
41564
  capName: "pipeline-orchestrator",
@@ -40983,6 +41650,12 @@ Object.freeze({
40983
41650
  addonId: null,
40984
41651
  access: "view"
40985
41652
  },
41653
+ "pipelineOrchestrator.getEffectiveShares": {
41654
+ capName: "pipeline-orchestrator",
41655
+ capScope: "system",
41656
+ addonId: null,
41657
+ access: "view"
41658
+ },
40986
41659
  "pipelineOrchestrator.getGlobalMetrics": {
40987
41660
  capName: "pipeline-orchestrator",
40988
41661
  capScope: "system",
@@ -41019,19 +41692,19 @@ Object.freeze({
41019
41692
  addonId: null,
41020
41693
  access: "view"
41021
41694
  },
41022
- "pipelineOrchestrator.getReconcileFromDiskStatus": {
41695
+ "pipelineOrchestrator.getPlacementStats": {
41023
41696
  capName: "pipeline-orchestrator",
41024
41697
  capScope: "system",
41025
41698
  addonId: null,
41026
41699
  access: "view"
41027
41700
  },
41028
- "pipelineOrchestrator.listAgentSettings": {
41701
+ "pipelineOrchestrator.getReconcileFromDiskStatus": {
41029
41702
  capName: "pipeline-orchestrator",
41030
41703
  capScope: "system",
41031
41704
  addonId: null,
41032
41705
  access: "view"
41033
41706
  },
41034
- "pipelineOrchestrator.listTemplates": {
41707
+ "pipelineOrchestrator.listAgentSettings": {
41035
41708
  capName: "pipeline-orchestrator",
41036
41709
  capScope: "system",
41037
41710
  addonId: null,
@@ -41043,6 +41716,12 @@ Object.freeze({
41043
41716
  addonId: null,
41044
41717
  access: "create"
41045
41718
  },
41719
+ "pipelineOrchestrator.planAutoTune": {
41720
+ capName: "pipeline-orchestrator",
41721
+ capScope: "system",
41722
+ addonId: null,
41723
+ access: "view"
41724
+ },
41046
41725
  "pipelineOrchestrator.rebalance": {
41047
41726
  capName: "pipeline-orchestrator",
41048
41727
  capScope: "system",
@@ -41085,12 +41764,6 @@ Object.freeze({
41085
41764
  addonId: null,
41086
41765
  access: "create"
41087
41766
  },
41088
- "pipelineOrchestrator.saveTemplate": {
41089
- capName: "pipeline-orchestrator",
41090
- capScope: "system",
41091
- addonId: null,
41092
- access: "create"
41093
- },
41094
41767
  "pipelineOrchestrator.setAgentCapabilities": {
41095
41768
  capName: "pipeline-orchestrator",
41096
41769
  capScope: "system",
@@ -41103,12 +41776,6 @@ Object.freeze({
41103
41776
  addonId: null,
41104
41777
  access: "create"
41105
41778
  },
41106
- "pipelineOrchestrator.setAgentDetectWeight": {
41107
- capName: "pipeline-orchestrator",
41108
- capScope: "system",
41109
- addonId: null,
41110
- access: "create"
41111
- },
41112
41779
  "pipelineOrchestrator.setAgentInferenceDevices": {
41113
41780
  capName: "pipeline-orchestrator",
41114
41781
  capScope: "system",
@@ -41145,6 +41812,12 @@ Object.freeze({
41145
41812
  addonId: null,
41146
41813
  access: "create"
41147
41814
  },
41815
+ "pipelineOrchestrator.setCameraStepSettings": {
41816
+ capName: "pipeline-orchestrator",
41817
+ capScope: "system",
41818
+ addonId: null,
41819
+ access: "create"
41820
+ },
41148
41821
  "pipelineOrchestrator.setCameraStepToggle": {
41149
41822
  capName: "pipeline-orchestrator",
41150
41823
  capScope: "system",
@@ -41163,25 +41836,37 @@ Object.freeze({
41163
41836
  addonId: null,
41164
41837
  access: "create"
41165
41838
  },
41839
+ "pipelineOrchestrator.setLoadBalancingShares": {
41840
+ capName: "pipeline-orchestrator",
41841
+ capScope: "system",
41842
+ addonId: null,
41843
+ access: "create"
41844
+ },
41166
41845
  "pipelineOrchestrator.setPipelineDevicePin": {
41167
41846
  capName: "pipeline-orchestrator",
41168
41847
  capScope: "system",
41169
41848
  addonId: null,
41170
41849
  access: "create"
41171
41850
  },
41172
- "pipelineOrchestrator.unassignAudio": {
41851
+ "pipelineOrchestrator.setShareSource": {
41173
41852
  capName: "pipeline-orchestrator",
41174
41853
  capScope: "system",
41175
41854
  addonId: null,
41176
41855
  access: "create"
41177
41856
  },
41178
- "pipelineOrchestrator.unassignPipeline": {
41857
+ "pipelineOrchestrator.suggestShares": {
41858
+ capName: "pipeline-orchestrator",
41859
+ capScope: "system",
41860
+ addonId: null,
41861
+ access: "view"
41862
+ },
41863
+ "pipelineOrchestrator.unassignAudio": {
41179
41864
  capName: "pipeline-orchestrator",
41180
41865
  capScope: "system",
41181
41866
  addonId: null,
41182
41867
  access: "create"
41183
41868
  },
41184
- "pipelineOrchestrator.updateTemplate": {
41869
+ "pipelineOrchestrator.unassignPipeline": {
41185
41870
  capName: "pipeline-orchestrator",
41186
41871
  capScope: "system",
41187
41872
  addonId: null,
@@ -42621,12 +43306,6 @@ Object.freeze({
42621
43306
  addonId: null,
42622
43307
  access: "view"
42623
43308
  },
42624
- "streamBroker.pullFrameHandles": {
42625
- capName: "stream-broker",
42626
- capScope: "system",
42627
- addonId: null,
42628
- access: "view"
42629
- },
42630
43309
  "streamBroker.regenerateRtspToken": {
42631
43310
  capName: "stream-broker",
42632
43311
  capScope: "system",
@@ -42693,12 +43372,6 @@ Object.freeze({
42693
43372
  addonId: null,
42694
43373
  access: "create"
42695
43374
  },
42696
- "streamBroker.subscribeFrames": {
42697
- capName: "stream-broker",
42698
- capScope: "system",
42699
- addonId: null,
42700
- access: "create"
42701
- },
42702
43375
  "streamBroker.unassignProfile": {
42703
43376
  capName: "stream-broker",
42704
43377
  capScope: "system",
@@ -42711,12 +43384,6 @@ Object.freeze({
42711
43384
  addonId: null,
42712
43385
  access: "create"
42713
43386
  },
42714
- "streamBroker.unsubscribeFrames": {
42715
- capName: "stream-broker",
42716
- capScope: "system",
42717
- addonId: null,
42718
- access: "create"
42719
- },
42720
43387
  "streamCatalog.getCatalog": {
42721
43388
  capName: "stream-catalog",
42722
43389
  capScope: "device",
@@ -43011,18 +43678,36 @@ Object.freeze({
43011
43678
  addonId: null,
43012
43679
  access: "delete"
43013
43680
  },
43681
+ "userManagement.findUserByExternalIdentity": {
43682
+ capName: "user-management",
43683
+ capScope: "system",
43684
+ addonId: null,
43685
+ access: "view"
43686
+ },
43014
43687
  "userManagement.getTotpStatus": {
43015
43688
  capName: "user-management",
43016
43689
  capScope: "system",
43017
43690
  addonId: null,
43018
43691
  access: "view"
43019
43692
  },
43693
+ "userManagement.linkExternalIdentity": {
43694
+ capName: "user-management",
43695
+ capScope: "system",
43696
+ addonId: null,
43697
+ access: "create"
43698
+ },
43020
43699
  "userManagement.listApiKeys": {
43021
43700
  capName: "user-management",
43022
43701
  capScope: "system",
43023
43702
  addonId: null,
43024
43703
  access: "view"
43025
43704
  },
43705
+ "userManagement.listExternalIdentities": {
43706
+ capName: "user-management",
43707
+ capScope: "system",
43708
+ addonId: null,
43709
+ access: "view"
43710
+ },
43026
43711
  "userManagement.listOauthSessions": {
43027
43712
  capName: "user-management",
43028
43713
  capScope: "system",
@@ -43101,6 +43786,12 @@ Object.freeze({
43101
43786
  addonId: null,
43102
43787
  access: "create"
43103
43788
  },
43789
+ "userManagement.unlinkExternalIdentity": {
43790
+ capName: "user-management",
43791
+ capScope: "system",
43792
+ addonId: null,
43793
+ access: "delete"
43794
+ },
43104
43795
  "userManagement.updateUser": {
43105
43796
  capName: "user-management",
43106
43797
  capScope: "system",
@@ -43413,6 +44104,12 @@ Object.freeze({
43413
44104
  addonId: null,
43414
44105
  access: "create"
43415
44106
  },
44107
+ "webrtcSession.applyDownlinkProbe": {
44108
+ capName: "webrtc-session",
44109
+ capScope: "device",
44110
+ addonId: null,
44111
+ access: "create"
44112
+ },
43416
44113
  "webrtcSession.closeSession": {
43417
44114
  capName: "webrtc-session",
43418
44115
  capScope: "device",
@@ -45224,11 +45921,6 @@ Object.freeze({
45224
45921
  form: "single",
45225
45922
  optional: false
45226
45923
  }],
45227
- "decoder.createSession": [{
45228
- name: "deviceId",
45229
- form: "single",
45230
- optional: true
45231
- }],
45232
45924
  "detectionPipeline.applyDeviceSettingsPatch": [{
45233
45925
  name: "deviceId",
45234
45926
  form: "single",
@@ -46439,6 +47131,11 @@ Object.freeze({
46439
47131
  form: "single",
46440
47132
  optional: false
46441
47133
  }],
47134
+ "pipelineAnalytics.setRetrainFrameComplete": [{
47135
+ name: "deviceId",
47136
+ form: "single",
47137
+ optional: false
47138
+ }],
46442
47139
  "pipelineAnalytics.setTrackFlags": [{
46443
47140
  name: "deviceId",
46444
47141
  form: "single",
@@ -46459,6 +47156,11 @@ Object.freeze({
46459
47156
  form: "single",
46460
47157
  optional: false
46461
47158
  }],
47159
+ "pipelineExecutor.clearModelBoundDeviceOverrides": [{
47160
+ name: "deviceIds",
47161
+ form: "array",
47162
+ optional: true
47163
+ }],
46462
47164
  "pipelineExecutor.runPipeline": [{
46463
47165
  name: "deviceId",
46464
47166
  form: "single",
@@ -46564,6 +47266,11 @@ Object.freeze({
46564
47266
  form: "single",
46565
47267
  optional: false
46566
47268
  }],
47269
+ "pipelineOrchestrator.setCameraStepSettings": [{
47270
+ name: "deviceId",
47271
+ form: "single",
47272
+ optional: false
47273
+ }],
46567
47274
  "pipelineOrchestrator.setCameraStepToggle": [{
46568
47275
  name: "deviceId",
46569
47276
  form: "single",
@@ -47335,6 +48042,11 @@ Object.freeze({
47335
48042
  form: "single",
47336
48043
  optional: false
47337
48044
  }],
48045
+ "webrtcSession.applyDownlinkProbe": [{
48046
+ name: "deviceId",
48047
+ form: "single",
48048
+ optional: false
48049
+ }],
47338
48050
  "webrtcSession.closeSession": [{
47339
48051
  name: "deviceId",
47340
48052
  form: "single",
@@ -47564,6 +48276,8 @@ new Map(Object.entries({
47564
48276
  "detection-blind": "device-events",
47565
48277
  "node-online": "system",
47566
48278
  "node-offline": "system",
48279
+ "node-restarting": "system",
48280
+ "node-updating": "system",
47567
48281
  "node-inference-unavailable": "system",
47568
48282
  "addon-crash-loop": "system",
47569
48283
  "addon-update-available": "system",
@@ -47641,18 +48355,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47641
48355
  kinds: [
47642
48356
  "node-offline",
47643
48357
  "node-online",
48358
+ "node-restarting",
47644
48359
  "node-inference-unavailable"
47645
48360
  ]
47646
48361
  },
47647
48362
  {
47648
48363
  id: "addons",
47649
48364
  family: "system",
47650
- label: "Addons",
47651
- kinds: [
47652
- "addon-crash-loop",
47653
- "addon-update-available",
47654
- "addon-updated"
47655
- ]
48365
+ label: "Addons stopped",
48366
+ kinds: ["addon-crash-loop"]
48367
+ },
48368
+ {
48369
+ id: "addon-updates",
48370
+ family: "system",
48371
+ label: "Addon updates",
48372
+ kinds: ["addon-update-available", "addon-updated"]
47656
48373
  },
47657
48374
  {
47658
48375
  id: "updates",
@@ -47660,6 +48377,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47660
48377
  label: "Server & container updates",
47661
48378
  kinds: [
47662
48379
  "server-update-available",
48380
+ "node-updating",
47663
48381
  "server-updated",
47664
48382
  "wrapper-update-available"
47665
48383
  ]
@@ -47807,18 +48525,21 @@ var STATE_SUMMARY_SECTION_VARS = [
47807
48525
  kinds: [
47808
48526
  "node-offline",
47809
48527
  "node-online",
48528
+ "node-restarting",
47810
48529
  "node-inference-unavailable"
47811
48530
  ]
47812
48531
  },
47813
48532
  {
47814
48533
  name: "summaryAddons",
47815
- label: "Summary: addons",
47816
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
47817
- kinds: [
47818
- "addon-crash-loop",
47819
- "addon-update-available",
47820
- "addon-updated"
47821
- ]
48534
+ label: "Summary: addons stopped",
48535
+ example: "hub — recorder stopped after repeated crashes",
48536
+ kinds: ["addon-crash-loop"]
48537
+ },
48538
+ {
48539
+ name: "summaryAddonUpdates",
48540
+ label: "Summary: addon updates",
48541
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
48542
+ kinds: ["addon-update-available", "addon-updated"]
47822
48543
  },
47823
48544
  {
47824
48545
  name: "summaryUpdates",
@@ -47826,6 +48547,7 @@ var STATE_SUMMARY_SECTION_VARS = [
47826
48547
  example: "server 1.2.377 → 1.2.378",
47827
48548
  kinds: [
47828
48549
  "server-update-available",
48550
+ "node-updating",
47829
48551
  "server-updated",
47830
48552
  "wrapper-update-available"
47831
48553
  ]
@@ -47858,7 +48580,7 @@ var STATE_SUMMARY_VARS = [
47858
48580
  {
47859
48581
  name: "summarySection",
47860
48582
  label: "Summary: this section",
47861
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
48583
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
47862
48584
  example: "Batterie scariche",
47863
48585
  group: "system",
47864
48586
  families: ["rule"],
@@ -47902,6 +48624,7 @@ var STATE_SUMMARY_VARS = [
47902
48624
  [...RULE_BODY_ONLY],
47903
48625
  [...RULE_TEXT],
47904
48626
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
48627
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
47905
48628
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
47906
48629
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
47907
48630
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -47942,6 +48665,8 @@ var STATE_SUMMARY_VARS = [
47942
48665
  [...RULE_TEXT],
47943
48666
  [...RULE_TEXT],
47944
48667
  [...RULE_TEXT],
48668
+ [...RULE_TEXT],
48669
+ [...RULE_TEXT],
47945
48670
  ...STATE_SUMMARY_VARS
47946
48671
  ];
47947
48672
  new Set([
@@ -48462,33 +49187,36 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
48462
49187
  var MB = 1024 * 1024;
48463
49188
  1024 * MB, 3072 * MB;
48464
49189
  //#endregion
48465
- Object.defineProperty(exports, "BOOT_RECOVERY_BACKOFF_MS", {
48466
- enumerable: true,
48467
- get: function() {
48468
- return BOOT_RECOVERY_BACKOFF_MS;
48469
- }
48470
- });
48471
- Object.defineProperty(exports, "BaseAddon", {
48472
- enumerable: true,
48473
- get: function() {
48474
- return BaseAddon;
48475
- }
48476
- });
48477
- Object.defineProperty(exports, "EventCategory", {
48478
- enumerable: true,
48479
- get: function() {
48480
- return EventCategory;
48481
- }
48482
- });
48483
- Object.defineProperty(exports, "meshNetworkCapability", {
48484
- enumerable: true,
48485
- get: function() {
48486
- return meshNetworkCapability;
48487
- }
48488
- });
48489
- Object.defineProperty(exports, "networkAccessCapability", {
48490
- enumerable: true,
48491
- get: function() {
48492
- return networkAccessCapability;
49190
+ //#region src/auth-key-file.ts
49191
+ /**
49192
+ * Hand the Tailscale auth key to `tailscale up` without putting it on argv
49193
+ * or in the environment (D783).
49194
+ *
49195
+ * The CLI accepts `--auth-key=file:<path>` and reads the key from that file.
49196
+ * The key is written owner-only (0600) into a fresh owner-only (0700) temp
49197
+ * dir, the flag is handed to `run`, and the dir is removed when `run`
49198
+ * settles — success or failure. Error text is passed through
49199
+ * {@link scrubSecret} so a `Command failed: …` message can never carry it.
49200
+ */
49201
+ var REDACTED = "‹redacted›";
49202
+ async function withAuthKeyFile(authKey, run) {
49203
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "camstack-ts-"));
49204
+ try {
49205
+ await fs.chmod(dir, 448);
49206
+ const file = path.join(dir, "authkey");
49207
+ await fs.writeFile(file, authKey, { mode: 384 });
49208
+ return await run(`--auth-key=file:${file}`);
49209
+ } finally {
49210
+ await fs.rm(dir, {
49211
+ recursive: true,
49212
+ force: true
49213
+ });
48493
49214
  }
48494
- });
49215
+ }
49216
+ /** Replace every occurrence of `secret` in `text`. Empty secrets are a no-op. */
49217
+ function scrubSecret(text, secret) {
49218
+ if (!secret) return text;
49219
+ return text.split(secret).join(REDACTED);
49220
+ }
49221
+ //#endregion
49222
+ export { BOOT_RECOVERY_BACKOFF_MS as a, networkAccessCapability as i, withAuthKeyFile as n, BaseAddon as o, meshNetworkCapability as r, EventCategory as s, scrubSecret as t };