openclawsetup 2.5.2 → 2.5.4
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 +43 -52
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { exec, execSync, spawnSync } from 'child_process';
|
|
14
|
-
import { existsSync, accessSync, constants as fsConstants, rmSync, readFileSync } from 'fs';
|
|
14
|
+
import { existsSync, accessSync, constants as fsConstants, rmSync, readFileSync, realpathSync } from 'fs';
|
|
15
15
|
import { homedir, platform } from 'os';
|
|
16
16
|
import { join } from 'path';
|
|
17
17
|
import { createInterface } from 'readline';
|
|
@@ -209,21 +209,45 @@ function detectExistingInstall() {
|
|
|
209
209
|
const openclawDir = join(home, '.openclaw');
|
|
210
210
|
const clawdbotDir = join(home, '.clawdbot');
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
// Verify a CLI command is the real gateway CLI (not openclawapi symlink)
|
|
213
|
+
function isRealGatewayCli(name) {
|
|
214
|
+
// Check if the command has 'gateway' or 'status' subcommand (openclawapi doesn't)
|
|
215
|
+
const result = safeExec(`${name} --version`);
|
|
216
|
+
if (!result.ok) return false;
|
|
217
|
+
// If the version output contains 'openclawapi', it's our config tool, not the gateway
|
|
218
|
+
if (result.output && result.output.toLowerCase().includes('openclawapi')) return false;
|
|
219
|
+
// Also check: if the binary resolves to openclawapi, skip it
|
|
220
|
+
const whichResult = safeExec(platform() === 'win32' ? `where ${name}` : `command -v ${name}`);
|
|
221
|
+
if (whichResult.ok && whichResult.output) {
|
|
222
|
+
try {
|
|
223
|
+
const realPath = realpathSync(whichResult.output.trim());
|
|
224
|
+
if (realPath.includes('openclawapi')) return false;
|
|
225
|
+
} catch {}
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
214
228
|
}
|
|
215
|
-
|
|
216
|
-
|
|
229
|
+
|
|
230
|
+
// Determine the working CLI name
|
|
231
|
+
function findWorkingCli() {
|
|
232
|
+
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
233
|
+
if (isRealGatewayCli(name)) return name;
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
217
236
|
}
|
|
218
237
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
238
|
+
if (existsSync(openclawDir) || existsSync(clawdbotDir)) {
|
|
239
|
+
const configDir = existsSync(openclawDir) ? openclawDir : clawdbotDir;
|
|
240
|
+
const cliName = findWorkingCli();
|
|
241
|
+
if (cliName) {
|
|
242
|
+
return { installed: true, configDir, name: cliName };
|
|
243
|
+
}
|
|
244
|
+
// Config dir exists but no working CLI found
|
|
245
|
+
return { installed: true, configDir, name: existsSync(openclawDir) ? 'openclaw' : 'clawdbot', cliMissing: true };
|
|
222
246
|
}
|
|
223
247
|
|
|
224
|
-
const
|
|
225
|
-
if (
|
|
226
|
-
return { installed: true, name:
|
|
248
|
+
const cliName = findWorkingCli();
|
|
249
|
+
if (cliName) {
|
|
250
|
+
return { installed: true, name: cliName };
|
|
227
251
|
}
|
|
228
252
|
|
|
229
253
|
return { installed: false };
|
|
@@ -512,48 +536,15 @@ async function installOpenClaw() {
|
|
|
512
536
|
async function runOnboard(cliName) {
|
|
513
537
|
console.log(colors.bold(colors.cyan('\n[2/2] 运行配置向导\n')));
|
|
514
538
|
|
|
515
|
-
|
|
539
|
+
console.log(colors.gray('-'.repeat(60)));
|
|
540
|
+
console.log(colors.gray('以下是官方 openclaw onboard 界面:'));
|
|
541
|
+
console.log(colors.gray('-'.repeat(60) + '\n'));
|
|
516
542
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
console.log(` ${colors.yellow('2')}. 手动安装(走官方 onboard 完整流程)`);
|
|
523
|
-
mode = await askQuestion('\n请选择 (1/2): ');
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if (mode.trim() === '2') {
|
|
527
|
-
// 手动模式:直接运行官方 onboard
|
|
528
|
-
console.log(colors.gray('\n' + '-'.repeat(60)));
|
|
529
|
-
console.log(colors.gray('以下是官方 openclaw onboard 界面:'));
|
|
530
|
-
console.log(colors.gray('-'.repeat(60) + '\n'));
|
|
531
|
-
|
|
532
|
-
const manualResult = runOnboardManual(cliName);
|
|
533
|
-
console.log(colors.gray('\n' + '-'.repeat(60)));
|
|
534
|
-
if (manualResult.status !== 0) {
|
|
535
|
-
log.warn(`onboard 退出码: ${manualResult.status}`);
|
|
536
|
-
log.hint('如果配置未完成,可以手动运行: ' + cliName + ' onboard');
|
|
537
|
-
}
|
|
538
|
-
} else {
|
|
539
|
-
// 自动模式:只用最安全的参数
|
|
540
|
-
console.log(colors.gray('\n正在自动安装(跳过模型和渠道配置)...\n'));
|
|
541
|
-
|
|
542
|
-
const { file, args } = getOnboardCommand(cliName, ['onboard', '--install-daemon']);
|
|
543
|
-
const result = spawnSync(file, args, { stdio: 'inherit' });
|
|
544
|
-
|
|
545
|
-
if (result.status !== 0) {
|
|
546
|
-
// 自动模式失败,回退到手动
|
|
547
|
-
log.warn('自动安装未完成,切换到手动模式...');
|
|
548
|
-
console.log(colors.gray('\n' + '-'.repeat(60)));
|
|
549
|
-
console.log(colors.gray('以下是官方 openclaw onboard 界面:'));
|
|
550
|
-
console.log(colors.gray('-'.repeat(60) + '\n'));
|
|
551
|
-
const manualResult = runOnboardManual(cliName);
|
|
552
|
-
if (manualResult.status !== 0) {
|
|
553
|
-
log.warn(`onboard 退出码: ${manualResult.status}`);
|
|
554
|
-
log.hint('如果配置未完成,可以手动运行: ' + cliName + ' onboard');
|
|
555
|
-
}
|
|
556
|
-
}
|
|
543
|
+
const manualResult = runOnboardManual(cliName);
|
|
544
|
+
console.log(colors.gray('\n' + '-'.repeat(60)));
|
|
545
|
+
if (manualResult.status !== 0) {
|
|
546
|
+
log.warn(`onboard 退出码: ${manualResult.status}`);
|
|
547
|
+
log.hint('如果配置未完成,可以手动运行: ' + cliName + ' onboard');
|
|
557
548
|
}
|
|
558
549
|
}
|
|
559
550
|
|