@yemi33/minions 0.1.654 → 0.1.656
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 +11 -0
- package/dashboard/js/render-meetings.js +2 -2
- package/dashboard/js/render-work-items.js +2 -2
- package/engine/cli.js +13 -2
- package/engine/github.js +21 -11
- package/engine/pipeline.js +8 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.656 (2026-04-09)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- bust require cache for package.json in engine start
|
|
7
|
+
- PRD discovery loop, github.js duplicate const, transcript null guards
|
|
8
|
+
|
|
9
|
+
## 0.1.655 (2026-04-09)
|
|
10
|
+
|
|
11
|
+
### Fixes
|
|
12
|
+
- skip PR reconciliation for projects with no PRs or work items
|
|
13
|
+
|
|
3
14
|
## 0.1.654 (2026-04-09)
|
|
4
15
|
|
|
5
16
|
### Fixes
|
|
@@ -197,7 +197,7 @@ function _renderMeetingDetail(m) {
|
|
|
197
197
|
|
|
198
198
|
// Wire up doc-chat Q&A panel for the meeting transcript
|
|
199
199
|
const transcript = (m.transcript || []).map(t =>
|
|
200
|
-
'### ' + t.agent + ' (' + t.type + ', Round ' + t.round + ')\n\n' + (t.content || '')
|
|
200
|
+
'### ' + (t.agent || 'agent') + ' (' + (t.type || '') + ', Round ' + (t.round || '?') + ')\n\n' + (t.content || '')
|
|
201
201
|
).join('\n\n---\n\n');
|
|
202
202
|
const meetingDoc = '# Meeting: ' + m.title + '\n\n**Agenda:** ' + m.agenda + '\n\n' + transcript;
|
|
203
203
|
_modalDocContext = { title: 'Meeting: ' + m.title, content: meetingDoc, selection: '' };
|
|
@@ -418,7 +418,7 @@ async function _createPlanFromMeeting(id, btn) {
|
|
|
418
418
|
|
|
419
419
|
// Use doc-chat to generate a structured plan from the meeting
|
|
420
420
|
const transcript = (m.transcript || []).map(function(t) {
|
|
421
|
-
return '### ' + t.agent + ' (' + t.type + ', Round ' + t.round + ')\n\n' + (t.content || '');
|
|
421
|
+
return '### ' + (t.agent || 'agent') + ' (' + (t.type || '') + ', Round ' + (t.round || '?') + ')\n\n' + (t.content || '');
|
|
422
422
|
}).join('\n\n---\n\n');
|
|
423
423
|
const meetingDoc = '# Meeting: ' + m.title + '\n\n**Agenda:** ' + m.agenda + '\n\n' + transcript;
|
|
424
424
|
|
|
@@ -455,7 +455,7 @@ function openWorkItemDetail(id) {
|
|
|
455
455
|
if (arts.prd) artPills += '<span onclick="planView(\'' + escHtml(arts.prd) + '\')" style="' + pillStyle + '">📄 PRD</span> ';
|
|
456
456
|
if (arts.sourcePlan) artPills += '<span onclick="planView(\'' + escHtml(arts.sourcePlan) + '\')" style="' + pillStyle + '">📋 Source Plan</span> ';
|
|
457
457
|
if (arts.notes && arts.notes.length > 0) arts.notes.forEach(function(n) {
|
|
458
|
-
var noteLabel = typeof n === 'object' ? (n.id || n.file || 'note').slice(0, 30) : String(n).replace(/\.md$/, '').slice(0, 30);
|
|
458
|
+
var noteLabel = (n && typeof n === 'object') ? (n.id || n.file || 'note').slice(0, 30) : String(n || 'note').replace(/\.md$/, '').slice(0, 30);
|
|
459
459
|
artPills += '<span onclick="closeModal();switchPage(\'inbox\')" style="' + pillStyle + '">📝 ' + escHtml(noteLabel) + '</span> ';
|
|
460
460
|
});
|
|
461
461
|
if (arts.skills && arts.skills.length > 0) arts.skills.forEach(function(s) { artPills += '<span onclick="openSkill(\'' + escHtml(s) + '\',\'minions\',\'\')" style="' + pillStyle + '">⚙ ' + escHtml(s) + '</span> '; });
|
|
@@ -490,7 +490,7 @@ function viewAgentOutput(logPath) {
|
|
|
490
490
|
document.getElementById('modal-body').style.whiteSpace = 'pre-wrap';
|
|
491
491
|
document.getElementById('modal').classList.add('open');
|
|
492
492
|
fetch('/api/agent-output?file=' + encodeURIComponent(logPath))
|
|
493
|
-
.then(function(r) { return r.text(); })
|
|
493
|
+
.then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); })
|
|
494
494
|
.then(function(content) {
|
|
495
495
|
document.getElementById('modal-body').textContent = content;
|
|
496
496
|
})
|
package/engine/cli.js
CHANGED
|
@@ -85,9 +85,20 @@ const commands = {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// Record version + git commit so dashboard can detect stale engine code
|
|
88
|
+
// Bust require cache so npm updates are detected after minions restart
|
|
88
89
|
let codeVersion = null;
|
|
89
|
-
try {
|
|
90
|
-
|
|
90
|
+
try {
|
|
91
|
+
const pkgPath = require.resolve('../package.json');
|
|
92
|
+
delete require.cache[pkgPath];
|
|
93
|
+
codeVersion = require('../package.json').version;
|
|
94
|
+
} catch {}
|
|
95
|
+
if (!codeVersion) {
|
|
96
|
+
try {
|
|
97
|
+
const pkgPath = require.resolve('@yemi33/minions/package.json');
|
|
98
|
+
delete require.cache[pkgPath];
|
|
99
|
+
codeVersion = require('@yemi33/minions/package.json').version;
|
|
100
|
+
} catch {}
|
|
101
|
+
}
|
|
91
102
|
let codeCommit = null;
|
|
92
103
|
try { codeCommit = require('child_process').execSync('git rev-parse --short HEAD', { cwd: path.resolve(__dirname, '..'), encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch {}
|
|
93
104
|
safeWrite(CONTROL_PATH, { state: 'running', pid: process.pid, started_at: e.ts(), codeVersion, codeCommit });
|
package/engine/github.js
CHANGED
|
@@ -511,6 +511,16 @@ async function reconcilePrs(config) {
|
|
|
511
511
|
// Skip projects in backoff (inaccessible repo)
|
|
512
512
|
if (isSlugInBackoff(slug)) continue;
|
|
513
513
|
|
|
514
|
+
// Skip projects with no tracked PRs and no work items — nothing to reconcile
|
|
515
|
+
const existingPrs = getPrs(project);
|
|
516
|
+
if (existingPrs.length === 0) {
|
|
517
|
+
try {
|
|
518
|
+
const wiPath = projectWorkItemsPath(project);
|
|
519
|
+
const wis = safeJson(wiPath) || [];
|
|
520
|
+
if (wis.length === 0) continue;
|
|
521
|
+
} catch { continue; }
|
|
522
|
+
}
|
|
523
|
+
|
|
514
524
|
// Fetch open PRs
|
|
515
525
|
const prsData = await ghApi('/pulls?state=open&per_page=100', slug);
|
|
516
526
|
if (!prsData || !Array.isArray(prsData)) {
|
|
@@ -527,8 +537,8 @@ async function reconcilePrs(config) {
|
|
|
527
537
|
if (ghPrs.length === 0) continue;
|
|
528
538
|
|
|
529
539
|
const prPath = projectPrPath(project);
|
|
530
|
-
const
|
|
531
|
-
const existingIds = new Set(
|
|
540
|
+
const currentPrs = safeJson(prPath) || [];
|
|
541
|
+
const existingIds = new Set(currentPrs.map(p => p.id));
|
|
532
542
|
let projectAdded = 0;
|
|
533
543
|
|
|
534
544
|
// Load work items to match branches
|
|
@@ -549,7 +559,7 @@ async function reconcilePrs(config) {
|
|
|
549
559
|
if (existingIds.has(prId)) {
|
|
550
560
|
if (confirmedItemId) {
|
|
551
561
|
addPrLink(prId, confirmedItemId);
|
|
552
|
-
const existing =
|
|
562
|
+
const existing = currentPrs.find(p => p.id === prId);
|
|
553
563
|
if (existing && !(existing.prdItems || []).includes(confirmedItemId)) {
|
|
554
564
|
existing.prdItems = Array.isArray(existing.prdItems) ? existing.prdItems : [];
|
|
555
565
|
existing.prdItems.push(confirmedItemId);
|
|
@@ -563,7 +573,7 @@ async function reconcilePrs(config) {
|
|
|
563
573
|
|
|
564
574
|
const prUrl = project.prUrlBase ? project.prUrlBase + ghPr.number : ghPr.html_url || '';
|
|
565
575
|
|
|
566
|
-
|
|
576
|
+
currentPrs.push({
|
|
567
577
|
id: prId,
|
|
568
578
|
title: (ghPr.title || `PR #${ghPr.number}`).slice(0, 120),
|
|
569
579
|
agent: (linkedItem?.dispatched_to || ghPr.user?.login || 'unknown').toLowerCase(),
|
|
@@ -584,7 +594,7 @@ async function reconcilePrs(config) {
|
|
|
584
594
|
// Backfill prdItems from pr-links for any PR with empty array
|
|
585
595
|
const prLinks = getPrLinks();
|
|
586
596
|
let backfilled = 0;
|
|
587
|
-
for (const pr of
|
|
597
|
+
for (const pr of currentPrs) {
|
|
588
598
|
const linked = prLinks[pr.id];
|
|
589
599
|
if (linked && !(pr.prdItems || []).includes(linked)) {
|
|
590
600
|
pr.prdItems = Array.isArray(pr.prdItems) ? pr.prdItems : [];
|
|
@@ -594,13 +604,13 @@ async function reconcilePrs(config) {
|
|
|
594
604
|
}
|
|
595
605
|
|
|
596
606
|
if (projectAdded > 0 || backfilled > 0) {
|
|
597
|
-
mutateJsonFileLocked(prPath, (
|
|
598
|
-
for (const pr of
|
|
599
|
-
const idx =
|
|
600
|
-
if (idx >= 0)
|
|
601
|
-
else
|
|
607
|
+
mutateJsonFileLocked(prPath, (lockedPrs) => {
|
|
608
|
+
for (const pr of currentPrs) {
|
|
609
|
+
const idx = lockedPrs.findIndex(p => p.id === pr.id);
|
|
610
|
+
if (idx >= 0) lockedPrs[idx] = pr;
|
|
611
|
+
else lockedPrs.push(pr);
|
|
602
612
|
}
|
|
603
|
-
return
|
|
613
|
+
return lockedPrs;
|
|
604
614
|
}, { defaultValue: [] });
|
|
605
615
|
totalAdded += projectAdded;
|
|
606
616
|
}
|
package/engine/pipeline.js
CHANGED
|
@@ -603,21 +603,21 @@ function isStageComplete(stage, stageState, run, config) {
|
|
|
603
603
|
const plans = artifacts.plans || [];
|
|
604
604
|
const discoveredPrds = [];
|
|
605
605
|
const discoveredWiIds = [];
|
|
606
|
+
const prdFiles = fs.existsSync(prdDir) ? safeReadDir(prdDir).filter(f => f.endsWith('.json')) : [];
|
|
606
607
|
for (const planFile of plans) {
|
|
607
|
-
const prdFiles = fs.existsSync(prdDir) ? safeReadDir(prdDir).filter(f => f.endsWith('.json')) : [];
|
|
608
608
|
for (const pf of prdFiles) {
|
|
609
609
|
const prd = safeJson(path.join(prdDir, pf));
|
|
610
610
|
if (prd?.source_plan === planFile && !(artifacts.prds || []).includes(pf) && !discoveredPrds.includes(pf)) {
|
|
611
611
|
discoveredPrds.push(pf);
|
|
612
612
|
}
|
|
613
613
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
614
|
+
}
|
|
615
|
+
const allPrds = [...(artifacts.prds || []), ...discoveredPrds];
|
|
616
|
+
for (const prdFile of allPrds) {
|
|
617
|
+
const prdItems = all.filter(w => w.sourcePlan === prdFile && w.type !== WORK_TYPE.PLAN_TO_PRD);
|
|
618
|
+
for (const wi of prdItems) {
|
|
619
|
+
if (!(artifacts.workItems || []).includes(wi.id) && !discoveredWiIds.includes(wi.id)) {
|
|
620
|
+
discoveredWiIds.push(wi.id);
|
|
621
621
|
}
|
|
622
622
|
}
|
|
623
623
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.656",
|
|
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"
|