@yemi33/minions 0.1.831 → 0.1.832

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.831 (2026-04-11)
3
+ ## 0.1.832 (2026-04-11)
4
4
 
5
5
  ### Features
6
6
  - stale PRD shows Regenerate PRD + Resume as-is buttons
@@ -13,6 +13,7 @@
13
13
  - diff-aware plan-to-prd triggered by Resume, not auto-dispatch
14
14
 
15
15
  ### Other
16
+ - refactor: migrate handlePrdRegenerate and handlePlansExecute to queuePlanToPrd
16
17
  - refactor: add PRD_ITEM_STATUS/PRD_MATERIALIZABLE constants, extract queuePlanToPrd
17
18
  - refactor: remove dead criteria variable, DRY plan resume functions
18
19
 
package/dashboard.js CHANGED
@@ -2402,31 +2402,19 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
2402
2402
  try { fs.unlinkSync(prdPath); } catch { /* cleanup */ }
2403
2403
 
2404
2404
  // Queue plan-to-prd regeneration with instructions to preserve completed items
2405
- const wiPath = path.join(MINIONS_DIR, 'work-items.json');
2406
-
2407
2405
  const completedContext = completedItems.length > 0
2408
2406
  ? `\n\n**Previously completed items (preserve their status in the new PRD):**\n${completedItems.map(i => `- ${i.id}: ${i.name} [${i.status}]`).join('\n')}`
2409
2407
  : '';
2410
2408
 
2411
- const id = 'W-' + shared.uid();
2412
- let alreadyQueuedId = null;
2413
- mutateWorkItems(wiPath, items => {
2414
- // Dedup: check if already queued
2415
- const alreadyQueued = items.find(w =>
2416
- w.type === 'plan-to-prd' && w.planFile === plan.source_plan && (w.status === WI_STATUS.PENDING || w.status === WI_STATUS.DISPATCHED)
2417
- );
2418
- if (alreadyQueued) { alreadyQueuedId = alreadyQueued.id; return; }
2419
- items.push({
2420
- id, title: `Regenerate PRD: ${plan.plan_summary || plan.source_plan}`,
2421
- type: 'plan-to-prd', priority: 'high',
2422
- description: `Plan file: plans/${plan.source_plan}\nTarget PRD filename: ${body.file}\nRegeneration requested by user after plan revision.${completedContext}`,
2423
- status: WI_STATUS.PENDING, created: new Date().toISOString(), createdBy: 'dashboard:regenerate',
2424
- project: plan.project || '', planFile: plan.source_plan,
2425
- _targetPrdFile: body.file,
2426
- });
2409
+ const queued = shared.queuePlanToPrd({
2410
+ planFile: plan.source_plan, prdFile: body.file,
2411
+ title: `Regenerate PRD: ${plan.plan_summary || plan.source_plan}`,
2412
+ description: `Plan file: plans/${plan.source_plan}\nTarget PRD filename: ${body.file}\nRegeneration requested by user after plan revision.${completedContext}`,
2413
+ project: plan.project || '', createdBy: 'dashboard:regenerate',
2414
+ extra: { _targetPrdFile: body.file },
2427
2415
  });
2428
- if (alreadyQueuedId) return jsonReply(res, 200, { id: alreadyQueuedId, alreadyQueued: true });
2429
- return jsonReply(res, 200, { id, file: plan.source_plan });
2416
+ if (!queued) return jsonReply(res, 200, { alreadyQueued: true });
2417
+ return jsonReply(res, 200, { ok: true, file: plan.source_plan });
2430
2418
  } catch (e) { return jsonReply(res, 500, { error: e.message }); }
2431
2419
  }
2432
2420
 
@@ -2440,28 +2428,15 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
2440
2428
  const planPath = path.join(MINIONS_DIR, 'plans', body.file);
2441
2429
  if (!fs.existsSync(planPath)) return jsonReply(res, 404, { error: 'plan file not found' });
2442
2430
 
2443
- // Atomic check-and-insert to prevent duplicates and races with engine
2444
- const centralPath = path.join(MINIONS_DIR, 'work-items.json');
2445
- let existingId = null;
2446
- const id = 'W-' + shared.uid();
2447
- mutateJsonFileLocked(centralPath, (items) => {
2448
- if (!Array.isArray(items)) items = [];
2449
- // Only block if actively pending/dispatched allow re-execute after completion
2450
- const existing = items.find(w => w.type === 'plan-to-prd' && w.planFile === body.file && (w.status === WI_STATUS.PENDING || w.status === WI_STATUS.DISPATCHED));
2451
- if (existing) { existingId = existing.id; return items; }
2452
- items.push({
2453
- id, title: 'Convert plan to PRD: ' + body.file.replace('.md', ''),
2454
- type: 'plan-to-prd', priority: 'high',
2455
- description: 'Plan file: plans/' + body.file,
2456
- status: WI_STATUS.PENDING, created: new Date().toISOString(),
2457
- createdBy: 'dashboard:execute', project: body.project || '',
2458
- planFile: body.file,
2459
- });
2460
- return items;
2461
- }, { defaultValue: [] });
2462
- if (existingId) return jsonReply(res, 200, { ok: true, id: existingId, alreadyQueued: true });
2431
+ const queued = shared.queuePlanToPrd({
2432
+ planFile: body.file,
2433
+ title: 'Convert plan to PRD: ' + body.file.replace('.md', ''),
2434
+ description: 'Plan file: plans/' + body.file,
2435
+ project: body.project || '', createdBy: 'dashboard:execute',
2436
+ });
2437
+ if (!queued) return jsonReply(res, 200, { ok: true, alreadyQueued: true });
2463
2438
  invalidateStatusCache();
2464
- return jsonReply(res, 200, { ok: true, id });
2439
+ return jsonReply(res, 200, { ok: true });
2465
2440
  } catch (e) { return jsonReply(res, 400, { error: e.message }); }
2466
2441
  }
2467
2442
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.831",
3
+ "version": "0.1.832",
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"