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.
Files changed (2) hide show
  1. package/bin/cli.mjs +63 -14
  2. 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' || os === 'darwin') return false;
151
+ if (os === 'win32') return false;
152
152
 
153
- try {
154
- const testDir = '/usr/lib/node_modules';
155
- if (existsSync(testDir)) {
156
- accessSync(testDir, fsConstants.W_OK);
157
- return false;
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
- return existsSync('/etc/cloud') || existsSync('/var/lib/cloud') || existsSync('/sys/hypervisor');
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
- log.hint('Linux 系统需要 sudo 权限安装全局包');
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
- // macOS 或有权限的 Linux:直接安装
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'], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawsetup",
3
- "version": "2.4.4",
3
+ "version": "2.4.6",
4
4
  "description": "OpenClaw 安装向导 - 智能安装、诊断、自动修复",
5
5
  "type": "module",
6
6
  "bin": {