@yemi33/minions 0.1.516 → 0.1.518
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 +10 -0
- package/dashboard/js/render-prd.js +18 -6
- package/engine/queries.js +16 -0
- package/engine.js +16 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.518 (2026-04-07)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- decomposed parents auto-promote to done, sub-task PRs aggregate to parent
|
|
7
|
+
|
|
8
|
+
## 0.1.517 (2026-04-07)
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
- decomposed PRD items show WIP while children run, DONE when all complete
|
|
12
|
+
|
|
3
13
|
## 0.1.516 (2026-04-07)
|
|
4
14
|
|
|
5
15
|
### Fixes
|
|
@@ -109,7 +109,14 @@ function renderPrdProgress(prog) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// PRD item statuses: missing → dispatched → done
|
|
112
|
-
const statusBadge = (s) => {
|
|
112
|
+
const statusBadge = (s, itemId) => {
|
|
113
|
+
// Decomposed: show WIP if children still running, DONE if all children done
|
|
114
|
+
if (s === 'decomposed' && itemId) {
|
|
115
|
+
const children = (window._lastWorkItems || []).filter(w => w.parent_id === itemId);
|
|
116
|
+
const allChildrenDone = children.length > 0 && children.every(c => c.status === 'done');
|
|
117
|
+
if (allChildrenDone) { s = 'done'; }
|
|
118
|
+
else { s = 'dispatched'; } // show as WIP while children are running
|
|
119
|
+
}
|
|
113
120
|
const styles = {
|
|
114
121
|
'done': 'background:rgba(63,185,80,0.15);color:var(--green)',
|
|
115
122
|
'dispatched': 'background:rgba(210,153,34,0.15);color:var(--yellow);animation:wipPulse 1.5s infinite',
|
|
@@ -173,7 +180,7 @@ function renderPrdProgress(prog) {
|
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
return '<div class="prd-item-row st-' + (i.status || 'missing') + '" style="flex-wrap:wrap;cursor:pointer" onclick="prdItemEdit(\'' + src + '\',\'' + iid + '\')">' +
|
|
176
|
-
statusBadge(i.status) +
|
|
183
|
+
statusBadge(i.status, i.id) +
|
|
177
184
|
'<span class="prd-item-id">' + escHtml(i.id) + '</span>' +
|
|
178
185
|
'<span class="prd-item-name" title="' + escHtml(i.name) + '">' + escHtml(i.name) + '</span>' +
|
|
179
186
|
wiLabel +
|
|
@@ -325,8 +332,13 @@ function renderPrdProgress(prog) {
|
|
|
325
332
|
if (d > maxDepth) maxDepth = d;
|
|
326
333
|
});
|
|
327
334
|
|
|
328
|
-
const statusColor = (s) => {
|
|
329
|
-
if (s === '
|
|
335
|
+
const statusColor = (s, itemId) => {
|
|
336
|
+
if (s === 'decomposed' && itemId) {
|
|
337
|
+
const ch = (window._lastWorkItems || []).filter(w => w.parent_id === itemId);
|
|
338
|
+
if (ch.length > 0 && ch.every(c => c.status === 'done')) return 'var(--green)';
|
|
339
|
+
return 'var(--yellow)'; // children still running
|
|
340
|
+
}
|
|
341
|
+
if (s === 'done') return 'var(--green)';
|
|
330
342
|
if (s === 'dispatched') return 'var(--yellow)';
|
|
331
343
|
if (s === 'failed') return 'var(--red)';
|
|
332
344
|
if (s === 'paused') return 'var(--muted)';
|
|
@@ -341,7 +353,7 @@ function renderPrdProgress(prog) {
|
|
|
341
353
|
html += '<div style="flex:1;min-width:0">' +
|
|
342
354
|
'<div style="font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px;text-align:center">' + colLabel + '</div>';
|
|
343
355
|
for (const i of col) {
|
|
344
|
-
const borderColor = statusColor(i.status);
|
|
356
|
+
const borderColor = statusColor(i.status, i.id);
|
|
345
357
|
const src = escHtml(i.source || '');
|
|
346
358
|
const iid = escHtml(i.id || '');
|
|
347
359
|
const agentId = wi[i.id]?.dispatched_to || '';
|
|
@@ -353,7 +365,7 @@ function renderPrdProgress(prog) {
|
|
|
353
365
|
'style="background:var(--surface2);border:1px solid var(--border);border-left:3px solid ' + borderColor + ';' + wipAnim +
|
|
354
366
|
'border-radius:4px;padding:6px 8px;margin-bottom:6px;cursor:pointer;font-size:11px">' +
|
|
355
367
|
'<div style="display:flex;align-items:center;gap:4px;margin-bottom:2px">' +
|
|
356
|
-
statusBadge(i.status) +
|
|
368
|
+
statusBadge(i.status, i.id) +
|
|
357
369
|
'<span style="font-weight:600;color:var(--text)">' + escHtml(i.id) + '</span>' +
|
|
358
370
|
'</div>' +
|
|
359
371
|
'<div style="color:var(--text);font-size:11px;line-height:1.3;margin-bottom:3px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical">' + escHtml(i.name) + '</div>' +
|
package/engine/queries.js
CHANGED
|
@@ -777,6 +777,22 @@ function getPrdInfo(config) {
|
|
|
777
777
|
const url = pr?.url || (project?.prUrlBase ? project.prUrlBase + wi._pr.replace('PR-', '') : '');
|
|
778
778
|
prdToPr[wi.id] = [{ id: wi._pr, url, title: pr?.title || '', status: pr?.status || 'active', _project: project?.name || '' }];
|
|
779
779
|
}
|
|
780
|
+
// Aggregate sub-task PRs to decomposed parent (sub-tasks aren't PRD items but their PRs should show)
|
|
781
|
+
for (const pr of allPrs) {
|
|
782
|
+
for (const itemId of (pr.prdItems || [])) {
|
|
783
|
+
// Find if this is a sub-task with a parent
|
|
784
|
+
const allItems = Object.values(wiById);
|
|
785
|
+
const wi = allItems.find(w => w.id === itemId && w.parent_id);
|
|
786
|
+
if (!wi) continue;
|
|
787
|
+
const parentId = wi.parent_id;
|
|
788
|
+
if (!prdToPr[parentId]) prdToPr[parentId] = [];
|
|
789
|
+
if (!prdToPr[parentId].some(p => p.id === pr.id)) {
|
|
790
|
+
const project = projects.find(p => p.name === pr._project) || projects[0] || null;
|
|
791
|
+
const url = pr.url || (project?.prUrlBase ? project.prUrlBase + pr.id.replace('PR-', '') : '');
|
|
792
|
+
prdToPr[parentId].push({ id: pr.id, url, title: pr.title || '', status: pr.status || 'active', _project: pr._project || '' });
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
780
796
|
|
|
781
797
|
// PRD JSON status is the source of truth — kept in sync with work item by syncPrdItemStatus.
|
|
782
798
|
// Map from PRD JSON values to display values (pending → missing for undispatched items)
|
package/engine.js
CHANGED
|
@@ -1696,6 +1696,22 @@ function discoverFromWorkItems(config, project) {
|
|
|
1696
1696
|
} catch (err) { log('warn', `discoverFromWorkItems: skipping ${item.id}: ${err.message}`); }
|
|
1697
1697
|
}
|
|
1698
1698
|
|
|
1699
|
+
// Auto-promote decomposed parents to done when all sub-tasks complete
|
|
1700
|
+
for (const item of items) {
|
|
1701
|
+
if (item.status !== WI_STATUS.DECOMPOSED || !item._subItemIds?.length) continue;
|
|
1702
|
+
const allSubsDone = item._subItemIds.every(sid => {
|
|
1703
|
+
const sub = items.find(i => i.id === sid);
|
|
1704
|
+
return sub && DONE_STATUSES.has(sub.status);
|
|
1705
|
+
});
|
|
1706
|
+
if (allSubsDone) {
|
|
1707
|
+
item.status = WI_STATUS.DONE;
|
|
1708
|
+
if (!item.completedAt) item.completedAt = ts();
|
|
1709
|
+
needsWrite = true;
|
|
1710
|
+
log('info', `Decomposed parent ${item.id} → done (all ${item._subItemIds.length} sub-tasks complete)`);
|
|
1711
|
+
if (item.sourcePlan) syncPrdItemStatus(item.id, WI_STATUS.DONE, item.sourcePlan);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1699
1715
|
// Write back updated statuses (always, since we mark items dispatched before newWork check)
|
|
1700
1716
|
if (newWork.length > 0) {
|
|
1701
1717
|
const workItemsPath = projectWorkItemsPath(project);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.518",
|
|
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"
|