yymaxapi 1.0.82 → 1.0.84
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/yymaxapi.js +57 -22
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -636,6 +636,28 @@ function getWslMirrorInfo() {
|
|
|
636
636
|
return { configPath, authProfiles };
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
+
function getGatewayListenOwner(port = 18789) {
|
|
640
|
+
if (process.platform === 'win32') return null;
|
|
641
|
+
|
|
642
|
+
const lsofResult = safeExec(`lsof -nP -iTCP:${port} -sTCP:LISTEN -F u 2>/dev/null`, { timeout: 3000 });
|
|
643
|
+
const lsofOutput = [lsofResult.output, lsofResult.stdout, lsofResult.stderr].filter(Boolean).join('\n');
|
|
644
|
+
const userLine = lsofOutput
|
|
645
|
+
.split('\n')
|
|
646
|
+
.map(line => line.trim())
|
|
647
|
+
.find(line => line.startsWith('u'));
|
|
648
|
+
if (userLine && userLine.length > 1) {
|
|
649
|
+
return userLine.slice(1).trim() || null;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const pidResult = safeExec(`lsof -ti :${port} 2>/dev/null | head -n1`, { timeout: 3000 });
|
|
653
|
+
const pid = pidResult.ok ? pidResult.output.trim().split('\n')[0] : '';
|
|
654
|
+
if (!/^\d+$/.test(pid)) return null;
|
|
655
|
+
|
|
656
|
+
const ownerResult = safeExec(`ps -o user= -p ${pid} 2>/dev/null`, { timeout: 3000 });
|
|
657
|
+
if (!ownerResult.ok || !ownerResult.output) return null;
|
|
658
|
+
return ownerResult.output.trim().split(/\s+/)[0] || null;
|
|
659
|
+
}
|
|
660
|
+
|
|
639
661
|
function getConfigPath() {
|
|
640
662
|
const homeDir = os.homedir();
|
|
641
663
|
const openclawStateDir = process.env.OPENCLAW_STATE_DIR || path.join(homeDir, '.openclaw');
|
|
@@ -664,23 +686,34 @@ function getConfigPath() {
|
|
|
664
686
|
|
|
665
687
|
const candidates = [];
|
|
666
688
|
if (envConfig) candidates.push(envConfig);
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
689
|
+
const rootCandidates = [];
|
|
690
|
+
let preferRootConfig = false;
|
|
691
|
+
|
|
692
|
+
const preferredCandidates = preferMoltbot
|
|
693
|
+
? [...moltbotCandidates, ...openclawCandidates]
|
|
694
|
+
: [...openclawCandidates, ...moltbotCandidates];
|
|
672
695
|
|
|
673
696
|
// Fallback: 当前用户非 root 时,也检查 /root 下的配置(OpenClaw 常以 root 安装)
|
|
674
697
|
if (process.platform !== 'win32' && homeDir !== '/root') {
|
|
675
698
|
const rootOpenclawDir = '/root/.openclaw';
|
|
676
699
|
const rootClawdbotDir = '/root/.clawdbot';
|
|
677
|
-
|
|
700
|
+
rootCandidates.push(
|
|
678
701
|
path.join(rootOpenclawDir, 'openclaw.json'),
|
|
679
702
|
path.join(rootOpenclawDir, 'moltbot.json'),
|
|
680
703
|
path.join(rootClawdbotDir, 'openclaw.json'),
|
|
681
704
|
path.join(rootClawdbotDir, 'clawdbot.json'),
|
|
682
705
|
path.join(rootClawdbotDir, 'moltbot.json')
|
|
683
706
|
);
|
|
707
|
+
|
|
708
|
+
const rootConfigExists = rootCandidates.some(p => p && fs.existsSync(p));
|
|
709
|
+
const gatewayOwner = getGatewayListenOwner();
|
|
710
|
+
preferRootConfig = rootConfigExists && gatewayOwner === 'root';
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if (preferRootConfig) {
|
|
714
|
+
candidates.push(...rootCandidates, ...preferredCandidates);
|
|
715
|
+
} else {
|
|
716
|
+
candidates.push(...preferredCandidates, ...rootCandidates);
|
|
684
717
|
}
|
|
685
718
|
|
|
686
719
|
// Windows + WSL: 尝试读取 WSL 内的配置文件
|
|
@@ -714,18 +747,6 @@ function getConfigPath() {
|
|
|
714
747
|
|
|
715
748
|
const configDir = path.dirname(openclawConfig);
|
|
716
749
|
|
|
717
|
-
const baseAuthCandidates = buildAuthCandidates([openclawStateDir, clawdbotStateDir]);
|
|
718
|
-
const moltbotAuthCandidates = buildAuthCandidates(moltbotStateDirs);
|
|
719
|
-
|
|
720
|
-
const authCandidates = preferMoltbot
|
|
721
|
-
? [...moltbotAuthCandidates, ...baseAuthCandidates]
|
|
722
|
-
: [...baseAuthCandidates, ...moltbotAuthCandidates];
|
|
723
|
-
|
|
724
|
-
const authProfiles = authCandidates.find(p => fs.existsSync(p)) || authCandidates[0];
|
|
725
|
-
const authSyncTargets = process.platform === 'win32'
|
|
726
|
-
? [...new Set(buildAuthCandidates([openclawStateDir, clawdbotStateDir]))].filter(p => p !== authProfiles)
|
|
727
|
-
: [];
|
|
728
|
-
|
|
729
750
|
const syncTargets = [];
|
|
730
751
|
if (openclawConfig.startsWith(openclawStateDir) && fs.existsSync(clawdbotStateDir)) {
|
|
731
752
|
syncTargets.push(
|
|
@@ -734,6 +755,20 @@ function getConfigPath() {
|
|
|
734
755
|
);
|
|
735
756
|
}
|
|
736
757
|
|
|
758
|
+
const primaryAuthBases = [configDir];
|
|
759
|
+
const secondaryAuthBases = preferMoltbot
|
|
760
|
+
? [...moltbotStateDirs, openclawStateDir, clawdbotStateDir]
|
|
761
|
+
: [openclawStateDir, clawdbotStateDir, ...moltbotStateDirs];
|
|
762
|
+
const authCandidates = [...new Set(buildAuthCandidates([...primaryAuthBases, ...secondaryAuthBases]))];
|
|
763
|
+
|
|
764
|
+
const authProfiles = authCandidates.find(p => fs.existsSync(p)) || authCandidates[0];
|
|
765
|
+
|
|
766
|
+
const authSyncBaseDirs = syncTargets.map(target => path.dirname(target));
|
|
767
|
+
if (process.platform === 'win32') {
|
|
768
|
+
authSyncBaseDirs.push(openclawStateDir, clawdbotStateDir);
|
|
769
|
+
}
|
|
770
|
+
const authSyncTargets = [...new Set(buildAuthCandidates(authSyncBaseDirs))].filter(p => p !== authProfiles);
|
|
771
|
+
|
|
737
772
|
return { openclawConfig, authProfiles, configDir, syncTargets, authSyncTargets, wslConfigPath, wslAuthProfiles };
|
|
738
773
|
}
|
|
739
774
|
|
|
@@ -3826,7 +3861,7 @@ async function autoActivate(paths, args = {}) {
|
|
|
3826
3861
|
const gwToken = config.gateway?.auth?.token;
|
|
3827
3862
|
if (gwToken) {
|
|
3828
3863
|
console.log(chalk.green(`\n🌐 Web Dashboard:`));
|
|
3829
|
-
console.log(chalk.cyan(` http://127.0.0.1:${gwPort}
|
|
3864
|
+
console.log(chalk.cyan(` http://127.0.0.1:${gwPort}/#token=${gwToken}`));
|
|
3830
3865
|
}
|
|
3831
3866
|
|
|
3832
3867
|
// ---- 配置完成后:测试连接 or 退出 ----
|
|
@@ -5070,7 +5105,7 @@ async function testConnection(paths, args = {}) {
|
|
|
5070
5105
|
console.log(chalk.cyan(` CLI 对话正常,Gateway 可达`));
|
|
5071
5106
|
console.log(chalk.gray(` 注: Gateway Dashboard 通过 WebSocket 通信,REST 端点返回 405 属正常现象`));
|
|
5072
5107
|
console.log(chalk.green(`\n🌐 Web Dashboard 访问地址:`));
|
|
5073
|
-
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}
|
|
5108
|
+
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}/#token=${gatewayToken}`));
|
|
5074
5109
|
} else if (result.success) {
|
|
5075
5110
|
console.log(chalk.green(`\n✅ Gateway 测试成功!Web Dashboard 可正常使用`));
|
|
5076
5111
|
console.log(chalk.cyan(` 响应时间: ${latency}ms`));
|
|
@@ -5081,7 +5116,7 @@ async function testConnection(paths, args = {}) {
|
|
|
5081
5116
|
});
|
|
5082
5117
|
console.log(chalk.yellow(` 模型回复: ${reply}`));
|
|
5083
5118
|
console.log(chalk.green(`\n🌐 Web Dashboard 访问地址:`));
|
|
5084
|
-
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}
|
|
5119
|
+
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}/#token=${gatewayToken}`));
|
|
5085
5120
|
} else {
|
|
5086
5121
|
if (result.reachable) {
|
|
5087
5122
|
console.log(chalk.yellow(`\n⚠ Gateway HTTP 可达,但接口返回限制`));
|
|
@@ -5095,7 +5130,7 @@ async function testConnection(paths, args = {}) {
|
|
|
5095
5130
|
console.log(chalk.yellow(` 这通常会导致 Dashboard 网页对话返回 401。`));
|
|
5096
5131
|
console.log(chalk.gray(`\n 建议操作:`));
|
|
5097
5132
|
console.log(chalk.gray(` 1) 复制最新地址并重新打开浏览器(不要用旧书签)`));
|
|
5098
|
-
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}
|
|
5133
|
+
console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}/#token=${gatewayToken}`));
|
|
5099
5134
|
console.log(chalk.gray(` 2) 执行 Gateway 重启:openclaw gateway restart / clawdbot gateway restart`));
|
|
5100
5135
|
console.log(chalk.gray(` 3) 若仍 401,检查是否存在多个配置目录(.openclaw 与 .clawdbot)`));
|
|
5101
5136
|
}
|