@camstack/addon-model-studio 1.1.262 → 1.1.264

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 (17) hide show
  1. package/dist/{MotionZonesSettings-DtoUJxd6.mjs → MotionZonesSettings-DXOf3xDp.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-Bd5lL0CO.mjs → PrivacyMaskSettings-DasEXHXg.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-BG0CBUrr.mjs → SceneMonitorEditor-ClVvQVl6.mjs} +3 -3
  4. package/dist/_stub.js +10 -10
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CmpS6H8K.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CU96npOu.mjs} +3 -3
  6. package/dist/{_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DlW3IlLM.mjs → _virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B0F3F6BP.mjs} +1 -1
  7. package/dist/{hostInit-Cuk6X8GJ.mjs → hostInit-Bsv1Txh4.mjs} +2 -2
  8. package/dist/model-studio.addon.js +191 -29
  9. package/dist/model-studio.addon.mjs +191 -29
  10. package/dist/{player-overlays-DXeDukPC.mjs → player-overlays-BWxIhTSh.mjs} +1 -1
  11. package/dist/remoteEntry.js +1 -1
  12. package/dist/{responsive-D9Bo78lO.mjs → responsive-Bb8t1Rws.mjs} +1 -1
  13. package/dist/{scene-monitor-copy-CQr7egaT.mjs → scene-monitor-copy-Bps8TGiG.mjs} +1 -1
  14. package/dist/{square-d__poSpa.mjs → square-DSJt_nVw.mjs} +1 -1
  15. package/dist/{trash-2-C0XdoZQu.mjs → trash-2-CzUTU-oX.mjs} +1 -1
  16. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CS43EGzM.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DSJOnpOj.mjs} +1 -1
  17. package/package.json +1 -1
@@ -5782,7 +5782,7 @@ var ZodIssueCode = {
5782
5782
  var ZodFirstPartyTypeKind;
5783
5783
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5784
5784
  //#endregion
5785
- //#region ../types/dist/sleep-DRqxtc0C.mjs
5785
+ //#region ../types/dist/sleep-bwsTj221.mjs
5786
5786
  /**
5787
5787
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5788
5788
  * window to float samples (D455).
@@ -7033,7 +7033,6 @@ function createHandle(raw, opts) {
7033
7033
  const writeAddon = (patch) => write("addon", opts.addonTree(), void 0, patch, () => readStoredAddonBlob(raw), (p) => raw.writeAddonStore(p));
7034
7034
  const readAddonStoreResult = raw.readAddonStoreResult;
7035
7035
  const readAddonStoreKeyResult = raw.readAddonStoreKeyResult;
7036
- const readDeviceStoreBatch = raw.readDeviceStoreBatch;
7037
7036
  const overrides = {
7038
7037
  readAddonStore: async () => resolveRead("addon", await raw.readAddonStore()),
7039
7038
  ...readAddonStoreResult !== void 0 ? { readAddonStoreResult: async () => {
@@ -7057,12 +7056,12 @@ function createHandle(raw, opts) {
7057
7056
  };
7058
7057
  } } : {},
7059
7058
  readDeviceStore: async (deviceId) => resolveRead(`device:${deviceId}`, await raw.readDeviceStore(deviceId)),
7060
- ...readDeviceStoreBatch !== void 0 ? { readDeviceStoreBatch: async (deviceIds) => {
7061
- const rows = await readDeviceStoreBatch.call(raw, deviceIds);
7059
+ readDeviceStoreBatch: async (deviceIds) => {
7060
+ const rows = await raw.readDeviceStoreBatch(deviceIds);
7062
7061
  const out = /* @__PURE__ */ new Map();
7063
7062
  for (const [deviceId, blob] of rows) out.set(deviceId, await resolveRead(`device:${deviceId}`, blob));
7064
7063
  return out;
7065
- } } : {},
7064
+ },
7066
7065
  writeAddonStore: async (patch) => {
7067
7066
  await writeAddon(patch);
7068
7067
  },
@@ -7889,7 +7888,7 @@ var BaseAddon = class {
7889
7888
  return this._addonSecretTree;
7890
7889
  }
7891
7890
  deviceSecretTree() {
7892
- this._deviceSecretTree ??= secretTreeFromSchema(this.deviceSettingsSchema());
7891
+ this._deviceSecretTree ??= mergeSecretStatePaths(secretTreeFromSchema(this.deviceSettingsSchema()), this.secretStatePaths);
7893
7892
  return this._deviceSecretTree;
7894
7893
  }
7895
7894
  /**
@@ -7965,42 +7964,135 @@ var BaseAddon = class {
7965
7964
  this[timerOf] = timer;
7966
7965
  }
7967
7966
  /**
7968
- * Wrap `ctx.settings.readAddonStore()` with a short retry budget so a
7969
- * transient settings-store outage (mid-restart of sqlite-settings, tsx-watch
7970
- * swap, or any race where the SqliteSettingsBackend is between shutdown and
7971
- * re-initialize) doesn't propagate up into `initialize()` and leave the
7967
+ * Wrap `ctx.settings.readAddonStore()` with a retry budget so a transient
7968
+ * settings-store outage doesn't propagate up into `initialize()` and leave the
7972
7969
  * addon permanently broken.
7973
7970
  *
7974
- * Retry only the two known infra fingerprints. Anything else propagates so
7975
- * real bugs surface immediately. After the budget expires we fall back to
7976
- * `{}` (defaults) — the addon's first successful patch will rehydrate.
7971
+ * Two kinds of outage, two budgets:
7972
+ * - the store's own restart fingerprints (`SqliteSettingsBackend not
7973
+ * initialized`, `provider not available`): a short budget, then the addon
7974
+ * falls back to `{}` (defaults) - its first successful patch rehydrates;
7975
+ * - a TRANSPORT failure (the hub is restarting while this runner boots:
7976
+ * `discovery deadline exceeded`, `parent could not route`, a refused or
7977
+ * timed-out connection). Since D870 a runner's settings read THROWS instead
7978
+ * of answering `{}`, so without a budget a hub restart ends in a respawn
7979
+ * loop. A long, bounded budget; only after it the error propagates - the
7980
+ * addon never runs on defaults for a store it could not ask.
7981
+ * Anything else propagates immediately so real bugs surface.
7977
7982
  */
7978
7983
  async readAddonStoreWithRetry() {
7979
7984
  const settings = this.rawSettings();
7980
7985
  if (!settings) return {};
7981
- const delaysMs = [
7982
- 150,
7983
- 350,
7984
- 600,
7985
- 900
7986
- ];
7987
7986
  let lastErr;
7988
- for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
7987
+ for (let attempt = 0;; attempt++) try {
7989
7988
  const stored = await settings.readAddonStore() ?? {};
7990
7989
  this.settingsStoreReady = true;
7991
7990
  return stored;
7992
7991
  } catch (err) {
7993
7992
  lastErr = err;
7994
- const msg = err instanceof Error ? err.message : String(err);
7995
- if (!(msg.includes("SqliteSettingsBackend not initialized") || msg.includes("provider not available"))) throw err;
7996
- if (attempt === delaysMs.length) break;
7997
- await new Promise((r) => setTimeout(r, delaysMs[attempt]));
7993
+ const kind = classifyStoreError(err);
7994
+ if (kind === "permanent") throw err;
7995
+ const delay = (kind === "transport" ? TRANSPORT_RETRY_DELAYS_MS : RESTART_RETRY_DELAYS_MS)[attempt];
7996
+ if (delay === void 0) {
7997
+ if (kind === "transport") throw err;
7998
+ break;
7999
+ }
8000
+ await new Promise((r) => setTimeout(r, delay));
7998
8001
  }
7999
8002
  this.settingsStoreReady = false;
8000
8003
  this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
8001
8004
  return {};
8002
8005
  }
8003
8006
  };
8007
+ /** The settings store's own restart fingerprints. */
8008
+ var RESTART_RETRY_DELAYS_MS = [
8009
+ 150,
8010
+ 350,
8011
+ 600,
8012
+ 900
8013
+ ];
8014
+ /** A hub restarting under a booting runner: ~100 s in total. */
8015
+ var TRANSPORT_RETRY_DELAYS_MS = [
8016
+ 150,
8017
+ 350,
8018
+ 600,
8019
+ 900,
8020
+ 2e3,
8021
+ 5e3,
8022
+ 1e4,
8023
+ 2e4,
8024
+ 3e4,
8025
+ 3e4
8026
+ ];
8027
+ var RESTART_FINGERPRINTS = ["SqliteSettingsBackend not initialized", "provider not available"];
8028
+ /** Node / socket error codes of a connection that did not happen or broke. */
8029
+ var TRANSPORT_CODES = new Set([
8030
+ "ECONNREFUSED",
8031
+ "ECONNRESET",
8032
+ "ETIMEDOUT",
8033
+ "EPIPE",
8034
+ "EHOSTUNREACH",
8035
+ "ENETUNREACH"
8036
+ ]);
8037
+ /** tRPC error codes that mean "the other side is not answering now", not "your call is wrong". */
8038
+ var UNAVAILABLE_TRPC_CODES = new Set([
8039
+ "TIMEOUT",
8040
+ "SERVICE_UNAVAILABLE",
8041
+ "BAD_GATEWAY",
8042
+ "GATEWAY_TIMEOUT"
8043
+ ]);
8044
+ /** The exact phrases OUR transport raises when it cannot reach the hub. */
8045
+ var TRANSPORT_PHRASES = [
8046
+ "discovery deadline exceeded",
8047
+ "parent could not route child unowned cap call",
8048
+ "UDS request timed out after",
8049
+ "channel closed"
8050
+ ];
8051
+ /** Moleculer error `type`s of a call that could not be served right now. */
8052
+ var MOLECULER_TRANSIENT_TYPES = new Set([
8053
+ "REQUEST_TIMEOUT",
8054
+ "SERVICE_NOT_FOUND",
8055
+ "SERVICE_NOT_AVAILABLE",
8056
+ "REQUEST_REJECTED",
8057
+ "BROKER_DISCONNECTED"
8058
+ ]);
8059
+ function stringProp(value, key) {
8060
+ if (typeof value !== "object" || value === null) return void 0;
8061
+ const found = Reflect.get(value, key);
8062
+ return typeof found === "string" ? found : void 0;
8063
+ }
8064
+ /** The code an error carries: its own, its cause's, or a tRPC `data.code`. */
8065
+ function errorCode(err) {
8066
+ const out = {};
8067
+ const cause = typeof err === "object" && err !== null ? Reflect.get(err, "cause") : void 0;
8068
+ const data = typeof err === "object" && err !== null ? Reflect.get(err, "data") : void 0;
8069
+ const node = stringProp(err, "code") ?? stringProp(cause, "code");
8070
+ if (node !== void 0) out.node = node;
8071
+ const trpc = stringProp(data, "code");
8072
+ if (trpc !== void 0) out.trpc = trpc;
8073
+ return out;
8074
+ }
8075
+ /**
8076
+ * Is a settings read failure worth retrying, and with which budget? Only
8077
+ * EXPLICIT signals count: a socket error code, a tRPC "unavailable" code, or
8078
+ * one of the exact phrases our own transport raises. A message that merely
8079
+ * contains "timed out" or "unreachable" is not evidence of anything, and
8080
+ * `settings store not wired` is a wiring bug that retrying cannot fix.
8081
+ */
8082
+ function classifyStoreError(err) {
8083
+ const message = err instanceof Error ? err.message : String(err);
8084
+ if (RESTART_FINGERPRINTS.some((f) => message.includes(f))) return "restart";
8085
+ const code = errorCode(err);
8086
+ if (code.node !== void 0 && TRANSPORT_CODES.has(code.node)) return "transport";
8087
+ if (code.trpc !== void 0 && UNAVAILABLE_TRPC_CODES.has(code.trpc)) return "transport";
8088
+ if (typeof err === "object" && err !== null) {
8089
+ if (Reflect.get(err, "retryable") === true) return "transport";
8090
+ const type = stringProp(err, "type");
8091
+ if (type !== void 0 && MOLECULER_TRANSIENT_TYPES.has(type)) return "transport";
8092
+ }
8093
+ if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
8094
+ return "permanent";
8095
+ }
8004
8096
  /**
8005
8097
  * Collect the keys of every field marked `perNode: true`, recursing into
8006
8098
  * layout containers (`group` fields and `sub-tabs` tabs) the same way
@@ -12176,11 +12268,10 @@ var ClipModelMetaSchema = object({
12176
12268
  /**
12177
12269
  * The `vector-store` index this model's vectors live in. ONE feature space
12178
12270
  * per index: two models share an index only when their vectors are ranked
12179
- * against each other, which for CLIP means never across families. MobileCLIP
12180
- * S1 and S2 share `object-clip` for history (separated by the row's
12181
- * `modelId`); any other model gets its own.
12271
+ * against each other, which for CLIP means never across families. Every
12272
+ * model gets its own.
12182
12273
  */
12183
- vectorIndex: string().regex(/^object-clip(-[a-z0-9][a-z0-9-]*)?$/),
12274
+ vectorIndex: string().regex(/^object-clip-[a-z0-9][a-z0-9-]*$/),
12184
12275
  /**
12185
12276
  * The text encoder's tokenizer, a declared SIBLING file of its onnx. The name
12186
12277
  * must be unique per tokenizer: every model's siblings land in ONE flat
@@ -16479,6 +16570,28 @@ id: union([string(), number()]) }), {
16479
16570
  kind: "mutation",
16480
16571
  auth: "admin"
16481
16572
  });
16573
+ /** One table of the settings database. */
16574
+ var StorageTableSchema = object({
16575
+ /** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
16576
+ name: string(),
16577
+ /** The owner prefix of a scoped name (`recorder` for `recorder:addon-settings`), else null. */
16578
+ owner: string().nullable(),
16579
+ rows: number().int().nonnegative(),
16580
+ /** Bytes the table's pages occupy (`dbstat`); null when the engine cannot measure. */
16581
+ bytes: number().int().nonnegative().nullable(),
16582
+ /** Declared by an addon since this engine process started (a running addon claims it). */
16583
+ declaredThisBoot: boolean()
16584
+ });
16585
+ method(object({ ownerPrefix: string().min(1).optional() }), object({ tables: array(StorageTableSchema) }), { auth: "admin" }), method(object({
16586
+ collection: string().min(1),
16587
+ expectRows: number().int().nonnegative()
16588
+ }), object({
16589
+ dropped: literal(true),
16590
+ rows: number().int().nonnegative()
16591
+ }), {
16592
+ kind: "mutation",
16593
+ auth: "admin"
16594
+ });
16482
16595
  /**
16483
16596
  * `keychain` — the hub's encrypted store of secret values (D787).
16484
16597
  *
@@ -17020,6 +17133,16 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
17020
17133
  kind: "mutation",
17021
17134
  auth: "admin",
17022
17135
  caller: "required"
17136
+ }), method(object({
17137
+ ref: string().min(1),
17138
+ value: string().min(1)
17139
+ }), object({
17140
+ ref: string(),
17141
+ version: number().int()
17142
+ }), {
17143
+ kind: "mutation",
17144
+ auth: "admin",
17145
+ caller: "required"
17023
17146
  }), method(object({ refs: array(string().min(1)).max(1e3) }), object({
17024
17147
  deleted: array(string()).readonly(),
17025
17148
  kept: array(object({
@@ -55291,7 +55414,19 @@ var TlsStatusSchema = object({
55291
55414
  sans: array(string()),
55292
55415
  caCertPem: string().nullable(),
55293
55416
  reissueError: string().nullable(),
55294
- restartRequired: boolean()
55417
+ restartRequired: boolean(),
55418
+ /** An uploaded certificate is served but no CA is kept for it and it is not publicly signed (D873). */
55419
+ caMissing: boolean(),
55420
+ /** Does the hub's own generated CA carry a critical name constraint? `null` while it has none. */
55421
+ localCaConstrained: boolean().nullable(),
55422
+ /** ISO time the generated CA was replaced by a constrained one; devices must re-download it. */
55423
+ caReplacedAt: string().nullable(),
55424
+ /** The uploaded certificate kept on disk, selectable again after "Revert to generated". */
55425
+ storedUpload: object({
55426
+ leafFingerprintSha256: string(),
55427
+ validTo: string(),
55428
+ hasCa: boolean()
55429
+ }).nullable()
55295
55430
  });
55296
55431
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
55297
55432
  /**
@@ -55347,6 +55482,9 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
55347
55482
  }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
55348
55483
  kind: "mutation",
55349
55484
  auth: "admin"
55485
+ }), method(_void(), TlsStatusSchema, {
55486
+ kind: "mutation",
55487
+ auth: "admin"
55350
55488
  });
55351
55489
  object({
55352
55490
  /** Lifecycle state of the lock. `jammed` means the motor reported
@@ -64461,6 +64599,12 @@ Object.freeze({
64461
64599
  addonId: null,
64462
64600
  access: "create"
64463
64601
  },
64602
+ "keychainAdmin.importSecret": {
64603
+ capName: "keychain-admin",
64604
+ capScope: "system",
64605
+ addonId: null,
64606
+ access: "create"
64607
+ },
64464
64608
  "keychainAdmin.listAudit": {
64465
64609
  capName: "keychain-admin",
64466
64610
  capScope: "system",
@@ -64857,6 +65001,12 @@ Object.freeze({
64857
65001
  addonId: null,
64858
65002
  access: "create"
64859
65003
  },
65004
+ "localNetwork.useStoredUploadedCertificate": {
65005
+ capName: "local-network",
65006
+ capScope: "system",
65007
+ addonId: null,
65008
+ access: "create"
65009
+ },
64860
65010
  "lockControl.getStatus": {
64861
65011
  capName: "lock-control",
64862
65012
  capScope: "device",
@@ -68241,6 +68391,18 @@ Object.freeze({
68241
68391
  addonId: null,
68242
68392
  access: "create"
68243
68393
  },
68394
+ "storageAdmin.dropCollection": {
68395
+ capName: "storage-admin",
68396
+ capScope: "system",
68397
+ addonId: null,
68398
+ access: "delete"
68399
+ },
68400
+ "storageAdmin.listTables": {
68401
+ capName: "storage-admin",
68402
+ capScope: "system",
68403
+ addonId: null,
68404
+ access: "view"
68405
+ },
68244
68406
  "storageEvictable.evict": {
68245
68407
  capName: "storage-evictable",
68246
68408
  capScope: "system",
@@ -5756,7 +5756,7 @@ var ZodIssueCode = {
5756
5756
  var ZodFirstPartyTypeKind;
5757
5757
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5758
5758
  //#endregion
5759
- //#region ../types/dist/sleep-DRqxtc0C.mjs
5759
+ //#region ../types/dist/sleep-bwsTj221.mjs
5760
5760
  /**
5761
5761
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5762
5762
  * window to float samples (D455).
@@ -7007,7 +7007,6 @@ function createHandle(raw, opts) {
7007
7007
  const writeAddon = (patch) => write("addon", opts.addonTree(), void 0, patch, () => readStoredAddonBlob(raw), (p) => raw.writeAddonStore(p));
7008
7008
  const readAddonStoreResult = raw.readAddonStoreResult;
7009
7009
  const readAddonStoreKeyResult = raw.readAddonStoreKeyResult;
7010
- const readDeviceStoreBatch = raw.readDeviceStoreBatch;
7011
7010
  const overrides = {
7012
7011
  readAddonStore: async () => resolveRead("addon", await raw.readAddonStore()),
7013
7012
  ...readAddonStoreResult !== void 0 ? { readAddonStoreResult: async () => {
@@ -7031,12 +7030,12 @@ function createHandle(raw, opts) {
7031
7030
  };
7032
7031
  } } : {},
7033
7032
  readDeviceStore: async (deviceId) => resolveRead(`device:${deviceId}`, await raw.readDeviceStore(deviceId)),
7034
- ...readDeviceStoreBatch !== void 0 ? { readDeviceStoreBatch: async (deviceIds) => {
7035
- const rows = await readDeviceStoreBatch.call(raw, deviceIds);
7033
+ readDeviceStoreBatch: async (deviceIds) => {
7034
+ const rows = await raw.readDeviceStoreBatch(deviceIds);
7036
7035
  const out = /* @__PURE__ */ new Map();
7037
7036
  for (const [deviceId, blob] of rows) out.set(deviceId, await resolveRead(`device:${deviceId}`, blob));
7038
7037
  return out;
7039
- } } : {},
7038
+ },
7040
7039
  writeAddonStore: async (patch) => {
7041
7040
  await writeAddon(patch);
7042
7041
  },
@@ -7863,7 +7862,7 @@ var BaseAddon = class {
7863
7862
  return this._addonSecretTree;
7864
7863
  }
7865
7864
  deviceSecretTree() {
7866
- this._deviceSecretTree ??= secretTreeFromSchema(this.deviceSettingsSchema());
7865
+ this._deviceSecretTree ??= mergeSecretStatePaths(secretTreeFromSchema(this.deviceSettingsSchema()), this.secretStatePaths);
7867
7866
  return this._deviceSecretTree;
7868
7867
  }
7869
7868
  /**
@@ -7939,42 +7938,135 @@ var BaseAddon = class {
7939
7938
  this[timerOf] = timer;
7940
7939
  }
7941
7940
  /**
7942
- * Wrap `ctx.settings.readAddonStore()` with a short retry budget so a
7943
- * transient settings-store outage (mid-restart of sqlite-settings, tsx-watch
7944
- * swap, or any race where the SqliteSettingsBackend is between shutdown and
7945
- * re-initialize) doesn't propagate up into `initialize()` and leave the
7941
+ * Wrap `ctx.settings.readAddonStore()` with a retry budget so a transient
7942
+ * settings-store outage doesn't propagate up into `initialize()` and leave the
7946
7943
  * addon permanently broken.
7947
7944
  *
7948
- * Retry only the two known infra fingerprints. Anything else propagates so
7949
- * real bugs surface immediately. After the budget expires we fall back to
7950
- * `{}` (defaults) — the addon's first successful patch will rehydrate.
7945
+ * Two kinds of outage, two budgets:
7946
+ * - the store's own restart fingerprints (`SqliteSettingsBackend not
7947
+ * initialized`, `provider not available`): a short budget, then the addon
7948
+ * falls back to `{}` (defaults) - its first successful patch rehydrates;
7949
+ * - a TRANSPORT failure (the hub is restarting while this runner boots:
7950
+ * `discovery deadline exceeded`, `parent could not route`, a refused or
7951
+ * timed-out connection). Since D870 a runner's settings read THROWS instead
7952
+ * of answering `{}`, so without a budget a hub restart ends in a respawn
7953
+ * loop. A long, bounded budget; only after it the error propagates - the
7954
+ * addon never runs on defaults for a store it could not ask.
7955
+ * Anything else propagates immediately so real bugs surface.
7951
7956
  */
7952
7957
  async readAddonStoreWithRetry() {
7953
7958
  const settings = this.rawSettings();
7954
7959
  if (!settings) return {};
7955
- const delaysMs = [
7956
- 150,
7957
- 350,
7958
- 600,
7959
- 900
7960
- ];
7961
7960
  let lastErr;
7962
- for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
7961
+ for (let attempt = 0;; attempt++) try {
7963
7962
  const stored = await settings.readAddonStore() ?? {};
7964
7963
  this.settingsStoreReady = true;
7965
7964
  return stored;
7966
7965
  } catch (err) {
7967
7966
  lastErr = err;
7968
- const msg = err instanceof Error ? err.message : String(err);
7969
- if (!(msg.includes("SqliteSettingsBackend not initialized") || msg.includes("provider not available"))) throw err;
7970
- if (attempt === delaysMs.length) break;
7971
- await new Promise((r) => setTimeout(r, delaysMs[attempt]));
7967
+ const kind = classifyStoreError(err);
7968
+ if (kind === "permanent") throw err;
7969
+ const delay = (kind === "transport" ? TRANSPORT_RETRY_DELAYS_MS : RESTART_RETRY_DELAYS_MS)[attempt];
7970
+ if (delay === void 0) {
7971
+ if (kind === "transport") throw err;
7972
+ break;
7973
+ }
7974
+ await new Promise((r) => setTimeout(r, delay));
7972
7975
  }
7973
7976
  this.settingsStoreReady = false;
7974
7977
  this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
7975
7978
  return {};
7976
7979
  }
7977
7980
  };
7981
+ /** The settings store's own restart fingerprints. */
7982
+ var RESTART_RETRY_DELAYS_MS = [
7983
+ 150,
7984
+ 350,
7985
+ 600,
7986
+ 900
7987
+ ];
7988
+ /** A hub restarting under a booting runner: ~100 s in total. */
7989
+ var TRANSPORT_RETRY_DELAYS_MS = [
7990
+ 150,
7991
+ 350,
7992
+ 600,
7993
+ 900,
7994
+ 2e3,
7995
+ 5e3,
7996
+ 1e4,
7997
+ 2e4,
7998
+ 3e4,
7999
+ 3e4
8000
+ ];
8001
+ var RESTART_FINGERPRINTS = ["SqliteSettingsBackend not initialized", "provider not available"];
8002
+ /** Node / socket error codes of a connection that did not happen or broke. */
8003
+ var TRANSPORT_CODES = new Set([
8004
+ "ECONNREFUSED",
8005
+ "ECONNRESET",
8006
+ "ETIMEDOUT",
8007
+ "EPIPE",
8008
+ "EHOSTUNREACH",
8009
+ "ENETUNREACH"
8010
+ ]);
8011
+ /** tRPC error codes that mean "the other side is not answering now", not "your call is wrong". */
8012
+ var UNAVAILABLE_TRPC_CODES = new Set([
8013
+ "TIMEOUT",
8014
+ "SERVICE_UNAVAILABLE",
8015
+ "BAD_GATEWAY",
8016
+ "GATEWAY_TIMEOUT"
8017
+ ]);
8018
+ /** The exact phrases OUR transport raises when it cannot reach the hub. */
8019
+ var TRANSPORT_PHRASES = [
8020
+ "discovery deadline exceeded",
8021
+ "parent could not route child unowned cap call",
8022
+ "UDS request timed out after",
8023
+ "channel closed"
8024
+ ];
8025
+ /** Moleculer error `type`s of a call that could not be served right now. */
8026
+ var MOLECULER_TRANSIENT_TYPES = new Set([
8027
+ "REQUEST_TIMEOUT",
8028
+ "SERVICE_NOT_FOUND",
8029
+ "SERVICE_NOT_AVAILABLE",
8030
+ "REQUEST_REJECTED",
8031
+ "BROKER_DISCONNECTED"
8032
+ ]);
8033
+ function stringProp(value, key) {
8034
+ if (typeof value !== "object" || value === null) return void 0;
8035
+ const found = Reflect.get(value, key);
8036
+ return typeof found === "string" ? found : void 0;
8037
+ }
8038
+ /** The code an error carries: its own, its cause's, or a tRPC `data.code`. */
8039
+ function errorCode(err) {
8040
+ const out = {};
8041
+ const cause = typeof err === "object" && err !== null ? Reflect.get(err, "cause") : void 0;
8042
+ const data = typeof err === "object" && err !== null ? Reflect.get(err, "data") : void 0;
8043
+ const node = stringProp(err, "code") ?? stringProp(cause, "code");
8044
+ if (node !== void 0) out.node = node;
8045
+ const trpc = stringProp(data, "code");
8046
+ if (trpc !== void 0) out.trpc = trpc;
8047
+ return out;
8048
+ }
8049
+ /**
8050
+ * Is a settings read failure worth retrying, and with which budget? Only
8051
+ * EXPLICIT signals count: a socket error code, a tRPC "unavailable" code, or
8052
+ * one of the exact phrases our own transport raises. A message that merely
8053
+ * contains "timed out" or "unreachable" is not evidence of anything, and
8054
+ * `settings store not wired` is a wiring bug that retrying cannot fix.
8055
+ */
8056
+ function classifyStoreError(err) {
8057
+ const message = err instanceof Error ? err.message : String(err);
8058
+ if (RESTART_FINGERPRINTS.some((f) => message.includes(f))) return "restart";
8059
+ const code = errorCode(err);
8060
+ if (code.node !== void 0 && TRANSPORT_CODES.has(code.node)) return "transport";
8061
+ if (code.trpc !== void 0 && UNAVAILABLE_TRPC_CODES.has(code.trpc)) return "transport";
8062
+ if (typeof err === "object" && err !== null) {
8063
+ if (Reflect.get(err, "retryable") === true) return "transport";
8064
+ const type = stringProp(err, "type");
8065
+ if (type !== void 0 && MOLECULER_TRANSIENT_TYPES.has(type)) return "transport";
8066
+ }
8067
+ if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
8068
+ return "permanent";
8069
+ }
7978
8070
  /**
7979
8071
  * Collect the keys of every field marked `perNode: true`, recursing into
7980
8072
  * layout containers (`group` fields and `sub-tabs` tabs) the same way
@@ -12150,11 +12242,10 @@ var ClipModelMetaSchema = object({
12150
12242
  /**
12151
12243
  * The `vector-store` index this model's vectors live in. ONE feature space
12152
12244
  * per index: two models share an index only when their vectors are ranked
12153
- * against each other, which for CLIP means never across families. MobileCLIP
12154
- * S1 and S2 share `object-clip` for history (separated by the row's
12155
- * `modelId`); any other model gets its own.
12245
+ * against each other, which for CLIP means never across families. Every
12246
+ * model gets its own.
12156
12247
  */
12157
- vectorIndex: string().regex(/^object-clip(-[a-z0-9][a-z0-9-]*)?$/),
12248
+ vectorIndex: string().regex(/^object-clip-[a-z0-9][a-z0-9-]*$/),
12158
12249
  /**
12159
12250
  * The text encoder's tokenizer, a declared SIBLING file of its onnx. The name
12160
12251
  * must be unique per tokenizer: every model's siblings land in ONE flat
@@ -16453,6 +16544,28 @@ id: union([string(), number()]) }), {
16453
16544
  kind: "mutation",
16454
16545
  auth: "admin"
16455
16546
  });
16547
+ /** One table of the settings database. */
16548
+ var StorageTableSchema = object({
16549
+ /** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
16550
+ name: string(),
16551
+ /** The owner prefix of a scoped name (`recorder` for `recorder:addon-settings`), else null. */
16552
+ owner: string().nullable(),
16553
+ rows: number().int().nonnegative(),
16554
+ /** Bytes the table's pages occupy (`dbstat`); null when the engine cannot measure. */
16555
+ bytes: number().int().nonnegative().nullable(),
16556
+ /** Declared by an addon since this engine process started (a running addon claims it). */
16557
+ declaredThisBoot: boolean()
16558
+ });
16559
+ method(object({ ownerPrefix: string().min(1).optional() }), object({ tables: array(StorageTableSchema) }), { auth: "admin" }), method(object({
16560
+ collection: string().min(1),
16561
+ expectRows: number().int().nonnegative()
16562
+ }), object({
16563
+ dropped: literal(true),
16564
+ rows: number().int().nonnegative()
16565
+ }), {
16566
+ kind: "mutation",
16567
+ auth: "admin"
16568
+ });
16456
16569
  /**
16457
16570
  * `keychain` — the hub's encrypted store of secret values (D787).
16458
16571
  *
@@ -16994,6 +17107,16 @@ method(object({}), KeychainStatusSchema, { auth: "admin" }), method(object({}),
16994
17107
  kind: "mutation",
16995
17108
  auth: "admin",
16996
17109
  caller: "required"
17110
+ }), method(object({
17111
+ ref: string().min(1),
17112
+ value: string().min(1)
17113
+ }), object({
17114
+ ref: string(),
17115
+ version: number().int()
17116
+ }), {
17117
+ kind: "mutation",
17118
+ auth: "admin",
17119
+ caller: "required"
16997
17120
  }), method(object({ refs: array(string().min(1)).max(1e3) }), object({
16998
17121
  deleted: array(string()).readonly(),
16999
17122
  kept: array(object({
@@ -55265,7 +55388,19 @@ var TlsStatusSchema = object({
55265
55388
  sans: array(string()),
55266
55389
  caCertPem: string().nullable(),
55267
55390
  reissueError: string().nullable(),
55268
- restartRequired: boolean()
55391
+ restartRequired: boolean(),
55392
+ /** An uploaded certificate is served but no CA is kept for it and it is not publicly signed (D873). */
55393
+ caMissing: boolean(),
55394
+ /** Does the hub's own generated CA carry a critical name constraint? `null` while it has none. */
55395
+ localCaConstrained: boolean().nullable(),
55396
+ /** ISO time the generated CA was replaced by a constrained one; devices must re-download it. */
55397
+ caReplacedAt: string().nullable(),
55398
+ /** The uploaded certificate kept on disk, selectable again after "Revert to generated". */
55399
+ storedUpload: object({
55400
+ leafFingerprintSha256: string(),
55401
+ validTo: string(),
55402
+ hasCa: boolean()
55403
+ }).nullable()
55269
55404
  });
55270
55405
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
55271
55406
  /**
@@ -55321,6 +55456,9 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
55321
55456
  }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
55322
55457
  kind: "mutation",
55323
55458
  auth: "admin"
55459
+ }), method(_void(), TlsStatusSchema, {
55460
+ kind: "mutation",
55461
+ auth: "admin"
55324
55462
  });
55325
55463
  object({
55326
55464
  /** Lifecycle state of the lock. `jammed` means the motor reported
@@ -64435,6 +64573,12 @@ Object.freeze({
64435
64573
  addonId: null,
64436
64574
  access: "create"
64437
64575
  },
64576
+ "keychainAdmin.importSecret": {
64577
+ capName: "keychain-admin",
64578
+ capScope: "system",
64579
+ addonId: null,
64580
+ access: "create"
64581
+ },
64438
64582
  "keychainAdmin.listAudit": {
64439
64583
  capName: "keychain-admin",
64440
64584
  capScope: "system",
@@ -64831,6 +64975,12 @@ Object.freeze({
64831
64975
  addonId: null,
64832
64976
  access: "create"
64833
64977
  },
64978
+ "localNetwork.useStoredUploadedCertificate": {
64979
+ capName: "local-network",
64980
+ capScope: "system",
64981
+ addonId: null,
64982
+ access: "create"
64983
+ },
64834
64984
  "lockControl.getStatus": {
64835
64985
  capName: "lock-control",
64836
64986
  capScope: "device",
@@ -68215,6 +68365,18 @@ Object.freeze({
68215
68365
  addonId: null,
68216
68366
  access: "create"
68217
68367
  },
68368
+ "storageAdmin.dropCollection": {
68369
+ capName: "storage-admin",
68370
+ capScope: "system",
68371
+ addonId: null,
68372
+ access: "delete"
68373
+ },
68374
+ "storageAdmin.listTables": {
68375
+ capName: "storage-admin",
68376
+ capScope: "system",
68377
+ addonId: null,
68378
+ access: "view"
68379
+ },
68218
68380
  "storageEvictable.evict": {
68219
68381
  capName: "storage-evictable",
68220
68382
  capScope: "system",
@@ -1,6 +1,6 @@
1
1
  import { S as e, d as t, u as n, v as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs";
2
2
  import { n as i, r as a, t as o } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { g as s, h as c } from "./responsive-D9Bo78lO.mjs";
3
+ import { g as s, h as c } from "./responsive-Bb8t1Rws.mjs";
4
4
  var l = s("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
6
6
  key: "qrunsl"
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CS43EGzM.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DSJOnpOj.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { S as e, d as t, g as n, i as r, l as i, n as a, r as o, u as s, v as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { h as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DlW3IlLM.mjs";
3
+ import { h as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B0F3F6BP.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  e();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {