@camstack/system 1.2.313 → 1.2.315

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 (111) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -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/autotrack/index.js +1 -1
  10. package/dist/builtins/autotrack/index.mjs +1 -1
  11. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  13. package/dist/builtins/camera-grid/index.js +1 -1
  14. package/dist/builtins/camera-grid/index.mjs +1 -1
  15. package/dist/builtins/composer/claim-gate.d.ts +32 -0
  16. package/dist/builtins/composer/composed-device-set.d.ts +38 -0
  17. package/dist/builtins/composer/composed-device.d.ts +4 -3
  18. package/dist/builtins/composer/composer-grafts.d.ts +54 -0
  19. package/dist/builtins/composer/composer-plan.d.ts +96 -0
  20. package/dist/builtins/composer/composer-verdict.d.ts +19 -0
  21. package/dist/builtins/composer/composer.addon.js +2717 -477
  22. package/dist/builtins/composer/composer.addon.mjs +2722 -482
  23. package/dist/builtins/composer/composer.d.ts +71 -52
  24. package/dist/builtins/composer/composition-runtime.d.ts +93 -9
  25. package/dist/builtins/composer/confirmed-seed.d.ts +32 -0
  26. package/dist/builtins/composer/existing-target.d.ts +96 -0
  27. package/dist/builtins/composer/field-record.d.ts +50 -0
  28. package/dist/builtins/composer/graft-host.d.ts +47 -0
  29. package/dist/builtins/composer/held-claims.d.ts +12 -0
  30. package/dist/builtins/composer/owned-fields-target.d.ts +55 -0
  31. package/dist/builtins/composer/slice-assembler.d.ts +10 -0
  32. package/dist/builtins/composer/source-readings.d.ts +122 -0
  33. package/dist/builtins/composer/source-tracker.d.ts +35 -42
  34. package/dist/builtins/console-logging/index.js +1 -1
  35. package/dist/builtins/console-logging/index.mjs +1 -1
  36. package/dist/builtins/core-blocks/composition-api.d.ts +7 -4
  37. package/dist/builtins/core-blocks/composition-peers.d.ts +9 -0
  38. package/dist/builtins/core-blocks/composition-sources.d.ts +16 -3
  39. package/dist/builtins/core-blocks/core-block-store.d.ts +8 -1
  40. package/dist/builtins/core-blocks/core-blocks.addon.d.ts +4 -3
  41. package/dist/builtins/core-blocks/core-blocks.addon.js +255 -79
  42. package/dist/builtins/core-blocks/core-blocks.addon.mjs +255 -79
  43. package/dist/builtins/device-manager/claimed-status-overlay.d.ts +12 -0
  44. package/dist/builtins/device-manager/device-manager.addon.d.ts +16 -0
  45. package/dist/builtins/device-manager/device-manager.addon.js +1825 -317
  46. package/dist/builtins/device-manager/device-manager.addon.mjs +1825 -317
  47. package/dist/builtins/device-manager/device-provider-context.d.ts +24 -2
  48. package/dist/builtins/device-manager/device-row-store.d.ts +2 -0
  49. package/dist/builtins/device-manager/device-state-claim-views.d.ts +77 -0
  50. package/dist/builtins/device-manager/device-state-claims.d.ts +43 -0
  51. package/dist/builtins/device-manager/device-state-mirror.d.ts +145 -61
  52. package/dist/builtins/device-manager/field-claims-index.d.ts +69 -0
  53. package/dist/builtins/device-manager/field-ownership.d.ts +53 -0
  54. package/dist/builtins/device-manager/migrate-device.d.ts +27 -0
  55. package/dist/builtins/device-manager/migrate-guard.d.ts +7 -0
  56. package/dist/builtins/device-manager/migrate-hardware-state.d.ts +55 -0
  57. package/dist/builtins/device-manager/migration-refused.d.ts +23 -0
  58. package/dist/builtins/device-manager/mirror-row-writer.d.ts +138 -0
  59. package/dist/builtins/device-manager/runtime-state-persist-gate.d.ts +4 -0
  60. package/dist/builtins/doorbell/binding-mirror.d.ts +1 -0
  61. package/dist/builtins/doorbell/doorbell-composition-migration.d.ts +59 -0
  62. package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +3 -0
  63. package/dist/builtins/doorbell/virtual-doorbell.addon.js +315 -10
  64. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +315 -10
  65. package/dist/builtins/hub-forwarder/index.js +1 -1
  66. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  67. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  68. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  69. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  70. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  71. package/dist/builtins/local-network/local-network.addon.js +1 -1
  72. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  73. package/dist/builtins/loki-logging/index.js +1 -1
  74. package/dist/builtins/loki-logging/index.mjs +1 -1
  75. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  76. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  77. package/dist/builtins/platform-probe/index.js +1 -1
  78. package/dist/builtins/platform-probe/index.mjs +1 -1
  79. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  80. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  81. package/dist/builtins/snapshot/index.js +1 -1
  82. package/dist/builtins/snapshot/index.mjs +1 -1
  83. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  84. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  85. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  86. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  87. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  88. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  89. package/dist/builtins/system-config/system-config.addon.js +1 -1
  90. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  91. package/dist/builtins/winston-logging/index.js +1 -1
  92. package/dist/builtins/winston-logging/index.mjs +1 -1
  93. package/dist/{child-cap-dispatch-CHTiHbsv.mjs → child-cap-dispatch-AAltfBUH.mjs} +1484 -1417
  94. package/dist/{child-cap-dispatch-Dyn_7ezH.js → child-cap-dispatch-DzcUd_ct.js} +1503 -1424
  95. package/dist/composition-sources-DYqQLRzF.js +122 -0
  96. package/dist/composition-sources-yonsRneP.mjs +111 -0
  97. package/dist/{dist-CkRwnhbo.js → dist-DVKv5i-e.js} +5396 -4331
  98. package/dist/{dist-Cj7pJmXq.mjs → dist-MzYJVCLE.mjs} +5330 -4331
  99. package/dist/index.js +137 -8
  100. package/dist/index.mjs +133 -8
  101. package/dist/kernel/capability-registry.d.ts +43 -1
  102. package/dist/kernel/index.d.ts +3 -1
  103. package/dist/kernel/moleculer/device-cap-proxy.d.ts +0 -10
  104. package/dist/kernel/status-overlay.d.ts +18 -0
  105. package/dist/kernel/transport/claimed-get-status.d.ts +15 -0
  106. package/dist/kernel/transport/index.d.ts +2 -0
  107. package/dist/kernel/transport/local-child-registry.d.ts +23 -0
  108. package/dist/kernel/transport/parent-unowned-call.d.ts +25 -0
  109. package/dist/{retired-settings-keys-C1duPikd.mjs → retired-settings-keys-8yY2sTc-.mjs} +1 -1
  110. package/dist/{retired-settings-keys-CGSuXhP8.js → retired-settings-keys-iY5I0nKM.js} +1 -1
  111. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-CkRwnhbo.js");
3
+ const require_dist = require("./dist-DVKv5i-e.js");
4
4
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
5
5
  require("./builtins/alerts/index.js");
6
6
  const require_builtins_composer_composer_addon = require("./builtins/composer/composer.addon.js");
@@ -29,7 +29,7 @@ require("./builtins/system-config/index.js");
29
29
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
30
30
  const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-ey4mbofz.js");
31
31
  const require_tls$1 = require("./tls-D_wUeOTD.js");
32
- const require_child_cap_dispatch = require("./child-cap-dispatch-Dyn_7ezH.js");
32
+ const require_child_cap_dispatch = require("./child-cap-dispatch-DzcUd_ct.js");
33
33
  const require_resource_monitor = require("./resource-monitor-DzNn_IZK.js");
34
34
  const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
35
35
  let zod = require("zod");
@@ -5853,6 +5853,36 @@ function scheduleSelfRestart(options = {}) {
5853
5853
  }, delayMs);
5854
5854
  }
5855
5855
  //#endregion
5856
+ //#region src/kernel/status-overlay.ts
5857
+ /** The answer for a device KNOWN to carry no claim — the old path, no overlay. */
5858
+ var UNCLAIMED = { kind: "unclaimed" };
5859
+ var GET_STATUS = "getStatus";
5860
+ /**
5861
+ * Wrap `provider` so that `getStatus` awaits the overlay, re-read at CALL time
5862
+ * (a claim released between resolve and call falls back to the native's own
5863
+ * `getStatus`; a device whose claims are not yet known has them resolved
5864
+ * first), and every other property is the provider's own.
5865
+ *
5866
+ * Other properties are read off the TARGET with the target as receiver, and a
5867
+ * function is bound to it: a class instance's methods then see their real
5868
+ * `this` — a Proxy as `this` would break `#private` fields and prototype
5869
+ * getters. The HA-shaped forwarding Proxy is unaffected either way.
5870
+ */
5871
+ function overlayGetStatus(provider, answer) {
5872
+ return new Proxy(provider, { get(target, prop) {
5873
+ if (prop === GET_STATUS) return async (...args) => {
5874
+ const current = await answer();
5875
+ if (current.kind === "claimed") return current.slice;
5876
+ if (current.kind === "unknown") return null;
5877
+ const native = Reflect.get(target, prop, target);
5878
+ if (typeof native !== "function") throw new Error("getStatus: the claim was released and the native provider implements no getStatus");
5879
+ return await native.apply(target, args);
5880
+ };
5881
+ const value = Reflect.get(target, prop, target);
5882
+ return typeof value === "function" ? value.bind(target) : value;
5883
+ } });
5884
+ }
5885
+ //#endregion
5856
5886
  //#region src/kernel/capability-registry.ts
5857
5887
  /**
5858
5888
  * Type-level bridge: the `providers` map stores heterogeneous capability
@@ -5865,6 +5895,19 @@ function scheduleSelfRestart(options = {}) {
5865
5895
  function asProvider(value) {
5866
5896
  return value;
5867
5897
  }
5898
+ /**
5899
+ * A parsed `status.schema` output is a record — every status schema is a
5900
+ * `z.object` (the `status` block's contract) — but `CapabilityStatusSchema`
5901
+ * types it as `ZodType<unknown>`, so the parsed value comes back `unknown`.
5902
+ * Narrowed structurally, never cast: a non-record output is answered `null`
5903
+ * ("not reported", D315), which is also what the aggregate does with it.
5904
+ */
5905
+ function asStatusSlice(parsed) {
5906
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
5907
+ const slice = {};
5908
+ for (const [key, value] of Object.entries(parsed)) slice[key] = value;
5909
+ return slice;
5910
+ }
5868
5911
  var CapabilityRegistry = class CapabilityRegistry {
5869
5912
  capabilities = /* @__PURE__ */ new Map();
5870
5913
  logger;
@@ -6354,13 +6397,95 @@ var CapabilityRegistry = class CapabilityRegistry {
6354
6397
  setNativeFallback(resolver) {
6355
6398
  this.nativeFallback = resolver;
6356
6399
  }
6357
- /** Resolve the native provider for `(capName, deviceId)` or null. */
6400
+ /**
6401
+ * Resolve the native provider for `(capName, deviceId)` or null. A CLAIMED
6402
+ * cap's provider is handed back with its `getStatus` overlaid (D663, S3) —
6403
+ * on the in-process branch AND the `nativeFallback` branch, which is the
6404
+ * path the HA feeder's devices take.
6405
+ */
6358
6406
  getNativeProvider(capName, deviceId) {
6359
6407
  const entry = this.nativeProviders.get(capName)?.get(deviceId);
6360
- if (entry) return entry.provider;
6361
- if (this.nativeFallback) return this.nativeFallback(capName, deviceId) ?? null;
6408
+ if (entry) return this.withOverlay(capName, deviceId, entry.provider);
6409
+ if (this.nativeFallback) {
6410
+ const fallback = this.nativeFallback(capName, deviceId);
6411
+ return this.withOverlay(capName, deviceId, fallback ?? null);
6412
+ }
6362
6413
  return null;
6363
6414
  }
6415
+ /** The device-manager's view over its mirror; `null` until installed. */
6416
+ statusOverlay = null;
6417
+ /** `(cap, device)` pairs whose merged slice currently fails its status schema — one warn per transition. */
6418
+ overlayParseFailing = /* @__PURE__ */ new Set();
6419
+ /**
6420
+ * Install (or remove, with `null`) the claimed-status overlay. Installed once
6421
+ * by the device-manager at init over its `DeviceStateMirror`; removed on its
6422
+ * shutdown. Wrappers already resolved re-read it at call time, so an
6423
+ * uninstall hands `getStatus` back to the native immediately.
6424
+ */
6425
+ setStatusOverlay(overlay) {
6426
+ this.statusOverlay = overlay;
6427
+ this.overlayParseFailing.clear();
6428
+ }
6429
+ /**
6430
+ * THE question every `getStatus` awaits before it is answered (the registry's
6431
+ * own wrappers at call time, and the three transport entries through
6432
+ * `answerClaimedGetStatus`). The overlay resolves the device's claims first;
6433
+ * `unknown` survives only when its row cannot be read, and the caller then
6434
+ * answers "not reported", never the native (D315, D49).
6435
+ *
6436
+ * A claimed slice is parsed with the cap's `status.schema` — S4 makes
6437
+ * `status ⊆ runtimeState`, so the merged runtime slice parses and a
6438
+ * runtime-only key such as `lastFetchedAt` is stripped. A slice that does not
6439
+ * parse is `null`, logged once per `(cap, device)` transition with the device
6440
+ * tag; a held claim is `null` without a parse. A cap with no `status` block
6441
+ * passes its merged slice through as is.
6442
+ */
6443
+ async resolveClaimedStatus(capName, deviceId) {
6444
+ if (this.statusOverlay === null) return UNCLAIMED;
6445
+ return this.parseClaimed(capName, deviceId, await this.statusOverlay.resolve(capName, deviceId));
6446
+ }
6447
+ parseClaimed(capName, deviceId, answer) {
6448
+ if (answer.kind !== "claimed" || answer.slice === null) return answer;
6449
+ const schema = this.getDefinition(capName)?.status?.schema;
6450
+ if (schema === void 0) return answer;
6451
+ const key = `${capName}:${deviceId}`;
6452
+ const parsed = schema.safeParse(answer.slice);
6453
+ if (parsed.success) {
6454
+ this.overlayParseFailing.delete(key);
6455
+ return {
6456
+ kind: "claimed",
6457
+ slice: asStatusSlice(parsed.data)
6458
+ };
6459
+ }
6460
+ if (!this.overlayParseFailing.has(key)) {
6461
+ this.overlayParseFailing.add(key);
6462
+ this.logger.warn("claimed cap: merged slice fails its status schema — answering null", {
6463
+ tags: { deviceId },
6464
+ meta: {
6465
+ capName,
6466
+ issues: parsed.error.issues.slice(0, 3)
6467
+ }
6468
+ });
6469
+ }
6470
+ return {
6471
+ kind: "claimed",
6472
+ slice: null
6473
+ };
6474
+ }
6475
+ /**
6476
+ * Hand `provider` back untouched when `(capName, deviceId)` is KNOWN to be
6477
+ * unclaimed; otherwise wrap it so `getStatus` awaits `resolveClaimedStatus`
6478
+ * (re-read at call time — the parse, and for an unknown device the row read,
6479
+ * happen only when `getStatus` is actually called) and everything else stays
6480
+ * the provider's own. An unclaimed device pays one in-memory lookup; with no
6481
+ * overlay installed it pays nothing.
6482
+ */
6483
+ withOverlay(capName, deviceId, provider) {
6484
+ if (this.statusOverlay === null) return provider;
6485
+ if (typeof provider !== "object" || provider === null) return provider;
6486
+ if (this.statusOverlay.peek(capName, deviceId).kind === "unclaimed") return provider;
6487
+ return overlayGetStatus(provider, () => this.resolveClaimedStatus(capName, deviceId));
6488
+ }
6364
6489
  /** Resolve the addonId that registered the native provider for `(capName, deviceId)`. */
6365
6490
  getNativeAddonId(capName, deviceId) {
6366
6491
  return this.nativeProviders.get(capName)?.get(deviceId)?.addonId ?? null;
@@ -6445,9 +6570,9 @@ var CapabilityRegistry = class CapabilityRegistry {
6445
6570
  if (native !== null) return native;
6446
6571
  const state = this.capabilities.get(capName);
6447
6572
  if (!state) return null;
6448
- if (state.definition.mode === "singleton") return this.resolveForDevice(capName, String(deviceId));
6573
+ if (state.definition.mode === "singleton") return this.withOverlay(capName, deviceId, this.resolveForDevice(capName, String(deviceId)));
6449
6574
  const first = state.providers.values().next();
6450
- return first.done ? null : asProvider(first.value);
6575
+ return first.done ? null : this.withOverlay(capName, deviceId, asProvider(first.value));
6451
6576
  }
6452
6577
  getAllProviders(capabilityName) {
6453
6578
  if (!this._ready) return [];
@@ -95987,6 +96112,7 @@ exports.FilesystemStorageAddon = require_builtins_sqlite_storage_filesystem_stor
95987
96112
  exports.FilesystemStorageProvider = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageProvider;
95988
96113
  exports.FrameDecoder = require_child_cap_dispatch.FrameDecoder;
95989
96114
  exports.FsStorageBackend = FsStorageBackend;
96115
+ exports.GET_STATUS_METHOD = require_child_cap_dispatch.GET_STATUS_METHOD;
95990
96116
  exports.HEALTH_MONITOR_GRACE_PERIOD_MS = HEALTH_MONITOR_GRACE_PERIOD_MS;
95991
96117
  exports.HEALTH_MONITOR_RETRY_INTERVALS_MS = HEALTH_MONITOR_RETRY_INTERVALS_MS;
95992
96118
  exports.HEALTH_MONITOR_TICK_MS = HEALTH_MONITOR_TICK_MS;
@@ -96076,6 +96202,7 @@ exports.SystemEventBus = SystemEventBus;
96076
96202
  exports.TRADITIONAL_NATIVE_PACKAGES = TRADITIONAL_NATIVE_PACKAGES;
96077
96203
  exports.ToastService = ToastService;
96078
96204
  exports.UDS_NO_ROUTE_PREFIX = require_child_cap_dispatch.UDS_NO_ROUTE_PREFIX;
96205
+ exports.UNCLAIMED = UNCLAIMED;
96079
96206
  exports.UdsLocalTransportClient = require_child_cap_dispatch.UdsLocalTransportClient;
96080
96207
  exports.UdsLocalTransportServer = require_child_cap_dispatch.UdsLocalTransportServer;
96081
96208
  exports.UserManager = require_builtins_local_auth_local_auth_addon.UserManager;
@@ -96087,6 +96214,7 @@ exports.__resetLoggingGateForTests = __resetLoggingGateForTests;
96087
96214
  exports.adaptBrokerToCluster = require_child_cap_dispatch.adaptBrokerToCluster;
96088
96215
  exports.addonSettingsCapability = require_dist.addonSettingsCapability;
96089
96216
  exports.allFamiliesListenHost = require_tls$1.allFamiliesListenHost;
96217
+ exports.answerClaimedGetStatus = require_child_cap_dispatch.answerClaimedGetStatus;
96090
96218
  exports.applyLanHttp = require_tls$1.applyLanHttp;
96091
96219
  exports.attributeStall = require_event_loop_stall_monitor.attributeStall;
96092
96220
  exports.bindPendingLanHttp = require_tls$1.bindPendingLanHttp;
@@ -96106,7 +96234,6 @@ exports.buildNativeCapProxy = require_child_cap_dispatch.buildNativeCapProxy;
96106
96234
  exports.buildNodeManifest = buildNodeManifest;
96107
96235
  exports.buildNpmChildEnv = require_child_cap_dispatch.buildNpmChildEnv;
96108
96236
  exports.buildStorageLocationRegistry = require_builtins_storage_orchestrator_storage_orchestrator_addon.buildStorageLocationRegistry;
96109
- exports.buildUdsNativeCapProxy = require_child_cap_dispatch.buildUdsNativeCapProxy;
96110
96237
  exports.builderMountedCapNames = builderMountedCapNames;
96111
96238
  exports.callRegisterNodeWithRetry = callRegisterNodeWithRetry;
96112
96239
  exports.callWithServiceDiscovery = require_child_cap_dispatch.callWithServiceDiscovery;
@@ -96171,6 +96298,7 @@ exports.describeProviderKindDrift = describeProviderKindDrift;
96171
96298
  exports.describeRss = require_child_cap_dispatch.describeRss;
96172
96299
  exports.detectWorkspacePackagesDir = detectWorkspacePackagesDir;
96173
96300
  exports.deviceCapResolverLink = require_child_cap_dispatch.deviceCapResolverLink;
96301
+ exports.deviceOfGetStatus = require_child_cap_dispatch.deviceOfGetStatus;
96174
96302
  exports.diffCapActionCensus = require_child_cap_dispatch.diffCapActionCensus;
96175
96303
  exports.diffEventPlane = require_child_cap_dispatch.diffEventPlane;
96176
96304
  exports.diffSocketPlane = require_child_cap_dispatch.diffSocketPlane;
@@ -96290,6 +96418,7 @@ exports.localEndpointPath = require_child_cap_dispatch.localEndpointPath;
96290
96418
  exports.localProviderLink = require_child_cap_dispatch.localProviderLink;
96291
96419
  exports.mountNativeCapService = require_child_cap_dispatch.mountNativeCapService;
96292
96420
  exports.nextRssBudgetState = require_child_cap_dispatch.nextRssBudgetState;
96421
+ exports.overlayGetStatus = overlayGetStatus;
96293
96422
  exports.parseCapAction = require_child_cap_dispatch.parseCapAction;
96294
96423
  exports.parseRangeHeader = require_event_loop_stall_monitor.parseRangeHeader;
96295
96424
  exports.parseRssBudgetMb = require_child_cap_dispatch.parseRssBudgetMb;
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 parseJsonUnknown, $t as objectInputDeclaresRequiredDeviceId, At as isArrayOutputSchema, Bt as lifecycleJobSchema, D as RUNTIME_DEFAULTS, Gn as emitDownForOwnedCaps, Gt as looseSchema, Hn as asNumber, It as isVoidInput, Lt as kebabToCamel, Mn as DATAPLANE_SECRET_HEADER$1, Nn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Nt as isObjectInput, Pn as DEVICE_STATUS_METHOD, Qn as parseJsonObject, Qt as objectInputDeclaresAddonId, Rn as ReadinessRegistry, S as METHOD_ACCESS_MAP, Tt as extractNestedAddonId, Un as asString$1, Vn as asJsonObject$1, Wn as createEvent, Wt as logLevelAtMost, cn as resolveMethodAuth, dn as scopesAllowDeviceCap, er as readinessKey, ir as EventCategory$1, jt as isCollectionArrayMethod, kn as errMsg$1, nr as scopeKey, qn as expandCapMethods, rn as procedureAuthKey, t as ALL_CAPABILITY_DEFINITIONS, tr as resolveCapMount, un as scopesAllowAddon, y as LOG_LEVEL_RANK, z as addonSettingsCapability, zn as ReadinessTimeoutError } from "./dist-Cj7pJmXq.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-MzYJVCLE.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";
@@ -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 CapUsageRegistry, $n as capActionLabel, $t as buildHeapSample, A as resolveHwAccel, An as createOutboundQueueGate, At as CapabilityUnavailableError, B as udsChildLogToWorkerEntry, Bn as diffSocketPlane, Bt as HEAP_RECLAIM_MIN_INTERVAL_MS, C as getBrokerEventBus, Cn as formatHeapSpaces, Ct as capBareAction, D as subscribePassthrough, Dn as OUTBOUND_QUEUE_COOLDOWN_MS, Dt as serializeTypedArrays, E as setNodeEventInterest, En as selectReportedSpaces, Et as deserializeTypedArrays, F as ipcParentLink, Fn as EMPTY_SOCKET_PLANE_BASELINE, Ft as resolveNpmInvocation, G as CapRouteResolver, Gn as recordSocketFrame, Gt as HUB_MAIN_HEAP_WATCH_LABEL, H as createUdsLoggerWithControl, Hn as readSocketQueues, Ht as HEAP_RECLAIM_TRIGGER_MB, I as localProviderLink, In as SOCKET_PLANE_TOP_N, It as runNpm, J as classifyCapRoute, Jn as socketDirectionMessages, Jt as RSS_BUDGET_REANNOUNCE_MIN_MS, K as callWithServiceDiscovery, Kn as sampleSocketDirection, Kt as HUB_MAIN_RSS_BUDGET_MB, L as createParentUnownedCallHandler, Ln as SOCKET_QUEUE_TOP_N, Lt as createAddonPeerBytesFacility, M as brokerTransportLink, Mn as MESH_QUEUE_TOP_N, Mt as installManifestNativeDeps, N as buildLinkChain, Nn as createMeshQueueReader, Nt as resolveAddonClass, O as AddonDepsManager, On as OUTBOUND_QUEUE_SUSTAIN_MS, Ot as DeviceRegistry, P as deviceCapResolverLink, Pn as formatMeshQueue, Pt as buildNpmChildEnv, Q as readMoleculerFanoutMode, Qn as MAX_CAP_ACTIONS_PER_PEER, Qt as ZERO_LOOP_DELAY, R as createUdsEventBridge, Rn as createSocketPlaneMeter, Rt as hostNodeIdOf, S as clusterEventTopic, Sn as emitHeapDiagnosticReport, St as capActionSuffix, T as registerEventBusService, Tn as readHeapSpaces, Tt as parseCapAction, U as AGENT_CAP_FWD_ACTION, Un as EMPTY_SOCKET_DIRECTION, Ut as HEAP_WATCH_INTERVAL_MS, V as createUdsLogger, Vn as formatSocketPlane, Vt as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, W as AGENT_CAP_FWD_SERVICE, Wn as createSocketDirectionCounters, Wt as HEAP_WATCH_WARN_RATIO, X as LocalChildRegistry, Xn as CAP_ACTION_UNLABELLED, Xt as RUNNER_HEAP_WATCH_INTERVAL_MS, Y as LocalChildClient, Yn as CAP_ACTION_OVERFLOW_LABEL, Yt as RSS_BUDGET_RELEASE_RATIO, Z as UDS_NO_ROUTE_PREFIX, Zn as EMPTY_CAP_ACTION_READING, Zt as RUNNER_RSS_BUDGET_ENV, _ as getWorkerDeviceRegistry, _n as createInspectorArrayBufferCensus, a as reapProcessGroup, an as nextRssBudgetState, ar as diffEventPlane, at as UdsLocalTransportServer, b as setHubConnected, bn as DECISIVE_HEAP_SPACES, bt as NATIVE_PROVIDER_SERVICE_INFIX, c as runnerOwnsProcessGroup, cn as shouldReclaim, ct as localEndpointPath, d as summarizeMembers, dn as strandedMb, dt as buildNativeCapProxy, en as createDeferredHeapWatchSink, er as createCapActionCensus, et as PARENT_ROUTED_PROVIDER_ADDON_ID, f as installManifestSystemDeps, fn as ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ft as buildUdsNativeCapProxy, g as createUdsAddonContext, gn as createArrayBufferCensusGate, gt as mountNativeCapService, h as createAddonContext, hn as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, in as hubMainRssBudget, ir as createEventPlaneReader, it as UdsLocalTransportClient, j as brokerCallForCap, jn as formatOutboundQueueVerdict, jt as copyBundledNativeModules, k as createKernelHwAccel, kn as OUTBOUND_QUEUE_THRESHOLD_BYTES, kt as CapabilityHandle, l as signalAllRunnerGroups, ln as startHeapWatch, lt as FrameDecoder, m as adaptBrokerToCluster, mn as ARRAY_BUFFER_CENSUS_THRESHOLD_MB, nn as createV8Reclaimer, nr as EVENT_PLANE_TOP_N, nt as getCapUsageRegistry, o as registerRunnerGroup, on as parseRssBudgetMb, or as formatEventPlane, ot as SocketChannel, p as installManifestPythonDeps, pn as ARRAY_BUFFER_CENSUS_SUSTAIN_MS, pt as createBrokerDeviceManagerApi, q as CapRouteError, qn as socketDirectionBytes, qt as HUB_RSS_BUDGET_ENV, r as defaultProcessGroupOps, rn as describeRss, rr as createEventPlaneMeter, rt as createLocalTransport, s as releaseRunnerGroup, sn as reclaimIntervalMs, st as PeerAnsweredError, t as CAP_METHOD_NOT_IMPLEMENTED, tn as createLoopDelayMeter, tr as diffCapActionCensus, tt as __resetCapUsageRegistryForTests, un as startRunnerHeapWatch, ut as encodeFrame, v as getOrInitReadinessRegistry, vn as formatArrayBufferCensus, vt as createAddonService, w as getMoleculerEventStats, wn as heapSpaceField, wt as capServiceName, x as EVENT_TOPIC_PREFIX, xn as HEAP_SPACE_REPORT_MIN_MB, xt as capActionName, y as getOrInitReadinessRegistryForClient, yn as isArrayBufferCensusReport, yt as validateProviderRegistrations, z as createUdsEventBus, zn as createSocketPlaneReader, zt as createAddonDataPlaneFacility } from "./child-cap-dispatch-CHTiHbsv.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-AAltfBUH.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";
@@ -5846,6 +5846,36 @@ function scheduleSelfRestart(options = {}) {
5846
5846
  }, delayMs);
5847
5847
  }
5848
5848
  //#endregion
5849
+ //#region src/kernel/status-overlay.ts
5850
+ /** The answer for a device KNOWN to carry no claim — the old path, no overlay. */
5851
+ var UNCLAIMED = { kind: "unclaimed" };
5852
+ var GET_STATUS = "getStatus";
5853
+ /**
5854
+ * Wrap `provider` so that `getStatus` awaits the overlay, re-read at CALL time
5855
+ * (a claim released between resolve and call falls back to the native's own
5856
+ * `getStatus`; a device whose claims are not yet known has them resolved
5857
+ * first), and every other property is the provider's own.
5858
+ *
5859
+ * Other properties are read off the TARGET with the target as receiver, and a
5860
+ * function is bound to it: a class instance's methods then see their real
5861
+ * `this` — a Proxy as `this` would break `#private` fields and prototype
5862
+ * getters. The HA-shaped forwarding Proxy is unaffected either way.
5863
+ */
5864
+ function overlayGetStatus(provider, answer) {
5865
+ return new Proxy(provider, { get(target, prop) {
5866
+ if (prop === GET_STATUS) return async (...args) => {
5867
+ const current = await answer();
5868
+ if (current.kind === "claimed") return current.slice;
5869
+ if (current.kind === "unknown") return null;
5870
+ const native = Reflect.get(target, prop, target);
5871
+ if (typeof native !== "function") throw new Error("getStatus: the claim was released and the native provider implements no getStatus");
5872
+ return await native.apply(target, args);
5873
+ };
5874
+ const value = Reflect.get(target, prop, target);
5875
+ return typeof value === "function" ? value.bind(target) : value;
5876
+ } });
5877
+ }
5878
+ //#endregion
5849
5879
  //#region src/kernel/capability-registry.ts
5850
5880
  /**
5851
5881
  * Type-level bridge: the `providers` map stores heterogeneous capability
@@ -5858,6 +5888,19 @@ function scheduleSelfRestart(options = {}) {
5858
5888
  function asProvider(value) {
5859
5889
  return value;
5860
5890
  }
5891
+ /**
5892
+ * A parsed `status.schema` output is a record — every status schema is a
5893
+ * `z.object` (the `status` block's contract) — but `CapabilityStatusSchema`
5894
+ * types it as `ZodType<unknown>`, so the parsed value comes back `unknown`.
5895
+ * Narrowed structurally, never cast: a non-record output is answered `null`
5896
+ * ("not reported", D315), which is also what the aggregate does with it.
5897
+ */
5898
+ function asStatusSlice(parsed) {
5899
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
5900
+ const slice = {};
5901
+ for (const [key, value] of Object.entries(parsed)) slice[key] = value;
5902
+ return slice;
5903
+ }
5861
5904
  var CapabilityRegistry = class CapabilityRegistry {
5862
5905
  capabilities = /* @__PURE__ */ new Map();
5863
5906
  logger;
@@ -6347,13 +6390,95 @@ var CapabilityRegistry = class CapabilityRegistry {
6347
6390
  setNativeFallback(resolver) {
6348
6391
  this.nativeFallback = resolver;
6349
6392
  }
6350
- /** Resolve the native provider for `(capName, deviceId)` or null. */
6393
+ /**
6394
+ * Resolve the native provider for `(capName, deviceId)` or null. A CLAIMED
6395
+ * cap's provider is handed back with its `getStatus` overlaid (D663, S3) —
6396
+ * on the in-process branch AND the `nativeFallback` branch, which is the
6397
+ * path the HA feeder's devices take.
6398
+ */
6351
6399
  getNativeProvider(capName, deviceId) {
6352
6400
  const entry = this.nativeProviders.get(capName)?.get(deviceId);
6353
- if (entry) return entry.provider;
6354
- if (this.nativeFallback) return this.nativeFallback(capName, deviceId) ?? null;
6401
+ if (entry) return this.withOverlay(capName, deviceId, entry.provider);
6402
+ if (this.nativeFallback) {
6403
+ const fallback = this.nativeFallback(capName, deviceId);
6404
+ return this.withOverlay(capName, deviceId, fallback ?? null);
6405
+ }
6355
6406
  return null;
6356
6407
  }
6408
+ /** The device-manager's view over its mirror; `null` until installed. */
6409
+ statusOverlay = null;
6410
+ /** `(cap, device)` pairs whose merged slice currently fails its status schema — one warn per transition. */
6411
+ overlayParseFailing = /* @__PURE__ */ new Set();
6412
+ /**
6413
+ * Install (or remove, with `null`) the claimed-status overlay. Installed once
6414
+ * by the device-manager at init over its `DeviceStateMirror`; removed on its
6415
+ * shutdown. Wrappers already resolved re-read it at call time, so an
6416
+ * uninstall hands `getStatus` back to the native immediately.
6417
+ */
6418
+ setStatusOverlay(overlay) {
6419
+ this.statusOverlay = overlay;
6420
+ this.overlayParseFailing.clear();
6421
+ }
6422
+ /**
6423
+ * THE question every `getStatus` awaits before it is answered (the registry's
6424
+ * own wrappers at call time, and the three transport entries through
6425
+ * `answerClaimedGetStatus`). The overlay resolves the device's claims first;
6426
+ * `unknown` survives only when its row cannot be read, and the caller then
6427
+ * answers "not reported", never the native (D315, D49).
6428
+ *
6429
+ * A claimed slice is parsed with the cap's `status.schema` — S4 makes
6430
+ * `status ⊆ runtimeState`, so the merged runtime slice parses and a
6431
+ * runtime-only key such as `lastFetchedAt` is stripped. A slice that does not
6432
+ * parse is `null`, logged once per `(cap, device)` transition with the device
6433
+ * tag; a held claim is `null` without a parse. A cap with no `status` block
6434
+ * passes its merged slice through as is.
6435
+ */
6436
+ async resolveClaimedStatus(capName, deviceId) {
6437
+ if (this.statusOverlay === null) return UNCLAIMED;
6438
+ return this.parseClaimed(capName, deviceId, await this.statusOverlay.resolve(capName, deviceId));
6439
+ }
6440
+ parseClaimed(capName, deviceId, answer) {
6441
+ if (answer.kind !== "claimed" || answer.slice === null) return answer;
6442
+ const schema = this.getDefinition(capName)?.status?.schema;
6443
+ if (schema === void 0) return answer;
6444
+ const key = `${capName}:${deviceId}`;
6445
+ const parsed = schema.safeParse(answer.slice);
6446
+ if (parsed.success) {
6447
+ this.overlayParseFailing.delete(key);
6448
+ return {
6449
+ kind: "claimed",
6450
+ slice: asStatusSlice(parsed.data)
6451
+ };
6452
+ }
6453
+ if (!this.overlayParseFailing.has(key)) {
6454
+ this.overlayParseFailing.add(key);
6455
+ this.logger.warn("claimed cap: merged slice fails its status schema — answering null", {
6456
+ tags: { deviceId },
6457
+ meta: {
6458
+ capName,
6459
+ issues: parsed.error.issues.slice(0, 3)
6460
+ }
6461
+ });
6462
+ }
6463
+ return {
6464
+ kind: "claimed",
6465
+ slice: null
6466
+ };
6467
+ }
6468
+ /**
6469
+ * Hand `provider` back untouched when `(capName, deviceId)` is KNOWN to be
6470
+ * unclaimed; otherwise wrap it so `getStatus` awaits `resolveClaimedStatus`
6471
+ * (re-read at call time — the parse, and for an unknown device the row read,
6472
+ * happen only when `getStatus` is actually called) and everything else stays
6473
+ * the provider's own. An unclaimed device pays one in-memory lookup; with no
6474
+ * overlay installed it pays nothing.
6475
+ */
6476
+ withOverlay(capName, deviceId, provider) {
6477
+ if (this.statusOverlay === null) return provider;
6478
+ if (typeof provider !== "object" || provider === null) return provider;
6479
+ if (this.statusOverlay.peek(capName, deviceId).kind === "unclaimed") return provider;
6480
+ return overlayGetStatus(provider, () => this.resolveClaimedStatus(capName, deviceId));
6481
+ }
6357
6482
  /** Resolve the addonId that registered the native provider for `(capName, deviceId)`. */
6358
6483
  getNativeAddonId(capName, deviceId) {
6359
6484
  return this.nativeProviders.get(capName)?.get(deviceId)?.addonId ?? null;
@@ -6438,9 +6563,9 @@ var CapabilityRegistry = class CapabilityRegistry {
6438
6563
  if (native !== null) return native;
6439
6564
  const state = this.capabilities.get(capName);
6440
6565
  if (!state) return null;
6441
- if (state.definition.mode === "singleton") return this.resolveForDevice(capName, String(deviceId));
6566
+ if (state.definition.mode === "singleton") return this.withOverlay(capName, deviceId, this.resolveForDevice(capName, String(deviceId)));
6442
6567
  const first = state.providers.values().next();
6443
- return first.done ? null : asProvider(first.value);
6568
+ return first.done ? null : this.withOverlay(capName, deviceId, asProvider(first.value));
6444
6569
  }
6445
6570
  getAllProviders(capabilityName) {
6446
6571
  if (!this._ready) return [];
@@ -95918,4 +96043,4 @@ var LifecycleJobEngine = class {
95918
96043
  }
95919
96044
  };
95920
96045
  //#endregion
95921
- 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, 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, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, buildUdsNativeCapProxy, 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, 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, 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 };
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 };
@@ -1,4 +1,5 @@
1
1
  import { CapabilityDeclaration, CapabilityDefinition, CapabilityInfo, CapabilityMode, CapabilityProviderMap, CollectionCapabilityMap, IEventBus, IScopedLogger, SingletonCapabilityMap } from '@camstack/types';
2
+ import { StatusOverlay, StatusOverlayAnswer } from './status-overlay.js';
2
3
  /** Result of creating a capability router (opaque to the kernel). */
3
4
  export type CapabilityRouter = unknown;
4
5
  /** Factory that creates a tRPC router from a capability definition + provider getter. */
@@ -260,8 +261,49 @@ export declare class CapabilityRegistry {
260
261
  * worker. Set once at hub boot time.
261
262
  */
262
263
  setNativeFallback(resolver: (capName: string, deviceId: number) => unknown | null): void;
263
- /** Resolve the native provider for `(capName, deviceId)` or null. */
264
+ /**
265
+ * Resolve the native provider for `(capName, deviceId)` or null. A CLAIMED
266
+ * cap's provider is handed back with its `getStatus` overlaid (D663, S3) —
267
+ * on the in-process branch AND the `nativeFallback` branch, which is the
268
+ * path the HA feeder's devices take.
269
+ */
264
270
  getNativeProvider<T = unknown>(capName: string, deviceId: number): T | null;
271
+ /** The device-manager's view over its mirror; `null` until installed. */
272
+ private statusOverlay;
273
+ /** `(cap, device)` pairs whose merged slice currently fails its status schema — one warn per transition. */
274
+ private readonly overlayParseFailing;
275
+ /**
276
+ * Install (or remove, with `null`) the claimed-status overlay. Installed once
277
+ * by the device-manager at init over its `DeviceStateMirror`; removed on its
278
+ * shutdown. Wrappers already resolved re-read it at call time, so an
279
+ * uninstall hands `getStatus` back to the native immediately.
280
+ */
281
+ setStatusOverlay(overlay: StatusOverlay | null): void;
282
+ /**
283
+ * THE question every `getStatus` awaits before it is answered (the registry's
284
+ * own wrappers at call time, and the three transport entries through
285
+ * `answerClaimedGetStatus`). The overlay resolves the device's claims first;
286
+ * `unknown` survives only when its row cannot be read, and the caller then
287
+ * answers "not reported", never the native (D315, D49).
288
+ *
289
+ * A claimed slice is parsed with the cap's `status.schema` — S4 makes
290
+ * `status ⊆ runtimeState`, so the merged runtime slice parses and a
291
+ * runtime-only key such as `lastFetchedAt` is stripped. A slice that does not
292
+ * parse is `null`, logged once per `(cap, device)` transition with the device
293
+ * tag; a held claim is `null` without a parse. A cap with no `status` block
294
+ * passes its merged slice through as is.
295
+ */
296
+ resolveClaimedStatus(capName: string, deviceId: number): Promise<StatusOverlayAnswer>;
297
+ private parseClaimed;
298
+ /**
299
+ * Hand `provider` back untouched when `(capName, deviceId)` is KNOWN to be
300
+ * unclaimed; otherwise wrap it so `getStatus` awaits `resolveClaimedStatus`
301
+ * (re-read at call time — the parse, and for an unknown device the row read,
302
+ * happen only when `getStatus` is actually called) and everything else stays
303
+ * the provider's own. An unclaimed device pays one in-memory lookup; with no
304
+ * overlay installed it pays nothing.
305
+ */
306
+ private withOverlay;
265
307
  /** Resolve the addonId that registered the native provider for `(capName, deviceId)`. */
266
308
  getNativeAddonId(capName: string, deviceId: number): string | null;
267
309
  /** List the capability names for which this device has a native provider registered. */
@@ -15,6 +15,8 @@ export { CapabilityHandle, CapabilityUnavailableError } from './capability-handl
15
15
  export { CapabilityRegistry } from './capability-registry.js';
16
16
  export { buildCapRouters, builderMountedCapNames } from './cap-router-builder.js';
17
17
  export type { CapRouterPrimitives, CapRouterServices, CapProviderGetter, RemoteProxyFactory, ProcedureBuilder, ProcedureResolverArgs, } from './cap-router-builder.js';
18
+ export { overlayGetStatus, UNCLAIMED } from './status-overlay.js';
19
+ export type { ClaimedStatusResolver, StatusOverlay, StatusOverlayAnswer } from './status-overlay.js';
18
20
  export { describeProviderKindDrift } from './provider-kind-drift.js';
19
21
  export type { ProviderKindHint } from './provider-kind-drift.js';
20
22
  export type { CapabilityRouter, CapabilityRouterFactory, ConfigReader, ProviderOwnerToken, } from './capability-registry.js';
@@ -66,7 +68,7 @@ export { installManifestNativeDeps } from './deps/manifest-native-deps.js';
66
68
  export { AddonHealthMonitor, HEALTH_MONITOR_TICK_MS, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, } from './addon-health-monitor.js';
67
69
  export type { AddonHealthPhase, AddonHealthState, AddonHealthSnapshot, AddonHealthMonitorOptions, } from './addon-health-monitor.js';
68
70
  export type { HubServiceDeps } from './moleculer/hub-service.js';
69
- export { createBrokerDeviceManagerApi, buildNativeCapProxy, buildUdsNativeCapProxy, mountNativeCapService, NATIVE_PROVIDER_SERVICE_INFIX, } from './moleculer/device-cap-proxy.js';
71
+ export { createBrokerDeviceManagerApi, buildNativeCapProxy, mountNativeCapService, NATIVE_PROVIDER_SERVICE_INFIX, } from './moleculer/device-cap-proxy.js';
70
72
  export type { WorkerDeviceManagerOptions } from './moleculer/device-cap-proxy.js';
71
73
  export { getWorkerDeviceRegistry } from './moleculer/addon-context-factory.js';
72
74
  export { localProviderLink, brokerTransportLink, deviceCapResolverLink, ipcParentLink, buildLinkChain, brokerCallForCap, } from './moleculer/trpc-links.js';
@@ -3,7 +3,6 @@ import { deviceOpsCapability } from '@camstack/types/addon';
3
3
  import { ServiceBroker } from 'moleculer';
4
4
  import { CapabilityRegistry } from '../capability-registry.js';
5
5
  import { DeviceRegistry } from '../device-registry.js';
6
- import { LocalChildRegistry } from '../transport/local-child-registry.js';
7
6
  export { NATIVE_PROVIDER_SERVICE_INFIX } from '../transport/cap-action-name.js';
8
7
  export interface WorkerDeviceManagerOptions {
9
8
  readonly api: AddonApi;
@@ -67,14 +66,5 @@ export declare function getWorkerNativeCapProvider(capName: string, deviceId: nu
67
66
  * worker `broker.createService` and the hub's Moleculer registry INFO packet.
68
67
  */
69
68
  export declare function buildNativeCapProxy(broker: ServiceBroker, addonId: string, capName: string, deviceId: number): Record<string, (input: unknown) => Promise<unknown>>;
70
- /**
71
- * Hub-side proxy for a device-scoped native cap whose owning runner is a
72
- * HUB-LOCAL forked child reachable over UDS. Mirrors {@link buildNativeCapProxy}
73
- * but dispatches via `LocalChildRegistry.callCapOnChild` (UDS) instead of
74
- * `broker.call` — the child no longer hosts a Moleculer service after the UDS
75
- * cutover, so a broker call fails "is not found". The `deviceId` is merged into
76
- * the method args (provider convention) and carried as the routing field.
77
- */
78
- export declare function buildUdsNativeCapProxy(registry: LocalChildRegistry, childId: string, capName: string, deviceId: number): Record<string, (input: unknown) => Promise<unknown>>;
79
69
  export declare function buildDeviceOpsProvider(device: IDevice): InferProvider<typeof deviceOpsCapability>;
80
70
  export declare function createBrokerDeviceManagerApi(opts: WorkerDeviceManagerOptions): DeviceManagerApi;
@@ -0,0 +1,18 @@
1
+ import { StatusOverlay, StatusOverlayAnswer } from '@camstack/types';
2
+ export type { StatusOverlay, StatusOverlayAnswer };
3
+ /** The answer for a device KNOWN to carry no claim — the old path, no overlay. */
4
+ export declare const UNCLAIMED: StatusOverlayAnswer;
5
+ /** Resolves the device's claims first, then answers. What every consumer awaits. */
6
+ export type ClaimedStatusResolver = (capName: string, deviceId: number) => Promise<StatusOverlayAnswer>;
7
+ /**
8
+ * Wrap `provider` so that `getStatus` awaits the overlay, re-read at CALL time
9
+ * (a claim released between resolve and call falls back to the native's own
10
+ * `getStatus`; a device whose claims are not yet known has them resolved
11
+ * first), and every other property is the provider's own.
12
+ *
13
+ * Other properties are read off the TARGET with the target as receiver, and a
14
+ * function is bound to it: a class instance's methods then see their real
15
+ * `this` — a Proxy as `this` would break `#private` fields and prototype
16
+ * getters. The HA-shaped forwarding Proxy is unaffected either way.
17
+ */
18
+ export declare function overlayGetStatus<T extends object>(provider: T, answer: () => Promise<StatusOverlayAnswer>): T;
@@ -0,0 +1,15 @@
1
+ import { ClaimedStatusResolver } from '../status-overlay.js';
2
+ export declare const GET_STATUS_METHOD = "getStatus";
3
+ /** What the entry knows about the call; `deviceId` wins over one inside `args`. */
4
+ export interface ClaimedGetStatusCall {
5
+ readonly capName: string;
6
+ readonly method: string;
7
+ readonly deviceId?: number;
8
+ readonly args?: unknown;
9
+ }
10
+ export interface ClaimedGetStatusAnswer {
11
+ readonly slice: Readonly<Record<string, unknown>> | null;
12
+ }
13
+ /** The device a `getStatus` is about, or `undefined` when the call is not one. */
14
+ export declare function deviceOfGetStatus(call: ClaimedGetStatusCall): number | undefined;
15
+ export declare function answerClaimedGetStatus(resolve: ClaimedStatusResolver | undefined, call: ClaimedGetStatusCall): Promise<ClaimedGetStatusAnswer | null>;
@@ -29,6 +29,8 @@ export type { UdsEventChannel } from './uds-event-bus.js';
29
29
  export { createUdsEventBridge } from './uds-event-bridge.js';
30
30
  export type { UdsEventBridgeDeps, ChildEventBroadcaster } from './uds-event-bridge.js';
31
31
  export { createParentUnownedCallHandler } from './parent-unowned-call.js';
32
+ export { answerClaimedGetStatus, deviceOfGetStatus, GET_STATUS_METHOD, } from './claimed-get-status.js';
33
+ export type { ClaimedGetStatusAnswer, ClaimedGetStatusCall } from './claimed-get-status.js';
32
34
  export type { ParentUnownedCallDeps, ParentUnownedCallLogger } from './parent-unowned-call.js';
33
35
  export { createHubCapForwardService, HUB_CAP_FWD_SERVICE, HUB_CAP_FWD_ACTION, } from './hub-cap-forward.js';
34
36
  export type { HubCapForwardParams, HubUnownedCallHandler } from './hub-cap-forward.js';