@yemi33/minions 0.1.2394 → 0.1.2395
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/dashboard/js/refresh.js +1 -1
- package/dashboard/js/render-prs.js +33 -4
- package/dashboard/shared/pr-merge-state.js +18 -0
- package/dashboard/slim/js/history.js +11 -2
- package/dashboard/slim/styles.css +2 -2
- package/dashboard/styles.css +4 -4
- package/dashboard-build.js +6 -0
- package/dashboard.js +4 -0
- package/package.json +1 -1
package/dashboard/js/refresh.js
CHANGED
|
@@ -137,6 +137,12 @@ function stripMarkdown(text) {
|
|
|
137
137
|
.trim();
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function _renderPrMergeConflictBadge(pr) {
|
|
141
|
+
if (!isPrMergeConflicted(pr)) return '';
|
|
142
|
+
return '<span class="pr-badge rejected merge-conflict" title="' + escapeHtml(PR_MERGE_CONFLICT_LABEL) +
|
|
143
|
+
'" aria-label="' + escapeHtml(PR_MERGE_CONFLICT_LABEL) + '">conflict</span>';
|
|
144
|
+
}
|
|
145
|
+
|
|
140
146
|
function prRow(pr) {
|
|
141
147
|
// Minions review (agent) state — separate from ADO human review
|
|
142
148
|
const sq = pr.minionsReview || {};
|
|
@@ -151,6 +157,9 @@ function prRow(pr) {
|
|
|
151
157
|
const buildTitle = pr.buildStaleMergeCommit
|
|
152
158
|
? 'ADO has builds on this PR\'s merge ref, but none target the current merge commit (typically after a rebase or target-branch advance). Engine classified from the pre-rebase build set and queued a fresh build (rate limited 30m). See Issue #2747.'
|
|
153
159
|
: (pr._buildStatusDetail || '');
|
|
160
|
+
const mergeConflictBadge = _renderPrMergeConflictBadge(pr);
|
|
161
|
+
const mergeStateHtml = mergeConflictBadge ||
|
|
162
|
+
'<span style="color:var(--muted);font-size:var(--text-base)" aria-label="No merge conflict reported">—</span>';
|
|
154
163
|
const statusClass = pr.status === 'merged' ? 'merged' : pr.status === 'abandoned' ? 'rejected' : pr.status === 'active' ? 'active' : 'draft';
|
|
155
164
|
const statusLabel = pr.status || 'active';
|
|
156
165
|
const branchError = pr._branchResolutionError?.reason || '';
|
|
@@ -312,6 +321,7 @@ function prRow(pr) {
|
|
|
312
321
|
'<td><span class="pr-badge ' + statusClass + '" title="' + escapeHtml(statusLabel) + '">' + escapeHtml(statusLabel) + '</span></td>' +
|
|
313
322
|
'<td><span class="pr-badge ' + reviewClass + '" title="' + escapeHtml(reviewTitle || reviewLabel) + '">' + escapeHtml(reviewLabel) + '</span></td>' +
|
|
314
323
|
'<td><span class="pr-badge ' + buildClass + '" title="' + escapeHtml(buildTitle || buildLabel) + '">' + escapeHtml(buildLabel) + '</span></td>' +
|
|
324
|
+
'<td>' + mergeStateHtml + '</td>' +
|
|
315
325
|
'<td><span class="' + branchClass + '" title="' + escapeHtml(branchError || branchLabel) + '">' + escapeHtml(branchLabel) + '</span>' + pendingReasonHtml + '</td>' +
|
|
316
326
|
'<td><span class="pr-agent" title="' + escapeHtml(agentText) + '">' + escapeHtml(agentText) + '</span></td>' +
|
|
317
327
|
'<td>' + reviewerCell + '</td>' +
|
|
@@ -323,7 +333,7 @@ function prRow(pr) {
|
|
|
323
333
|
}
|
|
324
334
|
|
|
325
335
|
// Explicit per-column widths keep the PR table from ballooning when titles or
|
|
326
|
-
// branches are long. Total
|
|
336
|
+
// branches are long. Total 1600px -> table grows past viewport on narrow
|
|
327
337
|
// windows and the .pr-table-wrap--prs container scrolls horizontally inside
|
|
328
338
|
// the viewport (sticky scrollbar — see styles.css).
|
|
329
339
|
const PRS_COLGROUP =
|
|
@@ -333,6 +343,7 @@ const PRS_COLGROUP =
|
|
|
333
343
|
'<col style="width:110px">' + // Status
|
|
334
344
|
'<col style="width:130px">' + // Review
|
|
335
345
|
'<col style="width:130px">' + // Build
|
|
346
|
+
'<col style="width:120px">' + // Merge conflict
|
|
336
347
|
'<col style="width:200px">' + // Branch
|
|
337
348
|
'<col style="width:140px">' + // Agent
|
|
338
349
|
'<col style="width:140px">' + // Signed Off By
|
|
@@ -345,7 +356,7 @@ function prTableHtml(rows) {
|
|
|
345
356
|
return '<div class="pr-table-wrap pr-table-wrap--prs"><table class="pr-table pr-table--prs">' +
|
|
346
357
|
PRS_COLGROUP +
|
|
347
358
|
'<thead><tr>' +
|
|
348
|
-
'<th>PR</th><th>Title</th><th>Status</th><th>Review</th><th>Build</th><th>Branch</th><th>Agent</th><th>Signed Off By</th><th>Observe</th><th>Created</th><th></th>' +
|
|
359
|
+
'<th>PR</th><th>Title</th><th>Status</th><th>Review</th><th>Build</th><th>Merge</th><th>Branch</th><th>Agent</th><th>Signed Off By</th><th>Observe</th><th>Created</th><th></th>' +
|
|
349
360
|
'</tr></thead><tbody>' + rows + '</tbody></table></div>';
|
|
350
361
|
}
|
|
351
362
|
|
|
@@ -474,11 +485,13 @@ function _renderPrDetail(pr) {
|
|
|
474
485
|
const statusClass = statusLabel === 'merged' ? 'pr-merged' :
|
|
475
486
|
statusLabel === 'abandoned' ? 'pr-abandoned' :
|
|
476
487
|
statusLabel === 'draft' ? 'draft' : 'pr-active';
|
|
488
|
+
const mergeConflictBadge = _renderPrMergeConflictBadge(pr);
|
|
477
489
|
|
|
478
490
|
const badges =
|
|
479
491
|
'<span class="pr-badge ' + statusClass + '" title="status">' + escapeHtml(String(statusLabel)) + '</span> ' +
|
|
480
492
|
'<span class="pr-badge ' + reviewClass + '" title="review">' + escapeHtml(String(reviewLabel)) + '</span> ' +
|
|
481
|
-
'<span class="pr-badge ' + buildClass + '" title="build">' + escapeHtml(String(buildLabel)) + '</span>'
|
|
493
|
+
'<span class="pr-badge ' + buildClass + '" title="build">' + escapeHtml(String(buildLabel)) + '</span>' +
|
|
494
|
+
(mergeConflictBadge ? ' ' + mergeConflictBadge : '');
|
|
482
495
|
|
|
483
496
|
// Linked WIs — join via item._pr === pr.id (stamped by engine/queries.js).
|
|
484
497
|
const wis = (window._lastWorkItems) || [];
|
|
@@ -845,4 +858,20 @@ async function resumeWorktreeHeldPause(btn) {
|
|
|
845
858
|
}
|
|
846
859
|
}
|
|
847
860
|
|
|
848
|
-
window.MinionsPrs = {
|
|
861
|
+
window.MinionsPrs = {
|
|
862
|
+
prRow,
|
|
863
|
+
prTableHtml,
|
|
864
|
+
renderPrs,
|
|
865
|
+
renderPrDetail: _renderPrDetail, // exported for testing
|
|
866
|
+
prPrev,
|
|
867
|
+
prNext,
|
|
868
|
+
openAllPrs,
|
|
869
|
+
openModal,
|
|
870
|
+
openAddPrModal,
|
|
871
|
+
openPrDetail,
|
|
872
|
+
unlinkPr,
|
|
873
|
+
togglePrObserve,
|
|
874
|
+
resumePausedCause,
|
|
875
|
+
resumeBuildFixIneffective,
|
|
876
|
+
resumeWorktreeHeldPause
|
|
877
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Shared by the classic PR table/detail and the slim activity-card renderer.
|
|
2
|
+
// `_mergeConflict` is the provider-normalized signal persisted by both pollers;
|
|
3
|
+
// mergeable must still be explicitly false so null/unknown polls never show a
|
|
4
|
+
// stale conflict and a later mergeable poll removes the badge immediately.
|
|
5
|
+
const PR_MERGE_CONFLICT_LABEL = 'Merge conflict: update the source branch or resolve conflicts before this pull request can merge.';
|
|
6
|
+
|
|
7
|
+
function isPrMergeConflicted(pr) {
|
|
8
|
+
if (!pr || (pr.status !== 'active' && pr.status !== 'linked')) return false;
|
|
9
|
+
if (pr.mergeable !== false) return false;
|
|
10
|
+
|
|
11
|
+
var mergeStateStatus = typeof pr.mergeStateStatus === 'string'
|
|
12
|
+
? pr.mergeStateStatus.trim().toLowerCase()
|
|
13
|
+
: '';
|
|
14
|
+
if (mergeStateStatus === 'blocked') return false;
|
|
15
|
+
if (mergeStateStatus === 'dirty') return true;
|
|
16
|
+
|
|
17
|
+
return pr._mergeConflict === true;
|
|
18
|
+
}
|
|
@@ -382,14 +382,23 @@
|
|
|
382
382
|
titleEl.textContent = title;
|
|
383
383
|
bodyTop.appendChild(titleEl);
|
|
384
384
|
|
|
385
|
-
// Status row — grid col 2, row 2 (aligns with rail-bottom).
|
|
386
|
-
//
|
|
385
|
+
// Status row — grid col 2, row 2 (aligns with rail-bottom). Uses the same
|
|
386
|
+
// pill component for lifecycle status and the independently-derived
|
|
387
|
+
// merge-conflict state.
|
|
387
388
|
var statusRow = document.createElement('div');
|
|
388
389
|
statusRow.className = 'completions-card-pr-status';
|
|
389
390
|
var chip = document.createElement('span');
|
|
390
391
|
chip.className = 'tile-chip ' + cls;
|
|
391
392
|
chip.textContent = p.status || '—';
|
|
392
393
|
statusRow.appendChild(chip);
|
|
394
|
+
if (isPrMergeConflicted(p)) {
|
|
395
|
+
var conflictChip = document.createElement('span');
|
|
396
|
+
conflictChip.className = 'tile-chip red merge-conflict';
|
|
397
|
+
conflictChip.textContent = 'conflict';
|
|
398
|
+
conflictChip.title = PR_MERGE_CONFLICT_LABEL;
|
|
399
|
+
conflictChip.setAttribute('aria-label', conflictChip.title);
|
|
400
|
+
statusRow.appendChild(conflictChip);
|
|
401
|
+
}
|
|
393
402
|
|
|
394
403
|
card.appendChild(rail);
|
|
395
404
|
card.appendChild(bodyTop);
|
|
@@ -1602,8 +1602,8 @@
|
|
|
1602
1602
|
}
|
|
1603
1603
|
.completions-card-chip-pr:hover { filter: brightness(1.2); }
|
|
1604
1604
|
/* PR card status row — occupies the same grid cell as the lineage row
|
|
1605
|
-
(col 2, row 2) so the rail-bottom time aligns with it. Holds
|
|
1606
|
-
|
|
1605
|
+
(col 2, row 2) so the rail-bottom time aligns with it. Holds lifecycle
|
|
1606
|
+
and optional conflict chips using the PR-list pill styling. */
|
|
1607
1607
|
.completions-card-pr-status {
|
|
1608
1608
|
grid-column: 2;
|
|
1609
1609
|
display: flex;
|
package/dashboard/styles.css
CHANGED
|
@@ -330,12 +330,12 @@
|
|
|
330
330
|
ellipsis overflow, and the horizontal scrollbar is pinned inside the
|
|
331
331
|
viewport via a bounded-height container on the standalone /prs page so
|
|
332
332
|
it stays reachable without scrolling to the bottom of a tall table. */
|
|
333
|
-
.pr-table--prs { table-layout: fixed; width: 100%; min-width:
|
|
333
|
+
.pr-table--prs { table-layout: fixed; width: 100%; min-width: 1600px; }
|
|
334
334
|
.pr-table--prs th, .pr-table--prs td { overflow: hidden; text-overflow: ellipsis; }
|
|
335
|
-
/* W-mqv5ccn7 — the
|
|
336
|
-
its own label; let the
|
|
335
|
+
/* W-mqv5ccn7 — the Signed Off By value must never ellipsis-truncate
|
|
336
|
+
its own label; let the reviewer cell (9th column) render in full
|
|
337
337
|
rather than inheriting the shared cell-level clip above. */
|
|
338
|
-
.pr-table--prs td:nth-child(
|
|
338
|
+
.pr-table--prs td:nth-child(9) { overflow: visible; }
|
|
339
339
|
.pr-table--prs th:last-child, .pr-table--prs td:last-child { width: auto; min-width: 0; }
|
|
340
340
|
.pr-table--prs .pr-title { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
341
341
|
.pr-table--prs .pr-agent { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; white-space: nowrap; }
|
package/dashboard-build.js
CHANGED
|
@@ -8,6 +8,7 @@ const shared = require('./engine/shared');
|
|
|
8
8
|
const { safeRead } = shared;
|
|
9
9
|
|
|
10
10
|
const MINIONS_DIR = __dirname;
|
|
11
|
+
const DASHBOARD_SHARED_JS = ['pr-merge-state'];
|
|
11
12
|
|
|
12
13
|
function buildDashboardHtml() {
|
|
13
14
|
const dashDir = path.join(MINIONS_DIR, 'dashboard');
|
|
@@ -52,6 +53,10 @@ function buildDashboardHtml() {
|
|
|
52
53
|
'confirm-dialog', 'modal', 'modal-qa', 'settings', 'qa', 'fre', 'refresh'
|
|
53
54
|
];
|
|
54
55
|
let jsHtml = '';
|
|
56
|
+
for (const f of DASHBOARD_SHARED_JS) {
|
|
57
|
+
const content = safeRead(path.join(dashDir, 'shared', f + '.js'));
|
|
58
|
+
jsHtml += `\n// ─── shared/${f}.js ────────────────────────────────────────\n${content}\n`;
|
|
59
|
+
}
|
|
55
60
|
for (const f of jsFiles) {
|
|
56
61
|
const content = safeRead(path.join(dashDir, 'js', f + '.js'));
|
|
57
62
|
jsHtml += `\n// ─── ${f}.js ────────────────────────────────────────\n${content}\n`;
|
|
@@ -87,6 +92,7 @@ function _slimSourcePaths(slimDir) {
|
|
|
87
92
|
path.join(slimDir, 'layout.html'),
|
|
88
93
|
path.join(slimDir, 'styles.css'),
|
|
89
94
|
path.join(slimDir, 'body.html'),
|
|
95
|
+
...DASHBOARD_SHARED_JS.map(f => path.join(MINIONS_DIR, 'dashboard', 'shared', f + '.js')),
|
|
90
96
|
...SLIM_JS_ORDER.map(f => path.join(slimDir, 'js', f + '.js')),
|
|
91
97
|
];
|
|
92
98
|
}
|
package/dashboard.js
CHANGED
|
@@ -1796,6 +1796,10 @@ function buildDashboardHtml() {
|
|
|
1796
1796
|
'confirm-dialog', 'modal', 'modal-qa', 'settings', 'qa', 'fre', 'refresh'
|
|
1797
1797
|
];
|
|
1798
1798
|
let jsHtml = '';
|
|
1799
|
+
for (const f of ['pr-merge-state']) {
|
|
1800
|
+
const content = safeRead(path.join(dashDir, 'shared', f + '.js'));
|
|
1801
|
+
jsHtml += `\n// ─── shared/${f}.js ────────────────────────────────────────\n${content}\n`;
|
|
1802
|
+
}
|
|
1799
1803
|
for (const f of jsFiles) {
|
|
1800
1804
|
const content = safeRead(path.join(dashDir, 'js', f + '.js'));
|
|
1801
1805
|
jsHtml += `\n// ─── ${f}.js ────────────────────────────────────────\n${content}\n`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2395",
|
|
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"
|