@camstack/system 1.2.438 → 1.2.440

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 (120) 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/{agent-https-BZIwS4xF.js → agent-https-DlpTMDqA.js} +252 -22
  6. package/dist/{agent-https-BPfHrI4c.mjs → agent-https-U0d4uvn2.mjs} +211 -23
  7. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  10. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  11. package/dist/builtins/alerts/alerts.addon.js +1 -1
  12. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  13. package/dist/builtins/autotrack/index.js +1 -1
  14. package/dist/builtins/autotrack/index.mjs +1 -1
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  16. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  17. package/dist/builtins/calendars/calendars.addon.js +1 -1
  18. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  19. package/dist/builtins/camera-grid/index.js +1 -1
  20. package/dist/builtins/camera-grid/index.mjs +1 -1
  21. package/dist/builtins/composer/composer.addon.js +2 -2
  22. package/dist/builtins/composer/composer.addon.mjs +2 -2
  23. package/dist/builtins/console-logging/index.js +1 -1
  24. package/dist/builtins/console-logging/index.mjs +1 -1
  25. package/dist/builtins/core-blocks/block-settings-store.d.ts +1 -1
  26. package/dist/builtins/core-blocks/core-blocks.addon.js +77 -11
  27. package/dist/builtins/core-blocks/core-blocks.addon.mjs +77 -12
  28. package/dist/builtins/core-blocks/index.mjs +1 -1
  29. package/dist/builtins/device-manager/device-manager.addon.js +197 -60
  30. package/dist/builtins/device-manager/device-manager.addon.mjs +196 -61
  31. package/dist/builtins/device-manager/device-removal-hooks.d.ts +0 -11
  32. package/dist/builtins/device-manager/device-tombstone-store.d.ts +12 -2
  33. package/dist/builtins/hub-forwarder/index.js +1 -1
  34. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  35. package/dist/builtins/keychain/index.js +29 -11
  36. package/dist/builtins/keychain/index.mjs +29 -11
  37. package/dist/builtins/keychain/keychain-service.d.ts +8 -0
  38. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  39. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  40. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  41. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  42. package/dist/builtins/local-network/local-network.addon.js +7 -2
  43. package/dist/builtins/local-network/local-network.addon.mjs +7 -2
  44. package/dist/builtins/loki-logging/index.js +1 -1
  45. package/dist/builtins/loki-logging/index.mjs +1 -1
  46. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  47. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  48. package/dist/builtins/platform-probe/index.js +1 -1
  49. package/dist/builtins/platform-probe/index.mjs +1 -1
  50. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  51. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  52. package/dist/builtins/snapshot/index.js +1 -1
  53. package/dist/builtins/snapshot/index.mjs +1 -1
  54. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  55. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  56. package/dist/builtins/sqlite-storage/index.js +1 -1
  57. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  58. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +38 -7
  59. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +69 -3
  60. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +69 -3
  61. package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +31 -0
  62. package/dist/builtins/storage-orchestrator/hub-settings-forward.d.ts +3 -3
  63. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +4 -4
  64. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +4 -4
  65. package/dist/builtins/system-config/system-config.addon.js +4 -4
  66. package/dist/builtins/system-config/system-config.addon.mjs +285 -285
  67. package/dist/builtins/winston-logging/index.js +1 -1
  68. package/dist/builtins/winston-logging/index.mjs +1 -1
  69. package/dist/{composition-sources-DpHGCjdL.mjs → composition-sources-CS0D7imL.mjs} +1 -1
  70. package/dist/{composition-sources-DI3Z83vG.js → composition-sources-cBG8fBTu.js} +1 -1
  71. package/dist/{constants-DQK705Sb.mjs → constants-CIzPjw7L.mjs} +1 -1
  72. package/dist/{constants-wkcn5Ij3.js → constants-CRI3QzT4.js} +1 -1
  73. package/dist/{device-ca-DvIZjXIl.mjs → device-ca-DLKXYseS.mjs} +2 -2
  74. package/dist/{device-ca-BSvkXqyI.js → device-ca-DNHjts4_.js} +2 -2
  75. package/dist/{dist-Dc8GKC5H.mjs → dist-9fcsrFU3.mjs} +271 -32
  76. package/dist/{dist-GgG-7amw.js → dist-BKhlcYz6.js} +288 -31
  77. package/dist/file-host-worker.js +1 -1
  78. package/dist/file-host-worker.mjs +1 -1
  79. package/dist/{hub-mdns-ciao-CBLvq2oj.js → hub-mdns-ciao-3Zc9G9MS.js} +377 -69
  80. package/dist/{hub-mdns-ciao-DMlQTdPU.mjs → hub-mdns-ciao-Dy2YjRqC.mjs} +344 -72
  81. package/dist/index.js +372 -339
  82. package/dist/index.mjs +361 -341
  83. package/dist/kernel/addon-settings-store.d.ts +43 -0
  84. package/dist/kernel/config-manager.d.ts +0 -19
  85. package/dist/kernel/device-settings-store.d.ts +74 -0
  86. package/dist/kernel/legacy-blob-guard.d.ts +58 -0
  87. package/dist/kernel/moleculer/runner-addon-settings.d.ts +34 -0
  88. package/dist/kernel/moleculer/runner-device-settings.d.ts +39 -0
  89. package/dist/kernel/prefix-walk.d.ts +39 -0
  90. package/dist/kernel/sections-store.d.ts +20 -0
  91. package/dist/kernel/settings-door-view.d.ts +2 -2
  92. package/dist/kernel/settings-view-types.d.ts +5 -30
  93. package/dist/kernel/store-settings-view.d.ts +0 -3
  94. package/dist/{lib-NNxHSOIE.js → lib-8oZrELLm.js} +1 -1
  95. package/dist/{lib-BeGzVQcd.mjs → lib-DK38ompL.mjs} +1 -1
  96. package/dist/prefix-range-D_KueXbQ.js +27 -0
  97. package/dist/prefix-range-Dl0znowN.mjs +22 -0
  98. package/dist/prefix-walk-DAOBSyH1.mjs +88 -0
  99. package/dist/prefix-walk-Dv6MLZlM.js +99 -0
  100. package/dist/{restore-archive-CTRz8v9o.js → restore-archive-49aZwkp8.js} +1 -1
  101. package/dist/{restore-archive-DPg9duVY.mjs → restore-archive-DgvDecXM.mjs} +82 -82
  102. package/dist/{retired-settings-keys-Is0zO8gX.mjs → retired-settings-keys-Bhwe4ymb.mjs} +2 -2
  103. package/dist/{retired-settings-keys-Dr_4lfKu.js → retired-settings-keys-D_VwZiDt.js} +10 -4
  104. package/dist/tls/agent-https.d.ts +2 -2
  105. package/dist/tls/boot-tls.d.ts +6 -0
  106. package/dist/tls/cert-evaluation.d.ts +1 -1
  107. package/dist/tls/cert-issue.d.ts +5 -1
  108. package/dist/tls/cert-manager.d.ts +18 -0
  109. package/dist/tls/cert-name-constraints.d.ts +53 -0
  110. package/dist/tls/index.d.ts +5 -4
  111. package/dist/tls/tls-actions.d.ts +27 -7
  112. package/dist/tls/tls-status.d.ts +22 -0
  113. package/dist/tls/uploaded-cert.d.ts +36 -4
  114. package/dist/{wal-maintenance-Bx3lcVA7.mjs → wal-maintenance-BZGmF-3U.mjs} +0 -0
  115. package/dist/{wal-maintenance-mjB2i-VR.js → wal-maintenance-C041zn6V.js} +0 -0
  116. package/dist/{x509.es-r7Ht1thA.js → x509.es-C4cOo48M.js} +36 -0
  117. package/dist/{x509.es-CDvj67p1.mjs → x509.es-DK__ETIe.mjs} +1 -1
  118. package/package.json +7 -2
  119. package/dist/{custom-action-registry-Bf_YnagS.js → custom-action-registry-BKmoaqG0.js} +1 -1
  120. package/dist/{custom-action-registry-BQnbN0DP.mjs → custom-action-registry-CyUuhATc.mjs} +1 -1
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  //#region src/builtins/loki-logging/loki-payload.ts
8
8
  /**
9
9
  * Loki rejects a label name that is not a valid Prometheus label
@@ -1,4 +1,4 @@
1
- import { Or as BaseAddon, mn as logDestinationCapability } from "../../dist-Dc8GKC5H.mjs";
1
+ import { gn as logDestinationCapability, jr as BaseAddon } from "../../dist-9fcsrFU3.mjs";
2
2
  //#region src/builtins/loki-logging/loki-payload.ts
3
3
  /**
4
4
  * Loki rejects a label name that is not a valid Prometheus label
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  let node_fs_promises = require("node:fs/promises");
8
8
  let node_os = require("node:os");
9
9
  node_os = require_chunk.__toESM(node_os);
@@ -1,4 +1,4 @@
1
- import { Dr as errMsg, In as resolveBucketMs, Jt as foldSnapshotByFunction, Nn as reducePoints, Or as BaseAddon, Wr as createEvent, bn as metricsProviderCapability, yi as EventCategory } from "../../dist-Dc8GKC5H.mjs";
1
+ import { Ar as errMsg, Fn as reducePoints, Rn as resolveBucketMs, Si as EventCategory, Sn as metricsProviderCapability, Xt as foldSnapshotByFunction, jr as BaseAddon, qr as createEvent } from "../../dist-9fcsrFU3.mjs";
2
2
  import { access, readFile, readdir } from "node:fs/promises";
3
3
  import * as os$1 from "node:os";
4
4
  import { platform } from "node:os";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  let node_os = require("node:os");
8
8
  node_os = require_chunk.__toESM(node_os);
9
9
  let node_fs = require("node:fs");
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM, r as __exportAll } from "../../chunk-CNf5ZN-e.mjs";
2
- import { An as platformProbeCapability, Dr as errMsg, Jr as emitReadiness, Kn as scoreRuntimes, Or as BaseAddon, yi as EventCategory, zt as enumerateInferenceDevices } from "../../dist-Dc8GKC5H.mjs";
2
+ import { Ar as errMsg, Jn as scoreRuntimes, Mn as platformProbeCapability, Si as EventCategory, Vt as enumerateInferenceDevices, Zr as emitReadiness, jr as BaseAddon } from "../../dist-9fcsrFU3.mjs";
3
3
  import * as os$1 from "node:os";
4
4
  import * as fs from "node:fs";
5
5
  import { execFile } from "node:child_process";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
8
8
  /**
9
9
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -1,4 +1,4 @@
1
- import { Or as BaseAddon, yi as EventCategory } from "../../dist-Dc8GKC5H.mjs";
1
+ import { Si as EventCategory, jr as BaseAddon } from "../../dist-9fcsrFU3.mjs";
2
2
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
3
3
  /**
4
4
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  const require_snapshot_courtesy = require("../../snapshot-courtesy-D_C5-nC0.js");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { Dr as errMsg, Er as DeviceType, Mt as deriveBatteryPresence, Or as BaseAddon, Xn as snapshotCapability, ct as bareAddonId, ii as nodePin, lt as batteryCapability, rr as streamQualityLabel, s as BatteryStatusSchema, wr as DeviceFeature, yi as EventCategory, yn as memoizePinnedFfmpeg } from "../../dist-Dc8GKC5H.mjs";
1
+ import { Ar as errMsg, Dr as DeviceFeature, Pt as deriveBatteryPresence, Qn as snapshotCapability, Si as EventCategory, dt as batteryCapability, jr as BaseAddon, kr as DeviceType, or as streamQualityLabel, s as BatteryStatusSchema, si as nodePin, ut as bareAddonId, xn as memoizePinnedFfmpeg } from "../../dist-9fcsrFU3.mjs";
2
2
  import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-CyFs1M3I.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let node_fs_promises = require("node:fs/promises");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Or as BaseAddon, qt as filesystemBrowseCapability, tr as storageProviderCapability } from "../../dist-Dc8GKC5H.mjs";
1
+ import { Yt as filesystemBrowseCapability, ir as storageProviderCapability, jr as BaseAddon } from "../../dist-9fcsrFU3.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
4
4
  import * as path$1 from "node:path";
@@ -4,7 +4,7 @@ Object.defineProperties(exports, {
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
6
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./filesystem-storage.addon.js");
7
- const require_wal_maintenance = require("../../wal-maintenance-mjB2i-VR.js");
7
+ const require_wal_maintenance = require("../../wal-maintenance-C041zn6V.js");
8
8
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./sqlite-settings.addon.js");
9
9
  //#region src/builtins/sqlite-storage/config-store.ts
10
10
  var ConfigStore = class {
@@ -1,5 +1,5 @@
1
1
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./filesystem-storage.addon.mjs";
2
- import { A as SQLITE_PAGE_CACHE_CEILING_KIB, B as sqliteEngineStorm, D as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, F as SQLITE_PROFILE_REPORT_FLOOR_MS, I as SQLITE_PROFILE_REPORT_INTERVAL_MS, L as SQLITE_PROFILE_TOP_N, M as sqliteMmapSizeFor, N as sqlitePageCacheKibFor, O as SQLITE_MMAP_CEILING_BYTES, P as SQLITE_ENGINE_STORM_WALL_SHARE, R as SQLITE_SLOW_CALL_MS, a as WalMaintenance, c as SqliteSettingsBackend, i as WAL_MAINTENANCE_INTERVAL_MS, j as SQLITE_PAGE_CACHE_FLOOR_KIB, k as SQLITE_MMAP_FLOOR_BYTES, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as SqliteOpProfiler } from "../../wal-maintenance-Bx3lcVA7.mjs";
2
+ import { A as SQLITE_PAGE_CACHE_FLOOR_KIB, D as SQLITE_MMAP_CEILING_BYTES, E as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, F as SQLITE_PROFILE_REPORT_INTERVAL_MS, I as SQLITE_PROFILE_TOP_N, L as SQLITE_SLOW_CALL_MS, M as sqlitePageCacheKibFor, N as SQLITE_ENGINE_STORM_WALL_SHARE, O as SQLITE_MMAP_FLOOR_BYTES, P as SQLITE_PROFILE_REPORT_FLOOR_MS, R as SqliteOpProfiler, a as WalMaintenance, c as SqliteSettingsBackend, i as WAL_MAINTENANCE_INTERVAL_MS, j as sqliteMmapSizeFor, k as SQLITE_PAGE_CACHE_CEILING_KIB, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as sqliteEngineStorm } from "../../wal-maintenance-BZGmF-3U.mjs";
3
3
  import { SqliteSettingsAddon } from "./sqlite-settings.addon.mjs";
4
4
  //#region src/builtins/sqlite-storage/config-store.ts
5
5
  var ConfigStore = class {
@@ -167,6 +167,8 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
167
167
  * the structured schema owns. Routes set/get/insert/update/query to
168
168
  * typed columns. Every collection MUST be declared here before use. */
169
169
  private readonly declaredCollections;
170
+ /** Tables an addon declared since THIS process started - a running addon claims them. */
171
+ private readonly declaredThisBoot;
170
172
  private readonly runtimeDefaults;
171
173
  /**
172
174
  * Canonical key/value collections — declared with a `(id TEXT PK,
@@ -193,6 +195,23 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
193
195
  private readonly options;
194
196
  constructor(dbPath: string, runtimeDefaults?: Record<string, unknown>, logger?: IScopedLogger, options?: SqliteSettingsBackendOptions);
195
197
  initialize(): Promise<void>;
198
+ /**
199
+ * The declaration a READ needs, or `null` when the table does not exist.
200
+ *
201
+ * A per-addon scoped canonical table (`<addonId>:addon-settings`, ...) is
202
+ * auto-declared on first use, and that used to include a READ: asking
203
+ * `count` or `get` about a scoped name that was never written CREATED the
204
+ * table. A read of a table nobody wrote is "absent" (D870), and creating an
205
+ * empty table per probed name is how an enumeration litters the database.
206
+ */
207
+ private declaredForRead;
208
+ /**
209
+ * Per-addon tables the runner used to keep (`<addonId>:addon-devices`, D870).
210
+ * Nothing writes them any more; they stay READABLE, by their old name, until
211
+ * the migration's drop phase removes them.
212
+ */
213
+ private static readonly LEGACY_SCOPED_KV_COLLECTIONS;
214
+ private declareLegacyScopedKv;
196
215
  private requireDeclared;
197
216
  /**
198
217
  * Decode a single column value off a SQLite row into the JS shape the
@@ -392,13 +411,8 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
392
411
  getAllDevice(deviceId: string): Record<string, unknown>;
393
412
  /** Set a device setting */
394
413
  setDevice(deviceId: string, key: string, value: unknown): void;
395
- getAddonDevice(addonId: string, deviceId: string): Record<string, unknown>;
396
- setAddonDevice(addonId: string, deviceId: string, values: Record<string, unknown>): void;
397
- clearAddonDevice(addonId: string, deviceId: string): void;
398
- private static readonly LEGACY_RUNTIME_STATE_ADDON_ID;
399
414
  /**
400
- * The device's whole cap-slice map. Canonical row first, legacy prefix as the
401
- * fallback. `{}` — never null — when the device has never persisted a slice,
415
+ * The device's whole cap-slice map. `{}` — never null — when the device has never persisted a slice,
402
416
  * because every caller treats the result as a cap map to iterate.
403
417
  */
404
418
  getDeviceRuntimeState(deviceId: string): Record<string, unknown>;
@@ -408,7 +422,7 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
408
422
  * slice the durability policy has since stopped persisting.
409
423
  */
410
424
  setDeviceRuntimeState(deviceId: string, blob: Record<string, unknown>): void;
411
- /** Forget the device's runtime state in BOTH stores (device removal). */
425
+ /** Forget the device's runtime state (device removal). */
412
426
  clearDeviceRuntimeState(deviceId: string): void;
413
427
  /** Seed system-settings with runtime defaults (first boot) */
414
428
  private seedDefaults;
@@ -421,6 +435,23 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
421
435
  /** Which file this backend serves. */
422
436
  getDatabaseId(): DataStoreDatabase;
423
437
  /**
438
+ * Every table of this file with rows and size. READ-ONLY: nothing is created,
439
+ * and no declaration is consulted or changed.
440
+ */
441
+ listTables(ownerPrefix?: string): readonly {
442
+ name: string;
443
+ owner: string | null;
444
+ rows: number;
445
+ bytes: number | null;
446
+ declaredThisBoot: boolean;
447
+ }[];
448
+ /**
449
+ * Drop one table nobody owns (D870 migration, one-shot). Refuses a canonical
450
+ * or engine table, one a running addon declared since boot, a table that is
451
+ * not there, and a row count other than the one the caller stated.
452
+ */
453
+ dropTable(name: string, expectRows: number): number;
454
+ /**
424
455
  * The tables this file's own `_collection_declarations` names — the
425
456
  * placement authority (D851). Read from DISK, not from memory, so a table
426
457
  * created and declared by an earlier life of the process still counts.
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
7
- const require_retired_settings_keys = require("../../retired-settings-keys-Dr_4lfKu.js");
8
- const require_wal_maintenance = require("../../wal-maintenance-mjB2i-VR.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
+ const require_retired_settings_keys = require("../../retired-settings-keys-D_VwZiDt.js");
8
+ const require_wal_maintenance = require("../../wal-maintenance-C041zn6V.js");
9
9
  const require_sqlite_snapshot_protocol = require("../../sqlite-snapshot-protocol-B9OndqZv.js");
10
10
  const require_wal_checkpoint_policy = require("../../wal-checkpoint-policy-d2z2qPqx.js");
11
11
  let node_fs_promises = require("node:fs/promises");
@@ -1204,6 +1204,68 @@ var PlacementRouter = class {
1204
1204
  }
1205
1205
  };
1206
1206
  //#endregion
1207
+ //#region src/builtins/sqlite-storage/storage-admin-provider.ts
1208
+ /**
1209
+ * The `storage-admin` provider of the SQLite engine (D870): the operator's
1210
+ * maintenance reach into the settings database - list its tables, drop one that
1211
+ * nothing owns any more. Every call is logged with its table and counts.
1212
+ *
1213
+ * `dropCollection` is a one-shot of the D870 migration: remove it, and the
1214
+ * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
1215
+ */
1216
+ var StorageAdminProvider = class {
1217
+ backend;
1218
+ logger;
1219
+ installedOwners;
1220
+ constructor(backend, logger, installedOwners) {
1221
+ this.backend = backend;
1222
+ this.logger = logger;
1223
+ this.installedOwners = installedOwners;
1224
+ }
1225
+ /** May this table be dropped AT ALL? Throws with the reason when not. */
1226
+ async assertDroppable(collection) {
1227
+ const colon = collection.indexOf(":");
1228
+ const base = colon > 0 ? collection.slice(colon + 1) : "";
1229
+ if (colon > 0 && require_dist.STORAGE_ADMIN_SCOPED_BASES.includes(base)) return;
1230
+ if (require_dist.STORAGE_ADMIN_MOVED_COLLECTIONS.includes(collection)) return;
1231
+ if (colon <= 0) throw new Error(`drop refused: "${collection}" is not a scoped table`);
1232
+ const installed = await this.installedOwners().catch((err) => {
1233
+ throw new Error(`drop refused: the installed addons could not be read (${err instanceof Error ? err.message : String(err)})`);
1234
+ });
1235
+ const owner = collection.slice(0, colon);
1236
+ if (installed.has(owner)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1237
+ }
1238
+ async listTables(input) {
1239
+ const tables = this.backend.listTables(input.ownerPrefix);
1240
+ this.logger.info("storage-admin: listed tables", { meta: {
1241
+ tables: tables.length,
1242
+ ownerPrefix: input.ownerPrefix ?? null
1243
+ } });
1244
+ return { tables: [...tables] };
1245
+ }
1246
+ async dropCollection(input) {
1247
+ try {
1248
+ await this.assertDroppable(input.collection);
1249
+ const rows = this.backend.dropTable(input.collection, input.expectRows);
1250
+ this.logger.warn("storage-admin: DROPPED a table", { meta: {
1251
+ collection: input.collection,
1252
+ rows
1253
+ } });
1254
+ return {
1255
+ dropped: true,
1256
+ rows
1257
+ };
1258
+ } catch (err) {
1259
+ this.logger.warn("storage-admin: drop refused", { meta: {
1260
+ collection: input.collection,
1261
+ expectRows: input.expectRows,
1262
+ error: err instanceof Error ? err.message : String(err)
1263
+ } });
1264
+ throw err;
1265
+ }
1266
+ }
1267
+ };
1268
+ //#endregion
1207
1269
  //#region src/builtins/sqlite-storage/retired-collections.ts
1208
1270
  /**
1209
1271
  * The dead tables.
@@ -1420,6 +1482,10 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
1420
1482
  {
1421
1483
  capability: require_dist.databaseSnapshotCapability,
1422
1484
  provider: new DatabaseSnapshotProvider(router)
1485
+ },
1486
+ {
1487
+ capability: require_dist.storageAdminCapability,
1488
+ provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)))
1423
1489
  }
1424
1490
  ];
1425
1491
  }
@@ -1,6 +1,6 @@
1
- import { Dr as errMsg, Dt as dataStoreProviderCapability, Nr as RUNTIME_DEFAULTS, Or as BaseAddon, Ot as databaseSnapshotCapability, S as DATA_STORE_DATABASES, b as DATABASE_SNAPSHOT_SUFFIX, ct as bareAddonId, ur as vectorStoreCapability, x as DATABASE_SNAPSHOT_TIMEOUT_MS, y as DATABASE_SNAPSHOT_PARTIAL_SUFFIX } from "../../dist-Dc8GKC5H.mjs";
2
- import { r as retiredKeyStoreOf, t as purgeRetiredSettingsKeys } from "../../retired-settings-keys-Is0zO8gX.mjs";
3
- import { C as callControl, E as controlTargetOf, S as trustResult, T as callVector, _ as collectTransferables, a as WalMaintenance, c as SqliteSettingsBackend, d as CrossDatabaseTransactError, f as DatabaseBusyError, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callData } from "../../wal-maintenance-Bx3lcVA7.mjs";
1
+ import { Ar as errMsg, At as databaseSnapshotCapability, Ir as RUNTIME_DEFAULTS, J as STORAGE_ADMIN_SCOPED_BASES, S as DATA_STORE_DATABASES, b as DATABASE_SNAPSHOT_SUFFIX, er as storageAdminCapability, jr as BaseAddon, kt as dataStoreProviderCapability, pr as vectorStoreCapability, q as STORAGE_ADMIN_MOVED_COLLECTIONS, ut as bareAddonId, x as DATABASE_SNAPSHOT_TIMEOUT_MS, y as DATABASE_SNAPSHOT_PARTIAL_SUFFIX } from "../../dist-9fcsrFU3.mjs";
2
+ import { i as retiredKeyStoreOf, n as purgeRetiredSettingsKeys } from "../../retired-settings-keys-Bhwe4ymb.mjs";
3
+ import { C as callData, S as callControl, T as controlTargetOf, _ as isFileHostMessage, a as WalMaintenance, c as SqliteSettingsBackend, d as DatabaseBusyError, f as DuplicatePlacementError, g as collectTransferables, l as CollectionPlacementError, o as createVectorIndex, p as rehydrateError, s as vectorProviderOf, u as CrossDatabaseTransactError, w as callVector, x as trustResult } from "../../wal-maintenance-BZGmF-3U.mjs";
4
4
  import { r as isSnapshotWorkerMessage } from "../../sqlite-snapshot-protocol-2QaTouWV.mjs";
5
5
  import { a as isWorkerMessage, t as WAL_CHECKPOINT_LARGE_PASS_FRAMES } from "../../wal-checkpoint-policy-BahrTtyD.mjs";
6
6
  import { createRequire } from "node:module";
@@ -1198,6 +1198,68 @@ var PlacementRouter = class {
1198
1198
  }
1199
1199
  };
1200
1200
  //#endregion
1201
+ //#region src/builtins/sqlite-storage/storage-admin-provider.ts
1202
+ /**
1203
+ * The `storage-admin` provider of the SQLite engine (D870): the operator's
1204
+ * maintenance reach into the settings database - list its tables, drop one that
1205
+ * nothing owns any more. Every call is logged with its table and counts.
1206
+ *
1207
+ * `dropCollection` is a one-shot of the D870 migration: remove it, and the
1208
+ * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
1209
+ */
1210
+ var StorageAdminProvider = class {
1211
+ backend;
1212
+ logger;
1213
+ installedOwners;
1214
+ constructor(backend, logger, installedOwners) {
1215
+ this.backend = backend;
1216
+ this.logger = logger;
1217
+ this.installedOwners = installedOwners;
1218
+ }
1219
+ /** May this table be dropped AT ALL? Throws with the reason when not. */
1220
+ async assertDroppable(collection) {
1221
+ const colon = collection.indexOf(":");
1222
+ const base = colon > 0 ? collection.slice(colon + 1) : "";
1223
+ if (colon > 0 && STORAGE_ADMIN_SCOPED_BASES.includes(base)) return;
1224
+ if (STORAGE_ADMIN_MOVED_COLLECTIONS.includes(collection)) return;
1225
+ if (colon <= 0) throw new Error(`drop refused: "${collection}" is not a scoped table`);
1226
+ const installed = await this.installedOwners().catch((err) => {
1227
+ throw new Error(`drop refused: the installed addons could not be read (${err instanceof Error ? err.message : String(err)})`);
1228
+ });
1229
+ const owner = collection.slice(0, colon);
1230
+ if (installed.has(owner)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1231
+ }
1232
+ async listTables(input) {
1233
+ const tables = this.backend.listTables(input.ownerPrefix);
1234
+ this.logger.info("storage-admin: listed tables", { meta: {
1235
+ tables: tables.length,
1236
+ ownerPrefix: input.ownerPrefix ?? null
1237
+ } });
1238
+ return { tables: [...tables] };
1239
+ }
1240
+ async dropCollection(input) {
1241
+ try {
1242
+ await this.assertDroppable(input.collection);
1243
+ const rows = this.backend.dropTable(input.collection, input.expectRows);
1244
+ this.logger.warn("storage-admin: DROPPED a table", { meta: {
1245
+ collection: input.collection,
1246
+ rows
1247
+ } });
1248
+ return {
1249
+ dropped: true,
1250
+ rows
1251
+ };
1252
+ } catch (err) {
1253
+ this.logger.warn("storage-admin: drop refused", { meta: {
1254
+ collection: input.collection,
1255
+ expectRows: input.expectRows,
1256
+ error: err instanceof Error ? err.message : String(err)
1257
+ } });
1258
+ throw err;
1259
+ }
1260
+ }
1261
+ };
1262
+ //#endregion
1201
1263
  //#region src/builtins/sqlite-storage/retired-collections.ts
1202
1264
  /**
1203
1265
  * The dead tables.
@@ -1414,6 +1476,10 @@ var SqliteSettingsAddon = class extends BaseAddon {
1414
1476
  {
1415
1477
  capability: databaseSnapshotCapability,
1416
1478
  provider: new DatabaseSnapshotProvider(router)
1479
+ },
1480
+ {
1481
+ capability: storageAdminCapability,
1482
+ provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)))
1417
1483
  }
1418
1484
  ];
1419
1485
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The `storage-admin` provider of the SQLite engine (D870): the operator's
3
+ * maintenance reach into the settings database - list its tables, drop one that
4
+ * nothing owns any more. Every call is logged with its table and counts.
5
+ *
6
+ * `dropCollection` is a one-shot of the D870 migration: remove it, and the
7
+ * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
8
+ */
9
+ import { type IScopedLogger, type IStorageAdminProvider, type StorageTable } from "@camstack/types";
10
+ import type { SqliteSettingsBackend } from "./sqlite-settings-backend.js";
11
+ export declare class StorageAdminProvider implements IStorageAdminProvider {
12
+ private readonly backend;
13
+ private readonly logger;
14
+ /** The addon ids installed on this hub; a throw means "cannot tell" and refuses the drop. */
15
+ private readonly installedOwners;
16
+ constructor(backend: SqliteSettingsBackend, logger: IScopedLogger, installedOwners: () => Promise<ReadonlySet<string>>);
17
+ /** May this table be dropped AT ALL? Throws with the reason when not. */
18
+ private assertDroppable;
19
+ listTables(input: {
20
+ ownerPrefix?: string | undefined;
21
+ }): Promise<{
22
+ tables: StorageTable[];
23
+ }>;
24
+ dropCollection(input: {
25
+ collection: string;
26
+ expectRows: number;
27
+ }): Promise<{
28
+ dropped: true;
29
+ rows: number;
30
+ }>;
31
+ }
@@ -30,9 +30,9 @@
30
30
  *
31
31
  * Per-node scoping already exists, one layer up, and it is per FIELD:
32
32
  * `BaseAddon` persists a `perNode: true` schema field as `<key>@<nodeId>`
33
- * inside the addon's single shared blob (`packages/types/src/addon/
34
- * per-node-store.ts`). The agent therefore reads and writes the SAME row the
35
- * hub's copy of that addon reads — `<addonId>:addon-settings` / `root` — and
33
+ * inside the addon's settings (`packages/types/src/addon/
34
+ * per-node-store.ts`). The agent therefore reads and writes the SAME rows the
35
+ * hub's copy of that addon reads — `addon-settings` `<addonId>.<field>` (D870) — and
36
36
  * the two agree by construction. Introducing a second, addon-level
37
37
  * `(nodeId, addonId)` row here would be a second authority over one fact,
38
38
  * which is the shape [D224](../../../../../docs/decisions/adr-0224-the-freshness-of-a-camera-fact-lives-in-its-provider.md)
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  let zod = require("zod");
8
8
  let node_crypto = require("node:crypto");
9
9
  let _camstack_types_node = require("@camstack/types/node");
@@ -1491,9 +1491,9 @@ function createHubCapForwardService(onUnownedCall, options = {}) {
1491
1491
  *
1492
1492
  * Per-node scoping already exists, one layer up, and it is per FIELD:
1493
1493
  * `BaseAddon` persists a `perNode: true` schema field as `<key>@<nodeId>`
1494
- * inside the addon's single shared blob (`packages/types/src/addon/
1495
- * per-node-store.ts`). The agent therefore reads and writes the SAME row the
1496
- * hub's copy of that addon reads — `<addonId>:addon-settings` / `root` — and
1494
+ * inside the addon's settings (`packages/types/src/addon/
1495
+ * per-node-store.ts`). The agent therefore reads and writes the SAME rows the
1496
+ * hub's copy of that addon reads — `addon-settings` `<addonId>.<field>` (D870) — and
1497
1497
  * the two agree by construction. Introducing a second, addon-level
1498
1498
  * `(nodeId, addonId)` row here would be a second authority over one fact,
1499
1499
  * which is the shape [D224](../../../../../docs/decisions/adr-0224-the-freshness-of-a-camera-fact-lives-in-its-provider.md)
@@ -1,4 +1,4 @@
1
- import { $ as StorageLocationTypeSchema, $n as storageMigrationCapability, Bn as resolveLocationMode, Hr as collectSecretConfigKeys, Mr as REDACTED_SECRET, Or as BaseAddon, Q as StorageLocationModeSchema, Qn as storageCapability, Ut as evictionPolicyOfLocation, Z as StorageCleanupJobSchema, Zt as gbToBytes, _i as transformSecretWrite, _n as mayReadLocation, di as resolveSecretMarkers, dr as withLocationMode, et as StorageMigrationJobSchema, ni as isSecretMarker, oi as parseJsonObject, pi as secretTreeFromPaths, qn as settingsStoreCapability, rn as isLocationEnabled, un as legacyModeOf, vn as mayWriteToLocation, xn as modeMayWrite, yi as EventCategory, z as LegacyStorageLocationDefaultSchema } from "../../dist-Dc8GKC5H.mjs";
1
+ import { $ as StorageCleanupJobSchema, $t as gbToBytes, Cn as modeMayWrite, Fr as REDACTED_SECRET, Gr as collectSecretConfigKeys, Gt as evictionPolicyOfLocation, Hn as resolveLocationMode, Si as EventCategory, Yn as settingsStoreCapability, ai as isSecretMarker, an as isLocationEnabled, bi as transformSecretWrite, bn as mayWriteToLocation, et as StorageLocationModeSchema, fn as legacyModeOf, gi as secretTreeFromPaths, jr as BaseAddon, li as parseJsonObject, mi as resolveSecretMarkers, mr as withLocationMode, nr as storageMigrationCapability, nt as StorageMigrationJobSchema, tr as storageCapability, tt as StorageLocationTypeSchema, yn as mayReadLocation, z as LegacyStorageLocationDefaultSchema } from "../../dist-9fcsrFU3.mjs";
2
2
  import { z } from "zod";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { containsOrEquals, physicalRootOf } from "@camstack/types/node";
@@ -1486,9 +1486,9 @@ function createHubCapForwardService(onUnownedCall, options = {}) {
1486
1486
  *
1487
1487
  * Per-node scoping already exists, one layer up, and it is per FIELD:
1488
1488
  * `BaseAddon` persists a `perNode: true` schema field as `<key>@<nodeId>`
1489
- * inside the addon's single shared blob (`packages/types/src/addon/
1490
- * per-node-store.ts`). The agent therefore reads and writes the SAME row the
1491
- * hub's copy of that addon reads — `<addonId>:addon-settings` / `root` — and
1489
+ * inside the addon's settings (`packages/types/src/addon/
1490
+ * per-node-store.ts`). The agent therefore reads and writes the SAME rows the
1491
+ * hub's copy of that addon reads — `addon-settings` `<addonId>.<field>` (D870) — and
1492
1492
  * the two agree by construction. Introducing a second, addon-level
1493
1493
  * `(nodeId, addonId)` row here would be a second authority over one fact,
1494
1494
  * which is the shape [D224](../../../../../docs/decisions/adr-0224-the-freshness-of-a-camera-fact-lives-in-its-provider.md)
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-GgG-7amw.js");
6
+ const require_dist = require("../../dist-BKhlcYz6.js");
7
7
  const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
8
- const require_x509_es = require("../../x509.es-r7Ht1thA.js");
9
- const require_agent_https = require("../../agent-https-BZIwS4xF.js");
10
- const require_constants$8 = require("../../constants-wkcn5Ij3.js");
8
+ const require_x509_es = require("../../x509.es-C4cOo48M.js");
9
+ const require_agent_https = require("../../agent-https-DlpTMDqA.js");
10
+ const require_constants$8 = require("../../constants-CRI3QzT4.js");
11
11
  const require_src$1 = require("../../src-CnAqG6EF.js");
12
12
  let zod = require("zod");
13
13
  let node_crypto = require("node:crypto");