@camstack/system 1.2.316 → 1.2.317
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/auth/auth-manager.d.ts +11 -0
- 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/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +347 -181
- package/dist/builtins/composer/composer.addon.mjs +347 -181
- package/dist/builtins/composer/composition-evaluation.d.ts +37 -0
- package/dist/builtins/composer/composition-runtime.d.ts +11 -52
- package/dist/builtins/composer/composition-target.d.ts +50 -0
- package/dist/builtins/composer/existing-target.d.ts +19 -1
- package/dist/builtins/composer/own-field-reads.d.ts +19 -0
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +265 -29
- package/dist/builtins/device-manager/device-manager.addon.mjs +265 -29
- package/dist/builtins/device-manager/device-provider-context.d.ts +6 -0
- package/dist/builtins/device-manager/device-source-activation.d.ts +26 -1
- package/dist/builtins/device-manager/device-state-mirror.d.ts +41 -9
- package/dist/builtins/device-manager/mirror-row-writer.d.ts +59 -1
- package/dist/builtins/doorbell/binding-mirror.d.ts +45 -81
- package/dist/builtins/doorbell/doorbell-extension-slot.d.ts +4 -3
- package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +53 -11
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +207 -82
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +207 -82
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- 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/local-auth.addon.js +47 -3
- package/dist/builtins/local-auth/local-auth.addon.mjs +46 -4
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- 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/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 +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +4 -4
- package/dist/builtins/system-config/system-config.addon.mjs +4 -4
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{child-cap-dispatch-AAltfBUH.mjs → child-cap-dispatch-C2VINHu1.mjs} +70 -18
- package/dist/{child-cap-dispatch-DzcUd_ct.js → child-cap-dispatch-C8uts1P4.js} +70 -18
- package/dist/{composition-sources-fUyF4z39.mjs → composition-sources-DVClu006.mjs} +1 -1
- package/dist/{composition-sources-BwE1POnF.js → composition-sources-Dep7nBwu.js} +1 -1
- package/dist/{dist-BPvku43i.mjs → dist-Dori4pf3.mjs} +85 -6
- package/dist/{dist-RAl10EfG.js → dist-a6p0V-IL.js} +85 -6
- package/dist/index.js +739 -350
- package/dist/index.mjs +737 -352
- package/dist/kernel/bootstrap-config.d.ts +8 -0
- package/dist/kernel/capability-registry.d.ts +30 -0
- package/dist/kernel/config-manager.d.ts +75 -129
- package/dist/kernel/index.d.ts +5 -2
- package/dist/kernel/moleculer/runtime-state-load.d.ts +19 -0
- package/dist/kernel/settings-door-view.d.ts +24 -1
- package/dist/kernel/settings-read-error.d.ts +37 -0
- package/dist/kernel/settings-view-types.d.ts +105 -0
- package/dist/kernel/store-settings-view.d.ts +17 -0
- package/dist/kernel/system-settings-mirror.d.ts +34 -0
- package/dist/kernel/system-settings-policy.d.ts +47 -0
- package/dist/{retired-settings-keys-D3rGTGq5.js → retired-settings-keys-DC1uHWPZ.js} +1 -1
- package/dist/{retired-settings-keys-DqVWSrVw.mjs → retired-settings-keys-DVcKRgzm.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { $n as asNumber, Bt as looseSchema, C as METHOD_ACCESS_MAP, Dt as isCollectionArrayMethod, Et as isArrayOutputSchema, Ft as lifecycleJobSchema, Jn as DEVICE_STATUS_METHOD, Jt as objectInputDeclaresRequiredDeviceId, Kn as DATAPLANE_SECRET_HEADER$1, Mt as kebabToCamel, O as RUNTIME_DEFAULTS, Qn as asJsonObject$1, Qt as procedureAuthKey, Wn as errMsg$1, Xn as ReadinessTimeoutError, Yn as ReadinessRegistry, b as LOG_LEVEL_RANK, dr as readinessKey, er as asString$1, fr as resolveCapMount, hr as EventCategory$1, in as resolveMethodAuth, ir as expandCapMethods, jt as isVoidInput, kt as isObjectInput, lr as parseJsonObject, nr as emitDownForOwnedCaps, on as scopesAllowAddon, pr as scopeKey, qn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, qt as objectInputDeclaresAddonId, sn as scopesAllowDeviceCap, t as ALL_CAPABILITY_DEFINITIONS, tr as createEvent, ur as parseJsonUnknown, xt as extractNestedAddonId, z as addonSettingsCapability, zt as logLevelAtMost } from "./dist-
|
|
2
|
+
import { $n as asNumber, Bt as looseSchema, C as METHOD_ACCESS_MAP, Dt as isCollectionArrayMethod, Et as isArrayOutputSchema, Ft as lifecycleJobSchema, Jn as DEVICE_STATUS_METHOD, Jt as objectInputDeclaresRequiredDeviceId, Kn as DATAPLANE_SECRET_HEADER$1, Mt as kebabToCamel, O as RUNTIME_DEFAULTS, Qn as asJsonObject$1, Qt as procedureAuthKey, Wn as errMsg$1, Xn as ReadinessTimeoutError, Yn as ReadinessRegistry, b as LOG_LEVEL_RANK, dr as readinessKey, er as asString$1, fr as resolveCapMount, hr as EventCategory$1, in as resolveMethodAuth, ir as expandCapMethods, jt as isVoidInput, kt as isObjectInput, lr as parseJsonObject, nr as emitDownForOwnedCaps, on as scopesAllowAddon, pr as scopeKey, qn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, qt as objectInputDeclaresAddonId, sn as scopesAllowDeviceCap, t as ALL_CAPABILITY_DEFINITIONS, tr as createEvent, ur as parseJsonUnknown, xt as extractNestedAddonId, z as addonSettingsCapability, zt as logLevelAtMost } from "./dist-Dori4pf3.mjs";
|
|
3
3
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
4
4
|
import "./builtins/alerts/index.mjs";
|
|
5
5
|
import { ComposerAddon } from "./builtins/composer/composer.addon.mjs";
|
|
@@ -13,7 +13,7 @@ import "./builtins/device-manager/index.mjs";
|
|
|
13
13
|
import { HubForwarderAddon, HubForwarderDestination } from "./builtins/hub-forwarder/index.mjs";
|
|
14
14
|
import { LivenessMonitorAddon } from "./builtins/liveness-monitor/liveness-monitor.addon.mjs";
|
|
15
15
|
import "./builtins/liveness-monitor/index.mjs";
|
|
16
|
-
import { LocalAuthAddon, a as
|
|
16
|
+
import { LocalAuthAddon, a as isSettingsReadUnavailable, c as ApiKeyManager, i as SettingsReadUnavailableError, n as ScopedTokenManager, o as require_ms, r as AuthManager, s as require_safe_buffer, t as UserManager } from "./builtins/local-auth/local-auth.addon.mjs";
|
|
17
17
|
import "./builtins/local-auth/index.mjs";
|
|
18
18
|
import { LokiDestination, LokiLoggingAddon } from "./builtins/loki-logging/index.mjs";
|
|
19
19
|
import NativeMetricsAddon, { t as NativeMetricsProvider } from "./builtins/native-metrics/native-metrics.addon.mjs";
|
|
@@ -28,7 +28,7 @@ import "./builtins/system-config/index.mjs";
|
|
|
28
28
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
29
29
|
import { _ as ensureModel, a as createFileDataPlaneHandler, c as parseRangeHeader, d as ModelDownloadService, g as downloadModel, h as downloadFile, i as startEventLoopStallMonitor, l as parseTokenizedUrl, m as deleteModelFromDisk, n as STALL_TICK_MS, o as contentTypeFor, p as collectModelFiles, r as attributeStall, s as createAuthenticatedFileServer, t as STALL_REPORT_MS, u as resolveFilePath, v as fetchJson, x as isModelDownloaded, y as getModelFilePath } from "./event-loop-stall-monitor-EXjzIxDz.mjs";
|
|
30
30
|
import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-IM-v7JV4.mjs";
|
|
31
|
-
import { $ as classifyCapRoute, $n as EMPTY_CAP_ACTION_READING, $t as RUNNER_RSS_BUDGET_ENV, A as resolveHwAccel, An as OUTBOUND_QUEUE_SUSTAIN_MS, At as DeviceRegistry, B as udsChildLogToWorkerEntry, Bn as createSocketPlaneMeter, Bt as hostNodeIdOf, C as getBrokerEventBus, Cn as HEAP_SPACE_REPORT_MIN_MB, Ct as capActionName, D as subscribePassthrough, Dn as readHeapSpaces, Dt as parseCapAction, E as setNodeEventInterest, En as heapSpaceField, Et as capServiceName, F as ipcParentLink, Fn as createMeshQueueReader, Ft as resolveAddonClass, G as UDS_NO_ROUTE_PREFIX, Gn as EMPTY_SOCKET_DIRECTION, Gt as HEAP_WATCH_INTERVAL_MS, H as createUdsLoggerWithControl, Hn as diffSocketPlane, Ht as HEAP_RECLAIM_MIN_INTERVAL_MS, I as localProviderLink, In as formatMeshQueue, It as buildNpmChildEnv, J as deviceOfGetStatus, Jn as sampleSocketDirection, Jt as HUB_MAIN_RSS_BUDGET_MB, K as GET_STATUS_METHOD, Kn as createSocketDirectionCounters, Kt as HEAP_WATCH_WARN_RATIO, L as createParentUnownedCallHandler, Ln as EMPTY_SOCKET_PLANE_BASELINE, Lt as resolveNpmInvocation, M as brokerTransportLink, Mn as createOutboundQueueGate, Mt as CapabilityUnavailableError, N as buildLinkChain, Nn as formatOutboundQueueVerdict, Nt as copyBundledNativeModules, O as AddonDepsManager, On as selectReportedSpaces, Ot as deserializeTypedArrays, P as deviceCapResolverLink, Pn as MESH_QUEUE_TOP_N, Pt as installManifestNativeDeps, Q as CapRouteError, Qn as CAP_ACTION_UNLABELLED, Qt as RUNNER_HEAP_WATCH_INTERVAL_MS, R as createUdsEventBridge, Rn as SOCKET_PLANE_TOP_N, Rt as runNpm, S as clusterEventTopic, Sn as DECISIVE_HEAP_SPACES, St as NATIVE_PROVIDER_SERVICE_INFIX, T as registerEventBusService, Tn as formatHeapSpaces, Tt as capBareAction, U as LocalChildClient, Un as formatSocketPlane, Ut as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, V as createUdsLogger, Vn as createSocketPlaneReader, Vt as createAddonDataPlaneFacility, W as LocalChildRegistry, Wn as readSocketQueues, Wt as HEAP_RECLAIM_TRIGGER_MB, X as AGENT_CAP_FWD_SERVICE, Xn as socketDirectionMessages, Xt as RSS_BUDGET_REANNOUNCE_MIN_MS, Y as AGENT_CAP_FWD_ACTION, Yn as socketDirectionBytes, Yt as HUB_RSS_BUDGET_ENV, Z as CapRouteResolver, Zn as CAP_ACTION_OVERFLOW_LABEL, Zt as RSS_BUDGET_RELEASE_RATIO, _ as getWorkerDeviceRegistry, _n as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, a as reapProcessGroup, an as describeRss, ar as createEventPlaneMeter, at as getCapUsageRegistry, b as setHubConnected, bn as formatArrayBufferCensus, bt as createAddonService, c as runnerOwnsProcessGroup, cn as parseRssBudgetMb, cr as formatEventPlane, ct as UdsLocalTransportServer, d as summarizeMembers, dn as startHeapWatch, dt as localEndpointPath, en as ZERO_LOOP_DELAY, er as MAX_CAP_ACTIONS_PER_PEER, et as callWithServiceDiscovery, f as installManifestSystemDeps, fn as startRunnerHeapWatch, ft as FrameDecoder, g as createUdsAddonContext, gn as ARRAY_BUFFER_CENSUS_THRESHOLD_MB, h as createAddonContext, hn as ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ht as createBrokerDeviceManagerApi, in as createV8Reclaimer, ir as EVENT_PLANE_TOP_N, it as __resetCapUsageRegistryForTests, j as brokerCallForCap, jn as OUTBOUND_QUEUE_THRESHOLD_BYTES, jt as CapabilityHandle, k as createKernelHwAccel, kn as OUTBOUND_QUEUE_COOLDOWN_MS, kt as serializeTypedArrays, l as signalAllRunnerGroups, ln as reclaimIntervalMs, lt as SocketChannel, m as adaptBrokerToCluster, mn as ARRAY_BUFFER_CENSUS_COOLDOWN_MS, mt as buildNativeCapProxy, nn as createDeferredHeapWatchSink, nr as createCapActionCensus, nt as CapUsageRegistry, o as registerRunnerGroup, on as hubMainRssBudget, or as createEventPlaneReader, ot as createLocalTransport, p as installManifestPythonDeps, pn as strandedMb, pt as encodeFrame, q as answerClaimedGetStatus, qn as recordSocketFrame, qt as HUB_MAIN_HEAP_WATCH_LABEL, r as defaultProcessGroupOps, rn as createLoopDelayMeter, rr as diffCapActionCensus, rt as PARENT_ROUTED_PROVIDER_ADDON_ID, s as releaseRunnerGroup, sn as nextRssBudgetState, sr as diffEventPlane, st as UdsLocalTransportClient, t as CAP_METHOD_NOT_IMPLEMENTED, tn as buildHeapSample, tr as capActionLabel, tt as readMoleculerFanoutMode, un as shouldReclaim, ut as PeerAnsweredError, v as getOrInitReadinessRegistry, vn as createArrayBufferCensusGate, vt as mountNativeCapService, w as getMoleculerEventStats, wn as emitHeapDiagnosticReport, wt as capActionSuffix, x as EVENT_TOPIC_PREFIX, xn as isArrayBufferCensusReport, xt as validateProviderRegistrations, y as getOrInitReadinessRegistryForClient, yn as createInspectorArrayBufferCensus, z as createUdsEventBus, zn as SOCKET_QUEUE_TOP_N, zt as createAddonPeerBytesFacility } from "./child-cap-dispatch-
|
|
31
|
+
import { $ as classifyCapRoute, $n as EMPTY_CAP_ACTION_READING, $t as RUNNER_RSS_BUDGET_ENV, A as resolveHwAccel, An as OUTBOUND_QUEUE_SUSTAIN_MS, At as DeviceRegistry, B as udsChildLogToWorkerEntry, Bn as createSocketPlaneMeter, Bt as hostNodeIdOf, C as getBrokerEventBus, Cn as HEAP_SPACE_REPORT_MIN_MB, Ct as capActionName, D as subscribePassthrough, Dn as readHeapSpaces, Dt as parseCapAction, E as setNodeEventInterest, En as heapSpaceField, Et as capServiceName, F as ipcParentLink, Fn as createMeshQueueReader, Ft as resolveAddonClass, G as UDS_NO_ROUTE_PREFIX, Gn as EMPTY_SOCKET_DIRECTION, Gt as HEAP_WATCH_INTERVAL_MS, H as createUdsLoggerWithControl, Hn as diffSocketPlane, Ht as HEAP_RECLAIM_MIN_INTERVAL_MS, I as localProviderLink, In as formatMeshQueue, It as buildNpmChildEnv, J as deviceOfGetStatus, Jn as sampleSocketDirection, Jt as HUB_MAIN_RSS_BUDGET_MB, K as GET_STATUS_METHOD, Kn as createSocketDirectionCounters, Kt as HEAP_WATCH_WARN_RATIO, L as createParentUnownedCallHandler, Ln as EMPTY_SOCKET_PLANE_BASELINE, Lt as resolveNpmInvocation, M as brokerTransportLink, Mn as createOutboundQueueGate, Mt as CapabilityUnavailableError, N as buildLinkChain, Nn as formatOutboundQueueVerdict, Nt as copyBundledNativeModules, O as AddonDepsManager, On as selectReportedSpaces, Ot as deserializeTypedArrays, P as deviceCapResolverLink, Pn as MESH_QUEUE_TOP_N, Pt as installManifestNativeDeps, Q as CapRouteError, Qn as CAP_ACTION_UNLABELLED, Qt as RUNNER_HEAP_WATCH_INTERVAL_MS, R as createUdsEventBridge, Rn as SOCKET_PLANE_TOP_N, Rt as runNpm, S as clusterEventTopic, Sn as DECISIVE_HEAP_SPACES, St as NATIVE_PROVIDER_SERVICE_INFIX, T as registerEventBusService, Tn as formatHeapSpaces, Tt as capBareAction, U as LocalChildClient, Un as formatSocketPlane, Ut as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, V as createUdsLogger, Vn as createSocketPlaneReader, Vt as createAddonDataPlaneFacility, W as LocalChildRegistry, Wn as readSocketQueues, Wt as HEAP_RECLAIM_TRIGGER_MB, X as AGENT_CAP_FWD_SERVICE, Xn as socketDirectionMessages, Xt as RSS_BUDGET_REANNOUNCE_MIN_MS, Y as AGENT_CAP_FWD_ACTION, Yn as socketDirectionBytes, Yt as HUB_RSS_BUDGET_ENV, Z as CapRouteResolver, Zn as CAP_ACTION_OVERFLOW_LABEL, Zt as RSS_BUDGET_RELEASE_RATIO, _ as getWorkerDeviceRegistry, _n as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, a as reapProcessGroup, an as describeRss, ar as createEventPlaneMeter, at as getCapUsageRegistry, b as setHubConnected, bn as formatArrayBufferCensus, bt as createAddonService, c as runnerOwnsProcessGroup, cn as parseRssBudgetMb, cr as formatEventPlane, ct as UdsLocalTransportServer, d as summarizeMembers, dn as startHeapWatch, dt as localEndpointPath, en as ZERO_LOOP_DELAY, er as MAX_CAP_ACTIONS_PER_PEER, et as callWithServiceDiscovery, f as installManifestSystemDeps, fn as startRunnerHeapWatch, ft as FrameDecoder, g as createUdsAddonContext, gn as ARRAY_BUFFER_CENSUS_THRESHOLD_MB, h as createAddonContext, hn as ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ht as createBrokerDeviceManagerApi, in as createV8Reclaimer, ir as EVENT_PLANE_TOP_N, it as __resetCapUsageRegistryForTests, j as brokerCallForCap, jn as OUTBOUND_QUEUE_THRESHOLD_BYTES, jt as CapabilityHandle, k as createKernelHwAccel, kn as OUTBOUND_QUEUE_COOLDOWN_MS, kt as serializeTypedArrays, l as signalAllRunnerGroups, ln as reclaimIntervalMs, lt as SocketChannel, m as adaptBrokerToCluster, mn as ARRAY_BUFFER_CENSUS_COOLDOWN_MS, mt as buildNativeCapProxy, nn as createDeferredHeapWatchSink, nr as createCapActionCensus, nt as CapUsageRegistry, o as registerRunnerGroup, on as hubMainRssBudget, or as createEventPlaneReader, ot as createLocalTransport, p as installManifestPythonDeps, pn as strandedMb, pt as encodeFrame, q as answerClaimedGetStatus, qn as recordSocketFrame, qt as HUB_MAIN_HEAP_WATCH_LABEL, r as defaultProcessGroupOps, rn as createLoopDelayMeter, rr as diffCapActionCensus, rt as PARENT_ROUTED_PROVIDER_ADDON_ID, s as releaseRunnerGroup, sn as nextRssBudgetState, sr as diffEventPlane, st as UdsLocalTransportClient, t as CAP_METHOD_NOT_IMPLEMENTED, tn as buildHeapSample, tr as capActionLabel, tt as readMoleculerFanoutMode, un as shouldReclaim, ut as PeerAnsweredError, v as getOrInitReadinessRegistry, vn as createArrayBufferCensusGate, vt as mountNativeCapService, w as getMoleculerEventStats, wn as emitHeapDiagnosticReport, wt as capActionSuffix, x as EVENT_TOPIC_PREFIX, xn as isArrayBufferCensusReport, xt as validateProviderRegistrations, y as getOrInitReadinessRegistryForClient, yn as createInspectorArrayBufferCensus, z as createUdsEventBus, zn as SOCKET_QUEUE_TOP_N, zt as createAddonPeerBytesFacility } from "./child-cap-dispatch-C2VINHu1.mjs";
|
|
32
32
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-B1v6E07R.mjs";
|
|
33
33
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
34
34
|
import { z } from "zod";
|
|
@@ -2745,7 +2745,7 @@ async function ensureAddonNativePrebuilds(addonDir, options) {
|
|
|
2745
2745
|
}
|
|
2746
2746
|
//#endregion
|
|
2747
2747
|
//#region src/kernel/addon-loader.ts
|
|
2748
|
-
function isRecord$
|
|
2748
|
+
function isRecord$3(value) {
|
|
2749
2749
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2750
2750
|
}
|
|
2751
2751
|
/**
|
|
@@ -2843,9 +2843,9 @@ async function importAddonModuleFresh(entryPath) {
|
|
|
2843
2843
|
* AddonPackageManifest + AddonDeclaration.
|
|
2844
2844
|
*/
|
|
2845
2845
|
function toAddonPackageManifest(value) {
|
|
2846
|
-
if (!isRecord$
|
|
2846
|
+
if (!isRecord$3(value)) return void 0;
|
|
2847
2847
|
if (!Array.isArray(value.addons)) return void 0;
|
|
2848
|
-
if (!value.addons.every((a) => isRecord$
|
|
2848
|
+
if (!value.addons.every((a) => isRecord$3(a) && typeof a.id === "string")) return void 0;
|
|
2849
2849
|
return value;
|
|
2850
2850
|
}
|
|
2851
2851
|
/** Minimal no-op logger for default parameter */
|
|
@@ -2995,7 +2995,7 @@ var AddonLoader = class {
|
|
|
2995
2995
|
}
|
|
2996
2996
|
if (!fs$17.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
|
|
2997
2997
|
const modUnknown = await importAddonModuleFresh(entryPath);
|
|
2998
|
-
const mod = isRecord$
|
|
2998
|
+
const mod = isRecord$3(modUnknown) ? modUnknown : {};
|
|
2999
2999
|
const AddonClass = resolveAddonClass(mod);
|
|
3000
3000
|
if (!AddonClass) throw new Error(`No addon class in ${entryPath}`);
|
|
3001
3001
|
this.addons.set(declaration.id, {
|
|
@@ -3011,7 +3011,7 @@ var AddonLoader = class {
|
|
|
3011
3011
|
/** Load addon from a direct path (for development/testing) */
|
|
3012
3012
|
async loadFromPath(addonId, modulePath, packageName, declaration, packageVersion = "0.0.0") {
|
|
3013
3013
|
const modUnknown = await importAddonModuleFresh(modulePath);
|
|
3014
|
-
const mod = isRecord$
|
|
3014
|
+
const mod = isRecord$3(modUnknown) ? modUnknown : {};
|
|
3015
3015
|
const AddonClass = resolveAddonClass(mod);
|
|
3016
3016
|
if (!AddonClass) throw new Error(`Module ${modulePath} has no default export`);
|
|
3017
3017
|
this.addons.set(addonId, {
|
|
@@ -6308,6 +6308,60 @@ var CapabilityRegistry = class CapabilityRegistry {
|
|
|
6308
6308
|
addonId
|
|
6309
6309
|
});
|
|
6310
6310
|
}
|
|
6311
|
+
/**
|
|
6312
|
+
* Re-apply the operator's PERSISTED preferences to providers that
|
|
6313
|
+
* registered before those preferences could be read — once, when the boot
|
|
6314
|
+
* read of them settles (D675).
|
|
6315
|
+
*
|
|
6316
|
+
* `registerProvider` consults the preference readers at the moment a
|
|
6317
|
+
* provider registers. With the settings engine isolated (D231) the
|
|
6318
|
+
* preferences arrive over an async door, so a provider can register before
|
|
6319
|
+
* they are known; the readers then answer "no preference" and the default
|
|
6320
|
+
* wins. This replays the answer the readers give NOW over every registered
|
|
6321
|
+
* provider: a singleton whose persisted choice is registered and not active
|
|
6322
|
+
* is switched to it, and a collection provider the operator disabled is
|
|
6323
|
+
* disabled again. It is one pass, triggered by the read settling — not a
|
|
6324
|
+
* wait, a poll or a retry (D3).
|
|
6325
|
+
*
|
|
6326
|
+
* `skip` names the capabilities that must not be switched live (infra caps
|
|
6327
|
+
* need a restart — the same rule `capabilities.setPreference` applies).
|
|
6328
|
+
*/
|
|
6329
|
+
applyPersistedPreferences(skip) {
|
|
6330
|
+
const singletons = [];
|
|
6331
|
+
const disabled = [];
|
|
6332
|
+
for (const [capability, state] of this.capabilities) {
|
|
6333
|
+
if (skip(capability)) continue;
|
|
6334
|
+
if (state.definition.mode === "singleton") {
|
|
6335
|
+
const choice = this.configReader?.(capability);
|
|
6336
|
+
if (choice === void 0 || !state.providers.has(choice)) continue;
|
|
6337
|
+
if (state.activeAddonId === choice) continue;
|
|
6338
|
+
state.activeAddonId = choice;
|
|
6339
|
+
singletons.push({
|
|
6340
|
+
capability,
|
|
6341
|
+
addonId: choice
|
|
6342
|
+
});
|
|
6343
|
+
this.emitEvent("capability:singleton-changed", {
|
|
6344
|
+
capability,
|
|
6345
|
+
addonId: choice
|
|
6346
|
+
});
|
|
6347
|
+
} else if (state.definition.mode === "collection") for (const addonId of this.collectionConfigReader?.(capability) ?? []) {
|
|
6348
|
+
if (!state.providers.has(addonId) || state.disabledProviders.has(addonId)) continue;
|
|
6349
|
+
state.disabledProviders.add(addonId);
|
|
6350
|
+
disabled.push({
|
|
6351
|
+
capability,
|
|
6352
|
+
addonId
|
|
6353
|
+
});
|
|
6354
|
+
this.emitEvent("capability:collection-provider-disabled", {
|
|
6355
|
+
capability,
|
|
6356
|
+
addonId
|
|
6357
|
+
});
|
|
6358
|
+
}
|
|
6359
|
+
}
|
|
6360
|
+
return {
|
|
6361
|
+
singletons,
|
|
6362
|
+
disabled
|
|
6363
|
+
};
|
|
6364
|
+
}
|
|
6311
6365
|
/** Enable a previously disabled collection provider. */
|
|
6312
6366
|
enableCollectionProvider(capability, addonId) {
|
|
6313
6367
|
const state = this.capabilities.get(capability);
|
|
@@ -7450,14 +7504,14 @@ async function runHubAddonBoot(steps) {
|
|
|
7450
7504
|
}
|
|
7451
7505
|
//#endregion
|
|
7452
7506
|
//#region src/kernel/settings-door-view.ts
|
|
7453
|
-
function isRecord$
|
|
7507
|
+
function isRecord$2(value) {
|
|
7454
7508
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7455
7509
|
}
|
|
7456
7510
|
function asBlob(value) {
|
|
7457
|
-
return isRecord$
|
|
7511
|
+
return isRecord$2(value) ? value : {};
|
|
7458
7512
|
}
|
|
7459
7513
|
function unwrapValue(parsed) {
|
|
7460
|
-
if (!isRecord$
|
|
7514
|
+
if (!isRecord$2(parsed) || !("value" in parsed)) return parsed;
|
|
7461
7515
|
return parsed.value;
|
|
7462
7516
|
}
|
|
7463
7517
|
/**
|
|
@@ -7507,7 +7561,7 @@ var PREFIX_PAGE_BUDGET = 512;
|
|
|
7507
7561
|
* A throw is the point: a caller that cannot be answered completely must not
|
|
7508
7562
|
* be handed something that looks like a complete answer.
|
|
7509
7563
|
*/
|
|
7510
|
-
async function loadPrefixed(door, collection, prefix) {
|
|
7564
|
+
async function loadPrefixed(door, collection, prefix, decode = unwrapValue) {
|
|
7511
7565
|
const range = prefixRange(prefix);
|
|
7512
7566
|
const result = {};
|
|
7513
7567
|
let cursor = range?.lo ?? null;
|
|
@@ -7527,7 +7581,7 @@ async function loadPrefixed(door, collection, prefix) {
|
|
|
7527
7581
|
for (const row of rows) {
|
|
7528
7582
|
if (range !== null && (row.id < range.lo || row.id >= range.hi)) continue;
|
|
7529
7583
|
if (!row.id.startsWith(prefix)) continue;
|
|
7530
|
-
result[row.id.slice(prefix.length)] =
|
|
7584
|
+
result[row.id.slice(prefix.length)] = decode(row.data);
|
|
7531
7585
|
}
|
|
7532
7586
|
if (rows.length < PREFIX_PAGE_ROWS) return result;
|
|
7533
7587
|
const last = rows[rows.length - 1];
|
|
@@ -7537,6 +7591,32 @@ async function loadPrefixed(door, collection, prefix) {
|
|
|
7537
7591
|
cursor = last.id;
|
|
7538
7592
|
}
|
|
7539
7593
|
}
|
|
7594
|
+
/**
|
|
7595
|
+
* Every `system-settings` row under `prefix`, keyed by the suffix — or a throw.
|
|
7596
|
+
*
|
|
7597
|
+
* `system-settings` stores the value ITSELF (`setSystem` / `door.set` write
|
|
7598
|
+
* `JSON.stringify(value)`), mostly scalars. The engine's `query` hands a KV row
|
|
7599
|
+
* back parsed only when its text is an object or an array; a scalar comes back
|
|
7600
|
+
* as `{ value: <its JSON text> }` — `"12h"` arrives as `{ value: '"12h"' }`.
|
|
7601
|
+
* That is not a value anyone stored, and guessing it back would misread a
|
|
7602
|
+
* stored object that happens to be `{ value: … }`. So the range read only
|
|
7603
|
+
* ENUMERATES the keys (same keyset walk and refusal as every prefix read
|
|
7604
|
+
* here), and each value is taken from `get`, which parses the row exactly
|
|
7605
|
+
* (D675). These reads are small and rare: a section's handful of keys when a
|
|
7606
|
+
* form opens, and the capability preferences once at boot.
|
|
7607
|
+
*/
|
|
7608
|
+
async function loadSystemSettingsPrefix(door, prefix, mayRead = () => true) {
|
|
7609
|
+
const listed = await loadPrefixed(door, "system-settings", prefix, () => null);
|
|
7610
|
+
const result = {};
|
|
7611
|
+
for (const suffix of Object.keys(listed).filter(mayRead)) {
|
|
7612
|
+
const value = await door.get({
|
|
7613
|
+
collection: "system-settings",
|
|
7614
|
+
key: `${prefix}${suffix}`
|
|
7615
|
+
});
|
|
7616
|
+
if (value !== void 0) result[suffix] = value;
|
|
7617
|
+
}
|
|
7618
|
+
return result;
|
|
7619
|
+
}
|
|
7540
7620
|
async function replacePrefixed(door, collection, prefix, values, wrap) {
|
|
7541
7621
|
const range = prefixRange(prefix);
|
|
7542
7622
|
if (range !== null) await door.deleteWhere({
|
|
@@ -7558,6 +7638,24 @@ function createDoorSettingsView(addonId, door, sections) {
|
|
|
7558
7638
|
async readAddonStore() {
|
|
7559
7639
|
return loadPrefixed(door, "addon-settings", addonPrefix);
|
|
7560
7640
|
},
|
|
7641
|
+
async readAddonStoreKeyResult(key) {
|
|
7642
|
+
try {
|
|
7643
|
+
const row = await door.get({
|
|
7644
|
+
collection: "addon-settings",
|
|
7645
|
+
key: `${addonPrefix}${key}`
|
|
7646
|
+
});
|
|
7647
|
+
return row === void 0 ? { kind: "absent" } : {
|
|
7648
|
+
kind: "present",
|
|
7649
|
+
value: unwrapValue(row)
|
|
7650
|
+
};
|
|
7651
|
+
} catch (err) {
|
|
7652
|
+
return {
|
|
7653
|
+
kind: "unreadable",
|
|
7654
|
+
reason: "store-read-failed",
|
|
7655
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7656
|
+
};
|
|
7657
|
+
}
|
|
7658
|
+
},
|
|
7561
7659
|
async writeAddonStore(patch) {
|
|
7562
7660
|
await replacePrefixed(door, "addon-settings", addonPrefix, {
|
|
7563
7661
|
...await loadPrefixed(door, "addon-settings", addonPrefix),
|
|
@@ -7636,6 +7734,121 @@ function createDoorSettingsView(addonId, door, sections) {
|
|
|
7636
7734
|
};
|
|
7637
7735
|
}
|
|
7638
7736
|
//#endregion
|
|
7737
|
+
//#region src/kernel/config-schema.ts
|
|
7738
|
+
/** Default data directory — used when CAMSTACK_DATA env var is not set */
|
|
7739
|
+
var DEFAULT_DATA_PATH = "camstack-data";
|
|
7740
|
+
var serverSchema = z.object({
|
|
7741
|
+
port: z.number().default(4443),
|
|
7742
|
+
host: z.string().default("0.0.0.0"),
|
|
7743
|
+
dataPath: z.string().default(DEFAULT_DATA_PATH)
|
|
7744
|
+
});
|
|
7745
|
+
var authSchema = z.object({
|
|
7746
|
+
jwtSecret: z.string().nullable().default(null),
|
|
7747
|
+
adminUsername: z.string().default("admin"),
|
|
7748
|
+
adminPassword: z.string().default("changeme")
|
|
7749
|
+
});
|
|
7750
|
+
var hubSchema = z.object({
|
|
7751
|
+
url: z.string().default("ws://localhost:4443/agent"),
|
|
7752
|
+
token: z.string().default("")
|
|
7753
|
+
});
|
|
7754
|
+
var agentSchema = z.object({
|
|
7755
|
+
name: z.string().default(""),
|
|
7756
|
+
/** Port for the agent status page (minimal HTML) */
|
|
7757
|
+
statusPort: z.number().default(4444)
|
|
7758
|
+
});
|
|
7759
|
+
var tlsSchema = z.object({
|
|
7760
|
+
/** Enable HTTPS (default: true) */
|
|
7761
|
+
enabled: z.boolean().default(true),
|
|
7762
|
+
/** Path to custom cert file (PEM). If not set, auto-generates self-signed. */
|
|
7763
|
+
certPath: z.string().optional(),
|
|
7764
|
+
/** Path to custom key file (PEM). Required if certPath is set. */
|
|
7765
|
+
keyPath: z.string().optional()
|
|
7766
|
+
});
|
|
7767
|
+
/**
|
|
7768
|
+
* Bootstrap-time addon configuration — read PURELY from YAML, before the
|
|
7769
|
+
* kernel can talk to the settings-store. This breaks the chicken-and-egg
|
|
7770
|
+
* where the settings store itself is implemented by an addon: the kernel
|
|
7771
|
+
* needs to know WHICH addon to load first to provide the store, and that
|
|
7772
|
+
* decision can't itself live in the store.
|
|
7773
|
+
*
|
|
7774
|
+
* Backward-compatible: every field is optional + defaults reproduce the
|
|
7775
|
+
* current hard-coded behavior. Existing config.yaml files keep working.
|
|
7776
|
+
*/
|
|
7777
|
+
var bootstrapAddonsSchema = z.object({
|
|
7778
|
+
/**
|
|
7779
|
+
* Addon implementing the `settings-store` capability. Loaded FIRST,
|
|
7780
|
+
* before any other addon is enabled — every other addon's enable
|
|
7781
|
+
* state, settings, and ordering lives in the store it provides.
|
|
7782
|
+
*
|
|
7783
|
+
* Default: '@camstack/addon-sqlite-storage' (the workspace's
|
|
7784
|
+
* default SQLite-backed store). Future alternatives could swap this
|
|
7785
|
+
* for postgres/redis without touching kernel code.
|
|
7786
|
+
*/
|
|
7787
|
+
settingsStoreAddon: z.string().default("@camstack/addon-sqlite-storage"),
|
|
7788
|
+
/**
|
|
7789
|
+
* How the launcher provisions REQUIRED_PACKAGES into `data/addons/`
|
|
7790
|
+
* on startup.
|
|
7791
|
+
*
|
|
7792
|
+
* - `'npm'` — pull from the npm registry (production default).
|
|
7793
|
+
* - `'local'` — copy `packages/<X>/` from the workspace into
|
|
7794
|
+
* `data/addons/<X>/`. Use for the Electron-
|
|
7795
|
+
* packaged bundle and the e2e harness.
|
|
7796
|
+
* - `'symlink'` — point `data/addons/<X>` at the workspace source
|
|
7797
|
+
* dir via a directory symlink. Dev-only: a
|
|
7798
|
+
* workspace rebuild (`npm run build -w <X>`) is
|
|
7799
|
+
* immediately reflected at the next addon load,
|
|
7800
|
+
* no copy step. Falls back to `'local'` on
|
|
7801
|
+
* platforms that reject symlink creation (Windows
|
|
7802
|
+
* without developer-mode).
|
|
7803
|
+
*
|
|
7804
|
+
* The `CAMSTACK_INSTALL_SOURCE` env var, when set, wins over this
|
|
7805
|
+
* field. Leave undefined to keep the launcher's default behaviour
|
|
7806
|
+
* (npm when no workspace, local when a bundled addons dir is
|
|
7807
|
+
* present, …).
|
|
7808
|
+
*/
|
|
7809
|
+
installSource: z.enum([
|
|
7810
|
+
"npm",
|
|
7811
|
+
"local",
|
|
7812
|
+
"symlink"
|
|
7813
|
+
]).optional(),
|
|
7814
|
+
/**
|
|
7815
|
+
* Override the kernel's hard-coded `AddonInstaller.REQUIRED_PACKAGES`.
|
|
7816
|
+
* Passing an array here REPLACES the default list entirely — useful
|
|
7817
|
+
* for stripped-down deployments (only the bundle of addons the
|
|
7818
|
+
* operator actually wants) and for forcing a different storage
|
|
7819
|
+
* backend at first boot.
|
|
7820
|
+
*
|
|
7821
|
+
* Leave undefined to use the kernel-shipped defaults.
|
|
7822
|
+
*/
|
|
7823
|
+
requiredAddons: z.array(z.string()).optional(),
|
|
7824
|
+
/**
|
|
7825
|
+
* Disable list applied AFTER the settings-store reports the enabled
|
|
7826
|
+
* set. Operator escape hatch — boot without a known-broken addon
|
|
7827
|
+
* without having to mutate the store.
|
|
7828
|
+
*/
|
|
7829
|
+
forceDisable: z.array(z.string()).default([])
|
|
7830
|
+
});
|
|
7831
|
+
/** Bootstrap config -- loaded from config.yaml ONLY at startup.
|
|
7832
|
+
* All other settings live in SQL (system_settings table). */
|
|
7833
|
+
var bootstrapSchema = z.object({
|
|
7834
|
+
/** Server mode: 'hub' (full server) or 'agent' (worker node) */
|
|
7835
|
+
mode: z.enum(["hub", "agent"]).default("hub"),
|
|
7836
|
+
server: serverSchema.default(serverSchema.parse({})),
|
|
7837
|
+
auth: authSchema.default(authSchema.parse({})),
|
|
7838
|
+
/** Hub connection config — only used when mode='agent' */
|
|
7839
|
+
hub: hubSchema.default(hubSchema.parse({})),
|
|
7840
|
+
/** Agent-specific config — only used when mode='agent' */
|
|
7841
|
+
agent: agentSchema.default(agentSchema.parse({})),
|
|
7842
|
+
/** TLS configuration */
|
|
7843
|
+
tls: tlsSchema.default(tlsSchema.parse({})),
|
|
7844
|
+
/**
|
|
7845
|
+
* Addon bootstrap directives — minimum addon set needed before the
|
|
7846
|
+
* kernel can reach the settings-store. See bootstrapAddonsSchema.
|
|
7847
|
+
* Spec: docs/superpowers/specs/2026-05-15-yaml-bootstrap-expansion.md
|
|
7848
|
+
*/
|
|
7849
|
+
bootstrap: bootstrapAddonsSchema.default(bootstrapAddonsSchema.parse({}))
|
|
7850
|
+
});
|
|
7851
|
+
//#endregion
|
|
7639
7852
|
//#region ../../node_modules/js-yaml/dist/js-yaml.mjs
|
|
7640
7853
|
/*! js-yaml 4.2.0 https://github.com/nodeca/js-yaml @license MIT */
|
|
7641
7854
|
var __create = Object.create;
|
|
@@ -9965,125 +10178,22 @@ var import_js_yaml = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((ex
|
|
|
9965
10178
|
var { Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load: load$1, loadAll, dump, YAMLException, types: types$3, safeLoad, safeLoadAll, safeDump } = import_js_yaml.default;
|
|
9966
10179
|
import_js_yaml.default;
|
|
9967
10180
|
//#endregion
|
|
9968
|
-
//#region src/kernel/config
|
|
9969
|
-
/** Default data directory — used when CAMSTACK_DATA env var is not set */
|
|
9970
|
-
var DEFAULT_DATA_PATH = "camstack-data";
|
|
9971
|
-
var serverSchema = z.object({
|
|
9972
|
-
port: z.number().default(4443),
|
|
9973
|
-
host: z.string().default("0.0.0.0"),
|
|
9974
|
-
dataPath: z.string().default(DEFAULT_DATA_PATH)
|
|
9975
|
-
});
|
|
9976
|
-
var authSchema = z.object({
|
|
9977
|
-
jwtSecret: z.string().nullable().default(null),
|
|
9978
|
-
adminUsername: z.string().default("admin"),
|
|
9979
|
-
adminPassword: z.string().default("changeme")
|
|
9980
|
-
});
|
|
9981
|
-
var hubSchema = z.object({
|
|
9982
|
-
url: z.string().default("ws://localhost:4443/agent"),
|
|
9983
|
-
token: z.string().default("")
|
|
9984
|
-
});
|
|
9985
|
-
var agentSchema = z.object({
|
|
9986
|
-
name: z.string().default(""),
|
|
9987
|
-
/** Port for the agent status page (minimal HTML) */
|
|
9988
|
-
statusPort: z.number().default(4444)
|
|
9989
|
-
});
|
|
9990
|
-
var tlsSchema = z.object({
|
|
9991
|
-
/** Enable HTTPS (default: true) */
|
|
9992
|
-
enabled: z.boolean().default(true),
|
|
9993
|
-
/** Path to custom cert file (PEM). If not set, auto-generates self-signed. */
|
|
9994
|
-
certPath: z.string().optional(),
|
|
9995
|
-
/** Path to custom key file (PEM). Required if certPath is set. */
|
|
9996
|
-
keyPath: z.string().optional()
|
|
9997
|
-
});
|
|
10181
|
+
//#region src/kernel/bootstrap-config.ts
|
|
9998
10182
|
/**
|
|
9999
|
-
*
|
|
10000
|
-
*
|
|
10001
|
-
*
|
|
10002
|
-
*
|
|
10003
|
-
* decision can't itself live in the store.
|
|
10004
|
-
*
|
|
10005
|
-
* Backward-compatible: every field is optional + defaults reproduce the
|
|
10006
|
-
* current hard-coded behavior. Existing config.yaml files keep working.
|
|
10183
|
+
* config.yaml + env: loading, the section writer and the legacy `raw` view —
|
|
10184
|
+
* `ConfigManager`'s bootstrap layer, split out of `config-manager.ts` (D675)
|
|
10185
|
+
* so that file stays one class. The `console.*` calls are the documented
|
|
10186
|
+
* residuals described on `ConfigManager` (no logger exists yet at boot).
|
|
10007
10187
|
*/
|
|
10008
|
-
|
|
10009
|
-
/**
|
|
10010
|
-
* Addon implementing the `settings-store` capability. Loaded FIRST,
|
|
10011
|
-
* before any other addon is enabled — every other addon's enable
|
|
10012
|
-
* state, settings, and ordering lives in the store it provides.
|
|
10013
|
-
*
|
|
10014
|
-
* Default: '@camstack/addon-sqlite-storage' (the workspace's
|
|
10015
|
-
* default SQLite-backed store). Future alternatives could swap this
|
|
10016
|
-
* for postgres/redis without touching kernel code.
|
|
10017
|
-
*/
|
|
10018
|
-
settingsStoreAddon: z.string().default("@camstack/addon-sqlite-storage"),
|
|
10019
|
-
/**
|
|
10020
|
-
* How the launcher provisions REQUIRED_PACKAGES into `data/addons/`
|
|
10021
|
-
* on startup.
|
|
10022
|
-
*
|
|
10023
|
-
* - `'npm'` — pull from the npm registry (production default).
|
|
10024
|
-
* - `'local'` — copy `packages/<X>/` from the workspace into
|
|
10025
|
-
* `data/addons/<X>/`. Use for the Electron-
|
|
10026
|
-
* packaged bundle and the e2e harness.
|
|
10027
|
-
* - `'symlink'` — point `data/addons/<X>` at the workspace source
|
|
10028
|
-
* dir via a directory symlink. Dev-only: a
|
|
10029
|
-
* workspace rebuild (`npm run build -w <X>`) is
|
|
10030
|
-
* immediately reflected at the next addon load,
|
|
10031
|
-
* no copy step. Falls back to `'local'` on
|
|
10032
|
-
* platforms that reject symlink creation (Windows
|
|
10033
|
-
* without developer-mode).
|
|
10034
|
-
*
|
|
10035
|
-
* The `CAMSTACK_INSTALL_SOURCE` env var, when set, wins over this
|
|
10036
|
-
* field. Leave undefined to keep the launcher's default behaviour
|
|
10037
|
-
* (npm when no workspace, local when a bundled addons dir is
|
|
10038
|
-
* present, …).
|
|
10039
|
-
*/
|
|
10040
|
-
installSource: z.enum([
|
|
10041
|
-
"npm",
|
|
10042
|
-
"local",
|
|
10043
|
-
"symlink"
|
|
10044
|
-
]).optional(),
|
|
10045
|
-
/**
|
|
10046
|
-
* Override the kernel's hard-coded `AddonInstaller.REQUIRED_PACKAGES`.
|
|
10047
|
-
* Passing an array here REPLACES the default list entirely — useful
|
|
10048
|
-
* for stripped-down deployments (only the bundle of addons the
|
|
10049
|
-
* operator actually wants) and for forcing a different storage
|
|
10050
|
-
* backend at first boot.
|
|
10051
|
-
*
|
|
10052
|
-
* Leave undefined to use the kernel-shipped defaults.
|
|
10053
|
-
*/
|
|
10054
|
-
requiredAddons: z.array(z.string()).optional(),
|
|
10055
|
-
/**
|
|
10056
|
-
* Disable list applied AFTER the settings-store reports the enabled
|
|
10057
|
-
* set. Operator escape hatch — boot without a known-broken addon
|
|
10058
|
-
* without having to mutate the store.
|
|
10059
|
-
*/
|
|
10060
|
-
forceDisable: z.array(z.string()).default([])
|
|
10061
|
-
});
|
|
10062
|
-
/** Bootstrap config -- loaded from config.yaml ONLY at startup.
|
|
10063
|
-
* All other settings live in SQL (system_settings table). */
|
|
10064
|
-
var bootstrapSchema = z.object({
|
|
10065
|
-
/** Server mode: 'hub' (full server) or 'agent' (worker node) */
|
|
10066
|
-
mode: z.enum(["hub", "agent"]).default("hub"),
|
|
10067
|
-
server: serverSchema.default(serverSchema.parse({})),
|
|
10068
|
-
auth: authSchema.default(authSchema.parse({})),
|
|
10069
|
-
/** Hub connection config — only used when mode='agent' */
|
|
10070
|
-
hub: hubSchema.default(hubSchema.parse({})),
|
|
10071
|
-
/** Agent-specific config — only used when mode='agent' */
|
|
10072
|
-
agent: agentSchema.default(agentSchema.parse({})),
|
|
10073
|
-
/** TLS configuration */
|
|
10074
|
-
tls: tlsSchema.default(tlsSchema.parse({})),
|
|
10075
|
-
/**
|
|
10076
|
-
* Addon bootstrap directives — minimum addon set needed before the
|
|
10077
|
-
* kernel can reach the settings-store. See bootstrapAddonsSchema.
|
|
10078
|
-
* Spec: docs/superpowers/specs/2026-05-15-yaml-bootstrap-expansion.md
|
|
10079
|
-
*/
|
|
10080
|
-
bootstrap: bootstrapAddonsSchema.default(bootstrapAddonsSchema.parse({}))
|
|
10081
|
-
});
|
|
10082
|
-
//#endregion
|
|
10083
|
-
//#region src/kernel/config-manager.ts
|
|
10084
|
-
function isRecord(value) {
|
|
10188
|
+
function isRecord$1(value) {
|
|
10085
10189
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10086
10190
|
}
|
|
10191
|
+
/** Sections that live in config.yaml. Everything else goes to the settings-store. */
|
|
10192
|
+
var BOOTSTRAP_SECTIONS = new Set([
|
|
10193
|
+
"server",
|
|
10194
|
+
"auth",
|
|
10195
|
+
"mode"
|
|
10196
|
+
]);
|
|
10087
10197
|
/**
|
|
10088
10198
|
* Maps environment variable names to dot-notation config paths.
|
|
10089
10199
|
* Only bootstrap-level env vars -- runtime settings come from the
|
|
@@ -10097,17 +10207,360 @@ var ENV_VAR_MAP = {
|
|
|
10097
10207
|
CAMSTACK_ADMIN_USER: "auth.adminUsername",
|
|
10098
10208
|
CAMSTACK_ADMIN_PASS: "auth.adminPassword"
|
|
10099
10209
|
};
|
|
10100
|
-
|
|
10210
|
+
/** config.yaml, env overrides applied, parsed. */
|
|
10211
|
+
function loadBootstrapConfig(configPath) {
|
|
10212
|
+
const merged = applyEnvOverrides(asJsonObject(loadYaml(configPath)) ?? {});
|
|
10213
|
+
const config = bootstrapSchema.parse(merged);
|
|
10214
|
+
warnDefaultCredentials(config);
|
|
10215
|
+
return config;
|
|
10216
|
+
}
|
|
10217
|
+
function writeBootstrapSection(configPath, section, data) {
|
|
10218
|
+
if (!BOOTSTRAP_SECTIONS.has(section)) throw new Error(`[ConfigManager] Section "${section}" is a runtime setting — use setSection() to persist via the settings-store, not update() which writes to config.yaml`);
|
|
10219
|
+
let raw = {};
|
|
10220
|
+
if (fs$17.existsSync(configPath)) raw = asJsonObject(load$1(fs$17.readFileSync(configPath, "utf-8"))) ?? {};
|
|
10221
|
+
const existing = asJsonObject(raw[section]) ?? {};
|
|
10222
|
+
raw[section] = {
|
|
10223
|
+
...existing,
|
|
10224
|
+
...data
|
|
10225
|
+
};
|
|
10226
|
+
const validation = bootstrapSchema.safeParse(raw);
|
|
10227
|
+
if (!validation.success) throw new Error(`[ConfigManager] Invalid config update for section "${section}": ${validation.error.message}`);
|
|
10228
|
+
const tmpPath = `${configPath}.tmp`;
|
|
10229
|
+
fs$17.writeFileSync(tmpPath, dump(raw, {
|
|
10230
|
+
lineWidth: 120,
|
|
10231
|
+
indent: 2,
|
|
10232
|
+
quotingType: "\""
|
|
10233
|
+
}), "utf-8");
|
|
10234
|
+
fs$17.renameSync(tmpPath, configPath);
|
|
10235
|
+
return validation.data;
|
|
10236
|
+
}
|
|
10237
|
+
/**
|
|
10238
|
+
* Returns a merged view of bootstrap config + runtime defaults for backward compat.
|
|
10239
|
+
*/
|
|
10240
|
+
function buildRawAppConfig(bootstrapConfig) {
|
|
10241
|
+
const features = {
|
|
10242
|
+
streaming: RUNTIME_DEFAULTS["features.streaming"],
|
|
10243
|
+
notifications: RUNTIME_DEFAULTS["features.notifications"],
|
|
10244
|
+
objectDetection: RUNTIME_DEFAULTS["features.objectDetection"],
|
|
10245
|
+
remoteAccess: RUNTIME_DEFAULTS["features.remoteAccess"],
|
|
10246
|
+
agentCluster: RUNTIME_DEFAULTS["features.agentCluster"],
|
|
10247
|
+
smartHome: RUNTIME_DEFAULTS["features.smartHome"],
|
|
10248
|
+
recordings: RUNTIME_DEFAULTS["features.recordings"],
|
|
10249
|
+
backup: RUNTIME_DEFAULTS["features.backup"],
|
|
10250
|
+
repl: RUNTIME_DEFAULTS["features.repl"]
|
|
10251
|
+
};
|
|
10252
|
+
return {
|
|
10253
|
+
...bootstrapConfig,
|
|
10254
|
+
features,
|
|
10255
|
+
storage: {
|
|
10256
|
+
provider: RUNTIME_DEFAULTS["storage.provider"],
|
|
10257
|
+
locations: { ...RUNTIME_DEFAULTS["storage.locations"] }
|
|
10258
|
+
},
|
|
10259
|
+
logging: {
|
|
10260
|
+
level: RUNTIME_DEFAULTS["logging.level"],
|
|
10261
|
+
retentionDays: RUNTIME_DEFAULTS["logging.retentionDays"]
|
|
10262
|
+
},
|
|
10263
|
+
eventBus: { ringBufferSize: RUNTIME_DEFAULTS["eventBus.ringBufferSize"] },
|
|
10264
|
+
retention: {
|
|
10265
|
+
detectionEventsDays: RUNTIME_DEFAULTS["retention.detectionEventsDays"],
|
|
10266
|
+
audioLevelsDays: RUNTIME_DEFAULTS["retention.audioLevelsDays"]
|
|
10267
|
+
},
|
|
10268
|
+
providers: [...RUNTIME_DEFAULTS["providers"]]
|
|
10269
|
+
};
|
|
10270
|
+
}
|
|
10271
|
+
/**
|
|
10272
|
+
* Deep-set a value in a nested plain object using a dot-notation path.
|
|
10273
|
+
* Returns a new object (immutable).
|
|
10274
|
+
*/
|
|
10275
|
+
function setNested(obj, configPath, value) {
|
|
10276
|
+
const [head, ...rest] = configPath.split(".");
|
|
10277
|
+
if (!head) return obj;
|
|
10278
|
+
if (rest.length === 0) return {
|
|
10279
|
+
...obj,
|
|
10280
|
+
[head]: value
|
|
10281
|
+
};
|
|
10282
|
+
const existing = obj[head];
|
|
10283
|
+
const child = isRecord$1(existing) ? existing : {};
|
|
10284
|
+
return {
|
|
10285
|
+
...obj,
|
|
10286
|
+
[head]: setNested(child, rest.join("."), value)
|
|
10287
|
+
};
|
|
10288
|
+
}
|
|
10289
|
+
/**
|
|
10290
|
+
* Apply env var overrides onto the raw YAML object.
|
|
10291
|
+
* Only bootstrap-level env vars are applied.
|
|
10292
|
+
*/
|
|
10293
|
+
function applyEnvOverrides(raw) {
|
|
10294
|
+
let result = { ...raw };
|
|
10295
|
+
for (const [envKey, configPath] of Object.entries(ENV_VAR_MAP)) {
|
|
10296
|
+
const envValue = process.env[envKey];
|
|
10297
|
+
if (envValue === void 0 || envValue === "") continue;
|
|
10298
|
+
const coerced = configPath === "server.port" ? Number(envValue) : envValue;
|
|
10299
|
+
result = setNested(result, configPath, coerced);
|
|
10300
|
+
console.log(`[ConfigManager] Env override applied: ${envKey} → ${configPath}`);
|
|
10301
|
+
}
|
|
10302
|
+
return result;
|
|
10303
|
+
}
|
|
10304
|
+
function loadYaml(configPath) {
|
|
10305
|
+
if (!fs$17.existsSync(configPath)) {
|
|
10306
|
+
console.warn(`[ConfigManager] Config file not found at: ${configPath}\n → Using built-in defaults. Set CONFIG_PATH env var or create the file.\n → Example path from project root: ./server/backend/data/config.yaml`);
|
|
10307
|
+
return {};
|
|
10308
|
+
}
|
|
10309
|
+
const parsed = load$1(fs$17.readFileSync(configPath, "utf-8")) ?? {};
|
|
10310
|
+
console.log(`[ConfigManager] Loaded config from: ${configPath}`);
|
|
10311
|
+
return parsed;
|
|
10312
|
+
}
|
|
10313
|
+
function warnDefaultCredentials(config) {
|
|
10314
|
+
if (config.auth.adminPassword === "changeme") console.warn("[ConfigManager] Warning: Using default admin password \"changeme\". Set auth.adminPassword in your config.yaml or the CAMSTACK_ADMIN_PASS env var.");
|
|
10315
|
+
}
|
|
10316
|
+
//#endregion
|
|
10317
|
+
//#region src/kernel/store-settings-view.ts
|
|
10318
|
+
function createStoreSettingsView(addonId, cm) {
|
|
10319
|
+
const viewAddonConfig = () => !cm.hasSyncStore() ? asJsonObject(cm.getBootstrap(`addons.${addonId}`)) ?? {} : cm.getAddonConfig(addonId);
|
|
10320
|
+
const viewAddonDevice = (deviceId) => !cm.hasSyncStore() ? {} : cm.getAddonDevice(addonId, deviceId);
|
|
10321
|
+
return {
|
|
10322
|
+
async readAddonStore() {
|
|
10323
|
+
return viewAddonConfig();
|
|
10324
|
+
},
|
|
10325
|
+
async readAddonStoreKeyResult(key) {
|
|
10326
|
+
if (!cm.hasSyncStore()) return {
|
|
10327
|
+
kind: "unreadable",
|
|
10328
|
+
reason: "store-read-failed",
|
|
10329
|
+
error: "settings store not wired"
|
|
10330
|
+
};
|
|
10331
|
+
try {
|
|
10332
|
+
const all = cm.getAddonConfig(addonId);
|
|
10333
|
+
return key in all ? {
|
|
10334
|
+
kind: "present",
|
|
10335
|
+
value: all[key]
|
|
10336
|
+
} : { kind: "absent" };
|
|
10337
|
+
} catch (err) {
|
|
10338
|
+
return {
|
|
10339
|
+
kind: "unreadable",
|
|
10340
|
+
reason: "store-read-failed",
|
|
10341
|
+
error: err instanceof Error ? err.message : String(err)
|
|
10342
|
+
};
|
|
10343
|
+
}
|
|
10344
|
+
},
|
|
10345
|
+
async writeAddonStore(patch) {
|
|
10346
|
+
const existing = viewAddonConfig();
|
|
10347
|
+
cm.setAddonConfig(addonId, {
|
|
10348
|
+
...existing,
|
|
10349
|
+
...patch
|
|
10350
|
+
});
|
|
10351
|
+
},
|
|
10352
|
+
async readDeviceStore(deviceId) {
|
|
10353
|
+
return viewAddonDevice(String(deviceId));
|
|
10354
|
+
},
|
|
10355
|
+
async readDeviceStoreBatch(deviceIds) {
|
|
10356
|
+
const out = /* @__PURE__ */ new Map();
|
|
10357
|
+
for (const deviceId of deviceIds) try {
|
|
10358
|
+
out.set(deviceId, viewAddonDevice(String(deviceId)));
|
|
10359
|
+
} catch {
|
|
10360
|
+
out.set(deviceId, {});
|
|
10361
|
+
}
|
|
10362
|
+
return out;
|
|
10363
|
+
},
|
|
10364
|
+
async writeDeviceStore(deviceId, patch) {
|
|
10365
|
+
const key = String(deviceId);
|
|
10366
|
+
const existing = viewAddonDevice(key);
|
|
10367
|
+
cm.setAddonDevice(addonId, key, {
|
|
10368
|
+
...existing,
|
|
10369
|
+
...patch
|
|
10370
|
+
});
|
|
10371
|
+
},
|
|
10372
|
+
async clearDeviceStore(deviceId) {
|
|
10373
|
+
cm.clearAddonDevice(addonId, String(deviceId));
|
|
10374
|
+
},
|
|
10375
|
+
async readDeviceRuntimeState(deviceId) {
|
|
10376
|
+
return cm.getDeviceRuntimeState(String(deviceId));
|
|
10377
|
+
},
|
|
10378
|
+
async writeDeviceRuntimeState(deviceId, data) {
|
|
10379
|
+
cm.setDeviceRuntimeState(String(deviceId), data);
|
|
10380
|
+
},
|
|
10381
|
+
async clearDeviceRuntimeState(deviceId) {
|
|
10382
|
+
cm.clearDeviceRuntimeState(String(deviceId));
|
|
10383
|
+
},
|
|
10384
|
+
async getSection(section) {
|
|
10385
|
+
return cm.getSection(section);
|
|
10386
|
+
},
|
|
10387
|
+
async setSection(section, patch) {
|
|
10388
|
+
const existing = cm.getSection(section);
|
|
10389
|
+
cm.setSection(section, {
|
|
10390
|
+
...existing,
|
|
10391
|
+
...patch
|
|
10392
|
+
});
|
|
10393
|
+
}
|
|
10394
|
+
};
|
|
10395
|
+
}
|
|
10396
|
+
//#endregion
|
|
10397
|
+
//#region src/kernel/system-settings-policy.ts
|
|
10398
|
+
/**
|
|
10399
|
+
* Which `system-settings` keys the STORE may answer, and which the kernel
|
|
10400
|
+
* loads from the door into memory at boot — D675.
|
|
10401
|
+
*
|
|
10402
|
+
* ## The store never outranks env + config.yaml for a bootstrap section
|
|
10403
|
+
*
|
|
10404
|
+
* `system-settings` holds, among other things, `auth.jwtSecret`,
|
|
10405
|
+
* `auth.adminUsername` and `auth.adminPassword` — written there by
|
|
10406
|
+
* `local-auth` (and by older builds) next to `auth.tokenExpiry`. The live
|
|
10407
|
+
* container supplies the same three from env (`CAMSTACK_JWT_SECRET`,
|
|
10408
|
+
* `CAMSTACK_ADMIN_USER`, `CAMSTACK_ADMIN_PASS`). While the store layer was
|
|
10409
|
+
* skipped (every read since D231) env won by accident. Merging the store back
|
|
10410
|
+
* in "highest priority" would let a stale DB copy replace the JWT secret —
|
|
10411
|
+
* invalidating every token — and change the login password.
|
|
10412
|
+
*
|
|
10413
|
+
* So a bootstrap-owned section is answered from env + config.yaml ONLY, and
|
|
10414
|
+
* the store may add exactly the keys in {@link STORE_READABLE_BOOTSTRAP_KEYS}:
|
|
10415
|
+
* today `auth.tokenExpiry`, the one value the operator edits in the UI
|
|
10416
|
+
* (System → Authentication). Widening this list is a security decision, not a
|
|
10417
|
+
* convenience.
|
|
10418
|
+
*/
|
|
10419
|
+
/** Top-level sections whose authority is env + config.yaml (`bootstrapSchema`). */
|
|
10420
|
+
var BOOTSTRAP_OWNED_SECTIONS = new Set([
|
|
10421
|
+
"mode",
|
|
10422
|
+
"server",
|
|
10423
|
+
"auth",
|
|
10424
|
+
"hub",
|
|
10425
|
+
"agent",
|
|
10426
|
+
"tls",
|
|
10427
|
+
"bootstrap"
|
|
10428
|
+
]);
|
|
10429
|
+
/** The only keys under a bootstrap-owned section the store may answer. */
|
|
10430
|
+
var STORE_READABLE_BOOTSTRAP_KEYS = new Set(["auth.tokenExpiry"]);
|
|
10431
|
+
/** May the settings store answer `key`, or is it env + config.yaml only? */
|
|
10432
|
+
function storeMayAnswer(key) {
|
|
10433
|
+
const dot = key.indexOf(".");
|
|
10434
|
+
const section = dot === -1 ? key : key.slice(0, dot);
|
|
10435
|
+
if (!BOOTSTRAP_OWNED_SECTIONS.has(section)) return true;
|
|
10436
|
+
return STORE_READABLE_BOOTSTRAP_KEYS.has(key);
|
|
10437
|
+
}
|
|
10438
|
+
/**
|
|
10439
|
+
* Key prefixes loaded from the door into memory ONCE at boot, so the
|
|
10440
|
+
* synchronous readers that need them (the capability registry's preference
|
|
10441
|
+
* readers, `capabilities.getPreference`) answer the persisted value after a
|
|
10442
|
+
* reboot. Capability preferences are the only prefix: every other synchronous
|
|
10443
|
+
* caller of `ConfigManager.get` either reads a bootstrap key or runs before the
|
|
10444
|
+
* door exists.
|
|
10445
|
+
*/
|
|
10446
|
+
var PRELOADED_SYSTEM_PREFIXES = ["capabilities."];
|
|
10447
|
+
/**
|
|
10448
|
+
* Single keys loaded the same way. `auth.tokenExpiry` is read synchronously on
|
|
10449
|
+
* every mint by the hub's `AuthService` (`AuthManager.signToken`).
|
|
10450
|
+
*/
|
|
10451
|
+
var PRELOADED_SYSTEM_KEYS = ["auth.tokenExpiry"];
|
|
10452
|
+
/** Is `key` served from the boot-time mirror when the engine is isolated? */
|
|
10453
|
+
function isPreloadedSystemKey(key) {
|
|
10454
|
+
if (PRELOADED_SYSTEM_KEYS.includes(key)) return true;
|
|
10455
|
+
return PRELOADED_SYSTEM_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
10456
|
+
}
|
|
10457
|
+
/**
|
|
10458
|
+
* The stored keys of `section` the store may answer (`storeMayAnswer`,
|
|
10459
|
+
* D675): everything for an ordinary section, only the allow-listed keys for a
|
|
10460
|
+
* bootstrap-owned one.
|
|
10461
|
+
*/
|
|
10462
|
+
function filterStoreSection(section, stored) {
|
|
10463
|
+
const out = {};
|
|
10464
|
+
for (const [key, value] of Object.entries(stored)) if (storeMayAnswer(`${section}.${key}`)) out[key] = value;
|
|
10465
|
+
return out;
|
|
10466
|
+
}
|
|
10467
|
+
//#endregion
|
|
10468
|
+
//#region src/kernel/system-settings-mirror.ts
|
|
10469
|
+
function errorText$1(err) {
|
|
10470
|
+
return err instanceof Error ? err.message : String(err);
|
|
10471
|
+
}
|
|
10472
|
+
var SystemSettingsMirror = class {
|
|
10473
|
+
state = { kind: "pending" };
|
|
10474
|
+
/** The door the current read belongs to; a replaced door owns the mirror. */
|
|
10475
|
+
door = null;
|
|
10476
|
+
preload = null;
|
|
10477
|
+
/**
|
|
10478
|
+
* Writes to preloaded keys made through THIS process. They win over the boot
|
|
10479
|
+
* read (they are newer) and survive a failed one, so an operator's Save is
|
|
10480
|
+
* reported back even when the boot read was lost.
|
|
10481
|
+
*/
|
|
10482
|
+
writes = /* @__PURE__ */ new Map();
|
|
10483
|
+
/** Start the ONE read for `door`. Called by `ConfigManager.setSettingsDoor`. */
|
|
10484
|
+
load(door) {
|
|
10485
|
+
this.door = door;
|
|
10486
|
+
this.state = { kind: "pending" };
|
|
10487
|
+
this.preload = this.read(door);
|
|
10488
|
+
}
|
|
10489
|
+
/** The in-flight / settled boot read, or `null` before any door. */
|
|
10490
|
+
whenLoaded() {
|
|
10491
|
+
return this.preload;
|
|
10492
|
+
}
|
|
10493
|
+
/**
|
|
10494
|
+
* A preloaded key's value: `undefined` when the store holds none, or a THROW
|
|
10495
|
+
* (`preload-pending` / `preload-failed`) when it is not known.
|
|
10496
|
+
*/
|
|
10497
|
+
get(key) {
|
|
10498
|
+
if (this.writes.has(key)) return this.writes.get(key);
|
|
10499
|
+
const state = this.state;
|
|
10500
|
+
switch (state.kind) {
|
|
10501
|
+
case "loaded": return state.values.get(key);
|
|
10502
|
+
case "pending": throw new SettingsReadUnavailableError("ConfigManager.get", "preload-pending", `"${key}" is read from the boot-time mirror, whose one read has not settled yet`);
|
|
10503
|
+
case "failed": throw new SettingsReadUnavailableError("ConfigManager.get", "preload-failed", `"${key}" is unknown: the boot-time read of the settings store failed (${state.error})`);
|
|
10504
|
+
}
|
|
10505
|
+
}
|
|
10506
|
+
/** Record a write to a preloaded key so the mirror reports it. */
|
|
10507
|
+
noteWrite(key, value) {
|
|
10508
|
+
if (isPreloadedSystemKey(key)) this.writes.set(key, value);
|
|
10509
|
+
}
|
|
10510
|
+
/** Every row under the preloaded prefixes plus each preloaded key. Never rejects. */
|
|
10511
|
+
async read(door) {
|
|
10512
|
+
try {
|
|
10513
|
+
const values = /* @__PURE__ */ new Map();
|
|
10514
|
+
for (const prefix of PRELOADED_SYSTEM_PREFIXES) {
|
|
10515
|
+
const rows = await loadSystemSettingsPrefix(door, prefix);
|
|
10516
|
+
for (const [suffix, value] of Object.entries(rows)) values.set(`${prefix}${suffix}`, value);
|
|
10517
|
+
}
|
|
10518
|
+
for (const key of PRELOADED_SYSTEM_KEYS) {
|
|
10519
|
+
const value = await door.get({
|
|
10520
|
+
collection: "system-settings",
|
|
10521
|
+
key
|
|
10522
|
+
});
|
|
10523
|
+
if (value !== void 0) values.set(key, value);
|
|
10524
|
+
}
|
|
10525
|
+
if (this.door === door) this.state = {
|
|
10526
|
+
kind: "loaded",
|
|
10527
|
+
values
|
|
10528
|
+
};
|
|
10529
|
+
return {
|
|
10530
|
+
kind: "loaded",
|
|
10531
|
+
keyCount: values.size
|
|
10532
|
+
};
|
|
10533
|
+
} catch (err) {
|
|
10534
|
+
const error = errorText$1(err);
|
|
10535
|
+
if (this.door === door) this.state = {
|
|
10536
|
+
kind: "failed",
|
|
10537
|
+
error
|
|
10538
|
+
};
|
|
10539
|
+
return {
|
|
10540
|
+
kind: "failed",
|
|
10541
|
+
error
|
|
10542
|
+
};
|
|
10543
|
+
}
|
|
10544
|
+
}
|
|
10545
|
+
};
|
|
10546
|
+
//#endregion
|
|
10547
|
+
//#region src/kernel/config-manager.ts
|
|
10548
|
+
function isRecord(value) {
|
|
10549
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10550
|
+
}
|
|
10551
|
+
function errorText(err) {
|
|
10552
|
+
return err instanceof Error ? err.message : String(err);
|
|
10553
|
+
}
|
|
10554
|
+
var ConfigManager = class {
|
|
10101
10555
|
configPath;
|
|
10102
10556
|
bootstrapConfig;
|
|
10103
10557
|
settingsStore = null;
|
|
10104
10558
|
settingsDoor = null;
|
|
10559
|
+
/** Boot-time mirror of the preloaded `system-settings` keys (door mode, D675). */
|
|
10560
|
+
systemMirror = new SystemSettingsMirror();
|
|
10105
10561
|
constructor(configPath) {
|
|
10106
10562
|
this.configPath = configPath;
|
|
10107
|
-
|
|
10108
|
-
const merged = this.applyEnvOverrides(asJsonObject(rawYaml) ?? {});
|
|
10109
|
-
this.bootstrapConfig = bootstrapSchema.parse(merged);
|
|
10110
|
-
this.warnDefaultCredentials();
|
|
10563
|
+
this.bootstrapConfig = loadBootstrapConfig(configPath);
|
|
10111
10564
|
}
|
|
10112
10565
|
/**
|
|
10113
10566
|
* Wire the settings-store backend. Called once, after the `settings-store`
|
|
@@ -10124,6 +10577,25 @@ var ConfigManager = class ConfigManager {
|
|
|
10124
10577
|
*/
|
|
10125
10578
|
setSettingsDoor(door) {
|
|
10126
10579
|
this.settingsDoor = door;
|
|
10580
|
+
this.systemMirror.load(door);
|
|
10581
|
+
}
|
|
10582
|
+
/**
|
|
10583
|
+
* Resolves once the boot read of the preloaded `system-settings` keys has
|
|
10584
|
+
* settled — the hook the addon registry uses to log it and to replay the
|
|
10585
|
+
* capability preferences onto providers that registered before it (D675).
|
|
10586
|
+
* `null` when no door has been wired (a sync store needs no preload).
|
|
10587
|
+
*/
|
|
10588
|
+
whenSystemSettingsPreloaded() {
|
|
10589
|
+
return this.systemMirror.whenLoaded();
|
|
10590
|
+
}
|
|
10591
|
+
backendMode() {
|
|
10592
|
+
if (this.settingsStore !== null) return "store";
|
|
10593
|
+
if (this.settingsDoor !== null) return "door";
|
|
10594
|
+
return "unwired";
|
|
10595
|
+
}
|
|
10596
|
+
/** The refusal every sync addon-scoped reader raises without a sync store. */
|
|
10597
|
+
refuseSyncRead(reader, subject) {
|
|
10598
|
+
return this.backendMode() === "door" ? new SettingsReadUnavailableError(`ConfigManager.${reader}`, "door-only", `${subject}: the settings engine is isolated and has no synchronous handle — read it through the settings view (createSettingsView / readAddonStoreResult)`) : new SettingsReadUnavailableError(`ConfigManager.${reader}`, "not-wired", `${subject}: no settings backend is wired yet`);
|
|
10127
10599
|
}
|
|
10128
10600
|
get(configPath) {
|
|
10129
10601
|
return this.resolveConfigValue(configPath);
|
|
@@ -10131,35 +10603,52 @@ var ConfigManager = class ConfigManager {
|
|
|
10131
10603
|
resolveConfigValue(configPath) {
|
|
10132
10604
|
const bootstrapValue = this.getFromBootstrap(configPath);
|
|
10133
10605
|
if (bootstrapValue !== void 0) return bootstrapValue;
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
if (storeValue !== void 0) return storeValue;
|
|
10137
|
-
const nested = this.getNestedFromSystemSettings(configPath);
|
|
10138
|
-
if (nested !== null) return nested;
|
|
10139
|
-
}
|
|
10606
|
+
const storeValue = this.readStoreLayer(configPath);
|
|
10607
|
+
if (storeValue !== void 0) return storeValue;
|
|
10140
10608
|
if (configPath in RUNTIME_DEFAULTS) return RUNTIME_DEFAULTS[configPath];
|
|
10141
10609
|
return this.getFromRuntimeDefaults(configPath) ?? void 0;
|
|
10142
10610
|
}
|
|
10143
10611
|
/**
|
|
10144
|
-
*
|
|
10145
|
-
*
|
|
10612
|
+
* The settings-store layer of {@link get}: the stored value, `undefined`
|
|
10613
|
+
* when the store holds nothing (or may not answer this key), or a THROW
|
|
10614
|
+
* when the store cannot be asked.
|
|
10615
|
+
*/
|
|
10616
|
+
readStoreLayer(configPath) {
|
|
10617
|
+
if (!storeMayAnswer(configPath)) return void 0;
|
|
10618
|
+
switch (this.backendMode()) {
|
|
10619
|
+
case "store": {
|
|
10620
|
+
const store = this.settingsStore;
|
|
10621
|
+
if (store === null) return void 0;
|
|
10622
|
+
const storeValue = store.getSystem(configPath);
|
|
10623
|
+
if (storeValue !== void 0) return storeValue;
|
|
10624
|
+
return this.getNestedFromSystemSettings(configPath) ?? void 0;
|
|
10625
|
+
}
|
|
10626
|
+
case "door":
|
|
10627
|
+
if (isPreloadedSystemKey(configPath)) return this.systemMirror.get(configPath);
|
|
10628
|
+
throw new SettingsReadUnavailableError("ConfigManager.get", "door-only", `"${configPath}" may be stored, and the isolated engine cannot be read synchronously — only ${[...PRELOADED_SYSTEM_PREFIXES, ...PRELOADED_SYSTEM_KEYS].join(", ")} are mirrored at boot`);
|
|
10629
|
+
case "unwired": return;
|
|
10630
|
+
}
|
|
10631
|
+
}
|
|
10632
|
+
/**
|
|
10633
|
+
* Write a value to the settings-store. Resolves only once the write LANDED:
|
|
10634
|
+
* on the isolated engine it awaits the door, and a failed write REJECTS and
|
|
10635
|
+
* is not reported back by the mirror (D675 — it used to be fire-and-forget,
|
|
10636
|
+
* so a lost write read as saved for the life of the process). Rejects when
|
|
10637
|
+
* no store is wired.
|
|
10146
10638
|
*/
|
|
10147
|
-
set(key, value) {
|
|
10639
|
+
async set(key, value) {
|
|
10148
10640
|
if (this.settingsStore !== null) {
|
|
10149
10641
|
this.settingsStore.setSystem(key, value);
|
|
10150
10642
|
return;
|
|
10151
10643
|
}
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
return;
|
|
10161
|
-
}
|
|
10162
|
-
throw new Error("[ConfigManager] SettingsStore not initialized -- call setSettingsStore() first");
|
|
10644
|
+
const door = this.settingsDoor;
|
|
10645
|
+
if (door === null) throw new SettingsReadUnavailableError("ConfigManager.set", "not-wired", `"${key}" cannot be written: no settings backend is wired yet`);
|
|
10646
|
+
await door.set({
|
|
10647
|
+
collection: "system-settings",
|
|
10648
|
+
key,
|
|
10649
|
+
value
|
|
10650
|
+
});
|
|
10651
|
+
this.systemMirror.noteWrite(key, value);
|
|
10163
10652
|
}
|
|
10164
10653
|
/**
|
|
10165
10654
|
* Bulk-read all keys that belong to a logical section.
|
|
@@ -10175,17 +10664,40 @@ var ConfigManager = class ConfigManager {
|
|
|
10175
10664
|
* shadowing the rest of the section that only lives in config.yaml.
|
|
10176
10665
|
* The kernel is agnostic about the store backend — any `ISettingsStore`
|
|
10177
10666
|
* implementation (sqlite, redis, in-memory, …) behaves identically here.
|
|
10667
|
+
*
|
|
10668
|
+
* D675: a bootstrap-owned section takes ONLY allow-listed keys from the
|
|
10669
|
+
* store (a stored `auth.jwtSecret` never replaces env), and with only the
|
|
10670
|
+
* door wired this sync read THROWS — the settings view's `getSection` reads
|
|
10671
|
+
* the door.
|
|
10178
10672
|
*/
|
|
10179
10673
|
getSection(section) {
|
|
10674
|
+
const mode = this.backendMode();
|
|
10675
|
+
if (mode === "door") throw new SettingsReadUnavailableError("ConfigManager.getSection", "door-only", `section "${section}": the settings engine is isolated — read it through the settings view (ctx.settings.getSection)`);
|
|
10676
|
+
const merged = this.sectionBase(section);
|
|
10677
|
+
if (mode === "store") {
|
|
10678
|
+
const nested = this.getNestedFromSystemSettings(section);
|
|
10679
|
+
if (nested) Object.assign(merged, filterStoreSection(section, nested));
|
|
10680
|
+
}
|
|
10681
|
+
return merged;
|
|
10682
|
+
}
|
|
10683
|
+
/** Runtime defaults, then config.yaml + env — the layers under the store. */
|
|
10684
|
+
sectionBase(section) {
|
|
10180
10685
|
const merged = {};
|
|
10181
10686
|
const defaults = asJsonObject(this.getFromRuntimeDefaults(section));
|
|
10182
10687
|
if (defaults) Object.assign(merged, defaults);
|
|
10183
10688
|
const bootstrapSection = asJsonObject({ ...this.bootstrapConfig }[section]);
|
|
10184
10689
|
if (bootstrapSection) Object.assign(merged, bootstrapSection);
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10690
|
+
return merged;
|
|
10691
|
+
}
|
|
10692
|
+
/**
|
|
10693
|
+
* {@link getSection} through the async door — what the door-backed settings
|
|
10694
|
+
* view answers (D675). Same layers, same allow-list; a failed door read
|
|
10695
|
+
* THROWS rather than handing back the defaults as if nothing were stored.
|
|
10696
|
+
*/
|
|
10697
|
+
async readSectionThroughDoor(door, section) {
|
|
10698
|
+
const merged = this.sectionBase(section);
|
|
10699
|
+
const stored = await loadSystemSettingsPrefix(door, `${section}.`, (key) => storeMayAnswer(`${section}.${key}`));
|
|
10700
|
+
Object.assign(merged, filterStoreSection(section, stored));
|
|
10189
10701
|
return merged;
|
|
10190
10702
|
}
|
|
10191
10703
|
/**
|
|
@@ -10196,44 +10708,58 @@ var ConfigManager = class ConfigManager {
|
|
|
10196
10708
|
if (this.settingsStore === null) throw new Error("[ConfigManager] SettingsStore not initialized -- call setSettingsStore() first");
|
|
10197
10709
|
for (const [key, value] of Object.entries(data)) this.settingsStore.setSystem(`${section}.${key}`, value);
|
|
10198
10710
|
}
|
|
10199
|
-
/**
|
|
10711
|
+
/**
|
|
10712
|
+
* Read all config for an addon — SYNC store only. THROWS without one: its
|
|
10713
|
+
* old bootstrap fallback answered `{}` for every addon on every
|
|
10714
|
+
* isolated-engine hub (D675). Async three-way: {@link readAddonGlobalStrict}.
|
|
10715
|
+
*/
|
|
10200
10716
|
getAddonConfig(addonId) {
|
|
10201
10717
|
if (this.settingsStore !== null) return this.settingsStore.getAllAddon(addonId);
|
|
10202
|
-
|
|
10718
|
+
throw this.refuseSyncRead("getAddonConfig", `addon "${addonId}"`);
|
|
10719
|
+
}
|
|
10720
|
+
/**
|
|
10721
|
+
* One addon's global store, three-way (D675): the record, `{}` when the
|
|
10722
|
+
* store ANSWERED with nothing, or a THROW when it could not be asked.
|
|
10723
|
+
* Behind `addonSettingsRaw.getGlobal` and `$hub.getAddonConfig`.
|
|
10724
|
+
*/
|
|
10725
|
+
async readAddonGlobalStrict(addonId) {
|
|
10726
|
+
const read = await this.createSettingsView(addonId).readAddonStoreResult();
|
|
10727
|
+
switch (read.kind) {
|
|
10728
|
+
case "value": return read.value;
|
|
10729
|
+
case "missing": return {};
|
|
10730
|
+
case "failed": throw new SettingsReadUnavailableError("ConfigManager.readAddonGlobalStrict", this.backendMode() === "unwired" ? "not-wired" : "read-failed", `addon "${addonId}": ${read.error}`);
|
|
10731
|
+
}
|
|
10732
|
+
}
|
|
10733
|
+
/** One addon's per-device overrides, three-way like {@link readAddonGlobalStrict}. */
|
|
10734
|
+
async readAddonDeviceStrict(addonId, deviceId) {
|
|
10735
|
+
const door = this.settingsDoor;
|
|
10736
|
+
switch (this.backendMode()) {
|
|
10737
|
+
case "store": return this.getAddonDevice(addonId, String(deviceId));
|
|
10738
|
+
case "door":
|
|
10739
|
+
if (door === null) break;
|
|
10740
|
+
try {
|
|
10741
|
+
return await this.createDoorBackedSettingsView(addonId, door).readDeviceStore(deviceId);
|
|
10742
|
+
} catch (err) {
|
|
10743
|
+
throw new SettingsReadUnavailableError("ConfigManager.readAddonDeviceStrict", "read-failed", `addon "${addonId}" device ${deviceId}: ${errorText(err)}`);
|
|
10744
|
+
}
|
|
10745
|
+
case "unwired": break;
|
|
10746
|
+
}
|
|
10747
|
+
throw this.refuseSyncRead("readAddonDeviceStrict", `addon "${addonId}" device ${deviceId}`);
|
|
10203
10748
|
}
|
|
10204
10749
|
/** Write (bulk-replace) config for an addon to addon_settings. */
|
|
10205
10750
|
setAddonConfig(addonId, config) {
|
|
10206
10751
|
if (this.settingsStore === null) throw new Error("[ConfigManager] SettingsStore not initialized -- call setSettingsStore() first");
|
|
10207
10752
|
this.settingsStore.setAllAddon(addonId, config);
|
|
10208
10753
|
}
|
|
10209
|
-
/** Read all config for a provider from provider_settings. */
|
|
10210
|
-
getProviderConfig(providerId) {
|
|
10211
|
-
if (this.settingsStore !== null) return this.settingsStore.getAllProvider(providerId);
|
|
10212
|
-
return {};
|
|
10213
|
-
}
|
|
10214
|
-
/** Write (upsert) a single key for a provider to provider_settings. */
|
|
10215
|
-
setProviderConfig(providerId, key, value) {
|
|
10216
|
-
if (this.settingsStore === null) throw new Error("[ConfigManager] SettingsStore not initialized -- call setSettingsStore() first");
|
|
10217
|
-
this.settingsStore.setProvider(providerId, key, value);
|
|
10218
|
-
}
|
|
10219
|
-
/** Read all config for a device from device_settings. */
|
|
10220
|
-
getDeviceConfig(deviceId) {
|
|
10221
|
-
if (this.settingsStore !== null) return this.settingsStore.getAllDevice(deviceId);
|
|
10222
|
-
return {};
|
|
10223
|
-
}
|
|
10224
|
-
/** Write (upsert) a single key for a device to device_settings. */
|
|
10225
|
-
setDeviceConfig(deviceId, key, value) {
|
|
10226
|
-
if (this.settingsStore === null) throw new Error("[ConfigManager] SettingsStore not initialized -- call setSettingsStore() first");
|
|
10227
|
-
this.settingsStore.setDevice(deviceId, key, value);
|
|
10228
|
-
}
|
|
10229
10754
|
/**
|
|
10230
10755
|
* Read per-device overrides for a specific addon. Returns a flat record
|
|
10231
10756
|
* of field → value. Missing keys fall back to the addon-global value via
|
|
10232
10757
|
* `getAddonConfig(addonId)` — that composition is the resolver service's
|
|
10233
10758
|
* responsibility, not ConfigManager's.
|
|
10759
|
+
* SYNC store only — THROWS without one (D675); async: {@link readAddonDeviceStrict}.
|
|
10234
10760
|
*/
|
|
10235
10761
|
getAddonDevice(addonId, deviceId) {
|
|
10236
|
-
if (this.settingsStore === null)
|
|
10762
|
+
if (this.settingsStore === null) throw this.refuseSyncRead("getAddonDevice", `addon "${addonId}" device "${deviceId}"`);
|
|
10237
10763
|
return this.settingsStore.getAddonDevice(addonId, deviceId);
|
|
10238
10764
|
}
|
|
10239
10765
|
/**
|
|
@@ -10254,12 +10780,11 @@ var ConfigManager = class ConfigManager {
|
|
|
10254
10780
|
this.settingsStore.clearAddonDevice(addonId, deviceId);
|
|
10255
10781
|
}
|
|
10256
10782
|
/**
|
|
10257
|
-
* The device's persisted runtime-state blob.
|
|
10258
|
-
*
|
|
10259
|
-
* which is what every caller already handles.
|
|
10783
|
+
* The device's persisted runtime-state blob. THROWS before the store is
|
|
10784
|
+
* wired: a store not asked is not an empty row (D677, D675).
|
|
10260
10785
|
*/
|
|
10261
10786
|
getDeviceRuntimeState(deviceId) {
|
|
10262
|
-
if (this.settingsStore === null)
|
|
10787
|
+
if (this.settingsStore === null) throw this.refuseSyncRead("getDeviceRuntimeState", `runtime state of device ${deviceId}`);
|
|
10263
10788
|
return this.settingsStore.getDeviceRuntimeState(deviceId);
|
|
10264
10789
|
}
|
|
10265
10790
|
/**
|
|
@@ -10327,6 +10852,7 @@ var ConfigManager = class ConfigManager {
|
|
|
10327
10852
|
};
|
|
10328
10853
|
}
|
|
10329
10854
|
},
|
|
10855
|
+
readAddonStoreKeyResult: (key) => active().readAddonStoreKeyResult(key),
|
|
10330
10856
|
writeAddonStore: (patch) => active().writeAddonStore(patch),
|
|
10331
10857
|
readDeviceStore: (deviceId) => active().readDeviceStore(deviceId),
|
|
10332
10858
|
readDeviceStoreBatch: (deviceIds) => active().readDeviceStoreBatch(deviceIds),
|
|
@@ -10342,81 +10868,39 @@ var ConfigManager = class ConfigManager {
|
|
|
10342
10868
|
/** The async-door backend of {@link createSettingsView}. */
|
|
10343
10869
|
createDoorBackedSettingsView(addonId, door) {
|
|
10344
10870
|
return createDoorSettingsView(addonId, door, {
|
|
10345
|
-
getSection: (section) => this.
|
|
10871
|
+
getSection: (section) => this.readSectionThroughDoor(door, section),
|
|
10346
10872
|
setSection: async (section, patch) => {
|
|
10347
|
-
for (const [key, value] of Object.entries(patch))
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10873
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
10874
|
+
const fullKey = `${section}.${key}`;
|
|
10875
|
+
await door.set({
|
|
10876
|
+
collection: "system-settings",
|
|
10877
|
+
key: fullKey,
|
|
10878
|
+
value
|
|
10879
|
+
});
|
|
10880
|
+
this.systemMirror.noteWrite(fullKey, value);
|
|
10881
|
+
}
|
|
10352
10882
|
}
|
|
10353
10883
|
});
|
|
10354
10884
|
}
|
|
10355
10885
|
/** The sync-`ISettingsStore` backend of {@link createSettingsView}. */
|
|
10356
10886
|
createStoreSettingsView(addonId) {
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
async writeAddonStore(patch) {
|
|
10363
|
-
const existing = cm.getAddonConfig(addonId);
|
|
10364
|
-
cm.setAddonConfig(addonId, {
|
|
10365
|
-
...existing,
|
|
10366
|
-
...patch
|
|
10367
|
-
});
|
|
10368
|
-
},
|
|
10369
|
-
async readDeviceStore(deviceId) {
|
|
10370
|
-
return cm.getAddonDevice(addonId, String(deviceId));
|
|
10371
|
-
},
|
|
10372
|
-
async readDeviceStoreBatch(deviceIds) {
|
|
10373
|
-
const out = /* @__PURE__ */ new Map();
|
|
10374
|
-
for (const deviceId of deviceIds) try {
|
|
10375
|
-
out.set(deviceId, cm.getAddonDevice(addonId, String(deviceId)));
|
|
10376
|
-
} catch {
|
|
10377
|
-
out.set(deviceId, {});
|
|
10378
|
-
}
|
|
10379
|
-
return out;
|
|
10380
|
-
},
|
|
10381
|
-
async writeDeviceStore(deviceId, patch) {
|
|
10382
|
-
const key = String(deviceId);
|
|
10383
|
-
const existing = cm.getAddonDevice(addonId, key);
|
|
10384
|
-
cm.setAddonDevice(addonId, key, {
|
|
10385
|
-
...existing,
|
|
10386
|
-
...patch
|
|
10387
|
-
});
|
|
10388
|
-
},
|
|
10389
|
-
async clearDeviceStore(deviceId) {
|
|
10390
|
-
cm.clearAddonDevice(addonId, String(deviceId));
|
|
10391
|
-
},
|
|
10392
|
-
async readDeviceRuntimeState(deviceId) {
|
|
10393
|
-
return cm.getDeviceRuntimeState(String(deviceId));
|
|
10394
|
-
},
|
|
10395
|
-
async writeDeviceRuntimeState(deviceId, data) {
|
|
10396
|
-
cm.setDeviceRuntimeState(String(deviceId), data);
|
|
10397
|
-
},
|
|
10398
|
-
async clearDeviceRuntimeState(deviceId) {
|
|
10399
|
-
cm.clearDeviceRuntimeState(String(deviceId));
|
|
10400
|
-
},
|
|
10401
|
-
async getSection(section) {
|
|
10402
|
-
return cm.getSection(section);
|
|
10403
|
-
},
|
|
10404
|
-
async setSection(section, patch) {
|
|
10405
|
-
const existing = cm.getSection(section);
|
|
10406
|
-
cm.setSection(section, {
|
|
10407
|
-
...existing,
|
|
10408
|
-
...patch
|
|
10409
|
-
});
|
|
10410
|
-
}
|
|
10411
|
-
};
|
|
10887
|
+
return createStoreSettingsView(addonId, this);
|
|
10888
|
+
}
|
|
10889
|
+
/** Is a SYNC `ISettingsStore` wired? (The store-backed view's D294-window test.) */
|
|
10890
|
+
hasSyncStore() {
|
|
10891
|
+
return this.settingsStore !== null;
|
|
10412
10892
|
}
|
|
10413
10893
|
getBootstrap(configPath) {
|
|
10414
10894
|
return this.getFromBootstrap(configPath);
|
|
10415
10895
|
}
|
|
10416
|
-
/**
|
|
10896
|
+
/**
|
|
10897
|
+
* Features — the sync store when wired, else RUNTIME_DEFAULTS DELIBERATELY
|
|
10898
|
+
* (not `get()`, which refuses in door mode, D675): nothing writes
|
|
10899
|
+
* `features.*` beyond sqlite-settings' first-boot seed of these defaults.
|
|
10900
|
+
*/
|
|
10417
10901
|
get features() {
|
|
10418
10902
|
const g = (key) => {
|
|
10419
|
-
const storeValue = this.get(`features.${key}`);
|
|
10903
|
+
const storeValue = this.settingsStore !== null ? this.get(`features.${key}`) : void 0;
|
|
10420
10904
|
if (typeof storeValue === "boolean") return storeValue;
|
|
10421
10905
|
return RUNTIME_DEFAULTS[`features.${key}`];
|
|
10422
10906
|
};
|
|
@@ -10432,115 +10916,16 @@ var ConfigManager = class ConfigManager {
|
|
|
10432
10916
|
repl: g("repl")
|
|
10433
10917
|
};
|
|
10434
10918
|
}
|
|
10435
|
-
/**
|
|
10436
|
-
* Returns a merged view of bootstrap config + runtime defaults for backward compat.
|
|
10437
|
-
*/
|
|
10919
|
+
/** Bootstrap config + runtime defaults, for backward compat. */
|
|
10438
10920
|
get raw() {
|
|
10439
|
-
|
|
10440
|
-
streaming: RUNTIME_DEFAULTS["features.streaming"],
|
|
10441
|
-
notifications: RUNTIME_DEFAULTS["features.notifications"],
|
|
10442
|
-
objectDetection: RUNTIME_DEFAULTS["features.objectDetection"],
|
|
10443
|
-
remoteAccess: RUNTIME_DEFAULTS["features.remoteAccess"],
|
|
10444
|
-
agentCluster: RUNTIME_DEFAULTS["features.agentCluster"],
|
|
10445
|
-
smartHome: RUNTIME_DEFAULTS["features.smartHome"],
|
|
10446
|
-
recordings: RUNTIME_DEFAULTS["features.recordings"],
|
|
10447
|
-
backup: RUNTIME_DEFAULTS["features.backup"],
|
|
10448
|
-
repl: RUNTIME_DEFAULTS["features.repl"]
|
|
10449
|
-
};
|
|
10450
|
-
return {
|
|
10451
|
-
...this.bootstrapConfig,
|
|
10452
|
-
features,
|
|
10453
|
-
storage: {
|
|
10454
|
-
provider: RUNTIME_DEFAULTS["storage.provider"],
|
|
10455
|
-
locations: { ...RUNTIME_DEFAULTS["storage.locations"] }
|
|
10456
|
-
},
|
|
10457
|
-
logging: {
|
|
10458
|
-
level: RUNTIME_DEFAULTS["logging.level"],
|
|
10459
|
-
retentionDays: RUNTIME_DEFAULTS["logging.retentionDays"]
|
|
10460
|
-
},
|
|
10461
|
-
eventBus: { ringBufferSize: RUNTIME_DEFAULTS["eventBus.ringBufferSize"] },
|
|
10462
|
-
retention: {
|
|
10463
|
-
detectionEventsDays: RUNTIME_DEFAULTS["retention.detectionEventsDays"],
|
|
10464
|
-
audioLevelsDays: RUNTIME_DEFAULTS["retention.audioLevelsDays"]
|
|
10465
|
-
},
|
|
10466
|
-
providers: [...RUNTIME_DEFAULTS["providers"]]
|
|
10467
|
-
};
|
|
10921
|
+
return buildRawAppConfig(this.bootstrapConfig);
|
|
10468
10922
|
}
|
|
10469
|
-
/** Sections that live in config.yaml. Everything else goes to the settings-store. */
|
|
10470
|
-
static BOOTSTRAP_SECTIONS = new Set([
|
|
10471
|
-
"server",
|
|
10472
|
-
"auth",
|
|
10473
|
-
"mode"
|
|
10474
|
-
]);
|
|
10475
10923
|
/**
|
|
10476
|
-
* Atomically update one top-level section
|
|
10477
|
-
*
|
|
10478
|
-
* Runtime settings must use setSection() which writes to the settings-store.
|
|
10924
|
+
* Atomically update one top-level bootstrap section (server, auth, mode) of
|
|
10925
|
+
* config.yaml and sync in-memory. Runtime settings use setSection().
|
|
10479
10926
|
*/
|
|
10480
10927
|
update(section, data) {
|
|
10481
|
-
|
|
10482
|
-
let raw = {};
|
|
10483
|
-
if (fs$17.existsSync(this.configPath)) raw = asJsonObject(load$1(fs$17.readFileSync(this.configPath, "utf-8"))) ?? {};
|
|
10484
|
-
const existing = asJsonObject(raw[section]) ?? {};
|
|
10485
|
-
raw[section] = {
|
|
10486
|
-
...existing,
|
|
10487
|
-
...data
|
|
10488
|
-
};
|
|
10489
|
-
const validation = bootstrapSchema.safeParse(raw);
|
|
10490
|
-
if (!validation.success) throw new Error(`[ConfigManager] Invalid config update for section "${section}": ${validation.error.message}`);
|
|
10491
|
-
const tmpPath = `${this.configPath}.tmp`;
|
|
10492
|
-
fs$17.writeFileSync(tmpPath, dump(raw, {
|
|
10493
|
-
lineWidth: 120,
|
|
10494
|
-
indent: 2,
|
|
10495
|
-
quotingType: "\""
|
|
10496
|
-
}), "utf-8");
|
|
10497
|
-
fs$17.renameSync(tmpPath, this.configPath);
|
|
10498
|
-
this.bootstrapConfig = validation.data;
|
|
10499
|
-
}
|
|
10500
|
-
/**
|
|
10501
|
-
* Deep-set a value in a nested plain object using a dot-notation path.
|
|
10502
|
-
* Returns a new object (immutable).
|
|
10503
|
-
*/
|
|
10504
|
-
setNested(obj, configPath, value) {
|
|
10505
|
-
const [head, ...rest] = configPath.split(".");
|
|
10506
|
-
if (!head) return obj;
|
|
10507
|
-
if (rest.length === 0) return {
|
|
10508
|
-
...obj,
|
|
10509
|
-
[head]: value
|
|
10510
|
-
};
|
|
10511
|
-
const existing = obj[head];
|
|
10512
|
-
const child = isRecord(existing) ? existing : {};
|
|
10513
|
-
return {
|
|
10514
|
-
...obj,
|
|
10515
|
-
[head]: this.setNested(child, rest.join("."), value)
|
|
10516
|
-
};
|
|
10517
|
-
}
|
|
10518
|
-
/**
|
|
10519
|
-
* Apply env var overrides onto the raw YAML object.
|
|
10520
|
-
* Only bootstrap-level env vars are applied.
|
|
10521
|
-
*/
|
|
10522
|
-
applyEnvOverrides(raw) {
|
|
10523
|
-
let result = { ...raw };
|
|
10524
|
-
for (const [envKey, configPath] of Object.entries(ENV_VAR_MAP)) {
|
|
10525
|
-
const envValue = process.env[envKey];
|
|
10526
|
-
if (envValue === void 0 || envValue === "") continue;
|
|
10527
|
-
const coerced = configPath === "server.port" ? Number(envValue) : envValue;
|
|
10528
|
-
result = this.setNested(result, configPath, coerced);
|
|
10529
|
-
console.log(`[ConfigManager] Env override applied: ${envKey} → ${configPath}`);
|
|
10530
|
-
}
|
|
10531
|
-
return result;
|
|
10532
|
-
}
|
|
10533
|
-
loadYaml() {
|
|
10534
|
-
if (!fs$17.existsSync(this.configPath)) {
|
|
10535
|
-
console.warn(`[ConfigManager] Config file not found at: ${this.configPath}\n → Using built-in defaults. Set CONFIG_PATH env var or create the file.\n → Example path from project root: ./server/backend/data/config.yaml`);
|
|
10536
|
-
return {};
|
|
10537
|
-
}
|
|
10538
|
-
const parsed = load$1(fs$17.readFileSync(this.configPath, "utf-8")) ?? {};
|
|
10539
|
-
console.log(`[ConfigManager] Loaded config from: ${this.configPath}`);
|
|
10540
|
-
return parsed;
|
|
10541
|
-
}
|
|
10542
|
-
warnDefaultCredentials() {
|
|
10543
|
-
if (this.bootstrapConfig.auth.adminPassword === "changeme") console.warn("[ConfigManager] Warning: Using default admin password \"changeme\". Set auth.adminPassword in your config.yaml or the CAMSTACK_ADMIN_PASS env var.");
|
|
10928
|
+
this.bootstrapConfig = writeBootstrapSection(this.configPath, section, data);
|
|
10544
10929
|
}
|
|
10545
10930
|
getFromBootstrap(configPath) {
|
|
10546
10931
|
const keys = configPath.split(".");
|
|
@@ -96043,4 +96428,4 @@ var LifecycleJobEngine = class {
|
|
|
96043
96428
|
}
|
|
96044
96429
|
};
|
|
96045
96430
|
//#endregion
|
|
96046
|
-
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, answerClaimedGetStatus, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, overlayGetStatus, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
96431
|
+
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORE_READABLE_BOOTSTRAP_KEYS, ScopedLogger, ScopedTokenManager, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, answerClaimedGetStatus, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSettingsReadUnavailable, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, overlayGetStatus, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, storeMayAnswer, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|