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.
Files changed (2) hide show
  1. package/bin/cli.mjs +43 -52
  2. 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
- if (existsSync(openclawDir)) {
213
- return { installed: true, configDir: openclawDir, name: 'openclaw' };
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
- if (existsSync(clawdbotDir)) {
216
- return { installed: true, configDir: clawdbotDir, name: 'clawdbot' };
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
- const openclawResult = safeExec('openclaw --version');
220
- if (openclawResult.ok) {
221
- return { installed: true, name: 'openclaw', version: openclawResult.output };
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 clawdbotResult = safeExec('clawdbot --version');
225
- if (clawdbotResult.ok) {
226
- return { installed: true, name: 'clawdbot', version: clawdbotResult.output };
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
- const options = parseArgs();
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
- let mode = options.manual ? '2' : options.auto ? '1' : '';
519
- if (!mode) {
520
- console.log(colors.cyan('请选择安装模式:'));
521
- console.log(` ${colors.yellow('1')}. 自动安装(跳过所有配置,后续单独配置模型和渠道)`);
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawsetup",
3
- "version": "2.5.2",
3
+ "version": "2.5.4",
4
4
  "description": "OpenClaw 安装向导 - 智能安装、诊断、自动修复",
5
5
  "type": "module",
6
6
  "bin": {