git-watchtower 1.11.3 → 1.11.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-watchtower",
3
- "version": "1.11.3",
3
+ "version": "1.11.5",
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": {
@@ -71,8 +71,9 @@ function loadConfig(projectRoot) {
71
71
  return null;
72
72
  }
73
73
 
74
- // Migrate old format if needed
75
- return migrateConfig(raw);
74
+ // Migrate old format if needed, then validate
75
+ const migrated = migrateConfig(raw);
76
+ return validateConfig(migrated);
76
77
  }
77
78
 
78
79
  /**
@@ -336,6 +336,8 @@ async function getChangedFiles(branchName, baseBranch = 'HEAD', cwd) {
336
336
  * @returns {{added: number, deleted: number}}
337
337
  */
338
338
  function parseDiffStats(diffStatOutput) {
339
+ if (!diffStatOutput) return { added: 0, deleted: 0 };
340
+
339
341
  // Parse the summary line: "X files changed, Y insertions(+), Z deletions(-)"
340
342
  const match = diffStatOutput.match(/(\d+) insertions?\(\+\).*?(\d+) deletions?\(-\)/);
341
343
  if (match) {
@@ -318,7 +318,15 @@ class Coordinator {
318
318
  */
319
319
  _handleWorkerMessage(socket, msg, setWorkerId, getWorkerId) {
320
320
  switch (msg.type) {
321
- case 'register':
321
+ case 'register': {
322
+ // Prevent re-registration: a socket that already registered cannot change its ID
323
+ const currentId = getWorkerId();
324
+ if (currentId) break;
325
+
326
+ // Reject if this ID is already claimed by a different socket
327
+ const existingSocket = this.workerSockets.get(msg.id);
328
+ if (existingSocket && existingSocket !== socket) break;
329
+
322
330
  setWorkerId(msg.id);
323
331
  this.workerSockets.set(msg.id, socket);
324
332
  this.projects.set(msg.id, {
@@ -331,6 +339,7 @@ class Coordinator {
331
339
  this._sendMessage(socket, { type: 'registered', id: msg.id });
332
340
  this._notifyProjectsChanged();
333
341
  break;
342
+ }
334
343
 
335
344
  case 'state': {
336
345
  // Validate sender — only accept state for the worker's own registered ID
@@ -63,33 +63,9 @@ function injectLiveReload(html) {
63
63
  return html;
64
64
  }
65
65
 
66
- /**
67
- * Parse git diff --stat output into { added, deleted } counts.
68
- * @param {string} diffOutput - Output from `git diff --stat`
69
- * @returns {{ added: number, deleted: number }}
70
- */
71
- function parseDiffStats(diffOutput) {
72
- if (!diffOutput) return { added: 0, deleted: 0 };
73
-
74
- // Parse the summary line: "X files changed, Y insertions(+), Z deletions(-)"
75
- const match = diffOutput.match(/(\d+) insertions?\(\+\).*?(\d+) deletions?\(-\)/);
76
- if (match) {
77
- return { added: parseInt(match[1], 10), deleted: parseInt(match[2], 10) };
78
- }
79
-
80
- // Try to match just insertions or just deletions
81
- const insertMatch = diffOutput.match(/(\d+) insertions?\(\+\)/);
82
- const deleteMatch = diffOutput.match(/(\d+) deletions?\(-\)/);
83
- return {
84
- added: insertMatch ? parseInt(insertMatch[1], 10) : 0,
85
- deleted: deleteMatch ? parseInt(deleteMatch[1], 10) : 0,
86
- };
87
- }
88
-
89
66
  module.exports = {
90
67
  MIME_TYPES,
91
68
  getMimeType,
92
69
  LIVE_RELOAD_SCRIPT,
93
70
  injectLiveReload,
94
- parseDiffStats,
95
71
  };