@yemi33/minions 0.1.233 → 0.1.235
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 +6 -0
- package/bin/minions.js +20 -1
- package/engine/cleanup.js +2 -0
- package/engine/cli.js +13 -4
- package/engine/lifecycle.js +25 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.235 (2026-04-03)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- CLI audit — kill dashboard on restart, expose kill/complete, update help
|
|
7
|
+
- clean _pendingReason on all status→done transitions, not just updateWorkItemStatus
|
|
8
|
+
|
|
3
9
|
## 0.1.233 (2026-04-03)
|
|
4
10
|
|
|
5
11
|
### Fixes
|
package/bin/minions.js
CHANGED
|
@@ -431,6 +431,7 @@ const engineCmds = new Set([
|
|
|
431
431
|
'start', 'stop', 'status', 'pause', 'resume',
|
|
432
432
|
'queue', 'sources', 'discover', 'dispatch',
|
|
433
433
|
'spawn', 'work', 'cleanup', 'mcp-sync', 'plan',
|
|
434
|
+
'kill', 'complete',
|
|
434
435
|
]);
|
|
435
436
|
|
|
436
437
|
if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
@@ -454,9 +455,13 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
|
454
455
|
minions pause / resume Pause/resume dispatching
|
|
455
456
|
minions dispatch Force a dispatch cycle
|
|
456
457
|
minions discover Dry-run work discovery
|
|
458
|
+
minions queue Show dispatch queue (pending/active/completed)
|
|
459
|
+
minions sources Show work source status per project
|
|
457
460
|
minions work <title> [opts] Add a work item
|
|
458
461
|
minions spawn <agent> <prompt> Manually spawn an agent
|
|
459
462
|
minions plan <file|text> [proj] Run a plan
|
|
463
|
+
minions kill Kill all active agents and reset to pending
|
|
464
|
+
minions complete <dispatch-id> Manually mark a dispatch as completed
|
|
460
465
|
minions cleanup Clean temp files, worktrees, zombies
|
|
461
466
|
minions nuke --confirm Factory reset (delete state, reset config to defaults)
|
|
462
467
|
|
|
@@ -484,8 +489,22 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
|
484
489
|
} else if (cmd === 'up' || cmd === 'restart') {
|
|
485
490
|
// Start both engine and dashboard — the go-to command after a reboot
|
|
486
491
|
ensureInstalled();
|
|
487
|
-
// Stop engine if running
|
|
492
|
+
// Stop engine if running
|
|
488
493
|
try { execSync(`node "${path.join(MINIONS_HOME, 'engine.js')}" stop`, { stdio: 'ignore', cwd: MINIONS_HOME }); } catch {}
|
|
494
|
+
// Kill existing dashboard
|
|
495
|
+
try {
|
|
496
|
+
if (process.platform === 'win32') {
|
|
497
|
+
const out = execSync('wmic process where "name=\'node.exe\'" get processid,commandline /format:csv', { encoding: 'utf8', timeout: 10000, windowsHide: true });
|
|
498
|
+
for (const line of out.split('\n')) {
|
|
499
|
+
if (line.includes('dashboard.js') && line.includes('minions')) {
|
|
500
|
+
const pid = line.split(',').pop()?.trim();
|
|
501
|
+
if (pid && pid !== String(process.pid)) try { process.kill(parseInt(pid)); } catch {}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
} else {
|
|
505
|
+
try { execSync('lsof -ti:7331 | xargs kill -9 2>/dev/null', { timeout: 5000 }); } catch {}
|
|
506
|
+
}
|
|
507
|
+
} catch {}
|
|
489
508
|
const engineProc = spawn(process.execPath, [path.join(MINIONS_HOME, 'engine.js'), 'start'], {
|
|
490
509
|
cwd: MINIONS_HOME, stdio: 'ignore', detached: true, windowsHide: true
|
|
491
510
|
});
|
package/engine/cleanup.js
CHANGED
|
@@ -364,6 +364,7 @@ function runCleanup(config, verbose = false) {
|
|
|
364
364
|
for (const item of items) {
|
|
365
365
|
if (LEGACY_DONE_STATUSES.has(item.status)) {
|
|
366
366
|
item.status = 'done';
|
|
367
|
+
delete item._pendingReason;
|
|
367
368
|
migrated++;
|
|
368
369
|
}
|
|
369
370
|
}
|
|
@@ -381,6 +382,7 @@ function runCleanup(config, verbose = false) {
|
|
|
381
382
|
for (const item of centralItems) {
|
|
382
383
|
if (LEGACY_DONE_STATUSES.has(item.status)) {
|
|
383
384
|
item.status = 'done';
|
|
385
|
+
delete item._pendingReason;
|
|
384
386
|
migrated++;
|
|
385
387
|
}
|
|
386
388
|
}
|
package/engine/cli.js
CHANGED
|
@@ -37,8 +37,9 @@ function handleCommand(cmd, args) {
|
|
|
37
37
|
console.log(' spawn <a> <p> Manually spawn agent with prompt');
|
|
38
38
|
console.log(' work <title> [o] Add to work-items.json queue');
|
|
39
39
|
console.log(' plan <src> [p] Generate PRD from a plan (file or text)');
|
|
40
|
-
console.log('
|
|
41
|
-
console.log('
|
|
40
|
+
console.log(' kill Kill all active agents, reset to pending');
|
|
41
|
+
console.log(' complete <id> Mark a dispatch as done');
|
|
42
|
+
console.log(' cleanup Clean temp files, worktrees, zombies');
|
|
42
43
|
console.log(' mcp-sync Sync MCP servers from ~/.claude.json');
|
|
43
44
|
console.log(' doctor Check prerequisites and runtime health');
|
|
44
45
|
process.exit(1);
|
|
@@ -567,11 +568,19 @@ const commands = {
|
|
|
567
568
|
|
|
568
569
|
complete(id) {
|
|
569
570
|
if (!id) {
|
|
570
|
-
console.log('Usage:
|
|
571
|
+
console.log('Usage: minions complete <dispatch-id>');
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
const dispatch = getDispatch();
|
|
575
|
+
const found = (dispatch.active || []).some(d => d.id === id);
|
|
576
|
+
if (!found) {
|
|
577
|
+
console.log(` Dispatch "${id}" not found in active queue.`);
|
|
578
|
+
const pending = (dispatch.pending || []).some(d => d.id === id);
|
|
579
|
+
if (pending) console.log(' (It is in pending — it hasn\'t started yet.)');
|
|
571
580
|
return;
|
|
572
581
|
}
|
|
573
582
|
engine().completeDispatch(id, 'success');
|
|
574
|
-
console.log(`Marked ${id} as completed.`);
|
|
583
|
+
console.log(` Marked ${id} as completed.`);
|
|
575
584
|
},
|
|
576
585
|
|
|
577
586
|
dispatch() {
|
package/engine/lifecycle.js
CHANGED
|
@@ -284,23 +284,33 @@ function checkPlanCompletion(meta, config) {
|
|
|
284
284
|
shared.safeWrite(planPath, plan);
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
// Also archive the source .md plan if it exists
|
|
287
|
+
// Also archive the source .md plan if it exists (use source_plan field, not content matching)
|
|
288
288
|
const planArchiveDir = path.join(PLANS_DIR, 'archive');
|
|
289
289
|
if (!fs.existsSync(planArchiveDir)) fs.mkdirSync(planArchiveDir, { recursive: true });
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
fs.renameSync(path.join(PLANS_DIR, md), path.join(planArchiveDir, md));
|
|
298
|
-
log('info', `Archived source plan: plans/archive/${md}`);
|
|
299
|
-
} catch (err) { log('warn', `Failed to archive plan ${md}: ${err.message}`); }
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
290
|
+
if (plan.source_plan) {
|
|
291
|
+
const mdPath = path.join(PLANS_DIR, plan.source_plan);
|
|
292
|
+
if (fs.existsSync(mdPath)) {
|
|
293
|
+
try {
|
|
294
|
+
fs.renameSync(mdPath, path.join(planArchiveDir, plan.source_plan));
|
|
295
|
+
log('info', `Archived source plan: plans/archive/${plan.source_plan}`);
|
|
296
|
+
} catch (err) { log('warn', `Failed to archive source plan ${plan.source_plan}: ${err.message}`); }
|
|
302
297
|
}
|
|
303
|
-
}
|
|
298
|
+
} else {
|
|
299
|
+
// Fallback: scan for matching .md files (legacy PRDs without source_plan)
|
|
300
|
+
try {
|
|
301
|
+
const mdFiles = fs.readdirSync(PLANS_DIR).filter(f => f.endsWith('.md'));
|
|
302
|
+
for (const md of mdFiles) {
|
|
303
|
+
const mdContent = shared.safeRead(path.join(PLANS_DIR, md)) || '';
|
|
304
|
+
if (mdContent.includes(projectName) || mdContent.includes(plan.plan_summary?.slice(0, 40) || '___nomatch___')) {
|
|
305
|
+
try {
|
|
306
|
+
fs.renameSync(path.join(PLANS_DIR, md), path.join(planArchiveDir, md));
|
|
307
|
+
log('info', `Archived source plan: plans/archive/${md}`);
|
|
308
|
+
} catch (err) { log('warn', `Failed to archive plan ${md}: ${err.message}`); }
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
} catch (err) { log('warn', `Plan archive scan: ${err.message}`); }
|
|
313
|
+
}
|
|
304
314
|
|
|
305
315
|
// 6. Clean up ALL worktrees created for this plan's work items (shared-branch + per-item)
|
|
306
316
|
try {
|
|
@@ -791,6 +801,7 @@ async function handlePostMerge(pr, project, config, newStatus) {
|
|
|
791
801
|
log('info', `Post-merge: marking work item ${mergedItemId} as done (was ${item.status}) for ${pr.id}`);
|
|
792
802
|
item.status = 'done';
|
|
793
803
|
item.completedAt = ts();
|
|
804
|
+
delete item._pendingReason;
|
|
794
805
|
item._mergedVia = pr.id;
|
|
795
806
|
found = true;
|
|
796
807
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.235",
|
|
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"
|