@camstack/addon-post-analysis 1.2.55 → 1.2.58

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.
@@ -5,6 +5,15 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __exportAll = (all, no_symbols) => {
9
+ let target = {};
10
+ for (var name in all) __defProp(target, name, {
11
+ get: all[name],
12
+ enumerable: true
13
+ });
14
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
15
+ return target;
16
+ };
8
17
  var __copyProps = (to, from, except, desc) => {
9
18
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
19
  key = keys[i];
@@ -7307,6 +7316,104 @@ object({
7307
7316
  })
7308
7317
  });
7309
7318
  /**
7319
+ * Adoption job — the background form of `device-adoption.adopt`.
7320
+ *
7321
+ * ## Why this exists
7322
+ *
7323
+ * `adopt({childNativeIds: [...]})` materialises one CamStack device per
7324
+ * candidate PLUS every accessory child, and the whole array shares ONE UDS
7325
+ * request deadline (60s). Measured on the live hub against Home Assistant:
7326
+ * each device the kernel creates costs ~450 ms — `devices.create` pre-seeds
7327
+ * meta with up to eleven SEQUENTIAL round trips (`setName`, `setType`,
7328
+ * `setRole`, … `persistConfig`) before the class is constructed — and an
7329
+ * accessory child costs the same as its parent. So the real unit of work is
7330
+ * the CHILD, not the candidate:
7331
+ *
7332
+ * - 25 candidates averaging 6 children → ~150 devices → **>60s, times out**
7333
+ * - ONE candidate with 217 children → ~217 devices → **>60s, times out**
7334
+ *
7335
+ * That second line is why this is a job and not a smaller batch. No chunking,
7336
+ * no bounded concurrency over candidates and no per-call tuning can fix a
7337
+ * shape where **N=1 already exceeds the deadline** — the count that blows the
7338
+ * budget is the source system's accessory fan-out, which the operator does not
7339
+ * choose and cannot see. A design that only works below some N is the same bug
7340
+ * deferred.
7341
+ *
7342
+ * ## What the timeout did NOT do
7343
+ *
7344
+ * It did not stop the work. The UDS deadline ends the CALLER's wait; the
7345
+ * provider's loop runs to completion. Measured: a 25-candidate adopt that
7346
+ * "failed" at 60s had adopted 17 by 87s and all 25 by ~130s. The operator saw
7347
+ * an error and had no way to learn that. Every field below exists so that
7348
+ * question has an answer.
7349
+ *
7350
+ * ## Idempotency
7351
+ *
7352
+ * Jobs are in-RAM; a restart forgets them. That is safe here because adoption
7353
+ * is keyed by a stable id (`ha:<broker>:dev:<nativeId>` and equivalents), so
7354
+ * re-running a job re-adopts nothing: an already-adopted candidate is SKIPPED
7355
+ * by the engine before any provider call and lands in `alreadyAdopted`. It is
7356
+ * never a duplicate device, and never an error the operator has to interpret.
7357
+ */
7358
+ var AdoptionJobStateSchema = _enum([
7359
+ "running",
7360
+ "done",
7361
+ "failed",
7362
+ "cancelled"
7363
+ ]);
7364
+ /**
7365
+ * Per-candidate result. Every candidate the job was asked to adopt ends in
7366
+ * exactly one of these buckets — there is no silent drop, and the operator can
7367
+ * always answer "which of my 25 landed?".
7368
+ *
7369
+ * - `adopted` — created now by this job.
7370
+ * - `already-adopted` — a device for this candidate existed before the job
7371
+ * reached it (a re-run, or a retry after a timeout). Not an error.
7372
+ * - `failed` — the provider threw; `error` carries the message.
7373
+ * - `cancelled` — the operator cancelled before this candidate was reached.
7374
+ */
7375
+ var AdoptionOutcomeSchema = _enum([
7376
+ "adopted",
7377
+ "already-adopted",
7378
+ "failed",
7379
+ "cancelled"
7380
+ ]);
7381
+ var AdoptionCandidateResultSchema = object({
7382
+ childNativeId: string(),
7383
+ outcome: AdoptionOutcomeSchema,
7384
+ /** The materialised parent device id — null for `failed` / `cancelled`. */
7385
+ parentDeviceId: number().int().nonnegative().nullable(),
7386
+ /** Accessory children created for this candidate. */
7387
+ accessoryCount: number().int().nonnegative(),
7388
+ /** Failure message; null unless `outcome === 'failed'`. */
7389
+ error: string().nullable()
7390
+ });
7391
+ var AdoptionJobSchema = object({
7392
+ jobId: string(),
7393
+ /** The integration provider this job adopts through (the `addonId` pin). */
7394
+ addonId: string(),
7395
+ integrationId: string(),
7396
+ state: AdoptionJobStateSchema,
7397
+ /** Candidates the job was asked to adopt. Known up front, so never null. */
7398
+ total: number().int().nonnegative(),
7399
+ /** Candidates that have reached a terminal bucket. */
7400
+ processed: number().int().nonnegative(),
7401
+ adopted: number().int().nonnegative(),
7402
+ alreadyAdopted: number().int().nonnegative(),
7403
+ failed: number().int().nonnegative(),
7404
+ /** Accessory child devices created across every candidate — the real unit
7405
+ * of work, surfaced so a slow job is legible rather than mysterious. */
7406
+ accessoriesCreated: number().int().nonnegative(),
7407
+ /** The candidate currently being adopted; null when idle or finished. */
7408
+ currentChildNativeId: string().nullable(),
7409
+ /** One entry per candidate, in the order they were processed. */
7410
+ results: array(AdoptionCandidateResultSchema).readonly(),
7411
+ startedAt: number(),
7412
+ finishedAt: number().nullable(),
7413
+ /** Set only when the job itself broke (not a per-candidate failure). */
7414
+ error: string().nullable()
7415
+ });
7416
+ /**
7310
7417
  * Per-camera FUNCTION SWITCHES — the one coherent on/off surface over the
7311
7418
  * pipeline functions an operator thinks in terms of.
7312
7419
  *
@@ -12219,6 +12326,15 @@ method(object({
12219
12326
  }), method(ReleaseInputSchema.extend({ addonId: string() }), _void(), {
12220
12327
  kind: "mutation",
12221
12328
  auth: "admin"
12329
+ }), method(AdoptInputSchema.extend({ addonId: string() }), object({ jobId: string() }), {
12330
+ kind: "mutation",
12331
+ auth: "admin"
12332
+ }), method(object({
12333
+ addonId: string(),
12334
+ integrationId: string().optional()
12335
+ }), array(AdoptionJobSchema).readonly(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
12336
+ kind: "mutation",
12337
+ auth: "admin"
12222
12338
  }), method(ResyncInputSchema, ResyncResultSchema, {
12223
12339
  kind: "mutation",
12224
12340
  auth: "admin"
@@ -15591,6 +15707,76 @@ object({
15591
15707
  * Each provider returns a static descriptor; the core enumerates them
15592
15708
  * to validate the `integration=` query param and resolve the consent
15593
15709
  * label + the scopes baked into the issued token.
15710
+ *
15711
+ * ## Declaring one
15712
+ *
15713
+ * An OAuth client is integration-specific knowledge — who the client is, what
15714
+ * it may ask for, where it may be sent — so it is declared by the ADDON that
15715
+ * owns the integration, never by the kernel and never as a branch inside
15716
+ * `oauth2-routes.ts` ([D101](../../../../docs/decisions/adr-0101.md)). Three
15717
+ * steps, no others:
15718
+ *
15719
+ * 1. Add `{ "name": "oauth-integration" }` to the addon's `camstack.addons[]`
15720
+ * manifest entry. This is also what tells the hub, at addon-LOAD time, that
15721
+ * a descriptor is owed — see "the boot window" below.
15722
+ * 2. Return a provider from `onInitialize()`:
15723
+ *
15724
+ * ```ts
15725
+ * const provider: IOauthIntegrationProvider = {
15726
+ * getDescriptor: async () => ({
15727
+ * integrationId: 'my-thing', // the `integration=` query param
15728
+ * displayName: 'My Thing',
15729
+ * requestedScopes: [ … ], // see below
15730
+ * allowedRedirectPrefixes: ['https://callback.example/'],
15731
+ * }),
15732
+ * }
15733
+ * return [{ capability: oauthIntegrationCapability, provider }]
15734
+ * ```
15735
+ *
15736
+ * The descriptor must be **static** — it is read on the authorize path, so
15737
+ * never put an await on network or disk behind it, and never register it
15738
+ * behind one either (a provider is registered only once `onInitialize`
15739
+ * RETURNS, so anything awaited before the return delays linking).
15740
+ * 3. Nothing else. There is no allow-list to join, no id to register with the
15741
+ * core, and no per-integration branch anywhere: `/api/oauth2/authorize` and
15742
+ * `/api/oauth2/integrations` are built from this collection alone.
15743
+ *
15744
+ * **Scopes. `requestedScopes` has exactly ONE meaning: what the integration
15745
+ * NEEDS to function.** Not a blast radius, not a conservative
15746
+ * under-declaration, not a description of some other path the addon happens to
15747
+ * have. Derive it from what the client actually calls **with this token** —
15748
+ * every tRPC path against `METHOD_ACCESS_MAP`, plus an `addon:` grant for every
15749
+ * addon HTTP route it posts to — and write the call that justifies each entry
15750
+ * next to it. Two integrations once used this field to mean two different
15751
+ * things; the operator ruled there is one meaning, and any third integration
15752
+ * inherits it (2026-08-09).
15753
+ *
15754
+ * This is not documentation, it is the ENFORCEMENT INPUT. Since
15755
+ * [D103](../../../../docs/decisions/adr-0103.md) the `/addon/:addonId/*` gate
15756
+ * checks an integration token's grant before letting it reach an
15757
+ * `access: 'authenticated'` route, so an **under-declaration is an integration
15758
+ * that stops working** — a missing `addon:` entry means `403 Token scope
15759
+ * mismatch` on every control the client tries to actuate. Widen the descriptor
15760
+ * honestly rather than weakening a check to make a route pass.
15761
+ *
15762
+ * Prefer a narrow `capability:` scope to a `category:` one unless the client
15763
+ * genuinely needs a whole family; a category scope grants every future member
15764
+ * of that category too. `category:system [create]` has been rejected once and
15765
+ * should stay rejected: it hands `addons.installPackage` to an integration.
15766
+ *
15767
+ * Calls the ADDON itself makes over `ctx.api` run as the addon and are not
15768
+ * scope-checked, so they are not what this field describes — but reaching the
15769
+ * addon's route in the first place IS, and that is the entry to declare.
15770
+ *
15771
+ * **The boot window.** An addon registers its provider after its runner forks
15772
+ * and initialises, so between hub start and that moment this collection is
15773
+ * incomplete and an `integrationId` can be legitimately absent. The core does
15774
+ * not wait, poll or cache around this ([D3](../../../../docs/decisions/adr-0003.md)):
15775
+ * it compares the manifest declarers against the registered providers and
15776
+ * answers `503 temporarily_unavailable` (with `Retry-After` and the pending
15777
+ * addon ids) instead of `400 unknown integration`, and reports
15778
+ * `complete: false` on `GET /api/oauth2/integrations`. A client should retry
15779
+ * while the list is incomplete rather than conclude the hub cannot do OAuth.
15594
15780
  */
15595
15781
  var OauthIntegrationDescriptorSchema = object({
15596
15782
  /** Stable id used as the `integration=` query param, e.g. 'export-alexa'. */
@@ -15621,7 +15807,30 @@ var OauthIntegrationDescriptorSchema = object({
15621
15807
  * present, /api/oauth2/authorize bakes THIS into the code instead of the
15622
15808
  * hub-global `publicHubUrl()`, so a forked exporter addon (which can't set
15623
15809
  * the hub's env) drives the claim that its cloud Lambda routes back on. */
15624
- hubUrl: string().optional()
15810
+ hubUrl: string().optional(),
15811
+ /**
15812
+ * How long a REFRESH token issued for this integration lives — seconds, or
15813
+ * `'never'` for a token minted with no `exp` claim at all. Omit to keep the
15814
+ * 30-day default, which is what every link used before this field existed.
15815
+ *
15816
+ * Declared here for the same reason `requestedScopes` is: the integration
15817
+ * knows what it needs. Amazon's account linking and a Home Assistant config
15818
+ * entry are both meant to survive indefinitely, and re-linking is a manual
15819
+ * user action, so a 30-day expiry silently unlinks a working integration.
15820
+ *
15821
+ * **The security posture, stated so it is owned deliberately.** A refresh
15822
+ * token that never expires is permanent access if it leaks. What bounds it is
15823
+ * revocation, not time: `oauthRefresh` re-reads the session on every use and
15824
+ * returns `null` once `revokedAt` is set, as does `oauthVerifyAccessToken`.
15825
+ * The one gap is the ACCESS token — it is a plain signed JWT that nothing
15826
+ * re-checks against the session on the `/trpc` and `/addon/*` paths, so
15827
+ * revoking a link takes effect there only after its remaining hour. That hour
15828
+ * is why the access TTL is not configurable.
15829
+ *
15830
+ * The value is baked into the authorization code at `/authorize` and travels
15831
+ * on the tokens, so editing this field changes FUTURE links only.
15832
+ */
15833
+ refreshTokenTtlSec: union([number().int().positive(), literal("never")]).optional()
15625
15834
  });
15626
15835
  method(_void(), OauthIntegrationDescriptorSchema);
15627
15836
  /**
@@ -19103,6 +19312,37 @@ DeviceType.Camera, method(object({
19103
19312
  lastCapturedAt: number().nullable(),
19104
19313
  cacheAgeMs: number().nullable(),
19105
19314
  etag: string().nullable()
19315
+ }))), systemMethod(object({
19316
+ /** The tiles a surface is actually rendering. One entry per (device,
19317
+ * width) the caller will paint — the width is snapped to the server's
19318
+ * ladder and becomes part of the link's SIGNED identity. */
19319
+ targets: array(object({
19320
+ deviceId: number(),
19321
+ /** Target width in px. Omit for the frame as captured — correct
19322
+ * for a full-bleed surface, wrong (and expensive) for a grid. */
19323
+ width: number().int().positive().optional()
19324
+ })).min(1).max(200) }), array(object({
19325
+ deviceId: number(),
19326
+ /** Root-relative signed path, or null when the link plane is not
19327
+ * served (no data-plane facility). Present even for a device that has
19328
+ * never captured — the request is what triggers the first one (D94). */
19329
+ url: string().nullable(),
19330
+ /** Epoch ms of the frame this link serves. Null = never captured.
19331
+ * THE honest age: the tRPC path carried none before this. */
19332
+ capturedAt: number().nullable(),
19333
+ /** Age of that frame at the moment the answer was built. */
19334
+ ageMs: number().nullable(),
19335
+ /** Epoch ms after which `url` stops verifying. */
19336
+ expiresAt: number().nullable(),
19337
+ /** Ladder rung the bytes are at; null = the frame as captured. */
19338
+ width: number().nullable(),
19339
+ /** The device has never produced a frame. An empty state, not a
19340
+ * failure — and never a reason to withhold the link (D94). */
19341
+ neverCaptured: boolean(),
19342
+ /** A sleeping battery camera: the frame is deliberately stale and will
19343
+ * NOT refresh in the background. A surface should say so rather than
19344
+ * present it as current. */
19345
+ sleeping: boolean()
19106
19346
  })));
19107
19347
  /**
19108
19348
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
@@ -19148,11 +19388,29 @@ var SsoBridgeClaimsSchema = object({
19148
19388
  codeChallenge: string().optional(),
19149
19389
  /** OAuth session registry id — set on `oauth-access`/`oauth-refresh`
19150
19390
  * tokens so the verify path can check the session is not revoked. */
19151
- sessionId: string().optional()
19391
+ sessionId: string().optional(),
19392
+ /**
19393
+ * The refresh lifetime this LINK was created with, in seconds, or `'never'`.
19394
+ * Baked into the code at `/authorize` from the integration's descriptor and
19395
+ * carried forward so `oauthRefresh` re-mints with the same lifetime. It rides
19396
+ * on the token rather than being re-read from the descriptor on purpose:
19397
+ * editing a descriptor must not retroactively extend or shorten a link the
19398
+ * operator already consented to.
19399
+ */
19400
+ refreshTtl: union([number().int().positive(), literal("never")]).optional()
19152
19401
  });
19153
19402
  method(object({
19154
19403
  claims: SsoBridgeClaimsSchema,
19155
- ttlSec: number().int().positive().optional()
19404
+ /**
19405
+ * Seconds, or `'never'` for a token minted with NO `exp` claim.
19406
+ *
19407
+ * `'never'` is a literal rather than `undefined`/`0` because omitting
19408
+ * this field already means "the 5-minute SSO hand-off default", and
19409
+ * `jwt.sign` THROWS on `{ expiresIn: undefined }` — a "no expiry" that
19410
+ * went through the numeric path would fail at mint time and break
19411
+ * linking rather than produce an eternal token.
19412
+ */
19413
+ ttlSec: union([number().int().positive(), literal("never")]).optional()
19156
19414
  }), object({ token: string() })), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable());
19157
19415
  var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
19158
19416
  providerId: string().min(1),
@@ -21147,6 +21405,37 @@ onColorChanged: { data: object({
21147
21405
  */
21148
21406
  runtimeState: ColorStatusSchema
21149
21407
  };
21408
+ var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
21409
+ object({
21410
+ outcome: literal("validated"),
21411
+ /** Round-trip of the sign-in, when the provider measured it. */
21412
+ latencyMs: number().nonnegative().optional(),
21413
+ /** Optional human detail worth showing next to the tick
21414
+ * ("3 devices visible on this account"). */
21415
+ detail: string().optional()
21416
+ }).strict(),
21417
+ object({
21418
+ outcome: literal("rejected"),
21419
+ error: string()
21420
+ }).strict(),
21421
+ object({
21422
+ outcome: literal("inconclusive"),
21423
+ error: string()
21424
+ }).strict()
21425
+ ]);
21426
+ var ConnectionTestInputSchema = object({
21427
+ /** Candidate integration settings, exactly as the create form collected them. */
21428
+ settings: record(string(), unknown()) });
21429
+ /**
21430
+ * What the provider's test actually DOES, so the UI can say it in words before
21431
+ * the operator presses the button ("Signs in to the Dreo cloud"). Purely
21432
+ * descriptive — it never changes routing.
21433
+ */
21434
+ var ConnectionTestDescriptorSchema = object({ label: string() });
21435
+ method(ConnectionTestInputSchema, ConnectionTestOutcomeSchema, {
21436
+ kind: "mutation",
21437
+ auth: "admin"
21438
+ }), method(_void(), ConnectionTestDescriptorSchema, { auth: "admin" });
21150
21439
  /**
21151
21440
  * Upstream-system connectivity sensor — distinct from `device-status`,
21152
21441
  * which is the kernel-managed online/offline flag for the device's
@@ -22534,15 +22823,57 @@ var AvailableIntegrationTypeSchema = object({
22534
22823
  * flow can import (e.g. HA areas). Drives the adopt modal's "import
22535
22824
  * locations" checkbox. Provider-declared in the addon manifest. */
22536
22825
  supportsLocationImport: boolean(),
22826
+ /**
22827
+ * True when this integration DECLARES a pre-creation test (the
22828
+ * `connection-test` cap, or a broker whose settings it stores). Drives the
22829
+ * Test button: an integration that cannot be tested must say so up front
22830
+ * rather than offering a button that always answers the same nonsense.
22831
+ */
22832
+ canTest: boolean(),
22537
22833
  existingInstances: array(object({
22538
22834
  id: string(),
22539
22835
  name: string()
22540
22836
  })),
22541
22837
  canAdd: boolean()
22542
22838
  });
22839
+ /**
22840
+ * Why a test could not be answered as a plain boolean.
22841
+ *
22842
+ * `success` alone collapsed four different situations into one red box, and the
22843
+ * one that mattered most — "nobody ever asked the remote anything" — looked
22844
+ * exactly like "the remote said no". The status is the discriminator:
22845
+ *
22846
+ * - `validated` — a provider-declared test ran and the remote ACCEPTED.
22847
+ * - `rejected` — a provider-declared test ran and the remote REFUSED.
22848
+ * The only status that blocks `integrations.create`.
22849
+ * - `inconclusive` — a test IS declared but could not complete (timeout,
22850
+ * DNS, 5xx). Nothing was observed; not a failure.
22851
+ * - `unsupported` — this integration declares NO test. Nothing was
22852
+ * observed either; not a failure, and not a pass.
22853
+ *
22854
+ * `unsupported` and `inconclusive` both carry `success: false` so an older
22855
+ * client can never read them as a green tick, and both carry an `error` string
22856
+ * that SAYS the test did not run rather than inventing a failure.
22857
+ */
22858
+ var TestConnectionStatusEnum = _enum([
22859
+ "validated",
22860
+ "rejected",
22861
+ "inconclusive",
22862
+ "unsupported"
22863
+ ]);
22543
22864
  var TestConnectionResultSchema$1 = object({
22865
+ /** True ONLY for `validated`. Never true for a test that did not run. */
22544
22866
  success: boolean(),
22545
- error: string().optional()
22867
+ error: string().optional(),
22868
+ /** Optional for wire back-compat with clients built before the tri-state;
22869
+ * the server always sets it. */
22870
+ status: TestConnectionStatusEnum.optional(),
22871
+ /** Addon id whose declared test answered — `null` when none did. Lets the UI
22872
+ * attribute a result instead of blaming "the integration". */
22873
+ testedBy: string().nullable().optional(),
22874
+ latencyMs: number().nonnegative().optional(),
22875
+ /** Human detail from a `validated` result ("3 devices on this account"). */
22876
+ detail: string().optional()
22546
22877
  });
22547
22878
  var CreateIntegrationInputSchema = object({
22548
22879
  addonId: string(),
@@ -26345,7 +26676,12 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
26345
26676
  hubUrl: string(),
26346
26677
  /** PKCE (RFC 7636) S256 challenge. Baked into the signed code; a code
26347
26678
  * that carries one can ONLY be exchanged with the matching verifier. */
26348
- codeChallenge: string().optional()
26679
+ codeChallenge: string().optional(),
26680
+ /** The integration's declared refresh lifetime — seconds, or `'never'`.
26681
+ * From `OauthIntegrationDescriptor.refreshTokenTtlSec`. Baked into the
26682
+ * code so the link carries its own lifetime; omit for the 30-day
26683
+ * default. */
26684
+ refreshTtlSec: union([number().int().positive(), literal("never")]).optional()
26349
26685
  }), object({ code: string() }), {
26350
26686
  kind: "mutation",
26351
26687
  access: "create"
@@ -28824,6 +29160,18 @@ Object.freeze({
28824
29160
  addonId: null,
28825
29161
  access: "create"
28826
29162
  },
29163
+ "connectionTest.describeTest": {
29164
+ capName: "connection-test",
29165
+ capScope: "system",
29166
+ addonId: null,
29167
+ access: "view"
29168
+ },
29169
+ "connectionTest.testSettings": {
29170
+ capName: "connection-test",
29171
+ capScope: "system",
29172
+ addonId: null,
29173
+ access: "create"
29174
+ },
28827
29175
  "consumables.reset": {
28828
29176
  capName: "consumables",
28829
29177
  capScope: "device",
@@ -29214,6 +29562,12 @@ Object.freeze({
29214
29562
  addonId: null,
29215
29563
  access: "create"
29216
29564
  },
29565
+ "deviceManager.adoptionCancelJob": {
29566
+ capName: "device-manager",
29567
+ capScope: "system",
29568
+ addonId: null,
29569
+ access: "create"
29570
+ },
29217
29571
  "deviceManager.adoptionListCandidateFilters": {
29218
29572
  capName: "device-manager",
29219
29573
  capScope: "system",
@@ -29226,6 +29580,12 @@ Object.freeze({
29226
29580
  addonId: null,
29227
29581
  access: "view"
29228
29582
  },
29583
+ "deviceManager.adoptionListJobs": {
29584
+ capName: "device-manager",
29585
+ capScope: "system",
29586
+ addonId: null,
29587
+ access: "view"
29588
+ },
29229
29589
  "deviceManager.adoptionRefresh": {
29230
29590
  capName: "device-manager",
29231
29591
  capScope: "system",
@@ -29244,6 +29604,12 @@ Object.freeze({
29244
29604
  addonId: null,
29245
29605
  access: "create"
29246
29606
  },
29607
+ "deviceManager.adoptionStartJob": {
29608
+ capName: "device-manager",
29609
+ capScope: "system",
29610
+ addonId: null,
29611
+ access: "create"
29612
+ },
29247
29613
  "deviceManager.allocateDeviceId": {
29248
29614
  capName: "device-manager",
29249
29615
  capScope: "system",
@@ -32382,6 +32748,12 @@ Object.freeze({
32382
32748
  addonId: null,
32383
32749
  access: "view"
32384
32750
  },
32751
+ "snapshot.getSnapshotLinks": {
32752
+ capName: "snapshot",
32753
+ capScope: "device",
32754
+ addonId: null,
32755
+ access: "view"
32756
+ },
32385
32757
  "snapshot.getSnapshotOverview": {
32386
32758
  capName: "snapshot",
32387
32759
  capScope: "device",
@@ -33913,6 +34285,12 @@ Object.defineProperty(exports, "TrackSourceSchema", {
33913
34285
  return TrackSourceSchema;
33914
34286
  }
33915
34287
  });
34288
+ Object.defineProperty(exports, "__exportAll", {
34289
+ enumerable: true,
34290
+ get: function() {
34291
+ return __exportAll;
34292
+ }
34293
+ });
33916
34294
  Object.defineProperty(exports, "__toESM", {
33917
34295
  enumerable: true,
33918
34296
  get: function() {