@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 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 === 'done' || s === 'decomposed') return 'var(--green)';
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.516",
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"