openclawsetup 2.4.4 → 2.4.6
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/bin/cli.mjs +63 -14
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -148,16 +148,41 @@ function checkNodeVersion() {
|
|
|
148
148
|
|
|
149
149
|
function needsSudo() {
|
|
150
150
|
const os = platform();
|
|
151
|
-
if (os === 'win32'
|
|
151
|
+
if (os === 'win32') return false;
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
// 获取 npm 全局安装目录并检查写权限
|
|
154
|
+
const npmPrefixResult = safeExec('npm prefix -g');
|
|
155
|
+
if (npmPrefixResult.ok && npmPrefixResult.output) {
|
|
156
|
+
const globalDir = join(npmPrefixResult.output.trim(), 'lib', 'node_modules');
|
|
157
|
+
try {
|
|
158
|
+
if (existsSync(globalDir)) {
|
|
159
|
+
accessSync(globalDir, fsConstants.W_OK);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
// 目录不存在,检查父目录
|
|
163
|
+
const parentDir = npmPrefixResult.output.trim();
|
|
164
|
+
if (existsSync(parentDir)) {
|
|
165
|
+
accessSync(parentDir, fsConstants.W_OK);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
} catch {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 回退检查
|
|
174
|
+
const testDirs = os === 'darwin'
|
|
175
|
+
? ['/usr/local/lib/node_modules', '/opt/homebrew/lib/node_modules']
|
|
176
|
+
: ['/usr/lib/node_modules'];
|
|
177
|
+
for (const testDir of testDirs) {
|
|
178
|
+
try {
|
|
179
|
+
if (existsSync(testDir)) {
|
|
180
|
+
accessSync(testDir, fsConstants.W_OK);
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
} catch {
|
|
184
|
+
return true;
|
|
158
185
|
}
|
|
159
|
-
} catch {
|
|
160
|
-
return true;
|
|
161
186
|
}
|
|
162
187
|
return true;
|
|
163
188
|
}
|
|
@@ -200,9 +225,9 @@ function getConfigInfo() {
|
|
|
200
225
|
try {
|
|
201
226
|
const raw = readFileSync(configPath, 'utf8');
|
|
202
227
|
const json = JSON.parse(raw);
|
|
203
|
-
const token = json.token || json.gatewayToken || '';
|
|
204
|
-
const port = Number(json.port || json.gatewayPort || 18789);
|
|
205
|
-
const bind = json.bind || json.gatewayBind || '';
|
|
228
|
+
const token = json.gateway?.auth?.token || json.token || json.gatewayToken || '';
|
|
229
|
+
const port = Number(json.gateway?.port || json.port || json.gatewayPort || 18789);
|
|
230
|
+
const bind = json.gateway?.bind || json.bind || json.gatewayBind || '';
|
|
206
231
|
return { configDir: cfg.dir, configPath, token, port, bind, raw };
|
|
207
232
|
} catch {
|
|
208
233
|
try {
|
|
@@ -227,7 +252,17 @@ function getConfigInfo() {
|
|
|
227
252
|
}
|
|
228
253
|
|
|
229
254
|
function detectVps() {
|
|
230
|
-
|
|
255
|
+
if (platform() !== 'linux') return false;
|
|
256
|
+
// Cloud provider markers
|
|
257
|
+
if (existsSync('/etc/cloud') || existsSync('/var/lib/cloud') || existsSync('/sys/hypervisor')) return true;
|
|
258
|
+
// SSH session = remote server
|
|
259
|
+
if (process.env.SSH_CLIENT || process.env.SSH_TTY || process.env.SSH_CONNECTION) return true;
|
|
260
|
+
// systemd-detect-virt
|
|
261
|
+
const virt = safeExec('systemd-detect-virt 2>/dev/null');
|
|
262
|
+
if (virt.ok && virt.output.trim() && virt.output.trim() !== 'none') return true;
|
|
263
|
+
// Headless Linux (no display) likely a server
|
|
264
|
+
if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) return true;
|
|
265
|
+
return false;
|
|
231
266
|
}
|
|
232
267
|
|
|
233
268
|
function getServerIp() {
|
|
@@ -387,7 +422,8 @@ async function installOpenClaw() {
|
|
|
387
422
|
console.log(colors.bold(colors.cyan('\n[1/2] 安装 OpenClaw CLI\n')));
|
|
388
423
|
|
|
389
424
|
if (useSudo) {
|
|
390
|
-
|
|
425
|
+
const osName = platform() === 'darwin' ? 'macOS' : 'Linux';
|
|
426
|
+
log.hint(`${osName} 系统需要 sudo 权限安装全局包`);
|
|
391
427
|
console.log(colors.yellow('\n请运行以下命令:'));
|
|
392
428
|
console.log(colors.green(' sudo npm install -g openclaw@latest\n'));
|
|
393
429
|
|
|
@@ -403,7 +439,7 @@ async function installOpenClaw() {
|
|
|
403
439
|
return 'openclaw';
|
|
404
440
|
}
|
|
405
441
|
|
|
406
|
-
//
|
|
442
|
+
// 有权限:直接安装
|
|
407
443
|
console.log(colors.gray('正在安装 openclaw...\n'));
|
|
408
444
|
|
|
409
445
|
const result = spawnSync('npm', ['install', '-g', 'openclaw@latest'], {
|
|
@@ -416,6 +452,19 @@ async function installOpenClaw() {
|
|
|
416
452
|
return 'openclaw';
|
|
417
453
|
}
|
|
418
454
|
|
|
455
|
+
// 安装失败,可能是权限问题,尝试 sudo(非 Windows)
|
|
456
|
+
if (platform() !== 'win32') {
|
|
457
|
+
log.warn('安装失败,可能是权限不足,尝试使用 sudo...');
|
|
458
|
+
const sudoResult = spawnSync('sudo', ['npm', 'install', '-g', 'openclaw@latest'], {
|
|
459
|
+
stdio: 'inherit',
|
|
460
|
+
shell: true,
|
|
461
|
+
});
|
|
462
|
+
if (sudoResult.status === 0) {
|
|
463
|
+
log.success('OpenClaw CLI 安装完成(sudo)');
|
|
464
|
+
return 'openclaw';
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
419
468
|
// 尝试 clawdbot
|
|
420
469
|
log.warn('openclaw 安装失败,尝试 clawdbot...');
|
|
421
470
|
const fallback = spawnSync('npm', ['install', '-g', 'clawdbot@latest'], {
|