camstack 1.2.137 → 1.2.138

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.
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-BOlMCOeT.js
23637
- var require_dist_BOlMCOeT = __commonJS({
23638
- "../system/dist/dist-BOlMCOeT.js"(exports) {
23636
+ // ../system/dist/dist-B17W9ngu.js
23637
+ var require_dist_B17W9ngu = __commonJS({
23638
+ "../system/dist/dist-B17W9ngu.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -44623,8 +44623,8 @@ var require_dist_BOlMCOeT = __commonJS({
44623
44623
  *
44624
44624
  * An **empty array reads NOTHING** — `[]` is an empty page, never
44625
44625
  * "every camera". A request for no devices is a request, not an
44626
- * omission; same contract as `deviceManager.listFleet` and
44627
- * `pipelineAnalytics.listRecentTracks`.
44626
+ * omission; same contract as `deviceManager.listAll`'s `deviceIds`
44627
+ * and `pipelineAnalytics.listRecentTracks`.
44628
44628
  *
44629
44629
  * Absent (`undefined`) is the omission, and keeps the cluster-wide view.
44630
44630
  */
@@ -61586,7 +61586,7 @@ var require_alerts_addon = __commonJS({
61586
61586
  [Symbol.toStringTag]: { value: "Module" }
61587
61587
  });
61588
61588
  require_chunk_Cek0wNdY();
61589
- var require_dist10 = require_dist_BOlMCOeT();
61589
+ var require_dist10 = require_dist_B17W9ngu();
61590
61590
  function selectExpired(alerts, cutoffMs) {
61591
61591
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
61592
61592
  }
@@ -62405,7 +62405,7 @@ var require_console_logging = __commonJS({
62405
62405
  [Symbol.toStringTag]: { value: "Module" }
62406
62406
  });
62407
62407
  require_chunk_Cek0wNdY();
62408
- var require_dist10 = require_dist_BOlMCOeT();
62408
+ var require_dist10 = require_dist_B17W9ngu();
62409
62409
  var require_formatter = require_formatter_DqAKDlvN();
62410
62410
  var LEVEL_RANK = {
62411
62411
  debug: 0,
@@ -62499,7 +62499,7 @@ var require_core_blocks_addon = __commonJS({
62499
62499
  "use strict";
62500
62500
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
62501
62501
  var require_chunk = require_chunk_Cek0wNdY();
62502
- var require_dist10 = require_dist_BOlMCOeT();
62502
+ var require_dist10 = require_dist_B17W9ngu();
62503
62503
  var node_crypto = __require("crypto");
62504
62504
  var node_fs_promises = __require("fs/promises");
62505
62505
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -63396,11 +63396,11 @@ var require_core_blocks = __commonJS({
63396
63396
  }
63397
63397
  });
63398
63398
 
63399
- // ../system/dist/retired-settings-keys-xEAlYnv7.js
63400
- var require_retired_settings_keys_xEAlYnv7 = __commonJS({
63401
- "../system/dist/retired-settings-keys-xEAlYnv7.js"(exports) {
63399
+ // ../system/dist/retired-settings-keys-CjvB7Etx.js
63400
+ var require_retired_settings_keys_CjvB7Etx = __commonJS({
63401
+ "../system/dist/retired-settings-keys-CjvB7Etx.js"(exports) {
63402
63402
  "use strict";
63403
- var require_dist10 = require_dist_BOlMCOeT();
63403
+ var require_dist10 = require_dist_B17W9ngu();
63404
63404
  function settingsStoreIsAuthoritativeHere(env) {
63405
63405
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
63406
63406
  return raw === "" || raw === "hub";
@@ -65635,8 +65635,8 @@ var require_device_manager_addon = __commonJS({
65635
65635
  [Symbol.toStringTag]: { value: "Module" }
65636
65636
  });
65637
65637
  require_chunk_Cek0wNdY();
65638
- var require_dist10 = require_dist_BOlMCOeT();
65639
- var require_retired_settings_keys = require_retired_settings_keys_xEAlYnv7();
65638
+ var require_dist10 = require_dist_B17W9ngu();
65639
+ var require_retired_settings_keys = require_retired_settings_keys_CjvB7Etx();
65640
65640
  var node_crypto = __require("crypto");
65641
65641
  var _camstack_types_node = require_node();
65642
65642
  var JOB_HISTORY = 20;
@@ -71261,7 +71261,7 @@ var require_hub_forwarder = __commonJS({
71261
71261
  [Symbol.toStringTag]: { value: "Module" }
71262
71262
  });
71263
71263
  require_chunk_Cek0wNdY();
71264
- var require_dist10 = require_dist_BOlMCOeT();
71264
+ var require_dist10 = require_dist_B17W9ngu();
71265
71265
  var require_formatter = require_formatter_DqAKDlvN();
71266
71266
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
71267
71267
  var HubForwarderDestination = class {
@@ -71398,7 +71398,7 @@ var require_liveness_monitor_addon = __commonJS({
71398
71398
  "use strict";
71399
71399
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
71400
71400
  require_chunk_Cek0wNdY();
71401
- var require_dist10 = require_dist_BOlMCOeT();
71401
+ var require_dist10 = require_dist_B17W9ngu();
71402
71402
  var NO_DEVICES = "liveness:no-devices";
71403
71403
  var ALL_OFFLINE = "liveness:all-devices-offline";
71404
71404
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -71594,7 +71594,7 @@ var require_local_auth_addon = __commonJS({
71594
71594
  [Symbol.toStringTag]: { value: "Module" }
71595
71595
  });
71596
71596
  var require_chunk = require_chunk_Cek0wNdY();
71597
- var require_dist10 = require_dist_BOlMCOeT();
71597
+ var require_dist10 = require_dist_B17W9ngu();
71598
71598
  var node_crypto = __require("crypto");
71599
71599
  node_crypto = require_chunk.__toESM(node_crypto);
71600
71600
  var crypto$1 = __require("crypto");
@@ -79407,7 +79407,7 @@ var require_loki_logging = __commonJS({
79407
79407
  [Symbol.toStringTag]: { value: "Module" }
79408
79408
  });
79409
79409
  require_chunk_Cek0wNdY();
79410
- var require_dist10 = require_dist_BOlMCOeT();
79410
+ var require_dist10 = require_dist_B17W9ngu();
79411
79411
  function sanitizeLabelName(raw) {
79412
79412
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
79413
79413
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79873,31 +79873,18 @@ var require_loki_logging = __commonJS({
79873
79873
  }
79874
79874
  });
79875
79875
 
79876
- // ../system/dist/resource-monitor-CdnzxBLP.js
79877
- var require_resource_monitor_CdnzxBLP = __commonJS({
79878
- "../system/dist/resource-monitor-CdnzxBLP.js"(exports) {
79876
+ // ../system/dist/resource-monitor-LVE1BoLs.js
79877
+ var require_resource_monitor_LVE1BoLs = __commonJS({
79878
+ "../system/dist/resource-monitor-LVE1BoLs.js"(exports) {
79879
79879
  "use strict";
79880
79880
  var require_chunk = require_chunk_Cek0wNdY();
79881
+ var require_builtins_native_metrics_native_metrics_addon = require_native_metrics_addon();
79881
79882
  var node_child_process = __require("child_process");
79882
- var node_fs = __require("fs");
79883
- node_fs = require_chunk.__toESM(node_fs);
79883
+ var node_os = __require("os");
79884
79884
  var resource_monitor_exports = /* @__PURE__ */ require_chunk.__exportAll({
79885
79885
  getPidStats: () => getPidStats,
79886
79886
  getSinglePidStats: () => getSinglePidStats
79887
79887
  });
79888
- function readProcRss(pid) {
79889
- try {
79890
- const status = node_fs.readFileSync(`/proc/${pid}/status`, "utf8");
79891
- const anon = status.match(/^RssAnon:\s+(\d+)/m);
79892
- const file = status.match(/^RssFile:\s+(\d+)/m);
79893
- return {
79894
- privateBytes: anon ? parseInt(anon[1], 10) * 1024 : void 0,
79895
- sharedBytes: file ? parseInt(file[1], 10) * 1024 : void 0
79896
- };
79897
- } catch {
79898
- return {};
79899
- }
79900
- }
79901
79888
  function execPsForPids(pids) {
79902
79889
  return new Promise((resolve, reject) => {
79903
79890
  (0, node_child_process.execFile)("ps", [
@@ -79911,6 +79898,11 @@ var require_resource_monitor_CdnzxBLP = __commonJS({
79911
79898
  });
79912
79899
  });
79913
79900
  }
79901
+ var defaultDeps = {
79902
+ platform: (0, node_os.platform)(),
79903
+ reader: require_builtins_native_metrics_native_metrics_addon.nodeProcReader,
79904
+ spawnPs: execPsForPids
79905
+ };
79914
79906
  function parsePsOutput(stdout) {
79915
79907
  const result = /* @__PURE__ */ new Map();
79916
79908
  for (const line of stdout.trim().split("\n")) {
@@ -79924,17 +79916,47 @@ var require_resource_monitor_CdnzxBLP = __commonJS({
79924
79916
  if (isNaN(pid) || isNaN(cpu) || isNaN(rssKb)) continue;
79925
79917
  result.set(pid, {
79926
79918
  cpu: Math.round(cpu * 10) / 10,
79927
- memory: rssKb * 1024,
79928
- ...readProcRss(pid)
79919
+ memory: rssKb * 1024
79929
79920
  });
79930
79921
  }
79931
79922
  return result;
79932
79923
  }
79933
- async function getPidStats(pids) {
79924
+ async function readProcPidStats(pid, uptimeSec, reader) {
79925
+ let stat;
79926
+ let status;
79927
+ try {
79928
+ [stat, status] = await Promise.all([reader.readStat(pid), reader.readStatus(pid)]);
79929
+ } catch {
79930
+ return null;
79931
+ }
79932
+ const parsed = require_builtins_native_metrics_native_metrics_addon.parseProcStat(stat);
79933
+ if (parsed === null) return null;
79934
+ const rss = require_builtins_native_metrics_native_metrics_addon.parseProcStatusRss(status);
79935
+ if (rss.rssBytes === void 0) return null;
79936
+ return {
79937
+ cpu: require_builtins_native_metrics_native_metrics_addon.lifetimeCpuPercent({
79938
+ ticks: parsed.ticks,
79939
+ startTicks: parsed.startTicks,
79940
+ uptimeSec
79941
+ }),
79942
+ memory: rss.rssBytes,
79943
+ privateBytes: rss.privateBytes,
79944
+ sharedBytes: rss.sharedBytes
79945
+ };
79946
+ }
79947
+ async function readProcPidStatsAll(pids, reader) {
79948
+ const uptimeSec = await reader.readUptimeSec();
79949
+ const entries = await Promise.all(pids.map(async (pid) => [pid, await readProcPidStats(pid, uptimeSec, reader)]));
79950
+ const result = /* @__PURE__ */ new Map();
79951
+ for (const [pid, stats] of entries) if (stats !== null) result.set(pid, stats);
79952
+ return result;
79953
+ }
79954
+ async function getPidStats(pids, deps = defaultDeps) {
79934
79955
  const pidArray = typeof pids === "number" ? [pids] : [...pids];
79935
79956
  if (pidArray.length === 0) return /* @__PURE__ */ new Map();
79936
79957
  try {
79937
- return parsePsOutput(await execPsForPids(pidArray));
79958
+ if (deps.platform === "linux") return await readProcPidStatsAll(pidArray, deps.reader);
79959
+ return parsePsOutput(await deps.spawnPs(pidArray));
79938
79960
  } catch {
79939
79961
  return /* @__PURE__ */ new Map();
79940
79962
  }
@@ -79972,14 +79994,14 @@ var require_native_metrics_addon = __commonJS({
79972
79994
  [Symbol.toStringTag]: { value: "Module" }
79973
79995
  });
79974
79996
  var require_chunk = require_chunk_Cek0wNdY();
79975
- var require_dist10 = require_dist_BOlMCOeT();
79997
+ var require_dist10 = require_dist_B17W9ngu();
79976
79998
  var node_fs_promises = __require("fs/promises");
79977
- var node_child_process = __require("child_process");
79978
- var node_util = __require("util");
79979
79999
  var node_fs = __require("fs");
79980
80000
  node_fs = require_chunk.__toESM(node_fs);
80001
+ var node_child_process = __require("child_process");
79981
80002
  var node_os = __require("os");
79982
80003
  node_os = require_chunk.__toESM(node_os);
80004
+ var node_util = __require("util");
79983
80005
  var nodeCgroupFileReader = { read(path) {
79984
80006
  try {
79985
80007
  return (0, node_fs.readFileSync)(path, "utf8");
@@ -80825,470 +80847,6 @@ var require_native_metrics_addon = __commonJS({
80825
80847
  }
80826
80848
  }
80827
80849
  };
80828
- var IS_DARWIN = node_os.platform() === "darwin";
80829
- var IS_LINUX = node_os.platform() === "linux";
80830
- var NativeMetricsProvider = class {
80831
- id = "native";
80832
- cachedSnapshot = null;
80833
- samplingTimer = null;
80834
- macMemTimer = null;
80835
- prevCpu;
80836
- diagnostics = null;
80837
- consecutiveSampleErrors = 0;
80838
- constructor() {
80839
- this.prevCpu = aggregateCpuTimes();
80840
- }
80841
- /**
80842
- * Optional diagnostics sink for sampling errors. The first failure and
80843
- * every Nth failure thereafter are reported so a permanently-broken
80844
- * collector doesn't spam logs but is still observable.
80845
- */
80846
- setDiagnostics(diag) {
80847
- this.diagnostics = diag;
80848
- }
80849
- startSampling(intervalMs) {
80850
- if (IS_DARWIN) {
80851
- sampleMacMemory(this);
80852
- this.macMemTimer = setInterval(() => sampleMacMemory(this), 5e3);
80853
- if (this.macMemTimer.unref) this.macMemTimer.unref();
80854
- }
80855
- this.collectSnapshot().then((s) => {
80856
- this.cachedSnapshot = s;
80857
- this.consecutiveSampleErrors = 0;
80858
- }).catch((err) => this.reportSampleError(err));
80859
- this.samplingTimer = setInterval(() => {
80860
- this.collectSnapshot().then((s) => {
80861
- this.cachedSnapshot = s;
80862
- this.consecutiveSampleErrors = 0;
80863
- }).catch((err) => this.reportSampleError(err));
80864
- }, intervalMs);
80865
- if (this.samplingTimer.unref) this.samplingTimer.unref();
80866
- }
80867
- reportSampleError(err) {
80868
- this.consecutiveSampleErrors++;
80869
- if (!this.diagnostics) return;
80870
- if (!(this.consecutiveSampleErrors === 1 || this.consecutiveSampleErrors % 60 === 0)) return;
80871
- this.diagnostics.warn("metrics-provider sample failed", {
80872
- consecutiveErrors: this.consecutiveSampleErrors,
80873
- error: err instanceof Error ? err.message : String(err)
80874
- });
80875
- }
80876
- stopSampling() {
80877
- if (this.samplingTimer) {
80878
- clearInterval(this.samplingTimer);
80879
- this.samplingTimer = null;
80880
- }
80881
- if (this.macMemTimer) {
80882
- clearInterval(this.macMemTimer);
80883
- this.macMemTimer = null;
80884
- }
80885
- }
80886
- async collectSnapshot() {
80887
- const cpu = this.sampleCpu();
80888
- const memory = this.getMemoryInfo();
80889
- const processInfo = getProcessResources();
80890
- const [gpu, network, disk, cpuTemp] = await Promise.all([
80891
- getGpuInfoInternal().catch(() => null),
80892
- takeNetworkIoSnapshot(),
80893
- takeDiskIoSnapshot(),
80894
- getCpuTemperatureInternal().catch(() => null)
80895
- ]);
80896
- const snapshot = {
80897
- cpu,
80898
- memory,
80899
- gpu,
80900
- network,
80901
- disk,
80902
- pressure: {
80903
- cpu: getPressure("cpu"),
80904
- memory: getPressure("memory"),
80905
- io: getPressure("io")
80906
- },
80907
- process: processInfo,
80908
- cpuTemperature: cpuTemp,
80909
- timestampMs: Date.now()
80910
- };
80911
- this.cachedSnapshot = snapshot;
80912
- return snapshot;
80913
- }
80914
- async getCached() {
80915
- return this.cachedSnapshot;
80916
- }
80917
- async getCurrent() {
80918
- const s = this.cachedSnapshot ?? await this.collectSnapshot();
80919
- const mb = (bytes) => Math.round(bytes / 1024 / 1024);
80920
- return {
80921
- cpuPercent: s.cpu.total,
80922
- memoryPercent: s.memory.percent,
80923
- memoryUsedMB: mb(s.memory.usedBytes),
80924
- memoryTotalMB: mb(s.memory.totalBytes),
80925
- temperature: s.cpuTemperature ?? void 0,
80926
- gpuPercent: s.gpu?.utilization,
80927
- gpuMemoryPercent: s.gpu && s.gpu.memoryTotalBytes > 0 ? Math.round(s.gpu.memoryUsedBytes / s.gpu.memoryTotalBytes * 1e3) / 10 : void 0
80928
- };
80929
- }
80930
- async getDiskSpace(input) {
80931
- return getDiskSpaceInternal(input.dirPath);
80932
- }
80933
- async getGpuInfo() {
80934
- return getGpuInfoInternal();
80935
- }
80936
- async getCpuTemperature() {
80937
- return getCpuTemperatureInternal();
80938
- }
80939
- async getProcessStats(input) {
80940
- const { getPidStats } = await Promise.resolve().then(() => require_resource_monitor_CdnzxBLP()).then((n) => n.resource_monitor_exports);
80941
- const raw = await getPidStats(input.pids);
80942
- const result = [];
80943
- for (const [pid, s] of raw) result.push({
80944
- pid,
80945
- cpu: s.cpu,
80946
- memory: s.memory,
80947
- privateBytes: s.privateBytes,
80948
- sharedBytes: s.sharedBytes
80949
- });
80950
- return result;
80951
- }
80952
- sampleCpu() {
80953
- const curr = aggregateCpuTimes();
80954
- const prev = this.prevCpu;
80955
- this.prevCpu = curr;
80956
- const dUser = curr.user - prev.user;
80957
- const dNice = curr.nice - prev.nice;
80958
- const dSys = curr.sys - prev.sys;
80959
- const dIrq = curr.irq - prev.irq;
80960
- const dIdle = curr.idle - prev.idle;
80961
- const dTotal = dUser + dNice + dSys + dIrq + dIdle;
80962
- const pct = (v) => dTotal === 0 ? 0 : Math.round(v / dTotal * 1e3) / 10;
80963
- return {
80964
- total: pct(dUser + dNice + dSys + dIrq),
80965
- user: pct(dUser),
80966
- system: pct(dSys),
80967
- irq: pct(dIrq),
80968
- nice: pct(dNice),
80969
- loadAvg: node_os.loadavg(),
80970
- cores: node_os.cpus().length
80971
- };
80972
- }
80973
- /** Cached macOS memory (set by sampleMacMemory timer). */
80974
- _cachedMacMem = null;
80975
- getMemoryInfo() {
80976
- const total = node_os.totalmem();
80977
- if (total === 0) return {
80978
- percent: 0,
80979
- totalBytes: 0,
80980
- usedBytes: 0,
80981
- availableBytes: 0,
80982
- swapUsedBytes: 0,
80983
- swapTotalBytes: 0
80984
- };
80985
- if (IS_DARWIN && this._cachedMacMem !== null) return this._cachedMacMem;
80986
- const free = node_os.freemem();
80987
- const used = total - free;
80988
- let swapUsedBytes = 0;
80989
- let swapTotalBytes = 0;
80990
- if (IS_LINUX) try {
80991
- const meminfo = node_fs.readFileSync("/proc/meminfo", "utf-8");
80992
- const swapTotal = parseInt(meminfo.match(/SwapTotal:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
80993
- const swapFree = parseInt(meminfo.match(/SwapFree:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
80994
- swapTotalBytes = swapTotal;
80995
- swapUsedBytes = swapTotal - swapFree;
80996
- } catch {
80997
- }
80998
- return {
80999
- percent: Math.round((total - free) / total * 1e3) / 10,
81000
- totalBytes: total,
81001
- usedBytes: used,
81002
- availableBytes: free,
81003
- swapUsedBytes,
81004
- swapTotalBytes
81005
- };
81006
- }
81007
- };
81008
- function aggregateCpuTimes() {
81009
- const cpus = node_os.cpus();
81010
- let user = 0, nice = 0, sys = 0, irq = 0, idle = 0;
81011
- for (const cpu of cpus) {
81012
- user += cpu.times.user;
81013
- nice += cpu.times.nice;
81014
- sys += cpu.times.sys;
81015
- irq += cpu.times.irq;
81016
- idle += cpu.times.idle;
81017
- }
81018
- return {
81019
- user,
81020
- nice,
81021
- sys,
81022
- irq,
81023
- idle
81024
- };
81025
- }
81026
- function sampleMacMemory(provider) {
81027
- try {
81028
- const output = (0, node_child_process.execFileSync)("vm_stat", {
81029
- timeout: 2e3,
81030
- encoding: "utf-8"
81031
- });
81032
- const pageSize = 16384;
81033
- const parse4 = (label) => {
81034
- const match = output.match(new RegExp(`${label}:\\s+(\\d+)`));
81035
- return match ? parseInt(match[1], 10) * pageSize : 0;
81036
- };
81037
- const free = parse4("Pages free");
81038
- const inactive = parse4("Pages inactive");
81039
- const purgeable = parse4("Pages purgeable");
81040
- const speculative = parse4("Pages speculative");
81041
- const available = free + inactive + purgeable + speculative;
81042
- const total = node_os.totalmem();
81043
- const used = total - available;
81044
- let swapUsedBytes = 0;
81045
- let swapTotalBytes = 0;
81046
- try {
81047
- const swapOut = (0, node_child_process.execFileSync)("sysctl", ["-n", "vm.swapusage"], {
81048
- timeout: 2e3,
81049
- encoding: "utf-8"
81050
- });
81051
- const totalMatch = swapOut.match(/total\s*=\s*([\d.]+)M/);
81052
- const usedMatch = swapOut.match(/used\s*=\s*([\d.]+)M/);
81053
- if (totalMatch) swapTotalBytes = parseFloat(totalMatch[1]) * 1024 * 1024;
81054
- if (usedMatch) swapUsedBytes = parseFloat(usedMatch[1]) * 1024 * 1024;
81055
- } catch {
81056
- }
81057
- provider._cachedMacMem = {
81058
- percent: Math.round(used / total * 1e3) / 10,
81059
- totalBytes: total,
81060
- usedBytes: used,
81061
- availableBytes: available,
81062
- swapUsedBytes,
81063
- swapTotalBytes
81064
- };
81065
- } catch {
81066
- provider._cachedMacMem = null;
81067
- }
81068
- }
81069
- function getDiskSpaceInternal(dirPath) {
81070
- return new Promise((resolve, reject) => {
81071
- node_fs.statfs(dirPath, (err, stats) => {
81072
- if (err) return reject(err);
81073
- const totalBytes = stats.blocks * stats.bsize;
81074
- const availableBytes = stats.bavail * stats.bsize;
81075
- const usedBytes = totalBytes - stats.bfree * stats.bsize;
81076
- resolve({
81077
- path: dirPath,
81078
- totalBytes,
81079
- usedBytes,
81080
- availableBytes,
81081
- percent: totalBytes > 0 ? Math.round(usedBytes / totalBytes * 1e3) / 10 : 0
81082
- });
81083
- });
81084
- });
81085
- }
81086
- async function takeDiskIoSnapshot() {
81087
- const now = Date.now();
81088
- if (IS_LINUX) try {
81089
- const data = node_fs.readFileSync("/proc/diskstats", "utf-8");
81090
- let readOps = 0, readBytes = 0, writeOps = 0, writeBytes = 0;
81091
- for (const line of data.split("\n")) {
81092
- const parts = line.trim().split(/\s+/);
81093
- if (parts.length < 14) continue;
81094
- const devName = parts[2];
81095
- if (/\d+$/.test(devName) && !/^nvme\d+n\d+$/.test(devName)) continue;
81096
- readOps += parseInt(parts[3], 10) || 0;
81097
- readBytes += (parseInt(parts[5], 10) || 0) * 512;
81098
- writeOps += parseInt(parts[7], 10) || 0;
81099
- writeBytes += (parseInt(parts[9], 10) || 0) * 512;
81100
- }
81101
- return {
81102
- readBytes,
81103
- writeBytes,
81104
- readOps,
81105
- writeOps,
81106
- timestampMs: now
81107
- };
81108
- } catch {
81109
- }
81110
- return {
81111
- readBytes: 0,
81112
- writeBytes: 0,
81113
- readOps: 0,
81114
- writeOps: 0,
81115
- timestampMs: now
81116
- };
81117
- }
81118
- async function takeNetworkIoSnapshot() {
81119
- const now = Date.now();
81120
- if (IS_LINUX) try {
81121
- const data = node_fs.readFileSync("/proc/net/dev", "utf-8");
81122
- let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
81123
- for (const line of data.split("\n")) {
81124
- const match = line.match(/^\s*(\w+):\s+(.+)$/);
81125
- if (!match) continue;
81126
- if (match[1] === "lo") continue;
81127
- const cols = match[2].trim().split(/\s+/);
81128
- rxBytes += parseInt(cols[0], 10) || 0;
81129
- rxPackets += parseInt(cols[1], 10) || 0;
81130
- rxErrors += parseInt(cols[2], 10) || 0;
81131
- txBytes += parseInt(cols[8], 10) || 0;
81132
- txPackets += parseInt(cols[9], 10) || 0;
81133
- txErrors += parseInt(cols[10], 10) || 0;
81134
- }
81135
- return {
81136
- rxBytes,
81137
- txBytes,
81138
- rxPackets,
81139
- txPackets,
81140
- rxErrors,
81141
- txErrors,
81142
- timestampMs: now
81143
- };
81144
- } catch {
81145
- }
81146
- if (IS_DARWIN) try {
81147
- const stdout = await execAsync("netstat", ["-ib"]);
81148
- let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
81149
- for (const line of stdout.split("\n")) {
81150
- const parts = line.trim().split(/\s+/);
81151
- if (parts.length < 11) continue;
81152
- if (parts[0] === "lo0" || parts[0] === "Name") continue;
81153
- if (!parts[2]?.startsWith("Link#")) continue;
81154
- rxPackets += parseInt(parts[4], 10) || 0;
81155
- rxErrors += parseInt(parts[5], 10) || 0;
81156
- rxBytes += parseInt(parts[6], 10) || 0;
81157
- txPackets += parseInt(parts[7], 10) || 0;
81158
- txErrors += parseInt(parts[8], 10) || 0;
81159
- txBytes += parseInt(parts[9], 10) || 0;
81160
- }
81161
- return {
81162
- rxBytes,
81163
- txBytes,
81164
- rxPackets,
81165
- txPackets,
81166
- rxErrors,
81167
- txErrors,
81168
- timestampMs: now
81169
- };
81170
- } catch {
81171
- }
81172
- return {
81173
- rxBytes: 0,
81174
- txBytes: 0,
81175
- rxPackets: 0,
81176
- txPackets: 0,
81177
- rxErrors: 0,
81178
- txErrors: 0,
81179
- timestampMs: now
81180
- };
81181
- }
81182
- async function getCpuTemperatureInternal() {
81183
- if (IS_LINUX) for (const p of ["/sys/class/thermal/thermal_zone0/temp", "/sys/class/hwmon/hwmon0/temp1_input"]) try {
81184
- const raw = node_fs.readFileSync(p, "utf-8").trim();
81185
- const millideg = parseInt(raw, 10);
81186
- if (!isNaN(millideg)) return Math.round(millideg / 100) / 10;
81187
- } catch {
81188
- continue;
81189
- }
81190
- if (IS_DARWIN) try {
81191
- const match = (await execAsync("sudo", [
81192
- "-n",
81193
- "powermetrics",
81194
- "--samplers",
81195
- "smc",
81196
- "-i",
81197
- "1",
81198
- "-n",
81199
- "1"
81200
- ], 3e3)).match(/CPU die temperature:\s+([\d.]+)\s*C/);
81201
- if (match) return Math.round(parseFloat(match[1]) * 10) / 10;
81202
- } catch {
81203
- }
81204
- return null;
81205
- }
81206
- async function getGpuInfoInternal() {
81207
- if (IS_DARWIN) try {
81208
- const utilMatch = (await execAsync("ioreg", [
81209
- "-r",
81210
- "-d",
81211
- "1",
81212
- "-c",
81213
- "IOAccelerator"
81214
- ])).match(/"GPU Core Utilization"\s*=\s*(\d+)/);
81215
- const util = utilMatch ? parseInt(utilMatch[1], 10) : 0;
81216
- const utilPct = util > 1e3 ? Math.round(util / 1e7) : util;
81217
- return {
81218
- utilization: Math.min(100, utilPct),
81219
- model: "Apple Silicon GPU",
81220
- memoryUsedBytes: 0,
81221
- memoryTotalBytes: 0,
81222
- temperature: null
81223
- };
81224
- } catch {
81225
- }
81226
- if (IS_LINUX) try {
81227
- const parts = (await execAsync("nvidia-smi", ["--query-gpu=utilization.gpu,name,memory.used,memory.total,temperature.gpu", "--format=csv,noheader,nounits"])).trim().split(",").map((s) => s.trim());
81228
- if (parts.length >= 5) return {
81229
- utilization: parseInt(parts[0], 10) || 0,
81230
- model: parts[1] ?? "Unknown GPU",
81231
- memoryUsedBytes: (parseInt(parts[2], 10) || 0) * 1024 * 1024,
81232
- memoryTotalBytes: (parseInt(parts[3], 10) || 0) * 1024 * 1024,
81233
- temperature: parseInt(parts[4], 10) || null
81234
- };
81235
- } catch {
81236
- }
81237
- return null;
81238
- }
81239
- function getProcessResources() {
81240
- let openFds = 0;
81241
- let threadCount = 0;
81242
- if (IS_LINUX) {
81243
- try {
81244
- openFds = node_fs.readdirSync(`/proc/${process.pid}/fd`).length;
81245
- } catch {
81246
- }
81247
- try {
81248
- const match = node_fs.readFileSync(`/proc/${process.pid}/status`, "utf-8").match(/Threads:\s+(\d+)/);
81249
- if (match) threadCount = parseInt(match[1], 10);
81250
- } catch {
81251
- }
81252
- }
81253
- const nodeProcess = process;
81254
- return {
81255
- openFds,
81256
- threadCount,
81257
- activeHandles: (nodeProcess._getActiveHandles?.() ?? []).length,
81258
- activeRequests: (nodeProcess._getActiveRequests?.() ?? []).length
81259
- };
81260
- }
81261
- function getPressure(resource) {
81262
- if (!IS_LINUX) return null;
81263
- try {
81264
- const data = node_fs.readFileSync(`/proc/pressure/${resource}`, "utf-8");
81265
- const parseLine = (prefix) => {
81266
- const match = data.match(new RegExp(`${prefix} avg10=(\\d+\\.\\d+) avg60=(\\d+\\.\\d+) avg300=(\\d+\\.\\d+)`));
81267
- if (!match) return null;
81268
- return {
81269
- avg10: parseFloat(match[1]),
81270
- avg60: parseFloat(match[2]),
81271
- avg300: parseFloat(match[3])
81272
- };
81273
- };
81274
- const some = parseLine("some");
81275
- if (!some) return null;
81276
- return {
81277
- some,
81278
- full: parseLine("full")
81279
- };
81280
- } catch {
81281
- return null;
81282
- }
81283
- }
81284
- function execAsync(cmd, args, timeoutMs = 5e3) {
81285
- return new Promise((resolve, reject) => {
81286
- (0, node_child_process.execFile)(cmd, args, { timeout: timeoutMs }, (err, stdout) => {
81287
- if (err) return reject(err);
81288
- resolve(stdout);
81289
- });
81290
- });
81291
- }
81292
80850
  var LOAD_SERIES_COLLECTION = "metrics:node-load-samples";
81293
80851
  var DEFAULT_MAX_ROWS = 5e5;
81294
80852
  var LOAD_SERIES_COLUMNS = [
@@ -81801,6 +81359,657 @@ var require_native_metrics_addon = __commonJS({
81801
81359
  oldestAtMs
81802
81360
  };
81803
81361
  }
81362
+ var nodeAccessCheck = (path) => (0, node_fs_promises.access)(path, node_fs.constants.X_OK);
81363
+ async function findOnPath(binary, pathEnv, check = nodeAccessCheck) {
81364
+ const dirs = (pathEnv ?? "").split(":").filter((dir) => dir.length > 0);
81365
+ for (const dir of dirs) {
81366
+ const candidate = `${dir}/${binary}`;
81367
+ try {
81368
+ await check(candidate);
81369
+ return candidate;
81370
+ } catch {
81371
+ }
81372
+ }
81373
+ return null;
81374
+ }
81375
+ var NVIDIA_SMI_ARGS = ["--query-gpu=utilization.gpu,name,memory.used,memory.total,temperature.gpu", "--format=csv,noheader,nounits"];
81376
+ async function readNvidiaGpu(deps) {
81377
+ const binary = await deps.findOnPath("nvidia-smi");
81378
+ if (binary === null) return null;
81379
+ let stdout;
81380
+ try {
81381
+ stdout = await deps.exec(binary, NVIDIA_SMI_ARGS);
81382
+ } catch {
81383
+ return null;
81384
+ }
81385
+ const parts = stdout.trim().split(",").map((s) => s.trim());
81386
+ if (parts.length < 5) return null;
81387
+ return {
81388
+ utilization: parseInt(parts[0], 10) || 0,
81389
+ model: parts[1] ?? "Unknown GPU",
81390
+ memoryUsedBytes: (parseInt(parts[2], 10) || 0) * 1024 * 1024,
81391
+ memoryTotalBytes: (parseInt(parts[3], 10) || 0) * 1024 * 1024,
81392
+ temperature: parseInt(parts[4], 10) || null
81393
+ };
81394
+ }
81395
+ var IS_DARWIN = node_os.platform() === "darwin";
81396
+ var IS_LINUX = node_os.platform() === "linux";
81397
+ var NativeMetricsProvider = class {
81398
+ id = "native";
81399
+ cachedSnapshot = null;
81400
+ samplingTimer = null;
81401
+ macMemTimer = null;
81402
+ prevCpu;
81403
+ diagnostics = null;
81404
+ consecutiveSampleErrors = 0;
81405
+ constructor() {
81406
+ this.prevCpu = aggregateCpuTimes();
81407
+ }
81408
+ /**
81409
+ * Optional diagnostics sink for sampling errors. The first failure and
81410
+ * every Nth failure thereafter are reported so a permanently-broken
81411
+ * collector doesn't spam logs but is still observable.
81412
+ */
81413
+ setDiagnostics(diag) {
81414
+ this.diagnostics = diag;
81415
+ }
81416
+ startSampling(intervalMs) {
81417
+ if (IS_DARWIN) {
81418
+ sampleMacMemory(this);
81419
+ this.macMemTimer = setInterval(() => sampleMacMemory(this), 5e3);
81420
+ if (this.macMemTimer.unref) this.macMemTimer.unref();
81421
+ }
81422
+ this.collectSnapshot().then((s) => {
81423
+ this.cachedSnapshot = s;
81424
+ this.consecutiveSampleErrors = 0;
81425
+ }).catch((err) => this.reportSampleError(err));
81426
+ this.samplingTimer = setInterval(() => {
81427
+ this.collectSnapshot().then((s) => {
81428
+ this.cachedSnapshot = s;
81429
+ this.consecutiveSampleErrors = 0;
81430
+ }).catch((err) => this.reportSampleError(err));
81431
+ }, intervalMs);
81432
+ if (this.samplingTimer.unref) this.samplingTimer.unref();
81433
+ }
81434
+ reportSampleError(err) {
81435
+ this.consecutiveSampleErrors++;
81436
+ if (!this.diagnostics) return;
81437
+ if (!(this.consecutiveSampleErrors === 1 || this.consecutiveSampleErrors % 60 === 0)) return;
81438
+ this.diagnostics.warn("metrics-provider sample failed", {
81439
+ consecutiveErrors: this.consecutiveSampleErrors,
81440
+ error: err instanceof Error ? err.message : String(err)
81441
+ });
81442
+ }
81443
+ stopSampling() {
81444
+ if (this.samplingTimer) {
81445
+ clearInterval(this.samplingTimer);
81446
+ this.samplingTimer = null;
81447
+ }
81448
+ if (this.macMemTimer) {
81449
+ clearInterval(this.macMemTimer);
81450
+ this.macMemTimer = null;
81451
+ }
81452
+ }
81453
+ async collectSnapshot() {
81454
+ const cpu = this.sampleCpu();
81455
+ const memory = this.getMemoryInfo();
81456
+ const processInfo = getProcessResources();
81457
+ const [gpu, network, disk, cpuTemp] = await Promise.all([
81458
+ getGpuInfoInternal().catch(() => null),
81459
+ takeNetworkIoSnapshot(),
81460
+ takeDiskIoSnapshot(),
81461
+ getCpuTemperatureInternal().catch(() => null)
81462
+ ]);
81463
+ const snapshot = {
81464
+ cpu,
81465
+ memory,
81466
+ gpu,
81467
+ network,
81468
+ disk,
81469
+ pressure: {
81470
+ cpu: getPressure("cpu"),
81471
+ memory: getPressure("memory"),
81472
+ io: getPressure("io")
81473
+ },
81474
+ process: processInfo,
81475
+ cpuTemperature: cpuTemp,
81476
+ timestampMs: Date.now()
81477
+ };
81478
+ this.cachedSnapshot = snapshot;
81479
+ return snapshot;
81480
+ }
81481
+ async getCached() {
81482
+ return this.cachedSnapshot;
81483
+ }
81484
+ async getCurrent() {
81485
+ const s = this.cachedSnapshot ?? await this.collectSnapshot();
81486
+ const mb = (bytes) => Math.round(bytes / 1024 / 1024);
81487
+ return {
81488
+ cpuPercent: s.cpu.total,
81489
+ memoryPercent: s.memory.percent,
81490
+ memoryUsedMB: mb(s.memory.usedBytes),
81491
+ memoryTotalMB: mb(s.memory.totalBytes),
81492
+ temperature: s.cpuTemperature ?? void 0,
81493
+ gpuPercent: s.gpu?.utilization,
81494
+ gpuMemoryPercent: s.gpu && s.gpu.memoryTotalBytes > 0 ? Math.round(s.gpu.memoryUsedBytes / s.gpu.memoryTotalBytes * 1e3) / 10 : void 0
81495
+ };
81496
+ }
81497
+ async getDiskSpace(input) {
81498
+ return getDiskSpaceInternal(input.dirPath);
81499
+ }
81500
+ async getGpuInfo() {
81501
+ return getGpuInfoInternal();
81502
+ }
81503
+ async getCpuTemperature() {
81504
+ return getCpuTemperatureInternal();
81505
+ }
81506
+ async getProcessStats(input) {
81507
+ const { getPidStats } = await Promise.resolve().then(() => require_resource_monitor_LVE1BoLs()).then((n) => n.resource_monitor_exports);
81508
+ const raw = await getPidStats(input.pids);
81509
+ const result = [];
81510
+ for (const [pid, s] of raw) result.push({
81511
+ pid,
81512
+ cpu: s.cpu,
81513
+ memory: s.memory,
81514
+ privateBytes: s.privateBytes,
81515
+ sharedBytes: s.sharedBytes
81516
+ });
81517
+ return result;
81518
+ }
81519
+ sampleCpu() {
81520
+ const curr = aggregateCpuTimes();
81521
+ const prev = this.prevCpu;
81522
+ this.prevCpu = curr;
81523
+ const dUser = curr.user - prev.user;
81524
+ const dNice = curr.nice - prev.nice;
81525
+ const dSys = curr.sys - prev.sys;
81526
+ const dIrq = curr.irq - prev.irq;
81527
+ const dIdle = curr.idle - prev.idle;
81528
+ const dTotal = dUser + dNice + dSys + dIrq + dIdle;
81529
+ const pct = (v) => dTotal === 0 ? 0 : Math.round(v / dTotal * 1e3) / 10;
81530
+ return {
81531
+ total: pct(dUser + dNice + dSys + dIrq),
81532
+ user: pct(dUser),
81533
+ system: pct(dSys),
81534
+ irq: pct(dIrq),
81535
+ nice: pct(dNice),
81536
+ loadAvg: node_os.loadavg(),
81537
+ cores: node_os.cpus().length
81538
+ };
81539
+ }
81540
+ /** Cached macOS memory (set by sampleMacMemory timer). */
81541
+ _cachedMacMem = null;
81542
+ getMemoryInfo() {
81543
+ const total = node_os.totalmem();
81544
+ if (total === 0) return {
81545
+ percent: 0,
81546
+ totalBytes: 0,
81547
+ usedBytes: 0,
81548
+ availableBytes: 0,
81549
+ swapUsedBytes: 0,
81550
+ swapTotalBytes: 0
81551
+ };
81552
+ if (IS_DARWIN && this._cachedMacMem !== null) return this._cachedMacMem;
81553
+ const free = node_os.freemem();
81554
+ const used = total - free;
81555
+ let swapUsedBytes = 0;
81556
+ let swapTotalBytes = 0;
81557
+ if (IS_LINUX) try {
81558
+ const meminfo = node_fs.readFileSync("/proc/meminfo", "utf-8");
81559
+ const swapTotal = parseInt(meminfo.match(/SwapTotal:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
81560
+ const swapFree = parseInt(meminfo.match(/SwapFree:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
81561
+ swapTotalBytes = swapTotal;
81562
+ swapUsedBytes = swapTotal - swapFree;
81563
+ } catch {
81564
+ }
81565
+ return {
81566
+ percent: Math.round((total - free) / total * 1e3) / 10,
81567
+ totalBytes: total,
81568
+ usedBytes: used,
81569
+ availableBytes: free,
81570
+ swapUsedBytes,
81571
+ swapTotalBytes
81572
+ };
81573
+ }
81574
+ };
81575
+ function aggregateCpuTimes() {
81576
+ const cpus = node_os.cpus();
81577
+ let user = 0, nice = 0, sys = 0, irq = 0, idle = 0;
81578
+ for (const cpu of cpus) {
81579
+ user += cpu.times.user;
81580
+ nice += cpu.times.nice;
81581
+ sys += cpu.times.sys;
81582
+ irq += cpu.times.irq;
81583
+ idle += cpu.times.idle;
81584
+ }
81585
+ return {
81586
+ user,
81587
+ nice,
81588
+ sys,
81589
+ irq,
81590
+ idle
81591
+ };
81592
+ }
81593
+ function sampleMacMemory(provider) {
81594
+ try {
81595
+ const output = (0, node_child_process.execFileSync)("vm_stat", {
81596
+ timeout: 2e3,
81597
+ encoding: "utf-8"
81598
+ });
81599
+ const pageSize = 16384;
81600
+ const parse4 = (label) => {
81601
+ const match = output.match(new RegExp(`${label}:\\s+(\\d+)`));
81602
+ return match ? parseInt(match[1], 10) * pageSize : 0;
81603
+ };
81604
+ const free = parse4("Pages free");
81605
+ const inactive = parse4("Pages inactive");
81606
+ const purgeable = parse4("Pages purgeable");
81607
+ const speculative = parse4("Pages speculative");
81608
+ const available = free + inactive + purgeable + speculative;
81609
+ const total = node_os.totalmem();
81610
+ const used = total - available;
81611
+ let swapUsedBytes = 0;
81612
+ let swapTotalBytes = 0;
81613
+ try {
81614
+ const swapOut = (0, node_child_process.execFileSync)("sysctl", ["-n", "vm.swapusage"], {
81615
+ timeout: 2e3,
81616
+ encoding: "utf-8"
81617
+ });
81618
+ const totalMatch = swapOut.match(/total\s*=\s*([\d.]+)M/);
81619
+ const usedMatch = swapOut.match(/used\s*=\s*([\d.]+)M/);
81620
+ if (totalMatch) swapTotalBytes = parseFloat(totalMatch[1]) * 1024 * 1024;
81621
+ if (usedMatch) swapUsedBytes = parseFloat(usedMatch[1]) * 1024 * 1024;
81622
+ } catch {
81623
+ }
81624
+ provider._cachedMacMem = {
81625
+ percent: Math.round(used / total * 1e3) / 10,
81626
+ totalBytes: total,
81627
+ usedBytes: used,
81628
+ availableBytes: available,
81629
+ swapUsedBytes,
81630
+ swapTotalBytes
81631
+ };
81632
+ } catch {
81633
+ provider._cachedMacMem = null;
81634
+ }
81635
+ }
81636
+ function getDiskSpaceInternal(dirPath) {
81637
+ return new Promise((resolve, reject) => {
81638
+ node_fs.statfs(dirPath, (err, stats) => {
81639
+ if (err) return reject(err);
81640
+ const totalBytes = stats.blocks * stats.bsize;
81641
+ const availableBytes = stats.bavail * stats.bsize;
81642
+ const usedBytes = totalBytes - stats.bfree * stats.bsize;
81643
+ resolve({
81644
+ path: dirPath,
81645
+ totalBytes,
81646
+ usedBytes,
81647
+ availableBytes,
81648
+ percent: totalBytes > 0 ? Math.round(usedBytes / totalBytes * 1e3) / 10 : 0
81649
+ });
81650
+ });
81651
+ });
81652
+ }
81653
+ async function takeDiskIoSnapshot() {
81654
+ const now = Date.now();
81655
+ if (IS_LINUX) try {
81656
+ const data = node_fs.readFileSync("/proc/diskstats", "utf-8");
81657
+ let readOps = 0, readBytes = 0, writeOps = 0, writeBytes = 0;
81658
+ for (const line of data.split("\n")) {
81659
+ const parts = line.trim().split(/\s+/);
81660
+ if (parts.length < 14) continue;
81661
+ const devName = parts[2];
81662
+ if (/\d+$/.test(devName) && !/^nvme\d+n\d+$/.test(devName)) continue;
81663
+ readOps += parseInt(parts[3], 10) || 0;
81664
+ readBytes += (parseInt(parts[5], 10) || 0) * 512;
81665
+ writeOps += parseInt(parts[7], 10) || 0;
81666
+ writeBytes += (parseInt(parts[9], 10) || 0) * 512;
81667
+ }
81668
+ return {
81669
+ readBytes,
81670
+ writeBytes,
81671
+ readOps,
81672
+ writeOps,
81673
+ timestampMs: now
81674
+ };
81675
+ } catch {
81676
+ }
81677
+ return {
81678
+ readBytes: 0,
81679
+ writeBytes: 0,
81680
+ readOps: 0,
81681
+ writeOps: 0,
81682
+ timestampMs: now
81683
+ };
81684
+ }
81685
+ async function takeNetworkIoSnapshot() {
81686
+ const now = Date.now();
81687
+ if (IS_LINUX) try {
81688
+ const data = node_fs.readFileSync("/proc/net/dev", "utf-8");
81689
+ let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
81690
+ for (const line of data.split("\n")) {
81691
+ const match = line.match(/^\s*(\w+):\s+(.+)$/);
81692
+ if (!match) continue;
81693
+ if (match[1] === "lo") continue;
81694
+ const cols = match[2].trim().split(/\s+/);
81695
+ rxBytes += parseInt(cols[0], 10) || 0;
81696
+ rxPackets += parseInt(cols[1], 10) || 0;
81697
+ rxErrors += parseInt(cols[2], 10) || 0;
81698
+ txBytes += parseInt(cols[8], 10) || 0;
81699
+ txPackets += parseInt(cols[9], 10) || 0;
81700
+ txErrors += parseInt(cols[10], 10) || 0;
81701
+ }
81702
+ return {
81703
+ rxBytes,
81704
+ txBytes,
81705
+ rxPackets,
81706
+ txPackets,
81707
+ rxErrors,
81708
+ txErrors,
81709
+ timestampMs: now
81710
+ };
81711
+ } catch {
81712
+ }
81713
+ if (IS_DARWIN) try {
81714
+ const stdout = await execAsync("netstat", ["-ib"]);
81715
+ let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
81716
+ for (const line of stdout.split("\n")) {
81717
+ const parts = line.trim().split(/\s+/);
81718
+ if (parts.length < 11) continue;
81719
+ if (parts[0] === "lo0" || parts[0] === "Name") continue;
81720
+ if (!parts[2]?.startsWith("Link#")) continue;
81721
+ rxPackets += parseInt(parts[4], 10) || 0;
81722
+ rxErrors += parseInt(parts[5], 10) || 0;
81723
+ rxBytes += parseInt(parts[6], 10) || 0;
81724
+ txPackets += parseInt(parts[7], 10) || 0;
81725
+ txErrors += parseInt(parts[8], 10) || 0;
81726
+ txBytes += parseInt(parts[9], 10) || 0;
81727
+ }
81728
+ return {
81729
+ rxBytes,
81730
+ txBytes,
81731
+ rxPackets,
81732
+ txPackets,
81733
+ rxErrors,
81734
+ txErrors,
81735
+ timestampMs: now
81736
+ };
81737
+ } catch {
81738
+ }
81739
+ return {
81740
+ rxBytes: 0,
81741
+ txBytes: 0,
81742
+ rxPackets: 0,
81743
+ txPackets: 0,
81744
+ rxErrors: 0,
81745
+ txErrors: 0,
81746
+ timestampMs: now
81747
+ };
81748
+ }
81749
+ async function getCpuTemperatureInternal() {
81750
+ if (IS_LINUX) for (const p of ["/sys/class/thermal/thermal_zone0/temp", "/sys/class/hwmon/hwmon0/temp1_input"]) try {
81751
+ const raw = node_fs.readFileSync(p, "utf-8").trim();
81752
+ const millideg = parseInt(raw, 10);
81753
+ if (!isNaN(millideg)) return Math.round(millideg / 100) / 10;
81754
+ } catch {
81755
+ continue;
81756
+ }
81757
+ if (IS_DARWIN) try {
81758
+ const match = (await execAsync("sudo", [
81759
+ "-n",
81760
+ "powermetrics",
81761
+ "--samplers",
81762
+ "smc",
81763
+ "-i",
81764
+ "1",
81765
+ "-n",
81766
+ "1"
81767
+ ], 3e3)).match(/CPU die temperature:\s+([\d.]+)\s*C/);
81768
+ if (match) return Math.round(parseFloat(match[1]) * 10) / 10;
81769
+ } catch {
81770
+ }
81771
+ return null;
81772
+ }
81773
+ async function getGpuInfoInternal() {
81774
+ if (IS_DARWIN) try {
81775
+ const utilMatch = (await execAsync("ioreg", [
81776
+ "-r",
81777
+ "-d",
81778
+ "1",
81779
+ "-c",
81780
+ "IOAccelerator"
81781
+ ])).match(/"GPU Core Utilization"\s*=\s*(\d+)/);
81782
+ const util = utilMatch ? parseInt(utilMatch[1], 10) : 0;
81783
+ const utilPct = util > 1e3 ? Math.round(util / 1e7) : util;
81784
+ return {
81785
+ utilization: Math.min(100, utilPct),
81786
+ model: "Apple Silicon GPU",
81787
+ memoryUsedBytes: 0,
81788
+ memoryTotalBytes: 0,
81789
+ temperature: null
81790
+ };
81791
+ } catch {
81792
+ }
81793
+ if (IS_LINUX) return readNvidiaGpu({
81794
+ findOnPath: (binary) => findOnPath(binary, process.env["PATH"]),
81795
+ exec: (command, args) => execAsync(command, [...args])
81796
+ });
81797
+ return null;
81798
+ }
81799
+ function getProcessResources() {
81800
+ let openFds = 0;
81801
+ let threadCount = 0;
81802
+ if (IS_LINUX) {
81803
+ try {
81804
+ openFds = node_fs.readdirSync(`/proc/${process.pid}/fd`).length;
81805
+ } catch {
81806
+ }
81807
+ try {
81808
+ const match = node_fs.readFileSync(`/proc/${process.pid}/status`, "utf-8").match(/Threads:\s+(\d+)/);
81809
+ if (match) threadCount = parseInt(match[1], 10);
81810
+ } catch {
81811
+ }
81812
+ }
81813
+ const nodeProcess = process;
81814
+ return {
81815
+ openFds,
81816
+ threadCount,
81817
+ activeHandles: (nodeProcess._getActiveHandles?.() ?? []).length,
81818
+ activeRequests: (nodeProcess._getActiveRequests?.() ?? []).length
81819
+ };
81820
+ }
81821
+ function getPressure(resource) {
81822
+ if (!IS_LINUX) return null;
81823
+ try {
81824
+ const data = node_fs.readFileSync(`/proc/pressure/${resource}`, "utf-8");
81825
+ const parseLine = (prefix) => {
81826
+ const match = data.match(new RegExp(`${prefix} avg10=(\\d+\\.\\d+) avg60=(\\d+\\.\\d+) avg300=(\\d+\\.\\d+)`));
81827
+ if (!match) return null;
81828
+ return {
81829
+ avg10: parseFloat(match[1]),
81830
+ avg60: parseFloat(match[2]),
81831
+ avg300: parseFloat(match[3])
81832
+ };
81833
+ };
81834
+ const some = parseLine("some");
81835
+ if (!some) return null;
81836
+ return {
81837
+ some,
81838
+ full: parseLine("full")
81839
+ };
81840
+ } catch {
81841
+ return null;
81842
+ }
81843
+ }
81844
+ function execAsync(cmd, args, timeoutMs = 5e3) {
81845
+ return new Promise((resolve, reject) => {
81846
+ (0, node_child_process.execFile)(cmd, args, { timeout: timeoutMs }, (err, stdout) => {
81847
+ if (err) return reject(err);
81848
+ resolve(stdout);
81849
+ });
81850
+ });
81851
+ }
81852
+ function parseProcStat(line) {
81853
+ const close = line.lastIndexOf(")");
81854
+ const open = line.indexOf("(");
81855
+ if (close < 0 || open < 0 || close < open) return null;
81856
+ const pid = Number(line.slice(0, open).trim());
81857
+ const comm = line.slice(open + 1, close);
81858
+ const rest = line.slice(close + 1).trim().split(/\s+/);
81859
+ const state = rest[0];
81860
+ const ppid = Number(rest[1]);
81861
+ const pgid = Number(rest[2]);
81862
+ const utime = Number(rest[11]);
81863
+ const stime = Number(rest[12]);
81864
+ const startTicks = Number(rest[19]);
81865
+ const rssPages = Number(rest[21]);
81866
+ if (state === void 0 || state === "") return null;
81867
+ if (![
81868
+ pid,
81869
+ ppid,
81870
+ pgid,
81871
+ utime,
81872
+ stime,
81873
+ startTicks,
81874
+ rssPages
81875
+ ].every(Number.isFinite)) return null;
81876
+ return {
81877
+ pid,
81878
+ comm,
81879
+ state,
81880
+ ppid,
81881
+ pgid,
81882
+ ticks: utime + stime,
81883
+ startTicks,
81884
+ rssPages
81885
+ };
81886
+ }
81887
+ function statusKb(status, key) {
81888
+ const match = status.match(new RegExp(`^${key}:\\s+(\\d+)`, "m"));
81889
+ return match ? parseInt(match[1], 10) * 1024 : void 0;
81890
+ }
81891
+ function parseProcStatusRss(status) {
81892
+ return {
81893
+ rssBytes: statusKb(status, "VmRSS"),
81894
+ privateBytes: statusKb(status, "RssAnon"),
81895
+ sharedBytes: statusKb(status, "RssFile")
81896
+ };
81897
+ }
81898
+ function elapsedSecSince(input) {
81899
+ return Math.max(0, Math.floor(input.uptimeSec - input.startTicks / 100));
81900
+ }
81901
+ function lifetimeCpuPercent(input) {
81902
+ const elapsedSec = input.uptimeSec - input.startTicks / 100;
81903
+ if (!(elapsedSec > 0)) return 0;
81904
+ const cpuSec = input.ticks / 100;
81905
+ return Math.round(cpuSec / elapsedSec * 1e3) / 10;
81906
+ }
81907
+ var PID_RE = /^\d+$/;
81908
+ var nodeProcReader = {
81909
+ listPids: async () => (await (0, node_fs_promises.readdir)("/proc")).filter((entry) => PID_RE.test(entry)).map((entry) => Number(entry)),
81910
+ readStat: (pid) => (0, node_fs_promises.readFile)(`/proc/${pid}/stat`, "latin1"),
81911
+ readStatus: (pid) => (0, node_fs_promises.readFile)(`/proc/${pid}/status`, "latin1"),
81912
+ readCmdline: (pid) => (0, node_fs_promises.readFile)(`/proc/${pid}/cmdline`, "latin1"),
81913
+ readUptimeSec: async () => {
81914
+ const [first] = (await (0, node_fs_promises.readFile)("/proc/uptime", "latin1")).trim().split(/\s+/);
81915
+ const seconds = Number(first);
81916
+ if (!Number.isFinite(seconds)) throw new Error(`/proc/uptime unreadable: ${String(first)}`);
81917
+ return seconds;
81918
+ }
81919
+ };
81920
+ function commandFromCmdline(cmdline, comm) {
81921
+ const joined = cmdline.split("\0").filter((part) => part.length > 0).join(" ");
81922
+ return joined.length > 0 ? joined : `[${comm}]`;
81923
+ }
81924
+ var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
81925
+ async function readProcRow(pid, uptimeSec, reader) {
81926
+ let stat;
81927
+ let cmdline;
81928
+ let status;
81929
+ try {
81930
+ [stat, cmdline, status] = await Promise.all([
81931
+ reader.readStat(pid),
81932
+ reader.readCmdline(pid),
81933
+ reader.readStatus(pid)
81934
+ ]);
81935
+ } catch {
81936
+ return null;
81937
+ }
81938
+ const parsed = parseProcStat(stat);
81939
+ if (parsed === null) return null;
81940
+ const rss = parseProcStatusRss(status);
81941
+ return {
81942
+ pid: parsed.pid,
81943
+ ppid: parsed.ppid,
81944
+ pgid: parsed.pgid,
81945
+ cpuPercent: lifetimeCpuPercent({
81946
+ ticks: parsed.ticks,
81947
+ startTicks: parsed.startTicks,
81948
+ uptimeSec
81949
+ }),
81950
+ memoryRssBytes: rss.rssBytes ?? 0,
81951
+ uptimeSec: elapsedSecSince({
81952
+ startTicks: parsed.startTicks,
81953
+ uptimeSec
81954
+ }),
81955
+ command: commandFromCmdline(cmdline, parsed.comm)
81956
+ };
81957
+ }
81958
+ async function readProcProcessTable(reader = nodeProcReader) {
81959
+ const [pids, uptimeSec] = await Promise.all([reader.listPids(), reader.readUptimeSec()]);
81960
+ return (await Promise.all(pids.map((pid) => readProcRow(pid, uptimeSec, reader)))).filter((row) => row !== null);
81961
+ }
81962
+ function parseEtime(etime) {
81963
+ const dashParts = etime.split("-");
81964
+ let days = 0;
81965
+ let hms = etime;
81966
+ if (dashParts.length === 2) {
81967
+ days = parseInt(dashParts[0], 10) || 0;
81968
+ hms = dashParts[1];
81969
+ }
81970
+ const parts = hms.split(":").map((p) => parseInt(p, 10) || 0);
81971
+ let hours = 0;
81972
+ let minutes = 0;
81973
+ let seconds = 0;
81974
+ if (parts.length === 3) [hours, minutes, seconds] = parts;
81975
+ else if (parts.length === 2) [minutes, seconds] = parts;
81976
+ else if (parts.length === 1) [seconds] = parts;
81977
+ return days * 86400 + hours * 3600 + minutes * 60 + seconds;
81978
+ }
81979
+ var PS_ROW_RE = /^(\d+)\s+(\d+)\s+(\d+)\s+([\d.]+)\s+(\d+)\s+(\S+)\s+(.+)$/;
81980
+ function parsePsTable(stdout) {
81981
+ const rows = [];
81982
+ for (const line of stdout.split("\n")) {
81983
+ const match = line.trim().match(PS_ROW_RE);
81984
+ if (!match) continue;
81985
+ const [, pidS, ppidS, pgidS, cpuS, rssS, etimeS, command] = match;
81986
+ rows.push({
81987
+ pid: parseInt(pidS, 10),
81988
+ ppid: parseInt(ppidS, 10),
81989
+ pgid: parseInt(pgidS, 10),
81990
+ cpuPercent: Math.round(parseFloat(cpuS) * 10) / 10,
81991
+ memoryRssBytes: parseInt(rssS, 10) * 1024,
81992
+ uptimeSec: parseEtime(etimeS),
81993
+ command
81994
+ });
81995
+ }
81996
+ return rows;
81997
+ }
81998
+ async function spawnPsTable() {
81999
+ const { stdout } = await execFileAsync("ps", ["-eo", "pid=,ppid=,pgid=,pcpu=,rss=,etime=,command="], {
82000
+ timeout: 5e3,
82001
+ maxBuffer: 8 * 1024 * 1024
82002
+ });
82003
+ return parsePsTable(stdout);
82004
+ }
82005
+ var defaultDeps = {
82006
+ platform: (0, node_os.platform)(),
82007
+ reader: nodeProcReader,
82008
+ spawnPs: spawnPsTable
82009
+ };
82010
+ function readProcessTable(deps = defaultDeps) {
82011
+ return deps.platform === "linux" ? readProcProcessTable(deps.reader) : deps.spawnPs();
82012
+ }
81804
82013
  var CAMSTACK_CMD_RE = /(camstack|tsx\s+watch\s.*launcher\.ts|packages\/agent\/dist\/cli\.js|inference_pool\.py|bench-(inference-pool|nodeav)|node .*\/packages\/)/;
81805
82014
  function classifyProcess(pid, selfPid, managed) {
81806
82015
  if (pid === selfPid) return "root";
@@ -81933,7 +82142,6 @@ var require_native_metrics_addon = __commonJS({
81933
82142
  return out;
81934
82143
  }
81935
82144
  };
81936
- var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
81937
82145
  var METRICS_SNAPSHOT_INTERVAL_MS = 5e3;
81938
82146
  var METRICS_SNAPSHOT_HEARTBEAT_MS = 6e4;
81939
82147
  function coarsenResourcesSnapshot(snapshot) {
@@ -82241,7 +82449,23 @@ var require_native_metrics_addon = __commonJS({
82241
82449
  } });
82242
82450
  }
82243
82451
  }
82244
- /** (Re)arm the fixed-cadence process-tree timer at the configured interval. */
82452
+ /**
82453
+ * (Re)arm the process-tree timer at the configured interval.
82454
+ *
82455
+ * The process-tree snapshot is FIXED-CADENCE, and its cadence is the
82456
+ * operator's `loadSeriesCadenceSec` (5-60 s, 10 by default).
82457
+ *
82458
+ * It used to emit only ON A CHANGE, with a 60 s fallback heartbeat, and the
82459
+ * dedup is gone rather than tuned. A conditional emit makes a hole in the
82460
+ * series mean two different things — "nothing changed" and "nobody reported"
82461
+ * — and telling those apart is the entire reason an operator opens this chart
82462
+ * after a spike. Now a gap means exactly one thing.
82463
+ *
82464
+ * It is not free: the emit rate is deterministic, so the durable table's row
82465
+ * count is too (nodes x processes / cadence, no discount for a quiet fleet).
82466
+ * The measured cost of that is in `docs/architecture/load-ledger.md`, and it
82467
+ * is why the retention default is six hours rather than three days.
82468
+ */
82245
82469
  startProcessSnapshotTimer() {
82246
82470
  if (this.processSnapshotTimer) clearInterval(this.processSnapshotTimer);
82247
82471
  this.processSnapshotTimer = setInterval(() => this.emitProcessesSnapshot(), this.loadConfig.cadenceSec * 1e3);
@@ -82304,7 +82528,8 @@ var require_native_metrics_addon = __commonJS({
82304
82528
  /**
82305
82529
  * Emit one `metrics.node-processes-snapshot` for this node.
82306
82530
  *
82307
- * Heavy — a full OS `ps -eo` scan plus a `$process.list` broker call — and
82531
+ * Heavy — a full process-table read (`/proc` on Linux, `ps -eo` elsewhere;
82532
+ * `proc-process-table.ts`) plus a `$process.list` broker call — and
82308
82533
  * UNCONDITIONAL. The change-detection that used to guard it is gone: with a
82309
82534
  * fixed cadence a missing interval means exactly one thing, and that is the
82310
82535
  * property an operator investigating a spike is actually looking for.
@@ -82408,34 +82633,18 @@ var require_native_metrics_addon = __commonJS({
82408
82633
  cpuSplits
82409
82634
  });
82410
82635
  }
82411
- /** Raw `ps` scan returning every pid + command + resource stats. */
82636
+ /**
82637
+ * Every pid + command + resource stats on this node.
82638
+ *
82639
+ * From `/proc` on Linux — no fork. This used to be a `ps -eo` child on every
82640
+ * tick, i.e. a synchronous `fork()` of hub-main at p50 91 ms (D441, D452).
82641
+ * `ps` remains the source only on a platform without `/proc`.
82642
+ */
82412
82643
  async runPs() {
82413
82644
  try {
82414
- const { stdout } = await execFileAsync("ps", ["-eo", "pid=,ppid=,pgid=,pcpu=,rss=,etime=,command="], {
82415
- timeout: 5e3,
82416
- maxBuffer: 8 * 1024 * 1024
82417
- });
82418
- const lines = stdout.split("\n");
82419
- const rows = [];
82420
- for (const line of lines) {
82421
- const trimmed = line.trim();
82422
- if (!trimmed) continue;
82423
- const match = trimmed.match(/^(\d+)\s+(\d+)\s+(\d+)\s+([\d.]+)\s+(\d+)\s+(\S+)\s+(.+)$/);
82424
- if (!match) continue;
82425
- const [, pidS, ppidS, pgidS, cpuS, rssS, etimeS, command] = match;
82426
- rows.push({
82427
- pid: parseInt(pidS, 10),
82428
- ppid: parseInt(ppidS, 10),
82429
- pgid: parseInt(pgidS, 10),
82430
- cpuPercent: Math.round(parseFloat(cpuS) * 10) / 10,
82431
- memoryRssBytes: parseInt(rssS, 10) * 1024,
82432
- uptimeSec: parseEtime(etimeS),
82433
- command
82434
- });
82435
- }
82436
- return rows;
82645
+ return await readProcessTable();
82437
82646
  } catch (err) {
82438
- this.ctx.logger.warn("ps scan failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
82647
+ this.ctx.logger.warn("process table read failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
82439
82648
  return [];
82440
82649
  }
82441
82650
  }
@@ -82520,23 +82729,12 @@ var require_native_metrics_addon = __commonJS({
82520
82729
  }] });
82521
82730
  }
82522
82731
  };
82523
- function parseEtime(etime) {
82524
- const dashParts = etime.split("-");
82525
- let days = 0;
82526
- let hms = etime;
82527
- if (dashParts.length === 2) {
82528
- days = parseInt(dashParts[0], 10) || 0;
82529
- hms = dashParts[1];
82530
- }
82531
- const parts = hms.split(":").map((p) => parseInt(p, 10) || 0);
82532
- let hours = 0, minutes = 0, seconds = 0;
82533
- if (parts.length === 3) [hours, minutes, seconds] = parts;
82534
- else if (parts.length === 2) [minutes, seconds] = parts;
82535
- else if (parts.length === 1) [seconds] = parts;
82536
- return days * 86400 + hours * 3600 + minutes * 60 + seconds;
82537
- }
82538
82732
  exports.NativeMetricsProvider = NativeMetricsProvider;
82539
82733
  exports.default = NativeMetricsAddon;
82734
+ exports.lifetimeCpuPercent = lifetimeCpuPercent;
82735
+ exports.nodeProcReader = nodeProcReader;
82736
+ exports.parseProcStat = parseProcStat;
82737
+ exports.parseProcStatusRss = parseProcStatusRss;
82540
82738
  }
82541
82739
  });
82542
82740
 
@@ -82549,7 +82747,7 @@ var require_filesystem_storage_addon = __commonJS({
82549
82747
  [Symbol.toStringTag]: { value: "Module" }
82550
82748
  });
82551
82749
  var require_chunk = require_chunk_Cek0wNdY();
82552
- var require_dist10 = require_dist_BOlMCOeT();
82750
+ var require_dist10 = require_dist_B17W9ngu();
82553
82751
  var node_crypto = __require("crypto");
82554
82752
  var node_fs_promises = __require("fs/promises");
82555
82753
  var node_path = __require("path");
@@ -82882,6 +83080,117 @@ var require_filesystem_storage_addon = __commonJS({
82882
83080
  }
82883
83081
  });
82884
83082
 
83083
+ // ../system/dist/wal-checkpoint-policy-CCJZngds.js
83084
+ var require_wal_checkpoint_policy_CCJZngds = __commonJS({
83085
+ "../system/dist/wal-checkpoint-policy-CCJZngds.js"(exports) {
83086
+ "use strict";
83087
+ var WAL_CHECKPOINT_MAX_INTERVAL_MS = 6e4;
83088
+ var WAL_CHECKPOINT_POLL_MS = 1e3;
83089
+ var WAL_CHECKPOINT_SLOW_MS = 1e3;
83090
+ function decideCheckpoint(input) {
83091
+ const intervalDue = input.sinceLastRunMs >= WAL_CHECKPOINT_MAX_INTERVAL_MS;
83092
+ if (input.mxFrame === null || input.nBackfill === null) return intervalDue ? {
83093
+ run: true,
83094
+ reason: "unknown-interval",
83095
+ pendingFrames: null
83096
+ } : {
83097
+ run: false,
83098
+ reason: "unknown-below-interval",
83099
+ pendingFrames: null
83100
+ };
83101
+ const pendingFrames = Math.max(0, input.mxFrame - input.nBackfill);
83102
+ if (pendingFrames === 0) return {
83103
+ run: false,
83104
+ reason: "nothing-pending",
83105
+ pendingFrames
83106
+ };
83107
+ if (pendingFrames >= 1e3) return {
83108
+ run: true,
83109
+ reason: "threshold",
83110
+ pendingFrames
83111
+ };
83112
+ if (intervalDue) return {
83113
+ run: true,
83114
+ reason: "interval",
83115
+ pendingFrames
83116
+ };
83117
+ return {
83118
+ run: false,
83119
+ reason: "below-threshold",
83120
+ pendingFrames
83121
+ };
83122
+ }
83123
+ var WAL_INDEX_MXFRAME_OFFSET = 16;
83124
+ var WAL_INDEX_HDR_SIZE = 48;
83125
+ var WAL_INDEX_NBACKFILL_OFFSET = 96;
83126
+ function parseWalIndexHeader(buffer) {
83127
+ if (buffer.length < 100) return null;
83128
+ const copy1 = buffer.subarray(0, WAL_INDEX_HDR_SIZE);
83129
+ const copy2 = buffer.subarray(WAL_INDEX_HDR_SIZE, WAL_INDEX_HDR_SIZE * 2);
83130
+ if (!copy1.equals(copy2)) return null;
83131
+ return {
83132
+ mxFrame: buffer.readUInt32LE(WAL_INDEX_MXFRAME_OFFSET),
83133
+ nBackfill: buffer.readUInt32LE(WAL_INDEX_NBACKFILL_OFFSET)
83134
+ };
83135
+ }
83136
+ function isRecord(value) {
83137
+ return typeof value === "object" && value !== null;
83138
+ }
83139
+ function isWorkerMessage(value) {
83140
+ if (!isRecord(value)) return false;
83141
+ switch (value["kind"]) {
83142
+ case "ready":
83143
+ return true;
83144
+ case "failed":
83145
+ return typeof value["error"] === "string";
83146
+ case "checkpointed":
83147
+ return typeof value["reason"] === "string" && (typeof value["pendingFrames"] === "number" || value["pendingFrames"] === null) && typeof value["walFrames"] === "number" && typeof value["checkpointedFrames"] === "number" && typeof value["busy"] === "boolean" && typeof value["ms"] === "number";
83148
+ default:
83149
+ return false;
83150
+ }
83151
+ }
83152
+ function isWorkerStop(value) {
83153
+ return isRecord(value) && value["kind"] === "stop";
83154
+ }
83155
+ Object.defineProperty(exports, "WAL_CHECKPOINT_POLL_MS", {
83156
+ enumerable: true,
83157
+ get: function() {
83158
+ return WAL_CHECKPOINT_POLL_MS;
83159
+ }
83160
+ });
83161
+ Object.defineProperty(exports, "WAL_CHECKPOINT_SLOW_MS", {
83162
+ enumerable: true,
83163
+ get: function() {
83164
+ return WAL_CHECKPOINT_SLOW_MS;
83165
+ }
83166
+ });
83167
+ Object.defineProperty(exports, "decideCheckpoint", {
83168
+ enumerable: true,
83169
+ get: function() {
83170
+ return decideCheckpoint;
83171
+ }
83172
+ });
83173
+ Object.defineProperty(exports, "isWorkerMessage", {
83174
+ enumerable: true,
83175
+ get: function() {
83176
+ return isWorkerMessage;
83177
+ }
83178
+ });
83179
+ Object.defineProperty(exports, "isWorkerStop", {
83180
+ enumerable: true,
83181
+ get: function() {
83182
+ return isWorkerStop;
83183
+ }
83184
+ });
83185
+ Object.defineProperty(exports, "parseWalIndexHeader", {
83186
+ enumerable: true,
83187
+ get: function() {
83188
+ return parseWalIndexHeader;
83189
+ }
83190
+ });
83191
+ }
83192
+ });
83193
+
82885
83194
  // ../../node_modules/better-sqlite3/lib/util.js
82886
83195
  var require_util2 = __commonJS({
82887
83196
  "../../node_modules/better-sqlite3/lib/util.js"(exports) {
@@ -83665,13 +83974,17 @@ var require_sqlite_settings_addon = __commonJS({
83665
83974
  [Symbol.toStringTag]: { value: "Module" }
83666
83975
  });
83667
83976
  var require_chunk = require_chunk_Cek0wNdY();
83668
- var require_dist10 = require_dist_BOlMCOeT();
83669
- var require_retired_settings_keys = require_retired_settings_keys_xEAlYnv7();
83977
+ var require_dist10 = require_dist_B17W9ngu();
83978
+ var require_retired_settings_keys = require_retired_settings_keys_CjvB7Etx();
83979
+ var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
83670
83980
  var node_crypto = __require("crypto");
83981
+ var node_path = __require("path");
83982
+ node_path = require_chunk.__toESM(node_path);
83671
83983
  var node_fs = __require("fs");
83672
83984
  var node_module = __require("module");
83673
83985
  var better_sqlite3 = require_lib();
83674
83986
  better_sqlite3 = require_chunk.__toESM(better_sqlite3);
83987
+ var node_worker_threads = __require("worker_threads");
83675
83988
  var memo = /* @__PURE__ */ new Map();
83676
83989
  function sqlShape(sql, collection) {
83677
83990
  const key = `${collection}\0${sql}`;
@@ -83900,6 +84213,7 @@ var require_sqlite_settings_addon = __commonJS({
83900
84213
  var SQLITE_PAGE_CACHE_FLOOR_KIB = -65536;
83901
84214
  var SQLITE_MMAP_FLOOR_BYTES = 268435456;
83902
84215
  var SQLITE_JOURNAL_SIZE_LIMIT_BYTES = 67108864;
84216
+ var SQLITE_WAL_AUTOCHECKPOINT_BOUND_PAGES = 1e4;
83903
84217
  var MIB = 1048576;
83904
84218
  var MMAP_SIZE_MULTIPLE = 1.25;
83905
84219
  var SQLITE_MMAP_CEILING_BYTES = 2 * 1024 * MIB;
@@ -84331,6 +84645,7 @@ var require_sqlite_settings_addon = __commonJS({
84331
84645
  this.db.pragma(`cache_size = ${pageCacheKib}`);
84332
84646
  this.db.pragma(`mmap_size = ${mmapSizeBytes}`);
84333
84647
  this.db.pragma(`journal_size_limit = ${SQLITE_JOURNAL_SIZE_LIMIT_BYTES}`);
84648
+ this.db.pragma(`wal_autocheckpoint = ${SQLITE_WAL_AUTOCHECKPOINT_BOUND_PAGES}`);
84334
84649
  const occupancy = sqliteOccupancy({
84335
84650
  pageCount: this.readPragmaNumber("page_count"),
84336
84651
  freelistCount: this.readPragmaNumber("freelist_count"),
@@ -85719,6 +86034,154 @@ var require_sqlite_settings_addon = __commonJS({
85719
86034
  if (modelId !== null) out["modelId"] = modelId;
85720
86035
  return out;
85721
86036
  }
86037
+ var EMPTY_STATS = {
86038
+ checkpoints: 0,
86039
+ frames: 0,
86040
+ slow: 0,
86041
+ maxMs: 0,
86042
+ totalMs: 0,
86043
+ busy: 0
86044
+ };
86045
+ function defaultWorkerPath() {
86046
+ const require_ = (0, node_module.createRequire)(__require("url").pathToFileURL(__filename).href);
86047
+ const packageRoot = node_path.default.dirname(require_.resolve("@camstack/system/package.json"));
86048
+ return node_path.default.join(packageRoot, "dist", "wal-checkpoint-worker.js");
86049
+ }
86050
+ var WalCheckpointer = class {
86051
+ dbPath;
86052
+ logger;
86053
+ pollMs;
86054
+ slowMs;
86055
+ summaryIntervalMs;
86056
+ spawn;
86057
+ worker = null;
86058
+ summaryTimer = null;
86059
+ stopping = false;
86060
+ statsValue = EMPTY_STATS;
86061
+ constructor(options) {
86062
+ this.dbPath = options.dbPath;
86063
+ this.logger = options.logger;
86064
+ this.pollMs = options.pollMs ?? 1e3;
86065
+ this.slowMs = options.slowMs ?? 1e3;
86066
+ this.summaryIntervalMs = options.summaryIntervalMs ?? 6e5;
86067
+ const workerPath = options.workerPath ?? defaultWorkerPath();
86068
+ const execArgv = options.workerExecArgv;
86069
+ this.spawn = options.workerFactory ?? ((workerData) => new node_worker_threads.Worker(workerPath, {
86070
+ workerData,
86071
+ ...execArgv !== void 0 ? { execArgv: [...execArgv] } : {}
86072
+ }));
86073
+ }
86074
+ /** Totals since the last summary line. */
86075
+ get stats() {
86076
+ return this.statsValue;
86077
+ }
86078
+ isRunning() {
86079
+ return this.worker !== null;
86080
+ }
86081
+ start() {
86082
+ if (this.worker !== null) return;
86083
+ this.stopping = false;
86084
+ const worker2 = this.spawn({
86085
+ dbPath: this.dbPath,
86086
+ pollMs: this.pollMs
86087
+ });
86088
+ this.worker = worker2;
86089
+ worker2.on("message", (message) => this.onMessage(message));
86090
+ worker2.on("error", (err) => {
86091
+ this.logger.error("WAL checkpoint worker threw", { meta: { error: require_dist10.errMsg(err) } });
86092
+ });
86093
+ worker2.on("exit", (code) => this.onExit(code));
86094
+ const summaryTimer = setInterval(() => this.logSummary(), this.summaryIntervalMs);
86095
+ summaryTimer.unref?.();
86096
+ this.summaryTimer = summaryTimer;
86097
+ this.logger.info("WAL checkpoint worker armed", { meta: {
86098
+ pollMs: this.pollMs,
86099
+ slowMs: this.slowMs
86100
+ } });
86101
+ }
86102
+ /** Ask the thread to close its connection and exit; resolves when it has. */
86103
+ async stop() {
86104
+ const worker2 = this.worker;
86105
+ if (worker2 === null) return;
86106
+ this.stopping = true;
86107
+ if (this.summaryTimer !== null) {
86108
+ clearInterval(this.summaryTimer);
86109
+ this.summaryTimer = null;
86110
+ }
86111
+ const stop = { kind: "stop" };
86112
+ const exited = new Promise((resolve) => worker2.once("exit", () => resolve()));
86113
+ worker2.postMessage(stop);
86114
+ await exited;
86115
+ this.worker = null;
86116
+ }
86117
+ /** One message off the port. Public so the spec can feed it directly. */
86118
+ onMessage(message) {
86119
+ if (!require_wal_checkpoint_policy.isWorkerMessage(message)) {
86120
+ this.logger.warn("WAL checkpoint worker sent an unreadable message", { meta: { message: String(message) } });
86121
+ return;
86122
+ }
86123
+ this.handle(message);
86124
+ }
86125
+ handle(message) {
86126
+ switch (message.kind) {
86127
+ case "ready":
86128
+ return;
86129
+ case "failed":
86130
+ this.logger.warn("WAL checkpoint failed on the worker", { meta: { error: message.error } });
86131
+ return;
86132
+ case "checkpointed":
86133
+ this.record(message);
86134
+ return;
86135
+ }
86136
+ }
86137
+ record(report) {
86138
+ const slow = report.ms >= this.slowMs;
86139
+ const prev = this.statsValue;
86140
+ this.statsValue = {
86141
+ checkpoints: prev.checkpoints + 1,
86142
+ frames: prev.frames + report.checkpointedFrames,
86143
+ slow: prev.slow + (slow ? 1 : 0),
86144
+ maxMs: Math.max(prev.maxMs, report.ms),
86145
+ totalMs: prev.totalMs + report.ms,
86146
+ busy: prev.busy + (report.busy ? 1 : 0)
86147
+ };
86148
+ if (slow) this.logger.warn("WAL checkpoint held the worker", { meta: {
86149
+ ms: report.ms,
86150
+ reason: report.reason,
86151
+ pendingFrames: report.pendingFrames,
86152
+ walFrames: report.walFrames,
86153
+ checkpointedFrames: report.checkpointedFrames,
86154
+ busy: report.busy
86155
+ } });
86156
+ }
86157
+ logSummary() {
86158
+ const stats = this.statsValue;
86159
+ this.statsValue = EMPTY_STATS;
86160
+ if (stats.checkpoints === 0) return;
86161
+ this.logger.info("WAL checkpoints on the worker", { meta: {
86162
+ windowMs: this.summaryIntervalMs,
86163
+ checkpoints: stats.checkpoints,
86164
+ frames: stats.frames,
86165
+ slow: stats.slow,
86166
+ maxMs: stats.maxMs,
86167
+ totalMs: stats.totalMs,
86168
+ busy: stats.busy
86169
+ } });
86170
+ }
86171
+ onExit(code) {
86172
+ const wasStopping = this.stopping;
86173
+ this.worker = null;
86174
+ if (this.summaryTimer !== null) {
86175
+ clearInterval(this.summaryTimer);
86176
+ this.summaryTimer = null;
86177
+ }
86178
+ if (wasStopping) return;
86179
+ this.logger.error("WAL checkpoint worker died \u2014 the engine autocheckpoint bound is now the only checkpoint", { meta: {
86180
+ exitCode: code,
86181
+ dbPath: this.dbPath
86182
+ } });
86183
+ }
86184
+ };
85722
86185
  var WAL_HIGH_WATER_BYTES = 67108864;
85723
86186
  var WAL_IDLE_QUIET_MS = 3e4;
85724
86187
  var WAL_CHECKPOINT_BUSY_TIMEOUT_MS = 250;
@@ -85869,6 +86332,7 @@ var require_sqlite_settings_addon = __commonJS({
85869
86332
  backend = null;
85870
86333
  vectorIndex = null;
85871
86334
  walMaintenance = null;
86335
+ walCheckpointer = null;
85872
86336
  constructor() {
85873
86337
  super({});
85874
86338
  }
@@ -85941,6 +86405,12 @@ var require_sqlite_settings_addon = __commonJS({
85941
86405
  maintenance.start();
85942
86406
  this.walMaintenance = maintenance;
85943
86407
  }
86408
+ const checkpointer = new WalCheckpointer({
86409
+ dbPath,
86410
+ logger: this.ctx.logger.child("WalCheckpoint")
86411
+ });
86412
+ checkpointer.start();
86413
+ this.walCheckpointer = checkpointer;
85944
86414
  this.ctx.logger.info("Initialized successfully");
85945
86415
  return [{
85946
86416
  capability: require_dist10.dataStoreProviderCapability,
@@ -85953,6 +86423,8 @@ var require_sqlite_settings_addon = __commonJS({
85953
86423
  async onShutdown() {
85954
86424
  this.walMaintenance?.stop();
85955
86425
  this.walMaintenance = null;
86426
+ await this.walCheckpointer?.stop();
86427
+ this.walCheckpointer = null;
85956
86428
  await this.backend?.shutdown();
85957
86429
  }
85958
86430
  getBackend() {
@@ -86170,7 +86642,7 @@ var require_storage_orchestrator_addon = __commonJS({
86170
86642
  [Symbol.toStringTag]: { value: "Module" }
86171
86643
  });
86172
86644
  var require_chunk = require_chunk_Cek0wNdY();
86173
- var require_dist10 = require_dist_BOlMCOeT();
86645
+ var require_dist10 = require_dist_B17W9ngu();
86174
86646
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
86175
86647
  var zod = require_zod();
86176
86648
  var node_crypto = __require("crypto");
@@ -89820,7 +90292,7 @@ var require_system_config_addon = __commonJS({
89820
90292
  [Symbol.toStringTag]: { value: "Module" }
89821
90293
  });
89822
90294
  require_chunk_Cek0wNdY();
89823
- var require_dist10 = require_dist_BOlMCOeT();
90295
+ var require_dist10 = require_dist_B17W9ngu();
89824
90296
  var SECTION_TITLES = {
89825
90297
  server: "Server",
89826
90298
  auth: "Authentication"
@@ -107881,7 +108353,7 @@ var require_winston_logging = __commonJS({
107881
108353
  [Symbol.toStringTag]: { value: "Module" }
107882
108354
  });
107883
108355
  var require_chunk = require_chunk_Cek0wNdY();
107884
- var require_dist10 = require_dist_BOlMCOeT();
108356
+ var require_dist10 = require_dist_B17W9ngu();
107885
108357
  var require_formatter = require_formatter_DqAKDlvN();
107886
108358
  var node_path = __require("path");
107887
108359
  node_path = require_chunk.__toESM(node_path);
@@ -108018,17 +108490,17 @@ var require_winston_logging = __commonJS({
108018
108490
  }
108019
108491
  });
108020
108492
 
108021
- // ../system/dist/event-loop-stall-monitor-DM9OAzy8.js
108022
- var require_event_loop_stall_monitor_DM9OAzy8 = __commonJS({
108023
- "../system/dist/event-loop-stall-monitor-DM9OAzy8.js"(exports) {
108493
+ // ../system/dist/event-loop-stall-monitor-CAsHdMwP.js
108494
+ var require_event_loop_stall_monitor_CAsHdMwP = __commonJS({
108495
+ "../system/dist/event-loop-stall-monitor-CAsHdMwP.js"(exports) {
108024
108496
  "use strict";
108025
108497
  var require_chunk = require_chunk_Cek0wNdY();
108026
108498
  var node_crypto = __require("crypto");
108027
108499
  var node_path = __require("path");
108028
108500
  node_path = require_chunk.__toESM(node_path);
108029
- var node_util = __require("util");
108030
108501
  var node_fs = __require("fs");
108031
108502
  node_fs = require_chunk.__toESM(node_fs);
108503
+ var node_util = __require("util");
108032
108504
  var node_http = __require("http");
108033
108505
  var node_zlib = __require("zlib");
108034
108506
  var node_perf_hooks = __require("perf_hooks");
@@ -109004,19 +109476,19 @@ var require_event_loop_stall_monitor_DM9OAzy8 = __commonJS({
109004
109476
  }
109005
109477
  });
109006
109478
 
109007
- // ../system/dist/tls-BxQlomxd.js
109008
- var require_tls_BxQlomxd = __commonJS({
109009
- "../system/dist/tls-BxQlomxd.js"(exports) {
109479
+ // ../system/dist/tls-BFs4PzoW.js
109480
+ var require_tls_BFs4PzoW = __commonJS({
109481
+ "../system/dist/tls-BFs4PzoW.js"(exports) {
109010
109482
  "use strict";
109011
109483
  var require_chunk = require_chunk_Cek0wNdY();
109012
109484
  var node_crypto = __require("crypto");
109013
109485
  var node_fs_promises = __require("fs/promises");
109014
109486
  var node_path = __require("path");
109015
- var node_child_process = __require("child_process");
109016
- var node_util = __require("util");
109017
109487
  var node_fs = __require("fs");
109488
+ var node_child_process = __require("child_process");
109018
109489
  var node_os = __require("os");
109019
109490
  node_os = require_chunk.__toESM(node_os);
109491
+ var node_util = __require("util");
109020
109492
  var node_http = __require("http");
109021
109493
  var node_net = __require("net");
109022
109494
  var DEFAULT_HTTP_PORT = 4480;
@@ -120515,9 +120987,9 @@ var require_dist2 = __commonJS({
120515
120987
  }
120516
120988
  });
120517
120989
 
120518
- // ../system/dist/manifest-system-deps-Bo92lg5u.js
120519
- var require_manifest_system_deps_Bo92lg5u = __commonJS({
120520
- "../system/dist/manifest-system-deps-Bo92lg5u.js"(exports) {
120990
+ // ../system/dist/manifest-system-deps-g_nK0xsF.js
120991
+ var require_manifest_system_deps_g_nK0xsF = __commonJS({
120992
+ "../system/dist/manifest-system-deps-g_nK0xsF.js"(exports) {
120521
120993
  "use strict";
120522
120994
  var require_chunk = require_chunk_Cek0wNdY();
120523
120995
  require_hub_cap_forward_DmHNjbB0();
@@ -120527,12 +120999,12 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120527
120999
  var node_fs_promises = __require("fs/promises");
120528
121000
  var node_path = __require("path");
120529
121001
  node_path = require_chunk.__toESM(node_path);
120530
- var node_child_process = __require("child_process");
120531
- var node_util = __require("util");
120532
121002
  var node_fs = __require("fs");
120533
121003
  node_fs = require_chunk.__toESM(node_fs);
121004
+ var node_child_process = __require("child_process");
120534
121005
  var node_os = __require("os");
120535
121006
  node_os = require_chunk.__toESM(node_os);
121007
+ var node_util = __require("util");
120536
121008
  var node_http = __require("http");
120537
121009
  var node_v8 = __require("v8");
120538
121010
  node_v8 = require_chunk.__toESM(node_v8);
@@ -120688,12 +121160,15 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120688
121160
  peers.push({
120689
121161
  peerId: child.childId,
120690
121162
  tx: traffic.tx,
120691
- rx: traffic.rx
121163
+ rx: traffic.rx,
121164
+ queuedBytes: registry.getChildQueuedBytes(child.childId)
120692
121165
  });
120693
121166
  }
121167
+ const forward = registry.readForwardCensus?.();
120694
121168
  return {
120695
121169
  peers,
120696
- peersConnected: listed.length
121170
+ peersConnected: listed.length,
121171
+ ...forward === void 0 ? {} : { forward }
120697
121172
  };
120698
121173
  } catch {
120699
121174
  return;
@@ -120701,7 +121176,36 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120701
121176
  };
120702
121177
  }
120703
121178
  var SOCKET_PLANE_TOP_N = 5;
121179
+ var SOCKET_QUEUE_TOP_N = 3;
121180
+ function readSocketQueues(current) {
121181
+ let totalBytes = 0;
121182
+ let unmeasured = 0;
121183
+ const holding = [];
121184
+ for (const peer of current.peers) {
121185
+ if (peer.queuedBytes === null) {
121186
+ unmeasured += 1;
121187
+ continue;
121188
+ }
121189
+ totalBytes += peer.queuedBytes;
121190
+ if (peer.queuedBytes > 0) holding.push({
121191
+ peerId: peer.peerId,
121192
+ bytes: peer.queuedBytes
121193
+ });
121194
+ }
121195
+ return {
121196
+ totalBytes,
121197
+ unmeasured,
121198
+ top: holding.toSorted((a, b) => b.bytes - a.bytes || a.peerId.localeCompare(b.peerId)).slice(0, 3)
121199
+ };
121200
+ }
120704
121201
  var EMPTY_SOCKET_PLANE_BASELINE = { peers: /* @__PURE__ */ new Map() };
121202
+ function diffForward(current, before) {
121203
+ if (current === void 0) return void 0;
121204
+ return {
121205
+ raw: Math.max(0, current.raw - (before?.raw ?? 0)),
121206
+ decoded: Math.max(0, current.decoded - (before?.decoded ?? 0))
121207
+ };
121208
+ }
120705
121209
  function diffDirection(current, before) {
120706
121210
  const previous = before ?? EMPTY_SOCKET_DIRECTION;
120707
121211
  return {
@@ -120726,6 +121230,9 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120726
121230
  function peerMessages(delta) {
120727
121231
  return socketDirectionMessages(delta.tx) + socketDirectionMessages(delta.rx);
120728
121232
  }
121233
+ function peerBytes(delta) {
121234
+ return socketDirectionBytes(delta.tx) + socketDirectionBytes(delta.rx);
121235
+ }
120729
121236
  function diffSocketPlane(baseline, current, topN = 5) {
120730
121237
  const deltas = [];
120731
121238
  let tx = EMPTY_SOCKET_DIRECTION;
@@ -120741,12 +121248,16 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120741
121248
  rx = addDirection(rx, delta.rx);
120742
121249
  if (peerMessages(delta) > 0) deltas.push(delta);
120743
121250
  }
121251
+ const forward = diffForward(current.forward, baseline.forward);
120744
121252
  return {
120745
121253
  peersConnected: current.peersConnected,
120746
121254
  peersMeasured: current.peers.length,
120747
121255
  tx,
120748
121256
  rx,
120749
- top: deltas.toSorted((a, b) => peerMessages(b) - peerMessages(a) || a.peerId.localeCompare(b.peerId)).slice(0, topN)
121257
+ top: deltas.toSorted((a, b) => peerMessages(b) - peerMessages(a) || a.peerId.localeCompare(b.peerId)).slice(0, topN),
121258
+ topBytes: deltas.toSorted((a, b) => peerBytes(b) - peerBytes(a) || a.peerId.localeCompare(b.peerId)).slice(0, topN),
121259
+ queued: readSocketQueues(current),
121260
+ ...forward === void 0 ? {} : { forward }
120750
121261
  };
120751
121262
  }
120752
121263
  function createSocketPlaneMeter(reader, topN = 5) {
@@ -120755,23 +121266,166 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
120755
121266
  const current = reader();
120756
121267
  if (current === void 0) return void 0;
120757
121268
  const window2 = diffSocketPlane(baseline, current, topN);
120758
- baseline = { peers: new Map(current.peers.map((p) => [p.peerId, p])) };
121269
+ baseline = {
121270
+ peers: new Map(current.peers.map((p) => [p.peerId, p])),
121271
+ ...current.forward === void 0 ? {} : { forward: current.forward }
121272
+ };
120759
121273
  return window2;
120760
121274
  } };
120761
121275
  }
120762
- function kb(bytes) {
121276
+ function kb$1(bytes) {
120763
121277
  return Math.round(bytes / 1024);
120764
121278
  }
120765
121279
  function formatDirection(sample) {
120766
- return `req:${sample.reqMessages}/${kb(sample.reqBytes)}kB,res:${sample.resMessages}/${kb(sample.resBytes)}kB,evt:${sample.evtMessages}/${kb(sample.evtBytes)}kB`;
121280
+ return `req:${sample.reqMessages}/${kb$1(sample.reqBytes)}kB,res:${sample.resMessages}/${kb$1(sample.resBytes)}kB,evt:${sample.evtMessages}/${kb$1(sample.evtBytes)}kB`;
121281
+ }
121282
+ function formatPeerBytes(sample) {
121283
+ return `${kb$1(sample.reqBytes)}/${kb$1(sample.resBytes)}/${kb$1(sample.evtBytes)}`;
120767
121284
  }
120768
121285
  function formatPeer(delta) {
120769
- return `${delta.peerId}:tx=${delta.tx.reqMessages}/${delta.tx.resMessages}/${delta.tx.evtMessages}:rx=${delta.rx.reqMessages}/${delta.rx.resMessages}/${delta.rx.evtMessages}:kB=${kb(socketDirectionBytes(delta.tx))}/${kb(socketDirectionBytes(delta.rx))}`;
121286
+ return `${delta.peerId}:tx=${delta.tx.reqMessages}/${delta.tx.resMessages}/${delta.tx.evtMessages}:rx=${delta.rx.reqMessages}/${delta.rx.resMessages}/${delta.rx.evtMessages}:txkB=${formatPeerBytes(delta.tx)}:rxkB=${formatPeerBytes(delta.rx)}`;
120770
121287
  }
120771
121288
  function formatSocketPlane(window2) {
120772
121289
  if (window2 === void 0) return "";
120773
121290
  const top = window2.top.map(formatPeer).join(",");
120774
- return ` socketPeers=${window2.peersMeasured}/${window2.peersConnected} socketTx=${formatDirection(window2.tx)} socketRx=${formatDirection(window2.rx)}` + (top.length === 0 ? "" : ` socketTop=${top}`);
121291
+ const named = new Set(window2.top.map((p) => p.peerId));
121292
+ const topBytes = window2.topBytes.filter((p) => !named.has(p.peerId)).map(formatPeer).join(",");
121293
+ const queuedTop = window2.queued.top.map((p) => `${p.peerId}:${kb$1(p.bytes)}`).join(",");
121294
+ return ` socketPeers=${window2.peersMeasured}/${window2.peersConnected} socketTx=${formatDirection(window2.tx)} socketRx=${formatDirection(window2.rx)}` + (top.length === 0 ? "" : ` socketTop=${top}`) + (topBytes.length === 0 ? "" : ` socketTopBytes=${topBytes}`) + ` socketQueued=${kb$1(window2.queued.totalBytes)}kB` + (window2.queued.unmeasured === 0 ? "" : ` socketQueuedUnmeasured=${window2.queued.unmeasured}`) + (queuedTop.length === 0 ? "" : ` socketQueuedTop=${queuedTop}`) + (window2.forward === void 0 ? "" : ` socketFwd=${window2.forward.raw}/${window2.forward.decoded}`);
121295
+ }
121296
+ function isRecord$1(value) {
121297
+ return typeof value === "object" && value !== null;
121298
+ }
121299
+ function writerSocketsOf(broker) {
121300
+ if (!isRecord$1(broker)) return void 0;
121301
+ const transit = broker["transit"];
121302
+ if (!isRecord$1(transit)) return void 0;
121303
+ const transporter = transit["tx"];
121304
+ if (!isRecord$1(transporter)) return void 0;
121305
+ const writer = transporter["writer"];
121306
+ if (!isRecord$1(writer)) return void 0;
121307
+ const sockets = writer["sockets"];
121308
+ return sockets instanceof Map ? sockets : void 0;
121309
+ }
121310
+ function readSocket(nodeId, socket) {
121311
+ if (typeof nodeId !== "string" || !isRecord$1(socket)) return void 0;
121312
+ const queuedBytes = socket["writableLength"];
121313
+ const bytesWritten = socket["bytesWritten"];
121314
+ if (typeof queuedBytes !== "number" || typeof bytesWritten !== "number") return void 0;
121315
+ return {
121316
+ nodeId,
121317
+ queuedBytes,
121318
+ bytesWritten
121319
+ };
121320
+ }
121321
+ function createMeshQueueReader(getBroker) {
121322
+ return () => {
121323
+ try {
121324
+ const sockets = writerSocketsOf(getBroker());
121325
+ if (sockets === void 0) return void 0;
121326
+ const peers = [];
121327
+ for (const [nodeId, socket] of sockets) {
121328
+ const peer = readSocket(nodeId, socket);
121329
+ if (peer !== void 0) peers.push(peer);
121330
+ }
121331
+ return peers;
121332
+ } catch {
121333
+ return;
121334
+ }
121335
+ };
121336
+ }
121337
+ var MESH_QUEUE_TOP_N = 3;
121338
+ function kb(bytes) {
121339
+ return Math.round(bytes / 1024);
121340
+ }
121341
+ function formatMeshQueue(peers) {
121342
+ if (peers === void 0) return "";
121343
+ const total = peers.reduce((sum, p) => sum + p.queuedBytes, 0);
121344
+ const top = peers.filter((p) => p.queuedBytes > 0).toSorted((a, b) => b.queuedBytes - a.queuedBytes || a.nodeId.localeCompare(b.nodeId)).slice(0, 3).map((p) => `${p.nodeId}:${kb(p.queuedBytes)}`).join(",");
121345
+ return ` meshQueued=${kb(total)}kB` + (top.length === 0 ? "" : ` meshQueuedTop=${top}`);
121346
+ }
121347
+ var OUTBOUND_QUEUE_THRESHOLD_BYTES = 64 * 1024 * 1024;
121348
+ var OUTBOUND_QUEUE_SUSTAIN_MS = 6e4;
121349
+ var OUTBOUND_QUEUE_COOLDOWN_MS = 10 * 6e4;
121350
+ var RELEASE_RATIO = 0.5;
121351
+ function createOutboundQueueGate(options = {}) {
121352
+ const thresholdBytes = options.thresholdBytes ?? 67108864;
121353
+ const sustainMs = options.sustainMs ?? 6e4;
121354
+ const cooldownMs = options.cooldownMs ?? 6e5;
121355
+ const tracked = /* @__PURE__ */ new Map();
121356
+ const judgeOne = (peerId, bytes, at) => {
121357
+ const state = tracked.get(peerId);
121358
+ if (bytes >= thresholdBytes) {
121359
+ const next = state === void 0 ? {
121360
+ aboveSince: at,
121361
+ peakBytes: bytes,
121362
+ lastNamedAt: null
121363
+ } : {
121364
+ ...state,
121365
+ peakBytes: Math.max(state.peakBytes, bytes)
121366
+ };
121367
+ const heldForMs = at - next.aboveSince;
121368
+ const due = heldForMs >= sustainMs && (next.lastNamedAt === null || at - next.lastNamedAt >= cooldownMs);
121369
+ tracked.set(peerId, due ? {
121370
+ ...next,
121371
+ lastNamedAt: at
121372
+ } : next);
121373
+ return due ? {
121374
+ kind: "sustained",
121375
+ peerId,
121376
+ bytes,
121377
+ peakBytes: next.peakBytes,
121378
+ heldForMs
121379
+ } : void 0;
121380
+ }
121381
+ if (state === void 0) return void 0;
121382
+ if (bytes >= thresholdBytes * RELEASE_RATIO) return void 0;
121383
+ tracked.delete(peerId);
121384
+ if (state.lastNamedAt === null) return void 0;
121385
+ return {
121386
+ kind: "released",
121387
+ peerId,
121388
+ peakBytes: state.peakBytes,
121389
+ toBytes: bytes,
121390
+ heldForMs: at - state.aboveSince,
121391
+ gone: false
121392
+ };
121393
+ };
121394
+ return { observe(readings, at) {
121395
+ const verdicts = [];
121396
+ const seen = /* @__PURE__ */ new Set();
121397
+ for (const reading of readings) {
121398
+ seen.add(reading.peerId);
121399
+ const verdict = judgeOne(reading.peerId, reading.bytes, at);
121400
+ if (verdict !== void 0) verdicts.push(verdict);
121401
+ }
121402
+ for (const [peerId, state] of tracked) {
121403
+ if (seen.has(peerId)) continue;
121404
+ tracked.delete(peerId);
121405
+ if (state.lastNamedAt === null) continue;
121406
+ verdicts.push({
121407
+ kind: "released",
121408
+ peerId,
121409
+ peakBytes: state.peakBytes,
121410
+ toBytes: 0,
121411
+ heldForMs: at - state.aboveSince,
121412
+ gone: true
121413
+ });
121414
+ }
121415
+ return verdicts;
121416
+ } };
121417
+ }
121418
+ var BYTES_PER_MB$1 = 1048576;
121419
+ function mb$2(bytes) {
121420
+ return Math.round(bytes / BYTES_PER_MB$1);
121421
+ }
121422
+ function duration(ms) {
121423
+ const seconds = Math.round(ms / 1e3);
121424
+ return seconds < 120 ? `${seconds}s` : `${Math.round(seconds / 60)}m`;
121425
+ }
121426
+ function formatOutboundQueueVerdict(label, verdict) {
121427
+ if (verdict.kind === "sustained") return `[mem] ${label} outbound queue to ${verdict.peerId} has held ${mb$2(verdict.bytes)}MB (peak ${mb$2(verdict.peakBytes)}MB) for ${duration(verdict.heldForMs)} \u2014 the peer is not draining what this process writes to it. This is socket.writableLength on the channel itself; a sum over _getActiveHandles() does not list an unref'd socket and would miss it.`;
121428
+ return `[mem] ${label} outbound queue to ${verdict.peerId} RELEASED \u2014 ${mb$2(verdict.peakBytes)}MB at peak, ${mb$2(verdict.toBytes)}MB now, held ${duration(verdict.heldForMs)}` + (verdict.gone ? " (peer gone: the socket closed and dropped its queue)" : " (drained)");
120775
121429
  }
120776
121430
  var DECISIVE_HEAP_SPACES = ["old_space", "large_object_space"];
120777
121431
  var HEAP_SPACE_REPORT_MIN_MB = 32;
@@ -121097,6 +121751,21 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
121097
121751
  if (loop === void 0) return `${line}${suffix}`;
121098
121752
  return `${line} loopP50=${loop.p50Ms}ms loopP99=${loop.p99Ms}ms loopMax=${loop.maxMs}ms${suffix}`;
121099
121753
  }
121754
+ function outboundQueueReadings(uds, mesh) {
121755
+ const readings = [];
121756
+ for (const peer of uds?.peers ?? []) {
121757
+ if (peer.queuedBytes === null) continue;
121758
+ readings.push({
121759
+ peerId: `uds:${peer.peerId}`,
121760
+ bytes: peer.queuedBytes
121761
+ });
121762
+ }
121763
+ for (const node of mesh ?? []) readings.push({
121764
+ peerId: `mesh:${node.nodeId}`,
121765
+ bytes: node.queuedBytes
121766
+ });
121767
+ return readings;
121768
+ }
121100
121769
  function startHeapWatch(label = HUB_MAIN_HEAP_WATCH_LABEL, sink = consoleSink, intervalMs = HEAP_WATCH_INTERVAL_MS, reclaimOptions, loopDelay = createLoopDelayMeter(), execArgv = process.execArgv, announceCeilingOrigin = true, rssBudget, probes) {
121101
121770
  const readSpaces = probes?.readSpaces ?? readHeapSpaces;
121102
121771
  const eventPlane = probes?.eventPlane === void 0 ? void 0 : createEventPlaneMeter(probes.eventPlane);
@@ -121178,7 +121847,7 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
121178
121847
  const due = at - lastLoggedAt >= intervalMs;
121179
121848
  if (mode === "escalated" || due) {
121180
121849
  lastLoggedAt = at;
121181
- const line = format2(label, sample, loopDelay?.read(), budgetMb, `${formatHeapSpaces(readSpaces())}${formatEventPlane(eventPlane?.read())}` + formatSocketPlane(socketPlane?.read()));
121850
+ const line = format2(label, sample, loopDelay?.read(), budgetMb, `${formatHeapSpaces(readSpaces())}${formatEventPlane(eventPlane?.read())}` + formatSocketPlane(socketPlane?.read()) + formatMeshQueue(meshQueue?.()));
121182
121851
  if (sample.nearLimit) sink.warn(`${line} \u2014 APPROACHING HEAP LIMIT`);
121183
121852
  else if (mode === "escalated") sink.warn(`${line} \u2014 heap elevated, sampling every ${probeIntervalMs}ms`);
121184
121853
  else sink.info(line);
@@ -121187,9 +121856,18 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
121187
121856
  checkRssBudget(sample, at);
121188
121857
  maybeReclaim(sample);
121189
121858
  judgeArrayBuffers(sample, at);
121859
+ judgeOutboundQueues(at);
121190
121860
  } catch {
121191
121861
  }
121192
121862
  };
121863
+ const meshQueue = probes?.meshQueue;
121864
+ const queueReader = probes?.socketPlane;
121865
+ const queueGate = queueReader === void 0 && meshQueue === void 0 ? void 0 : createOutboundQueueGate(probes?.outboundQueue);
121866
+ const judgeOutboundQueues = (at) => {
121867
+ if (queueGate === void 0) return;
121868
+ const readings = outboundQueueReadings(queueReader?.(), meshQueue?.());
121869
+ for (const verdict of queueGate.observe(readings, at)) sink.warn(formatOutboundQueueVerdict(label, verdict));
121870
+ };
121193
121871
  const censusProbe = probes?.arrayBufferCensus;
121194
121872
  const censusGate = censusProbe === void 0 ? void 0 : createArrayBufferCensusGate(censusProbe);
121195
121873
  let censusInFlight = false;
@@ -124414,6 +125092,32 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124414
125092
  Buffer.from(body.buffer, body.byteOffset, body.byteLength).copy(out, 4);
124415
125093
  return out;
124416
125094
  }
125095
+ var PAYLOAD_KEY_BYTES = Buffer.from([162, ...Buffer.from("pl")]);
125096
+ var BIN32_MARKER = 198;
125097
+ var FIXMAP_BASE = 128;
125098
+ var FIXMAP_MAX_COUNT = 15;
125099
+ function encodeFrameHead(frame, payload) {
125100
+ const envelope = encode(frame, ENCODE_OPTIONS);
125101
+ const first = envelope[0];
125102
+ if (envelope.byteLength === 0 || first === void 0 || first < FIXMAP_BASE || first > 142) throw new Error(`encodeFrameHead: envelope must be a msgpack fixmap with at most ${FIXMAP_MAX_COUNT - 1} keys (got leading byte 0x${(first ?? 0).toString(16)})`);
125103
+ const bodyLength = envelope.byteLength + PAYLOAD_KEY_BYTES.byteLength + 5 + payload.byteLength;
125104
+ const head = Buffer.allocUnsafe(HEADER_BYTES + envelope.byteLength + PAYLOAD_KEY_BYTES.byteLength + 5);
125105
+ head.writeUInt32BE(bodyLength, 0);
125106
+ Buffer.from(envelope.buffer, envelope.byteOffset, envelope.byteLength).copy(head, HEADER_BYTES);
125107
+ head[HEADER_BYTES] = first + 1;
125108
+ let at = HEADER_BYTES + envelope.byteLength;
125109
+ PAYLOAD_KEY_BYTES.copy(head, at);
125110
+ at += PAYLOAD_KEY_BYTES.byteLength;
125111
+ head[at] = BIN32_MARKER;
125112
+ head.writeUInt32BE(payload.byteLength, at + 1);
125113
+ return head;
125114
+ }
125115
+ function packPayload(value) {
125116
+ return encode(value, ENCODE_OPTIONS);
125117
+ }
125118
+ function unpackPayload(bytes) {
125119
+ return decode(bytes);
125120
+ }
124417
125121
  var HEADER_BYTES = 4;
124418
125122
  var SLAB_WASTE_MAX_BYTES = 4096;
124419
125123
  var FrameDecoder = class {
@@ -124531,6 +125235,14 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124531
125235
  if (process.platform === "win32") return `\\\\.\\pipe\\camstack-${safe}`;
124532
125236
  return (0, node_path.join)((0, node_os.tmpdir)(), `camstack-${safe}.sock`);
124533
125237
  }
125238
+ var PayloadReply = class {
125239
+ body;
125240
+ payload;
125241
+ constructor(body, payload) {
125242
+ this.body = body;
125243
+ this.payload = payload;
125244
+ }
125245
+ };
124534
125246
  var SocketChannel = class {
124535
125247
  socket;
124536
125248
  nextId = 1;
@@ -124590,7 +125302,7 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124590
125302
  k: "req",
124591
125303
  id,
124592
125304
  body
124593
- });
125305
+ }, opts?.payload);
124594
125306
  });
124595
125307
  }
124596
125308
  emit(body) {
@@ -124630,11 +125342,38 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124630
125342
  rx: sampleSocketDirection(this.rxCounters)
124631
125343
  };
124632
125344
  }
124633
- send(frame) {
125345
+ /**
125346
+ * Bytes handed to the socket that the kernel has not taken yet — the
125347
+ * `Writable` buffer plus the write in flight. Read LIVE, never cached: this
125348
+ * is the number that says whether the peer is draining what we write, and
125349
+ * it is read on every heartbeat probe (D446). An unref'd socket keeps it
125350
+ * exactly like a ref'd one, which is why it is read here and not summed
125351
+ * over `_getActiveHandles()`.
125352
+ */
125353
+ queuedBytes() {
125354
+ return this.socket.writableLength;
125355
+ }
125356
+ /**
125357
+ * Write one frame. With a payload the head and the tail are two `write`
125358
+ * calls under `cork()` — the kernel sees one `writev`, and the payload bytes
125359
+ * are never copied into the head. A forwarded payload is a view into the
125360
+ * frame it arrived on, and that frame's buffer is never mutated, so handing
125361
+ * the view to the socket is safe.
125362
+ */
125363
+ send(frame, payload) {
124634
125364
  if (this.closed) return;
124635
- const encoded = encodeFrame(frame);
124636
- recordSocketFrame(this.txCounters, frame.k, encoded.byteLength);
124637
- this.socket.write(encoded);
125365
+ if (payload === void 0) {
125366
+ const encoded = encodeFrame(frame);
125367
+ recordSocketFrame(this.txCounters, frame.k, encoded.byteLength);
125368
+ this.socket.write(encoded);
125369
+ return;
125370
+ }
125371
+ const head = encodeFrameHead(frame, payload);
125372
+ recordSocketFrame(this.txCounters, frame.k, head.byteLength + payload.byteLength);
125373
+ this.socket.cork();
125374
+ this.socket.write(head);
125375
+ this.socket.write(payload);
125376
+ this.socket.uncork();
124638
125377
  }
124639
125378
  onData(chunk) {
124640
125379
  const frames = this.decoder.push(chunk);
@@ -124654,8 +125393,14 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124654
125393
  recordSocketFrame(this.rxCounters, frame.k, wireBytes);
124655
125394
  if (frame.k === "req") {
124656
125395
  try {
124657
- const result = await this.requestHandler(frame.body);
124658
- this.send({
125396
+ const result = await this.requestHandler(frame.body, frame.pl);
125397
+ if (result instanceof PayloadReply) this.send({
125398
+ k: "res",
125399
+ id: frame.id,
125400
+ ok: true,
125401
+ body: result.body
125402
+ }, result.payload);
125403
+ else this.send({
124659
125404
  k: "res",
124660
125405
  id: frame.id,
124661
125406
  ok: true,
@@ -124676,8 +125421,9 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
124676
125421
  if (!p) return;
124677
125422
  this.pending.delete(frame.id);
124678
125423
  if (p.timer !== null) clearTimeout(p.timer);
124679
- if (frame.ok) p.resolve(frame.body);
124680
- else p.reject(new Error(frame.err));
125424
+ if (!frame.ok) p.reject(new Error(frame.err));
125425
+ else if (frame.pl !== void 0) p.resolve(new PayloadReply(frame.body, frame.pl));
125426
+ else p.resolve(frame.body);
124681
125427
  return;
124682
125428
  }
124683
125429
  this.eventHandler(frame.body);
@@ -125066,397 +125812,15 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125066
125812
  }
125067
125813
  }
125068
125814
  }
125069
- var DISCOVERY_ERROR_TYPES = /* @__PURE__ */ new Set(["SERVICE_NOT_FOUND", "SERVICE_NOT_AVAILABLE"]);
125070
- var DEFAULT_DISCOVERY_TIMEOUT_MS$1 = 3e4;
125071
- function isDiscoveryError(err) {
125072
- if (typeof err !== "object" || err === null) return false;
125073
- const type = err.type;
125074
- return typeof type === "string" && DISCOVERY_ERROR_TYPES.has(type);
125075
- }
125076
- async function callWithServiceDiscovery(broker, serviceName, action, params, opts, discoveryTimeoutMs = DEFAULT_DISCOVERY_TIMEOUT_MS$1) {
125077
- try {
125078
- return await broker.call(action, params, opts);
125079
- } catch (err) {
125080
- if (!isDiscoveryError(err)) throw err;
125081
- await broker.waitForServices([serviceName], discoveryTimeoutMs);
125082
- return await broker.call(action, params, opts);
125083
- }
125084
- }
125085
- function buildMessage(capName, method, detail) {
125086
- const call = method !== void 0 ? `${capName}.${method}` : capName;
125087
- const target = detail.nodeId !== void 0 ? ` to node ${detail.nodeId}` : "";
125088
- const rejectedStr = detail.rejected.map((r) => `${r.kind}=${r.why}`).join("; ");
125089
- const rejectedClause = rejectedStr.length > 0 ? ` (rejected: ${rejectedStr})` : "";
125090
- return `${call} not routable${target}: ${detail.reason}${rejectedClause}`;
125091
- }
125092
- var CapRouteError = class extends Error {
125093
- reason;
125094
- nodeId;
125095
- rejected;
125096
- /**
125097
- * @param cause Optional original error that triggered this routing failure.
125098
- * Stored as `Error.cause` (TC39 standard option, Node 16.9+).
125099
- * Dispatchers wrapping transport errors MUST pass the original.
125100
- */
125101
- constructor(capName, method, detail, cause) {
125102
- super(buildMessage(capName, method, detail), cause !== void 0 ? { cause } : void 0);
125103
- this.name = "CapRouteError";
125104
- this.reason = detail.reason;
125105
- this.nodeId = detail.nodeId;
125106
- this.rejected = detail.rejected;
125107
- }
125108
- };
125109
- function classifyCapRoute(capName, opts, snapshot) {
125110
- const rejected = [];
125111
- if (opts.nodeId !== void 0) return classifyExplicitNode(capName, opts.nodeId, opts.deviceId, snapshot, rejected);
125112
- return classifySingleton(capName, opts.deviceId, snapshot, rejected);
125113
- }
125114
- function classifyExplicitNode(capName, nodeId, deviceId, snap, rejected) {
125115
- if (nodeId === snap.hubNodeId) {
125116
- const residentProvides = snap.hubResidentProvides;
125117
- const providesOnHub = residentProvides ?? snap.hubInProcessProvides;
125118
- const getRef = residentProvides !== void 0 ? snap.getHubResidentProviderRef : snap.getInProcessProviderRef;
125119
- if (providesOnHub(capName)) {
125120
- const ref = getRef?.(capName) ?? null;
125121
- if (ref !== null) return {
125122
- kind: "hub-in-process",
125123
- capName,
125124
- ref
125125
- };
125126
- rejected.push({
125127
- kind: "hub-in-process",
125128
- why: "provider ref not available in snapshot"
125129
- });
125130
- throw new CapRouteError(capName, void 0, {
125131
- reason: "no-provider",
125132
- nodeId,
125133
- rejected
125134
- });
125135
- }
125136
- if (snap.hubLocalChildProvides(capName, deviceId)) {
125137
- const childId = snap.getHubLocalChildId?.(capName, deviceId) ?? null;
125138
- if (childId !== null) return {
125139
- kind: "hub-local-uds",
125140
- capName,
125141
- childId
125142
- };
125143
- rejected.push({
125144
- kind: "hub-local-uds",
125145
- why: "child id not resolvable from snapshot"
125146
- });
125147
- throw new CapRouteError(capName, void 0, {
125148
- reason: "no-provider",
125149
- nodeId,
125150
- rejected
125151
- });
125152
- }
125153
- rejected.push({
125154
- kind: "hub-in-process",
125155
- why: "hub does not provide this cap in-process"
125156
- });
125157
- rejected.push({
125158
- kind: "hub-local-uds",
125159
- why: "no hub-local child provides this cap"
125160
- });
125161
- throw new CapRouteError(capName, void 0, {
125162
- reason: "no-provider",
125163
- nodeId,
125164
- rejected
125165
- });
125166
- }
125167
- if (!snap.nodeOnline(nodeId)) {
125168
- rejected.push({
125169
- kind: "remote-moleculer",
125170
- why: `node ${nodeId} is offline`
125171
- });
125172
- throw new CapRouteError(capName, void 0, {
125173
- reason: "node-offline",
125174
- nodeId,
125175
- rejected
125176
- });
125177
- }
125178
- if (snap.nodeIsAgent(nodeId)) {
125179
- if (snap.nodeKnowsCap(nodeId, capName)) return {
125180
- kind: "agent-child-forward",
125181
- capName,
125182
- agentNodeId: nodeId,
125183
- childId: snap.getAgentChildId?.(nodeId, capName) ?? void 0
125184
- };
125185
- rejected.push({
125186
- kind: "agent-child-forward",
125187
- why: `agent ${nodeId} does not know cap ${capName}`
125188
- });
125189
- throw new CapRouteError(capName, void 0, {
125190
- reason: "no-provider",
125191
- nodeId,
125192
- rejected
125193
- });
125194
- }
125195
- return {
125196
- kind: "remote-moleculer",
125197
- capName,
125198
- nodeId
125199
- };
125200
- }
125201
- function classifySingleton(capName, deviceId, snap, rejected) {
125202
- if (snap.hubInProcessProvides(capName)) {
125203
- const ref = snap.getInProcessProviderRef?.(capName) ?? null;
125204
- if (ref !== null) return {
125205
- kind: "hub-in-process",
125206
- capName,
125207
- ref
125208
- };
125209
- rejected.push({
125210
- kind: "hub-in-process",
125211
- why: "provider ref not available in snapshot"
125212
- });
125213
- } else rejected.push({
125214
- kind: "hub-in-process",
125215
- why: "hub does not provide this cap in-process"
125216
- });
125217
- if (snap.hubLocalChildProvides(capName, deviceId)) {
125218
- const childId = snap.getHubLocalChildId?.(capName, deviceId) ?? null;
125219
- if (childId !== null) return {
125220
- kind: "hub-local-uds",
125221
- capName,
125222
- childId
125223
- };
125224
- rejected.push({
125225
- kind: "hub-local-uds",
125226
- why: "child id not resolvable from snapshot"
125227
- });
125228
- } else rejected.push({
125229
- kind: "hub-local-uds",
125230
- why: "no hub-local child provides this cap"
125231
- });
125232
- const knownNodes = snap.listKnownNodeIds?.() ?? [];
125233
- for (const nodeId of knownNodes) if (nodeId !== snap.hubNodeId && snap.nodeOnline(nodeId) && snap.nodeKnowsCap(nodeId, capName)) return {
125234
- kind: "remote-moleculer",
125235
- capName,
125236
- nodeId
125237
- };
125238
- rejected.push({
125239
- kind: "remote-moleculer",
125240
- why: "no online remote node knows this cap"
125241
- });
125242
- throw new CapRouteError(capName, void 0, {
125243
- reason: "no-provider",
125244
- rejected
125245
- });
125246
- }
125247
- var AGENT_CAP_FWD_SERVICE = "$agent-cap-fwd";
125248
- var AGENT_CAP_FWD_ACTION = `${AGENT_CAP_FWD_SERVICE}.forward`;
125249
- var REMOTE_CALL_TIMEOUT_MS = 6e4;
125250
- function extractDeviceId(args) {
125251
- if (args === null || typeof args !== "object") return void 0;
125252
- const raw = Reflect.get(args, "deviceId");
125253
- return typeof raw === "number" ? raw : void 0;
125254
- }
125255
- function extractNodeId(args) {
125256
- if (args === null || typeof args !== "object") return void 0;
125257
- const raw = Reflect.get(args, "nodeId");
125258
- return typeof raw === "string" && raw.length > 0 ? raw : void 0;
125259
- }
125260
- function withCallerAddonId(args, callerAddonId) {
125261
- if (callerAddonId === void 0) return args;
125262
- if (args === null || typeof args !== "object" || Array.isArray(args)) return args;
125815
+ function liftRoutingHints(args) {
125816
+ if (args === null || typeof args !== "object" || Array.isArray(args)) return {};
125817
+ const nodeId = Reflect.get(args, "nodeId");
125818
+ const addonId = Reflect.get(args, "addonId");
125263
125819
  return {
125264
- ...args,
125265
- callerAddonId
125820
+ ...typeof nodeId === "string" && nodeId.length > 0 ? { nodeId } : {},
125821
+ ...typeof addonId === "string" && addonId.length > 0 ? { addonId } : {}
125266
125822
  };
125267
125823
  }
125268
- var CapRouteResolver = class {
125269
- hubNodeId;
125270
- broker;
125271
- hubLocalRegistry;
125272
- nodeAuthority;
125273
- inProcessProviders;
125274
- hubResidentProviders;
125275
- capTimeoutMs;
125276
- snapshot;
125277
- constructor(deps) {
125278
- this.hubNodeId = deps.hubNodeId;
125279
- this.broker = deps.broker;
125280
- this.hubLocalRegistry = deps.hubLocalRegistry;
125281
- this.nodeAuthority = deps.nodeAuthority;
125282
- this.inProcessProviders = deps.inProcessProviders;
125283
- this.hubResidentProviders = deps.hubResidentProviders;
125284
- this.capTimeoutMs = deps.capTimeoutMs;
125285
- this.snapshot = this.buildSnapshot();
125286
- }
125287
- /** Per-call RPC timeout: the cap method's declared override, else the default. */
125288
- callTimeout(capName, method) {
125289
- return this.capTimeoutMs?.(capName, method) ?? REMOTE_CALL_TIMEOUT_MS;
125290
- }
125291
- resolveCapRoute(capName, opts) {
125292
- return classifyCapRoute(capName, opts, this.snapshot);
125293
- }
125294
- /**
125295
- * Resolve the hub-local-uds route for a cap owned by a forked hub-local
125296
- * child, IGNORING any in-hub provider registered for the same cap name.
125297
- *
125298
- * `resolveCapRoute` gives Priority 1 to `hub-in-process`: when an in-hub
125299
- * provider (e.g. a wrapper) is registered for the cap, the route always
125300
- * classifies as `hub-in-process` and the hub-local-uds NATIVE child is never
125301
- * reached. That is correct for the generic dispatch path (the wrapper is the
125302
- * active provider), but WRONG for the native-cap fallback
125303
- * (`setNativeFallback`), whose contract is to reach the NATIVE provider in
125304
- * the forked vendor child so a wrapper can delegate to it. A wrapper cap
125305
- * with a forked native (today: `snapshot`) otherwise resolves to the wrapper
125306
- * itself, the native is never invoked, and the wrapper silently falls
125307
- * through to its secondary strategy.
125308
- *
125309
- * This method consults ONLY the hub-local-child authority
125310
- * (`hubLocalChildProvides` + `getHubLocalChildId`, both deviceId-aware), so
125311
- * it returns the native child route regardless of any in-process shadow.
125312
- * Returns null when no hub-local child owns `(capName, deviceId)` — the
125313
- * caller then falls through to its remote-resolution branch.
125314
- */
125315
- resolveHubLocalUdsRoute(capName, deviceId) {
125316
- if (!this.snapshot.hubLocalChildProvides(capName, deviceId)) return null;
125317
- const childId = this.snapshot.getHubLocalChildId?.(capName, deviceId) ?? null;
125318
- if (childId === null) return null;
125319
- return {
125320
- kind: "hub-local-uds",
125321
- capName,
125322
- childId
125323
- };
125324
- }
125325
- /**
125326
- * @param addonId Optional out-of-band PROVIDER-selection hint (Task 7.5a):
125327
- * the addonId of the provider the CALLER already resolved (e.g.
125328
- * `buildCapCallFn`'s `deps.addonId` for a registered grouped-runner
125329
- * provider). Only meaningful for `agent-child-forward` — a `remote-moleculer`
125330
- * route already encodes the provider in its action name
125331
- * (`${addonId}.${cap}.${method}`, via `NodeCapAuthority.getAddonId`), and a
125332
- * `hub-local-uds` caller that already knows the addonId (`buildCapCallFn`)
125333
- * talks to `LocalChildRegistry.callCapOnChild` directly rather than through
125334
- * `dispatch`.
125335
- * @param callerAddonId Optional out-of-band CALLER-identity hint — the
125336
- * addon that ORIGINATED the call, distinct from `addonId` above (which
125337
- * names the resolved PROVIDER, not the caller). Set by
125338
- * `onUnownedCall` from `CapCallInput.callerAddonId`
125339
- * (`LocalChildRegistry` stamped it off the registered `childId`). Only
125340
- * the `hub-in-process` branch consumes it — merged into `args` so a
125341
- * diagnostic tool deep in that provider (e.g. device-manager's
125342
- * fleet-read census) can read it without every provider method changing
125343
- * signature, the same "extra field the provider destructures or
125344
- * ignores" convention `nodeId` already uses on this path.
125345
- */
125346
- async dispatch(route, method, args, addonId, callerAddonId) {
125347
- try {
125348
- return await this.dispatchInner(route, method, args, addonId, callerAddonId);
125349
- } catch (err) {
125350
- if (err instanceof CapRouteError) throw err;
125351
- const nodeId = this.routeNodeId(route);
125352
- const cause = err instanceof Error ? err : new Error(String(err));
125353
- throw new CapRouteError(route.capName, method, {
125354
- reason: "transport-failed",
125355
- nodeId,
125356
- rejected: [{
125357
- kind: route.kind,
125358
- why: cause.message
125359
- }]
125360
- }, cause);
125361
- }
125362
- }
125363
- /**
125364
- * Inner dispatch: may throw CapRouteError (validation failures) or arbitrary
125365
- * transport errors. The outer `dispatch` wraps non-CapRouteErrors.
125366
- */
125367
- async dispatchInner(route, method, args, addonId, callerAddonId) {
125368
- switch (route.kind) {
125369
- case "hub-in-process":
125370
- return route.ref.invoke(method, withCallerAddonId(args, callerAddonId));
125371
- case "hub-local-uds": {
125372
- const registry = this.hubLocalRegistry;
125373
- if (registry === null) throw new CapRouteError(route.capName, method, {
125374
- reason: "no-provider",
125375
- rejected: [{
125376
- kind: "hub-local-uds",
125377
- why: "UDS registry not available"
125378
- }]
125379
- });
125380
- const deviceId = extractDeviceId(args);
125381
- const input = {
125382
- capName: route.capName,
125383
- method,
125384
- args,
125385
- ...deviceId !== void 0 ? { deviceId } : {}
125386
- };
125387
- return registry.callCapOnChild(route.childId, input);
125388
- }
125389
- case "remote-moleculer": {
125390
- const addonId2 = this.nodeAuthority.getAddonId(route.nodeId, route.capName);
125391
- if (addonId2 === null) throw new CapRouteError(route.capName, method, {
125392
- reason: "no-provider",
125393
- nodeId: route.nodeId,
125394
- rejected: [{
125395
- kind: "remote-moleculer",
125396
- why: `no addonId known for ${route.nodeId}/${route.capName}`
125397
- }]
125398
- });
125399
- const deviceId = extractDeviceId(args);
125400
- const isNative = this.nodeAuthority.isNativeCap(route.nodeId, route.capName, deviceId);
125401
- const action = capActionName(addonId2, route.capName, method, isNative);
125402
- return callWithServiceDiscovery(this.broker, addonId2, action, args, {
125403
- nodeID: route.nodeId,
125404
- timeout: this.callTimeout(route.capName, method)
125405
- });
125406
- }
125407
- case "agent-child-forward": {
125408
- const deviceId = extractDeviceId(args);
125409
- const params = {
125410
- capName: route.capName,
125411
- method,
125412
- args,
125413
- ...route.childId !== void 0 ? { childId: route.childId } : {},
125414
- ...deviceId !== void 0 ? { deviceId } : {},
125415
- ...addonId !== void 0 ? { addonId } : {}
125416
- };
125417
- return callWithServiceDiscovery(this.broker, AGENT_CAP_FWD_SERVICE, AGENT_CAP_FWD_ACTION, params, {
125418
- nodeID: route.agentNodeId,
125419
- timeout: this.callTimeout(route.capName, method)
125420
- });
125421
- }
125422
- }
125423
- }
125424
- buildSnapshot() {
125425
- const hubLocalRegistry = this.hubLocalRegistry;
125426
- const nodeAuthority = this.nodeAuthority;
125427
- const inProcessProviders = this.inProcessProviders;
125428
- const hubResidentProviders = this.hubResidentProviders;
125429
- return {
125430
- hubNodeId: this.hubNodeId,
125431
- hubInProcessProvides: (cap) => inProcessProviders(cap) !== null,
125432
- ...hubResidentProviders !== void 0 ? {
125433
- hubResidentProvides: (cap) => hubResidentProviders(cap) !== null,
125434
- getHubResidentProviderRef: (cap) => hubResidentProviders(cap)
125435
- } : {},
125436
- hubLocalChildProvides: (cap, deviceId) => hubLocalRegistry !== null && hubLocalRegistry.resolveChildId(cap, deviceId) !== null,
125437
- nodeKnowsCap: (nodeId, cap) => nodeAuthority.nodeKnowsCap(nodeId, cap),
125438
- nodeIsAgent: (nodeId) => nodeAuthority.nodeIsAgent(nodeId),
125439
- nodeOnline: (nodeId) => nodeAuthority.nodeOnline(nodeId),
125440
- listKnownNodeIds: () => nodeAuthority.listNodeIds(),
125441
- getInProcessProviderRef: (cap) => inProcessProviders(cap),
125442
- getHubLocalChildId: (cap, deviceId) => hubLocalRegistry !== null ? hubLocalRegistry.resolveChildId(cap, deviceId) : null,
125443
- getAgentChildId: (agentNodeId, cap) => nodeAuthority.getAgentChildId(agentNodeId, cap)
125444
- };
125445
- }
125446
- /** Extract a nodeId string from a route for error reporting, or undefined. */
125447
- routeNodeId(route) {
125448
- switch (route.kind) {
125449
- case "hub-in-process":
125450
- return this.hubNodeId;
125451
- case "hub-local-uds":
125452
- return `${this.hubNodeId}/${route.childId}`;
125453
- case "remote-moleculer":
125454
- return route.nodeId;
125455
- case "agent-child-forward":
125456
- return route.agentNodeId;
125457
- }
125458
- }
125459
- };
125460
125824
  function readFanoutMode() {
125461
125825
  const raw = process.env.CAMSTACK_UDS_EVENT_FANOUT;
125462
125826
  if (raw === "shadow" || raw === "broadcast") return raw;
@@ -125484,6 +125848,9 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125484
125848
  /** See {@link LocalChildRegistryOptions.isAggregatedCollectionMethod}. */
125485
125849
  isAggregatedCollectionMethod;
125486
125850
  isAddonPinnedCall;
125851
+ /** See {@link ForwardCensus}. Mutable counters on the hot path, by design. */
125852
+ forwardedRaw = 0;
125853
+ forwardedDecoded = 0;
125487
125854
  /** See {@link LocalChildRegistryOptions.capTimeoutMs}. */
125488
125855
  capTimeoutMs;
125489
125856
  /** See {@link LocalChildRegistryOptions.capUsageObserver}. */
@@ -125559,6 +125926,24 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125559
125926
  return entry.channel.readTraffic?.() ?? null;
125560
125927
  }
125561
125928
  /**
125929
+ * Bytes this process has written to a child that the child has not yet
125930
+ * taken, live, or `null` when the channel keeps no such reading. Read on
125931
+ * every heartbeat probe (D446) — a child that stops draining is the shape
125932
+ * of an outbound-queue episode, and the number lives on the channel.
125933
+ */
125934
+ getChildQueuedBytes(childId) {
125935
+ const entry = this.children.get(childId);
125936
+ if (entry === void 0) return null;
125937
+ return entry.channel.queuedBytes?.() ?? null;
125938
+ }
125939
+ /** Cumulative {@link ForwardCensus} of this parent's `cap-call-out` routing. */
125940
+ readForwardCensus() {
125941
+ return {
125942
+ raw: this.forwardedRaw,
125943
+ decoded: this.forwardedDecoded
125944
+ };
125945
+ }
125946
+ /**
125562
125947
  * The regime the counters above were produced under, read once from
125563
125948
  * `CAMSTACK_UDS_EVENT_FANOUT` at construction.
125564
125949
  *
@@ -125937,7 +126322,7 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125937
126322
  return;
125938
126323
  }
125939
126324
  });
125940
- channel.onRequest(async (body) => {
126325
+ channel.onRequest(async (body, payload) => {
125941
126326
  const msg = body;
125942
126327
  if (msg.kind === "register") {
125943
126328
  if (childId !== null && childId !== msg.childId) throw new Error(`child attempted to change identity from "${childId}" to "${msg.childId}"`);
@@ -125954,7 +126339,8 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125954
126339
  channel,
125955
126340
  caps: msg.caps,
125956
126341
  eventPatterns,
125957
- incarnation
126342
+ incarnation,
126343
+ rawForward: msg.rawForward === true
125958
126344
  });
125959
126345
  this.logPatternSet(msg.childId, eventPatterns);
125960
126346
  this.registeredHandler({
@@ -125963,23 +126349,28 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125963
126349
  incarnation,
125964
126350
  ...msg.customActions !== void 0 ? { customActions: msg.customActions } : {}
125965
126351
  });
125966
- return { ok: true };
126352
+ return {
126353
+ ok: true,
126354
+ rawForward: true
126355
+ };
125967
126356
  }
125968
126357
  if (msg.kind === "cap-call-out") {
125969
126358
  const out = msg;
125970
- const input = {
126359
+ const hints = out.hints ?? liftRoutingHints(out.args);
126360
+ const materialise = () => payload !== void 0 ? unpackPayload(payload) : out.args;
126361
+ const buildInput = () => ({
125971
126362
  capName: out.capName,
125972
126363
  method: out.method,
125973
- args: out.args,
126364
+ args: materialise(),
125974
126365
  ...out.deviceId !== void 0 ? { deviceId: out.deviceId } : {},
125975
126366
  ...out.nodeId !== void 0 ? { nodeId: out.nodeId } : {},
125976
126367
  ...out.native === true ? { native: true } : {},
125977
126368
  ...childId !== null ? { callerAddonId: childId } : {}
125978
- };
125979
- const pinnedNodeId = out.nodeId ?? extractNodeId(out.args);
126369
+ });
126370
+ const pinnedNodeId = out.nodeId ?? hints.nodeId;
125980
126371
  const pinTargetsThisNode = pinnedNodeId !== void 0 && this.ownNodeId !== void 0 && pinnedNodeId === this.ownNodeId;
125981
126372
  const aggregated = pinnedNodeId === void 0 && this.isAggregatedCollectionMethod?.(out.capName, out.method) === true;
125982
- const addonPinned = pinnedNodeId === void 0 && this.isAddonPinnedCall?.(out.capName, out.method, out.args) === true;
126373
+ const addonPinned = pinnedNodeId === void 0 && this.isAddonPinnedCall?.(out.capName, out.method, hints) === true;
125983
126374
  const target = !(out.native === true) && !aggregated && !addonPinned && (pinnedNodeId === void 0 || pinTargetsThisNode) ? this.resolveChildId(out.capName, out.deviceId) : null;
125984
126375
  this.recordCapUsage(childId, target, out.capName, out.method);
125985
126376
  if (target !== null) {
@@ -125987,9 +126378,27 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
125987
126378
  this.egressRoutedCaps.add(out.capName);
125988
126379
  this.logger?.info("routed child egress over UDS", { capName: out.capName });
125989
126380
  }
125990
- return this.callCap(input);
126381
+ const entry = this.children.get(target);
126382
+ if (payload !== void 0 && entry !== void 0 && entry.rawForward) {
126383
+ this.forwardedRaw += 1;
126384
+ const forward = {
126385
+ kind: "cap-call",
126386
+ capName: out.capName,
126387
+ method: out.method,
126388
+ args: void 0,
126389
+ ...out.deviceId !== void 0 ? { deviceId: out.deviceId } : {}
126390
+ };
126391
+ const declared = this.capTimeoutMs?.(out.capName, out.method);
126392
+ return entry.channel.request(forward, {
126393
+ ...typeof declared === "number" ? { timeoutMs: declared } : {},
126394
+ payload
126395
+ });
126396
+ }
126397
+ this.forwardedDecoded += 1;
126398
+ return this.callCap(buildInput());
125991
126399
  }
125992
- if (this.onUnownedCall !== void 0) return this.onUnownedCall(input);
126400
+ this.forwardedDecoded += 1;
126401
+ if (this.onUnownedCall !== void 0) return this.onUnownedCall(buildInput());
125993
126402
  throw new Error(`${UDS_NO_ROUTE_PREFIX}: cap-call-out has no local provider for "${out.capName}" and no fallback`);
125994
126403
  }
125995
126404
  if (msg.kind === "readiness-request") return {
@@ -126017,6 +126426,10 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126017
126426
  });
126018
126427
  }
126019
126428
  };
126429
+ function ackAcceptsRawForward(ack) {
126430
+ if (ack === null || typeof ack !== "object") return false;
126431
+ return ack.rawForward === true;
126432
+ }
126020
126433
  var LocalChildClient = class {
126021
126434
  options;
126022
126435
  client = null;
@@ -126057,6 +126470,13 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126057
126470
  latestCustomActions = null;
126058
126471
  /** Events and logs queued while the channel is not yet open. */
126059
126472
  pendingEmits = [];
126473
+ /**
126474
+ * Whether the parent acknowledged raw-forward at `register`. Until it has,
126475
+ * `callOut` sends args inline exactly as every child always did — a legacy
126476
+ * parent would decode a payload-borne call to `args: undefined` and run the
126477
+ * provider on nothing, silently. Re-read on every re-register.
126478
+ */
126479
+ parentRawForward = false;
126060
126480
  /** Handler for parent→child events. Registered via `onEvent`. */
126061
126481
  eventHandler = null;
126062
126482
  /**
@@ -126164,15 +126584,20 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126164
126584
  if (this.client !== null) throw new Error("LocalChildClient: already started \u2014 call close() first");
126165
126585
  const client = createLocalTransport().createClient(this.options.nodeId);
126166
126586
  const channel = await client.connect();
126167
- channel.onRequest(async (body) => {
126587
+ channel.onRequest(async (body, payload) => {
126168
126588
  const msg = body;
126169
- if (msg.kind === "cap-call") return this.options.dispatch({
126170
- capName: msg.capName,
126171
- method: msg.method,
126172
- args: msg.args,
126173
- ...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {},
126174
- ...msg.addonId !== void 0 ? { addonId: msg.addonId } : {}
126175
- });
126589
+ if (msg.kind === "cap-call") {
126590
+ const args = payload !== void 0 ? unpackPayload(payload) : msg.args;
126591
+ const result = await this.options.dispatch({
126592
+ capName: msg.capName,
126593
+ method: msg.method,
126594
+ args,
126595
+ ...msg.deviceId !== void 0 ? { deviceId: msg.deviceId } : {},
126596
+ ...msg.addonId !== void 0 ? { addonId: msg.addonId } : {}
126597
+ });
126598
+ if (payload !== void 0 && result !== void 0) return new PayloadReply(void 0, packPayload(result));
126599
+ return result;
126600
+ }
126176
126601
  if (msg.kind === "addon-call") {
126177
126602
  if (this.addonCallHandler === null) throw new Error(`LocalChildClient: addon-call for "${msg.addonId}" arrived but no onAddonCall handler is registered`);
126178
126603
  return this.addonCallHandler({
@@ -126196,7 +126621,7 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126196
126621
  });
126197
126622
  const register = this.registerFrame(this.latestCaps);
126198
126623
  try {
126199
- await channel.request(register);
126624
+ this.parentRawForward = ackAcceptsRawForward(await channel.request(register));
126200
126625
  } catch (err) {
126201
126626
  await client.close();
126202
126627
  throw err;
@@ -126224,7 +126649,7 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126224
126649
  this.latestCaps = caps;
126225
126650
  if (customActions !== void 0) this.latestCustomActions = customActions;
126226
126651
  if (this.channel === null) return;
126227
- await this.channel.request(this.registerFrame(caps));
126652
+ this.parentRawForward = ackAcceptsRawForward(await this.channel.request(this.registerFrame(caps)));
126228
126653
  }
126229
126654
  /**
126230
126655
  * The register frame: caps, plus everything a re-register must atomically
@@ -126238,7 +126663,8 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126238
126663
  childId: this.options.childId,
126239
126664
  caps,
126240
126665
  ...this.hasDeclaredEventPatterns ? { eventPatterns: this.latestEventPatterns } : {},
126241
- ...this.latestCustomActions !== null ? { customActions: this.latestCustomActions } : {}
126666
+ ...this.latestCustomActions !== null ? { customActions: this.latestCustomActions } : {},
126667
+ rawForward: true
126242
126668
  };
126243
126669
  }
126244
126670
  /**
@@ -126289,14 +126715,29 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126289
126715
  */
126290
126716
  async callOut(input) {
126291
126717
  if (this.channel === null) throw new Error("LocalChildClient: callOut before start");
126718
+ const routing = {
126719
+ ...input.deviceId !== void 0 ? { deviceId: input.deviceId } : {},
126720
+ ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {},
126721
+ ...input.native === true ? { native: true } : {}
126722
+ };
126723
+ if (this.parentRawForward && input.args !== void 0) {
126724
+ const hints = liftRoutingHints(input.args);
126725
+ const msg2 = {
126726
+ kind: "cap-call-out",
126727
+ capName: input.capName,
126728
+ method: input.method,
126729
+ ...Object.keys(hints).length > 0 ? { hints } : {},
126730
+ ...routing
126731
+ };
126732
+ const reply = await this.channel.request(msg2, { payload: packPayload(input.args) });
126733
+ return reply instanceof PayloadReply ? unpackPayload(reply.payload) : reply;
126734
+ }
126292
126735
  const msg = {
126293
126736
  kind: "cap-call-out",
126294
126737
  capName: input.capName,
126295
126738
  method: input.method,
126296
126739
  args: input.args,
126297
- ...input.deviceId !== void 0 ? { deviceId: input.deviceId } : {},
126298
- ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {},
126299
- ...input.native === true ? { native: true } : {}
126740
+ ...routing
126300
126741
  };
126301
126742
  return this.channel.request(msg);
126302
126743
  }
@@ -126307,6 +126748,397 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
126307
126748
  this.channel = null;
126308
126749
  }
126309
126750
  };
126751
+ function buildMessage(capName, method, detail) {
126752
+ const call = method !== void 0 ? `${capName}.${method}` : capName;
126753
+ const target = detail.nodeId !== void 0 ? ` to node ${detail.nodeId}` : "";
126754
+ const rejectedStr = detail.rejected.map((r) => `${r.kind}=${r.why}`).join("; ");
126755
+ const rejectedClause = rejectedStr.length > 0 ? ` (rejected: ${rejectedStr})` : "";
126756
+ return `${call} not routable${target}: ${detail.reason}${rejectedClause}`;
126757
+ }
126758
+ var CapRouteError = class extends Error {
126759
+ reason;
126760
+ nodeId;
126761
+ rejected;
126762
+ /**
126763
+ * @param cause Optional original error that triggered this routing failure.
126764
+ * Stored as `Error.cause` (TC39 standard option, Node 16.9+).
126765
+ * Dispatchers wrapping transport errors MUST pass the original.
126766
+ */
126767
+ constructor(capName, method, detail, cause) {
126768
+ super(buildMessage(capName, method, detail), cause !== void 0 ? { cause } : void 0);
126769
+ this.name = "CapRouteError";
126770
+ this.reason = detail.reason;
126771
+ this.nodeId = detail.nodeId;
126772
+ this.rejected = detail.rejected;
126773
+ }
126774
+ };
126775
+ function classifyCapRoute(capName, opts, snapshot) {
126776
+ const rejected = [];
126777
+ if (opts.nodeId !== void 0) return classifyExplicitNode(capName, opts.nodeId, opts.deviceId, snapshot, rejected);
126778
+ return classifySingleton(capName, opts.deviceId, snapshot, rejected);
126779
+ }
126780
+ function classifyExplicitNode(capName, nodeId, deviceId, snap, rejected) {
126781
+ if (nodeId === snap.hubNodeId) {
126782
+ const residentProvides = snap.hubResidentProvides;
126783
+ const providesOnHub = residentProvides ?? snap.hubInProcessProvides;
126784
+ const getRef = residentProvides !== void 0 ? snap.getHubResidentProviderRef : snap.getInProcessProviderRef;
126785
+ if (providesOnHub(capName)) {
126786
+ const ref = getRef?.(capName) ?? null;
126787
+ if (ref !== null) return {
126788
+ kind: "hub-in-process",
126789
+ capName,
126790
+ ref
126791
+ };
126792
+ rejected.push({
126793
+ kind: "hub-in-process",
126794
+ why: "provider ref not available in snapshot"
126795
+ });
126796
+ throw new CapRouteError(capName, void 0, {
126797
+ reason: "no-provider",
126798
+ nodeId,
126799
+ rejected
126800
+ });
126801
+ }
126802
+ if (snap.hubLocalChildProvides(capName, deviceId)) {
126803
+ const childId = snap.getHubLocalChildId?.(capName, deviceId) ?? null;
126804
+ if (childId !== null) return {
126805
+ kind: "hub-local-uds",
126806
+ capName,
126807
+ childId
126808
+ };
126809
+ rejected.push({
126810
+ kind: "hub-local-uds",
126811
+ why: "child id not resolvable from snapshot"
126812
+ });
126813
+ throw new CapRouteError(capName, void 0, {
126814
+ reason: "no-provider",
126815
+ nodeId,
126816
+ rejected
126817
+ });
126818
+ }
126819
+ rejected.push({
126820
+ kind: "hub-in-process",
126821
+ why: "hub does not provide this cap in-process"
126822
+ });
126823
+ rejected.push({
126824
+ kind: "hub-local-uds",
126825
+ why: "no hub-local child provides this cap"
126826
+ });
126827
+ throw new CapRouteError(capName, void 0, {
126828
+ reason: "no-provider",
126829
+ nodeId,
126830
+ rejected
126831
+ });
126832
+ }
126833
+ if (!snap.nodeOnline(nodeId)) {
126834
+ rejected.push({
126835
+ kind: "remote-moleculer",
126836
+ why: `node ${nodeId} is offline`
126837
+ });
126838
+ throw new CapRouteError(capName, void 0, {
126839
+ reason: "node-offline",
126840
+ nodeId,
126841
+ rejected
126842
+ });
126843
+ }
126844
+ if (snap.nodeIsAgent(nodeId)) {
126845
+ if (snap.nodeKnowsCap(nodeId, capName)) return {
126846
+ kind: "agent-child-forward",
126847
+ capName,
126848
+ agentNodeId: nodeId,
126849
+ childId: snap.getAgentChildId?.(nodeId, capName) ?? void 0
126850
+ };
126851
+ rejected.push({
126852
+ kind: "agent-child-forward",
126853
+ why: `agent ${nodeId} does not know cap ${capName}`
126854
+ });
126855
+ throw new CapRouteError(capName, void 0, {
126856
+ reason: "no-provider",
126857
+ nodeId,
126858
+ rejected
126859
+ });
126860
+ }
126861
+ return {
126862
+ kind: "remote-moleculer",
126863
+ capName,
126864
+ nodeId
126865
+ };
126866
+ }
126867
+ function classifySingleton(capName, deviceId, snap, rejected) {
126868
+ if (snap.hubInProcessProvides(capName)) {
126869
+ const ref = snap.getInProcessProviderRef?.(capName) ?? null;
126870
+ if (ref !== null) return {
126871
+ kind: "hub-in-process",
126872
+ capName,
126873
+ ref
126874
+ };
126875
+ rejected.push({
126876
+ kind: "hub-in-process",
126877
+ why: "provider ref not available in snapshot"
126878
+ });
126879
+ } else rejected.push({
126880
+ kind: "hub-in-process",
126881
+ why: "hub does not provide this cap in-process"
126882
+ });
126883
+ if (snap.hubLocalChildProvides(capName, deviceId)) {
126884
+ const childId = snap.getHubLocalChildId?.(capName, deviceId) ?? null;
126885
+ if (childId !== null) return {
126886
+ kind: "hub-local-uds",
126887
+ capName,
126888
+ childId
126889
+ };
126890
+ rejected.push({
126891
+ kind: "hub-local-uds",
126892
+ why: "child id not resolvable from snapshot"
126893
+ });
126894
+ } else rejected.push({
126895
+ kind: "hub-local-uds",
126896
+ why: "no hub-local child provides this cap"
126897
+ });
126898
+ const knownNodes = snap.listKnownNodeIds?.() ?? [];
126899
+ for (const nodeId of knownNodes) if (nodeId !== snap.hubNodeId && snap.nodeOnline(nodeId) && snap.nodeKnowsCap(nodeId, capName)) return {
126900
+ kind: "remote-moleculer",
126901
+ capName,
126902
+ nodeId
126903
+ };
126904
+ rejected.push({
126905
+ kind: "remote-moleculer",
126906
+ why: "no online remote node knows this cap"
126907
+ });
126908
+ throw new CapRouteError(capName, void 0, {
126909
+ reason: "no-provider",
126910
+ rejected
126911
+ });
126912
+ }
126913
+ var DISCOVERY_ERROR_TYPES = /* @__PURE__ */ new Set(["SERVICE_NOT_FOUND", "SERVICE_NOT_AVAILABLE"]);
126914
+ var DEFAULT_DISCOVERY_TIMEOUT_MS$1 = 3e4;
126915
+ function isDiscoveryError(err) {
126916
+ if (typeof err !== "object" || err === null) return false;
126917
+ const type = err.type;
126918
+ return typeof type === "string" && DISCOVERY_ERROR_TYPES.has(type);
126919
+ }
126920
+ async function callWithServiceDiscovery(broker, serviceName, action, params, opts, discoveryTimeoutMs = DEFAULT_DISCOVERY_TIMEOUT_MS$1) {
126921
+ try {
126922
+ return await broker.call(action, params, opts);
126923
+ } catch (err) {
126924
+ if (!isDiscoveryError(err)) throw err;
126925
+ await broker.waitForServices([serviceName], discoveryTimeoutMs);
126926
+ return await broker.call(action, params, opts);
126927
+ }
126928
+ }
126929
+ var AGENT_CAP_FWD_SERVICE = "$agent-cap-fwd";
126930
+ var AGENT_CAP_FWD_ACTION = `${AGENT_CAP_FWD_SERVICE}.forward`;
126931
+ var REMOTE_CALL_TIMEOUT_MS = 6e4;
126932
+ function extractDeviceId(args) {
126933
+ if (args === null || typeof args !== "object") return void 0;
126934
+ const raw = Reflect.get(args, "deviceId");
126935
+ return typeof raw === "number" ? raw : void 0;
126936
+ }
126937
+ function extractNodeId(args) {
126938
+ if (args === null || typeof args !== "object") return void 0;
126939
+ const raw = Reflect.get(args, "nodeId");
126940
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
126941
+ }
126942
+ function withCallerAddonId(args, callerAddonId) {
126943
+ if (callerAddonId === void 0) return args;
126944
+ if (args === null || typeof args !== "object" || Array.isArray(args)) return args;
126945
+ return {
126946
+ ...args,
126947
+ callerAddonId
126948
+ };
126949
+ }
126950
+ var CapRouteResolver = class {
126951
+ hubNodeId;
126952
+ broker;
126953
+ hubLocalRegistry;
126954
+ nodeAuthority;
126955
+ inProcessProviders;
126956
+ hubResidentProviders;
126957
+ capTimeoutMs;
126958
+ snapshot;
126959
+ constructor(deps) {
126960
+ this.hubNodeId = deps.hubNodeId;
126961
+ this.broker = deps.broker;
126962
+ this.hubLocalRegistry = deps.hubLocalRegistry;
126963
+ this.nodeAuthority = deps.nodeAuthority;
126964
+ this.inProcessProviders = deps.inProcessProviders;
126965
+ this.hubResidentProviders = deps.hubResidentProviders;
126966
+ this.capTimeoutMs = deps.capTimeoutMs;
126967
+ this.snapshot = this.buildSnapshot();
126968
+ }
126969
+ /** Per-call RPC timeout: the cap method's declared override, else the default. */
126970
+ callTimeout(capName, method) {
126971
+ return this.capTimeoutMs?.(capName, method) ?? REMOTE_CALL_TIMEOUT_MS;
126972
+ }
126973
+ resolveCapRoute(capName, opts) {
126974
+ return classifyCapRoute(capName, opts, this.snapshot);
126975
+ }
126976
+ /**
126977
+ * Resolve the hub-local-uds route for a cap owned by a forked hub-local
126978
+ * child, IGNORING any in-hub provider registered for the same cap name.
126979
+ *
126980
+ * `resolveCapRoute` gives Priority 1 to `hub-in-process`: when an in-hub
126981
+ * provider (e.g. a wrapper) is registered for the cap, the route always
126982
+ * classifies as `hub-in-process` and the hub-local-uds NATIVE child is never
126983
+ * reached. That is correct for the generic dispatch path (the wrapper is the
126984
+ * active provider), but WRONG for the native-cap fallback
126985
+ * (`setNativeFallback`), whose contract is to reach the NATIVE provider in
126986
+ * the forked vendor child so a wrapper can delegate to it. A wrapper cap
126987
+ * with a forked native (today: `snapshot`) otherwise resolves to the wrapper
126988
+ * itself, the native is never invoked, and the wrapper silently falls
126989
+ * through to its secondary strategy.
126990
+ *
126991
+ * This method consults ONLY the hub-local-child authority
126992
+ * (`hubLocalChildProvides` + `getHubLocalChildId`, both deviceId-aware), so
126993
+ * it returns the native child route regardless of any in-process shadow.
126994
+ * Returns null when no hub-local child owns `(capName, deviceId)` — the
126995
+ * caller then falls through to its remote-resolution branch.
126996
+ */
126997
+ resolveHubLocalUdsRoute(capName, deviceId) {
126998
+ if (!this.snapshot.hubLocalChildProvides(capName, deviceId)) return null;
126999
+ const childId = this.snapshot.getHubLocalChildId?.(capName, deviceId) ?? null;
127000
+ if (childId === null) return null;
127001
+ return {
127002
+ kind: "hub-local-uds",
127003
+ capName,
127004
+ childId
127005
+ };
127006
+ }
127007
+ /**
127008
+ * @param addonId Optional out-of-band PROVIDER-selection hint (Task 7.5a):
127009
+ * the addonId of the provider the CALLER already resolved (e.g.
127010
+ * `buildCapCallFn`'s `deps.addonId` for a registered grouped-runner
127011
+ * provider). Only meaningful for `agent-child-forward` — a `remote-moleculer`
127012
+ * route already encodes the provider in its action name
127013
+ * (`${addonId}.${cap}.${method}`, via `NodeCapAuthority.getAddonId`), and a
127014
+ * `hub-local-uds` caller that already knows the addonId (`buildCapCallFn`)
127015
+ * talks to `LocalChildRegistry.callCapOnChild` directly rather than through
127016
+ * `dispatch`.
127017
+ * @param callerAddonId Optional out-of-band CALLER-identity hint — the
127018
+ * addon that ORIGINATED the call, distinct from `addonId` above (which
127019
+ * names the resolved PROVIDER, not the caller). Set by
127020
+ * `onUnownedCall` from `CapCallInput.callerAddonId`
127021
+ * (`LocalChildRegistry` stamped it off the registered `childId`). Only
127022
+ * the `hub-in-process` branch consumes it — merged into `args` so a
127023
+ * diagnostic tool deep in that provider (e.g. device-manager's
127024
+ * fleet-read census) can read it without every provider method changing
127025
+ * signature, the same "extra field the provider destructures or
127026
+ * ignores" convention `nodeId` already uses on this path.
127027
+ */
127028
+ async dispatch(route, method, args, addonId, callerAddonId) {
127029
+ try {
127030
+ return await this.dispatchInner(route, method, args, addonId, callerAddonId);
127031
+ } catch (err) {
127032
+ if (err instanceof CapRouteError) throw err;
127033
+ const nodeId = this.routeNodeId(route);
127034
+ const cause = err instanceof Error ? err : new Error(String(err));
127035
+ throw new CapRouteError(route.capName, method, {
127036
+ reason: "transport-failed",
127037
+ nodeId,
127038
+ rejected: [{
127039
+ kind: route.kind,
127040
+ why: cause.message
127041
+ }]
127042
+ }, cause);
127043
+ }
127044
+ }
127045
+ /**
127046
+ * Inner dispatch: may throw CapRouteError (validation failures) or arbitrary
127047
+ * transport errors. The outer `dispatch` wraps non-CapRouteErrors.
127048
+ */
127049
+ async dispatchInner(route, method, args, addonId, callerAddonId) {
127050
+ switch (route.kind) {
127051
+ case "hub-in-process":
127052
+ return route.ref.invoke(method, withCallerAddonId(args, callerAddonId));
127053
+ case "hub-local-uds": {
127054
+ const registry = this.hubLocalRegistry;
127055
+ if (registry === null) throw new CapRouteError(route.capName, method, {
127056
+ reason: "no-provider",
127057
+ rejected: [{
127058
+ kind: "hub-local-uds",
127059
+ why: "UDS registry not available"
127060
+ }]
127061
+ });
127062
+ const deviceId = extractDeviceId(args);
127063
+ const input = {
127064
+ capName: route.capName,
127065
+ method,
127066
+ args,
127067
+ ...deviceId !== void 0 ? { deviceId } : {}
127068
+ };
127069
+ return registry.callCapOnChild(route.childId, input);
127070
+ }
127071
+ case "remote-moleculer": {
127072
+ const addonId2 = this.nodeAuthority.getAddonId(route.nodeId, route.capName);
127073
+ if (addonId2 === null) throw new CapRouteError(route.capName, method, {
127074
+ reason: "no-provider",
127075
+ nodeId: route.nodeId,
127076
+ rejected: [{
127077
+ kind: "remote-moleculer",
127078
+ why: `no addonId known for ${route.nodeId}/${route.capName}`
127079
+ }]
127080
+ });
127081
+ const deviceId = extractDeviceId(args);
127082
+ const isNative = this.nodeAuthority.isNativeCap(route.nodeId, route.capName, deviceId);
127083
+ const action = capActionName(addonId2, route.capName, method, isNative);
127084
+ return callWithServiceDiscovery(this.broker, addonId2, action, args, {
127085
+ nodeID: route.nodeId,
127086
+ timeout: this.callTimeout(route.capName, method)
127087
+ });
127088
+ }
127089
+ case "agent-child-forward": {
127090
+ const deviceId = extractDeviceId(args);
127091
+ const params = {
127092
+ capName: route.capName,
127093
+ method,
127094
+ args,
127095
+ ...route.childId !== void 0 ? { childId: route.childId } : {},
127096
+ ...deviceId !== void 0 ? { deviceId } : {},
127097
+ ...addonId !== void 0 ? { addonId } : {}
127098
+ };
127099
+ return callWithServiceDiscovery(this.broker, AGENT_CAP_FWD_SERVICE, AGENT_CAP_FWD_ACTION, params, {
127100
+ nodeID: route.agentNodeId,
127101
+ timeout: this.callTimeout(route.capName, method)
127102
+ });
127103
+ }
127104
+ }
127105
+ }
127106
+ buildSnapshot() {
127107
+ const hubLocalRegistry = this.hubLocalRegistry;
127108
+ const nodeAuthority = this.nodeAuthority;
127109
+ const inProcessProviders = this.inProcessProviders;
127110
+ const hubResidentProviders = this.hubResidentProviders;
127111
+ return {
127112
+ hubNodeId: this.hubNodeId,
127113
+ hubInProcessProvides: (cap) => inProcessProviders(cap) !== null,
127114
+ ...hubResidentProviders !== void 0 ? {
127115
+ hubResidentProvides: (cap) => hubResidentProviders(cap) !== null,
127116
+ getHubResidentProviderRef: (cap) => hubResidentProviders(cap)
127117
+ } : {},
127118
+ hubLocalChildProvides: (cap, deviceId) => hubLocalRegistry !== null && hubLocalRegistry.resolveChildId(cap, deviceId) !== null,
127119
+ nodeKnowsCap: (nodeId, cap) => nodeAuthority.nodeKnowsCap(nodeId, cap),
127120
+ nodeIsAgent: (nodeId) => nodeAuthority.nodeIsAgent(nodeId),
127121
+ nodeOnline: (nodeId) => nodeAuthority.nodeOnline(nodeId),
127122
+ listKnownNodeIds: () => nodeAuthority.listNodeIds(),
127123
+ getInProcessProviderRef: (cap) => inProcessProviders(cap),
127124
+ getHubLocalChildId: (cap, deviceId) => hubLocalRegistry !== null ? hubLocalRegistry.resolveChildId(cap, deviceId) : null,
127125
+ getAgentChildId: (agentNodeId, cap) => nodeAuthority.getAgentChildId(agentNodeId, cap)
127126
+ };
127127
+ }
127128
+ /** Extract a nodeId string from a route for error reporting, or undefined. */
127129
+ routeNodeId(route) {
127130
+ switch (route.kind) {
127131
+ case "hub-in-process":
127132
+ return this.hubNodeId;
127133
+ case "hub-local-uds":
127134
+ return `${this.hubNodeId}/${route.childId}`;
127135
+ case "remote-moleculer":
127136
+ return route.nodeId;
127137
+ case "agent-child-forward":
127138
+ return route.agentNodeId;
127139
+ }
127140
+ }
127141
+ };
126310
127142
  var LEVEL_ORDER = {
126311
127143
  debug: 0,
126312
127144
  info: 1,
@@ -128380,12 +129212,36 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
128380
129212
  return LocalChildRegistry;
128381
129213
  }
128382
129214
  });
129215
+ Object.defineProperty(exports, "MESH_QUEUE_TOP_N", {
129216
+ enumerable: true,
129217
+ get: function() {
129218
+ return MESH_QUEUE_TOP_N;
129219
+ }
129220
+ });
128383
129221
  Object.defineProperty(exports, "NATIVE_PROVIDER_SERVICE_INFIX", {
128384
129222
  enumerable: true,
128385
129223
  get: function() {
128386
129224
  return NATIVE_PROVIDER_SERVICE_INFIX;
128387
129225
  }
128388
129226
  });
129227
+ Object.defineProperty(exports, "OUTBOUND_QUEUE_COOLDOWN_MS", {
129228
+ enumerable: true,
129229
+ get: function() {
129230
+ return OUTBOUND_QUEUE_COOLDOWN_MS;
129231
+ }
129232
+ });
129233
+ Object.defineProperty(exports, "OUTBOUND_QUEUE_SUSTAIN_MS", {
129234
+ enumerable: true,
129235
+ get: function() {
129236
+ return OUTBOUND_QUEUE_SUSTAIN_MS;
129237
+ }
129238
+ });
129239
+ Object.defineProperty(exports, "OUTBOUND_QUEUE_THRESHOLD_BYTES", {
129240
+ enumerable: true,
129241
+ get: function() {
129242
+ return OUTBOUND_QUEUE_THRESHOLD_BYTES;
129243
+ }
129244
+ });
128389
129245
  Object.defineProperty(exports, "PARENT_ROUTED_PROVIDER_ADDON_ID", {
128390
129246
  enumerable: true,
128391
129247
  get: function() {
@@ -128422,6 +129278,12 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
128422
129278
  return SOCKET_PLANE_TOP_N;
128423
129279
  }
128424
129280
  });
129281
+ Object.defineProperty(exports, "SOCKET_QUEUE_TOP_N", {
129282
+ enumerable: true,
129283
+ get: function() {
129284
+ return SOCKET_QUEUE_TOP_N;
129285
+ }
129286
+ });
128425
129287
  Object.defineProperty(exports, "SocketChannel", {
128426
129288
  enumerable: true,
128427
129289
  get: function() {
@@ -128620,6 +129482,18 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
128620
129482
  return createLoopDelayMeter;
128621
129483
  }
128622
129484
  });
129485
+ Object.defineProperty(exports, "createMeshQueueReader", {
129486
+ enumerable: true,
129487
+ get: function() {
129488
+ return createMeshQueueReader;
129489
+ }
129490
+ });
129491
+ Object.defineProperty(exports, "createOutboundQueueGate", {
129492
+ enumerable: true,
129493
+ get: function() {
129494
+ return createOutboundQueueGate;
129495
+ }
129496
+ });
128623
129497
  Object.defineProperty(exports, "createParentUnownedCallHandler", {
128624
129498
  enumerable: true,
128625
129499
  get: function() {
@@ -128734,6 +129608,18 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
128734
129608
  return formatHeapSpaces;
128735
129609
  }
128736
129610
  });
129611
+ Object.defineProperty(exports, "formatMeshQueue", {
129612
+ enumerable: true,
129613
+ get: function() {
129614
+ return formatMeshQueue;
129615
+ }
129616
+ });
129617
+ Object.defineProperty(exports, "formatOutboundQueueVerdict", {
129618
+ enumerable: true,
129619
+ get: function() {
129620
+ return formatOutboundQueueVerdict;
129621
+ }
129622
+ });
128737
129623
  Object.defineProperty(exports, "formatSocketPlane", {
128738
129624
  enumerable: true,
128739
129625
  get: function() {
@@ -128878,6 +129764,12 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
128878
129764
  return readMoleculerFanoutMode;
128879
129765
  }
128880
129766
  });
129767
+ Object.defineProperty(exports, "readSocketQueues", {
129768
+ enumerable: true,
129769
+ get: function() {
129770
+ return readSocketQueues;
129771
+ }
129772
+ });
128881
129773
  Object.defineProperty(exports, "reclaimIntervalMs", {
128882
129774
  enumerable: true,
128883
129775
  get: function() {
@@ -129013,11 +129905,11 @@ var require_manifest_system_deps_Bo92lg5u = __commonJS({
129013
129905
  }
129014
129906
  });
129015
129907
 
129016
- // ../system/dist/custom-action-registry-BDwM5qAK.js
129017
- var require_custom_action_registry_BDwM5qAK = __commonJS({
129018
- "../system/dist/custom-action-registry-BDwM5qAK.js"(exports) {
129908
+ // ../system/dist/custom-action-registry-DKWhaWL1.js
129909
+ var require_custom_action_registry_DKWhaWL1 = __commonJS({
129910
+ "../system/dist/custom-action-registry-DKWhaWL1.js"(exports) {
129019
129911
  "use strict";
129020
- var require_dist10 = require_dist_BOlMCOeT();
129912
+ var require_dist10 = require_dist_B17W9ngu();
129021
129913
  var CustomActionRegistry = class {
129022
129914
  byAddon = /* @__PURE__ */ new Map();
129023
129915
  registerAddon(addonId, catalog, handler) {
@@ -132831,7 +133723,7 @@ var require_dist3 = __commonJS({
132831
133723
  "use strict";
132832
133724
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
132833
133725
  var require_chunk = require_chunk_Cek0wNdY();
132834
- var require_dist10 = require_dist_BOlMCOeT();
133726
+ var require_dist10 = require_dist_B17W9ngu();
132835
133727
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
132836
133728
  require_alerts();
132837
133729
  var require_formatter = require_formatter_DqAKDlvN();
@@ -132856,25 +133748,25 @@ var require_dist3 = __commonJS({
132856
133748
  var require_builtins_system_config_system_config_addon = require_system_config_addon();
132857
133749
  require_system_config();
132858
133750
  var require_builtins_winston_logging_index = require_winston_logging();
132859
- var require_event_loop_stall_monitor = require_event_loop_stall_monitor_DM9OAzy8();
132860
- var require_tls$1 = require_tls_BxQlomxd();
132861
- var require_manifest_system_deps = require_manifest_system_deps_Bo92lg5u();
132862
- var require_resource_monitor = require_resource_monitor_CdnzxBLP();
132863
- var require_custom_action_registry = require_custom_action_registry_BDwM5qAK();
133751
+ var require_event_loop_stall_monitor = require_event_loop_stall_monitor_CAsHdMwP();
133752
+ var require_tls$1 = require_tls_BFs4PzoW();
133753
+ var require_manifest_system_deps = require_manifest_system_deps_g_nK0xsF();
133754
+ var require_resource_monitor = require_resource_monitor_LVE1BoLs();
133755
+ var require_custom_action_registry = require_custom_action_registry_DKWhaWL1();
132864
133756
  var zod = require_zod();
132865
133757
  var node_crypto = __require("crypto");
132866
133758
  var _camstack_types_node = require_node();
132867
133759
  var node_fs_promises = __require("fs/promises");
132868
133760
  var node_path = __require("path");
132869
133761
  node_path = require_chunk.__toESM(node_path, 1);
132870
- var node_child_process = __require("child_process");
132871
- var node_util = __require("util");
132872
- node_util = require_chunk.__toESM(node_util);
132873
133762
  var node_fs = __require("fs");
132874
133763
  var node_fs$1 = require_chunk.__toESM(node_fs, 1);
132875
133764
  node_fs = require_chunk.__toESM(node_fs);
133765
+ var node_child_process = __require("child_process");
132876
133766
  var node_os = __require("os");
132877
133767
  node_os = require_chunk.__toESM(node_os);
133768
+ var node_util = __require("util");
133769
+ node_util = require_chunk.__toESM(node_util);
132878
133770
  var node_http = __require("http");
132879
133771
  var node_vm = __require("vm");
132880
133772
  node_vm = require_chunk.__toESM(node_vm);
@@ -212614,33 +213506,13 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
212614
213506
  }
212615
213507
  }
212616
213508
  async function getPidStats$1(pids) {
212617
- if (pids.length === 0) return /* @__PURE__ */ new Map();
212618
- return new Promise((resolve) => {
212619
- (0, node_child_process.execFile)("ps", [
212620
- "-o",
212621
- "pid=,pcpu=,rss=",
212622
- "-p",
212623
- pids.join(",")
212624
- ], { timeout: 5e3 }, (err, stdout) => {
212625
- const result = /* @__PURE__ */ new Map();
212626
- if (err || !stdout) {
212627
- resolve(result);
212628
- return;
212629
- }
212630
- for (const line of stdout.trim().split("\n")) {
212631
- const parts = line.trim().split(/\s+/);
212632
- if (parts.length < 3) continue;
212633
- const pid = parseInt(parts[0], 10);
212634
- const cpu = parseFloat(parts[1]);
212635
- const rssKb = parseInt(parts[2], 10);
212636
- if (!isNaN(pid) && !isNaN(cpu) && !isNaN(rssKb)) result.set(pid, {
212637
- cpu: Math.round(cpu * 10) / 10,
212638
- memoryRss: rssKb * 1024
212639
- });
212640
- }
212641
- resolve(result);
212642
- });
213509
+ const stats = await require_resource_monitor.getPidStats(pids);
213510
+ const result = /* @__PURE__ */ new Map();
213511
+ for (const [pid, s] of stats) result.set(pid, {
213512
+ cpu: s.cpu,
213513
+ memoryRss: s.memory
212643
213514
  });
213515
+ return result;
212644
213516
  }
212645
213517
  var EMPTY_HEAP_DECLARATION = {
212646
213518
  profile: void 0,
@@ -213629,6 +214501,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213629
214501
  exports.LokiDestination = require_builtins_loki_logging_index.LokiDestination$1;
213630
214502
  exports.LokiLoggingAddon = require_builtins_loki_logging_index.LokiLoggingAddon$1;
213631
214503
  exports.MAX_LEAF_VALIDITY_DAYS = require_tls$1.MAX_LEAF_VALIDITY_DAYS;
214504
+ exports.MESH_QUEUE_TOP_N = require_manifest_system_deps.MESH_QUEUE_TOP_N;
213632
214505
  exports.METHOD_ACCESS_MAP = require_dist10.METHOD_ACCESS_MAP;
213633
214506
  exports.ModelDownloadService = require_event_loop_stall_monitor.ModelDownloadService;
213634
214507
  exports.NATIVE_PROVIDER_SERVICE_INFIX = require_manifest_system_deps.NATIVE_PROVIDER_SERVICE_INFIX;
@@ -213637,6 +214510,9 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213637
214510
  exports.NativeMetricsProvider = require_builtins_native_metrics_native_metrics_addon.NativeMetricsProvider;
213638
214511
  exports.NetworkQualityTracker = NetworkQualityTracker;
213639
214512
  exports.NotificationService = NotificationService;
214513
+ exports.OUTBOUND_QUEUE_COOLDOWN_MS = require_manifest_system_deps.OUTBOUND_QUEUE_COOLDOWN_MS;
214514
+ exports.OUTBOUND_QUEUE_SUSTAIN_MS = require_manifest_system_deps.OUTBOUND_QUEUE_SUSTAIN_MS;
214515
+ exports.OUTBOUND_QUEUE_THRESHOLD_BYTES = require_manifest_system_deps.OUTBOUND_QUEUE_THRESHOLD_BYTES;
213640
214516
  exports.PARENT_ROUTED_PROVIDER_ADDON_ID = require_manifest_system_deps.PARENT_ROUTED_PROVIDER_ADDON_ID;
213641
214517
  Object.defineProperty(exports, "PYTHON_VERSION", {
213642
214518
  enumerable: true,
@@ -213660,6 +214536,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213660
214536
  exports.RingBuffer = RingBuffer;
213661
214537
  exports.SERVER_AUTH_OID = require_tls$1.SERVER_AUTH_OID;
213662
214538
  exports.SOCKET_PLANE_TOP_N = require_manifest_system_deps.SOCKET_PLANE_TOP_N;
214539
+ exports.SOCKET_QUEUE_TOP_N = require_manifest_system_deps.SOCKET_QUEUE_TOP_N;
213663
214540
  exports.STALL_REPORT_MS = require_event_loop_stall_monitor.STALL_REPORT_MS;
213664
214541
  exports.STALL_TICK_MS = require_event_loop_stall_monitor.STALL_TICK_MS;
213665
214542
  exports.ScopedLogger = ScopedLogger;
@@ -213745,6 +214622,8 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213745
214622
  exports.createKernelHwAccel = require_manifest_system_deps.createKernelHwAccel;
213746
214623
  exports.createLocalTransport = require_manifest_system_deps.createLocalTransport;
213747
214624
  exports.createLoopDelayMeter = require_manifest_system_deps.createLoopDelayMeter;
214625
+ exports.createMeshQueueReader = require_manifest_system_deps.createMeshQueueReader;
214626
+ exports.createOutboundQueueGate = require_manifest_system_deps.createOutboundQueueGate;
213748
214627
  exports.createParentUnownedCallHandler = require_manifest_system_deps.createParentUnownedCallHandler;
213749
214628
  exports.createProcessService = createProcessService;
213750
214629
  exports.createReadinessService = createReadinessService;
@@ -213815,6 +214694,8 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213815
214694
  exports.formatEventPlane = require_manifest_system_deps.formatEventPlane;
213816
214695
  exports.formatHeapSpaces = require_manifest_system_deps.formatHeapSpaces;
213817
214696
  exports.formatLogLine = require_formatter.formatLogLine;
214697
+ exports.formatMeshQueue = require_manifest_system_deps.formatMeshQueue;
214698
+ exports.formatOutboundQueueVerdict = require_manifest_system_deps.formatOutboundQueueVerdict;
213818
214699
  exports.formatSocketPlane = require_manifest_system_deps.formatSocketPlane;
213819
214700
  exports.getBrokerEventBus = require_manifest_system_deps.getBrokerEventBus;
213820
214701
  exports.getCapUsageRegistry = require_manifest_system_deps.getCapUsageRegistry;
@@ -213892,6 +214773,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
213892
214773
  exports.readLanHttpState = require_tls$1.readLanHttpState;
213893
214774
  exports.readMoleculerFanoutMode = require_manifest_system_deps.readMoleculerFanoutMode;
213894
214775
  exports.readPendingRestart = readPendingRestart;
214776
+ exports.readSocketQueues = require_manifest_system_deps.readSocketQueues;
213895
214777
  exports.readTlsAccessStatus = require_tls$1.readTlsAccessStatus;
213896
214778
  exports.readTlsMode = require_tls$1.readTlsMode;
213897
214779
  exports.readinessKey = require_dist10.readinessKey;
@@ -235898,8 +236780,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
235898
236780
  *
235899
236781
  * An **empty array reads NOTHING** — `[]` is an empty page, never
235900
236782
  * "every camera". A request for no devices is a request, not an
235901
- * omission; same contract as `deviceManager.listFleet` and
235902
- * `pipelineAnalytics.listRecentTracks`.
236783
+ * omission; same contract as `deviceManager.listAll`'s `deviceIds`
236784
+ * and `pipelineAnalytics.listRecentTracks`.
235903
236785
  *
235904
236786
  * Absent (`undefined`) is the omission, and keeps the cluster-wide view.
235905
236787
  */
@@ -416020,6 +416902,355 @@ var require_auth_whoami = __commonJS({
416020
416902
  }
416021
416903
  });
416022
416904
 
416905
+ // ../../server/backend/dist/api/backup-download-pump.js
416906
+ var require_backup_download_pump = __commonJS({
416907
+ "../../server/backend/dist/api/backup-download-pump.js"(exports) {
416908
+ "use strict";
416909
+ Object.defineProperty(exports, "__esModule", { value: true });
416910
+ exports.BACKUP_DOWNLOAD_DRAIN_GRACE_MS = exports.BACKUP_DOWNLOAD_CHUNK_BYTES = void 0;
416911
+ exports.pumpDownload = pumpDownload;
416912
+ exports.BACKUP_DOWNLOAD_CHUNK_BYTES = 8 * 1024 * 1024;
416913
+ exports.BACKUP_DOWNLOAD_DRAIN_GRACE_MS = 6e4;
416914
+ function waitForDrain(sink, graceMs) {
416915
+ return new Promise((resolve) => {
416916
+ const settle = (outcome) => {
416917
+ sink.off("drain", onDrain);
416918
+ sink.off("close", onClose);
416919
+ clearTimeout(timer);
416920
+ resolve(outcome);
416921
+ };
416922
+ const onDrain = () => settle("drained");
416923
+ const onClose = () => settle("closed");
416924
+ const timer = setTimeout(() => settle("timeout"), graceMs);
416925
+ sink.on("drain", onDrain);
416926
+ sink.on("close", onClose);
416927
+ });
416928
+ }
416929
+ function errorOf(err) {
416930
+ return err instanceof Error ? err : new Error(String(err));
416931
+ }
416932
+ async function pumpDownload(options) {
416933
+ const { sizeBytes, read, sink } = options;
416934
+ const chunkBytes = options.chunkBytes ?? exports.BACKUP_DOWNLOAD_CHUNK_BYTES;
416935
+ const graceMs = options.graceMs ?? exports.BACKUP_DOWNLOAD_DRAIN_GRACE_MS;
416936
+ const now = options.now ?? (() => Date.now());
416937
+ const startedAt = now();
416938
+ let offset = 0;
416939
+ let drainWaits = 0;
416940
+ let drainWaitMaxMs = 0;
416941
+ const counters = () => ({
416942
+ bytesWritten: offset,
416943
+ drainWaits,
416944
+ drainWaitMaxMs,
416945
+ durationMs: now() - startedAt
416946
+ });
416947
+ while (offset < sizeBytes) {
416948
+ if (sink.destroyed)
416949
+ return { status: "peer-gone", ...counters() };
416950
+ const length = Math.min(chunkBytes, sizeBytes - offset);
416951
+ let chunk;
416952
+ try {
416953
+ chunk = await read(offset, length);
416954
+ } catch (err) {
416955
+ const error = errorOf(err);
416956
+ sink.destroy(error);
416957
+ return { status: "source-failed", error: error.message, ...counters() };
416958
+ }
416959
+ if (chunk.byteLength === 0) {
416960
+ const error = new Error(`backup download: empty chunk at offset ${offset}/${sizeBytes}`);
416961
+ sink.destroy(error);
416962
+ return { status: "source-failed", error: error.message, ...counters() };
416963
+ }
416964
+ if (sink.destroyed)
416965
+ return { status: "peer-gone", ...counters() };
416966
+ const accepted = sink.write(chunk);
416967
+ offset += chunk.byteLength;
416968
+ if (accepted)
416969
+ continue;
416970
+ const waitStartedAt = now();
416971
+ const outcome = await waitForDrain(sink, graceMs);
416972
+ const waitedMs = now() - waitStartedAt;
416973
+ drainWaits += 1;
416974
+ if (waitedMs > drainWaitMaxMs)
416975
+ drainWaitMaxMs = waitedMs;
416976
+ if (outcome === "closed")
416977
+ return { status: "peer-gone", ...counters() };
416978
+ if (outcome === "timeout") {
416979
+ const queuedBytes = sink.writableLength;
416980
+ sink.destroy(new Error(`backup download: client stopped reading \u2014 ${queuedBytes} bytes queued for ${waitedMs} ms`));
416981
+ return { status: "drain-timeout", heldForMs: waitedMs, queuedBytes, ...counters() };
416982
+ }
416983
+ }
416984
+ sink.end();
416985
+ return { status: "completed", ...counters() };
416986
+ }
416987
+ }
416988
+ });
416989
+
416990
+ // ../../server/backend/dist/api/trpc/client-ip.js
416991
+ var require_client_ip = __commonJS({
416992
+ "../../server/backend/dist/api/trpc/client-ip.js"(exports) {
416993
+ "use strict";
416994
+ Object.defineProperty(exports, "__esModule", { value: true });
416995
+ exports.extractClientIp = extractClientIp;
416996
+ exports.extractCfConnectingIp = extractCfConnectingIp;
416997
+ exports.extractPeerIp = extractPeerIp;
416998
+ exports.extractUserAgent = extractUserAgent;
416999
+ exports.ipClass = ipClass;
417000
+ exports.classifyClient = classifyClient;
417001
+ exports.classifyClientRequest = classifyClientRequest;
417002
+ exports.deriveRelayOnly = deriveRelayOnly;
417003
+ exports.isRemoteClientIp = isRemoteClientIp;
417004
+ function extractClientIp(req) {
417005
+ if (!req)
417006
+ return null;
417007
+ const xff = req.headers["x-forwarded-for"];
417008
+ const xffValue = Array.isArray(xff) ? xff[0] : xff;
417009
+ if (typeof xffValue === "string" && xffValue.length > 0) {
417010
+ const first = xffValue.split(",")[0]?.trim();
417011
+ if (first)
417012
+ return normalizeIp(first);
417013
+ }
417014
+ if ("ip" in req && typeof req.ip === "string" && req.ip.length > 0) {
417015
+ return normalizeIp(req.ip);
417016
+ }
417017
+ const remote = req.socket?.remoteAddress;
417018
+ if (typeof remote === "string" && remote.length > 0) {
417019
+ return normalizeIp(remote);
417020
+ }
417021
+ return null;
417022
+ }
417023
+ function extractCfConnectingIp(req) {
417024
+ if (!req)
417025
+ return null;
417026
+ const raw = req.headers["cf-connecting-ip"];
417027
+ const value = Array.isArray(raw) ? raw[0] : raw;
417028
+ if (typeof value === "string" && value.length > 0)
417029
+ return normalizeIp(value.trim());
417030
+ return null;
417031
+ }
417032
+ function extractPeerIp(req) {
417033
+ if (!req)
417034
+ return null;
417035
+ const remote = req.socket?.remoteAddress;
417036
+ if (typeof remote === "string" && remote.length > 0)
417037
+ return normalizeIp(remote);
417038
+ return null;
417039
+ }
417040
+ function extractUserAgent(req) {
417041
+ if (!req)
417042
+ return null;
417043
+ const ua = req.headers["user-agent"];
417044
+ const value = Array.isArray(ua) ? ua[0] : ua;
417045
+ if (typeof value === "string" && value.length > 0)
417046
+ return value;
417047
+ return null;
417048
+ }
417049
+ function normalizeIp(ip) {
417050
+ let out = ip.trim();
417051
+ if (out.startsWith("::ffff:"))
417052
+ out = out.slice("::ffff:".length);
417053
+ const pct = out.indexOf("%");
417054
+ if (pct !== -1)
417055
+ out = out.slice(0, pct);
417056
+ return out;
417057
+ }
417058
+ function ipClass(ip) {
417059
+ if (!ip)
417060
+ return "lan";
417061
+ if (ip.includes(":")) {
417062
+ if (isTailscaleIpv6(ip))
417063
+ return "vpn";
417064
+ if (isPrivateIpv6(ip))
417065
+ return "lan";
417066
+ return "remote";
417067
+ }
417068
+ if (isIpv4(ip)) {
417069
+ if (isTailscaleIpv4(ip))
417070
+ return "vpn";
417071
+ if (isPrivateIpv4(ip))
417072
+ return "lan";
417073
+ return "remote";
417074
+ }
417075
+ return "lan";
417076
+ }
417077
+ function classifyClient(args) {
417078
+ if (args.peerIsLocal && args.cfConnectingIp)
417079
+ return ipClass(args.cfConnectingIp);
417080
+ return ipClass(args.clientIp);
417081
+ }
417082
+ function classifyClientRequest(req) {
417083
+ if (!req)
417084
+ return null;
417085
+ const clientIp = extractClientIp(req);
417086
+ const cfConnectingIp = extractCfConnectingIp(req);
417087
+ const peerIp = extractPeerIp(req);
417088
+ const peerIsLocal = peerIp !== null && ipClass(peerIp) !== "remote";
417089
+ return classifyClient({ clientIp, cfConnectingIp, peerIsLocal });
417090
+ }
417091
+ function deriveRelayOnly(clientClass) {
417092
+ return clientClass === "remote";
417093
+ }
417094
+ function isRemoteClientIp(ip) {
417095
+ return ipClass(ip) === "remote";
417096
+ }
417097
+ function isIpv4(ip) {
417098
+ const parts = ip.split(".");
417099
+ if (parts.length !== 4)
417100
+ return false;
417101
+ return parts.every((p) => {
417102
+ if (!/^\d{1,3}$/.test(p))
417103
+ return false;
417104
+ const n = Number.parseInt(p, 10);
417105
+ return n >= 0 && n <= 255;
417106
+ });
417107
+ }
417108
+ function isTailscaleIpv4(ip) {
417109
+ const parts = ip.split(".").map((p) => Number.parseInt(p, 10));
417110
+ const [a, b] = parts;
417111
+ if (a === void 0 || b === void 0)
417112
+ return false;
417113
+ return a === 100 && b >= 64 && b <= 127;
417114
+ }
417115
+ function isPrivateIpv4(ip) {
417116
+ const parts = ip.split(".").map((p) => Number.parseInt(p, 10));
417117
+ const [a, b] = parts;
417118
+ if (a === void 0 || b === void 0)
417119
+ return false;
417120
+ if (a === 10)
417121
+ return true;
417122
+ if (a === 127)
417123
+ return true;
417124
+ if (a === 172 && b >= 16 && b <= 31)
417125
+ return true;
417126
+ if (a === 192 && b === 168)
417127
+ return true;
417128
+ if (a === 169 && b === 254)
417129
+ return true;
417130
+ return false;
417131
+ }
417132
+ function isTailscaleIpv6(ip) {
417133
+ return ip.toLowerCase().startsWith("fd7a:115c:a1e0:");
417134
+ }
417135
+ function isPrivateIpv6(ip) {
417136
+ const lower = ip.toLowerCase();
417137
+ if (lower === "::1")
417138
+ return true;
417139
+ if (lower === "::")
417140
+ return true;
417141
+ if (lower.startsWith("fe80"))
417142
+ return true;
417143
+ if (lower.startsWith("fc") || lower.startsWith("fd"))
417144
+ return true;
417145
+ return false;
417146
+ }
417147
+ }
417148
+ });
417149
+
417150
+ // ../../server/backend/dist/api/backup-download.js
417151
+ var require_backup_download = __commonJS({
417152
+ "../../server/backend/dist/api/backup-download.js"(exports) {
417153
+ "use strict";
417154
+ Object.defineProperty(exports, "__esModule", { value: true });
417155
+ exports.registerBackupDownloadRoute = registerBackupDownloadRoute;
417156
+ var backup_download_pump_js_1 = require_backup_download_pump();
417157
+ var client_ip_js_1 = require_client_ip();
417158
+ function safeAttachmentName(name) {
417159
+ return name.replace(/[\r\n"]/g, "_");
417160
+ }
417161
+ function registerBackupDownloadRoute(fastify, options) {
417162
+ const { verifier, capabilities, logger } = options;
417163
+ const chunkBytes = options.chunkBytes ?? backup_download_pump_js_1.BACKUP_DOWNLOAD_CHUNK_BYTES;
417164
+ const graceMs = options.graceMs ?? backup_download_pump_js_1.BACKUP_DOWNLOAD_DRAIN_GRACE_MS;
417165
+ fastify.get("/api/backup/download/:locationId/:archiveId", async (request, reply) => {
417166
+ const authHeader = request.headers.authorization;
417167
+ if (!authHeader) {
417168
+ return reply.status(401).send({ error: "Unauthorized" });
417169
+ }
417170
+ try {
417171
+ const payload = verifier.verifyToken(authHeader.replace("Bearer ", ""));
417172
+ if (!payload.isAdmin) {
417173
+ return reply.status(403).send({ error: "Admin required" });
417174
+ }
417175
+ } catch {
417176
+ return reply.status(401).send({ error: "Invalid token" });
417177
+ }
417178
+ const { locationId, archiveId } = request.params;
417179
+ const backup = capabilities.getSingleton("backup");
417180
+ if (!backup?.listArchives) {
417181
+ return reply.status(503).send({ error: "Backup orchestrator unavailable" });
417182
+ }
417183
+ const archives = await backup.listArchives({ destinationId: locationId });
417184
+ const archive = archives.find((a) => a.id === archiveId);
417185
+ if (!archive) {
417186
+ return reply.status(404).send({ error: "Archive not found" });
417187
+ }
417188
+ const storage = capabilities.getSingleton("storage");
417189
+ if (!storage?.beginDownload) {
417190
+ return reply.status(503).send({ error: "Storage cap unavailable" });
417191
+ }
417192
+ const { downloadId, sizeBytes } = await storage.beginDownload({
417193
+ location: locationId,
417194
+ relativePath: archive.filename
417195
+ });
417196
+ reply.hijack();
417197
+ reply.raw.writeHead(200, {
417198
+ "content-type": "application/gzip",
417199
+ "content-length": String(sizeBytes),
417200
+ "content-disposition": `attachment; filename="${safeAttachmentName(`${archive.label ?? archive.id}.tar.gz`)}"`
417201
+ });
417202
+ const facts = {
417203
+ locationId,
417204
+ archiveId,
417205
+ filename: archive.filename,
417206
+ sizeBytes,
417207
+ ip: (0, client_ip_js_1.extractClientIp)(request.raw) ?? "(unidentified)",
417208
+ chunkBytes,
417209
+ graceMs
417210
+ };
417211
+ let result;
417212
+ try {
417213
+ result = await (0, backup_download_pump_js_1.pumpDownload)({
417214
+ sizeBytes,
417215
+ chunkBytes,
417216
+ graceMs,
417217
+ sink: reply.raw,
417218
+ read: (offset, length) => storage.readChunk({ downloadId, offset, length })
417219
+ });
417220
+ } finally {
417221
+ try {
417222
+ await storage.endDownload({ downloadId });
417223
+ } catch (err) {
417224
+ logger.warn("backup archive download: the storage cap refused to close the handle", {
417225
+ meta: { ...facts, error: err instanceof Error ? err.message : String(err) }
417226
+ });
417227
+ }
417228
+ }
417229
+ logOutcome(logger, facts, result);
417230
+ });
417231
+ }
417232
+ function logOutcome(logger, facts, result) {
417233
+ const meta = { ...facts, ...result };
417234
+ switch (result.status) {
417235
+ case "completed":
417236
+ logger.info("backup archive download completed", { meta });
417237
+ return;
417238
+ case "peer-gone":
417239
+ logger.info("backup archive download abandoned \u2014 the client closed the connection", { meta });
417240
+ return;
417241
+ case "drain-timeout":
417242
+ logger.warn("backup archive download cut \u2014 the client stopped reading and the response queue stayed unsent for the whole grace period (nothing more is read; the queue is released)", { meta });
417243
+ return;
417244
+ case "source-failed":
417245
+ logger.warn("backup archive download failed \u2014 the storage cap could not serve the archive", {
417246
+ meta
417247
+ });
417248
+ return;
417249
+ }
417250
+ }
417251
+ }
417252
+ });
417253
+
416023
417254
  // ../../server/backend/dist/auth/session-cookie.js
416024
417255
  var require_session_cookie = __commonJS({
416025
417256
  "../../server/backend/dist/auth/session-cookie.js"(exports) {
@@ -422314,166 +423545,6 @@ var require_core_cap_bridge = __commonJS({
422314
423545
  }
422315
423546
  });
422316
423547
 
422317
- // ../../server/backend/dist/api/trpc/client-ip.js
422318
- var require_client_ip = __commonJS({
422319
- "../../server/backend/dist/api/trpc/client-ip.js"(exports) {
422320
- "use strict";
422321
- Object.defineProperty(exports, "__esModule", { value: true });
422322
- exports.extractClientIp = extractClientIp;
422323
- exports.extractCfConnectingIp = extractCfConnectingIp;
422324
- exports.extractPeerIp = extractPeerIp;
422325
- exports.extractUserAgent = extractUserAgent;
422326
- exports.ipClass = ipClass;
422327
- exports.classifyClient = classifyClient;
422328
- exports.classifyClientRequest = classifyClientRequest;
422329
- exports.deriveRelayOnly = deriveRelayOnly;
422330
- exports.isRemoteClientIp = isRemoteClientIp;
422331
- function extractClientIp(req) {
422332
- if (!req)
422333
- return null;
422334
- const xff = req.headers["x-forwarded-for"];
422335
- const xffValue = Array.isArray(xff) ? xff[0] : xff;
422336
- if (typeof xffValue === "string" && xffValue.length > 0) {
422337
- const first = xffValue.split(",")[0]?.trim();
422338
- if (first)
422339
- return normalizeIp(first);
422340
- }
422341
- if ("ip" in req && typeof req.ip === "string" && req.ip.length > 0) {
422342
- return normalizeIp(req.ip);
422343
- }
422344
- const remote = req.socket?.remoteAddress;
422345
- if (typeof remote === "string" && remote.length > 0) {
422346
- return normalizeIp(remote);
422347
- }
422348
- return null;
422349
- }
422350
- function extractCfConnectingIp(req) {
422351
- if (!req)
422352
- return null;
422353
- const raw = req.headers["cf-connecting-ip"];
422354
- const value = Array.isArray(raw) ? raw[0] : raw;
422355
- if (typeof value === "string" && value.length > 0)
422356
- return normalizeIp(value.trim());
422357
- return null;
422358
- }
422359
- function extractPeerIp(req) {
422360
- if (!req)
422361
- return null;
422362
- const remote = req.socket?.remoteAddress;
422363
- if (typeof remote === "string" && remote.length > 0)
422364
- return normalizeIp(remote);
422365
- return null;
422366
- }
422367
- function extractUserAgent(req) {
422368
- if (!req)
422369
- return null;
422370
- const ua = req.headers["user-agent"];
422371
- const value = Array.isArray(ua) ? ua[0] : ua;
422372
- if (typeof value === "string" && value.length > 0)
422373
- return value;
422374
- return null;
422375
- }
422376
- function normalizeIp(ip) {
422377
- let out = ip.trim();
422378
- if (out.startsWith("::ffff:"))
422379
- out = out.slice("::ffff:".length);
422380
- const pct = out.indexOf("%");
422381
- if (pct !== -1)
422382
- out = out.slice(0, pct);
422383
- return out;
422384
- }
422385
- function ipClass(ip) {
422386
- if (!ip)
422387
- return "lan";
422388
- if (ip.includes(":")) {
422389
- if (isTailscaleIpv6(ip))
422390
- return "vpn";
422391
- if (isPrivateIpv6(ip))
422392
- return "lan";
422393
- return "remote";
422394
- }
422395
- if (isIpv4(ip)) {
422396
- if (isTailscaleIpv4(ip))
422397
- return "vpn";
422398
- if (isPrivateIpv4(ip))
422399
- return "lan";
422400
- return "remote";
422401
- }
422402
- return "lan";
422403
- }
422404
- function classifyClient(args) {
422405
- if (args.peerIsLocal && args.cfConnectingIp)
422406
- return ipClass(args.cfConnectingIp);
422407
- return ipClass(args.clientIp);
422408
- }
422409
- function classifyClientRequest(req) {
422410
- if (!req)
422411
- return null;
422412
- const clientIp = extractClientIp(req);
422413
- const cfConnectingIp = extractCfConnectingIp(req);
422414
- const peerIp = extractPeerIp(req);
422415
- const peerIsLocal = peerIp !== null && ipClass(peerIp) !== "remote";
422416
- return classifyClient({ clientIp, cfConnectingIp, peerIsLocal });
422417
- }
422418
- function deriveRelayOnly(clientClass) {
422419
- return clientClass === "remote";
422420
- }
422421
- function isRemoteClientIp(ip) {
422422
- return ipClass(ip) === "remote";
422423
- }
422424
- function isIpv4(ip) {
422425
- const parts = ip.split(".");
422426
- if (parts.length !== 4)
422427
- return false;
422428
- return parts.every((p) => {
422429
- if (!/^\d{1,3}$/.test(p))
422430
- return false;
422431
- const n = Number.parseInt(p, 10);
422432
- return n >= 0 && n <= 255;
422433
- });
422434
- }
422435
- function isTailscaleIpv4(ip) {
422436
- const parts = ip.split(".").map((p) => Number.parseInt(p, 10));
422437
- const [a, b] = parts;
422438
- if (a === void 0 || b === void 0)
422439
- return false;
422440
- return a === 100 && b >= 64 && b <= 127;
422441
- }
422442
- function isPrivateIpv4(ip) {
422443
- const parts = ip.split(".").map((p) => Number.parseInt(p, 10));
422444
- const [a, b] = parts;
422445
- if (a === void 0 || b === void 0)
422446
- return false;
422447
- if (a === 10)
422448
- return true;
422449
- if (a === 127)
422450
- return true;
422451
- if (a === 172 && b >= 16 && b <= 31)
422452
- return true;
422453
- if (a === 192 && b === 168)
422454
- return true;
422455
- if (a === 169 && b === 254)
422456
- return true;
422457
- return false;
422458
- }
422459
- function isTailscaleIpv6(ip) {
422460
- return ip.toLowerCase().startsWith("fd7a:115c:a1e0:");
422461
- }
422462
- function isPrivateIpv6(ip) {
422463
- const lower = ip.toLowerCase();
422464
- if (lower === "::1")
422465
- return true;
422466
- if (lower === "::")
422467
- return true;
422468
- if (lower.startsWith("fe80"))
422469
- return true;
422470
- if (lower.startsWith("fc") || lower.startsWith("fd"))
422471
- return true;
422472
- return false;
422473
- }
422474
- }
422475
- });
422476
-
422477
423548
  // ../../server/backend/dist/api/trpc/http-request-census-hook.js
422478
423549
  var require_http_request_census_hook = __commonJS({
422479
423550
  "../../server/backend/dist/api/trpc/http-request-census-hook.js"(exports) {
@@ -433254,6 +434325,7 @@ var require_main4 = __commonJS({
433254
434325
  var ws_2 = require_ws();
433255
434326
  var addon_upload_1 = require_addon_upload();
433256
434327
  var auth_whoami_1 = require_auth_whoami();
434328
+ var backup_download_js_1 = require_backup_download();
433257
434329
  var health_routes_1 = require_health_routes();
433258
434330
  var adaptive_probe_routes_1 = require_adaptive_probe_routes();
433259
434331
  var model_distributor_js_1 = require_model_distributor();
@@ -433401,6 +434473,12 @@ var require_main4 = __commonJS({
433401
434473
  socketPlane: (0, system_1.createSocketPlaneReader)({
433402
434474
  registry: () => moleculerForEventPlane?.childRegistry ?? null
433403
434475
  }),
434476
+ // The write queue to every peer NODE, from Moleculer's own writer
434477
+ // sockets. Those are unref'd (`TcpWriter.connect`), so the 2026-09-10
434478
+ // exclusion of "every socket queue" — a sum over `_getActiveHandles()` —
434479
+ // never saw them. With the UDS queues above, every outbound plane this
434480
+ // process writes to is now on the line and judged on every probe (D446).
434481
+ meshQueue: (0, system_1.createMeshQueueReader)(() => moleculerForEventPlane?.broker ?? null),
433404
434482
  // The ArrayBuffer census, armed by the probe itself. Twice on 2026-09-10
433405
434483
  // this process's `arrayBuffers` climbed linearly for an hour (to 1.3 GB
433406
434484
  // and to 5 GB, both LIVE across a forced compaction) and released in one
@@ -433716,70 +434794,10 @@ var require_main4 = __commonJS({
433716
434794
  });
433717
434795
  }
433718
434796
  });
433719
- fastify.get("/api/backup/download/:locationId/:archiveId", async (request, reply) => {
433720
- const authHeader = request.headers.authorization;
433721
- if (!authHeader) {
433722
- return reply.status(401).send({ error: "Unauthorized" });
433723
- }
433724
- try {
433725
- const token2 = authHeader.replace("Bearer ", "");
433726
- const downloadAuth = app.get(auth_service_1.AuthService);
433727
- const payload = downloadAuth.verifyToken(token2);
433728
- if (!payload.isAdmin) {
433729
- return reply.status(403).send({ error: "Admin required" });
433730
- }
433731
- } catch {
433732
- return reply.status(401).send({ error: "Invalid token" });
433733
- }
433734
- const { locationId, archiveId } = request.params;
433735
- const backupSingleton = capabilityRegistry.getSingleton("backup");
433736
- if (!backupSingleton?.listArchives) {
433737
- return reply.status(503).send({ error: "Backup orchestrator unavailable" });
433738
- }
433739
- const archives = await backupSingleton.listArchives({ destinationId: locationId });
433740
- const archive = archives.find((a) => a.id === archiveId);
433741
- if (!archive) {
433742
- return reply.status(404).send({ error: "Archive not found" });
433743
- }
433744
- const storage = capabilityRegistry.getSingleton("storage");
433745
- if (!storage?.beginDownload) {
433746
- return reply.status(503).send({ error: "Storage cap unavailable" });
433747
- }
433748
- const downloadName = `${archive.label ?? archive.id}.tar.gz`;
433749
- const safeName = downloadName.replace(/[\r\n"]/g, "_");
433750
- reply.header("content-type", "application/gzip");
433751
- reply.header("content-length", String(archive.sizeBytes));
433752
- reply.header("content-disposition", `attachment; filename="${safeName}"`);
433753
- const { downloadId, sizeBytes } = await storage.beginDownload({
433754
- location: locationId,
433755
- relativePath: archive.filename
433756
- });
433757
- const CHUNK = 8 * 1024 * 1024;
433758
- try {
433759
- let offset = 0;
433760
- while (offset < sizeBytes) {
433761
- const len = Math.min(CHUNK, sizeBytes - offset);
433762
- const chunk = await storage.readChunk({ downloadId, offset, length: len });
433763
- if (chunk.byteLength === 0) {
433764
- throw new Error(`backup download: empty chunk at offset ${offset}/${sizeBytes}`);
433765
- }
433766
- reply.raw.write(chunk);
433767
- offset += chunk.byteLength;
433768
- }
433769
- reply.raw.end();
433770
- } catch (err) {
433771
- console.error("[backup-download] stream failed:", err);
433772
- if (!reply.raw.headersSent) {
433773
- return reply.status(500).send({ error: "Download failed" });
433774
- }
433775
- reply.raw.destroy(err instanceof Error ? err : new Error(String(err)));
433776
- } finally {
433777
- try {
433778
- await storage.endDownload({ downloadId });
433779
- } catch {
433780
- }
433781
- }
433782
- return reply;
434797
+ (0, backup_download_js_1.registerBackupDownloadRoute)(fastify, {
434798
+ verifier: app.get(auth_service_1.AuthService),
434799
+ capabilities: capabilityRegistry,
434800
+ logger: app.get(logging_service_1.LoggingService).createLogger("backup-download")
433783
434801
  });
433784
434802
  fastify.post("/api/auth/session", async (request, reply) => {
433785
434803
  const token2 = request.body?.token;