@yemi33/minions 0.1.321 → 0.1.323
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 +8 -0
- package/dashboard.js +8 -2
- package/engine/cleanup.js +2 -2
- package/engine/lifecycle.js +8 -8
- package/engine.js +2 -2
- package/minions.js +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.323 (2026-04-03)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- scan skips NugetCache, OneDrive, .vs, packages + validates .git/HEAD
|
|
7
|
+
|
|
8
|
+
### Other
|
|
9
|
+
- refactor: final magic string replacements in engine, lifecycle, cleanup
|
|
10
|
+
|
|
3
11
|
## 0.1.321 (2026-04-03)
|
|
4
12
|
|
|
5
13
|
### Fixes
|
package/dashboard.js
CHANGED
|
@@ -2897,7 +2897,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
2897
2897
|
|
|
2898
2898
|
// Find git repos recursively (same logic as minions.js findGitRepos)
|
|
2899
2899
|
const skipDirs = new Set(['node_modules', '.git', '.hg', 'AppData', '$Recycle.Bin', 'Windows',
|
|
2900
|
-
'Program Files', 'Program Files (x86)', '.cache', '.npm', '.yarn', '.nuget', '
|
|
2900
|
+
'Program Files', 'Program Files (x86)', '.cache', '.npm', '.yarn', '.nuget', 'NugetCache',
|
|
2901
|
+
'worktrees', '.minions', '.squad', '.vs', '.vscode', 'obj', 'bin', 'packages',
|
|
2902
|
+
'OneDrive', 'OneDrive - Microsoft', '.copilot', 'marketplace-cache']);
|
|
2901
2903
|
const repos = [];
|
|
2902
2904
|
function walk(dir, depth) {
|
|
2903
2905
|
if (depth > maxDepth) return;
|
|
@@ -2905,7 +2907,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
2905
2907
|
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
2906
2908
|
for (const e of entries) {
|
|
2907
2909
|
if (!e.isDirectory()) continue;
|
|
2908
|
-
if (e.name === '.git') {
|
|
2910
|
+
if (e.name === '.git') {
|
|
2911
|
+
// Validate it's a real repo — must have HEAD file
|
|
2912
|
+
try { if (fs.existsSync(path.join(dir, '.git', 'HEAD'))) repos.push(dir); } catch {}
|
|
2913
|
+
return;
|
|
2914
|
+
}
|
|
2909
2915
|
if (e.name.startsWith('.') || skipDirs.has(e.name)) continue;
|
|
2910
2916
|
walk(path.join(dir, e.name), depth + 1);
|
|
2911
2917
|
}
|
package/engine/cleanup.js
CHANGED
|
@@ -111,7 +111,7 @@ function runCleanup(config, verbose = false) {
|
|
|
111
111
|
const prs = safeJson(projectPrPath(project)) || [];
|
|
112
112
|
const mergedBranches = new Set();
|
|
113
113
|
for (const pr of prs) {
|
|
114
|
-
if (pr.status ===
|
|
114
|
+
if (pr.status === shared.PR_STATUS.MERGED || pr.status === shared.PR_STATUS.ABANDONED || pr.status === shared.PLAN_STATUS.COMPLETED) {
|
|
115
115
|
if (pr.branch) mergedBranches.add(pr.branch);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -223,7 +223,7 @@ function runCleanup(config, verbose = false) {
|
|
|
223
223
|
const freshPrs = safeJson(projectPrPath(project)) || [];
|
|
224
224
|
const freshMergedBranches = new Set();
|
|
225
225
|
for (const pr of freshPrs) {
|
|
226
|
-
if (pr.status ===
|
|
226
|
+
if (pr.status === shared.PR_STATUS.MERGED || pr.status === shared.PR_STATUS.ABANDONED || pr.status === shared.PLAN_STATUS.COMPLETED) {
|
|
227
227
|
if (pr.branch) freshMergedBranches.add(pr.branch);
|
|
228
228
|
}
|
|
229
229
|
}
|
package/engine/lifecycle.js
CHANGED
|
@@ -197,7 +197,7 @@ function checkPlanCompletion(meta, config) {
|
|
|
197
197
|
const prs = (safeJson(shared.projectPrPath(p)) || [])
|
|
198
198
|
.filter(pr => {
|
|
199
199
|
const linkedId = prLinks[pr.id];
|
|
200
|
-
return pr.status ===
|
|
200
|
+
return pr.status === PR_STATUS.ACTIVE && linkedId && doneItems.find(w => w.id === linkedId);
|
|
201
201
|
});
|
|
202
202
|
if (prs.length > 0) {
|
|
203
203
|
projectPrs[p.name] = { project: p, prs, mainBranch: p.mainBranch || 'main' };
|
|
@@ -693,7 +693,7 @@ function updatePrAfterReview(agentId, pr, project) {
|
|
|
693
693
|
// Record the reviewer — actual verdict comes from ADO/GitHub votes via pollPrStatus.
|
|
694
694
|
// Set to 'waiting' so pollPrStatus updates it with the real vote on next cycle.
|
|
695
695
|
const dispatch = getDispatch();
|
|
696
|
-
const completedEntry = (dispatch.completed || []).find(d => d.agent === agentId && d.type ===
|
|
696
|
+
const completedEntry = (dispatch.completed || []).find(d => d.agent === agentId && d.type === WORK_TYPE.REVIEW);
|
|
697
697
|
|
|
698
698
|
// Set reviewStatus to 'waiting' (single source of truth — synced from ADO/GitHub votes on next poll)
|
|
699
699
|
target.reviewStatus = 'waiting';
|
|
@@ -988,7 +988,7 @@ function updateMetrics(agentId, dispatchItem, result, taskUsage, prsCreatedCount
|
|
|
988
988
|
if (result === DISPATCH_RESULT.SUCCESS) {
|
|
989
989
|
m.tasksCompleted++;
|
|
990
990
|
if (prsCreatedCount > 0) m.prsCreated = (m.prsCreated || 0) + prsCreatedCount;
|
|
991
|
-
if (dispatchItem.type ===
|
|
991
|
+
if (dispatchItem.type === WORK_TYPE.REVIEW) m.reviewsDone++;
|
|
992
992
|
} else if (result === 'retry') {
|
|
993
993
|
// Auto-retry: count cost but not as a final outcome
|
|
994
994
|
m.tasksRetried = (m.tasksRetried || 0) + 1;
|
|
@@ -1243,7 +1243,7 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
|
|
|
1243
1243
|
}
|
|
1244
1244
|
|
|
1245
1245
|
// Detect implement tasks that completed without creating a PR
|
|
1246
|
-
if (isSuccess && (type ===
|
|
1246
|
+
if (isSuccess && (type === WORK_TYPE.IMPLEMENT || type === WORK_TYPE.IMPLEMENT_LARGE || type === WORK_TYPE.FIX) && prsCreatedCount === 0 && meta?.item?.id) {
|
|
1247
1247
|
// Check if a PR already exists linked to this work item (from a previous attempt)
|
|
1248
1248
|
const projects = shared.getProjects(config);
|
|
1249
1249
|
const existingPrFound = Object.values(getPrLinks()).includes(meta.item.id);
|
|
@@ -1280,8 +1280,8 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
|
|
|
1280
1280
|
}
|
|
1281
1281
|
}
|
|
1282
1282
|
|
|
1283
|
-
if (type ===
|
|
1284
|
-
if (type ===
|
|
1283
|
+
if (type === WORK_TYPE.REVIEW) updatePrAfterReview(agentId, meta?.pr, meta?.project);
|
|
1284
|
+
if (type === WORK_TYPE.FIX) updatePrAfterFix(meta?.pr, meta?.project, meta?.source);
|
|
1285
1285
|
checkForLearnings(agentId, config.agents[agentId], dispatchItem.task);
|
|
1286
1286
|
if (isSuccess) extractSkillsFromOutput(stdout, agentId, dispatchItem, config);
|
|
1287
1287
|
updateAgentHistory(agentId, dispatchItem, result);
|
|
@@ -1311,14 +1311,14 @@ function syncPrdFromPrs(config) {
|
|
|
1311
1311
|
for (const project of allProjects) {
|
|
1312
1312
|
const wiPath = projectWorkItemsPath(project);
|
|
1313
1313
|
const items = safeJson(wiPath) || [];
|
|
1314
|
-
const hasPending = items.some(wi => wi.status ===
|
|
1314
|
+
const hasPending = items.some(wi => wi.status === WI_STATUS.PENDING && !wi._pr);
|
|
1315
1315
|
if (!hasPending) continue;
|
|
1316
1316
|
const reconciled = reconcileItemsWithPrs(items, allPrs);
|
|
1317
1317
|
if (reconciled > 0) {
|
|
1318
1318
|
safeWrite(wiPath, items);
|
|
1319
1319
|
// Sync done status to PRD JSON for each newly reconciled item
|
|
1320
1320
|
for (const wi of items) {
|
|
1321
|
-
if (wi.status ===
|
|
1321
|
+
if (wi.status === WI_STATUS.DONE) syncPrdItemStatus(wi.id, 'done', wi.sourcePlan);
|
|
1322
1322
|
}
|
|
1323
1323
|
totalReconciled += reconciled;
|
|
1324
1324
|
}
|
package/engine.js
CHANGED
|
@@ -1319,7 +1319,7 @@ function discoverFromPrs(config, project) {
|
|
|
1319
1319
|
}
|
|
1320
1320
|
|
|
1321
1321
|
// PRs with build failures — route to author (has session context from implementing)
|
|
1322
|
-
if (pr.status ===
|
|
1322
|
+
if (pr.status === PR_STATUS.ACTIVE && pr.buildStatus === 'failing') {
|
|
1323
1323
|
const key = `build-fix-${project?.name || 'default'}-${pr.id}`;
|
|
1324
1324
|
if (isAlreadyDispatched(key) || isOnCooldown(key, cooldownMs)) continue;
|
|
1325
1325
|
const agentId = resolveAgent('fix', config, pr.agent);
|
|
@@ -1638,7 +1638,7 @@ function materializeSpecsAsWorkItems(config, project) {
|
|
|
1638
1638
|
|
|
1639
1639
|
const prs = getPrs(project);
|
|
1640
1640
|
const mergedPrs = prs.filter(pr =>
|
|
1641
|
-
(pr.status ===
|
|
1641
|
+
(pr.status === PR_STATUS.MERGED || pr.status === PLAN_STATUS.COMPLETED) &&
|
|
1642
1642
|
!tracker.processedPrs[pr.id]
|
|
1643
1643
|
);
|
|
1644
1644
|
|
package/minions.js
CHANGED
|
@@ -257,7 +257,9 @@ function findGitRepos(rootDir, maxDepth = 3) {
|
|
|
257
257
|
// Skip common non-project dirs
|
|
258
258
|
const base = path.basename(dir);
|
|
259
259
|
if (['node_modules', '.git', '.hg', 'AppData', '$Recycle.Bin', 'Windows', 'Program Files',
|
|
260
|
-
'Program Files (x86)', '.cache', '.npm', '.yarn', '.nuget', '
|
|
260
|
+
'Program Files (x86)', '.cache', '.npm', '.yarn', '.nuget', 'NugetCache',
|
|
261
|
+
'worktrees', '.minions', '.squad', '.vs', '.vscode', 'obj', 'bin', 'packages',
|
|
262
|
+
'OneDrive', 'OneDrive - Microsoft', '.copilot', 'marketplace-cache'].includes(base)) return;
|
|
261
263
|
// Skip minions home directory itself
|
|
262
264
|
if (path.resolve(dir) === path.resolve(MINIONS_HOME)) return;
|
|
263
265
|
|
|
@@ -271,6 +273,8 @@ function findGitRepos(rootDir, maxDepth = 3) {
|
|
|
271
273
|
if (content.trimStart().startsWith('gitdir:')) return; // worktree, skip
|
|
272
274
|
} catch {}
|
|
273
275
|
}
|
|
276
|
+
// Validate it's a real repo — must have HEAD file
|
|
277
|
+
if (stat.isDirectory() && !fs.existsSync(path.join(gitDir, 'HEAD'))) return;
|
|
274
278
|
repos.push(dir);
|
|
275
279
|
return; // Don't recurse into git repos (they may have nested submodules)
|
|
276
280
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.323",
|
|
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"
|