@camstack/addon-provider-homematic 1.2.127 → 1.2.129

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
@@ -5379,7 +5379,7 @@ var ZodIssueCode = {
5379
5379
  var ZodFirstPartyTypeKind;
5380
5380
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5381
5381
  //#endregion
5382
- //#region ../types/dist/sleep-BNeXenvr.mjs
5382
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5383
5383
  /**
5384
5384
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5385
5385
  * window to float samples (D455).
@@ -15267,6 +15267,10 @@ var DeviceInfoSchema = object({
15267
15267
  isCamera: boolean(),
15268
15268
  /** Current config values — serializable snapshot */
15269
15269
  config: record(string(), unknown()),
15270
+ /** Paths inside `config` the device's schema declares secret (D783) —
15271
+ * what the non-admin redaction withholds. Paths, never values. Absent
15272
+ * when the owning runner has not reported them. */
15273
+ secretConfigPaths: array(string()).optional(),
15270
15274
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15271
15275
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15272
15276
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15472,7 +15476,13 @@ var DeviceRegisterPayloadSchema = object({
15472
15476
  * call (workers re-register on init), so probe-driven updates
15473
15477
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15474
15478
  features: array(string()).optional(),
15475
- config: record(string(), unknown())
15479
+ config: record(string(), unknown()),
15480
+ /** Config paths the device's own schema DECLARES secret
15481
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15482
+ * `connection.password`). Re-published on every register; the non-admin
15483
+ * redaction withholds them at any depth (D783). Optional: an older runner
15484
+ * omits it and the keyword backstop applies. */
15485
+ secretConfigPaths: array(string()).optional()
15476
15486
  });
15477
15487
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15478
15488
  var DevicePersistConfigPayloadSchema = object({
@@ -17131,7 +17141,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
17131
17141
  icon: string().optional(),
17132
17142
  /** Addon-owned HTTP route the button navigates to (GET). */
17133
17143
  startUrl: string(),
17134
- stage: LoginStageEnum
17144
+ stage: LoginStageEnum,
17145
+ /**
17146
+ * The provider names an external identity a signed-in user can link to
17147
+ * their own account (D782): `auth.listLinkableProviders` /
17148
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17149
+ * whatever their id. Absent / false — a login button only (magic-link).
17150
+ */
17151
+ linkable: boolean().optional()
17135
17152
  }),
17136
17153
  object({
17137
17154
  kind: literal("widget"),
@@ -22566,7 +22583,13 @@ var RetrainFrameSchema = object({
22566
22583
  sizeBytes: number().int(),
22567
22584
  width: number().int(),
22568
22585
  height: number().int(),
22569
- copiedAt: number()
22586
+ copiedAt: number(),
22587
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22588
+ capturedAt: number().optional(),
22589
+ /** The operator's "every subject in this frame is boxed". Detector
22590
+ * evaluation keeps only complete frames: an unboxed subject would count as
22591
+ * a false positive. */
22592
+ complete: boolean()
22570
22593
  });
22571
22594
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22572
22595
  var RetrainCopyRefusalSchema = _enum([
@@ -22587,6 +22610,51 @@ var RetrainFrameListSchema = object({
22587
22610
  /** What the page pre-selects — the native key frame when one survives. */
22588
22611
  autoPickMediaId: number().int().optional()
22589
22612
  });
22613
+ /**
22614
+ * Which frames an annotated export carries. Every field narrows; an empty
22615
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22616
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22617
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22618
+ * export carried (`exportedInBatch`).
22619
+ */
22620
+ var RetrainExportFilterSchema = object({
22621
+ deviceIds: array(number()).optional(),
22622
+ frameIds: array(string()).max(2e4).optional(),
22623
+ batchId: string().optional(),
22624
+ /** Only frames the operator marked complete (all subjects boxed). */
22625
+ completeOnly: boolean().optional()
22626
+ });
22627
+ /**
22628
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22629
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22630
+ * convention — the classifier layout.
22631
+ */
22632
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22633
+ /**
22634
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22635
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22636
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22637
+ * logged.
22638
+ */
22639
+ var RetrainArchiveTargetSchema = object({
22640
+ kind: literal("http"),
22641
+ method: _enum(["PUT", "POST"]),
22642
+ url: string().url(),
22643
+ headers: record(string(), string()).optional()
22644
+ });
22645
+ var RetrainArchiveResultSchema = object({
22646
+ batchId: string(),
22647
+ frames: number().int(),
22648
+ crops: number().int(),
22649
+ annotations: number().int(),
22650
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22651
+ missing: number().int(),
22652
+ bytes: number().int(),
22653
+ /** sha256 of the exact bytes sent. */
22654
+ sha256: string(),
22655
+ /** The target's HTTP status. */
22656
+ status: number().int()
22657
+ });
22590
22658
  /** What the operator asked the assist to look for. */
22591
22659
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22592
22660
  kind: literal("package"),
@@ -23381,9 +23449,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23381
23449
  }), RetrainTransitionResultSchema, {
23382
23450
  kind: "mutation",
23383
23451
  auth: "admin"
23384
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23452
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23385
23453
  kind: "query",
23386
23454
  auth: "admin"
23455
+ }), method(object({
23456
+ deviceId: number(),
23457
+ trackId: string(),
23458
+ frameId: string(),
23459
+ complete: boolean()
23460
+ }), RetrainFrameSchema, {
23461
+ kind: "mutation",
23462
+ auth: "admin"
23463
+ }), method(object({
23464
+ filter: RetrainExportFilterSchema,
23465
+ layout: RetrainExportLayoutSchema,
23466
+ target: RetrainArchiveTargetSchema
23467
+ }), RetrainArchiveResultSchema, {
23468
+ kind: "mutation",
23469
+ auth: "admin",
23470
+ timeoutMs: 60 * 6e4
23387
23471
  }), method(object({
23388
23472
  /** Which of the three event tables owns the row. */
23389
23473
  ownerType: EventOwnerTypeSchema,
@@ -26713,7 +26797,19 @@ var SsoBridgeClaimsSchema = object({
26713
26797
  * editing a descriptor must not retroactively extend or shorten a link the
26714
26798
  * operator already consented to.
26715
26799
  */
26716
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26800
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26801
+ /**
26802
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26803
+ * that was started from a signed-in user's "Link" button: the finish then
26804
+ * links this identity to the intent's user instead of signing anyone in.
26805
+ * The handle carries no user id — the hub resolves it, single-use.
26806
+ */
26807
+ linkIntent: string().optional(),
26808
+ /**
26809
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26810
+ * subject is unique only per issuer, so a link is bound to it.
26811
+ */
26812
+ issuer: string().optional()
26717
26813
  });
26718
26814
  method(object({
26719
26815
  claims: SsoBridgeClaimsSchema,
@@ -28648,7 +28744,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28648
28744
  * field their hints were silently stripped by the schema and the
28649
28745
  * adaptive ladder started blind on the client's display size.
28650
28746
  */
28651
- hints: webrtcClientHintsSchema.optional()
28747
+ hints: webrtcClientHintsSchema.optional(),
28748
+ /**
28749
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28750
+ * through the `intercom` cap's push-talk triple. When `true` and the
28751
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28752
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28753
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28754
+ *
28755
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28756
+ * with `intercom`, when the linked user may control that camera. The
28757
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28758
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28759
+ * intercom cap's own surface (share tokens gate it there), and this
28760
+ * flag must not become a second door to the camera's speaker.
28761
+ */
28762
+ talkback: boolean().optional()
28652
28763
  }), object({
28653
28764
  sessionId: string(),
28654
28765
  sdpAnswer: string()
@@ -28950,6 +29061,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28950
29061
  var RestartAddonResultSchema = unknown();
28951
29062
  var InstallPackageResultSchema = unknown();
28952
29063
  var ReloadPackagesResultSchema = unknown();
29064
+ /**
29065
+ * What an uninstall did on ONE node.
29066
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29067
+ * - `not-installed` — the node did not have it (nothing to do).
29068
+ * - `refused` — protected / bootstrap package; nothing touched.
29069
+ * - `failed` — attempted and did not complete; `error` says why.
29070
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29071
+ * back-fill never returns the package, and the stale-addon sweep removes the
29072
+ * copy when the node registers again (only once the hub no longer has it).
29073
+ */
29074
+ var UninstallNodeOutcomeSchema = _enum([
29075
+ "uninstalled",
29076
+ "not-installed",
29077
+ "refused",
29078
+ "failed",
29079
+ "pending-reconnect"
29080
+ ]);
29081
+ var UninstallNodeResultSchema = object({
29082
+ nodeId: string(),
29083
+ outcome: UninstallNodeOutcomeSchema,
29084
+ error: string().optional(),
29085
+ addonIds: array(string()).readonly(),
29086
+ runnersStopped: array(string()).readonly(),
29087
+ warnings: array(string()).readonly()
29088
+ });
29089
+ var UninstallPackageResultSchema = object({
29090
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
29091
+ success: boolean(),
29092
+ packageName: string(),
29093
+ results: array(UninstallNodeResultSchema).readonly()
29094
+ });
29095
+ /**
29096
+ * `unreachable` lists online agents whose status read FAILED — absence from
29097
+ * `installations` is only "not installed" for a node that answered (D315).
29098
+ */
29099
+ var PackageInstallationsSchema = object({
29100
+ installations: array(object({
29101
+ packageName: string(),
29102
+ nodeId: string(),
29103
+ nodeName: string(),
29104
+ isHub: boolean(),
29105
+ isOnline: boolean(),
29106
+ version: string().nullable(),
29107
+ addonIds: array(string()).readonly(),
29108
+ source: _enum(["live", "recorded"]),
29109
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
29110
+ onHub: boolean()
29111
+ })).readonly(),
29112
+ unreachable: array(object({
29113
+ nodeId: string(),
29114
+ error: string()
29115
+ })).readonly()
29116
+ });
28953
29117
  var BulkUpdateItemStatusSchema = _enum([
28954
29118
  "queued",
28955
29119
  "updating",
@@ -29032,10 +29196,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29032
29196
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29033
29197
  kind: "mutation",
29034
29198
  auth: "admin"
29035
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29199
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29200
+ packageName: string().min(1),
29201
+ nodeId: string().optional(),
29202
+ everywhere: boolean().optional()
29203
+ }), UninstallPackageResultSchema, {
29036
29204
  kind: "mutation",
29037
29205
  auth: "admin"
29038
- }), method(_void(), ReloadPackagesResultSchema, {
29206
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29039
29207
  kind: "mutation",
29040
29208
  auth: "admin"
29041
29209
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -38945,6 +39113,32 @@ var TotpStatusSchema = object({
38945
39113
  /** Null when no row exists OR the row is still pending confirmation. */
38946
39114
  confirmedAt: number().nullable()
38947
39115
  });
39116
+ /**
39117
+ * user-management — singleton capability for user accounts, API keys,
39118
+ * and scoped tokens.
39119
+ *
39120
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
39121
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
39122
+ * because non-admins never reach these. If/when we open non-admin
39123
+ * delegation, structural caller-scope subset check goes inside the
39124
+ * provider.
39125
+ */
39126
+ var ExternalIdentitySchema = object({
39127
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39128
+ provider: string(),
39129
+ /** The IdP's stable subject (`sub`) for this account. */
39130
+ subject: string(),
39131
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39132
+ issuer: string(),
39133
+ userId: string(),
39134
+ /** What the IdP called the account at link time (username / email) — display only. */
39135
+ label: string().optional(),
39136
+ linkedAt: number()
39137
+ });
39138
+ var ExternalIdentityKeySchema = object({
39139
+ provider: string().min(1),
39140
+ subject: string().min(1)
39141
+ });
38948
39142
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
38949
39143
  kind: "mutation",
38950
39144
  auth: "admin",
@@ -39058,7 +39252,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39058
39252
  userId: string(),
39059
39253
  username: string(),
39060
39254
  scopes: array(TokenScopeSchema)
39061
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39255
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39256
+ userId: string(),
39257
+ issuer: string()
39258
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39259
+ userId: string(),
39260
+ issuer: string().min(1),
39261
+ label: string().optional()
39262
+ }), object({ success: literal(true) }), {
39263
+ kind: "mutation",
39264
+ auth: "admin",
39265
+ access: "create"
39266
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39267
+ kind: "mutation",
39268
+ auth: "admin",
39269
+ access: "delete"
39270
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39062
39271
  kind: "mutation",
39063
39272
  auth: "admin",
39064
39273
  access: "delete"
@@ -41468,6 +41677,12 @@ Object.freeze({
41468
41677
  addonId: null,
41469
41678
  access: "view"
41470
41679
  },
41680
+ "addons.listInstallations": {
41681
+ capName: "addons",
41682
+ capScope: "system",
41683
+ addonId: null,
41684
+ access: "view"
41685
+ },
41471
41686
  "addons.listJobs": {
41472
41687
  capName: "addons",
41473
41688
  capScope: "system",
@@ -45692,6 +45907,12 @@ Object.freeze({
45692
45907
  addonId: null,
45693
45908
  access: "create"
45694
45909
  },
45910
+ "pipelineAnalytics.setRetrainFrameComplete": {
45911
+ capName: "pipeline-analytics",
45912
+ capScope: "device",
45913
+ addonId: null,
45914
+ access: "create"
45915
+ },
45695
45916
  "pipelineAnalytics.setTrackFlags": {
45696
45917
  capName: "pipeline-analytics",
45697
45918
  capScope: "device",
@@ -45728,6 +45949,12 @@ Object.freeze({
45728
45949
  addonId: null,
45729
45950
  access: "delete"
45730
45951
  },
45952
+ "pipelineAnalytics.writeRetrainArchive": {
45953
+ capName: "pipeline-analytics",
45954
+ capScope: "device",
45955
+ addonId: null,
45956
+ access: "create"
45957
+ },
45731
45958
  "pipelineExecutor.cacheFrameInPool": {
45732
45959
  capName: "pipeline-executor",
45733
45960
  capScope: "system",
@@ -48080,18 +48307,36 @@ Object.freeze({
48080
48307
  addonId: null,
48081
48308
  access: "delete"
48082
48309
  },
48310
+ "userManagement.findUserByExternalIdentity": {
48311
+ capName: "user-management",
48312
+ capScope: "system",
48313
+ addonId: null,
48314
+ access: "view"
48315
+ },
48083
48316
  "userManagement.getTotpStatus": {
48084
48317
  capName: "user-management",
48085
48318
  capScope: "system",
48086
48319
  addonId: null,
48087
48320
  access: "view"
48088
48321
  },
48322
+ "userManagement.linkExternalIdentity": {
48323
+ capName: "user-management",
48324
+ capScope: "system",
48325
+ addonId: null,
48326
+ access: "create"
48327
+ },
48089
48328
  "userManagement.listApiKeys": {
48090
48329
  capName: "user-management",
48091
48330
  capScope: "system",
48092
48331
  addonId: null,
48093
48332
  access: "view"
48094
48333
  },
48334
+ "userManagement.listExternalIdentities": {
48335
+ capName: "user-management",
48336
+ capScope: "system",
48337
+ addonId: null,
48338
+ access: "view"
48339
+ },
48095
48340
  "userManagement.listOauthSessions": {
48096
48341
  capName: "user-management",
48097
48342
  capScope: "system",
@@ -48170,6 +48415,12 @@ Object.freeze({
48170
48415
  addonId: null,
48171
48416
  access: "create"
48172
48417
  },
48418
+ "userManagement.unlinkExternalIdentity": {
48419
+ capName: "user-management",
48420
+ capScope: "system",
48421
+ addonId: null,
48422
+ access: "delete"
48423
+ },
48173
48424
  "userManagement.updateUser": {
48174
48425
  capName: "user-management",
48175
48426
  capScope: "system",
@@ -51509,6 +51760,11 @@ Object.freeze({
51509
51760
  form: "single",
51510
51761
  optional: false
51511
51762
  }],
51763
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51764
+ name: "deviceId",
51765
+ form: "single",
51766
+ optional: false
51767
+ }],
51512
51768
  "pipelineAnalytics.setTrackFlags": [{
51513
51769
  name: "deviceId",
51514
51770
  form: "single",
@@ -53660,7 +53916,7 @@ var homematicConfigSchema = object({
53660
53916
  enableGroups: boolean().default(true).describe("Enable groups (heating groups / VirtualDevices)"),
53661
53917
  enableBidcosWired: boolean().default(false).describe("Enable BidCos-Wired (HM-Wired)"),
53662
53918
  username: string().default("").describe("WebUI username (optional — enables names / rooms / sysvars)"),
53663
- password: string().default("").describe("WebUI password (optional)"),
53919
+ password: string().default("").describe("WebUI password (optional)").meta({ secret: true }),
53664
53920
  callbackHost: string().default("").describe("Address the CCU calls back to for event push (this hub LAN IP)"),
53665
53921
  callbackPort: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1).max(65535).default(2128)).describe("Local XML-RPC callback server port"),
53666
53922
  tls: boolean().default(false).describe("Use TLS for the CCU transport")
package/dist/addon.mjs CHANGED
@@ -5380,7 +5380,7 @@ var ZodIssueCode = {
5380
5380
  var ZodFirstPartyTypeKind;
5381
5381
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5382
5382
  //#endregion
5383
- //#region ../types/dist/sleep-BNeXenvr.mjs
5383
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5384
5384
  /**
5385
5385
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5386
5386
  * window to float samples (D455).
@@ -15268,6 +15268,10 @@ var DeviceInfoSchema = object({
15268
15268
  isCamera: boolean(),
15269
15269
  /** Current config values — serializable snapshot */
15270
15270
  config: record(string(), unknown()),
15271
+ /** Paths inside `config` the device's schema declares secret (D783) —
15272
+ * what the non-admin redaction withholds. Paths, never values. Absent
15273
+ * when the owning runner has not reported them. */
15274
+ secretConfigPaths: array(string()).optional(),
15271
15275
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15272
15276
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15273
15277
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15473,7 +15477,13 @@ var DeviceRegisterPayloadSchema = object({
15473
15477
  * call (workers re-register on init), so probe-driven updates
15474
15478
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15475
15479
  features: array(string()).optional(),
15476
- config: record(string(), unknown())
15480
+ config: record(string(), unknown()),
15481
+ /** Config paths the device's own schema DECLARES secret
15482
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15483
+ * `connection.password`). Re-published on every register; the non-admin
15484
+ * redaction withholds them at any depth (D783). Optional: an older runner
15485
+ * omits it and the keyword backstop applies. */
15486
+ secretConfigPaths: array(string()).optional()
15477
15487
  });
15478
15488
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15479
15489
  var DevicePersistConfigPayloadSchema = object({
@@ -17132,7 +17142,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
17132
17142
  icon: string().optional(),
17133
17143
  /** Addon-owned HTTP route the button navigates to (GET). */
17134
17144
  startUrl: string(),
17135
- stage: LoginStageEnum
17145
+ stage: LoginStageEnum,
17146
+ /**
17147
+ * The provider names an external identity a signed-in user can link to
17148
+ * their own account (D782): `auth.listLinkableProviders` /
17149
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17150
+ * whatever their id. Absent / false — a login button only (magic-link).
17151
+ */
17152
+ linkable: boolean().optional()
17136
17153
  }),
17137
17154
  object({
17138
17155
  kind: literal("widget"),
@@ -22567,7 +22584,13 @@ var RetrainFrameSchema = object({
22567
22584
  sizeBytes: number().int(),
22568
22585
  width: number().int(),
22569
22586
  height: number().int(),
22570
- copiedAt: number()
22587
+ copiedAt: number(),
22588
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22589
+ capturedAt: number().optional(),
22590
+ /** The operator's "every subject in this frame is boxed". Detector
22591
+ * evaluation keeps only complete frames: an unboxed subject would count as
22592
+ * a false positive. */
22593
+ complete: boolean()
22571
22594
  });
22572
22595
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22573
22596
  var RetrainCopyRefusalSchema = _enum([
@@ -22588,6 +22611,51 @@ var RetrainFrameListSchema = object({
22588
22611
  /** What the page pre-selects — the native key frame when one survives. */
22589
22612
  autoPickMediaId: number().int().optional()
22590
22613
  });
22614
+ /**
22615
+ * Which frames an annotated export carries. Every field narrows; an empty
22616
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22617
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22618
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22619
+ * export carried (`exportedInBatch`).
22620
+ */
22621
+ var RetrainExportFilterSchema = object({
22622
+ deviceIds: array(number()).optional(),
22623
+ frameIds: array(string()).max(2e4).optional(),
22624
+ batchId: string().optional(),
22625
+ /** Only frames the operator marked complete (all subjects boxed). */
22626
+ completeOnly: boolean().optional()
22627
+ });
22628
+ /**
22629
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22630
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22631
+ * convention — the classifier layout.
22632
+ */
22633
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22634
+ /**
22635
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22636
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22637
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22638
+ * logged.
22639
+ */
22640
+ var RetrainArchiveTargetSchema = object({
22641
+ kind: literal("http"),
22642
+ method: _enum(["PUT", "POST"]),
22643
+ url: string().url(),
22644
+ headers: record(string(), string()).optional()
22645
+ });
22646
+ var RetrainArchiveResultSchema = object({
22647
+ batchId: string(),
22648
+ frames: number().int(),
22649
+ crops: number().int(),
22650
+ annotations: number().int(),
22651
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22652
+ missing: number().int(),
22653
+ bytes: number().int(),
22654
+ /** sha256 of the exact bytes sent. */
22655
+ sha256: string(),
22656
+ /** The target's HTTP status. */
22657
+ status: number().int()
22658
+ });
22591
22659
  /** What the operator asked the assist to look for. */
22592
22660
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22593
22661
  kind: literal("package"),
@@ -23382,9 +23450,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23382
23450
  }), RetrainTransitionResultSchema, {
23383
23451
  kind: "mutation",
23384
23452
  auth: "admin"
23385
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23453
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23386
23454
  kind: "query",
23387
23455
  auth: "admin"
23456
+ }), method(object({
23457
+ deviceId: number(),
23458
+ trackId: string(),
23459
+ frameId: string(),
23460
+ complete: boolean()
23461
+ }), RetrainFrameSchema, {
23462
+ kind: "mutation",
23463
+ auth: "admin"
23464
+ }), method(object({
23465
+ filter: RetrainExportFilterSchema,
23466
+ layout: RetrainExportLayoutSchema,
23467
+ target: RetrainArchiveTargetSchema
23468
+ }), RetrainArchiveResultSchema, {
23469
+ kind: "mutation",
23470
+ auth: "admin",
23471
+ timeoutMs: 60 * 6e4
23388
23472
  }), method(object({
23389
23473
  /** Which of the three event tables owns the row. */
23390
23474
  ownerType: EventOwnerTypeSchema,
@@ -26714,7 +26798,19 @@ var SsoBridgeClaimsSchema = object({
26714
26798
  * editing a descriptor must not retroactively extend or shorten a link the
26715
26799
  * operator already consented to.
26716
26800
  */
26717
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26801
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26802
+ /**
26803
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26804
+ * that was started from a signed-in user's "Link" button: the finish then
26805
+ * links this identity to the intent's user instead of signing anyone in.
26806
+ * The handle carries no user id — the hub resolves it, single-use.
26807
+ */
26808
+ linkIntent: string().optional(),
26809
+ /**
26810
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26811
+ * subject is unique only per issuer, so a link is bound to it.
26812
+ */
26813
+ issuer: string().optional()
26718
26814
  });
26719
26815
  method(object({
26720
26816
  claims: SsoBridgeClaimsSchema,
@@ -28649,7 +28745,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28649
28745
  * field their hints were silently stripped by the schema and the
28650
28746
  * adaptive ladder started blind on the client's display size.
28651
28747
  */
28652
- hints: webrtcClientHintsSchema.optional()
28748
+ hints: webrtcClientHintsSchema.optional(),
28749
+ /**
28750
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28751
+ * through the `intercom` cap's push-talk triple. When `true` and the
28752
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28753
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28754
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28755
+ *
28756
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28757
+ * with `intercom`, when the linked user may control that camera. The
28758
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28759
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28760
+ * intercom cap's own surface (share tokens gate it there), and this
28761
+ * flag must not become a second door to the camera's speaker.
28762
+ */
28763
+ talkback: boolean().optional()
28653
28764
  }), object({
28654
28765
  sessionId: string(),
28655
28766
  sdpAnswer: string()
@@ -28951,6 +29062,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28951
29062
  var RestartAddonResultSchema = unknown();
28952
29063
  var InstallPackageResultSchema = unknown();
28953
29064
  var ReloadPackagesResultSchema = unknown();
29065
+ /**
29066
+ * What an uninstall did on ONE node.
29067
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29068
+ * - `not-installed` — the node did not have it (nothing to do).
29069
+ * - `refused` — protected / bootstrap package; nothing touched.
29070
+ * - `failed` — attempted and did not complete; `error` says why.
29071
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29072
+ * back-fill never returns the package, and the stale-addon sweep removes the
29073
+ * copy when the node registers again (only once the hub no longer has it).
29074
+ */
29075
+ var UninstallNodeOutcomeSchema = _enum([
29076
+ "uninstalled",
29077
+ "not-installed",
29078
+ "refused",
29079
+ "failed",
29080
+ "pending-reconnect"
29081
+ ]);
29082
+ var UninstallNodeResultSchema = object({
29083
+ nodeId: string(),
29084
+ outcome: UninstallNodeOutcomeSchema,
29085
+ error: string().optional(),
29086
+ addonIds: array(string()).readonly(),
29087
+ runnersStopped: array(string()).readonly(),
29088
+ warnings: array(string()).readonly()
29089
+ });
29090
+ var UninstallPackageResultSchema = object({
29091
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
29092
+ success: boolean(),
29093
+ packageName: string(),
29094
+ results: array(UninstallNodeResultSchema).readonly()
29095
+ });
29096
+ /**
29097
+ * `unreachable` lists online agents whose status read FAILED — absence from
29098
+ * `installations` is only "not installed" for a node that answered (D315).
29099
+ */
29100
+ var PackageInstallationsSchema = object({
29101
+ installations: array(object({
29102
+ packageName: string(),
29103
+ nodeId: string(),
29104
+ nodeName: string(),
29105
+ isHub: boolean(),
29106
+ isOnline: boolean(),
29107
+ version: string().nullable(),
29108
+ addonIds: array(string()).readonly(),
29109
+ source: _enum(["live", "recorded"]),
29110
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
29111
+ onHub: boolean()
29112
+ })).readonly(),
29113
+ unreachable: array(object({
29114
+ nodeId: string(),
29115
+ error: string()
29116
+ })).readonly()
29117
+ });
28954
29118
  var BulkUpdateItemStatusSchema = _enum([
28955
29119
  "queued",
28956
29120
  "updating",
@@ -29033,10 +29197,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29033
29197
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29034
29198
  kind: "mutation",
29035
29199
  auth: "admin"
29036
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29200
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29201
+ packageName: string().min(1),
29202
+ nodeId: string().optional(),
29203
+ everywhere: boolean().optional()
29204
+ }), UninstallPackageResultSchema, {
29037
29205
  kind: "mutation",
29038
29206
  auth: "admin"
29039
- }), method(_void(), ReloadPackagesResultSchema, {
29207
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29040
29208
  kind: "mutation",
29041
29209
  auth: "admin"
29042
29210
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -38946,6 +39114,32 @@ var TotpStatusSchema = object({
38946
39114
  /** Null when no row exists OR the row is still pending confirmation. */
38947
39115
  confirmedAt: number().nullable()
38948
39116
  });
39117
+ /**
39118
+ * user-management — singleton capability for user accounts, API keys,
39119
+ * and scoped tokens.
39120
+ *
39121
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
39122
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
39123
+ * because non-admins never reach these. If/when we open non-admin
39124
+ * delegation, structural caller-scope subset check goes inside the
39125
+ * provider.
39126
+ */
39127
+ var ExternalIdentitySchema = object({
39128
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39129
+ provider: string(),
39130
+ /** The IdP's stable subject (`sub`) for this account. */
39131
+ subject: string(),
39132
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39133
+ issuer: string(),
39134
+ userId: string(),
39135
+ /** What the IdP called the account at link time (username / email) — display only. */
39136
+ label: string().optional(),
39137
+ linkedAt: number()
39138
+ });
39139
+ var ExternalIdentityKeySchema = object({
39140
+ provider: string().min(1),
39141
+ subject: string().min(1)
39142
+ });
38949
39143
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
38950
39144
  kind: "mutation",
38951
39145
  auth: "admin",
@@ -39059,7 +39253,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39059
39253
  userId: string(),
39060
39254
  username: string(),
39061
39255
  scopes: array(TokenScopeSchema)
39062
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39256
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39257
+ userId: string(),
39258
+ issuer: string()
39259
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39260
+ userId: string(),
39261
+ issuer: string().min(1),
39262
+ label: string().optional()
39263
+ }), object({ success: literal(true) }), {
39264
+ kind: "mutation",
39265
+ auth: "admin",
39266
+ access: "create"
39267
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39268
+ kind: "mutation",
39269
+ auth: "admin",
39270
+ access: "delete"
39271
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39063
39272
  kind: "mutation",
39064
39273
  auth: "admin",
39065
39274
  access: "delete"
@@ -41469,6 +41678,12 @@ Object.freeze({
41469
41678
  addonId: null,
41470
41679
  access: "view"
41471
41680
  },
41681
+ "addons.listInstallations": {
41682
+ capName: "addons",
41683
+ capScope: "system",
41684
+ addonId: null,
41685
+ access: "view"
41686
+ },
41472
41687
  "addons.listJobs": {
41473
41688
  capName: "addons",
41474
41689
  capScope: "system",
@@ -45693,6 +45908,12 @@ Object.freeze({
45693
45908
  addonId: null,
45694
45909
  access: "create"
45695
45910
  },
45911
+ "pipelineAnalytics.setRetrainFrameComplete": {
45912
+ capName: "pipeline-analytics",
45913
+ capScope: "device",
45914
+ addonId: null,
45915
+ access: "create"
45916
+ },
45696
45917
  "pipelineAnalytics.setTrackFlags": {
45697
45918
  capName: "pipeline-analytics",
45698
45919
  capScope: "device",
@@ -45729,6 +45950,12 @@ Object.freeze({
45729
45950
  addonId: null,
45730
45951
  access: "delete"
45731
45952
  },
45953
+ "pipelineAnalytics.writeRetrainArchive": {
45954
+ capName: "pipeline-analytics",
45955
+ capScope: "device",
45956
+ addonId: null,
45957
+ access: "create"
45958
+ },
45732
45959
  "pipelineExecutor.cacheFrameInPool": {
45733
45960
  capName: "pipeline-executor",
45734
45961
  capScope: "system",
@@ -48081,18 +48308,36 @@ Object.freeze({
48081
48308
  addonId: null,
48082
48309
  access: "delete"
48083
48310
  },
48311
+ "userManagement.findUserByExternalIdentity": {
48312
+ capName: "user-management",
48313
+ capScope: "system",
48314
+ addonId: null,
48315
+ access: "view"
48316
+ },
48084
48317
  "userManagement.getTotpStatus": {
48085
48318
  capName: "user-management",
48086
48319
  capScope: "system",
48087
48320
  addonId: null,
48088
48321
  access: "view"
48089
48322
  },
48323
+ "userManagement.linkExternalIdentity": {
48324
+ capName: "user-management",
48325
+ capScope: "system",
48326
+ addonId: null,
48327
+ access: "create"
48328
+ },
48090
48329
  "userManagement.listApiKeys": {
48091
48330
  capName: "user-management",
48092
48331
  capScope: "system",
48093
48332
  addonId: null,
48094
48333
  access: "view"
48095
48334
  },
48335
+ "userManagement.listExternalIdentities": {
48336
+ capName: "user-management",
48337
+ capScope: "system",
48338
+ addonId: null,
48339
+ access: "view"
48340
+ },
48096
48341
  "userManagement.listOauthSessions": {
48097
48342
  capName: "user-management",
48098
48343
  capScope: "system",
@@ -48171,6 +48416,12 @@ Object.freeze({
48171
48416
  addonId: null,
48172
48417
  access: "create"
48173
48418
  },
48419
+ "userManagement.unlinkExternalIdentity": {
48420
+ capName: "user-management",
48421
+ capScope: "system",
48422
+ addonId: null,
48423
+ access: "delete"
48424
+ },
48174
48425
  "userManagement.updateUser": {
48175
48426
  capName: "user-management",
48176
48427
  capScope: "system",
@@ -51510,6 +51761,11 @@ Object.freeze({
51510
51761
  form: "single",
51511
51762
  optional: false
51512
51763
  }],
51764
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51765
+ name: "deviceId",
51766
+ form: "single",
51767
+ optional: false
51768
+ }],
51513
51769
  "pipelineAnalytics.setTrackFlags": [{
51514
51770
  name: "deviceId",
51515
51771
  form: "single",
@@ -53661,7 +53917,7 @@ var homematicConfigSchema = object({
53661
53917
  enableGroups: boolean().default(true).describe("Enable groups (heating groups / VirtualDevices)"),
53662
53918
  enableBidcosWired: boolean().default(false).describe("Enable BidCos-Wired (HM-Wired)"),
53663
53919
  username: string().default("").describe("WebUI username (optional — enables names / rooms / sysvars)"),
53664
- password: string().default("").describe("WebUI password (optional)"),
53920
+ password: string().default("").describe("WebUI password (optional)").meta({ secret: true }),
53665
53921
  callbackHost: string().default("").describe("Address the CCU calls back to for event push (this hub LAN IP)"),
53666
53922
  callbackPort: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1).max(65535).default(2128)).describe("Local XML-RPC callback server port"),
53667
53923
  tls: boolean().default(false).describe("Use TLS for the CCU transport")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.127",
3
+ "version": "1.2.129",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",