@yemi33/minions 0.1.1565 → 0.1.1567
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 +5 -0
- package/dashboard/js/render-plans.js +11 -3
- package/dashboard.js +75 -60
- package/engine/ado.js +6 -0
- package/engine/github.js +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -574,8 +574,12 @@ async function planApprove(file, btn) {
|
|
|
574
574
|
|
|
575
575
|
async function planDelete(file) {
|
|
576
576
|
_stopPlanPoll();
|
|
577
|
-
|
|
578
|
-
|
|
577
|
+
var isPrd = file.endsWith('.json');
|
|
578
|
+
var confirmMsg = isPrd
|
|
579
|
+
? 'Delete PRD "' + file + '"? This cannot be undone. The source plan will be kept.'
|
|
580
|
+
: 'Delete plan "' + file + '"? This cannot be undone.';
|
|
581
|
+
if (!confirm(confirmMsg)) return;
|
|
582
|
+
showToast('cmd-toast', isPrd ? 'PRD deleted' : 'Plan deleted', true);
|
|
579
583
|
markDeleted('plan:' + file);
|
|
580
584
|
try { closeModal(); } catch { /* may not be open */ }
|
|
581
585
|
if (window._lastPlans) renderPlans(window._lastPlans);
|
|
@@ -593,7 +597,11 @@ async function planDelete(file) {
|
|
|
593
597
|
showToast('cmd-toast', 'Delete failed: ' + (d.error || 'unknown'), false);
|
|
594
598
|
refresh(); // revert optimistic
|
|
595
599
|
}
|
|
596
|
-
} catch (e) {
|
|
600
|
+
} catch (e) {
|
|
601
|
+
clearDeleted('plan:' + file);
|
|
602
|
+
showToast('cmd-toast', 'Error: ' + e.message, false);
|
|
603
|
+
refresh();
|
|
604
|
+
}
|
|
597
605
|
}
|
|
598
606
|
|
|
599
607
|
async function planArchive(file, btn) {
|
package/dashboard.js
CHANGED
|
@@ -5521,71 +5521,86 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5521
5521
|
}
|
|
5522
5522
|
});
|
|
5523
5523
|
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
const { exec } = require('child_process');
|
|
5534
|
-
try {
|
|
5535
|
-
if (process.platform === 'win32') {
|
|
5536
|
-
exec(`start "" "http://localhost:${PORT}"`);
|
|
5537
|
-
} else if (process.platform === 'darwin') {
|
|
5538
|
-
exec(`open http://localhost:${PORT}`);
|
|
5539
|
-
} else {
|
|
5540
|
-
exec(`xdg-open http://localhost:${PORT}`);
|
|
5541
|
-
}
|
|
5542
|
-
} catch (e) {
|
|
5543
|
-
console.log(` Could not auto-open browser: ${e.message}`);
|
|
5544
|
-
console.log(` Please open http://localhost:${PORT} manually.`);
|
|
5545
|
-
}
|
|
5524
|
+
// Exported for testing — pure helpers with no hidden side effects.
|
|
5525
|
+
// Production entry points use the closures directly; tests import via require('./dashboard').
|
|
5526
|
+
module.exports = {
|
|
5527
|
+
getMcpServers,
|
|
5528
|
+
_filterCcTabSessions,
|
|
5529
|
+
_getVersionCheckInterval,
|
|
5530
|
+
_parseWatchInterval,
|
|
5531
|
+
parsePinnedEntries,
|
|
5532
|
+
};
|
|
5546
5533
|
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5534
|
+
// Start the HTTP server only when run directly (node dashboard.js).
|
|
5535
|
+
// When required as a module (e.g. by unit tests), skip the listen/watchdog/signal
|
|
5536
|
+
// handlers so tests can import exported helpers without binding to port 7331.
|
|
5537
|
+
if (require.main === module) {
|
|
5538
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
5539
|
+
console.log(`\n Minions Mission Control`);
|
|
5540
|
+
console.log(` -----------------------------------`);
|
|
5541
|
+
console.log(` http://localhost:${PORT}`);
|
|
5542
|
+
console.log(`\n Watching:`);
|
|
5543
|
+
console.log(` Minions dir: ${MINIONS_DIR}`);
|
|
5544
|
+
console.log(` Projects: ${PROJECTS.map(p => `${p.name} (${p.localPath})`).join(', ')}`);
|
|
5545
|
+
console.log(`\n Auto-refreshes every 4s. Ctrl+C to stop.\n`);
|
|
5546
|
+
|
|
5547
|
+
const { exec } = require('child_process');
|
|
5552
5548
|
try {
|
|
5553
|
-
|
|
5554
|
-
|
|
5549
|
+
if (process.platform === 'win32') {
|
|
5550
|
+
exec(`start "" "http://localhost:${PORT}"`);
|
|
5551
|
+
} else if (process.platform === 'darwin') {
|
|
5552
|
+
exec(`open http://localhost:${PORT}`);
|
|
5553
|
+
} else {
|
|
5554
|
+
exec(`xdg-open http://localhost:${PORT}`);
|
|
5555
|
+
}
|
|
5556
|
+
} catch (e) {
|
|
5557
|
+
console.log(` Could not auto-open browser: ${e.message}`);
|
|
5558
|
+
console.log(` Please open http://localhost:${PORT} manually.`);
|
|
5559
|
+
}
|
|
5555
5560
|
|
|
5556
|
-
|
|
5557
|
-
|
|
5561
|
+
// ─── Engine Watchdog ─────────────────────────────────────────────────────
|
|
5562
|
+
// Every 30s, check if engine PID is alive. If dead but control.json says
|
|
5563
|
+
// running, auto-restart it. Prevents silent engine death.
|
|
5564
|
+
const { execSync } = require('child_process');
|
|
5565
|
+
setInterval(() => {
|
|
5558
5566
|
try {
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
+
const control = getEngineState();
|
|
5568
|
+
if (control.state !== 'running' || !control.pid) return;
|
|
5569
|
+
|
|
5570
|
+
// Check if PID is alive
|
|
5571
|
+
let alive = false;
|
|
5572
|
+
try {
|
|
5573
|
+
if (process.platform === 'win32') {
|
|
5574
|
+
const out = execSync(`tasklist /FI "PID eq ${control.pid}" /NH`, { encoding: 'utf8', timeout: 3000, windowsHide: true });
|
|
5575
|
+
alive = out.includes(String(control.pid));
|
|
5576
|
+
} else {
|
|
5577
|
+
process.kill(control.pid, 0); // signal 0 = check existence
|
|
5578
|
+
alive = true;
|
|
5579
|
+
}
|
|
5580
|
+
} catch { alive = false; }
|
|
5567
5581
|
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5582
|
+
if (!alive) {
|
|
5583
|
+
console.log(`[watchdog] Engine PID ${control.pid} is dead — auto-restarting...`);
|
|
5584
|
+
restartEngine();
|
|
5585
|
+
}
|
|
5586
|
+
} catch (e) {
|
|
5587
|
+
console.error(`[watchdog] Error: ${e.message}`);
|
|
5571
5588
|
}
|
|
5572
|
-
}
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
}, 30000);
|
|
5576
|
-
console.log(` Engine watchdog: active (checks every 30s)`);
|
|
5577
|
-
});
|
|
5589
|
+
}, 30000);
|
|
5590
|
+
console.log(` Engine watchdog: active (checks every 30s)`);
|
|
5591
|
+
});
|
|
5578
5592
|
|
|
5579
|
-
server.on('error', e => {
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
});
|
|
5593
|
+
server.on('error', e => {
|
|
5594
|
+
if (e.code === 'EADDRINUSE') {
|
|
5595
|
+
console.error(`\n Port ${PORT} already in use. Kill the existing process or change PORT.\n`);
|
|
5596
|
+
} else {
|
|
5597
|
+
console.error(e);
|
|
5598
|
+
}
|
|
5599
|
+
process.exit(1);
|
|
5600
|
+
});
|
|
5587
5601
|
|
|
5588
|
-
// ── Graceful shutdown: flush debounced writes ──────────────────────────────
|
|
5589
|
-
server.on('close', () => flushPendingDocSessions());
|
|
5590
|
-
process.on('SIGTERM', () => { flushPendingDocSessions(); process.exit(0); });
|
|
5591
|
-
process.on('SIGINT', () => { flushPendingDocSessions(); process.exit(0); });
|
|
5602
|
+
// ── Graceful shutdown: flush debounced writes ──────────────────────────────
|
|
5603
|
+
server.on('close', () => flushPendingDocSessions());
|
|
5604
|
+
process.on('SIGTERM', () => { flushPendingDocSessions(); process.exit(0); });
|
|
5605
|
+
process.on('SIGINT', () => { flushPendingDocSessions(); process.exit(0); });
|
|
5606
|
+
}
|
package/engine/ado.js
CHANGED
|
@@ -430,6 +430,12 @@ async function pollPrStatus(config) {
|
|
|
430
430
|
if (newReviewStatus === 'approved') {
|
|
431
431
|
delete pr._reviewFixCycles;
|
|
432
432
|
delete pr._evalEscalated;
|
|
433
|
+
// Teams notification for PR approval — non-blocking, edge-triggered (only on transition)
|
|
434
|
+
try {
|
|
435
|
+
const teams = require('./teams');
|
|
436
|
+
const prFilePath = shared.projectPrPath(project);
|
|
437
|
+
teams.teamsNotifyPrEvent(pr, 'pr-approved', project, prFilePath).catch(() => {});
|
|
438
|
+
} catch {}
|
|
433
439
|
}
|
|
434
440
|
}
|
|
435
441
|
|
package/engine/github.js
CHANGED
|
@@ -414,6 +414,12 @@ async function pollPrStatus(config) {
|
|
|
414
414
|
if (newReviewStatus === 'approved') {
|
|
415
415
|
delete pr._reviewFixCycles;
|
|
416
416
|
delete pr._evalEscalated;
|
|
417
|
+
// Teams notification for PR approval — non-blocking, edge-triggered (only on transition)
|
|
418
|
+
try {
|
|
419
|
+
const teams = require('./teams');
|
|
420
|
+
const prFilePath = shared.projectPrPath(project);
|
|
421
|
+
teams.teamsNotifyPrEvent(pr, 'pr-approved', project, prFilePath).catch(() => {});
|
|
422
|
+
} catch {}
|
|
417
423
|
}
|
|
418
424
|
}
|
|
419
425
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1567",
|
|
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"
|