robot-resources 1.12.4 → 1.13.0
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/lib/install-node-shim.js +37 -10
- package/lib/install-router-files.js +48 -0
- package/lib/shell-config.js +25 -10
- package/lib/uninstall.js +13 -0
- package/package.json +1 -1
package/lib/install-node-shim.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { writeShellLine, hasShellLine } from './shell-config.js';
|
|
2
2
|
import { readConfig } from './config.mjs';
|
|
3
3
|
import { detectNodeAgent } from './detect.js';
|
|
4
|
+
import { installRouterFiles } from './install-router-files.js';
|
|
4
5
|
|
|
5
6
|
const PLATFORM_URL = process.env.RR_PLATFORM_URL || 'https://api.robotresources.ai';
|
|
6
7
|
|
|
@@ -9,16 +10,20 @@ const PLATFORM_URL = process.env.RR_PLATFORM_URL || 'https://api.robotresources.
|
|
|
9
10
|
* the non-OC Node path.
|
|
10
11
|
*
|
|
11
12
|
* Steps:
|
|
12
|
-
* 1.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* 1. Copy the bundled `@robot-resources/router` files to a stable absolute
|
|
14
|
+
* path under `~/.robot-resources/router/` (mirrors the OC plugin pattern
|
|
15
|
+
* at `~/.openclaw/extensions/`). Phase 8 fix: previously NODE_OPTIONS
|
|
16
|
+
* used the bare module name `@robot-resources/router/auto` which only
|
|
17
|
+
* resolved when the user was cd'd inside a project that had the
|
|
18
|
+
* package in its node_modules. From any other cwd, EVERY `node`
|
|
19
|
+
* command crashed with "Cannot find module".
|
|
20
|
+
* 2. Append the marker block to detected rc files (zsh / bash / fish)
|
|
21
|
+
* with the ABSOLUTE PATH to the copied auto.cjs.
|
|
22
|
+
* 3. Emit `node_shim_installed` telemetry.
|
|
17
23
|
*
|
|
18
24
|
* The user has to start a new shell (or `source` the file) for the
|
|
19
25
|
* NODE_OPTIONS to take effect — we tell them this in the wizard's
|
|
20
|
-
* post-install message.
|
|
21
|
-
* shell; that's a Phase 6 nice-to-have.
|
|
26
|
+
* post-install message.
|
|
22
27
|
*
|
|
23
28
|
* Windows: shell-config.writeShellLine returns no rc files on Windows
|
|
24
29
|
* (we only support POSIX in P3). The wizard prints manual instructions
|
|
@@ -40,8 +45,8 @@ export async function installNodeShim({ cwd = process.cwd(), dryRun = false } =
|
|
|
40
45
|
reason: 'windows_not_supported_yet',
|
|
41
46
|
message:
|
|
42
47
|
'Windows shell-config writing is not yet supported. Set ' +
|
|
43
|
-
'NODE_OPTIONS
|
|
44
|
-
'system environment variables, or wait for Phase 6.',
|
|
48
|
+
'NODE_OPTIONS to point at ~/.robot-resources/router/auto.cjs manually ' +
|
|
49
|
+
'in your system environment variables, or wait for Phase 6.',
|
|
45
50
|
};
|
|
46
51
|
}
|
|
47
52
|
|
|
@@ -58,8 +63,29 @@ export async function installNodeShim({ cwd = process.cwd(), dryRun = false } =
|
|
|
58
63
|
return { ok: true, message: 'Dry-run: would have written NODE_OPTIONS to shell rc.' };
|
|
59
64
|
}
|
|
60
65
|
|
|
66
|
+
// Phase 8: copy router to an absolute path under ~/.robot-resources/router/
|
|
67
|
+
// before we wire the shell config. If the copy fails, we don't write a
|
|
68
|
+
// broken NODE_OPTIONS line.
|
|
69
|
+
let autoPath;
|
|
70
|
+
try {
|
|
71
|
+
autoPath = installRouterFiles();
|
|
72
|
+
} catch (err) {
|
|
73
|
+
await emit({
|
|
74
|
+
shell: 'unknown',
|
|
75
|
+
shell_config_path: null,
|
|
76
|
+
sdks_detected: sdks,
|
|
77
|
+
dry_run: false,
|
|
78
|
+
reason: 'router_copy_failed',
|
|
79
|
+
error_messages: [err.message],
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
message: `Could not copy router files to ~/.robot-resources/router/: ${err.message}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
61
87
|
const alreadyInstalled = hasShellLine();
|
|
62
|
-
const result = writeShellLine();
|
|
88
|
+
const result = writeShellLine({ autoPath });
|
|
63
89
|
|
|
64
90
|
// Single shell value for the funnel even though we may have written to
|
|
65
91
|
// multiple rc files. Pick the dominant one for telemetry.
|
|
@@ -74,6 +100,7 @@ export async function installNodeShim({ cwd = process.cwd(), dryRun = false } =
|
|
|
74
100
|
files_written: result.written.length,
|
|
75
101
|
files_with_errors: result.errors.length,
|
|
76
102
|
error_messages: result.errors.map((e) => `${e.path}: ${e.message}`).slice(0, 3),
|
|
103
|
+
auto_path: autoPath,
|
|
77
104
|
});
|
|
78
105
|
|
|
79
106
|
if (alreadyInstalled && result.written.length === 0) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, copyFileSync, cpSync, rmSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Copy `@robot-resources/router` to ~/.robot-resources/router/ and return
|
|
10
|
+
* the absolute path to its auto.cjs.
|
|
11
|
+
*
|
|
12
|
+
* Phase 8 fix. Mirrors `installPluginFiles()` in tool-config.js (the OC
|
|
13
|
+
* plugin path that's worked since Phase 0). The destination is a stable
|
|
14
|
+
* user-scoped location that survives npm/npx cache cleanups, so the
|
|
15
|
+
* NODE_OPTIONS line we write to shell rc doesn't break when caches expire.
|
|
16
|
+
*
|
|
17
|
+
* Files copied: auto.cjs, index.js, package.json, lib/ (recursive).
|
|
18
|
+
* Each call wipes lib/ first so files removed in newer router versions
|
|
19
|
+
* don't linger from a previous install.
|
|
20
|
+
*
|
|
21
|
+
* Why this is its own module: extracted from install-node-shim.js for
|
|
22
|
+
* testability — vitest can mock the whole module without us mocking
|
|
23
|
+
* node:fs / node:module manually in every install-shim test case.
|
|
24
|
+
*/
|
|
25
|
+
export function installRouterFiles({ home = homedir() } = {}) {
|
|
26
|
+
const pkgPath = require.resolve('@robot-resources/router/package.json');
|
|
27
|
+
const pkgDir = dirname(pkgPath);
|
|
28
|
+
const targetDir = join(home, '.robot-resources', 'router');
|
|
29
|
+
mkdirSync(targetDir, { recursive: true });
|
|
30
|
+
|
|
31
|
+
for (const file of ['auto.cjs', 'index.js', 'package.json']) {
|
|
32
|
+
const src = join(pkgDir, file);
|
|
33
|
+
if (existsSync(src)) {
|
|
34
|
+
copyFileSync(src, join(targetDir, file));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Refresh lib/ — wipe + recopy so we don't accumulate stale files across
|
|
39
|
+
// router upgrades. Same pattern as tool-config.js installPluginFiles().
|
|
40
|
+
const srcLib = join(pkgDir, 'lib');
|
|
41
|
+
const dstLib = join(targetDir, 'lib');
|
|
42
|
+
if (existsSync(srcLib)) {
|
|
43
|
+
rmSync(dstLib, { recursive: true, force: true });
|
|
44
|
+
cpSync(srcLib, dstLib, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return join(targetDir, 'auto.cjs');
|
|
48
|
+
}
|
package/lib/shell-config.js
CHANGED
|
@@ -11,10 +11,19 @@ import { join } from 'node:path';
|
|
|
11
11
|
* regex-matching against the user's actual shell content:
|
|
12
12
|
*
|
|
13
13
|
* # >>> robot-resources: NODE_OPTIONS auto-attach >>>
|
|
14
|
-
* export NODE_OPTIONS="${NODE_OPTIONS:-} --require
|
|
14
|
+
* export NODE_OPTIONS="${NODE_OPTIONS:-} --require /Users/x/.robot-resources/router/auto.cjs"
|
|
15
15
|
* # <<< robot-resources <<<
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Phase 8 fix: NODE_OPTIONS now uses an ABSOLUTE PATH to the auto.cjs the
|
|
18
|
+
* wizard copied to ~/.robot-resources/router/. The previous bare-module
|
|
19
|
+
* form `--require @robot-resources/router/auto` only resolved when the user
|
|
20
|
+
* was cd'd inside a project that had `@robot-resources/router` in its
|
|
21
|
+
* node_modules — and broke EVERY Node command from any other cwd with
|
|
22
|
+
* `Cannot find module`. Result: every wizard-success Node user pre-Phase-8
|
|
23
|
+
* had a NODE_OPTIONS line that crashed `node`/`npm`/etc. Symptom in
|
|
24
|
+
* Supabase: `node_shim_installed: 8` but `adapter_attached: 0`.
|
|
25
|
+
*
|
|
26
|
+
* Behavior decisions (preserved from Phase 3):
|
|
18
27
|
* - If NODE_OPTIONS is already set with a different --require (rare; e.g.
|
|
19
28
|
* dd-trace), append ours after theirs. Both load. The user keeps their
|
|
20
29
|
* existing tooling. The shell expansion `${NODE_OPTIONS:-} ...` handles
|
|
@@ -27,12 +36,14 @@ import { join } from 'node:path';
|
|
|
27
36
|
const MARK_BEGIN = '# >>> robot-resources: NODE_OPTIONS auto-attach >>>';
|
|
28
37
|
const MARK_END = '# <<< robot-resources <<<';
|
|
29
38
|
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
function buildPosixLine(autoPath) {
|
|
40
|
+
return `export NODE_OPTIONS="\${NODE_OPTIONS:-} --require ${autoPath}"`;
|
|
41
|
+
}
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
function buildFishLine(autoPath) {
|
|
44
|
+
// Fish has different syntax (no `export`, uses `set -x`).
|
|
45
|
+
return `set -x NODE_OPTIONS "$NODE_OPTIONS --require ${autoPath}"`;
|
|
46
|
+
}
|
|
36
47
|
|
|
37
48
|
/**
|
|
38
49
|
* Discover which rc files are present for this user. Returns a list of
|
|
@@ -73,7 +84,11 @@ export function hasShellLine(home = homedir()) {
|
|
|
73
84
|
* others on one failure. Per-file errors are returned as warnings the
|
|
74
85
|
* caller can surface.
|
|
75
86
|
*/
|
|
76
|
-
export function writeShellLine(home = homedir()) {
|
|
87
|
+
export function writeShellLine({ autoPath, home = homedir() }) {
|
|
88
|
+
if (!autoPath) {
|
|
89
|
+
throw new Error('writeShellLine requires { autoPath } — absolute path to auto.cjs');
|
|
90
|
+
}
|
|
91
|
+
|
|
77
92
|
const rcs = listShellRcFiles(home);
|
|
78
93
|
const written = [];
|
|
79
94
|
const errors = [];
|
|
@@ -97,7 +112,7 @@ export function writeShellLine(home = homedir()) {
|
|
|
97
112
|
continue;
|
|
98
113
|
}
|
|
99
114
|
|
|
100
|
-
const line = rc.kind === 'fish' ?
|
|
115
|
+
const line = rc.kind === 'fish' ? buildFishLine(autoPath) : buildPosixLine(autoPath);
|
|
101
116
|
const block =
|
|
102
117
|
(text && !text.endsWith('\n') ? '\n' : '') +
|
|
103
118
|
'\n' + MARK_BEGIN + '\n' + line + '\n' + MARK_END + '\n';
|
|
@@ -165,4 +180,4 @@ function getMode(path) {
|
|
|
165
180
|
}
|
|
166
181
|
|
|
167
182
|
// Exported for tests + telemetry payloads.
|
|
168
|
-
export { MARK_BEGIN, MARK_END,
|
|
183
|
+
export { MARK_BEGIN, MARK_END, buildPosixLine, buildFishLine };
|
package/lib/uninstall.js
CHANGED
|
@@ -100,6 +100,19 @@ export function runUninstall({ purge = false } = {}) {
|
|
|
100
100
|
errors.push({ component: 'shell_config_node_options', message: err.message });
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
// 3b. Copied router dir at ~/.robot-resources/router/ (Phase 8). The shell
|
|
104
|
+
// line points at this absolute path — once the line is gone, the
|
|
105
|
+
// copied files are dead weight. Remove them.
|
|
106
|
+
const routerDir = join(homedir(), '.robot-resources', 'router');
|
|
107
|
+
if (existsSync(routerDir)) {
|
|
108
|
+
try {
|
|
109
|
+
rmSync(routerDir, { recursive: true, force: true });
|
|
110
|
+
components_removed.push('node_shim_router_dir');
|
|
111
|
+
} catch (err) {
|
|
112
|
+
errors.push({ component: 'node_shim_router_dir', message: err.message });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
103
116
|
// 4. Python shim — `pip uninstall -y robot-resources` against the resolved
|
|
104
117
|
// venv. Skip silently if no venv detected (the user may have installed
|
|
105
118
|
// via the wizard but already deleted the venv themselves).
|