@camstack/addon-pipeline 1.2.272 → 1.2.273

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-kQnvoRyv.js → default-detection-model-9Solpn0K.js} +1 -1
  4. package/dist/{default-detection-model-DqrqHCuw.mjs → default-detection-model-DCFaNnYd.mjs} +1 -1
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-DBHsAlUE.mjs → dist-BRT-qKlE.mjs} +254 -7
  8. package/dist/{dist-DygcLvgG.js → dist-DRDzfOnl.js} +254 -7
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-CACCuE7t.js → node-BmTPPuIg.js} +1 -1
  12. package/dist/{node-j_3VvNQJ.mjs → node-Dwu66ZR4.mjs} +1 -1
  13. package/dist/pipeline-runner/index.js +3 -3
  14. package/dist/pipeline-runner/index.mjs +3 -3
  15. package/dist/{process-memory-fse8NnRi.js → process-memory-BTwHfysZ.js} +1 -1
  16. package/dist/{process-memory-DcoIQGG5.mjs → process-memory-Cx4oDFz9.mjs} +1 -1
  17. package/dist/recorder/index.js +4 -3
  18. package/dist/recorder/index.mjs +4 -3
  19. package/dist/{segment-demux-js-Ce24Y2G0.js → segment-demux-js--ePyI476.js} +1 -1
  20. package/dist/{segment-demux-js-DSgNEMf6.mjs → segment-demux-js-BKvYCad_.mjs} +1 -1
  21. package/dist/stream-broker/_stub.js +2 -2
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BSZUBMBY.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-shbmpL8E.mjs} +2 -2
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C_SEu7AC.mjs +26 -0
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C8RTK6nJ.mjs +26 -0
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-lVR0hopj.mjs → hostInit-CtVYKCNe.mjs} +2 -2
  28. package/dist/stream-broker/index.js +3 -3
  29. package/dist/stream-broker/index.mjs +3 -3
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-_bHa4uUp.mjs +0 -26
  33. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CeR_IxxU.mjs +0 -26
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-DygcLvgG.js");
7
- const require_process_memory = require("../process-memory-fse8NnRi.js");
6
+ const require_dist = require("../dist-DRDzfOnl.js");
7
+ const require_process_memory = require("../process-memory-BTwHfysZ.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_chunk.__toESM(node_fs);
10
10
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as hydrateSchema, Jt as audioChunkBytesPerSample, Lt as errMsg, N as audioAnalysisCapability, Ot as resolvePoolMemoryPolicy, P as audioAnalyzerCapability, Qt as expandAudioChunkToF32le, Wt as BaseAddon, bn as EventCategory, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, rn as nodePin, s as DEFAULT_AUDIO_ANALYZER_CONFIG, w as PoolMemoryWatchdog, y as HF_BASE_URL } from "../dist-DBHsAlUE.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DcoIQGG5.mjs";
2
+ import { $t as hydrateSchema, Jt as audioChunkBytesPerSample, Lt as errMsg, N as audioAnalysisCapability, Ot as resolvePoolMemoryPolicy, P as audioAnalyzerCapability, Qt as expandAudioChunkToF32le, Wt as BaseAddon, bn as EventCategory, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, rn as nodePin, s as DEFAULT_AUDIO_ANALYZER_CONFIG, w as PoolMemoryWatchdog, y as HF_BASE_URL } from "../dist-BRT-qKlE.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Cx4oDFz9.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
6
6
  import { downloadFile } from "@camstack/system/addon-utils";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-DygcLvgG.js");
1
+ const require_dist = require("./dist-DRDzfOnl.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-DBHsAlUE.mjs";
1
+ import { F as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-BRT-qKlE.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-DygcLvgG.js");
7
- const require_node = require("../node-CACCuE7t.js");
8
- const require_default_detection_model = require("../default-detection-model-kQnvoRyv.js");
6
+ const require_dist = require("../dist-DRDzfOnl.js");
7
+ const require_node = require("../node-BmTPPuIg.js");
8
+ const require_default_detection_model = require("../default-detection-model-9Solpn0K.js");
9
9
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
10
- const require_process_memory = require("../process-memory-fse8NnRi.js");
10
+ const require_process_memory = require("../process-memory-BTwHfysZ.js");
11
11
  let node_os = require("node:os");
12
12
  node_os = require_chunk.__toESM(node_os);
13
13
  let node_fs = require("node:fs");
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as hydrateSchema, At as runtimeDevices$1, Ft as supportedRuntimes$1, G as detectionPipelineCapability, J as enumerateInferenceDevices, Lt as errMsg, Ot as resolvePoolMemoryPolicy, Tt as resolveClusterStepModelId, V as defaultDeviceFor$1, Wt as BaseAddon, X as evaluateZoneRules, Yt as createEvent, bn as EventCategory, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as object, ht as pickClusterStepModels, in as parseJsonUnknown, it as loadContributionCapability, j as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, ln as array, m as DEVICE_BACKEND_TO_FORMAT, nt as inferModelProvider, pt as overlayClusterStepSettings, rn as nodePin, sn as sleep, t as APPLE_SA_TO_MACRO, vn as string, w as PoolMemoryWatchdog, yn as union, yt as pipelineExecutorCapability } from "../dist-DBHsAlUE.mjs";
3
- import { s as readProcessCost } from "../node-j_3VvNQJ.mjs";
4
- import { a as localFrameRegistry, c as ALL_STEPS, d as getStepDefinition, f as resolveModelForFormat, l as getDefaultModelForFormat, n as resolveDefaultDetectionModel, p as landmarkPrecisionVerdict, r as macroGateVerdict, s as ALL_PIPELINE_STEPS, u as getStep } from "../default-detection-model-DqrqHCuw.mjs";
2
+ import { $t as hydrateSchema, At as runtimeDevices$1, Ft as supportedRuntimes$1, G as detectionPipelineCapability, J as enumerateInferenceDevices, Lt as errMsg, Ot as resolvePoolMemoryPolicy, Tt as resolveClusterStepModelId, V as defaultDeviceFor$1, Wt as BaseAddon, X as evaluateZoneRules, Yt as createEvent, bn as EventCategory, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as object, ht as pickClusterStepModels, in as parseJsonUnknown, it as loadContributionCapability, j as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, ln as array, m as DEVICE_BACKEND_TO_FORMAT, nt as inferModelProvider, pt as overlayClusterStepSettings, rn as nodePin, sn as sleep, t as APPLE_SA_TO_MACRO, vn as string, w as PoolMemoryWatchdog, yn as union, yt as pipelineExecutorCapability } from "../dist-BRT-qKlE.mjs";
3
+ import { s as readProcessCost } from "../node-Dwu66ZR4.mjs";
4
+ import { a as localFrameRegistry, c as ALL_STEPS, d as getStepDefinition, f as resolveModelForFormat, l as getDefaultModelForFormat, n as resolveDefaultDetectionModel, p as landmarkPrecisionVerdict, r as macroGateVerdict, s as ALL_PIPELINE_STEPS, u as getStep } from "../default-detection-model-DCFaNnYd.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DcoIQGG5.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Cx4oDFz9.mjs";
7
7
  import * as os from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -5360,7 +5360,7 @@ var ZodIssueCode = {
5360
5360
  var ZodFirstPartyTypeKind;
5361
5361
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5362
5362
  //#endregion
5363
- //#region ../types/dist/sleep-CiR4z7r9.mjs
5363
+ //#region ../types/dist/sleep-CopaBJss.mjs
5364
5364
  /**
5365
5365
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5366
5366
  * window to float samples (D455).
@@ -5592,6 +5592,12 @@ Object.fromEntries([
5592
5592
  icon: "circle-dot",
5593
5593
  order: 40
5594
5594
  },
5595
+ {
5596
+ id: "clips",
5597
+ label: "Clips",
5598
+ icon: "clapperboard",
5599
+ order: 41
5600
+ },
5595
5601
  {
5596
5602
  id: "engine",
5597
5603
  label: "Inference Engine",
@@ -16436,6 +16442,8 @@ method(object({
16436
16442
  deviceId: number(),
16437
16443
  capName: string(),
16438
16444
  wrapperAddonId: string(),
16445
+ /** The `ClipSource.source` id to toggle. Absent = all of the addon's. */
16446
+ sourceId: string().optional(),
16439
16447
  active: boolean()
16440
16448
  }), _void(), {
16441
16449
  kind: "mutation",
@@ -27229,29 +27237,257 @@ var ClipSchema = object({
27229
27237
  holes: array(object({
27230
27238
  startMs: number(),
27231
27239
  endMs: number()
27232
- })).optional()
27240
+ })).optional(),
27241
+ /**
27242
+ * A URL that MAY produce this clip's still, asked only for rows actually on
27243
+ * screen. The opposite of {@link ClipSchema.thumbnail}: that one is VOUCHED
27244
+ * (a JPEG is already on disk), this one is an offer. The route answers 200
27245
+ * with the image, or 204 with `x-camstack-reason` when it could not mint one
27246
+ * — a surface latches that refusal to the instant rather than retrying.
27247
+ *
27248
+ * Never both: a clip with a vouched `thumbnail` needs no mint.
27249
+ */
27250
+ thumbnailMint: string().optional(),
27251
+ /**
27252
+ * Why no still will be produced for this clip RIGHT NOW — set when the
27253
+ * provider already knows, so the surface draws the glyph and the reason
27254
+ * instead of firing a mint that cannot succeed.
27255
+ *
27256
+ * `sleeping` — a standalone battery camera; a read would be a wake (D549 4).
27257
+ * `camera-refused` — the camera answered the CoverPreview with a refusal.
27258
+ * `no-keyframe` — the window holds no decodable I-frame (an event that sits
27259
+ * inside no file is the measured case).
27260
+ * `unsupported` — this source cannot mint stills at all.
27261
+ */
27262
+ thumbnailUnavailable: object({ reason: _enum([
27263
+ "sleeping",
27264
+ "camera-refused",
27265
+ "no-keyframe",
27266
+ "unsupported"
27267
+ ]) }).optional(),
27268
+ /**
27269
+ * When the catalog this row came from was last CONFIRMED against the device.
27270
+ * Absent means "this row was read live". A persisted catalog served while a
27271
+ * camera sleeps carries the age it really has — a cached list is never drawn
27272
+ * as current (D549 13).
27273
+ */
27274
+ catalogAsOf: number().optional(),
27275
+ /**
27276
+ * The camera's OWN type strings for this clip, all of them, unmapped
27277
+ * (`md`, `people`, `dog_cat`, `sched`, …). Kept beside {@link labels}
27278
+ * because a firmware inventing a type must not vanish: the mapping into our
27279
+ * filter vocabulary is lossy on purpose and this is the lossless copy
27280
+ * (D549 20).
27281
+ */
27282
+ nativeTypes: array(string()).optional(),
27283
+ /**
27284
+ * What the subject DID — `crossline`, `intrude`, `loitering`. A behaviour
27285
+ * travels BESIDE a class, never instead of one, and the class filter ignores
27286
+ * it: "a person crossed a line" is still a person (D549 20).
27287
+ */
27288
+ behaviours: array(string()).optional(),
27289
+ /**
27290
+ * The same recording as two files — the sub twin (what the row and its
27291
+ * thumbnail are) and its main twin, matched at listing time so a quality
27292
+ * change never re-searches the camera (D549 15). `getClipPlayback`'s
27293
+ * `profile` picks between them: `low | mid` → sub, `high` → main.
27294
+ */
27295
+ streams: object({
27296
+ sub: object({
27297
+ id: string(),
27298
+ bytes: number().optional()
27299
+ }).optional(),
27300
+ main: object({
27301
+ id: string(),
27302
+ bytes: number().optional()
27303
+ }).optional()
27304
+ }).optional(),
27305
+ /** The camera says it holds a sub-stream copy of this recording. */
27306
+ supportSub: boolean().optional(),
27307
+ /**
27308
+ * Whether this row has bytes behind it. ABSENT means yes — every clip that
27309
+ * IS a file is playable, and only a source that lists EVENTS can produce a
27310
+ * row with nothing to play (the measured case: 1 of 29 hub events on 3628
27311
+ * fell inside no file). Such a row is shown, never dropped and never offered
27312
+ * as playable-then-failing (D549 19).
27313
+ */
27314
+ playable: boolean().optional(),
27315
+ /** Why {@link playable} is false, verbatim (`no-file-for-window`). */
27316
+ unplayableReason: string().optional()
27233
27317
  });
27234
27318
  var ClipPlaybackSchema = object({
27235
- /** HLS master URL through the hub data-plane (Range + token in path). */
27319
+ /**
27320
+ * A media URL through the hub data-plane. {@link ClipPlaybackSchema.format}
27321
+ * says what kind — an HLS master playlist for a recording-derived clip, a
27322
+ * progressive MP4 for a native file the vendor addon muxed and serves with
27323
+ * `Range`. The URL is NOT a credential: both planes are registered
27324
+ * `access: 'authenticated'` and the hub's `/addon/<id>/<prefix>` proxy takes
27325
+ * the session cookie, so nothing is appended to it (D549 22).
27326
+ */
27236
27327
  playbackUrl: string(),
27328
+ /**
27329
+ * How to play {@link playbackUrl}. Absent means `hls` — the shape every
27330
+ * existing consumer already assumes. A player that branches on this is the
27331
+ * one change a native clip needs; a player that ignores it will hand an MP4
27332
+ * to hls.js and fail parsing it as a manifest.
27333
+ */
27334
+ format: _enum(["hls", "mp4"]).optional(),
27335
+ /**
27336
+ * Which twin was actually served. A clip that holds only one stream answers
27337
+ * with the one it has, and the surface SAYS so — a missing main twin is
27338
+ * never served silently as if it were the asked-for quality (D549 15).
27339
+ */
27340
+ served: CamProfileSchema.optional(),
27237
27341
  /** Optional LAN/remote alternates for the same clip. */
27238
27342
  playbackEndpoints: array(string()).optional(),
27239
27343
  token: string().optional()
27240
27344
  });
27345
+ /**
27346
+ * Why a source cannot answer right now — per SOURCE, never fleet-wide.
27347
+ *
27348
+ * `ok` is the only state whose clip list may be read as complete. The other
27349
+ * three exist because an empty list from a sleeping camera reads as "this
27350
+ * camera has no recordings", which is the defect this whole line of work is
27351
+ * about: a battery camera nobody woke (`sleeping`), a camera that could not be
27352
+ * reached at all (`unreachable`, also what a provider that THREW reports), a
27353
+ * camera whose SD card is not mounted (`no-storage`, measured on 640 —
27354
+ * `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
27355
+ * camera whose OWN index disagrees with its OWN calendar (`index-empty`,
27356
+ * measured on 618: the calendar marks 3–20 September, days 6–20 list zero
27357
+ * files on both streams and both filters, with 177 GB free). That last one is
27358
+ * a defect ON THE CAMERA, and the only honest thing a provider can do is say
27359
+ * which days it asked for and got nothing — "no clips" would be a lie about a
27360
+ * card that is full of them.
27361
+ */
27362
+ var ClipSourceAvailabilitySchema = object({
27363
+ state: _enum([
27364
+ "ok",
27365
+ "sleeping",
27366
+ "unreachable",
27367
+ "no-storage",
27368
+ "index-empty"
27369
+ ]),
27370
+ /** Free text, shown verbatim. Names the camera's own refusal when there is one. */
27371
+ reason: string().optional(),
27372
+ /** When this source's catalog was last CONFIRMED. A cached list is never
27373
+ * drawn as current: the surface shows the age whenever it is older than the
27374
+ * refresh interval. */
27375
+ catalogAsOf: number().optional()
27376
+ });
27377
+ /**
27378
+ * One SOURCE of clips for a camera — a row of the picker, and the namespace
27379
+ * every clip id from it is prefixed with (`analytics`,
27380
+ * `native:reolink:onboard`, `hksv`, …).
27381
+ *
27382
+ * A provider lists the sources IT serves for that device, and answers for each
27383
+ * of them whether it can answer at all. A provider with nothing to offer on a
27384
+ * camera returns `[]` — it is not that camera's business.
27385
+ */
27386
+ var ClipSourceSchema = object({
27387
+ /** The value this source stamps on {@link ClipSchema.source}, and the prefix
27388
+ * of every clip id it mints. `getClipPlayback` routes on it. */
27389
+ source: string(),
27390
+ /** Operator-facing name of the source ("CamStack recordings", "SD card"). */
27391
+ label: string(),
27392
+ /**
27393
+ * The addon that SERVES this row.
27394
+ *
27395
+ * A surface cannot otherwise resolve a source to who answers it, and the
27396
+ * alternative — a `native:reolink:* → provider-reolink` table inside the
27397
+ * widget — is a second authority on provider identity living in the one
27398
+ * package with no business knowing it, wrong the day a third source appears
27399
+ * (D557). One addon may serve SEVERAL sources: `addon-provider-reolink`
27400
+ * answers a hub child with both `native:reolink:onboard` and
27401
+ * `native:reolink:hub`, which is why the per-device switch is keyed by
27402
+ * SOURCE and not by this (D555).
27403
+ *
27404
+ * Optional for version skew only. The collection dispatcher stamps it from
27405
+ * the registry, so a row that travelled through the fan-out carries the
27406
+ * authoritative id whatever the provider filled in.
27407
+ */
27408
+ addonId: string().optional(),
27409
+ /**
27410
+ * Which API this source resolved to FOR THIS CAMERA, when it has a choice.
27411
+ *
27412
+ * A source may cover one store through more than one surface — the Reolink
27413
+ * provider reads a hub child through the parent's event log and a standalone
27414
+ * through its own file list, because that is what each camera answers. The
27415
+ * CHOICE is the provider's, made from what the camera is, and is never a row
27416
+ * the operator has to understand; but it is REPORTED, because a source that
27417
+ * silently reads a different API on two cameras and then behaves differently
27418
+ * is the thing nobody can debug later. Absent when the source has only one
27419
+ * way to read its store.
27420
+ */
27421
+ via: string().optional(),
27422
+ availability: ClipSourceAvailabilitySchema,
27423
+ /**
27424
+ * The operator switched this source OFF for this camera.
27425
+ *
27426
+ * Deliberately NOT a member of {@link ClipSourceAvailabilitySchema}'s
27427
+ * vocabulary. That enum models what the source CAN do — a sleeping camera, an
27428
+ * unmounted card, an index that disagrees with its own calendar — and a
27429
+ * switched-off source could answer perfectly well; the operator decided it
27430
+ * should not. Folding the choice in is how `disabled` and `broken` stop being
27431
+ * distinguishable, which is the D62 rule this repo has already paid for twice:
27432
+ * an off switch is REPORTED off (`CameraStatus.switchedOff`, the same word),
27433
+ * and disabled must never look like broken. It is also what lets every
27434
+ * exhaustive consumer of the availability enum keep compiling.
27435
+ *
27436
+ * A switched-off source contributes NO clips (`listClips` never calls it) and
27437
+ * its row carries no `catalogAsOf`: nothing confirms a catalog it is not
27438
+ * allowed to serve, and a frozen age that can only grow draws a stalling
27439
+ * source rather than an off switch.
27440
+ *
27441
+ * The row survives BECAUSE it is the control the operator switches the source
27442
+ * back on from — D554 decision 4's rule ("a source that cannot answer
27443
+ * produces a ROW, not an absence") applied to the one case D556 carved out of
27444
+ * it, and D557's own kept property ("a source is never hidden, only its
27445
+ * rows"). Absent means on.
27446
+ *
27447
+ * A provider never sets this — like {@link ClipSourceSchema.addonId} it is
27448
+ * stamped by the collection dispatcher, which holds the registry's projection
27449
+ * of the persisted authority (D556) and is the only place that knows it.
27450
+ */
27451
+ switchedOff: boolean().optional()
27452
+ });
27241
27453
  DeviceType.Camera, method(object({
27242
27454
  deviceId: number(),
27243
27455
  since: number(),
27244
27456
  until: number(),
27245
- limit: number().int().positive().optional()
27457
+ limit: number().int().positive().optional(),
27458
+ /**
27459
+ * View filter over {@link ClipSourceSchema.source} values — the
27460
+ * picker's selection, forwarded so a provider need not list what
27461
+ * nobody is looking at. ABSENT means every source this camera has,
27462
+ * which is the honest default for a surface whose whole point is that
27463
+ * nothing is hidden (D554 3). A provider with one source ignores it.
27464
+ */
27465
+ sources: array(string()).optional()
27246
27466
  }), array(ClipSchema).readonly(), {
27247
27467
  kind: "query",
27248
- auth: "admin"
27468
+ auth: "protected"
27469
+ }), method(object({ deviceId: number() }), array(ClipSourceSchema).readonly(), {
27470
+ kind: "query",
27471
+ auth: "protected"
27249
27472
  }), method(object({
27250
27473
  deviceId: number(),
27251
- clipId: string()
27474
+ clipId: string(),
27475
+ /**
27476
+ * Which twin to serve, on the ONE quality scale the system already has
27477
+ * (`CamProfileSchema`). `low | mid` → the sub file, `high` → the main
27478
+ * twin; both ids are already on the row so this never re-searches the
27479
+ * camera. Absent means the provider's own default (the sub file, which
27480
+ * every source is measured to hold).
27481
+ *
27482
+ * `auto` is deliberately NOT accepted here: a stored file has no
27483
+ * broker session, so the adaptive tier cannot be resolved for it. The
27484
+ * viewer resolves `auto` to a profile the same way live does, before
27485
+ * it calls (D549 15).
27486
+ */
27487
+ profile: CamProfileSchema.optional()
27252
27488
  }), ClipPlaybackSchema, {
27253
27489
  kind: "query",
27254
- auth: "admin"
27490
+ auth: "protected"
27255
27491
  });
27256
27492
  /**
27257
27493
  * Optional client-side hints sent at session creation to help the provider
@@ -41825,6 +42061,12 @@ Object.freeze({
41825
42061
  addonId: null,
41826
42062
  access: "view"
41827
42063
  },
42064
+ "videoclips.listSources": {
42065
+ capName: "videoclips",
42066
+ capScope: "device",
42067
+ addonId: null,
42068
+ access: "view"
42069
+ },
41828
42070
  "viewerUi.getStaticDir": {
41829
42071
  capName: "viewer-ui",
41830
42072
  capScope: "system",
@@ -43833,6 +44075,11 @@ Object.freeze({
43833
44075
  form: "single",
43834
44076
  optional: false
43835
44077
  }],
44078
+ "videoclips.listSources": [{
44079
+ name: "deviceId",
44080
+ form: "single",
44081
+ optional: false
44082
+ }],
43836
44083
  "waterHeater.setAway": [{
43837
44084
  name: "deviceId",
43838
44085
  form: "single",