yymaxapi 1.0.11 → 1.0.12
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 +107 -1
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -552,6 +552,70 @@ function syncClawdbotConfigs(paths, config) {
|
|
|
552
552
|
function writeConfigWithSync(paths, config) {
|
|
553
553
|
writeConfig(paths.openclawConfig, config);
|
|
554
554
|
syncClawdbotConfigs(paths, config);
|
|
555
|
+
syncToWsl(paths.openclawConfig);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// ============ WSL 检测与同步 ============
|
|
559
|
+
let _wslDetected = null;
|
|
560
|
+
|
|
561
|
+
function isWslAvailable() {
|
|
562
|
+
if (process.platform !== 'win32') return false;
|
|
563
|
+
if (_wslDetected !== null) return _wslDetected;
|
|
564
|
+
try {
|
|
565
|
+
const r = execFileSync('wsl', ['--status'], { encoding: 'utf8', timeout: 5000, stdio: 'pipe' });
|
|
566
|
+
_wslDetected = true;
|
|
567
|
+
} catch {
|
|
568
|
+
// wsl --status 可能返回非零但 WSL 仍可用,检查 wsl.exe 是否存在
|
|
569
|
+
try {
|
|
570
|
+
execFileSync('wsl', ['echo', 'ok'], { encoding: 'utf8', timeout: 5000, stdio: 'pipe' });
|
|
571
|
+
_wslDetected = true;
|
|
572
|
+
} catch {
|
|
573
|
+
_wslDetected = false;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return _wslDetected;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
function getWslHome() {
|
|
580
|
+
try {
|
|
581
|
+
const home = execFileSync('wsl', ['bash', '-c', 'echo $HOME'], { encoding: 'utf8', timeout: 5000 }).trim();
|
|
582
|
+
return home || null;
|
|
583
|
+
} catch { return null; }
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
function isGatewayInWsl(port = 18789) {
|
|
587
|
+
if (!isWslAvailable()) return false;
|
|
588
|
+
try {
|
|
589
|
+
// 检查占用 gateway 端口的进程是否是 wslrelay
|
|
590
|
+
const r = safeExec(`netstat -ano | findstr ":${port}"`, { timeout: 5000 });
|
|
591
|
+
if (!r.ok || !r.output) return false;
|
|
592
|
+
const lines = r.output.split('\n').filter(l => l.includes('LISTENING'));
|
|
593
|
+
for (const line of lines) {
|
|
594
|
+
const pid = line.trim().split(/\s+/).pop();
|
|
595
|
+
if (pid) {
|
|
596
|
+
const taskR = safeExec(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { timeout: 5000 });
|
|
597
|
+
if (taskR.ok && taskR.output && taskR.output.toLowerCase().includes('wslrelay')) {
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
} catch {}
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
function syncToWsl(windowsConfigPath) {
|
|
607
|
+
if (!isWslAvailable()) return;
|
|
608
|
+
try {
|
|
609
|
+
const wslHome = getWslHome();
|
|
610
|
+
if (!wslHome) return;
|
|
611
|
+
// 将 Windows 路径转为 WSL /mnt/c/ 路径
|
|
612
|
+
const winNorm = windowsConfigPath.replace(/\\/g, '/');
|
|
613
|
+
const match = winNorm.match(/^([A-Za-z]):\/(.*)/);
|
|
614
|
+
if (!match) return;
|
|
615
|
+
const wslSrc = `/mnt/${match[1].toLowerCase()}/${match[2]}`;
|
|
616
|
+
const wslDest = `${wslHome}/.openclaw/openclaw.json`;
|
|
617
|
+
execFileSync('wsl', ['bash', '-c', `mkdir -p "${wslHome}/.openclaw" && cp "${wslSrc}" "${wslDest}"`], { timeout: 10000, stdio: 'ignore' });
|
|
618
|
+
} catch { /* ignore - WSL sync is best-effort */ }
|
|
555
619
|
}
|
|
556
620
|
|
|
557
621
|
function coerceModelsRecord(value) {
|
|
@@ -2220,6 +2284,12 @@ async function testConnection(paths, args = {}) {
|
|
|
2220
2284
|
try {
|
|
2221
2285
|
execSync('taskkill /F /FI "IMAGENAME eq node.exe" /FI "STATUS eq Not Responding" 2>nul', { stdio: 'ignore' });
|
|
2222
2286
|
} catch { /* ignore */ }
|
|
2287
|
+
// WSL 内的 agent 进程也要清理
|
|
2288
|
+
if (isWslAvailable()) {
|
|
2289
|
+
try {
|
|
2290
|
+
execSync('wsl -- bash -c "pkill -f \'openclaw.*agent\' 2>/dev/null; pkill -f \'clawdbot.*agent\' 2>/dev/null; pkill -f \'moltbot.*agent\' 2>/dev/null; true"', { stdio: 'ignore', timeout: 10000 });
|
|
2291
|
+
} catch { /* ignore */ }
|
|
2292
|
+
}
|
|
2223
2293
|
} else {
|
|
2224
2294
|
// Unix: 杀掉所有 openclaw/clawdbot/moltbot agent 子进程(排除 gateway)
|
|
2225
2295
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
@@ -2371,8 +2441,44 @@ async function testConnection(paths, args = {}) {
|
|
|
2371
2441
|
|
|
2372
2442
|
// ============ 重启 Gateway ============
|
|
2373
2443
|
async function restartGateway() {
|
|
2374
|
-
console.log(chalk.cyan('\n
|
|
2444
|
+
console.log(chalk.cyan('\n正在重启 OpenClaw Gateway...'));
|
|
2445
|
+
|
|
2446
|
+
const gatewayPort = 18789;
|
|
2447
|
+
const gwInWsl = isGatewayInWsl(gatewayPort);
|
|
2448
|
+
|
|
2449
|
+
// 如果 Gateway 在 WSL 里,优先用 wsl -- 重启
|
|
2450
|
+
if (gwInWsl) {
|
|
2451
|
+
console.log(chalk.gray(' [检测] Gateway 运行在 WSL 中'));
|
|
2452
|
+
return new Promise((resolve) => {
|
|
2453
|
+
const wslCmds = [
|
|
2454
|
+
'wsl -- bash -c "openclaw gateway restart"',
|
|
2455
|
+
'wsl -- bash -c "clawdbot gateway restart"',
|
|
2456
|
+
'wsl -- bash -c "moltbot gateway restart"',
|
|
2457
|
+
];
|
|
2458
|
+
let tried = 0;
|
|
2459
|
+
const tryNext = () => {
|
|
2460
|
+
if (tried >= wslCmds.length) {
|
|
2461
|
+
console.log(chalk.yellow('⚠ WSL 内 Gateway 重启失败,尝试 Windows 原生重启...'));
|
|
2462
|
+
restartGatewayNative().then(resolve);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
const cmd = wslCmds[tried++];
|
|
2466
|
+
exec(cmd, { timeout: 30000 }, (error) => {
|
|
2467
|
+
if (error) { tryNext(); }
|
|
2468
|
+
else {
|
|
2469
|
+
console.log(chalk.green('✅ Gateway 已重启 (WSL)'));
|
|
2470
|
+
resolve();
|
|
2471
|
+
}
|
|
2472
|
+
});
|
|
2473
|
+
};
|
|
2474
|
+
tryNext();
|
|
2475
|
+
});
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
return restartGatewayNative();
|
|
2479
|
+
}
|
|
2375
2480
|
|
|
2481
|
+
async function restartGatewayNative() {
|
|
2376
2482
|
const { cliBinary: resolved, nodeMajor } = getCliMeta();
|
|
2377
2483
|
const nodeInfo = findCompatibleNode(nodeMajor);
|
|
2378
2484
|
const env = { ...process.env, PATH: extendPathEnv(nodeInfo ? nodeInfo.path : null) };
|