@yeaft/webchat-agent 0.1.207 → 0.1.209

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.
@@ -10,6 +10,13 @@ import { stopAgentHeartbeat } from './heartbeat.js';
10
10
 
11
11
  const PM2_APP_NAME = 'yeaft-agent';
12
12
 
13
+ // Derive absolute paths for npm/pm2 from current node executable.
14
+ // In launchd/systemd environments, PATH may not include nvm/node dirs,
15
+ // but process.execPath always points to the running node binary.
16
+ const nodeBinDir = dirname(process.execPath);
17
+ const npmPath = join(nodeBinDir, 'npm');
18
+ const pm2Path = join(nodeBinDir, 'pm2');
19
+
13
20
  // Shared cleanup logic for restart/upgrade
14
21
  function cleanupAndExit(exitCode) {
15
22
  setTimeout(() => {
@@ -46,7 +53,7 @@ export async function handleUpgradeAgent() {
46
53
  const pkgName = ctx.pkgName || '@yeaft/webchat-agent';
47
54
  // Check latest version (async to avoid blocking heartbeat)
48
55
  const latestVersion = await new Promise((resolve, reject) => {
49
- execFile('npm', ['view', pkgName, 'version'], { stdio: 'pipe', shell: process.platform === 'win32' }, (err, stdout) => {
56
+ execFile(npmPath, ['view', pkgName, 'version'], { stdio: 'pipe' }, (err, stdout) => {
50
57
  if (err) reject(err); else resolve(stdout.toString().trim());
51
58
  });
52
59
  });
@@ -74,7 +81,7 @@ export async function handleUpgradeAgent() {
74
81
 
75
82
  // 判断全局安装 vs 局部安装
76
83
  const isGlobalInstall = await new Promise((resolve) => {
77
- execFile('npm', ['prefix', '-g'], { shell: process.platform === 'win32' }, (err, stdout) => {
84
+ execFile(npmPath, ['prefix', '-g'], (err, stdout) => {
78
85
  if (err) { resolve(false); return; }
79
86
  const globalPrefix = stdout.toString().trim().replace(/\\/g, '/');
80
87
  resolve(installDir === globalPrefix || installDir === globalPrefix + '/lib');
@@ -94,7 +101,7 @@ export async function handleUpgradeAgent() {
94
101
  const isPm2 = !!process.env.pm_id;
95
102
  if (isPm2) {
96
103
  try {
97
- execFileSync('pm2', ['delete', PM2_APP_NAME], { shell: process.platform === 'win32', stdio: 'pipe' });
104
+ execFileSync(pm2Path, ['delete', PM2_APP_NAME], { stdio: 'pipe' });
98
105
  console.log(`[Agent] PM2 app deleted to prevent auto-restart during upgrade`);
99
106
  } catch {
100
107
  console.log(`[Agent] PM2 delete skipped (app may not be registered)`);
@@ -131,6 +138,8 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
131
138
  // Determine the target package directory inside node_modules
132
139
  const pkgDir = join(installDir, 'node_modules', ...pkgName.split('/')).replace(/\//g, '\\');
133
140
 
141
+ const pm2Win = pm2Path.replace(/\//g, '\\');
142
+
134
143
  const batLines = [
135
144
  '@echo off',
136
145
  'setlocal',
@@ -178,7 +187,7 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
178
187
  // Use Node.js worker for file-level upgrade (avoids EBUSY on directory rename)
179
188
  batLines.push(
180
189
  'echo [Upgrade] Running upgrade worker at %time%... >> "%LOGFILE%"',
181
- 'node "%WORKER%" "%PKG%" "%PKG_DIR%" "%LOGFILE%"',
190
+ `"${process.execPath.replace(/\//g, '\\')}" "%WORKER%" "%PKG%" "%PKG_DIR%" "%LOGFILE%"`,
182
191
  'if not "%errorlevel%"=="0" (',
183
192
  ' echo [Upgrade] Worker failed with exit code %errorlevel% at %time% >> "%LOGFILE%"',
184
193
  ' goto CLEANUP',
@@ -193,8 +202,8 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
193
202
  batLines.push(
194
203
  'echo [Upgrade] Re-registering agent via PM2... >> "%LOGFILE%"',
195
204
  `if exist "${ecoPath}" (`,
196
- ` call pm2 start "${ecoPath}" >> "%LOGFILE%" 2>&1`,
197
- ' call pm2 save >> "%LOGFILE%" 2>&1',
205
+ ` call "${pm2Win}" start "${ecoPath}" >> "%LOGFILE%" 2>&1`,
206
+ ` call "${pm2Win}" save >> "%LOGFILE%" 2>&1`,
198
207
  ' echo [Upgrade] PM2 app re-registered at %time% >> "%LOGFILE%"',
199
208
  ') else (',
200
209
  ' echo [Upgrade] WARNING: ecosystem.config.cjs not found, PM2 not restarted >> "%LOGFILE%"',
@@ -241,12 +250,17 @@ function spawnUnixUpgradeScript(pkgName, installDir, isGlobalInstall, latestVers
241
250
  const isLaunchd = platform() === 'darwin' && existsSync(join(process.env.HOME || '', 'Library', 'LaunchAgents', 'com.yeaft.agent.plist'));
242
251
  const cwd = isGlobalInstall ? undefined : installDir;
243
252
 
253
+ // Ensure PATH includes the node bin dir (critical for launchd which has minimal PATH)
254
+ const currentPath = process.env.PATH || '/usr/bin:/bin:/usr/sbin:/sbin';
255
+ const exportPath = currentPath.includes(nodeBinDir) ? currentPath : `${nodeBinDir}:${currentPath}`;
256
+
244
257
  const shLines = [
245
258
  '#!/bin/bash',
246
259
  `PID=${pid}`,
247
260
  `PKG="${pkgName}@latest"`,
261
+ `NPM="${npmPath}"`,
248
262
  `LOGFILE="${join(configDir, 'logs', 'upgrade.log')}"`,
249
- `export PATH="${process.env.PATH}"`,
263
+ `export PATH="${exportPath}"`,
250
264
  '',
251
265
  '# Redirect all output to log file',
252
266
  'exec > "$LOGFILE" 2>&1',
@@ -285,10 +299,10 @@ function spawnUnixUpgradeScript(pkgName, installDir, isGlobalInstall, latestVers
285
299
  );
286
300
  }
287
301
 
288
- // npm install
302
+ // npm install (use absolute path via $NPM variable)
289
303
  const npmCmd = isGlobalInstall
290
- ? `npm install -g "$PKG"`
291
- : `cd "$INSTALL_DIR" && npm install "$PKG"`;
304
+ ? `"$NPM" install -g "$PKG"`
305
+ : `cd "$INSTALL_DIR" && "$NPM" install "$PKG"`;
292
306
 
293
307
  shLines.push(
294
308
  'echo "[Upgrade] Installing $PKG..."',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.207",
3
+ "version": "0.1.209",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",