@camstack/types 1.2.245 → 1.2.246

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.
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-Da9UCU5_.js");
2
+ const require_sleep = require("./sleep-DWUJM120.js");
3
3
  const require_event_category = require("./event-category-BVfsrBYA.js");
4
4
  const require_err_msg = require("./err-msg-COpsHMw2.js");
5
5
  //#region src/generated/cap-input-defaults.ts
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as DeviceType, Dt as DisposerChain, G as readNodePin, J as ReadinessTimeoutError, L as expandCapMethods, Mt as emitReadiness, Ot as BaseAddon, S as DEVICE_CHILDREN_BATCH_MAX, T as describeCustomActions, Tt as DATAPLANE_SECRET_HEADER, W as nodePin, Z as scopeKey, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, j as adminUiCapability, kt as normalizeAddonInitResult, m as createDeviceProxy, p as isDeviceScopedCap, q as ReadinessRegistry, s as asString, t as sleep, u as parseJsonUnknown, x as viewerUiCapability } from "./sleep-i3eUVc-d.mjs";
1
+ import { A as DeviceType, Dt as DisposerChain, G as readNodePin, J as ReadinessTimeoutError, L as expandCapMethods, Mt as emitReadiness, Ot as BaseAddon, S as DEVICE_CHILDREN_BATCH_MAX, T as describeCustomActions, Tt as DATAPLANE_SECRET_HEADER, W as nodePin, Z as scopeKey, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, j as adminUiCapability, kt as normalizeAddonInitResult, m as createDeviceProxy, p as isDeviceScopedCap, q as ReadinessRegistry, s as asString, t as sleep, u as parseJsonUnknown, x as viewerUiCapability } from "./sleep-COWaSCAi.mjs";
2
2
  import { t as EventCategory } from "./event-category-BVDXG4tB.mjs";
3
3
  import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
4
4
  //#region src/generated/cap-input-defaults.ts
@@ -118,8 +118,8 @@ export type { IUserPasskeysProvider, PasskeySummary } from './user-passkeys.cap.
118
118
  export { PasskeySummarySchema, userPasskeysCapability } from './user-passkeys.cap.js';
119
119
  export type { IVectorStoreProvider } from './vector-store.cap.js';
120
120
  export { VectorDeclareIndexInputSchema, VectorDeleteByFilterInputSchema, VectorDeleteInputSchema, VectorDeleteResultSchema, type VectorFilter, VectorFilterSchema, VectorGetInputSchema, VectorGetResultSchema, type VectorItem, VectorItemSchema, type VectorMatch, VectorMatchSchema, type VectorMetadata, VectorMetadataSchema, type VectorMetric, VectorMetricSchema, VectorQueryInputSchema, VectorQueryResultSchema, VectorStatsInputSchema, VectorStatsResultSchema, VectorUpsertInputSchema, VectorUpsertResultSchema, vectorStoreCapability, } from './vector-store.cap.js';
121
- export type { Clip, ClipBytes, ClipPlayback, ClipSource, ClipSourceAvailability, ClipStillDisposition, ClipStillRefusalCode, ClipStreamAudio, ClipStreamAudioReason, ClipStreamDial, ClipWake, IVideoclipsProvider, } from './videoclips.cap.js';
122
- export { CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_REASON_HEADER_MAX, CLIP_STILL_REASON_HEADER, CLIP_STREAM_TRANSPORT_HEADER, ClipBytesSchema, ClipPlaybackSchema, ClipSchema, ClipSourceAvailabilitySchema, ClipSourceSchema, ClipStillDispositionSchema, ClipStillRefusalCodeSchema, ClipStreamAudioReasonSchema, ClipStreamAudioSchema, ClipStreamDialSchema, ClipWakeSchema, MAX_CLIP_EVENT_IDS, MAX_CLIP_LABELS, VIDEOCLIPS_MAX_READ_BYTES, clipReasonHeaderValue, videoclipsCapability, } from './videoclips.cap.js';
121
+ export type { Clip, ClipBytes, ClipBytesOffer, ClipPlayback, ClipSource, ClipSourceAvailability, ClipStillDisposition, ClipStillRefusalCode, ClipStreamAudio, ClipStreamAudioReason, ClipPlaybackOptions, ClipStreamDial, ClipWake, IVideoclipsProvider, } from './videoclips.cap.js';
122
+ export { CLIP_BROKER_PACED_RATES, CLIP_REALTIME_SOURCE_RATES, CLIP_PLAYBACK_OPTIONS, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_REASON_HEADER_MAX, CLIP_STILL_REASON_HEADER, CLIP_STREAM_TRANSPORT_HEADER, ClipBytesOfferSchema, ClipBytesSchema, ClipPlaybackOptionsSchema, ClipPlaybackSchema, ClipSchema, ClipSourceAvailabilitySchema, ClipSourceSchema, ClipStillDispositionSchema, ClipStillRefusalCodeSchema, ClipStreamAudioReasonSchema, ClipStreamAudioSchema, ClipStreamDialSchema, ClipWakeSchema, MAX_CLIP_EVENT_IDS, MAX_CLIP_LABELS, VIDEOCLIPS_MAX_OFFER_BYTES, VIDEOCLIPS_MAX_READ_BYTES, clipReasonHeaderValue, videoclipsCapability, } from './videoclips.cap.js';
123
123
  export type { IViewerUiProvider } from './viewer-ui.cap.js';
124
124
  export { viewerUiCapability } from './viewer-ui.cap.js';
125
125
  export { type IWebrtcSessionProvider, type WebrtcClientHints, type WebrtcLadderDecision, WebrtcLadderDecisionSchema, type WebrtcSessionDebug, WebrtcSessionDebugSchema, type WebrtcStreamChoice, WebrtcStreamChoiceSchema, type WebrtcStreamTarget, WebrtcStreamTargetSchema, type WebrtcTierFailure, WebrtcTierFailureSchema, webrtcClientHintsSchema, webrtcSessionCapability, } from './webrtc-session.cap.js';
@@ -67,6 +67,7 @@ export declare const ClipStillRefusalCodeSchema: z.ZodEnum<{
67
67
  "no-keyframe": "no-keyframe";
68
68
  "queue-full": "queue-full";
69
69
  "camera-backoff": "camera-backoff";
70
+ "decode-failed": "decode-failed";
70
71
  "no-catalog-row": "no-catalog-row";
71
72
  "unknown-device": "unknown-device";
72
73
  "uid-missing": "uid-missing";
@@ -249,11 +250,36 @@ export type ClipWake = z.infer<typeof ClipWakeSchema>;
249
250
  * the size in the message, never truncates. Half a video is worse than an
250
251
  * honest refusal.
251
252
  *
252
- * The clean follow-on is a CHUNKED read so a `high` twin of a long clip stops
253
- * being refusable at all. That is a later slice, named here so the bound is
254
- * not mistaken for a design ceiling.
253
+ * **Superseded as the way a clip export gets its bytes** (D613). The bound is
254
+ * a property of the ENVELOPE, not of clips, so the cure was a transport with
255
+ * no envelope: {@link videoclipsCapability.methods.offerClipBytes} hands back
256
+ * a one-shot `peerBytes` ticket and the consumer streams it straight to disk,
257
+ * holding nothing. This method stays for a consumer that genuinely wants the
258
+ * bytes in hand, and for a provider not yet redeployed — with this bound,
259
+ * which for an inline read is not going to move.
255
260
  */
256
261
  export declare const VIDEOCLIPS_MAX_READ_BYTES: number;
262
+ /**
263
+ * Hard ceiling on ONE {@link videoclipsCapability.methods.offerClipBytes}
264
+ * transfer — ten times {@link VIDEOCLIPS_MAX_READ_BYTES}, and the reasoning is
265
+ * not "ten times more comfortable".
266
+ *
267
+ * The inline bound is set by what is HELD: a base64 envelope is the payload at
268
+ * ~1.33× in the provider AND the same again in the caller, so 50 MiB of clip
269
+ * is ~133 MiB of heap across two processes. Over `peerBytes` the consumer
270
+ * holds one socket chunk at a time and writes straight through to the export
271
+ * file, so its contribution is flat whatever the clip weighs. What is left is
272
+ * the PRODUCER's own copy, and that is a property of how each provider makes a
273
+ * clip rather than of this transport: Hikvision's fetch writes to a scratch
274
+ * FILE and offers it (nothing is held), Reolink's cmd-5 transfer is collected
275
+ * in memory and offered from there (one copy, the one it already had).
276
+ *
277
+ * So this number bounds the worst provider, not the transport, and it is named
278
+ * separately so that lifting it is a statement about a provider rather than
279
+ * about clips. Above it the provider REFUSES with the size in the message and
280
+ * never truncates: half a video is worse than an honest refusal.
281
+ */
282
+ export declare const VIDEOCLIPS_MAX_OFFER_BYTES: number;
257
283
  /**
258
284
  * A clip's finished bytes, inline — the twin of `recordingExport.readExportBytes`.
259
285
  *
@@ -273,6 +299,34 @@ export declare const ClipBytesSchema: z.ZodObject<{
273
299
  durationMs: z.ZodOptional<z.ZodNumber>;
274
300
  }, z.core.$strip>;
275
301
  export type ClipBytes = z.infer<typeof ClipBytesSchema>;
302
+ /**
303
+ * Where a clip's finished bytes can be TAKEN (D613) — the answer to
304
+ * {@link videoclipsCapability.methods.offerClipBytes}.
305
+ *
306
+ * Everything {@link ClipBytesSchema} carries except the bytes themselves, plus
307
+ * the one-shot ticket that leads to them. The metadata is answered BEFORE the
308
+ * transfer on purpose: a consumer learns which twin it got, what to call the
309
+ * file and how long the clip runs without having to read a byte, so a decision
310
+ * it would make on that metadata (a wrong twin, an implausible duration) costs
311
+ * no transfer at all.
312
+ */
313
+ export declare const ClipBytesOfferSchema: z.ZodObject<{
314
+ ticket: z.ZodObject<{
315
+ url: z.ZodString;
316
+ hostNodeId: z.ZodString;
317
+ expiresAtMs: z.ZodNumber;
318
+ declaredBytes: z.ZodNullable<z.ZodNumber>;
319
+ }, z.core.$strip>;
320
+ contentType: z.ZodString;
321
+ name: z.ZodString;
322
+ served: z.ZodEnum<{
323
+ high: "high";
324
+ mid: "mid";
325
+ low: "low";
326
+ }>;
327
+ durationMs: z.ZodOptional<z.ZodNumber>;
328
+ }, z.core.$strip>;
329
+ export type ClipBytesOffer = z.infer<typeof ClipBytesOfferSchema>;
276
330
  /**
277
331
  * Where a clip's STREAM can be dialled (D597) — the answer to
278
332
  * {@link videoclipsCapability.methods.dialClipStream}.
@@ -338,6 +392,86 @@ export declare const ClipStreamDialSchema: z.ZodObject<{
338
392
  }>>;
339
393
  }, z.core.$strip>;
340
394
  export type ClipStreamDial = z.infer<typeof ClipStreamDialSchema>;
395
+ /**
396
+ * The playback rates a clip can be DELIVERED at, ascending, always with `1`.
397
+ *
398
+ * These are the BROKER's: it re-paces frames it has already demuxed — the
399
+ * `MonotonicClock` divides source elapsed time by the factor and the pacer
400
+ * pushes that much faster — so the domain is the recorded one, {0} ∪ [0.25, 4],
401
+ * and this is the discrete ladder drawn from it. `1.5` is in it because a
402
+ * re-pacer has no reason to refuse it.
403
+ *
404
+ * `8` and `16` are deliberately NOT here. They are the CAMERA's own
405
+ * `<playSpeed>` (Reolink cmd-5 replay), a different mechanism, still unwired
406
+ * (D597, D600) — a rate change there costs a new dial and a new stream, and
407
+ * the camera's 8x would need a resample the clip audio path has no decoder
408
+ * for. Offering them today accepts a rate and delivers 1x, which is the whole
409
+ * defect this list exists to end (D612). When `playSpeed` IS wired its rates
410
+ * join THIS array — a second list elsewhere is the second authority D62
411
+ * forbids.
412
+ *
413
+ * Every entry must survive the broker's `clampPlaybackRate` unchanged: a set
414
+ * that offers what the clamp then moves is the same lie one step later.
415
+ */
416
+ export declare const CLIP_BROKER_PACED_RATES: readonly number[];
417
+ /**
418
+ * The rates a REALTIME-BOUND stream can be delivered at.
419
+ *
420
+ * **Measured, and it is the whole reason this second ladder exists.** A
421
+ * Hikvision RTSP replay is not a fast fetch: it delivers the recording at the
422
+ * speed it was recorded. On 1436, 2026-09-23, one stream carried 176 access
423
+ * units in 14 274 ms of wall clock at a measured 12.5 fps — 14.08 s of media
424
+ * in 14.27 s, **1.01× realtime** — and a whole 18 s clip took 22.3 s to fetch
425
+ * end to end. Reolink's cmd-5 transfer, which {@link CLIP_BROKER_PACED_RATES}
426
+ * was written for, lands the same bytes at 49–62× and therefore has the entire
427
+ * clip in hand within the first second.
428
+ *
429
+ * The broker's pacer consumes `rate` seconds of media per second of wall
430
+ * clock while the socket supplies one. So at any rate above 1 the buffer
431
+ * drains at `(rate − 1)×` and a stream that is only seconds old runs dry
432
+ * almost at once — the viewer stops, the queue empties, and the provider's
433
+ * own drain gate eventually reports `peer-stalled`. Nothing about that is a
434
+ * bug to be fixed with a bigger buffer: there is no buffer, because the bytes
435
+ * do not exist yet.
436
+ *
437
+ * So the honest answer is the DECLARATION (D612's own rule, applied to the
438
+ * case it did not yet have): a rate this transport cannot deliver is never
439
+ * offered. Below 1 is free — a slower pacer only lets the buffer grow.
440
+ *
441
+ * When a clip is served from a FILE the constraint is gone with the transport,
442
+ * which is why `file` keeps the full ladder.
443
+ */
444
+ export declare const CLIP_REALTIME_SOURCE_RATES: readonly number[];
445
+ /**
446
+ * What a surface may DRAW for this provider's clips — the answer to
447
+ * {@link videoclipsCapability.methods.getPlaybackOptions} (D612).
448
+ *
449
+ * The envelope is a PROVIDER fact, not a clip fact, and that is measured, not
450
+ * assumed: the broker's `chooseClipPath` reads exactly two inputs — whether
451
+ * `dialClipStream` and `readClipBytes` are wired — and both are constants of
452
+ * the broker's own closure over the provider's methods. The `profile` it is
453
+ * handed is explicitly not read. So every clip of a provider is served the
454
+ * same way, and a per-clip channel carried a value that could not vary. The
455
+ * per-clip `clipTransport` server message was removed for exactly that reason.
456
+ *
457
+ * Queried per camera, before a clip is picked, so a control is rendered or
458
+ * DISABLED rather than offered and refused at play time (D62: a disabled
459
+ * control reads as unavailable, one that undoes the gesture reads as broken).
460
+ */
461
+ export declare const ClipPlaybackOptionsSchema: z.ZodObject<{
462
+ transport: z.ZodEnum<{
463
+ file: "file";
464
+ stream: "stream";
465
+ }>;
466
+ seek: z.ZodEnum<{
467
+ forward: "forward";
468
+ free: "free";
469
+ }>;
470
+ stepBack: z.ZodBoolean;
471
+ scrub: z.ZodBoolean;
472
+ rates: z.ZodReadonly<z.ZodArray<z.ZodNumber>>;
473
+ }, z.core.$strip>;
474
+ export type ClipPlaybackOptions = z.infer<typeof ClipPlaybackOptionsSchema>;
341
475
  export declare const ClipSourceAvailabilitySchema: z.ZodObject<{
342
476
  state: z.ZodEnum<{
343
477
  ok: "ok";
@@ -533,14 +667,18 @@ export declare const videoclipsCapability: {
533
667
  *
534
668
  * `getClipPlayback` is the right answer for a player: it hands back a URL
535
669
  * on a plane the hub serves `access:'authenticated'`, which a browser and a
536
- * viewer session satisfy. It is the wrong answer for another ADDON. There
537
- * is no addon→addon byte transport in this framework — `AddonDataPlane`
538
- * only lets an addon SERVE, on `127.0.0.1` behind a per-listener secret
539
- * only the hub may present — so a recorder that wants a camera's clip
540
- * cannot fetch that URL. This method is the one seam that exists for it,
541
- * and it is deliberately the same shape (and the same bound) as
542
- * `recordingExport.readExportBytes`, which exists for the mirror-image
543
- * reason.
670
+ * viewer session satisfy. It is the wrong answer for another ADDON: the
671
+ * hub's proxy in front of that plane takes only a user credential, which
672
+ * an addon does not hold, so a recorder that wants a camera's clip cannot
673
+ * fetch that URL. This method is the shape that answer forced — the same
674
+ * one (and the same bound) as `recordingExport.readExportBytes`.
675
+ *
676
+ * **It is no longer the only seam.** Until D613 there was no addon→addon
677
+ * byte transport at all; there is now
678
+ * ({@link offerClipBytes}, over `ctx.peerBytes`), it holds nothing on
679
+ * either side, and it is what a clip EXPORT uses. This method remains for
680
+ * a consumer that genuinely wants the bytes in hand, and as the named
681
+ * fallback for a provider not yet redeployed.
544
682
  *
545
683
  * Routing needs no `provider` pin: the id is source-prefixed and
546
684
  * self-contained, so `device-collection-dispatch.ts` rule 3 hands the call
@@ -588,6 +726,72 @@ export declare const videoclipsCapability: {
588
726
  }, z.core.$strip>, "query"> & {
589
727
  readonly providerOptional: true;
590
728
  };
729
+ /**
730
+ * Where this clip's finished bytes can be TAKEN — the by-handle read a
731
+ * clip EXPORT pulls, over the addon→addon byte transport (D613).
732
+ *
733
+ * This is {@link readClipBytes} with the envelope removed. Same gates,
734
+ * same vocabulary, same completion rules, same `served` contract — the
735
+ * only difference is that the bytes travel over a one-shot loopback
736
+ * socket instead of inside a base64 field, so neither side holds the
737
+ * payload whole and the 50 MiB refusal on a long `high` twin stops
738
+ * existing. The bound that remains is
739
+ * {@link VIDEOCLIPS_MAX_OFFER_BYTES}, and it bounds the PRODUCER's own
740
+ * copy rather than the transport.
741
+ *
742
+ * **The ticket is loopback and same-host.** A provider on an agent mints a
743
+ * URL that means nothing on the hub, and `ctx.peerBytes.open` refuses it
744
+ * `cross-node` by name rather than dialling whatever else holds that port
745
+ * here. A consumer that can be on the other side of a node boundary from
746
+ * its provider must be able to read that refusal and say so; it must not
747
+ * treat it as "no bytes".
748
+ *
749
+ * **A ticket is a one-shot bearer credential with a seconds-long life.**
750
+ * Take it immediately, never persist it, never log its `url`. An untaken
751
+ * ticket costs the provider one map entry until its TTL, and outstanding
752
+ * tickets are bounded — which is also what makes a per-frame misuse of
753
+ * this method refuse by name rather than work slowly (D9/D18: this is a
754
+ * by-handle fetch of finished media, not a frame pipe).
755
+ *
756
+ * Optional on the provider for the same reason `readClipBytes` is: a
757
+ * source with no camera socket behind it has no bytes. A provider that
758
+ * predates this method answers `NOT_IMPLEMENTED`, and a consumer may fall
759
+ * back to `readClipBytes` — but it says so in the log, with the deploy
760
+ * hint, because that fallback re-imposes the 50 MiB refusal and an
761
+ * operator who sees `too-large-to-transfer` after this shipped is looking
762
+ * at a stale addon, not at a clip that cannot be exported.
763
+ */
764
+ readonly offerClipBytes: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
765
+ deviceId: z.ZodNumber;
766
+ clipId: z.ZodString;
767
+ provider: z.ZodString;
768
+ profile: z.ZodOptional<z.ZodEnum<{
769
+ high: "high";
770
+ mid: "mid";
771
+ low: "low";
772
+ }>>;
773
+ maxBytes: z.ZodOptional<z.ZodNumber>;
774
+ wake: z.ZodOptional<z.ZodEnum<{
775
+ authorised: "authorised";
776
+ }>>;
777
+ }, z.core.$strip>, z.ZodObject<{
778
+ ticket: z.ZodObject<{
779
+ url: z.ZodString;
780
+ hostNodeId: z.ZodString;
781
+ expiresAtMs: z.ZodNumber;
782
+ declaredBytes: z.ZodNullable<z.ZodNumber>;
783
+ }, z.core.$strip>;
784
+ contentType: z.ZodString;
785
+ name: z.ZodString;
786
+ served: z.ZodEnum<{
787
+ high: "high";
788
+ mid: "mid";
789
+ low: "low";
790
+ }>;
791
+ durationMs: z.ZodOptional<z.ZodNumber>;
792
+ }, z.core.$strip>, "query"> & {
793
+ readonly providerOptional: true;
794
+ };
591
795
  /**
592
796
  * Where this clip's STREAM can be dialled (D597) — the forward-only
593
797
  * fMP4 the provider writes from the first muxed byte, for the broker to
@@ -639,6 +843,92 @@ export declare const videoclipsCapability: {
639
843
  }, z.core.$strip>, "query"> & {
640
844
  readonly providerOptional: true;
641
845
  };
846
+ /**
847
+ * What a surface may DRAW for this provider's clips: the rates it can be
848
+ * played at, whether scrub is served, how far a position may be moved,
849
+ * and whether a backward frame-step means anything (D612).
850
+ *
851
+ * **The only authority.** The per-clip `clipTransport` server message
852
+ * that used to carry the same answer was removed: the broker's transport
853
+ * choice reads nothing that varies per clip, so the clip level had no
854
+ * information the provider does not already have, and two channels that
855
+ * can disagree are worse than one (D62).
856
+ *
857
+ * Asked per camera and per provider, so it must stay CHEAP — it is a
858
+ * statement about wiring, answered from a constant, never a call to the
859
+ * camera. A provider answers with one of {@link CLIP_PLAYBACK_OPTIONS}
860
+ * and never composes an envelope of its own.
861
+ *
862
+ * Optional, and absence is load-bearing: a provider that has not answered
863
+ * has not restricted anything, and a viewer reads it as the freedom it
864
+ * always had. See D612 on the rollout order that absence implies.
865
+ */
866
+ readonly getPlaybackOptions: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
867
+ deviceId: z.ZodNumber;
868
+ provider: z.ZodString;
869
+ }, z.core.$strip>, z.ZodObject<{
870
+ transport: z.ZodEnum<{
871
+ file: "file";
872
+ stream: "stream";
873
+ }>;
874
+ seek: z.ZodEnum<{
875
+ forward: "forward";
876
+ free: "free";
877
+ }>;
878
+ stepBack: z.ZodBoolean;
879
+ scrub: z.ZodBoolean;
880
+ rates: z.ZodReadonly<z.ZodArray<z.ZodNumber>>;
881
+ }, z.core.$strip>, "query"> & {
882
+ readonly providerOptional: true;
883
+ };
642
884
  };
643
885
  };
644
886
  export type IVideoclipsProvider = InferProvider<typeof videoclipsCapability>;
887
+ /**
888
+ * NOTE ON PLACEMENT: this block lives AFTER the capability definition on
889
+ * purpose. `scripts/lib/parse-cap.ts` finds a cap by the FIRST
890
+ * `export const <X> = {` in the file, so an object literal declared above
891
+ * `videoclipsCapability` is silently taken for the capability itself and
892
+ * codegen emits a `DeviceProxy` entry that does not type-check. Found the
893
+ * hard way, 2026-09-23.
894
+ */
895
+ /**
896
+ * The two envelopes, spelled ONCE.
897
+ *
898
+ * A provider answers with the entry for the transport its own wiring buys —
899
+ * `stream` if it implements `dialClipStream`, `file` if it implements only
900
+ * `readClipBytes` — and never composes one of its own. One table is what
901
+ * makes "the provider may not promise what no clip can be given" structural
902
+ * instead of a discipline: there is nothing else to promise.
903
+ */
904
+ export declare const CLIP_PLAYBACK_OPTIONS: {
905
+ readonly stream: {
906
+ readonly transport: "stream";
907
+ readonly seek: "forward";
908
+ readonly stepBack: false;
909
+ readonly scrub: false;
910
+ readonly rates: readonly number[];
911
+ };
912
+ /**
913
+ * A `stream` whose SOURCE runs at realtime — a Hikvision RTSP replay.
914
+ *
915
+ * Same verbs as `stream`, a shorter rate ladder, and the difference is a
916
+ * measurement rather than a preference: see
917
+ * {@link CLIP_REALTIME_SOURCE_RATES}. A third entry rather than a parameter,
918
+ * because a provider must still be able to do nothing but NAME one of these.
919
+ */
920
+ readonly realtimeStream: {
921
+ readonly transport: "stream";
922
+ readonly seek: "forward";
923
+ readonly stepBack: false;
924
+ readonly scrub: false;
925
+ readonly rates: readonly number[];
926
+ };
927
+ readonly file: {
928
+ readonly transport: "file";
929
+ readonly seek: "free";
930
+ readonly stepBack: true;
931
+ readonly scrub: true;
932
+ readonly rates: readonly number[];
933
+ };
934
+ };
@@ -9131,6 +9131,13 @@ export type AppRouter = TrpcCoreRouter<{
9131
9131
  output: z.infer<typeof videoclipsCapability.methods.readClipBytes.output>;
9132
9132
  meta: object;
9133
9133
  }>;
9134
+ offerClipBytes: TRPCQueryProcedure<{
9135
+ input: {
9136
+ [x: string]: unknown;
9137
+ } & z.input<typeof videoclipsCapability.methods.offerClipBytes.input>;
9138
+ output: z.infer<typeof videoclipsCapability.methods.offerClipBytes.output>;
9139
+ meta: object;
9140
+ }>;
9134
9141
  dialClipStream: TRPCQueryProcedure<{
9135
9142
  input: {
9136
9143
  [x: string]: unknown;
@@ -9138,6 +9145,13 @@ export type AppRouter = TrpcCoreRouter<{
9138
9145
  output: z.infer<typeof videoclipsCapability.methods.dialClipStream.output>;
9139
9146
  meta: object;
9140
9147
  }>;
9148
+ getPlaybackOptions: TRPCQueryProcedure<{
9149
+ input: {
9150
+ [x: string]: unknown;
9151
+ } & z.input<typeof videoclipsCapability.methods.getPlaybackOptions.input>;
9152
+ output: z.infer<typeof videoclipsCapability.methods.getPlaybackOptions.output>;
9153
+ meta: object;
9154
+ }>;
9141
9155
  }>>;
9142
9156
  viewerUi: TRPCBuiltRouter<{
9143
9157
  ctx: TrpcContext;
@@ -6,7 +6,7 @@
6
6
  * scope+access check inside `protectedProcedure` (see
7
7
  * `server/backend/src/api/trpc/trpc.middleware.ts`).
8
8
  *
9
- * Coverage: 1169 method paths across 160 capabilities.
9
+ * Coverage: 1171 method paths across 160 capabilities.
10
10
  */
11
11
  import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
12
12
  export interface MethodAccessRecord {
@@ -6,7 +6,7 @@
6
6
  * system-scope cap that takes a deviceId was previously never device-filtered
7
7
  * — see the generator header).
8
8
  *
9
- * Coverage: 395 methods carry a device reference, of which
9
+ * Coverage: 397 methods carry a device reference, of which
10
10
  * 141 are on SYSTEM-scope caps.
11
11
  *
12
12
  * Top-level fields, number arrays, and one-level arrays of objects carrying
package/dist/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export type * from './interfaces/addon.js';
22
22
  export { DEFAULT_ADDON_PLACEMENT, isAgentOnlyPlacement, isDeployableToAgent, isIsolatedBuiltin, resolveAddonExecution, resolveAddonGroup, resolveAddonPlacement, resolveRunnerId, } from './interfaces/addon.js';
23
23
  export type * from './interfaces/addon-data-plane.js';
24
24
  export { DATAPLANE_SECRET_HEADER, SHARE_VIEW_KINDS } from './interfaces/addon-data-plane.js';
25
+ export type * from './interfaces/addon-peer-bytes.js';
26
+ export { PeerBytesTicketSchema, PEER_BYTES_CHUNK_BYTES, PEER_BYTES_MAX_OUTSTANDING, PEER_BYTES_STALL_MS, PEER_BYTES_TICKET_TTL_MS, } from './interfaces/addon-peer-bytes.js';
25
27
  export type * from './interfaces/addon-routes.js';
26
28
  export * from './interfaces/adoption-job.js';
27
29
  export type * from './interfaces/agent.js';