@camstack/system 1.2.66 → 1.2.67

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 (53) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  8. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  9. package/dist/builtins/console-logging/index.js +1 -1
  10. package/dist/builtins/console-logging/index.mjs +1 -1
  11. package/dist/builtins/core-blocks/blocks-integration.d.ts +24 -0
  12. package/dist/builtins/core-blocks/core-blocks.addon.d.ts +14 -0
  13. package/dist/builtins/core-blocks/core-blocks.addon.js +99 -2
  14. package/dist/builtins/core-blocks/core-blocks.addon.mjs +99 -2
  15. package/dist/builtins/device-manager/device-manager.addon.js +3 -1
  16. package/dist/builtins/device-manager/device-manager.addon.mjs +3 -1
  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 +1 -1
  40. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
  41. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  42. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  43. package/dist/builtins/system-config/system-config.addon.js +1 -1
  44. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  45. package/dist/builtins/winston-logging/index.js +1 -1
  46. package/dist/builtins/winston-logging/index.mjs +1 -1
  47. package/dist/{dist-DqPyKwVB.mjs → dist-CbS6uoSb.mjs} +2465 -2075
  48. package/dist/{dist-CIkGOAcz.js → dist-NRYjb8qK.js} +1891 -1489
  49. package/dist/index.js +28 -4
  50. package/dist/index.mjs +28 -4
  51. package/dist/kernel/cap-router-builder.d.ts +19 -0
  52. package/dist/kernel/capability-registry.d.ts +14 -1
  53. 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-CIkGOAcz.js");
3
+ const require_dist = require("./dist-NRYjb8qK.js");
4
4
  const require_model_download_service = require("./model-download-service-Caj1kaSi.js");
5
5
  const require_manifest_python_deps = require("./manifest-python-deps-BE6l8Y4W.js");
6
6
  const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
@@ -6043,6 +6043,23 @@ var CapabilityRegistry = class CapabilityRegistry {
6043
6043
  if (!state) return null;
6044
6044
  return state.providers.get(addonId) ?? null;
6045
6045
  }
6046
+ /**
6047
+ * Every registry KEY currently registered for `capability`, disabled ones
6048
+ * included — i.e. exactly the ids {@link getProviderByAddonId} can resolve.
6049
+ * Keys are bare (`homeassistant-export`) for hub-local providers and
6050
+ * `<addonId>@<nodeId>` for providers that registered from another node.
6051
+ *
6052
+ * Exists so an unresolvable `{ addonId }` pin can REFUSE with the valid ids
6053
+ * spelled out (the `addons.custom` unknown-id posture) instead of silently
6054
+ * degrading to another provider's answer — a fabricated `addonId` used to
6055
+ * return the first-registered provider's status, indistinguishable from
6056
+ * success (2026-08-09).
6057
+ */
6058
+ getProviderAddonIds(capability) {
6059
+ const state = this.capabilities.get(capability);
6060
+ if (!state) return [];
6061
+ return [...state.providers.keys()];
6062
+ }
6046
6063
  /** Bare addonId from a registry key (`webrtc-native@dev-agent-0` → `webrtc-native`). */
6047
6064
  bareAddonId(key) {
6048
6065
  const at = key.indexOf("@");
@@ -6602,11 +6619,18 @@ function stripKeys(input, keys) {
6602
6619
  * the same local-first → remote-proxy routing the codegen's
6603
6620
  * `resolveProvider` does. `nodeId` undefined / `'hub'` resolves the local
6604
6621
  * provider; otherwise it crosses to the named node via the proxy.
6622
+ *
6623
+ * `pinnedAddonId` is the EXPLICIT top-level `{ addonId }` collection selector
6624
+ * (never the one recovered from a nested mutation payload). When it is set and
6625
+ * the local lookup misses, {@link CapRouterServices.rejectUnresolvedAddonPin}
6626
+ * gets to refuse before the hub-proxy fallthrough turns a wrong id into
6627
+ * another provider's answer.
6605
6628
  */
6606
- function resolveProviderForCall(capName, nodeId, getLocal, services) {
6629
+ function resolveProviderForCall(capName, nodeId, getLocal, services, pinnedAddonId) {
6607
6630
  if (!nodeId || nodeId === "hub") {
6608
6631
  const local = getLocal();
6609
6632
  if (local !== null && local !== void 0) return local;
6633
+ if (pinnedAddonId !== void 0) services.rejectUnresolvedAddonPin?.(capName, pinnedAddonId);
6610
6634
  const proxy = services.remoteProxy(capName, "hub");
6611
6635
  if (proxy) return proxy;
6612
6636
  return services.noProvider(capName);
@@ -6661,7 +6685,7 @@ function buildOneCapRouter(def, primitives, services) {
6661
6685
  }).optional() : zod.z.object({ nodeId: zod.z.string().optional() }).optional();
6662
6686
  procedures[method.name] = base.input(voidSelector)[procKind](({ input, ctx }) => {
6663
6687
  const sel = input ?? {};
6664
- return (nodeIdData ? requireLocal(capName, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services) : resolveProviderForCall(capName, sel.nodeId, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services))[method.name]?.();
6688
+ return (nodeIdData ? requireLocal(capName, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services) : resolveProviderForCall(capName, sel.nodeId, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services, isCollection ? sel.addonId : void 0))[method.name]?.();
6665
6689
  });
6666
6690
  continue;
6667
6691
  }
@@ -6679,7 +6703,7 @@ function buildOneCapRouter(def, primitives, services) {
6679
6703
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
6680
6704
  const canRecoverNestedAddonId = !require_dist.isArrayOutputSchema(method.schema.output) && !require_dist.objectInputDeclaresAddonId(method.schema.input);
6681
6705
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? require_dist.extractNestedAddonId(rest) : void 0);
6682
- const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services);
6706
+ const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId);
6683
6707
  const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6684
6708
  return provider[method.name]?.(payload);
6685
6709
  }
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 { Ct as asString$1, Dt as expandCapMethods, F as extractNestedAddonId, Ft as scopeKey, H as kebabToCamel, K as logLevelAtMost, L as isArrayOutputSchema, Lt as EventCategory$1, Mt as parseJsonUnknown$1, Nt as readinessKey, Pt as resolveCapMount, R as isCollectionArrayMethod, St as asNumber, Tt as emitDownForOwnedCaps, U as lifecycleJobSchema, V as isVoidInput, Z as objectInputDeclaresAddonId, et as procedureAuthKey, ft as DATAPLANE_SECRET_HEADER$1, g as addonSettingsCapability, jt as parseJsonObject, l as METHOD_ACCESS_MAP, mt as DEVICE_STATUS_METHOD, pt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, q as looseSchema, t as ALL_CAPABILITY_DEFINITIONS, u as RUNTIME_DEFAULTS, ut as errMsg$1, vt as ReadinessRegistry, wt as createEvent, xt as asJsonObject$1, yt as ReadinessTimeoutError, z as isObjectInput } from "./dist-DqPyKwVB.mjs";
2
+ import { $ as objectInputDeclaresAddonId, B as isCollectionArrayMethod, Ct as asJsonObject$1, Dt as emitDownForOwnedCaps, Et as createEvent, Ft as readinessKey, G as lifecycleJobSchema, It as resolveCapMount, J as logLevelAtMost, L as extractNestedAddonId, Lt as scopeKey, Nt as parseJsonObject, Pt as parseJsonUnknown$1, Tt as asString$1, U as isVoidInput, V as isObjectInput, W as kebabToCamel, Y as looseSchema, bt as ReadinessRegistry, d as METHOD_ACCESS_MAP, f as RUNTIME_DEFAULTS, ft as errMsg$1, gt as DEVICE_STATUS_METHOD, ht as DEVICE_SETTINGS_CONTRIBUTION_METHODS, kt as expandCapMethods, mt as DATAPLANE_SECRET_HEADER$1, nt as procedureAuthKey, t as ALL_CAPABILITY_DEFINITIONS, v as addonSettingsCapability, wt as asNumber, xt as ReadinessTimeoutError, z as isArrayOutputSchema, zt as EventCategory$1 } from "./dist-CbS6uoSb.mjs";
3
3
  import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-CTBHzORJ.mjs";
4
4
  import { $ as buildNativeCapProxy, A as createHubCapForwardService, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as resolveAddonClass, D as localProviderLink, E as ipcParentLink, F as createUdsLogger, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, N as createUdsEventBus, O as HUB_CAP_FWD_ACTION, P as udsChildLogToWorkerEntry, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as runNpm, T as ipcChildLink, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, k as HUB_CAP_FWD_SERVICE, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-Dz1ryHIN.mjs";
5
5
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BkP504Vq.mjs";
@@ -6035,6 +6035,23 @@ var CapabilityRegistry = class CapabilityRegistry {
6035
6035
  if (!state) return null;
6036
6036
  return state.providers.get(addonId) ?? null;
6037
6037
  }
6038
+ /**
6039
+ * Every registry KEY currently registered for `capability`, disabled ones
6040
+ * included — i.e. exactly the ids {@link getProviderByAddonId} can resolve.
6041
+ * Keys are bare (`homeassistant-export`) for hub-local providers and
6042
+ * `<addonId>@<nodeId>` for providers that registered from another node.
6043
+ *
6044
+ * Exists so an unresolvable `{ addonId }` pin can REFUSE with the valid ids
6045
+ * spelled out (the `addons.custom` unknown-id posture) instead of silently
6046
+ * degrading to another provider's answer — a fabricated `addonId` used to
6047
+ * return the first-registered provider's status, indistinguishable from
6048
+ * success (2026-08-09).
6049
+ */
6050
+ getProviderAddonIds(capability) {
6051
+ const state = this.capabilities.get(capability);
6052
+ if (!state) return [];
6053
+ return [...state.providers.keys()];
6054
+ }
6038
6055
  /** Bare addonId from a registry key (`webrtc-native@dev-agent-0` → `webrtc-native`). */
6039
6056
  bareAddonId(key) {
6040
6057
  const at = key.indexOf("@");
@@ -6594,11 +6611,18 @@ function stripKeys(input, keys) {
6594
6611
  * the same local-first → remote-proxy routing the codegen's
6595
6612
  * `resolveProvider` does. `nodeId` undefined / `'hub'` resolves the local
6596
6613
  * provider; otherwise it crosses to the named node via the proxy.
6614
+ *
6615
+ * `pinnedAddonId` is the EXPLICIT top-level `{ addonId }` collection selector
6616
+ * (never the one recovered from a nested mutation payload). When it is set and
6617
+ * the local lookup misses, {@link CapRouterServices.rejectUnresolvedAddonPin}
6618
+ * gets to refuse before the hub-proxy fallthrough turns a wrong id into
6619
+ * another provider's answer.
6597
6620
  */
6598
- function resolveProviderForCall(capName, nodeId, getLocal, services) {
6621
+ function resolveProviderForCall(capName, nodeId, getLocal, services, pinnedAddonId) {
6599
6622
  if (!nodeId || nodeId === "hub") {
6600
6623
  const local = getLocal();
6601
6624
  if (local !== null && local !== void 0) return local;
6625
+ if (pinnedAddonId !== void 0) services.rejectUnresolvedAddonPin?.(capName, pinnedAddonId);
6602
6626
  const proxy = services.remoteProxy(capName, "hub");
6603
6627
  if (proxy) return proxy;
6604
6628
  return services.noProvider(capName);
@@ -6653,7 +6677,7 @@ function buildOneCapRouter(def, primitives, services) {
6653
6677
  }).optional() : z.object({ nodeId: z.string().optional() }).optional();
6654
6678
  procedures[method.name] = base.input(voidSelector)[procKind](({ input, ctx }) => {
6655
6679
  const sel = input ?? {};
6656
- return (nodeIdData ? requireLocal(capName, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services) : resolveProviderForCall(capName, sel.nodeId, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services))[method.name]?.();
6680
+ return (nodeIdData ? requireLocal(capName, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services) : resolveProviderForCall(capName, sel.nodeId, () => getLocal(ctx, isCollection ? sel.addonId : void 0), services, isCollection ? sel.addonId : void 0))[method.name]?.();
6657
6681
  });
6658
6682
  continue;
6659
6683
  }
@@ -6671,7 +6695,7 @@ function buildOneCapRouter(def, primitives, services) {
6671
6695
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
6672
6696
  const canRecoverNestedAddonId = !isArrayOutputSchema(method.schema.output) && !objectInputDeclaresAddonId(method.schema.input);
6673
6697
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? extractNestedAddonId(rest) : void 0);
6674
- const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services);
6698
+ const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId);
6675
6699
  const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6676
6700
  return provider[method.name]?.(payload);
6677
6701
  }
@@ -72,6 +72,25 @@ export interface CapRouterServices {
72
72
  * back to `badRequest` in that case so the call still fails closed.
73
73
  */
74
74
  readonly unauthorized?: (message: string) => never;
75
+ /**
76
+ * Called when an EXPLICIT top-level `{ addonId }` collection pin resolved to
77
+ * no local provider, BEFORE the hub-proxy fallthrough. Implementations throw
78
+ * (naming the id and enumerating the valid ones) when the cap has providers
79
+ * registered and none of them matches; they return normally when the cap has
80
+ * no local providers at all, which is the legitimate "the cap lives in a
81
+ * forked hub worker" case the fallthrough exists for.
82
+ *
83
+ * Why: without this the pin was simply DROPPED. `getLocalProvider` returned
84
+ * null for an unknown addonId, which reads identically to "not resident on
85
+ * the hub root", so the call fell through to `remoteProxy(cap, 'hub')` and
86
+ * the Moleculer prefix lookup answered from the FIRST hub-side provider.
87
+ * `deviceExport.getStatus { addonId: 'questo-non-esiste-affatto' }` returned
88
+ * Alexa's `linked / 3` — the caller could not tell it had been misrouted
89
+ * (2026-08-09). OPTIONAL for framework-live-update version skew: an older
90
+ * server hands a services object without it and the builder keeps the old
91
+ * fallthrough rather than crashing.
92
+ */
93
+ readonly rejectUnresolvedAddonPin?: (capName: string, addonId: string) => void;
75
94
  }
76
95
  /**
77
96
  * Build a single capability's router (the runtime equivalent of one
@@ -1,4 +1,4 @@
1
- import { CapabilityDefinition, CapabilityDeclaration, CapabilityMode, CapabilityInfo, CapabilityProviderMap, SingletonCapabilityMap, CollectionCapabilityMap, IScopedLogger, IEventBus } from '@camstack/types';
1
+ import { CapabilityDeclaration, CapabilityDefinition, CapabilityInfo, CapabilityMode, CapabilityProviderMap, CollectionCapabilityMap, IEventBus, IScopedLogger, SingletonCapabilityMap } from '@camstack/types';
2
2
  import { ConfigManager } from './config-manager.js';
3
3
  /** Result of creating a capability router (opaque to the kernel). */
4
4
  export type CapabilityRouter = unknown;
@@ -327,6 +327,19 @@ export declare class CapabilityRegistry {
327
327
  /** Get a specific addon's provider by addon ID. */
328
328
  getProviderByAddonId<K extends keyof CapabilityProviderMap>(capability: K, addonId: string): CapabilityProviderMap[K] | null;
329
329
  getProviderByAddonId<T = unknown>(capability: string, addonId: string): T | null;
330
+ /**
331
+ * Every registry KEY currently registered for `capability`, disabled ones
332
+ * included — i.e. exactly the ids {@link getProviderByAddonId} can resolve.
333
+ * Keys are bare (`homeassistant-export`) for hub-local providers and
334
+ * `<addonId>@<nodeId>` for providers that registered from another node.
335
+ *
336
+ * Exists so an unresolvable `{ addonId }` pin can REFUSE with the valid ids
337
+ * spelled out (the `addons.custom` unknown-id posture) instead of silently
338
+ * degrading to another provider's answer — a fabricated `addonId` used to
339
+ * return the first-registered provider's status, indistinguishable from
340
+ * success (2026-08-09).
341
+ */
342
+ getProviderAddonIds(capability: string): readonly string[];
330
343
  /** Bare addonId from a registry key (`webrtc-native@dev-agent-0` → `webrtc-native`). */
331
344
  private bareAddonId;
332
345
  /** nodeId a provider key belongs to (bare → 'hub', `@node` → node). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.66",
3
+ "version": "1.2.67",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",