openclawsetup 2.8.5 → 2.8.7

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 +90 -20
  2. package/package.json +1 -1
package/bin/cli.mjs CHANGED
@@ -1127,7 +1127,7 @@ function ensureConfigFilePresent(config, cliName) {
1127
1127
  }
1128
1128
  const result = safeExec(`${cliName} onboard --install-daemon`, { timeout: 240000 });
1129
1129
  if (!result.ok && process.stdin.isTTY && process.stdout.isTTY) {
1130
- spawnSync(cliName, ['onboard'], { stdio: 'inherit', shell: true });
1130
+ spawnSync(`${cliName} onboard`, { stdio: 'inherit', shell: true });
1131
1131
  }
1132
1132
  const recheck = getConfigInfo();
1133
1133
  if (recheck.configPath && existsSync(recheck.configPath)) {
@@ -1153,8 +1153,8 @@ async function repairBrokenConfig(config, cliName, strongMode = false) {
1153
1153
  } catch {
1154
1154
  try {
1155
1155
  const backupPath = backupBrokenConfig(config.configPath);
1156
- const onboardArgs = strongMode ? ['onboard', '--install-daemon'] : ['onboard'];
1157
- spawnSync(cliName, onboardArgs, { stdio: 'inherit', shell: true });
1156
+ const onboardCmd = strongMode ? `${cliName} onboard --install-daemon` : `${cliName} onboard`;
1157
+ spawnSync(onboardCmd, { stdio: 'inherit', shell: true });
1158
1158
  const recheck = getConfigInfo();
1159
1159
  if (recheck.configPath && existsSync(recheck.configPath)) {
1160
1160
  return {
@@ -1404,7 +1404,7 @@ async function validateModelConfig(autoFix = false, strongMode = false) {
1404
1404
  }
1405
1405
  }
1406
1406
 
1407
- spawnSync('npx', ['openclawapi@latest'], { stdio: 'inherit', shell: true });
1407
+ spawnSync('npx openclawapi@latest', { stdio: 'inherit', shell: true });
1408
1408
  const recheck = getConfigInfo();
1409
1409
  const recheckHasModels = recheck.raw.includes('"models"') || recheck.raw.includes('"providers"');
1410
1410
  const recheckHasApiKey = recheck.raw.includes('"apiKey"') || recheck.raw.includes('"api_key"');
@@ -1614,7 +1614,7 @@ async function installOpenClaw() {
1614
1614
  // 有权限:直接安装
1615
1615
  console.log(colors.gray('正在安装 openclaw...\n'));
1616
1616
 
1617
- const result = spawnSync('npm', ['install', '-g', 'openclaw@latest'], {
1617
+ const result = spawnSync('npm install -g openclaw@latest', {
1618
1618
  stdio: 'inherit',
1619
1619
  shell: true,
1620
1620
  });
@@ -1627,7 +1627,7 @@ async function installOpenClaw() {
1627
1627
  // 安装失败,可能是权限问题,尝试 sudo(非 Windows)
1628
1628
  if (platform() !== 'win32') {
1629
1629
  log.warn('安装失败,可能是权限不足,尝试使用 sudo...');
1630
- const sudoResult = spawnSync('sudo', ['npm', 'install', '-g', 'openclaw@latest'], {
1630
+ const sudoResult = spawnSync('sudo npm install -g openclaw@latest', {
1631
1631
  stdio: 'inherit',
1632
1632
  shell: true,
1633
1633
  });
@@ -1640,7 +1640,7 @@ async function installOpenClaw() {
1640
1640
 
1641
1641
  // 尝试 clawdbot
1642
1642
  log.warn('openclaw 安装失败,尝试 clawdbot...');
1643
- const fallback = spawnSync('npm', ['install', '-g', 'clawdbot@latest'], {
1643
+ const fallback = spawnSync('npm install -g clawdbot@latest', {
1644
1644
  stdio: 'inherit',
1645
1645
  shell: true,
1646
1646
  });
@@ -1939,7 +1939,7 @@ async function updateOpenClaw(cliName) {
1939
1939
  console.log(colors.green(` ${cliName} gateway restart\n`));
1940
1940
  } else {
1941
1941
  console.log(colors.gray('\n正在更新...\n'));
1942
- spawnSync('npm', ['install', '-g', `${cliName}@latest`], {
1942
+ spawnSync(`npm install -g ${cliName}@latest`, {
1943
1943
  stdio: 'inherit',
1944
1944
  shell: true,
1945
1945
  });
@@ -1959,6 +1959,63 @@ async function updateOpenClaw(cliName) {
1959
1959
  }
1960
1960
  }
1961
1961
 
1962
+ // ============ 安装后 Gateway 验证 ============
1963
+
1964
+ async function verifyAndStartGateway(cliName) {
1965
+ const config = getConfigInfo();
1966
+ const port = config.port || DEFAULT_GATEWAY_PORT;
1967
+
1968
+ console.log(colors.cyan('\n验证 Gateway 服务...'));
1969
+
1970
+ // 等待 Gateway 启动(onboard 可能刚启动 daemon,需要时间)
1971
+ await sleep(3000);
1972
+
1973
+ // 检查端口是否在监听
1974
+ const portCheck = getPortCheckOutput(port);
1975
+ if (portCheck.ok && hasListeningState(portCheck.output)) {
1976
+ // 端口在监听,再验证 health
1977
+ const health = gatewayHealthRequest(port);
1978
+ if (health.ok) {
1979
+ log.success('Gateway 运行正常');
1980
+ return;
1981
+ }
1982
+ }
1983
+
1984
+ // Gateway 未启动,尝试手动启动
1985
+ log.warn('Gateway 未就绪,正在尝试启动...');
1986
+
1987
+ const startResult = await ensureGatewayRunning(cliName, 'start');
1988
+ if (startResult.ok) {
1989
+ // 再次验证端口
1990
+ await sleep(2000);
1991
+ const recheck = getPortCheckOutput(port);
1992
+ if (recheck.ok && hasListeningState(recheck.output)) {
1993
+ log.success('Gateway 已启动');
1994
+ return;
1995
+ }
1996
+ }
1997
+
1998
+ // 仍然失败,尝试 restart
1999
+ log.warn('启动失败,尝试重启...');
2000
+ const restartResult = await ensureGatewayRunning(cliName, 'restart');
2001
+ if (restartResult.ok) {
2002
+ await sleep(2000);
2003
+ const recheck2 = getPortCheckOutput(port);
2004
+ if (recheck2.ok && hasListeningState(recheck2.output)) {
2005
+ log.success('Gateway 已重启成功');
2006
+ return;
2007
+ }
2008
+ }
2009
+
2010
+ // 所有尝试失败
2011
+ log.error(`Gateway 未能在端口 ${port} 上启动`);
2012
+ console.log(colors.yellow('\n请手动排查:'));
2013
+ console.log(` 1. 运行: ${colors.green(`${cliName} gateway start`)}`);
2014
+ console.log(` 2. 查看日志: ${colors.green(`${cliName} gateway logs`)}`);
2015
+ console.log(` 3. 检查端口: ${colors.green(`${cliName} status`)}`);
2016
+ console.log(` 4. 运行诊断: ${colors.green(`npx openclawsetup@latest --fix`)}`);
2017
+ }
2018
+
1962
2019
  // ============ 完成信息 ============
1963
2020
 
1964
2021
  function showCompletionInfo(cliName) {
@@ -2030,7 +2087,7 @@ async function uninstallOpenClaw(existing) {
2030
2087
  console.log(colors.green(' rm -rf ~/.openclaw ~/.clawdbot\n'));
2031
2088
  await waitForEnter('卸载完成后按回车继续...');
2032
2089
  } else {
2033
- spawnSync('npm', ['uninstall', '-g', cliName], { stdio: 'inherit', shell: true });
2090
+ spawnSync(`npm uninstall -g ${cliName}`, { stdio: 'inherit', shell: true });
2034
2091
  }
2035
2092
 
2036
2093
  const config = getConfigInfo();
@@ -2262,9 +2319,21 @@ async function runHealthCheck(cliName, autoFix = false, strongMode = false) {
2262
2319
  console.log(colors.yellow(' 尝试重启并恢复端口监听...'));
2263
2320
  const recovered = await ensureGatewayRunning(activeCli, 'restart');
2264
2321
  if (recovered.ok) {
2265
- await sleep(2500);
2266
- const recheck = getPortCheckOutput(port);
2267
- if (recheck.ok && recheck.output && hasListeningState(recheck.output)) {
2322
+ // Windows 上 Gateway 启动较慢,轮询等待端口就绪
2323
+ const maxWait = platform() === 'win32' ? 15000 : 8000;
2324
+ const interval = 1500;
2325
+ let waited = 0;
2326
+ let portReady = false;
2327
+ while (waited < maxWait) {
2328
+ await sleep(interval);
2329
+ waited += interval;
2330
+ const recheck = getPortCheckOutput(port);
2331
+ if (recheck.ok && recheck.output && hasListeningState(recheck.output)) {
2332
+ portReady = true;
2333
+ break;
2334
+ }
2335
+ }
2336
+ if (portReady) {
2268
2337
  log.success(`端口 ${port} 已恢复监听`);
2269
2338
  fixed.push(`端口监听已恢复(${port})`);
2270
2339
  portHealthy = true;
@@ -2706,7 +2775,7 @@ async function showInteractiveMenu(existing) {
2706
2775
  break;
2707
2776
  case '7':
2708
2777
  console.log(colors.cyan('\n启动模型配置...'));
2709
- spawnSync('npx', ['openclawapi@latest'], {
2778
+ spawnSync('npx openclawapi@latest', {
2710
2779
  stdio: 'inherit',
2711
2780
  shell: true,
2712
2781
  });
@@ -2721,13 +2790,13 @@ async function showInteractiveMenu(existing) {
2721
2790
  const chatChoice = await askQuestion('\n请选择 (a/b/c/0): ');
2722
2791
  switch (chatChoice.trim().toLowerCase()) {
2723
2792
  case 'a':
2724
- spawnSync('npx', ['openclawdc@latest'], { stdio: 'inherit', shell: true });
2793
+ spawnSync('npx openclawdc@latest', { stdio: 'inherit', shell: true });
2725
2794
  break;
2726
2795
  case 'b':
2727
- spawnSync('npx', ['openclaw-chat-cn@latest', 'feishu'], { stdio: 'inherit', shell: true });
2796
+ spawnSync('npx openclaw-chat-cn@latest feishu', { stdio: 'inherit', shell: true });
2728
2797
  break;
2729
2798
  case 'c':
2730
- spawnSync(cliName, ['onboard'], { stdio: 'inherit', shell: true });
2799
+ spawnSync(`${cliName} onboard`, { stdio: 'inherit', shell: true });
2731
2800
  break;
2732
2801
  }
2733
2802
  await waitForEnter('\n按回车返回菜单...');
@@ -2792,10 +2861,8 @@ async function main() {
2792
2861
  if (latestVersion && compareSemver(currentVersion, latestVersion) < 0) {
2793
2862
  console.log(colors.yellow(`\n⚠ 当前版本 ${currentVersion},最新版本 ${latestVersion}`));
2794
2863
  console.log(colors.yellow(' 正在更新到最新版本...\n'));
2795
- const updateCmd = platform() === 'win32'
2796
- ? `npx --yes openclawsetup@${latestVersion}`
2797
- : `npx --yes openclawsetup@${latestVersion}`;
2798
- spawnSync(updateCmd.split(' ')[0], updateCmd.split(' ').slice(1), {
2864
+ const updateCmd = `npx --yes openclawsetup@${latestVersion}`;
2865
+ spawnSync(updateCmd, {
2799
2866
  stdio: 'inherit',
2800
2867
  shell: true,
2801
2868
  });
@@ -2880,6 +2947,9 @@ async function main() {
2880
2947
  // 运行 onboard
2881
2948
  await runOnboard(cliName);
2882
2949
 
2950
+ // 验证 Gateway 是否启动,未启动则尝试启动
2951
+ await verifyAndStartGateway(cliName);
2952
+
2883
2953
  // 显示完成信息
2884
2954
  showCompletionInfo(cliName);
2885
2955
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawsetup",
3
- "version": "2.8.5",
3
+ "version": "2.8.7",
4
4
  "description": "OpenClaw 安装向导 - 智能安装、诊断、自动修复",
5
5
  "type": "module",
6
6
  "bin": {