@camstack/system 1.2.276 → 1.2.278

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 (62) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/autotrack/index.js +1 -1
  8. package/dist/builtins/autotrack/index.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/camera-grid/index.js +1 -1
  12. package/dist/builtins/camera-grid/index.mjs +1 -1
  13. package/dist/builtins/console-logging/index.js +1 -1
  14. package/dist/builtins/console-logging/index.mjs +1 -1
  15. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  16. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  17. package/dist/builtins/device-manager/device-bindings-store.d.ts +10 -0
  18. package/dist/builtins/device-manager/device-manager.addon.d.ts +0 -2
  19. package/dist/builtins/device-manager/device-manager.addon.js +63 -118
  20. package/dist/builtins/device-manager/device-manager.addon.mjs +64 -116
  21. package/dist/builtins/device-manager/device-meta-types.d.ts +15 -27
  22. package/dist/builtins/device-manager/device-source-activation.d.ts +9 -43
  23. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  24. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  25. package/dist/builtins/hub-forwarder/index.js +1 -1
  26. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  27. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  28. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  29. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  30. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  31. package/dist/builtins/local-network/local-network.addon.js +1 -1
  32. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  33. package/dist/builtins/loki-logging/index.js +1 -1
  34. package/dist/builtins/loki-logging/index.mjs +1 -1
  35. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  36. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  37. package/dist/builtins/platform-probe/index.js +1 -1
  38. package/dist/builtins/platform-probe/index.mjs +1 -1
  39. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  40. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  41. package/dist/builtins/snapshot/index.js +1 -1
  42. package/dist/builtins/snapshot/index.mjs +1 -1
  43. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  44. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  45. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  46. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  47. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  48. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  49. package/dist/builtins/system-config/system-config.addon.js +1 -1
  50. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  51. package/dist/builtins/winston-logging/index.js +1 -1
  52. package/dist/builtins/winston-logging/index.mjs +1 -1
  53. package/dist/{dist-D_OlSf31.js → dist-BWz_gZ5l.js} +145 -85
  54. package/dist/{dist-AHdiIdJH.mjs → dist-D1atncyi.mjs} +145 -85
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.js +14 -67
  57. package/dist/index.mjs +16 -66
  58. package/dist/kernel/capability-registry.d.ts +12 -42
  59. package/dist/kernel/index.d.ts +0 -1
  60. package/dist/{retired-settings-keys-LwFyTKun.js → retired-settings-keys-Ek9MPzCi.js} +1 -1
  61. package/dist/{retired-settings-keys-Cp3oG_aH.mjs → retired-settings-keys-rG_QVMT3.mjs} +1 -1
  62. package/package.json +1 -1
@@ -691,7 +691,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
691
691
  return EventCategory;
692
692
  }({});
693
693
  //#endregion
694
- //#region ../types/dist/sleep-CopaBJss.mjs
694
+ //#region ../types/dist/sleep-CaB_hL5g.mjs
695
695
  /**
696
696
  * The audio chunk plane's byte format, and the ONE expansion from a coded
697
697
  * window to float samples (D455).
@@ -892,12 +892,6 @@ var WELL_KNOWN_TAB_MAP = Object.fromEntries([
892
892
  icon: "circle-dot",
893
893
  order: 40
894
894
  },
895
- {
896
- id: "clips",
897
- label: "Clips",
898
- icon: "clapperboard",
899
- order: 41
900
- },
901
895
  {
902
896
  id: "engine",
903
897
  label: "Inference Engine",
@@ -3860,6 +3854,20 @@ var EVENT_OWNER_TYPES = [
3860
3854
  * nothing failing until a caller asked.
3861
3855
  */
3862
3856
  var EventOwnerTypeSchema = zod.z.enum(EVENT_OWNER_TYPES);
3857
+ /**
3858
+ * The owner kinds a media-PRESENCE probe may ask about: the three event tables
3859
+ * plus `track`.
3860
+ *
3861
+ * `videoclips` resolves a clip's still the way `resolveDefaultEventMedia` does
3862
+ * — the event's OWN media when it has any, else its owning TRACK's — so the
3863
+ * probe needs exactly this union and no more of {@link MediaOwnerType}. Built
3864
+ * FROM {@link EVENT_OWNER_TYPES} so a fourth event table reaches the probe the
3865
+ * day it is declared, rather than being accepted by one side and refused by the
3866
+ * other.
3867
+ */
3868
+ var MEDIA_PRESENCE_OWNER_KINDS = [...EVENT_OWNER_TYPES, "track"];
3869
+ /** The same list as a Zod enum, for the cap input that carries it. */
3870
+ var MediaPresenceOwnerKindSchema = zod.z.enum(MEDIA_PRESENCE_OWNER_KINDS);
3863
3871
  new Set(EVENT_OWNER_TYPES);
3864
3872
  /**
3865
3873
  * Shared video / audio encode profile schemas used by every consumer
@@ -13244,30 +13252,30 @@ var deviceManagerCapability = {
13244
13252
  */
13245
13253
  getAllBindings: method(zod.z.object({}), zod.z.array(DeviceBindingsForDeviceSchema)),
13246
13254
  /**
13247
- * Activate (or deactivate) a wrapper addon — or ONE of its sources — for a
13248
- * (device, cap) pair.
13249
- *
13250
- * Persists the binding via ctx.settings; `active: false` on a SINGLETON cap
13251
- * clears the wrapper (falling back to native if one is registered). On a
13252
- * COLLECTION cap it adds to the per-device DENY set instead, and the
13253
- * wrapper binding is left exactly as it was — a cap with several sources
13254
- * has no "which one" for `getBindings` to answer (D556).
13255
- *
13256
- * `sourceId` is what makes the switch match its label. One addon can serve
13257
- * several of a device's sources (`addon-provider-reolink` answers a hub
13258
- * child with `native:reolink:onboard` AND `native:reolink:hub`), so a
13259
- * toggle keyed by addon would turn off both while saying it turned off one
13260
- * — the D62 defect with the polarity reversed (D557). Naming the source
13261
- * denies exactly that source. OMITTING it keeps the cap-wide meaning
13262
- * D556 shipped: every source this addon serves for this device, which is
13263
- * also how a deny entry persisted before the re-key is still read.
13255
+ * Activate (or deactivate) a wrapper addon for a (device, cap) pair — the
13256
+ * per-camera function switch's ONE authority (D62).
13257
+ *
13258
+ * SINGLETON capabilities only. Persists the binding via ctx.settings;
13259
+ * `active: false` clears the wrapper (falling back to native if one is
13260
+ * registered) by persisting the explicit `{ wrapperAddonId: null }` marker,
13261
+ * which is what stops `getBindings` re-binding a `defaultActive` wrapper.
13262
+ *
13263
+ * **A COLLECTION capability is REFUSED by name.** It briefly took a
13264
+ * `sourceId` and wrote a per-device DENY set, so one of an addon's several
13265
+ * sources could be switched off without switching off the rest (D556, then
13266
+ * D555's re-key by source). The operator removed the whole idea the same
13267
+ * day: *"tutti i providers funzionano sempre, non serve
13268
+ * disattivarli/attivarli … loro vivono lì"* (D557 amended, third). A
13269
+ * collection cap's providers are a DERIVED set — every addon that provides
13270
+ * the cap for this device type, computed on every read and persisted
13271
+ * nowhere — so there is nothing here to activate, and a verb that accepted
13272
+ * the call could only write a field the enumeration does not read. That is
13273
+ * the D62 shape, and this repo has shipped it four times.
13264
13274
  */
13265
13275
  setWrapperActive: method(zod.z.object({
13266
13276
  deviceId: zod.z.number(),
13267
13277
  capName: zod.z.string(),
13268
13278
  wrapperAddonId: zod.z.string(),
13269
- /** The `ClipSource.source` id to toggle. Absent = all of the addon's. */
13270
- sourceId: zod.z.string().optional(),
13271
13279
  active: zod.z.boolean()
13272
13280
  }), zod.z.void(), {
13273
13281
  kind: "mutation",
@@ -21800,6 +21808,35 @@ var pipelineAnalyticsCapability = {
21800
21808
  deviceId: zod.z.number()
21801
21809
  }), zod.z.array(MediaFileInfoSchema).readonly()),
21802
21810
  /**
21811
+ * Which of `ownerIds` hold at least ONE media row — an INDEX read, never a
21812
+ * blob read, and the LICENCE `videoclips` needs to publish a `thumbnail`.
21813
+ *
21814
+ * The event-media URL is stamped from a template for every event in the
21815
+ * system, so "the plane is up" was being served as "there are bytes": 64 of
21816
+ * one camera's 179 clips pointed at a 404 (device 3836, 2026-08-17). This
21817
+ * is the question that turns the stamp into a claim.
21818
+ *
21819
+ * It is on the WIRE because the clip source is registered by the addon that
21820
+ * owns the FOOTAGE, not by this one (D560) — the probe used to be an
21821
+ * in-process `MediaStore` read. One call per OWNER KIND, never one per
21822
+ * owner: that N+1 is what `MediaStore.ownersWithMedia` was written to
21823
+ * prevent, and crossing a process boundary makes it worse, not better.
21824
+ * `ownerIds` is bounded at the same 5 000 the annotation fetch is bounded
21825
+ * at, so one pathological camera-day cannot mint an unbounded request.
21826
+ *
21827
+ * THROWS rather than answering partially. A probe that quietly
21828
+ * under-reports reads as "these owners have nothing" and the caller drops
21829
+ * thumbnails that exist — the opposite failure to the one above, and
21830
+ * equally invisible.
21831
+ *
21832
+ * `deviceId` is the authorization subject, exactly as on `getEventMedia`.
21833
+ */
21834
+ ownersWithMedia: method(zod.z.object({
21835
+ deviceId: zod.z.number(),
21836
+ ownerKind: MediaPresenceOwnerKindSchema,
21837
+ ownerIds: zod.z.array(zod.z.string()).max(5e3)
21838
+ }), zod.z.array(zod.z.string()).readonly()),
21839
+ /**
21803
21840
  * Search object events by text query using CLIP cosine similarity.
21804
21841
  * Encodes `text` via the `embedding-encoder` cap, queries the
21805
21842
  * `ObjectEmbeddingStore` with optional prefilters, ranks all matching
@@ -25951,6 +25988,18 @@ var vectorStoreCapability = {
25951
25988
  stats: method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" })
25952
25989
  }
25953
25990
  };
25991
+ zod.z.enum([
25992
+ "queue-full",
25993
+ "camera-backoff",
25994
+ "sleeping",
25995
+ "camera-refused",
25996
+ "no-keyframe",
25997
+ "no-catalog-row",
25998
+ "unsupported",
25999
+ "unknown-device",
26000
+ "uid-missing"
26001
+ ]);
26002
+ zod.z.enum(["deferred", "final"]);
25954
26003
  var ClipSchema = zod.z.object({
25955
26004
  /** Opaque, provider-namespaced id. The default provider encodes the time
25956
26005
  * window so `getClipPlayback` is self-contained (no event re-query). */
@@ -26101,7 +26150,25 @@ var ClipSchema = zod.z.object({
26101
26150
  */
26102
26151
  playable: zod.z.boolean().optional(),
26103
26152
  /** Why {@link playable} is false, verbatim (`no-file-for-window`). */
26104
- unplayableReason: zod.z.string().optional()
26153
+ unplayableReason: zod.z.string().optional(),
26154
+ /**
26155
+ * This clip is STILL BEING WRITTEN, so {@link ClipSchema.timeRange}`.endMs`
26156
+ * is not its end.
26157
+ *
26158
+ * Absent — the common case — means the row is closed and its `endMs` is the
26159
+ * end of the recording. Present and `true` means the source told us the file
26160
+ * has no end yet, and the `endMs` we carry is whatever the camera's index
26161
+ * entry happened to hold: on a Reolink E1 Outdoor PoE (592, measured
26162
+ * 2026-09-20) the newest file `…_192927_000000_…_0.mp4` reported an `endTime`
26163
+ * of 19:29:56 and STILL reported it eight minutes later, while the file went
26164
+ * on growing. A surface that drew 29 s there was lying about a clip that
26165
+ * plays for minutes, on the one row the operator looks at first.
26166
+ *
26167
+ * `endMs` is deliberately still a number: it is the best bound anything has
26168
+ * for a mint window or a byte fetch, and every consumer already requires it.
26169
+ * This flag says what it is WORTH, and a duration is not drawn from it.
26170
+ */
26171
+ inProgress: zod.z.boolean().optional()
26105
26172
  });
26106
26173
  var ClipPlaybackSchema = zod.z.object({
26107
26174
  /**
@@ -26184,59 +26251,17 @@ var ClipSourceSchema = zod.z.object({
26184
26251
  * alternative — a `native:reolink:* → provider-reolink` table inside the
26185
26252
  * widget — is a second authority on provider identity living in the one
26186
26253
  * package with no business knowing it, wrong the day a third source appears
26187
- * (D557). One addon may serve SEVERAL sources: `addon-provider-reolink`
26188
- * answers a hub child with both `native:reolink:onboard` and
26189
- * `native:reolink:hub`, which is why the per-device switch is keyed by
26190
- * SOURCE and not by this (D555).
26254
+ * (D557). One addon may serve SEVERAL sources, which is why the per-device
26255
+ * switch is keyed by SOURCE and not by this (D555) — `addon-provider-reolink`
26256
+ * served a hub child two of them until the two views were measured to be one
26257
+ * store read twice (D555) and then read ONE way (D565).
26191
26258
  *
26192
26259
  * Optional for version skew only. The collection dispatcher stamps it from
26193
26260
  * the registry, so a row that travelled through the fan-out carries the
26194
26261
  * authoritative id whatever the provider filled in.
26195
26262
  */
26196
26263
  addonId: zod.z.string().optional(),
26197
- /**
26198
- * Which API this source resolved to FOR THIS CAMERA, when it has a choice.
26199
- *
26200
- * A source may cover one store through more than one surface — the Reolink
26201
- * provider reads a hub child through the parent's event log and a standalone
26202
- * through its own file list, because that is what each camera answers. The
26203
- * CHOICE is the provider's, made from what the camera is, and is never a row
26204
- * the operator has to understand; but it is REPORTED, because a source that
26205
- * silently reads a different API on two cameras and then behaves differently
26206
- * is the thing nobody can debug later. Absent when the source has only one
26207
- * way to read its store.
26208
- */
26209
- via: zod.z.string().optional(),
26210
- availability: ClipSourceAvailabilitySchema,
26211
- /**
26212
- * The operator switched this source OFF for this camera.
26213
- *
26214
- * Deliberately NOT a member of {@link ClipSourceAvailabilitySchema}'s
26215
- * vocabulary. That enum models what the source CAN do — a sleeping camera, an
26216
- * unmounted card, an index that disagrees with its own calendar — and a
26217
- * switched-off source could answer perfectly well; the operator decided it
26218
- * should not. Folding the choice in is how `disabled` and `broken` stop being
26219
- * distinguishable, which is the D62 rule this repo has already paid for twice:
26220
- * an off switch is REPORTED off (`CameraStatus.switchedOff`, the same word),
26221
- * and disabled must never look like broken. It is also what lets every
26222
- * exhaustive consumer of the availability enum keep compiling.
26223
- *
26224
- * A switched-off source contributes NO clips (`listClips` never calls it) and
26225
- * its row carries no `catalogAsOf`: nothing confirms a catalog it is not
26226
- * allowed to serve, and a frozen age that can only grow draws a stalling
26227
- * source rather than an off switch.
26228
- *
26229
- * The row survives BECAUSE it is the control the operator switches the source
26230
- * back on from — D554 decision 4's rule ("a source that cannot answer
26231
- * produces a ROW, not an absence") applied to the one case D556 carved out of
26232
- * it, and D557's own kept property ("a source is never hidden, only its
26233
- * rows"). Absent means on.
26234
- *
26235
- * A provider never sets this — like {@link ClipSourceSchema.addonId} it is
26236
- * stamped by the collection dispatcher, which holds the registry's projection
26237
- * of the persisted authority (D556) and is the only place that knows it.
26238
- */
26239
- switchedOff: zod.z.boolean().optional()
26264
+ availability: ClipSourceAvailabilitySchema
26240
26265
  });
26241
26266
  var videoclipsCapability = {
26242
26267
  name: "videoclips",
@@ -26256,17 +26281,31 @@ var videoclipsCapability = {
26256
26281
  * `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
26257
26282
  * binding entry derives the same section a native one does.
26258
26283
  *
26259
- * `topTab` because the browser owns the whole pane (a day's clips, a source
26260
- * list and a player), exactly as `ptz` does; the widget itself is
26261
- * `host/clips-browser` in ui-library's `HOST_WIDGETS`.
26284
+ * **It is a SECTION of the Recording tab, at the end of it — not a tab of
26285
+ * its own.** It shipped as a `clips` top-tab and the operator rejected the
26286
+ * placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
26287
+ * necessario, una nuova sezione alla fine per le clips"*. The Recording tab
26288
+ * already holds the recorder's panel, the schedule bands and the unified
26289
+ * retention policy; footage the camera itself holds is the same question,
26290
+ * asked of a different store. `order: 100` puts it after all of them with
26291
+ * room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
26292
+ * a well-known id nobody declares is an invitation to mint the tab again.
26293
+ *
26294
+ * `topTab` stays: the browser owns a pane (a day's tiles, a source list and
26295
+ * a player) and the Config tab's inner bar has no room for one. The widget
26296
+ * itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
26297
+ * the admin Recordings page renders every `location:'top-tab'` +
26298
+ * `tab:'recording'` section behind its camera picker
26299
+ * (`CameraRecordingSettingsSection`), this declaration lands the section on
26300
+ * BOTH surfaces with no second wiring.
26262
26301
  */
26263
26302
  deviceConfig: { ui: {
26264
26303
  kind: "widget",
26265
26304
  widgetId: "host/clips-browser",
26266
- tab: "clips",
26305
+ tab: "recording",
26267
26306
  topTab: true,
26268
26307
  label: "Clips",
26269
- order: 0
26308
+ order: 100
26270
26309
  } },
26271
26310
  methods: {
26272
26311
  listClips: method(zod.z.object({
@@ -26275,13 +26314,23 @@ var videoclipsCapability = {
26275
26314
  until: zod.z.number(),
26276
26315
  limit: zod.z.number().int().positive().optional(),
26277
26316
  /**
26278
- * View filter over {@link ClipSourceSchema.source} values — the
26279
- * picker's selection, forwarded so a provider need not list what
26280
- * nobody is looking at. ABSENT means every source this camera has,
26281
- * which is the honest default for a surface whose whole point is that
26282
- * nothing is hidden (D554 3). A provider with one source ignores it.
26317
+ * WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
26318
+ * carries, never a source id and never a list.
26319
+ *
26320
+ * Absent means the device's BOUND provider, which is CamStack on every
26321
+ * camera today because that is what `deviceManager.getBindings`
26322
+ * answers with. A provider the device is not bound to is refused by
26323
+ * name rather than answered by another one (D552's
26324
+ * `rejectUnresolvedAddonPin` rule).
26325
+ *
26326
+ * It replaced `sources?: string[]`, a VIEW filter over source ids that
26327
+ * assumed the answer was a fan-out over everything a camera has. The
26328
+ * operator settled otherwise on 2026-09-20 — *"il get videoclips
26329
+ * prendere un provider opzionale, di default va su camstack"*,
26330
+ * *"l'utilizzatore è uno solo"* — so the list is asked of one provider
26331
+ * at a time and there is nothing to filter out of it.
26283
26332
  */
26284
- sources: zod.z.array(zod.z.string()).optional()
26333
+ provider: zod.z.string().optional()
26285
26334
  }), zod.z.array(ClipSchema).readonly(), {
26286
26335
  kind: "query",
26287
26336
  auth: "protected"
@@ -43705,6 +43754,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
43705
43754
  addonId: null,
43706
43755
  access: "view"
43707
43756
  },
43757
+ "pipelineAnalytics.ownersWithMedia": {
43758
+ capName: "pipeline-analytics",
43759
+ capScope: "device",
43760
+ addonId: null,
43761
+ access: "view"
43762
+ },
43708
43763
  "pipelineAnalytics.pauseForStorageMigration": {
43709
43764
  capName: "pipeline-analytics",
43710
43765
  capScope: "device",
@@ -47605,6 +47660,11 @@ Object.freeze({
47605
47660
  form: "single",
47606
47661
  optional: false
47607
47662
  }],
47663
+ "pipelineAnalytics.ownersWithMedia": [{
47664
+ name: "deviceId",
47665
+ form: "single",
47666
+ optional: false
47667
+ }],
47608
47668
  "pipelineAnalytics.proposeRetrainAnnotations": [{
47609
47669
  name: "deviceId",
47610
47670
  form: "single",