@camstack/addon-provider-tuya 0.2.28 → 0.2.29

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 +249 -79
  2. package/dist/addon.mjs +249 -79
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -7450,7 +7450,7 @@ function method(input, output, options) {
7450
7450
  input,
7451
7451
  output,
7452
7452
  kind: options?.kind ?? "query",
7453
- auth: options?.auth ?? "protected",
7453
+ ...options?.auth !== void 0 ? { auth: options.auth } : {},
7454
7454
  ...options?.access !== void 0 ? { access: options.access } : {},
7455
7455
  ...options?.caller !== void 0 ? { caller: options.caller } : {},
7456
7456
  timeoutMs: options?.timeoutMs
@@ -7474,7 +7474,7 @@ function event(data) {
7474
7474
  }
7475
7475
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
7476
7476
  var VersionOutputSchema$1 = object({ version: string() });
7477
- method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
7477
+ method(_void(), StaticDirOutputSchema$1, { auth: "admin" }), method(_void(), VersionOutputSchema$1, { auth: "admin" });
7478
7478
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
7479
7479
  DeviceType["Camera"] = "camera";
7480
7480
  DeviceType["Hub"] = "hub";
@@ -7795,7 +7795,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
7795
7795
  }({});
7796
7796
  var StaticDirOutputSchema = object({ staticDir: string() });
7797
7797
  var VersionOutputSchema = object({ version: string() });
7798
- method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
7798
+ method(_void(), StaticDirOutputSchema, { auth: "admin" }), method(_void(), VersionOutputSchema, { auth: "admin" });
7799
7799
  /**
7800
7800
  * device-ops — device-scoped cap that unifies the per-IDevice operations
7801
7801
  * previously routed through the `.device-ops` Moleculer bridge service.
@@ -8421,24 +8421,6 @@ var RecordingRetentionSchema = object({
8421
8421
  maxSizeGb: number().min(0).optional()
8422
8422
  });
8423
8423
  /**
8424
- * Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
8425
- * sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
8426
- * previews at. Five graduated steps; absent on a config = `standard` (the
8427
- * shipped default, matching `sheet-geometry`/`sheet-composer`).
8428
- *
8429
- * Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
8430
- * Each window's index sidecar carries its own tile dims, so a camera whose
8431
- * preset changed over time renders every historical window at the dims it was
8432
- * written with.
8433
- */
8434
- var ScrubThumbnailPresetSchema = _enum([
8435
- "minimal",
8436
- "low",
8437
- "standard",
8438
- "high",
8439
- "max"
8440
- ]);
8441
- /**
8442
8424
  * The full per-camera recording intent — the wire shape of a RecordingTarget.
8443
8425
  *
8444
8426
  * `bands` is the ONLY authored recording intent: what to record, when, and on
@@ -8446,7 +8428,11 @@ var ScrubThumbnailPresetSchema = _enum([
8446
8428
  * other field is a storage knob (profiles, segment length, retention, scrub).
8447
8429
  *
8448
8430
  * STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
8449
- * `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
8431
+ * `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30,
8432
+ * and `scrubThumbnails` — a five-step fidelity knob for a sprite tier that was
8433
+ * deleted on 2026-07-24 and had ZERO consumers in the recorder — on 2026-08-25
8434
+ * (D62: a switch that writes a store nobody reads is worse than no switch).
8435
+ * Stored rows keep loading: the READ schema is `.strip()` (config-store.ts).
8450
8436
  * A stale caller must fail loudly — silently stripping its legacy intent would
8451
8437
  * persist a band-less config, i.e. silently stop recording the camera.
8452
8438
  */
@@ -8469,14 +8455,7 @@ var RecordingConfigSchema = object({
8469
8455
  * "off" is the absence of a covering band, never a band value.
8470
8456
  */
8471
8457
  bands: array(RecordingBandSchema).default([]),
8472
- retention: RecordingRetentionSchema.optional(),
8473
- /**
8474
- * Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
8475
- * timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
8476
- * windows only — existing sheets are immutable, and each window's index
8477
- * carries its own tile dims so mixed-preset history renders correctly.
8478
- */
8479
- scrubThumbnails: ScrubThumbnailPresetSchema.optional()
8458
+ retention: RecordingRetentionSchema.optional()
8480
8459
  }).strict();
8481
8460
  /**
8482
8461
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
@@ -8552,10 +8531,11 @@ var RelocateFootageInputSchema = object({
8552
8531
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8553
8532
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8554
8533
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8555
- var StorageMigrationMediaMoveInputSchema = object({
8534
+ var RelocateMediaInputSchema = object({
8556
8535
  toLocationId: string(),
8557
8536
  throttleMbps: number().min(1).max(1e3).optional()
8558
- }).extend({ leaseId: string().min(1) });
8537
+ });
8538
+ var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8559
8539
  /** The independently selectable logical storage classes. `recordings`
8560
8540
  * encompasses the high and mid segment profiles; `recordingsLow` is low
8561
8541
  * segments; `eventMedia` is post-analysis blobs. */
@@ -8850,7 +8830,26 @@ var LabelDefinitionSchema = object({
8850
8830
  description: string().optional(),
8851
8831
  icon: string().optional()
8852
8832
  });
8853
- var ClassMapDefinitionSchema = object({
8833
+ /**
8834
+ * Wire schema for a per-model CATALOG classMap override
8835
+ * (`ModelCatalogEntry.classMap` / `ModelConvertMetadata.classMap`) —
8836
+ * restricted to {@link CLASS_MAP_MACRO_TARGETS}, the only macros the
8837
+ * detection pipeline executor actually routes.
8838
+ *
8839
+ * This is deliberately a DIFFERENT, narrower shape than the general-purpose
8840
+ * `ClassMapDefinition` interface above (e.g. `IDetectionAddon.getClassMap()`
8841
+ * and the audio `YAMNET_TO_MACRO` catalog both use macro targets outside this
8842
+ * enum) — the two used to share the name `ClassMapDefinition`/
8843
+ * `ClassMapDefinitionSchema`, which made the schema-type-twin guard
8844
+ * (`scripts/check-schema-type-twins.ts`) flag them as a duplicated shape. They
8845
+ * are not: it is two different concepts colliding on a name. Keep this type
8846
+ * under its own name rather than reusing `ClassMapDefinition` — reusing it
8847
+ * would either narrow every `ClassMapDefinition` consumer to the four
8848
+ * detection macros (breaking `YAMNET_TO_MACRO`) or drop the validation this
8849
+ * schema exists for (see the "rejects a classMap whose target is not a
8850
+ * detection macro" test in `model-catalog-schema.test.ts`).
8851
+ */
8852
+ var DetectionCatalogClassMapSchema = object({
8854
8853
  mapping: record(string(), _enum([
8855
8854
  "person",
8856
8855
  "vehicle",
@@ -9055,7 +9054,7 @@ var ModelCatalogEntrySchema = object({
9055
9054
  * applies (Frigate / COCO public catalog). Set on a custom model whose raw
9056
9055
  * labels already ARE the CamStack macros (Scrypted identity map).
9057
9056
  */
9058
- classMap: ClassMapDefinitionSchema.optional()
9057
+ classMap: DetectionCatalogClassMapSchema.optional()
9059
9058
  });
9060
9059
  var ConvertTargetSchema = discriminatedUnion("format", [object({
9061
9060
  format: literal("openvino"),
@@ -9085,7 +9084,7 @@ var ModelConvertMetadataSchema = object({
9085
9084
  "segmentation"
9086
9085
  ]),
9087
9086
  faceAlignment: boolean().optional(),
9088
- classMap: ClassMapDefinitionSchema.optional()
9087
+ classMap: DetectionCatalogClassMapSchema.optional()
9089
9088
  });
9090
9089
  var ConvertResultSchema = object({
9091
9090
  entry: ModelCatalogEntrySchema,
@@ -9948,7 +9947,7 @@ var AddonPageDeclarationSchema = object({
9948
9947
  /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
9949
9948
  sectionLabel: string().optional()
9950
9949
  });
9951
- method(_void(), array(AddonPageDeclarationSchema).readonly());
9950
+ method(_void(), array(AddonPageDeclarationSchema).readonly(), { auth: "admin" });
9952
9951
  var AddonHttpRouteSchema = object({
9953
9952
  method: _enum([
9954
9953
  "GET",
@@ -10183,7 +10182,7 @@ var WidgetMetadataSchema = object({
10183
10182
  defaultColumns: number().int().min(1).max(12).default(6),
10184
10183
  defaultRows: number().int().min(1).max(12).default(1)
10185
10184
  });
10186
- method(_void(), array(WidgetMetadataSchema).readonly());
10185
+ method(_void(), array(WidgetMetadataSchema).readonly(), { auth: "admin" });
10187
10186
  /**
10188
10187
  * `addon-widgets` — system-scoped singleton aggregator cap. Public-facing
10189
10188
  * surface that admin-ui consumes through `useAddonWidgetsListWidgets()`.
@@ -11807,7 +11806,7 @@ var CustomModelDescriptorSchema = object({
11807
11806
  stepId: string(),
11808
11807
  entry: ModelCatalogEntrySchema
11809
11808
  });
11810
- method(_void(), array(CustomModelDescriptorSchema).readonly());
11809
+ method(_void(), array(CustomModelDescriptorSchema).readonly(), { auth: "admin" });
11811
11810
  /**
11812
11811
  * Query filter for settings-store collections.
11813
11812
  */
@@ -11894,7 +11893,8 @@ method(object({
11894
11893
  }), _void(), { kind: "mutation" }), method(object({
11895
11894
  namespace: string().optional(),
11896
11895
  collection: string(),
11897
- filter: QueryFilterSchema.optional()
11896
+ filter: QueryFilterSchema.optional(),
11897
+ columns: array(string()).readonly().optional()
11898
11898
  }), array(SettingsRecordSchema).readonly()), method(object({
11899
11899
  namespace: string().optional(),
11900
11900
  collection: string(),
@@ -11957,46 +11957,87 @@ var EngineInfoSchema = object({
11957
11957
  kind: _enum(["relational", "vector"]),
11958
11958
  displayName: string()
11959
11959
  });
11960
- method(_void(), EngineInfoSchema), method(object({
11960
+ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11961
11961
  namespace: string().optional(),
11962
11962
  collection: string(),
11963
11963
  key: string()
11964
- }), unknown()), method(object({
11964
+ }), unknown(), { auth: "admin" }), method(object({
11965
11965
  namespace: string().optional(),
11966
11966
  collection: string(),
11967
11967
  key: string(),
11968
11968
  value: unknown()
11969
- }), _void(), { kind: "mutation" }), method(object({
11969
+ }), _void(), {
11970
+ kind: "mutation",
11971
+ auth: "admin"
11972
+ }), method(object({
11970
11973
  namespace: string().optional(),
11971
11974
  collection: string(),
11972
- filter: QueryFilterSchema.optional()
11973
- }), array(SettingsRecordSchema).readonly()), method(object({
11975
+ filter: QueryFilterSchema.optional(),
11976
+ /**
11977
+ * SQL-level column projection — MUST mirror `settings-store.query`.
11978
+ *
11979
+ * ⚠ An earlier version of this comment blamed Zod stripping, and that
11980
+ * was wrong — corrected 2026-08-26 after the hop map
11981
+ * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
11982
+ * There is **no Zod parse at all** between the door and the engine: the
11983
+ * dispatcher forwards the payload verbatim and UDS carries it whole. A
11984
+ * field declared here reaches `SqliteSettingsBackend` either way.
11985
+ *
11986
+ * What actually lost `columns` was the THIRD declaration of this shape:
11987
+ * `SettingsQueryInput` in `interfaces/storage.ts`, a hand-written TS
11988
+ * interface the engine destructures from. The field existed on both
11989
+ * schemas and the engine still never read it, because nothing checks a
11990
+ * registered provider against `InferProvider<cap>` —
11991
+ * `ProviderRegistration.provider` is typed `object`.
11992
+ *
11993
+ * It is declared here anyway, and must stay in step with
11994
+ * `settings-store.query`: a caller reading only the cap definitions has
11995
+ * to be able to see that this call carries a projection.
11996
+ * `data-door-schema-parity.spec.ts` keeps the two aligned.
11997
+ */
11998
+ columns: array(string()).readonly().optional()
11999
+ }), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
11974
12000
  namespace: string().optional(),
11975
12001
  collection: string(),
11976
12002
  record: SettingsRecordSchema
11977
- }), _void(), { kind: "mutation" }), method(object({
12003
+ }), _void(), {
12004
+ kind: "mutation",
12005
+ auth: "admin"
12006
+ }), method(object({
11978
12007
  namespace: string().optional(),
11979
12008
  collection: string(),
11980
12009
  id: string(),
11981
12010
  data: record(string(), unknown())
11982
- }), _void(), { kind: "mutation" }), method(object({
12011
+ }), _void(), {
12012
+ kind: "mutation",
12013
+ auth: "admin"
12014
+ }), method(object({
11983
12015
  namespace: string().optional(),
11984
12016
  collection: string(),
11985
12017
  key: string()
11986
- }), _void(), { kind: "mutation" }), method(object({
12018
+ }), _void(), {
12019
+ kind: "mutation",
12020
+ auth: "admin"
12021
+ }), method(object({
11987
12022
  namespace: string().optional(),
11988
12023
  collection: string(),
11989
12024
  filter: MutationFilterSchema
11990
- }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
12025
+ }), object({ deleted: number().int() }), {
12026
+ kind: "mutation",
12027
+ auth: "admin"
12028
+ }), method(object({
11991
12029
  namespace: string().optional(),
11992
12030
  collection: string(),
11993
12031
  filter: MutationFilterSchema,
11994
12032
  data: record(string(), unknown())
11995
- }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
12033
+ }), object({ updated: number().int() }), {
12034
+ kind: "mutation",
12035
+ auth: "admin"
12036
+ }), method(object({
11996
12037
  namespace: string().optional(),
11997
12038
  collection: string(),
11998
12039
  filter: QueryFilterSchema.optional()
11999
- }), number()), method(object({
12040
+ }), number(), { auth: "admin" }), method(object({
12000
12041
  namespace: string().optional(),
12001
12042
  collection: string(),
12002
12043
  field: string(),
@@ -12006,15 +12047,18 @@ method(_void(), EngineInfoSchema), method(object({
12006
12047
  }), array(object({
12007
12048
  bucket: number().int(),
12008
12049
  count: number().int()
12009
- })).readonly()), method(object({
12050
+ })).readonly(), { auth: "admin" }), method(object({
12010
12051
  namespace: string().optional(),
12011
12052
  collection: string()
12012
- }), boolean()), method(object({
12053
+ }), boolean(), { auth: "admin" }), method(object({
12013
12054
  namespace: string().optional(),
12014
12055
  collection: string(),
12015
12056
  columns: array(CollectionColumnSchema).readonly(),
12016
12057
  indexes: array(CollectionIndexSchema).readonly().optional()
12017
- }), _void(), { kind: "mutation" });
12058
+ }), _void(), {
12059
+ kind: "mutation",
12060
+ auth: "admin"
12061
+ });
12018
12062
  /**
12019
12063
  * shm ring usage stats for a `frameSink: 'shm'` decoder session —
12020
12064
  * exposed via `decoder.getShmStats` so downstream consumers can
@@ -13321,7 +13365,7 @@ method(object({
13321
13365
  crop: _instanceof(Uint8Array),
13322
13366
  width: number(),
13323
13367
  height: number()
13324
- }), EmbeddingResultSchema), method(object({ text: string() }), EmbeddingResultSchema), method(_void(), EmbeddingInfoSchema);
13368
+ }), EmbeddingResultSchema, { auth: "admin" }), method(object({ text: string() }), EmbeddingResultSchema, { auth: "admin" }), method(_void(), EmbeddingInfoSchema, { auth: "admin" });
13325
13369
  /**
13326
13370
  * filesystem-browse — per-node capability for browsing the node's local
13327
13371
  * filesystem. Reads are unconfined (whole filesystem, from `/` down); WRITES
@@ -13614,19 +13658,22 @@ method(LlmGenerateBaseInputSchema.extend({
13614
13658
  runtime: ManagedRuntimeConfigSchema,
13615
13659
  /** The managed profile's timeout, threaded by the hub provider. */
13616
13660
  timeoutMs: number().int().positive().optional()
13617
- }), LlmGenerateResultSchema, { kind: "mutation" }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
13661
+ }), LlmGenerateResultSchema, {
13662
+ kind: "mutation",
13663
+ auth: "admin"
13664
+ }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
13618
13665
  kind: "mutation",
13619
13666
  auth: "admin"
13620
13667
  }), method(object({}), _void(), {
13621
13668
  kind: "mutation",
13622
13669
  auth: "admin"
13623
- }), method(object({}), LlmRuntimeStatusSchema), method(object({ model: ManagedModelRefSchema }), _void(), {
13670
+ }), method(object({}), LlmRuntimeStatusSchema, { auth: "admin" }), method(object({ model: ManagedModelRefSchema }), _void(), {
13624
13671
  kind: "mutation",
13625
13672
  auth: "admin"
13626
13673
  }), method(object({ file: string() }), _void(), {
13627
13674
  kind: "mutation",
13628
13675
  auth: "admin"
13629
- }), method(object({}), array(LlmNodeModelSchema)), method(object({}), LlmRuntimeDiskUsageSchema);
13676
+ }), method(object({}), array(LlmNodeModelSchema), { auth: "admin" }), method(object({}), LlmRuntimeDiskUsageSchema, { auth: "admin" });
13630
13677
  /**
13631
13678
  * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
13632
13679
  * methods concat-fan across providers; single-row methods route to ONE
@@ -17137,7 +17184,7 @@ var OauthIntegrationDescriptorSchema = object({
17137
17184
  */
17138
17185
  refreshTokenTtlSec: union([number().int().positive(), literal("never")]).optional()
17139
17186
  });
17140
- method(_void(), OauthIntegrationDescriptorSchema);
17187
+ method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
17141
17188
  /**
17142
17189
  * pipeline-analytics — device-scoped wrapper cap. Refines raw
17143
17190
  * per-frame detections emitted by the pipeline runner into tracked
@@ -18332,6 +18379,15 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18332
18379
  }), method(object({ jobId: string() }), RelocateJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
18333
18380
  kind: "mutation",
18334
18381
  auth: "admin"
18382
+ }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
18383
+ kind: "mutation",
18384
+ auth: "admin"
18385
+ }), method(object({}), array(RelocateJobSchema).readonly(), {
18386
+ kind: "query",
18387
+ auth: "admin"
18388
+ }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
18389
+ kind: "mutation",
18390
+ auth: "admin"
18335
18391
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
18336
18392
  kind: "query",
18337
18393
  auth: "admin"
@@ -18486,6 +18542,11 @@ object({
18486
18542
  "jpeg"
18487
18543
  ])
18488
18544
  });
18545
+ /**
18546
+ * Process-local frame identity. It is serializable so it can ride an in-process
18547
+ * capability call, but `registryId` deliberately prevents resolution in any
18548
+ * other process or execution group.
18549
+ */
18489
18550
  var FrameRefSchema = object({
18490
18551
  registryId: string().min(1),
18491
18552
  id: string().min(1),
@@ -20691,7 +20752,7 @@ method(object({
20691
20752
  * linking rather than produce an eternal token.
20692
20753
  */
20693
20754
  ttlSec: union([number().int().positive(), literal("never")]).optional()
20694
- }), object({ token: string() })), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable());
20755
+ }), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
20695
20756
  var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
20696
20757
  providerId: string().min(1),
20697
20758
  displayName: string().min(1),
@@ -20786,10 +20847,13 @@ var EvictResultSchema = object({
20786
20847
  /** True when the provider has nothing left it is willing to drop on this location. */
20787
20848
  exhausted: boolean()
20788
20849
  });
20789
- method(object({ locationId: string() }), EvictableUsageSchema), method(object({
20850
+ method(object({ locationId: string() }), EvictableUsageSchema, { auth: "admin" }), method(object({
20790
20851
  locationId: string(),
20791
20852
  targetBytes: number().int().positive()
20792
- }), EvictResultSchema, { kind: "mutation" });
20853
+ }), EvictResultSchema, {
20854
+ kind: "mutation",
20855
+ auth: "admin"
20856
+ });
20793
20857
  method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin" }), method(StorageMigrationInputSchema, object({ jobId: string() }), {
20794
20858
  kind: "mutation",
20795
20859
  auth: "admin"
@@ -20849,26 +20913,50 @@ var ReadChunkInputSchema = object({
20849
20913
  length: number()
20850
20914
  });
20851
20915
  var EndDownloadInputSchema = object({ downloadId: string() });
20852
- method(_void(), ProviderInfoSchema), method(object({ config: record(string(), unknown()) }), TestLocationResultSchema, { auth: "admin" }), method(object({
20916
+ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config: record(string(), unknown()) }), TestLocationResultSchema, { auth: "admin" }), method(object({
20853
20917
  location: StorageLocationSchema,
20854
20918
  relativePath: string()
20855
- }), string()), method(object({
20919
+ }), string(), { auth: "admin" }), method(object({
20856
20920
  location: StorageLocationSchema,
20857
20921
  relativePath: string(),
20858
20922
  data: _instanceof(Uint8Array)
20859
- }), _void(), { kind: "mutation" }), method(object({
20923
+ }), _void(), {
20924
+ kind: "mutation",
20925
+ auth: "admin"
20926
+ }), method(object({
20860
20927
  location: StorageLocationSchema,
20861
20928
  relativePath: string()
20862
- }), _instanceof(Uint8Array)), method(object({
20929
+ }), _instanceof(Uint8Array), { auth: "admin" }), method(object({
20863
20930
  location: StorageLocationSchema,
20864
20931
  relativePath: string()
20865
- }), boolean()), method(object({
20932
+ }), boolean(), { auth: "admin" }), method(object({
20866
20933
  location: StorageLocationSchema,
20867
20934
  prefix: string().optional()
20868
- }), array(string()).readonly()), method(object({
20935
+ }), array(string()).readonly(), { auth: "admin" }), method(object({
20869
20936
  location: StorageLocationSchema,
20870
20937
  relativePath: string()
20871
- }), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
20938
+ }), _void(), {
20939
+ kind: "mutation",
20940
+ auth: "admin"
20941
+ }), method(object({ location: StorageLocationSchema }), number().nullable(), { auth: "admin" }), method(BeginUploadInputSchema, BeginUploadResultSchema, {
20942
+ kind: "mutation",
20943
+ auth: "admin"
20944
+ }), method(WriteChunkInputSchema, _void(), {
20945
+ kind: "mutation",
20946
+ auth: "admin"
20947
+ }), method(FinalizeUploadInputSchema, _void(), {
20948
+ kind: "mutation",
20949
+ auth: "admin"
20950
+ }), method(AbortUploadInputSchema, _void(), {
20951
+ kind: "mutation",
20952
+ auth: "admin"
20953
+ }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, {
20954
+ kind: "mutation",
20955
+ auth: "admin"
20956
+ }), method(ReadChunkInputSchema, _instanceof(Uint8Array), { auth: "admin" }), method(EndDownloadInputSchema, _void(), {
20957
+ kind: "mutation",
20958
+ auth: "admin"
20959
+ });
20872
20960
  /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20873
20961
  var ProfileSettingsSchemaBridge = unknown().nullable();
20874
20962
  var ProfileSettingsBagSchema = record(string(), unknown());
@@ -21126,7 +21214,8 @@ method(object({
21126
21214
  access: "create"
21127
21215
  }), method(object({ userId: string().optional() }), object({ optionsJSON: record(string(), unknown()) }), {
21128
21216
  kind: "mutation",
21129
- access: "view"
21217
+ access: "view",
21218
+ auth: "admin"
21130
21219
  }), method(object({
21131
21220
  /** Required — the user the assertion belongs to (verified). */
21132
21221
  userId: string(),
@@ -21134,10 +21223,12 @@ method(object({
21134
21223
  response: record(string(), unknown())
21135
21224
  }), object({ verified: boolean() }), {
21136
21225
  kind: "mutation",
21137
- access: "view"
21226
+ access: "view",
21227
+ auth: "admin"
21138
21228
  }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
21139
21229
  kind: "mutation",
21140
- access: "view"
21230
+ access: "view",
21231
+ auth: "admin"
21141
21232
  }), method(object({
21142
21233
  /** AuthenticationResponseJSON from the browser. */
21143
21234
  response: record(string(), unknown()) }), object({
@@ -21145,7 +21236,8 @@ response: record(string(), unknown()) }), object({
21145
21236
  userId: string().nullable()
21146
21237
  }), {
21147
21238
  kind: "mutation",
21148
- access: "view"
21239
+ access: "view",
21240
+ auth: "admin"
21149
21241
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
21150
21242
  userId: string(),
21151
21243
  credentialId: string()
@@ -21317,7 +21409,19 @@ var VectorStatsResultSchema = object({
21317
21409
  /** False when the backend ranks approximately. */
21318
21410
  exact: boolean()
21319
21411
  });
21320
- method(VectorDeclareIndexInputSchema, _void(), { kind: "mutation" }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, { kind: "mutation" }), method(VectorQueryInputSchema, VectorQueryResultSchema), method(VectorGetInputSchema, VectorGetResultSchema), method(VectorDeleteInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorStatsInputSchema, VectorStatsResultSchema);
21412
+ method(VectorDeclareIndexInputSchema, _void(), {
21413
+ kind: "mutation",
21414
+ auth: "admin"
21415
+ }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, {
21416
+ kind: "mutation",
21417
+ auth: "admin"
21418
+ }), method(VectorQueryInputSchema, VectorQueryResultSchema, { auth: "admin" }), method(VectorGetInputSchema, VectorGetResultSchema, { auth: "admin" }), method(VectorDeleteInputSchema, VectorDeleteResultSchema, {
21419
+ kind: "mutation",
21420
+ auth: "admin"
21421
+ }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, {
21422
+ kind: "mutation",
21423
+ auth: "admin"
21424
+ }), method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" });
21321
21425
  var ClipSchema = object({
21322
21426
  /** Opaque, provider-namespaced id. The default provider encodes the time
21323
21427
  * window so `getClipPlayback` is self-contained (no event re-query). */
@@ -23778,7 +23882,27 @@ var MediaFileLiteSchema$1 = object({
23778
23882
  sizeBytes: number(),
23779
23883
  timestamp: number()
23780
23884
  });
23781
- method(_void(), array(IdentitySchema).readonly()), method(object({ name: string().min(1) }), IdentitySchema, {
23885
+ method(object({
23886
+ /**
23887
+ * Inline {@link IdentitySchema.coverBase64} on every row.
23888
+ *
23889
+ * Default `false`, the same inversion `listRecentFaces` and
23890
+ * `listPlates` took on 2026-08-25 (see `include-crops-default.ts` for
23891
+ * why the burden belongs on the caller that WANTS the bytes). Measured
23892
+ * on the live hub the same day: four identities cost 40,979 B with the
23893
+ * covers inline, ~10 KB of base64 per row, on a query this UI mounts
23894
+ * four times and the viewer holds at `staleTime: 30_000`.
23895
+ *
23896
+ * Nothing loses its avatar: `coverMediaKey` is already on every row and
23897
+ * the `event-media` plane serves that key `immutable` with an ETag.
23898
+ *
23899
+ * **This is an INPUT field, so it does not reach the addon until the
23900
+ * next train** — the hub router validates cap inputs against its own
23901
+ * compiled Zod and strips a key it does not know. Until then the
23902
+ * provider sees `undefined`, which resolves to `false`: the cheap shape
23903
+ * is what ships, and the opt-in becomes reachable when the train lands.
23904
+ */
23905
+ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly()), method(object({ name: string().min(1) }), IdentitySchema, {
23782
23906
  kind: "mutation",
23783
23907
  auth: "admin"
23784
23908
  }), method(object({
@@ -26668,8 +26792,10 @@ var PlateInfoSchema = object({
26668
26792
  keyFrameMediaKey: string().optional(),
26669
26793
  base64: string().optional(),
26670
26794
  /**
26671
- * Same crop as a data-plane URL. `getPlateByTrack` returns this and
26672
- * never inlines JPEG; `listPlates` still inlines for the admin-ui.
26795
+ * Same crop as a data-plane URL, always present when the plate has a stored
26796
+ * crop. `getPlateByTrack` returns this and never inlines JPEG; `listPlates`
26797
+ * and `searchPlates` inline the crop only when their `includeCrops` input is
26798
+ * left at its `true` default.
26673
26799
  */
26674
26800
  cropUrl: string().optional()
26675
26801
  });
@@ -26689,14 +26815,34 @@ var PlateClusterSchema = object({
26689
26815
  });
26690
26816
  method(object({
26691
26817
  deviceId: number().int().optional(),
26692
- limit: number().int().positive().optional()
26818
+ limit: number().int().positive().optional(),
26819
+ /**
26820
+ * Inline the base64 crop on every row. Default `true` — the existing
26821
+ * behaviour, kept so no caller breaks.
26822
+ *
26823
+ * Set `false` once the caller renders {@link PlateInfo.cropUrl}.
26824
+ * Measured on the live hub at the 500 rows the Plates view asks for:
26825
+ * 879,403 B and 27.7 s with the crops inline, against a few KiB of
26826
+ * metadata without them — and the browser then caches the images.
26827
+ *
26828
+ * This is the plate twin of `faceGallery.listRecentFaces`'s option;
26829
+ * plates were the one gallery list left without it.
26830
+ *
26831
+ * **This is an INPUT field, so it does not reach the addon until the
26832
+ * next train.** The hub router validates cap inputs against its own
26833
+ * compiled Zod and strips a key it does not know. Until the train
26834
+ * ships, sending `false` is harmless and keeps the crops inline.
26835
+ */
26836
+ includeCrops: boolean().optional()
26693
26837
  }).optional(), array(PlateInfoSchema).readonly()), method(object({
26694
26838
  deviceId: number().int(),
26695
26839
  trackId: string()
26696
26840
  }), PlateInfoSchema.nullable()), method(object({ plateId: string() }), array(MediaFileLiteSchema).readonly()), method(object({
26697
26841
  text: string().min(1),
26698
26842
  maxDistance: number().int().min(0).optional(),
26699
- limit: number().int().positive().optional()
26843
+ limit: number().int().positive().optional(),
26844
+ /** See `listPlates.includeCrops`. Default `true`. */
26845
+ includeCrops: boolean().optional()
26700
26846
  }), array(PlateInfoSchema).readonly()), method(object({
26701
26847
  maxDistance: number().int().min(0).optional(),
26702
26848
  minClusterSize: number().int().min(2).optional(),
@@ -26710,7 +26856,13 @@ method(object({
26710
26856
  }), method(object({ plateId: string() }), _void(), {
26711
26857
  kind: "mutation",
26712
26858
  auth: "admin"
26713
- }), method(_void(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
26859
+ }), method(object({
26860
+ /** Inline {@link VehicleSchema.coverBase64} on every row. Default
26861
+ * `false` — the vehicle twin of `faceGallery.listIdentities`'s
26862
+ * option; `coverMediaKey` + the `event-media` plane carry the picture.
26863
+ * INPUT field: stripped by the hub router until the train ships, which
26864
+ * resolves to `false` and is exactly the intended default. */
26865
+ includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
26714
26866
  kind: "mutation",
26715
26867
  auth: "admin"
26716
26868
  }), method(object({
@@ -33971,6 +34123,12 @@ Object.freeze({
33971
34123
  addonId: null,
33972
34124
  access: "create"
33973
34125
  },
34126
+ "pipelineAnalytics.cancelRelocateMedia": {
34127
+ capName: "pipeline-analytics",
34128
+ capScope: "device",
34129
+ addonId: null,
34130
+ access: "create"
34131
+ },
33974
34132
  "pipelineAnalytics.cancelStorageMigrationMove": {
33975
34133
  capName: "pipeline-analytics",
33976
34134
  capScope: "device",
@@ -34145,6 +34303,12 @@ Object.freeze({
34145
34303
  addonId: null,
34146
34304
  access: "view"
34147
34305
  },
34306
+ "pipelineAnalytics.listRelocateMediaJobs": {
34307
+ capName: "pipeline-analytics",
34308
+ capScope: "device",
34309
+ addonId: null,
34310
+ access: "view"
34311
+ },
34148
34312
  "pipelineAnalytics.listRetrainAnnotations": {
34149
34313
  capName: "pipeline-analytics",
34150
34314
  capScope: "device",
@@ -34223,6 +34387,12 @@ Object.freeze({
34223
34387
  addonId: null,
34224
34388
  access: "create"
34225
34389
  },
34390
+ "pipelineAnalytics.relocateMedia": {
34391
+ capName: "pipeline-analytics",
34392
+ capScope: "device",
34393
+ addonId: null,
34394
+ access: "create"
34395
+ },
34226
34396
  "pipelineAnalytics.restageRetrainTrack": {
34227
34397
  capName: "pipeline-analytics",
34228
34398
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -7449,7 +7449,7 @@ function method(input, output, options) {
7449
7449
  input,
7450
7450
  output,
7451
7451
  kind: options?.kind ?? "query",
7452
- auth: options?.auth ?? "protected",
7452
+ ...options?.auth !== void 0 ? { auth: options.auth } : {},
7453
7453
  ...options?.access !== void 0 ? { access: options.access } : {},
7454
7454
  ...options?.caller !== void 0 ? { caller: options.caller } : {},
7455
7455
  timeoutMs: options?.timeoutMs
@@ -7473,7 +7473,7 @@ function event(data) {
7473
7473
  }
7474
7474
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
7475
7475
  var VersionOutputSchema$1 = object({ version: string() });
7476
- method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
7476
+ method(_void(), StaticDirOutputSchema$1, { auth: "admin" }), method(_void(), VersionOutputSchema$1, { auth: "admin" });
7477
7477
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
7478
7478
  DeviceType["Camera"] = "camera";
7479
7479
  DeviceType["Hub"] = "hub";
@@ -7794,7 +7794,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
7794
7794
  }({});
7795
7795
  var StaticDirOutputSchema = object({ staticDir: string() });
7796
7796
  var VersionOutputSchema = object({ version: string() });
7797
- method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
7797
+ method(_void(), StaticDirOutputSchema, { auth: "admin" }), method(_void(), VersionOutputSchema, { auth: "admin" });
7798
7798
  /**
7799
7799
  * device-ops — device-scoped cap that unifies the per-IDevice operations
7800
7800
  * previously routed through the `.device-ops` Moleculer bridge service.
@@ -8420,24 +8420,6 @@ var RecordingRetentionSchema = object({
8420
8420
  maxSizeGb: number().min(0).optional()
8421
8421
  });
8422
8422
  /**
8423
- * Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
8424
- * sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
8425
- * previews at. Five graduated steps; absent on a config = `standard` (the
8426
- * shipped default, matching `sheet-geometry`/`sheet-composer`).
8427
- *
8428
- * Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
8429
- * Each window's index sidecar carries its own tile dims, so a camera whose
8430
- * preset changed over time renders every historical window at the dims it was
8431
- * written with.
8432
- */
8433
- var ScrubThumbnailPresetSchema = _enum([
8434
- "minimal",
8435
- "low",
8436
- "standard",
8437
- "high",
8438
- "max"
8439
- ]);
8440
- /**
8441
8423
  * The full per-camera recording intent — the wire shape of a RecordingTarget.
8442
8424
  *
8443
8425
  * `bands` is the ONLY authored recording intent: what to record, when, and on
@@ -8445,7 +8427,11 @@ var ScrubThumbnailPresetSchema = _enum([
8445
8427
  * other field is a storage knob (profiles, segment length, retention, scrub).
8446
8428
  *
8447
8429
  * STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
8448
- * `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
8430
+ * `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30,
8431
+ * and `scrubThumbnails` — a five-step fidelity knob for a sprite tier that was
8432
+ * deleted on 2026-07-24 and had ZERO consumers in the recorder — on 2026-08-25
8433
+ * (D62: a switch that writes a store nobody reads is worse than no switch).
8434
+ * Stored rows keep loading: the READ schema is `.strip()` (config-store.ts).
8449
8435
  * A stale caller must fail loudly — silently stripping its legacy intent would
8450
8436
  * persist a band-less config, i.e. silently stop recording the camera.
8451
8437
  */
@@ -8468,14 +8454,7 @@ var RecordingConfigSchema = object({
8468
8454
  * "off" is the absence of a covering band, never a band value.
8469
8455
  */
8470
8456
  bands: array(RecordingBandSchema).default([]),
8471
- retention: RecordingRetentionSchema.optional(),
8472
- /**
8473
- * Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
8474
- * timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
8475
- * windows only — existing sheets are immutable, and each window's index
8476
- * carries its own tile dims so mixed-preset history renders correctly.
8477
- */
8478
- scrubThumbnails: ScrubThumbnailPresetSchema.optional()
8457
+ retention: RecordingRetentionSchema.optional()
8479
8458
  }).strict();
8480
8459
  /**
8481
8460
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
@@ -8551,10 +8530,11 @@ var RelocateFootageInputSchema = object({
8551
8530
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8552
8531
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8553
8532
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8554
- var StorageMigrationMediaMoveInputSchema = object({
8533
+ var RelocateMediaInputSchema = object({
8555
8534
  toLocationId: string(),
8556
8535
  throttleMbps: number().min(1).max(1e3).optional()
8557
- }).extend({ leaseId: string().min(1) });
8536
+ });
8537
+ var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8558
8538
  /** The independently selectable logical storage classes. `recordings`
8559
8539
  * encompasses the high and mid segment profiles; `recordingsLow` is low
8560
8540
  * segments; `eventMedia` is post-analysis blobs. */
@@ -8849,7 +8829,26 @@ var LabelDefinitionSchema = object({
8849
8829
  description: string().optional(),
8850
8830
  icon: string().optional()
8851
8831
  });
8852
- var ClassMapDefinitionSchema = object({
8832
+ /**
8833
+ * Wire schema for a per-model CATALOG classMap override
8834
+ * (`ModelCatalogEntry.classMap` / `ModelConvertMetadata.classMap`) —
8835
+ * restricted to {@link CLASS_MAP_MACRO_TARGETS}, the only macros the
8836
+ * detection pipeline executor actually routes.
8837
+ *
8838
+ * This is deliberately a DIFFERENT, narrower shape than the general-purpose
8839
+ * `ClassMapDefinition` interface above (e.g. `IDetectionAddon.getClassMap()`
8840
+ * and the audio `YAMNET_TO_MACRO` catalog both use macro targets outside this
8841
+ * enum) — the two used to share the name `ClassMapDefinition`/
8842
+ * `ClassMapDefinitionSchema`, which made the schema-type-twin guard
8843
+ * (`scripts/check-schema-type-twins.ts`) flag them as a duplicated shape. They
8844
+ * are not: it is two different concepts colliding on a name. Keep this type
8845
+ * under its own name rather than reusing `ClassMapDefinition` — reusing it
8846
+ * would either narrow every `ClassMapDefinition` consumer to the four
8847
+ * detection macros (breaking `YAMNET_TO_MACRO`) or drop the validation this
8848
+ * schema exists for (see the "rejects a classMap whose target is not a
8849
+ * detection macro" test in `model-catalog-schema.test.ts`).
8850
+ */
8851
+ var DetectionCatalogClassMapSchema = object({
8853
8852
  mapping: record(string(), _enum([
8854
8853
  "person",
8855
8854
  "vehicle",
@@ -9054,7 +9053,7 @@ var ModelCatalogEntrySchema = object({
9054
9053
  * applies (Frigate / COCO public catalog). Set on a custom model whose raw
9055
9054
  * labels already ARE the CamStack macros (Scrypted identity map).
9056
9055
  */
9057
- classMap: ClassMapDefinitionSchema.optional()
9056
+ classMap: DetectionCatalogClassMapSchema.optional()
9058
9057
  });
9059
9058
  var ConvertTargetSchema = discriminatedUnion("format", [object({
9060
9059
  format: literal("openvino"),
@@ -9084,7 +9083,7 @@ var ModelConvertMetadataSchema = object({
9084
9083
  "segmentation"
9085
9084
  ]),
9086
9085
  faceAlignment: boolean().optional(),
9087
- classMap: ClassMapDefinitionSchema.optional()
9086
+ classMap: DetectionCatalogClassMapSchema.optional()
9088
9087
  });
9089
9088
  var ConvertResultSchema = object({
9090
9089
  entry: ModelCatalogEntrySchema,
@@ -9947,7 +9946,7 @@ var AddonPageDeclarationSchema = object({
9947
9946
  /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
9948
9947
  sectionLabel: string().optional()
9949
9948
  });
9950
- method(_void(), array(AddonPageDeclarationSchema).readonly());
9949
+ method(_void(), array(AddonPageDeclarationSchema).readonly(), { auth: "admin" });
9951
9950
  var AddonHttpRouteSchema = object({
9952
9951
  method: _enum([
9953
9952
  "GET",
@@ -10182,7 +10181,7 @@ var WidgetMetadataSchema = object({
10182
10181
  defaultColumns: number().int().min(1).max(12).default(6),
10183
10182
  defaultRows: number().int().min(1).max(12).default(1)
10184
10183
  });
10185
- method(_void(), array(WidgetMetadataSchema).readonly());
10184
+ method(_void(), array(WidgetMetadataSchema).readonly(), { auth: "admin" });
10186
10185
  /**
10187
10186
  * `addon-widgets` — system-scoped singleton aggregator cap. Public-facing
10188
10187
  * surface that admin-ui consumes through `useAddonWidgetsListWidgets()`.
@@ -11806,7 +11805,7 @@ var CustomModelDescriptorSchema = object({
11806
11805
  stepId: string(),
11807
11806
  entry: ModelCatalogEntrySchema
11808
11807
  });
11809
- method(_void(), array(CustomModelDescriptorSchema).readonly());
11808
+ method(_void(), array(CustomModelDescriptorSchema).readonly(), { auth: "admin" });
11810
11809
  /**
11811
11810
  * Query filter for settings-store collections.
11812
11811
  */
@@ -11893,7 +11892,8 @@ method(object({
11893
11892
  }), _void(), { kind: "mutation" }), method(object({
11894
11893
  namespace: string().optional(),
11895
11894
  collection: string(),
11896
- filter: QueryFilterSchema.optional()
11895
+ filter: QueryFilterSchema.optional(),
11896
+ columns: array(string()).readonly().optional()
11897
11897
  }), array(SettingsRecordSchema).readonly()), method(object({
11898
11898
  namespace: string().optional(),
11899
11899
  collection: string(),
@@ -11956,46 +11956,87 @@ var EngineInfoSchema = object({
11956
11956
  kind: _enum(["relational", "vector"]),
11957
11957
  displayName: string()
11958
11958
  });
11959
- method(_void(), EngineInfoSchema), method(object({
11959
+ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11960
11960
  namespace: string().optional(),
11961
11961
  collection: string(),
11962
11962
  key: string()
11963
- }), unknown()), method(object({
11963
+ }), unknown(), { auth: "admin" }), method(object({
11964
11964
  namespace: string().optional(),
11965
11965
  collection: string(),
11966
11966
  key: string(),
11967
11967
  value: unknown()
11968
- }), _void(), { kind: "mutation" }), method(object({
11968
+ }), _void(), {
11969
+ kind: "mutation",
11970
+ auth: "admin"
11971
+ }), method(object({
11969
11972
  namespace: string().optional(),
11970
11973
  collection: string(),
11971
- filter: QueryFilterSchema.optional()
11972
- }), array(SettingsRecordSchema).readonly()), method(object({
11974
+ filter: QueryFilterSchema.optional(),
11975
+ /**
11976
+ * SQL-level column projection — MUST mirror `settings-store.query`.
11977
+ *
11978
+ * ⚠ An earlier version of this comment blamed Zod stripping, and that
11979
+ * was wrong — corrected 2026-08-26 after the hop map
11980
+ * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
11981
+ * There is **no Zod parse at all** between the door and the engine: the
11982
+ * dispatcher forwards the payload verbatim and UDS carries it whole. A
11983
+ * field declared here reaches `SqliteSettingsBackend` either way.
11984
+ *
11985
+ * What actually lost `columns` was the THIRD declaration of this shape:
11986
+ * `SettingsQueryInput` in `interfaces/storage.ts`, a hand-written TS
11987
+ * interface the engine destructures from. The field existed on both
11988
+ * schemas and the engine still never read it, because nothing checks a
11989
+ * registered provider against `InferProvider<cap>` —
11990
+ * `ProviderRegistration.provider` is typed `object`.
11991
+ *
11992
+ * It is declared here anyway, and must stay in step with
11993
+ * `settings-store.query`: a caller reading only the cap definitions has
11994
+ * to be able to see that this call carries a projection.
11995
+ * `data-door-schema-parity.spec.ts` keeps the two aligned.
11996
+ */
11997
+ columns: array(string()).readonly().optional()
11998
+ }), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
11973
11999
  namespace: string().optional(),
11974
12000
  collection: string(),
11975
12001
  record: SettingsRecordSchema
11976
- }), _void(), { kind: "mutation" }), method(object({
12002
+ }), _void(), {
12003
+ kind: "mutation",
12004
+ auth: "admin"
12005
+ }), method(object({
11977
12006
  namespace: string().optional(),
11978
12007
  collection: string(),
11979
12008
  id: string(),
11980
12009
  data: record(string(), unknown())
11981
- }), _void(), { kind: "mutation" }), method(object({
12010
+ }), _void(), {
12011
+ kind: "mutation",
12012
+ auth: "admin"
12013
+ }), method(object({
11982
12014
  namespace: string().optional(),
11983
12015
  collection: string(),
11984
12016
  key: string()
11985
- }), _void(), { kind: "mutation" }), method(object({
12017
+ }), _void(), {
12018
+ kind: "mutation",
12019
+ auth: "admin"
12020
+ }), method(object({
11986
12021
  namespace: string().optional(),
11987
12022
  collection: string(),
11988
12023
  filter: MutationFilterSchema
11989
- }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
12024
+ }), object({ deleted: number().int() }), {
12025
+ kind: "mutation",
12026
+ auth: "admin"
12027
+ }), method(object({
11990
12028
  namespace: string().optional(),
11991
12029
  collection: string(),
11992
12030
  filter: MutationFilterSchema,
11993
12031
  data: record(string(), unknown())
11994
- }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
12032
+ }), object({ updated: number().int() }), {
12033
+ kind: "mutation",
12034
+ auth: "admin"
12035
+ }), method(object({
11995
12036
  namespace: string().optional(),
11996
12037
  collection: string(),
11997
12038
  filter: QueryFilterSchema.optional()
11998
- }), number()), method(object({
12039
+ }), number(), { auth: "admin" }), method(object({
11999
12040
  namespace: string().optional(),
12000
12041
  collection: string(),
12001
12042
  field: string(),
@@ -12005,15 +12046,18 @@ method(_void(), EngineInfoSchema), method(object({
12005
12046
  }), array(object({
12006
12047
  bucket: number().int(),
12007
12048
  count: number().int()
12008
- })).readonly()), method(object({
12049
+ })).readonly(), { auth: "admin" }), method(object({
12009
12050
  namespace: string().optional(),
12010
12051
  collection: string()
12011
- }), boolean()), method(object({
12052
+ }), boolean(), { auth: "admin" }), method(object({
12012
12053
  namespace: string().optional(),
12013
12054
  collection: string(),
12014
12055
  columns: array(CollectionColumnSchema).readonly(),
12015
12056
  indexes: array(CollectionIndexSchema).readonly().optional()
12016
- }), _void(), { kind: "mutation" });
12057
+ }), _void(), {
12058
+ kind: "mutation",
12059
+ auth: "admin"
12060
+ });
12017
12061
  /**
12018
12062
  * shm ring usage stats for a `frameSink: 'shm'` decoder session —
12019
12063
  * exposed via `decoder.getShmStats` so downstream consumers can
@@ -13320,7 +13364,7 @@ method(object({
13320
13364
  crop: _instanceof(Uint8Array),
13321
13365
  width: number(),
13322
13366
  height: number()
13323
- }), EmbeddingResultSchema), method(object({ text: string() }), EmbeddingResultSchema), method(_void(), EmbeddingInfoSchema);
13367
+ }), EmbeddingResultSchema, { auth: "admin" }), method(object({ text: string() }), EmbeddingResultSchema, { auth: "admin" }), method(_void(), EmbeddingInfoSchema, { auth: "admin" });
13324
13368
  /**
13325
13369
  * filesystem-browse — per-node capability for browsing the node's local
13326
13370
  * filesystem. Reads are unconfined (whole filesystem, from `/` down); WRITES
@@ -13613,19 +13657,22 @@ method(LlmGenerateBaseInputSchema.extend({
13613
13657
  runtime: ManagedRuntimeConfigSchema,
13614
13658
  /** The managed profile's timeout, threaded by the hub provider. */
13615
13659
  timeoutMs: number().int().positive().optional()
13616
- }), LlmGenerateResultSchema, { kind: "mutation" }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
13660
+ }), LlmGenerateResultSchema, {
13661
+ kind: "mutation",
13662
+ auth: "admin"
13663
+ }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
13617
13664
  kind: "mutation",
13618
13665
  auth: "admin"
13619
13666
  }), method(object({}), _void(), {
13620
13667
  kind: "mutation",
13621
13668
  auth: "admin"
13622
- }), method(object({}), LlmRuntimeStatusSchema), method(object({ model: ManagedModelRefSchema }), _void(), {
13669
+ }), method(object({}), LlmRuntimeStatusSchema, { auth: "admin" }), method(object({ model: ManagedModelRefSchema }), _void(), {
13623
13670
  kind: "mutation",
13624
13671
  auth: "admin"
13625
13672
  }), method(object({ file: string() }), _void(), {
13626
13673
  kind: "mutation",
13627
13674
  auth: "admin"
13628
- }), method(object({}), array(LlmNodeModelSchema)), method(object({}), LlmRuntimeDiskUsageSchema);
13675
+ }), method(object({}), array(LlmNodeModelSchema), { auth: "admin" }), method(object({}), LlmRuntimeDiskUsageSchema, { auth: "admin" });
13629
13676
  /**
13630
13677
  * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
13631
13678
  * methods concat-fan across providers; single-row methods route to ONE
@@ -17136,7 +17183,7 @@ var OauthIntegrationDescriptorSchema = object({
17136
17183
  */
17137
17184
  refreshTokenTtlSec: union([number().int().positive(), literal("never")]).optional()
17138
17185
  });
17139
- method(_void(), OauthIntegrationDescriptorSchema);
17186
+ method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
17140
17187
  /**
17141
17188
  * pipeline-analytics — device-scoped wrapper cap. Refines raw
17142
17189
  * per-frame detections emitted by the pipeline runner into tracked
@@ -18331,6 +18378,15 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18331
18378
  }), method(object({ jobId: string() }), RelocateJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
18332
18379
  kind: "mutation",
18333
18380
  auth: "admin"
18381
+ }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
18382
+ kind: "mutation",
18383
+ auth: "admin"
18384
+ }), method(object({}), array(RelocateJobSchema).readonly(), {
18385
+ kind: "query",
18386
+ auth: "admin"
18387
+ }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
18388
+ kind: "mutation",
18389
+ auth: "admin"
18334
18390
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
18335
18391
  kind: "query",
18336
18392
  auth: "admin"
@@ -18485,6 +18541,11 @@ object({
18485
18541
  "jpeg"
18486
18542
  ])
18487
18543
  });
18544
+ /**
18545
+ * Process-local frame identity. It is serializable so it can ride an in-process
18546
+ * capability call, but `registryId` deliberately prevents resolution in any
18547
+ * other process or execution group.
18548
+ */
18488
18549
  var FrameRefSchema = object({
18489
18550
  registryId: string().min(1),
18490
18551
  id: string().min(1),
@@ -20690,7 +20751,7 @@ method(object({
20690
20751
  * linking rather than produce an eternal token.
20691
20752
  */
20692
20753
  ttlSec: union([number().int().positive(), literal("never")]).optional()
20693
- }), object({ token: string() })), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable());
20754
+ }), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
20694
20755
  var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
20695
20756
  providerId: string().min(1),
20696
20757
  displayName: string().min(1),
@@ -20785,10 +20846,13 @@ var EvictResultSchema = object({
20785
20846
  /** True when the provider has nothing left it is willing to drop on this location. */
20786
20847
  exhausted: boolean()
20787
20848
  });
20788
- method(object({ locationId: string() }), EvictableUsageSchema), method(object({
20849
+ method(object({ locationId: string() }), EvictableUsageSchema, { auth: "admin" }), method(object({
20789
20850
  locationId: string(),
20790
20851
  targetBytes: number().int().positive()
20791
- }), EvictResultSchema, { kind: "mutation" });
20852
+ }), EvictResultSchema, {
20853
+ kind: "mutation",
20854
+ auth: "admin"
20855
+ });
20792
20856
  method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin" }), method(StorageMigrationInputSchema, object({ jobId: string() }), {
20793
20857
  kind: "mutation",
20794
20858
  auth: "admin"
@@ -20848,26 +20912,50 @@ var ReadChunkInputSchema = object({
20848
20912
  length: number()
20849
20913
  });
20850
20914
  var EndDownloadInputSchema = object({ downloadId: string() });
20851
- method(_void(), ProviderInfoSchema), method(object({ config: record(string(), unknown()) }), TestLocationResultSchema, { auth: "admin" }), method(object({
20915
+ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config: record(string(), unknown()) }), TestLocationResultSchema, { auth: "admin" }), method(object({
20852
20916
  location: StorageLocationSchema,
20853
20917
  relativePath: string()
20854
- }), string()), method(object({
20918
+ }), string(), { auth: "admin" }), method(object({
20855
20919
  location: StorageLocationSchema,
20856
20920
  relativePath: string(),
20857
20921
  data: _instanceof(Uint8Array)
20858
- }), _void(), { kind: "mutation" }), method(object({
20922
+ }), _void(), {
20923
+ kind: "mutation",
20924
+ auth: "admin"
20925
+ }), method(object({
20859
20926
  location: StorageLocationSchema,
20860
20927
  relativePath: string()
20861
- }), _instanceof(Uint8Array)), method(object({
20928
+ }), _instanceof(Uint8Array), { auth: "admin" }), method(object({
20862
20929
  location: StorageLocationSchema,
20863
20930
  relativePath: string()
20864
- }), boolean()), method(object({
20931
+ }), boolean(), { auth: "admin" }), method(object({
20865
20932
  location: StorageLocationSchema,
20866
20933
  prefix: string().optional()
20867
- }), array(string()).readonly()), method(object({
20934
+ }), array(string()).readonly(), { auth: "admin" }), method(object({
20868
20935
  location: StorageLocationSchema,
20869
20936
  relativePath: string()
20870
- }), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
20937
+ }), _void(), {
20938
+ kind: "mutation",
20939
+ auth: "admin"
20940
+ }), method(object({ location: StorageLocationSchema }), number().nullable(), { auth: "admin" }), method(BeginUploadInputSchema, BeginUploadResultSchema, {
20941
+ kind: "mutation",
20942
+ auth: "admin"
20943
+ }), method(WriteChunkInputSchema, _void(), {
20944
+ kind: "mutation",
20945
+ auth: "admin"
20946
+ }), method(FinalizeUploadInputSchema, _void(), {
20947
+ kind: "mutation",
20948
+ auth: "admin"
20949
+ }), method(AbortUploadInputSchema, _void(), {
20950
+ kind: "mutation",
20951
+ auth: "admin"
20952
+ }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, {
20953
+ kind: "mutation",
20954
+ auth: "admin"
20955
+ }), method(ReadChunkInputSchema, _instanceof(Uint8Array), { auth: "admin" }), method(EndDownloadInputSchema, _void(), {
20956
+ kind: "mutation",
20957
+ auth: "admin"
20958
+ });
20871
20959
  /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20872
20960
  var ProfileSettingsSchemaBridge = unknown().nullable();
20873
20961
  var ProfileSettingsBagSchema = record(string(), unknown());
@@ -21125,7 +21213,8 @@ method(object({
21125
21213
  access: "create"
21126
21214
  }), method(object({ userId: string().optional() }), object({ optionsJSON: record(string(), unknown()) }), {
21127
21215
  kind: "mutation",
21128
- access: "view"
21216
+ access: "view",
21217
+ auth: "admin"
21129
21218
  }), method(object({
21130
21219
  /** Required — the user the assertion belongs to (verified). */
21131
21220
  userId: string(),
@@ -21133,10 +21222,12 @@ method(object({
21133
21222
  response: record(string(), unknown())
21134
21223
  }), object({ verified: boolean() }), {
21135
21224
  kind: "mutation",
21136
- access: "view"
21225
+ access: "view",
21226
+ auth: "admin"
21137
21227
  }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
21138
21228
  kind: "mutation",
21139
- access: "view"
21229
+ access: "view",
21230
+ auth: "admin"
21140
21231
  }), method(object({
21141
21232
  /** AuthenticationResponseJSON from the browser. */
21142
21233
  response: record(string(), unknown()) }), object({
@@ -21144,7 +21235,8 @@ response: record(string(), unknown()) }), object({
21144
21235
  userId: string().nullable()
21145
21236
  }), {
21146
21237
  kind: "mutation",
21147
- access: "view"
21238
+ access: "view",
21239
+ auth: "admin"
21148
21240
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
21149
21241
  userId: string(),
21150
21242
  credentialId: string()
@@ -21316,7 +21408,19 @@ var VectorStatsResultSchema = object({
21316
21408
  /** False when the backend ranks approximately. */
21317
21409
  exact: boolean()
21318
21410
  });
21319
- method(VectorDeclareIndexInputSchema, _void(), { kind: "mutation" }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, { kind: "mutation" }), method(VectorQueryInputSchema, VectorQueryResultSchema), method(VectorGetInputSchema, VectorGetResultSchema), method(VectorDeleteInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorStatsInputSchema, VectorStatsResultSchema);
21411
+ method(VectorDeclareIndexInputSchema, _void(), {
21412
+ kind: "mutation",
21413
+ auth: "admin"
21414
+ }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, {
21415
+ kind: "mutation",
21416
+ auth: "admin"
21417
+ }), method(VectorQueryInputSchema, VectorQueryResultSchema, { auth: "admin" }), method(VectorGetInputSchema, VectorGetResultSchema, { auth: "admin" }), method(VectorDeleteInputSchema, VectorDeleteResultSchema, {
21418
+ kind: "mutation",
21419
+ auth: "admin"
21420
+ }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, {
21421
+ kind: "mutation",
21422
+ auth: "admin"
21423
+ }), method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" });
21320
21424
  var ClipSchema = object({
21321
21425
  /** Opaque, provider-namespaced id. The default provider encodes the time
21322
21426
  * window so `getClipPlayback` is self-contained (no event re-query). */
@@ -23777,7 +23881,27 @@ var MediaFileLiteSchema$1 = object({
23777
23881
  sizeBytes: number(),
23778
23882
  timestamp: number()
23779
23883
  });
23780
- method(_void(), array(IdentitySchema).readonly()), method(object({ name: string().min(1) }), IdentitySchema, {
23884
+ method(object({
23885
+ /**
23886
+ * Inline {@link IdentitySchema.coverBase64} on every row.
23887
+ *
23888
+ * Default `false`, the same inversion `listRecentFaces` and
23889
+ * `listPlates` took on 2026-08-25 (see `include-crops-default.ts` for
23890
+ * why the burden belongs on the caller that WANTS the bytes). Measured
23891
+ * on the live hub the same day: four identities cost 40,979 B with the
23892
+ * covers inline, ~10 KB of base64 per row, on a query this UI mounts
23893
+ * four times and the viewer holds at `staleTime: 30_000`.
23894
+ *
23895
+ * Nothing loses its avatar: `coverMediaKey` is already on every row and
23896
+ * the `event-media` plane serves that key `immutable` with an ETag.
23897
+ *
23898
+ * **This is an INPUT field, so it does not reach the addon until the
23899
+ * next train** — the hub router validates cap inputs against its own
23900
+ * compiled Zod and strips a key it does not know. Until then the
23901
+ * provider sees `undefined`, which resolves to `false`: the cheap shape
23902
+ * is what ships, and the opt-in becomes reachable when the train lands.
23903
+ */
23904
+ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly()), method(object({ name: string().min(1) }), IdentitySchema, {
23781
23905
  kind: "mutation",
23782
23906
  auth: "admin"
23783
23907
  }), method(object({
@@ -26667,8 +26791,10 @@ var PlateInfoSchema = object({
26667
26791
  keyFrameMediaKey: string().optional(),
26668
26792
  base64: string().optional(),
26669
26793
  /**
26670
- * Same crop as a data-plane URL. `getPlateByTrack` returns this and
26671
- * never inlines JPEG; `listPlates` still inlines for the admin-ui.
26794
+ * Same crop as a data-plane URL, always present when the plate has a stored
26795
+ * crop. `getPlateByTrack` returns this and never inlines JPEG; `listPlates`
26796
+ * and `searchPlates` inline the crop only when their `includeCrops` input is
26797
+ * left at its `true` default.
26672
26798
  */
26673
26799
  cropUrl: string().optional()
26674
26800
  });
@@ -26688,14 +26814,34 @@ var PlateClusterSchema = object({
26688
26814
  });
26689
26815
  method(object({
26690
26816
  deviceId: number().int().optional(),
26691
- limit: number().int().positive().optional()
26817
+ limit: number().int().positive().optional(),
26818
+ /**
26819
+ * Inline the base64 crop on every row. Default `true` — the existing
26820
+ * behaviour, kept so no caller breaks.
26821
+ *
26822
+ * Set `false` once the caller renders {@link PlateInfo.cropUrl}.
26823
+ * Measured on the live hub at the 500 rows the Plates view asks for:
26824
+ * 879,403 B and 27.7 s with the crops inline, against a few KiB of
26825
+ * metadata without them — and the browser then caches the images.
26826
+ *
26827
+ * This is the plate twin of `faceGallery.listRecentFaces`'s option;
26828
+ * plates were the one gallery list left without it.
26829
+ *
26830
+ * **This is an INPUT field, so it does not reach the addon until the
26831
+ * next train.** The hub router validates cap inputs against its own
26832
+ * compiled Zod and strips a key it does not know. Until the train
26833
+ * ships, sending `false` is harmless and keeps the crops inline.
26834
+ */
26835
+ includeCrops: boolean().optional()
26692
26836
  }).optional(), array(PlateInfoSchema).readonly()), method(object({
26693
26837
  deviceId: number().int(),
26694
26838
  trackId: string()
26695
26839
  }), PlateInfoSchema.nullable()), method(object({ plateId: string() }), array(MediaFileLiteSchema).readonly()), method(object({
26696
26840
  text: string().min(1),
26697
26841
  maxDistance: number().int().min(0).optional(),
26698
- limit: number().int().positive().optional()
26842
+ limit: number().int().positive().optional(),
26843
+ /** See `listPlates.includeCrops`. Default `true`. */
26844
+ includeCrops: boolean().optional()
26699
26845
  }), array(PlateInfoSchema).readonly()), method(object({
26700
26846
  maxDistance: number().int().min(0).optional(),
26701
26847
  minClusterSize: number().int().min(2).optional(),
@@ -26709,7 +26855,13 @@ method(object({
26709
26855
  }), method(object({ plateId: string() }), _void(), {
26710
26856
  kind: "mutation",
26711
26857
  auth: "admin"
26712
- }), method(_void(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
26858
+ }), method(object({
26859
+ /** Inline {@link VehicleSchema.coverBase64} on every row. Default
26860
+ * `false` — the vehicle twin of `faceGallery.listIdentities`'s
26861
+ * option; `coverMediaKey` + the `event-media` plane carry the picture.
26862
+ * INPUT field: stripped by the hub router until the train ships, which
26863
+ * resolves to `false` and is exactly the intended default. */
26864
+ includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
26713
26865
  kind: "mutation",
26714
26866
  auth: "admin"
26715
26867
  }), method(object({
@@ -33970,6 +34122,12 @@ Object.freeze({
33970
34122
  addonId: null,
33971
34123
  access: "create"
33972
34124
  },
34125
+ "pipelineAnalytics.cancelRelocateMedia": {
34126
+ capName: "pipeline-analytics",
34127
+ capScope: "device",
34128
+ addonId: null,
34129
+ access: "create"
34130
+ },
33973
34131
  "pipelineAnalytics.cancelStorageMigrationMove": {
33974
34132
  capName: "pipeline-analytics",
33975
34133
  capScope: "device",
@@ -34144,6 +34302,12 @@ Object.freeze({
34144
34302
  addonId: null,
34145
34303
  access: "view"
34146
34304
  },
34305
+ "pipelineAnalytics.listRelocateMediaJobs": {
34306
+ capName: "pipeline-analytics",
34307
+ capScope: "device",
34308
+ addonId: null,
34309
+ access: "view"
34310
+ },
34147
34311
  "pipelineAnalytics.listRetrainAnnotations": {
34148
34312
  capName: "pipeline-analytics",
34149
34313
  capScope: "device",
@@ -34222,6 +34386,12 @@ Object.freeze({
34222
34386
  addonId: null,
34223
34387
  access: "create"
34224
34388
  },
34389
+ "pipelineAnalytics.relocateMedia": {
34390
+ capName: "pipeline-analytics",
34391
+ capScope: "device",
34392
+ addonId: null,
34393
+ access: "create"
34394
+ },
34225
34395
  "pipelineAnalytics.restageRetrainTrack": {
34226
34396
  capName: "pipeline-analytics",
34227
34397
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.28",
3
+ "version": "0.2.29",
4
4
  "description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
5
5
  "keywords": [
6
6
  "camstack",