@camstack/addon-provider-tuya 0.2.140 → 0.2.142

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -819,7 +819,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
819
819
  return [...byId.values()];
820
820
  }
821
821
  //#endregion
822
- //#region ../types/dist/event-category-7pZEBmVg.mjs
822
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
823
823
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
824
824
  EventCategory["SystemBoot"] = "system.boot";
825
825
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1136,6 +1136,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1136
1136
  */
1137
1137
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
1138
1138
  /**
1139
+ * A camera's motion source has fired constantly with no subject for an hour
1140
+ * (motion duty or session count over the bar, zero detections) — it is not
1141
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
1142
+ * {@link PipelineMotionCalm}.
1143
+ */
1144
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
1145
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
1146
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
1147
+ /**
1139
1148
  * Per-camera pipeline config was mutated by the orchestrator
1140
1149
  * (3-level settings change via `setAgentAddonDefaults` /
1141
1150
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -6242,7 +6251,7 @@ var ZodIssueCode = {
6242
6251
  var ZodFirstPartyTypeKind;
6243
6252
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6244
6253
  //#endregion
6245
- //#region ../types/dist/sleep-CueztlR1.mjs
6254
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
6246
6255
  /**
6247
6256
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6248
6257
  * window to float samples (D455).
@@ -8771,7 +8780,7 @@ var EntryDescriptorSchema = object({
8771
8780
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
8772
8781
  fields: record(string(), unknown())
8773
8782
  }).strict();
8774
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
8783
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
8775
8784
  var RecordKindDeclarationSchema = object({
8776
8785
  database: _enum(RECORD_DATABASES).default("settings"),
8777
8786
  class: _enum(RECORD_CLASSES),
@@ -8790,14 +8799,6 @@ var RecordKindDeclarationSchema = object({
8790
8799
  secretPaths: array(string().min(1)).default([]),
8791
8800
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8792
8801
  secretArrayKeys: record(string(), string()).default({}),
8793
- /**
8794
- * RETIRED (D900): the legacy table a kind adopted from during the records
8795
- * migration. Nothing declares it any more and nothing reads it; the schema
8796
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8797
- * (an orphaned kind is never redeclared) and an addon built before the
8798
- * removal still sends it. Never set it.
8799
- */
8800
- adoptsFrom: string().min(1).optional(),
8801
8802
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8802
8803
  transactFamily: string().min(1).optional(),
8803
8804
  entry: EntryDescriptorSchema.optional()
@@ -13475,17 +13476,6 @@ object({
13475
13476
  createdAt: number(),
13476
13477
  updatedAt: number()
13477
13478
  });
13478
- object({
13479
- id: string(),
13480
- label: string(),
13481
- isAdmin: boolean().default(false),
13482
- allowedProviders: AllowedProviderSchema,
13483
- allowedDevices: AllowedDevicesSchema,
13484
- tokenHash: string(),
13485
- tokenPrefix: string(),
13486
- createdAt: number(),
13487
- lastUsedAt: number().optional()
13488
- });
13489
13479
  object({
13490
13480
  id: string(),
13491
13481
  userId: string(),
@@ -17467,16 +17457,36 @@ var RecordKindStateSchema = _enum([
17467
17457
  var DeclareKindResultSchema = object({
17468
17458
  kindId: number().int(),
17469
17459
  state: RecordKindStateSchema,
17470
- createdIndexes: array(string()),
17471
- /**
17472
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
17473
- * it stays on the wire, null, because an addon built before the removal reads
17474
- * an ABSENT field as "adoption pending" and refuses to start.
17475
- */
17476
- adoptionPending: _null()
17460
+ createdIndexes: array(string())
17477
17461
  });
17478
17462
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
17479
17463
  var SecretRefsList = array(string());
17464
+ /**
17465
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
17466
+ * All ops of one call share ONE database file and ONE `transactFamily`.
17467
+ */
17468
+ var RecordTransactOpSchema = discriminatedUnion("op", [
17469
+ object({
17470
+ op: literal("put"),
17471
+ kind: RecordKindNameSchema,
17472
+ record: RecordInputSchema,
17473
+ ifRev: number().int().min(0).optional()
17474
+ }),
17475
+ object({
17476
+ op: literal("patch"),
17477
+ kind: RecordKindNameSchema,
17478
+ id: RecordIdSchema,
17479
+ data: RecordBodySchema,
17480
+ at: number().int().nullable().optional(),
17481
+ expiresAt: number().int().nullable().optional(),
17482
+ ifRev: number().int().min(1).optional()
17483
+ }),
17484
+ object({
17485
+ op: literal("delete"),
17486
+ kind: RecordKindNameSchema,
17487
+ id: RecordIdSchema
17488
+ })
17489
+ ]);
17480
17490
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
17481
17491
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
17482
17492
  kind: "mutation",
@@ -17583,6 +17593,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
17583
17593
  }), {
17584
17594
  kind: "mutation",
17585
17595
  auth: "admin"
17596
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
17597
+ results: array(object({
17598
+ rev: number().int().nullable(),
17599
+ deleted: boolean()
17600
+ })),
17601
+ releasedRefs: SecretRefsList,
17602
+ secretRefs: SecretRefsList
17603
+ }), {
17604
+ kind: "mutation",
17605
+ auth: "admin"
17586
17606
  }), method(object({
17587
17607
  deviceId: number().int(),
17588
17608
  kinds: array(RecordKindNameSchema).optional()
@@ -43194,9 +43214,13 @@ var NcSystemEventKindSchema = _enum([
43194
43214
  "node-updating",
43195
43215
  "node-inference-unavailable",
43196
43216
  "detection-blind",
43217
+ "motion-noisy",
43218
+ "motion-calm",
43197
43219
  "recording-stalled",
43198
43220
  "recording-healthy",
43199
43221
  "recording-degraded",
43222
+ "device-attention-required",
43223
+ "device-attention-resolved",
43200
43224
  "storage-location-low",
43201
43225
  "storage-location-critical",
43202
43226
  "storage-location-ok",
@@ -48757,7 +48781,6 @@ var RecommendationReasonSchema = discriminatedUnion("kind", [
48757
48781
  modelId: string()
48758
48782
  }),
48759
48783
  object({ kind: literal("cpu-device") }),
48760
- object({ kind: literal("coral-untouched") }),
48761
48784
  object({ kind: literal("device-disabled") }),
48762
48785
  object({ kind: literal("device-unavailable") }),
48763
48786
  object({ kind: literal("node-offline") }),
@@ -48855,11 +48878,6 @@ var AutoTuneWarningSchema = discriminatedUnion("kind", [
48855
48878
  kind: literal("detector-store-unreadable"),
48856
48879
  error: string()
48857
48880
  }),
48858
- object({
48859
- kind: literal("coral-enabled"),
48860
- nodeId: string(),
48861
- deviceKey: string()
48862
- }),
48863
48881
  object({
48864
48882
  kind: literal("custom-pin-kept"),
48865
48883
  nodeId: string(),
@@ -56528,6 +56546,16 @@ var DishwasherStatusSchema = object({
56528
56546
  powerState: string().nullable(),
56529
56547
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
56530
56548
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
56549
+ /**
56550
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
56551
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
56552
+ * when none is reported. A cleared reminder is not an unknown one.
56553
+ */
56554
+ filterCleaningDue: boolean().nullable(),
56555
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
56556
+ machineCareDue: boolean().nullable(),
56557
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
56558
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
56531
56559
  /** Option states: null when the appliance does not expose the option or has not said. */
56532
56560
  halfLoad: boolean().nullable(),
56533
56561
  hygienePlus: boolean().nullable(),
@@ -65178,16 +65206,6 @@ var UpdateUserInputSchema = object({
65178
65206
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
65179
65207
  scopes: array(TokenScopeSchema).optional()
65180
65208
  });
65181
- var ApiKeySummarySchema = object({
65182
- id: string(),
65183
- label: string(),
65184
- isAdmin: boolean().default(false),
65185
- allowedProviders: union([array(string()), literal("*")]).optional(),
65186
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
65187
- tokenPrefix: string(),
65188
- createdAt: number(),
65189
- lastUsedAt: number().optional()
65190
- });
65191
65209
  var OauthSessionSummarySchema = object({
65192
65210
  id: string(),
65193
65211
  userId: string(),
@@ -65209,8 +65227,7 @@ var TotpStatusSchema = object({
65209
65227
  confirmedAt: number().nullable()
65210
65228
  });
65211
65229
  /**
65212
- * user-management — singleton capability for user accounts and the
65213
- * legacy API-key rows.
65230
+ * user-management — singleton capability for user accounts.
65214
65231
  *
65215
65232
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
65216
65233
  * — the subset check on `setUserScopes` is moot
@@ -65266,10 +65283,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
65266
65283
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
65267
65284
  kind: "mutation",
65268
65285
  access: "view"
65269
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
65270
- kind: "mutation",
65271
- auth: "admin",
65272
- access: "delete"
65273
65286
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
65274
65287
  kind: "mutation",
65275
65288
  auth: "admin",
@@ -74725,6 +74738,12 @@ Object.freeze({
74725
74738
  addonId: null,
74726
74739
  access: "view"
74727
74740
  },
74741
+ "records.transact": {
74742
+ capName: "records",
74743
+ capScope: "system",
74744
+ addonId: null,
74745
+ access: "create"
74746
+ },
74728
74747
  "sceneMonitor.captureReference": {
74729
74748
  capName: "scene-monitor",
74730
74749
  capScope: "device",
@@ -76057,12 +76076,6 @@ Object.freeze({
76057
76076
  addonId: null,
76058
76077
  access: "view"
76059
76078
  },
76060
- "userManagement.listApiKeys": {
76061
- capName: "user-management",
76062
- capScope: "system",
76063
- addonId: null,
76064
- access: "view"
76065
- },
76066
76079
  "userManagement.listExternalIdentities": {
76067
76080
  capName: "user-management",
76068
76081
  capScope: "system",
@@ -76117,12 +76130,6 @@ Object.freeze({
76117
76130
  addonId: null,
76118
76131
  access: "create"
76119
76132
  },
76120
- "userManagement.revokeApiKey": {
76121
- capName: "user-management",
76122
- capScope: "system",
76123
- addonId: null,
76124
- access: "delete"
76125
- },
76126
76133
  "userManagement.revokeOauthSession": {
76127
76134
  capName: "user-management",
76128
76135
  capScope: "system",
@@ -79487,9 +79494,13 @@ new Map(Object.entries({
79487
79494
  "stream-online": "device-events",
79488
79495
  "stream-offline": "device-events",
79489
79496
  "detection-blind": "device-events",
79497
+ "motion-noisy": "device-events",
79498
+ "motion-calm": "device-events",
79490
79499
  "recording-stalled": "device-events",
79491
79500
  "recording-healthy": "device-events",
79492
79501
  "recording-degraded": "device-events",
79502
+ "device-attention-required": "device-events",
79503
+ "device-attention-resolved": "device-events",
79493
79504
  "node-online": "system",
79494
79505
  "node-offline": "system",
79495
79506
  "node-restarting": "system",
@@ -79572,6 +79583,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79572
79583
  label: "Detecting nothing",
79573
79584
  kinds: ["detection-blind"]
79574
79585
  },
79586
+ {
79587
+ id: "motion-noise",
79588
+ family: "device-events",
79589
+ label: "Motion without a subject",
79590
+ kinds: ["motion-noisy", "motion-calm"]
79591
+ },
79575
79592
  {
79576
79593
  id: "recording",
79577
79594
  family: "device-events",
@@ -79582,6 +79599,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79582
79599
  "recording-degraded"
79583
79600
  ]
79584
79601
  },
79602
+ {
79603
+ id: "device-attention",
79604
+ family: "device-events",
79605
+ label: "Needs attention",
79606
+ kinds: ["device-attention-required", "device-attention-resolved"]
79607
+ },
79585
79608
  {
79586
79609
  id: "nodes",
79587
79610
  family: "system",
@@ -79721,6 +79744,7 @@ var ALERT_EPISODE = [
79721
79744
  "alert-error",
79722
79745
  "alert-critical-resolved"
79723
79746
  ];
79747
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
79724
79748
  var UPDATES = [
79725
79749
  "addon-update-available",
79726
79750
  "server-update-available",
@@ -79750,9 +79774,12 @@ var DEVICE_EVENTS = [
79750
79774
  "stream-online",
79751
79775
  "stream-offline",
79752
79776
  "detection-blind",
79777
+ "motion-noisy",
79778
+ "motion-calm",
79753
79779
  "recording-stalled",
79754
79780
  "recording-healthy",
79755
79781
  "recording-degraded",
79782
+ ...DEVICE_ATTENTION,
79756
79783
  ...ALARM
79757
79784
  ];
79758
79785
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -79920,7 +79947,9 @@ var STATE_SUMMARY_VARS = [
79920
79947
  [...RULE_TEXT],
79921
79948
  [...RULE_TEXT],
79922
79949
  [...RULE_TEXT],
79923
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79950
+ [...RULE_TEXT],
79951
+ [...RULE_TEXT],
79952
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79924
79953
  [...RULE_TEXT],
79925
79954
  [...RULE_TEXT],
79926
79955
  [...RULE_TEXT],
@@ -79942,11 +79971,11 @@ var STATE_SUMMARY_VARS = [
79942
79971
  [...RULE_TEXT],
79943
79972
  [...RULE_TEXT],
79944
79973
  [...RULE_TEXT],
79974
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79945
79975
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79976
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79946
79977
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79947
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79948
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79949
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79978
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79950
79979
  [...RULE_TEXT],
79951
79980
  [...RULE_TEXT],
79952
79981
  [...RULE_TEXT],
@@ -80022,6 +80051,15 @@ new Map([
80022
80051
  snapshotLabel: "Tanks low or full now",
80023
80052
  snapshotSection: "tanks"
80024
80053
  },
80054
+ {
80055
+ id: "motion-noise",
80056
+ family: "device-events",
80057
+ label: "Motion without a subject (constant / calm again)",
80058
+ bad: ["motion-noisy"],
80059
+ recovery: ["motion-calm"],
80060
+ snapshotLabel: "Cameras with constant motion now",
80061
+ snapshotSection: null
80062
+ },
80025
80063
  {
80026
80064
  id: "recording-health",
80027
80065
  family: "device-events",
@@ -80031,6 +80069,15 @@ new Map([
80031
80069
  snapshotLabel: "Recordings stalled now",
80032
80070
  snapshotSection: null
80033
80071
  },
80072
+ {
80073
+ id: "device-attention",
80074
+ family: "device-events",
80075
+ label: "Device needs attention (raised / resolved)",
80076
+ bad: ["device-attention-required"],
80077
+ recovery: ["device-attention-resolved"],
80078
+ snapshotLabel: "Devices needing attention now",
80079
+ snapshotSection: null
80080
+ },
80034
80081
  {
80035
80082
  id: "node-connectivity",
80036
80083
  family: "system",
@@ -80667,7 +80714,7 @@ function buildConnectionFormSchema() {
80667
80714
  id: "credentials",
80668
80715
  title: "Tuya IoT cloud project",
80669
80716
  titleKey: "provider-tuya:connection.s_credentials.title",
80670
- description: "Create a free project at iot.tuya.com, link your Smart Life / Tuya app account to it, and paste the project's Access ID and Access Secret. CamStack uses them to fetch each device's local key, then controls the devices directly over your LAN (no ongoing cloud).",
80717
+ description: "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
80671
80718
  descriptionKey: "provider-tuya:connection.s_credentials.description",
80672
80719
  columns: 1,
80673
80720
  fields: [{
package/dist/addon.mjs CHANGED
@@ -818,7 +818,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
818
818
  return [...byId.values()];
819
819
  }
820
820
  //#endregion
821
- //#region ../types/dist/event-category-7pZEBmVg.mjs
821
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
822
822
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
823
823
  EventCategory["SystemBoot"] = "system.boot";
824
824
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1135,6 +1135,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1135
1135
  */
1136
1136
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
1137
1137
  /**
1138
+ * A camera's motion source has fired constantly with no subject for an hour
1139
+ * (motion duty or session count over the bar, zero detections) — it is not
1140
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
1141
+ * {@link PipelineMotionCalm}.
1142
+ */
1143
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
1144
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
1145
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
1146
+ /**
1138
1147
  * Per-camera pipeline config was mutated by the orchestrator
1139
1148
  * (3-level settings change via `setAgentAddonDefaults` /
1140
1149
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -6241,7 +6250,7 @@ var ZodIssueCode = {
6241
6250
  var ZodFirstPartyTypeKind;
6242
6251
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6243
6252
  //#endregion
6244
- //#region ../types/dist/sleep-CueztlR1.mjs
6253
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
6245
6254
  /**
6246
6255
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6247
6256
  * window to float samples (D455).
@@ -8770,7 +8779,7 @@ var EntryDescriptorSchema = object({
8770
8779
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
8771
8780
  fields: record(string(), unknown())
8772
8781
  }).strict();
8773
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
8782
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
8774
8783
  var RecordKindDeclarationSchema = object({
8775
8784
  database: _enum(RECORD_DATABASES).default("settings"),
8776
8785
  class: _enum(RECORD_CLASSES),
@@ -8789,14 +8798,6 @@ var RecordKindDeclarationSchema = object({
8789
8798
  secretPaths: array(string().min(1)).default([]),
8790
8799
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8791
8800
  secretArrayKeys: record(string(), string()).default({}),
8792
- /**
8793
- * RETIRED (D900): the legacy table a kind adopted from during the records
8794
- * migration. Nothing declares it any more and nothing reads it; the schema
8795
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8796
- * (an orphaned kind is never redeclared) and an addon built before the
8797
- * removal still sends it. Never set it.
8798
- */
8799
- adoptsFrom: string().min(1).optional(),
8800
8801
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8801
8802
  transactFamily: string().min(1).optional(),
8802
8803
  entry: EntryDescriptorSchema.optional()
@@ -13474,17 +13475,6 @@ object({
13474
13475
  createdAt: number(),
13475
13476
  updatedAt: number()
13476
13477
  });
13477
- object({
13478
- id: string(),
13479
- label: string(),
13480
- isAdmin: boolean().default(false),
13481
- allowedProviders: AllowedProviderSchema,
13482
- allowedDevices: AllowedDevicesSchema,
13483
- tokenHash: string(),
13484
- tokenPrefix: string(),
13485
- createdAt: number(),
13486
- lastUsedAt: number().optional()
13487
- });
13488
13478
  object({
13489
13479
  id: string(),
13490
13480
  userId: string(),
@@ -17466,16 +17456,36 @@ var RecordKindStateSchema = _enum([
17466
17456
  var DeclareKindResultSchema = object({
17467
17457
  kindId: number().int(),
17468
17458
  state: RecordKindStateSchema,
17469
- createdIndexes: array(string()),
17470
- /**
17471
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
17472
- * it stays on the wire, null, because an addon built before the removal reads
17473
- * an ABSENT field as "adoption pending" and refuses to start.
17474
- */
17475
- adoptionPending: _null()
17459
+ createdIndexes: array(string())
17476
17460
  });
17477
17461
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
17478
17462
  var SecretRefsList = array(string());
17463
+ /**
17464
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
17465
+ * All ops of one call share ONE database file and ONE `transactFamily`.
17466
+ */
17467
+ var RecordTransactOpSchema = discriminatedUnion("op", [
17468
+ object({
17469
+ op: literal("put"),
17470
+ kind: RecordKindNameSchema,
17471
+ record: RecordInputSchema,
17472
+ ifRev: number().int().min(0).optional()
17473
+ }),
17474
+ object({
17475
+ op: literal("patch"),
17476
+ kind: RecordKindNameSchema,
17477
+ id: RecordIdSchema,
17478
+ data: RecordBodySchema,
17479
+ at: number().int().nullable().optional(),
17480
+ expiresAt: number().int().nullable().optional(),
17481
+ ifRev: number().int().min(1).optional()
17482
+ }),
17483
+ object({
17484
+ op: literal("delete"),
17485
+ kind: RecordKindNameSchema,
17486
+ id: RecordIdSchema
17487
+ })
17488
+ ]);
17479
17489
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
17480
17490
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
17481
17491
  kind: "mutation",
@@ -17582,6 +17592,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
17582
17592
  }), {
17583
17593
  kind: "mutation",
17584
17594
  auth: "admin"
17595
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
17596
+ results: array(object({
17597
+ rev: number().int().nullable(),
17598
+ deleted: boolean()
17599
+ })),
17600
+ releasedRefs: SecretRefsList,
17601
+ secretRefs: SecretRefsList
17602
+ }), {
17603
+ kind: "mutation",
17604
+ auth: "admin"
17585
17605
  }), method(object({
17586
17606
  deviceId: number().int(),
17587
17607
  kinds: array(RecordKindNameSchema).optional()
@@ -43193,9 +43213,13 @@ var NcSystemEventKindSchema = _enum([
43193
43213
  "node-updating",
43194
43214
  "node-inference-unavailable",
43195
43215
  "detection-blind",
43216
+ "motion-noisy",
43217
+ "motion-calm",
43196
43218
  "recording-stalled",
43197
43219
  "recording-healthy",
43198
43220
  "recording-degraded",
43221
+ "device-attention-required",
43222
+ "device-attention-resolved",
43199
43223
  "storage-location-low",
43200
43224
  "storage-location-critical",
43201
43225
  "storage-location-ok",
@@ -48756,7 +48780,6 @@ var RecommendationReasonSchema = discriminatedUnion("kind", [
48756
48780
  modelId: string()
48757
48781
  }),
48758
48782
  object({ kind: literal("cpu-device") }),
48759
- object({ kind: literal("coral-untouched") }),
48760
48783
  object({ kind: literal("device-disabled") }),
48761
48784
  object({ kind: literal("device-unavailable") }),
48762
48785
  object({ kind: literal("node-offline") }),
@@ -48854,11 +48877,6 @@ var AutoTuneWarningSchema = discriminatedUnion("kind", [
48854
48877
  kind: literal("detector-store-unreadable"),
48855
48878
  error: string()
48856
48879
  }),
48857
- object({
48858
- kind: literal("coral-enabled"),
48859
- nodeId: string(),
48860
- deviceKey: string()
48861
- }),
48862
48880
  object({
48863
48881
  kind: literal("custom-pin-kept"),
48864
48882
  nodeId: string(),
@@ -56527,6 +56545,16 @@ var DishwasherStatusSchema = object({
56527
56545
  powerState: string().nullable(),
56528
56546
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
56529
56547
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
56548
+ /**
56549
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
56550
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
56551
+ * when none is reported. A cleared reminder is not an unknown one.
56552
+ */
56553
+ filterCleaningDue: boolean().nullable(),
56554
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
56555
+ machineCareDue: boolean().nullable(),
56556
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
56557
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
56530
56558
  /** Option states: null when the appliance does not expose the option or has not said. */
56531
56559
  halfLoad: boolean().nullable(),
56532
56560
  hygienePlus: boolean().nullable(),
@@ -65177,16 +65205,6 @@ var UpdateUserInputSchema = object({
65177
65205
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
65178
65206
  scopes: array(TokenScopeSchema).optional()
65179
65207
  });
65180
- var ApiKeySummarySchema = object({
65181
- id: string(),
65182
- label: string(),
65183
- isAdmin: boolean().default(false),
65184
- allowedProviders: union([array(string()), literal("*")]).optional(),
65185
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
65186
- tokenPrefix: string(),
65187
- createdAt: number(),
65188
- lastUsedAt: number().optional()
65189
- });
65190
65208
  var OauthSessionSummarySchema = object({
65191
65209
  id: string(),
65192
65210
  userId: string(),
@@ -65208,8 +65226,7 @@ var TotpStatusSchema = object({
65208
65226
  confirmedAt: number().nullable()
65209
65227
  });
65210
65228
  /**
65211
- * user-management — singleton capability for user accounts and the
65212
- * legacy API-key rows.
65229
+ * user-management — singleton capability for user accounts.
65213
65230
  *
65214
65231
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
65215
65232
  * — the subset check on `setUserScopes` is moot
@@ -65265,10 +65282,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
65265
65282
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
65266
65283
  kind: "mutation",
65267
65284
  access: "view"
65268
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
65269
- kind: "mutation",
65270
- auth: "admin",
65271
- access: "delete"
65272
65285
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
65273
65286
  kind: "mutation",
65274
65287
  auth: "admin",
@@ -74724,6 +74737,12 @@ Object.freeze({
74724
74737
  addonId: null,
74725
74738
  access: "view"
74726
74739
  },
74740
+ "records.transact": {
74741
+ capName: "records",
74742
+ capScope: "system",
74743
+ addonId: null,
74744
+ access: "create"
74745
+ },
74727
74746
  "sceneMonitor.captureReference": {
74728
74747
  capName: "scene-monitor",
74729
74748
  capScope: "device",
@@ -76056,12 +76075,6 @@ Object.freeze({
76056
76075
  addonId: null,
76057
76076
  access: "view"
76058
76077
  },
76059
- "userManagement.listApiKeys": {
76060
- capName: "user-management",
76061
- capScope: "system",
76062
- addonId: null,
76063
- access: "view"
76064
- },
76065
76078
  "userManagement.listExternalIdentities": {
76066
76079
  capName: "user-management",
76067
76080
  capScope: "system",
@@ -76116,12 +76129,6 @@ Object.freeze({
76116
76129
  addonId: null,
76117
76130
  access: "create"
76118
76131
  },
76119
- "userManagement.revokeApiKey": {
76120
- capName: "user-management",
76121
- capScope: "system",
76122
- addonId: null,
76123
- access: "delete"
76124
- },
76125
76132
  "userManagement.revokeOauthSession": {
76126
76133
  capName: "user-management",
76127
76134
  capScope: "system",
@@ -79486,9 +79493,13 @@ new Map(Object.entries({
79486
79493
  "stream-online": "device-events",
79487
79494
  "stream-offline": "device-events",
79488
79495
  "detection-blind": "device-events",
79496
+ "motion-noisy": "device-events",
79497
+ "motion-calm": "device-events",
79489
79498
  "recording-stalled": "device-events",
79490
79499
  "recording-healthy": "device-events",
79491
79500
  "recording-degraded": "device-events",
79501
+ "device-attention-required": "device-events",
79502
+ "device-attention-resolved": "device-events",
79492
79503
  "node-online": "system",
79493
79504
  "node-offline": "system",
79494
79505
  "node-restarting": "system",
@@ -79571,6 +79582,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79571
79582
  label: "Detecting nothing",
79572
79583
  kinds: ["detection-blind"]
79573
79584
  },
79585
+ {
79586
+ id: "motion-noise",
79587
+ family: "device-events",
79588
+ label: "Motion without a subject",
79589
+ kinds: ["motion-noisy", "motion-calm"]
79590
+ },
79574
79591
  {
79575
79592
  id: "recording",
79576
79593
  family: "device-events",
@@ -79581,6 +79598,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79581
79598
  "recording-degraded"
79582
79599
  ]
79583
79600
  },
79601
+ {
79602
+ id: "device-attention",
79603
+ family: "device-events",
79604
+ label: "Needs attention",
79605
+ kinds: ["device-attention-required", "device-attention-resolved"]
79606
+ },
79584
79607
  {
79585
79608
  id: "nodes",
79586
79609
  family: "system",
@@ -79720,6 +79743,7 @@ var ALERT_EPISODE = [
79720
79743
  "alert-error",
79721
79744
  "alert-critical-resolved"
79722
79745
  ];
79746
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
79723
79747
  var UPDATES = [
79724
79748
  "addon-update-available",
79725
79749
  "server-update-available",
@@ -79749,9 +79773,12 @@ var DEVICE_EVENTS = [
79749
79773
  "stream-online",
79750
79774
  "stream-offline",
79751
79775
  "detection-blind",
79776
+ "motion-noisy",
79777
+ "motion-calm",
79752
79778
  "recording-stalled",
79753
79779
  "recording-healthy",
79754
79780
  "recording-degraded",
79781
+ ...DEVICE_ATTENTION,
79755
79782
  ...ALARM
79756
79783
  ];
79757
79784
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -79919,7 +79946,9 @@ var STATE_SUMMARY_VARS = [
79919
79946
  [...RULE_TEXT],
79920
79947
  [...RULE_TEXT],
79921
79948
  [...RULE_TEXT],
79922
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79949
+ [...RULE_TEXT],
79950
+ [...RULE_TEXT],
79951
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79923
79952
  [...RULE_TEXT],
79924
79953
  [...RULE_TEXT],
79925
79954
  [...RULE_TEXT],
@@ -79941,11 +79970,11 @@ var STATE_SUMMARY_VARS = [
79941
79970
  [...RULE_TEXT],
79942
79971
  [...RULE_TEXT],
79943
79972
  [...RULE_TEXT],
79973
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79944
79974
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79975
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79945
79976
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79946
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79947
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79948
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79977
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79949
79978
  [...RULE_TEXT],
79950
79979
  [...RULE_TEXT],
79951
79980
  [...RULE_TEXT],
@@ -80021,6 +80050,15 @@ new Map([
80021
80050
  snapshotLabel: "Tanks low or full now",
80022
80051
  snapshotSection: "tanks"
80023
80052
  },
80053
+ {
80054
+ id: "motion-noise",
80055
+ family: "device-events",
80056
+ label: "Motion without a subject (constant / calm again)",
80057
+ bad: ["motion-noisy"],
80058
+ recovery: ["motion-calm"],
80059
+ snapshotLabel: "Cameras with constant motion now",
80060
+ snapshotSection: null
80061
+ },
80024
80062
  {
80025
80063
  id: "recording-health",
80026
80064
  family: "device-events",
@@ -80030,6 +80068,15 @@ new Map([
80030
80068
  snapshotLabel: "Recordings stalled now",
80031
80069
  snapshotSection: null
80032
80070
  },
80071
+ {
80072
+ id: "device-attention",
80073
+ family: "device-events",
80074
+ label: "Device needs attention (raised / resolved)",
80075
+ bad: ["device-attention-required"],
80076
+ recovery: ["device-attention-resolved"],
80077
+ snapshotLabel: "Devices needing attention now",
80078
+ snapshotSection: null
80079
+ },
80033
80080
  {
80034
80081
  id: "node-connectivity",
80035
80082
  family: "system",
@@ -80666,7 +80713,7 @@ function buildConnectionFormSchema() {
80666
80713
  id: "credentials",
80667
80714
  title: "Tuya IoT cloud project",
80668
80715
  titleKey: "provider-tuya:connection.s_credentials.title",
80669
- description: "Create a free project at iot.tuya.com, link your Smart Life / Tuya app account to it, and paste the project's Access ID and Access Secret. CamStack uses them to fetch each device's local key, then controls the devices directly over your LAN (no ongoing cloud).",
80716
+ description: "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
80670
80717
  descriptionKey: "provider-tuya:connection.s_credentials.description",
80671
80718
  columns: 1,
80672
80719
  fields: [{
package/i18n/en.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "connection.s_credentials.title": "Tuya IoT cloud project",
3
- "connection.s_credentials.description": "Create a free project at iot.tuya.com, link your Smart Life / Tuya app account to it, and paste the project's Access ID and Access Secret. CamStack uses them to fetch each device's local key, then controls the devices directly over your LAN (no ongoing cloud).",
3
+ "connection.s_credentials.description": "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
4
4
  "connection.s_credentials.accessId.label": "Access ID / Client ID",
5
5
  "connection.s_credentials.accessSecret.label": "Access Secret / Client Secret",
6
6
  "connection.s_region.title": "Region",
package/i18n/it.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "connection.s_credentials.title": "Progetto cloud Tuya IoT",
3
- "connection.s_credentials.description": "Crea un progetto gratuito su iot.tuya.com, collega a esso l'account dell'app Smart Life / Tuya e incolla Access ID e Access Secret del progetto. CamStack li usa per recuperare la chiave locale di ogni dispositivo, poi controlla i dispositivi direttamente sulla LAN (nessun cloud in uso).",
3
+ "connection.s_credentials.description": "Crea un progetto su iot.tuya.com, collega il tuo account Smart Life / Tuya e incolla Access ID e Access Secret.",
4
4
  "connection.s_credentials.accessId.label": "Access ID / Client ID",
5
5
  "connection.s_credentials.accessSecret.label": "Access Secret / Client Secret",
6
6
  "connection.s_region.title": "Regione",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.140",
3
+ "version": "0.2.142",
4
4
  "description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
5
5
  "keywords": [
6
6
  "camstack",