@yemi33/minions 0.1.192 → 0.1.194

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,9 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.192 (2026-04-02)
3
+ ## 0.1.194 (2026-04-02)
4
4
 
5
5
  ### Engine
6
+ - engine/ado.js
7
+ - engine/github.js
8
+ - engine/lifecycle.js
6
9
  - engine/queries.js
10
+ - engine/shared.js
7
11
 
8
12
  ### Dashboard
9
13
  - dashboard.js
@@ -13,6 +17,9 @@
13
17
  ### Documentation
14
18
  - README.md
15
19
 
20
+ ### Other
21
+ - test/unit.test.js
22
+
16
23
  ## 0.1.189 (2026-04-02)
17
24
 
18
25
  ### Dashboard
package/engine/ado.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  const path = require('path');
7
7
  const shared = require('./shared');
8
- const { exec, getAdoOrgBase, addPrLink, log, dateStamp } = shared;
8
+ const { exec, getAdoOrgBase, log, dateStamp } = shared;
9
9
  const { getPrs } = require('./queries');
10
10
 
11
11
  // Lazy require to avoid circular dependency — only needed for engine().handlePostMerge
@@ -366,9 +366,8 @@ async function reconcilePrs(config) {
366
366
  const confirmedItemId = linkedItem ? linkedItemId : null;
367
367
 
368
368
  if (existingIds.has(prId)) {
369
- // PR already tracked — write link to pr-links.json if we can extract an ID
369
+ // PR already tracked — update prdItems if we can extract an ID
370
370
  if (confirmedItemId) {
371
- addPrLink(prId, confirmedItemId);
372
371
  const existing = existingPrs.find(p => p.id === prId);
373
372
  if (existing && !(existing.prdItems || []).includes(confirmedItemId)) {
374
373
  existing.prdItems = Array.isArray(existing.prdItems) ? existing.prdItems : [];
@@ -391,7 +390,6 @@ async function reconcilePrs(config) {
391
390
  url: prUrl,
392
391
  prdItems: confirmedItemId ? [confirmedItemId] : [],
393
392
  });
394
- if (confirmedItemId) addPrLink(prId, confirmedItemId);
395
393
  existingIds.add(prId);
396
394
  projectAdded++;
397
395
  log('info', `PR reconciliation: added ${prId} (branch: ${branch}${confirmedItemId ? ', linked to ' + confirmedItemId : ''}) to ${project.name}`);
package/engine/github.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  const shared = require('./shared');
8
- const { exec, getProjects, projectPrPath, projectWorkItemsPath, safeJson, safeWrite, MINIONS_DIR, addPrLink, log, dateStamp } = shared;
8
+ const { exec, getProjects, projectPrPath, projectWorkItemsPath, safeJson, safeWrite, MINIONS_DIR, log, dateStamp } = shared;
9
9
  const { getPrs } = require('./queries');
10
10
  const path = require('path');
11
11
 
@@ -341,7 +341,6 @@ async function reconcilePrs(config) {
341
341
 
342
342
  if (existingIds.has(prId)) {
343
343
  if (confirmedItemId) {
344
- addPrLink(prId, confirmedItemId);
345
344
  const existing = existingPrs.find(p => p.id === prId);
346
345
  if (existing && !(existing.prdItems || []).includes(confirmedItemId)) {
347
346
  existing.prdItems = Array.isArray(existing.prdItems) ? existing.prdItems : [];
@@ -364,7 +363,6 @@ async function reconcilePrs(config) {
364
363
  url: prUrl,
365
364
  prdItems: confirmedItemId ? [confirmedItemId] : [],
366
365
  });
367
- if (confirmedItemId) addPrLink(prId, confirmedItemId);
368
366
  existingIds.add(prId);
369
367
  projectAdded++;
370
368
 
@@ -6,7 +6,7 @@
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
8
  const shared = require('./shared');
9
- const { safeRead, safeJson, safeWrite, safeReadDir, execSilent, projectPrPath, getPrLinks, addPrLink,
9
+ const { safeRead, safeJson, safeWrite, safeReadDir, execSilent, projectPrPath, getPrLinks,
10
10
  mutateJsonFileLocked, log, ts, dateStamp } = shared;
11
11
  const { trackEngineUsage } = require('./llm');
12
12
  const queries = require('./queries');
@@ -735,7 +735,7 @@ async function handlePostMerge(pr, project, config, newStatus) {
735
735
  // Mark review as approved since it was merged
736
736
  pr.reviewStatus = 'approved';
737
737
 
738
- // Resolve linked work item from pr-links or PR branch name
738
+ // Resolve linked work item from PR.prdItems or PR branch name
739
739
  let mergedItemId = getPrLinks()[pr.id];
740
740
  if (!mergedItemId && pr.branch) {
741
741
  const branchMatch = pr.branch.match(/(P-[a-z0-9]{6,})/i) || pr.branch.match(/(W-[a-z0-9]+)/i);
package/engine/queries.js CHANGED
@@ -582,7 +582,7 @@ function getPrdInfo(config) {
582
582
  for (const wi of centralWi) { if (!wi.id) { console.warn('[queries] Skipping central work item without id:', JSON.stringify(wi).slice(0, 120)); continue; } if (wi.sourcePlan && !wiById[wi.id]) wiById[wi.id] = wi; }
583
583
  } catch { /* optional */ }
584
584
 
585
- // PR-to-PRD linking — primary source is pr-links.json (single-writer, never clobbered by polling)
585
+ // PR-to-PRD linking — derived from PR.prdItems (single source of truth)
586
586
  const allPrs = getPullRequests(config);
587
587
  const prById = {};
588
588
  for (const pr of allPrs) prById[pr.id] = pr;
package/engine/shared.js CHANGED
@@ -7,7 +7,7 @@ const fs = require('fs');
7
7
  const path = require('path');
8
8
 
9
9
  const MINIONS_DIR = path.resolve(__dirname, '..');
10
- const PR_LINKS_PATH = path.join(MINIONS_DIR, 'engine', 'pr-links.json');
10
+ const CENTRAL_WI_PATH = path.join(MINIONS_DIR, 'work-items.json');
11
11
  const LOG_PATH = path.join(__dirname, 'log.json');
12
12
 
13
13
  // ── Timestamps & Logging ────────────────────────────────────────────────────
@@ -501,7 +501,7 @@ function parseSkillFrontmatter(content, filename) {
501
501
  // Never touched by polling loops — only written when a PR is first linked to a PRD item.
502
502
 
503
503
  function getPrLinks() {
504
- // Derive from PR.prdItems (single source of truth) + legacy pr-links.json as fallback
504
+ // Derive from PR.prdItems (single source of truth)
505
505
  const links = {};
506
506
  try {
507
507
  const projects = getProjects();
@@ -514,24 +514,9 @@ function getPrLinks() {
514
514
  }
515
515
  }
516
516
  } catch { /* optional */ }
517
- // Merge legacy pr-links.json for items not yet in PR.prdItems
518
- try {
519
- const legacy = JSON.parse(require('fs').readFileSync(PR_LINKS_PATH, 'utf8'));
520
- for (const [prId, itemId] of Object.entries(legacy)) {
521
- if (!links[prId]) links[prId] = itemId;
522
- }
523
- } catch { /* optional */ }
524
517
  return links;
525
518
  }
526
519
 
527
- function addPrLink(prId, itemId) {
528
- if (!prId || !itemId) return;
529
- const links = getPrLinks();
530
- if (links[prId] === itemId) return; // already correct, no write needed
531
- links[prId] = itemId;
532
- safeWrite(PR_LINKS_PATH, links);
533
- }
534
-
535
520
  /**
536
521
  * Locked mutation of a project's pull-requests.json.
537
522
  * Single source of truth for PR data including prdItems links.
@@ -561,7 +546,7 @@ function linkPrToItem(project, prId, itemId) {
561
546
 
562
547
  module.exports = {
563
548
  MINIONS_DIR,
564
- PR_LINKS_PATH,
549
+ CENTRAL_WI_PATH,
565
550
  LOG_PATH,
566
551
  ts,
567
552
  logTs,
@@ -595,7 +580,6 @@ module.exports = {
595
580
  projectWorkItemsPath,
596
581
  projectPrPath,
597
582
  getPrLinks,
598
- addPrLink,
599
583
  mutatePrs,
600
584
  linkPrToItem,
601
585
  nextWorkItemId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.192",
3
+ "version": "0.1.194",
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"