@yemi33/minions 0.1.1001 → 0.1.1002
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 +2 -2
- package/engine/ado.js +24 -0
- package/engine/lifecycle.js +20 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1002 (2026-04-15)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- fix stopAfter=0 watch expiry — run forever for all conditions (#1117)
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
- gate auto-fix conflict dispatch behind autoFixConflicts flag
|
|
26
26
|
|
|
27
27
|
### Fixes
|
|
28
|
+
- extend auto-link fallback to ADO projects
|
|
28
29
|
- auto-link existing GitHub PR when agent completes without creating one
|
|
29
30
|
- preserve ordered lists across blank lines in markdown renderer
|
|
30
31
|
- restore CC rendering and tab bar
|
|
@@ -44,7 +45,6 @@
|
|
|
44
45
|
- address review feedback — move writeToInbox outside lock, add absolute condition auto-expire
|
|
45
46
|
- fix watches feature gaps — human notifications, branch stub, status-change init, unique keys
|
|
46
47
|
- skip isAlreadyDispatched in needsReReview to allow re-review within 1hr
|
|
47
|
-
- skip SessionStart hook settings test on CI
|
|
48
48
|
|
|
49
49
|
### Other
|
|
50
50
|
- docs: update CLAUDE.md with recent Minions architecture changes
|
package/engine/ado.js
CHANGED
|
@@ -890,6 +890,29 @@ const isAdoThrottled = () => _adoThrottle.isThrottled();
|
|
|
890
890
|
/** Returns a snapshot of the current throttle state. Calls isAdoThrottled() for a fresh value. */
|
|
891
891
|
const getAdoThrottleState = () => _adoThrottle.getState();
|
|
892
892
|
|
|
893
|
+
/**
|
|
894
|
+
* Query ADO for an open PR on a specific branch.
|
|
895
|
+
* Used as a last-resort fallback when an agent completes without logging a PR URL
|
|
896
|
+
* but a PR may already exist from a prior orphaned dispatch.
|
|
897
|
+
* @param {object} project — project config with adoOrg, adoProject, repositoryId, prUrlBase
|
|
898
|
+
* @param {string} branch — source branch name (without refs/heads/ prefix)
|
|
899
|
+
* @returns {{ prNumber: number, url: string }|null}
|
|
900
|
+
*/
|
|
901
|
+
async function findOpenPrOnBranch(project, branch) {
|
|
902
|
+
if (!project.adoOrg || !project.adoProject || !project.repositoryId || !branch) return null;
|
|
903
|
+
const token = await getAdoToken();
|
|
904
|
+
if (!token) return null;
|
|
905
|
+
const orgBase = shared.getAdoOrgBase(project);
|
|
906
|
+
const sourceRef = encodeURIComponent(`refs/heads/${branch}`);
|
|
907
|
+
const url = `${orgBase}/${project.adoProject}/_apis/git/repositories/${project.repositoryId}/pullrequests?searchCriteria.status=active&searchCriteria.sourceRefName=${sourceRef}&api-version=7.1`;
|
|
908
|
+
const data = await adoFetch(url, token);
|
|
909
|
+
const pr = (data.value || [])[0];
|
|
910
|
+
if (!pr) return null;
|
|
911
|
+
const prNumber = pr.pullRequestId;
|
|
912
|
+
const prUrl = project.prUrlBase ? `${project.prUrlBase}${prNumber}` : `https://dev.azure.com/${project.adoOrg}/${project.adoProject}/_git/${project.repositoryId}/pullrequest/${prNumber}`;
|
|
913
|
+
return { prNumber, url: prUrl };
|
|
914
|
+
}
|
|
915
|
+
|
|
893
916
|
/** Reset throttle state — exported for testing only. */
|
|
894
917
|
function _resetAdoThrottle() {
|
|
895
918
|
_adoThrottle._reset();
|
|
@@ -913,6 +936,7 @@ module.exports = {
|
|
|
913
936
|
getAdoThrottleState,
|
|
914
937
|
fetchAdoPrMetadata,
|
|
915
938
|
fetchSinglePrBuildStatus,
|
|
939
|
+
findOpenPrOnBranch,
|
|
916
940
|
_resetAdoThrottle, // exported for testing
|
|
917
941
|
_setAdoThrottleForTest, // exported for testing
|
|
918
942
|
};
|
package/engine/lifecycle.js
CHANGED
|
@@ -1792,37 +1792,44 @@ async function runPostCompletionHooks(dispatchItem, agentId, code, stdout, confi
|
|
|
1792
1792
|
}
|
|
1793
1793
|
}
|
|
1794
1794
|
}
|
|
1795
|
-
// Last resort: query
|
|
1795
|
+
// Last resort: query the platform directly for an open PR on this branch.
|
|
1796
1796
|
// Handles the case where a prior orphaned dispatch created a PR but the engine
|
|
1797
|
-
// never processed its output — so the PR exists on
|
|
1797
|
+
// never processed its output — so the PR exists on the platform but not in pull-requests.json.
|
|
1798
1798
|
if (!existingPrFound && meta?.branch) {
|
|
1799
1799
|
const projectObj = shared.getProjects(config).find(p => p.name === meta?.project?.name);
|
|
1800
|
-
|
|
1801
|
-
if (projectObj?.repoHost === 'github' && ghSlug) {
|
|
1800
|
+
if (projectObj) {
|
|
1802
1801
|
try {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1802
|
+
let found = null;
|
|
1803
|
+
if (projectObj.repoHost === 'github') {
|
|
1804
|
+
const ghSlug = projectObj.prUrlBase?.match(/github\.com\/([^/]+\/[^/]+)\/pull/)?.[1];
|
|
1805
|
+
if (ghSlug) {
|
|
1806
|
+
const raw = await execAsync(`gh pr list --head "${meta.branch}" --repo ${ghSlug} --json number,url,state --limit 1`, { timeout: 15000, windowsHide: true });
|
|
1807
|
+
const hits = JSON.parse(raw || '[]');
|
|
1808
|
+
if (hits.length > 0 && hits[0].state === 'OPEN') found = { prNumber: hits[0].number, url: hits[0].url };
|
|
1809
|
+
}
|
|
1810
|
+
} else {
|
|
1811
|
+
found = await require('./ado').findOpenPrOnBranch(projectObj, meta.branch);
|
|
1812
|
+
}
|
|
1813
|
+
if (found) {
|
|
1814
|
+
const fullId = `PR-${found.prNumber}`;
|
|
1808
1815
|
const prPath = shared.projectPrPath(projectObj);
|
|
1809
1816
|
mutateJsonFileLocked(prPath, prs => {
|
|
1810
1817
|
if (!Array.isArray(prs)) prs = [];
|
|
1811
1818
|
if (prs.some(p => p.id === fullId)) return prs;
|
|
1812
1819
|
prs.push({
|
|
1813
|
-
id: fullId, prNumber:
|
|
1820
|
+
id: fullId, prNumber: found.prNumber, title: meta.item?.title || '',
|
|
1814
1821
|
agent: agentId, branch: meta.branch, reviewStatus: 'pending',
|
|
1815
|
-
status: PR_STATUS.ACTIVE, created: ts(), url: found
|
|
1822
|
+
status: PR_STATUS.ACTIVE, created: ts(), url: found.url,
|
|
1816
1823
|
prdItems: meta.item?.id ? [meta.item.id] : [],
|
|
1817
1824
|
sourcePlan: meta.item?.sourcePlan || '', itemType: meta.item?.itemType || '',
|
|
1818
1825
|
});
|
|
1819
1826
|
return prs;
|
|
1820
1827
|
});
|
|
1821
1828
|
if (meta.item?.id) addPrLink(fullId, meta.item.id);
|
|
1822
|
-
log('info', `Auto-linked existing
|
|
1829
|
+
log('info', `Auto-linked existing PR ${fullId} on branch ${meta.branch} for ${meta.item?.id}`);
|
|
1823
1830
|
existingPrFound = true;
|
|
1824
1831
|
}
|
|
1825
|
-
} catch (e) { log('warn', `
|
|
1832
|
+
} catch (e) { log('warn', `PR lookup for branch ${meta.branch}: ${e.message}`); }
|
|
1826
1833
|
}
|
|
1827
1834
|
}
|
|
1828
1835
|
if (!existingPrFound) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1002",
|
|
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"
|