@yemi33/minions 0.1.1550 → 0.1.1552
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 +9 -3
- package/engine/queries.js +49 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1552 (2026-04-27)
|
|
4
4
|
|
|
5
5
|
### Fixes
|
|
6
|
-
-
|
|
6
|
+
- scan all project subdirs for PR data in PRD view
|
|
7
|
+
|
|
8
|
+
## 0.1.1551 (2026-04-27)
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
- derive PR URL from canonical PR ID scope, not projects[0]
|
|
12
|
+
|
|
13
|
+
## 0.1.1549 (2026-04-24)
|
|
7
14
|
|
|
8
15
|
### Other
|
|
9
|
-
- test(engine): add unit tests for isWorktreeRetryableError, removeStaleIndexLock, _maxTurnsForType, buildProjectContext, normalizeAc (#1752)
|
|
10
16
|
- test(timeout): add unit tests for checkIdleThreshold, checkSteering, checkTimeouts (#1748)
|
|
11
17
|
|
|
12
18
|
## 0.1.1548 (2026-04-23)
|
package/engine/queries.js
CHANGED
|
@@ -1021,6 +1021,52 @@ function getPrdInfo(config) {
|
|
|
1021
1021
|
const allPrs = getPullRequests(config);
|
|
1022
1022
|
const prById = {};
|
|
1023
1023
|
for (const pr of allPrs) prById[pr.id] = pr;
|
|
1024
|
+
// Also scan project subdirectories that aren't in config (e.g. removed projects
|
|
1025
|
+
// whose pull-requests.json still holds last-known status). getPrLinks already
|
|
1026
|
+
// reads all subdirs, so without this PRs from those dirs would have status/title
|
|
1027
|
+
// missing in the PRD view and fall back to literal 'active'/'' defaults.
|
|
1028
|
+
try {
|
|
1029
|
+
const projectsDir = path.join(MINIONS_DIR, 'projects');
|
|
1030
|
+
const projectsByName = new Map(projects.map(p => [p.name, p]));
|
|
1031
|
+
for (const d of fs.readdirSync(projectsDir, { withFileTypes: true })) {
|
|
1032
|
+
if (!d.isDirectory() || projectsByName.has(d.name)) continue;
|
|
1033
|
+
const ghostPath = path.join(projectsDir, d.name, 'pull-requests.json');
|
|
1034
|
+
const ghostPrs = safeJson(ghostPath);
|
|
1035
|
+
if (!Array.isArray(ghostPrs)) continue;
|
|
1036
|
+
shared.normalizePrRecords(ghostPrs, null);
|
|
1037
|
+
for (const pr of ghostPrs) {
|
|
1038
|
+
if (pr?.id && !prById[pr.id]) {
|
|
1039
|
+
pr._project = d.name;
|
|
1040
|
+
prById[pr.id] = pr;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
} catch { /* projects dir missing */ }
|
|
1045
|
+
|
|
1046
|
+
// Build URL for a PR when pr.url isn't set. Prefer the PR ID's own scope
|
|
1047
|
+
// (e.g. `github:owner/repo#123` → github.com URL) so a github PR never gets
|
|
1048
|
+
// an ADO URL just because the only configured project happens to be ADO.
|
|
1049
|
+
// Only use a project's prUrlBase when its host actually matches the PR.
|
|
1050
|
+
const _buildPrUrlFromId = (prId, pr) => {
|
|
1051
|
+
if (pr?.url) return pr.url;
|
|
1052
|
+
const canonical = shared.parseCanonicalPrId(prId);
|
|
1053
|
+
if (canonical) {
|
|
1054
|
+
const [host, rest] = canonical.scope.split(':');
|
|
1055
|
+
if (host === 'github') return `https://github.com/${rest}/pull/${canonical.prNumber}`;
|
|
1056
|
+
if (host === 'ado') {
|
|
1057
|
+
const [org, adoProject, repo] = rest.split('/');
|
|
1058
|
+
if (org && adoProject && repo) {
|
|
1059
|
+
return `https://dev.azure.com/${org}/${adoProject}/_git/${repo}/pullrequest/${canonical.prNumber}`;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
// Legacy `PR-N` ID with no host scope: only use project's prUrlBase if a
|
|
1064
|
+
// matching project (by name) exists. Never blindly fall back to projects[0].
|
|
1065
|
+
const project = pr?._project ? projects.find(p => p.name === pr._project) : null;
|
|
1066
|
+
const prNumber = shared.getPrNumber(pr || prId);
|
|
1067
|
+
if (project?.prUrlBase && prNumber != null) return project.prUrlBase + prNumber;
|
|
1068
|
+
return '';
|
|
1069
|
+
};
|
|
1024
1070
|
|
|
1025
1071
|
const prdToPr = {};
|
|
1026
1072
|
const prLinks = shared.getPrLinks(); // { "PR-xxxx": ["P-xxxx", "P-yyyy"] }
|
|
@@ -1030,9 +1076,7 @@ function getPrdInfo(config) {
|
|
|
1030
1076
|
// (or are typed as verify) and would bleed through as duplicate entries on every
|
|
1031
1077
|
// constituent item. They are surfaced via renderE2eSection instead. (#1220)
|
|
1032
1078
|
if ((itemIds || []).length > 1 || pr?.itemType === 'verify' || pr?.title?.startsWith('[E2E]')) continue;
|
|
1033
|
-
const
|
|
1034
|
-
const prNumber = shared.getPrNumber(pr || prId);
|
|
1035
|
-
const url = pr?.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
|
|
1079
|
+
const url = _buildPrUrlFromId(prId, pr);
|
|
1036
1080
|
for (const itemId of (itemIds || [])) {
|
|
1037
1081
|
if (!prdToPr[itemId]) prdToPr[itemId] = [];
|
|
1038
1082
|
prdToPr[itemId].push({ id: prId, url, title: pr?.title || '', status: pr?.status || 'active', _project: pr?._project || '' });
|
|
@@ -1046,8 +1090,7 @@ function getPrdInfo(config) {
|
|
|
1046
1090
|
const exactPr = prById[canonicalPrId] || null;
|
|
1047
1091
|
const displayMatches = exactPr ? [] : Object.values(prById).filter(candidate => shared.getPrDisplayId(candidate) === shared.getPrDisplayId(wi._pr));
|
|
1048
1092
|
const pr = exactPr || (displayMatches.length === 1 ? displayMatches[0] : null);
|
|
1049
|
-
const
|
|
1050
|
-
const url = pr?.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
|
|
1093
|
+
const url = _buildPrUrlFromId(canonicalPrId || wi._pr, pr);
|
|
1051
1094
|
prdToPr[wi.id] = [{ id: pr?.id || canonicalPrId || wi._pr, url, title: pr?.title || '', status: pr?.status || 'active', _project: project?.name || '' }];
|
|
1052
1095
|
}
|
|
1053
1096
|
// Aggregate sub-task PRs to decomposed parent (sub-tasks aren't PRD items but their PRs should show)
|
|
@@ -1060,9 +1103,7 @@ function getPrdInfo(config) {
|
|
|
1060
1103
|
const parentId = wi.parent_id;
|
|
1061
1104
|
if (!prdToPr[parentId]) prdToPr[parentId] = [];
|
|
1062
1105
|
if (!prdToPr[parentId].some(p => p.id === pr.id)) {
|
|
1063
|
-
const
|
|
1064
|
-
const prNumber = shared.getPrNumber(pr);
|
|
1065
|
-
const url = pr.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
|
|
1106
|
+
const url = _buildPrUrlFromId(pr.id, pr);
|
|
1066
1107
|
prdToPr[parentId].push({ id: pr.id, url, title: pr.title || '', status: pr.status || 'active', _project: pr._project || '' });
|
|
1067
1108
|
}
|
|
1068
1109
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1552",
|
|
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"
|