@yeaft/webchat-agent 0.0.37 → 0.0.38
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/connection.js +96 -13
- package/package.json +1 -1
package/connection.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
2
|
import { execSync, execFile, spawn } from 'child_process';
|
|
3
|
-
import { writeFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { writeFileSync, mkdirSync, existsSync, cpSync, rmSync } from 'fs';
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import { platform } from 'os';
|
|
6
6
|
import ctx from './context.js';
|
|
@@ -371,12 +371,13 @@ async function handleMessage(msg) {
|
|
|
371
371
|
// 例如 C:/Users/x/myproject/node_modules/@yeaft/webchat-agent/cli.js → C:/Users/x/myproject
|
|
372
372
|
const installDir = scriptPath.substring(0, nmIndex);
|
|
373
373
|
|
|
374
|
-
// 判断全局安装 vs
|
|
374
|
+
// 判断全局安装 vs 局部安装
|
|
375
|
+
// npm 全局 node_modules: prefix/lib/node_modules (Linux/macOS) 或 prefix/node_modules (Windows)
|
|
375
376
|
const isGlobalInstall = await new Promise((resolve) => {
|
|
376
377
|
execFile('npm', ['prefix', '-g'], { shell: true }, (err, stdout) => {
|
|
377
378
|
if (err) { resolve(false); return; }
|
|
378
379
|
const globalPrefix = stdout.toString().trim().replace(/\\/g, '/');
|
|
379
|
-
resolve(installDir === globalPrefix);
|
|
380
|
+
resolve(installDir === globalPrefix || installDir === globalPrefix + '/lib');
|
|
380
381
|
});
|
|
381
382
|
});
|
|
382
383
|
|
|
@@ -459,18 +460,100 @@ async function handleMessage(msg) {
|
|
|
459
460
|
console.log(`[Agent] Spawned upgrade script (PID wait for ${pid}, pm2=${isPm2}, dir=${installDir}): ${batPath}`);
|
|
460
461
|
sendToServer({ type: 'upgrade_agent_ack', success: true, version: latestVersion, pendingRestart: true });
|
|
461
462
|
} else {
|
|
462
|
-
// Linux/macOS:
|
|
463
|
+
// Linux/macOS: 生成 detached shell 脚本,先停止服务再升级再启动
|
|
464
|
+
// 避免在升级过程中 systemd 不断重启已删除的旧版本
|
|
465
|
+
const pid = process.pid;
|
|
466
|
+
const configDir = getConfigDir();
|
|
467
|
+
mkdirSync(configDir, { recursive: true });
|
|
468
|
+
const shPath = join(configDir, 'upgrade.sh');
|
|
469
|
+
const isSystemd = existsSync(join(process.env.HOME || '', '.config', 'systemd', 'user', 'yeaft-agent.service'));
|
|
470
|
+
const isLaunchd = platform() === 'darwin' && existsSync(join(process.env.HOME || '', 'Library', 'LaunchAgents', 'com.yeaft.agent.plist'));
|
|
463
471
|
const cwd = isGlobalInstall ? undefined : installDir;
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
472
|
+
|
|
473
|
+
const shLines = [
|
|
474
|
+
'#!/bin/bash',
|
|
475
|
+
`PID=${pid}`,
|
|
476
|
+
`PKG="${pkgName}@${latestVersion}"`,
|
|
477
|
+
...(cwd ? [`INSTALL_DIR="${cwd}"`] : []),
|
|
478
|
+
'',
|
|
479
|
+
'# Wait for current process to exit',
|
|
480
|
+
'COUNT=0',
|
|
481
|
+
'while kill -0 $PID 2>/dev/null; do',
|
|
482
|
+
' COUNT=$((COUNT+1))',
|
|
483
|
+
' if [ $COUNT -ge 30 ]; then',
|
|
484
|
+
' echo "[Upgrade] Timeout waiting for PID $PID to exit"',
|
|
485
|
+
' break',
|
|
486
|
+
' fi',
|
|
487
|
+
' sleep 2',
|
|
488
|
+
'done',
|
|
489
|
+
'',
|
|
490
|
+
];
|
|
491
|
+
|
|
492
|
+
// 停止服务管理器的自动重启
|
|
493
|
+
if (isSystemd) {
|
|
494
|
+
shLines.push(
|
|
495
|
+
'# Stop systemd service to prevent restart loop',
|
|
496
|
+
'systemctl --user stop yeaft-agent 2>/dev/null',
|
|
497
|
+
'sleep 1',
|
|
498
|
+
'',
|
|
499
|
+
);
|
|
500
|
+
} else if (isLaunchd) {
|
|
501
|
+
const plistPath = join(process.env.HOME || '', 'Library', 'LaunchAgents', 'com.yeaft.agent.plist');
|
|
502
|
+
shLines.push(
|
|
503
|
+
'# Unload launchd service to prevent restart loop',
|
|
504
|
+
`launchctl unload "${plistPath}" 2>/dev/null`,
|
|
505
|
+
'sleep 1',
|
|
506
|
+
'',
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// npm install
|
|
511
|
+
const npmCmd = isGlobalInstall
|
|
512
|
+
? `npm install -g "$PKG"`
|
|
513
|
+
: `cd "$INSTALL_DIR" && npm install "$PKG"`;
|
|
514
|
+
|
|
515
|
+
shLines.push(
|
|
516
|
+
'echo "[Upgrade] Installing $PKG..."',
|
|
517
|
+
npmCmd,
|
|
518
|
+
'EXIT_CODE=$?',
|
|
519
|
+
'if [ $EXIT_CODE -ne 0 ]; then',
|
|
520
|
+
' echo "[Upgrade] npm install failed with exit code $EXIT_CODE"',
|
|
521
|
+
'else',
|
|
522
|
+
' echo "[Upgrade] Successfully installed $PKG"',
|
|
523
|
+
'fi',
|
|
524
|
+
'',
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
// 重新启动服务
|
|
528
|
+
if (isSystemd) {
|
|
529
|
+
shLines.push(
|
|
530
|
+
'# Restart systemd service',
|
|
531
|
+
'systemctl --user start yeaft-agent',
|
|
532
|
+
'echo "[Upgrade] Service restarted via systemd"',
|
|
533
|
+
);
|
|
534
|
+
} else if (isLaunchd) {
|
|
535
|
+
const plistPath = join(process.env.HOME || '', 'Library', 'LaunchAgents', 'com.yeaft.agent.plist');
|
|
536
|
+
shLines.push(
|
|
537
|
+
'# Reload launchd service',
|
|
538
|
+
`launchctl load "${plistPath}"`,
|
|
539
|
+
'echo "[Upgrade] Service restarted via launchd"',
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// 清理脚本自身
|
|
544
|
+
shLines.push('', `rm -f "${shPath}"`);
|
|
545
|
+
|
|
546
|
+
writeFileSync(shPath, shLines.join('\n'), { mode: 0o755 });
|
|
547
|
+
const child = spawn('bash', [shPath], {
|
|
548
|
+
detached: true,
|
|
549
|
+
stdio: 'ignore',
|
|
468
550
|
});
|
|
469
|
-
|
|
470
|
-
|
|
551
|
+
child.unref();
|
|
552
|
+
console.log(`[Agent] Spawned upgrade script: ${shPath}`);
|
|
553
|
+
sendToServer({ type: 'upgrade_agent_ack', success: true, version: latestVersion, pendingRestart: true });
|
|
471
554
|
}
|
|
472
555
|
|
|
473
|
-
//
|
|
556
|
+
// 清理并退出,让升级脚本接管
|
|
474
557
|
setTimeout(() => {
|
|
475
558
|
for (const [, term] of ctx.terminals) {
|
|
476
559
|
if (term.pty) { try { term.pty.kill(); } catch {} }
|
|
@@ -488,8 +571,8 @@ async function handleMessage(msg) {
|
|
|
488
571
|
ctx.ws.close();
|
|
489
572
|
}
|
|
490
573
|
clearTimeout(ctx.reconnectTimer);
|
|
491
|
-
console.log('[Agent] Cleanup done, exiting...');
|
|
492
|
-
process.exit(
|
|
574
|
+
console.log('[Agent] Cleanup done, exiting for upgrade...');
|
|
575
|
+
process.exit(0);
|
|
493
576
|
}, 500);
|
|
494
577
|
} catch (e) {
|
|
495
578
|
console.error('[Agent] Upgrade failed:', e.message);
|