@camstack/system 1.2.444 → 1.2.445
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.
- package/dist/addon-runner.js +40 -31
- package/dist/addon-runner.mjs +41 -32
- package/dist/{agent-https-DlpTMDqA.js → agent-https-CiOW0-sj.js} +810 -12
- package/dist/{agent-https-U0d4uvn2.mjs → agent-https-D4Q8iFNd.mjs} +697 -13
- package/dist/auth/admin-token-manager.d.ts +9 -3
- package/dist/auth/api-key-manager.d.ts +9 -3
- package/dist/auth/auth-audit-log.d.ts +9 -3
- package/dist/auth/device-credential-manager.d.ts +5 -1
- package/dist/auth/external-identity-manager.d.ts +8 -21
- package/dist/auth/login-session-manager.d.ts +11 -3
- package/dist/auth/scoped-token-manager.d.ts +8 -52
- package/dist/auth/totp-manager.d.ts +11 -3
- package/dist/auth/user-manager.d.ts +10 -17
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alert-store.d.ts +32 -0
- package/dist/builtins/alerts/alerts.addon.d.ts +9 -2
- package/dist/builtins/alerts/alerts.addon.js +289 -150
- package/dist/builtins/alerts/alerts.addon.mjs +288 -150
- package/dist/builtins/alerts/record-kinds.d.ts +15 -0
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +1 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +134 -193
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +134 -193
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/record-kinds.d.ts +58 -0
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +4 -2
- package/dist/builtins/calendars/calendar-prefs-store.d.ts +13 -5
- package/dist/builtins/calendars/calendars.addon.d.ts +2 -2
- package/dist/builtins/calendars/calendars.addon.js +67 -64
- package/dist/builtins/calendars/calendars.addon.mjs +59 -64
- package/dist/builtins/calendars/record-kinds.d.ts +18 -0
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/cluster-agent/record-kinds.d.ts +36 -0
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/block-settings-store.d.ts +8 -4
- package/dist/builtins/core-blocks/core-block-store.d.ts +8 -16
- package/dist/builtins/core-blocks/core-blocks.addon.js +85 -112
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +86 -113
- package/dist/builtins/core-blocks/index.mjs +1 -1
- package/dist/builtins/core-blocks/record-kinds.d.ts +26 -0
- package/dist/builtins/device-manager/device-manager.addon.js +111 -187
- package/dist/builtins/device-manager/device-manager.addon.mjs +110 -187
- package/dist/builtins/device-manager/device-tombstone-store.d.ts +9 -48
- package/dist/builtins/device-manager/record-kinds.d.ts +14 -0
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +152 -22
- package/dist/builtins/keychain/index.mjs +152 -22
- package/dist/builtins/keychain/keychain-service.d.ts +3 -2
- package/dist/builtins/keychain/keychain-store.d.ts +13 -2
- package/dist/builtins/keychain/record-kinds.d.ts +16 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/auth-schema.d.ts +3 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2903 -2123
- package/dist/builtins/local-auth/local-auth.addon.mjs +2904 -2124
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +8 -48
- package/dist/builtins/local-auth/record-kinds.d.ts +141 -0
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/records/legacy-table-row-count.d.ts +5 -0
- package/dist/builtins/records/phase6-declare-gate.d.ts +28 -0
- package/dist/builtins/records-isolated.d.ts +10 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/integration-record-kinds.d.ts +30 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +10 -16
- package/dist/builtins/sqlite-storage/records/count-settings-array-legacy.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/count-settings-brokers-legacy.d.ts +6 -0
- package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/records-engine.d.ts +4 -0
- package/dist/builtins/sqlite-storage/records/records-provider.d.ts +5 -1
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +17 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +111 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +111 -3
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +9 -1
- package/dist/builtins/storage-orchestrator/drain-state-store.d.ts +5 -2
- package/dist/builtins/storage-orchestrator/location-store.d.ts +7 -2
- package/dist/builtins/storage-orchestrator/record-kinds.d.ts +38 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +2 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +196 -5
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +195 -6
- package/dist/builtins/system-config/record-kinds.d.ts +32 -0
- package/dist/builtins/system-config/system-config.addon.js +53 -618
- package/dist/builtins/system-config/system-config.addon.mjs +29 -577
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-C3rKncIF.mjs → composition-sources-BMt5cFYb.mjs} +1 -1
- package/dist/{composition-sources-NAPZddic.js → composition-sources-D3fi9Xns.js} +1 -1
- package/dist/{constants-BKX2QnIg.mjs → constants-BMHCxRzb.mjs} +1 -1
- package/dist/{constants-BXiNEIeV.js → constants-Br879Axi.js} +1 -1
- package/dist/{device-ca-DT9X2S6d.js → device-ca-CnJ_va7i.js} +1 -1
- package/dist/{device-ca-jxjSL8Ov.mjs → device-ca-T8osSMos.mjs} +1 -1
- package/dist/{dist-DERK-gP5.mjs → dist-BNunRyXT.mjs} +174 -58
- package/dist/{dist-D1vECb_6.js → dist-DgOG8flk.js} +233 -57
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-Cah9GCIg.js → hub-mdns-ciao-BIkTHq-n.js} +2 -2
- package/dist/{hub-mdns-ciao-CRaC97V0.mjs → hub-mdns-ciao-D16oRQ9K.mjs} +2 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +3093 -2820
- package/dist/index.mjs +3065 -2809
- package/dist/kernel/index.d.ts +2 -0
- package/dist/kernel/moleculer/event-bus.d.ts +3 -1
- package/dist/kernel/moleculer/mesh-mtls/mesh-certificate-registry.d.ts +5 -1
- package/dist/kernel/moleculer/remote-logger.d.ts +2 -2
- package/dist/kernel/transport/cap-route-resolver.d.ts +9 -38
- package/dist/phase6-declare-gate-Ci1-8uUn.js +98 -0
- package/dist/phase6-declare-gate-tkKOEitw.mjs +93 -0
- package/dist/read-all-rows-CVoO1ONM.js +29 -0
- package/dist/read-all-rows-TaPqdWNF.mjs +25 -0
- package/dist/records/read-all-rows.d.ts +6 -0
- package/dist/{restore-archive-daKyE24F.mjs → restore-archive-DR9MtO7J.mjs} +339 -9
- package/dist/{restore-archive-Dy-qKTdF.js → restore-archive-DjJnCgap.js} +353 -5
- package/dist/tls/agent-https-names.d.ts +9 -13
- package/dist/{wal-maintenance-dAv4IdzC.js → wal-maintenance-CODGqhKY.js} +0 -0
- package/dist/{wal-maintenance-zRc24mOC.mjs → wal-maintenance-CfvgtQ7C.mjs} +0 -0
- package/package.json +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ci as createEvent, Di as defineRecordKinds, Lr as errMsg, Rr as BaseAddon, ft as alertsCapability, i as AlertSchema, la as EventCategory } from "../../dist-BNunRyXT.mjs";
|
|
2
|
+
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
|
+
import { t as resolvePhase6UseRecordsPathForHub } from "../../phase6-declare-gate-tkKOEitw.mjs";
|
|
2
4
|
//#region src/builtins/alerts/critical-push.ts
|
|
3
5
|
/** Alert categories that are critical system findings. */
|
|
4
6
|
var CRITICAL_CATEGORIES = new Set([
|
|
@@ -277,6 +279,210 @@ function runnerPushLine(record) {
|
|
|
277
279
|
return record.state === "refused" ? `${where}: refused to start. ${record.remedy ?? "See the Addons page."}` : `${where}: stopped after repeated crashes. Restart it from the Addons page.`;
|
|
278
280
|
}
|
|
279
281
|
//#endregion
|
|
282
|
+
//#region src/builtins/alerts/record-kinds.ts
|
|
283
|
+
var import_read_all_rows = require_read_all_rows();
|
|
284
|
+
/**
|
|
285
|
+
* Record kinds owned by alert-center (records plan phase 4).
|
|
286
|
+
*/
|
|
287
|
+
/** Legacy collection / adoptsFrom target (canonical KV before phase 4). */
|
|
288
|
+
var ALERTS_COLLECTION = "alerts";
|
|
289
|
+
var _alertCenterRecordKinds = defineRecordKinds({ alerts: {
|
|
290
|
+
schema: AlertSchema.omit({ id: true }),
|
|
291
|
+
class: "audit",
|
|
292
|
+
writeTrigger: "EventBus categories the alert center tracks, operator mark read/dismiss, and model-download progress merges",
|
|
293
|
+
device: "none",
|
|
294
|
+
at: "none",
|
|
295
|
+
indexes: [
|
|
296
|
+
{
|
|
297
|
+
name: "read",
|
|
298
|
+
fields: ["read"]
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
name: "created_at",
|
|
302
|
+
fields: ["createdAt"]
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "updated_at",
|
|
306
|
+
fields: ["updatedAt"]
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
retention: {
|
|
310
|
+
owner: "alert-center",
|
|
311
|
+
reason: "maxAlerts cap and retentionDays enforced on write (enforceMaxAlerts / enforceRetention); read alerts preferred when trimming overflow"
|
|
312
|
+
},
|
|
313
|
+
adoptsFrom: ALERTS_COLLECTION
|
|
314
|
+
} });
|
|
315
|
+
var alertCenterRecordKinds = _alertCenterRecordKinds;
|
|
316
|
+
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
317
|
+
var alertsRecordKind = _alertCenterRecordKinds.alerts;
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/builtins/alerts/alert-store.ts
|
|
320
|
+
function toRecord(row) {
|
|
321
|
+
return {
|
|
322
|
+
id: row.id,
|
|
323
|
+
data: row.data
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function toRecordFromLegacy(row) {
|
|
327
|
+
return {
|
|
328
|
+
id: row.id,
|
|
329
|
+
data: row.data
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function isRecord(value) {
|
|
333
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
334
|
+
}
|
|
335
|
+
function legacyGetData(value) {
|
|
336
|
+
if (!isRecord(value)) return null;
|
|
337
|
+
if ("data" in value) {
|
|
338
|
+
const data = value.data;
|
|
339
|
+
return isRecord(data) ? data : null;
|
|
340
|
+
}
|
|
341
|
+
return value;
|
|
342
|
+
}
|
|
343
|
+
var AlertStore = class AlertStore {
|
|
344
|
+
kind;
|
|
345
|
+
legacyStore;
|
|
346
|
+
constructor(kind, legacyStore) {
|
|
347
|
+
this.kind = kind;
|
|
348
|
+
this.legacyStore = legacyStore;
|
|
349
|
+
}
|
|
350
|
+
static of(records) {
|
|
351
|
+
return new AlertStore(records.kind(alertsRecordKind), null);
|
|
352
|
+
}
|
|
353
|
+
static legacy(store) {
|
|
354
|
+
return new AlertStore(null, store);
|
|
355
|
+
}
|
|
356
|
+
async legacyRows() {
|
|
357
|
+
const store = this.legacyStore;
|
|
358
|
+
if (store === null) return [];
|
|
359
|
+
return (await store.query.query({
|
|
360
|
+
collection: ALERTS_COLLECTION,
|
|
361
|
+
filter: {}
|
|
362
|
+
})).map((row) => toRecordFromLegacy({
|
|
363
|
+
id: row.id,
|
|
364
|
+
data: row.data
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
async list(filter) {
|
|
368
|
+
let out;
|
|
369
|
+
const kind = this.kind;
|
|
370
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
371
|
+
else out = [...await this.legacyRows()];
|
|
372
|
+
if (filter?.unreadOnly === true) out = out.filter((r) => r.data["read"] === false);
|
|
373
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
374
|
+
const limit = filter?.limit ?? 100;
|
|
375
|
+
return out.slice(0, limit);
|
|
376
|
+
}
|
|
377
|
+
async countUnread() {
|
|
378
|
+
return (await this.list({
|
|
379
|
+
unreadOnly: true,
|
|
380
|
+
limit: 1e4
|
|
381
|
+
})).length;
|
|
382
|
+
}
|
|
383
|
+
async countAll() {
|
|
384
|
+
const kind = this.kind;
|
|
385
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).length;
|
|
386
|
+
return (await this.legacyRows()).length;
|
|
387
|
+
}
|
|
388
|
+
async getData(id) {
|
|
389
|
+
const kind = this.kind;
|
|
390
|
+
if (kind !== null) {
|
|
391
|
+
const row = await kind.get(id);
|
|
392
|
+
if (row === null) return null;
|
|
393
|
+
return row.data;
|
|
394
|
+
}
|
|
395
|
+
const store = this.legacyStore;
|
|
396
|
+
if (store === null) return null;
|
|
397
|
+
return legacyGetData(await store.get.query({
|
|
398
|
+
collection: ALERTS_COLLECTION,
|
|
399
|
+
key: id
|
|
400
|
+
}));
|
|
401
|
+
}
|
|
402
|
+
async mergeUpdate(id, patch) {
|
|
403
|
+
const existing = await this.getData(id);
|
|
404
|
+
if (existing === null) return;
|
|
405
|
+
await this.putRaw(id, {
|
|
406
|
+
...existing,
|
|
407
|
+
...patch
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
async persist(alert) {
|
|
411
|
+
const { id, ...body } = alert;
|
|
412
|
+
const data = alertsRecordKind.schema.parse(body);
|
|
413
|
+
const kind = this.kind;
|
|
414
|
+
if (kind !== null) {
|
|
415
|
+
await kind.put({
|
|
416
|
+
id,
|
|
417
|
+
data
|
|
418
|
+
});
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
await this.putRaw(id, {
|
|
422
|
+
...body,
|
|
423
|
+
id
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
async putRaw(id, data) {
|
|
427
|
+
const { id: _drop, ...body } = AlertSchema.parse({
|
|
428
|
+
id,
|
|
429
|
+
...data
|
|
430
|
+
});
|
|
431
|
+
const kind = this.kind;
|
|
432
|
+
if (kind !== null) {
|
|
433
|
+
await kind.put({
|
|
434
|
+
id,
|
|
435
|
+
data: body
|
|
436
|
+
});
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const store = this.legacyStore;
|
|
440
|
+
if (store === null) return;
|
|
441
|
+
await store.set.mutate({
|
|
442
|
+
collection: ALERTS_COLLECTION,
|
|
443
|
+
key: id,
|
|
444
|
+
value: {
|
|
445
|
+
id,
|
|
446
|
+
...body
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
async delete(id) {
|
|
451
|
+
const kind = this.kind;
|
|
452
|
+
if (kind !== null) {
|
|
453
|
+
await kind.delete(id);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const store = this.legacyStore;
|
|
457
|
+
if (store === null) return;
|
|
458
|
+
await store.delete.mutate({
|
|
459
|
+
collection: ALERTS_COLLECTION,
|
|
460
|
+
key: id
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
async listAllByCreatedAtAsc() {
|
|
464
|
+
const kind = this.kind;
|
|
465
|
+
let out;
|
|
466
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind)).map(toRecord);
|
|
467
|
+
else out = [...await this.legacyRows()];
|
|
468
|
+
out.sort((a, b) => Number(a.data["createdAt"] ?? 0) - Number(b.data["createdAt"] ?? 0));
|
|
469
|
+
return out;
|
|
470
|
+
}
|
|
471
|
+
async listRecent(limit) {
|
|
472
|
+
const kind = this.kind;
|
|
473
|
+
let out;
|
|
474
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
475
|
+
else out = [...await this.legacyRows()];
|
|
476
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
477
|
+
return out.slice(0, limit);
|
|
478
|
+
}
|
|
479
|
+
async findWhereDataField(field, value) {
|
|
480
|
+
const kind = this.kind;
|
|
481
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).filter((r) => r.data[field] === value).map(toRecord);
|
|
482
|
+
return (await this.legacyRows()).filter((r) => r.data[field] === value);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
//#endregion
|
|
280
486
|
//#region src/builtins/alerts/alerts.addon.ts
|
|
281
487
|
var CATEGORY_MAPPINGS = {
|
|
282
488
|
"addon.crashed": {
|
|
@@ -449,13 +655,18 @@ var DEFAULT_CONFIG = {
|
|
|
449
655
|
maxAlerts: 500,
|
|
450
656
|
retentionDays: 30,
|
|
451
657
|
criticalPushEnabled: true,
|
|
452
|
-
criticalPushTargetIds:
|
|
658
|
+
criticalPushTargetIds: []
|
|
453
659
|
};
|
|
660
|
+
/** Accept the live `string[]` shape and the pre-multiselect CSV string. */
|
|
661
|
+
function normalizeCriticalPushTargetIds(raw) {
|
|
662
|
+
if (Array.isArray(raw)) return raw.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim());
|
|
663
|
+
if (typeof raw === "string" && raw.trim().length > 0) return raw.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
664
|
+
return [];
|
|
665
|
+
}
|
|
454
666
|
/** One burst of critical findings (a whole boot of refused runners) is ONE digest push. */
|
|
455
667
|
var PUSH_COALESCE_MS = 2e3;
|
|
456
668
|
/** Addons whose (re)start is a reason to retry pending critical pushes. */
|
|
457
669
|
var PUSH_RECONCILE_ADDONS = new Set(["notifiers", "notification-center"]);
|
|
458
|
-
var ALERTS_COLLECTION = "alerts";
|
|
459
670
|
var EVENT_SOURCE = {
|
|
460
671
|
type: "addon",
|
|
461
672
|
id: "alert-center"
|
|
@@ -476,6 +687,7 @@ function toPrunable(record) {
|
|
|
476
687
|
};
|
|
477
688
|
}
|
|
478
689
|
var AlertCenterAddon = class extends BaseAddon {
|
|
690
|
+
alertStore = null;
|
|
479
691
|
unsubscribers = [];
|
|
480
692
|
/** How long a burst of critical findings is gathered into one digest push. */
|
|
481
693
|
pushCoalesceMs;
|
|
@@ -490,6 +702,11 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
490
702
|
*/
|
|
491
703
|
rateLimitCounters = /* @__PURE__ */ new Map();
|
|
492
704
|
async onInitialize() {
|
|
705
|
+
const records = this.ctx.records;
|
|
706
|
+
const store = this.ctx.api?.settingsStore;
|
|
707
|
+
const useRecords = records !== void 0 && store !== void 0 && await resolvePhase6UseRecordsPathForHub(this.ctx, "alert-center", alertCenterRecordKinds, ["alerts"]);
|
|
708
|
+
this.alertStore = useRecords && records !== void 0 ? AlertStore.of(records) : store === void 0 ? null : AlertStore.legacy(store);
|
|
709
|
+
if (this.alertStore === null) throw new Error("alert-center needs ctx.records or settings-store on the hub");
|
|
493
710
|
const alertsProvider = {
|
|
494
711
|
emit: (alert) => this.emitAlert(alert),
|
|
495
712
|
update: (input) => this.updateAlert(input.alertId, input.patch),
|
|
@@ -509,6 +726,7 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
509
726
|
this.unsubscribers = unsubs;
|
|
510
727
|
this.reconcilePendingPushes();
|
|
511
728
|
this.dismissLegacyStreamCards(void 0);
|
|
729
|
+
this.migrateCriticalPushTargetIds();
|
|
512
730
|
this.ctx.logger.info("Initialized", { meta: { trackedCategoriesCount: TRACKED_CATEGORIES.length } });
|
|
513
731
|
return [{
|
|
514
732
|
capability: alertsCapability,
|
|
@@ -556,43 +774,28 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
556
774
|
type: "boolean",
|
|
557
775
|
key: "criticalPushEnabled",
|
|
558
776
|
label: "Push critical system alerts",
|
|
559
|
-
description: "A runner that failed or refused to start, or a node whose runners are degraded, is pushed straight to the notifier targets
|
|
777
|
+
description: "A runner that failed or refused to start, or a node whose runners are degraded, is pushed straight to the notifier targets — even when Notification Center is down. This path does not use notification rules.",
|
|
560
778
|
default: true
|
|
561
779
|
}),
|
|
562
780
|
this.field({
|
|
563
|
-
type: "
|
|
781
|
+
type: "notification-target-multiselect",
|
|
564
782
|
key: "criticalPushTargetIds",
|
|
565
783
|
label: "Critical push targets",
|
|
566
|
-
description: "
|
|
567
|
-
default:
|
|
784
|
+
description: "Notifier targets that receive critical system alerts. Empty = every enabled shared (not personal) target.",
|
|
785
|
+
default: []
|
|
568
786
|
})
|
|
569
787
|
]
|
|
570
788
|
}] });
|
|
571
789
|
}
|
|
572
790
|
async listAlerts(filter) {
|
|
573
|
-
const
|
|
574
|
-
if (
|
|
575
|
-
|
|
576
|
-
if (filter?.unreadOnly) whereClause.read = false;
|
|
577
|
-
return (await backend.query.query({
|
|
578
|
-
collection: ALERTS_COLLECTION,
|
|
579
|
-
filter: {
|
|
580
|
-
where: Object.keys(whereClause).length > 0 ? whereClause : void 0,
|
|
581
|
-
orderBy: {
|
|
582
|
-
field: "updatedAt",
|
|
583
|
-
direction: "desc"
|
|
584
|
-
},
|
|
585
|
-
limit: filter?.limit ?? 100
|
|
586
|
-
}
|
|
587
|
-
})).map(parseAlert);
|
|
791
|
+
const store = this.alertStore;
|
|
792
|
+
if (store === null) return [];
|
|
793
|
+
return (await store.list(filter)).map(parseAlert);
|
|
588
794
|
}
|
|
589
795
|
async getUnreadCount() {
|
|
590
|
-
const
|
|
591
|
-
if (
|
|
592
|
-
return
|
|
593
|
-
collection: ALERTS_COLLECTION,
|
|
594
|
-
filter: { where: { read: false } }
|
|
595
|
-
});
|
|
796
|
+
const store = this.alertStore;
|
|
797
|
+
if (store === null) return 0;
|
|
798
|
+
return store.countUnread();
|
|
596
799
|
}
|
|
597
800
|
async markRead(alertId) {
|
|
598
801
|
await this.mergeUpdate(alertId, {
|
|
@@ -601,11 +804,11 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
601
804
|
});
|
|
602
805
|
}
|
|
603
806
|
async markAllRead() {
|
|
604
|
-
const
|
|
605
|
-
if (
|
|
606
|
-
const unread = await
|
|
607
|
-
|
|
608
|
-
|
|
807
|
+
const store = this.alertStore;
|
|
808
|
+
if (store === null) return;
|
|
809
|
+
const unread = await store.list({
|
|
810
|
+
unreadOnly: true,
|
|
811
|
+
limit: 1e4
|
|
609
812
|
});
|
|
610
813
|
const now = Date.now();
|
|
611
814
|
for (const record of unread) await this.mergeUpdate(record.id, {
|
|
@@ -702,14 +905,14 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
702
905
|
}
|
|
703
906
|
}
|
|
704
907
|
async readRunnerRecord(alertId) {
|
|
705
|
-
const
|
|
706
|
-
if (
|
|
707
|
-
const raw = await
|
|
708
|
-
|
|
709
|
-
|
|
908
|
+
const store = this.alertStore;
|
|
909
|
+
if (store === null) return null;
|
|
910
|
+
const raw = await store.getData(alertId);
|
|
911
|
+
if (raw === null) return null;
|
|
912
|
+
const alert = AlertSchema.safeParse({
|
|
913
|
+
id: alertId,
|
|
914
|
+
...raw
|
|
710
915
|
});
|
|
711
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
712
|
-
const alert = AlertSchema.safeParse(raw);
|
|
713
916
|
if (!alert.success || alert.data.status === "dismissed") return null;
|
|
714
917
|
return parseRunnerRecord(alert.data.metadata?.["runner"]);
|
|
715
918
|
}
|
|
@@ -837,13 +1040,10 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
837
1040
|
});
|
|
838
1041
|
}
|
|
839
1042
|
async readAlertRaw(alertId) {
|
|
840
|
-
const
|
|
841
|
-
if (
|
|
842
|
-
const raw = await
|
|
843
|
-
|
|
844
|
-
key: alertId
|
|
845
|
-
});
|
|
846
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
1043
|
+
const store = this.alertStore;
|
|
1044
|
+
if (store === null) return null;
|
|
1045
|
+
const raw = await store.getData(alertId);
|
|
1046
|
+
if (raw === null) return null;
|
|
847
1047
|
const rec = Object.fromEntries(Object.entries(raw));
|
|
848
1048
|
const meta = rec["metadata"];
|
|
849
1049
|
const push = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta["push"] : void 0;
|
|
@@ -861,9 +1061,19 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
861
1061
|
pushPolicy() {
|
|
862
1062
|
return {
|
|
863
1063
|
enabled: this.config.criticalPushEnabled,
|
|
864
|
-
targetIds: this.config.criticalPushTargetIds
|
|
1064
|
+
targetIds: normalizeCriticalPushTargetIds(this.config.criticalPushTargetIds)
|
|
865
1065
|
};
|
|
866
1066
|
}
|
|
1067
|
+
/** Rewrite a legacy CSV `criticalPushTargetIds` string into `string[]`. */
|
|
1068
|
+
async migrateCriticalPushTargetIds() {
|
|
1069
|
+
const raw = this.config.criticalPushTargetIds;
|
|
1070
|
+
if (typeof raw !== "string") return;
|
|
1071
|
+
try {
|
|
1072
|
+
await this.updateGlobalSettings({ criticalPushTargetIds: normalizeCriticalPushTargetIds(raw) });
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
this.ctx.logger.warn("criticalPushTargetIds CSV migration failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
867
1077
|
pushPorts() {
|
|
868
1078
|
const api = this.ctx.api;
|
|
869
1079
|
return {
|
|
@@ -940,27 +1150,16 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
940
1150
|
return this.pushChain;
|
|
941
1151
|
}
|
|
942
1152
|
async storePushState(alertId, push) {
|
|
943
|
-
const
|
|
944
|
-
if (
|
|
945
|
-
const raw = await
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
});
|
|
949
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
950
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
951
|
-
const meta = existing["metadata"];
|
|
1153
|
+
const store = this.alertStore;
|
|
1154
|
+
if (store === null) return;
|
|
1155
|
+
const raw = await store.getData(alertId);
|
|
1156
|
+
if (raw === null) return;
|
|
1157
|
+
const meta = raw["metadata"];
|
|
952
1158
|
const metadata = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta : {};
|
|
953
|
-
await
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
...existing,
|
|
958
|
-
metadata: {
|
|
959
|
-
...metadata,
|
|
960
|
-
push
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
});
|
|
1159
|
+
await store.mergeUpdate(alertId, { metadata: {
|
|
1160
|
+
...metadata,
|
|
1161
|
+
push
|
|
1162
|
+
} });
|
|
964
1163
|
}
|
|
965
1164
|
/**
|
|
966
1165
|
* Retry every critical alert whose push is still pending - at boot and when
|
|
@@ -968,19 +1167,10 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
968
1167
|
* delivered is skipped by its key, so reconciling never sends twice.
|
|
969
1168
|
*/
|
|
970
1169
|
async reconcilePendingPushes() {
|
|
971
|
-
const
|
|
972
|
-
if (
|
|
1170
|
+
const store = this.alertStore;
|
|
1171
|
+
if (store === null) return;
|
|
973
1172
|
try {
|
|
974
|
-
const rows = await
|
|
975
|
-
collection: ALERTS_COLLECTION,
|
|
976
|
-
filter: {
|
|
977
|
-
orderBy: {
|
|
978
|
-
field: "updatedAt",
|
|
979
|
-
direction: "desc"
|
|
980
|
-
},
|
|
981
|
-
limit: 500
|
|
982
|
-
}
|
|
983
|
-
});
|
|
1173
|
+
const rows = await store.listRecent(500);
|
|
984
1174
|
for (const row of rows) {
|
|
985
1175
|
const parsed = AlertSchema.safeParse({
|
|
986
1176
|
id: row.id,
|
|
@@ -1007,12 +1197,9 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1007
1197
|
const modelId = data.modelId ?? "unknown";
|
|
1008
1198
|
const progress = data.progress ?? 0;
|
|
1009
1199
|
const stableId = `model-download:${modelId}`;
|
|
1010
|
-
const
|
|
1011
|
-
if (
|
|
1012
|
-
if (
|
|
1013
|
-
collection: ALERTS_COLLECTION,
|
|
1014
|
-
filter: { where: { id: stableId } }
|
|
1015
|
-
})).length > 0) {
|
|
1200
|
+
const store = this.alertStore;
|
|
1201
|
+
if (store === null) return;
|
|
1202
|
+
if (await store.getData(stableId) !== null) {
|
|
1016
1203
|
const now = Date.now();
|
|
1017
1204
|
if (progress >= 100) {
|
|
1018
1205
|
await this.mergeUpdate(stableId, {
|
|
@@ -1353,45 +1540,14 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1353
1540
|
* so we must read the existing record, merge the patch, and write back.
|
|
1354
1541
|
*/
|
|
1355
1542
|
async mergeUpdate(id, patch) {
|
|
1356
|
-
const
|
|
1357
|
-
if (
|
|
1358
|
-
|
|
1359
|
-
collection: ALERTS_COLLECTION,
|
|
1360
|
-
key: id
|
|
1361
|
-
});
|
|
1362
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
1363
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
1364
|
-
await backend.set.mutate({
|
|
1365
|
-
collection: ALERTS_COLLECTION,
|
|
1366
|
-
key: id,
|
|
1367
|
-
value: {
|
|
1368
|
-
...existing,
|
|
1369
|
-
...patch
|
|
1370
|
-
}
|
|
1371
|
-
});
|
|
1543
|
+
const store = this.alertStore;
|
|
1544
|
+
if (store === null) return;
|
|
1545
|
+
await store.mergeUpdate(id, patch);
|
|
1372
1546
|
}
|
|
1373
1547
|
async persistAlert(alert) {
|
|
1374
|
-
const
|
|
1375
|
-
if (
|
|
1376
|
-
|
|
1377
|
-
id: alert.id,
|
|
1378
|
-
category: alert.category,
|
|
1379
|
-
severity: alert.severity,
|
|
1380
|
-
title: alert.title,
|
|
1381
|
-
message: alert.message,
|
|
1382
|
-
status: alert.status,
|
|
1383
|
-
read: alert.read,
|
|
1384
|
-
createdAt: alert.createdAt,
|
|
1385
|
-
updatedAt: alert.updatedAt,
|
|
1386
|
-
...alert.progress !== void 0 ? { progress: alert.progress } : {},
|
|
1387
|
-
...alert.source ? { source: alert.source } : {},
|
|
1388
|
-
...alert.metadata ? { metadata: alert.metadata } : {}
|
|
1389
|
-
};
|
|
1390
|
-
await backend.set.mutate({
|
|
1391
|
-
collection: ALERTS_COLLECTION,
|
|
1392
|
-
key: alert.id,
|
|
1393
|
-
value: data
|
|
1394
|
-
});
|
|
1548
|
+
const store = this.alertStore;
|
|
1549
|
+
if (store === null) return;
|
|
1550
|
+
await store.persist(alert);
|
|
1395
1551
|
}
|
|
1396
1552
|
emitAlertCreatedEvent(alert) {
|
|
1397
1553
|
this.ctx.eventBus?.emit(createEvent("alert.created", EVENT_SOURCE, {
|
|
@@ -1411,36 +1567,18 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1411
1567
|
}));
|
|
1412
1568
|
}
|
|
1413
1569
|
async enforceMaxAlerts() {
|
|
1414
|
-
const
|
|
1415
|
-
if (
|
|
1416
|
-
if (await
|
|
1417
|
-
const all = await
|
|
1418
|
-
|
|
1419
|
-
filter: { orderBy: {
|
|
1420
|
-
field: "createdAt",
|
|
1421
|
-
direction: "asc"
|
|
1422
|
-
} }
|
|
1423
|
-
});
|
|
1424
|
-
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await backend.delete.mutate({
|
|
1425
|
-
collection: ALERTS_COLLECTION,
|
|
1426
|
-
key: id
|
|
1427
|
-
});
|
|
1570
|
+
const store = this.alertStore;
|
|
1571
|
+
if (store === null) return;
|
|
1572
|
+
if (await store.countAll() <= this.config.maxAlerts) return;
|
|
1573
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1574
|
+
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await store.delete(id);
|
|
1428
1575
|
}
|
|
1429
1576
|
async enforceRetention() {
|
|
1430
|
-
const
|
|
1431
|
-
if (
|
|
1577
|
+
const store = this.alertStore;
|
|
1578
|
+
if (store === null) return;
|
|
1432
1579
|
const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1e3;
|
|
1433
|
-
const all = await
|
|
1434
|
-
|
|
1435
|
-
filter: { orderBy: {
|
|
1436
|
-
field: "createdAt",
|
|
1437
|
-
direction: "asc"
|
|
1438
|
-
} }
|
|
1439
|
-
});
|
|
1440
|
-
for (const id of selectExpired(all.map(toPrunable), cutoff)) await backend.delete.mutate({
|
|
1441
|
-
collection: ALERTS_COLLECTION,
|
|
1442
|
-
key: id
|
|
1443
|
-
});
|
|
1580
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1581
|
+
for (const id of selectExpired(all.map(toPrunable), cutoff)) await store.delete(id);
|
|
1444
1582
|
}
|
|
1445
1583
|
};
|
|
1446
1584
|
//#endregion
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record kinds owned by alert-center (records plan phase 4).
|
|
3
|
+
*/
|
|
4
|
+
import { type Alert, type DefinedRecordKind } from "@camstack/types";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
/** Legacy collection / adoptsFrom target (canonical KV before phase 4). */
|
|
7
|
+
export declare const ALERTS_COLLECTION = "alerts";
|
|
8
|
+
export type AlertBody = Omit<Alert, "id">;
|
|
9
|
+
export declare const AlertBodySchema: z.ZodType<AlertBody>;
|
|
10
|
+
export type AlertCenterRecordKindsMap = {
|
|
11
|
+
readonly alerts: DefinedRecordKind<z.ZodType<AlertBody>>;
|
|
12
|
+
};
|
|
13
|
+
export declare const alertCenterRecordKinds: AlertCenterRecordKindsMap;
|
|
14
|
+
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
15
|
+
export declare const alertsRecordKind: DefinedRecordKind<z.ZodType<AlertBody>>;
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-DgOG8flk.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Lr as errMsg, P as FIRST_LEVEL_MACRO_CLASSES, Pi as isEvent, Rr as BaseAddon, ht as bareAddonId, la as EventCategory, zn as ptzAutotrackCapability } from "../../dist-BNunRyXT.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -2,6 +2,7 @@ import type { ProviderRegistration } from "@camstack/types";
|
|
|
2
2
|
import { BaseAddon } from "@camstack/types";
|
|
3
3
|
export declare class BackupOrchestratorAddon extends BaseAddon<Record<string, never>> {
|
|
4
4
|
private systemBackup;
|
|
5
|
+
private backupRecords;
|
|
5
6
|
private policies;
|
|
6
7
|
private schedules;
|
|
7
8
|
/** Backup encryption keys — PUBLIC keys only (see encryption-key-store.ts). */
|