@camstack/addon-post-analysis 1.2.668 → 1.2.669

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 (15) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{clip-model-registry-BYJ5lbPi.mjs → clip-model-registry-BPvijtCz.mjs} +170 -58
  3. package/dist/{clip-model-registry-DTC5bkf8.js → clip-model-registry-CbzBwacH.js} +170 -58
  4. package/dist/embedding-encoder/index.js +6 -2
  5. package/dist/embedding-encoder/index.mjs +6 -2
  6. package/dist/pipeline-analytics/_stub.js +2 -2
  7. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DBEA3TPX.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C4QK9e1e.mjs} +2 -2
  8. package/dist/pipeline-analytics/{_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DxtNkzmw.mjs → _virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-9HsFj_VL.mjs} +1 -1
  9. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-anSYIl3S.mjs +26 -0
  10. package/dist/pipeline-analytics/{hostInit-ChYqK-gn.mjs → hostInit-CPLvPO3K.mjs} +9 -9
  11. package/dist/pipeline-analytics/index.js +1 -1
  12. package/dist/pipeline-analytics/index.mjs +1 -1
  13. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  14. package/package.json +2 -2
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CU7mDiJp.mjs +0 -26
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.669] - 2026-11-05
11
+
12
+ ### Changed
13
+
14
+ - Embedding encoder model setting is declared on the cluster hook; the form and stored value are unchanged.
15
+
10
16
  ## [1.2.668] - 2026-11-05
11
17
 
12
18
  ### Changed
@@ -6038,7 +6038,7 @@ var ZodIssueCode = {
6038
6038
  var ZodFirstPartyTypeKind;
6039
6039
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6040
6040
  //#endregion
6041
- //#region ../types/dist/sleep-D1jjWAr8.mjs
6041
+ //#region ../types/dist/sleep-DEZaLbiu.mjs
6042
6042
  /**
6043
6043
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6044
6044
  * window to float samples (D455).
@@ -6840,6 +6840,12 @@ function projectStore(store, perNodeKeys, nodeId) {
6840
6840
  }
6841
6841
  return out;
6842
6842
  }
6843
+ /** Every scope, in the order the guard and the docs list them. */
6844
+ var SCOPED_SETTINGS_SCOPES = [
6845
+ "cluster",
6846
+ "device-defaults",
6847
+ "node"
6848
+ ];
6843
6849
  var GLOBAL_SCOPE = { kind: "global" };
6844
6850
  /** The scope every addon-wide (not per-node, not per-device) setting lives in. */
6845
6851
  function globalSecretScope() {
@@ -7689,6 +7695,13 @@ var BaseAddon = class {
7689
7695
  */
7690
7696
  secretStatePaths = [];
7691
7697
  _addonSecretTree = null;
7698
+ /**
7699
+ * D986 M4: the scoped schemas this addon declared, resolved once per capability
7700
+ * (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
7701
+ * see them. Empty until loaded: the readers then fall back to {@link globalSettingsSchema}.
7702
+ */
7703
+ _scopedByCap = /* @__PURE__ */ new Map();
7704
+ _nodeKeysByCap = /* @__PURE__ */ new Map();
7692
7705
  _deviceSecretTree = null;
7693
7706
  /** Refs the last resolved config pointed at — a change to one re-resolves. */
7694
7707
  _configSecretRefs = /* @__PURE__ */ new Set();
@@ -7758,6 +7771,7 @@ var BaseAddon = class {
7758
7771
  this._ctx = context;
7759
7772
  this._secretSettings = null;
7760
7773
  }
7774
+ await this.loadScopedSchemas();
7761
7775
  await this.resolveConfig();
7762
7776
  if (secrets !== void 0) this._secretChangeUnsub = secrets.onChange((ref) => {
7763
7777
  if (this._configSecretRefs.has(ref)) this.scheduleSecretReresolve(SECRET_CHANGE_DEBOUNCE_MS);
@@ -7767,6 +7781,7 @@ var BaseAddon = class {
7767
7781
  const normalized = normalizeAddonInitResult(result);
7768
7782
  const providers = normalized && "providers" in normalized && normalized.providers ? normalized.providers : [];
7769
7783
  this._registeredCapNames = providers.map((p) => p.capability.name);
7784
+ await this.loadScopedSchemas();
7770
7785
  return normalized;
7771
7786
  }
7772
7787
  /**
@@ -7855,6 +7870,16 @@ var BaseAddon = class {
7855
7870
  schema(schema) {
7856
7871
  return schema;
7857
7872
  }
7873
+ /**
7874
+ * The capability names whose scoped settings schemas ({@link clusterSettingsSchema},
7875
+ * {@link nodeSettingsSchema}, {@link deviceDefaultsSchema}) this addon declares. Read BEFORE
7876
+ * `onInitialize`, when the providers it registers are not known yet: the first config resolve
7877
+ * must already know which keys are per node. Names the providers register at init are added
7878
+ * once known.
7879
+ */
7880
+ scopedSettingsCapabilities() {
7881
+ return [];
7882
+ }
7858
7883
  /** Override to provide global-level settings UI schema. */
7859
7884
  globalSettingsSchema(_cap) {
7860
7885
  return null;
@@ -7898,7 +7923,8 @@ var BaseAddon = class {
7898
7923
  return [];
7899
7924
  }
7900
7925
  async getGlobalSettings(overlay, cap, nodeId) {
7901
- const schema = this.globalSettingsSchema(cap);
7926
+ await this.loadScopedSchemas(cap);
7927
+ const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
7902
7928
  if (!schema) return { sections: [] };
7903
7929
  const projected = await this.readRawProjectedStore(nodeId, cap);
7904
7930
  return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
@@ -7933,10 +7959,9 @@ var BaseAddon = class {
7933
7959
  *
7934
7960
  * Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
7935
7961
  * needs its connection fields, the default integration the addon's own sections. It is the
7936
- * SHAPE of the form only — the values live in `integrations.getSettings`, and the write path is
7937
- * unchanged (`integrations.setSettings` for an account integration).
7962
+ * SHAPE of the form only — the values live on the instance record.
7938
7963
  */
7939
- async integrationSettingsSchema(_instance) {
7964
+ async integrationFormSchema(_instance) {
7940
7965
  return null;
7941
7966
  }
7942
7967
  /**
@@ -7982,7 +8007,7 @@ var BaseAddon = class {
7982
8007
  * per-instance schema when it declares one, else its global schema (what they always showed).
7983
8008
  */
7984
8009
  async getIntegrationFormSchema(instance, nodeId) {
7985
- const scoped = await this.integrationSettingsSchema(instance);
8010
+ const scoped = await this.integrationFormSchema(instance);
7986
8011
  if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
7987
8012
  return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
7988
8013
  }
@@ -8030,6 +8055,7 @@ var BaseAddon = class {
8030
8055
  * resolved blob back is a no-op for every unchanged secret.
8031
8056
  */
8032
8057
  async resolveGlobalStore(nodeId, cap) {
8058
+ await this.loadScopedSchemas(cap);
8033
8059
  const raw = await this._ctx?.settings?.readAddonStore() ?? {};
8034
8060
  return this.projectForNode(raw, nodeId, cap);
8035
8061
  }
@@ -8040,6 +8066,7 @@ var BaseAddon = class {
8040
8066
  }
8041
8067
  /** The PROJECTED store with its markers — the form hydrate only (D798). */
8042
8068
  async readRawProjectedStore(nodeId, cap) {
8069
+ await this.loadScopedSchemas(cap);
8043
8070
  const raw = await this.rawSettings()?.readAddonStore() ?? {};
8044
8071
  return this.projectForNode(raw, nodeId, cap);
8045
8072
  }
@@ -8142,6 +8169,7 @@ var BaseAddon = class {
8142
8169
  await this.applyGlobalPatch(patch, nodeId);
8143
8170
  }
8144
8171
  async applyGlobalPatch(barePatch, nodeId) {
8172
+ await this.loadScopedSchemas();
8145
8173
  const keys = this.perNodeKeys();
8146
8174
  const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
8147
8175
  const target = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
@@ -8155,7 +8183,8 @@ var BaseAddon = class {
8155
8183
  await this.resolveConfig();
8156
8184
  await this.onConfigChanged();
8157
8185
  this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
8158
- this.maybeAutoRestart(Object.keys(barePatch), this.globalSettingsSchema());
8186
+ const legacy = this.globalSettingsSchema();
8187
+ this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
8159
8188
  }
8160
8189
  /**
8161
8190
  * The set of field keys the global settings schema declares `perNode: true`
@@ -8163,14 +8192,67 @@ var BaseAddon = class {
8163
8192
  * declarations). Empty set ⇒ every per-node code path is bypassed and the
8164
8193
  * settings API behaves exactly like the legacy node-agnostic one.
8165
8194
  */
8166
- _perNodeKeysCache = /* @__PURE__ */ new Map();
8195
+ /**
8196
+ * Load the scoped schemas of every capability this addon declares (the override and the
8197
+ * providers registered at init, plus `extraCap`) that is not loaded yet, then drop what was
8198
+ * derived from the previous set. Idempotent.
8199
+ */
8200
+ async loadScopedSchemas(extraCap) {
8201
+ const caps = new Set([
8202
+ ...this.scopedSettingsCapabilities(),
8203
+ ...this._registeredCapNames,
8204
+ ...extraCap === void 0 ? [] : [extraCap]
8205
+ ]);
8206
+ let added = false;
8207
+ for (const cap of caps) {
8208
+ if (this._scopedByCap.has(cap)) continue;
8209
+ const loaded = [];
8210
+ for (const scope of SCOPED_SETTINGS_SCOPES) {
8211
+ const schema = await this.getScopedSettingsSchema(scope, cap);
8212
+ if (schema !== null) loaded.push({
8213
+ scope,
8214
+ schema
8215
+ });
8216
+ }
8217
+ this._scopedByCap.set(cap, loaded);
8218
+ added = true;
8219
+ }
8220
+ if (!added) return;
8221
+ this._nodeKeysByCap = /* @__PURE__ */ new Map();
8222
+ this._addonSecretTree = null;
8223
+ }
8224
+ /**
8225
+ * The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
8226
+ * sections of its scoped schemas, so dropping the old hook does not blank the form.
8227
+ */
8228
+ scopedFormSchema(cap) {
8229
+ const byId = /* @__PURE__ */ new Map();
8230
+ for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
8231
+ return byId.size === 0 ? null : { sections: [...byId.values()] };
8232
+ }
8233
+ /** Every loaded scoped schema of `cap`, or of every loaded capability. */
8234
+ loadedScopedSchemas(cap) {
8235
+ if (cap !== void 0) return this._scopedByCap.get(cap) ?? [];
8236
+ return [...this._scopedByCap.values()].flat();
8237
+ }
8238
+ /**
8239
+ * The field keys that are stored per node: every field of a {@link nodeSettingsSchema}, plus
8240
+ * the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
8241
+ * per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
8242
+ * per-node code path is bypassed and the settings API behaves like the node-agnostic one.
8243
+ * Call {@link loadScopedSchemas} first (the async seams do).
8244
+ */
8167
8245
  perNodeKeys(cap) {
8168
8246
  const cacheKey = cap ?? "";
8169
- const cached = this._perNodeKeysCache.get(cacheKey);
8247
+ const cached = this._nodeKeysByCap.get(cacheKey);
8170
8248
  if (cached) return cached;
8171
- const schema = this.globalSettingsSchema(cap);
8172
- const keys = new Set(schema ? schema.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
8173
- this._perNodeKeysCache.set(cacheKey, keys);
8249
+ const legacy = this.globalSettingsSchema(cap);
8250
+ const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
8251
+ for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
8252
+ if (scope !== "node") continue;
8253
+ for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
8254
+ }
8255
+ this._nodeKeysByCap.set(cacheKey, keys);
8174
8256
  return keys;
8175
8257
  }
8176
8258
  /**
@@ -8180,10 +8262,9 @@ var BaseAddon = class {
8180
8262
  * time to return its response before the addon is torn down and
8181
8263
  * re-initialised by `AddonRegistryService.restartAddon`.
8182
8264
  */
8183
- maybeAutoRestart(patchKeys, schema) {
8184
- if (!schema) return;
8265
+ maybeAutoRestart(patchKeys, schemas) {
8185
8266
  const restartKeys = /* @__PURE__ */ new Set();
8186
- for (const section of schema.sections) for (const field of section.fields) {
8267
+ for (const schema of schemas) for (const section of schema.sections) for (const field of section.fields) {
8187
8268
  if (field.type === "separator" || field.type === "info") continue;
8188
8269
  if (field.requiresRestart) restartKeys.add(field.key);
8189
8270
  }
@@ -8379,12 +8460,14 @@ var BaseAddon = class {
8379
8460
  * here, in the addon's own process, so the hub keeps no copy of it.
8380
8461
  */
8381
8462
  async getDeclaredSettingsKeys() {
8463
+ await this.loadScopedSchemas();
8382
8464
  return { keys: [...this.declaredKeySet()].toSorted() };
8383
8465
  }
8384
8466
  declaredKeySet() {
8385
8467
  const keys = new Set(Object.keys(this.defaults));
8386
8468
  const schema = this.globalSettingsSchema();
8387
8469
  if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
8470
+ for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
8388
8471
  for (const key of this._declaredStateKeys) keys.add(key);
8389
8472
  for (const path of this.secretStatePaths) {
8390
8473
  const root = path.split(/[.[]/, 1)[0];
@@ -8480,7 +8563,11 @@ var BaseAddon = class {
8480
8563
  }
8481
8564
  /** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
8482
8565
  addonSecretTree() {
8483
- this._addonSecretTree ??= mergeSecretStatePaths(secretTreeFromSchema(this.globalSettingsSchema()), this.secretStatePaths);
8566
+ if (this._addonSecretTree === null) {
8567
+ const tree = new Map(secretTreeFromSchema(this.globalSettingsSchema()));
8568
+ for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
8569
+ this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
8570
+ }
8484
8571
  return this._addonSecretTree;
8485
8572
  }
8486
8573
  deviceSecretTree() {
@@ -8730,6 +8817,23 @@ function dropPerNodeFields(fields) {
8730
8817
  }
8731
8818
  return kept;
8732
8819
  }
8820
+ /** The keys of the value-holding fields, recursing into layout containers. */
8821
+ function collectValueFieldKeys(fields) {
8822
+ const collected = [];
8823
+ for (const field of fields) {
8824
+ if (field.type === "group") {
8825
+ collected.push(...collectValueFieldKeys(field.fields));
8826
+ continue;
8827
+ }
8828
+ if (field.type === "sub-tabs") {
8829
+ for (const tab of field.tabs) collected.push(...collectValueFieldKeys(tab.fields));
8830
+ continue;
8831
+ }
8832
+ if (field.type === "separator" || field.type === "info") continue;
8833
+ if ("key" in field && typeof field.key === "string") collected.push(field.key);
8834
+ }
8835
+ return collected;
8836
+ }
8733
8837
  function collectFieldKeys(fields) {
8734
8838
  const collected = [];
8735
8839
  for (const field of fields) {
@@ -57114,11 +57218,7 @@ var CreateIntegrationInputSchema = object({
57114
57218
  info: record(string(), unknown()).optional(),
57115
57219
  /** `stableId` of the discovery candidate the form was seeded from (D984). */
57116
57220
  originStableId: string().optional(),
57117
- settings: record(string(), unknown()).optional(),
57118
- /** Keys of `settings` the form's schema declares secret (by type) — kept in
57119
- * the keychain, not the table (D787). */
57120
- secretKeys: array(string()).optional(),
57121
- skipRestart: boolean().optional()
57221
+ settings: record(string(), unknown()).optional()
57122
57222
  });
57123
57223
  var UpdateIntegrationInputSchema = object({
57124
57224
  id: string(),
@@ -57139,22 +57239,6 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
57139
57239
  }), method(object({ id: string() }), DeleteIntegrationResultSchema, {
57140
57240
  kind: "mutation",
57141
57241
  auth: "admin"
57142
- }), method(object({ id: string() }), record(string(), unknown()), { auth: "admin" }), method(object({
57143
- id: string(),
57144
- settings: record(string(), unknown()),
57145
- /** Keys the form's schema declares secret (by type) — keychain-stored (D787). */
57146
- secretKeys: array(string()).optional(),
57147
- /** The integration's own addon applies the change in-process and asks the hub not to respawn it. */
57148
- skipRestart: boolean().optional()
57149
- }), object({ success: boolean() }), {
57150
- kind: "mutation",
57151
- auth: "admin"
57152
- }), method(object({ id: string() }), object({
57153
- rows: number().int().nonnegative(),
57154
- secrets: number().int().nonnegative()
57155
- }), {
57156
- kind: "mutation",
57157
- auth: "admin"
57158
57242
  }), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
57159
57243
  addonId: string(),
57160
57244
  settings: record(string(), unknown())
@@ -60226,6 +60310,27 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
60226
60310
  }), {
60227
60311
  kind: "mutation",
60228
60312
  auth: "admin"
60313
+ }), method(object({ integrationId: string().min(1) }), record(string(), unknown()), { auth: "admin" }), method(object({ integrationId: string().min(1) }), object({
60314
+ rows: number().int().nonnegative(),
60315
+ secrets: number().int().nonnegative()
60316
+ }), {
60317
+ kind: "mutation",
60318
+ auth: "admin"
60319
+ }), method(object({
60320
+ integrationId: string().min(1),
60321
+ patch: record(string(), unknown())
60322
+ }), object({ written: boolean() }), {
60323
+ kind: "mutation",
60324
+ auth: "admin"
60325
+ }), method(object({
60326
+ integrationId: string().min(1),
60327
+ keys: array(string().min(1))
60328
+ }), object({
60329
+ present: boolean(),
60330
+ removed: record(string(), unknown())
60331
+ }), {
60332
+ kind: "mutation",
60333
+ auth: "admin"
60229
60334
  });
60230
60335
  method(object({
60231
60336
  sourceUrl: string(),
@@ -88394,13 +88499,6 @@ Object.freeze({
88394
88499
  access: "create",
88395
88500
  role: "admin"
88396
88501
  },
88397
- "integrations.clearSettings": {
88398
- capName: "integrations",
88399
- capScope: "system",
88400
- addonId: null,
88401
- access: "delete",
88402
- role: "admin"
88403
- },
88404
88502
  "integrations.create": {
88405
88503
  capName: "integrations",
88406
88504
  capScope: "system",
@@ -88436,13 +88534,6 @@ Object.freeze({
88436
88534
  access: "view",
88437
88535
  role: "admin"
88438
88536
  },
88439
- "integrations.getSettings": {
88440
- capName: "integrations",
88441
- capScope: "system",
88442
- addonId: null,
88443
- access: "view",
88444
- role: "admin"
88445
- },
88446
88537
  "integrations.list": {
88447
88538
  capName: "integrations",
88448
88539
  capScope: "system",
@@ -88450,13 +88541,6 @@ Object.freeze({
88450
88541
  access: "view",
88451
88542
  role: "admin"
88452
88543
  },
88453
- "integrations.setSettings": {
88454
- capName: "integrations",
88455
- capScope: "system",
88456
- addonId: null,
88457
- access: "create",
88458
- role: "admin"
88459
- },
88460
88544
  "integrations.testConnection": {
88461
88545
  capName: "integrations",
88462
88546
  capScope: "system",
@@ -89451,6 +89535,13 @@ Object.freeze({
89451
89535
  access: "view",
89452
89536
  role: "admin"
89453
89537
  },
89538
+ "migrations.clearLegacyIntegrationRows": {
89539
+ capName: "migrations",
89540
+ capScope: "system",
89541
+ addonId: null,
89542
+ access: "delete",
89543
+ role: "admin"
89544
+ },
89454
89545
  "migrations.declareOwner": {
89455
89546
  capName: "migrations",
89456
89547
  capScope: "system",
@@ -89458,6 +89549,13 @@ Object.freeze({
89458
89549
  access: "create",
89459
89550
  role: "admin"
89460
89551
  },
89552
+ "migrations.deleteLegacyIntegrationRowKeys": {
89553
+ capName: "migrations",
89554
+ capScope: "system",
89555
+ addonId: null,
89556
+ access: "delete",
89557
+ role: "admin"
89558
+ },
89461
89559
  "migrations.dryRun": {
89462
89560
  capName: "migrations",
89463
89561
  capScope: "system",
@@ -89493,6 +89591,20 @@ Object.freeze({
89493
89591
  access: "create",
89494
89592
  role: "admin"
89495
89593
  },
89594
+ "migrations.patchLegacyIntegrationRows": {
89595
+ capName: "migrations",
89596
+ capScope: "system",
89597
+ addonId: null,
89598
+ access: "create",
89599
+ role: "admin"
89600
+ },
89601
+ "migrations.readLegacyIntegrationRows": {
89602
+ capName: "migrations",
89603
+ capScope: "system",
89604
+ addonId: null,
89605
+ access: "view",
89606
+ role: "admin"
89607
+ },
89496
89608
  "migrations.restorePreMigration": {
89497
89609
  capName: "migrations",
89498
89610
  capScope: "system",