@yemi33/minions 0.1.416 → 0.1.418

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/CHANGELOG.md CHANGED
@@ -1,12 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.416 (2026-04-06)
3
+ ## 0.1.418 (2026-04-06)
4
+
5
+ ### Features
6
+ - Convert remaining lifecycle.js safeWrite calls to mutateJsonFileLocked
7
+
8
+ ## 0.1.417 (2026-04-06)
4
9
 
5
10
  ### Features
6
11
  - Fix notes.md race condition and null guards in consolidation.js
7
12
  - Replace 5 raw status strings with WI_STATUS constants
8
13
  - Fix null crashes in lifecycle.js syncPrsFromOutput and createReviewFeedbackForAuthor
9
14
 
15
+ ### Fixes
16
+ - restart kills zombie dashboard via port-based detection
17
+
10
18
  ## 0.1.414 (2026-04-06)
11
19
 
12
20
  ### Fixes
package/bin/minions.js CHANGED
@@ -28,6 +28,42 @@ const os = require('os');
28
28
  const { spawn, execSync } = require('child_process');
29
29
 
30
30
  const PKG_ROOT = path.resolve(__dirname, '..');
31
+
32
+ /** Kill process(es) listening on a given port. Works cross-platform. */
33
+ function killByPort(port) {
34
+ try {
35
+ if (process.platform === 'win32') {
36
+ const out = execSync(`netstat -ano | findstr ":${port} " | findstr LISTENING`, { encoding: 'utf8', timeout: 5000, windowsHide: true });
37
+ const pids = new Set();
38
+ for (const line of out.split('\n')) {
39
+ const pid = line.trim().split(/\s+/).pop();
40
+ if (pid && /^\d+$/.test(pid) && pid !== '0' && pid !== String(process.pid)) pids.add(pid);
41
+ }
42
+ for (const pid of pids) try { process.kill(parseInt(pid)); } catch {}
43
+ } else {
44
+ execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null`, { timeout: 5000 });
45
+ }
46
+ } catch {}
47
+ }
48
+
49
+ /** Kill minions processes by command-line pattern matching (wmic on Windows, pkill on Unix). */
50
+ function killMinionsProcesses(patterns) {
51
+ try {
52
+ if (process.platform === 'win32') {
53
+ const out = execSync('wmic process where "name=\'node.exe\'" get processid,commandline /format:csv', { encoding: 'utf8', timeout: 10000, windowsHide: true });
54
+ for (const line of out.split('\n')) {
55
+ if (patterns.some(p => line.includes(p))) {
56
+ const pid = line.split(',').pop()?.trim();
57
+ if (pid && /^\d+$/.test(pid) && pid !== String(process.pid)) try { process.kill(parseInt(pid)); } catch {}
58
+ }
59
+ }
60
+ } else {
61
+ for (const p of patterns) {
62
+ try { execSync(`pkill -f "${p}" 2>/dev/null`, { timeout: 5000 }); } catch {}
63
+ }
64
+ }
65
+ } catch {}
66
+ }
31
67
  const DEFAULT_MINIONS_HOME = path.join(os.homedir(), '.minions');
32
68
  const ROOT_POINTER_PATH = path.join(os.homedir(), '.minions-root');
33
69
  const LEGACY_DEFAULT_SQUAD_HOME = path.join(os.homedir(), '.squad');
@@ -495,20 +531,8 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
495
531
  ensureInstalled();
496
532
  // Stop engine if running
497
533
  try { execSync(`node "${path.join(MINIONS_HOME, 'engine.js')}" stop`, { stdio: 'ignore', cwd: MINIONS_HOME }); } catch {}
498
- // Kill existing dashboard
499
- try {
500
- if (process.platform === 'win32') {
501
- const out = execSync('wmic process where "name=\'node.exe\'" get processid,commandline /format:csv', { encoding: 'utf8', timeout: 10000, windowsHide: true });
502
- for (const line of out.split('\n')) {
503
- if (line.includes('dashboard.js') && line.includes('minions')) {
504
- const pid = line.split(',').pop()?.trim();
505
- if (pid && pid !== String(process.pid)) try { process.kill(parseInt(pid)); } catch {}
506
- }
507
- }
508
- } else {
509
- try { execSync('lsof -ti:7331 | xargs kill -9 2>/dev/null', { timeout: 5000 }); } catch {}
510
- }
511
- } catch {}
534
+ // Kill existing dashboard — port-based is reliable across all setups
535
+ killByPort(7331);
512
536
  const engineProc = spawn(process.execPath, [path.join(MINIONS_HOME, 'engine.js'), 'start'], {
513
537
  cwd: MINIONS_HOME, stdio: 'ignore', detached: true, windowsHide: true
514
538
  });
@@ -550,22 +574,8 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
550
574
 
551
575
  // 1. Kill all processes
552
576
  try { execSync(`node "${path.join(MINIONS_HOME, 'engine.js')}" stop`, { stdio: 'ignore', cwd: MINIONS_HOME }); } catch {}
553
- // Kill dashboard
554
- try {
555
- if (process.platform === 'win32') {
556
- const out = execSync('wmic process where "name=\'node.exe\'" get processid,commandline /format:csv', { encoding: 'utf8', timeout: 10000, windowsHide: true });
557
- for (const line of out.split('\n')) {
558
- if (line.includes('minions') && (line.includes('engine.js') || line.includes('dashboard.js') || line.includes('spawn-agent.js'))) {
559
- const pid = line.split(',').pop()?.trim();
560
- if (pid && pid !== String(process.pid)) {
561
- try { process.kill(parseInt(pid)); } catch {}
562
- }
563
- }
564
- }
565
- } else {
566
- try { execSync('lsof -ti:7331 | xargs kill -9 2>/dev/null', { timeout: 5000 }); } catch {}
567
- }
568
- } catch {}
577
+ killByPort(7331);
578
+ killMinionsProcesses(['engine.js', 'dashboard.js', 'spawn-agent.js']);
569
579
  console.log(' Killed all processes');
570
580
 
571
581
  // 2. Delete runtime state
@@ -650,21 +660,8 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
650
660
 
651
661
  // 1. Kill all processes
652
662
  try { execSync(`node "${path.join(MINIONS_HOME, 'engine.js')}" stop`, { stdio: 'ignore', cwd: MINIONS_HOME, timeout: 10000 }); } catch {}
653
- try {
654
- if (process.platform === 'win32') {
655
- const out = execSync('wmic process where "name=\'node.exe\'" get processid,commandline /format:csv', { encoding: 'utf8', timeout: 10000, windowsHide: true });
656
- for (const line of out.split('\n')) {
657
- if (line.includes('minions') && (line.includes('engine.js') || line.includes('dashboard.js') || line.includes('spawn-agent.js'))) {
658
- const pid = line.split(',').pop()?.trim();
659
- if (pid && pid !== String(process.pid)) try { process.kill(parseInt(pid)); } catch {}
660
- }
661
- }
662
- } else {
663
- try { execSync('pkill -f "minions.*engine.js" 2>/dev/null', { timeout: 5000 }); } catch {}
664
- try { execSync('pkill -f "minions.*dashboard.js" 2>/dev/null', { timeout: 5000 }); } catch {}
665
- try { execSync('lsof -ti:7331 | xargs kill -9 2>/dev/null', { timeout: 5000 }); } catch {}
666
- }
667
- } catch {}
663
+ killByPort(7331);
664
+ killMinionsProcesses(['engine.js', 'dashboard.js', 'spawn-agent.js']);
668
665
  console.log(' Killed all processes');
669
666
 
670
667
  // 2. Remove minions-authored skills from ~/.claude/skills/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.416",
3
+ "version": "0.1.418",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"