@camstack/system 1.2.21 → 1.2.23
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 +1 -1
- package/dist/addon-runner.mjs +1 -1
- 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/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +17 -13
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1319 -1097
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1319 -1097
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +33 -0
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.d.ts +16 -0
- package/dist/builtins/local-network/local-network.addon.js +30 -2
- package/dist/builtins/local-network/local-network.addon.mjs +30 -2
- package/dist/builtins/loki-logging/index.js +34 -12
- package/dist/builtins/loki-logging/index.mjs +34 -12
- package/dist/builtins/loki-logging/loki-logging.addon.d.ts +19 -0
- 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/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/sqlite-settings.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +7 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +112 -6
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +112 -6
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +17 -1
- package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +5 -0
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-DmQ6thmF.mjs → dist-CIek6F9X.mjs} +536 -76
- package/dist/{dist-OQ1yU92D.js → dist-CS0pdC8l.js} +536 -76
- package/dist/index.js +58 -8
- package/dist/index.mjs +58 -8
- package/dist/kernel/capability-registry.d.ts +9 -0
- package/dist/kernel/transport/local-child-registry.d.ts +18 -0
- package/dist/kernel/transport/parent-unowned-call.d.ts +22 -0
- package/dist/logging/log-manager.d.ts +32 -1
- package/dist/logging/partitioned-log-buffer.d.ts +15 -3
- package/dist/{manifest-python-deps-B30qVAuW.mjs → manifest-python-deps-57PA4rHm.mjs} +15 -6
- package/dist/{manifest-python-deps-CnRW2Utv.js → manifest-python-deps-CqDPWqEE.js} +14 -5
- package/package.json +3 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ISettingsBackend, TableSchema } from '@camstack/types';
|
|
2
|
+
/**
|
|
3
|
+
* A backup schedule row.
|
|
4
|
+
*
|
|
5
|
+
* `locationIds` is the fan-out set (destination `backups` locations).
|
|
6
|
+
* `retentionCount` applies to every one of them for THIS schedule's
|
|
7
|
+
* runs. `dataSources` optionally narrows which top-level state
|
|
8
|
+
* locations get archived; empty = the orchestrator's full default set.
|
|
9
|
+
*/
|
|
10
|
+
export interface BackupSchedule {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly label: string;
|
|
13
|
+
readonly cron: string;
|
|
14
|
+
readonly enabled: boolean;
|
|
15
|
+
readonly locationIds: readonly string[];
|
|
16
|
+
readonly retentionCount: number;
|
|
17
|
+
readonly dataSources?: readonly string[];
|
|
18
|
+
/** ms-epoch of the last successful run. */
|
|
19
|
+
readonly lastRunAt?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare const BACKUP_SCHEDULES_SCHEMA: TableSchema;
|
|
22
|
+
export declare class BackupScheduleService {
|
|
23
|
+
private readonly backend;
|
|
24
|
+
private tableEnsured;
|
|
25
|
+
constructor(backend: ISettingsBackend);
|
|
26
|
+
initialize(): Promise<void>;
|
|
27
|
+
private ensureTable;
|
|
28
|
+
list(): Promise<readonly BackupSchedule[]>;
|
|
29
|
+
get(id: string): Promise<BackupSchedule | null>;
|
|
30
|
+
/** Replace-or-insert (delete + insert — mirrors the policy store). */
|
|
31
|
+
upsert(s: BackupSchedule): Promise<void>;
|
|
32
|
+
delete(id: string): Promise<void>;
|
|
33
|
+
}
|
|
@@ -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-CS0pdC8l.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -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-CS0pdC8l.js");
|
|
7
7
|
let _camstack_types_node = require("@camstack/types/node");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as sleep, C as deviceStatusCapability, Ct as isDeviceConfigCap, D as enumerateSchemaFields, E as enumerateItemArrayFields, G as parseStreamParamsFormPatch, O as evaluateLinkExpression, S as deviceStateCapability, U as normalizeUnit, Y as setByPath, _ as applyTransform, a as CAP_NAMES_WITH_STATUS, at as BaseAddon, b as buildStreamParamsConfigSchema, dt as DeviceType, it as errMsg, j as getByPath, jt as EventCategory, l as STREAM_PROFILE_META, lt as DeviceFeature, mt as WELL_KNOWN_TAB_MAP, o as DeviceStatusSchema, rt as validateExpressionSource, t as ALL_CAPABILITY_DEFINITIONS, tt as toExpressionValue, ut as DeviceRole, x as deviceManagerCapability } from "../../dist-
|
|
1
|
+
import { At as sleep, C as deviceStatusCapability, Ct as isDeviceConfigCap, D as enumerateSchemaFields, E as enumerateItemArrayFields, G as parseStreamParamsFormPatch, O as evaluateLinkExpression, S as deviceStateCapability, U as normalizeUnit, Y as setByPath, _ as applyTransform, a as CAP_NAMES_WITH_STATUS, at as BaseAddon, b as buildStreamParamsConfigSchema, dt as DeviceType, it as errMsg, j as getByPath, jt as EventCategory, l as STREAM_PROFILE_META, lt as DeviceFeature, mt as WELL_KNOWN_TAB_MAP, o as DeviceStatusSchema, rt as validateExpressionSource, t as ALL_CAPABILITY_DEFINITIONS, tt as toExpressionValue, ut as DeviceRole, x as deviceManagerCapability } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
8
8
|
/**
|
|
9
9
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as BaseAddon, dt as DeviceType, it as errMsg, jt as EventCategory, vt as createEvent, w as doorbellCapability } from "../../dist-
|
|
1
|
+
import { at as BaseAddon, dt as DeviceType, it as errMsg, jt as EventCategory, vt as createEvent, w as doorbellCapability } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
3
3
|
/**
|
|
4
4
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -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-CS0pdC8l.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { at as BaseAddon, f as UserRecordSchema, nt as userManagementCapability, r as ApiKeyRecordSchema, u as ScopedTokenSchema, v as authProviderCapability } from "../../dist-
|
|
2
|
+
import { at as BaseAddon, f as UserRecordSchema, nt as userManagementCapability, r as ApiKeyRecordSchema, u as ScopedTokenSchema, v as authProviderCapability } from "../../dist-CIek6F9X.mjs";
|
|
3
3
|
import * as crypto$1 from "node:crypto";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import nodeCrypto from "crypto";
|
|
@@ -20,6 +20,14 @@ interface LocalNetworkConfig {
|
|
|
20
20
|
* with LAN/Wi-Fi addresses) from "operator explicitly cleared the
|
|
21
21
|
* allowlist" (true + empty → respect operator's choice). */
|
|
22
22
|
readonly bootSeeded: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The endpoint outbound artifacts (notification attachment links, deep
|
|
25
|
+
* links) must be addressed by. Empty = AUTO: the first public candidate,
|
|
26
|
+
* never loopback. Stored VERBATIM rather than as an index into the candidate
|
|
27
|
+
* list — interfaces come and go, and an index would silently re-point at a
|
|
28
|
+
* different address after a reboot.
|
|
29
|
+
*/
|
|
30
|
+
readonly notificationBaseUrl: string;
|
|
23
31
|
}
|
|
24
32
|
export declare class LocalNetworkAddon extends BaseAddon<LocalNetworkConfig> {
|
|
25
33
|
private pollTimer;
|
|
@@ -35,6 +43,14 @@ export declare class LocalNetworkAddon extends BaseAddon<LocalNetworkConfig> {
|
|
|
35
43
|
*/
|
|
36
44
|
private meshEndpoint;
|
|
37
45
|
constructor();
|
|
46
|
+
/**
|
|
47
|
+
* What AUTO currently resolves to for outbound artifact links: the first
|
|
48
|
+
* PUBLIC candidate, never loopback and never a LAN address — a link is
|
|
49
|
+
* opened on someone's phone, off this network, possibly hours later.
|
|
50
|
+
* `null` when nothing public is reachable (the caller then ships bytes only
|
|
51
|
+
* rather than a link that 404s).
|
|
52
|
+
*/
|
|
53
|
+
private resolveNotificationEndpoint;
|
|
38
54
|
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
39
55
|
protected onShutdown(): Promise<void>;
|
|
40
56
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
4
4
|
let node_os = require("node:os");
|
|
5
5
|
node_os = require_chunk.__toESM(node_os);
|
|
6
6
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
@@ -44,9 +44,25 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
44
44
|
constructor() {
|
|
45
45
|
super({
|
|
46
46
|
allowedAddresses: [],
|
|
47
|
-
bootSeeded: false
|
|
47
|
+
bootSeeded: false,
|
|
48
|
+
notificationBaseUrl: ""
|
|
48
49
|
});
|
|
49
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* What AUTO currently resolves to for outbound artifact links: the first
|
|
53
|
+
* PUBLIC candidate, never loopback and never a LAN address — a link is
|
|
54
|
+
* opened on someone's phone, off this network, possibly hours later.
|
|
55
|
+
* `null` when nothing public is reachable (the caller then ships bytes only
|
|
56
|
+
* rather than a link that 404s).
|
|
57
|
+
*/
|
|
58
|
+
resolveNotificationEndpoint() {
|
|
59
|
+
const explicit = this.config.notificationBaseUrl;
|
|
60
|
+
if (explicit !== "") return explicit;
|
|
61
|
+
if (this.publicHostname !== "") return `https://${this.publicHostname}`;
|
|
62
|
+
const mesh = this.meshEndpoint;
|
|
63
|
+
if (mesh !== null && mesh.host !== "") return `https://${mesh.host}:${mesh.port}`;
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
50
66
|
async onInitialize() {
|
|
51
67
|
if (!this.config.bootSeeded) {
|
|
52
68
|
const seed = autoSeedAllowlist(this.enumerate());
|
|
@@ -71,6 +87,18 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
71
87
|
await this.reconcileMeshEndpoint();
|
|
72
88
|
return { endpoints: buildEndpoints(interfaces, input.port, includeLoopback, ipv4Only, this.publicHostname, scheme, this.meshEndpoint) };
|
|
73
89
|
},
|
|
90
|
+
getNotificationEndpoint: async () => ({
|
|
91
|
+
baseUrl: this.config.notificationBaseUrl === "" ? null : this.config.notificationBaseUrl,
|
|
92
|
+
resolved: this.resolveNotificationEndpoint()
|
|
93
|
+
}),
|
|
94
|
+
setNotificationEndpoint: async ({ baseUrl }) => {
|
|
95
|
+
await this.updateGlobalSettings({ notificationBaseUrl: baseUrl ?? "" });
|
|
96
|
+
this.ctx.logger.info("local-network: notification endpoint set", { meta: { baseUrl: baseUrl ?? "(auto)" } });
|
|
97
|
+
return {
|
|
98
|
+
baseUrl: baseUrl === "" ? null : baseUrl,
|
|
99
|
+
resolved: this.resolveNotificationEndpoint()
|
|
100
|
+
};
|
|
101
|
+
},
|
|
74
102
|
getAllowedAddresses: async () => ({ addresses: this.config.allowedAddresses }),
|
|
75
103
|
resetAllowlistToBestMatch: async () => {
|
|
76
104
|
const seed = autoSeedAllowlist(this.enumerate());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as localNetworkCapability, at as BaseAddon, jt as EventCategory } from "../../dist-
|
|
1
|
+
import { R as localNetworkCapability, at as BaseAddon, jt as EventCategory } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
4
4
|
/**
|
|
@@ -41,9 +41,25 @@ var LocalNetworkAddon = class extends BaseAddon {
|
|
|
41
41
|
constructor() {
|
|
42
42
|
super({
|
|
43
43
|
allowedAddresses: [],
|
|
44
|
-
bootSeeded: false
|
|
44
|
+
bootSeeded: false,
|
|
45
|
+
notificationBaseUrl: ""
|
|
45
46
|
});
|
|
46
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* What AUTO currently resolves to for outbound artifact links: the first
|
|
50
|
+
* PUBLIC candidate, never loopback and never a LAN address — a link is
|
|
51
|
+
* opened on someone's phone, off this network, possibly hours later.
|
|
52
|
+
* `null` when nothing public is reachable (the caller then ships bytes only
|
|
53
|
+
* rather than a link that 404s).
|
|
54
|
+
*/
|
|
55
|
+
resolveNotificationEndpoint() {
|
|
56
|
+
const explicit = this.config.notificationBaseUrl;
|
|
57
|
+
if (explicit !== "") return explicit;
|
|
58
|
+
if (this.publicHostname !== "") return `https://${this.publicHostname}`;
|
|
59
|
+
const mesh = this.meshEndpoint;
|
|
60
|
+
if (mesh !== null && mesh.host !== "") return `https://${mesh.host}:${mesh.port}`;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
47
63
|
async onInitialize() {
|
|
48
64
|
if (!this.config.bootSeeded) {
|
|
49
65
|
const seed = autoSeedAllowlist(this.enumerate());
|
|
@@ -68,6 +84,18 @@ var LocalNetworkAddon = class extends BaseAddon {
|
|
|
68
84
|
await this.reconcileMeshEndpoint();
|
|
69
85
|
return { endpoints: buildEndpoints(interfaces, input.port, includeLoopback, ipv4Only, this.publicHostname, scheme, this.meshEndpoint) };
|
|
70
86
|
},
|
|
87
|
+
getNotificationEndpoint: async () => ({
|
|
88
|
+
baseUrl: this.config.notificationBaseUrl === "" ? null : this.config.notificationBaseUrl,
|
|
89
|
+
resolved: this.resolveNotificationEndpoint()
|
|
90
|
+
}),
|
|
91
|
+
setNotificationEndpoint: async ({ baseUrl }) => {
|
|
92
|
+
await this.updateGlobalSettings({ notificationBaseUrl: baseUrl ?? "" });
|
|
93
|
+
this.ctx.logger.info("local-network: notification endpoint set", { meta: { baseUrl: baseUrl ?? "(auto)" } });
|
|
94
|
+
return {
|
|
95
|
+
baseUrl: baseUrl === "" ? null : baseUrl,
|
|
96
|
+
resolved: this.resolveNotificationEndpoint()
|
|
97
|
+
};
|
|
98
|
+
},
|
|
71
99
|
getAllowedAddresses: async () => ({ addresses: this.config.allowedAddresses }),
|
|
72
100
|
resetAllowlistToBestMatch: async () => {
|
|
73
101
|
const seed = autoSeedAllowlist(this.enumerate());
|
|
@@ -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-CS0pdC8l.js");
|
|
7
7
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
8
8
|
/**
|
|
9
9
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -295,7 +295,8 @@ var LokiDestination = class {
|
|
|
295
295
|
//#endregion
|
|
296
296
|
//#region src/builtins/loki-logging/loki-logging.addon.ts
|
|
297
297
|
var DEFAULTS = {
|
|
298
|
-
enabled:
|
|
298
|
+
enabled: true,
|
|
299
|
+
migratedEnabled: false,
|
|
299
300
|
url: "",
|
|
300
301
|
job: "camstack",
|
|
301
302
|
level: "info",
|
|
@@ -315,12 +316,39 @@ var LokiLoggingAddon = class extends require_dist.BaseAddon {
|
|
|
315
316
|
async onInitialize() {
|
|
316
317
|
this.destination = new LokiDestination();
|
|
317
318
|
await this.destination.initialize(this.destinationConfig());
|
|
318
|
-
this.ctx.logger.info(this.config.
|
|
319
|
+
this.ctx.logger.info(this.config.url.length > 0 ? `Loki logging initialized → ${this.config.url}` : "Loki logging registered but inactive (no URL set)");
|
|
320
|
+
await this.migrateRetiredEnabledFlag();
|
|
319
321
|
return [{
|
|
320
322
|
capability: require_dist.logDestinationCapability,
|
|
321
323
|
provider: this.destination
|
|
322
324
|
}];
|
|
323
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* ONE-SHOT: carry a stored `enabled: false` over to the orchestrator's
|
|
328
|
+
* per-destination toggle, then never look at the flag again.
|
|
329
|
+
*
|
|
330
|
+
* Without this, retiring the private setting would silently RE-ENABLE Loki
|
|
331
|
+
* for every operator who had turned it off — shipping their logs to a host
|
|
332
|
+
* they may no longer control. Best-effort: if the toggle call fails the
|
|
333
|
+
* migration is simply retried next boot (the flag is only cleared on
|
|
334
|
+
* success).
|
|
335
|
+
*/
|
|
336
|
+
async migrateRetiredEnabledFlag() {
|
|
337
|
+
if (this.config.migratedEnabled) return;
|
|
338
|
+
try {
|
|
339
|
+
if (!this.config.enabled) {
|
|
340
|
+
await this.ctx.api.addons.setCapabilityProviderEnabled.mutate({
|
|
341
|
+
capName: "log-destination",
|
|
342
|
+
addonId: this.ctx.id,
|
|
343
|
+
enabled: false
|
|
344
|
+
});
|
|
345
|
+
this.ctx.logger.info("Loki logging: the retired `enabled: false` setting was carried over to the per-destination toggle — re-enable it there if you want Loki shipping again.");
|
|
346
|
+
}
|
|
347
|
+
await this.updateGlobalSettings({ migratedEnabled: true });
|
|
348
|
+
} catch (err) {
|
|
349
|
+
this.ctx.logger.warn("Loki logging: enablement migration deferred to next boot", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
350
|
+
}
|
|
351
|
+
}
|
|
324
352
|
async onShutdown() {
|
|
325
353
|
await this.destination?.shutdown();
|
|
326
354
|
this.destination = null;
|
|
@@ -334,7 +362,7 @@ var LokiLoggingAddon = class extends require_dist.BaseAddon {
|
|
|
334
362
|
*/
|
|
335
363
|
async onConfigChanged() {
|
|
336
364
|
await this.destination?.reconfigure(this.destinationConfig());
|
|
337
|
-
this.ctx.logger.info(this.config.
|
|
365
|
+
this.ctx.logger.info(this.config.url.length > 0 ? `Loki logging reconfigured → ${this.config.url}` : "Loki logging now inactive (no URL)");
|
|
338
366
|
}
|
|
339
367
|
/**
|
|
340
368
|
* `node` is a Loki LABEL, so it must be the node's real identity and must not
|
|
@@ -350,6 +378,7 @@ var LokiLoggingAddon = class extends require_dist.BaseAddon {
|
|
|
350
378
|
destinationConfig() {
|
|
351
379
|
return {
|
|
352
380
|
...this.config,
|
|
381
|
+
enabled: true,
|
|
353
382
|
node: this.ctx.kernel.localNodeId ?? "hub"
|
|
354
383
|
};
|
|
355
384
|
}
|
|
@@ -361,16 +390,9 @@ var LokiLoggingAddon = class extends require_dist.BaseAddon {
|
|
|
361
390
|
return this.schema({ sections: [{
|
|
362
391
|
id: "loki-logging",
|
|
363
392
|
title: "Loki",
|
|
364
|
-
description: "Ship this node’s logs to a Grafana Loki instance. Independent of the rotated-file and console destinations
|
|
393
|
+
description: "Ship this node’s logs to a Grafana Loki instance. Independent of the rotated-file and console destinations. Turn it on or off with the Enable/Disable control on this destination — the same one every other destination uses.",
|
|
365
394
|
columns: 2,
|
|
366
395
|
fields: [
|
|
367
|
-
this.field({
|
|
368
|
-
type: "boolean",
|
|
369
|
-
key: "enabled",
|
|
370
|
-
label: "Enabled",
|
|
371
|
-
description: "Off by default. Needs a URL below to do anything.",
|
|
372
|
-
default: false
|
|
373
|
-
}),
|
|
374
396
|
this.field({
|
|
375
397
|
type: "text",
|
|
376
398
|
key: "url",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { at as BaseAddon, z as logDestinationCapability } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
3
3
|
/**
|
|
4
4
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -290,7 +290,8 @@ var LokiDestination = class {
|
|
|
290
290
|
//#endregion
|
|
291
291
|
//#region src/builtins/loki-logging/loki-logging.addon.ts
|
|
292
292
|
var DEFAULTS = {
|
|
293
|
-
enabled:
|
|
293
|
+
enabled: true,
|
|
294
|
+
migratedEnabled: false,
|
|
294
295
|
url: "",
|
|
295
296
|
job: "camstack",
|
|
296
297
|
level: "info",
|
|
@@ -310,12 +311,39 @@ var LokiLoggingAddon = class extends BaseAddon {
|
|
|
310
311
|
async onInitialize() {
|
|
311
312
|
this.destination = new LokiDestination();
|
|
312
313
|
await this.destination.initialize(this.destinationConfig());
|
|
313
|
-
this.ctx.logger.info(this.config.
|
|
314
|
+
this.ctx.logger.info(this.config.url.length > 0 ? `Loki logging initialized → ${this.config.url}` : "Loki logging registered but inactive (no URL set)");
|
|
315
|
+
await this.migrateRetiredEnabledFlag();
|
|
314
316
|
return [{
|
|
315
317
|
capability: logDestinationCapability,
|
|
316
318
|
provider: this.destination
|
|
317
319
|
}];
|
|
318
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* ONE-SHOT: carry a stored `enabled: false` over to the orchestrator's
|
|
323
|
+
* per-destination toggle, then never look at the flag again.
|
|
324
|
+
*
|
|
325
|
+
* Without this, retiring the private setting would silently RE-ENABLE Loki
|
|
326
|
+
* for every operator who had turned it off — shipping their logs to a host
|
|
327
|
+
* they may no longer control. Best-effort: if the toggle call fails the
|
|
328
|
+
* migration is simply retried next boot (the flag is only cleared on
|
|
329
|
+
* success).
|
|
330
|
+
*/
|
|
331
|
+
async migrateRetiredEnabledFlag() {
|
|
332
|
+
if (this.config.migratedEnabled) return;
|
|
333
|
+
try {
|
|
334
|
+
if (!this.config.enabled) {
|
|
335
|
+
await this.ctx.api.addons.setCapabilityProviderEnabled.mutate({
|
|
336
|
+
capName: "log-destination",
|
|
337
|
+
addonId: this.ctx.id,
|
|
338
|
+
enabled: false
|
|
339
|
+
});
|
|
340
|
+
this.ctx.logger.info("Loki logging: the retired `enabled: false` setting was carried over to the per-destination toggle — re-enable it there if you want Loki shipping again.");
|
|
341
|
+
}
|
|
342
|
+
await this.updateGlobalSettings({ migratedEnabled: true });
|
|
343
|
+
} catch (err) {
|
|
344
|
+
this.ctx.logger.warn("Loki logging: enablement migration deferred to next boot", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
345
|
+
}
|
|
346
|
+
}
|
|
319
347
|
async onShutdown() {
|
|
320
348
|
await this.destination?.shutdown();
|
|
321
349
|
this.destination = null;
|
|
@@ -329,7 +357,7 @@ var LokiLoggingAddon = class extends BaseAddon {
|
|
|
329
357
|
*/
|
|
330
358
|
async onConfigChanged() {
|
|
331
359
|
await this.destination?.reconfigure(this.destinationConfig());
|
|
332
|
-
this.ctx.logger.info(this.config.
|
|
360
|
+
this.ctx.logger.info(this.config.url.length > 0 ? `Loki logging reconfigured → ${this.config.url}` : "Loki logging now inactive (no URL)");
|
|
333
361
|
}
|
|
334
362
|
/**
|
|
335
363
|
* `node` is a Loki LABEL, so it must be the node's real identity and must not
|
|
@@ -345,6 +373,7 @@ var LokiLoggingAddon = class extends BaseAddon {
|
|
|
345
373
|
destinationConfig() {
|
|
346
374
|
return {
|
|
347
375
|
...this.config,
|
|
376
|
+
enabled: true,
|
|
348
377
|
node: this.ctx.kernel.localNodeId ?? "hub"
|
|
349
378
|
};
|
|
350
379
|
}
|
|
@@ -356,16 +385,9 @@ var LokiLoggingAddon = class extends BaseAddon {
|
|
|
356
385
|
return this.schema({ sections: [{
|
|
357
386
|
id: "loki-logging",
|
|
358
387
|
title: "Loki",
|
|
359
|
-
description: "Ship this node’s logs to a Grafana Loki instance. Independent of the rotated-file and console destinations
|
|
388
|
+
description: "Ship this node’s logs to a Grafana Loki instance. Independent of the rotated-file and console destinations. Turn it on or off with the Enable/Disable control on this destination — the same one every other destination uses.",
|
|
360
389
|
columns: 2,
|
|
361
390
|
fields: [
|
|
362
|
-
this.field({
|
|
363
|
-
type: "boolean",
|
|
364
|
-
key: "enabled",
|
|
365
|
-
label: "Enabled",
|
|
366
|
-
description: "Off by default. Needs a URL below to do anything.",
|
|
367
|
-
default: false
|
|
368
|
-
}),
|
|
369
391
|
this.field({
|
|
370
392
|
type: "text",
|
|
371
393
|
key: "url",
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { LogLevel, ProviderRegistration, BaseAddon } from '@camstack/types';
|
|
2
2
|
import { LokiDestination } from './loki-destination.js';
|
|
3
3
|
interface LokiAddonConfig {
|
|
4
|
+
/**
|
|
5
|
+
* RETIRED (2026-07-30). Enablement is the orchestrator's per-destination
|
|
6
|
+
* toggle now — the ONE truth for every log destination. Kept only so a
|
|
7
|
+
* stored `false` can be migrated ONCE into a registry disable: without that,
|
|
8
|
+
* an operator who had Loki off would silently start shipping logs after this
|
|
9
|
+
* update. `migratedEnabled` marks the migration done; the field is then dead.
|
|
10
|
+
*/
|
|
4
11
|
readonly enabled: boolean;
|
|
12
|
+
readonly migratedEnabled: boolean;
|
|
5
13
|
readonly url: string;
|
|
6
14
|
readonly job: string;
|
|
7
15
|
readonly level: LogLevel;
|
|
@@ -17,6 +25,17 @@ export declare class LokiLoggingAddon extends BaseAddon<LokiAddonConfig> {
|
|
|
17
25
|
private destination;
|
|
18
26
|
constructor();
|
|
19
27
|
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
28
|
+
/**
|
|
29
|
+
* ONE-SHOT: carry a stored `enabled: false` over to the orchestrator's
|
|
30
|
+
* per-destination toggle, then never look at the flag again.
|
|
31
|
+
*
|
|
32
|
+
* Without this, retiring the private setting would silently RE-ENABLE Loki
|
|
33
|
+
* for every operator who had turned it off — shipping their logs to a host
|
|
34
|
+
* they may no longer control. Best-effort: if the toggle call fails the
|
|
35
|
+
* migration is simply retried next boot (the flag is only cleared on
|
|
36
|
+
* success).
|
|
37
|
+
*/
|
|
38
|
+
private migrateRetiredEnabledFlag;
|
|
20
39
|
protected onShutdown(): Promise<void>;
|
|
21
40
|
/**
|
|
22
41
|
* React to a settings change (enable/disable, URL, level, batching) without a
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as metricsProviderCapability, at as BaseAddon, jt as EventCategory, vt as createEvent } from "../../dist-
|
|
1
|
+
import { H as metricsProviderCapability, at as BaseAddon, jt as EventCategory, vt as createEvent } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import { execFile, execFileSync } from "node:child_process";
|
|
4
4
|
import { promisify } from "node:util";
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { J as scoreRuntimes, K as platformProbeCapability, T as enumerateInferenceDevices, at as BaseAddon, bt as emitReadiness, it as errMsg, jt as EventCategory } from "../../dist-
|
|
2
|
+
import { J as scoreRuntimes, K as platformProbeCapability, T as enumerateInferenceDevices, at as BaseAddon, bt as emitReadiness, it as errMsg, jt as EventCategory } from "../../dist-CIek6F9X.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { execFile } from "node:child_process";
|
|
5
5
|
import { promisify } from "node:util";
|
|
@@ -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-CS0pdC8l.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as BaseAddon, jt as EventCategory } from "../../dist-
|
|
1
|
+
import { at as BaseAddon, jt as EventCategory } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_child_process = require("node:child_process");
|
|
8
8
|
//#region src/builtins/snapshot/snapshot-coalescing.ts
|
|
9
9
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Z as snapshotCapability, at as BaseAddon, dt as DeviceType, et as streamQualityLabel, i as BatteryStatusSchema, it as errMsg, lt as DeviceFeature, wt as nodePin } from "../../dist-
|
|
1
|
+
import { Z as snapshotCapability, at as BaseAddon, dt as DeviceType, et as streamQualityLabel, i as BatteryStatusSchema, it as errMsg, lt as DeviceFeature, wt as nodePin } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
//#region src/builtins/snapshot/snapshot-coalescing.ts
|
|
4
4
|
/**
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as storageProviderCapability, A as filesystemBrowseCapability, at as BaseAddon } from "../../dist-
|
|
1
|
+
import { $ as storageProviderCapability, A as filesystemBrowseCapability, at as BaseAddon } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
@@ -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-
|
|
6
|
+
const require_dist = require("../../dist-CS0pdC8l.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let better_sqlite3 = require("better-sqlite3");
|
|
9
9
|
better_sqlite3 = require_chunk.__toESM(better_sqlite3);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Et as parseJsonUnknown, X as settingsStoreCapability, at as BaseAddon, c as RUNTIME_DEFAULTS, ht as asJsonObject, it as errMsg } from "../../dist-
|
|
1
|
+
import { Et as parseJsonUnknown, X as settingsStoreCapability, at as BaseAddon, c as RUNTIME_DEFAULTS, ht as asJsonObject, it as errMsg } from "../../dist-CIek6F9X.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
//#region src/builtins/sqlite-storage/sqlite-settings-backend.ts
|
|
@@ -64,6 +64,13 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
|
|
|
64
64
|
* the recorder so disk-pressure is a single core concern.
|
|
65
65
|
*/
|
|
66
66
|
private resolveLocationThresholds;
|
|
67
|
+
/** statfs capacity of a location's basePath, walking up to the nearest
|
|
68
|
+
* existing ancestor. Null for remote-node locations or unstattable paths. */
|
|
69
|
+
private localCapacityOf;
|
|
70
|
+
/** Per-location cap on EVICTABLE bytes (`config.maxUsedGb`): the operator's
|
|
71
|
+
* "recordings may use at most N GB in total" — enforced by the pressure
|
|
72
|
+
* manager alongside the free-percent guard. */
|
|
73
|
+
private resolveLocationMaxUsedBytes;
|
|
67
74
|
private locationBasePath;
|
|
68
75
|
/**
|
|
69
76
|
* A stable key for the PHYSICAL storage device behind a location — the
|