@camstack/system 1.2.30 → 1.2.32

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 (60) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.d.ts +10 -0
  6. package/dist/builtins/alerts/alerts.addon.js +60 -1
  7. package/dist/builtins/alerts/alerts.addon.mjs +60 -1
  8. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +135 -92
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +135 -92
  10. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +12 -14
  11. package/dist/builtins/backup-orchestrator/schedule-store.d.ts +6 -6
  12. package/dist/builtins/console-logging/index.js +1 -1
  13. package/dist/builtins/console-logging/index.mjs +1 -1
  14. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  16. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  17. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  18. package/dist/builtins/hub-forwarder/index.js +1 -1
  19. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  20. package/dist/builtins/liveness-monitor/index.d.ts +2 -0
  21. package/dist/builtins/liveness-monitor/index.js +6 -0
  22. package/dist/builtins/liveness-monitor/index.mjs +2 -0
  23. package/dist/builtins/liveness-monitor/liveness-checks.d.ts +67 -0
  24. package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +32 -0
  25. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +216 -0
  26. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +212 -0
  27. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  28. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  29. package/dist/builtins/local-network/local-network.addon.js +1 -1
  30. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  31. package/dist/builtins/loki-logging/index.js +1 -1
  32. package/dist/builtins/loki-logging/index.mjs +1 -1
  33. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  34. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  35. package/dist/builtins/platform-probe/index.js +1 -1
  36. package/dist/builtins/platform-probe/index.mjs +1 -1
  37. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  38. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  39. package/dist/builtins/snapshot/index.js +1 -1
  40. package/dist/builtins/snapshot/index.mjs +1 -1
  41. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  42. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  43. package/dist/builtins/sqlite-storage/integration-registry.d.ts +3 -3
  44. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +6 -8
  45. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -25
  46. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -25
  47. package/dist/builtins/storage-orchestrator/location-store.d.ts +17 -24
  48. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +0 -6
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +130 -121
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +130 -121
  51. package/dist/builtins/system-config/system-config.addon.js +1 -1
  52. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  53. package/dist/builtins/winston-logging/index.js +1 -1
  54. package/dist/builtins/winston-logging/index.mjs +1 -1
  55. package/dist/{dist-Dr_P0DOB.mjs → dist-BL_FHWPP.mjs} +33 -2
  56. package/dist/{dist-VIwdvws5.js → dist-CSs1A90r.js} +33 -2
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.js +365 -224
  59. package/dist/index.mjs +365 -225
  60. package/package.json +10 -1
@@ -1,4 +1,4 @@
1
- import { $ as storageCapability, Et as parseJsonObject, Z as settingsStoreCapability, d as StorageLocationTypeSchema, ot as BaseAddon } from "../../dist-Dr_P0DOB.mjs";
1
+ import { $ as storageCapability, Et as parseJsonObject, Z as settingsStoreCapability, d as StorageLocationTypeSchema, ot as BaseAddon } from "../../dist-BL_FHWPP.mjs";
2
2
  import * as path$1 from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { buildStorageLocationRegistry } from "@camstack/system";
@@ -528,7 +528,7 @@ var StorageOrchestratorService = class {
528
528
  };
529
529
  //#endregion
530
530
  //#region src/builtins/storage-orchestrator/location-store.ts
531
- var STORAGE_LOCATIONS_TABLE = "storage_locations";
531
+ var STORAGE_LOCATIONS = "storage_locations";
532
532
  /**
533
533
  * Reserved key under which the cluster `nodeId` (SP1) is persisted INSIDE
534
534
  * the `config` JSON blob. Storing it in the blob rather than a dedicated
@@ -541,125 +541,147 @@ var STORAGE_LOCATIONS_TABLE = "storage_locations";
541
541
  * API consumers and providers never see it.
542
542
  */
543
543
  var NODE_ID_CONFIG_KEY = "__nodeId";
544
- var STORAGE_LOCATIONS_SCHEMA = {
545
- columns: [
546
- {
547
- name: "id",
548
- type: "TEXT",
549
- primaryKey: true
550
- },
551
- {
552
- name: "type",
553
- type: "TEXT",
554
- notNull: true
555
- },
556
- {
557
- name: "display_name",
558
- type: "TEXT",
559
- notNull: true
560
- },
561
- {
562
- name: "provider_id",
563
- type: "TEXT",
564
- notNull: true
565
- },
566
- {
567
- name: "config",
568
- type: "TEXT",
569
- notNull: true,
570
- defaultValue: "{}"
571
- },
572
- {
573
- name: "is_default",
574
- type: "INTEGER",
575
- notNull: true,
576
- defaultValue: 0
577
- },
578
- {
579
- name: "is_system",
580
- type: "INTEGER",
581
- notNull: true,
582
- defaultValue: 0
583
- },
584
- {
585
- name: "created_at",
586
- type: "INTEGER",
587
- notNull: true
588
- },
589
- {
590
- name: "updated_at",
591
- type: "INTEGER",
592
- notNull: true
593
- }
594
- ],
595
- indexes: [{
596
- name: "idx_storage_locations_type",
597
- columns: ["type"]
598
- }]
599
- };
600
544
  /**
601
- * SQLite-backed implementation of `ILocationStore` uses the
602
- * `settings-store` cap's structured-table surface (`ensureTable` /
603
- * `tableInsert` / `tableUpdate` / `tableDelete` / `tableQuery`). Wired
604
- * to the live `ISettingsBackend` provider obtained from
605
- * `kernel.capabilityRegistry.getSingleton('settings-store')`.
606
- *
607
- * The cap-router surface (`ctx.api.settingsStore.*`) does NOT expose
608
- * the `tableXxx` methods — they're only on the raw `ISettingsBackend`.
609
- * Same constraint that drives `IntegrationRegistry` to take a direct
610
- * provider reference instead of going through the cap.
545
+ * `config` is declared `JSON`, so the store hands the surface an object and
546
+ * gets an object back. There is deliberately NO `node_id` column `nodeId`
547
+ * rides inside the blob under a reserved key (see {@link NODE_ID_CONFIG_KEY}),
548
+ * because a newly-declared column would put this table through
549
+ * `declareCollection`'s destructive rebuild and wipe operator customizations
550
+ * such as `recordings:default`'s `minFreePercent`.
551
+ */
552
+ var STORAGE_LOCATIONS_COLUMNS = [
553
+ {
554
+ name: "id",
555
+ type: "TEXT",
556
+ primaryKey: true
557
+ },
558
+ {
559
+ name: "type",
560
+ type: "TEXT",
561
+ notNull: true
562
+ },
563
+ {
564
+ name: "display_name",
565
+ type: "TEXT",
566
+ notNull: true
567
+ },
568
+ {
569
+ name: "provider_id",
570
+ type: "TEXT",
571
+ notNull: true
572
+ },
573
+ {
574
+ name: "config",
575
+ type: "JSON",
576
+ notNull: true,
577
+ defaultValue: "{}"
578
+ },
579
+ {
580
+ name: "is_default",
581
+ type: "INTEGER",
582
+ notNull: true,
583
+ defaultValue: 0
584
+ },
585
+ {
586
+ name: "is_system",
587
+ type: "INTEGER",
588
+ notNull: true,
589
+ defaultValue: 0
590
+ },
591
+ {
592
+ name: "created_at",
593
+ type: "INTEGER",
594
+ notNull: true
595
+ },
596
+ {
597
+ name: "updated_at",
598
+ type: "INTEGER",
599
+ notNull: true
600
+ }
601
+ ];
602
+ var STORAGE_LOCATIONS_INDEXES = [{
603
+ name: "idx_storage_locations_type",
604
+ columns: ["type"]
605
+ }];
606
+ /**
607
+ * `ILocationStore` on the `settings-store` collection surface — the same door
608
+ * every other consumer uses. It holds the `data-store-provider` engine object
609
+ * directly (not the `settings-store` singleton) because since D44 the
610
+ * storage-orchestrator IS that singleton, and asking the registry for it would
611
+ * route this table back through the orchestrator itself.
611
612
  */
612
613
  var SqliteLocationStore = class {
613
- backend;
614
- tableEnsured = false;
615
- constructor(backend) {
616
- this.backend = backend;
614
+ store;
615
+ declared = false;
616
+ constructor(store) {
617
+ this.store = store;
617
618
  }
618
619
  /**
619
- * Lazy `ensureTable` — keeps the constructor cheap and async-free.
620
- * Called from every mutation/read path; the backend's `ensureTable`
621
- * is itself idempotent (additive migration), so repeated calls are
622
- * effectively no-ops after the first.
620
+ * Lazy `declareCollection` — keeps the constructor cheap and async-free.
621
+ * Called from every mutation/read path; `declareCollection` is idempotent
622
+ * (and additive on shape changes), so repeated calls collapse to a no-op.
623
623
  */
624
- async ensureTable() {
625
- if (this.tableEnsured) return;
626
- if (!this.backend.ensureTable) throw new Error("SqliteLocationStore: settings backend does not implement ensureTable — expected the SQLite settings backend, got a backend without structured-table support");
627
- await this.backend.ensureTable(STORAGE_LOCATIONS_TABLE, STORAGE_LOCATIONS_SCHEMA);
628
- this.tableEnsured = true;
624
+ async ensureDeclared() {
625
+ if (this.declared) return;
626
+ await this.store.declareCollection({
627
+ collection: STORAGE_LOCATIONS,
628
+ columns: STORAGE_LOCATIONS_COLUMNS,
629
+ indexes: STORAGE_LOCATIONS_INDEXES
630
+ });
631
+ this.declared = true;
629
632
  }
630
633
  async loadAll() {
631
- await this.ensureTable();
632
- if (!this.backend.tableQuery) return [];
633
- const rows = await this.backend.tableQuery(STORAGE_LOCATIONS_TABLE, { orderBy: {
634
- field: "created_at",
635
- direction: "asc"
636
- } });
634
+ await this.ensureDeclared();
635
+ const rows = await this.store.query({
636
+ collection: STORAGE_LOCATIONS,
637
+ filter: { orderBy: {
638
+ field: "created_at",
639
+ direction: "asc"
640
+ } }
641
+ });
637
642
  const out = [];
638
643
  for (const row of rows) {
639
- const mapped = mapRowToLocation(row);
644
+ const mapped = mapRowToLocation(row.data);
640
645
  if (mapped) out.push(mapped);
641
646
  }
642
647
  return out;
643
648
  }
644
649
  /**
645
- * Replace-or-insert. Implemented as `delete` + `insert` rather than
646
- * the conditional `tableUpdate` path because the orchestrator
647
- * serializes every mutation through the in-memory map before
648
- * dispatching to the store — there's no contention to lose, and the
649
- * delete-then-insert path is unconditionally simpler.
650
+ * Replace-or-insert. Implemented as delete + insert rather than a
651
+ * conditional update because the orchestrator serializes every mutation
652
+ * through the in-memory map before dispatching to the store — there's no
653
+ * contention to lose, and delete-then-insert is unconditionally simpler.
650
654
  */
651
655
  async upsert(loc) {
652
- await this.ensureTable();
653
- if (!this.backend.tableDelete || !this.backend.tableInsert) throw new Error("SqliteLocationStore: backend missing tableDelete/tableInsert");
654
- await this.backend.tableDelete(STORAGE_LOCATIONS_TABLE, { id: loc.id });
655
- await this.backend.tableInsert(STORAGE_LOCATIONS_TABLE, mapLocationToRow(loc));
656
+ await this.ensureDeclared();
657
+ await this.store.deleteWhere({
658
+ collection: STORAGE_LOCATIONS,
659
+ filter: { where: { id: loc.id } }
660
+ });
661
+ await this.store.insert({
662
+ collection: STORAGE_LOCATIONS,
663
+ record: {
664
+ id: loc.id,
665
+ data: mapLocationToRow(loc)
666
+ }
667
+ });
656
668
  }
657
669
  async delete(id) {
658
- await this.ensureTable();
659
- if (!this.backend.tableDelete) throw new Error("SqliteLocationStore: backend missing tableDelete");
660
- await this.backend.tableDelete(STORAGE_LOCATIONS_TABLE, { id });
670
+ await this.ensureDeclared();
671
+ await this.store.deleteWhere({
672
+ collection: STORAGE_LOCATIONS,
673
+ filter: { where: { id } }
674
+ });
661
675
  }
662
676
  };
677
+ function isPlainObject(value) {
678
+ return value !== null && typeof value === "object" && !Array.isArray(value);
679
+ }
680
+ function readConfig(raw) {
681
+ if (isPlainObject(raw)) return { ...raw };
682
+ if (typeof raw === "string" && raw.length > 0) return parseJsonObject(raw) ?? {};
683
+ return {};
684
+ }
663
685
  function mapLocationToRow(loc) {
664
686
  const storedConfig = loc.nodeId !== void 0 ? {
665
687
  ...loc.config,
@@ -670,7 +692,7 @@ function mapLocationToRow(loc) {
670
692
  type: loc.type,
671
693
  display_name: loc.displayName,
672
694
  provider_id: loc.providerId,
673
- config: JSON.stringify(storedConfig),
695
+ config: storedConfig,
674
696
  is_default: loc.isDefault ? 1 : 0,
675
697
  is_system: loc.isSystem ? 1 : 0,
676
698
  created_at: loc.createdAt,
@@ -678,11 +700,9 @@ function mapLocationToRow(loc) {
678
700
  };
679
701
  }
680
702
  /**
681
- * Decode a row read from the structured table. Returns `null` when the
682
- * row's `type` doesn't parse against the Zod enumthe caller skips
683
- * the row and logs. Defensive against schema drift across upgrades
684
- * (e.g. an older build wrote a since-removed `recordings-archive`
685
- * type and the new build no longer recognises it).
703
+ * Decode a row read from the collection. Returns `null` when the row's `type`
704
+ * fails the id-format schema or the row has no id a corrupt row (hand-edited,
705
+ * partial migration) is skipped rather than taking the boot read down with it.
686
706
  */
687
707
  function mapRowToLocation(row) {
688
708
  const typeRaw = row["type"];
@@ -691,8 +711,7 @@ function mapRowToLocation(row) {
691
711
  const type = parsedType.data;
692
712
  const id = String(row["id"] ?? "");
693
713
  if (!id) return null;
694
- const configRaw = row["config"];
695
- const storedConfig = typeof configRaw === "string" && configRaw.length > 0 ? parseJsonObject(configRaw) ?? {} : {};
714
+ const storedConfig = readConfig(row["config"]);
696
715
  const nodeIdRaw = storedConfig[NODE_ID_CONFIG_KEY];
697
716
  const nodeId = typeof nodeIdRaw === "string" && nodeIdRaw.length > 0 ? nodeIdRaw : void 0;
698
717
  const config = { ...storedConfig };
@@ -1203,26 +1222,16 @@ var StorageOrchestratorAddon = class extends BaseAddon {
1203
1222
  * addon *is* that singleton, so asking the registry for it would hand
1204
1223
  * the orchestrator its own dispatcher and route its location table back
1205
1224
  * through itself.
1206
- *
1207
- * The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
1208
- * still open: those six methods live on the concrete backend and on no
1209
- * cap. Promoting them to the door is a separate task; until then this
1210
- * holds the engine object directly, which only works because the engine
1211
- * is in-process on this node.
1212
1225
  */
1213
1226
  resolveLocationStore(quiet = false) {
1214
1227
  const reg = this.ctx.kernel.capabilityRegistry;
1215
1228
  if (!reg) return null;
1216
- const backend = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
1217
- if (!backend) {
1229
+ const engine = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
1230
+ if (!engine) {
1218
1231
  if (!quiet) this.ctx.logger.warn("storage-orchestrator: no data-store-provider engine yet — running in-memory until one registers");
1219
1232
  return null;
1220
1233
  }
1221
- if (!backend.ensureTable || !backend.tableInsert) {
1222
- if (!quiet) this.ctx.logger.warn("storage-orchestrator: settings backend lacks structured-table support — running in-memory only");
1223
- return null;
1224
- }
1225
- return new SqliteLocationStore(backend);
1234
+ return new SqliteLocationStore(engine);
1226
1235
  }
1227
1236
  /**
1228
1237
  * Late-wire the persistence store once a `data-store-provider` engine
@@ -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-VIwdvws5.js");
6
+ const require_dist = require("../../dist-CSs1A90r.js");
7
7
  //#region src/builtins/system-config/system-config.addon.ts
8
8
  /**
9
9
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -1,4 +1,4 @@
1
- import { Ct as hydrateSchema, at as errMsg, ot as BaseAddon } from "../../dist-Dr_P0DOB.mjs";
1
+ import { Ct as hydrateSchema, at as errMsg, ot as BaseAddon } from "../../dist-BL_FHWPP.mjs";
2
2
  //#region src/builtins/system-config/system-config.addon.ts
3
3
  /**
4
4
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -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-VIwdvws5.js");
6
+ const require_dist = require("../../dist-CSs1A90r.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-Dr_P0DOB.mjs";
1
+ import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-BL_FHWPP.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  import * as path$1 from "node:path";
4
4
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- //#region ../types/dist/event-category-Bz24uP1U.mjs
2
+ //#region ../types/dist/event-category-41fKf-q9.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -59,6 +59,26 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
59
59
  */
60
60
  EventCategory["AddonRetryScheduled"] = "addon.retry-scheduled";
61
61
  /**
62
+ * A liveness invariant of this node is false — it has no devices, every
63
+ * camera is offline, or a camera that was recording has stopped producing
64
+ * segments. Emitted by the `liveness-monitor` builtin, once per fault (the
65
+ * `findingId` is stable across ticks), only after its boot grace period.
66
+ * AlertCenter raises a persistent operator-visible alert.
67
+ *
68
+ * It exists because on 2026-08-03 the hub ran four hours with zero devices
69
+ * and zero recordings while every surface stayed quiet.
70
+ *
71
+ * Payload: `{ findingId, severity, title, message, deviceId? }`.
72
+ */
73
+ EventCategory["SystemLivenessFailed"] = "system.liveness-failed";
74
+ /**
75
+ * A previously reported liveness fault is true again. AlertCenter dismisses
76
+ * the matching `SystemLivenessFailed` alert.
77
+ *
78
+ * Payload: `{ findingId }`.
79
+ */
80
+ EventCategory["SystemLivenessRecovered"] = "system.liveness-recovered";
81
+ /**
62
82
  * Monitor is attempting to reload a failed addon NOW. UI uses this
63
83
  * to show a spinner during the retry attempt. Same transient nature
64
84
  * as AddonRetryScheduled.
@@ -14583,7 +14603,18 @@ var CollectionColumnSchema = z.object({
14583
14603
  ]),
14584
14604
  primaryKey: z.boolean().optional(),
14585
14605
  notNull: z.boolean().optional(),
14586
- unique: z.boolean().optional()
14606
+ unique: z.boolean().optional(),
14607
+ /**
14608
+ * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
14609
+ * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
14610
+ * collection surface simply cannot express their existing tables — which is
14611
+ * why they were still on the uncapped `table*` API.
14612
+ */
14613
+ defaultValue: z.union([
14614
+ z.string(),
14615
+ z.number(),
14616
+ z.boolean()
14617
+ ]).optional()
14587
14618
  });
14588
14619
  var CollectionIndexSchema = z.object({
14589
14620
  name: z.string(),
@@ -1,5 +1,5 @@
1
1
  let zod = require("zod");
2
- //#region ../types/dist/event-category-Bz24uP1U.mjs
2
+ //#region ../types/dist/event-category-41fKf-q9.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -59,6 +59,26 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
59
59
  */
60
60
  EventCategory["AddonRetryScheduled"] = "addon.retry-scheduled";
61
61
  /**
62
+ * A liveness invariant of this node is false — it has no devices, every
63
+ * camera is offline, or a camera that was recording has stopped producing
64
+ * segments. Emitted by the `liveness-monitor` builtin, once per fault (the
65
+ * `findingId` is stable across ticks), only after its boot grace period.
66
+ * AlertCenter raises a persistent operator-visible alert.
67
+ *
68
+ * It exists because on 2026-08-03 the hub ran four hours with zero devices
69
+ * and zero recordings while every surface stayed quiet.
70
+ *
71
+ * Payload: `{ findingId, severity, title, message, deviceId? }`.
72
+ */
73
+ EventCategory["SystemLivenessFailed"] = "system.liveness-failed";
74
+ /**
75
+ * A previously reported liveness fault is true again. AlertCenter dismisses
76
+ * the matching `SystemLivenessFailed` alert.
77
+ *
78
+ * Payload: `{ findingId }`.
79
+ */
80
+ EventCategory["SystemLivenessRecovered"] = "system.liveness-recovered";
81
+ /**
62
82
  * Monitor is attempting to reload a failed addon NOW. UI uses this
63
83
  * to show a spinner during the retry attempt. Same transient nature
64
84
  * as AddonRetryScheduled.
@@ -14583,7 +14603,18 @@ var CollectionColumnSchema = zod.z.object({
14583
14603
  ]),
14584
14604
  primaryKey: zod.z.boolean().optional(),
14585
14605
  notNull: zod.z.boolean().optional(),
14586
- unique: zod.z.boolean().optional()
14606
+ unique: zod.z.boolean().optional(),
14607
+ /**
14608
+ * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
14609
+ * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
14610
+ * collection surface simply cannot express their existing tables — which is
14611
+ * why they were still on the uncapped `table*` API.
14612
+ */
14613
+ defaultValue: zod.z.union([
14614
+ zod.z.string(),
14615
+ zod.z.number(),
14616
+ zod.z.boolean()
14617
+ ]).optional()
14587
14618
  });
14588
14619
  var CollectionIndexSchema = zod.z.object({
14589
14620
  name: zod.z.string(),
package/dist/index.d.ts CHANGED
@@ -47,6 +47,7 @@ export { StorageOrchestratorAddon, StorageOrchestratorService, } from './builtin
47
47
  export type { ListLocationsFilter, StorageProviderLookup, } from './builtins/storage-orchestrator/index.js';
48
48
  export { default as NativeMetricsAddon } from './builtins/native-metrics/native-metrics.addon.js';
49
49
  export { AlertCenterAddon } from './builtins/alerts/index.js';
50
+ export { LivenessMonitorAddon } from './builtins/liveness-monitor/index.js';
50
51
  export { NativeMetricsProvider } from './builtins/native-metrics/native-metrics-provider.js';
51
52
  export { SystemConfigAddon } from './builtins/system-config/index.js';
52
53
  export { LocalAuthAddon } from './builtins/local-auth/index.js';