git-watchtower 1.14.7 → 1.14.8

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.
@@ -3390,9 +3390,34 @@ function restartProcess() {
3390
3390
  restoreTerminalTitle();
3391
3391
  if (process.stdin.isTTY) process.stdin.setRawMode(false);
3392
3392
 
3393
- // Stop server, watcher, polling
3394
- if (fileWatcher) fileWatcher.close();
3395
- if (pollIntervalId) clearTimeout(pollIntervalId);
3393
+ // Silence the parent before the replacement takes over the TTY. The parent
3394
+ // stays alive waiting on child.on('close') to forward the exit code, and
3395
+ // stdio is inherited — so any stray listener here will race with the child
3396
+ // (keystrokes consumed twice, render() drawing frames on top of the child's
3397
+ // UI, Ctrl+C intercepted by both, etc.).
3398
+ try { process.stdin.removeAllListeners('data'); } catch (_) { /* stdin may be detached */ }
3399
+ try { process.stdin.pause(); } catch (_) { /* stdin may already be paused */ }
3400
+ try { process.stdout.removeAllListeners('resize'); } catch (_) { /* stdout may be detached */ }
3401
+ try { process.removeAllListeners('SIGWINCH'); } catch (_) { /* no SIGWINCH handler registered */ }
3402
+ try { process.removeAllListeners('SIGINT'); } catch (_) { /* no SIGINT handler registered */ }
3403
+ try { process.removeAllListeners('SIGTERM'); } catch (_) { /* no SIGTERM handler registered */ }
3404
+
3405
+ // Stop every scheduler that can trigger a render while we're waiting on the
3406
+ // child. periodicUpdateCheck in particular will fire render() on completion
3407
+ // and would draw over the replacement's frames.
3408
+ if (pollIntervalId) {
3409
+ try { clearTimeout(pollIntervalId); } catch (_) { /* defensive */ }
3410
+ pollIntervalId = null;
3411
+ }
3412
+ if (periodicUpdateCheck) {
3413
+ try { periodicUpdateCheck.stop(); } catch (_) { /* interval may already be cleared */ }
3414
+ }
3415
+ if (fileWatcher) {
3416
+ try { fileWatcher.close(); } catch (_) { /* watcher may already be closed */ }
3417
+ fileWatcher = null;
3418
+ }
3419
+
3420
+ // Stop server, SSE clients, web dashboard
3396
3421
  if (SERVER_MODE === 'command') stopServerProcess();
3397
3422
  else if (SERVER_MODE === 'static') {
3398
3423
  clients.forEach(client => client.end());
@@ -3408,6 +3433,12 @@ function restartProcess() {
3408
3433
  monitorLockFile = null;
3409
3434
  }
3410
3435
 
3436
+ // The parent's 'exit' handler (process.on('exit', cleanupResources)) writes
3437
+ // ANSI escapes — showCursor / restoreScreen — to the shared TTY. Once the
3438
+ // child owns the screen those writes would corrupt its UI on parent exit,
3439
+ // so mark cleanup as already done.
3440
+ _resourcesCleaned = true;
3441
+
3411
3442
  console.log('\n♻ Restarting git-watchtower...\n');
3412
3443
 
3413
3444
  const { spawn: spawnChild } = require('child_process');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-watchtower",
3
- "version": "1.14.7",
3
+ "version": "1.14.8",
4
4
  "description": "Terminal-based Git branch monitor with activity sparklines and optional dev server with live reload",
5
5
  "main": "bin/git-watchtower.js",
6
6
  "bin": {