@remcp/runtime 0.2.195 → 0.2.196

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remcp/runtime",
3
- "version": "0.2.195",
3
+ "version": "0.2.196",
4
4
  "description": "First-party ReMCP local device runtime: filesystem, terminal, computer-use, browser, diagnostics and document tools over MCP.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,27 @@
1
+ // Read-only macOS kernel telemetry. These readings are not physical RAM occupancy.
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+
5
+ const exec = promisify(execFile);
6
+ const options = { timeout: 1200, maxBuffer: 4096, windowsHide: true };
7
+ const command = (file, args) => exec(file, args, options).then(({ stdout }) => stdout).catch(() => '');
8
+
9
+ export function parseDarwinMemoryPressure(output, levelOutput) {
10
+ const match = /^System-wide memory free percentage:\s*(\d{1,3})%\s*$/m.exec(String(output).slice(0, 4096));
11
+ const free = match ? Number(match[1]) : NaN;
12
+ const level = /^\s*([124])\s*$/.exec(String(levelOutput).slice(0, 32))?.[1];
13
+ return {
14
+ effectiveFreeRatio: Number.isInteger(free) && free >= 0 && free <= 100 ? free / 100 : null,
15
+ effectiveFreeMethod: Number.isInteger(free) && free >= 0 && free <= 100 ? 'darwin-memory_pressure-Q' : null,
16
+ pressureLevel: ({ '1': 'normal', '2': 'warning', '4': 'critical' })[level] ?? null,
17
+ pressureMethod: level ? 'darwin-kernel-sysctl' : null,
18
+ };
19
+ }
20
+
21
+ export async function readDarwinMemoryPressure(runner = command) {
22
+ const [free, level] = await Promise.all([
23
+ runner('/usr/bin/memory_pressure', ['-Q']),
24
+ runner('/usr/sbin/sysctl', ['-n', 'kern.memorystatus_vm_pressure_level']),
25
+ ]);
26
+ return parseDarwinMemoryPressure(free, level);
27
+ }
@@ -6,6 +6,7 @@ import { runtimeConfig } from '../config.mjs';
6
6
  import { clampInteger, fail, requireInteger, text } from '../util.mjs';
7
7
  import { cpuUtilizationRatio, cpuFrequencyMHz, cpuPerCoreUtilizationRatios } from './cpu-telemetry.mjs';
8
8
  import { diskVolumes, networkRates, thermalReadings } from './system-telemetry.mjs';
9
+ import { readDarwinMemoryPressure } from './darwin-memory-pressure.mjs';
9
10
 
10
11
  const run = promisify(execFile);
11
12
 
@@ -50,6 +51,7 @@ export async function getSystemInfoTool() {
50
51
  const volumesPromise = diskVolumes();
51
52
  const thermalPromise = thermalReadings();
52
53
  const networkPromise = networkRates();
54
+ const memoryPressurePromise = process.platform === 'darwin' ? readDarwinMemoryPressure() : Promise.resolve(null);
53
55
  const sampledCpus = await new Promise(resolve => setTimeout(() => resolve(os.cpus()), 140));
54
56
  const utilizationRatio = cpuUtilizationRatio(cpus, sampledCpus);
55
57
  const frequencyMHz = cpuFrequencyMHz(sampledCpus);
@@ -74,6 +76,8 @@ export async function getSystemInfoTool() {
74
76
  totalBytes: totalMem,
75
77
  freeBytes: freeMem,
76
78
  usedRatio: totalMem ? Number(((totalMem - freeMem) / totalMem).toFixed(3)) : 0,
79
+ usedMethod: 'os.freemem-physical-occupancy',
80
+ ...(await memoryPressurePromise),
77
81
  },
78
82
  disk: await diskPromise,
79
83
  volumes: await volumesPromise,