@yemi33/minions 0.1.804 → 0.1.806
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 +3 -1
- package/engine/ado.js +12 -6
- package/engine/timeout.js +2 -2
- package/engine.js +12 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.806 (2026-04-10)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- configurable ignored comment authors — auto-filtered, never trigger fixes
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
- cap review→fix cycles at evalMaxIterations (default 3)
|
|
10
10
|
|
|
11
11
|
### Fixes
|
|
12
|
+
- adoFetch supports method/body for PATCH requests (auto-complete)
|
|
13
|
+
- prevent false [process-exit] detection from tool result content
|
|
12
14
|
- allow PRD item retry when work item is missing (closes #781) (#807)
|
|
13
15
|
- handle force-pushed dep branches on retry (closes #738) (#806)
|
|
14
16
|
- project-scoped skill work items instruct wrong file path format (closes #790) (#804)
|
package/engine/ado.js
CHANGED
|
@@ -60,21 +60,26 @@ async function getAdoToken() {
|
|
|
60
60
|
return null;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
async function adoFetch(url, token,
|
|
63
|
+
async function adoFetch(url, token, opts = {}) {
|
|
64
|
+
const _retryCount = typeof opts === 'number' ? opts : (opts._retryCount || 0); // backward compat
|
|
65
|
+
const method = (typeof opts === 'object' && opts.method) || 'GET';
|
|
66
|
+
const body = (typeof opts === 'object' && opts.body) || undefined;
|
|
64
67
|
const MAX_RETRIES = 1;
|
|
65
68
|
const res = await fetch(url, {
|
|
66
|
-
|
|
69
|
+
method,
|
|
70
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
71
|
+
signal: AbortSignal.timeout(30000),
|
|
72
|
+
body,
|
|
67
73
|
});
|
|
68
|
-
if (!res.ok) throw new Error(`ADO API ${res.status}: ${res.statusText}`);
|
|
74
|
+
if (!res.ok) throw new Error(`ADO API ${method} ${res.status}: ${res.statusText}`);
|
|
69
75
|
const text = await res.text();
|
|
70
76
|
if (!text || text.trimStart().startsWith('<')) {
|
|
71
|
-
// Invalidate cached token — it's likely expired
|
|
72
77
|
_adoTokenCache = { token: null, expiresAt: 0 };
|
|
73
78
|
if (_retryCount < MAX_RETRIES) {
|
|
74
79
|
const freshToken = await getAdoToken();
|
|
75
80
|
if (freshToken) {
|
|
76
81
|
log('info', 'ADO token expired mid-session — refreshed and retrying');
|
|
77
|
-
return adoFetch(url, freshToken, _retryCount + 1);
|
|
82
|
+
return adoFetch(url, freshToken, { ...opts, _retryCount: _retryCount + 1 });
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
throw new Error(`ADO returned HTML instead of JSON (likely auth redirect) for ${url.split('?')[0]}`);
|
|
@@ -85,7 +90,8 @@ async function adoFetch(url, token, _retryCount = 0) {
|
|
|
85
90
|
/** Fetch raw text from ADO API (for build logs which aren't JSON). */
|
|
86
91
|
async function adoFetchText(url, token) {
|
|
87
92
|
const res = await fetch(url, {
|
|
88
|
-
headers: { 'Authorization': `Bearer ${token}` }
|
|
93
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
94
|
+
signal: AbortSignal.timeout(30000),
|
|
89
95
|
});
|
|
90
96
|
if (!res.ok) throw new Error(`ADO API ${res.status}: ${res.statusText}`);
|
|
91
97
|
return res.text();
|
package/engine/timeout.js
CHANGED
|
@@ -193,7 +193,7 @@ function checkTimeouts(config) {
|
|
|
193
193
|
fs.closeSync(fd);
|
|
194
194
|
liveLog = buf.toString('utf8');
|
|
195
195
|
} catch { /* ENOENT or read failure — liveLog stays undefined */ }
|
|
196
|
-
if (liveLog && (liveLog.includes('"type":"result"') || liveLog.includes('[process-exit]'))) {
|
|
196
|
+
if (liveLog && (liveLog.includes('"type":"result"') || liveLog.includes('\n[process-exit]'))) {
|
|
197
197
|
completedViaOutput = true;
|
|
198
198
|
const isSuccess = liveLog.includes('"subtype":"success"');
|
|
199
199
|
log('info', `Agent ${item.agent} (${item.id}) completed via output detection (${isSuccess ? 'success' : 'error'})`);
|
|
@@ -237,7 +237,7 @@ function checkTimeouts(config) {
|
|
|
237
237
|
if (liveLog) {
|
|
238
238
|
// If the output contains a result event or process-exit sentinel, the agent is done.
|
|
239
239
|
// Don't extend timeout for stale blocking tool calls from before the result (#716).
|
|
240
|
-
if (liveLog.includes('"type":"result"') || liveLog.includes('[process-exit]')) {
|
|
240
|
+
if (liveLog.includes('"type":"result"') || liveLog.includes('\n[process-exit]')) {
|
|
241
241
|
// Agent completed but close event didn't fire — let orphan/hung detection handle it.
|
|
242
242
|
// Don't set isBlocking — use base heartbeat timeout.
|
|
243
243
|
} else {
|
package/engine.js
CHANGED
|
@@ -2698,16 +2698,27 @@ let tickCount = 0;
|
|
|
2698
2698
|
const completedPlanCache = new Set();
|
|
2699
2699
|
|
|
2700
2700
|
let tickRunning = false;
|
|
2701
|
+
let _tickStartedAt = 0;
|
|
2702
|
+
const TICK_TIMEOUT_MS = 300000; // 5 min — force-release tick lock if stuck
|
|
2701
2703
|
|
|
2702
2704
|
async function tick() {
|
|
2703
|
-
if (tickRunning)
|
|
2705
|
+
if (tickRunning) {
|
|
2706
|
+
if (_tickStartedAt && Date.now() - _tickStartedAt > TICK_TIMEOUT_MS) {
|
|
2707
|
+
log('error', `Tick hung for ${Math.round((Date.now() - _tickStartedAt) / 1000)}s — force-releasing lock`);
|
|
2708
|
+
tickRunning = false;
|
|
2709
|
+
_tickStartedAt = 0;
|
|
2710
|
+
}
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2704
2713
|
tickRunning = true;
|
|
2714
|
+
_tickStartedAt = Date.now();
|
|
2705
2715
|
try {
|
|
2706
2716
|
await tickInner();
|
|
2707
2717
|
} catch (e) {
|
|
2708
2718
|
log('error', `Tick error: ${e.message}`);
|
|
2709
2719
|
} finally {
|
|
2710
2720
|
tickRunning = false;
|
|
2721
|
+
_tickStartedAt = 0;
|
|
2711
2722
|
}
|
|
2712
2723
|
}
|
|
2713
2724
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.806",
|
|
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"
|