@yemi33/minions 0.1.666 → 0.1.667

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,6 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.666 (2026-04-09)
3
+ ## 0.1.667 (2026-04-09)
4
+
5
+ ### Features
6
+ - show skip reason on work item row when dispatch is blocked (#628)
4
7
 
5
8
  ### Fixes
6
9
  - write status marker to live output during steering resume gap
@@ -49,6 +49,7 @@ function wiRow(item) {
49
49
  '<td>' + priBadge(item.priority) + '</td>' +
50
50
  '<td>' + statusBadge(item.status || 'pending') +
51
51
  (item._pendingReason && item.status === 'pending' ? ' <span style="font-size:9px;color:var(--muted);margin-left:4px" title="Pending reason: ' + escHtml(item._pendingReason) + '">' + escHtml(item._pendingReason.replace(/_/g, ' ')) + '</span>' : '') +
52
+ (item._skipReason && item.status === 'pending' ? ' <span style="font-size:9px;color:var(--yellow);margin-left:4px" title="Dispatch blocked: ' + escHtml(item._skipReason) + (item._blockedBy ? ' (by ' + escHtml(item._blockedBy) + ')' : '') + '">' + escHtml(item._skipReason.replace(/_/g, ' ')) + (item._blockedBy ? ' <span style="color:var(--muted)">(' + escHtml(item._blockedBy) + ')</span>' : '') + '</span>' : '') +
52
53
  (item.status === 'failed' ? ' ' + wiRetryBtn(item) : '') +
53
54
  '</td>' +
54
55
  '<td>' +
@@ -439,6 +440,7 @@ function openWorkItemDetail(id) {
439
440
  if (item.completedAt) html += field('Completed', escHtml(new Date(item.completedAt).toLocaleString()));
440
441
  if (item.failReason) html += field('Failure Reason', '<span style="color:var(--red)">' + escHtml(item.failReason) + '</span>');
441
442
  if (item._pendingReason && item.status === 'pending') html += field('Pending Reason', escHtml(item._pendingReason.replace(/_/g, ' ')));
443
+ if (item._skipReason && item.status === 'pending') html += field('Dispatch Blocked', '<span style="color:var(--yellow)">' + escHtml(item._skipReason.replace(/_/g, ' ')) + '</span>' + (item._blockedBy ? ' — blocked by <strong>' + escHtml(item._blockedBy) + '</strong>' : ''));
442
444
  if (item.depends_on?.length) html += field('Depends On', item.depends_on.map(d => '<code>' + escHtml(d) + '</code>').join(', '));
443
445
  if (item.acceptanceCriteria?.length) html += field('Acceptance Criteria', '<ul style="margin:0;padding-left:20px">' + item.acceptanceCriteria.map(c => '<li>' + escHtml(c) + '</li>').join('') + '</ul>');
444
446
  if (item.references?.length) html += field('References', item.references.map(r => '<a href="' + escHtml(r.url) + '" target="_blank" style="color:var(--blue)">' + escHtml(r.title || r.url) + '</a>' + (r.type ? ' <span style="color:var(--muted);font-size:10px">(' + escHtml(r.type) + ')</span>' : '')).join('<br>'));
package/dashboard.html CHANGED
@@ -2792,6 +2792,7 @@ function wiRow(item) {
2792
2792
  '<td>' + priBadge(item.priority) + '</td>' +
2793
2793
  '<td>' + statusBadge(item.status || 'pending') +
2794
2794
  (item._pendingReason ? ' <span style="font-size:9px;color:var(--muted);margin-left:4px" title="Pending reason: ' + escHtml(item._pendingReason) + '">' + escHtml(item._pendingReason.replace(/_/g, ' ')) + '</span>' : '') +
2795
+ (item._skipReason && item.status === 'pending' ? ' <span style="font-size:9px;color:var(--yellow);margin-left:4px" title="Dispatch blocked: ' + escHtml(item._skipReason) + (item._blockedBy ? ' (by ' + escHtml(item._blockedBy) + ')' : '') + '">' + escHtml(item._skipReason.replace(/_/g, ' ')) + (item._blockedBy ? ' <span style="color:var(--muted)">(' + escHtml(item._blockedBy) + ')</span>' : '') + '</span>' : '') +
2795
2796
  (item.status === 'failed' ? ' <button class="pr-pager-btn" style="font-size:9px;padding:1px 6px;color:var(--yellow);border-color:var(--yellow);margin-left:4px" onclick="event.stopPropagation();retryWorkItem(\'' + escHtml(item.id) + '\',\'' + escHtml(item._source || '') + '\')">Retry</button>' : '') +
2796
2797
  '</td>' +
2797
2798
  '<td>' +
package/engine/queries.js CHANGED
@@ -656,6 +656,33 @@ function getWorkItems(config) {
656
656
  }
657
657
  }
658
658
 
659
+ // Cross-reference with dispatch pending entries to surface skipReason + blockedBy (#617)
660
+ const pendingByWiId = new Map();
661
+ for (const d of (dispatch.pending || [])) {
662
+ if (d.meta?.item?.id && d.skipReason) {
663
+ pendingByWiId.set(d.meta.item.id, d);
664
+ }
665
+ }
666
+ if (pendingByWiId.size > 0) {
667
+ // Build branch → active agent name map for blockedBy lookup
668
+ const branchToAgent = new Map();
669
+ for (const d of (dispatch.active || [])) {
670
+ if (d.meta?.branch) branchToAgent.set(d.meta.branch, d.agentName || d.agent || '');
671
+ }
672
+ for (const item of allItems) {
673
+ const pendingEntry = pendingByWiId.get(item.id);
674
+ if (!pendingEntry) continue;
675
+ item._skipReason = pendingEntry.skipReason;
676
+ if (pendingEntry.skipReason === 'branch_locked' && pendingEntry.meta?.branch) {
677
+ const blocker = branchToAgent.get(pendingEntry.meta.branch);
678
+ if (blocker) item._blockedBy = blocker;
679
+ } else if (pendingEntry.skipReason === 'agent_busy') {
680
+ const activeEntry = (dispatch.active || []).find(d => d.agent === pendingEntry.agent);
681
+ if (activeEntry) item._blockedBy = activeEntry.agentName || activeEntry.agent || '';
682
+ }
683
+ }
684
+ }
685
+
659
686
  // Cross-reference with PRs
660
687
  const allPrs = getPullRequests(config);
661
688
  for (const item of allItems) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.666",
3
+ "version": "0.1.667",
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"