@yemi33/minions 0.1.1550 → 0.1.1551

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 CHANGED
@@ -1,12 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1550 (2026-04-24)
3
+ ## 0.1.1551 (2026-04-27)
4
4
 
5
5
  ### Fixes
6
- - escape </script> literal in utils.js (closes #1746) (#1751)
6
+ - derive PR URL from canonical PR ID scope, not projects[0]
7
+
8
+ ## 0.1.1549 (2026-04-24)
7
9
 
8
10
  ### Other
9
- - test(engine): add unit tests for isWorktreeRetryableError, removeStaleIndexLock, _maxTurnsForType, buildProjectContext, normalizeAc (#1752)
10
11
  - test(timeout): add unit tests for checkIdleThreshold, checkSteering, checkTimeouts (#1748)
11
12
 
12
13
  ## 0.1.1548 (2026-04-23)
package/engine/queries.js CHANGED
@@ -1022,6 +1022,31 @@ function getPrdInfo(config) {
1022
1022
  const prById = {};
1023
1023
  for (const pr of allPrs) prById[pr.id] = pr;
1024
1024
 
1025
+ // Build URL for a PR when pr.url isn't set. Prefer the PR ID's own scope
1026
+ // (e.g. `github:owner/repo#123` → github.com URL) so a github PR never gets
1027
+ // an ADO URL just because the only configured project happens to be ADO.
1028
+ // Only use a project's prUrlBase when its host actually matches the PR.
1029
+ const _buildPrUrlFromId = (prId, pr) => {
1030
+ if (pr?.url) return pr.url;
1031
+ const canonical = shared.parseCanonicalPrId(prId);
1032
+ if (canonical) {
1033
+ const [host, rest] = canonical.scope.split(':');
1034
+ if (host === 'github') return `https://github.com/${rest}/pull/${canonical.prNumber}`;
1035
+ if (host === 'ado') {
1036
+ const [org, adoProject, repo] = rest.split('/');
1037
+ if (org && adoProject && repo) {
1038
+ return `https://dev.azure.com/${org}/${adoProject}/_git/${repo}/pullrequest/${canonical.prNumber}`;
1039
+ }
1040
+ }
1041
+ }
1042
+ // Legacy `PR-N` ID with no host scope: only use project's prUrlBase if a
1043
+ // matching project (by name) exists. Never blindly fall back to projects[0].
1044
+ const project = pr?._project ? projects.find(p => p.name === pr._project) : null;
1045
+ const prNumber = shared.getPrNumber(pr || prId);
1046
+ if (project?.prUrlBase && prNumber != null) return project.prUrlBase + prNumber;
1047
+ return '';
1048
+ };
1049
+
1025
1050
  const prdToPr = {};
1026
1051
  const prLinks = shared.getPrLinks(); // { "PR-xxxx": ["P-xxxx", "P-yyyy"] }
1027
1052
  for (const [prId, itemIds] of Object.entries(prLinks)) {
@@ -1030,9 +1055,7 @@ function getPrdInfo(config) {
1030
1055
  // (or are typed as verify) and would bleed through as duplicate entries on every
1031
1056
  // constituent item. They are surfaced via renderE2eSection instead. (#1220)
1032
1057
  if ((itemIds || []).length > 1 || pr?.itemType === 'verify' || pr?.title?.startsWith('[E2E]')) continue;
1033
- const project = projects.find(p => p.name === pr?._project) || projects[0] || null;
1034
- const prNumber = shared.getPrNumber(pr || prId);
1035
- const url = pr?.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
1058
+ const url = _buildPrUrlFromId(prId, pr);
1036
1059
  for (const itemId of (itemIds || [])) {
1037
1060
  if (!prdToPr[itemId]) prdToPr[itemId] = [];
1038
1061
  prdToPr[itemId].push({ id: prId, url, title: pr?.title || '', status: pr?.status || 'active', _project: pr?._project || '' });
@@ -1046,8 +1069,7 @@ function getPrdInfo(config) {
1046
1069
  const exactPr = prById[canonicalPrId] || null;
1047
1070
  const displayMatches = exactPr ? [] : Object.values(prById).filter(candidate => shared.getPrDisplayId(candidate) === shared.getPrDisplayId(wi._pr));
1048
1071
  const pr = exactPr || (displayMatches.length === 1 ? displayMatches[0] : null);
1049
- const prNumber = shared.getPrNumber(pr || wi._pr);
1050
- const url = pr?.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
1072
+ const url = _buildPrUrlFromId(canonicalPrId || wi._pr, pr);
1051
1073
  prdToPr[wi.id] = [{ id: pr?.id || canonicalPrId || wi._pr, url, title: pr?.title || '', status: pr?.status || 'active', _project: project?.name || '' }];
1052
1074
  }
1053
1075
  // Aggregate sub-task PRs to decomposed parent (sub-tasks aren't PRD items but their PRs should show)
@@ -1060,9 +1082,7 @@ function getPrdInfo(config) {
1060
1082
  const parentId = wi.parent_id;
1061
1083
  if (!prdToPr[parentId]) prdToPr[parentId] = [];
1062
1084
  if (!prdToPr[parentId].some(p => p.id === pr.id)) {
1063
- const project = projects.find(p => p.name === pr._project) || projects[0] || null;
1064
- const prNumber = shared.getPrNumber(pr);
1065
- const url = pr.url || (project?.prUrlBase && prNumber != null ? project.prUrlBase + prNumber : '');
1085
+ const url = _buildPrUrlFromId(pr.id, pr);
1066
1086
  prdToPr[parentId].push({ id: pr.id, url, title: pr.title || '', status: pr.status || 'active', _project: pr._project || '' });
1067
1087
  }
1068
1088
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1550",
3
+ "version": "0.1.1551",
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"