@camstack/system 1.2.139 → 1.2.141

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 (64) 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/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-linked-devices.d.ts +4 -2
  16. package/dist/builtins/device-manager/device-manager.addon.js +210 -21
  17. package/dist/builtins/device-manager/device-manager.addon.mjs +210 -21
  18. package/dist/builtins/device-manager/device-meta-actions.d.ts +27 -0
  19. package/dist/builtins/device-manager/device-row-store.d.ts +21 -3
  20. package/dist/builtins/device-manager/fleet-read-census.d.ts +20 -1
  21. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  22. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  23. package/dist/builtins/hub-forwarder/index.js +1 -1
  24. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  25. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  26. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  27. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  28. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  29. package/dist/builtins/local-network/local-network.addon.js +1 -1
  30. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  31. package/dist/builtins/loki-logging/index.js +1 -1
  32. package/dist/builtins/loki-logging/index.mjs +1 -1
  33. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  34. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  35. package/dist/builtins/platform-probe/index.js +1 -1
  36. package/dist/builtins/platform-probe/index.mjs +1 -1
  37. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  38. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  39. package/dist/builtins/snapshot/index.js +1 -1
  40. package/dist/builtins/snapshot/index.mjs +1 -1
  41. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  42. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  43. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  44. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  45. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  46. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  47. package/dist/builtins/system-config/system-config.addon.js +1 -1
  48. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  49. package/dist/builtins/winston-logging/index.js +1 -1
  50. package/dist/builtins/winston-logging/index.mjs +1 -1
  51. package/dist/{dist-D595vzqY.mjs → dist-6mn3LQvB.mjs} +2521 -2333
  52. package/dist/{dist-MqjCyx1E.js → dist-BNhvXrQk.js} +2521 -2333
  53. package/dist/index.js +28 -17
  54. package/dist/index.mjs +29 -17
  55. package/dist/kernel/cap-router-builder.d.ts +13 -0
  56. package/dist/kernel/index.d.ts +1 -1
  57. package/dist/kernel/moleculer/trpc-links.d.ts +1 -12
  58. package/dist/kernel/transport/cap-route-resolver.d.ts +35 -1
  59. package/dist/kernel/transport/child-cap-protocol.d.ts +14 -0
  60. package/dist/{manifest-python-deps-08rqn6xN.mjs → manifest-python-deps-D3zYlMEa.mjs} +49 -47
  61. package/dist/{manifest-python-deps-C9x9vrqt.js → manifest-python-deps-DBQarwp9.js} +48 -52
  62. package/dist/{retired-settings-keys-IVq6xR9i.js → retired-settings-keys-DVgdWTd7.js} +1 -1
  63. package/dist/{retired-settings-keys-BvxgnDT1.mjs → retired-settings-keys-SYwVv_Ym.mjs} +1 -1
  64. 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-MqjCyx1E.js");
3
+ const require_dist = require("./dist-BNhvXrQk.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_formatter = require("./formatter-DqAKDlvN.js");
@@ -26,7 +26,7 @@ require("./builtins/system-config/index.js");
26
26
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
27
27
  const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
28
28
  const require_tls$1 = require("./tls-u8QCJCFE.js");
29
- const require_manifest_python_deps = require("./manifest-python-deps-C9x9vrqt.js");
29
+ const require_manifest_python_deps = require("./manifest-python-deps-DBQarwp9.js");
30
30
  const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
31
31
  const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
32
32
  let zod = require("zod");
@@ -6410,11 +6410,31 @@ function methodsFor(def) {
6410
6410
  schema: m,
6411
6411
  isVoid: require_dist.isVoidInput(m.input),
6412
6412
  isObject: require_dist.isObjectInput(m.input),
6413
- callerRequired: m.caller === "required"
6413
+ callerRequired: m.caller === "required",
6414
+ isArrayOutput: m.kind !== "subscription" && require_dist.isArrayOutputSchema(m.output)
6414
6415
  };
6415
6416
  });
6416
6417
  }
6417
6418
  /**
6419
+ * Invoke `method.name` on a resolved provider, raising the canonical
6420
+ * "method not found" error (Task 7.5d) when the provider does not implement
6421
+ * it — the naive `provider[method.name]?.(payload)` optional call let a
6422
+ * missing method answer `undefined` (200 to the caller). EXCEPTION, mirrored
6423
+ * from `child-cap-dispatch.ts`'s `isCollectionListMethod` graceful skip: a
6424
+ * COLLECTION cap's array-output method degrades to `[]` — the hub fans that
6425
+ * method across every registered provider
6426
+ * (`resolveCollectionProvider`/`concatArrayMethod`), so ONE provider not
6427
+ * implementing it is a graceful skip, not an error. Every other missing
6428
+ * method (singleton, device-native, or a collection's SCALAR method) is a
6429
+ * real implementation gap and fails loud.
6430
+ */
6431
+ function invokeCapMethod(provider, method, payload, capName, isCollection, services) {
6432
+ const fn = provider[method.name];
6433
+ if (typeof fn === "function") return fn(payload);
6434
+ if (isCollection && method.isArrayOutput) return [];
6435
+ return (services.methodNotFound ?? ((cap, m) => services.badRequest(`Capability "${cap}" has no method "${m}"`)))(capName, method.name);
6436
+ }
6437
+ /**
6418
6438
  * Extract the authenticated caller identity from the (structurally
6419
6439
  * unknown) tRPC context. The builder cannot import the server's
6420
6440
  * `TrpcContext`, so the read is narrowing-based: `ctx.user.id` (string)
@@ -6534,37 +6554,29 @@ function buildOneCapRouter(def, primitives, services) {
6534
6554
  }).optional() : zod.z.object({ nodeId: zod.z.string().optional() }).optional();
6535
6555
  procedures[method.name] = base.input(voidSelector)[procKind](({ input, ctx }) => {
6536
6556
  const sel = input ?? {};
6537
- 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]?.();
6557
+ return invokeCapMethod(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, void 0, capName, isCollection, services);
6538
6558
  });
6539
6559
  continue;
6540
6560
  }
6541
6561
  if (method.isObject) {
6542
6562
  const schema = nodeIdData ? inputSchema : require_dist.looseSchema(inputSchema);
6543
6563
  procedures[method.name] = base.input(schema)[procKind](({ input, ctx }) => {
6544
- if (nodeIdData) {
6545
- const provider = requireLocal(capName, () => getLocal(ctx), services);
6546
- const payload = method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input;
6547
- return provider[method.name]?.(payload);
6548
- }
6564
+ if (nodeIdData) return invokeCapMethod(requireLocal(capName, () => getLocal(ctx), services), method, method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input, capName, isCollection, services);
6549
6565
  if (isCollection) {
6550
6566
  const { rest, picked } = stripKeys(input, ["nodeId", "addonId"]);
6551
6567
  const nodeId = typeof picked.nodeId === "string" ? picked.nodeId : void 0;
6552
6568
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
6553
6569
  const canRecoverNestedAddonId = !require_dist.isArrayOutputSchema(method.schema.output) && !require_dist.objectInputDeclaresAddonId(method.schema.input);
6554
6570
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? require_dist.extractNestedAddonId(rest) : void 0);
6555
- const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId);
6556
- const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6557
- return provider[method.name]?.(payload);
6571
+ return invokeCapMethod(resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId), method, method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest, capName, isCollection, services);
6558
6572
  }
6559
6573
  const { rest, picked } = stripKeys(input, ["nodeId"]);
6560
- const provider = resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services);
6561
- const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6562
- return provider[method.name]?.(payload);
6574
+ return invokeCapMethod(resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services), method, method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest, capName, isCollection, services);
6563
6575
  });
6564
6576
  continue;
6565
6577
  }
6566
6578
  procedures[method.name] = base.input(inputSchema)[procKind](({ input, ctx }) => {
6567
- return requireLocal(capName, () => getLocal(ctx), services)[method.name]?.(input);
6579
+ return invokeCapMethod(requireLocal(capName, () => getLocal(ctx), services), method, input, capName, isCollection, services);
6568
6580
  });
6569
6581
  }
6570
6582
  return primitives.router(procedures);
@@ -95389,7 +95401,6 @@ Object.defineProperty(exports, "installPythonRequirements", {
95389
95401
  return _camstack_types_node.installPythonRequirements;
95390
95402
  }
95391
95403
  });
95392
- exports.ipcChildLink = require_manifest_python_deps.ipcChildLink;
95393
95404
  exports.ipcParentLink = require_manifest_python_deps.ipcParentLink;
95394
95405
  exports.isAddonDeploySource = isAddonDeploySource;
95395
95406
  exports.isArrayOutputSchema = require_dist.isArrayOutputSchema;
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 { At as asJsonObject$1, B as extractNestedAddonId, Bt as parseJsonObject, Ct as DEVICE_STATUS_METHOD, Dt as ReadinessRegistry, H as isArrayOutputSchema, Ht as readinessKey, It as expandCapMethods, J as lifecycleJobSchema, K as isVoidInput, Kt as EventCategory$1, Mt as asString$1, Nt as createEvent, Ot as ReadinessTimeoutError, Pt as emitDownForOwnedCaps, Q as looseSchema, St as DEVICE_SETTINGS_CONTRIBUTION_METHODS, U as isCollectionArrayMethod, Ut as resolveCapMount, Vt as parseJsonUnknown$1, W as isObjectInput, Wt as scopeKey, Z as logLevelAtMost, at as resolveMethodAuth, ct as scopesAllowDeviceCap, d as METHOD_ACCESS_MAP, f as RUNTIME_DEFAULTS, it as procedureAuthKey, jt as asNumber, q as kebabToCamel, st as scopesAllowAddon, t as ALL_CAPABILITY_DEFINITIONS, tt as objectInputDeclaresAddonId, xt as DATAPLANE_SECRET_HEADER$1, y as addonSettingsCapability, yt as errMsg$1 } from "./dist-D595vzqY.mjs";
2
+ import { At as asJsonObject$1, B as extractNestedAddonId, Bt as parseJsonObject, Ct as DEVICE_STATUS_METHOD, Dt as ReadinessRegistry, H as isArrayOutputSchema, Ht as readinessKey, It as expandCapMethods, J as lifecycleJobSchema, K as isVoidInput, Kt as EventCategory$1, Mt as asString$1, Nt as createEvent, Ot as ReadinessTimeoutError, Pt as emitDownForOwnedCaps, Q as looseSchema, St as DEVICE_SETTINGS_CONTRIBUTION_METHODS, U as isCollectionArrayMethod, Ut as resolveCapMount, Vt as parseJsonUnknown$1, W as isObjectInput, Wt as scopeKey, Z as logLevelAtMost, at as resolveMethodAuth, ct as scopesAllowDeviceCap, d as METHOD_ACCESS_MAP, f as RUNTIME_DEFAULTS, it as procedureAuthKey, jt as asNumber, q as kebabToCamel, st as scopesAllowAddon, t as ALL_CAPABILITY_DEFINITIONS, tt as objectInputDeclaresAddonId, xt as DATAPLANE_SECRET_HEADER$1, y as addonSettingsCapability, yt as errMsg$1 } from "./dist-6mn3LQvB.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-CQhPGSJm.mjs";
28
- import { $ as buildNativeCapProxy, A as createHubCapForwardService, At as buildHeapSample, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as runNpm, D as localProviderLink, Dt as HEAP_WATCH_INTERVAL_MS, E as ipcParentLink, Et as HEAP_RECLAIM_TRIGGER_MB, F as createUdsLogger, Ft as strandedMb, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, Mt as shouldReclaim, N as createUdsEventBus, Nt as startHeapWatch, O as HUB_CAP_FWD_ACTION, Ot as HEAP_WATCH_WARN_RATIO, P as udsChildLogToWorkerEntry, Pt as startRunnerHeapWatch, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as resolveNpmInvocation, T as ipcChildLink, Tt as HEAP_RECLAIM_MIN_INTERVAL_MS, 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, jt as createV8Reclaimer, k as HUB_CAP_FWD_SERVICE, kt as RUNNER_HEAP_WATCH_INTERVAL_MS, 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 resolveAddonClass, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-08rqn6xN.mjs";
28
+ import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, At as createV8Reclaimer, B as AGENT_CAP_FWD_SERVICE, C as brokerTransportLink, Ct as createAddonDataPlaneFacility, D as HUB_CAP_FWD_ACTION, Dt as HEAP_WATCH_WARN_RATIO, E as localProviderLink, Et as HEAP_WATCH_INTERVAL_MS, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, Mt as startHeapWatch, N as udsChildLogToWorkerEntry, Nt as startRunnerHeapWatch, O as HUB_CAP_FWD_SERVICE, Ot as RUNNER_HEAP_WATCH_INTERVAL_MS, P as createUdsLogger, Pt as strandedMb, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerCallForCap, St as runNpm, T as ipcParentLink, Tt as HEAP_RECLAIM_TRIGGER_MB, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as createKernelHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as __resetCapUsageRegistryForTests, bt as resolveAddonClass, c as setHubConnected, ct as capActionName, d as getBrokerEventBus, dt as capServiceName, et as createBrokerDeviceManagerApi, f as getMoleculerEventStats, ft as parseCapAction, g as AddonDepsManager, gt as CapabilityHandle, h as subscribePassthrough, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, jt as shouldReclaim, k as createHubCapForwardService, kt as buildHeapSample, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as setNodeEventInterest, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as registerEventBusService, pt as deserializeTypedArrays, q as UdsLocalTransportServer, r as createAddonContext, rt as mountNativeCapService, s as getOrInitReadinessRegistryForClient, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestPythonDeps, u as clusterEventTopic, ut as capBareAction, v as resolveHwAccel, vt as copyBundledNativeModules, w as buildLinkChain, wt as HEAP_RECLAIM_MIN_INTERVAL_MS, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as installManifestNativeDeps, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-D3zYlMEa.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";
@@ -6403,11 +6403,31 @@ function methodsFor(def) {
6403
6403
  schema: m,
6404
6404
  isVoid: isVoidInput(m.input),
6405
6405
  isObject: isObjectInput(m.input),
6406
- callerRequired: m.caller === "required"
6406
+ callerRequired: m.caller === "required",
6407
+ isArrayOutput: m.kind !== "subscription" && isArrayOutputSchema(m.output)
6407
6408
  };
6408
6409
  });
6409
6410
  }
6410
6411
  /**
6412
+ * Invoke `method.name` on a resolved provider, raising the canonical
6413
+ * "method not found" error (Task 7.5d) when the provider does not implement
6414
+ * it — the naive `provider[method.name]?.(payload)` optional call let a
6415
+ * missing method answer `undefined` (200 to the caller). EXCEPTION, mirrored
6416
+ * from `child-cap-dispatch.ts`'s `isCollectionListMethod` graceful skip: a
6417
+ * COLLECTION cap's array-output method degrades to `[]` — the hub fans that
6418
+ * method across every registered provider
6419
+ * (`resolveCollectionProvider`/`concatArrayMethod`), so ONE provider not
6420
+ * implementing it is a graceful skip, not an error. Every other missing
6421
+ * method (singleton, device-native, or a collection's SCALAR method) is a
6422
+ * real implementation gap and fails loud.
6423
+ */
6424
+ function invokeCapMethod(provider, method, payload, capName, isCollection, services) {
6425
+ const fn = provider[method.name];
6426
+ if (typeof fn === "function") return fn(payload);
6427
+ if (isCollection && method.isArrayOutput) return [];
6428
+ return (services.methodNotFound ?? ((cap, m) => services.badRequest(`Capability "${cap}" has no method "${m}"`)))(capName, method.name);
6429
+ }
6430
+ /**
6411
6431
  * Extract the authenticated caller identity from the (structurally
6412
6432
  * unknown) tRPC context. The builder cannot import the server's
6413
6433
  * `TrpcContext`, so the read is narrowing-based: `ctx.user.id` (string)
@@ -6527,37 +6547,29 @@ function buildOneCapRouter(def, primitives, services) {
6527
6547
  }).optional() : z.object({ nodeId: z.string().optional() }).optional();
6528
6548
  procedures[method.name] = base.input(voidSelector)[procKind](({ input, ctx }) => {
6529
6549
  const sel = input ?? {};
6530
- 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]?.();
6550
+ return invokeCapMethod(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, void 0, capName, isCollection, services);
6531
6551
  });
6532
6552
  continue;
6533
6553
  }
6534
6554
  if (method.isObject) {
6535
6555
  const schema = nodeIdData ? inputSchema : looseSchema(inputSchema);
6536
6556
  procedures[method.name] = base.input(schema)[procKind](({ input, ctx }) => {
6537
- if (nodeIdData) {
6538
- const provider = requireLocal(capName, () => getLocal(ctx), services);
6539
- const payload = method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input;
6540
- return provider[method.name]?.(payload);
6541
- }
6557
+ if (nodeIdData) return invokeCapMethod(requireLocal(capName, () => getLocal(ctx), services), method, method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input, capName, isCollection, services);
6542
6558
  if (isCollection) {
6543
6559
  const { rest, picked } = stripKeys(input, ["nodeId", "addonId"]);
6544
6560
  const nodeId = typeof picked.nodeId === "string" ? picked.nodeId : void 0;
6545
6561
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
6546
6562
  const canRecoverNestedAddonId = !isArrayOutputSchema(method.schema.output) && !objectInputDeclaresAddonId(method.schema.input);
6547
6563
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? extractNestedAddonId(rest) : void 0);
6548
- const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId);
6549
- const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6550
- return provider[method.name]?.(payload);
6564
+ return invokeCapMethod(resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services, topLevelAddonId), method, method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest, capName, isCollection, services);
6551
6565
  }
6552
6566
  const { rest, picked } = stripKeys(input, ["nodeId"]);
6553
- const provider = resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services);
6554
- const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
6555
- return provider[method.name]?.(payload);
6567
+ return invokeCapMethod(resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services), method, method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest, capName, isCollection, services);
6556
6568
  });
6557
6569
  continue;
6558
6570
  }
6559
6571
  procedures[method.name] = base.input(inputSchema)[procKind](({ input, ctx }) => {
6560
- return requireLocal(capName, () => getLocal(ctx), services)[method.name]?.(input);
6572
+ return invokeCapMethod(requireLocal(capName, () => getLocal(ctx), services), method, input, capName, isCollection, services);
6561
6573
  });
6562
6574
  }
6563
6575
  return primitives.router(procedures);
@@ -95101,4 +95113,4 @@ var LifecycleJobEngine = class {
95101
95113
  }
95102
95114
  };
95103
95115
  //#endregion
95104
- 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, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, 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_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, 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, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, 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, __resetCapUsageRegistryForTests, 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, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
95116
+ 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, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, 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_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, 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, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, 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, __resetCapUsageRegistryForTests, 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, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -91,6 +91,19 @@ export interface CapRouterServices {
91
91
  * fallthrough rather than crashing.
92
92
  */
93
93
  readonly rejectUnresolvedAddonPin?: (capName: string, addonId: string) => void;
94
+ /**
95
+ * Raise the canonical error for a resolved provider that does NOT
96
+ * implement `method` (Task 7.5d). Before this existed the router called
97
+ * `provider[method.name]?.(payload)` — an optional call that let a missing
98
+ * method answer `undefined`, which tRPC serializes as a 200. The UDS child
99
+ * dispatcher (`child-cap-dispatch.ts`) hits the SAME condition (a provider
100
+ * missing a method) and THROWS; two authorities disagreeing about the same
101
+ * defect is worse than either alone, and the hub's silence is the one a
102
+ * caller cannot detect. OPTIONAL for framework-live-update version skew: an
103
+ * older server hands a services object without it; the builder falls back
104
+ * to `badRequest` so the call still fails closed instead of answering 200.
105
+ */
106
+ readonly methodNotFound?: (capName: string, method: string) => never;
94
107
  }
95
108
  /**
96
109
  * Build a single capability's router (the runtime equivalent of one
@@ -65,7 +65,7 @@ export type { HubServiceDeps } from './moleculer/hub-service.js';
65
65
  export { createBrokerDeviceManagerApi, buildNativeCapProxy, buildUdsNativeCapProxy, mountNativeCapService, NATIVE_PROVIDER_SERVICE_INFIX, } from './moleculer/device-cap-proxy.js';
66
66
  export type { WorkerDeviceManagerOptions } from './moleculer/device-cap-proxy.js';
67
67
  export { getWorkerDeviceRegistry } from './moleculer/addon-context-factory.js';
68
- export { localProviderLink, brokerTransportLink, ipcChildLink, ipcParentLink, buildLinkChain, brokerCallForCap, } from './moleculer/trpc-links.js';
68
+ export { localProviderLink, brokerTransportLink, ipcParentLink, buildLinkChain, brokerCallForCap, } from './moleculer/trpc-links.js';
69
69
  export type { LocalProviderResolver, BrokerCapCallOpts } from './moleculer/trpc-links.js';
70
70
  export { createProcessService } from './moleculer/process-service.js';
71
71
  export type { ProcessInfo } from './moleculer/process-service.js';
@@ -1,7 +1,7 @@
1
1
  import { TRPCLink } from '@trpc/client';
2
2
  import { AnyRouter } from '@trpc/server';
3
3
  import { ServiceBroker } from 'moleculer';
4
- import { CapCallInput, LocalChildRegistry } from '../transport/index.js';
4
+ import { CapCallInput } from '../transport/index.js';
5
5
  /**
6
6
  * Resolver for in-process capability providers.
7
7
  *
@@ -171,17 +171,6 @@ export interface BrokerTransportLinkOptions {
171
171
  readonly discoveryTimeoutMs?: number;
172
172
  }
173
173
  export declare function brokerTransportLink<TRouter extends AnyRouter>(broker: ServiceBroker, serviceMap?: Readonly<Record<string, string>>, observerOpts?: CapUsageObserverOptions, linkOptions?: BrokerTransportLinkOptions): TRPCLink<TRouter>;
174
- /**
175
- * Middle link that routes a cap op to a LOCAL addon-runner over UDS via the
176
- * `LocalChildRegistry`. If no local child owns `(capName, deviceId?)`, the op
177
- * passes through to `next(op)` (e.g. `brokerTransportLink` for remote agents),
178
- * so this link is transparent for everything it does not own.
179
- *
180
- * `deviceId` for device-scoped caps is read from `op.input` (the same place
181
- * the codegen'd device-scoped routers carry it); the full `op.input` is
182
- * forwarded as the child method's argument.
183
- */
184
- export declare function ipcChildLink<TRouter extends AnyRouter>(registry: LocalChildRegistry): TRPCLink<TRouter>;
185
174
  /**
186
175
  * Middle link that routes a child addon's outbound `ctx.api` cap call to the
187
176
  * parent hub over UDS via `callOut` (obtained at call-time so the child can
@@ -114,6 +114,19 @@ export interface AgentCapForwardParams {
114
114
  */
115
115
  readonly childId?: string;
116
116
  readonly deviceId?: number;
117
+ /**
118
+ * Out-of-band PROVIDER-selection hint — the twin of `CapCallMessage.addonId`
119
+ * (Task 7.5a). A GROUPED runner (`execution.group`) on an AGENT can host two
120
+ * co-located addons registering the SAME collection cap, exactly like the
121
+ * hub-local-uds case (`LocalChildRegistry.toCapCall`'s `addonId`, threaded by
122
+ * `buildCapCallFn`'s hub-local branch). Before this field existed, the hub had
123
+ * no channel to carry the selector across the hub→agent envelope — grouped-
124
+ * runner provider selection worked on the hub and silently fell back to
125
+ * "whichever provider is first" on an agent. Absent → the agent dispatch falls
126
+ * back to its sole provider for the cap (same fallback `child-cap-dispatch.ts`
127
+ * already has for a call that never carried the hint).
128
+ */
129
+ readonly addonId?: string;
117
130
  }
118
131
  /** The Moleculer service name that Task 6's agent registers. */
119
132
  export declare const AGENT_CAP_FWD_SERVICE: "$agent-cap-fwd";
@@ -170,7 +183,28 @@ export declare class CapRouteResolver {
170
183
  * caller then falls through to its remote-resolution branch.
171
184
  */
172
185
  resolveHubLocalUdsRoute(capName: string, deviceId?: number): HubLocalUdsRoute | null;
173
- dispatch(route: CapRoute, method: string, args: unknown): Promise<unknown>;
186
+ /**
187
+ * @param addonId Optional out-of-band PROVIDER-selection hint (Task 7.5a):
188
+ * the addonId of the provider the CALLER already resolved (e.g.
189
+ * `buildCapCallFn`'s `deps.addonId` for a registered grouped-runner
190
+ * provider). Only meaningful for `agent-child-forward` — a `remote-moleculer`
191
+ * route already encodes the provider in its action name
192
+ * (`${addonId}.${cap}.${method}`, via `NodeCapAuthority.getAddonId`), and a
193
+ * `hub-local-uds` caller that already knows the addonId (`buildCapCallFn`)
194
+ * talks to `LocalChildRegistry.callCapOnChild` directly rather than through
195
+ * `dispatch`.
196
+ * @param callerAddonId Optional out-of-band CALLER-identity hint — the
197
+ * addon that ORIGINATED the call, distinct from `addonId` above (which
198
+ * names the resolved PROVIDER, not the caller). Set by
199
+ * `onUnownedCall` from `CapCallInput.callerAddonId`
200
+ * (`LocalChildRegistry` stamped it off the registered `childId`). Only
201
+ * the `hub-in-process` branch consumes it — merged into `args` so a
202
+ * diagnostic tool deep in that provider (e.g. device-manager's
203
+ * fleet-read census) can read it without every provider method changing
204
+ * signature, the same "extra field the provider destructures or
205
+ * ignores" convention `nodeId` already uses on this path.
206
+ */
207
+ dispatch(route: CapRoute, method: string, args: unknown, addonId?: string, callerAddonId?: string): Promise<unknown>;
174
208
  /**
175
209
  * Inner dispatch: may throw CapRouteError (validation failures) or arbitrary
176
210
  * transport errors. The outer `dispatch` wraps non-CapRouteErrors.
@@ -136,6 +136,20 @@ export interface CapCallMessage {
136
136
  * the child dispatch falls back to its sole provider for the cap.
137
137
  */
138
138
  readonly addonId?: string;
139
+ /**
140
+ * Out-of-band CALLER-identity hint — the addon that ORIGINATED this call,
141
+ * as distinct from {@link addonId} (which names the resolved PROVIDER).
142
+ * Set ONLY by `LocalChildRegistry` when it turns a registered child's
143
+ * `cap-call-out` into a `CapCallInput` for `onUnownedCall`: the parent
144
+ * already knows which `childId` sent the message (it owns the UDS
145
+ * connection the frame arrived on), and stamps it here rather than
146
+ * trusting anything the child claims in its `args`. Absent for a call that
147
+ * did not arrive over the cap channel (hub-in-process, HTTP/tRPC) — those
148
+ * callers are attributed by other means (see
149
+ * `fleet-read-census.ts#siteOf`). A provider that does not care about its
150
+ * caller simply never reads it.
151
+ */
152
+ readonly callerAddonId?: string;
139
153
  /**
140
154
  * Native-only routing hint — see {@link CapCallOutMessage.native}. Carried
141
155
  * here because `CapCallInput` (the type every parent-side router takes) is
@@ -4735,6 +4735,24 @@ function extractNodeId(args) {
4735
4735
  const raw = Reflect.get(args, "nodeId");
4736
4736
  return typeof raw === "string" && raw.length > 0 ? raw : void 0;
4737
4737
  }
4738
+ /**
4739
+ * Merge `callerAddonId` into `args` as an extra field — the SAME "provider
4740
+ * destructures what it needs and ignores the rest" convention
4741
+ * {@link extractNodeId} already relies on for the inline `nodeId` pin.
4742
+ * `undefined` (the overwhelmingly common case: no caller hint, or the census
4743
+ * consuming it is disarmed) returns `args` unchanged — no allocation. A
4744
+ * non-object `args` (or `null`/array) is returned unchanged too: there is
4745
+ * nowhere to attach an extra key without changing the payload's shape, and a
4746
+ * provider taking a bare value never reads `callerAddonId` off it anyway.
4747
+ */
4748
+ function withCallerAddonId(args, callerAddonId) {
4749
+ if (callerAddonId === void 0) return args;
4750
+ if (args === null || typeof args !== "object" || Array.isArray(args)) return args;
4751
+ return {
4752
+ ...args,
4753
+ callerAddonId
4754
+ };
4755
+ }
4738
4756
  var CapRouteResolver = class {
4739
4757
  hubNodeId;
4740
4758
  broker;
@@ -4792,9 +4810,30 @@ var CapRouteResolver = class {
4792
4810
  childId
4793
4811
  };
4794
4812
  }
4795
- async dispatch(route, method, args) {
4813
+ /**
4814
+ * @param addonId Optional out-of-band PROVIDER-selection hint (Task 7.5a):
4815
+ * the addonId of the provider the CALLER already resolved (e.g.
4816
+ * `buildCapCallFn`'s `deps.addonId` for a registered grouped-runner
4817
+ * provider). Only meaningful for `agent-child-forward` — a `remote-moleculer`
4818
+ * route already encodes the provider in its action name
4819
+ * (`${addonId}.${cap}.${method}`, via `NodeCapAuthority.getAddonId`), and a
4820
+ * `hub-local-uds` caller that already knows the addonId (`buildCapCallFn`)
4821
+ * talks to `LocalChildRegistry.callCapOnChild` directly rather than through
4822
+ * `dispatch`.
4823
+ * @param callerAddonId Optional out-of-band CALLER-identity hint — the
4824
+ * addon that ORIGINATED the call, distinct from `addonId` above (which
4825
+ * names the resolved PROVIDER, not the caller). Set by
4826
+ * `onUnownedCall` from `CapCallInput.callerAddonId`
4827
+ * (`LocalChildRegistry` stamped it off the registered `childId`). Only
4828
+ * the `hub-in-process` branch consumes it — merged into `args` so a
4829
+ * diagnostic tool deep in that provider (e.g. device-manager's
4830
+ * fleet-read census) can read it without every provider method changing
4831
+ * signature, the same "extra field the provider destructures or
4832
+ * ignores" convention `nodeId` already uses on this path.
4833
+ */
4834
+ async dispatch(route, method, args, addonId, callerAddonId) {
4796
4835
  try {
4797
- return await this.dispatchInner(route, method, args);
4836
+ return await this.dispatchInner(route, method, args, addonId, callerAddonId);
4798
4837
  } catch (err) {
4799
4838
  if (err instanceof CapRouteError) throw err;
4800
4839
  const nodeId = this.routeNodeId(route);
@@ -4813,9 +4852,9 @@ var CapRouteResolver = class {
4813
4852
  * Inner dispatch: may throw CapRouteError (validation failures) or arbitrary
4814
4853
  * transport errors. The outer `dispatch` wraps non-CapRouteErrors.
4815
4854
  */
4816
- async dispatchInner(route, method, args) {
4855
+ async dispatchInner(route, method, args, addonId, callerAddonId) {
4817
4856
  switch (route.kind) {
4818
- case "hub-in-process": return route.ref.invoke(method, args);
4857
+ case "hub-in-process": return route.ref.invoke(method, withCallerAddonId(args, callerAddonId));
4819
4858
  case "hub-local-uds": {
4820
4859
  const registry = this.hubLocalRegistry;
4821
4860
  if (registry === null) throw new CapRouteError(route.capName, method, {
@@ -4859,7 +4898,8 @@ var CapRouteResolver = class {
4859
4898
  method,
4860
4899
  args,
4861
4900
  ...route.childId !== void 0 ? { childId: route.childId } : {},
4862
- ...deviceId !== void 0 ? { deviceId } : {}
4901
+ ...deviceId !== void 0 ? { deviceId } : {},
4902
+ ...addonId !== void 0 ? { addonId } : {}
4863
4903
  };
4864
4904
  return callWithServiceDiscovery(this.broker, AGENT_CAP_FWD_SERVICE, AGENT_CAP_FWD_ACTION, params, {
4865
4905
  nodeID: route.agentNodeId,
@@ -5356,7 +5396,8 @@ var LocalChildRegistry = class {
5356
5396
  args: out.args,
5357
5397
  ...out.deviceId !== void 0 ? { deviceId: out.deviceId } : {},
5358
5398
  ...out.nodeId !== void 0 ? { nodeId: out.nodeId } : {},
5359
- ...out.native === true ? { native: true } : {}
5399
+ ...out.native === true ? { native: true } : {},
5400
+ ...childId !== null ? { callerAddonId: childId } : {}
5360
5401
  };
5361
5402
  const pinnedNodeId = out.nodeId ?? extractNodeId(out.args);
5362
5403
  const pinTargetsThisNode = pinnedNodeId !== void 0 && this.ownNodeId !== void 0 && pinnedNodeId === this.ownNodeId;
@@ -5965,7 +6006,7 @@ function createParentUnownedCallHandler(deps) {
5965
6006
  ...nodeId !== void 0 ? { nodeId } : {},
5966
6007
  ...deviceId !== void 0 ? { deviceId } : {}
5967
6008
  });
5968
- return await resolver.dispatch(route, input.method, input.args);
6009
+ return input.callerAddonId !== void 0 ? await resolver.dispatch(route, input.method, input.args, void 0, input.callerAddonId) : await resolver.dispatch(route, input.method, input.args);
5969
6010
  } catch (err) {
5970
6011
  if (!(err instanceof CapRouteError) || err.reason !== "no-provider") throw err;
5971
6012
  }
@@ -6444,45 +6485,6 @@ function brokerTransportLink(broker, serviceMap, observerOpts, linkOptions) {
6444
6485
  };
6445
6486
  }
6446
6487
  /**
6447
- * Middle link that routes a cap op to a LOCAL addon-runner over UDS via the
6448
- * `LocalChildRegistry`. If no local child owns `(capName, deviceId?)`, the op
6449
- * passes through to `next(op)` (e.g. `brokerTransportLink` for remote agents),
6450
- * so this link is transparent for everything it does not own.
6451
- *
6452
- * `deviceId` for device-scoped caps is read from `op.input` (the same place
6453
- * the codegen'd device-scoped routers carry it); the full `op.input` is
6454
- * forwarded as the child method's argument.
6455
- */
6456
- function ipcChildLink(registry) {
6457
- return () => {
6458
- return ({ op, next }) => {
6459
- const parsed = parsePath(op.path);
6460
- if (!parsed) return next(op);
6461
- const input = op.input;
6462
- const inputObj = input && typeof input === "object" && !Array.isArray(input) ? input : null;
6463
- const deviceId = inputObj && typeof inputObj.deviceId === "number" ? inputObj.deviceId : void 0;
6464
- if (registry.resolveChildId(parsed.capName, deviceId) === null) return next(op);
6465
- return observable((observer) => {
6466
- registry.callCap({
6467
- capName: parsed.capName,
6468
- method: parsed.method,
6469
- args: op.input,
6470
- deviceId
6471
- }).then((data) => {
6472
- observer.next({ result: {
6473
- type: "data",
6474
- data
6475
- } });
6476
- observer.complete();
6477
- }).catch((cause) => {
6478
- observer.error(TRPCClientError.from(cause instanceof Error ? cause : new Error(String(cause))));
6479
- });
6480
- return () => {};
6481
- });
6482
- };
6483
- };
6484
- }
6485
- /**
6486
6488
  * Middle link that routes a child addon's outbound `ctx.api` cap call to the
6487
6489
  * parent hub over UDS via `callOut` (obtained at call-time so the child can
6488
6490
  * reconnect without rebuilding its tRPC client).
@@ -8175,4 +8177,4 @@ async function installManifestPythonDeps(declaration, addonDir, deps, logger) {
8175
8177
  await deps.installPythonRequirements(reqAbs);
8176
8178
  }
8177
8179
  //#endregion
8178
- export { buildNativeCapProxy as $, createHubCapForwardService as A, buildHeapSample as At, AGENT_CAP_FWD_ACTION as B, brokerTransportLink as C, runNpm as Ct, localProviderLink as D, HEAP_WATCH_INTERVAL_MS as Dt, ipcParentLink as E, HEAP_RECLAIM_TRIGGER_MB as Et, createUdsLogger as F, strandedMb as Ft, callWithServiceDiscovery as G, CapRouteResolver as H, createUdsLoggerWithControl as I, UdsLocalTransportServer as J, createLocalTransport as K, LocalChildClient as L, createUdsEventBridge as M, shouldReclaim as Mt, createUdsEventBus as N, startHeapWatch as Nt, HUB_CAP_FWD_ACTION as O, HEAP_WATCH_WARN_RATIO as Ot, udsChildLogToWorkerEntry as P, startRunnerHeapWatch as Pt, encodeFrame as Q, LocalChildRegistry as R, brokerCallForCap as S, resolveNpmInvocation as St, ipcChildLink as T, HEAP_RECLAIM_MIN_INTERVAL_MS as Tt, CapRouteError as U, AGENT_CAP_FWD_SERVICE as V, classifyCapRoute as W, localEndpointPath as X, SocketChannel as Y, FrameDecoder as Z, createKernelHwAccel as _, CapabilityHandle as _t, getWorkerDeviceRegistry as a, setWorkerNativeCapsChangeListener as at, __resetCapUsageRegistryForTests as b, installManifestNativeDeps as bt, setHubConnected as c, NATIVE_PROVIDER_SERVICE_INFIX as ct, getBrokerEventBus as d, capBareAction as dt, buildUdsNativeCapProxy as et, getMoleculerEventStats as f, capServiceName as ft, AddonDepsManager as g, DeviceRegistry as gt, subscribePassthrough as h, serializeTypedArrays as ht, createUdsAddonContext as i, mountNativeCapService as it, createParentUnownedCallHandler as j, createV8Reclaimer as jt, HUB_CAP_FWD_SERVICE as k, RUNNER_HEAP_WATCH_INTERVAL_MS as kt, EVENT_TOPIC_PREFIX as l, capActionName as lt, setNodeEventInterest as m, deserializeTypedArrays as mt, adaptBrokerToCluster as n, getWorkerNativeCapProvider as nt, getOrInitReadinessRegistry as o, createAddonService as ot, registerEventBusService as p, parseCapAction as pt, UdsLocalTransportClient as q, createAddonContext as r, getWorkerNativeCapSnapshot as rt, getOrInitReadinessRegistryForClient as s, validateProviderRegistrations as st, installManifestPythonDeps as t, createBrokerDeviceManagerApi as tt, clusterEventTopic as u, capActionSuffix as ut, resolveHwAccel as v, CapabilityUnavailableError as vt, buildLinkChain as w, createAddonDataPlaneFacility as wt, getCapUsageRegistry as x, resolveAddonClass as xt, CapUsageRegistry as y, copyBundledNativeModules as yt, UDS_NO_ROUTE_PREFIX as z };
8180
+ export { buildUdsNativeCapProxy as $, createParentUnownedCallHandler as A, createV8Reclaimer as At, AGENT_CAP_FWD_SERVICE as B, brokerTransportLink as C, createAddonDataPlaneFacility as Ct, HUB_CAP_FWD_ACTION as D, HEAP_WATCH_WARN_RATIO as Dt, localProviderLink as E, HEAP_WATCH_INTERVAL_MS as Et, createUdsLoggerWithControl as F, createLocalTransport as G, CapRouteError as H, LocalChildClient as I, SocketChannel as J, UdsLocalTransportClient as K, LocalChildRegistry as L, createUdsEventBus as M, startHeapWatch as Mt, udsChildLogToWorkerEntry as N, startRunnerHeapWatch as Nt, HUB_CAP_FWD_SERVICE as O, RUNNER_HEAP_WATCH_INTERVAL_MS as Ot, createUdsLogger as P, strandedMb as Pt, buildNativeCapProxy as Q, UDS_NO_ROUTE_PREFIX as R, brokerCallForCap as S, runNpm as St, ipcParentLink as T, HEAP_RECLAIM_TRIGGER_MB as Tt, classifyCapRoute as U, CapRouteResolver as V, callWithServiceDiscovery as W, FrameDecoder as X, localEndpointPath as Y, encodeFrame as Z, createKernelHwAccel as _, CapabilityUnavailableError as _t, getWorkerDeviceRegistry as a, createAddonService as at, __resetCapUsageRegistryForTests as b, resolveAddonClass as bt, setHubConnected as c, capActionName as ct, getBrokerEventBus as d, capServiceName as dt, createBrokerDeviceManagerApi as et, getMoleculerEventStats as f, parseCapAction as ft, AddonDepsManager as g, CapabilityHandle as gt, subscribePassthrough as h, DeviceRegistry as ht, createUdsAddonContext as i, setWorkerNativeCapsChangeListener as it, createUdsEventBridge as j, shouldReclaim as jt, createHubCapForwardService as k, buildHeapSample as kt, EVENT_TOPIC_PREFIX as l, capActionSuffix as lt, setNodeEventInterest as m, serializeTypedArrays as mt, adaptBrokerToCluster as n, getWorkerNativeCapSnapshot as nt, getOrInitReadinessRegistry as o, validateProviderRegistrations as ot, registerEventBusService as p, deserializeTypedArrays as pt, UdsLocalTransportServer as q, createAddonContext as r, mountNativeCapService as rt, getOrInitReadinessRegistryForClient as s, NATIVE_PROVIDER_SERVICE_INFIX as st, installManifestPythonDeps as t, getWorkerNativeCapProvider as tt, clusterEventTopic as u, capBareAction as ut, resolveHwAccel as v, copyBundledNativeModules as vt, buildLinkChain as w, HEAP_RECLAIM_MIN_INTERVAL_MS as wt, getCapUsageRegistry as x, resolveNpmInvocation as xt, CapUsageRegistry as y, installManifestNativeDeps as yt, AGENT_CAP_FWD_ACTION as z };