@camstack/addon-import-alexa 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 +270 -14
  2. package/dist/addon.mjs +270 -14
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5409,7 +5409,7 @@ var ZodIssueCode = {
5409
5409
  var ZodFirstPartyTypeKind;
5410
5410
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5411
5411
  //#endregion
5412
- //#region ../types/dist/sleep-BNeXenvr.mjs
5412
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5413
5413
  /**
5414
5414
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5415
5415
  * window to float samples (D455).
@@ -8348,8 +8348,8 @@ function buildAddonRouteProvider(id, routes) {
8348
8348
  const reply = buildCapturingReply(envelope);
8349
8349
  const request = {
8350
8350
  params: {
8351
- ...input.params,
8352
- ...match.params
8351
+ ...match.params,
8352
+ ...input.params
8353
8353
  },
8354
8354
  query: input.query,
8355
8355
  body: input.body,
@@ -15320,6 +15320,10 @@ var DeviceInfoSchema = object({
15320
15320
  isCamera: boolean(),
15321
15321
  /** Current config values — serializable snapshot */
15322
15322
  config: record(string(), unknown()),
15323
+ /** Paths inside `config` the device's schema declares secret (D783) —
15324
+ * what the non-admin redaction withholds. Paths, never values. Absent
15325
+ * when the owning runner has not reported them. */
15326
+ secretConfigPaths: array(string()).optional(),
15323
15327
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15324
15328
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15325
15329
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15525,7 +15529,13 @@ var DeviceRegisterPayloadSchema = object({
15525
15529
  * call (workers re-register on init), so probe-driven updates
15526
15530
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15527
15531
  features: array(string()).optional(),
15528
- config: record(string(), unknown())
15532
+ config: record(string(), unknown()),
15533
+ /** Config paths the device's own schema DECLARES secret
15534
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15535
+ * `connection.password`). Re-published on every register; the non-admin
15536
+ * redaction withholds them at any depth (D783). Optional: an older runner
15537
+ * omits it and the keyword backstop applies. */
15538
+ secretConfigPaths: array(string()).optional()
15529
15539
  });
15530
15540
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15531
15541
  var DevicePersistConfigPayloadSchema = object({
@@ -17184,7 +17194,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
17184
17194
  icon: string().optional(),
17185
17195
  /** Addon-owned HTTP route the button navigates to (GET). */
17186
17196
  startUrl: string(),
17187
- stage: LoginStageEnum
17197
+ stage: LoginStageEnum,
17198
+ /**
17199
+ * The provider names an external identity a signed-in user can link to
17200
+ * their own account (D782): `auth.listLinkableProviders` /
17201
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17202
+ * whatever their id. Absent / false — a login button only (magic-link).
17203
+ */
17204
+ linkable: boolean().optional()
17188
17205
  }),
17189
17206
  object({
17190
17207
  kind: literal("widget"),
@@ -22619,7 +22636,13 @@ var RetrainFrameSchema = object({
22619
22636
  sizeBytes: number().int(),
22620
22637
  width: number().int(),
22621
22638
  height: number().int(),
22622
- copiedAt: number()
22639
+ copiedAt: number(),
22640
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22641
+ capturedAt: number().optional(),
22642
+ /** The operator's "every subject in this frame is boxed". Detector
22643
+ * evaluation keeps only complete frames: an unboxed subject would count as
22644
+ * a false positive. */
22645
+ complete: boolean()
22623
22646
  });
22624
22647
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22625
22648
  var RetrainCopyRefusalSchema = _enum([
@@ -22640,6 +22663,51 @@ var RetrainFrameListSchema = object({
22640
22663
  /** What the page pre-selects — the native key frame when one survives. */
22641
22664
  autoPickMediaId: number().int().optional()
22642
22665
  });
22666
+ /**
22667
+ * Which frames an annotated export carries. Every field narrows; an empty
22668
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22669
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22670
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22671
+ * export carried (`exportedInBatch`).
22672
+ */
22673
+ var RetrainExportFilterSchema = object({
22674
+ deviceIds: array(number()).optional(),
22675
+ frameIds: array(string()).max(2e4).optional(),
22676
+ batchId: string().optional(),
22677
+ /** Only frames the operator marked complete (all subjects boxed). */
22678
+ completeOnly: boolean().optional()
22679
+ });
22680
+ /**
22681
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22682
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22683
+ * convention — the classifier layout.
22684
+ */
22685
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22686
+ /**
22687
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22688
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22689
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22690
+ * logged.
22691
+ */
22692
+ var RetrainArchiveTargetSchema = object({
22693
+ kind: literal("http"),
22694
+ method: _enum(["PUT", "POST"]),
22695
+ url: string().url(),
22696
+ headers: record(string(), string()).optional()
22697
+ });
22698
+ var RetrainArchiveResultSchema = object({
22699
+ batchId: string(),
22700
+ frames: number().int(),
22701
+ crops: number().int(),
22702
+ annotations: number().int(),
22703
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22704
+ missing: number().int(),
22705
+ bytes: number().int(),
22706
+ /** sha256 of the exact bytes sent. */
22707
+ sha256: string(),
22708
+ /** The target's HTTP status. */
22709
+ status: number().int()
22710
+ });
22643
22711
  /** What the operator asked the assist to look for. */
22644
22712
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22645
22713
  kind: literal("package"),
@@ -23434,9 +23502,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23434
23502
  }), RetrainTransitionResultSchema, {
23435
23503
  kind: "mutation",
23436
23504
  auth: "admin"
23437
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23505
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23438
23506
  kind: "query",
23439
23507
  auth: "admin"
23508
+ }), method(object({
23509
+ deviceId: number(),
23510
+ trackId: string(),
23511
+ frameId: string(),
23512
+ complete: boolean()
23513
+ }), RetrainFrameSchema, {
23514
+ kind: "mutation",
23515
+ auth: "admin"
23516
+ }), method(object({
23517
+ filter: RetrainExportFilterSchema,
23518
+ layout: RetrainExportLayoutSchema,
23519
+ target: RetrainArchiveTargetSchema
23520
+ }), RetrainArchiveResultSchema, {
23521
+ kind: "mutation",
23522
+ auth: "admin",
23523
+ timeoutMs: 60 * 6e4
23440
23524
  }), method(object({
23441
23525
  /** Which of the three event tables owns the row. */
23442
23526
  ownerType: EventOwnerTypeSchema,
@@ -26766,7 +26850,19 @@ var SsoBridgeClaimsSchema = object({
26766
26850
  * editing a descriptor must not retroactively extend or shorten a link the
26767
26851
  * operator already consented to.
26768
26852
  */
26769
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26853
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26854
+ /**
26855
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26856
+ * that was started from a signed-in user's "Link" button: the finish then
26857
+ * links this identity to the intent's user instead of signing anyone in.
26858
+ * The handle carries no user id — the hub resolves it, single-use.
26859
+ */
26860
+ linkIntent: string().optional(),
26861
+ /**
26862
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26863
+ * subject is unique only per issuer, so a link is bound to it.
26864
+ */
26865
+ issuer: string().optional()
26770
26866
  });
26771
26867
  method(object({
26772
26868
  claims: SsoBridgeClaimsSchema,
@@ -28701,7 +28797,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28701
28797
  * field their hints were silently stripped by the schema and the
28702
28798
  * adaptive ladder started blind on the client's display size.
28703
28799
  */
28704
- hints: webrtcClientHintsSchema.optional()
28800
+ hints: webrtcClientHintsSchema.optional(),
28801
+ /**
28802
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28803
+ * through the `intercom` cap's push-talk triple. When `true` and the
28804
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28805
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28806
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28807
+ *
28808
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28809
+ * with `intercom`, when the linked user may control that camera. The
28810
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28811
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28812
+ * intercom cap's own surface (share tokens gate it there), and this
28813
+ * flag must not become a second door to the camera's speaker.
28814
+ */
28815
+ talkback: boolean().optional()
28705
28816
  }), object({
28706
28817
  sessionId: string(),
28707
28818
  sdpAnswer: string()
@@ -29003,6 +29114,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
29003
29114
  var RestartAddonResultSchema = unknown();
29004
29115
  var InstallPackageResultSchema = unknown();
29005
29116
  var ReloadPackagesResultSchema = unknown();
29117
+ /**
29118
+ * What an uninstall did on ONE node.
29119
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29120
+ * - `not-installed` — the node did not have it (nothing to do).
29121
+ * - `refused` — protected / bootstrap package; nothing touched.
29122
+ * - `failed` — attempted and did not complete; `error` says why.
29123
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29124
+ * back-fill never returns the package, and the stale-addon sweep removes the
29125
+ * copy when the node registers again (only once the hub no longer has it).
29126
+ */
29127
+ var UninstallNodeOutcomeSchema = _enum([
29128
+ "uninstalled",
29129
+ "not-installed",
29130
+ "refused",
29131
+ "failed",
29132
+ "pending-reconnect"
29133
+ ]);
29134
+ var UninstallNodeResultSchema = object({
29135
+ nodeId: string(),
29136
+ outcome: UninstallNodeOutcomeSchema,
29137
+ error: string().optional(),
29138
+ addonIds: array(string()).readonly(),
29139
+ runnersStopped: array(string()).readonly(),
29140
+ warnings: array(string()).readonly()
29141
+ });
29142
+ var UninstallPackageResultSchema = object({
29143
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
29144
+ success: boolean(),
29145
+ packageName: string(),
29146
+ results: array(UninstallNodeResultSchema).readonly()
29147
+ });
29148
+ /**
29149
+ * `unreachable` lists online agents whose status read FAILED — absence from
29150
+ * `installations` is only "not installed" for a node that answered (D315).
29151
+ */
29152
+ var PackageInstallationsSchema = object({
29153
+ installations: array(object({
29154
+ packageName: string(),
29155
+ nodeId: string(),
29156
+ nodeName: string(),
29157
+ isHub: boolean(),
29158
+ isOnline: boolean(),
29159
+ version: string().nullable(),
29160
+ addonIds: array(string()).readonly(),
29161
+ source: _enum(["live", "recorded"]),
29162
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
29163
+ onHub: boolean()
29164
+ })).readonly(),
29165
+ unreachable: array(object({
29166
+ nodeId: string(),
29167
+ error: string()
29168
+ })).readonly()
29169
+ });
29006
29170
  var BulkUpdateItemStatusSchema = _enum([
29007
29171
  "queued",
29008
29172
  "updating",
@@ -29085,10 +29249,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29085
29249
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29086
29250
  kind: "mutation",
29087
29251
  auth: "admin"
29088
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29252
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29253
+ packageName: string().min(1),
29254
+ nodeId: string().optional(),
29255
+ everywhere: boolean().optional()
29256
+ }), UninstallPackageResultSchema, {
29089
29257
  kind: "mutation",
29090
29258
  auth: "admin"
29091
- }), method(_void(), ReloadPackagesResultSchema, {
29259
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29092
29260
  kind: "mutation",
29093
29261
  auth: "admin"
29094
29262
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -39015,6 +39183,32 @@ var TotpStatusSchema = object({
39015
39183
  /** Null when no row exists OR the row is still pending confirmation. */
39016
39184
  confirmedAt: number().nullable()
39017
39185
  });
39186
+ /**
39187
+ * user-management — singleton capability for user accounts, API keys,
39188
+ * and scoped tokens.
39189
+ *
39190
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
39191
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
39192
+ * because non-admins never reach these. If/when we open non-admin
39193
+ * delegation, structural caller-scope subset check goes inside the
39194
+ * provider.
39195
+ */
39196
+ var ExternalIdentitySchema = object({
39197
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39198
+ provider: string(),
39199
+ /** The IdP's stable subject (`sub`) for this account. */
39200
+ subject: string(),
39201
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39202
+ issuer: string(),
39203
+ userId: string(),
39204
+ /** What the IdP called the account at link time (username / email) — display only. */
39205
+ label: string().optional(),
39206
+ linkedAt: number()
39207
+ });
39208
+ var ExternalIdentityKeySchema = object({
39209
+ provider: string().min(1),
39210
+ subject: string().min(1)
39211
+ });
39018
39212
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
39019
39213
  kind: "mutation",
39020
39214
  auth: "admin",
@@ -39128,7 +39322,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39128
39322
  userId: string(),
39129
39323
  username: string(),
39130
39324
  scopes: array(TokenScopeSchema)
39131
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39325
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39326
+ userId: string(),
39327
+ issuer: string()
39328
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39329
+ userId: string(),
39330
+ issuer: string().min(1),
39331
+ label: string().optional()
39332
+ }), object({ success: literal(true) }), {
39333
+ kind: "mutation",
39334
+ auth: "admin",
39335
+ access: "create"
39336
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39337
+ kind: "mutation",
39338
+ auth: "admin",
39339
+ access: "delete"
39340
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39132
39341
  kind: "mutation",
39133
39342
  auth: "admin",
39134
39343
  access: "delete"
@@ -41538,6 +41747,12 @@ Object.freeze({
41538
41747
  addonId: null,
41539
41748
  access: "view"
41540
41749
  },
41750
+ "addons.listInstallations": {
41751
+ capName: "addons",
41752
+ capScope: "system",
41753
+ addonId: null,
41754
+ access: "view"
41755
+ },
41541
41756
  "addons.listJobs": {
41542
41757
  capName: "addons",
41543
41758
  capScope: "system",
@@ -45762,6 +45977,12 @@ Object.freeze({
45762
45977
  addonId: null,
45763
45978
  access: "create"
45764
45979
  },
45980
+ "pipelineAnalytics.setRetrainFrameComplete": {
45981
+ capName: "pipeline-analytics",
45982
+ capScope: "device",
45983
+ addonId: null,
45984
+ access: "create"
45985
+ },
45765
45986
  "pipelineAnalytics.setTrackFlags": {
45766
45987
  capName: "pipeline-analytics",
45767
45988
  capScope: "device",
@@ -45798,6 +46019,12 @@ Object.freeze({
45798
46019
  addonId: null,
45799
46020
  access: "delete"
45800
46021
  },
46022
+ "pipelineAnalytics.writeRetrainArchive": {
46023
+ capName: "pipeline-analytics",
46024
+ capScope: "device",
46025
+ addonId: null,
46026
+ access: "create"
46027
+ },
45801
46028
  "pipelineExecutor.cacheFrameInPool": {
45802
46029
  capName: "pipeline-executor",
45803
46030
  capScope: "system",
@@ -48150,18 +48377,36 @@ Object.freeze({
48150
48377
  addonId: null,
48151
48378
  access: "delete"
48152
48379
  },
48380
+ "userManagement.findUserByExternalIdentity": {
48381
+ capName: "user-management",
48382
+ capScope: "system",
48383
+ addonId: null,
48384
+ access: "view"
48385
+ },
48153
48386
  "userManagement.getTotpStatus": {
48154
48387
  capName: "user-management",
48155
48388
  capScope: "system",
48156
48389
  addonId: null,
48157
48390
  access: "view"
48158
48391
  },
48392
+ "userManagement.linkExternalIdentity": {
48393
+ capName: "user-management",
48394
+ capScope: "system",
48395
+ addonId: null,
48396
+ access: "create"
48397
+ },
48159
48398
  "userManagement.listApiKeys": {
48160
48399
  capName: "user-management",
48161
48400
  capScope: "system",
48162
48401
  addonId: null,
48163
48402
  access: "view"
48164
48403
  },
48404
+ "userManagement.listExternalIdentities": {
48405
+ capName: "user-management",
48406
+ capScope: "system",
48407
+ addonId: null,
48408
+ access: "view"
48409
+ },
48165
48410
  "userManagement.listOauthSessions": {
48166
48411
  capName: "user-management",
48167
48412
  capScope: "system",
@@ -48240,6 +48485,12 @@ Object.freeze({
48240
48485
  addonId: null,
48241
48486
  access: "create"
48242
48487
  },
48488
+ "userManagement.unlinkExternalIdentity": {
48489
+ capName: "user-management",
48490
+ capScope: "system",
48491
+ addonId: null,
48492
+ access: "delete"
48493
+ },
48243
48494
  "userManagement.updateUser": {
48244
48495
  capName: "user-management",
48245
48496
  capScope: "system",
@@ -51579,6 +51830,11 @@ Object.freeze({
51579
51830
  form: "single",
51580
51831
  optional: false
51581
51832
  }],
51833
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51834
+ name: "deviceId",
51835
+ form: "single",
51836
+ optional: false
51837
+ }],
51582
51838
  "pipelineAnalytics.setTrackFlags": [{
51583
51839
  name: "deviceId",
51584
51840
  form: "single",
@@ -53648,13 +53904,13 @@ var alexaConnectionSchema = object({
53648
53904
  * proxy login (preferred: it carries the refresh token + lets the session
53649
53905
  * auto-refresh). This is the primary auth input.
53650
53906
  */
53651
- cookie: string().default("").describe("Captured Alexa cookie / cookieData blob (from proxy login)"),
53907
+ cookie: string().default("").describe("Captured Alexa cookie / cookieData blob (from proxy login)").meta({ secret: true }),
53652
53908
  /**
53653
53909
  * Refresh token. NOTE: a bare refresh token alone is NOT sufficient to init
53654
53910
  * alexa-remote2 — supply the full cookie / cookieData blob (which embeds it).
53655
53911
  * Retained for provenance / forward-compat.
53656
53912
  */
53657
- refreshToken: string().default("").describe("Alexa refresh token (must be inside cookie blob)"),
53913
+ refreshToken: string().default("").describe("Alexa refresh token (must be inside cookie blob)").meta({ secret: true }),
53658
53914
  /** Device-registration secret some flows need. */
53659
53915
  macDms: string().default("").describe("macDms device-registration secret (optional)"),
53660
53916
  /** Poll interval for state sync (Alexa has no clean 3rd-party push). */
package/dist/addon.mjs CHANGED
@@ -5409,7 +5409,7 @@ var ZodIssueCode = {
5409
5409
  var ZodFirstPartyTypeKind;
5410
5410
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5411
5411
  //#endregion
5412
- //#region ../types/dist/sleep-BNeXenvr.mjs
5412
+ //#region ../types/dist/sleep-B0JG7-_F.mjs
5413
5413
  /**
5414
5414
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5415
5415
  * window to float samples (D455).
@@ -8348,8 +8348,8 @@ function buildAddonRouteProvider(id, routes) {
8348
8348
  const reply = buildCapturingReply(envelope);
8349
8349
  const request = {
8350
8350
  params: {
8351
- ...input.params,
8352
- ...match.params
8351
+ ...match.params,
8352
+ ...input.params
8353
8353
  },
8354
8354
  query: input.query,
8355
8355
  body: input.body,
@@ -15320,6 +15320,10 @@ var DeviceInfoSchema = object({
15320
15320
  isCamera: boolean(),
15321
15321
  /** Current config values — serializable snapshot */
15322
15322
  config: record(string(), unknown()),
15323
+ /** Paths inside `config` the device's schema declares secret (D783) —
15324
+ * what the non-admin redaction withholds. Paths, never values. Absent
15325
+ * when the owning runner has not reported them. */
15326
+ secretConfigPaths: array(string()).optional(),
15323
15327
  /** Hardware + identity blob (manufacturer / model / firmware / sn /
15324
15328
  * uid / mac / …). Populated by drivers; editable via setMetadata. */
15325
15329
  metadata: record(string(), unknown()).nullable().optional(),
@@ -15525,7 +15529,13 @@ var DeviceRegisterPayloadSchema = object({
15525
15529
  * call (workers re-register on init), so probe-driven updates
15526
15530
  * (e.g. PTZ flag flipping after the abilities probe) propagate. */
15527
15531
  features: array(string()).optional(),
15528
- config: record(string(), unknown())
15532
+ config: record(string(), unknown()),
15533
+ /** Config paths the device's own schema DECLARES secret
15534
+ * (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
15535
+ * `connection.password`). Re-published on every register; the non-admin
15536
+ * redaction withholds them at any depth (D783). Optional: an older runner
15537
+ * omits it and the keyword backstop applies. */
15538
+ secretConfigPaths: array(string()).optional()
15529
15539
  });
15530
15540
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
15531
15541
  var DevicePersistConfigPayloadSchema = object({
@@ -17184,7 +17194,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
17184
17194
  icon: string().optional(),
17185
17195
  /** Addon-owned HTTP route the button navigates to (GET). */
17186
17196
  startUrl: string(),
17187
- stage: LoginStageEnum
17197
+ stage: LoginStageEnum,
17198
+ /**
17199
+ * The provider names an external identity a signed-in user can link to
17200
+ * their own account (D782): `auth.listLinkableProviders` /
17201
+ * `beginExternalLink` offer exactly the redirect methods that set this,
17202
+ * whatever their id. Absent / false — a login button only (magic-link).
17203
+ */
17204
+ linkable: boolean().optional()
17188
17205
  }),
17189
17206
  object({
17190
17207
  kind: literal("widget"),
@@ -22619,7 +22636,13 @@ var RetrainFrameSchema = object({
22619
22636
  sizeBytes: number().int(),
22620
22637
  width: number().int(),
22621
22638
  height: number().int(),
22622
- copiedAt: number()
22639
+ copiedAt: number(),
22640
+ /** When the CAMERA captured the frame. Absent on a copy taken before D785. */
22641
+ capturedAt: number().optional(),
22642
+ /** The operator's "every subject in this frame is boxed". Detector
22643
+ * evaluation keeps only complete frames: an unboxed subject would count as
22644
+ * a false positive. */
22645
+ complete: boolean()
22623
22646
  });
22624
22647
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
22625
22648
  var RetrainCopyRefusalSchema = _enum([
@@ -22640,6 +22663,51 @@ var RetrainFrameListSchema = object({
22640
22663
  /** What the page pre-selects — the native key frame when one survives. */
22641
22664
  autoPickMediaId: number().int().optional()
22642
22665
  });
22666
+ /**
22667
+ * Which frames an annotated export carries. Every field narrows; an empty
22668
+ * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
22669
+ * list owned by whoever trains (the training orchestrator), so `frameIds` is
22670
+ * the primitive a version export uses; `batchId` re-selects what an earlier
22671
+ * export carried (`exportedInBatch`).
22672
+ */
22673
+ var RetrainExportFilterSchema = object({
22674
+ deviceIds: array(number()).optional(),
22675
+ frameIds: array(string()).max(2e4).optional(),
22676
+ batchId: string().optional(),
22677
+ /** Only frames the operator marked complete (all subjects boxed). */
22678
+ completeOnly: boolean().optional()
22679
+ });
22680
+ /**
22681
+ * `frames`: the full frame copies, boxes in `annotations.json`.
22682
+ * `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
22683
+ * convention — the classifier layout.
22684
+ */
22685
+ var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
22686
+ /**
22687
+ * Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
22688
+ * the archive, sent chunk by chunk. Covers a presigned PUT and a provider
22689
+ * addon's data-plane upload route alike. Headers are sent verbatim and never
22690
+ * logged.
22691
+ */
22692
+ var RetrainArchiveTargetSchema = object({
22693
+ kind: literal("http"),
22694
+ method: _enum(["PUT", "POST"]),
22695
+ url: string().url(),
22696
+ headers: record(string(), string()).optional()
22697
+ });
22698
+ var RetrainArchiveResultSchema = object({
22699
+ batchId: string(),
22700
+ frames: number().int(),
22701
+ crops: number().int(),
22702
+ annotations: number().int(),
22703
+ /** Frames planned but not shipped (unreadable copy, path too long). */
22704
+ missing: number().int(),
22705
+ bytes: number().int(),
22706
+ /** sha256 of the exact bytes sent. */
22707
+ sha256: string(),
22708
+ /** The target's HTTP status. */
22709
+ status: number().int()
22710
+ });
22643
22711
  /** What the operator asked the assist to look for. */
22644
22712
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
22645
22713
  kind: literal("package"),
@@ -23434,9 +23502,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23434
23502
  }), RetrainTransitionResultSchema, {
23435
23503
  kind: "mutation",
23436
23504
  auth: "admin"
23437
- }), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
23505
+ }), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
23438
23506
  kind: "query",
23439
23507
  auth: "admin"
23508
+ }), method(object({
23509
+ deviceId: number(),
23510
+ trackId: string(),
23511
+ frameId: string(),
23512
+ complete: boolean()
23513
+ }), RetrainFrameSchema, {
23514
+ kind: "mutation",
23515
+ auth: "admin"
23516
+ }), method(object({
23517
+ filter: RetrainExportFilterSchema,
23518
+ layout: RetrainExportLayoutSchema,
23519
+ target: RetrainArchiveTargetSchema
23520
+ }), RetrainArchiveResultSchema, {
23521
+ kind: "mutation",
23522
+ auth: "admin",
23523
+ timeoutMs: 60 * 6e4
23440
23524
  }), method(object({
23441
23525
  /** Which of the three event tables owns the row. */
23442
23526
  ownerType: EventOwnerTypeSchema,
@@ -26766,7 +26850,19 @@ var SsoBridgeClaimsSchema = object({
26766
26850
  * editing a descriptor must not retroactively extend or shorten a link the
26767
26851
  * operator already consented to.
26768
26852
  */
26769
- refreshTtl: union([number().int().positive(), literal("never")]).optional()
26853
+ refreshTtl: union([number().int().positive(), literal("never")]).optional(),
26854
+ /**
26855
+ * Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
26856
+ * that was started from a signed-in user's "Link" button: the finish then
26857
+ * links this identity to the intent's user instead of signing anyone in.
26858
+ * The handle carries no user id — the hub resolves it, single-use.
26859
+ */
26860
+ linkIntent: string().optional(),
26861
+ /**
26862
+ * Verified `iss` of the id_token behind an OIDC login bridge (D782). A
26863
+ * subject is unique only per issuer, so a link is bound to it.
26864
+ */
26865
+ issuer: string().optional()
26770
26866
  });
26771
26867
  method(object({
26772
26868
  claims: SsoBridgeClaimsSchema,
@@ -28701,7 +28797,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28701
28797
  * field their hints were silently stripped by the schema and the
28702
28798
  * adaptive ladder started blind on the client's display size.
28703
28799
  */
28704
- hints: webrtcClientHintsSchema.optional()
28800
+ hints: webrtcClientHintsSchema.optional(),
28801
+ /**
28802
+ * Talk-back (D771): relay the PEER's audio to the device's speaker
28803
+ * through the `intercom` cap's push-talk triple. When `true` and the
28804
+ * offer lets the peer send audio, the answer's audio is `sendrecv`
28805
+ * and every inbound frame goes to `intercom.pushTalkAudio` for this
28806
+ * `deviceId`; absent/false answers `sendonly`, as for every viewer.
28807
+ *
28808
+ * TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
28809
+ * with `intercom`, when the linked user may control that camera. The
28810
+ * hub STRIPS it from every request-bound call (a browser), exactly as
28811
+ * it overwrites `relayOnly` — a viewer's talk permission is the
28812
+ * intercom cap's own surface (share tokens gate it there), and this
28813
+ * flag must not become a second door to the camera's speaker.
28814
+ */
28815
+ talkback: boolean().optional()
28705
28816
  }), object({
28706
28817
  sessionId: string(),
28707
28818
  sdpAnswer: string()
@@ -29003,6 +29114,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
29003
29114
  var RestartAddonResultSchema = unknown();
29004
29115
  var InstallPackageResultSchema = unknown();
29005
29116
  var ReloadPackagesResultSchema = unknown();
29117
+ /**
29118
+ * What an uninstall did on ONE node.
29119
+ * - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
29120
+ * - `not-installed` — the node did not have it (nothing to do).
29121
+ * - `refused` — protected / bootstrap package; nothing touched.
29122
+ * - `failed` — attempted and did not complete; `error` says why.
29123
+ * - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
29124
+ * back-fill never returns the package, and the stale-addon sweep removes the
29125
+ * copy when the node registers again (only once the hub no longer has it).
29126
+ */
29127
+ var UninstallNodeOutcomeSchema = _enum([
29128
+ "uninstalled",
29129
+ "not-installed",
29130
+ "refused",
29131
+ "failed",
29132
+ "pending-reconnect"
29133
+ ]);
29134
+ var UninstallNodeResultSchema = object({
29135
+ nodeId: string(),
29136
+ outcome: UninstallNodeOutcomeSchema,
29137
+ error: string().optional(),
29138
+ addonIds: array(string()).readonly(),
29139
+ runnersStopped: array(string()).readonly(),
29140
+ warnings: array(string()).readonly()
29141
+ });
29142
+ var UninstallPackageResultSchema = object({
29143
+ /** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
29144
+ success: boolean(),
29145
+ packageName: string(),
29146
+ results: array(UninstallNodeResultSchema).readonly()
29147
+ });
29148
+ /**
29149
+ * `unreachable` lists online agents whose status read FAILED — absence from
29150
+ * `installations` is only "not installed" for a node that answered (D315).
29151
+ */
29152
+ var PackageInstallationsSchema = object({
29153
+ installations: array(object({
29154
+ packageName: string(),
29155
+ nodeId: string(),
29156
+ nodeName: string(),
29157
+ isHub: boolean(),
29158
+ isOnline: boolean(),
29159
+ version: string().nullable(),
29160
+ addonIds: array(string()).readonly(),
29161
+ source: _enum(["live", "recorded"]),
29162
+ /** The hub installs this package too. `false` on an agent row = an orphan. */
29163
+ onHub: boolean()
29164
+ })).readonly(),
29165
+ unreachable: array(object({
29166
+ nodeId: string(),
29167
+ error: string()
29168
+ })).readonly()
29169
+ });
29006
29170
  var BulkUpdateItemStatusSchema = _enum([
29007
29171
  "queued",
29008
29172
  "updating",
@@ -29085,10 +29249,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
29085
29249
  }), method(object({ packageName: string() }), InstallPackageResultSchema, {
29086
29250
  kind: "mutation",
29087
29251
  auth: "admin"
29088
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({ packageName: string() }), unknown(), {
29252
+ }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
29253
+ packageName: string().min(1),
29254
+ nodeId: string().optional(),
29255
+ everywhere: boolean().optional()
29256
+ }), UninstallPackageResultSchema, {
29089
29257
  kind: "mutation",
29090
29258
  auth: "admin"
29091
- }), method(_void(), ReloadPackagesResultSchema, {
29259
+ }), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
29092
29260
  kind: "mutation",
29093
29261
  auth: "admin"
29094
29262
  }), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
@@ -39015,6 +39183,32 @@ var TotpStatusSchema = object({
39015
39183
  /** Null when no row exists OR the row is still pending confirmation. */
39016
39184
  confirmedAt: number().nullable()
39017
39185
  });
39186
+ /**
39187
+ * user-management — singleton capability for user accounts, API keys,
39188
+ * and scoped tokens.
39189
+ *
39190
+ * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
39191
+ * — the subset check on `setUserScopes` / `createScopedToken` is moot
39192
+ * because non-admins never reach these. If/when we open non-admin
39193
+ * delegation, structural caller-scope subset check goes inside the
39194
+ * provider.
39195
+ */
39196
+ var ExternalIdentitySchema = object({
39197
+ /** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
39198
+ provider: string(),
39199
+ /** The IdP's stable subject (`sub`) for this account. */
39200
+ subject: string(),
39201
+ /** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
39202
+ issuer: string(),
39203
+ userId: string(),
39204
+ /** What the IdP called the account at link time (username / email) — display only. */
39205
+ label: string().optional(),
39206
+ linkedAt: number()
39207
+ });
39208
+ var ExternalIdentityKeySchema = object({
39209
+ provider: string().min(1),
39210
+ subject: string().min(1)
39211
+ });
39018
39212
  method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
39019
39213
  kind: "mutation",
39020
39214
  auth: "admin",
@@ -39128,7 +39322,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
39128
39322
  userId: string(),
39129
39323
  username: string(),
39130
39324
  scopes: array(TokenScopeSchema)
39131
- }).nullable(), { access: "view" }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39325
+ }).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
39326
+ userId: string(),
39327
+ issuer: string()
39328
+ }).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
39329
+ userId: string(),
39330
+ issuer: string().min(1),
39331
+ label: string().optional()
39332
+ }), object({ success: literal(true) }), {
39333
+ kind: "mutation",
39334
+ auth: "admin",
39335
+ access: "create"
39336
+ }), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
39337
+ kind: "mutation",
39338
+ auth: "admin",
39339
+ access: "delete"
39340
+ }), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
39132
39341
  kind: "mutation",
39133
39342
  auth: "admin",
39134
39343
  access: "delete"
@@ -41538,6 +41747,12 @@ Object.freeze({
41538
41747
  addonId: null,
41539
41748
  access: "view"
41540
41749
  },
41750
+ "addons.listInstallations": {
41751
+ capName: "addons",
41752
+ capScope: "system",
41753
+ addonId: null,
41754
+ access: "view"
41755
+ },
41541
41756
  "addons.listJobs": {
41542
41757
  capName: "addons",
41543
41758
  capScope: "system",
@@ -45762,6 +45977,12 @@ Object.freeze({
45762
45977
  addonId: null,
45763
45978
  access: "create"
45764
45979
  },
45980
+ "pipelineAnalytics.setRetrainFrameComplete": {
45981
+ capName: "pipeline-analytics",
45982
+ capScope: "device",
45983
+ addonId: null,
45984
+ access: "create"
45985
+ },
45765
45986
  "pipelineAnalytics.setTrackFlags": {
45766
45987
  capName: "pipeline-analytics",
45767
45988
  capScope: "device",
@@ -45798,6 +46019,12 @@ Object.freeze({
45798
46019
  addonId: null,
45799
46020
  access: "delete"
45800
46021
  },
46022
+ "pipelineAnalytics.writeRetrainArchive": {
46023
+ capName: "pipeline-analytics",
46024
+ capScope: "device",
46025
+ addonId: null,
46026
+ access: "create"
46027
+ },
45801
46028
  "pipelineExecutor.cacheFrameInPool": {
45802
46029
  capName: "pipeline-executor",
45803
46030
  capScope: "system",
@@ -48150,18 +48377,36 @@ Object.freeze({
48150
48377
  addonId: null,
48151
48378
  access: "delete"
48152
48379
  },
48380
+ "userManagement.findUserByExternalIdentity": {
48381
+ capName: "user-management",
48382
+ capScope: "system",
48383
+ addonId: null,
48384
+ access: "view"
48385
+ },
48153
48386
  "userManagement.getTotpStatus": {
48154
48387
  capName: "user-management",
48155
48388
  capScope: "system",
48156
48389
  addonId: null,
48157
48390
  access: "view"
48158
48391
  },
48392
+ "userManagement.linkExternalIdentity": {
48393
+ capName: "user-management",
48394
+ capScope: "system",
48395
+ addonId: null,
48396
+ access: "create"
48397
+ },
48159
48398
  "userManagement.listApiKeys": {
48160
48399
  capName: "user-management",
48161
48400
  capScope: "system",
48162
48401
  addonId: null,
48163
48402
  access: "view"
48164
48403
  },
48404
+ "userManagement.listExternalIdentities": {
48405
+ capName: "user-management",
48406
+ capScope: "system",
48407
+ addonId: null,
48408
+ access: "view"
48409
+ },
48165
48410
  "userManagement.listOauthSessions": {
48166
48411
  capName: "user-management",
48167
48412
  capScope: "system",
@@ -48240,6 +48485,12 @@ Object.freeze({
48240
48485
  addonId: null,
48241
48486
  access: "create"
48242
48487
  },
48488
+ "userManagement.unlinkExternalIdentity": {
48489
+ capName: "user-management",
48490
+ capScope: "system",
48491
+ addonId: null,
48492
+ access: "delete"
48493
+ },
48243
48494
  "userManagement.updateUser": {
48244
48495
  capName: "user-management",
48245
48496
  capScope: "system",
@@ -51579,6 +51830,11 @@ Object.freeze({
51579
51830
  form: "single",
51580
51831
  optional: false
51581
51832
  }],
51833
+ "pipelineAnalytics.setRetrainFrameComplete": [{
51834
+ name: "deviceId",
51835
+ form: "single",
51836
+ optional: false
51837
+ }],
51582
51838
  "pipelineAnalytics.setTrackFlags": [{
51583
51839
  name: "deviceId",
51584
51840
  form: "single",
@@ -53648,13 +53904,13 @@ var alexaConnectionSchema = object({
53648
53904
  * proxy login (preferred: it carries the refresh token + lets the session
53649
53905
  * auto-refresh). This is the primary auth input.
53650
53906
  */
53651
- cookie: string().default("").describe("Captured Alexa cookie / cookieData blob (from proxy login)"),
53907
+ cookie: string().default("").describe("Captured Alexa cookie / cookieData blob (from proxy login)").meta({ secret: true }),
53652
53908
  /**
53653
53909
  * Refresh token. NOTE: a bare refresh token alone is NOT sufficient to init
53654
53910
  * alexa-remote2 — supply the full cookie / cookieData blob (which embeds it).
53655
53911
  * Retained for provenance / forward-compat.
53656
53912
  */
53657
- refreshToken: string().default("").describe("Alexa refresh token (must be inside cookie blob)"),
53913
+ refreshToken: string().default("").describe("Alexa refresh token (must be inside cookie blob)").meta({ secret: true }),
53658
53914
  /** Device-registration secret some flows need. */
53659
53915
  macDms: string().default("").describe("macDms device-registration secret (optional)"),
53660
53916
  /** Poll interval for state sync (Alexa has no clean 3rd-party push). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-import-alexa",
3
- "version": "0.2.120",
3
+ "version": "0.2.122",
4
4
  "description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
5
5
  "keywords": [
6
6
  "camstack",