@yemi33/minions 0.1.1584 → 0.1.1585

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,9 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1584 (2026-04-28)
3
+ ## 0.1.1585 (2026-04-28)
4
4
 
5
5
  ### Fixes
6
+ - optimistic UI for planApprove cascades to linked PRD
6
7
  - stack chain-of-thought above progress block (was side-by-side)
7
8
 
8
9
  ### Other
@@ -559,6 +559,32 @@ async function planView(file) {
559
559
  async function planApprove(file, btn) {
560
560
  if (btn) { btn.dataset.origText = btn.textContent; btn.textContent = 'Approving...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
561
561
  showToast('cmd-toast', 'Plan approved — work will begin on next engine tick', true);
562
+
563
+ // Optimistic UI: mutate cached state and re-render so both the plan card and
564
+ // PRD view reflect 'approved' immediately. The .md card's display status
565
+ // follows the linked PRD's status via lookup in renderPlanCard, so updating
566
+ // the PRD entry covers both. Refresh after fetch reconciles with truth.
567
+ const isPrd = typeof file === 'string' && file.endsWith('.json');
568
+ if (Array.isArray(window._lastPlans)) {
569
+ for (const p of window._lastPlans) {
570
+ if (p.file === file) {
571
+ p.status = 'approved';
572
+ p.planStale = false;
573
+ delete p.pausedAt;
574
+ }
575
+ }
576
+ try { renderPlans(window._lastPlans); } catch { /* render is best-effort */ }
577
+ }
578
+ if (isPrd && window._lastStatus?.prdProgress?.items) {
579
+ for (const item of window._lastStatus.prdProgress.items) {
580
+ if (item.source === file) {
581
+ item.planStatus = 'approved';
582
+ item.planStale = false;
583
+ }
584
+ }
585
+ if (typeof rerenderPrdFromCache === 'function') rerenderPrdFromCache();
586
+ }
587
+
562
588
  try {
563
589
  const res = await fetch('/api/plans/approve', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ file }) });
564
590
  if (res.ok) {
@@ -568,8 +594,14 @@ async function planApprove(file, btn) {
568
594
  if (btn) { btn.textContent = btn.dataset.origText || 'Approve'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
569
595
  const d = await res.json().catch(() => ({}));
570
596
  showToast('cmd-toast', 'Approve failed: ' + (d.error || 'unknown'), false);
597
+ // Refresh to revert optimistic state from server truth
598
+ refresh();
571
599
  }
572
- } catch (e) { if (btn) { btn.textContent = btn.dataset.origText || 'Approve'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } showToast('cmd-toast', 'Error: ' + e.message, false); }
600
+ } catch (e) {
601
+ if (btn) { btn.textContent = btn.dataset.origText || 'Approve'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
602
+ showToast('cmd-toast', 'Error: ' + e.message, false);
603
+ refresh();
604
+ }
573
605
  }
574
606
 
575
607
  async function planDelete(file) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1584",
3
+ "version": "0.1.1585",
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"