@camstack/addon-provider-wyze 0.2.132 → 0.2.133

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
@@ -5409,7 +5409,7 @@ var ZodIssueCode = {
5409
5409
  var ZodFirstPartyTypeKind;
5410
5410
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5411
5411
  //#endregion
5412
- //#region ../types/dist/sleep-Cr5YOk3m.mjs
5412
+ //#region ../types/dist/sleep-DujUvOcb.mjs
5413
5413
  /**
5414
5414
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5415
5415
  * window to float samples (D455).
@@ -15002,6 +15002,14 @@ var KeychainAuditEntrySchema = object({
15002
15002
  ref: string().nullable(),
15003
15003
  detail: string().nullable()
15004
15004
  });
15005
+ var KEYCHAIN_RESET_CONFIRMATION = "RESET KEYCHAIN";
15006
+ /**
15007
+ * Secrets the HUB itself holds (owner `system`) that no settings form shows:
15008
+ * `jwt-signing-key` — the session signing key (D797). It is always "in use",
15009
+ * never an orphan; it is generated on a fresh hub and replaced only through
15010
+ * {@link keychainAdminCapability.methods.setSystemSecret}.
15011
+ */
15012
+ var SystemHeldSecretNameSchema = _enum(["jwt-signing-key"]);
15005
15013
  method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}), array(KeychainAdminSecretSchema).readonly(), { auth: "admin" }), method(object({ limit: number().int().min(1).max(500).optional() }), array(KeychainAuditEntrySchema).readonly(), { auth: "admin" }), method(object({ ref: string().min(1) }), object({
15006
15014
  value: string(),
15007
15015
  version: number().int()
@@ -15009,6 +15017,16 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
15009
15017
  kind: "mutation",
15010
15018
  auth: "admin",
15011
15019
  caller: "required"
15020
+ }), method(object({
15021
+ name: SystemHeldSecretNameSchema,
15022
+ value: string().min(16)
15023
+ }), object({
15024
+ ref: string(),
15025
+ version: number().int()
15026
+ }), {
15027
+ kind: "mutation",
15028
+ auth: "admin",
15029
+ caller: "required"
15012
15030
  }), method(object({ refs: array(string().min(1)).max(1e3) }), object({
15013
15031
  deleted: array(string()).readonly(),
15014
15032
  kept: array(object({
@@ -15038,7 +15056,7 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
15038
15056
  kind: "mutation",
15039
15057
  auth: "admin",
15040
15058
  caller: "required"
15041
- }), method(object({ confirm: literal("RESET KEYCHAIN") }), object({
15059
+ }), method(object({ confirm: literal(KEYCHAIN_RESET_CONFIRMATION) }), object({
15042
15060
  archivedCollection: string().nullable(),
15043
15061
  archived: number().int()
15044
15062
  }), {
@@ -23482,6 +23500,9 @@ var RetrainExportFilterSchema = object({
23482
23500
  frameIds: array(string()).max(2e4).optional(),
23483
23501
  /** Only frames in at least one of these named collections. */
23484
23502
  collectionIds: array(string()).max(200).optional(),
23503
+ /** Exactly the frames of this dataset version (and its completeOnly). An
23504
+ * unknown id selects nothing. */
23505
+ datasetVersionId: string().optional(),
23485
23506
  batchId: string().optional(),
23486
23507
  /** Only frames the operator marked complete (all subjects boxed). */
23487
23508
  completeOnly: boolean().optional()
@@ -23649,6 +23670,67 @@ var RetrainLlmAssistResultSchema = discriminatedUnion("kind", [object({
23649
23670
  ]),
23650
23671
  detail: string().optional()
23651
23672
  })]);
23673
+ /** What a dataset version is cut from. Every field narrows. */
23674
+ var RetrainDatasetSelectionSchema = object({
23675
+ deviceIds: array(number()).readonly().optional(),
23676
+ collectionIds: array(string()).max(200).readonly().optional(),
23677
+ frameIds: array(string()).max(2e4).readonly().optional()
23678
+ });
23679
+ /** The counts a dataset is judged by. */
23680
+ var RetrainDatasetStatsSchema = object({
23681
+ frames: number().int(),
23682
+ completeFrames: number().int(),
23683
+ /** `completeFrames / frames`, 0..1. */
23684
+ completeness: number(),
23685
+ /** Boxes to learn (model errors excluded). */
23686
+ subjects: number().int(),
23687
+ modelErrors: number().int(),
23688
+ /** Complete frames with no subject. */
23689
+ hardNegatives: number().int(),
23690
+ /** Subjects per class × camera × day/night. */
23691
+ cells: array(object({
23692
+ macroClass: string(),
23693
+ deviceId: number(),
23694
+ lighting: _enum([
23695
+ "day",
23696
+ "night",
23697
+ "unknown"
23698
+ ]),
23699
+ subjects: number().int(),
23700
+ frames: number().int()
23701
+ })).readonly(),
23702
+ cameras: array(object({
23703
+ deviceId: number(),
23704
+ frames: number().int(),
23705
+ completeFrames: number().int()
23706
+ })).readonly()
23707
+ });
23708
+ /** An immutable dataset version, without its frame list. */
23709
+ var RetrainDatasetVersionSchema = object({
23710
+ id: string(),
23711
+ name: string(),
23712
+ createdAt: number(),
23713
+ selection: RetrainDatasetSelectionSchema,
23714
+ layout: RetrainExportLayoutSchema,
23715
+ completeOnly: boolean(),
23716
+ frameCount: number().int(),
23717
+ /** sha256 of what the frames taught when the version was frozen. */
23718
+ annotationHash: string(),
23719
+ /** The export manifest schema the version was cut under. */
23720
+ manifestSchema: string(),
23721
+ stats: RetrainDatasetStatsSchema
23722
+ });
23723
+ var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
23724
+ kind: literal("created"),
23725
+ version: RetrainDatasetVersionSchema
23726
+ }), object({
23727
+ kind: literal("refused"),
23728
+ reason: _enum([
23729
+ "empty-name",
23730
+ "duplicate-name",
23731
+ "no-frames"
23732
+ ])
23733
+ })]);
23652
23734
  /** The outcome of a lifecycle move owned by the retrain page. */
23653
23735
  var RetrainTransitionResultSchema = object({
23654
23736
  trackId: string(),
@@ -24438,6 +24520,36 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24438
24520
  kind: "mutation",
24439
24521
  auth: "admin",
24440
24522
  timeoutMs: 60 * 6e4
24523
+ }), method(object({
24524
+ selection: RetrainDatasetSelectionSchema,
24525
+ completeOnly: boolean().optional()
24526
+ }), RetrainDatasetStatsSchema, {
24527
+ kind: "query",
24528
+ auth: "admin"
24529
+ }), method(object({
24530
+ name: string().max(120),
24531
+ selection: RetrainDatasetSelectionSchema,
24532
+ layout: RetrainExportLayoutSchema,
24533
+ completeOnly: boolean()
24534
+ }), CreateRetrainDatasetVersionResultSchema, {
24535
+ kind: "mutation",
24536
+ auth: "admin",
24537
+ timeoutMs: 12e4
24538
+ }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
24539
+ kind: "query",
24540
+ auth: "admin"
24541
+ }), method(object({ id: string() }), object({ deleted: boolean() }), {
24542
+ kind: "mutation",
24543
+ auth: "admin"
24544
+ }), method(object({ id: string() }), object({
24545
+ found: boolean(),
24546
+ annotationHash: string(),
24547
+ matches: boolean(),
24548
+ missingFrames: number().int()
24549
+ }), {
24550
+ kind: "query",
24551
+ auth: "admin",
24552
+ timeoutMs: 12e4
24441
24553
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
24442
24554
  kind: "query",
24443
24555
  auth: "admin"
@@ -45789,6 +45901,12 @@ Object.freeze({
45789
45901
  addonId: null,
45790
45902
  access: "create"
45791
45903
  },
45904
+ "keychainAdmin.setSystemSecret": {
45905
+ capName: "keychain-admin",
45906
+ capScope: "system",
45907
+ addonId: null,
45908
+ access: "create"
45909
+ },
45792
45910
  "keychainAdmin.status": {
45793
45911
  capName: "keychain-admin",
45794
45912
  capScope: "system",
@@ -47235,6 +47353,12 @@ Object.freeze({
47235
47353
  addonId: null,
47236
47354
  access: "create"
47237
47355
  },
47356
+ "pipelineAnalytics.createRetrainDatasetVersion": {
47357
+ capName: "pipeline-analytics",
47358
+ capScope: "device",
47359
+ addonId: null,
47360
+ access: "create"
47361
+ },
47238
47362
  "pipelineAnalytics.deleteDeviceEvents": {
47239
47363
  capName: "pipeline-analytics",
47240
47364
  capScope: "device",
@@ -47247,6 +47371,12 @@ Object.freeze({
47247
47371
  addonId: null,
47248
47372
  access: "delete"
47249
47373
  },
47374
+ "pipelineAnalytics.deleteRetrainDatasetVersion": {
47375
+ capName: "pipeline-analytics",
47376
+ capScope: "device",
47377
+ addonId: null,
47378
+ access: "delete"
47379
+ },
47250
47380
  "pipelineAnalytics.deleteTracks": {
47251
47381
  capName: "pipeline-analytics",
47252
47382
  capScope: "device",
@@ -47469,6 +47599,12 @@ Object.freeze({
47469
47599
  addonId: null,
47470
47600
  access: "view"
47471
47601
  },
47602
+ "pipelineAnalytics.listRetrainDatasetVersions": {
47603
+ capName: "pipeline-analytics",
47604
+ capScope: "device",
47605
+ addonId: null,
47606
+ access: "view"
47607
+ },
47472
47608
  "pipelineAnalytics.listRetrainFrames": {
47473
47609
  capName: "pipeline-analytics",
47474
47610
  capScope: "device",
@@ -47511,6 +47647,12 @@ Object.freeze({
47511
47647
  addonId: null,
47512
47648
  access: "create"
47513
47649
  },
47650
+ "pipelineAnalytics.previewRetrainDataset": {
47651
+ capName: "pipeline-analytics",
47652
+ capScope: "device",
47653
+ addonId: null,
47654
+ access: "view"
47655
+ },
47514
47656
  "pipelineAnalytics.proposeRetrainAnnotations": {
47515
47657
  capName: "pipeline-analytics",
47516
47658
  capScope: "device",
@@ -47649,6 +47791,12 @@ Object.freeze({
47649
47791
  addonId: null,
47650
47792
  access: "create"
47651
47793
  },
47794
+ "pipelineAnalytics.verifyRetrainDatasetVersion": {
47795
+ capName: "pipeline-analytics",
47796
+ capScope: "device",
47797
+ addonId: null,
47798
+ access: "view"
47799
+ },
47652
47800
  "pipelineAnalytics.wipeAllAnalytics": {
47653
47801
  capName: "pipeline-analytics",
47654
47802
  capScope: "device",
@@ -60347,6 +60495,20 @@ function getString(obj, key) {
60347
60495
  const v = obj[key];
60348
60496
  return typeof v === "string" ? v : "";
60349
60497
  }
60498
+ /**
60499
+ * Keys the account form declares. They belong to `integration.settings`; in
60500
+ * the addon's global store they are stale leftovers.
60501
+ */
60502
+ var GLOBAL_CREDENTIAL_KEYS = [
60503
+ "email",
60504
+ "password",
60505
+ "apiKey",
60506
+ "apiId"
60507
+ ];
60508
+ /** A stored value worth removing: a non-empty string or a keychain marker. */
60509
+ function isStoredValue(v) {
60510
+ return typeof v === "string" && v.length > 0 || isSecretMarker(v);
60511
+ }
60350
60512
  /** Extract account credentials from an integration's settings, or null. */
60351
60513
  function credentialsFromSettings(settings) {
60352
60514
  const email = getString(settings, "email").trim();
@@ -60411,6 +60573,9 @@ var WyzeProviderAddon = class extends BaseDeviceProvider {
60411
60573
  });
60412
60574
  });
60413
60575
  });
60576
+ await this.purgeStaleGlobalCredentials().catch((err) => {
60577
+ this.ctx.logger.warn("could not remove stale Wyze credentials from the global store", { meta: { error: errMsg(err) } });
60578
+ });
60414
60579
  await this.reconcileIntegrations();
60415
60580
  this.subscribeIntegrationLifecycle();
60416
60581
  return [
@@ -60546,8 +60711,25 @@ var WyzeProviderAddon = class extends BaseDeviceProvider {
60546
60711
  }
60547
60712
  });
60548
60713
  }
60714
+ globalSettingsSchema() {
60715
+ return buildSettingsSchema();
60716
+ }
60549
60717
  async getGlobalSettings() {
60550
- return hydrateSchema(buildSettingsSchema(), {});
60718
+ return hydrateSchema(this.globalSettingsSchema(), {});
60719
+ }
60720
+ /**
60721
+ * Remove account credentials left in the GLOBAL store. They are dead — the
60722
+ * addon reads credentials only from `integration.settings` — and an older
60723
+ * build left them there as plaintext. Idempotent: a clean store is not
60724
+ * written. Secret keys are cleared through `clearSecrets`, which also drops
60725
+ * any keychain value a marker points at.
60726
+ */
60727
+ async purgeStaleGlobalCredentials() {
60728
+ const stored = await this.resolveGlobalStore();
60729
+ const present = GLOBAL_CREDENTIAL_KEYS.filter((key) => isStoredValue(stored[key]));
60730
+ if (present.length === 0) return;
60731
+ await this.clearSecrets(present);
60732
+ this.ctx.logger.info("Removed stale Wyze credentials from the addon global store", { meta: { keys: present } });
60551
60733
  }
60552
60734
  async onGetCreationSchema(type) {
60553
60735
  if (type !== DeviceType.Camera) return null;
package/dist/addon.mjs CHANGED
@@ -5388,7 +5388,7 @@ var ZodIssueCode = {
5388
5388
  var ZodFirstPartyTypeKind;
5389
5389
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5390
5390
  //#endregion
5391
- //#region ../types/dist/sleep-Cr5YOk3m.mjs
5391
+ //#region ../types/dist/sleep-DujUvOcb.mjs
5392
5392
  /**
5393
5393
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5394
5394
  * window to float samples (D455).
@@ -14981,6 +14981,14 @@ var KeychainAuditEntrySchema = object({
14981
14981
  ref: string().nullable(),
14982
14982
  detail: string().nullable()
14983
14983
  });
14984
+ var KEYCHAIN_RESET_CONFIRMATION = "RESET KEYCHAIN";
14985
+ /**
14986
+ * Secrets the HUB itself holds (owner `system`) that no settings form shows:
14987
+ * `jwt-signing-key` — the session signing key (D797). It is always "in use",
14988
+ * never an orphan; it is generated on a fresh hub and replaced only through
14989
+ * {@link keychainAdminCapability.methods.setSystemSecret}.
14990
+ */
14991
+ var SystemHeldSecretNameSchema = _enum(["jwt-signing-key"]);
14984
14992
  method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}), array(KeychainAdminSecretSchema).readonly(), { auth: "admin" }), method(object({ limit: number().int().min(1).max(500).optional() }), array(KeychainAuditEntrySchema).readonly(), { auth: "admin" }), method(object({ ref: string().min(1) }), object({
14985
14993
  value: string(),
14986
14994
  version: number().int()
@@ -14988,6 +14996,16 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
14988
14996
  kind: "mutation",
14989
14997
  auth: "admin",
14990
14998
  caller: "required"
14999
+ }), method(object({
15000
+ name: SystemHeldSecretNameSchema,
15001
+ value: string().min(16)
15002
+ }), object({
15003
+ ref: string(),
15004
+ version: number().int()
15005
+ }), {
15006
+ kind: "mutation",
15007
+ auth: "admin",
15008
+ caller: "required"
14991
15009
  }), method(object({ refs: array(string().min(1)).max(1e3) }), object({
14992
15010
  deleted: array(string()).readonly(),
14993
15011
  kept: array(object({
@@ -15017,7 +15035,7 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
15017
15035
  kind: "mutation",
15018
15036
  auth: "admin",
15019
15037
  caller: "required"
15020
- }), method(object({ confirm: literal("RESET KEYCHAIN") }), object({
15038
+ }), method(object({ confirm: literal(KEYCHAIN_RESET_CONFIRMATION) }), object({
15021
15039
  archivedCollection: string().nullable(),
15022
15040
  archived: number().int()
15023
15041
  }), {
@@ -23461,6 +23479,9 @@ var RetrainExportFilterSchema = object({
23461
23479
  frameIds: array(string()).max(2e4).optional(),
23462
23480
  /** Only frames in at least one of these named collections. */
23463
23481
  collectionIds: array(string()).max(200).optional(),
23482
+ /** Exactly the frames of this dataset version (and its completeOnly). An
23483
+ * unknown id selects nothing. */
23484
+ datasetVersionId: string().optional(),
23464
23485
  batchId: string().optional(),
23465
23486
  /** Only frames the operator marked complete (all subjects boxed). */
23466
23487
  completeOnly: boolean().optional()
@@ -23628,6 +23649,67 @@ var RetrainLlmAssistResultSchema = discriminatedUnion("kind", [object({
23628
23649
  ]),
23629
23650
  detail: string().optional()
23630
23651
  })]);
23652
+ /** What a dataset version is cut from. Every field narrows. */
23653
+ var RetrainDatasetSelectionSchema = object({
23654
+ deviceIds: array(number()).readonly().optional(),
23655
+ collectionIds: array(string()).max(200).readonly().optional(),
23656
+ frameIds: array(string()).max(2e4).readonly().optional()
23657
+ });
23658
+ /** The counts a dataset is judged by. */
23659
+ var RetrainDatasetStatsSchema = object({
23660
+ frames: number().int(),
23661
+ completeFrames: number().int(),
23662
+ /** `completeFrames / frames`, 0..1. */
23663
+ completeness: number(),
23664
+ /** Boxes to learn (model errors excluded). */
23665
+ subjects: number().int(),
23666
+ modelErrors: number().int(),
23667
+ /** Complete frames with no subject. */
23668
+ hardNegatives: number().int(),
23669
+ /** Subjects per class × camera × day/night. */
23670
+ cells: array(object({
23671
+ macroClass: string(),
23672
+ deviceId: number(),
23673
+ lighting: _enum([
23674
+ "day",
23675
+ "night",
23676
+ "unknown"
23677
+ ]),
23678
+ subjects: number().int(),
23679
+ frames: number().int()
23680
+ })).readonly(),
23681
+ cameras: array(object({
23682
+ deviceId: number(),
23683
+ frames: number().int(),
23684
+ completeFrames: number().int()
23685
+ })).readonly()
23686
+ });
23687
+ /** An immutable dataset version, without its frame list. */
23688
+ var RetrainDatasetVersionSchema = object({
23689
+ id: string(),
23690
+ name: string(),
23691
+ createdAt: number(),
23692
+ selection: RetrainDatasetSelectionSchema,
23693
+ layout: RetrainExportLayoutSchema,
23694
+ completeOnly: boolean(),
23695
+ frameCount: number().int(),
23696
+ /** sha256 of what the frames taught when the version was frozen. */
23697
+ annotationHash: string(),
23698
+ /** The export manifest schema the version was cut under. */
23699
+ manifestSchema: string(),
23700
+ stats: RetrainDatasetStatsSchema
23701
+ });
23702
+ var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
23703
+ kind: literal("created"),
23704
+ version: RetrainDatasetVersionSchema
23705
+ }), object({
23706
+ kind: literal("refused"),
23707
+ reason: _enum([
23708
+ "empty-name",
23709
+ "duplicate-name",
23710
+ "no-frames"
23711
+ ])
23712
+ })]);
23631
23713
  /** The outcome of a lifecycle move owned by the retrain page. */
23632
23714
  var RetrainTransitionResultSchema = object({
23633
23715
  trackId: string(),
@@ -24417,6 +24499,36 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24417
24499
  kind: "mutation",
24418
24500
  auth: "admin",
24419
24501
  timeoutMs: 60 * 6e4
24502
+ }), method(object({
24503
+ selection: RetrainDatasetSelectionSchema,
24504
+ completeOnly: boolean().optional()
24505
+ }), RetrainDatasetStatsSchema, {
24506
+ kind: "query",
24507
+ auth: "admin"
24508
+ }), method(object({
24509
+ name: string().max(120),
24510
+ selection: RetrainDatasetSelectionSchema,
24511
+ layout: RetrainExportLayoutSchema,
24512
+ completeOnly: boolean()
24513
+ }), CreateRetrainDatasetVersionResultSchema, {
24514
+ kind: "mutation",
24515
+ auth: "admin",
24516
+ timeoutMs: 12e4
24517
+ }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
24518
+ kind: "query",
24519
+ auth: "admin"
24520
+ }), method(object({ id: string() }), object({ deleted: boolean() }), {
24521
+ kind: "mutation",
24522
+ auth: "admin"
24523
+ }), method(object({ id: string() }), object({
24524
+ found: boolean(),
24525
+ annotationHash: string(),
24526
+ matches: boolean(),
24527
+ missingFrames: number().int()
24528
+ }), {
24529
+ kind: "query",
24530
+ auth: "admin",
24531
+ timeoutMs: 12e4
24420
24532
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
24421
24533
  kind: "query",
24422
24534
  auth: "admin"
@@ -45768,6 +45880,12 @@ Object.freeze({
45768
45880
  addonId: null,
45769
45881
  access: "create"
45770
45882
  },
45883
+ "keychainAdmin.setSystemSecret": {
45884
+ capName: "keychain-admin",
45885
+ capScope: "system",
45886
+ addonId: null,
45887
+ access: "create"
45888
+ },
45771
45889
  "keychainAdmin.status": {
45772
45890
  capName: "keychain-admin",
45773
45891
  capScope: "system",
@@ -47214,6 +47332,12 @@ Object.freeze({
47214
47332
  addonId: null,
47215
47333
  access: "create"
47216
47334
  },
47335
+ "pipelineAnalytics.createRetrainDatasetVersion": {
47336
+ capName: "pipeline-analytics",
47337
+ capScope: "device",
47338
+ addonId: null,
47339
+ access: "create"
47340
+ },
47217
47341
  "pipelineAnalytics.deleteDeviceEvents": {
47218
47342
  capName: "pipeline-analytics",
47219
47343
  capScope: "device",
@@ -47226,6 +47350,12 @@ Object.freeze({
47226
47350
  addonId: null,
47227
47351
  access: "delete"
47228
47352
  },
47353
+ "pipelineAnalytics.deleteRetrainDatasetVersion": {
47354
+ capName: "pipeline-analytics",
47355
+ capScope: "device",
47356
+ addonId: null,
47357
+ access: "delete"
47358
+ },
47229
47359
  "pipelineAnalytics.deleteTracks": {
47230
47360
  capName: "pipeline-analytics",
47231
47361
  capScope: "device",
@@ -47448,6 +47578,12 @@ Object.freeze({
47448
47578
  addonId: null,
47449
47579
  access: "view"
47450
47580
  },
47581
+ "pipelineAnalytics.listRetrainDatasetVersions": {
47582
+ capName: "pipeline-analytics",
47583
+ capScope: "device",
47584
+ addonId: null,
47585
+ access: "view"
47586
+ },
47451
47587
  "pipelineAnalytics.listRetrainFrames": {
47452
47588
  capName: "pipeline-analytics",
47453
47589
  capScope: "device",
@@ -47490,6 +47626,12 @@ Object.freeze({
47490
47626
  addonId: null,
47491
47627
  access: "create"
47492
47628
  },
47629
+ "pipelineAnalytics.previewRetrainDataset": {
47630
+ capName: "pipeline-analytics",
47631
+ capScope: "device",
47632
+ addonId: null,
47633
+ access: "view"
47634
+ },
47493
47635
  "pipelineAnalytics.proposeRetrainAnnotations": {
47494
47636
  capName: "pipeline-analytics",
47495
47637
  capScope: "device",
@@ -47628,6 +47770,12 @@ Object.freeze({
47628
47770
  addonId: null,
47629
47771
  access: "create"
47630
47772
  },
47773
+ "pipelineAnalytics.verifyRetrainDatasetVersion": {
47774
+ capName: "pipeline-analytics",
47775
+ capScope: "device",
47776
+ addonId: null,
47777
+ access: "view"
47778
+ },
47631
47779
  "pipelineAnalytics.wipeAllAnalytics": {
47632
47780
  capName: "pipeline-analytics",
47633
47781
  capScope: "device",
@@ -60326,6 +60474,20 @@ function getString(obj, key) {
60326
60474
  const v = obj[key];
60327
60475
  return typeof v === "string" ? v : "";
60328
60476
  }
60477
+ /**
60478
+ * Keys the account form declares. They belong to `integration.settings`; in
60479
+ * the addon's global store they are stale leftovers.
60480
+ */
60481
+ var GLOBAL_CREDENTIAL_KEYS = [
60482
+ "email",
60483
+ "password",
60484
+ "apiKey",
60485
+ "apiId"
60486
+ ];
60487
+ /** A stored value worth removing: a non-empty string or a keychain marker. */
60488
+ function isStoredValue(v) {
60489
+ return typeof v === "string" && v.length > 0 || isSecretMarker(v);
60490
+ }
60329
60491
  /** Extract account credentials from an integration's settings, or null. */
60330
60492
  function credentialsFromSettings(settings) {
60331
60493
  const email = getString(settings, "email").trim();
@@ -60390,6 +60552,9 @@ var WyzeProviderAddon = class extends BaseDeviceProvider {
60390
60552
  });
60391
60553
  });
60392
60554
  });
60555
+ await this.purgeStaleGlobalCredentials().catch((err) => {
60556
+ this.ctx.logger.warn("could not remove stale Wyze credentials from the global store", { meta: { error: errMsg(err) } });
60557
+ });
60393
60558
  await this.reconcileIntegrations();
60394
60559
  this.subscribeIntegrationLifecycle();
60395
60560
  return [
@@ -60525,8 +60690,25 @@ var WyzeProviderAddon = class extends BaseDeviceProvider {
60525
60690
  }
60526
60691
  });
60527
60692
  }
60693
+ globalSettingsSchema() {
60694
+ return buildSettingsSchema();
60695
+ }
60528
60696
  async getGlobalSettings() {
60529
- return hydrateSchema(buildSettingsSchema(), {});
60697
+ return hydrateSchema(this.globalSettingsSchema(), {});
60698
+ }
60699
+ /**
60700
+ * Remove account credentials left in the GLOBAL store. They are dead — the
60701
+ * addon reads credentials only from `integration.settings` — and an older
60702
+ * build left them there as plaintext. Idempotent: a clean store is not
60703
+ * written. Secret keys are cleared through `clearSecrets`, which also drops
60704
+ * any keychain value a marker points at.
60705
+ */
60706
+ async purgeStaleGlobalCredentials() {
60707
+ const stored = await this.resolveGlobalStore();
60708
+ const present = GLOBAL_CREDENTIAL_KEYS.filter((key) => isStoredValue(stored[key]));
60709
+ if (present.length === 0) return;
60710
+ await this.clearSecrets(present);
60711
+ this.ctx.logger.info("Removed stale Wyze credentials from the addon global store", { meta: { keys: present } });
60530
60712
  }
60531
60713
  async onGetCreationSchema(type) {
60532
60714
  if (type !== DeviceType.Camera) return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.2.132",
3
+ "version": "0.2.133",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",