openclawsetup 2.8.11 → 2.8.13

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 +97 -16
  2. package/package.json +1 -1
package/bin/cli.mjs CHANGED
@@ -208,6 +208,28 @@ function safeFileRead(path) {
208
208
  }
209
209
  }
210
210
 
211
+ function sanitizeAuthProfiles(raw) {
212
+ try {
213
+ const obj = JSON.parse(raw);
214
+ const redact = (o) => {
215
+ if (!o || typeof o !== 'object') return o;
216
+ const copy = Array.isArray(o) ? [...o] : { ...o };
217
+ for (const k of Object.keys(copy)) {
218
+ if (/^(key|token|access|refresh|apiKey)$/i.test(k) && typeof copy[k] === 'string') {
219
+ const v = copy[k];
220
+ copy[k] = v.length > 8 ? `${v.slice(0, 4)}...${v.slice(-4)}` : '<REDACTED>';
221
+ } else if (typeof copy[k] === 'object') {
222
+ copy[k] = redact(copy[k]);
223
+ }
224
+ }
225
+ return copy;
226
+ };
227
+ return JSON.stringify(redact(obj), null, 2);
228
+ } catch {
229
+ return sanitizeText(raw);
230
+ }
231
+ }
232
+
211
233
  function runCmdCapture(cmd, timeout = 20000) {
212
234
  const result = safeExec(cmd, { timeout });
213
235
  if (result.ok) {
@@ -499,12 +521,12 @@ async function collectEvidencePackage(options = {}) {
499
521
 
500
522
  const snapshot = gatherEnvironmentSnapshot();
501
523
  const tokenOptimizationPreview = createTokenOptimizationPlan();
502
- const cliName = snapshot.openclaw.detectedInstall?.name || findWorkingCliName() || 'openclaw';
524
+ const cliName = snapshot.openclaw.detectedInstall?.name || findWorkingCliName(snapshot.openclaw.configDir?.includes('.clawdbot') ? 'clawdbot' : undefined) || 'openclaw';
503
525
 
504
526
  const captures = {
505
527
  doctor: runCmdCapture(`${cliName} doctor`, quick ? 20000 : 90000),
506
528
  status: runCmdCapture(`${cliName} status`, 20000),
507
- gatewayLogs: runCmdCapture(`${cliName} gateway logs`, quick ? 20000 : 45000),
529
+ gatewayLogs: runCmdCapture(`${cliName} logs --lines 80`, quick ? 20000 : 45000),
508
530
  cliVersion: runCmdCapture(`${cliName} --version`, 15000),
509
531
  npmListGlobalOpenclaw: runCmdCapture('npm ls -g openclaw --depth=0', 20000),
510
532
  npmListGlobalClawdbot: runCmdCapture('npm ls -g clawdbot --depth=0', 20000),
@@ -528,16 +550,56 @@ async function collectEvidencePackage(options = {}) {
528
550
  const configRaw = safeFileRead(snapshot.openclaw.configPath);
529
551
  const safeConfigPreview = sanitizeText(truncateText(configRaw, 20000));
530
552
 
553
+ // Capture auth-profiles.json (critical for 401 debugging)
554
+ const configDir = snapshot.openclaw.configDir || '';
555
+ const authProfilesCandidates = configDir ? [
556
+ join(configDir, 'agents', 'main', 'agent', 'auth-profiles.json'),
557
+ join(configDir, 'agent', 'auth-profiles.json'),
558
+ ] : [];
559
+ let authProfilesPath = '';
560
+ let authProfilesRaw = '';
561
+ for (const candidate of authProfilesCandidates) {
562
+ const content = safeFileRead(candidate);
563
+ if (content) {
564
+ authProfilesPath = candidate;
565
+ authProfilesRaw = content;
566
+ break;
567
+ }
568
+ }
569
+ // Redact key values but preserve structure for debugging
570
+ const safeAuthProfiles = authProfilesRaw ? sanitizeAuthProfiles(authProfilesRaw) : '';
571
+
572
+ // Try to read Gateway log file directly
573
+ const logFileCandidates = configDir ? [
574
+ join(configDir, 'gateway.log'),
575
+ join(configDir, 'logs', 'gateway.log'),
576
+ join(configDir, 'agents', 'main', 'agent', 'gateway.log'),
577
+ ] : [];
578
+ let gatewayLogContent = '';
579
+ for (const candidate of logFileCandidates) {
580
+ const content = safeFileRead(candidate);
581
+ if (content) {
582
+ // Take last 5000 chars
583
+ gatewayLogContent = sanitizeText(content.length > 5000 ? content.slice(-5000) : content);
584
+ break;
585
+ }
586
+ }
587
+
531
588
  const summary = {
532
589
  meta: {
533
590
  generatedAt: new Date().toISOString(),
534
591
  durationMs: Date.now() - startedAt,
535
592
  quick,
536
- evidenceVersion: '1.0.0',
593
+ evidenceVersion: '1.1.0',
537
594
  },
538
595
  snapshot,
539
596
  tokenOptimizationPreview,
540
597
  captures,
598
+ authProfiles: {
599
+ path: authProfilesPath || '(not found)',
600
+ content: safeAuthProfiles || '(empty or missing)',
601
+ },
602
+ gatewayLogFile: gatewayLogContent || '(not found)',
541
603
  strongCheck: strongCheckResult
542
604
  ? {
543
605
  issuesCount: strongCheckResult.issues?.length || 0,
@@ -550,6 +612,9 @@ async function collectEvidencePackage(options = {}) {
550
612
 
551
613
  writeFileSync(join(evidenceDir, 'summary.json'), `${JSON.stringify(summary, null, 2)}\n`, 'utf8');
552
614
  writeFileSync(join(evidenceDir, 'config.preview.json.txt'), `${safeConfigPreview || '<empty>'}\n`, 'utf8');
615
+ if (safeAuthProfiles) {
616
+ writeFileSync(join(evidenceDir, 'auth-profiles.preview.json.txt'), `${safeAuthProfiles}\n`, 'utf8');
617
+ }
553
618
 
554
619
  const readme = [
555
620
  '# OpenClaw 排障证据包',
@@ -561,6 +626,7 @@ async function collectEvidencePackage(options = {}) {
561
626
  '## 文件说明',
562
627
  '- summary.json: 机器可解析的完整诊断结果(已脱敏)',
563
628
  '- config.preview.json.txt: 配置文件预览(已脱敏)',
629
+ '- auth-profiles.preview.json.txt: 认证配置预览(已脱敏,如存在)',
564
630
  '',
565
631
  '## 发给技术支持',
566
632
  '请把整个证据包文件夹(或 zip)发给技术支持即可。',
@@ -631,9 +697,9 @@ ${colors.cyan('安装后配置模型:')}
631
697
  npx openclawapi@latest # 交互式配置
632
698
 
633
699
  ${colors.cyan('常见问题快速修复:')}
634
- Gateway 未启动: openclaw gateway start
700
+ Gateway 未启动: openclaw gateway start (或 clawdbot gateway start)
635
701
  端口被占用: openclaw config set gateway.port 18790
636
- 配置文件损坏: rm ~/.openclaw/openclaw.json && openclaw onboard
702
+ 配置文件损坏: 重新运行 npx openclawsetup@latest
637
703
  `);
638
704
  }
639
705
 
@@ -730,8 +796,17 @@ function isRealGatewayCli(name) {
730
796
  return true;
731
797
  }
732
798
 
733
- function findWorkingCliName() {
734
- for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
799
+ function findWorkingCliName(preferredName) {
800
+ const candidates = ['openclaw', 'clawdbot', 'moltbot'];
801
+ // If a preferred name is given (e.g. matching the config dir), check it first
802
+ if (preferredName) {
803
+ const reordered = [preferredName, ...candidates.filter(n => n !== preferredName)];
804
+ for (const name of reordered) {
805
+ if (isRealGatewayCli(name)) return name;
806
+ }
807
+ return null;
808
+ }
809
+ for (const name of candidates) {
735
810
  if (isRealGatewayCli(name)) return name;
736
811
  }
737
812
  return null;
@@ -743,13 +818,17 @@ function detectExistingInstall() {
743
818
  const clawdbotDir = join(home, '.clawdbot');
744
819
 
745
820
  if (existsSync(openclawDir) || existsSync(clawdbotDir)) {
821
+ // Prefer the CLI that matches the config directory to avoid cross-config issues
822
+ // e.g. if config is in ~/.clawdbot, prefer 'clawdbot' CLI (reads ~/.clawdbot/clawdbot.json)
823
+ // if config is in ~/.openclaw, prefer 'openclaw' CLI (reads ~/.openclaw/openclaw.json)
746
824
  const configDir = existsSync(openclawDir) ? openclawDir : clawdbotDir;
747
- const cliName = findWorkingCliName();
825
+ const preferredCli = existsSync(openclawDir) ? 'openclaw' : 'clawdbot';
826
+ const cliName = findWorkingCliName(preferredCli);
748
827
  if (cliName) {
749
828
  return { installed: true, configDir, name: cliName };
750
829
  }
751
830
  // Config dir exists but no working CLI found
752
- return { installed: true, configDir, name: existsSync(openclawDir) ? 'openclaw' : 'clawdbot', cliMissing: true };
831
+ return { installed: true, configDir, name: preferredCli, cliMissing: true };
753
832
  }
754
833
 
755
834
  const cliName = findWorkingCliName();
@@ -1630,7 +1709,7 @@ function showInstallGuide() {
1630
1709
  console.log(colors.bold(colors.cyan(' 📖 OpenClaw 安装指引')));
1631
1710
  console.log(colors.bold(colors.cyan('='.repeat(60))));
1632
1711
 
1633
- console.log(colors.yellow('\n接下来会运行官方 openclaw onboard 命令'));
1712
+ console.log(colors.yellow('\n接下来会运行官方 onboard 命令'));
1634
1713
  console.log(colors.yellow('自动模式会按以下推荐选择(可随时接管):\n'));
1635
1714
 
1636
1715
  console.log(colors.cyan('┌─────────────────────────────────────────────────────────┐'));
@@ -1844,7 +1923,7 @@ async function runOnboard(cliName) {
1844
1923
  console.log(colors.bold(colors.cyan('\n[2/2] 运行配置向导\n')));
1845
1924
 
1846
1925
  console.log(colors.gray('-'.repeat(60)));
1847
- console.log(colors.gray('以下是官方 openclaw onboard 界面:'));
1926
+ console.log(colors.gray('以下是官方 onboard 界面:'));
1848
1927
  console.log(colors.gray('-'.repeat(60) + '\n'));
1849
1928
 
1850
1929
  const manualResult = runOnboardManual(cliName);
@@ -2203,7 +2282,7 @@ function showCompletionInfo(cliName) {
2203
2282
  console.log(colors.cyan('\n下一步 - 配置 AI 模型(必须):'));
2204
2283
  console.log(` ${colors.yellow('npx openclawapi@latest preset-claude')}`);
2205
2284
 
2206
- showDashboardAccessInfo();
2285
+ showDashboardAccessInfo(cliName);
2207
2286
 
2208
2287
  console.log(colors.cyan('\n常用命令:'));
2209
2288
  console.log(` 查看状态: ${colors.yellow(`${cliName} status`)}`);
@@ -2218,12 +2297,14 @@ function showCompletionInfo(cliName) {
2218
2297
  console.log('');
2219
2298
  }
2220
2299
 
2221
- function showDashboardAccessInfo() {
2300
+ function showDashboardAccessInfo(cliName) {
2222
2301
  const config = getConfigInfo();
2223
2302
  const port = config.port || 18789;
2224
2303
  const tokenRaw = getDashboardToken(config) || '<你的token>';
2225
2304
  const tokenMasked = maskToken(tokenRaw);
2226
2305
  const dashboardUrl = `http://127.0.0.1:${port}/?token=${tokenMasked}`;
2306
+ const activeCli = cliName || (config.configPath?.includes('.clawdbot') ? 'clawdbot' : 'openclaw');
2307
+ const configFileName = config.configPath || `~/.${activeCli}/${activeCli}.json`;
2227
2308
 
2228
2309
  if (detectVps()) {
2229
2310
  const serverIp = getServerIp() || '<服务器IP>';
@@ -2239,10 +2320,10 @@ function showDashboardAccessInfo() {
2239
2320
  console.log(` ${colors.green(dashboardUrl)}`);
2240
2321
  console.log('');
2241
2322
  console.log(colors.yellow(' 方式二:直接暴露端口(不推荐,有安全风险)'));
2242
- console.log(colors.gray(' 1. 修改配置文件 ~/.openclaw/openclaw.json'));
2323
+ console.log(colors.gray(` 1. 修改配置文件 ${configFileName}`));
2243
2324
  console.log(colors.gray(' 将 "bind": "loopback" 改为 "bind": "all"'));
2244
2325
  console.log(colors.gray(` 2. 在云服务器控制台开放端口 ${port}`));
2245
- console.log(colors.gray(' 3. 重启 Gateway:openclaw gateway restart'));
2326
+ console.log(colors.gray(` 3. 重启 Gateway:${activeCli} gateway restart`));
2246
2327
  console.log(colors.gray(` 4. 访问:http://${serverIp}:${port}/?token=...`));
2247
2328
  } else {
2248
2329
  console.log(colors.cyan('\nDashboard 访问:'));
@@ -2894,7 +2975,7 @@ async function showInteractiveMenu(existing) {
2894
2975
  console.log(colors.bold(colors.cyan(' 🦞 OpenClaw 管理菜单')));
2895
2976
  console.log(colors.bold(colors.cyan('='.repeat(50))));
2896
2977
 
2897
- showDashboardAccessInfo();
2978
+ showDashboardAccessInfo(cliName);
2898
2979
 
2899
2980
  console.log(colors.cyan('\n请选择操作:'));
2900
2981
  console.log(` ${colors.yellow('1')}. 状态信息`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawsetup",
3
- "version": "2.8.11",
3
+ "version": "2.8.13",
4
4
  "description": "OpenClaw 安装向导 - 智能安装、诊断、自动修复",
5
5
  "type": "module",
6
6
  "bin": {