openclawsetup 2.8.2 → 2.8.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.
Files changed (2) hide show
  1. package/bin/cli.mjs +83 -12
  2. package/package.json +1 -1
package/bin/cli.mjs CHANGED
@@ -858,14 +858,69 @@ function getDashboardToken(config) {
858
858
 
859
859
  function parseStatusOutput(statusOutput) {
860
860
  const text = (statusOutput || '').toLowerCase();
861
- const runningKeywords = ['running', 'active', '已运行', '运行中', '在线'];
862
- const stoppedKeywords = ['stopped', 'inactive', 'not running', '未运行', '停止'];
861
+ const stoppedRegex = [
862
+ /\bnot\s+running\b/,
863
+ /\bstopped\b/,
864
+ /\binactive\b/,
865
+ /\boffline\b/,
866
+ ];
867
+ const runningRegex = [
868
+ /\brunning\b/,
869
+ /\bactive\b/,
870
+ /\bonline\b/,
871
+ ];
872
+ const stoppedKeywords = ['未运行', '已停止', '停止', '离线'];
873
+ const runningKeywords = ['已运行', '运行中', '在线'];
863
874
 
864
- if (runningKeywords.some((word) => text.includes(word))) return 'running';
875
+ if (stoppedRegex.some((pattern) => pattern.test(text))) return 'stopped';
865
876
  if (stoppedKeywords.some((word) => text.includes(word))) return 'stopped';
877
+ if (runningRegex.some((pattern) => pattern.test(text))) return 'running';
878
+ if (runningKeywords.some((word) => text.includes(word))) return 'running';
866
879
  return 'unknown';
867
880
  }
868
881
 
882
+ function isCommandTimeout(result) {
883
+ if (!result || result.ok) return false;
884
+ const raw = `${result.error || ''} ${result.stderr || ''}`.toLowerCase();
885
+ return raw.includes('timed out') || raw.includes('etimedout') || raw.includes('sigterm') || raw.includes('killed');
886
+ }
887
+
888
+ function probeGatewayStatus(cliName, timeout = STATUS_CMD_TIMEOUT_MS) {
889
+ const attempts = [
890
+ `${cliName} status`,
891
+ `${cliName} gateway status`,
892
+ ];
893
+
894
+ let state = 'unknown';
895
+ let output = '';
896
+ let timedOut = false;
897
+ let error = '';
898
+
899
+ for (const cmd of attempts) {
900
+ const result = safeExec(cmd, { timeout });
901
+ if (isCommandTimeout(result)) {
902
+ timedOut = true;
903
+ continue;
904
+ }
905
+ if (!result.ok) {
906
+ if (!error) error = result.stderr || result.error || '';
907
+ continue;
908
+ }
909
+ if (!result.output) continue;
910
+
911
+ output = result.output;
912
+ const parsed = parseStatusOutput(result.output);
913
+ if (parsed === 'running') {
914
+ return { state: 'running', output, timedOut, error };
915
+ }
916
+ if (parsed === 'stopped') {
917
+ state = 'stopped';
918
+ }
919
+ }
920
+
921
+ return { state, output, timedOut, error };
922
+ }
923
+
869
924
  function getPortCheckOutput(port, timeout = PORT_CHECK_TIMEOUT_MS) {
870
925
  const cmd = platform() === 'win32'
871
926
  ? `netstat -ano | findstr :${port}`
@@ -1375,12 +1430,18 @@ function getOnboardHelp(cliName) {
1375
1430
  return '';
1376
1431
  }
1377
1432
 
1433
+ function extractOnboardFlags(helpText = '') {
1434
+ const matches = helpText.toLowerCase().match(/--[a-z0-9][a-z0-9-]*/g) || [];
1435
+ return new Set(matches);
1436
+ }
1437
+
1378
1438
  function buildOnboardArgsFromHelp(helpText, options) {
1379
1439
  const help = helpText.toLowerCase();
1440
+ const flagSet = extractOnboardFlags(helpText);
1380
1441
  const args = [];
1381
1442
  const enabled = [];
1382
1443
 
1383
- const pickFlag = (flags) => flags.find((flag) => help.includes(flag));
1444
+ const pickFlag = (flags) => flags.find((flag) => flagSet.has(flag));
1384
1445
 
1385
1446
  const yesFlag = pickFlag(['--yes', '--assume-yes', '--accept', '--agree']);
1386
1447
  if (yesFlag) {
@@ -1393,10 +1454,10 @@ function buildOnboardArgsFromHelp(helpText, options) {
1393
1454
  args.push(installDaemonFlag);
1394
1455
  }
1395
1456
 
1396
- if (help.includes('--quickstart')) {
1457
+ if (flagSet.has('--quickstart')) {
1397
1458
  args.push('--quickstart');
1398
1459
  enabled.push('quickstart');
1399
- } else if (help.includes('--mode') && (help.includes('quickstart') || help.includes('quick start'))) {
1460
+ } else if (flagSet.has('--mode') && (help.includes('quickstart') || help.includes('quick start'))) {
1400
1461
  args.push('--mode', 'quickstart');
1401
1462
  enabled.push('quickstart');
1402
1463
  }
@@ -1417,10 +1478,10 @@ function buildOnboardArgsFromHelp(helpText, options) {
1417
1478
  }
1418
1479
  }
1419
1480
 
1420
- if (help.includes('--ui') && (help.includes('web') || help.includes('dashboard'))) {
1481
+ if (flagSet.has('--ui') && (help.includes('web') || help.includes('dashboard'))) {
1421
1482
  args.push('--ui', 'web');
1422
1483
  enabled.push('ui-web');
1423
- } else if (help.includes('--web')) {
1484
+ } else if (flagSet.has('--web')) {
1424
1485
  args.push('--web');
1425
1486
  enabled.push('ui-web');
1426
1487
  }
@@ -2026,16 +2087,26 @@ async function runHealthCheck(cliName, autoFix = false, strongMode = false) {
2026
2087
 
2027
2088
  // 3. 检查 Gateway 进程
2028
2089
  console.log(colors.cyan('检查 Gateway 进程...'));
2029
- const statusResult = safeExec(`${activeCli} status`);
2030
- const statusState = statusResult.ok ? parseStatusOutput(statusResult.output) : 'unknown';
2090
+ const statusProbe = probeGatewayStatus(activeCli, STATUS_CMD_TIMEOUT_MS);
2091
+ const statusState = statusProbe.state;
2092
+ const portForStatus = selectHealthPort(config, strongMode);
2093
+ const statusPortResult = getPortCheckOutput(portForStatus, PORT_CHECK_TIMEOUT_MS);
2094
+ const statusPortListening = Boolean(statusPortResult.ok && statusPortResult.output);
2031
2095
 
2032
- if (statusResult.ok && statusState === 'running') {
2096
+ if (statusState === 'running' || (statusState !== 'running' && statusPortListening)) {
2033
2097
  log.success('Gateway 进程正在运行');
2098
+ if (statusProbe.timedOut) {
2099
+ log.hint('状态命令超时,已按端口监听判定为运行中');
2100
+ } else if (statusState !== 'running' && statusPortListening) {
2101
+ log.hint('状态命令返回非运行,但端口可访问(兼容判定)');
2102
+ }
2034
2103
  } else {
2035
2104
  const issue = summarizeIssue(
2036
2105
  'error',
2037
2106
  'Gateway 未运行',
2038
- statusResult.ok ? 'Gateway 状态为停止/未知' : (statusResult.stderr || statusResult.error || '状态检查失败'),
2107
+ statusProbe.output
2108
+ ? 'Gateway 状态为停止/未知'
2109
+ : (statusProbe.error || '状态检查失败'),
2039
2110
  `运行 ${activeCli} gateway start 启动服务`,
2040
2111
  `${activeCli} gateway start`,
2041
2112
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawsetup",
3
- "version": "2.8.2",
3
+ "version": "2.8.3",
4
4
  "description": "OpenClaw 安装向导 - 智能安装、诊断、自动修复",
5
5
  "type": "module",
6
6
  "bin": {