@yemi33/minions 0.1.550 → 0.1.551
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 +5 -0
- package/dashboard/js/render-prs.js +2 -2
- package/dashboard/styles.css +1 -0
- package/engine/ado.js +34 -0
- package/engine.js +3 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,8 +12,8 @@ function prRow(pr) {
|
|
|
12
12
|
const reviewSource = sq.status || effectiveReviewStatus || 'pending';
|
|
13
13
|
const reviewClass = reviewSource === 'approved' ? 'approved' : (reviewSource === 'changes-requested' || reviewSource === 'rejected') ? 'rejected' : reviewSource === 'waiting' ? 'building' : 'draft';
|
|
14
14
|
const reviewLabel = sq.status === 'waiting' ? 'reviewing (minions)' : sq.status ? sq.status + ' (minions)' : (effectiveReviewStatus || 'pending');
|
|
15
|
-
const buildClass = pr.buildStatus === 'passing' ? 'build-pass' : pr.buildStatus === 'failing' ? 'build-fail' : pr.buildStatus === 'running' ? 'building' : 'no-build';
|
|
16
|
-
const buildLabel = pr.buildStatus || 'none';
|
|
15
|
+
const buildClass = pr._buildStatusStale ? 'build-stale' : pr.buildStatus === 'passing' ? 'build-pass' : pr.buildStatus === 'failing' ? 'build-fail' : pr.buildStatus === 'running' ? 'building' : 'no-build';
|
|
16
|
+
const buildLabel = (pr.buildStatus || 'none') + (pr._buildStatusStale ? ' (stale)' : '');
|
|
17
17
|
const statusClass = pr.status === 'merged' ? 'merged' : pr.status === 'abandoned' ? 'rejected' : pr.status === 'active' ? 'active' : 'draft';
|
|
18
18
|
const statusLabel = pr.status || 'active';
|
|
19
19
|
const url = pr.url || '#';
|
package/dashboard/styles.css
CHANGED
|
@@ -251,6 +251,7 @@
|
|
|
251
251
|
.pr-badge.build-pass { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
252
252
|
.pr-badge.build-fail { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); }
|
|
253
253
|
.pr-badge.no-build { background: var(--surface); color: var(--muted); border: 1px solid var(--border); }
|
|
254
|
+
.pr-badge.build-stale { background: rgba(210,153,34,0.15); color: var(--orange); border: 1px dashed var(--orange); }
|
|
254
255
|
.error-details-btn { font-size: var(--text-xs); padding: var(--space-1) var(--space-3); margin-left: var(--space-2); background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); border-radius: var(--radius-lg); cursor: pointer; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }
|
|
255
256
|
.error-details-btn:hover { background: rgba(248,81,73,0.3); }
|
|
256
257
|
.pr-empty { color: var(--muted); font-style: italic; font-size: var(--text-md); padding: var(--space-6) 0; }
|
package/engine/ado.js
CHANGED
|
@@ -21,6 +21,20 @@ function engine() {
|
|
|
21
21
|
let _adoTokenCache = { token: null, expiresAt: 0 };
|
|
22
22
|
let _adoTokenFailedUntil = 0; // backoff: skip azureauth calls until this timestamp
|
|
23
23
|
|
|
24
|
+
// ─── Auth Failure Tracking ──────────────────────────────────────────────────
|
|
25
|
+
// Set when pollPrStatus encounters auth errors mid-loop. The engine checks this
|
|
26
|
+
// to bypass the normal 6-tick cadence and re-poll on the next tick.
|
|
27
|
+
let _adoPollHadAuthFailure = false;
|
|
28
|
+
|
|
29
|
+
/** Check if auth failure during PR poll means an early re-poll is needed. */
|
|
30
|
+
function needsAdoPollRetry() { return _adoPollHadAuthFailure; }
|
|
31
|
+
|
|
32
|
+
/** Detect auth-related errors from adoFetch (HTML redirect, 401, 403). */
|
|
33
|
+
function isAdoAuthError(err) {
|
|
34
|
+
const msg = err?.message || '';
|
|
35
|
+
return msg.includes('auth redirect') || msg.includes('HTML instead of JSON') || /ADO API (401|403)/.test(msg);
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
async function getAdoToken() {
|
|
25
39
|
if (_adoTokenCache.token && Date.now() < _adoTokenCache.expiresAt) {
|
|
26
40
|
return _adoTokenCache.token;
|
|
@@ -133,16 +147,23 @@ async function forEachActivePr(config, token, callback) {
|
|
|
133
147
|
// ─── PR Status Polling ───────────────────────────────────────────────────────
|
|
134
148
|
|
|
135
149
|
async function pollPrStatus(config) {
|
|
150
|
+
_adoPollHadAuthFailure = false; // reset before polling — set again if errors recur
|
|
151
|
+
|
|
136
152
|
const token = await getAdoToken();
|
|
137
153
|
if (!token) {
|
|
138
154
|
log('warn', 'Skipping PR status poll — no ADO token available');
|
|
155
|
+
_adoPollHadAuthFailure = true; // trigger retry on next tick
|
|
139
156
|
return;
|
|
140
157
|
}
|
|
141
158
|
|
|
142
159
|
const totalUpdated = await forEachActivePr(config, token, async (project, pr, prNum, orgBase) => {
|
|
160
|
+
try {
|
|
143
161
|
const repoBase = `${orgBase}/${project.adoProject}/_apis/git/repositories/${project.repositoryId}/pullrequests/${prNum}`;
|
|
144
162
|
let updated = false;
|
|
145
163
|
|
|
164
|
+
// Clear stale flag — we're attempting a fresh poll
|
|
165
|
+
if (pr._buildStatusStale) { delete pr._buildStatusStale; updated = true; }
|
|
166
|
+
|
|
146
167
|
const prData = await adoFetch(`${repoBase}?api-version=7.1`, token);
|
|
147
168
|
|
|
148
169
|
let newStatus = pr.status;
|
|
@@ -278,6 +299,17 @@ async function pollPrStatus(config) {
|
|
|
278
299
|
}
|
|
279
300
|
|
|
280
301
|
return updated;
|
|
302
|
+
} catch (err) {
|
|
303
|
+
// Auth errors → mark build status stale so dashboard shows uncertainty
|
|
304
|
+
// and engine re-polls on next tick instead of waiting 6 ticks
|
|
305
|
+
if (isAdoAuthError(err)) {
|
|
306
|
+
pr._buildStatusStale = true;
|
|
307
|
+
_adoPollHadAuthFailure = true;
|
|
308
|
+
log('warn', `PR ${pr.id}: build status marked stale (auth error: ${err.message})`);
|
|
309
|
+
return true; // count as updated to persist the stale flag
|
|
310
|
+
}
|
|
311
|
+
throw err; // re-throw non-auth errors for forEachActivePr to handle
|
|
312
|
+
}
|
|
281
313
|
});
|
|
282
314
|
|
|
283
315
|
if (totalUpdated > 0) {
|
|
@@ -520,5 +552,7 @@ module.exports = {
|
|
|
520
552
|
pollPrHumanComments,
|
|
521
553
|
reconcilePrs,
|
|
522
554
|
checkLiveReviewStatus,
|
|
555
|
+
needsAdoPollRetry,
|
|
556
|
+
isAdoAuthError, // exported for testing
|
|
523
557
|
};
|
|
524
558
|
|
package/engine.js
CHANGED
|
@@ -937,7 +937,7 @@ function reconcileItemsWithPrs(items, allPrs, { onlyIds } = {}) {
|
|
|
937
937
|
// ─── Inbox Consolidation (extracted to engine/consolidation.js) ──────────────
|
|
938
938
|
|
|
939
939
|
const { consolidateInbox } = require('./engine/consolidation');
|
|
940
|
-
const { pollPrStatus, pollPrHumanComments, reconcilePrs, checkLiveReviewStatus: adoCheckLiveReview } = require('./engine/ado');
|
|
940
|
+
const { pollPrStatus, pollPrHumanComments, reconcilePrs, checkLiveReviewStatus: adoCheckLiveReview, needsAdoPollRetry } = require('./engine/ado');
|
|
941
941
|
const { pollPrStatus: ghPollPrStatus, pollPrHumanComments: ghPollPrHumanComments, reconcilePrs: ghReconcilePrs, checkLiveReviewStatus: ghCheckLiveReview } = require('./engine/github');
|
|
942
942
|
|
|
943
943
|
// ─── State Snapshot ─────────────────────────────────────────────────────────
|
|
@@ -2447,7 +2447,8 @@ async function tickInner() {
|
|
|
2447
2447
|
|
|
2448
2448
|
// 2.6. Poll PR status: build, review, merge (every 6 ticks = ~3 minutes)
|
|
2449
2449
|
// Awaited so PR state is consistent before discoverWork reads it
|
|
2450
|
-
if (
|
|
2450
|
+
// Also re-polls early if previous tick had ADO auth failures (stale build status recovery)
|
|
2451
|
+
if (tickCount % 6 === 0 || needsAdoPollRetry()) {
|
|
2451
2452
|
try { await pollPrStatus(config); } catch (err) { log('warn', `ADO PR status poll error: ${err?.message || err}${err?.stack ? ' | ' + err.stack.split('\n')[1]?.trim() : ''}`); }
|
|
2452
2453
|
try { await ghPollPrStatus(config); } catch (err) { log('warn', `GitHub PR status poll error: ${err?.message || err}${err?.stack ? ' | ' + err.stack.split('\n')[1]?.trim() : ''}`); }
|
|
2453
2454
|
// Sync PR status back to PRD items (missing → done when active PR exists)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.551",
|
|
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"
|