@camstack/system 1.2.156 → 1.2.159

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/addon-runner.js +17 -16
  2. package/dist/addon-runner.mjs +2 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/console-logging/index.js +1 -1
  12. package/dist/builtins/console-logging/index.mjs +1 -1
  13. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  14. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  16. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  17. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  18. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  19. package/dist/builtins/hub-forwarder/index.js +1 -1
  20. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  21. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  22. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  23. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  24. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  25. package/dist/builtins/local-network/local-network.addon.js +1 -1
  26. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  27. package/dist/builtins/loki-logging/index.js +1 -1
  28. package/dist/builtins/loki-logging/index.mjs +1 -1
  29. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  30. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  31. package/dist/builtins/platform-probe/index.js +1 -1
  32. package/dist/builtins/platform-probe/index.mjs +1 -1
  33. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  34. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  35. package/dist/builtins/snapshot/index.js +1 -1
  36. package/dist/builtins/snapshot/index.mjs +1 -1
  37. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  38. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  39. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  40. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  41. package/dist/builtins/sqlite-storage/vector-index-shared.d.ts +30 -5
  42. package/dist/builtins/sqlite-storage/vector-index-vec.d.ts +28 -6
  43. package/dist/builtins/storage-orchestrator/access-guards.d.ts +32 -0
  44. package/dist/builtins/storage-orchestrator/location-secrets.d.ts +33 -0
  45. package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +71 -1
  46. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +26 -0
  47. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +491 -9
  48. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +491 -9
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +37 -1
  50. package/dist/builtins/system-config/system-config.addon.js +1 -1
  51. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  52. package/dist/builtins/winston-logging/index.js +1 -1
  53. package/dist/builtins/winston-logging/index.mjs +1 -1
  54. package/dist/{dist-CDgIzo82.js → dist-Ck2jkBZk.js} +463 -10
  55. package/dist/{dist-LvKus-mT.mjs → dist-DLh4_rn3.mjs} +446 -11
  56. package/dist/index.js +204 -151
  57. package/dist/index.mjs +67 -15
  58. package/dist/kernel/config-manager.d.ts +31 -0
  59. package/dist/kernel/deps/manifest-system-deps.d.ts +15 -0
  60. package/dist/kernel/index.d.ts +2 -0
  61. package/dist/kernel/settings-door-view.d.ts +2 -2
  62. package/dist/kernel/storage-location-registry.d.ts +16 -1
  63. package/dist/{manifest-python-deps-DVODn-qc.js → manifest-system-deps-8boi90D9.js} +202 -7
  64. package/dist/{manifest-python-deps-CD14Pv0-.mjs → manifest-system-deps-tZZYG3RR.mjs} +197 -8
  65. package/dist/{retired-settings-keys-CV4QVdXj.mjs → retired-settings-keys-Bi0ZKBjb.mjs} +1 -1
  66. package/dist/{retired-settings-keys-BfAzWvPC.js → retired-settings-keys-Dp_CyuCW.js} +1 -1
  67. package/package.json +2 -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 { $ as isVoidInput, $t as scopeKey, At as DATAPLANE_SECRET_HEADER$1, Bt as asNumber, C as addonSettingsCapability, G as extractNestedAddonId, Gt as expandCapMethods, Ht as createEvent, It as ReadinessRegistry, J as isArrayOutputSchema, Lt as ReadinessTimeoutError, Mt as DEVICE_STATUS_METHOD, Ot as errMsg$1, Qt as resolveCapMount, Ut as emitDownForOwnedCaps, Vt as asString$1, X as isObjectInput, Xt as parseJsonUnknown$1, Y as isCollectionArrayMethod, Yt as parseJsonObject, Zt as readinessKey, _t as scopesAllowDeviceCap, at as looseSchema, ct as objectInputDeclaresAddonId, dt as procedureAuthKey, et as kebabToCamel, f as LOG_LEVEL_RANK, gt as scopesAllowAddon, it as logLevelAtMost, jt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, m as RUNTIME_DEFAULTS, mt as resolveMethodAuth, p as METHOD_ACCESS_MAP, t as ALL_CAPABILITY_DEFINITIONS, tn as EventCategory$1, tt as lifecycleJobSchema, zt as asJsonObject$1 } from "./dist-LvKus-mT.mjs";
2
+ import { $ as isObjectInput, $t as parseJsonUnknown$1, Bt as ReadinessTimeoutError, Ft as DEVICE_STATUS_METHOD, Gt as createEvent, Ht as asJsonObject$1, J as extractNestedAddonId, Jt as expandCapMethods, Kt as emitDownForOwnedCaps, Nt as DATAPLANE_SECRET_HEADER$1, Pt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Q as isCollectionArrayMethod, Qt as parseJsonObject, T as addonSettingsCapability, Ut as asNumber, Wt as asString$1, Z as isArrayOutputSchema, _t as resolveMethodAuth, bt as scopesAllowDeviceCap, ct as looseSchema, dt as objectInputDeclaresAddonId, en as readinessKey, f as LOG_LEVEL_RANK, h as RUNTIME_DEFAULTS, in as EventCategory$1, it as lifecycleJobSchema, jt as errMsg$1, mt as procedureAuthKey, nn as scopeKey, nt as isVoidInput, p as METHOD_ACCESS_MAP, rt as kebabToCamel, st as logLevelAtMost, t as ALL_CAPABILITY_DEFINITIONS, tn as resolveCapMount, yt as scopesAllowAddon, zt as ReadinessRegistry } from "./dist-DLh4_rn3.mjs";
3
3
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
4
4
  import "./builtins/alerts/index.mjs";
5
5
  import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
@@ -25,7 +25,7 @@ import "./builtins/system-config/index.mjs";
25
25
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
26
26
  import { a as parseTokenizedUrl, c as collectModelFiles, d as downloadModel, f as ensureModel, h as isModelDownloaded, i as parseRangeHeader, l as deleteModelFromDisk, m as getModelFilePath, n as contentTypeFor, o as resolveFilePath, p as fetchJson, r as createAuthenticatedFileServer, s as ModelDownloadService, t as createFileDataPlaneHandler, u as downloadFile } from "./file-data-plane-BhKdxJgf.mjs";
27
27
  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-DOTmtLCW.mjs";
28
- import { $ as buildNativeCapProxy, $t as RUNNER_HEAP_SNAPSHOT_ENV, A as createParentUnownedCallHandler, At as HUB_MAIN_HEAP_WATCH_LABEL, B as AGENT_CAP_FWD_SERVICE, Bt as createLoopDelayMeter, C as brokerTransportLink, Ct as runNpm, D as HUB_CAP_FWD_ACTION, Dt as HEAP_RECLAIM_TRIGGER_MB, E as localProviderLink, Et as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, F as createUdsLoggerWithControl, Ft as RUNNER_HEAP_WATCH_INTERVAL_MS, G as readMoleculerFanoutMode, Gt as parseRssBudgetMb, H as CapRouteError, Ht as describeRss, I as LocalChildClient, It as RUNNER_RSS_BUDGET_ENV, J as UdsLocalTransportServer, Jt as startHeapWatch, K as createLocalTransport, Kt as reclaimIntervalMs, L as LocalChildRegistry, Lt as ZERO_LOOP_DELAY, M as createUdsEventBus, Mt as HUB_RSS_BUDGET_ENV, N as udsChildLogToWorkerEntry, Nt as RSS_BUDGET_REANNOUNCE_MIN_MS, O as HUB_CAP_FWD_SERVICE, Ot as HEAP_WATCH_INTERVAL_MS, P as createUdsLogger, Pt as RSS_BUDGET_RELEASE_RATIO, Q as encodeFrame, Qt as HEAP_SPACE_REPORT_MIN_MB, R as UDS_NO_ROUTE_PREFIX, Rt as buildHeapSample, S as brokerCallForCap, Sn as formatEventPlane, St as resolveNpmInvocation, T as ipcParentLink, Tt as HEAP_RECLAIM_MIN_INTERVAL_MS, U as classifyCapRoute, Ut as hubMainRssBudget, V as CapRouteResolver, Vt as createV8Reclaimer, W as callWithServiceDiscovery, Wt as nextRssBudgetState, X as localEndpointPath, Xt as strandedMb, Y as SocketChannel, Yt as startRunnerHeapWatch, Z as FrameDecoder, Zt as DECISIVE_HEAP_SPACES, _ as createKernelHwAccel, _n as socketDirectionMessages, _t as CapabilityHandle, a as getWorkerDeviceRegistry, an as selectReportedSpaces, b as __resetCapUsageRegistryForTests, bn as createEventPlaneReader, bt as installManifestNativeDeps, c as setHubConnected, cn as createSocketPlaneMeter, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dn as formatSocketPlane, dt as capBareAction, en as emitHeapDiagnosticReport, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, fn as EMPTY_SOCKET_DIRECTION, ft as capServiceName, g as AddonDepsManager, gn as socketDirectionBytes, gt as DeviceRegistry, h as subscribePassthrough, hn as sampleSocketDirection, ht as serializeTypedArrays, i as createUdsAddonContext, in as readHeapSpaces, it as mountNativeCapService, j as createUdsEventBridge, jt as HUB_MAIN_RSS_BUDGET_MB, k as createHubCapForwardService, kt as HEAP_WATCH_WARN_RATIO, l as EVENT_TOPIC_PREFIX, ln as createSocketPlaneReader, lt as capActionName, m as setNodeEventInterest, mn as recordSocketFrame, mt as deserializeTypedArrays, n as adaptBrokerToCluster, nn as heapSnapshotAuthorised, o as getOrInitReadinessRegistry, on as EMPTY_SOCKET_PLANE_BASELINE, ot as createAddonService, p as registerEventBusService, pn as createSocketDirectionCounters, pt as parseCapAction, q as UdsLocalTransportClient, qt as shouldReclaim, r as createAddonContext, rn as heapSpaceField, s as getOrInitReadinessRegistryForClient, sn as SOCKET_PLANE_TOP_N, st as validateProviderRegistrations, t as installManifestPythonDeps, tn as formatHeapSpaces, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, un as diffSocketPlane, ut as capActionSuffix, v as resolveHwAccel, vn as EVENT_PLANE_TOP_N, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xn as diffEventPlane, xt as resolveAddonClass, y as CapUsageRegistry, yn as createEventPlaneMeter, yt as copyBundledNativeModules, z as AGENT_CAP_FWD_ACTION, zt as createDeferredHeapWatchSink } from "./manifest-python-deps-CD14Pv0-.mjs";
28
+ import { $ as encodeFrame, $t as HEAP_SPACE_REPORT_MIN_MB, A as createHubCapForwardService, At as HEAP_WATCH_WARN_RATIO, B as AGENT_CAP_FWD_ACTION, Bt as createDeferredHeapWatchSink, C as brokerCallForCap, Cn as formatEventPlane, Ct as resolveNpmInvocation, D as localProviderLink, Dt as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, E as ipcParentLink, Et as HEAP_RECLAIM_MIN_INTERVAL_MS, F as createUdsLogger, Ft as RSS_BUDGET_RELEASE_RATIO, G as callWithServiceDiscovery, Gt as nextRssBudgetState, H as CapRouteResolver, Ht as createV8Reclaimer, I as createUdsLoggerWithControl, It as RUNNER_HEAP_WATCH_INTERVAL_MS, J as UdsLocalTransportClient, Jt as shouldReclaim, K as readMoleculerFanoutMode, Kt as parseRssBudgetMb, L as LocalChildClient, Lt as RUNNER_RSS_BUDGET_ENV, M as createUdsEventBridge, Mt as HUB_MAIN_RSS_BUDGET_MB, N as createUdsEventBus, Nt as HUB_RSS_BUDGET_ENV, O as HUB_CAP_FWD_ACTION, Ot as HEAP_RECLAIM_TRIGGER_MB, P as udsChildLogToWorkerEntry, Pt as RSS_BUDGET_REANNOUNCE_MIN_MS, Q as FrameDecoder, Qt as DECISIVE_HEAP_SPACES, R as LocalChildRegistry, Rt as ZERO_LOOP_DELAY, S as getCapUsageRegistry, Sn as diffEventPlane, St as resolveAddonClass, T as buildLinkChain, Tt as createAddonDataPlaneFacility, U as CapRouteError, Ut as describeRss, V as AGENT_CAP_FWD_SERVICE, Vt as createLoopDelayMeter, W as classifyCapRoute, Wt as hubMainRssBudget, X as SocketChannel, Xt as startRunnerHeapWatch, Y as UdsLocalTransportServer, Yt as startHeapWatch, Z as localEndpointPath, Zt as strandedMb, _ as AddonDepsManager, _n as socketDirectionBytes, _t as DeviceRegistry, a as createUdsAddonContext, an as readHeapSpaces, at as mountNativeCapService, b as CapUsageRegistry, bn as createEventPlaneMeter, bt as copyBundledNativeModules, c as getOrInitReadinessRegistryForClient, cn as SOCKET_PLANE_TOP_N, ct as validateProviderRegistrations, d as clusterEventTopic, dn as diffSocketPlane, dt as capActionSuffix, en as RUNNER_HEAP_SNAPSHOT_ENV, et as buildNativeCapProxy, f as getBrokerEventBus, fn as formatSocketPlane, ft as capBareAction, g as subscribePassthrough, gn as sampleSocketDirection, gt as serializeTypedArrays, h as setNodeEventInterest, hn as recordSocketFrame, ht as deserializeTypedArrays, i as createAddonContext, in as heapSpaceField, j as createParentUnownedCallHandler, jt as HUB_MAIN_HEAP_WATCH_LABEL, k as HUB_CAP_FWD_SERVICE, kt as HEAP_WATCH_INTERVAL_MS, l as setHubConnected, ln as createSocketPlaneMeter, lt as NATIVE_PROVIDER_SERVICE_INFIX, m as registerEventBusService, mn as createSocketDirectionCounters, mt as parseCapAction, n as installManifestPythonDeps, nn as formatHeapSpaces, nt as createBrokerDeviceManagerApi, o as getWorkerDeviceRegistry, on as selectReportedSpaces, p as getMoleculerEventStats, pn as EMPTY_SOCKET_DIRECTION, pt as capServiceName, q as createLocalTransport, qt as reclaimIntervalMs, r as adaptBrokerToCluster, rn as heapSnapshotAuthorised, s as getOrInitReadinessRegistry, sn as EMPTY_SOCKET_PLANE_BASELINE, st as createAddonService, t as installManifestSystemDeps, tn as emitHeapDiagnosticReport, tt as buildUdsNativeCapProxy, u as EVENT_TOPIC_PREFIX, un as createSocketPlaneReader, ut as capActionName, v as createKernelHwAccel, vn as socketDirectionMessages, vt as CapabilityHandle, w as brokerTransportLink, wt as runNpm, x as __resetCapUsageRegistryForTests, xn as createEventPlaneReader, xt as installManifestNativeDeps, y as resolveHwAccel, yn as EVENT_PLANE_TOP_N, yt as CapabilityUnavailableError, z as UDS_NO_ROUTE_PREFIX, zt as buildHeapSample } from "./manifest-system-deps-tZZYG3RR.mjs";
29
29
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BWmQ5i-o.mjs";
30
30
  import { t as CustomActionRegistry } from "./custom-action-registry-F__gp_VX.mjs";
31
31
  import { z } from "zod";
@@ -9605,20 +9605,63 @@ var ConfigManager = class ConfigManager {
9605
9605
  if (this.settingsStore === null) return;
9606
9606
  this.settingsStore.clearDeviceRuntimeState(deviceId);
9607
9607
  }
9608
+ /**
9609
+ * The addon's `ctx.settings`.
9610
+ *
9611
+ * The backend is chosen on EVERY call, never frozen when the view is built.
9612
+ * That is not a nicety: `settings-store` is owned by `storage-orchestrator`,
9613
+ * so the door is wired by `registerProvider` STRICTLY AFTER that addon's
9614
+ * context — and therefore its settings view — already exists. A view bound at
9615
+ * construction handed the door's own owner the sync-store backend, whose
9616
+ * writes throw for the whole life of the process once `sqlite-settings` runs
9617
+ * isolated (D181: no sync `ISettingsStore` reaches hub-main, only the async
9618
+ * door). Reads were worse than the writes: they answered `{}` in silence.
9619
+ * That is what made `storageMigration.start` fail on its first durable write
9620
+ * while every other addon's persistence worked. See D294.
9621
+ */
9608
9622
  createSettingsView(addonId) {
9609
- if (this.settingsStore === null && this.settingsDoor !== null) {
9623
+ const storeBacked = this.createStoreSettingsView(addonId);
9624
+ let doorBacked = null;
9625
+ let doorBackedSource = null;
9626
+ const active = () => {
9627
+ if (this.settingsStore !== null) return storeBacked;
9610
9628
  const door = this.settingsDoor;
9611
- return createDoorSettingsView(addonId, door, {
9612
- getSection: (section) => this.getSection(section),
9613
- setSection: async (section, patch) => {
9614
- for (const [key, value] of Object.entries(patch)) await door.set({
9615
- collection: "system-settings",
9616
- key: `${section}.${key}`,
9617
- value
9618
- });
9619
- }
9620
- });
9621
- }
9629
+ if (door === null) return storeBacked;
9630
+ if (doorBacked === null || doorBackedSource !== door) {
9631
+ doorBackedSource = door;
9632
+ doorBacked = this.createDoorBackedSettingsView(addonId, door);
9633
+ }
9634
+ return doorBacked;
9635
+ };
9636
+ return {
9637
+ readAddonStore: () => active().readAddonStore(),
9638
+ writeAddonStore: (patch) => active().writeAddonStore(patch),
9639
+ readDeviceStore: (deviceId) => active().readDeviceStore(deviceId),
9640
+ readDeviceStoreBatch: (deviceIds) => active().readDeviceStoreBatch(deviceIds),
9641
+ writeDeviceStore: (deviceId, patch) => active().writeDeviceStore(deviceId, patch),
9642
+ clearDeviceStore: (deviceId) => active().clearDeviceStore(deviceId),
9643
+ getSection: (section) => active().getSection(section),
9644
+ setSection: (section, patch) => active().setSection(section, patch),
9645
+ readDeviceRuntimeState: (deviceId) => active().readDeviceRuntimeState(deviceId),
9646
+ writeDeviceRuntimeState: (deviceId, data) => active().writeDeviceRuntimeState(deviceId, data),
9647
+ clearDeviceRuntimeState: (deviceId) => active().clearDeviceRuntimeState(deviceId)
9648
+ };
9649
+ }
9650
+ /** The async-door backend of {@link createSettingsView}. */
9651
+ createDoorBackedSettingsView(addonId, door) {
9652
+ return createDoorSettingsView(addonId, door, {
9653
+ getSection: (section) => this.getSection(section),
9654
+ setSection: async (section, patch) => {
9655
+ for (const [key, value] of Object.entries(patch)) await door.set({
9656
+ collection: "system-settings",
9657
+ key: `${section}.${key}`,
9658
+ value
9659
+ });
9660
+ }
9661
+ });
9662
+ }
9663
+ /** The sync-`ISettingsStore` backend of {@link createSettingsView}. */
9664
+ createStoreSettingsView(addonId) {
9622
9665
  const cm = this;
9623
9666
  return {
9624
9667
  async readAddonStore() {
@@ -9634,6 +9677,15 @@ var ConfigManager = class ConfigManager {
9634
9677
  async readDeviceStore(deviceId) {
9635
9678
  return cm.getAddonDevice(addonId, String(deviceId));
9636
9679
  },
9680
+ async readDeviceStoreBatch(deviceIds) {
9681
+ const out = /* @__PURE__ */ new Map();
9682
+ for (const deviceId of deviceIds) try {
9683
+ out.set(deviceId, cm.getAddonDevice(addonId, String(deviceId)));
9684
+ } catch {
9685
+ out.set(deviceId, {});
9686
+ }
9687
+ return out;
9688
+ },
9637
9689
  async writeDeviceStore(deviceId, patch) {
9638
9690
  const key = String(deviceId);
9639
9691
  const existing = cm.getAddonDevice(addonId, key);
@@ -95283,4 +95335,4 @@ var LifecycleJobEngine = class {
95283
95335
  }
95284
95336
  };
95285
95337
  //#endregion
95286
- export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, 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, 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_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, 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_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_SNAPSHOT_ENV, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatEventPlane, formatHeapSpaces, formatLogLine, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSnapshotAuthorised, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
95338
+ export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, 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, 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_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, 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_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_SNAPSHOT_ENV, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatEventPlane, formatHeapSpaces, formatLogLine, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSnapshotAuthorised, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -31,6 +31,19 @@ export interface AddonSettingsView {
31
31
  writeDeviceRuntimeState(deviceId: number, data: Record<string, unknown>): Promise<void>;
32
32
  clearDeviceRuntimeState(deviceId: number): Promise<void>;
33
33
  }
34
+ /**
35
+ * A CONCRETE backend behind {@link ConfigManager.createSettingsView} — the
36
+ * sync-`ISettingsStore` one or the async-door one.
37
+ *
38
+ * `readDeviceStoreBatch` is required here and optional on
39
+ * {@link AddonSettingsView} because both of these can answer it, so the view
40
+ * the kernel hands an addon never has to decide whether the method exists.
41
+ * The optionality on the public interface stays for the implementation that
42
+ * genuinely cannot batch: a forked runner's UDS-backed view.
43
+ */
44
+ export interface SettingsViewBackend extends AddonSettingsView {
45
+ readDeviceStoreBatch(deviceIds: readonly number[]): Promise<ReadonlyMap<number, Record<string, unknown>>>;
46
+ }
34
47
  export interface ISettingsStore {
35
48
  getSystem(key: string): unknown;
36
49
  setSystem(key: string, value: unknown): void;
@@ -181,7 +194,25 @@ export declare class ConfigManager {
181
194
  setDeviceRuntimeState(deviceId: string, blob: Record<string, unknown>): void;
182
195
  /** Forget the device's runtime state. No-op before the store is wired. */
183
196
  clearDeviceRuntimeState(deviceId: string): void;
197
+ /**
198
+ * The addon's `ctx.settings`.
199
+ *
200
+ * The backend is chosen on EVERY call, never frozen when the view is built.
201
+ * That is not a nicety: `settings-store` is owned by `storage-orchestrator`,
202
+ * so the door is wired by `registerProvider` STRICTLY AFTER that addon's
203
+ * context — and therefore its settings view — already exists. A view bound at
204
+ * construction handed the door's own owner the sync-store backend, whose
205
+ * writes throw for the whole life of the process once `sqlite-settings` runs
206
+ * isolated (D181: no sync `ISettingsStore` reaches hub-main, only the async
207
+ * door). Reads were worse than the writes: they answered `{}` in silence.
208
+ * That is what made `storageMigration.start` fail on its first durable write
209
+ * while every other addon's persistence worked. See D294.
210
+ */
184
211
  createSettingsView(addonId: string): AddonSettingsView;
212
+ /** The async-door backend of {@link createSettingsView}. */
213
+ private createDoorBackedSettingsView;
214
+ /** The sync-`ISettingsStore` backend of {@link createSettingsView}. */
215
+ private createStoreSettingsView;
185
216
  /** Get all system-wide activation overrides. */
186
217
  getSystemActivation(): Readonly<Record<string, boolean>>;
187
218
  /** Set system-wide activation for a capability/addon pair. */
@@ -0,0 +1,15 @@
1
+ import { AddonDeclaration, IScopedLogger } from '@camstack/types';
2
+ /** Host package managers this mechanism knows how to drive. */
3
+ export type SystemPackageManager = 'apt' | 'apk' | 'dnf' | 'brew';
4
+ /** Test seams — production callers omit these. */
5
+ export interface InstallManifestSystemDepsOptions {
6
+ readonly hasBinary?: (binary: string) => Promise<boolean>;
7
+ readonly detectManager?: () => Promise<SystemPackageManager | null>;
8
+ readonly run?: (command: string, args: readonly string[]) => Promise<void>;
9
+ readonly platform?: NodeJS.Platform;
10
+ }
11
+ /**
12
+ * Satisfy every `systemDependencies` entry the declaration carries.
13
+ * Resolves regardless of outcome — see the docblock.
14
+ */
15
+ export declare function installManifestSystemDeps(declaration: AddonDeclaration, logger: IScopedLogger, options?: InstallManifestSystemDepsOptions): Promise<void>;
@@ -60,6 +60,8 @@ export type { StreamProbeBrokerDeps } from './moleculer/stream-probe-service.js'
60
60
  export { resolveHwAccel, createKernelHwAccel } from './hwaccel/hwaccel-resolver.js';
61
61
  export { AddonDepsManager } from './deps/addon-deps-manager.js';
62
62
  export { installManifestPythonDeps } from './deps/manifest-python-deps.js';
63
+ export { installManifestSystemDeps } from './deps/manifest-system-deps.js';
64
+ export type { InstallManifestSystemDepsOptions, SystemPackageManager, } from './deps/manifest-system-deps.js';
63
65
  export { installManifestNativeDeps } from './deps/manifest-native-deps.js';
64
66
  export { AddonHealthMonitor, HEALTH_MONITOR_TICK_MS, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, } from './addon-health-monitor.js';
65
67
  export type { AddonHealthPhase, AddonHealthState, AddonHealthSnapshot, AddonHealthMonitorOptions, } from './addon-health-monitor.js';
@@ -1,7 +1,7 @@
1
1
  import { ISettingsStoreProvider } from '@camstack/types';
2
- import { AddonSettingsView } from './config-manager.js';
2
+ import { SettingsViewBackend } from './config-manager.js';
3
3
  export interface DoorSectionAccess {
4
4
  getSection(section: string): Record<string, unknown>;
5
5
  setSection(section: string, patch: Record<string, unknown>): void | Promise<void>;
6
6
  }
7
- export declare function createDoorSettingsView(addonId: string, door: ISettingsStoreProvider, sections: DoorSectionAccess): AddonSettingsView;
7
+ export declare function createDoorSettingsView(addonId: string, door: ISettingsStoreProvider, sections: DoorSectionAccess): SettingsViewBackend;
@@ -1,4 +1,4 @@
1
- import { StorageLocationDeclaration } from '@camstack/types';
1
+ import { StorageAccess, StorageLocationDeclaration } from '@camstack/types';
2
2
  /**
3
3
  * Read-only view over all aggregated storage-location declarations.
4
4
  *
@@ -15,6 +15,15 @@ export interface StorageLocationRegistry {
15
15
  * Convenience shortcut over `get(id)?.cardinality`.
16
16
  */
17
17
  cardinalityOf(id: string): 'single' | 'multi' | null;
18
+ /**
19
+ * The declared {@link StorageAccess} of `id`, or `null` when no addon
20
+ * declared it. An UNDECLARED `access` on a DECLARED id resolves to
21
+ * `STORAGE_ACCESS_FALLBACK` (`'local-path'`) — fail-closed, so a kind that
22
+ * says nothing is treated as doing raw filesystem I/O and refuses a remote
23
+ * provider. `null` is reserved for "nobody declared this id at all", which
24
+ * callers treat separately.
25
+ */
26
+ accessOf(id: string): StorageAccess | null;
18
27
  /**
19
28
  * Stable, immutable list of all aggregated declarations (insertion order of
20
29
  * first occurrence per `id`).
@@ -33,6 +42,12 @@ export interface StorageLocationRegistry {
33
42
  * - **Cardinality conflict throws**: if two addons declare the same `id` with
34
43
  * different `cardinality` values an `Error` is thrown immediately (message
35
44
  * contains the words "cardinality" and the conflicting `id`).
45
+ * - **Access conflict throws**, for the same reason and more sharply: the
46
+ * EFFECTIVE access (declared, else `STORAGE_ACCESS_FALLBACK`) must agree.
47
+ * "First declarer wins" is the right rule for a display name and a
48
+ * catastrophic one for a safety constraint — it would let a second addon
49
+ * silently widen a kind that the first one restricted, which is exactly the
50
+ * accident this constraint exists to make impossible.
36
51
  *
37
52
  * @param perAddon - One entry per addon; each entry is that addon's
38
53
  * `storageLocations` declaration array.
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- require("./dist-CDgIzo82.js");
2
+ require("./dist-Ck2jkBZk.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  node_crypto = require_chunk.__toESM(node_crypto);
5
5
  let _camstack_types_node = require("@camstack/types/node");
@@ -1607,7 +1607,7 @@ function createAddonDataPlaneFacility(args) {
1607
1607
  * Failures THROW with an actionable message — a caller must never proceed as
1608
1608
  * if dependencies were installed when they were not.
1609
1609
  */
1610
- var execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
1610
+ var execFileAsync$2 = (0, node_util.promisify)(node_child_process.execFile);
1611
1611
  var DEFAULT_REGISTRY = "https://registry.npmjs.org";
1612
1612
  /** Where the bootstrap lands inside `cacheDir` (npm tgz carries a `package/` prefix). */
1613
1613
  function bootstrappedCliPath(cacheDir) {
@@ -1615,7 +1615,7 @@ function bootstrappedCliPath(cacheDir) {
1615
1615
  }
1616
1616
  async function defaultProbeSystemNpm() {
1617
1617
  try {
1618
- await execFileAsync$1("npm", ["--version"], { timeout: 15e3 });
1618
+ await execFileAsync$2("npm", ["--version"], { timeout: 15e3 });
1619
1619
  return true;
1620
1620
  } catch {
1621
1621
  return false;
@@ -1633,7 +1633,7 @@ async function defaultDownloadTarball(url, destTgz) {
1633
1633
  await node_fs.promises.writeFile(destTgz, bytes);
1634
1634
  }
1635
1635
  async function defaultExtractTarball(tgzPath, destDir) {
1636
- await execFileAsync$1("tar", [
1636
+ await execFileAsync$2("tar", [
1637
1637
  "-xzf",
1638
1638
  tgzPath,
1639
1639
  "-C",
@@ -1672,7 +1672,7 @@ async function runNpm(args, options) {
1672
1672
  registry: options.registry,
1673
1673
  logger: options.logger
1674
1674
  });
1675
- return execFileAsync$1(invocation.command, [...invocation.argsPrefix, ...args], {
1675
+ return execFileAsync$2(invocation.command, [...invocation.argsPrefix, ...args], {
1676
1676
  ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
1677
1677
  timeout: options.timeout ?? 3e5
1678
1678
  });
@@ -1752,7 +1752,7 @@ function resolveAddonClass(mod) {
1752
1752
  }
1753
1753
  //#endregion
1754
1754
  //#region src/kernel/deps/manifest-native-deps.ts
1755
- var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
1755
+ var execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
1756
1756
  /**
1757
1757
  * Fallback bootstrap-cache location when the caller doesn't thread one
1758
1758
  * through (the forked addon-runner's spawn-time install). tmpdir survives the
@@ -2061,7 +2061,7 @@ async function rebuildNativeDeps(addonDir, packageNames, logger, npmCacheDir, re
2061
2061
  return;
2062
2062
  }
2063
2063
  logger.warn("@electron/rebuild not available — falling back to npx", { meta: { addonDir } });
2064
- await execFileAsync("npx", [
2064
+ await execFileAsync$1("npx", [
2065
2065
  "--yes",
2066
2066
  "electron-rebuild",
2067
2067
  "-m",
@@ -9504,6 +9504,195 @@ async function installManifestPythonDeps(declaration, addonDir, deps, logger) {
9504
9504
  await deps.installPythonRequirements(reqAbs);
9505
9505
  }
9506
9506
  //#endregion
9507
+ //#region src/kernel/deps/manifest-system-deps.ts
9508
+ /**
9509
+ * Auto-install the host binaries declared in an addon's manifest
9510
+ * (`camstack.addons[].systemDependencies`) before `onInitialize()` runs.
9511
+ *
9512
+ * ── Why this is framework and not addon-local ──────────────────────────────
9513
+ * The Python precedent (`camstack.addons[].python.requirements` →
9514
+ * `installManifestPythonDeps`, called from the same place in
9515
+ * `addon-runner.ts`) already answers "this addon needs something installed,
9516
+ * satisfy it before its caps register". A binary is the same question with a
9517
+ * different package manager, so it gets the same mechanism rather than a
9518
+ * second one per addon — CLAUDE.md forbids a parallel answer where one exists,
9519
+ * and the next addon that needs `rclone` or `mediainfo` inherits this for
9520
+ * free instead of copying a startup routine.
9521
+ *
9522
+ * ── The four things this has to get right ──────────────────────────────────
9523
+ * 1. **Cheap on the common path.** The binary is probed first; the package
9524
+ * manager is only invoked when it is genuinely absent. Runners respawn
9525
+ * routinely (deploys, updates, crash recovery) and a network round-trip on
9526
+ * every boot is a cost the Python mechanism does not impose either.
9527
+ * 2. **Runs every boot, not once.** The install lands INSIDE the container
9528
+ * and is lost on every image update. That is expected. "Already
9529
+ * installed" is a success, not an error.
9530
+ * 3. **Honest, not fatal.** A failure warns and returns. The addon still
9531
+ * loads; the capability that wraps the binary is responsible for refusing
9532
+ * loudly on its own surface. Aborting the runner here would take the
9533
+ * addon's SIBLINGS down with it (they share `execution.group`).
9534
+ * 4. **Platform reality is stated, not assumed.** An unsupported host logs
9535
+ * which manager it looked for and continues. Silence would read as
9536
+ * "installed".
9537
+ *
9538
+ * Every branch that declines to install SAYS SO. A dependency step that
9539
+ * produced no line at all is indistinguishable from one that never ran, and
9540
+ * the failure it precedes ("smbclient: ENOENT") arrives minutes later in a
9541
+ * different addon's logs.
9542
+ */
9543
+ var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
9544
+ /** How long a single package-manager invocation may take. */
9545
+ var INSTALL_TIMEOUT_MS = 300 * 1e3;
9546
+ /** How long the `command -v <binary>` presence probe may take. */
9547
+ var PROBE_TIMEOUT_MS = 1e4;
9548
+ /**
9549
+ * Satisfy every `systemDependencies` entry the declaration carries.
9550
+ * Resolves regardless of outcome — see the docblock.
9551
+ */
9552
+ async function installManifestSystemDeps(declaration, logger, options = {}) {
9553
+ const deps = declaration.systemDependencies;
9554
+ if (!deps || deps.length === 0) return;
9555
+ const hasBinary = options.hasBinary ?? defaultHasBinary;
9556
+ const detectManager = options.detectManager ?? defaultDetectManager;
9557
+ const run = options.run ?? defaultRun;
9558
+ const platform = options.platform ?? process.platform;
9559
+ for (const dep of deps) try {
9560
+ await satisfyOne(dep, declaration.id, {
9561
+ hasBinary,
9562
+ detectManager,
9563
+ run,
9564
+ platform
9565
+ }, logger);
9566
+ } catch (err) {
9567
+ logger.warn("system dependency step failed", { meta: {
9568
+ addonId: declaration.id,
9569
+ binary: dep.binary,
9570
+ error: err instanceof Error ? err.message : String(err)
9571
+ } });
9572
+ }
9573
+ }
9574
+ async function satisfyOne(dep, addonId, rt, logger) {
9575
+ if (await rt.hasBinary(dep.binary)) {
9576
+ logger.debug("system dependency already present", { meta: {
9577
+ addonId,
9578
+ binary: dep.binary
9579
+ } });
9580
+ return;
9581
+ }
9582
+ const manager = await rt.detectManager();
9583
+ if (manager === null) {
9584
+ logger.warn("system dependency missing and no supported package manager on this host", { meta: {
9585
+ addonId,
9586
+ binary: dep.binary,
9587
+ platform: rt.platform,
9588
+ ...dep.reason !== void 0 ? { reason: dep.reason } : {}
9589
+ } });
9590
+ return;
9591
+ }
9592
+ const packageName = dep.packages[manager];
9593
+ if (packageName === void 0 || packageName.length === 0) {
9594
+ logger.warn("system dependency missing and the addon declares no package for this manager", { meta: {
9595
+ addonId,
9596
+ binary: dep.binary,
9597
+ manager,
9598
+ ...dep.reason !== void 0 ? { reason: dep.reason } : {}
9599
+ } });
9600
+ return;
9601
+ }
9602
+ const plan = planFor(manager, packageName);
9603
+ logger.info("installing system dependency", { meta: {
9604
+ addonId,
9605
+ binary: dep.binary,
9606
+ manager,
9607
+ package: packageName
9608
+ } });
9609
+ try {
9610
+ for (const [command, args] of plan.steps) await rt.run(command, args);
9611
+ } catch (err) {
9612
+ logger.warn("system dependency install failed — the addon loads, its capability must refuse", { meta: {
9613
+ addonId,
9614
+ binary: dep.binary,
9615
+ manager,
9616
+ package: packageName,
9617
+ error: err instanceof Error ? err.message : String(err),
9618
+ ...dep.reason !== void 0 ? { reason: dep.reason } : {}
9619
+ } });
9620
+ return;
9621
+ }
9622
+ if (!await rt.hasBinary(dep.binary)) {
9623
+ logger.warn("system dependency installed but the binary still does not resolve", { meta: {
9624
+ addonId,
9625
+ binary: dep.binary,
9626
+ manager,
9627
+ package: packageName
9628
+ } });
9629
+ return;
9630
+ }
9631
+ logger.info("system dependency installed", { meta: {
9632
+ addonId,
9633
+ binary: dep.binary,
9634
+ manager,
9635
+ package: packageName
9636
+ } });
9637
+ }
9638
+ function planFor(manager, packageName) {
9639
+ switch (manager) {
9640
+ case "apt": return {
9641
+ manager,
9642
+ steps: [["apt-get", ["update"]], ["apt-get", [
9643
+ "install",
9644
+ "-y",
9645
+ "--no-install-recommends",
9646
+ packageName
9647
+ ]]]
9648
+ };
9649
+ case "apk": return {
9650
+ manager,
9651
+ steps: [["apk", [
9652
+ "add",
9653
+ "--no-cache",
9654
+ packageName
9655
+ ]]]
9656
+ };
9657
+ case "dnf": return {
9658
+ manager,
9659
+ steps: [["dnf", [
9660
+ "install",
9661
+ "-y",
9662
+ packageName
9663
+ ]]]
9664
+ };
9665
+ case "brew": return {
9666
+ manager,
9667
+ steps: [["brew", ["install", packageName]]]
9668
+ };
9669
+ }
9670
+ }
9671
+ async function defaultHasBinary(binary) {
9672
+ try {
9673
+ await execFileAsync("command", ["-v", binary], {
9674
+ timeout: PROBE_TIMEOUT_MS,
9675
+ shell: process.platform === "win32" ? false : "/bin/sh"
9676
+ });
9677
+ return true;
9678
+ } catch {
9679
+ return false;
9680
+ }
9681
+ }
9682
+ async function defaultDetectManager() {
9683
+ const candidates = node_os.platform() === "darwin" ? ["brew"] : [
9684
+ "apt",
9685
+ "apk",
9686
+ "dnf",
9687
+ "brew"
9688
+ ];
9689
+ for (const candidate of candidates) if (await defaultHasBinary(candidate === "apt" ? "apt-get" : candidate)) return candidate;
9690
+ return null;
9691
+ }
9692
+ async function defaultRun(command, args) {
9693
+ await execFileAsync(command, [...args], { timeout: INSTALL_TIMEOUT_MS });
9694
+ }
9695
+ //#endregion
9507
9696
  Object.defineProperty(exports, "AGENT_CAP_FWD_ACTION", {
9508
9697
  enumerable: true,
9509
9698
  get: function() {
@@ -10098,6 +10287,12 @@ Object.defineProperty(exports, "installManifestPythonDeps", {
10098
10287
  return installManifestPythonDeps;
10099
10288
  }
10100
10289
  });
10290
+ Object.defineProperty(exports, "installManifestSystemDeps", {
10291
+ enumerable: true,
10292
+ get: function() {
10293
+ return installManifestSystemDeps;
10294
+ }
10295
+ });
10101
10296
  Object.defineProperty(exports, "ipcParentLink", {
10102
10297
  enumerable: true,
10103
10298
  get: function() {