@yemi33/minions 0.1.1105 → 0.1.1107
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 +4 -1
- package/dashboard/js/render-agents.js +1 -1
- package/dashboard/js/render-meetings.js +1 -1
- package/dashboard/js/render-pinned.js +1 -1
- package/dashboard/js/render-pipelines.js +1 -1
- package/dashboard/js/render-plans.js +2 -2
- package/dashboard/js/render-prd.js +2 -2
- package/dashboard/js/render-schedules.js +2 -2
- package/dashboard/js/render-watches.js +1 -1
- package/dashboard/js/render-work-items.js +1 -1
- package/dashboard/js/settings.js +2 -2
- package/dashboard/js/utils.js +21 -1
- package/engine/ado.js +16 -3
- package/engine/github.js +13 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1107 (2026-04-18)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- seed realActivityMap at spawn time, stamp pid in live-output (#1200)
|
|
7
7
|
|
|
8
8
|
### Fixes
|
|
9
|
+
- preserve buildErrorLog through transient build states (#1232) (#1274)
|
|
9
10
|
- annotate fast-exit empty-output failures with diagnostic hint (#1276)
|
|
10
11
|
- invalidate PRD cache on pr-links.json change + guard aggregate PRs (#1220) (#1272)
|
|
11
12
|
- pass --add-dir for minions + ~/.claude to agents (#1271)
|
|
@@ -23,6 +24,8 @@
|
|
|
23
24
|
- harden settings save and migrate pr poll config
|
|
24
25
|
|
|
25
26
|
### Other
|
|
27
|
+
- Clarify PR poll labels
|
|
28
|
+
- Prevent modal opens on text selection
|
|
26
29
|
- refactor: clarify settings page section structure and PR polling dependencies
|
|
27
30
|
- refactor: extract _probeClaudePackage helper, use shared.log for spawn errors
|
|
28
31
|
- Make work item descriptions scrollable
|
|
@@ -4,7 +4,7 @@ function renderAgents(agents) {
|
|
|
4
4
|
agentData = agents;
|
|
5
5
|
const grid = document.getElementById('agents-grid');
|
|
6
6
|
grid.innerHTML = agents.map(a => `
|
|
7
|
-
<div class="agent-card ${statusColor(a.status)}" onclick="openAgentDetail('${escHtml(a.id)}')">
|
|
7
|
+
<div class="agent-card ${statusColor(a.status)}" onclick="if(shouldIgnoreSelectionClick(event))return;openAgentDetail('${escHtml(a.id)}')">
|
|
8
8
|
<div class="agent-card-header">
|
|
9
9
|
<span class="agent-name"><span class="agent-emoji">${escHtml(a.emoji)}</span>${escHtml(a.name)}</span>
|
|
10
10
|
<span class="status-badge ${escHtml(a.status)}">${escHtml(a.status)}</span>
|
|
@@ -48,7 +48,7 @@ function renderMeetings(meetings) {
|
|
|
48
48
|
const dt = m.completedAt || m.createdAt;
|
|
49
49
|
const timeStr = dt ? new Date(dt).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }) : '';
|
|
50
50
|
|
|
51
|
-
return '<div data-file="meetings/' + escHtml(m.id) + '.json" style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:8px;cursor:pointer;position:relative" onclick="openMeetingDetail(\'' + escHtml(m.id) + '\')">' +
|
|
51
|
+
return '<div data-file="meetings/' + escHtml(m.id) + '.json" style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:8px;cursor:pointer;position:relative" onclick="if(shouldIgnoreSelectionClick(event))return;openMeetingDetail(\'' + escHtml(m.id) + '\')">' +
|
|
52
52
|
'<div style="display:flex;justify-content:space-between;align-items:center">' +
|
|
53
53
|
'<strong style="font-size:13px">' + escHtml(m.title) + '</strong>' +
|
|
54
54
|
'<div style="display:flex;align-items:center;gap:8px">' +
|
|
@@ -13,7 +13,7 @@ function renderPinned(entries) {
|
|
|
13
13
|
el.innerHTML = entries.map((e, i) =>
|
|
14
14
|
'<div class="pinned-card" data-file="pinned:' + escHtml(e.title) + '" style="padding:8px 12px;margin-bottom:6px;background:var(--surface2);border-left:3px solid ' +
|
|
15
15
|
(e.level === 'critical' ? 'var(--red)' : e.level === 'warning' ? 'var(--yellow)' : 'var(--blue)') +
|
|
16
|
-
';border-radius:4px;cursor:pointer" onclick="openPinnedView(' + i + ')">' +
|
|
16
|
+
';border-radius:4px;cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openPinnedView(' + i + ')">' +
|
|
17
17
|
'<div style="display:flex;justify-content:space-between;align-items:center">' +
|
|
18
18
|
'<strong style="font-size:var(--text-md)">' + escHtml(e.title) + '</strong>' +
|
|
19
19
|
'<button class="pr-pager-btn" style="font-size:9px;padding:1px 6px;color:var(--red);border-color:var(--red)" data-pin-title="' + escHtml(e.title) + '" onclick="event.stopPropagation();removePinnedNote(this.dataset.pinTitle)">Unpin</button>' +
|
|
@@ -277,7 +277,7 @@ function renderPipelines(pipelines) {
|
|
|
277
277
|
var allResources = _collectMonitoredResources(p);
|
|
278
278
|
var resourcesHtml = _renderMonitoredResources(allResources, { compact: true });
|
|
279
279
|
|
|
280
|
-
return '<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:8px;cursor:pointer" onclick="openPipelineDetail(\'' + escHtml(p.id) + '\')">' +
|
|
280
|
+
return '<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:8px;cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openPipelineDetail(\'' + escHtml(p.id) + '\')">' +
|
|
281
281
|
'<div style="display:flex;justify-content:space-between;align-items:center">' +
|
|
282
282
|
'<strong style="font-size:13px">' + escHtml(p.title) + '</strong>' +
|
|
283
283
|
'<div style="display:flex;align-items:center;gap:8px">' +
|
|
@@ -263,7 +263,7 @@ function renderPlans(plans) {
|
|
|
263
263
|
const versionBadge = p.version ? ' <span style="font-size:9px;font-weight:700;padding:1px 5px;border-radius:3px;background:rgba(56,139,253,0.15);color:var(--blue);vertical-align:middle">v' + p.version + '</span>' : '';
|
|
264
264
|
const statusColors = { 'completed': 'var(--green)', 'dispatched': 'var(--blue)', 'converting': 'var(--yellow)', 'paused': 'var(--muted)', 'awaiting-approval': 'var(--yellow)', 'approved': 'var(--green)', 'rejected': 'var(--red)', 'has-failures': 'var(--red)', 'revision-requested': 'var(--purple,#a855f7)', 'active': 'var(--muted)' };
|
|
265
265
|
const cardClass = effectiveStatus === 'dispatched' || effectiveStatus === 'converting' ? 'working' : effectiveStatus === 'awaiting-approval' || effectiveStatus === 'paused' ? 'awaiting' : effectiveStatus;
|
|
266
|
-
return '<div class="plan-card ' + cardClass + '" data-file="plans/' + escHtml(p.file) + '" style="cursor:pointer' + (isArchived ? ';opacity:0.7' : '') + '" onclick="planView(\'' + escHtml(p.file) + '\')">' +
|
|
266
|
+
return '<div class="plan-card ' + cardClass + '" data-file="plans/' + escHtml(p.file) + '" style="cursor:pointer' + (isArchived ? ';opacity:0.7' : '') + '" onclick="if(shouldIgnoreSelectionClick(event))return;planView(\'' + escHtml(p.file) + '\')">' +
|
|
267
267
|
'<div class="plan-card-header">' +
|
|
268
268
|
'<div><div class="plan-card-title">' + escHtml(p.summary || p.file) + versionBadge + '</div>' +
|
|
269
269
|
'<div class="plan-card-meta">' +
|
|
@@ -323,7 +323,7 @@ function openArchivedPlansModal() {
|
|
|
323
323
|
const html = plans.map(p => {
|
|
324
324
|
const itemCount = p.itemCount || 0;
|
|
325
325
|
const completed = p.completedAt ? p.completedAt.slice(0, 10) : '';
|
|
326
|
-
return '<div class="plan-card" data-file="plans/' + escHtml(p.file) + '" style="cursor:pointer;opacity:0.8" onclick="planView(\'' + escHtml(p.file) + '\')">' +
|
|
326
|
+
return '<div class="plan-card" data-file="plans/' + escHtml(p.file) + '" style="cursor:pointer;opacity:0.8" onclick="if(shouldIgnoreSelectionClick(event))return;planView(\'' + escHtml(p.file) + '\')">' +
|
|
327
327
|
'<div class="plan-card-header">' +
|
|
328
328
|
'<div><div class="plan-card-title" style="font-size:13px">' + escHtml(p.summary || p.file) + '</div>' +
|
|
329
329
|
'<div class="plan-card-meta">' +
|
|
@@ -203,7 +203,7 @@ function renderPrdProgress(prog) {
|
|
|
203
203
|
? '<span onclick="event.stopPropagation();prdItemReopen(\'' + escHtml(i.source || '') + '\',\'' + escHtml(i.id) + '\')" style="color:var(--blue);cursor:pointer;font-size:9px;padding:1px 5px;background:rgba(56,139,253,0.1);border:1px solid rgba(56,139,253,0.3);border-radius:3px" title="Re-open: set to updated so engine re-dispatches on existing branch">re-open</span>'
|
|
204
204
|
: '';
|
|
205
205
|
|
|
206
|
-
return '<div class="prd-item-row st-' + (i.status || 'missing') + '" style="flex-wrap:wrap;cursor:pointer" onclick="prdItemEdit(\'' + src + '\',\'' + iid + '\')">' +
|
|
206
|
+
return '<div class="prd-item-row st-' + (i.status || 'missing') + '" style="flex-wrap:wrap;cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;prdItemEdit(\'' + src + '\',\'' + iid + '\')">' +
|
|
207
207
|
statusBadge(i.status, i.id) +
|
|
208
208
|
'<span class="prd-item-id">' + escHtml(i.id) + '</span>' +
|
|
209
209
|
'<span class="prd-item-name" title="' + escHtml(i.name) + '">' + escHtml(i.name) + '</span>' +
|
|
@@ -579,7 +579,7 @@ function openArchivedPrdModal() {
|
|
|
579
579
|
const done = g.items.filter(it => it.status === 'done').length;
|
|
580
580
|
const failed = g.items.filter(it => it.status === 'failed').length;
|
|
581
581
|
const completed = g.completedAt ? new Date(g.completedAt).toLocaleDateString() : '';
|
|
582
|
-
return '<div class="plan-card" style="cursor:pointer;margin-bottom:8px" onclick="showArchivedPrdDetail(\'' + escHtml(g.file) + '\')">' +
|
|
582
|
+
return '<div class="plan-card" style="cursor:pointer;margin-bottom:8px" onclick="if(shouldIgnoreSelectionClick(event))return;showArchivedPrdDetail(\'' + escHtml(g.file) + '\')">' +
|
|
583
583
|
'<div class="plan-card-title" style="font-size:13px">' + escHtml(g.summary || g.file) + '</div>' +
|
|
584
584
|
'<div class="plan-card-meta">' +
|
|
585
585
|
(g._projects.length > 0 ? g._projects.map(function(p) { return '<span>' + escHtml(p) + '</span>'; }).join(' ') : '') +
|
|
@@ -250,7 +250,7 @@ function _renderScheduleCalendar(schedules) {
|
|
|
250
250
|
var strikeStyle = s.enabled === false ? 'text-decoration:line-through;' : '';
|
|
251
251
|
var timeLabel = String(sl.hour).padStart(2, '0') + ':' + String(sl.minute).padStart(2, '0');
|
|
252
252
|
html += '<div class="sched-cal-slot" style="background:' + colors.bg + ';border-left-color:' + colors.border + ';color:' + colors.text + ';opacity:' + opacity + '" ' +
|
|
253
|
-
'onclick="openScheduleDetail(\'' + escHtml(s.id) + '\')" title="' + escHtml(s.title + ' — ' + timeLabel + ' — ' + (s.type || 'implement')) + '">' +
|
|
253
|
+
'onclick="if(shouldIgnoreSelectionClick(event))return;openScheduleDetail(\'' + escHtml(s.id) + '\')" title="' + escHtml(s.title + ' — ' + timeLabel + ' — ' + (s.type || 'implement')) + '">' +
|
|
254
254
|
'<span style="font-weight:600;' + strikeStyle + '">' + escHtml((s.title || s.id).slice(0, 25)) + '</span>' +
|
|
255
255
|
'<span style="font-size:9px;opacity:0.7"> ' + timeLabel + '</span>' +
|
|
256
256
|
'</div>';
|
|
@@ -292,7 +292,7 @@ function renderSchedules(schedules) {
|
|
|
292
292
|
const lastRun = s._lastRun ? timeAgo(s._lastRun) : 'never';
|
|
293
293
|
const typeBadge = '<span class="dispatch-type ' + escHtml(s.type || 'implement') + '">' + escHtml(s.type || 'implement') + '</span>';
|
|
294
294
|
const humanCron = _cronToHuman(s.cron || '');
|
|
295
|
-
html += '<tr style="cursor:pointer" onclick="openScheduleDetail(\'' + escHtml(s.id) + '\')">' +
|
|
295
|
+
html += '<tr style="cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openScheduleDetail(\'' + escHtml(s.id) + '\')">' +
|
|
296
296
|
'<td><span class="pr-id">' + escHtml(s.id || '') + '</span></td>' +
|
|
297
297
|
'<td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escHtml(s.title || '') + '">' + escHtml(s.title || '') + '</td>' +
|
|
298
298
|
'<td><span title="' + escHtml(s.cron || '') + '" style="font-size:11px;color:var(--blue)">' + escHtml(humanCron) + '</span></td>' +
|
|
@@ -89,7 +89,7 @@ function renderWatches(watchesData) {
|
|
|
89
89
|
var lastTriggered = w.last_triggered ? timeAgo(w.last_triggered) : 'never';
|
|
90
90
|
var triggerInfo = (w.triggerCount || 0) + (w.stopAfter > 0 ? '/' + w.stopAfter : '');
|
|
91
91
|
|
|
92
|
-
html += '<tr style="cursor:pointer" onclick="openWatchDetail(\'' + escHtml(w.id) + '\')">' +
|
|
92
|
+
html += '<tr style="cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openWatchDetail(\'' + escHtml(w.id) + '\')">' +
|
|
93
93
|
'<td><span class="pr-id">' + escHtml(w.id) + '</span></td>' +
|
|
94
94
|
'<td style="max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escHtml(w.description || w.target) + '">' + escHtml(w.target) + '</td>' +
|
|
95
95
|
'<td><span class="dispatch-type explore">' + escHtml(targetLabel) + '</span></td>' +
|
|
@@ -40,7 +40,7 @@ function wiRow(item) {
|
|
|
40
40
|
: (item.branchStrategy === 'shared-branch' && item.status === 'done')
|
|
41
41
|
? '<span style="font-size:9px;color:var(--muted)" title="Part of shared branch — aggregate PR created at verify stage">shared branch</span>'
|
|
42
42
|
: '<span style="color:var(--muted)">—</span>';
|
|
43
|
-
return '<tr style="cursor:pointer" onclick="if(
|
|
43
|
+
return '<tr style="cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openWorkItemDetail(\'' + escHtml(item.id) + '\')">' +
|
|
44
44
|
'<td><span class="pr-id">' + escHtml(item.id || '') + '</span></td>' +
|
|
45
45
|
'<td style="max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escHtml((item.title || '').slice(0, 200)) + '">' + escHtml(item.title || '') + '</td>' +
|
|
46
46
|
'<td><span style="font-size:10px;color:var(--muted)">' + escHtml(item._source || '') + '</span>' +
|
package/dashboard/js/settings.js
CHANGED
|
@@ -68,8 +68,8 @@ async function openSettings() {
|
|
|
68
68
|
'</div>' +
|
|
69
69
|
settingsToggle('GitHub Polling', 'set-ghPollEnabled', e.ghPollEnabled !== false, 'Keeps GitHub PR build results, votes, and comments fresh each tick (reconciliation always runs regardless)') +
|
|
70
70
|
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px">' +
|
|
71
|
-
settingsField('Status Poll Frequency', 'set-prPollStatusEvery', e.prPollStatusEvery ?? e.adoPollStatusEvery ?? 12, 'ticks', 'Poll PR build/review/merge status every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
|
|
72
|
-
settingsField('Comments Poll Frequency', 'set-prPollCommentsEvery', e.prPollCommentsEvery ?? e.adoPollCommentsEvery ?? 12, 'ticks', 'Poll PR human comments every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
|
|
71
|
+
settingsField('PR Status Poll Frequency', 'set-prPollStatusEvery', e.prPollStatusEvery ?? e.adoPollStatusEvery ?? 12, 'ticks', 'Poll PR build/review/merge status every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
|
|
72
|
+
settingsField('PR Comments Poll Frequency', 'set-prPollCommentsEvery', e.prPollCommentsEvery ?? e.adoPollCommentsEvery ?? 12, 'ticks', 'Poll PR human comments every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
|
|
73
73
|
'</div>' +
|
|
74
74
|
'</div>' +
|
|
75
75
|
|
package/dashboard/js/utils.js
CHANGED
|
@@ -129,6 +129,26 @@ function statusColor(s) {
|
|
|
129
129
|
return s === 'working' ? 'working' : s === 'done' ? 'done' : s === 'error' ? 'error' : '';
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
var SELECTION_CLICK_GUARD_MS = 300;
|
|
133
|
+
var _lastTextSelectionAt = 0;
|
|
134
|
+
|
|
135
|
+
function _selectionHasText() {
|
|
136
|
+
var sel = window.getSelection ? window.getSelection() : null;
|
|
137
|
+
return !!(sel && !sel.isCollapsed && sel.toString().trim());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function _markRecentTextSelection() {
|
|
141
|
+
if (_selectionHasText()) _lastTextSelectionAt = Date.now();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
document.addEventListener('selectionchange', _markRecentTextSelection);
|
|
145
|
+
document.addEventListener('mouseup', _markRecentTextSelection);
|
|
146
|
+
|
|
147
|
+
function shouldIgnoreSelectionClick() {
|
|
148
|
+
if (_selectionHasText()) return true;
|
|
149
|
+
return (Date.now() - _lastTextSelectionAt) < SELECTION_CLICK_GUARD_MS;
|
|
150
|
+
}
|
|
151
|
+
|
|
132
152
|
function llmCopyBtn() {
|
|
133
153
|
return '<button class="llm-copy-btn" onclick="event.stopPropagation();copyLlmText(this)" title="Copy">⎘</button>';
|
|
134
154
|
}
|
|
@@ -462,4 +482,4 @@ async function submitBugReport() {
|
|
|
462
482
|
}
|
|
463
483
|
}
|
|
464
484
|
|
|
465
|
-
window.MinionsUtils = { wakeEngine, escHtml, renderMd, normalizePlanFile, timeAgo, statusColor, llmCopyBtn, copyLlmText, openBugReport, submitBugReport };
|
|
485
|
+
window.MinionsUtils = { wakeEngine, escHtml, renderMd, normalizePlanFile, timeAgo, statusColor, shouldIgnoreSelectionClick, llmCopyBtn, copyLlmText, openBugReport, submitBugReport };
|
package/engine/ado.js
CHANGED
|
@@ -465,6 +465,11 @@ async function pollPrStatus(config) {
|
|
|
465
465
|
} catch (e) { log('warn', `ADO build query for ${pr.id}: ${e.message}`); }
|
|
466
466
|
}
|
|
467
467
|
|
|
468
|
+
// Record actual poll time — makes lastBuildCheck reflect when the engine last
|
|
469
|
+
// talked to ADO, not when the agent was dispatched. Issue #1233.
|
|
470
|
+
pr.lastBuildCheck = ts();
|
|
471
|
+
updated = true;
|
|
472
|
+
|
|
468
473
|
if (pr.buildStatus !== buildStatus) {
|
|
469
474
|
log('info', `PR ${pr.id} build: ${pr.buildStatus || 'none'} → ${buildStatus}${buildFailReason ? ' (' + buildFailReason + ')' : ''}`);
|
|
470
475
|
pr.buildStatus = buildStatus;
|
|
@@ -475,9 +480,17 @@ async function pollPrStatus(config) {
|
|
|
475
480
|
if (buildStatus === 'failing') delete pr._autoCompleted;
|
|
476
481
|
if (buildStatus !== 'failing') {
|
|
477
482
|
delete pr._buildFailNotified;
|
|
478
|
-
|
|
479
|
-
//
|
|
480
|
-
|
|
483
|
+
// Preserve buildErrorLog + buildFixAttempts through transient 'none'/'running'
|
|
484
|
+
// transitions — only clear on confirmed 'passing' recovery. Issue #1232: 'none'
|
|
485
|
+
// can also occur when ADO recomputes the merge commit after a target-branch
|
|
486
|
+
// update but no new builds have been triggered yet (filter by sourceVersion
|
|
487
|
+
// returns []), which previously wiped the last known error log and caused
|
|
488
|
+
// fix agents to be dispatched blind.
|
|
489
|
+
if (buildStatus === 'passing') {
|
|
490
|
+
delete pr.buildErrorLog;
|
|
491
|
+
// Reset build fix retry counter on recovery — allows fresh auto-fix cycles if build breaks again
|
|
492
|
+
if (pr.buildFixAttempts) { delete pr.buildFixAttempts; delete pr.buildFixEscalated; }
|
|
493
|
+
}
|
|
481
494
|
}
|
|
482
495
|
updated = true;
|
|
483
496
|
|
package/engine/github.js
CHANGED
|
@@ -422,6 +422,10 @@ async function pollPrStatus(config) {
|
|
|
422
422
|
if (prData.state === 'open' && prData.head?.sha) {
|
|
423
423
|
const checksData = await ghApi(`/commits/${prData.head.sha}/check-runs`, slug);
|
|
424
424
|
if (checksData && checksData.check_runs) {
|
|
425
|
+
// Record actual poll time — makes lastBuildCheck reflect when the engine last
|
|
426
|
+
// talked to GitHub, not when the agent was dispatched. Issue #1233.
|
|
427
|
+
pr.lastBuildCheck = ts();
|
|
428
|
+
updated = true;
|
|
425
429
|
const runs = checksData.check_runs;
|
|
426
430
|
let buildStatus = 'none';
|
|
427
431
|
let buildFailReason = '';
|
|
@@ -452,9 +456,15 @@ async function pollPrStatus(config) {
|
|
|
452
456
|
if (buildStatus === 'failing') delete pr._autoCompleted; // allow re-merge after fix
|
|
453
457
|
if (buildStatus !== 'failing') {
|
|
454
458
|
delete pr._buildFailNotified;
|
|
455
|
-
|
|
456
|
-
//
|
|
457
|
-
|
|
459
|
+
// Preserve buildErrorLog + buildFixAttempts through transient 'none'/'running'
|
|
460
|
+
// transitions — only clear on confirmed 'passing' recovery. Issue #1232:
|
|
461
|
+
// clearing on every non-failing transition blinded the next fix agent
|
|
462
|
+
// while a queued build was still running.
|
|
463
|
+
if (buildStatus === 'passing') {
|
|
464
|
+
delete pr.buildErrorLog;
|
|
465
|
+
// Reset build fix retry counter on recovery — allows fresh auto-fix cycles if build breaks again
|
|
466
|
+
if (pr.buildFixAttempts) { delete pr.buildFixAttempts; delete pr.buildFixEscalated; }
|
|
467
|
+
}
|
|
458
468
|
}
|
|
459
469
|
updated = true;
|
|
460
470
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1107",
|
|
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"
|