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.
- package/bin/cli.mjs +90 -20
- 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
|
|
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
|
|
1157
|
-
spawnSync(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
2266
|
-
const
|
|
2267
|
-
|
|
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
|
|
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
|
|
2793
|
+
spawnSync('npx openclawdc@latest', { stdio: 'inherit', shell: true });
|
|
2725
2794
|
break;
|
|
2726
2795
|
case 'b':
|
|
2727
|
-
spawnSync('npx
|
|
2796
|
+
spawnSync('npx openclaw-chat-cn@latest feishu', { stdio: 'inherit', shell: true });
|
|
2728
2797
|
break;
|
|
2729
2798
|
case 'c':
|
|
2730
|
-
spawnSync(cliName
|
|
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 =
|
|
2796
|
-
|
|
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
|
}
|