@camstack/addon-notifiers 1.2.102 → 1.2.104

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 (3) hide show
  1. package/dist/addon.js +131 -50
  2. package/dist/addon.mjs +131 -50
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -29,7 +29,7 @@ let node_fs = require("node:fs");
29
29
  let node_path = require("node:path");
30
30
  node_path = __toESM(node_path);
31
31
  let node_url = require("node:url");
32
- //#region ../types/dist/event-category-DAXzJeTX.mjs
32
+ //#region ../types/dist/event-category-ZyX6jcse.mjs
33
33
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
34
34
  EventCategory["SystemBoot"] = "system.boot";
35
35
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -590,7 +590,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
590
590
  * a package zone — a newly-appeared stationary object of a package class
591
591
  * that cleared the class / zone / dwell / size gates. Payload:
592
592
  * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
593
- * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
593
+ * entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
594
594
  * Telemetry (D8): the durable record is the `package-events` store row;
595
595
  * this bus topic drives notifier rules + live UI. See
596
596
  * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
@@ -5376,7 +5376,7 @@ var ZodIssueCode = {
5376
5376
  var ZodFirstPartyTypeKind;
5377
5377
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5378
5378
  //#endregion
5379
- //#region ../types/dist/sleep-BnujYGPe.mjs
5379
+ //#region ../types/dist/sleep-CnLyvg3w.mjs
5380
5380
  /**
5381
5381
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5382
5382
  * window to float samples (D455).
@@ -7327,13 +7327,30 @@ new Set([
7327
7327
  "scene",
7328
7328
  "motion",
7329
7329
  "object",
7330
- "audio"
7330
+ "audio",
7331
+ "mosaic"
7331
7332
  ]);
7332
- new Set([
7333
+ /**
7334
+ * The owner types that are event tables, in the order the event-media resolver
7335
+ * should consider them. Exported so a consumer asking "is this key an event?"
7336
+ * does not re-spell the list and drift from it.
7337
+ */
7338
+ var EVENT_OWNER_TYPES = [
7333
7339
  "motion",
7334
7340
  "object",
7335
7341
  "audio"
7336
- ]);
7342
+ ];
7343
+ /**
7344
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7345
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7346
+ * `(table, id)`).
7347
+ *
7348
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7349
+ * table would otherwise be accepted by the codec and refused at the door, with
7350
+ * nothing failing until a caller asked.
7351
+ */
7352
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7353
+ new Set(EVENT_OWNER_TYPES);
7337
7354
  /**
7338
7355
  * Build an `IAddonRouteProvider` from a list of routes. Implements
7339
7356
  * both the operator-facing `getRoutes` (returning route descriptors
@@ -12588,6 +12605,16 @@ method(object({
12588
12605
  filter: QueryFilterSchema.optional(),
12589
12606
  columns: array(string()).readonly().optional()
12590
12607
  }), array(SettingsRecordSchema).readonly()), method(object({
12608
+ namespace: string().optional(),
12609
+ collection: string(),
12610
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12611
+ * index on the collection. Never empty. */
12612
+ conflict: array(string()).readonly(),
12613
+ record: BulkRecordSchema
12614
+ }), object({
12615
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12616
+ * row's own id on an update. */
12617
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12591
12618
  namespace: string().optional(),
12592
12619
  collection: string(),
12593
12620
  record: object({
@@ -12722,6 +12749,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12722
12749
  id: union([string(), number()]) }), {
12723
12750
  kind: "mutation",
12724
12751
  auth: "admin"
12752
+ }), method(object({
12753
+ namespace: string().optional(),
12754
+ collection: string(),
12755
+ conflict: array(string()).readonly(),
12756
+ record: BulkRecordSchema
12757
+ }), object({ id: union([string(), number()]) }), {
12758
+ kind: "mutation",
12759
+ auth: "admin"
12725
12760
  }), method(object({
12726
12761
  namespace: string().optional(),
12727
12762
  collection: string(),
@@ -18952,8 +18987,8 @@ var TrackPositionSchema = object({
18952
18987
  var TrackSnapshotSchema = object({
18953
18988
  timestamp: number(),
18954
18989
  position: TrackPositionSchema,
18955
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
18956
- mediaKey: string()
18990
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
18991
+ mediaId: number().int()
18957
18992
  });
18958
18993
  /**
18959
18994
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19557,14 +19592,14 @@ var ObjectEventSchema = object({
19557
19592
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19558
19593
  frameWidth: number().optional(),
19559
19594
  frameHeight: number().optional(),
19560
- /** MediaStore key for the crop attached to this event (if any). */
19561
- mediaKey: string().optional(),
19562
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19595
+ /** Media row id of the crop attached to this event (if any) — D482. */
19596
+ mediaId: number().int().optional(),
19597
+ /** Design B: media row id of the track's native-resolution key frame (the
19563
19598
  * best-detection full frame). Resolve via the event-media data-plane
19564
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19599
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19565
19600
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19566
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19567
- keyFrameMediaKey: string().optional(),
19601
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19602
+ keyFrameMediaId: number().int().optional(),
19568
19603
  /** Populated by B5 (recording playback URL for this event). */
19569
19604
  mediaUrl: string().optional(),
19570
19605
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19614,7 +19649,7 @@ var MediaFileKindEnum = _enum([
19614
19649
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19615
19650
  *
19616
19651
  * `url` points at the `event-media` data plane
19617
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19652
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19618
19653
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19619
19654
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19620
19655
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19622,10 +19657,13 @@ var MediaFileKindEnum = _enum([
19622
19657
  * `data-plane-access.ts` for the rule and the one gap it does not close
19623
19658
  * (per-device scoping).
19624
19659
  *
19625
- * The URL is built from the row's **stored** key, which is not always its
19626
- * published `kind`: a track's face/plate crop is stored as `crop` under
19660
+ * The URL is built from the row's own id, which since D482 says nothing about
19661
+ * the row's owner or kind — and that is the point. The published `kind` is not
19662
+ * the stored one (a track's face/plate crop is stored as `crop` under
19627
19663
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19628
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19664
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19665
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19666
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19629
19667
  *
19630
19668
  * ## `base64` is TRANSITIONAL and is going away
19631
19669
  *
@@ -19638,7 +19676,19 @@ var MediaFileKindEnum = _enum([
19638
19676
  * `analytics-query-facade.ts`; nothing else reads it.
19639
19677
  */
19640
19678
  var MediaFileSchema = object({
19641
- key: string(),
19679
+ /**
19680
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19681
+ *
19682
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19683
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19684
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19685
+ * different rows that spell the same number, and a track whose
19686
+ * `bestEventId` was an object event was served a motion event's snapshot —
19687
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19688
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19689
+ * at all.
19690
+ */
19691
+ mediaId: number().int(),
19642
19692
  kind: MediaFileKindEnum,
19643
19693
  sizeBytes: number(),
19644
19694
  timestamp: number()
@@ -19746,7 +19796,7 @@ var RetrainTrackSchema = object({
19746
19796
  });
19747
19797
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19748
19798
  var RetrainFrameCandidateSchema = object({
19749
- mediaKey: string(),
19799
+ mediaId: number().int(),
19750
19800
  kind: MediaFileKindEnum,
19751
19801
  timestamp: number(),
19752
19802
  sizeBytes: number().int(),
@@ -19760,7 +19810,7 @@ var RetrainFrameSchema = object({
19760
19810
  deviceId: number(),
19761
19811
  trackId: string(),
19762
19812
  /** Provenance only. It may already point at nothing — that is expected. */
19763
- sourceMediaKey: string(),
19813
+ sourceMediaId: number().int(),
19764
19814
  sourceKind: MediaFileKindEnum,
19765
19815
  sizeBytes: number().int(),
19766
19816
  width: number().int(),
@@ -19776,7 +19826,7 @@ var RetrainCopyRefusalSchema = _enum([
19776
19826
  var RetrainFrameSelectionSchema = object({
19777
19827
  copied: array(RetrainFrameSchema).readonly(),
19778
19828
  refused: array(object({
19779
- sourceMediaKey: string(),
19829
+ sourceMediaId: number().int(),
19780
19830
  reason: RetrainCopyRefusalSchema
19781
19831
  })).readonly()
19782
19832
  });
@@ -19784,7 +19834,7 @@ var RetrainFrameListSchema = object({
19784
19834
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19785
19835
  copies: array(RetrainFrameSchema).readonly(),
19786
19836
  /** What the page pre-selects — the native key frame when one survives. */
19787
- autoPickMediaKey: string().optional()
19837
+ autoPickMediaId: number().int().optional()
19788
19838
  });
19789
19839
  /** What the operator asked the assist to look for. */
19790
19840
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -19879,9 +19929,11 @@ var RecentTracksQueryInput = object({
19879
19929
  });
19880
19930
  /**
19881
19931
  * A Summary (D359): the per-camera session envelope that references tracks.
19882
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19883
- * served by the event-media plane by key), null until the first frame with a
19884
- * member visible has been materialised.
19932
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
19933
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
19934
+ * first frame with a member visible has been materialised (D482 — it was the
19935
+ * row's composite key, which embedded the owner and could name another table's
19936
+ * row once event ids became per-table rowids).
19885
19937
  */
19886
19938
  var SummarySchema = object({
19887
19939
  id: string(),
@@ -19890,7 +19942,7 @@ var SummarySchema = object({
19890
19942
  lastActiveAt: number(),
19891
19943
  sealedAt: number().nullable(),
19892
19944
  memberCount: number().int().nonnegative(),
19893
- groupShotKey: string().nullable()
19945
+ groupShotMediaId: number().int().nullable()
19894
19946
  });
19895
19947
  var SummariesQueryInput = object({
19896
19948
  deviceIds: array(number()).min(1),
@@ -20444,7 +20496,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20444
20496
  }), method(object({
20445
20497
  deviceId: number(),
20446
20498
  trackId: string(),
20447
- mediaKeys: array(string()).min(1)
20499
+ mediaIds: array(number().int()).min(1)
20448
20500
  }), RetrainFrameSelectionSchema, {
20449
20501
  kind: "mutation",
20450
20502
  auth: "admin"
@@ -20512,7 +20564,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20512
20564
  kind: "query",
20513
20565
  auth: "admin"
20514
20566
  }), method(object({
20515
- eventId: string(),
20567
+ /** Which of the three event tables owns the row. */
20568
+ ownerType: EventOwnerTypeSchema,
20569
+ /** The event's rowid in that table (D474: an event id is a number). */
20570
+ eventId: number().int(),
20516
20571
  kind: MediaFileKindEnum.optional(),
20517
20572
  deviceId: number()
20518
20573
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20523,7 +20578,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20523
20578
  trackId: string(),
20524
20579
  deviceId: number()
20525
20580
  }), array(MediaFileInfoSchema).readonly()), method(object({
20526
- eventId: string(),
20581
+ ownerType: EventOwnerTypeSchema,
20582
+ eventId: number().int(),
20527
20583
  deviceId: number()
20528
20584
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20529
20585
  kind: "mutation",
@@ -24986,8 +25042,8 @@ var IdentitySchema = object({
24986
25042
  id: string(),
24987
25043
  name: string(),
24988
25044
  sampleCount: number().int().nonnegative(),
24989
- coverMediaKey: string().optional(),
24990
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25045
+ coverMediaId: number().int().optional(),
25046
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
24991
25047
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
24992
25048
  coverBase64: string().optional()
24993
25049
  });
@@ -25013,8 +25069,8 @@ var IdentitySampleAuditRowSchema = object({
25013
25069
  enrolledAt: number().int(),
25014
25070
  deviceId: number().int().optional(),
25015
25071
  source: _enum(["detected", "photo"]),
25016
- /** The enrolled crop's media key, so the panel can show the evidence. */
25017
- mediaKey: string().optional(),
25072
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25073
+ mediaId: number().int().optional(),
25018
25074
  /**
25019
25075
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
25020
25076
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25083,15 +25139,15 @@ var FaceInfoSchema = object({
25083
25139
  */
25084
25140
  cropUrl: string().optional(),
25085
25141
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
25086
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
25142
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
25087
25143
  * legacy rows written before design B. */
25088
25144
  faceBbox: BoundingBoxSchema.optional(),
25089
25145
  /** Design B: MediaStore key of the track's native-resolution key frame.
25090
25146
  * Fetch the native JPEG via the event-media data-plane
25091
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
25147
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
25092
25148
  * track produced no key frame (e.g. native/onboard source) — the UI falls
25093
25149
  * back to the inline `base64` face crop. */
25094
- keyFrameMediaKey: string().optional(),
25150
+ keyFrameMediaId: number().int().optional(),
25095
25151
  /** Winning identity-match cosine (0..1) for this face's track, when an
25096
25152
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
25097
25153
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -25160,11 +25216,14 @@ var FaceClusterSchema = object({
25160
25216
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
25161
25217
  * dialog already rendering its key FRAME from the `event-media` plane.
25162
25218
  *
25163
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
25164
- * media key directly, so this needed no new plane and no new access decision.
25219
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
25220
+ * resolves a media row by its own id, so this needed no new plane and no new
25221
+ * access decision.
25165
25222
  */
25166
25223
  var MediaFileLiteSchema$1 = object({
25167
- key: string(),
25224
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
25225
+ * (D482). It was the row's composite key, which embedded the owner. */
25226
+ mediaId: number().int(),
25168
25227
  kind: string(),
25169
25228
  url: string(),
25170
25229
  sizeBytes: number(),
@@ -25181,7 +25240,7 @@ method(object({
25181
25240
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
25182
25241
  * four times and the viewer holds at `staleTime: 30_000`.
25183
25242
  *
25184
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
25243
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
25185
25244
  * the `event-media` plane serves that key `immutable` with an ETag.
25186
25245
  *
25187
25246
  * **This is an INPUT field, so it does not reach the addon until the
@@ -27649,8 +27708,8 @@ var VehicleSchema = object({
27649
27708
  id: string(),
27650
27709
  name: string(),
27651
27710
  sampleCount: number().int().nonnegative(),
27652
- coverMediaKey: string().optional(),
27653
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
27711
+ coverMediaId: number().int().optional(),
27712
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
27654
27713
  coverBase64: string().optional()
27655
27714
  });
27656
27715
  var VehicleSampleInfoSchema = object({
@@ -27683,7 +27742,7 @@ var PlateInfoSchema = object({
27683
27742
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
27684
27743
  plateBbox: BoundingBoxSchema.optional(),
27685
27744
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
27686
- keyFrameMediaKey: string().optional(),
27745
+ keyFrameMediaId: number().int().optional(),
27687
27746
  base64: string().optional(),
27688
27747
  /**
27689
27748
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -27704,11 +27763,14 @@ var PlateInfoSchema = object({
27704
27763
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
27705
27764
  * dialog already rendering its key FRAME from the `event-media` plane.
27706
27765
  *
27707
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
27708
- * media key directly, so this needed no new plane and no new access decision.
27766
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
27767
+ * resolves a media row by its own id, so this needed no new plane and no new
27768
+ * access decision.
27709
27769
  */
27710
27770
  var MediaFileLiteSchema = object({
27711
- key: string(),
27771
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
27772
+ * (D482). It was the row's composite key, which embedded the owner. */
27773
+ mediaId: number().int(),
27712
27774
  kind: string(),
27713
27775
  url: string(),
27714
27776
  sizeBytes: number(),
@@ -27767,7 +27829,7 @@ method(object({
27767
27829
  }), method(object({
27768
27830
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
27769
27831
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
27770
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
27832
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
27771
27833
  * INPUT field: stripped by the hub router until the train ships, which
27772
27834
  * resolves to `false` and is exactly the intended default. */
27773
27835
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -29091,7 +29153,14 @@ var SceneReferenceSchema = object({
29091
29153
  modelId: string(),
29092
29154
  condition: SceneConditionSchema,
29093
29155
  capturedAt: number(),
29094
- thumbnailMediaId: string().optional(),
29156
+ /**
29157
+ * The reference thumbnail's media ROW id (D482).
29158
+ *
29159
+ * The name already said `mediaId` while the value was the row's composite
29160
+ * key — a leftover that read as done and was not. It is the row's own id
29161
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
29162
+ */
29163
+ thumbnailMediaId: number().int().optional(),
29095
29164
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
29096
29165
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
29097
29166
  * normalized rect frame a different piece of world, and the scene would
@@ -30539,7 +30608,7 @@ var StationaryObjectSchema = object({
30539
30608
  /** Enrichment label carried from the source track (identity / plate). */
30540
30609
  label: string().optional(),
30541
30610
  /** Native-resolution key-frame media key for the parked object's best image. */
30542
- keyFrameMediaKey: string().optional()
30611
+ keyFrameMediaId: number().int().optional()
30543
30612
  });
30544
30613
  var CameraOccupancySnapshotSchema = object({
30545
30614
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -31695,6 +31764,12 @@ Object.freeze({
31695
31764
  addonId: null,
31696
31765
  access: "create"
31697
31766
  },
31767
+ "dataStoreProvider.upsert": {
31768
+ capName: "data-store-provider",
31769
+ capScope: "system",
31770
+ addonId: null,
31771
+ access: "create"
31772
+ },
31698
31773
  "dayNight.getOptions": {
31699
31774
  capName: "day-night",
31700
31775
  capScope: "device",
@@ -35559,6 +35634,12 @@ Object.freeze({
35559
35634
  addonId: null,
35560
35635
  access: "create"
35561
35636
  },
35637
+ "settingsStore.upsert": {
35638
+ capName: "settings-store",
35639
+ capScope: "system",
35640
+ addonId: null,
35641
+ access: "create"
35642
+ },
35562
35643
  "smtpProvider.getStatus": {
35563
35644
  capName: "smtp-provider",
35564
35645
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -2,7 +2,7 @@ import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
2
2
  import { readFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- //#region ../types/dist/event-category-DAXzJeTX.mjs
5
+ //#region ../types/dist/event-category-ZyX6jcse.mjs
6
6
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
7
7
  EventCategory["SystemBoot"] = "system.boot";
8
8
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -563,7 +563,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
563
563
  * a package zone — a newly-appeared stationary object of a package class
564
564
  * that cleared the class / zone / dwell / size gates. Payload:
565
565
  * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
566
- * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
566
+ * entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
567
567
  * Telemetry (D8): the durable record is the `package-events` store row;
568
568
  * this bus topic drives notifier rules + live UI. See
569
569
  * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
@@ -5349,7 +5349,7 @@ var ZodIssueCode = {
5349
5349
  var ZodFirstPartyTypeKind;
5350
5350
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5351
5351
  //#endregion
5352
- //#region ../types/dist/sleep-BnujYGPe.mjs
5352
+ //#region ../types/dist/sleep-CnLyvg3w.mjs
5353
5353
  /**
5354
5354
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5355
5355
  * window to float samples (D455).
@@ -7300,13 +7300,30 @@ new Set([
7300
7300
  "scene",
7301
7301
  "motion",
7302
7302
  "object",
7303
- "audio"
7303
+ "audio",
7304
+ "mosaic"
7304
7305
  ]);
7305
- new Set([
7306
+ /**
7307
+ * The owner types that are event tables, in the order the event-media resolver
7308
+ * should consider them. Exported so a consumer asking "is this key an event?"
7309
+ * does not re-spell the list and drift from it.
7310
+ */
7311
+ var EVENT_OWNER_TYPES = [
7306
7312
  "motion",
7307
7313
  "object",
7308
7314
  "audio"
7309
- ]);
7315
+ ];
7316
+ /**
7317
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7318
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7319
+ * `(table, id)`).
7320
+ *
7321
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7322
+ * table would otherwise be accepted by the codec and refused at the door, with
7323
+ * nothing failing until a caller asked.
7324
+ */
7325
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7326
+ new Set(EVENT_OWNER_TYPES);
7310
7327
  /**
7311
7328
  * Build an `IAddonRouteProvider` from a list of routes. Implements
7312
7329
  * both the operator-facing `getRoutes` (returning route descriptors
@@ -12561,6 +12578,16 @@ method(object({
12561
12578
  filter: QueryFilterSchema.optional(),
12562
12579
  columns: array(string()).readonly().optional()
12563
12580
  }), array(SettingsRecordSchema).readonly()), method(object({
12581
+ namespace: string().optional(),
12582
+ collection: string(),
12583
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12584
+ * index on the collection. Never empty. */
12585
+ conflict: array(string()).readonly(),
12586
+ record: BulkRecordSchema
12587
+ }), object({
12588
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12589
+ * row's own id on an update. */
12590
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12564
12591
  namespace: string().optional(),
12565
12592
  collection: string(),
12566
12593
  record: object({
@@ -12695,6 +12722,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12695
12722
  id: union([string(), number()]) }), {
12696
12723
  kind: "mutation",
12697
12724
  auth: "admin"
12725
+ }), method(object({
12726
+ namespace: string().optional(),
12727
+ collection: string(),
12728
+ conflict: array(string()).readonly(),
12729
+ record: BulkRecordSchema
12730
+ }), object({ id: union([string(), number()]) }), {
12731
+ kind: "mutation",
12732
+ auth: "admin"
12698
12733
  }), method(object({
12699
12734
  namespace: string().optional(),
12700
12735
  collection: string(),
@@ -18925,8 +18960,8 @@ var TrackPositionSchema = object({
18925
18960
  var TrackSnapshotSchema = object({
18926
18961
  timestamp: number(),
18927
18962
  position: TrackPositionSchema,
18928
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
18929
- mediaKey: string()
18963
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
18964
+ mediaId: number().int()
18930
18965
  });
18931
18966
  /**
18932
18967
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19530,14 +19565,14 @@ var ObjectEventSchema = object({
19530
19565
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19531
19566
  frameWidth: number().optional(),
19532
19567
  frameHeight: number().optional(),
19533
- /** MediaStore key for the crop attached to this event (if any). */
19534
- mediaKey: string().optional(),
19535
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19568
+ /** Media row id of the crop attached to this event (if any) — D482. */
19569
+ mediaId: number().int().optional(),
19570
+ /** Design B: media row id of the track's native-resolution key frame (the
19536
19571
  * best-detection full frame). Resolve via the event-media data-plane
19537
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19572
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19538
19573
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19539
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19540
- keyFrameMediaKey: string().optional(),
19574
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19575
+ keyFrameMediaId: number().int().optional(),
19541
19576
  /** Populated by B5 (recording playback URL for this event). */
19542
19577
  mediaUrl: string().optional(),
19543
19578
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19587,7 +19622,7 @@ var MediaFileKindEnum = _enum([
19587
19622
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19588
19623
  *
19589
19624
  * `url` points at the `event-media` data plane
19590
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19625
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19591
19626
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19592
19627
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19593
19628
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19595,10 +19630,13 @@ var MediaFileKindEnum = _enum([
19595
19630
  * `data-plane-access.ts` for the rule and the one gap it does not close
19596
19631
  * (per-device scoping).
19597
19632
  *
19598
- * The URL is built from the row's **stored** key, which is not always its
19599
- * published `kind`: a track's face/plate crop is stored as `crop` under
19633
+ * The URL is built from the row's own id, which since D482 says nothing about
19634
+ * the row's owner or kind — and that is the point. The published `kind` is not
19635
+ * the stored one (a track's face/plate crop is stored as `crop` under
19600
19636
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19601
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19637
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19638
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19639
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19602
19640
  *
19603
19641
  * ## `base64` is TRANSITIONAL and is going away
19604
19642
  *
@@ -19611,7 +19649,19 @@ var MediaFileKindEnum = _enum([
19611
19649
  * `analytics-query-facade.ts`; nothing else reads it.
19612
19650
  */
19613
19651
  var MediaFileSchema = object({
19614
- key: string(),
19652
+ /**
19653
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19654
+ *
19655
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19656
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19657
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19658
+ * different rows that spell the same number, and a track whose
19659
+ * `bestEventId` was an object event was served a motion event's snapshot —
19660
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19661
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19662
+ * at all.
19663
+ */
19664
+ mediaId: number().int(),
19615
19665
  kind: MediaFileKindEnum,
19616
19666
  sizeBytes: number(),
19617
19667
  timestamp: number()
@@ -19719,7 +19769,7 @@ var RetrainTrackSchema = object({
19719
19769
  });
19720
19770
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19721
19771
  var RetrainFrameCandidateSchema = object({
19722
- mediaKey: string(),
19772
+ mediaId: number().int(),
19723
19773
  kind: MediaFileKindEnum,
19724
19774
  timestamp: number(),
19725
19775
  sizeBytes: number().int(),
@@ -19733,7 +19783,7 @@ var RetrainFrameSchema = object({
19733
19783
  deviceId: number(),
19734
19784
  trackId: string(),
19735
19785
  /** Provenance only. It may already point at nothing — that is expected. */
19736
- sourceMediaKey: string(),
19786
+ sourceMediaId: number().int(),
19737
19787
  sourceKind: MediaFileKindEnum,
19738
19788
  sizeBytes: number().int(),
19739
19789
  width: number().int(),
@@ -19749,7 +19799,7 @@ var RetrainCopyRefusalSchema = _enum([
19749
19799
  var RetrainFrameSelectionSchema = object({
19750
19800
  copied: array(RetrainFrameSchema).readonly(),
19751
19801
  refused: array(object({
19752
- sourceMediaKey: string(),
19802
+ sourceMediaId: number().int(),
19753
19803
  reason: RetrainCopyRefusalSchema
19754
19804
  })).readonly()
19755
19805
  });
@@ -19757,7 +19807,7 @@ var RetrainFrameListSchema = object({
19757
19807
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19758
19808
  copies: array(RetrainFrameSchema).readonly(),
19759
19809
  /** What the page pre-selects — the native key frame when one survives. */
19760
- autoPickMediaKey: string().optional()
19810
+ autoPickMediaId: number().int().optional()
19761
19811
  });
19762
19812
  /** What the operator asked the assist to look for. */
19763
19813
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -19852,9 +19902,11 @@ var RecentTracksQueryInput = object({
19852
19902
  });
19853
19903
  /**
19854
19904
  * A Summary (D359): the per-camera session envelope that references tracks.
19855
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19856
- * served by the event-media plane by key), null until the first frame with a
19857
- * member visible has been materialised.
19905
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
19906
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
19907
+ * first frame with a member visible has been materialised (D482 — it was the
19908
+ * row's composite key, which embedded the owner and could name another table's
19909
+ * row once event ids became per-table rowids).
19858
19910
  */
19859
19911
  var SummarySchema = object({
19860
19912
  id: string(),
@@ -19863,7 +19915,7 @@ var SummarySchema = object({
19863
19915
  lastActiveAt: number(),
19864
19916
  sealedAt: number().nullable(),
19865
19917
  memberCount: number().int().nonnegative(),
19866
- groupShotKey: string().nullable()
19918
+ groupShotMediaId: number().int().nullable()
19867
19919
  });
19868
19920
  var SummariesQueryInput = object({
19869
19921
  deviceIds: array(number()).min(1),
@@ -20417,7 +20469,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20417
20469
  }), method(object({
20418
20470
  deviceId: number(),
20419
20471
  trackId: string(),
20420
- mediaKeys: array(string()).min(1)
20472
+ mediaIds: array(number().int()).min(1)
20421
20473
  }), RetrainFrameSelectionSchema, {
20422
20474
  kind: "mutation",
20423
20475
  auth: "admin"
@@ -20485,7 +20537,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20485
20537
  kind: "query",
20486
20538
  auth: "admin"
20487
20539
  }), method(object({
20488
- eventId: string(),
20540
+ /** Which of the three event tables owns the row. */
20541
+ ownerType: EventOwnerTypeSchema,
20542
+ /** The event's rowid in that table (D474: an event id is a number). */
20543
+ eventId: number().int(),
20489
20544
  kind: MediaFileKindEnum.optional(),
20490
20545
  deviceId: number()
20491
20546
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20496,7 +20551,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20496
20551
  trackId: string(),
20497
20552
  deviceId: number()
20498
20553
  }), array(MediaFileInfoSchema).readonly()), method(object({
20499
- eventId: string(),
20554
+ ownerType: EventOwnerTypeSchema,
20555
+ eventId: number().int(),
20500
20556
  deviceId: number()
20501
20557
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20502
20558
  kind: "mutation",
@@ -24959,8 +25015,8 @@ var IdentitySchema = object({
24959
25015
  id: string(),
24960
25016
  name: string(),
24961
25017
  sampleCount: number().int().nonnegative(),
24962
- coverMediaKey: string().optional(),
24963
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25018
+ coverMediaId: number().int().optional(),
25019
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
24964
25020
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
24965
25021
  coverBase64: string().optional()
24966
25022
  });
@@ -24986,8 +25042,8 @@ var IdentitySampleAuditRowSchema = object({
24986
25042
  enrolledAt: number().int(),
24987
25043
  deviceId: number().int().optional(),
24988
25044
  source: _enum(["detected", "photo"]),
24989
- /** The enrolled crop's media key, so the panel can show the evidence. */
24990
- mediaKey: string().optional(),
25045
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25046
+ mediaId: number().int().optional(),
24991
25047
  /**
24992
25048
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
24993
25049
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25056,15 +25112,15 @@ var FaceInfoSchema = object({
25056
25112
  */
25057
25113
  cropUrl: string().optional(),
25058
25114
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
25059
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
25115
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
25060
25116
  * legacy rows written before design B. */
25061
25117
  faceBbox: BoundingBoxSchema.optional(),
25062
25118
  /** Design B: MediaStore key of the track's native-resolution key frame.
25063
25119
  * Fetch the native JPEG via the event-media data-plane
25064
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
25120
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
25065
25121
  * track produced no key frame (e.g. native/onboard source) — the UI falls
25066
25122
  * back to the inline `base64` face crop. */
25067
- keyFrameMediaKey: string().optional(),
25123
+ keyFrameMediaId: number().int().optional(),
25068
25124
  /** Winning identity-match cosine (0..1) for this face's track, when an
25069
25125
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
25070
25126
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -25133,11 +25189,14 @@ var FaceClusterSchema = object({
25133
25189
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
25134
25190
  * dialog already rendering its key FRAME from the `event-media` plane.
25135
25191
  *
25136
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
25137
- * media key directly, so this needed no new plane and no new access decision.
25192
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
25193
+ * resolves a media row by its own id, so this needed no new plane and no new
25194
+ * access decision.
25138
25195
  */
25139
25196
  var MediaFileLiteSchema$1 = object({
25140
- key: string(),
25197
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
25198
+ * (D482). It was the row's composite key, which embedded the owner. */
25199
+ mediaId: number().int(),
25141
25200
  kind: string(),
25142
25201
  url: string(),
25143
25202
  sizeBytes: number(),
@@ -25154,7 +25213,7 @@ method(object({
25154
25213
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
25155
25214
  * four times and the viewer holds at `staleTime: 30_000`.
25156
25215
  *
25157
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
25216
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
25158
25217
  * the `event-media` plane serves that key `immutable` with an ETag.
25159
25218
  *
25160
25219
  * **This is an INPUT field, so it does not reach the addon until the
@@ -27622,8 +27681,8 @@ var VehicleSchema = object({
27622
27681
  id: string(),
27623
27682
  name: string(),
27624
27683
  sampleCount: number().int().nonnegative(),
27625
- coverMediaKey: string().optional(),
27626
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
27684
+ coverMediaId: number().int().optional(),
27685
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
27627
27686
  coverBase64: string().optional()
27628
27687
  });
27629
27688
  var VehicleSampleInfoSchema = object({
@@ -27656,7 +27715,7 @@ var PlateInfoSchema = object({
27656
27715
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
27657
27716
  plateBbox: BoundingBoxSchema.optional(),
27658
27717
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
27659
- keyFrameMediaKey: string().optional(),
27718
+ keyFrameMediaId: number().int().optional(),
27660
27719
  base64: string().optional(),
27661
27720
  /**
27662
27721
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -27677,11 +27736,14 @@ var PlateInfoSchema = object({
27677
27736
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
27678
27737
  * dialog already rendering its key FRAME from the `event-media` plane.
27679
27738
  *
27680
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
27681
- * media key directly, so this needed no new plane and no new access decision.
27739
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
27740
+ * resolves a media row by its own id, so this needed no new plane and no new
27741
+ * access decision.
27682
27742
  */
27683
27743
  var MediaFileLiteSchema = object({
27684
- key: string(),
27744
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
27745
+ * (D482). It was the row's composite key, which embedded the owner. */
27746
+ mediaId: number().int(),
27685
27747
  kind: string(),
27686
27748
  url: string(),
27687
27749
  sizeBytes: number(),
@@ -27740,7 +27802,7 @@ method(object({
27740
27802
  }), method(object({
27741
27803
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
27742
27804
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
27743
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
27805
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
27744
27806
  * INPUT field: stripped by the hub router until the train ships, which
27745
27807
  * resolves to `false` and is exactly the intended default. */
27746
27808
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -29064,7 +29126,14 @@ var SceneReferenceSchema = object({
29064
29126
  modelId: string(),
29065
29127
  condition: SceneConditionSchema,
29066
29128
  capturedAt: number(),
29067
- thumbnailMediaId: string().optional(),
29129
+ /**
29130
+ * The reference thumbnail's media ROW id (D482).
29131
+ *
29132
+ * The name already said `mediaId` while the value was the row's composite
29133
+ * key — a leftover that read as done and was not. It is the row's own id
29134
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
29135
+ */
29136
+ thumbnailMediaId: number().int().optional(),
29068
29137
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
29069
29138
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
29070
29139
  * normalized rect frame a different piece of world, and the scene would
@@ -30512,7 +30581,7 @@ var StationaryObjectSchema = object({
30512
30581
  /** Enrichment label carried from the source track (identity / plate). */
30513
30582
  label: string().optional(),
30514
30583
  /** Native-resolution key-frame media key for the parked object's best image. */
30515
- keyFrameMediaKey: string().optional()
30584
+ keyFrameMediaId: number().int().optional()
30516
30585
  });
30517
30586
  var CameraOccupancySnapshotSchema = object({
30518
30587
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -31668,6 +31737,12 @@ Object.freeze({
31668
31737
  addonId: null,
31669
31738
  access: "create"
31670
31739
  },
31740
+ "dataStoreProvider.upsert": {
31741
+ capName: "data-store-provider",
31742
+ capScope: "system",
31743
+ addonId: null,
31744
+ access: "create"
31745
+ },
31671
31746
  "dayNight.getOptions": {
31672
31747
  capName: "day-night",
31673
31748
  capScope: "device",
@@ -35532,6 +35607,12 @@ Object.freeze({
35532
35607
  addonId: null,
35533
35608
  access: "create"
35534
35609
  },
35610
+ "settingsStore.upsert": {
35611
+ capName: "settings-store",
35612
+ capScope: "system",
35613
+ addonId: null,
35614
+ access: "create"
35615
+ },
35535
35616
  "smtpProvider.getStatus": {
35536
35617
  capName: "smtp-provider",
35537
35618
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.102",
3
+ "version": "1.2.104",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",