@camstack/addon-provider-dreo 0.2.120 → 0.2.122

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 +267 -11
  2. package/dist/addon.mjs +267 -11
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5406,7 +5406,7 @@ var ZodIssueCode = {
5406
5406
  var ZodFirstPartyTypeKind;
5407
5407
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5408
5408
  //#endregion
5409
- //#region ../types/dist/sleep-BNeXenvr.mjs
5409
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5410
5410
  /**
5411
5411
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5412
5412
  * window to float samples (D455).
@@ -15132,6 +15132,10 @@ var DeviceInfoSchema = object({
15132
15132
  isCamera: boolean(),
15133
15133
  /** Current config values — serializable snapshot */
15134
15134
  config: record(string(), unknown()),
15135
+ /** Paths inside `config` the device's schema declares secret (D783) —
15136
+ * what the non-admin redaction withholds. Paths, never values. Absent
15137
+ * when the owning runner has not reported them. */
15138
+ secretConfigPaths: array(string()).optional(),
15135
15139
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15136
15140
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15137
15141
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15337,7 +15341,13 @@ var DeviceRegisterPayloadSchema = object({
15337
15341
  * call (workers re-register on init), so probe-driven updates
15338
15342
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15339
15343
  features: array(string()).optional(),
15340
- config: record(string(), unknown())
15344
+ config: record(string(), unknown()),
15345
+ /** Config paths the device's own schema DECLARES secret
15346
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15347
+ * `connection.password`). Re-published on every register; the non-admin
15348
+ * redaction withholds them at any depth (D783). Optional: an older runner
15349
+ * omits it and the keyword backstop applies. */
15350
+ secretConfigPaths: array(string()).optional()
15341
15351
  });
15342
15352
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15343
15353
  var DevicePersistConfigPayloadSchema = object({
@@ -16996,7 +17006,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
16996
17006
  icon: string().optional(),
16997
17007
  /** Addon-owned HTTP route the button navigates to (GET). */
16998
17008
  startUrl: string(),
16999
- stage: LoginStageEnum
17009
+ stage: LoginStageEnum,
17010
+ /**
17011
+ * The provider names an external identity a signed-in user can link to
17012
+ * their own account (D782): `auth.listLinkableProviders` /
17013
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17014
+ * whatever their id. Absent / false — a login button only (magic-link).
17015
+ */
17016
+ linkable: boolean().optional()
17000
17017
  }),
17001
17018
  object({
17002
17019
  kind: literal("widget"),
@@ -22431,7 +22448,13 @@ var RetrainFrameSchema = object({
22431
22448
  sizeBytes: number().int(),
22432
22449
  width: number().int(),
22433
22450
  height: number().int(),
22434
- copiedAt: number()
22451
+ copiedAt: number(),
22452
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22453
+ capturedAt: number().optional(),
22454
+ /** The operator's "every subject in this frame is boxed". Detector
22455
+ * evaluation keeps only complete frames: an unboxed subject would count as
22456
+ * a false positive. */
22457
+ complete: boolean()
22435
22458
  });
22436
22459
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22437
22460
  var RetrainCopyRefusalSchema = _enum([
@@ -22452,6 +22475,51 @@ var RetrainFrameListSchema = object({
22452
22475
  /** What the page pre-selects — the native key frame when one survives. */
22453
22476
  autoPickMediaId: number().int().optional()
22454
22477
  });
22478
+ /**
22479
+ * Which frames an annotated export carries. Every field narrows; an empty
22480
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22481
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22482
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22483
+ * export carried (`exportedInBatch`).
22484
+ */
22485
+ var RetrainExportFilterSchema = object({
22486
+ deviceIds: array(number()).optional(),
22487
+ frameIds: array(string()).max(2e4).optional(),
22488
+ batchId: string().optional(),
22489
+ /** Only frames the operator marked complete (all subjects boxed). */
22490
+ completeOnly: boolean().optional()
22491
+ });
22492
+ /**
22493
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22494
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22495
+ * convention — the classifier layout.
22496
+ */
22497
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22498
+ /**
22499
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22500
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22501
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22502
+ * logged.
22503
+ */
22504
+ var RetrainArchiveTargetSchema = object({
22505
+ kind: literal("http"),
22506
+ method: _enum(["PUT", "POST"]),
22507
+ url: string().url(),
22508
+ headers: record(string(), string()).optional()
22509
+ });
22510
+ var RetrainArchiveResultSchema = object({
22511
+ batchId: string(),
22512
+ frames: number().int(),
22513
+ crops: number().int(),
22514
+ annotations: number().int(),
22515
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22516
+ missing: number().int(),
22517
+ bytes: number().int(),
22518
+ /** sha256 of the exact bytes sent. */
22519
+ sha256: string(),
22520
+ /** The target's HTTP status. */
22521
+ status: number().int()
22522
+ });
22455
22523
  /** What the operator asked the assist to look for. */
22456
22524
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22457
22525
  kind: literal("package"),
@@ -23246,9 +23314,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23246
23314
  }), RetrainTransitionResultSchema, {
23247
23315
  kind: "mutation",
23248
23316
  auth: "admin"
23249
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23317
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23250
23318
  kind: "query",
23251
23319
  auth: "admin"
23320
+ }), method(object({
23321
+ deviceId: number(),
23322
+ trackId: string(),
23323
+ frameId: string(),
23324
+ complete: boolean()
23325
+ }), RetrainFrameSchema, {
23326
+ kind: "mutation",
23327
+ auth: "admin"
23328
+ }), method(object({
23329
+ filter: RetrainExportFilterSchema,
23330
+ layout: RetrainExportLayoutSchema,
23331
+ target: RetrainArchiveTargetSchema
23332
+ }), RetrainArchiveResultSchema, {
23333
+ kind: "mutation",
23334
+ auth: "admin",
23335
+ timeoutMs: 60 * 6e4
23252
23336
  }), method(object({
23253
23337
  /** Which of the three event tables owns the row. */
23254
23338
  ownerType: EventOwnerTypeSchema,
@@ -26578,7 +26662,19 @@ var SsoBridgeClaimsSchema = object({
26578
26662
  * editing a descriptor must not retroactively extend or shorten a link the
26579
26663
  * operator already consented to.
26580
26664
  */
26581
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26665
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26666
+ /**
26667
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26668
+ * that was started from a signed-in user's "Link" button: the finish then
26669
+ * links this identity to the intent's user instead of signing anyone in.
26670
+ * The handle carries no user id — the hub resolves it, single-use.
26671
+ */
26672
+ linkIntent: string().optional(),
26673
+ /**
26674
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26675
+ * subject is unique only per issuer, so a link is bound to it.
26676
+ */
26677
+ issuer: string().optional()
26582
26678
  });
26583
26679
  method(object({
26584
26680
  claims: SsoBridgeClaimsSchema,
@@ -28513,7 +28609,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28513
28609
  * field their hints were silently stripped by the schema and the
28514
28610
  * adaptive ladder started blind on the client's display size.
28515
28611
  */
28516
- hints: webrtcClientHintsSchema.optional()
28612
+ hints: webrtcClientHintsSchema.optional(),
28613
+ /**
28614
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28615
+ * through the `intercom` cap's push-talk triple. When `true` and the
28616
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28617
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28618
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28619
+ *
28620
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28621
+ * with `intercom`, when the linked user may control that camera. The
28622
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28623
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28624
+ * intercom cap's own surface (share tokens gate it there), and this
28625
+ * flag must not become a second door to the camera's speaker.
28626
+ */
28627
+ talkback: boolean().optional()
28517
28628
  }), object({
28518
28629
  sessionId: string(),
28519
28630
  sdpAnswer: string()
@@ -28815,6 +28926,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28815
28926
  var RestartAddonResultSchema = unknown();
28816
28927
  var InstallPackageResultSchema = unknown();
28817
28928
  var ReloadPackagesResultSchema = unknown();
28929
+ /**
28930
+ * What an uninstall did on ONE node.
28931
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
28932
+ * - `not-installed` — the node did not have it (nothing to do).
28933
+ * - `refused` — protected / bootstrap package; nothing touched.
28934
+ * - `failed` — attempted and did not complete; `error` says why.
28935
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
28936
+ * back-fill never returns the package, and the stale-addon sweep removes the
28937
+ * copy when the node registers again (only once the hub no longer has it).
28938
+ */
28939
+ var UninstallNodeOutcomeSchema = _enum([
28940
+ "uninstalled",
28941
+ "not-installed",
28942
+ "refused",
28943
+ "failed",
28944
+ "pending-reconnect"
28945
+ ]);
28946
+ var UninstallNodeResultSchema = object({
28947
+ nodeId: string(),
28948
+ outcome: UninstallNodeOutcomeSchema,
28949
+ error: string().optional(),
28950
+ addonIds: array(string()).readonly(),
28951
+ runnersStopped: array(string()).readonly(),
28952
+ warnings: array(string()).readonly()
28953
+ });
28954
+ var UninstallPackageResultSchema = object({
28955
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
28956
+ success: boolean(),
28957
+ packageName: string(),
28958
+ results: array(UninstallNodeResultSchema).readonly()
28959
+ });
28960
+ /**
28961
+ * `unreachable` lists online agents whose status read FAILED — absence from
28962
+ * `installations` is only "not installed" for a node that answered (D315).
28963
+ */
28964
+ var PackageInstallationsSchema = object({
28965
+ installations: array(object({
28966
+ packageName: string(),
28967
+ nodeId: string(),
28968
+ nodeName: string(),
28969
+ isHub: boolean(),
28970
+ isOnline: boolean(),
28971
+ version: string().nullable(),
28972
+ addonIds: array(string()).readonly(),
28973
+ source: _enum(["live", "recorded"]),
28974
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
28975
+ onHub: boolean()
28976
+ })).readonly(),
28977
+ unreachable: array(object({
28978
+ nodeId: string(),
28979
+ error: string()
28980
+ })).readonly()
28981
+ });
28818
28982
  var BulkUpdateItemStatusSchema = _enum([
28819
28983
  "queued",
28820
28984
  "updating",
@@ -28897,10 +29061,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
28897
29061
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
28898
29062
  kind: "mutation",
28899
29063
  auth: "admin"
28900
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29064
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29065
+ packageName: string().min(1),
29066
+ nodeId: string().optional(),
29067
+ everywhere: boolean().optional()
29068
+ }), UninstallPackageResultSchema, {
28901
29069
  kind: "mutation",
28902
29070
  auth: "admin"
28903
- }), method(_void(), ReloadPackagesResultSchema, {
29071
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
28904
29072
  kind: "mutation",
28905
29073
  auth: "admin"
28906
29074
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -38818,6 +38986,32 @@ var TotpStatusSchema = object({
38818
38986
  /** Null when no row exists OR the row is still pending confirmation. */
38819
38987
  confirmedAt: number().nullable()
38820
38988
  });
38989
+ /**
38990
+ * user-management — singleton capability for user accounts, API keys,
38991
+ * and scoped tokens.
38992
+ *
38993
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
38994
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
38995
+ * because non-admins never reach these. If/when we open non-admin
38996
+ * delegation, structural caller-scope subset check goes inside the
38997
+ * provider.
38998
+ */
38999
+ var ExternalIdentitySchema = object({
39000
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39001
+ provider: string(),
39002
+ /** The IdP's stable subject (`sub`) for this account. */
39003
+ subject: string(),
39004
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39005
+ issuer: string(),
39006
+ userId: string(),
39007
+ /** What the IdP called the account at link time (username / email) — display only. */
39008
+ label: string().optional(),
39009
+ linkedAt: number()
39010
+ });
39011
+ var ExternalIdentityKeySchema = object({
39012
+ provider: string().min(1),
39013
+ subject: string().min(1)
39014
+ });
38821
39015
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
38822
39016
  kind: "mutation",
38823
39017
  auth: "admin",
@@ -38931,7 +39125,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
38931
39125
  userId: string(),
38932
39126
  username: string(),
38933
39127
  scopes: array(TokenScopeSchema)
38934
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39128
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39129
+ userId: string(),
39130
+ issuer: string()
39131
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39132
+ userId: string(),
39133
+ issuer: string().min(1),
39134
+ label: string().optional()
39135
+ }), object({ success: literal(true) }), {
39136
+ kind: "mutation",
39137
+ auth: "admin",
39138
+ access: "create"
39139
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39140
+ kind: "mutation",
39141
+ auth: "admin",
39142
+ access: "delete"
39143
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
38935
39144
  kind: "mutation",
38936
39145
  auth: "admin",
38937
39146
  access: "delete"
@@ -41341,6 +41550,12 @@ Object.freeze({
41341
41550
  addonId: null,
41342
41551
  access: "view"
41343
41552
  },
41553
+ "addons.listInstallations": {
41554
+ capName: "addons",
41555
+ capScope: "system",
41556
+ addonId: null,
41557
+ access: "view"
41558
+ },
41344
41559
  "addons.listJobs": {
41345
41560
  capName: "addons",
41346
41561
  capScope: "system",
@@ -45565,6 +45780,12 @@ Object.freeze({
45565
45780
  addonId: null,
45566
45781
  access: "create"
45567
45782
  },
45783
+ "pipelineAnalytics.setRetrainFrameComplete": {
45784
+ capName: "pipeline-analytics",
45785
+ capScope: "device",
45786
+ addonId: null,
45787
+ access: "create"
45788
+ },
45568
45789
  "pipelineAnalytics.setTrackFlags": {
45569
45790
  capName: "pipeline-analytics",
45570
45791
  capScope: "device",
@@ -45601,6 +45822,12 @@ Object.freeze({
45601
45822
  addonId: null,
45602
45823
  access: "delete"
45603
45824
  },
45825
+ "pipelineAnalytics.writeRetrainArchive": {
45826
+ capName: "pipeline-analytics",
45827
+ capScope: "device",
45828
+ addonId: null,
45829
+ access: "create"
45830
+ },
45604
45831
  "pipelineExecutor.cacheFrameInPool": {
45605
45832
  capName: "pipeline-executor",
45606
45833
  capScope: "system",
@@ -47953,18 +48180,36 @@ Object.freeze({
47953
48180
  addonId: null,
47954
48181
  access: "delete"
47955
48182
  },
48183
+ "userManagement.findUserByExternalIdentity": {
48184
+ capName: "user-management",
48185
+ capScope: "system",
48186
+ addonId: null,
48187
+ access: "view"
48188
+ },
47956
48189
  "userManagement.getTotpStatus": {
47957
48190
  capName: "user-management",
47958
48191
  capScope: "system",
47959
48192
  addonId: null,
47960
48193
  access: "view"
47961
48194
  },
48195
+ "userManagement.linkExternalIdentity": {
48196
+ capName: "user-management",
48197
+ capScope: "system",
48198
+ addonId: null,
48199
+ access: "create"
48200
+ },
47962
48201
  "userManagement.listApiKeys": {
47963
48202
  capName: "user-management",
47964
48203
  capScope: "system",
47965
48204
  addonId: null,
47966
48205
  access: "view"
47967
48206
  },
48207
+ "userManagement.listExternalIdentities": {
48208
+ capName: "user-management",
48209
+ capScope: "system",
48210
+ addonId: null,
48211
+ access: "view"
48212
+ },
47968
48213
  "userManagement.listOauthSessions": {
47969
48214
  capName: "user-management",
47970
48215
  capScope: "system",
@@ -48043,6 +48288,12 @@ Object.freeze({
48043
48288
  addonId: null,
48044
48289
  access: "create"
48045
48290
  },
48291
+ "userManagement.unlinkExternalIdentity": {
48292
+ capName: "user-management",
48293
+ capScope: "system",
48294
+ addonId: null,
48295
+ access: "delete"
48296
+ },
48046
48297
  "userManagement.updateUser": {
48047
48298
  capName: "user-management",
48048
48299
  capScope: "system",
@@ -51382,6 +51633,11 @@ Object.freeze({
51382
51633
  form: "single",
51383
51634
  optional: false
51384
51635
  }],
51636
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51637
+ name: "deviceId",
51638
+ form: "single",
51639
+ optional: false
51640
+ }],
51385
51641
  "pipelineAnalytics.setTrackFlags": [{
51386
51642
  name: "deviceId",
51387
51643
  form: "single",
@@ -53449,7 +53705,7 @@ var DreoRegionSchema = _enum(DREO_REGIONS);
53449
53705
  */
53450
53706
  var dreoConfigSchema = object({
53451
53707
  email: string().min(1).describe("Dreo account email"),
53452
- password: string().min(1).describe("Dreo account password"),
53708
+ password: string().min(1).describe("Dreo account password").meta({ secret: true }),
53453
53709
  region: DreoRegionSchema.default("us").describe("Dreo cloud region")
53454
53710
  });
53455
53711
  /**
package/dist/addon.mjs CHANGED
@@ -5407,7 +5407,7 @@ var ZodIssueCode = {
5407
5407
  var ZodFirstPartyTypeKind;
5408
5408
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5409
5409
  //#endregion
5410
- //#region ../types/dist/sleep-BNeXenvr.mjs
5410
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5411
5411
  /**
5412
5412
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5413
5413
  * window to float samples (D455).
@@ -15133,6 +15133,10 @@ var DeviceInfoSchema = object({
15133
15133
  isCamera: boolean(),
15134
15134
  /** Current config values — serializable snapshot */
15135
15135
  config: record(string(), unknown()),
15136
+ /** Paths inside `config` the device's schema declares secret (D783) —
15137
+ * what the non-admin redaction withholds. Paths, never values. Absent
15138
+ * when the owning runner has not reported them. */
15139
+ secretConfigPaths: array(string()).optional(),
15136
15140
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15137
15141
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15138
15142
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15338,7 +15342,13 @@ var DeviceRegisterPayloadSchema = object({
15338
15342
  * call (workers re-register on init), so probe-driven updates
15339
15343
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15340
15344
  features: array(string()).optional(),
15341
- config: record(string(), unknown())
15345
+ config: record(string(), unknown()),
15346
+ /** Config paths the device's own schema DECLARES secret
15347
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15348
+ * `connection.password`). Re-published on every register; the non-admin
15349
+ * redaction withholds them at any depth (D783). Optional: an older runner
15350
+ * omits it and the keyword backstop applies. */
15351
+ secretConfigPaths: array(string()).optional()
15342
15352
  });
15343
15353
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15344
15354
  var DevicePersistConfigPayloadSchema = object({
@@ -16997,7 +17007,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
16997
17007
  icon: string().optional(),
16998
17008
  /** Addon-owned HTTP route the button navigates to (GET). */
16999
17009
  startUrl: string(),
17000
- stage: LoginStageEnum
17010
+ stage: LoginStageEnum,
17011
+ /**
17012
+ * The provider names an external identity a signed-in user can link to
17013
+ * their own account (D782): `auth.listLinkableProviders` /
17014
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17015
+ * whatever their id. Absent / false — a login button only (magic-link).
17016
+ */
17017
+ linkable: boolean().optional()
17001
17018
  }),
17002
17019
  object({
17003
17020
  kind: literal("widget"),
@@ -22432,7 +22449,13 @@ var RetrainFrameSchema = object({
22432
22449
  sizeBytes: number().int(),
22433
22450
  width: number().int(),
22434
22451
  height: number().int(),
22435
- copiedAt: number()
22452
+ copiedAt: number(),
22453
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22454
+ capturedAt: number().optional(),
22455
+ /** The operator's "every subject in this frame is boxed". Detector
22456
+ * evaluation keeps only complete frames: an unboxed subject would count as
22457
+ * a false positive. */
22458
+ complete: boolean()
22436
22459
  });
22437
22460
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22438
22461
  var RetrainCopyRefusalSchema = _enum([
@@ -22453,6 +22476,51 @@ var RetrainFrameListSchema = object({
22453
22476
  /** What the page pre-selects — the native key frame when one survives. */
22454
22477
  autoPickMediaId: number().int().optional()
22455
22478
  });
22479
+ /**
22480
+ * Which frames an annotated export carries. Every field narrows; an empty
22481
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22482
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22483
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22484
+ * export carried (`exportedInBatch`).
22485
+ */
22486
+ var RetrainExportFilterSchema = object({
22487
+ deviceIds: array(number()).optional(),
22488
+ frameIds: array(string()).max(2e4).optional(),
22489
+ batchId: string().optional(),
22490
+ /** Only frames the operator marked complete (all subjects boxed). */
22491
+ completeOnly: boolean().optional()
22492
+ });
22493
+ /**
22494
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22495
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22496
+ * convention — the classifier layout.
22497
+ */
22498
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22499
+ /**
22500
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22501
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22502
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22503
+ * logged.
22504
+ */
22505
+ var RetrainArchiveTargetSchema = object({
22506
+ kind: literal("http"),
22507
+ method: _enum(["PUT", "POST"]),
22508
+ url: string().url(),
22509
+ headers: record(string(), string()).optional()
22510
+ });
22511
+ var RetrainArchiveResultSchema = object({
22512
+ batchId: string(),
22513
+ frames: number().int(),
22514
+ crops: number().int(),
22515
+ annotations: number().int(),
22516
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22517
+ missing: number().int(),
22518
+ bytes: number().int(),
22519
+ /** sha256 of the exact bytes sent. */
22520
+ sha256: string(),
22521
+ /** The target's HTTP status. */
22522
+ status: number().int()
22523
+ });
22456
22524
  /** What the operator asked the assist to look for. */
22457
22525
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22458
22526
  kind: literal("package"),
@@ -23247,9 +23315,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23247
23315
  }), RetrainTransitionResultSchema, {
23248
23316
  kind: "mutation",
23249
23317
  auth: "admin"
23250
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23318
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23251
23319
  kind: "query",
23252
23320
  auth: "admin"
23321
+ }), method(object({
23322
+ deviceId: number(),
23323
+ trackId: string(),
23324
+ frameId: string(),
23325
+ complete: boolean()
23326
+ }), RetrainFrameSchema, {
23327
+ kind: "mutation",
23328
+ auth: "admin"
23329
+ }), method(object({
23330
+ filter: RetrainExportFilterSchema,
23331
+ layout: RetrainExportLayoutSchema,
23332
+ target: RetrainArchiveTargetSchema
23333
+ }), RetrainArchiveResultSchema, {
23334
+ kind: "mutation",
23335
+ auth: "admin",
23336
+ timeoutMs: 60 * 6e4
23253
23337
  }), method(object({
23254
23338
  /** Which of the three event tables owns the row. */
23255
23339
  ownerType: EventOwnerTypeSchema,
@@ -26579,7 +26663,19 @@ var SsoBridgeClaimsSchema = object({
26579
26663
  * editing a descriptor must not retroactively extend or shorten a link the
26580
26664
  * operator already consented to.
26581
26665
  */
26582
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26666
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26667
+ /**
26668
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26669
+ * that was started from a signed-in user's "Link" button: the finish then
26670
+ * links this identity to the intent's user instead of signing anyone in.
26671
+ * The handle carries no user id — the hub resolves it, single-use.
26672
+ */
26673
+ linkIntent: string().optional(),
26674
+ /**
26675
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26676
+ * subject is unique only per issuer, so a link is bound to it.
26677
+ */
26678
+ issuer: string().optional()
26583
26679
  });
26584
26680
  method(object({
26585
26681
  claims: SsoBridgeClaimsSchema,
@@ -28514,7 +28610,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28514
28610
  * field their hints were silently stripped by the schema and the
28515
28611
  * adaptive ladder started blind on the client's display size.
28516
28612
  */
28517
- hints: webrtcClientHintsSchema.optional()
28613
+ hints: webrtcClientHintsSchema.optional(),
28614
+ /**
28615
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28616
+ * through the `intercom` cap's push-talk triple. When `true` and the
28617
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28618
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28619
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28620
+ *
28621
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28622
+ * with `intercom`, when the linked user may control that camera. The
28623
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28624
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28625
+ * intercom cap's own surface (share tokens gate it there), and this
28626
+ * flag must not become a second door to the camera's speaker.
28627
+ */
28628
+ talkback: boolean().optional()
28518
28629
  }), object({
28519
28630
  sessionId: string(),
28520
28631
  sdpAnswer: string()
@@ -28816,6 +28927,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28816
28927
  var RestartAddonResultSchema = unknown();
28817
28928
  var InstallPackageResultSchema = unknown();
28818
28929
  var ReloadPackagesResultSchema = unknown();
28930
+ /**
28931
+ * What an uninstall did on ONE node.
28932
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
28933
+ * - `not-installed` — the node did not have it (nothing to do).
28934
+ * - `refused` — protected / bootstrap package; nothing touched.
28935
+ * - `failed` — attempted and did not complete; `error` says why.
28936
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
28937
+ * back-fill never returns the package, and the stale-addon sweep removes the
28938
+ * copy when the node registers again (only once the hub no longer has it).
28939
+ */
28940
+ var UninstallNodeOutcomeSchema = _enum([
28941
+ "uninstalled",
28942
+ "not-installed",
28943
+ "refused",
28944
+ "failed",
28945
+ "pending-reconnect"
28946
+ ]);
28947
+ var UninstallNodeResultSchema = object({
28948
+ nodeId: string(),
28949
+ outcome: UninstallNodeOutcomeSchema,
28950
+ error: string().optional(),
28951
+ addonIds: array(string()).readonly(),
28952
+ runnersStopped: array(string()).readonly(),
28953
+ warnings: array(string()).readonly()
28954
+ });
28955
+ var UninstallPackageResultSchema = object({
28956
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
28957
+ success: boolean(),
28958
+ packageName: string(),
28959
+ results: array(UninstallNodeResultSchema).readonly()
28960
+ });
28961
+ /**
28962
+ * `unreachable` lists online agents whose status read FAILED — absence from
28963
+ * `installations` is only "not installed" for a node that answered (D315).
28964
+ */
28965
+ var PackageInstallationsSchema = object({
28966
+ installations: array(object({
28967
+ packageName: string(),
28968
+ nodeId: string(),
28969
+ nodeName: string(),
28970
+ isHub: boolean(),
28971
+ isOnline: boolean(),
28972
+ version: string().nullable(),
28973
+ addonIds: array(string()).readonly(),
28974
+ source: _enum(["live", "recorded"]),
28975
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
28976
+ onHub: boolean()
28977
+ })).readonly(),
28978
+ unreachable: array(object({
28979
+ nodeId: string(),
28980
+ error: string()
28981
+ })).readonly()
28982
+ });
28819
28983
  var BulkUpdateItemStatusSchema = _enum([
28820
28984
  "queued",
28821
28985
  "updating",
@@ -28898,10 +29062,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
28898
29062
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
28899
29063
  kind: "mutation",
28900
29064
  auth: "admin"
28901
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29065
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29066
+ packageName: string().min(1),
29067
+ nodeId: string().optional(),
29068
+ everywhere: boolean().optional()
29069
+ }), UninstallPackageResultSchema, {
28902
29070
  kind: "mutation",
28903
29071
  auth: "admin"
28904
- }), method(_void(), ReloadPackagesResultSchema, {
29072
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
28905
29073
  kind: "mutation",
28906
29074
  auth: "admin"
28907
29075
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -38819,6 +38987,32 @@ var TotpStatusSchema = object({
38819
38987
  /** Null when no row exists OR the row is still pending confirmation. */
38820
38988
  confirmedAt: number().nullable()
38821
38989
  });
38990
+ /**
38991
+ * user-management — singleton capability for user accounts, API keys,
38992
+ * and scoped tokens.
38993
+ *
38994
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
38995
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
38996
+ * because non-admins never reach these. If/when we open non-admin
38997
+ * delegation, structural caller-scope subset check goes inside the
38998
+ * provider.
38999
+ */
39000
+ var ExternalIdentitySchema = object({
39001
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39002
+ provider: string(),
39003
+ /** The IdP's stable subject (`sub`) for this account. */
39004
+ subject: string(),
39005
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39006
+ issuer: string(),
39007
+ userId: string(),
39008
+ /** What the IdP called the account at link time (username / email) — display only. */
39009
+ label: string().optional(),
39010
+ linkedAt: number()
39011
+ });
39012
+ var ExternalIdentityKeySchema = object({
39013
+ provider: string().min(1),
39014
+ subject: string().min(1)
39015
+ });
38822
39016
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
38823
39017
  kind: "mutation",
38824
39018
  auth: "admin",
@@ -38932,7 +39126,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
38932
39126
  userId: string(),
38933
39127
  username: string(),
38934
39128
  scopes: array(TokenScopeSchema)
38935
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39129
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39130
+ userId: string(),
39131
+ issuer: string()
39132
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39133
+ userId: string(),
39134
+ issuer: string().min(1),
39135
+ label: string().optional()
39136
+ }), object({ success: literal(true) }), {
39137
+ kind: "mutation",
39138
+ auth: "admin",
39139
+ access: "create"
39140
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39141
+ kind: "mutation",
39142
+ auth: "admin",
39143
+ access: "delete"
39144
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
38936
39145
  kind: "mutation",
38937
39146
  auth: "admin",
38938
39147
  access: "delete"
@@ -41342,6 +41551,12 @@ Object.freeze({
41342
41551
  addonId: null,
41343
41552
  access: "view"
41344
41553
  },
41554
+ "addons.listInstallations": {
41555
+ capName: "addons",
41556
+ capScope: "system",
41557
+ addonId: null,
41558
+ access: "view"
41559
+ },
41345
41560
  "addons.listJobs": {
41346
41561
  capName: "addons",
41347
41562
  capScope: "system",
@@ -45566,6 +45781,12 @@ Object.freeze({
45566
45781
  addonId: null,
45567
45782
  access: "create"
45568
45783
  },
45784
+ "pipelineAnalytics.setRetrainFrameComplete": {
45785
+ capName: "pipeline-analytics",
45786
+ capScope: "device",
45787
+ addonId: null,
45788
+ access: "create"
45789
+ },
45569
45790
  "pipelineAnalytics.setTrackFlags": {
45570
45791
  capName: "pipeline-analytics",
45571
45792
  capScope: "device",
@@ -45602,6 +45823,12 @@ Object.freeze({
45602
45823
  addonId: null,
45603
45824
  access: "delete"
45604
45825
  },
45826
+ "pipelineAnalytics.writeRetrainArchive": {
45827
+ capName: "pipeline-analytics",
45828
+ capScope: "device",
45829
+ addonId: null,
45830
+ access: "create"
45831
+ },
45605
45832
  "pipelineExecutor.cacheFrameInPool": {
45606
45833
  capName: "pipeline-executor",
45607
45834
  capScope: "system",
@@ -47954,18 +48181,36 @@ Object.freeze({
47954
48181
  addonId: null,
47955
48182
  access: "delete"
47956
48183
  },
48184
+ "userManagement.findUserByExternalIdentity": {
48185
+ capName: "user-management",
48186
+ capScope: "system",
48187
+ addonId: null,
48188
+ access: "view"
48189
+ },
47957
48190
  "userManagement.getTotpStatus": {
47958
48191
  capName: "user-management",
47959
48192
  capScope: "system",
47960
48193
  addonId: null,
47961
48194
  access: "view"
47962
48195
  },
48196
+ "userManagement.linkExternalIdentity": {
48197
+ capName: "user-management",
48198
+ capScope: "system",
48199
+ addonId: null,
48200
+ access: "create"
48201
+ },
47963
48202
  "userManagement.listApiKeys": {
47964
48203
  capName: "user-management",
47965
48204
  capScope: "system",
47966
48205
  addonId: null,
47967
48206
  access: "view"
47968
48207
  },
48208
+ "userManagement.listExternalIdentities": {
48209
+ capName: "user-management",
48210
+ capScope: "system",
48211
+ addonId: null,
48212
+ access: "view"
48213
+ },
47969
48214
  "userManagement.listOauthSessions": {
47970
48215
  capName: "user-management",
47971
48216
  capScope: "system",
@@ -48044,6 +48289,12 @@ Object.freeze({
48044
48289
  addonId: null,
48045
48290
  access: "create"
48046
48291
  },
48292
+ "userManagement.unlinkExternalIdentity": {
48293
+ capName: "user-management",
48294
+ capScope: "system",
48295
+ addonId: null,
48296
+ access: "delete"
48297
+ },
48047
48298
  "userManagement.updateUser": {
48048
48299
  capName: "user-management",
48049
48300
  capScope: "system",
@@ -51383,6 +51634,11 @@ Object.freeze({
51383
51634
  form: "single",
51384
51635
  optional: false
51385
51636
  }],
51637
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51638
+ name: "deviceId",
51639
+ form: "single",
51640
+ optional: false
51641
+ }],
51386
51642
  "pipelineAnalytics.setTrackFlags": [{
51387
51643
  name: "deviceId",
51388
51644
  form: "single",
@@ -53450,7 +53706,7 @@ var DreoRegionSchema = _enum(DREO_REGIONS);
53450
53706
  */
53451
53707
  var dreoConfigSchema = object({
53452
53708
  email: string().min(1).describe("Dreo account email"),
53453
- password: string().min(1).describe("Dreo account password"),
53709
+ password: string().min(1).describe("Dreo account password").meta({ secret: true }),
53454
53710
  region: DreoRegionSchema.default("us").describe("Dreo cloud region")
53455
53711
  });
53456
53712
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.2.120",
3
+ "version": "0.2.122",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",