@camstack/system 1.2.439 → 1.2.441

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 (103) hide show
  1. package/dist/addon-runner.js +743 -79
  2. package/dist/addon-runner.mjs +743 -79
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +1 -1
  10. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  15. package/dist/builtins/calendars/calendars.addon.js +1 -1
  16. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  17. package/dist/builtins/camera-grid/index.js +1 -1
  18. package/dist/builtins/camera-grid/index.mjs +1 -1
  19. package/dist/builtins/composer/composer.addon.js +2 -2
  20. package/dist/builtins/composer/composer.addon.mjs +2 -2
  21. package/dist/builtins/console-logging/index.js +1 -1
  22. package/dist/builtins/console-logging/index.mjs +1 -1
  23. package/dist/builtins/core-blocks/block-settings-store.d.ts +1 -1
  24. package/dist/builtins/core-blocks/core-blocks.addon.js +77 -11
  25. package/dist/builtins/core-blocks/core-blocks.addon.mjs +77 -12
  26. package/dist/builtins/core-blocks/index.mjs +1 -1
  27. package/dist/builtins/device-manager/device-manager.addon.js +181 -59
  28. package/dist/builtins/device-manager/device-manager.addon.mjs +180 -60
  29. package/dist/builtins/device-manager/device-removal-hooks.d.ts +0 -11
  30. package/dist/builtins/hub-forwarder/index.js +1 -1
  31. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  32. package/dist/builtins/keychain/index.js +29 -11
  33. package/dist/builtins/keychain/index.mjs +29 -11
  34. package/dist/builtins/keychain/keychain-service.d.ts +8 -0
  35. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  36. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  37. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  38. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  39. package/dist/builtins/local-network/local-network.addon.js +2 -2
  40. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  41. package/dist/builtins/loki-logging/index.js +1 -1
  42. package/dist/builtins/loki-logging/index.mjs +1 -1
  43. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  44. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  45. package/dist/builtins/platform-probe/index.js +1 -1
  46. package/dist/builtins/platform-probe/index.mjs +1 -1
  47. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  48. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  49. package/dist/builtins/snapshot/index.js +1 -1
  50. package/dist/builtins/snapshot/index.mjs +1 -1
  51. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  52. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  53. package/dist/builtins/sqlite-storage/index.js +1 -1
  54. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  55. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +38 -7
  56. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +69 -3
  57. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +69 -3
  58. package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +31 -0
  59. package/dist/builtins/storage-orchestrator/hub-settings-forward.d.ts +3 -3
  60. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +4 -4
  61. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +4 -4
  62. package/dist/builtins/system-config/system-config.addon.js +2 -2
  63. package/dist/builtins/system-config/system-config.addon.mjs +2 -2
  64. package/dist/builtins/winston-logging/index.js +1 -1
  65. package/dist/builtins/winston-logging/index.mjs +1 -1
  66. package/dist/{composition-sources-B4jC2FC7.js → composition-sources-BG-W2U0d.js} +1 -1
  67. package/dist/{composition-sources-BGOSCGWa.mjs → composition-sources-ByNISOnW.mjs} +1 -1
  68. package/dist/{constants-B92BjObl.mjs → constants-DJILnUSb.mjs} +1 -1
  69. package/dist/{constants-BRsjQwi-.js → constants-UojhAJcm.js} +1 -1
  70. package/dist/{device-ca-DHG9OW2m.js → device-ca-196DAEZT.js} +1 -1
  71. package/dist/{device-ca-46BUsWD1.mjs → device-ca-D8Ri9TVz.mjs} +1 -1
  72. package/dist/{dist-yI6kF6r6.mjs → dist-BWvkuc31.mjs} +248 -27
  73. package/dist/{dist-BOWdLjoK.js → dist-BiTCcaf-.js} +265 -26
  74. package/dist/file-host-worker.js +1 -1
  75. package/dist/file-host-worker.mjs +1 -1
  76. package/dist/{hub-mdns-ciao-DGwVc2uh.mjs → hub-mdns-ciao-Cnd0bTB9.mjs} +1 -1
  77. package/dist/{hub-mdns-ciao-D7S5AJRU.js → hub-mdns-ciao-DOBTq8qr.js} +1 -1
  78. package/dist/index.js +336 -336
  79. package/dist/index.mjs +337 -337
  80. package/dist/kernel/addon-settings-store.d.ts +43 -0
  81. package/dist/kernel/config-manager.d.ts +0 -19
  82. package/dist/kernel/device-settings-store.d.ts +74 -0
  83. package/dist/kernel/legacy-blob-guard.d.ts +58 -0
  84. package/dist/kernel/moleculer/runner-addon-settings.d.ts +34 -0
  85. package/dist/kernel/moleculer/runner-device-settings.d.ts +39 -0
  86. package/dist/kernel/prefix-walk.d.ts +39 -0
  87. package/dist/kernel/sections-store.d.ts +20 -0
  88. package/dist/kernel/settings-door-view.d.ts +2 -2
  89. package/dist/kernel/settings-view-types.d.ts +5 -30
  90. package/dist/kernel/store-settings-view.d.ts +0 -3
  91. package/dist/prefix-range-D_KueXbQ.js +27 -0
  92. package/dist/prefix-range-Dl0znowN.mjs +22 -0
  93. package/dist/prefix-walk-DAOBSyH1.mjs +88 -0
  94. package/dist/prefix-walk-Dv6MLZlM.js +99 -0
  95. package/dist/{restore-archive-CpdUO-uS.mjs → restore-archive-4ziluTU3.mjs} +1 -1
  96. package/dist/{restore-archive-DiGiI6Jp.js → restore-archive-CfSSjKnA.js} +1 -1
  97. package/dist/{retired-settings-keys-UsVtLOT0.mjs → retired-settings-keys-Bhwe4ymb.mjs} +2 -2
  98. package/dist/{retired-settings-keys-CyQ7uvta.js → retired-settings-keys-D_VwZiDt.js} +10 -4
  99. package/dist/{wal-maintenance-xsvdT5Go.mjs → wal-maintenance-B57SAp4a.mjs} +0 -0
  100. package/dist/{wal-maintenance-DEL_jeG0.js → wal-maintenance-CgZTNWAz.js} +0 -0
  101. package/package.json +5 -2
  102. package/dist/{custom-action-registry-Bf_YnagS.js → custom-action-registry-BKmoaqG0.js} +1 -1
  103. package/dist/{custom-action-registry-BQnbN0DP.mjs → custom-action-registry-CyUuhATc.mjs} +1 -1
@@ -718,7 +718,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
718
718
  return EventCategory;
719
719
  }({});
720
720
  //#endregion
721
- //#region ../types/dist/sleep-DRqxtc0C.mjs
721
+ //#region ../types/dist/sleep-bwsTj221.mjs
722
722
  /**
723
723
  * The audio chunk plane's byte format, and the ONE expansion from a coded
724
724
  * window to float samples (D455).
@@ -2079,7 +2079,6 @@ function createHandle(raw, opts) {
2079
2079
  const writeAddon = (patch) => write("addon", opts.addonTree(), void 0, patch, () => readStoredAddonBlob(raw), (p) => raw.writeAddonStore(p));
2080
2080
  const readAddonStoreResult = raw.readAddonStoreResult;
2081
2081
  const readAddonStoreKeyResult = raw.readAddonStoreKeyResult;
2082
- const readDeviceStoreBatch = raw.readDeviceStoreBatch;
2083
2082
  const overrides = {
2084
2083
  readAddonStore: async () => resolveRead("addon", await raw.readAddonStore()),
2085
2084
  ...readAddonStoreResult !== void 0 ? { readAddonStoreResult: async () => {
@@ -2103,12 +2102,12 @@ function createHandle(raw, opts) {
2103
2102
  };
2104
2103
  } } : {},
2105
2104
  readDeviceStore: async (deviceId) => resolveRead(`device:${deviceId}`, await raw.readDeviceStore(deviceId)),
2106
- ...readDeviceStoreBatch !== void 0 ? { readDeviceStoreBatch: async (deviceIds) => {
2107
- const rows = await readDeviceStoreBatch.call(raw, deviceIds);
2105
+ readDeviceStoreBatch: async (deviceIds) => {
2106
+ const rows = await raw.readDeviceStoreBatch(deviceIds);
2108
2107
  const out = /* @__PURE__ */ new Map();
2109
2108
  for (const [deviceId, blob] of rows) out.set(deviceId, await resolveRead(`device:${deviceId}`, blob));
2110
2109
  return out;
2111
- } } : {},
2110
+ },
2112
2111
  writeAddonStore: async (patch) => {
2113
2112
  await writeAddon(patch);
2114
2113
  },
@@ -2948,7 +2947,7 @@ var BaseAddon = class {
2948
2947
  return this._addonSecretTree;
2949
2948
  }
2950
2949
  deviceSecretTree() {
2951
- this._deviceSecretTree ??= secretTreeFromSchema(this.deviceSettingsSchema());
2950
+ this._deviceSecretTree ??= mergeSecretStatePaths(secretTreeFromSchema(this.deviceSettingsSchema()), this.secretStatePaths);
2952
2951
  return this._deviceSecretTree;
2953
2952
  }
2954
2953
  /**
@@ -3024,42 +3023,135 @@ var BaseAddon = class {
3024
3023
  this[timerOf] = timer;
3025
3024
  }
3026
3025
  /**
3027
- * Wrap `ctx.settings.readAddonStore()` with a short retry budget so a
3028
- * transient settings-store outage (mid-restart of sqlite-settings, tsx-watch
3029
- * swap, or any race where the SqliteSettingsBackend is between shutdown and
3030
- * re-initialize) doesn't propagate up into `initialize()` and leave the
3026
+ * Wrap `ctx.settings.readAddonStore()` with a retry budget so a transient
3027
+ * settings-store outage doesn't propagate up into `initialize()` and leave the
3031
3028
  * addon permanently broken.
3032
3029
  *
3033
- * Retry only the two known infra fingerprints. Anything else propagates so
3034
- * real bugs surface immediately. After the budget expires we fall back to
3035
- * `{}` (defaults) — the addon's first successful patch will rehydrate.
3030
+ * Two kinds of outage, two budgets:
3031
+ * - the store's own restart fingerprints (`SqliteSettingsBackend not
3032
+ * initialized`, `provider not available`): a short budget, then the addon
3033
+ * falls back to `{}` (defaults) - its first successful patch rehydrates;
3034
+ * - a TRANSPORT failure (the hub is restarting while this runner boots:
3035
+ * `discovery deadline exceeded`, `parent could not route`, a refused or
3036
+ * timed-out connection). Since D870 a runner's settings read THROWS instead
3037
+ * of answering `{}`, so without a budget a hub restart ends in a respawn
3038
+ * loop. A long, bounded budget; only after it the error propagates - the
3039
+ * addon never runs on defaults for a store it could not ask.
3040
+ * Anything else propagates immediately so real bugs surface.
3036
3041
  */
3037
3042
  async readAddonStoreWithRetry() {
3038
3043
  const settings = this.rawSettings();
3039
3044
  if (!settings) return {};
3040
- const delaysMs = [
3041
- 150,
3042
- 350,
3043
- 600,
3044
- 900
3045
- ];
3046
3045
  let lastErr;
3047
- for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
3046
+ for (let attempt = 0;; attempt++) try {
3048
3047
  const stored = await settings.readAddonStore() ?? {};
3049
3048
  this.settingsStoreReady = true;
3050
3049
  return stored;
3051
3050
  } catch (err) {
3052
3051
  lastErr = err;
3053
- const msg = err instanceof Error ? err.message : String(err);
3054
- if (!(msg.includes("SqliteSettingsBackend not initialized") || msg.includes("provider not available"))) throw err;
3055
- if (attempt === delaysMs.length) break;
3056
- await new Promise((r) => setTimeout(r, delaysMs[attempt]));
3052
+ const kind = classifyStoreError(err);
3053
+ if (kind === "permanent") throw err;
3054
+ const delay = (kind === "transport" ? TRANSPORT_RETRY_DELAYS_MS : RESTART_RETRY_DELAYS_MS)[attempt];
3055
+ if (delay === void 0) {
3056
+ if (kind === "transport") throw err;
3057
+ break;
3058
+ }
3059
+ await new Promise((r) => setTimeout(r, delay));
3057
3060
  }
3058
3061
  this.settingsStoreReady = false;
3059
3062
  this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
3060
3063
  return {};
3061
3064
  }
3062
3065
  };
3066
+ /** The settings store's own restart fingerprints. */
3067
+ var RESTART_RETRY_DELAYS_MS = [
3068
+ 150,
3069
+ 350,
3070
+ 600,
3071
+ 900
3072
+ ];
3073
+ /** A hub restarting under a booting runner: ~100 s in total. */
3074
+ var TRANSPORT_RETRY_DELAYS_MS = [
3075
+ 150,
3076
+ 350,
3077
+ 600,
3078
+ 900,
3079
+ 2e3,
3080
+ 5e3,
3081
+ 1e4,
3082
+ 2e4,
3083
+ 3e4,
3084
+ 3e4
3085
+ ];
3086
+ var RESTART_FINGERPRINTS = ["SqliteSettingsBackend not initialized", "provider not available"];
3087
+ /** Node / socket error codes of a connection that did not happen or broke. */
3088
+ var TRANSPORT_CODES = new Set([
3089
+ "ECONNREFUSED",
3090
+ "ECONNRESET",
3091
+ "ETIMEDOUT",
3092
+ "EPIPE",
3093
+ "EHOSTUNREACH",
3094
+ "ENETUNREACH"
3095
+ ]);
3096
+ /** tRPC error codes that mean "the other side is not answering now", not "your call is wrong". */
3097
+ var UNAVAILABLE_TRPC_CODES = new Set([
3098
+ "TIMEOUT",
3099
+ "SERVICE_UNAVAILABLE",
3100
+ "BAD_GATEWAY",
3101
+ "GATEWAY_TIMEOUT"
3102
+ ]);
3103
+ /** The exact phrases OUR transport raises when it cannot reach the hub. */
3104
+ var TRANSPORT_PHRASES = [
3105
+ "discovery deadline exceeded",
3106
+ "parent could not route child unowned cap call",
3107
+ "UDS request timed out after",
3108
+ "channel closed"
3109
+ ];
3110
+ /** Moleculer error `type`s of a call that could not be served right now. */
3111
+ var MOLECULER_TRANSIENT_TYPES = new Set([
3112
+ "REQUEST_TIMEOUT",
3113
+ "SERVICE_NOT_FOUND",
3114
+ "SERVICE_NOT_AVAILABLE",
3115
+ "REQUEST_REJECTED",
3116
+ "BROKER_DISCONNECTED"
3117
+ ]);
3118
+ function stringProp(value, key) {
3119
+ if (typeof value !== "object" || value === null) return void 0;
3120
+ const found = Reflect.get(value, key);
3121
+ return typeof found === "string" ? found : void 0;
3122
+ }
3123
+ /** The code an error carries: its own, its cause's, or a tRPC `data.code`. */
3124
+ function errorCode(err) {
3125
+ const out = {};
3126
+ const cause = typeof err === "object" && err !== null ? Reflect.get(err, "cause") : void 0;
3127
+ const data = typeof err === "object" && err !== null ? Reflect.get(err, "data") : void 0;
3128
+ const node = stringProp(err, "code") ?? stringProp(cause, "code");
3129
+ if (node !== void 0) out.node = node;
3130
+ const trpc = stringProp(data, "code");
3131
+ if (trpc !== void 0) out.trpc = trpc;
3132
+ return out;
3133
+ }
3134
+ /**
3135
+ * Is a settings read failure worth retrying, and with which budget? Only
3136
+ * EXPLICIT signals count: a socket error code, a tRPC "unavailable" code, or
3137
+ * one of the exact phrases our own transport raises. A message that merely
3138
+ * contains "timed out" or "unreachable" is not evidence of anything, and
3139
+ * `settings store not wired` is a wiring bug that retrying cannot fix.
3140
+ */
3141
+ function classifyStoreError(err) {
3142
+ const message = err instanceof Error ? err.message : String(err);
3143
+ if (RESTART_FINGERPRINTS.some((f) => message.includes(f))) return "restart";
3144
+ const code = errorCode(err);
3145
+ if (code.node !== void 0 && TRANSPORT_CODES.has(code.node)) return "transport";
3146
+ if (code.trpc !== void 0 && UNAVAILABLE_TRPC_CODES.has(code.trpc)) return "transport";
3147
+ if (typeof err === "object" && err !== null) {
3148
+ if (Reflect.get(err, "retryable") === true) return "transport";
3149
+ const type = stringProp(err, "type");
3150
+ if (type !== void 0 && MOLECULER_TRANSIENT_TYPES.has(type)) return "transport";
3151
+ }
3152
+ if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
3153
+ return "permanent";
3154
+ }
3063
3155
  /**
3064
3156
  * Collect the keys of every field marked `perNode: true`, recursing into
3065
3157
  * layout containers (`group` fields and `sub-tabs` tabs) the same way
@@ -4515,7 +4607,7 @@ function sleep(ms) {
4515
4607
  return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
4516
4608
  }
4517
4609
  //#endregion
4518
- //#region ../types/dist/err-msg-DLerKiVO.mjs
4610
+ //#region ../types/dist/err-msg--2RrYiLO.mjs
4519
4611
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
4520
4612
  DeviceType["Camera"] = "camera";
4521
4613
  DeviceType["Hub"] = "hub";
@@ -4784,6 +4876,9 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
4784
4876
  /** Virtual HA toggle (input_boolean.*) — distinguishable from a
4785
4877
  * real Switch device for UI rendering / export adapters. */
4786
4878
  DeviceRole["BinaryHelper"] = "binary-helper";
4879
+ /** A smart plug: a `switch` whose source says it is an outlet (HA
4880
+ * `device_class: outlet`). The Alexa export shows it as a SMARTPLUG. */
4881
+ DeviceRole["Outlet"] = "outlet";
4787
4882
  /** Generic motion / occupancy / moving event source. Distinct from
4788
4883
  * the camera accessory PirSensor role: that one is a camera child;
4789
4884
  * this is a standalone HA / 3rd-party motion sensor. */
@@ -4861,7 +4956,7 @@ function errMsg(err) {
4861
4956
  return String(err);
4862
4957
  }
4863
4958
  //#endregion
4864
- //#region ../types/dist/composition-EQ9Ok0Ee.mjs
4959
+ //#region ../types/dist/composition-DOwQB_Ua.mjs
4865
4960
  var AUDIO_ENCODER_BY_CODEC = {
4866
4961
  opus: "libopus",
4867
4962
  aac: "aac",
@@ -16168,6 +16263,89 @@ id: zod.z.union([zod.z.string(), zod.z.number()]) }), {
16168
16263
  })
16169
16264
  }
16170
16265
  };
16266
+ /** One table of the settings database. */
16267
+ var StorageTableSchema = zod.z.object({
16268
+ /** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
16269
+ name: zod.z.string(),
16270
+ /** The owner prefix of a scoped name (`recorder` for `recorder:addon-settings`), else null. */
16271
+ owner: zod.z.string().nullable(),
16272
+ rows: zod.z.number().int().nonnegative(),
16273
+ /** Bytes the table's pages occupy (`dbstat`); null when the engine cannot measure. */
16274
+ bytes: zod.z.number().int().nonnegative().nullable(),
16275
+ /** Declared by an addon since this engine process started (a running addon claims it). */
16276
+ declaredThisBoot: zod.z.boolean()
16277
+ });
16278
+ /**
16279
+ * The collections retired by exact name: the D870 ones (their data became keys
16280
+ * of the camera's settings) and the three D871 leftovers (the `stats-5m` tables
16281
+ * superseded by `stats-5m-v2`, and the unread `vec_object_clip`). No addon
16282
+ * declares any of them any more; the engine still refuses one a running addon
16283
+ * declared this boot. `dropCollection` may remove these, the
16284
+ * per-addon scoped `addon-settings` / `addon-devices` / `sections` tables, and
16285
+ * the tables of owners that are no longer installed - nothing else.
16286
+ */
16287
+ var STORAGE_ADMIN_MOVED_COLLECTIONS = [
16288
+ "stream-broker:probe-snapshots",
16289
+ "stream-broker:profile-map",
16290
+ "stream-broker:rtsp-tokens",
16291
+ "notification-center:device-mutes",
16292
+ "recorder:recording-configs",
16293
+ "pipeline-orchestrator:device-features",
16294
+ "pipeline-analytics:stats-5m",
16295
+ "pipeline-orchestrator:stats-5m",
16296
+ "vec_object_clip"
16297
+ ];
16298
+ /** The per-addon blob tables a scoped name may carry. */
16299
+ var STORAGE_ADMIN_SCOPED_BASES = [
16300
+ "addon-settings",
16301
+ "addon-devices",
16302
+ "sections"
16303
+ ];
16304
+ /**
16305
+ * storage-admin - the operator's maintenance reach into the settings database:
16306
+ * list its tables, drop one that nothing owns any more (D870).
16307
+ *
16308
+ * Hub-only, internal and `auth: 'admin'` explicitly (`internal` does not gate
16309
+ * the mount, see `data-store-provider`). Both methods are LOGGED by the engine
16310
+ * with the table and the counts. `dropCollection` is a ONE-SHOT of the D870
16311
+ * migration and is marked for removal once the last hub has run it.
16312
+ *
16313
+ * `listTables` is READ-ONLY: it never creates a table, which `count` and `get`
16314
+ * on an undeclared scoped name used to do.
16315
+ */
16316
+ var storageAdminCapability = {
16317
+ name: "storage-admin",
16318
+ scope: "system",
16319
+ mode: "singleton",
16320
+ internal: true,
16321
+ methods: {
16322
+ /**
16323
+ * Every table of the settings database with its row count and size,
16324
+ * optionally only those owned by `ownerPrefix`. Reads only.
16325
+ */
16326
+ listTables: method(zod.z.object({ ownerPrefix: zod.z.string().min(1).optional() }), zod.z.object({ tables: zod.z.array(StorageTableSchema) }), { auth: "admin" }),
16327
+ /**
16328
+ * Drop one table. REFUSES when an addon declared it since the engine
16329
+ * started (a running addon still owns it), when it is an engine or
16330
+ * canonical table, when it does not exist, or when its row count is not
16331
+ * `expectRows` - the caller states what it believes it is deleting. The
16332
+ * engine also refuses anything but `<owner>:(addon-settings|addon-devices|
16333
+ * sections)`, the retired collections by name, and tables of owners that
16334
+ * are not installed (and refuses when it cannot read the installed list).
16335
+ * Removed with the D870 migration script once the last hub ran it.
16336
+ */
16337
+ dropCollection: method(zod.z.object({
16338
+ collection: zod.z.string().min(1),
16339
+ expectRows: zod.z.number().int().nonnegative()
16340
+ }), zod.z.object({
16341
+ dropped: zod.z.literal(true),
16342
+ rows: zod.z.number().int().nonnegative()
16343
+ }), {
16344
+ kind: "mutation",
16345
+ auth: "admin"
16346
+ })
16347
+ }
16348
+ };
16171
16349
  /**
16172
16350
  * `keychain` — the hub's encrypted store of secret values (D787).
16173
16351
  *
@@ -16904,6 +17082,24 @@ var keychainAdminCapability = {
16904
17082
  auth: "admin",
16905
17083
  caller: "required"
16906
17084
  }),
17085
+ /**
17086
+ * Store a value an operator tool carries over from a retired store at an
17087
+ * addon's own ref (`secret://<owner>/<scope>/<path>`) and answer the ref -
17088
+ * the D870 migration moves a camera's restream tokens this way, so they
17089
+ * never sit in a settings row as plaintext. Audited as the operator; the
17090
+ * caller then writes the MARKER of the ref where the value used to be.
17091
+ */
17092
+ importSecret: method(zod.z.object({
17093
+ ref: zod.z.string().min(1),
17094
+ value: zod.z.string().min(1)
17095
+ }), zod.z.object({
17096
+ ref: zod.z.string(),
17097
+ version: zod.z.number().int()
17098
+ }), {
17099
+ kind: "mutation",
17100
+ auth: "admin",
17101
+ caller: "required"
17102
+ }),
16907
17103
  /** Delete refs no owner points at any more. Re-checked here; `unknown` is kept. */
16908
17104
  deleteOrphans: method(zod.z.object({ refs: zod.z.array(zod.z.string().min(1)).max(1e3) }), zod.z.object({
16909
17105
  deleted: zod.z.array(zod.z.string()).readonly(),
@@ -58990,6 +59186,12 @@ var ClimateControlStatusSchema = zod.z.object({
58990
59186
  /** Horizontal louver swing on/off. Null when the device has no
58991
59187
  * horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
58992
59188
  swingHorizontal: zod.z.boolean().nullable(),
59189
+ /** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
59190
+ minTemp: zod.z.number().nullable().optional(),
59191
+ /** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
59192
+ maxTemp: zod.z.number().nullable().optional(),
59193
+ /** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
59194
+ tempStep: zod.z.number().positive().nullable().optional(),
58993
59195
  /** Ms epoch when the slice was last updated (push or command). */
58994
59196
  lastFetchedAt: zod.z.number()
58995
59197
  });
@@ -76107,6 +76309,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
76107
76309
  addonId: null,
76108
76310
  access: "create"
76109
76311
  },
76312
+ "keychainAdmin.importSecret": {
76313
+ capName: "keychain-admin",
76314
+ capScope: "system",
76315
+ addonId: null,
76316
+ access: "create"
76317
+ },
76110
76318
  "keychainAdmin.listAudit": {
76111
76319
  capName: "keychain-admin",
76112
76320
  capScope: "system",
@@ -79893,6 +80101,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
79893
80101
  addonId: null,
79894
80102
  access: "create"
79895
80103
  },
80104
+ "storageAdmin.dropCollection": {
80105
+ capName: "storage-admin",
80106
+ capScope: "system",
80107
+ addonId: null,
80108
+ access: "delete"
80109
+ },
80110
+ "storageAdmin.listTables": {
80111
+ capName: "storage-admin",
80112
+ capScope: "system",
80113
+ addonId: null,
80114
+ access: "view"
80115
+ },
79896
80116
  "storageEvictable.evict": {
79897
80117
  capName: "storage-evictable",
79898
80118
  capScope: "system",
@@ -81537,6 +81757,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
81537
81757
  snapshotCapability,
81538
81758
  ssoBridgeCapability,
81539
81759
  storageCapability,
81760
+ storageAdminCapability,
81540
81761
  storageEvictableCapability,
81541
81762
  storageMigrationCapability,
81542
81763
  storageOccupancyCapability,
@@ -86265,6 +86486,18 @@ Object.defineProperty(exports, "STORAGE_ACCESS_FALLBACK", {
86265
86486
  return STORAGE_ACCESS_FALLBACK;
86266
86487
  }
86267
86488
  });
86489
+ Object.defineProperty(exports, "STORAGE_ADMIN_MOVED_COLLECTIONS", {
86490
+ enumerable: true,
86491
+ get: function() {
86492
+ return STORAGE_ADMIN_MOVED_COLLECTIONS;
86493
+ }
86494
+ });
86495
+ Object.defineProperty(exports, "STORAGE_ADMIN_SCOPED_BASES", {
86496
+ enumerable: true,
86497
+ get: function() {
86498
+ return STORAGE_ADMIN_SCOPED_BASES;
86499
+ }
86500
+ });
86268
86501
  Object.defineProperty(exports, "STREAM_PROFILE_META", {
86269
86502
  enumerable: true,
86270
86503
  get: function() {
@@ -87201,6 +87434,12 @@ Object.defineProperty(exports, "splitTranslationRef", {
87201
87434
  return splitTranslationRef;
87202
87435
  }
87203
87436
  });
87437
+ Object.defineProperty(exports, "storageAdminCapability", {
87438
+ enumerable: true,
87439
+ get: function() {
87440
+ return storageAdminCapability;
87441
+ }
87442
+ });
87204
87443
  Object.defineProperty(exports, "storageCapability", {
87205
87444
  enumerable: true,
87206
87445
  get: function() {
@@ -1,5 +1,5 @@
1
1
  require("./chunk-Cek0wNdY.js");
2
- const require_wal_maintenance = require("./wal-maintenance-DEL_jeG0.js");
2
+ const require_wal_maintenance = require("./wal-maintenance-CgZTNWAz.js");
3
3
  let node_worker_threads = require("node:worker_threads");
4
4
  //#region src/builtins/sqlite-storage/file-host-worker.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { C as callControl, E as controlTargetOf, T as callVector, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, c as SqliteSettingsBackend, h as serializeError, o as createVectorIndex, s as vectorProviderOf, w as callData, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-xsvdT5Go.mjs";
1
+ import { C as callData, S as callControl, T as controlTargetOf, a as WalMaintenance, b as trustInput, c as SqliteSettingsBackend, g as collectTransferables, m as serializeError, o as createVectorIndex, s as vectorProviderOf, v as isFileHostRequest, w as callVector, y as isFileHostWorkerData } from "./wal-maintenance-B57SAp4a.mjs";
2
2
  import { parentPort, threadId, workerData } from "node:worker_threads";
3
3
  //#region src/builtins/sqlite-storage/file-host-worker.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "./chunk-CNf5ZN-e.mjs";
2
- import { vi as userError } from "./dist-yI6kF6r6.mjs";
2
+ import { xi as userError } from "./dist-BWvkuc31.mjs";
3
3
  import { f as X509Certificate$1 } from "./x509.es-DK__ETIe.mjs";
4
4
  import { A as isConstrainedCa, E as reasonRequiresNewCa, M as permitsIdentity, P as readNameConstraints, T as evaluateExistingCert, _ as issueLeaf, g as generateCa, v as loadCa, y as collectCertIdentity } from "./agent-https-U0d4uvn2.mjs";
5
5
  import { X509Certificate, createPrivateKey } from "node:crypto";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-BOWdLjoK.js");
2
+ const require_dist = require("./dist-BiTCcaf-.js");
3
3
  const require_x509_es = require("./x509.es-C4cOo48M.js");
4
4
  const require_agent_https = require("./agent-https-DlpTMDqA.js");
5
5
  let node_crypto = require("node:crypto");