@camstack/addon-provider-rademacher 0.2.121 → 0.2.123

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
@@ -6355,7 +6355,7 @@ var ZodIssueCode = {
6355
6355
  var ZodFirstPartyTypeKind;
6356
6356
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6357
6357
  //#endregion
6358
- //#region ../types/dist/sleep-BNeXenvr.mjs
6358
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
6359
6359
  /**
6360
6360
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6361
6361
  * window to float samples (D455).
@@ -16177,6 +16177,10 @@ var DeviceInfoSchema = object({
16177
16177
  isCamera: boolean(),
16178
16178
  /** Current config values — serializable snapshot */
16179
16179
  config: record(string(), unknown()),
16180
+ /** Paths inside `config` the device's schema declares secret (D783) —
16181
+ * what the non-admin redaction withholds. Paths, never values. Absent
16182
+ * when the owning runner has not reported them. */
16183
+ secretConfigPaths: array(string()).optional(),
16180
16184
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
16181
16185
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
16182
16186
  metadata: record(string(), unknown()).nullable().optional(),
@@ -16382,7 +16386,13 @@ var DeviceRegisterPayloadSchema = object({
16382
16386
  * call (workers re-register on init), so probe-driven updates
16383
16387
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
16384
16388
  features: array(string()).optional(),
16385
- config: record(string(), unknown())
16389
+ config: record(string(), unknown()),
16390
+ /** Config paths the device's own schema DECLARES secret
16391
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
16392
+ * `connection.password`). Re-published on every register; the non-admin
16393
+ * redaction withholds them at any depth (D783). Optional: an older runner
16394
+ * omits it and the keyword backstop applies. */
16395
+ secretConfigPaths: array(string()).optional()
16386
16396
  });
16387
16397
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
16388
16398
  var DevicePersistConfigPayloadSchema = object({
@@ -18041,7 +18051,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
18041
18051
  icon: string().optional(),
18042
18052
  /** Addon-owned HTTP route the button navigates to (GET). */
18043
18053
  startUrl: string(),
18044
- stage: LoginStageEnum
18054
+ stage: LoginStageEnum,
18055
+ /**
18056
+ * The provider names an external identity a signed-in user can link to
18057
+ * their own account (D782): `auth.listLinkableProviders` /
18058
+ * `beginExternalLink` offer exactly the redirect methods that set this,
18059
+ * whatever their id. Absent / false — a login button only (magic-link).
18060
+ */
18061
+ linkable: boolean().optional()
18045
18062
  }),
18046
18063
  object({
18047
18064
  kind: literal("widget"),
@@ -23476,7 +23493,13 @@ var RetrainFrameSchema = object({
23476
23493
  sizeBytes: number().int(),
23477
23494
  width: number().int(),
23478
23495
  height: number().int(),
23479
- copiedAt: number()
23496
+ copiedAt: number(),
23497
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
23498
+ capturedAt: number().optional(),
23499
+ /** The operator's "every subject in this frame is boxed". Detector
23500
+ * evaluation keeps only complete frames: an unboxed subject would count as
23501
+ * a false positive. */
23502
+ complete: boolean()
23480
23503
  });
23481
23504
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
23482
23505
  var RetrainCopyRefusalSchema = _enum([
@@ -23497,6 +23520,51 @@ var RetrainFrameListSchema = object({
23497
23520
  /** What the page pre-selects — the native key frame when one survives. */
23498
23521
  autoPickMediaId: number().int().optional()
23499
23522
  });
23523
+ /**
23524
+ * Which frames an annotated export carries. Every field narrows; an empty
23525
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
23526
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
23527
+ * the primitive a version export uses; `batchId` re-selects what an earlier
23528
+ * export carried (`exportedInBatch`).
23529
+ */
23530
+ var RetrainExportFilterSchema = object({
23531
+ deviceIds: array(number()).optional(),
23532
+ frameIds: array(string()).max(2e4).optional(),
23533
+ batchId: string().optional(),
23534
+ /** Only frames the operator marked complete (all subjects boxed). */
23535
+ completeOnly: boolean().optional()
23536
+ });
23537
+ /**
23538
+ * `frames`: the full frame copies, boxes in `annotations.json`.
23539
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
23540
+ * convention — the classifier layout.
23541
+ */
23542
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
23543
+ /**
23544
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
23545
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
23546
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
23547
+ * logged.
23548
+ */
23549
+ var RetrainArchiveTargetSchema = object({
23550
+ kind: literal("http"),
23551
+ method: _enum(["PUT", "POST"]),
23552
+ url: string().url(),
23553
+ headers: record(string(), string()).optional()
23554
+ });
23555
+ var RetrainArchiveResultSchema = object({
23556
+ batchId: string(),
23557
+ frames: number().int(),
23558
+ crops: number().int(),
23559
+ annotations: number().int(),
23560
+ /** Frames planned but not shipped (unreadable copy, path too long). */
23561
+ missing: number().int(),
23562
+ bytes: number().int(),
23563
+ /** sha256 of the exact bytes sent. */
23564
+ sha256: string(),
23565
+ /** The target's HTTP status. */
23566
+ status: number().int()
23567
+ });
23500
23568
  /** What the operator asked the assist to look for. */
23501
23569
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
23502
23570
  kind: literal("package"),
@@ -24291,9 +24359,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24291
24359
  }), RetrainTransitionResultSchema, {
24292
24360
  kind: "mutation",
24293
24361
  auth: "admin"
24294
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
24362
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
24295
24363
  kind: "query",
24296
24364
  auth: "admin"
24365
+ }), method(object({
24366
+ deviceId: number(),
24367
+ trackId: string(),
24368
+ frameId: string(),
24369
+ complete: boolean()
24370
+ }), RetrainFrameSchema, {
24371
+ kind: "mutation",
24372
+ auth: "admin"
24373
+ }), method(object({
24374
+ filter: RetrainExportFilterSchema,
24375
+ layout: RetrainExportLayoutSchema,
24376
+ target: RetrainArchiveTargetSchema
24377
+ }), RetrainArchiveResultSchema, {
24378
+ kind: "mutation",
24379
+ auth: "admin",
24380
+ timeoutMs: 60 * 6e4
24297
24381
  }), method(object({
24298
24382
  /** Which of the three event tables owns the row. */
24299
24383
  ownerType: EventOwnerTypeSchema,
@@ -27623,7 +27707,19 @@ var SsoBridgeClaimsSchema = object({
27623
27707
  * editing a descriptor must not retroactively extend or shorten a link the
27624
27708
  * operator already consented to.
27625
27709
  */
27626
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
27710
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
27711
+ /**
27712
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
27713
+ * that was started from a signed-in user's "Link" button: the finish then
27714
+ * links this identity to the intent's user instead of signing anyone in.
27715
+ * The handle carries no user id — the hub resolves it, single-use.
27716
+ */
27717
+ linkIntent: string().optional(),
27718
+ /**
27719
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
27720
+ * subject is unique only per issuer, so a link is bound to it.
27721
+ */
27722
+ issuer: string().optional()
27627
27723
  });
27628
27724
  method(object({
27629
27725
  claims: SsoBridgeClaimsSchema,
@@ -29558,7 +29654,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
29558
29654
  * field their hints were silently stripped by the schema and the
29559
29655
  * adaptive ladder started blind on the client's display size.
29560
29656
  */
29561
- hints: webrtcClientHintsSchema.optional()
29657
+ hints: webrtcClientHintsSchema.optional(),
29658
+ /**
29659
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
29660
+ * through the `intercom` cap's push-talk triple. When `true` and the
29661
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
29662
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
29663
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
29664
+ *
29665
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
29666
+ * with `intercom`, when the linked user may control that camera. The
29667
+ * hub STRIPS it from every request-bound call (a browser), exactly as
29668
+ * it overwrites `relayOnly` — a viewer's talk permission is the
29669
+ * intercom cap's own surface (share tokens gate it there), and this
29670
+ * flag must not become a second door to the camera's speaker.
29671
+ */
29672
+ talkback: boolean().optional()
29562
29673
  }), object({
29563
29674
  sessionId: string(),
29564
29675
  sdpAnswer: string()
@@ -29860,6 +29971,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
29860
29971
  var RestartAddonResultSchema = unknown();
29861
29972
  var InstallPackageResultSchema = unknown();
29862
29973
  var ReloadPackagesResultSchema = unknown();
29974
+ /**
29975
+ * What an uninstall did on ONE node.
29976
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29977
+ * - `not-installed` — the node did not have it (nothing to do).
29978
+ * - `refused` — protected / bootstrap package; nothing touched.
29979
+ * - `failed` — attempted and did not complete; `error` says why.
29980
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29981
+ * back-fill never returns the package, and the stale-addon sweep removes the
29982
+ * copy when the node registers again (only once the hub no longer has it).
29983
+ */
29984
+ var UninstallNodeOutcomeSchema = _enum([
29985
+ "uninstalled",
29986
+ "not-installed",
29987
+ "refused",
29988
+ "failed",
29989
+ "pending-reconnect"
29990
+ ]);
29991
+ var UninstallNodeResultSchema = object({
29992
+ nodeId: string(),
29993
+ outcome: UninstallNodeOutcomeSchema,
29994
+ error: string().optional(),
29995
+ addonIds: array(string()).readonly(),
29996
+ runnersStopped: array(string()).readonly(),
29997
+ warnings: array(string()).readonly()
29998
+ });
29999
+ var UninstallPackageResultSchema = object({
30000
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
30001
+ success: boolean(),
30002
+ packageName: string(),
30003
+ results: array(UninstallNodeResultSchema).readonly()
30004
+ });
30005
+ /**
30006
+ * `unreachable` lists online agents whose status read FAILED — absence from
30007
+ * `installations` is only "not installed" for a node that answered (D315).
30008
+ */
30009
+ var PackageInstallationsSchema = object({
30010
+ installations: array(object({
30011
+ packageName: string(),
30012
+ nodeId: string(),
30013
+ nodeName: string(),
30014
+ isHub: boolean(),
30015
+ isOnline: boolean(),
30016
+ version: string().nullable(),
30017
+ addonIds: array(string()).readonly(),
30018
+ source: _enum(["live", "recorded"]),
30019
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
30020
+ onHub: boolean()
30021
+ })).readonly(),
30022
+ unreachable: array(object({
30023
+ nodeId: string(),
30024
+ error: string()
30025
+ })).readonly()
30026
+ });
29863
30027
  var BulkUpdateItemStatusSchema = _enum([
29864
30028
  "queued",
29865
30029
  "updating",
@@ -29942,10 +30106,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29942
30106
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29943
30107
  kind: "mutation",
29944
30108
  auth: "admin"
29945
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
30109
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
30110
+ packageName: string().min(1),
30111
+ nodeId: string().optional(),
30112
+ everywhere: boolean().optional()
30113
+ }), UninstallPackageResultSchema, {
29946
30114
  kind: "mutation",
29947
30115
  auth: "admin"
29948
- }), method(_void(), ReloadPackagesResultSchema, {
30116
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29949
30117
  kind: "mutation",
29950
30118
  auth: "admin"
29951
30119
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -39855,6 +40023,32 @@ var TotpStatusSchema = object({
39855
40023
  /** Null when no row exists OR the row is still pending confirmation. */
39856
40024
  confirmedAt: number().nullable()
39857
40025
  });
40026
+ /**
40027
+ * user-management — singleton capability for user accounts, API keys,
40028
+ * and scoped tokens.
40029
+ *
40030
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
40031
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
40032
+ * because non-admins never reach these. If/when we open non-admin
40033
+ * delegation, structural caller-scope subset check goes inside the
40034
+ * provider.
40035
+ */
40036
+ var ExternalIdentitySchema = object({
40037
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
40038
+ provider: string(),
40039
+ /** The IdP's stable subject (`sub`) for this account. */
40040
+ subject: string(),
40041
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
40042
+ issuer: string(),
40043
+ userId: string(),
40044
+ /** What the IdP called the account at link time (username / email) — display only. */
40045
+ label: string().optional(),
40046
+ linkedAt: number()
40047
+ });
40048
+ var ExternalIdentityKeySchema = object({
40049
+ provider: string().min(1),
40050
+ subject: string().min(1)
40051
+ });
39858
40052
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
39859
40053
  kind: "mutation",
39860
40054
  auth: "admin",
@@ -39968,7 +40162,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39968
40162
  userId: string(),
39969
40163
  username: string(),
39970
40164
  scopes: array(TokenScopeSchema)
39971
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
40165
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
40166
+ userId: string(),
40167
+ issuer: string()
40168
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
40169
+ userId: string(),
40170
+ issuer: string().min(1),
40171
+ label: string().optional()
40172
+ }), object({ success: literal(true) }), {
40173
+ kind: "mutation",
40174
+ auth: "admin",
40175
+ access: "create"
40176
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
40177
+ kind: "mutation",
40178
+ auth: "admin",
40179
+ access: "delete"
40180
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39972
40181
  kind: "mutation",
39973
40182
  auth: "admin",
39974
40183
  access: "delete"
@@ -42378,6 +42587,12 @@ Object.freeze({
42378
42587
  addonId: null,
42379
42588
  access: "view"
42380
42589
  },
42590
+ "addons.listInstallations": {
42591
+ capName: "addons",
42592
+ capScope: "system",
42593
+ addonId: null,
42594
+ access: "view"
42595
+ },
42381
42596
  "addons.listJobs": {
42382
42597
  capName: "addons",
42383
42598
  capScope: "system",
@@ -46602,6 +46817,12 @@ Object.freeze({
46602
46817
  addonId: null,
46603
46818
  access: "create"
46604
46819
  },
46820
+ "pipelineAnalytics.setRetrainFrameComplete": {
46821
+ capName: "pipeline-analytics",
46822
+ capScope: "device",
46823
+ addonId: null,
46824
+ access: "create"
46825
+ },
46605
46826
  "pipelineAnalytics.setTrackFlags": {
46606
46827
  capName: "pipeline-analytics",
46607
46828
  capScope: "device",
@@ -46638,6 +46859,12 @@ Object.freeze({
46638
46859
  addonId: null,
46639
46860
  access: "delete"
46640
46861
  },
46862
+ "pipelineAnalytics.writeRetrainArchive": {
46863
+ capName: "pipeline-analytics",
46864
+ capScope: "device",
46865
+ addonId: null,
46866
+ access: "create"
46867
+ },
46641
46868
  "pipelineExecutor.cacheFrameInPool": {
46642
46869
  capName: "pipeline-executor",
46643
46870
  capScope: "system",
@@ -48990,18 +49217,36 @@ Object.freeze({
48990
49217
  addonId: null,
48991
49218
  access: "delete"
48992
49219
  },
49220
+ "userManagement.findUserByExternalIdentity": {
49221
+ capName: "user-management",
49222
+ capScope: "system",
49223
+ addonId: null,
49224
+ access: "view"
49225
+ },
48993
49226
  "userManagement.getTotpStatus": {
48994
49227
  capName: "user-management",
48995
49228
  capScope: "system",
48996
49229
  addonId: null,
48997
49230
  access: "view"
48998
49231
  },
49232
+ "userManagement.linkExternalIdentity": {
49233
+ capName: "user-management",
49234
+ capScope: "system",
49235
+ addonId: null,
49236
+ access: "create"
49237
+ },
48999
49238
  "userManagement.listApiKeys": {
49000
49239
  capName: "user-management",
49001
49240
  capScope: "system",
49002
49241
  addonId: null,
49003
49242
  access: "view"
49004
49243
  },
49244
+ "userManagement.listExternalIdentities": {
49245
+ capName: "user-management",
49246
+ capScope: "system",
49247
+ addonId: null,
49248
+ access: "view"
49249
+ },
49005
49250
  "userManagement.listOauthSessions": {
49006
49251
  capName: "user-management",
49007
49252
  capScope: "system",
@@ -49080,6 +49325,12 @@ Object.freeze({
49080
49325
  addonId: null,
49081
49326
  access: "create"
49082
49327
  },
49328
+ "userManagement.unlinkExternalIdentity": {
49329
+ capName: "user-management",
49330
+ capScope: "system",
49331
+ addonId: null,
49332
+ access: "delete"
49333
+ },
49083
49334
  "userManagement.updateUser": {
49084
49335
  capName: "user-management",
49085
49336
  capScope: "system",
@@ -52419,6 +52670,11 @@ Object.freeze({
52419
52670
  form: "single",
52420
52671
  optional: false
52421
52672
  }],
52673
+ "pipelineAnalytics.setRetrainFrameComplete": [{
52674
+ name: "deviceId",
52675
+ form: "single",
52676
+ optional: false
52677
+ }],
52422
52678
  "pipelineAnalytics.setTrackFlags": [{
52423
52679
  name: "deviceId",
52424
52680
  form: "single",
@@ -54480,7 +54736,7 @@ var MB = 1024 * 1024;
54480
54736
  */
54481
54737
  var rademacherConnectionSchema = object({
54482
54738
  host: string().min(1).describe("HomePilot hub host name or IP address"),
54483
- password: string().default("").describe("Hub password (leave blank for an unprotected hub)"),
54739
+ password: string().default("").describe("Hub password (leave blank for an unprotected hub)").meta({ secret: true }),
54484
54740
  basePath: string().default("").describe("API base path override (blank = auto-probe: v1 \"\" / v2 \"/hp\")"),
54485
54741
  pollIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(2e3).max(36e5).default(3e4)).describe("Device-state poll interval (ms)")
54486
54742
  });
package/dist/addon.mjs CHANGED
@@ -6354,7 +6354,7 @@ var ZodIssueCode = {
6354
6354
  var ZodFirstPartyTypeKind;
6355
6355
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6356
6356
  //#endregion
6357
- //#region ../types/dist/sleep-BNeXenvr.mjs
6357
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
6358
6358
  /**
6359
6359
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6360
6360
  * window to float samples (D455).
@@ -16176,6 +16176,10 @@ var DeviceInfoSchema = object({
16176
16176
  isCamera: boolean(),
16177
16177
  /** Current config values — serializable snapshot */
16178
16178
  config: record(string(), unknown()),
16179
+ /** Paths inside `config` the device's schema declares secret (D783) —
16180
+ * what the non-admin redaction withholds. Paths, never values. Absent
16181
+ * when the owning runner has not reported them. */
16182
+ secretConfigPaths: array(string()).optional(),
16179
16183
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
16180
16184
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
16181
16185
  metadata: record(string(), unknown()).nullable().optional(),
@@ -16381,7 +16385,13 @@ var DeviceRegisterPayloadSchema = object({
16381
16385
  * call (workers re-register on init), so probe-driven updates
16382
16386
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
16383
16387
  features: array(string()).optional(),
16384
- config: record(string(), unknown())
16388
+ config: record(string(), unknown()),
16389
+ /** Config paths the device's own schema DECLARES secret
16390
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
16391
+ * `connection.password`). Re-published on every register; the non-admin
16392
+ * redaction withholds them at any depth (D783). Optional: an older runner
16393
+ * omits it and the keyword backstop applies. */
16394
+ secretConfigPaths: array(string()).optional()
16385
16395
  });
16386
16396
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
16387
16397
  var DevicePersistConfigPayloadSchema = object({
@@ -18040,7 +18050,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
18040
18050
  icon: string().optional(),
18041
18051
  /** Addon-owned HTTP route the button navigates to (GET). */
18042
18052
  startUrl: string(),
18043
- stage: LoginStageEnum
18053
+ stage: LoginStageEnum,
18054
+ /**
18055
+ * The provider names an external identity a signed-in user can link to
18056
+ * their own account (D782): `auth.listLinkableProviders` /
18057
+ * `beginExternalLink` offer exactly the redirect methods that set this,
18058
+ * whatever their id. Absent / false — a login button only (magic-link).
18059
+ */
18060
+ linkable: boolean().optional()
18044
18061
  }),
18045
18062
  object({
18046
18063
  kind: literal("widget"),
@@ -23475,7 +23492,13 @@ var RetrainFrameSchema = object({
23475
23492
  sizeBytes: number().int(),
23476
23493
  width: number().int(),
23477
23494
  height: number().int(),
23478
- copiedAt: number()
23495
+ copiedAt: number(),
23496
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
23497
+ capturedAt: number().optional(),
23498
+ /** The operator's "every subject in this frame is boxed". Detector
23499
+ * evaluation keeps only complete frames: an unboxed subject would count as
23500
+ * a false positive. */
23501
+ complete: boolean()
23479
23502
  });
23480
23503
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
23481
23504
  var RetrainCopyRefusalSchema = _enum([
@@ -23496,6 +23519,51 @@ var RetrainFrameListSchema = object({
23496
23519
  /** What the page pre-selects — the native key frame when one survives. */
23497
23520
  autoPickMediaId: number().int().optional()
23498
23521
  });
23522
+ /**
23523
+ * Which frames an annotated export carries. Every field narrows; an empty
23524
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
23525
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
23526
+ * the primitive a version export uses; `batchId` re-selects what an earlier
23527
+ * export carried (`exportedInBatch`).
23528
+ */
23529
+ var RetrainExportFilterSchema = object({
23530
+ deviceIds: array(number()).optional(),
23531
+ frameIds: array(string()).max(2e4).optional(),
23532
+ batchId: string().optional(),
23533
+ /** Only frames the operator marked complete (all subjects boxed). */
23534
+ completeOnly: boolean().optional()
23535
+ });
23536
+ /**
23537
+ * `frames`: the full frame copies, boxes in `annotations.json`.
23538
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
23539
+ * convention — the classifier layout.
23540
+ */
23541
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
23542
+ /**
23543
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
23544
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
23545
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
23546
+ * logged.
23547
+ */
23548
+ var RetrainArchiveTargetSchema = object({
23549
+ kind: literal("http"),
23550
+ method: _enum(["PUT", "POST"]),
23551
+ url: string().url(),
23552
+ headers: record(string(), string()).optional()
23553
+ });
23554
+ var RetrainArchiveResultSchema = object({
23555
+ batchId: string(),
23556
+ frames: number().int(),
23557
+ crops: number().int(),
23558
+ annotations: number().int(),
23559
+ /** Frames planned but not shipped (unreadable copy, path too long). */
23560
+ missing: number().int(),
23561
+ bytes: number().int(),
23562
+ /** sha256 of the exact bytes sent. */
23563
+ sha256: string(),
23564
+ /** The target's HTTP status. */
23565
+ status: number().int()
23566
+ });
23499
23567
  /** What the operator asked the assist to look for. */
23500
23568
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
23501
23569
  kind: literal("package"),
@@ -24290,9 +24358,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24290
24358
  }), RetrainTransitionResultSchema, {
24291
24359
  kind: "mutation",
24292
24360
  auth: "admin"
24293
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
24361
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
24294
24362
  kind: "query",
24295
24363
  auth: "admin"
24364
+ }), method(object({
24365
+ deviceId: number(),
24366
+ trackId: string(),
24367
+ frameId: string(),
24368
+ complete: boolean()
24369
+ }), RetrainFrameSchema, {
24370
+ kind: "mutation",
24371
+ auth: "admin"
24372
+ }), method(object({
24373
+ filter: RetrainExportFilterSchema,
24374
+ layout: RetrainExportLayoutSchema,
24375
+ target: RetrainArchiveTargetSchema
24376
+ }), RetrainArchiveResultSchema, {
24377
+ kind: "mutation",
24378
+ auth: "admin",
24379
+ timeoutMs: 60 * 6e4
24296
24380
  }), method(object({
24297
24381
  /** Which of the three event tables owns the row. */
24298
24382
  ownerType: EventOwnerTypeSchema,
@@ -27622,7 +27706,19 @@ var SsoBridgeClaimsSchema = object({
27622
27706
  * editing a descriptor must not retroactively extend or shorten a link the
27623
27707
  * operator already consented to.
27624
27708
  */
27625
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
27709
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
27710
+ /**
27711
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
27712
+ * that was started from a signed-in user's "Link" button: the finish then
27713
+ * links this identity to the intent's user instead of signing anyone in.
27714
+ * The handle carries no user id — the hub resolves it, single-use.
27715
+ */
27716
+ linkIntent: string().optional(),
27717
+ /**
27718
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
27719
+ * subject is unique only per issuer, so a link is bound to it.
27720
+ */
27721
+ issuer: string().optional()
27626
27722
  });
27627
27723
  method(object({
27628
27724
  claims: SsoBridgeClaimsSchema,
@@ -29557,7 +29653,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
29557
29653
  * field their hints were silently stripped by the schema and the
29558
29654
  * adaptive ladder started blind on the client's display size.
29559
29655
  */
29560
- hints: webrtcClientHintsSchema.optional()
29656
+ hints: webrtcClientHintsSchema.optional(),
29657
+ /**
29658
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
29659
+ * through the `intercom` cap's push-talk triple. When `true` and the
29660
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
29661
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
29662
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
29663
+ *
29664
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
29665
+ * with `intercom`, when the linked user may control that camera. The
29666
+ * hub STRIPS it from every request-bound call (a browser), exactly as
29667
+ * it overwrites `relayOnly` — a viewer's talk permission is the
29668
+ * intercom cap's own surface (share tokens gate it there), and this
29669
+ * flag must not become a second door to the camera's speaker.
29670
+ */
29671
+ talkback: boolean().optional()
29561
29672
  }), object({
29562
29673
  sessionId: string(),
29563
29674
  sdpAnswer: string()
@@ -29859,6 +29970,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
29859
29970
  var RestartAddonResultSchema = unknown();
29860
29971
  var InstallPackageResultSchema = unknown();
29861
29972
  var ReloadPackagesResultSchema = unknown();
29973
+ /**
29974
+ * What an uninstall did on ONE node.
29975
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29976
+ * - `not-installed` — the node did not have it (nothing to do).
29977
+ * - `refused` — protected / bootstrap package; nothing touched.
29978
+ * - `failed` — attempted and did not complete; `error` says why.
29979
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29980
+ * back-fill never returns the package, and the stale-addon sweep removes the
29981
+ * copy when the node registers again (only once the hub no longer has it).
29982
+ */
29983
+ var UninstallNodeOutcomeSchema = _enum([
29984
+ "uninstalled",
29985
+ "not-installed",
29986
+ "refused",
29987
+ "failed",
29988
+ "pending-reconnect"
29989
+ ]);
29990
+ var UninstallNodeResultSchema = object({
29991
+ nodeId: string(),
29992
+ outcome: UninstallNodeOutcomeSchema,
29993
+ error: string().optional(),
29994
+ addonIds: array(string()).readonly(),
29995
+ runnersStopped: array(string()).readonly(),
29996
+ warnings: array(string()).readonly()
29997
+ });
29998
+ var UninstallPackageResultSchema = object({
29999
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
30000
+ success: boolean(),
30001
+ packageName: string(),
30002
+ results: array(UninstallNodeResultSchema).readonly()
30003
+ });
30004
+ /**
30005
+ * `unreachable` lists online agents whose status read FAILED — absence from
30006
+ * `installations` is only "not installed" for a node that answered (D315).
30007
+ */
30008
+ var PackageInstallationsSchema = object({
30009
+ installations: array(object({
30010
+ packageName: string(),
30011
+ nodeId: string(),
30012
+ nodeName: string(),
30013
+ isHub: boolean(),
30014
+ isOnline: boolean(),
30015
+ version: string().nullable(),
30016
+ addonIds: array(string()).readonly(),
30017
+ source: _enum(["live", "recorded"]),
30018
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
30019
+ onHub: boolean()
30020
+ })).readonly(),
30021
+ unreachable: array(object({
30022
+ nodeId: string(),
30023
+ error: string()
30024
+ })).readonly()
30025
+ });
29862
30026
  var BulkUpdateItemStatusSchema = _enum([
29863
30027
  "queued",
29864
30028
  "updating",
@@ -29941,10 +30105,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29941
30105
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29942
30106
  kind: "mutation",
29943
30107
  auth: "admin"
29944
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
30108
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
30109
+ packageName: string().min(1),
30110
+ nodeId: string().optional(),
30111
+ everywhere: boolean().optional()
30112
+ }), UninstallPackageResultSchema, {
29945
30113
  kind: "mutation",
29946
30114
  auth: "admin"
29947
- }), method(_void(), ReloadPackagesResultSchema, {
30115
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29948
30116
  kind: "mutation",
29949
30117
  auth: "admin"
29950
30118
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -39854,6 +40022,32 @@ var TotpStatusSchema = object({
39854
40022
  /** Null when no row exists OR the row is still pending confirmation. */
39855
40023
  confirmedAt: number().nullable()
39856
40024
  });
40025
+ /**
40026
+ * user-management — singleton capability for user accounts, API keys,
40027
+ * and scoped tokens.
40028
+ *
40029
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
40030
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
40031
+ * because non-admins never reach these. If/when we open non-admin
40032
+ * delegation, structural caller-scope subset check goes inside the
40033
+ * provider.
40034
+ */
40035
+ var ExternalIdentitySchema = object({
40036
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
40037
+ provider: string(),
40038
+ /** The IdP's stable subject (`sub`) for this account. */
40039
+ subject: string(),
40040
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
40041
+ issuer: string(),
40042
+ userId: string(),
40043
+ /** What the IdP called the account at link time (username / email) — display only. */
40044
+ label: string().optional(),
40045
+ linkedAt: number()
40046
+ });
40047
+ var ExternalIdentityKeySchema = object({
40048
+ provider: string().min(1),
40049
+ subject: string().min(1)
40050
+ });
39857
40051
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
39858
40052
  kind: "mutation",
39859
40053
  auth: "admin",
@@ -39967,7 +40161,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39967
40161
  userId: string(),
39968
40162
  username: string(),
39969
40163
  scopes: array(TokenScopeSchema)
39970
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
40164
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
40165
+ userId: string(),
40166
+ issuer: string()
40167
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
40168
+ userId: string(),
40169
+ issuer: string().min(1),
40170
+ label: string().optional()
40171
+ }), object({ success: literal(true) }), {
40172
+ kind: "mutation",
40173
+ auth: "admin",
40174
+ access: "create"
40175
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
40176
+ kind: "mutation",
40177
+ auth: "admin",
40178
+ access: "delete"
40179
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39971
40180
  kind: "mutation",
39972
40181
  auth: "admin",
39973
40182
  access: "delete"
@@ -42377,6 +42586,12 @@ Object.freeze({
42377
42586
  addonId: null,
42378
42587
  access: "view"
42379
42588
  },
42589
+ "addons.listInstallations": {
42590
+ capName: "addons",
42591
+ capScope: "system",
42592
+ addonId: null,
42593
+ access: "view"
42594
+ },
42380
42595
  "addons.listJobs": {
42381
42596
  capName: "addons",
42382
42597
  capScope: "system",
@@ -46601,6 +46816,12 @@ Object.freeze({
46601
46816
  addonId: null,
46602
46817
  access: "create"
46603
46818
  },
46819
+ "pipelineAnalytics.setRetrainFrameComplete": {
46820
+ capName: "pipeline-analytics",
46821
+ capScope: "device",
46822
+ addonId: null,
46823
+ access: "create"
46824
+ },
46604
46825
  "pipelineAnalytics.setTrackFlags": {
46605
46826
  capName: "pipeline-analytics",
46606
46827
  capScope: "device",
@@ -46637,6 +46858,12 @@ Object.freeze({
46637
46858
  addonId: null,
46638
46859
  access: "delete"
46639
46860
  },
46861
+ "pipelineAnalytics.writeRetrainArchive": {
46862
+ capName: "pipeline-analytics",
46863
+ capScope: "device",
46864
+ addonId: null,
46865
+ access: "create"
46866
+ },
46640
46867
  "pipelineExecutor.cacheFrameInPool": {
46641
46868
  capName: "pipeline-executor",
46642
46869
  capScope: "system",
@@ -48989,18 +49216,36 @@ Object.freeze({
48989
49216
  addonId: null,
48990
49217
  access: "delete"
48991
49218
  },
49219
+ "userManagement.findUserByExternalIdentity": {
49220
+ capName: "user-management",
49221
+ capScope: "system",
49222
+ addonId: null,
49223
+ access: "view"
49224
+ },
48992
49225
  "userManagement.getTotpStatus": {
48993
49226
  capName: "user-management",
48994
49227
  capScope: "system",
48995
49228
  addonId: null,
48996
49229
  access: "view"
48997
49230
  },
49231
+ "userManagement.linkExternalIdentity": {
49232
+ capName: "user-management",
49233
+ capScope: "system",
49234
+ addonId: null,
49235
+ access: "create"
49236
+ },
48998
49237
  "userManagement.listApiKeys": {
48999
49238
  capName: "user-management",
49000
49239
  capScope: "system",
49001
49240
  addonId: null,
49002
49241
  access: "view"
49003
49242
  },
49243
+ "userManagement.listExternalIdentities": {
49244
+ capName: "user-management",
49245
+ capScope: "system",
49246
+ addonId: null,
49247
+ access: "view"
49248
+ },
49004
49249
  "userManagement.listOauthSessions": {
49005
49250
  capName: "user-management",
49006
49251
  capScope: "system",
@@ -49079,6 +49324,12 @@ Object.freeze({
49079
49324
  addonId: null,
49080
49325
  access: "create"
49081
49326
  },
49327
+ "userManagement.unlinkExternalIdentity": {
49328
+ capName: "user-management",
49329
+ capScope: "system",
49330
+ addonId: null,
49331
+ access: "delete"
49332
+ },
49082
49333
  "userManagement.updateUser": {
49083
49334
  capName: "user-management",
49084
49335
  capScope: "system",
@@ -52418,6 +52669,11 @@ Object.freeze({
52418
52669
  form: "single",
52419
52670
  optional: false
52420
52671
  }],
52672
+ "pipelineAnalytics.setRetrainFrameComplete": [{
52673
+ name: "deviceId",
52674
+ form: "single",
52675
+ optional: false
52676
+ }],
52421
52677
  "pipelineAnalytics.setTrackFlags": [{
52422
52678
  name: "deviceId",
52423
52679
  form: "single",
@@ -54479,7 +54735,7 @@ var MB = 1024 * 1024;
54479
54735
  */
54480
54736
  var rademacherConnectionSchema = object({
54481
54737
  host: string().min(1).describe("HomePilot hub host name or IP address"),
54482
- password: string().default("").describe("Hub password (leave blank for an unprotected hub)"),
54738
+ password: string().default("").describe("Hub password (leave blank for an unprotected hub)").meta({ secret: true }),
54483
54739
  basePath: string().default("").describe("API base path override (blank = auto-probe: v1 \"\" / v2 \"/hp\")"),
54484
54740
  pollIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(2e3).max(36e5).default(3e4)).describe("Device-state poll interval (ms)")
54485
54741
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.121",
3
+ "version": "0.2.123",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",