robot-resources 1.9.7 → 1.10.3

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/README.md CHANGED
@@ -57,7 +57,6 @@ Available as MCP tool after install:
57
57
  ## MCP Servers
58
58
 
59
59
  ```bash
60
- npx -y @robot-resources/router-mcp # Router stats + config
61
60
  npx -y @robot-resources/scraper-mcp # Scraper compression
62
61
  ```
63
62
 
package/lib/detect.js CHANGED
@@ -1,46 +1,8 @@
1
- import { execSync, execFileSync } from 'node:child_process';
2
1
  import { existsSync, readFileSync } from 'node:fs';
3
2
  import { homedir } from 'node:os';
4
3
  import { join } from 'node:path';
5
4
  import { stripJson5 } from './json5.js';
6
5
 
7
- // Re-export findPython from the shared cli-core implementation.
8
- export { findPython } from '@robot-resources/cli-core/python-bridge.mjs';
9
-
10
- import { getVenvPython, MANAGED_VENV_DIR } from '@robot-resources/cli-core/python-bridge.mjs';
11
-
12
- /**
13
- * Check if the router venv exists and has the package installed.
14
- * Returns { venvDir, venvPython } or null.
15
- */
16
- export function checkRouterVenv() {
17
- const venvPython = getVenvPython();
18
-
19
- if (!existsSync(venvPython)) return null;
20
-
21
- try {
22
- execSync(`"${venvPython}" -c "import robot_resources" 2>&1`, { encoding: 'utf-8' });
23
- return { venvDir: MANAGED_VENV_DIR, venvPython };
24
- } catch {
25
- return null;
26
- }
27
- }
28
-
29
- /**
30
- * Check if port 3838 is available.
31
- */
32
- export function isPortAvailable(port = 3838) {
33
- if (typeof port !== 'number' || !Number.isInteger(port) || port < 1 || port > 65535) {
34
- throw new Error('Invalid port number');
35
- }
36
- try {
37
- execFileSync('lsof', ['-i', `:${port}`, '-t'], { encoding: 'utf-8', stdio: 'pipe' });
38
- return false; // port is in use
39
- } catch {
40
- return true; // port is available (lsof returned non-zero = no process)
41
- }
42
- }
43
-
44
6
  /**
45
7
  * Check if OpenClaw is installed.
46
8
  */
@@ -154,18 +116,3 @@ export function isClaudeCodeInstalled() {
154
116
  export function isCursorInstalled() {
155
117
  return existsSync(join(homedir(), '.cursor'));
156
118
  }
157
-
158
- /**
159
- * Check if the router service is already registered.
160
- */
161
- export function isServiceRegistered() {
162
- if (process.platform === 'darwin') {
163
- const plistPath = join(homedir(), 'Library', 'LaunchAgents', 'ai.robotresources.router.plist');
164
- return existsSync(plistPath);
165
- }
166
- if (process.platform === 'linux') {
167
- const unitPath = join(homedir(), '.config', 'systemd', 'user', 'robot-resources-router.service');
168
- return existsSync(unitPath);
169
- }
170
- return false;
171
- }
@@ -12,7 +12,7 @@ const PROBE_TIMEOUT_MS = 5_000;
12
12
  * 1. Router — GET http://127.0.0.1:3838/health
13
13
  * 2. Scraper — check openclaw.json for scraper MCP registration
14
14
  * 3. Platform — GET {platformUrl}/v1/health with api_key
15
- * 4. MCP — check openclaw.json for openclaw-plugin registration
15
+ * 4. MCP — check openclaw.json for robot-resources-router registration
16
16
  *
17
17
  * @returns {{ status: 'healthy'|'partial'|'failed', components: Object, summary: string }}
18
18
  */
@@ -113,10 +113,10 @@ function probeMcp() {
113
113
  try {
114
114
  const ocPath = join(homedir(), '.openclaw', 'openclaw.json');
115
115
  const ocConfig = JSON.parse(readFileSync(ocPath, 'utf-8'));
116
- const hasPlugin = !!ocConfig?.plugins?.entries?.['openclaw-plugin']?.enabled;
116
+ const hasPlugin = !!ocConfig?.plugins?.entries?.['robot-resources-router']?.enabled;
117
117
  return {
118
118
  healthy: hasPlugin,
119
- detail: hasPlugin ? 'plugin registered' : 'openclaw-plugin not registered',
119
+ detail: hasPlugin ? 'plugin registered' : 'robot-resources-router not registered',
120
120
  };
121
121
  } catch {
122
122
  return { healthy: false, detail: 'openclaw.json not found' };
@@ -28,7 +28,7 @@ function readOrCreateOpenClawConfig() {
28
28
  /**
29
29
  * Trust the Robot Resources plugin in OpenClaw config.
30
30
  *
31
- * Adds "openclaw-plugin" to plugins.allow so OpenClaw loads it without
31
+ * Adds "robot-resources-router" to plugins.allow so OpenClaw loads it without
32
32
  * provenance warnings. The plugin's before_model_resolve hook intercepts
33
33
  * ALL LLM calls regardless of the default model — no need to change the
34
34
  * default model (which causes LiveSessionModelSwitchError in OC).
@@ -44,11 +44,11 @@ function trustPlugin() {
44
44
  if (!config.plugins) config.plugins = {};
45
45
  if (!Array.isArray(config.plugins.allow)) config.plugins.allow = [];
46
46
 
47
- if (config.plugins.allow.includes('openclaw-plugin')) {
47
+ if (config.plugins.allow.includes('robot-resources-router')) {
48
48
  return false;
49
49
  }
50
50
 
51
- config.plugins.allow.push('openclaw-plugin');
51
+ config.plugins.allow.push('robot-resources-router');
52
52
 
53
53
  writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
54
54
  return true;
@@ -94,22 +94,23 @@ function registerScraperMcp() {
94
94
  }
95
95
 
96
96
  /**
97
- * Copy the bundled plugin files to ~/.openclaw/extensions/openclaw-plugin/.
97
+ * Copy the bundled plugin files to ~/.openclaw/extensions/robot-resources-router/.
98
98
  *
99
- * The plugin ships as a CLI dependency (@robot-resources/openclaw-plugin).
99
+ * The plugin ships as a CLI dependency (@robot-resources/router — the
100
+ * router IS the OC plugin in the in-process architecture).
100
101
  * Instead of spawning `openclaw plugins install` (30s npm overhead),
101
102
  * we copy files directly. Same destination, same result.
102
103
  *
103
- * Since 0.5.5, the plugin is a thin shim (index.js) that imports the rest
104
+ * The plugin is a thin shim (index.js) that imports the rest
104
105
  * of its code from ./lib/*.js — copy the lib/ directory too, or the shim
105
106
  * fails to load with MODULE_NOT_FOUND.
106
107
  */
107
108
  function installPluginFiles() {
108
109
  const require = createRequire(import.meta.url);
109
- const pluginPkgPath = require.resolve('@robot-resources/openclaw-plugin/package.json');
110
+ const pluginPkgPath = require.resolve('@robot-resources/router/package.json');
110
111
  const pluginDir = dirname(pluginPkgPath);
111
112
 
112
- const targetDir = join(homedir(), '.openclaw', 'extensions', 'openclaw-plugin');
113
+ const targetDir = join(homedir(), '.openclaw', 'extensions', 'robot-resources-router');
113
114
  mkdirSync(targetDir, { recursive: true });
114
115
 
115
116
  for (const file of ['index.js', 'openclaw.plugin.json', 'package.json']) {
@@ -128,7 +129,7 @@ function installPluginFiles() {
128
129
 
129
130
  /**
130
131
  * Register the plugin in openclaw.json so OC loads it on gateway start.
131
- * Adds plugins.entries.openclaw-plugin = { enabled: true }.
132
+ * Adds plugins.entries.robot-resources-router = { enabled: true }.
132
133
  */
133
134
  function registerPluginEntry() {
134
135
  const configPath = join(homedir(), '.openclaw', 'openclaw.json');
@@ -140,9 +141,9 @@ function registerPluginEntry() {
140
141
  if (!config.plugins.entries) config.plugins.entries = {};
141
142
 
142
143
  // Already registered
143
- if (config.plugins.entries['openclaw-plugin']) return;
144
+ if (config.plugins.entries['robot-resources-router']) return;
144
145
 
145
- config.plugins.entries['openclaw-plugin'] = { enabled: true };
146
+ config.plugins.entries['robot-resources-router'] = { enabled: true };
146
147
 
147
148
  writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
148
149
  } catch {
@@ -153,7 +154,7 @@ function registerPluginEntry() {
153
154
  /**
154
155
  * Configure OpenClaw to route through Robot Resources Router.
155
156
  *
156
- * Copies the bundled @robot-resources/openclaw-plugin files into
157
+ * Copies the bundled @robot-resources/router files into
157
158
  * ~/.openclaw/extensions/. The plugin uses before_model_resolve to
158
159
  * override the provider — survives gateway restarts because it
159
160
  * lives in ~/.openclaw/extensions/, not in openclaw.json.
@@ -196,7 +197,7 @@ function configureOpenClaw() {
196
197
  // Plugin file copy failed — fall back to instructions
197
198
  const instructions = [
198
199
  'Could not auto-install plugin. Install manually:',
199
- ' openclaw plugins install @robot-resources/openclaw-plugin',
200
+ ' openclaw plugins install @robot-resources/router',
200
201
  ];
201
202
 
202
203
  if (authMode === 'subscription') {