@camstack/addon-provider-gree 0.2.97 → 0.2.99

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
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let dgram = require("dgram");
3
3
  let crypto$1 = require("crypto");
4
4
  let events = require("events");
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).
@@ -7316,13 +7316,30 @@ new Set([
7316
7316
  "scene",
7317
7317
  "motion",
7318
7318
  "object",
7319
- "audio"
7319
+ "audio",
7320
+ "mosaic"
7320
7321
  ]);
7321
- new Set([
7322
+ /**
7323
+ * The owner types that are event tables, in the order the event-media resolver
7324
+ * should consider them. Exported so a consumer asking "is this key an event?"
7325
+ * does not re-spell the list and drift from it.
7326
+ */
7327
+ var EVENT_OWNER_TYPES = [
7322
7328
  "motion",
7323
7329
  "object",
7324
7330
  "audio"
7325
- ]);
7331
+ ];
7332
+ /**
7333
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7334
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7335
+ * `(table, id)`).
7336
+ *
7337
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7338
+ * table would otherwise be accepted by the codec and refused at the door, with
7339
+ * nothing failing until a caller asked.
7340
+ */
7341
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7342
+ new Set(EVENT_OWNER_TYPES);
7326
7343
  var EncodeProfileSchema = object({
7327
7344
  video: object({
7328
7345
  codec: _enum([
@@ -12521,6 +12538,16 @@ method(object({
12521
12538
  filter: QueryFilterSchema.optional(),
12522
12539
  columns: array(string()).readonly().optional()
12523
12540
  }), array(SettingsRecordSchema).readonly()), method(object({
12541
+ namespace: string().optional(),
12542
+ collection: string(),
12543
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12544
+ * index on the collection. Never empty. */
12545
+ conflict: array(string()).readonly(),
12546
+ record: BulkRecordSchema
12547
+ }), object({
12548
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12549
+ * row's own id on an update. */
12550
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12524
12551
  namespace: string().optional(),
12525
12552
  collection: string(),
12526
12553
  record: object({
@@ -12655,6 +12682,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12655
12682
  id: union([string(), number()]) }), {
12656
12683
  kind: "mutation",
12657
12684
  auth: "admin"
12685
+ }), method(object({
12686
+ namespace: string().optional(),
12687
+ collection: string(),
12688
+ conflict: array(string()).readonly(),
12689
+ record: BulkRecordSchema
12690
+ }), object({ id: union([string(), number()]) }), {
12691
+ kind: "mutation",
12692
+ auth: "admin"
12658
12693
  }), method(object({
12659
12694
  namespace: string().optional(),
12660
12695
  collection: string(),
@@ -19137,8 +19172,8 @@ var TrackPositionSchema = object({
19137
19172
  var TrackSnapshotSchema = object({
19138
19173
  timestamp: number(),
19139
19174
  position: TrackPositionSchema,
19140
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
19141
- mediaKey: string()
19175
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
19176
+ mediaId: number().int()
19142
19177
  });
19143
19178
  /**
19144
19179
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19742,14 +19777,14 @@ var ObjectEventSchema = object({
19742
19777
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19743
19778
  frameWidth: number().optional(),
19744
19779
  frameHeight: number().optional(),
19745
- /** MediaStore key for the crop attached to this event (if any). */
19746
- mediaKey: string().optional(),
19747
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19780
+ /** Media row id of the crop attached to this event (if any) — D482. */
19781
+ mediaId: number().int().optional(),
19782
+ /** Design B: media row id of the track's native-resolution key frame (the
19748
19783
  * best-detection full frame). Resolve via the event-media data-plane
19749
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19784
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19750
19785
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19751
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19752
- keyFrameMediaKey: string().optional(),
19786
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19787
+ keyFrameMediaId: number().int().optional(),
19753
19788
  /** Populated by B5 (recording playback URL for this event). */
19754
19789
  mediaUrl: string().optional(),
19755
19790
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19799,7 +19834,7 @@ var MediaFileKindEnum = _enum([
19799
19834
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19800
19835
  *
19801
19836
  * `url` points at the `event-media` data plane
19802
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19837
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19803
19838
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19804
19839
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19805
19840
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19807,10 +19842,13 @@ var MediaFileKindEnum = _enum([
19807
19842
  * `data-plane-access.ts` for the rule and the one gap it does not close
19808
19843
  * (per-device scoping).
19809
19844
  *
19810
- * The URL is built from the row's **stored** key, which is not always its
19811
- * published `kind`: a track's face/plate crop is stored as `crop` under
19845
+ * The URL is built from the row's own id, which since D482 says nothing about
19846
+ * the row's owner or kind — and that is the point. The published `kind` is not
19847
+ * the stored one (a track's face/plate crop is stored as `crop` under
19812
19848
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19813
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19849
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19850
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19851
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19814
19852
  *
19815
19853
  * ## `base64` is TRANSITIONAL and is going away
19816
19854
  *
@@ -19823,7 +19861,19 @@ var MediaFileKindEnum = _enum([
19823
19861
  * `analytics-query-facade.ts`; nothing else reads it.
19824
19862
  */
19825
19863
  var MediaFileSchema = object({
19826
- key: string(),
19864
+ /**
19865
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19866
+ *
19867
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19868
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19869
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19870
+ * different rows that spell the same number, and a track whose
19871
+ * `bestEventId` was an object event was served a motion event's snapshot —
19872
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19873
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19874
+ * at all.
19875
+ */
19876
+ mediaId: number().int(),
19827
19877
  kind: MediaFileKindEnum,
19828
19878
  sizeBytes: number(),
19829
19879
  timestamp: number()
@@ -19931,7 +19981,7 @@ var RetrainTrackSchema = object({
19931
19981
  });
19932
19982
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19933
19983
  var RetrainFrameCandidateSchema = object({
19934
- mediaKey: string(),
19984
+ mediaId: number().int(),
19935
19985
  kind: MediaFileKindEnum,
19936
19986
  timestamp: number(),
19937
19987
  sizeBytes: number().int(),
@@ -19945,7 +19995,7 @@ var RetrainFrameSchema = object({
19945
19995
  deviceId: number(),
19946
19996
  trackId: string(),
19947
19997
  /** Provenance only. It may already point at nothing — that is expected. */
19948
- sourceMediaKey: string(),
19998
+ sourceMediaId: number().int(),
19949
19999
  sourceKind: MediaFileKindEnum,
19950
20000
  sizeBytes: number().int(),
19951
20001
  width: number().int(),
@@ -19961,7 +20011,7 @@ var RetrainCopyRefusalSchema = _enum([
19961
20011
  var RetrainFrameSelectionSchema = object({
19962
20012
  copied: array(RetrainFrameSchema).readonly(),
19963
20013
  refused: array(object({
19964
- sourceMediaKey: string(),
20014
+ sourceMediaId: number().int(),
19965
20015
  reason: RetrainCopyRefusalSchema
19966
20016
  })).readonly()
19967
20017
  });
@@ -19969,7 +20019,7 @@ var RetrainFrameListSchema = object({
19969
20019
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19970
20020
  copies: array(RetrainFrameSchema).readonly(),
19971
20021
  /** What the page pre-selects — the native key frame when one survives. */
19972
- autoPickMediaKey: string().optional()
20022
+ autoPickMediaId: number().int().optional()
19973
20023
  });
19974
20024
  /** What the operator asked the assist to look for. */
19975
20025
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -20064,9 +20114,11 @@ var RecentTracksQueryInput = object({
20064
20114
  });
20065
20115
  /**
20066
20116
  * A Summary (D359): the per-camera session envelope that references tracks.
20067
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
20068
- * served by the event-media plane by key), null until the first frame with a
20069
- * member visible has been materialised.
20117
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
20118
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
20119
+ * first frame with a member visible has been materialised (D482 — it was the
20120
+ * row's composite key, which embedded the owner and could name another table's
20121
+ * row once event ids became per-table rowids).
20070
20122
  */
20071
20123
  var SummarySchema = object({
20072
20124
  id: string(),
@@ -20075,7 +20127,7 @@ var SummarySchema = object({
20075
20127
  lastActiveAt: number(),
20076
20128
  sealedAt: number().nullable(),
20077
20129
  memberCount: number().int().nonnegative(),
20078
- groupShotKey: string().nullable()
20130
+ groupShotMediaId: number().int().nullable()
20079
20131
  });
20080
20132
  var SummariesQueryInput = object({
20081
20133
  deviceIds: array(number()).min(1),
@@ -20629,7 +20681,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20629
20681
  }), method(object({
20630
20682
  deviceId: number(),
20631
20683
  trackId: string(),
20632
- mediaKeys: array(string()).min(1)
20684
+ mediaIds: array(number().int()).min(1)
20633
20685
  }), RetrainFrameSelectionSchema, {
20634
20686
  kind: "mutation",
20635
20687
  auth: "admin"
@@ -20697,7 +20749,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20697
20749
  kind: "query",
20698
20750
  auth: "admin"
20699
20751
  }), method(object({
20700
- eventId: string(),
20752
+ /** Which of the three event tables owns the row. */
20753
+ ownerType: EventOwnerTypeSchema,
20754
+ /** The event's rowid in that table (D474: an event id is a number). */
20755
+ eventId: number().int(),
20701
20756
  kind: MediaFileKindEnum.optional(),
20702
20757
  deviceId: number()
20703
20758
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20708,7 +20763,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20708
20763
  trackId: string(),
20709
20764
  deviceId: number()
20710
20765
  }), array(MediaFileInfoSchema).readonly()), method(object({
20711
- eventId: string(),
20766
+ ownerType: EventOwnerTypeSchema,
20767
+ eventId: number().int(),
20712
20768
  deviceId: number()
20713
20769
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20714
20770
  kind: "mutation",
@@ -25901,8 +25957,8 @@ var IdentitySchema = object({
25901
25957
  id: string(),
25902
25958
  name: string(),
25903
25959
  sampleCount: number().int().nonnegative(),
25904
- coverMediaKey: string().optional(),
25905
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25960
+ coverMediaId: number().int().optional(),
25961
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
25906
25962
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
25907
25963
  coverBase64: string().optional()
25908
25964
  });
@@ -25928,8 +25984,8 @@ var IdentitySampleAuditRowSchema = object({
25928
25984
  enrolledAt: number().int(),
25929
25985
  deviceId: number().int().optional(),
25930
25986
  source: _enum(["detected", "photo"]),
25931
- /** The enrolled crop's media key, so the panel can show the evidence. */
25932
- mediaKey: string().optional(),
25987
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25988
+ mediaId: number().int().optional(),
25933
25989
  /**
25934
25990
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
25935
25991
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25998,15 +26054,15 @@ var FaceInfoSchema = object({
25998
26054
  */
25999
26055
  cropUrl: string().optional(),
26000
26056
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
26001
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
26057
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
26002
26058
  * legacy rows written before design B. */
26003
26059
  faceBbox: BoundingBoxSchema.optional(),
26004
26060
  /** Design B: MediaStore key of the track's native-resolution key frame.
26005
26061
  * Fetch the native JPEG via the event-media data-plane
26006
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
26062
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
26007
26063
  * track produced no key frame (e.g. native/onboard source) — the UI falls
26008
26064
  * back to the inline `base64` face crop. */
26009
- keyFrameMediaKey: string().optional(),
26065
+ keyFrameMediaId: number().int().optional(),
26010
26066
  /** Winning identity-match cosine (0..1) for this face's track, when an
26011
26067
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
26012
26068
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -26075,11 +26131,14 @@ var FaceClusterSchema = object({
26075
26131
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
26076
26132
  * dialog already rendering its key FRAME from the `event-media` plane.
26077
26133
  *
26078
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
26079
- * media key directly, so this needed no new plane and no new access decision.
26134
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
26135
+ * resolves a media row by its own id, so this needed no new plane and no new
26136
+ * access decision.
26080
26137
  */
26081
26138
  var MediaFileLiteSchema$1 = object({
26082
- key: string(),
26139
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
26140
+ * (D482). It was the row's composite key, which embedded the owner. */
26141
+ mediaId: number().int(),
26083
26142
  kind: string(),
26084
26143
  url: string(),
26085
26144
  sizeBytes: number(),
@@ -26096,7 +26155,7 @@ method(object({
26096
26155
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
26097
26156
  * four times and the viewer holds at `staleTime: 30_000`.
26098
26157
  *
26099
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
26158
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
26100
26159
  * the `event-media` plane serves that key `immutable` with an ETag.
26101
26160
  *
26102
26161
  * **This is an INPUT field, so it does not reach the addon until the
@@ -29459,8 +29518,8 @@ var VehicleSchema = object({
29459
29518
  id: string(),
29460
29519
  name: string(),
29461
29520
  sampleCount: number().int().nonnegative(),
29462
- coverMediaKey: string().optional(),
29463
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
29521
+ coverMediaId: number().int().optional(),
29522
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
29464
29523
  coverBase64: string().optional()
29465
29524
  });
29466
29525
  var VehicleSampleInfoSchema = object({
@@ -29493,7 +29552,7 @@ var PlateInfoSchema = object({
29493
29552
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
29494
29553
  plateBbox: BoundingBoxSchema.optional(),
29495
29554
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
29496
- keyFrameMediaKey: string().optional(),
29555
+ keyFrameMediaId: number().int().optional(),
29497
29556
  base64: string().optional(),
29498
29557
  /**
29499
29558
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -29514,11 +29573,14 @@ var PlateInfoSchema = object({
29514
29573
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
29515
29574
  * dialog already rendering its key FRAME from the `event-media` plane.
29516
29575
  *
29517
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
29518
- * media key directly, so this needed no new plane and no new access decision.
29576
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
29577
+ * resolves a media row by its own id, so this needed no new plane and no new
29578
+ * access decision.
29519
29579
  */
29520
29580
  var MediaFileLiteSchema = object({
29521
- key: string(),
29581
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
29582
+ * (D482). It was the row's composite key, which embedded the owner. */
29583
+ mediaId: number().int(),
29522
29584
  kind: string(),
29523
29585
  url: string(),
29524
29586
  sizeBytes: number(),
@@ -29577,7 +29639,7 @@ method(object({
29577
29639
  }), method(object({
29578
29640
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
29579
29641
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
29580
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
29642
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
29581
29643
  * INPUT field: stripped by the hub router until the train ships, which
29582
29644
  * resolves to `false` and is exactly the intended default. */
29583
29645
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -31146,7 +31208,14 @@ var SceneReferenceSchema = object({
31146
31208
  modelId: string(),
31147
31209
  condition: SceneConditionSchema,
31148
31210
  capturedAt: number(),
31149
- thumbnailMediaId: string().optional(),
31211
+ /**
31212
+ * The reference thumbnail's media ROW id (D482).
31213
+ *
31214
+ * The name already said `mediaId` while the value was the row's composite
31215
+ * key — a leftover that read as done and was not. It is the row's own id
31216
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
31217
+ */
31218
+ thumbnailMediaId: number().int().optional(),
31150
31219
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
31151
31220
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
31152
31221
  * normalized rect frame a different piece of world, and the scene would
@@ -33130,7 +33199,7 @@ var StationaryObjectSchema = object({
33130
33199
  /** Enrichment label carried from the source track (identity / plate). */
33131
33200
  label: string().optional(),
33132
33201
  /** Native-resolution key-frame media key for the parked object's best image. */
33133
- keyFrameMediaKey: string().optional()
33202
+ keyFrameMediaId: number().int().optional()
33134
33203
  });
33135
33204
  var CameraOccupancySnapshotSchema = object({
33136
33205
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -35868,6 +35937,12 @@ Object.freeze({
35868
35937
  addonId: null,
35869
35938
  access: "create"
35870
35939
  },
35940
+ "dataStoreProvider.upsert": {
35941
+ capName: "data-store-provider",
35942
+ capScope: "system",
35943
+ addonId: null,
35944
+ access: "create"
35945
+ },
35871
35946
  "dayNight.getOptions": {
35872
35947
  capName: "day-night",
35873
35948
  capScope: "device",
@@ -39732,6 +39807,12 @@ Object.freeze({
39732
39807
  addonId: null,
39733
39808
  access: "create"
39734
39809
  },
39810
+ "settingsStore.upsert": {
39811
+ capName: "settings-store",
39812
+ capScope: "system",
39813
+ addonId: null,
39814
+ access: "create"
39815
+ },
39735
39816
  "smtpProvider.getStatus": {
39736
39817
  capName: "smtp-provider",
39737
39818
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createSocket } from "dgram";
2
2
  import { createCipheriv, createDecipheriv } from "crypto";
3
3
  import { EventEmitter } from "events";
4
- //#region ../types/dist/event-category-DAXzJeTX.mjs
4
+ //#region ../types/dist/event-category-ZyX6jcse.mjs
5
5
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
6
6
  EventCategory["SystemBoot"] = "system.boot";
7
7
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -562,7 +562,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
562
562
  * a package zone — a newly-appeared stationary object of a package class
563
563
  * that cleared the class / zone / dwell / size gates. Payload:
564
564
  * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
565
- * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
565
+ * entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
566
566
  * Telemetry (D8): the durable record is the `package-events` store row;
567
567
  * this bus topic drives notifier rules + live UI. See
568
568
  * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
@@ -5348,7 +5348,7 @@ var ZodIssueCode = {
5348
5348
  var ZodFirstPartyTypeKind;
5349
5349
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5350
5350
  //#endregion
5351
- //#region ../types/dist/sleep-BnujYGPe.mjs
5351
+ //#region ../types/dist/sleep-CnLyvg3w.mjs
5352
5352
  /**
5353
5353
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5354
5354
  * window to float samples (D455).
@@ -7315,13 +7315,30 @@ new Set([
7315
7315
  "scene",
7316
7316
  "motion",
7317
7317
  "object",
7318
- "audio"
7318
+ "audio",
7319
+ "mosaic"
7319
7320
  ]);
7320
- new Set([
7321
+ /**
7322
+ * The owner types that are event tables, in the order the event-media resolver
7323
+ * should consider them. Exported so a consumer asking "is this key an event?"
7324
+ * does not re-spell the list and drift from it.
7325
+ */
7326
+ var EVENT_OWNER_TYPES = [
7321
7327
  "motion",
7322
7328
  "object",
7323
7329
  "audio"
7324
- ]);
7330
+ ];
7331
+ /**
7332
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7333
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7334
+ * `(table, id)`).
7335
+ *
7336
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7337
+ * table would otherwise be accepted by the codec and refused at the door, with
7338
+ * nothing failing until a caller asked.
7339
+ */
7340
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7341
+ new Set(EVENT_OWNER_TYPES);
7325
7342
  var EncodeProfileSchema = object({
7326
7343
  video: object({
7327
7344
  codec: _enum([
@@ -12520,6 +12537,16 @@ method(object({
12520
12537
  filter: QueryFilterSchema.optional(),
12521
12538
  columns: array(string()).readonly().optional()
12522
12539
  }), array(SettingsRecordSchema).readonly()), method(object({
12540
+ namespace: string().optional(),
12541
+ collection: string(),
12542
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12543
+ * index on the collection. Never empty. */
12544
+ conflict: array(string()).readonly(),
12545
+ record: BulkRecordSchema
12546
+ }), object({
12547
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12548
+ * row's own id on an update. */
12549
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12523
12550
  namespace: string().optional(),
12524
12551
  collection: string(),
12525
12552
  record: object({
@@ -12654,6 +12681,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12654
12681
  id: union([string(), number()]) }), {
12655
12682
  kind: "mutation",
12656
12683
  auth: "admin"
12684
+ }), method(object({
12685
+ namespace: string().optional(),
12686
+ collection: string(),
12687
+ conflict: array(string()).readonly(),
12688
+ record: BulkRecordSchema
12689
+ }), object({ id: union([string(), number()]) }), {
12690
+ kind: "mutation",
12691
+ auth: "admin"
12657
12692
  }), method(object({
12658
12693
  namespace: string().optional(),
12659
12694
  collection: string(),
@@ -19136,8 +19171,8 @@ var TrackPositionSchema = object({
19136
19171
  var TrackSnapshotSchema = object({
19137
19172
  timestamp: number(),
19138
19173
  position: TrackPositionSchema,
19139
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
19140
- mediaKey: string()
19174
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
19175
+ mediaId: number().int()
19141
19176
  });
19142
19177
  /**
19143
19178
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19741,14 +19776,14 @@ var ObjectEventSchema = object({
19741
19776
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19742
19777
  frameWidth: number().optional(),
19743
19778
  frameHeight: number().optional(),
19744
- /** MediaStore key for the crop attached to this event (if any). */
19745
- mediaKey: string().optional(),
19746
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19779
+ /** Media row id of the crop attached to this event (if any) — D482. */
19780
+ mediaId: number().int().optional(),
19781
+ /** Design B: media row id of the track's native-resolution key frame (the
19747
19782
  * best-detection full frame). Resolve via the event-media data-plane
19748
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19783
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19749
19784
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19750
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19751
- keyFrameMediaKey: string().optional(),
19785
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19786
+ keyFrameMediaId: number().int().optional(),
19752
19787
  /** Populated by B5 (recording playback URL for this event). */
19753
19788
  mediaUrl: string().optional(),
19754
19789
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19798,7 +19833,7 @@ var MediaFileKindEnum = _enum([
19798
19833
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19799
19834
  *
19800
19835
  * `url` points at the `event-media` data plane
19801
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19836
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19802
19837
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19803
19838
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19804
19839
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19806,10 +19841,13 @@ var MediaFileKindEnum = _enum([
19806
19841
  * `data-plane-access.ts` for the rule and the one gap it does not close
19807
19842
  * (per-device scoping).
19808
19843
  *
19809
- * The URL is built from the row's **stored** key, which is not always its
19810
- * published `kind`: a track's face/plate crop is stored as `crop` under
19844
+ * The URL is built from the row's own id, which since D482 says nothing about
19845
+ * the row's owner or kind — and that is the point. The published `kind` is not
19846
+ * the stored one (a track's face/plate crop is stored as `crop` under
19811
19847
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19812
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19848
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19849
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19850
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19813
19851
  *
19814
19852
  * ## `base64` is TRANSITIONAL and is going away
19815
19853
  *
@@ -19822,7 +19860,19 @@ var MediaFileKindEnum = _enum([
19822
19860
  * `analytics-query-facade.ts`; nothing else reads it.
19823
19861
  */
19824
19862
  var MediaFileSchema = object({
19825
- key: string(),
19863
+ /**
19864
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19865
+ *
19866
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19867
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19868
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19869
+ * different rows that spell the same number, and a track whose
19870
+ * `bestEventId` was an object event was served a motion event's snapshot —
19871
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19872
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19873
+ * at all.
19874
+ */
19875
+ mediaId: number().int(),
19826
19876
  kind: MediaFileKindEnum,
19827
19877
  sizeBytes: number(),
19828
19878
  timestamp: number()
@@ -19930,7 +19980,7 @@ var RetrainTrackSchema = object({
19930
19980
  });
19931
19981
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19932
19982
  var RetrainFrameCandidateSchema = object({
19933
- mediaKey: string(),
19983
+ mediaId: number().int(),
19934
19984
  kind: MediaFileKindEnum,
19935
19985
  timestamp: number(),
19936
19986
  sizeBytes: number().int(),
@@ -19944,7 +19994,7 @@ var RetrainFrameSchema = object({
19944
19994
  deviceId: number(),
19945
19995
  trackId: string(),
19946
19996
  /** Provenance only. It may already point at nothing — that is expected. */
19947
- sourceMediaKey: string(),
19997
+ sourceMediaId: number().int(),
19948
19998
  sourceKind: MediaFileKindEnum,
19949
19999
  sizeBytes: number().int(),
19950
20000
  width: number().int(),
@@ -19960,7 +20010,7 @@ var RetrainCopyRefusalSchema = _enum([
19960
20010
  var RetrainFrameSelectionSchema = object({
19961
20011
  copied: array(RetrainFrameSchema).readonly(),
19962
20012
  refused: array(object({
19963
- sourceMediaKey: string(),
20013
+ sourceMediaId: number().int(),
19964
20014
  reason: RetrainCopyRefusalSchema
19965
20015
  })).readonly()
19966
20016
  });
@@ -19968,7 +20018,7 @@ var RetrainFrameListSchema = object({
19968
20018
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19969
20019
  copies: array(RetrainFrameSchema).readonly(),
19970
20020
  /** What the page pre-selects — the native key frame when one survives. */
19971
- autoPickMediaKey: string().optional()
20021
+ autoPickMediaId: number().int().optional()
19972
20022
  });
19973
20023
  /** What the operator asked the assist to look for. */
19974
20024
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -20063,9 +20113,11 @@ var RecentTracksQueryInput = object({
20063
20113
  });
20064
20114
  /**
20065
20115
  * A Summary (D359): the per-camera session envelope that references tracks.
20066
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
20067
- * served by the event-media plane by key), null until the first frame with a
20068
- * member visible has been materialised.
20116
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
20117
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
20118
+ * first frame with a member visible has been materialised (D482 — it was the
20119
+ * row's composite key, which embedded the owner and could name another table's
20120
+ * row once event ids became per-table rowids).
20069
20121
  */
20070
20122
  var SummarySchema = object({
20071
20123
  id: string(),
@@ -20074,7 +20126,7 @@ var SummarySchema = object({
20074
20126
  lastActiveAt: number(),
20075
20127
  sealedAt: number().nullable(),
20076
20128
  memberCount: number().int().nonnegative(),
20077
- groupShotKey: string().nullable()
20129
+ groupShotMediaId: number().int().nullable()
20078
20130
  });
20079
20131
  var SummariesQueryInput = object({
20080
20132
  deviceIds: array(number()).min(1),
@@ -20628,7 +20680,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20628
20680
  }), method(object({
20629
20681
  deviceId: number(),
20630
20682
  trackId: string(),
20631
- mediaKeys: array(string()).min(1)
20683
+ mediaIds: array(number().int()).min(1)
20632
20684
  }), RetrainFrameSelectionSchema, {
20633
20685
  kind: "mutation",
20634
20686
  auth: "admin"
@@ -20696,7 +20748,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20696
20748
  kind: "query",
20697
20749
  auth: "admin"
20698
20750
  }), method(object({
20699
- eventId: string(),
20751
+ /** Which of the three event tables owns the row. */
20752
+ ownerType: EventOwnerTypeSchema,
20753
+ /** The event's rowid in that table (D474: an event id is a number). */
20754
+ eventId: number().int(),
20700
20755
  kind: MediaFileKindEnum.optional(),
20701
20756
  deviceId: number()
20702
20757
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20707,7 +20762,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20707
20762
  trackId: string(),
20708
20763
  deviceId: number()
20709
20764
  }), array(MediaFileInfoSchema).readonly()), method(object({
20710
- eventId: string(),
20765
+ ownerType: EventOwnerTypeSchema,
20766
+ eventId: number().int(),
20711
20767
  deviceId: number()
20712
20768
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20713
20769
  kind: "mutation",
@@ -25900,8 +25956,8 @@ var IdentitySchema = object({
25900
25956
  id: string(),
25901
25957
  name: string(),
25902
25958
  sampleCount: number().int().nonnegative(),
25903
- coverMediaKey: string().optional(),
25904
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25959
+ coverMediaId: number().int().optional(),
25960
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
25905
25961
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
25906
25962
  coverBase64: string().optional()
25907
25963
  });
@@ -25927,8 +25983,8 @@ var IdentitySampleAuditRowSchema = object({
25927
25983
  enrolledAt: number().int(),
25928
25984
  deviceId: number().int().optional(),
25929
25985
  source: _enum(["detected", "photo"]),
25930
- /** The enrolled crop's media key, so the panel can show the evidence. */
25931
- mediaKey: string().optional(),
25986
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25987
+ mediaId: number().int().optional(),
25932
25988
  /**
25933
25989
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
25934
25990
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25997,15 +26053,15 @@ var FaceInfoSchema = object({
25997
26053
  */
25998
26054
  cropUrl: string().optional(),
25999
26055
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
26000
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
26056
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
26001
26057
  * legacy rows written before design B. */
26002
26058
  faceBbox: BoundingBoxSchema.optional(),
26003
26059
  /** Design B: MediaStore key of the track's native-resolution key frame.
26004
26060
  * Fetch the native JPEG via the event-media data-plane
26005
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
26061
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
26006
26062
  * track produced no key frame (e.g. native/onboard source) — the UI falls
26007
26063
  * back to the inline `base64` face crop. */
26008
- keyFrameMediaKey: string().optional(),
26064
+ keyFrameMediaId: number().int().optional(),
26009
26065
  /** Winning identity-match cosine (0..1) for this face's track, when an
26010
26066
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
26011
26067
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -26074,11 +26130,14 @@ var FaceClusterSchema = object({
26074
26130
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
26075
26131
  * dialog already rendering its key FRAME from the `event-media` plane.
26076
26132
  *
26077
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
26078
- * media key directly, so this needed no new plane and no new access decision.
26133
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
26134
+ * resolves a media row by its own id, so this needed no new plane and no new
26135
+ * access decision.
26079
26136
  */
26080
26137
  var MediaFileLiteSchema$1 = object({
26081
- key: string(),
26138
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
26139
+ * (D482). It was the row's composite key, which embedded the owner. */
26140
+ mediaId: number().int(),
26082
26141
  kind: string(),
26083
26142
  url: string(),
26084
26143
  sizeBytes: number(),
@@ -26095,7 +26154,7 @@ method(object({
26095
26154
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
26096
26155
  * four times and the viewer holds at `staleTime: 30_000`.
26097
26156
  *
26098
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
26157
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
26099
26158
  * the `event-media` plane serves that key `immutable` with an ETag.
26100
26159
  *
26101
26160
  * **This is an INPUT field, so it does not reach the addon until the
@@ -29458,8 +29517,8 @@ var VehicleSchema = object({
29458
29517
  id: string(),
29459
29518
  name: string(),
29460
29519
  sampleCount: number().int().nonnegative(),
29461
- coverMediaKey: string().optional(),
29462
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
29520
+ coverMediaId: number().int().optional(),
29521
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
29463
29522
  coverBase64: string().optional()
29464
29523
  });
29465
29524
  var VehicleSampleInfoSchema = object({
@@ -29492,7 +29551,7 @@ var PlateInfoSchema = object({
29492
29551
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
29493
29552
  plateBbox: BoundingBoxSchema.optional(),
29494
29553
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
29495
- keyFrameMediaKey: string().optional(),
29554
+ keyFrameMediaId: number().int().optional(),
29496
29555
  base64: string().optional(),
29497
29556
  /**
29498
29557
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -29513,11 +29572,14 @@ var PlateInfoSchema = object({
29513
29572
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
29514
29573
  * dialog already rendering its key FRAME from the `event-media` plane.
29515
29574
  *
29516
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
29517
- * media key directly, so this needed no new plane and no new access decision.
29575
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
29576
+ * resolves a media row by its own id, so this needed no new plane and no new
29577
+ * access decision.
29518
29578
  */
29519
29579
  var MediaFileLiteSchema = object({
29520
- key: string(),
29580
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
29581
+ * (D482). It was the row's composite key, which embedded the owner. */
29582
+ mediaId: number().int(),
29521
29583
  kind: string(),
29522
29584
  url: string(),
29523
29585
  sizeBytes: number(),
@@ -29576,7 +29638,7 @@ method(object({
29576
29638
  }), method(object({
29577
29639
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
29578
29640
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
29579
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
29641
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
29580
29642
  * INPUT field: stripped by the hub router until the train ships, which
29581
29643
  * resolves to `false` and is exactly the intended default. */
29582
29644
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -31145,7 +31207,14 @@ var SceneReferenceSchema = object({
31145
31207
  modelId: string(),
31146
31208
  condition: SceneConditionSchema,
31147
31209
  capturedAt: number(),
31148
- thumbnailMediaId: string().optional(),
31210
+ /**
31211
+ * The reference thumbnail's media ROW id (D482).
31212
+ *
31213
+ * The name already said `mediaId` while the value was the row's composite
31214
+ * key — a leftover that read as done and was not. It is the row's own id
31215
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
31216
+ */
31217
+ thumbnailMediaId: number().int().optional(),
31149
31218
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
31150
31219
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
31151
31220
  * normalized rect frame a different piece of world, and the scene would
@@ -33129,7 +33198,7 @@ var StationaryObjectSchema = object({
33129
33198
  /** Enrichment label carried from the source track (identity / plate). */
33130
33199
  label: string().optional(),
33131
33200
  /** Native-resolution key-frame media key for the parked object's best image. */
33132
- keyFrameMediaKey: string().optional()
33201
+ keyFrameMediaId: number().int().optional()
33133
33202
  });
33134
33203
  var CameraOccupancySnapshotSchema = object({
33135
33204
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -35867,6 +35936,12 @@ Object.freeze({
35867
35936
  addonId: null,
35868
35937
  access: "create"
35869
35938
  },
35939
+ "dataStoreProvider.upsert": {
35940
+ capName: "data-store-provider",
35941
+ capScope: "system",
35942
+ addonId: null,
35943
+ access: "create"
35944
+ },
35870
35945
  "dayNight.getOptions": {
35871
35946
  capName: "day-night",
35872
35947
  capScope: "device",
@@ -39731,6 +39806,12 @@ Object.freeze({
39731
39806
  addonId: null,
39732
39807
  access: "create"
39733
39808
  },
39809
+ "settingsStore.upsert": {
39810
+ capName: "settings-store",
39811
+ capScope: "system",
39812
+ addonId: null,
39813
+ access: "create"
39814
+ },
39734
39815
  "smtpProvider.getStatus": {
39735
39816
  capName: "smtp-provider",
39736
39817
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-gree",
3
- "version": "0.2.97",
3
+ "version": "0.2.99",
4
4
  "description": "Gree air-conditioner device-provider addon for CamStack — wraps the @apocaliss92/nodegree local-UDP client (LAN discovery + AES control), exposing climate-control and fan-control",
5
5
  "keywords": [
6
6
  "camstack",