@remcp/remcp 0.2.198 → 0.2.200

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/remcp",
3
- "version": "0.2.198",
3
+ "version": "0.2.200",
4
4
  "description": "ReMCP device client: pair a computer with ReMCP and run the outbound-only agent that hosts the local MCP runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "README.md"
19
19
  ],
20
20
  "scripts": {
21
- "check": "node --check bin/remcp.mjs && node --check src/agent-deploy-reconnect.mjs && node --check src/agent-network-probe-client.mjs && node --check src/agent-relay-connection.mjs && node --check src/agent-responder.mjs && node --check src/agent-runtime-capabilities.mjs && node --check src/agent-update-monitor.mjs && node --check src/agent-update.mjs && node --check src/agent-utilities.mjs && node --check src/agent.mjs && node --check src/cli.mjs && node --check src/cli/config.mjs && node --check src/cli/connect.mjs && node --check src/cli/doctor.mjs && node --check src/cli/env.mjs && node --check src/cli/npm-global.mjs && node --check src/cli/pairing-qr.mjs && node --check src/cli/service-inventory.mjs && node --check src/cli/service-macos.mjs && node --check src/cli/service-paths.mjs && node --check src/cli/service.mjs && node --check src/cli/shell.mjs && node --check src/cli/update.mjs && node --check src/cli/windows-supervisor.mjs && node --check src/fetch-update-manifest.mjs && node --check src/fs-access.mjs && node --check src/npm.mjs && node --check src/runtime.mjs && node --check src/version.mjs",
21
+ "check": "node --check bin/remcp.mjs && node --check src/agent-deploy-reconnect.mjs && node --check src/agent-network-probe-client.mjs && node --check src/agent-relay-connection.mjs && node --check src/agent-responder.mjs && node --check src/agent-runtime-capabilities.mjs && node --check src/agent-update-monitor.mjs && node --check src/agent-update.mjs && node --check src/agent-utilities.mjs && node --check src/agent.mjs && node --check src/cli.mjs && node --check src/cli/config.mjs && node --check src/cli/connect.mjs && node --check src/cli/doctor.mjs && node --check src/cli/env.mjs && node --check src/cli/mac-native-temperature.mjs && node --check src/cli/npm-global.mjs && node --check src/cli/pairing-qr.mjs && node --check src/cli/service-inventory.mjs && node --check src/cli/service-macos.mjs && node --check src/cli/service-paths.mjs && node --check src/cli/service.mjs && node --check src/cli/shell.mjs && node --check src/cli/update.mjs && node --check src/cli/windows-supervisor.mjs && node --check src/fetch-update-manifest.mjs && node --check src/fs-access.mjs && node --check src/npm.mjs && node --check src/runtime.mjs && node --check src/version.mjs",
22
22
  "test": "node --test test/*.test.mjs"
23
23
  },
24
24
  "dependencies": {
@@ -0,0 +1,67 @@
1
+ // The global ReMCP installer deliberately disables npm lifecycle scripts.
2
+ // Opt in only the reviewed, version-pinned Apple Silicon temperature addon,
3
+ // after verifying its installed manifest and on-disk path. No sudo or shell.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+
7
+ const SENSOR_NAME = 'macos-temperature-sensor';
8
+ const SENSOR_VERSION = '2.1.1';
9
+ const SCRIPT = 'node-gyp rebuild';
10
+ const BINARY = path.join('build', 'Release', 'mac_temp_native.node');
11
+
12
+ function checkedManifest(file) {
13
+ const stats = fs.lstatSync(file);
14
+ if (!stats.isFile() || stats.size > 16384) throw new Error('invalid manifest');
15
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
16
+ }
17
+
18
+ function checkedDirectory(directory) {
19
+ const stats = fs.lstatSync(directory);
20
+ if (!stats.isDirectory() || stats.isSymbolicLink()) throw new Error('unsafe addon directory');
21
+ }
22
+
23
+ export function buildVettedMacTemperatureAddon({ runtimeRoot, resolved, runCommand, warn = console.error }) {
24
+ try {
25
+ checkedDirectory(runtimeRoot);
26
+ const runtime = checkedManifest(path.join(runtimeRoot, 'package.json'));
27
+ if (runtime.name !== '@remcp/runtime' ||
28
+ runtime.optionalDependencies?.[SENSOR_NAME] !== SENSOR_VERSION) return false;
29
+
30
+ const modules = path.join(runtimeRoot, 'node_modules');
31
+ const addonRoot = path.join(modules, SENSOR_NAME);
32
+ // The native module is optional; if npm omitted it, report unknown rather
33
+ // than reinstalling or executing a different dependency.
34
+ if (!fs.existsSync(addonRoot)) return false;
35
+ checkedDirectory(modules);
36
+ checkedDirectory(addonRoot);
37
+ const canonicalRoot = fs.realpathSync(runtimeRoot);
38
+ const canonicalAddon = fs.realpathSync(addonRoot);
39
+ if (!canonicalAddon.startsWith(canonicalRoot + path.sep)) throw new Error('addon escaped runtime');
40
+ const addon = checkedManifest(path.join(addonRoot, 'package.json'));
41
+ if (addon.name !== SENSOR_NAME || addon.version !== SENSOR_VERSION ||
42
+ addon.scripts?.install !== SCRIPT) throw new Error('unreviewed native addon');
43
+
44
+ const nativeBinary = path.join(addonRoot, BINARY);
45
+ for (const folder of [path.join(addonRoot, 'build'), path.join(addonRoot, 'build', 'Release')]) {
46
+ if (fs.existsSync(folder)) checkedDirectory(folder);
47
+ }
48
+ if (fs.existsSync(nativeBinary)) {
49
+ if (!fs.lstatSync(nativeBinary).isFile()) throw new Error('invalid native module');
50
+ return true;
51
+ }
52
+ // Execute precisely this verified package's known node-gyp script. Do not
53
+ // re-enable arbitrary transitive lifecycle scripts in global npm install.
54
+ runCommand(resolved.command, [
55
+ ...resolved.args, '--prefix', addonRoot, 'run', 'install',
56
+ '--foreground-scripts', '--ignore-scripts=false', '--no-audit', '--no-fund',
57
+ ], { timeout:90_000 });
58
+ if (!fs.existsSync(nativeBinary) || !fs.lstatSync(nativeBinary).isFile())
59
+ throw new Error('native build did not create its module');
60
+ return true;
61
+ } catch {
62
+ // The sensor is optional; do not roll back working ReMCP access because
63
+ // a Mac lacks Xcode Command Line Tools. Never leak npm command stderr.
64
+ warn('ReMCP: optional macOS temperature sensor unavailable; other tools remain functional.');
65
+ return false;
66
+ }
67
+ }
@@ -4,6 +4,7 @@ import process from 'node:process';
4
4
  import { resolveNpm } from '../npm.mjs';
5
5
  import { PACKAGE_NAME } from '../version.mjs';
6
6
  import { home, npm } from './env.mjs';
7
+ import { buildVettedMacTemperatureAddon } from './mac-native-temperature.mjs';
7
8
  import { output, run } from './shell.mjs';
8
9
 
9
10
  export function servicePlatform() {
@@ -34,6 +35,16 @@ function npmGlobalInstallArgs(specs, { preferOnline = false } = {}) {
34
35
 
35
36
  export function npmGlobalInstall(...specs) {
36
37
  run(npm.command, [...npm.args, ...npmGlobalInstallArgs(specs)]);
38
+ if (servicePlatform() === 'darwin' && specs.some(spec => /^@remcp\/runtime@[0-9]/.test(spec))) {
39
+ try {
40
+ buildVettedMacTemperatureAddon({
41
+ runtimeRoot:globalPackagePath(globalPrefix(), '@remcp/runtime'), resolved:npm, runCommand:run,
42
+ });
43
+ } catch {
44
+ // Native temperature is optional; a second prefix lookup cannot undo a successful CLI install.
45
+ console.error('ReMCP: optional macOS temperature sensor unavailable; other tools remain functional.');
46
+ }
47
+ }
37
48
  }
38
49
 
39
50
  function pathEntryExists(file) {
@@ -110,6 +121,9 @@ function transactionalMacGlobalInstall({ resolved, prefix, packageNames, specs,
110
121
  if (uniqueNames.includes(PACKAGE_NAME)) moveAside(path.join(prefix, 'bin', 'remcp'), 'bin-remcp');
111
122
 
112
123
  run(resolved.command, [...resolved.args, ...npmGlobalInstallArgs(specs, { preferOnline })]);
124
+ if (uniqueNames.includes('@remcp/runtime')) buildVettedMacTemperatureAddon({
125
+ runtimeRoot:globalPackagePath(prefix, '@remcp/runtime'), resolved, runCommand:run,
126
+ });
113
127
  } catch (error) {
114
128
  restore(error);
115
129
  throw error;