@yeaft/webchat-agent 0.1.135 → 0.1.137-release

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/cli.js CHANGED
@@ -178,10 +178,26 @@ function upgradeWindows(latestVersion) {
178
178
  const logDir = join(configDir, 'logs');
179
179
  mkdirSync(logDir, { recursive: true });
180
180
  const batPath = join(configDir, 'upgrade-cli.bat');
181
+ const vbsPath = join(configDir, 'upgrade-cli.vbs');
181
182
  const logPath = join(logDir, 'upgrade.log');
182
183
  const pid = process.pid;
183
184
  const pkgSpec = `${pkg.name}@${latestVersion}`;
184
185
 
186
+ // --- PM2 handling: delete app before exit to prevent auto-restart ---
187
+ let isPm2 = false;
188
+ const ecoPath = join(configDir, 'ecosystem.config.cjs');
189
+ try {
190
+ const pm2List = execSync('pm2 jlist', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
191
+ const apps = JSON.parse(pm2List);
192
+ isPm2 = Array.isArray(apps) && apps.some(app => app.name === 'yeaft-agent');
193
+ if (isPm2) {
194
+ execSync('pm2 delete yeaft-agent', { stdio: 'pipe' });
195
+ console.log('PM2 app deleted to prevent auto-restart during upgrade.');
196
+ }
197
+ } catch {
198
+ // PM2 not installed or not managing yeaft-agent — continue
199
+ }
200
+
185
201
  const batLines = [
186
202
  '@echo off',
187
203
  'setlocal',
@@ -195,6 +211,8 @@ function upgradeWindows(latestVersion) {
195
211
  'cd /d "%TEMP%"',
196
212
  '',
197
213
  'echo [Upgrade] Started at %date% %time% > "%LOGFILE%"',
214
+ `echo [Upgrade] Version: ${pkg.version} -> ${latestVersion} >> "%LOGFILE%"`,
215
+ `echo [Upgrade] PM2 managed: ${isPm2 ? 'yes (deleted pre-exit)' : 'no'} >> "%LOGFILE%"`,
198
216
  'echo [Upgrade] Waiting for CLI process (PID %PID%) to exit... >> "%LOGFILE%"',
199
217
  '',
200
218
  ':WAIT_LOOP',
@@ -202,34 +220,71 @@ function upgradeWindows(latestVersion) {
202
220
  'if errorlevel 1 goto PID_EXITED',
203
221
  'set /A COUNT+=1',
204
222
  'if %COUNT% GEQ %MAX_WAIT% (',
205
- ' echo [Upgrade] Timeout waiting for PID %PID% to exit after %MAX_WAIT% iterations >> "%LOGFILE%"',
223
+ ' echo [Upgrade] Timeout waiting for PID %PID% to exit after %MAX_WAIT%s >> "%LOGFILE%"',
206
224
  ' goto PID_EXITED',
207
225
  ')',
208
226
  'ping -n 3 127.0.0.1 >NUL',
209
227
  'goto WAIT_LOOP',
210
228
  ':PID_EXITED',
211
229
  '',
212
- 'echo [Upgrade] Process exited, running npm install -g %PKG%... >> "%LOGFILE%"',
230
+ ':: Extra wait for file locks to release',
231
+ 'echo [Upgrade] Process exited at %time%, waiting for file locks... >> "%LOGFILE%"',
232
+ 'ping -n 5 127.0.0.1 >NUL',
233
+ '',
234
+ 'echo [Upgrade] Running npm install -g %PKG%... >> "%LOGFILE%"',
213
235
  'call npm install -g %PKG% >> "%LOGFILE%" 2>&1',
214
236
  'if not "%errorlevel%"=="0" (',
215
- ' echo [Upgrade] npm install failed with exit code %errorlevel% >> "%LOGFILE%"',
216
- ' goto END',
237
+ ' echo [Upgrade] npm install failed with exit code %errorlevel% at %time% >> "%LOGFILE%"',
238
+ ' goto PM2_RESTART',
217
239
  ')',
218
- 'echo [Upgrade] Successfully upgraded. >> "%LOGFILE%"',
240
+ 'echo [Upgrade] npm install succeeded at %time% >> "%LOGFILE%"',
241
+ ];
242
+
243
+ // PM2 re-registration after successful upgrade
244
+ batLines.push(
219
245
  '',
220
- ':END',
246
+ ':PM2_RESTART',
247
+ );
248
+ if (isPm2) {
249
+ batLines.push(
250
+ 'echo [Upgrade] Re-registering agent via PM2... >> "%LOGFILE%"',
251
+ `if exist "${ecoPath}" (`,
252
+ ` call pm2 start "${ecoPath}" >> "%LOGFILE%" 2>&1`,
253
+ ' call pm2 save >> "%LOGFILE%" 2>&1',
254
+ ' echo [Upgrade] PM2 app re-registered at %time% >> "%LOGFILE%"',
255
+ ') else (',
256
+ ' echo [Upgrade] WARNING: ecosystem.config.cjs not found, PM2 not restarted >> "%LOGFILE%"',
257
+ ')',
258
+ );
259
+ }
260
+
261
+ batLines.push(
262
+ '',
263
+ 'echo [Upgrade] Finished at %time% >> "%LOGFILE%"',
264
+ ':CLEANUP',
265
+ `del /F /Q "${vbsPath}" 2>NUL`,
221
266
  `del /F /Q "${batPath}" 2>NUL`,
222
- ];
267
+ );
223
268
 
224
269
  writeFileSync(batPath, batLines.join('\r\n'));
225
- const child = spawn('cmd.exe', ['/c', batPath], {
270
+
271
+ // Use VBScript wrapper to fully detach the bat process from the parent.
272
+ // WshShell.Run with 0 (hidden window) and False (don't wait) ensures the bat
273
+ // runs completely independently — survives parent exit, no console window flash.
274
+ const vbsLines = [
275
+ 'Set WshShell = CreateObject("WScript.Shell")',
276
+ `WshShell.Run """${batPath}""", 0, False`,
277
+ ];
278
+ writeFileSync(vbsPath, vbsLines.join('\r\n'));
279
+
280
+ spawn('wscript.exe', [vbsPath], {
226
281
  detached: true,
227
282
  stdio: 'ignore',
228
283
  windowsHide: true,
229
- });
230
- child.unref();
231
- console.log(`Upgrade script spawned. This process will exit now.`);
232
- console.log(`The upgrade will proceed after this process exits.`);
284
+ }).unref();
285
+
286
+ console.log(`Upgrade script spawned via VBScript wrapper.`);
287
+ console.log(`This process will exit now. The upgrade will proceed after exit.`);
233
288
  console.log(`Check upgrade log: ${logPath}`);
234
289
  process.exit(0);
235
290
  }
@@ -116,6 +116,7 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
116
116
  const logDir = join(configDir, 'logs');
117
117
  mkdirSync(logDir, { recursive: true });
118
118
  const batPath = join(configDir, 'upgrade.bat');
119
+ const vbsPath = join(configDir, 'upgrade.vbs');
119
120
  const logPath = join(logDir, 'upgrade.log');
120
121
  const isPm2 = !!process.env.pm_id;
121
122
  const installDirWin = installDir.replace(/\//g, '\\');
@@ -145,18 +146,21 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
145
146
  ':: Change to temp dir to avoid EBUSY on cwd',
146
147
  'cd /d "%TEMP%"',
147
148
  '',
148
- ':: Redirect all output to log file',
149
149
  'echo [Upgrade] Started at %date% %time% > "%LOGFILE%"',
150
+ `echo [Upgrade] Version: ${ctx.agentVersion} -> ${latestVersion} >> "%LOGFILE%"`,
151
+ `echo [Upgrade] PM2 managed: ${isPm2 ? 'yes (deleted pre-exit)' : 'no'} >> "%LOGFILE%"`,
152
+ `echo [Upgrade] Install dir: ${installDirWin} >> "%LOGFILE%"`,
150
153
  ];
151
154
 
152
155
  // Wait for old process to exit (PM2 already deleted before exit, so no auto-restart race)
153
156
  batLines.push(
157
+ 'echo [Upgrade] Waiting for PID %PID% to exit... >> "%LOGFILE%"',
154
158
  ':WAIT_LOOP',
155
159
  'tasklist /FI "PID eq %PID%" /NH 2>NUL | findstr /C:"%PID%" >NUL',
156
160
  'if errorlevel 1 goto PID_EXITED',
157
161
  'set /A COUNT+=1',
158
162
  'if %COUNT% GEQ %MAX_WAIT% (',
159
- ' echo [Upgrade] Timeout waiting for PID %PID% to exit after %MAX_WAIT% iterations >> "%LOGFILE%"',
163
+ ' echo [Upgrade] Timeout waiting for PID %PID% to exit after %MAX_WAIT%s >> "%LOGFILE%"',
160
164
  ' goto PID_EXITED',
161
165
  ')',
162
166
  'ping -n 3 127.0.0.1 >NUL',
@@ -165,21 +169,21 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
165
169
  );
166
170
 
167
171
  // No need to pm2 stop — PM2 app was already deleted before process exit.
168
- // Wait a moment for file locks to release.
172
+ // Wait extra time for file locks to fully release.
169
173
  batLines.push(
170
- 'echo [Upgrade] Process exited, waiting for file locks... >> "%LOGFILE%"',
171
- 'ping -n 3 127.0.0.1 >NUL',
174
+ 'echo [Upgrade] Process exited at %time%, waiting for file locks... >> "%LOGFILE%"',
175
+ 'ping -n 5 127.0.0.1 >NUL',
172
176
  );
173
177
 
174
178
  // Use Node.js worker for file-level upgrade (avoids EBUSY on directory rename)
175
179
  batLines.push(
176
- 'echo [Upgrade] Running upgrade worker... >> "%LOGFILE%"',
180
+ 'echo [Upgrade] Running upgrade worker at %time%... >> "%LOGFILE%"',
177
181
  'node "%WORKER%" "%PKG%" "%PKG_DIR%" "%LOGFILE%"',
178
182
  'if not "%errorlevel%"=="0" (',
179
- ' echo [Upgrade] Worker failed with exit code %errorlevel% >> "%LOGFILE%"',
183
+ ' echo [Upgrade] Worker failed with exit code %errorlevel% at %time% >> "%LOGFILE%"',
180
184
  ' goto CLEANUP',
181
185
  ')',
182
- 'echo [Upgrade] Worker completed successfully >> "%LOGFILE%"',
186
+ 'echo [Upgrade] Worker completed successfully at %time% >> "%LOGFILE%"',
183
187
  );
184
188
 
185
189
  batLines.push(':CLEANUP');
@@ -187,26 +191,44 @@ function spawnWindowsUpgradeScript(pkgName, installDir, isGlobalInstall, latestV
187
191
  if (isPm2) {
188
192
  // Re-register and start via ecosystem config (PM2 app was deleted pre-exit)
189
193
  batLines.push(
190
- 'echo [Upgrade] Re-registering agent via pm2... >> "%LOGFILE%"',
191
- `call pm2 start "${ecoPath}" >> "%LOGFILE%" 2>&1`,
192
- 'call pm2 save >> "%LOGFILE%" 2>&1',
194
+ 'echo [Upgrade] Re-registering agent via PM2... >> "%LOGFILE%"',
195
+ `if exist "${ecoPath}" (`,
196
+ ` call pm2 start "${ecoPath}" >> "%LOGFILE%" 2>&1`,
197
+ ' call pm2 save >> "%LOGFILE%" 2>&1',
198
+ ' echo [Upgrade] PM2 app re-registered at %time% >> "%LOGFILE%"',
199
+ ') else (',
200
+ ' echo [Upgrade] WARNING: ecosystem.config.cjs not found, PM2 not restarted >> "%LOGFILE%"',
201
+ ')',
193
202
  );
194
203
  }
195
204
 
196
- // Clean up worker and bat script
205
+ // Clean up worker, vbs launcher, and bat script
197
206
  batLines.push(
207
+ '',
208
+ 'echo [Upgrade] Finished at %time% >> "%LOGFILE%"',
198
209
  `del /F /Q "${workerDst}" 2>NUL`,
210
+ `del /F /Q "${vbsPath}" 2>NUL`,
199
211
  `del /F /Q "${batPath}"`,
200
212
  );
201
213
 
202
214
  writeFileSync(batPath, batLines.join('\r\n'));
203
- const child = spawn('cmd.exe', ['/c', batPath], {
215
+
216
+ // Use VBScript wrapper to fully detach the bat process from the parent.
217
+ // WshShell.Run with 0 (hidden window) and False (don't wait) ensures the bat
218
+ // runs completely independently — survives parent exit, no console window flash.
219
+ const vbsLines = [
220
+ 'Set WshShell = CreateObject("WScript.Shell")',
221
+ `WshShell.Run """${batPath}""", 0, False`,
222
+ ];
223
+ writeFileSync(vbsPath, vbsLines.join('\r\n'));
224
+
225
+ spawn('wscript.exe', [vbsPath], {
204
226
  detached: true,
205
227
  stdio: 'ignore',
206
228
  windowsHide: true,
207
- });
208
- child.unref();
209
- console.log(`[Agent] Spawned upgrade script (PID wait for ${pid}, pm2=${isPm2}, dir=${installDir}): ${batPath}`);
229
+ }).unref();
230
+
231
+ console.log(`[Agent] Spawned upgrade via VBScript (PID wait for ${pid}, pm2=${isPm2}, dir=${installDir}): ${batPath}`);
210
232
  sendToServer({ type: 'upgrade_agent_ack', success: true, version: latestVersion, pendingRestart: true });
211
233
  }
212
234
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.135",
3
+ "version": "0.1.137-release",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",