@yemi33/minions 0.1.324 → 0.1.326

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,8 +1,14 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.324 (2026-04-03)
3
+ ## 0.1.326 (2026-04-03)
4
4
 
5
5
  ### Fixes
6
+ - stop writing legacy done aliases, add migration, keep read compat
7
+
8
+ ## 0.1.325 (2026-04-03)
9
+
10
+ ### Fixes
11
+ - guard retry-counter write path against unreadable work items file
6
12
  - 7 bugs from engine audit — runtime crashes, race conditions, stale state
7
13
  - scan skips NugetCache, OneDrive, .vs, packages + validates .git/HEAD
8
14
 
package/engine/cleanup.js CHANGED
@@ -431,16 +431,16 @@ function runCleanup(config, verbose = false) {
431
431
  }
432
432
  } catch (e) { log('warn', 'KB watchdog check: ' + e.message); }
433
433
 
434
- // 6. Migrate legacy work-item statuses to canonical values
434
+ // 6. Migrate legacy work-item statuses to canonical 'done'
435
435
  // in-pr, implemented, complete → done (one-time correction per item)
436
- const LEGACY_DONE_STATUSES = shared.DONE_STATUSES;
436
+ const LEGACY_DONE_ALIASES = new Set(['in-pr', 'implemented', 'complete']);
437
437
  for (const project of projects) {
438
438
  try {
439
439
  const wiPath = projectWorkItemsPath(project);
440
440
  const items = safeJson(wiPath) || [];
441
441
  let migrated = 0;
442
442
  for (const item of items) {
443
- if (LEGACY_DONE_STATUSES.has(item.status)) {
443
+ if (LEGACY_DONE_ALIASES.has(item.status)) {
444
444
  item.status = 'done';
445
445
  delete item._pendingReason;
446
446
  migrated++;
@@ -458,7 +458,7 @@ function runCleanup(config, verbose = false) {
458
458
  const centralItems = safeJson(centralPath) || [];
459
459
  let migrated = 0;
460
460
  for (const item of centralItems) {
461
- if (LEGACY_DONE_STATUSES.has(item.status)) {
461
+ if (LEGACY_DONE_ALIASES.has(item.status)) {
462
462
  item.status = 'done';
463
463
  delete item._pendingReason;
464
464
  migrated++;
@@ -485,7 +485,7 @@ function runCleanup(config, verbose = false) {
485
485
  if (!prd?.missing_features) continue;
486
486
  let migrated = 0;
487
487
  for (const feat of prd.missing_features) {
488
- if (LEGACY_DONE_STATUSES.has(feat.status)) {
488
+ if (LEGACY_DONE_ALIASES.has(feat.status)) {
489
489
  feat.status = 'done';
490
490
  migrated++;
491
491
  }
@@ -134,7 +134,8 @@ function completeDispatch(id, result = DISPATCH_RESULT.SUCCESS, reason = '', res
134
134
  ? path.join(MINIONS_DIR, 'work-items.json')
135
135
  : item.meta.project?.name ? projectWorkItemsPath({ name: item.meta.project.name, localPath: item.meta.project.localPath }) : null;
136
136
  if (wiPath) {
137
- const items = safeJson(wiPath) || [];
137
+ const items = safeJson(wiPath);
138
+ if (!items || !Array.isArray(items)) throw new Error('work items unreadable');
138
139
  const wi = items.find(i => i.id === item.meta.item.id);
139
140
  if (wi && wi.status !== WI_STATUS.PAUSED) {
140
141
  wi._retryCount = retries + 1;
@@ -789,13 +789,13 @@ async function handlePostMerge(pr, project, config, newStatus) {
789
789
  const plan = safeJson(path.join(prdDir, pf));
790
790
  if (!plan?.missing_features) continue;
791
791
  const feature = plan.missing_features.find(f => f.id === mergedItemId);
792
- if (feature && feature.status !== 'implemented') {
793
- feature.status = 'implemented';
792
+ if (feature && feature.status !== WI_STATUS.DONE) {
793
+ feature.status = WI_STATUS.DONE;
794
794
  shared.safeWrite(path.join(prdDir, pf), plan);
795
795
  updated++;
796
796
  }
797
797
  }
798
- if (updated > 0) log('info', `Post-merge: marked ${mergedItemId} as implemented for ${pr.id}`);
798
+ if (updated > 0) log('info', `Post-merge: marked ${mergedItemId} as done for ${pr.id}`);
799
799
  } catch (err) { log('warn', `Post-merge PRD update: ${err.message}`); }
800
800
 
801
801
  // Mark work item as done
package/engine/shared.js CHANGED
@@ -395,7 +395,9 @@ const WI_STATUS = {
395
395
  PENDING: 'pending', DISPATCHED: 'dispatched', DONE: 'done', FAILED: 'failed',
396
396
  PAUSED: 'paused', QUEUED: 'queued', NEEDS_REVIEW: 'needs-human-review', DECOMPOSED: 'decomposed',
397
397
  };
398
- const DONE_STATUSES = new Set([WI_STATUS.DONE, 'in-pr', 'implemented', 'complete']); // includes legacy aliases
398
+ // Read-side: accept legacy aliases for backward compat with old data/clients.
399
+ // Write-side: only WI_STATUS.DONE is written (cleanup.js migrates old values on each run).
400
+ const DONE_STATUSES = new Set([WI_STATUS.DONE, 'in-pr', 'implemented', 'complete']);
399
401
  const WORK_TYPE = {
400
402
  IMPLEMENT: 'implement', IMPLEMENT_LARGE: 'implement:large', FIX: 'fix', REVIEW: 'review',
401
403
  VERIFY: 'verify', PLAN: 'plan', PLAN_TO_PRD: 'plan-to-prd', DECOMPOSE: 'decompose',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.324",
3
+ "version": "0.1.326",
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"