@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
|
@@ -3,7 +3,9 @@ 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
|
+
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
|
+
const require_phase6_declare_gate = require("../../phase6-declare-gate-Ci1-8uUn.js");
|
|
7
9
|
//#region src/builtins/alerts/critical-push.ts
|
|
8
10
|
/** Alert categories that are critical system findings. */
|
|
9
11
|
var CRITICAL_CATEGORIES = new Set([
|
|
@@ -282,6 +284,211 @@ function runnerPushLine(record) {
|
|
|
282
284
|
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.`;
|
|
283
285
|
}
|
|
284
286
|
//#endregion
|
|
287
|
+
//#region src/builtins/alerts/record-kinds.ts
|
|
288
|
+
var import_read_all_rows = require_read_all_rows$1.require_read_all_rows();
|
|
289
|
+
/**
|
|
290
|
+
* Record kinds owned by alert-center (records plan phase 4).
|
|
291
|
+
*/
|
|
292
|
+
/** Legacy collection / adoptsFrom target (canonical KV before phase 4). */
|
|
293
|
+
var ALERTS_COLLECTION = "alerts";
|
|
294
|
+
var AlertBodySchema = require_dist.AlertSchema.omit({ id: true });
|
|
295
|
+
var _alertCenterRecordKinds = require_dist.defineRecordKinds({ alerts: {
|
|
296
|
+
schema: AlertBodySchema,
|
|
297
|
+
class: "audit",
|
|
298
|
+
writeTrigger: "EventBus categories the alert center tracks, operator mark read/dismiss, and model-download progress merges",
|
|
299
|
+
device: "none",
|
|
300
|
+
at: "none",
|
|
301
|
+
indexes: [
|
|
302
|
+
{
|
|
303
|
+
name: "read",
|
|
304
|
+
fields: ["read"]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "created_at",
|
|
308
|
+
fields: ["createdAt"]
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "updated_at",
|
|
312
|
+
fields: ["updatedAt"]
|
|
313
|
+
}
|
|
314
|
+
],
|
|
315
|
+
retention: {
|
|
316
|
+
owner: "alert-center",
|
|
317
|
+
reason: "maxAlerts cap and retentionDays enforced on write (enforceMaxAlerts / enforceRetention); read alerts preferred when trimming overflow"
|
|
318
|
+
},
|
|
319
|
+
adoptsFrom: ALERTS_COLLECTION
|
|
320
|
+
} });
|
|
321
|
+
var alertCenterRecordKinds = _alertCenterRecordKinds;
|
|
322
|
+
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
323
|
+
var alertsRecordKind = _alertCenterRecordKinds.alerts;
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/builtins/alerts/alert-store.ts
|
|
326
|
+
function toRecord(row) {
|
|
327
|
+
return {
|
|
328
|
+
id: row.id,
|
|
329
|
+
data: row.data
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function toRecordFromLegacy(row) {
|
|
333
|
+
return {
|
|
334
|
+
id: row.id,
|
|
335
|
+
data: row.data
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function isRecord(value) {
|
|
339
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
340
|
+
}
|
|
341
|
+
function legacyGetData(value) {
|
|
342
|
+
if (!isRecord(value)) return null;
|
|
343
|
+
if ("data" in value) {
|
|
344
|
+
const data = value.data;
|
|
345
|
+
return isRecord(data) ? data : null;
|
|
346
|
+
}
|
|
347
|
+
return value;
|
|
348
|
+
}
|
|
349
|
+
var AlertStore = class AlertStore {
|
|
350
|
+
kind;
|
|
351
|
+
legacyStore;
|
|
352
|
+
constructor(kind, legacyStore) {
|
|
353
|
+
this.kind = kind;
|
|
354
|
+
this.legacyStore = legacyStore;
|
|
355
|
+
}
|
|
356
|
+
static of(records) {
|
|
357
|
+
return new AlertStore(records.kind(alertsRecordKind), null);
|
|
358
|
+
}
|
|
359
|
+
static legacy(store) {
|
|
360
|
+
return new AlertStore(null, store);
|
|
361
|
+
}
|
|
362
|
+
async legacyRows() {
|
|
363
|
+
const store = this.legacyStore;
|
|
364
|
+
if (store === null) return [];
|
|
365
|
+
return (await store.query.query({
|
|
366
|
+
collection: ALERTS_COLLECTION,
|
|
367
|
+
filter: {}
|
|
368
|
+
})).map((row) => toRecordFromLegacy({
|
|
369
|
+
id: row.id,
|
|
370
|
+
data: row.data
|
|
371
|
+
}));
|
|
372
|
+
}
|
|
373
|
+
async list(filter) {
|
|
374
|
+
let out;
|
|
375
|
+
const kind = this.kind;
|
|
376
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
377
|
+
else out = [...await this.legacyRows()];
|
|
378
|
+
if (filter?.unreadOnly === true) out = out.filter((r) => r.data["read"] === false);
|
|
379
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
380
|
+
const limit = filter?.limit ?? 100;
|
|
381
|
+
return out.slice(0, limit);
|
|
382
|
+
}
|
|
383
|
+
async countUnread() {
|
|
384
|
+
return (await this.list({
|
|
385
|
+
unreadOnly: true,
|
|
386
|
+
limit: 1e4
|
|
387
|
+
})).length;
|
|
388
|
+
}
|
|
389
|
+
async countAll() {
|
|
390
|
+
const kind = this.kind;
|
|
391
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).length;
|
|
392
|
+
return (await this.legacyRows()).length;
|
|
393
|
+
}
|
|
394
|
+
async getData(id) {
|
|
395
|
+
const kind = this.kind;
|
|
396
|
+
if (kind !== null) {
|
|
397
|
+
const row = await kind.get(id);
|
|
398
|
+
if (row === null) return null;
|
|
399
|
+
return row.data;
|
|
400
|
+
}
|
|
401
|
+
const store = this.legacyStore;
|
|
402
|
+
if (store === null) return null;
|
|
403
|
+
return legacyGetData(await store.get.query({
|
|
404
|
+
collection: ALERTS_COLLECTION,
|
|
405
|
+
key: id
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
408
|
+
async mergeUpdate(id, patch) {
|
|
409
|
+
const existing = await this.getData(id);
|
|
410
|
+
if (existing === null) return;
|
|
411
|
+
await this.putRaw(id, {
|
|
412
|
+
...existing,
|
|
413
|
+
...patch
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
async persist(alert) {
|
|
417
|
+
const { id, ...body } = alert;
|
|
418
|
+
const data = alertsRecordKind.schema.parse(body);
|
|
419
|
+
const kind = this.kind;
|
|
420
|
+
if (kind !== null) {
|
|
421
|
+
await kind.put({
|
|
422
|
+
id,
|
|
423
|
+
data
|
|
424
|
+
});
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
await this.putRaw(id, {
|
|
428
|
+
...body,
|
|
429
|
+
id
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
async putRaw(id, data) {
|
|
433
|
+
const { id: _drop, ...body } = require_dist.AlertSchema.parse({
|
|
434
|
+
id,
|
|
435
|
+
...data
|
|
436
|
+
});
|
|
437
|
+
const kind = this.kind;
|
|
438
|
+
if (kind !== null) {
|
|
439
|
+
await kind.put({
|
|
440
|
+
id,
|
|
441
|
+
data: body
|
|
442
|
+
});
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const store = this.legacyStore;
|
|
446
|
+
if (store === null) return;
|
|
447
|
+
await store.set.mutate({
|
|
448
|
+
collection: ALERTS_COLLECTION,
|
|
449
|
+
key: id,
|
|
450
|
+
value: {
|
|
451
|
+
id,
|
|
452
|
+
...body
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
async delete(id) {
|
|
457
|
+
const kind = this.kind;
|
|
458
|
+
if (kind !== null) {
|
|
459
|
+
await kind.delete(id);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const store = this.legacyStore;
|
|
463
|
+
if (store === null) return;
|
|
464
|
+
await store.delete.mutate({
|
|
465
|
+
collection: ALERTS_COLLECTION,
|
|
466
|
+
key: id
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
async listAllByCreatedAtAsc() {
|
|
470
|
+
const kind = this.kind;
|
|
471
|
+
let out;
|
|
472
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind)).map(toRecord);
|
|
473
|
+
else out = [...await this.legacyRows()];
|
|
474
|
+
out.sort((a, b) => Number(a.data["createdAt"] ?? 0) - Number(b.data["createdAt"] ?? 0));
|
|
475
|
+
return out;
|
|
476
|
+
}
|
|
477
|
+
async listRecent(limit) {
|
|
478
|
+
const kind = this.kind;
|
|
479
|
+
let out;
|
|
480
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
481
|
+
else out = [...await this.legacyRows()];
|
|
482
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
483
|
+
return out.slice(0, limit);
|
|
484
|
+
}
|
|
485
|
+
async findWhereDataField(field, value) {
|
|
486
|
+
const kind = this.kind;
|
|
487
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).filter((r) => r.data[field] === value).map(toRecord);
|
|
488
|
+
return (await this.legacyRows()).filter((r) => r.data[field] === value);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
//#endregion
|
|
285
492
|
//#region src/builtins/alerts/alerts.addon.ts
|
|
286
493
|
var CATEGORY_MAPPINGS = {
|
|
287
494
|
"addon.crashed": {
|
|
@@ -454,13 +661,18 @@ var DEFAULT_CONFIG = {
|
|
|
454
661
|
maxAlerts: 500,
|
|
455
662
|
retentionDays: 30,
|
|
456
663
|
criticalPushEnabled: true,
|
|
457
|
-
criticalPushTargetIds:
|
|
664
|
+
criticalPushTargetIds: []
|
|
458
665
|
};
|
|
666
|
+
/** Accept the live `string[]` shape and the pre-multiselect CSV string. */
|
|
667
|
+
function normalizeCriticalPushTargetIds(raw) {
|
|
668
|
+
if (Array.isArray(raw)) return raw.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim());
|
|
669
|
+
if (typeof raw === "string" && raw.trim().length > 0) return raw.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
670
|
+
return [];
|
|
671
|
+
}
|
|
459
672
|
/** One burst of critical findings (a whole boot of refused runners) is ONE digest push. */
|
|
460
673
|
var PUSH_COALESCE_MS = 2e3;
|
|
461
674
|
/** Addons whose (re)start is a reason to retry pending critical pushes. */
|
|
462
675
|
var PUSH_RECONCILE_ADDONS = new Set(["notifiers", "notification-center"]);
|
|
463
|
-
var ALERTS_COLLECTION = "alerts";
|
|
464
676
|
var EVENT_SOURCE = {
|
|
465
677
|
type: "addon",
|
|
466
678
|
id: "alert-center"
|
|
@@ -481,6 +693,7 @@ function toPrunable(record) {
|
|
|
481
693
|
};
|
|
482
694
|
}
|
|
483
695
|
var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
696
|
+
alertStore = null;
|
|
484
697
|
unsubscribers = [];
|
|
485
698
|
/** How long a burst of critical findings is gathered into one digest push. */
|
|
486
699
|
pushCoalesceMs;
|
|
@@ -495,6 +708,11 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
495
708
|
*/
|
|
496
709
|
rateLimitCounters = /* @__PURE__ */ new Map();
|
|
497
710
|
async onInitialize() {
|
|
711
|
+
const records = this.ctx.records;
|
|
712
|
+
const store = this.ctx.api?.settingsStore;
|
|
713
|
+
const useRecords = records !== void 0 && store !== void 0 && await require_phase6_declare_gate.resolvePhase6UseRecordsPathForHub(this.ctx, "alert-center", alertCenterRecordKinds, ["alerts"]);
|
|
714
|
+
this.alertStore = useRecords && records !== void 0 ? AlertStore.of(records) : store === void 0 ? null : AlertStore.legacy(store);
|
|
715
|
+
if (this.alertStore === null) throw new Error("alert-center needs ctx.records or settings-store on the hub");
|
|
498
716
|
const alertsProvider = {
|
|
499
717
|
emit: (alert) => this.emitAlert(alert),
|
|
500
718
|
update: (input) => this.updateAlert(input.alertId, input.patch),
|
|
@@ -514,6 +732,7 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
514
732
|
this.unsubscribers = unsubs;
|
|
515
733
|
this.reconcilePendingPushes();
|
|
516
734
|
this.dismissLegacyStreamCards(void 0);
|
|
735
|
+
this.migrateCriticalPushTargetIds();
|
|
517
736
|
this.ctx.logger.info("Initialized", { meta: { trackedCategoriesCount: TRACKED_CATEGORIES.length } });
|
|
518
737
|
return [{
|
|
519
738
|
capability: require_dist.alertsCapability,
|
|
@@ -561,43 +780,28 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
561
780
|
type: "boolean",
|
|
562
781
|
key: "criticalPushEnabled",
|
|
563
782
|
label: "Push critical system alerts",
|
|
564
|
-
description: "A runner that failed or refused to start, or a node whose runners are degraded, is pushed straight to the notifier targets
|
|
783
|
+
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.",
|
|
565
784
|
default: true
|
|
566
785
|
}),
|
|
567
786
|
this.field({
|
|
568
|
-
type: "
|
|
787
|
+
type: "notification-target-multiselect",
|
|
569
788
|
key: "criticalPushTargetIds",
|
|
570
789
|
label: "Critical push targets",
|
|
571
|
-
description: "
|
|
572
|
-
default:
|
|
790
|
+
description: "Notifier targets that receive critical system alerts. Empty = every enabled shared (not personal) target.",
|
|
791
|
+
default: []
|
|
573
792
|
})
|
|
574
793
|
]
|
|
575
794
|
}] });
|
|
576
795
|
}
|
|
577
796
|
async listAlerts(filter) {
|
|
578
|
-
const
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
if (filter?.unreadOnly) whereClause.read = false;
|
|
582
|
-
return (await backend.query.query({
|
|
583
|
-
collection: ALERTS_COLLECTION,
|
|
584
|
-
filter: {
|
|
585
|
-
where: Object.keys(whereClause).length > 0 ? whereClause : void 0,
|
|
586
|
-
orderBy: {
|
|
587
|
-
field: "updatedAt",
|
|
588
|
-
direction: "desc"
|
|
589
|
-
},
|
|
590
|
-
limit: filter?.limit ?? 100
|
|
591
|
-
}
|
|
592
|
-
})).map(parseAlert);
|
|
797
|
+
const store = this.alertStore;
|
|
798
|
+
if (store === null) return [];
|
|
799
|
+
return (await store.list(filter)).map(parseAlert);
|
|
593
800
|
}
|
|
594
801
|
async getUnreadCount() {
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
597
|
-
return
|
|
598
|
-
collection: ALERTS_COLLECTION,
|
|
599
|
-
filter: { where: { read: false } }
|
|
600
|
-
});
|
|
802
|
+
const store = this.alertStore;
|
|
803
|
+
if (store === null) return 0;
|
|
804
|
+
return store.countUnread();
|
|
601
805
|
}
|
|
602
806
|
async markRead(alertId) {
|
|
603
807
|
await this.mergeUpdate(alertId, {
|
|
@@ -606,11 +810,11 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
606
810
|
});
|
|
607
811
|
}
|
|
608
812
|
async markAllRead() {
|
|
609
|
-
const
|
|
610
|
-
if (
|
|
611
|
-
const unread = await
|
|
612
|
-
|
|
613
|
-
|
|
813
|
+
const store = this.alertStore;
|
|
814
|
+
if (store === null) return;
|
|
815
|
+
const unread = await store.list({
|
|
816
|
+
unreadOnly: true,
|
|
817
|
+
limit: 1e4
|
|
614
818
|
});
|
|
615
819
|
const now = Date.now();
|
|
616
820
|
for (const record of unread) await this.mergeUpdate(record.id, {
|
|
@@ -707,14 +911,14 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
707
911
|
}
|
|
708
912
|
}
|
|
709
913
|
async readRunnerRecord(alertId) {
|
|
710
|
-
const
|
|
711
|
-
if (
|
|
712
|
-
const raw = await
|
|
713
|
-
|
|
714
|
-
|
|
914
|
+
const store = this.alertStore;
|
|
915
|
+
if (store === null) return null;
|
|
916
|
+
const raw = await store.getData(alertId);
|
|
917
|
+
if (raw === null) return null;
|
|
918
|
+
const alert = require_dist.AlertSchema.safeParse({
|
|
919
|
+
id: alertId,
|
|
920
|
+
...raw
|
|
715
921
|
});
|
|
716
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
717
|
-
const alert = require_dist.AlertSchema.safeParse(raw);
|
|
718
922
|
if (!alert.success || alert.data.status === "dismissed") return null;
|
|
719
923
|
return parseRunnerRecord(alert.data.metadata?.["runner"]);
|
|
720
924
|
}
|
|
@@ -842,13 +1046,10 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
842
1046
|
});
|
|
843
1047
|
}
|
|
844
1048
|
async readAlertRaw(alertId) {
|
|
845
|
-
const
|
|
846
|
-
if (
|
|
847
|
-
const raw = await
|
|
848
|
-
|
|
849
|
-
key: alertId
|
|
850
|
-
});
|
|
851
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
1049
|
+
const store = this.alertStore;
|
|
1050
|
+
if (store === null) return null;
|
|
1051
|
+
const raw = await store.getData(alertId);
|
|
1052
|
+
if (raw === null) return null;
|
|
852
1053
|
const rec = Object.fromEntries(Object.entries(raw));
|
|
853
1054
|
const meta = rec["metadata"];
|
|
854
1055
|
const push = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta["push"] : void 0;
|
|
@@ -866,9 +1067,19 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
866
1067
|
pushPolicy() {
|
|
867
1068
|
return {
|
|
868
1069
|
enabled: this.config.criticalPushEnabled,
|
|
869
|
-
targetIds: this.config.criticalPushTargetIds
|
|
1070
|
+
targetIds: normalizeCriticalPushTargetIds(this.config.criticalPushTargetIds)
|
|
870
1071
|
};
|
|
871
1072
|
}
|
|
1073
|
+
/** Rewrite a legacy CSV `criticalPushTargetIds` string into `string[]`. */
|
|
1074
|
+
async migrateCriticalPushTargetIds() {
|
|
1075
|
+
const raw = this.config.criticalPushTargetIds;
|
|
1076
|
+
if (typeof raw !== "string") return;
|
|
1077
|
+
try {
|
|
1078
|
+
await this.updateGlobalSettings({ criticalPushTargetIds: normalizeCriticalPushTargetIds(raw) });
|
|
1079
|
+
} catch (err) {
|
|
1080
|
+
this.ctx.logger.warn("criticalPushTargetIds CSV migration failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
872
1083
|
pushPorts() {
|
|
873
1084
|
const api = this.ctx.api;
|
|
874
1085
|
return {
|
|
@@ -945,27 +1156,16 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
945
1156
|
return this.pushChain;
|
|
946
1157
|
}
|
|
947
1158
|
async storePushState(alertId, push) {
|
|
948
|
-
const
|
|
949
|
-
if (
|
|
950
|
-
const raw = await
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
});
|
|
954
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
955
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
956
|
-
const meta = existing["metadata"];
|
|
1159
|
+
const store = this.alertStore;
|
|
1160
|
+
if (store === null) return;
|
|
1161
|
+
const raw = await store.getData(alertId);
|
|
1162
|
+
if (raw === null) return;
|
|
1163
|
+
const meta = raw["metadata"];
|
|
957
1164
|
const metadata = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta : {};
|
|
958
|
-
await
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
...existing,
|
|
963
|
-
metadata: {
|
|
964
|
-
...metadata,
|
|
965
|
-
push
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
});
|
|
1165
|
+
await store.mergeUpdate(alertId, { metadata: {
|
|
1166
|
+
...metadata,
|
|
1167
|
+
push
|
|
1168
|
+
} });
|
|
969
1169
|
}
|
|
970
1170
|
/**
|
|
971
1171
|
* Retry every critical alert whose push is still pending - at boot and when
|
|
@@ -973,19 +1173,10 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
973
1173
|
* delivered is skipped by its key, so reconciling never sends twice.
|
|
974
1174
|
*/
|
|
975
1175
|
async reconcilePendingPushes() {
|
|
976
|
-
const
|
|
977
|
-
if (
|
|
1176
|
+
const store = this.alertStore;
|
|
1177
|
+
if (store === null) return;
|
|
978
1178
|
try {
|
|
979
|
-
const rows = await
|
|
980
|
-
collection: ALERTS_COLLECTION,
|
|
981
|
-
filter: {
|
|
982
|
-
orderBy: {
|
|
983
|
-
field: "updatedAt",
|
|
984
|
-
direction: "desc"
|
|
985
|
-
},
|
|
986
|
-
limit: 500
|
|
987
|
-
}
|
|
988
|
-
});
|
|
1179
|
+
const rows = await store.listRecent(500);
|
|
989
1180
|
for (const row of rows) {
|
|
990
1181
|
const parsed = require_dist.AlertSchema.safeParse({
|
|
991
1182
|
id: row.id,
|
|
@@ -1012,12 +1203,9 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
1012
1203
|
const modelId = data.modelId ?? "unknown";
|
|
1013
1204
|
const progress = data.progress ?? 0;
|
|
1014
1205
|
const stableId = `model-download:${modelId}`;
|
|
1015
|
-
const
|
|
1016
|
-
if (
|
|
1017
|
-
if (
|
|
1018
|
-
collection: ALERTS_COLLECTION,
|
|
1019
|
-
filter: { where: { id: stableId } }
|
|
1020
|
-
})).length > 0) {
|
|
1206
|
+
const store = this.alertStore;
|
|
1207
|
+
if (store === null) return;
|
|
1208
|
+
if (await store.getData(stableId) !== null) {
|
|
1021
1209
|
const now = Date.now();
|
|
1022
1210
|
if (progress >= 100) {
|
|
1023
1211
|
await this.mergeUpdate(stableId, {
|
|
@@ -1358,45 +1546,14 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
1358
1546
|
* so we must read the existing record, merge the patch, and write back.
|
|
1359
1547
|
*/
|
|
1360
1548
|
async mergeUpdate(id, patch) {
|
|
1361
|
-
const
|
|
1362
|
-
if (
|
|
1363
|
-
|
|
1364
|
-
collection: ALERTS_COLLECTION,
|
|
1365
|
-
key: id
|
|
1366
|
-
});
|
|
1367
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
1368
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
1369
|
-
await backend.set.mutate({
|
|
1370
|
-
collection: ALERTS_COLLECTION,
|
|
1371
|
-
key: id,
|
|
1372
|
-
value: {
|
|
1373
|
-
...existing,
|
|
1374
|
-
...patch
|
|
1375
|
-
}
|
|
1376
|
-
});
|
|
1549
|
+
const store = this.alertStore;
|
|
1550
|
+
if (store === null) return;
|
|
1551
|
+
await store.mergeUpdate(id, patch);
|
|
1377
1552
|
}
|
|
1378
1553
|
async persistAlert(alert) {
|
|
1379
|
-
const
|
|
1380
|
-
if (
|
|
1381
|
-
|
|
1382
|
-
id: alert.id,
|
|
1383
|
-
category: alert.category,
|
|
1384
|
-
severity: alert.severity,
|
|
1385
|
-
title: alert.title,
|
|
1386
|
-
message: alert.message,
|
|
1387
|
-
status: alert.status,
|
|
1388
|
-
read: alert.read,
|
|
1389
|
-
createdAt: alert.createdAt,
|
|
1390
|
-
updatedAt: alert.updatedAt,
|
|
1391
|
-
...alert.progress !== void 0 ? { progress: alert.progress } : {},
|
|
1392
|
-
...alert.source ? { source: alert.source } : {},
|
|
1393
|
-
...alert.metadata ? { metadata: alert.metadata } : {}
|
|
1394
|
-
};
|
|
1395
|
-
await backend.set.mutate({
|
|
1396
|
-
collection: ALERTS_COLLECTION,
|
|
1397
|
-
key: alert.id,
|
|
1398
|
-
value: data
|
|
1399
|
-
});
|
|
1554
|
+
const store = this.alertStore;
|
|
1555
|
+
if (store === null) return;
|
|
1556
|
+
await store.persist(alert);
|
|
1400
1557
|
}
|
|
1401
1558
|
emitAlertCreatedEvent(alert) {
|
|
1402
1559
|
this.ctx.eventBus?.emit(require_dist.createEvent("alert.created", EVENT_SOURCE, {
|
|
@@ -1416,36 +1573,18 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
1416
1573
|
}));
|
|
1417
1574
|
}
|
|
1418
1575
|
async enforceMaxAlerts() {
|
|
1419
|
-
const
|
|
1420
|
-
if (
|
|
1421
|
-
if (await
|
|
1422
|
-
const all = await
|
|
1423
|
-
|
|
1424
|
-
filter: { orderBy: {
|
|
1425
|
-
field: "createdAt",
|
|
1426
|
-
direction: "asc"
|
|
1427
|
-
} }
|
|
1428
|
-
});
|
|
1429
|
-
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await backend.delete.mutate({
|
|
1430
|
-
collection: ALERTS_COLLECTION,
|
|
1431
|
-
key: id
|
|
1432
|
-
});
|
|
1576
|
+
const store = this.alertStore;
|
|
1577
|
+
if (store === null) return;
|
|
1578
|
+
if (await store.countAll() <= this.config.maxAlerts) return;
|
|
1579
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1580
|
+
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await store.delete(id);
|
|
1433
1581
|
}
|
|
1434
1582
|
async enforceRetention() {
|
|
1435
|
-
const
|
|
1436
|
-
if (
|
|
1583
|
+
const store = this.alertStore;
|
|
1584
|
+
if (store === null) return;
|
|
1437
1585
|
const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1e3;
|
|
1438
|
-
const all = await
|
|
1439
|
-
|
|
1440
|
-
filter: { orderBy: {
|
|
1441
|
-
field: "createdAt",
|
|
1442
|
-
direction: "asc"
|
|
1443
|
-
} }
|
|
1444
|
-
});
|
|
1445
|
-
for (const id of selectExpired(all.map(toPrunable), cutoff)) await backend.delete.mutate({
|
|
1446
|
-
collection: ALERTS_COLLECTION,
|
|
1447
|
-
key: id
|
|
1448
|
-
});
|
|
1586
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1587
|
+
for (const id of selectExpired(all.map(toPrunable), cutoff)) await store.delete(id);
|
|
1449
1588
|
}
|
|
1450
1589
|
};
|
|
1451
1590
|
//#endregion
|