@yemi33/minions 0.1.1663 → 0.1.1664
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 +6 -2
- package/engine/copilot-models.json +1 -1
- package/engine/dispatch.js +47 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1664 (2026-05-01)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
- prevent duplicate PR fix dispatch (#1953)
|
|
7
|
+
|
|
8
|
+
## 0.1.1662 (2026-05-01)
|
|
4
9
|
|
|
5
10
|
### Other
|
|
6
|
-
- test(shared): add unit tests for PR URL parsing & scope helpers (#1949)
|
|
7
11
|
- test(scheduler): add unit tests for cron parsing edge cases & discovery flow (#1948)
|
|
8
12
|
|
|
9
13
|
## 0.1.1661 (2026-05-01)
|
package/engine/dispatch.js
CHANGED
|
@@ -59,16 +59,52 @@ function mutateDispatch(mutator) {
|
|
|
59
59
|
|
|
60
60
|
// ─── Add to Dispatch ─────────────────────────────────────────────────────────
|
|
61
61
|
|
|
62
|
-
function
|
|
63
|
-
if (!
|
|
64
|
-
|
|
62
|
+
function getDispatchProjectKey(project) {
|
|
63
|
+
if (!project) return '';
|
|
64
|
+
return project.name || (project.localPath ? path.resolve(project.localPath).toLowerCase() : '');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getPrDispatchTargetKey(entry) {
|
|
68
|
+
if (!entry?.meta?.pr || !entry?.meta?.project) return null;
|
|
65
69
|
const project = entry.meta.project;
|
|
66
|
-
const projectKey = project
|
|
67
|
-
|| (project.localPath ? path.resolve(project.localPath).toLowerCase() : '');
|
|
70
|
+
const projectKey = getDispatchProjectKey(project);
|
|
68
71
|
if (!projectKey) return null;
|
|
69
72
|
const prKey = shared.getCanonicalPrId(project, entry.meta.pr, entry.meta.pr?.url || '');
|
|
70
73
|
if (!prKey) return null;
|
|
71
|
-
return `${projectKey}:${
|
|
74
|
+
return `${projectKey}:${prKey}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getPrDispatchDedupeKey(entry) {
|
|
78
|
+
if (!entry?.type) return null;
|
|
79
|
+
const targetKey = getPrDispatchTargetKey(entry);
|
|
80
|
+
if (!targetKey) return null;
|
|
81
|
+
const type = entry.type === WORK_TYPE.FIX ? WORK_TYPE.FIX : entry.type;
|
|
82
|
+
return `${targetKey}:${type}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getBranchDispatchLockKey(entry) {
|
|
86
|
+
const branch = entry?.meta?.branch || entry?.meta?.pr?.branch || '';
|
|
87
|
+
if (!branch) return null;
|
|
88
|
+
const normalizedBranch = shared.sanitizeBranch(branch);
|
|
89
|
+
if (!normalizedBranch) return null;
|
|
90
|
+
const projectKey = getDispatchProjectKey(entry?.meta?.project) || 'default';
|
|
91
|
+
return `${projectKey}:${normalizedBranch}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function findActivePrOrBranchLock(dispatch, item) {
|
|
95
|
+
if (item?.type !== WORK_TYPE.FIX) return null;
|
|
96
|
+
const active = dispatch.active || [];
|
|
97
|
+
const prTargetKey = getPrDispatchTargetKey(item);
|
|
98
|
+
if (prTargetKey) {
|
|
99
|
+
const existing = active.find(d => getPrDispatchTargetKey(d) === prTargetKey);
|
|
100
|
+
if (existing) return { existing, reason: `active PR dispatch ${prTargetKey}` };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const branchLockKey = getBranchDispatchLockKey(item);
|
|
104
|
+
if (!branchLockKey) return null;
|
|
105
|
+
const existing = active.find(d => getBranchDispatchLockKey(d) === branchLockKey);
|
|
106
|
+
if (!existing) return null;
|
|
107
|
+
return { existing, reason: `active branch dispatch ${branchLockKey}` };
|
|
72
108
|
}
|
|
73
109
|
|
|
74
110
|
function addToDispatch(item) {
|
|
@@ -106,6 +142,11 @@ function addToDispatch(item) {
|
|
|
106
142
|
return dispatch;
|
|
107
143
|
}
|
|
108
144
|
}
|
|
145
|
+
const activeLock = findActivePrOrBranchLock(dispatch, item);
|
|
146
|
+
if (activeLock) {
|
|
147
|
+
log('info', `Dedup: skipping ${item.id} — ${activeLock.reason} already in ${activeLock.existing.id}`);
|
|
148
|
+
return dispatch;
|
|
149
|
+
}
|
|
109
150
|
dispatch.pending.push(item);
|
|
110
151
|
added = true;
|
|
111
152
|
return dispatch;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1664",
|
|
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"
|