@camstack/system 1.1.60 → 1.1.62

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 (47) hide show
  1. package/dist/addon-runner.js +2 -2
  2. package/dist/addon-runner.mjs +2 -2
  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/device-manager/device-manager.addon.js +1 -1
  14. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  15. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  16. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  17. package/dist/builtins/hub-forwarder/index.js +1 -1
  18. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  19. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  20. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  21. package/dist/builtins/local-network/local-network.addon.js +1 -1
  22. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  23. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  24. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  25. package/dist/builtins/platform-probe/index.js +8 -5
  26. package/dist/builtins/platform-probe/index.mjs +8 -5
  27. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  28. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  29. package/dist/builtins/snapshot/index.js +1 -1
  30. package/dist/builtins/snapshot/index.mjs +1 -1
  31. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  32. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  33. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
  34. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
  35. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  36. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  37. package/dist/builtins/system-config/system-config.addon.js +1 -1
  38. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  39. package/dist/builtins/winston-logging/index.js +1 -1
  40. package/dist/builtins/winston-logging/index.mjs +1 -1
  41. package/dist/{dist-BgR9fJpL.mjs → dist-BqC8e44T.mjs} +59 -18
  42. package/dist/{dist-BNdI6_MP.js → dist-Z2gkbfp8.js} +59 -18
  43. package/dist/index.js +32 -5
  44. package/dist/index.mjs +32 -5
  45. package/dist/{manifest-python-deps-RSxmZ-Fu.mjs → manifest-python-deps-DQVZZVNo.mjs} +1 -1
  46. package/dist/{manifest-python-deps-ClarMoI9.js → manifest-python-deps-Houw5lw4.js} +1 -1
  47. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-BNdI6_MP.js");
3
- const require_manifest_python_deps = require("./manifest-python-deps-ClarMoI9.js");
2
+ const require_dist = require("./dist-Z2gkbfp8.js");
3
+ const require_manifest_python_deps = require("./manifest-python-deps-Houw5lw4.js");
4
4
  const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
5
5
  let node_fs = require("node:fs");
6
6
  node_fs = require_chunk.__toESM(node_fs);
@@ -1,5 +1,5 @@
1
- import { M as isCollectionArrayMethod, t as ALL_CAPABILITY_DEFINITIONS } from "./dist-BgR9fJpL.mjs";
2
- import { F as createUdsLoggerWithControl, I as LocalChildClient, bt as resolveAddonClass, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, vt as installManifestNativeDeps } from "./manifest-python-deps-RSxmZ-Fu.mjs";
1
+ import { M as isCollectionArrayMethod, t as ALL_CAPABILITY_DEFINITIONS } from "./dist-BqC8e44T.mjs";
2
+ import { F as createUdsLoggerWithControl, I as LocalChildClient, bt as resolveAddonClass, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, vt as installManifestNativeDeps } from "./manifest-python-deps-DQVZZVNo.mjs";
3
3
  import { t as CustomActionRegistry } from "./custom-action-registry-BEXwC-oo.mjs";
4
4
  import { register } from "node:module";
5
5
  import * as fs from "node:fs";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_chunk.__toESM(node_fs);
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, at as BaseAddon, f as addonPagesCapability, it as errMsg } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, at as BaseAddon, f as addonPagesCapability, it as errMsg } from "../../dist-BqC8e44T.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import * as fs from "node:fs";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_chunk.__toESM(node_fs);
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, at as BaseAddon, it as errMsg, m as addonWidgetsCapability } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, at as BaseAddon, it as errMsg, m as addonWidgetsCapability } from "../../dist-BqC8e44T.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import * as fs from "node:fs";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  //#region src/builtins/alerts/alerts.addon.ts
8
8
  var CATEGORY_MAPPINGS = {
9
9
  "addon.crashed": {
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, at as BaseAddon, h as alertsCapability, it as errMsg, n as AlertSchema, vt as createEvent } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, at as BaseAddon, h as alertsCapability, it as errMsg, n as AlertSchema, vt as createEvent } from "../../dist-BqC8e44T.mjs";
2
2
  //#region src/builtins/alerts/alerts.addon.ts
3
3
  var CATEGORY_MAPPINGS = {
4
4
  "addon.crashed": {
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_fs$1 = require_chunk.__toESM(node_fs, 1);
9
9
  node_fs = require_chunk.__toESM(node_fs);
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, at as BaseAddon, v as backupCapability } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, at as BaseAddon, v as backupCapability } from "../../dist-BqC8e44T.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import Kt from "node:fs";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/console-logging/console-destination.ts
9
9
  var LEVEL_RANK = {
@@ -1,4 +1,4 @@
1
- import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BgR9fJpL.mjs";
1
+ import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BqC8e44T.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/console-logging/console-destination.ts
4
4
  var LEVEL_RANK = {
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let _camstack_types_node = require("@camstack/types/node");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { A as getByPath, At as EventCategory, Ct as isDeviceConfigCap, D as evaluateLinkExpression, E as enumerateSchemaFields, H as normalizeUnit, S as deviceStatusCapability, T as enumerateItemArrayFields, W as parseStreamParamsFormPatch, Y as setByPath, a as DeviceStatusSchema, at as BaseAddon, b as deviceManagerCapability, c as STREAM_PROFILE_META, dt as DeviceType, g as applyTransform, i as CAP_NAMES_WITH_STATUS, it as errMsg, kt as sleep, lt as DeviceFeature, mt as WELL_KNOWN_TAB_MAP, rt as validateExpressionSource, t as ALL_CAPABILITY_DEFINITIONS, tt as toExpressionValue, ut as DeviceRole, x as deviceStateCapability, y as buildStreamParamsConfigSchema } from "../../dist-BgR9fJpL.mjs";
1
+ import { A as getByPath, At as EventCategory, Ct as isDeviceConfigCap, D as evaluateLinkExpression, E as enumerateSchemaFields, H as normalizeUnit, S as deviceStatusCapability, T as enumerateItemArrayFields, W as parseStreamParamsFormPatch, Y as setByPath, a as DeviceStatusSchema, at as BaseAddon, b as deviceManagerCapability, c as STREAM_PROFILE_META, dt as DeviceType, g as applyTransform, i as CAP_NAMES_WITH_STATUS, it as errMsg, kt as sleep, lt as DeviceFeature, mt as WELL_KNOWN_TAB_MAP, rt as validateExpressionSource, t as ALL_CAPABILITY_DEFINITIONS, tt as toExpressionValue, ut as DeviceRole, x as deviceStateCapability, y as buildStreamParamsConfigSchema } from "../../dist-BqC8e44T.mjs";
2
2
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  //#region src/builtins/doorbell/trigger-engine.ts
8
8
  /**
9
9
  * Pure trigger logic for the virtual-doorbell builtin — edge detection over
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, C as doorbellCapability, at as BaseAddon, dt as DeviceType, it as errMsg, vt as createEvent } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, C as doorbellCapability, at as BaseAddon, dt as DeviceType, it as errMsg, vt as createEvent } from "../../dist-BqC8e44T.mjs";
2
2
  //#region src/builtins/doorbell/trigger-engine.ts
3
3
  /**
4
4
  * Pure trigger logic for the virtual-doorbell builtin — edge detection over
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
9
9
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,4 +1,4 @@
1
- import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BgR9fJpL.mjs";
1
+ import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BqC8e44T.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
4
4
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_chunk.__toESM(node_crypto);
9
9
  let crypto$1 = require("crypto");
@@ -1,4 +1,4 @@
1
- import { _ as authProviderCapability, at as BaseAddon, d as UserRecordSchema, l as ScopedTokenSchema, nt as userManagementCapability, r as ApiKeyRecordSchema } from "../../dist-BgR9fJpL.mjs";
1
+ import { _ as authProviderCapability, at as BaseAddon, d as UserRecordSchema, l as ScopedTokenSchema, nt as userManagementCapability, r as ApiKeyRecordSchema } from "../../dist-BqC8e44T.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import * as crypto$1 from "node:crypto";
4
4
  import { randomUUID } from "node:crypto";
@@ -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-BNdI6_MP.js");
3
+ const require_dist = require("../../dist-Z2gkbfp8.js");
4
4
  let node_os = require("node:os");
5
5
  node_os = require_chunk.__toESM(node_os);
6
6
  //#region src/builtins/local-network/local-network.addon.ts
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, L as localNetworkCapability, at as BaseAddon } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, L as localNetworkCapability, at as BaseAddon } from "../../dist-BqC8e44T.mjs";
2
2
  import * as os from "node:os";
3
3
  //#region src/builtins/local-network/local-network.addon.ts
4
4
  /**
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_chunk.__toESM(node_fs);
9
9
  let node_child_process = require("node:child_process");
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, B as metricsProviderCapability, at as BaseAddon, vt as createEvent } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, B as metricsProviderCapability, at as BaseAddon, vt as createEvent } from "../../dist-BqC8e44T.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile, execFileSync } from "node:child_process";
4
4
  import { promisify } from "node:util";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_chunk.__toESM(node_fs);
9
9
  let node_child_process = require("node:child_process");
@@ -40,14 +40,17 @@ var DEFAULT_EDGETPU_LIB = "/data/deps/edgetpu/lib/libedgetpu.so.1";
40
40
  * wired through). Returns `null` when neither signal is found.
41
41
  */
42
42
  function classifyCoralAccelerator(fsx) {
43
+ let count = 0;
43
44
  for (const device of fsx.listUsbDevices()) {
44
45
  const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
45
46
  const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
46
- if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) return {
47
- type: "coral-edgetpu",
48
- bus: "usb"
49
- };
47
+ if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
50
48
  }
49
+ if (count > 0) return {
50
+ type: "coral-edgetpu",
51
+ bus: "usb",
52
+ count
53
+ };
51
54
  const libPath = process.env["CAMSTACK_EDGETPU_LIB"] ?? DEFAULT_EDGETPU_LIB;
52
55
  if (fsx.exists(libPath)) return {
53
56
  type: "coral-edgetpu",
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, G as platformProbeCapability, J as scoreRuntimes, at as BaseAddon, bt as emitReadiness, it as errMsg, w as enumerateInferenceDevices } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, G as platformProbeCapability, J as scoreRuntimes, at as BaseAddon, bt as emitReadiness, it as errMsg, w as enumerateInferenceDevices } from "../../dist-BqC8e44T.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
@@ -33,14 +33,17 @@ var DEFAULT_EDGETPU_LIB = "/data/deps/edgetpu/lib/libedgetpu.so.1";
33
33
  * wired through). Returns `null` when neither signal is found.
34
34
  */
35
35
  function classifyCoralAccelerator(fsx) {
36
+ let count = 0;
36
37
  for (const device of fsx.listUsbDevices()) {
37
38
  const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
38
39
  const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
39
- if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) return {
40
- type: "coral-edgetpu",
41
- bus: "usb"
42
- };
40
+ if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
43
41
  }
42
+ if (count > 0) return {
43
+ type: "coral-edgetpu",
44
+ bus: "usb",
45
+ count
46
+ };
44
47
  const libPath = process.env["CAMSTACK_EDGETPU_LIB"] ?? DEFAULT_EDGETPU_LIB;
45
48
  if (fsx.exists(libPath)) return {
46
49
  type: "coral-edgetpu",
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
8
8
  /**
9
9
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, at as BaseAddon } from "../../dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory, at as BaseAddon } from "../../dist-BqC8e44T.mjs";
2
2
  //#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
3
3
  /**
4
4
  * Reconcile the durable `enabledProviders` set against authoritative
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_child_process = require("node:child_process");
8
8
  //#region src/builtins/snapshot/snapshot-coalescing.ts
9
9
  /**
@@ -1,4 +1,4 @@
1
- import { V as nodePin, Z as snapshotCapability, at as BaseAddon, dt as DeviceType, et as streamQualityLabel, it as errMsg, lt as DeviceFeature } from "../../dist-BgR9fJpL.mjs";
1
+ import { V as nodePin, Z as snapshotCapability, at as BaseAddon, dt as DeviceType, et as streamQualityLabel, it as errMsg, lt as DeviceFeature } from "../../dist-BqC8e44T.mjs";
2
2
  import { execFile } from "node:child_process";
3
3
  //#region src/builtins/snapshot/snapshot-coalescing.ts
4
4
  /**
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_chunk.__toESM(node_fs);
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { $ as storageProviderCapability, at as BaseAddon, k as filesystemBrowseCapability } from "../../dist-BgR9fJpL.mjs";
1
+ import { $ as storageProviderCapability, at as BaseAddon, k as filesystemBrowseCapability } from "../../dist-BqC8e44T.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import * as path$1 from "node:path";
4
4
  import { basename, dirname, join, resolve, sep } from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let better_sqlite3 = require("better-sqlite3");
9
9
  better_sqlite3 = require_chunk.__toESM(better_sqlite3);
@@ -1,4 +1,4 @@
1
- import { Tt as parseJsonUnknown, X as settingsStoreCapability, at as BaseAddon, ht as asJsonObject, it as errMsg, s as RUNTIME_DEFAULTS } from "../../dist-BgR9fJpL.mjs";
1
+ import { Tt as parseJsonUnknown, X as settingsStoreCapability, at as BaseAddon, ht as asJsonObject, it as errMsg, s as RUNTIME_DEFAULTS } from "../../dist-BqC8e44T.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import Database from "better-sqlite3";
4
4
  //#region src/builtins/sqlite-storage/sqlite-settings-backend.ts
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_chunk.__toESM(node_path);
9
9
  let node_fs_promises = require("node:fs/promises");
@@ -1,4 +1,4 @@
1
- import { Q as storageCapability, at as BaseAddon, u as StorageLocationTypeSchema, wt as parseJsonObject } from "../../dist-BgR9fJpL.mjs";
1
+ import { Q as storageCapability, at as BaseAddon, u as StorageLocationTypeSchema, wt as parseJsonObject } from "../../dist-BqC8e44T.mjs";
2
2
  import * as path$1 from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { buildStorageLocationRegistry } from "@camstack/system";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  //#region src/builtins/system-config/system-config.addon.ts
8
8
  /**
9
9
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -1,4 +1,4 @@
1
- import { St as hydrateSchema, at as BaseAddon, it as errMsg } from "../../dist-BgR9fJpL.mjs";
1
+ import { St as hydrateSchema, at as BaseAddon, it as errMsg } from "../../dist-BqC8e44T.mjs";
2
2
  //#region src/builtins/system-config/system-config.addon.ts
3
3
  /**
4
4
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BNdI6_MP.js");
6
+ const require_dist = require("../../dist-Z2gkbfp8.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BgR9fJpL.mjs";
1
+ import { R as logDestinationCapability, at as BaseAddon } from "../../dist-BqC8e44T.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  import * as path$1 from "node:path";
4
4
  import path from "node:path";
@@ -8840,8 +8840,18 @@ var pipelineExecutorCapability = {
8840
8840
  * - `runtime` — main camera-serving engine (no idle TTL).
8841
8841
  * - `warm-override` — benchmark/test override held in the warm
8842
8842
  * cache; auto-disposed after the idle TTL.
8843
+ * - `device-pool` — a concurrent per-device pool (Phase 2
8844
+ * multi-device, keyed by `deviceKey`) resolved
8845
+ * via `resolveDeviceFactory`. Runs alongside the
8846
+ * `runtime` engine on a DIFFERENT accelerator
8847
+ * (NPU / iGPU / Coral) — this is how the
8848
+ * Engines tab shows all pools running at once.
8843
8849
  */
8844
- kind: z.enum(["runtime", "warm-override"]),
8850
+ kind: z.enum([
8851
+ "runtime",
8852
+ "warm-override",
8853
+ "device-pool"
8854
+ ]),
8845
8855
  /** Native pid of the underlying Python pool (null when no pool). */
8846
8856
  poolPid: z.number().nullable(),
8847
8857
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -16945,7 +16955,17 @@ var AgentPipelineSettingsSchema = z.object({
16945
16955
  * it already uses to reach the hub). Set this only when the auto-detected
16946
16956
  * address is wrong (multi-homed host, NAT, custom interface).
16947
16957
  */
16948
- reachableHost: z.string().optional()
16958
+ reachableHost: z.string().optional(),
16959
+ /**
16960
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16961
+ * weight}. Absent / all-disabled ⇒ the node's single default accelerator
16962
+ * (safe default); two+ enabled ⇒ the dispatcher balances detection sessions
16963
+ * across them so they run CONCURRENTLY.
16964
+ */
16965
+ inferenceDevices: z.record(z.string(), z.object({
16966
+ enabled: z.boolean(),
16967
+ weight: z.number().positive().optional()
16968
+ })).optional()
16949
16969
  });
16950
16970
  var CameraPipelineForAgentSchema = z.object({
16951
16971
  steps: z.array(PipelineStepInputSchema).readonly(),
@@ -27349,31 +27369,52 @@ function scoreRuntimes(hw) {
27349
27369
  };
27350
27370
  }
27351
27371
  var DEVICE_FOR_BACKEND = {
27352
- openvino: "gpu",
27353
27372
  cuda: "gpu",
27354
27373
  edgetpu: "usb",
27355
27374
  coreml: "all",
27356
27375
  cpu: "cpu"
27357
27376
  };
27377
+ function device(backend, dev, format, score) {
27378
+ return {
27379
+ key: backend === "cpu" ? "cpu" : `${backend}:${dev}`,
27380
+ backend,
27381
+ device: dev,
27382
+ format,
27383
+ runtime: "python",
27384
+ score,
27385
+ available: true
27386
+ };
27387
+ }
27358
27388
  /**
27359
- * Enumerate every usable inference device on a node, one descriptor per scored
27360
- * backend. Unlike the elected `bestScore`, this returns the FULL set so the
27361
- * orchestrator can run and balance across all accelerators concurrently.
27389
+ * Enumerate every usable inference device on a node one descriptor PER PHYSICAL
27390
+ * ACCELERATOR, so the orchestrator can run and balance across all of them
27391
+ * CONCURRENTLY (each device is its own pool). Critically, OpenVINO is expanded
27392
+ * into its distinct devices (NPU / iGPU / CPU) rather than a single AUTO entry:
27393
+ * the Intel NPU ("AI Boost") and the iGPU are separate accelerators and run in
27394
+ * parallel — collapsing them to AUTO would leave one idle. NPU is scored above
27395
+ * the iGPU (faster for int8 detection AND frees the GPU).
27362
27396
  */
27363
27397
  function enumerateInferenceDevices(hw) {
27364
27398
  const { scores } = scoreRuntimes(hw);
27365
- return scores.map((s) => {
27366
- const device = DEVICE_FOR_BACKEND[s.backend] ?? s.backend;
27367
- return {
27368
- key: s.backend === "cpu" ? "cpu" : `${s.backend}:${device}`,
27369
- backend: s.backend,
27370
- device,
27371
- format: s.format,
27372
- runtime: "python",
27373
- score: s.score,
27374
- available: s.available
27375
- };
27376
- });
27399
+ const out = [];
27400
+ for (const s of scores) {
27401
+ if (s.backend === "openvino") {
27402
+ if (hw.npu?.type === "intel-npu") out.push(device("openvino", "npu", s.format, s.score + 2));
27403
+ if (hw.gpu?.type === "intel") out.push(device("openvino", "gpu", s.format, s.score));
27404
+ continue;
27405
+ }
27406
+ if (s.backend === "edgetpu") {
27407
+ const coralCount = Math.max(1, hw.coral?.count ?? 1);
27408
+ for (let i = 0; i < coralCount; i++) {
27409
+ const dev = i === 0 ? "usb" : `usb:${i}`;
27410
+ out.push(device("edgetpu", dev, s.format, s.score));
27411
+ }
27412
+ continue;
27413
+ }
27414
+ const dev = DEVICE_FOR_BACKEND[s.backend] ?? s.backend;
27415
+ out.push(device(s.backend, dev, s.format, s.score));
27416
+ }
27417
+ return out;
27377
27418
  }
27378
27419
  //#endregion
27379
27420
  export { storageProviderCapability as $, getByPath as A, EventCategory as At, metricsProviderCapability as B, doorbellCapability as C, isDeviceConfigCap as Ct, evaluateLinkExpression as D, resolveCapMount as Dt, enumerateSchemaFields as E, readinessKey as Et, kebabToCamel as F, platformProbeCapability as G, normalizeUnit as H, lifecycleJobSchema as I, scoreRuntimes as J, procedureAuthKey as K, localNetworkCapability as L, isCollectionArrayMethod as M, isObjectInput as N, extractNestedAddonId as O, scopeKey as Ot, isVoidInput as P, storageCapability as Q, logDestinationCapability as R, deviceStatusCapability as S, hydrateSchema as St, enumerateItemArrayFields as T, parseJsonUnknown as Tt, objectInputDeclaresAddonId as U, nodePin as V, parseStreamParamsFormPatch as W, settingsStoreCapability as X, setByPath as Y, snapshotCapability as Z, authProviderCapability as _, asString as _t, DeviceStatusSchema as a, BaseAddon as at, deviceManagerCapability as b, emitReadiness as bt, STREAM_PROFILE_META as c, DEVICE_STATUS_METHOD as ct, UserRecordSchema as d, DeviceType as dt, streamQualityLabel as et, addonPagesCapability as f, ReadinessRegistry as ft, applyTransform as g, asNumber as gt, alertsCapability as h, asJsonObject as ht, CAP_NAMES_WITH_STATUS as i, errMsg as it, isArrayOutputSchema as j, filesystemBrowseCapability as k, sleep as kt, ScopedTokenSchema as l, DeviceFeature as lt, addonWidgetsCapability as m, WELL_KNOWN_TAB_MAP as mt, AlertSchema as n, userManagementCapability as nt, METHOD_ACCESS_MAP as o, DATAPLANE_SECRET_HEADER as ot, addonSettingsCapability as p, ReadinessTimeoutError as pt, readNodePin as q, ApiKeyRecordSchema as r, validateExpressionSource as rt, RUNTIME_DEFAULTS as s, DEVICE_SETTINGS_CONTRIBUTION_METHODS as st, ALL_CAPABILITY_DEFINITIONS as t, toExpressionValue as tt, StorageLocationTypeSchema as u, DeviceRole as ut, backupCapability as v, createEvent as vt, enumerateInferenceDevices as w, parseJsonObject as wt, deviceStateCapability as x, expandCapMethods as xt, buildStreamParamsConfigSchema as y, emitDownForOwnedCaps as yt, looseSchema as z };
@@ -8840,8 +8840,18 @@ var pipelineExecutorCapability = {
8840
8840
  * - `runtime` — main camera-serving engine (no idle TTL).
8841
8841
  * - `warm-override` — benchmark/test override held in the warm
8842
8842
  * cache; auto-disposed after the idle TTL.
8843
+ * - `device-pool` — a concurrent per-device pool (Phase 2
8844
+ * multi-device, keyed by `deviceKey`) resolved
8845
+ * via `resolveDeviceFactory`. Runs alongside the
8846
+ * `runtime` engine on a DIFFERENT accelerator
8847
+ * (NPU / iGPU / Coral) — this is how the
8848
+ * Engines tab shows all pools running at once.
8843
8849
  */
8844
- kind: zod.z.enum(["runtime", "warm-override"]),
8850
+ kind: zod.z.enum([
8851
+ "runtime",
8852
+ "warm-override",
8853
+ "device-pool"
8854
+ ]),
8845
8855
  /** Native pid of the underlying Python pool (null when no pool). */
8846
8856
  poolPid: zod.z.number().nullable(),
8847
8857
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -16945,7 +16955,17 @@ var AgentPipelineSettingsSchema = zod.z.object({
16945
16955
  * it already uses to reach the hub). Set this only when the auto-detected
16946
16956
  * address is wrong (multi-homed host, NAT, custom interface).
16947
16957
  */
16948
- reachableHost: zod.z.string().optional()
16958
+ reachableHost: zod.z.string().optional(),
16959
+ /**
16960
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16961
+ * weight}. Absent / all-disabled ⇒ the node's single default accelerator
16962
+ * (safe default); two+ enabled ⇒ the dispatcher balances detection sessions
16963
+ * across them so they run CONCURRENTLY.
16964
+ */
16965
+ inferenceDevices: zod.z.record(zod.z.string(), zod.z.object({
16966
+ enabled: zod.z.boolean(),
16967
+ weight: zod.z.number().positive().optional()
16968
+ })).optional()
16949
16969
  });
16950
16970
  var CameraPipelineForAgentSchema = zod.z.object({
16951
16971
  steps: zod.z.array(PipelineStepInputSchema).readonly(),
@@ -27349,31 +27369,52 @@ function scoreRuntimes(hw) {
27349
27369
  };
27350
27370
  }
27351
27371
  var DEVICE_FOR_BACKEND = {
27352
- openvino: "gpu",
27353
27372
  cuda: "gpu",
27354
27373
  edgetpu: "usb",
27355
27374
  coreml: "all",
27356
27375
  cpu: "cpu"
27357
27376
  };
27377
+ function device(backend, dev, format, score) {
27378
+ return {
27379
+ key: backend === "cpu" ? "cpu" : `${backend}:${dev}`,
27380
+ backend,
27381
+ device: dev,
27382
+ format,
27383
+ runtime: "python",
27384
+ score,
27385
+ available: true
27386
+ };
27387
+ }
27358
27388
  /**
27359
- * Enumerate every usable inference device on a node, one descriptor per scored
27360
- * backend. Unlike the elected `bestScore`, this returns the FULL set so the
27361
- * orchestrator can run and balance across all accelerators concurrently.
27389
+ * Enumerate every usable inference device on a node one descriptor PER PHYSICAL
27390
+ * ACCELERATOR, so the orchestrator can run and balance across all of them
27391
+ * CONCURRENTLY (each device is its own pool). Critically, OpenVINO is expanded
27392
+ * into its distinct devices (NPU / iGPU / CPU) rather than a single AUTO entry:
27393
+ * the Intel NPU ("AI Boost") and the iGPU are separate accelerators and run in
27394
+ * parallel — collapsing them to AUTO would leave one idle. NPU is scored above
27395
+ * the iGPU (faster for int8 detection AND frees the GPU).
27362
27396
  */
27363
27397
  function enumerateInferenceDevices(hw) {
27364
27398
  const { scores } = scoreRuntimes(hw);
27365
- return scores.map((s) => {
27366
- const device = DEVICE_FOR_BACKEND[s.backend] ?? s.backend;
27367
- return {
27368
- key: s.backend === "cpu" ? "cpu" : `${s.backend}:${device}`,
27369
- backend: s.backend,
27370
- device,
27371
- format: s.format,
27372
- runtime: "python",
27373
- score: s.score,
27374
- available: s.available
27375
- };
27376
- });
27399
+ const out = [];
27400
+ for (const s of scores) {
27401
+ if (s.backend === "openvino") {
27402
+ if (hw.npu?.type === "intel-npu") out.push(device("openvino", "npu", s.format, s.score + 2));
27403
+ if (hw.gpu?.type === "intel") out.push(device("openvino", "gpu", s.format, s.score));
27404
+ continue;
27405
+ }
27406
+ if (s.backend === "edgetpu") {
27407
+ const coralCount = Math.max(1, hw.coral?.count ?? 1);
27408
+ for (let i = 0; i < coralCount; i++) {
27409
+ const dev = i === 0 ? "usb" : `usb:${i}`;
27410
+ out.push(device("edgetpu", dev, s.format, s.score));
27411
+ }
27412
+ continue;
27413
+ }
27414
+ const dev = DEVICE_FOR_BACKEND[s.backend] ?? s.backend;
27415
+ out.push(device(s.backend, dev, s.format, s.score));
27416
+ }
27417
+ return out;
27377
27418
  }
27378
27419
  //#endregion
27379
27420
  Object.defineProperty(exports, "ALL_CAPABILITY_DEFINITIONS", {
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-BNdI6_MP.js");
3
+ const require_dist = require("./dist-Z2gkbfp8.js");
4
4
  const require_model_download_service = require("./model-download-service-hf0ookyy.js");
5
- const require_manifest_python_deps = require("./manifest-python-deps-ClarMoI9.js");
5
+ const require_manifest_python_deps = require("./manifest-python-deps-Houw5lw4.js");
6
6
  const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
7
7
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
8
8
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
@@ -41,11 +41,11 @@ node_vm = require_chunk.__toESM(node_vm);
41
41
  let node_os = require("node:os");
42
42
  node_os = require_chunk.__toESM(node_os);
43
43
  let node_fs_promises = require("node:fs/promises");
44
+ let node_url = require("node:url");
44
45
  let node_events = require("node:events");
45
46
  let node_stream = require("node:stream");
46
47
  node_stream = require_chunk.__toESM(node_stream, 1);
47
48
  let node_string_decoder = require("node:string_decoder");
48
- let node_url = require("node:url");
49
49
  let fs = require("fs");
50
50
  fs = require_chunk.__toESM(fs, 1);
51
51
  let path = require("path");
@@ -2241,6 +2241,33 @@ function isRecord$1(value) {
2241
2241
  return typeof value === "object" && value !== null && !Array.isArray(value);
2242
2242
  }
2243
2243
  /**
2244
+ * Import an addon entry module FRESH on every load, defeating Node's
2245
+ * per-URL ESM module cache.
2246
+ *
2247
+ * `camstack deploy` overwrites an addon's `dist/` in place (same path). Node
2248
+ * caches ESM modules by resolved URL, so a plain `import(entryPath)` after a
2249
+ * redeploy returns the STALE previously-cached module. The addon RUNNER child
2250
+ * is a fresh process so it reloads correctly — but hub-main also imports the
2251
+ * module to read its static catalog (`customActions` Zod schemas, addon class)
2252
+ * for the `addons.custom` "validate on the way in" guard. Without cache-busting
2253
+ * that guard keeps validating against the OLD schema, silently STRIPPING any
2254
+ * newly-added custom-action input field until a full hub restart (observed:
2255
+ * benchmark `deviceKey`/multi-device fan-out fields dropped after redeploy).
2256
+ *
2257
+ * Appending a `?v=<mtimeMs>` query makes each on-disk version a distinct module
2258
+ * URL, so a redeploy (new mtime) loads the fresh module. Falls back to a plain
2259
+ * import if the file can't be stat'd.
2260
+ */
2261
+ async function importAddonModuleFresh(entryPath) {
2262
+ let bust;
2263
+ try {
2264
+ bust = node_fs.statSync(entryPath).mtimeMs;
2265
+ } catch {
2266
+ return import(entryPath);
2267
+ }
2268
+ return import(`${(0, node_url.pathToFileURL)(entryPath).href}?v=${bust}`);
2269
+ }
2270
+ /**
2244
2271
  * Package.json manifest boundary: the `camstack` field is authored by third-party
2245
2272
  * addon packages. We minimally validate that it looks like an AddonPackageManifest
2246
2273
  * (has an `addons` array whose entries carry string `id`s) and pass it through as
@@ -2399,7 +2426,7 @@ var AddonLoader = class {
2399
2426
  ].find((p) => node_fs.existsSync(p)) ?? entryPath;
2400
2427
  }
2401
2428
  if (!node_fs.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
2402
- const modUnknown = await import(entryPath);
2429
+ const modUnknown = await importAddonModuleFresh(entryPath);
2403
2430
  const mod = isRecord$1(modUnknown) ? modUnknown : {};
2404
2431
  const AddonClass = require_manifest_python_deps.resolveAddonClass(mod);
2405
2432
  if (!AddonClass) throw new Error(`No addon class in ${entryPath}`);
@@ -2415,7 +2442,7 @@ var AddonLoader = class {
2415
2442
  }
2416
2443
  /** Load addon from a direct path (for development/testing) */
2417
2444
  async loadFromPath(addonId, modulePath, packageName, declaration, packageVersion = "0.0.0") {
2418
- const modUnknown = await import(modulePath);
2445
+ const modUnknown = await importAddonModuleFresh(modulePath);
2419
2446
  const mod = isRecord$1(modUnknown) ? modUnknown : {};
2420
2447
  const AddonClass = require_manifest_python_deps.resolveAddonClass(mod);
2421
2448
  if (!AddonClass) throw new Error(`Module ${modulePath} has no default export`);
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { At as EventCategory$1, Dt as resolveCapMount, Et as readinessKey, F as kebabToCamel, I as lifecycleJobSchema, K as procedureAuthKey, M as isCollectionArrayMethod, N as isObjectInput, O as extractNestedAddonId, Ot as scopeKey, P as isVoidInput, Tt as parseJsonUnknown$1, U as objectInputDeclaresAddonId, _t as asString$1, ct as DEVICE_STATUS_METHOD, ft as ReadinessRegistry, gt as asNumber, ht as asJsonObject$1, it as errMsg$1, j as isArrayOutputSchema, o as METHOD_ACCESS_MAP, ot as DATAPLANE_SECRET_HEADER$1, p as addonSettingsCapability, pt as ReadinessTimeoutError, s as RUNTIME_DEFAULTS, st as DEVICE_SETTINGS_CONTRIBUTION_METHODS, t as ALL_CAPABILITY_DEFINITIONS, vt as createEvent, wt as parseJsonObject, xt as expandCapMethods, yt as emitDownForOwnedCaps, z as looseSchema } from "./dist-BgR9fJpL.mjs";
1
+ import { At as EventCategory$1, Dt as resolveCapMount, Et as readinessKey, F as kebabToCamel, I as lifecycleJobSchema, K as procedureAuthKey, M as isCollectionArrayMethod, N as isObjectInput, O as extractNestedAddonId, Ot as scopeKey, P as isVoidInput, Tt as parseJsonUnknown$1, U as objectInputDeclaresAddonId, _t as asString$1, ct as DEVICE_STATUS_METHOD, ft as ReadinessRegistry, gt as asNumber, ht as asJsonObject$1, it as errMsg$1, j as isArrayOutputSchema, o as METHOD_ACCESS_MAP, ot as DATAPLANE_SECRET_HEADER$1, p as addonSettingsCapability, pt as ReadinessTimeoutError, s as RUNTIME_DEFAULTS, st as DEVICE_SETTINGS_CONTRIBUTION_METHODS, t as ALL_CAPABILITY_DEFINITIONS, vt as createEvent, wt as parseJsonObject, xt as expandCapMethods, yt as emitDownForOwnedCaps, z as looseSchema } from "./dist-BqC8e44T.mjs";
2
2
  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-Cp9f4dk6.mjs";
3
- import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, bt as resolveAddonClass, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, 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 getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, xt as createAddonDataPlaneFacility, y as __resetCapUsageRegistryForTests, yt as runNpm, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-RSxmZ-Fu.mjs";
3
+ import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, bt as resolveAddonClass, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, 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 getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, xt as createAddonDataPlaneFacility, y as __resetCapUsageRegistryForTests, yt as runNpm, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-DQVZZVNo.mjs";
4
4
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Le3l0qS2.mjs";
5
5
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
6
6
  import { SqliteSettingsAddon, t as SqliteSettingsBackend } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
@@ -36,10 +36,10 @@ import { promisify } from "node:util";
36
36
  import * as vm from "node:vm";
37
37
  import * as os$18 from "node:os";
38
38
  import { lstat, readdir, readlink, realpath } from "node:fs/promises";
39
+ import { fileURLToPath, pathToFileURL } from "node:url";
39
40
  import { EventEmitter } from "node:events";
40
41
  import As from "node:stream";
41
42
  import { StringDecoder } from "node:string_decoder";
42
- import { fileURLToPath } from "node:url";
43
43
  import { lstatSync, readdir as readdir$1, readdirSync, readlinkSync, realpathSync } from "fs";
44
44
  import "path";
45
45
  import { createRequire } from "module";
@@ -2233,6 +2233,33 @@ function isRecord$1(value) {
2233
2233
  return typeof value === "object" && value !== null && !Array.isArray(value);
2234
2234
  }
2235
2235
  /**
2236
+ * Import an addon entry module FRESH on every load, defeating Node's
2237
+ * per-URL ESM module cache.
2238
+ *
2239
+ * `camstack deploy` overwrites an addon's `dist/` in place (same path). Node
2240
+ * caches ESM modules by resolved URL, so a plain `import(entryPath)` after a
2241
+ * redeploy returns the STALE previously-cached module. The addon RUNNER child
2242
+ * is a fresh process so it reloads correctly — but hub-main also imports the
2243
+ * module to read its static catalog (`customActions` Zod schemas, addon class)
2244
+ * for the `addons.custom` "validate on the way in" guard. Without cache-busting
2245
+ * that guard keeps validating against the OLD schema, silently STRIPPING any
2246
+ * newly-added custom-action input field until a full hub restart (observed:
2247
+ * benchmark `deviceKey`/multi-device fan-out fields dropped after redeploy).
2248
+ *
2249
+ * Appending a `?v=<mtimeMs>` query makes each on-disk version a distinct module
2250
+ * URL, so a redeploy (new mtime) loads the fresh module. Falls back to a plain
2251
+ * import if the file can't be stat'd.
2252
+ */
2253
+ async function importAddonModuleFresh(entryPath) {
2254
+ let bust;
2255
+ try {
2256
+ bust = fs$17.statSync(entryPath).mtimeMs;
2257
+ } catch {
2258
+ return import(entryPath);
2259
+ }
2260
+ return import(`${pathToFileURL(entryPath).href}?v=${bust}`);
2261
+ }
2262
+ /**
2236
2263
  * Package.json manifest boundary: the `camstack` field is authored by third-party
2237
2264
  * addon packages. We minimally validate that it looks like an AddonPackageManifest
2238
2265
  * (has an `addons` array whose entries carry string `id`s) and pass it through as
@@ -2391,7 +2418,7 @@ var AddonLoader = class {
2391
2418
  ].find((p) => fs$17.existsSync(p)) ?? entryPath;
2392
2419
  }
2393
2420
  if (!fs$17.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
2394
- const modUnknown = await import(entryPath);
2421
+ const modUnknown = await importAddonModuleFresh(entryPath);
2395
2422
  const mod = isRecord$1(modUnknown) ? modUnknown : {};
2396
2423
  const AddonClass = resolveAddonClass(mod);
2397
2424
  if (!AddonClass) throw new Error(`No addon class in ${entryPath}`);
@@ -2407,7 +2434,7 @@ var AddonLoader = class {
2407
2434
  }
2408
2435
  /** Load addon from a direct path (for development/testing) */
2409
2436
  async loadFromPath(addonId, modulePath, packageName, declaration, packageVersion = "0.0.0") {
2410
- const modUnknown = await import(modulePath);
2437
+ const modUnknown = await importAddonModuleFresh(modulePath);
2411
2438
  const mod = isRecord$1(modUnknown) ? modUnknown : {};
2412
2439
  const AddonClass = resolveAddonClass(mod);
2413
2440
  if (!AddonClass) throw new Error(`Module ${modulePath} has no default export`);
@@ -1,4 +1,4 @@
1
- import { q as readNodePin } from "./dist-BgR9fJpL.mjs";
1
+ import { q as readNodePin } from "./dist-BqC8e44T.mjs";
2
2
  import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
3
3
  import { createServer } from "node:http";
4
4
  import * as fs from "node:fs";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-BNdI6_MP.js");
2
+ const require_dist = require("./dist-Z2gkbfp8.js");
3
3
  let _camstack_types_node = require("@camstack/types/node");
4
4
  let node_http = require("node:http");
5
5
  let node_fs = require("node:fs");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.1.60",
3
+ "version": "1.1.62",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",