@yemi33/minions 0.1.999 → 0.1.1001

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,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.999 (2026-04-15)
3
+ ## 0.1.1001 (2026-04-15)
4
4
 
5
5
  ### Features
6
6
  - fix stopAfter=0 watch expiry — run forever for all conditions (#1117)
@@ -25,6 +25,8 @@
25
25
  - gate auto-fix conflict dispatch behind autoFixConflicts flag
26
26
 
27
27
  ### Fixes
28
+ - auto-link existing GitHub PR when agent completes without creating one
29
+ - preserve ordered lists across blank lines in markdown renderer
28
30
  - restore CC rendering and tab bar
29
31
  - restore WATCH_ABSOLUTE_CONDITIONS import in watches.js lost in #1117 squash merge
30
32
  - remove dead 'meeting' row from routing.md — orchestrated by engine/meeting.js directly
@@ -43,8 +45,6 @@
43
45
  - fix watches feature gaps — human notifications, branch stub, status-change init, unique keys
44
46
  - skip isAlreadyDispatched in needsReReview to allow re-review within 1hr
45
47
  - skip SessionStart hook settings test on CI
46
- - loop queue flush so messages queued during combined send aren't orphaned
47
- - set lastPushedAt on fix completion to unblock re-review without poller
48
48
 
49
49
  ### Other
50
50
  - docs: update CLAUDE.md with recent Minions architecture changes
@@ -202,6 +202,17 @@ function _renderMdCore(s) {
202
202
  var listType = '';
203
203
 
204
204
  function closeList() { if (inList) { out.push(listType === 'ol' ? '</ol>' : '</ul>'); inList = false; } }
205
+ function nextNonEmptyLine(startIdx) {
206
+ for (var ni = startIdx; ni < lines.length; ni++) {
207
+ if (lines[ni].trim()) return lines[ni];
208
+ }
209
+ return '';
210
+ }
211
+ function continuesCurrentList(nextLine) {
212
+ if (!inList || !nextLine) return false;
213
+ if (listType === 'ol') return /^(\s*)\d+\.\s+(.+)/.test(nextLine);
214
+ return /^(\s*)[-*]\s+(.+)/.test(nextLine);
215
+ }
205
216
  function openList(type) {
206
217
  if (inList && listType !== type) closeList();
207
218
  if (!inList) {
@@ -291,12 +302,17 @@ function _renderMdCore(s) {
291
302
  continue;
292
303
  }
293
304
 
305
+ // Blank line → spacer
306
+ if (!line.trim()) {
307
+ if (continuesCurrentList(nextNonEmptyLine(i + 1))) continue;
308
+ closeList();
309
+ out.push('<div style="height:4px"></div>');
310
+ continue;
311
+ }
312
+
294
313
  // Non-list line — close any open list
295
314
  closeList();
296
315
 
297
- // Blank line → spacer
298
- if (!line.trim()) { out.push('<div style="height:4px"></div>'); continue; }
299
-
300
316
  out.push('<div>' + line + '</div>');
301
317
  }
302
318
  closeList();
@@ -1792,6 +1792,39 @@ async function runPostCompletionHooks(dispatchItem, agentId, code, stdout, confi
1792
1792
  }
1793
1793
  }
1794
1794
  }
1795
+ // Last resort: query GitHub directly for an open PR on this branch.
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 GitHub but not in pull-requests.json.
1798
+ if (!existingPrFound && meta?.branch) {
1799
+ const projectObj = shared.getProjects(config).find(p => p.name === meta?.project?.name);
1800
+ const ghSlug = projectObj?.prUrlBase?.match(/github\.com\/([^/]+\/[^/]+)\/pull/)?.[1];
1801
+ if (projectObj?.repoHost === 'github' && ghSlug) {
1802
+ try {
1803
+ const raw = await execAsync(`gh pr list --head "${meta.branch}" --repo ${ghSlug} --json number,url,state --limit 1`, { timeout: 15000, windowsHide: true });
1804
+ const found = JSON.parse(raw || '[]');
1805
+ if (found.length > 0 && found[0].state === 'OPEN') {
1806
+ const prNum = found[0].number;
1807
+ const fullId = `PR-${prNum}`;
1808
+ const prPath = shared.projectPrPath(projectObj);
1809
+ mutateJsonFileLocked(prPath, prs => {
1810
+ if (!Array.isArray(prs)) prs = [];
1811
+ if (prs.some(p => p.id === fullId)) return prs;
1812
+ prs.push({
1813
+ id: fullId, prNumber: prNum, title: meta.item?.title || '',
1814
+ agent: agentId, branch: meta.branch, reviewStatus: 'pending',
1815
+ status: PR_STATUS.ACTIVE, created: ts(), url: found[0].url,
1816
+ prdItems: meta.item?.id ? [meta.item.id] : [],
1817
+ sourcePlan: meta.item?.sourcePlan || '', itemType: meta.item?.itemType || '',
1818
+ });
1819
+ return prs;
1820
+ });
1821
+ if (meta.item?.id) addPrLink(fullId, meta.item.id);
1822
+ log('info', `Auto-linked existing GH PR ${fullId} on branch ${meta.branch} for ${meta.item?.id}`);
1823
+ existingPrFound = true;
1824
+ }
1825
+ } catch (e) { log('warn', `GH PR lookup for branch ${meta.branch}: ${e.message}`); }
1826
+ }
1827
+ }
1795
1828
  if (!existingPrFound) {
1796
1829
  const noPrWiPath = resolveWorkItemPath(meta);
1797
1830
  if (noPrWiPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.999",
3
+ "version": "0.1.1001",
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"