@yemi33/minions 0.1.838 → 0.1.840
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,12 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.840 (2026-04-11)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- optimistic UI updates for all dashboard actions
|
|
6
7
|
- per-item Re-open button on done PRD items (deterministic fallback)
|
|
7
8
|
- stale PRD shows Regenerate PRD + Resume as-is buttons
|
|
8
9
|
|
|
9
10
|
### Fixes
|
|
11
|
+
- restore text selection → doc-chat flow + regression tests
|
|
10
12
|
- use structured marker for diff-aware PRD update detection
|
|
11
13
|
- match playbook trigger phrase for diff-aware PRD updates
|
|
12
14
|
- engine only flags stale on plan revision, never auto-regenerates
|
package/dashboard/js/modal-qa.js
CHANGED
|
@@ -414,4 +414,30 @@ function _showThreadWrap() {
|
|
|
414
414
|
});
|
|
415
415
|
})();
|
|
416
416
|
|
|
417
|
+
// ── Text selection → "Ask about this" button ─────────────────────────────────
|
|
418
|
+
document.addEventListener('mouseup', function() {
|
|
419
|
+
var askBtn = document.getElementById('ask-selection-btn');
|
|
420
|
+
if (!askBtn) return;
|
|
421
|
+
// Only act inside modal body
|
|
422
|
+
var sel = window.getSelection();
|
|
423
|
+
if (!sel || sel.isCollapsed || !sel.toString().trim()) {
|
|
424
|
+
askBtn.style.display = 'none';
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
var modalBody = document.getElementById('modal-body');
|
|
428
|
+
if (!modalBody || !modalBody.contains(sel.anchorNode)) {
|
|
429
|
+
askBtn.style.display = 'none';
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
var text = sel.toString().trim();
|
|
433
|
+
if (!text) { askBtn.style.display = 'none'; return; }
|
|
434
|
+
_modalDocContext.selection = text;
|
|
435
|
+
// Position near the selection
|
|
436
|
+
var range = sel.getRangeAt(0);
|
|
437
|
+
var rect = range.getBoundingClientRect();
|
|
438
|
+
askBtn.style.top = (rect.bottom + 4) + 'px';
|
|
439
|
+
askBtn.style.left = rect.left + 'px';
|
|
440
|
+
askBtn.style.display = 'block';
|
|
441
|
+
});
|
|
442
|
+
|
|
417
443
|
window.MinionsQA = { showModalQa, modalAskAboutSelection, clearQaSelection, clearQaConversation, modalSend, qaAbort, toggleDocChat, _showThreadWrap };
|
|
@@ -558,16 +558,16 @@ async function planView(file) {
|
|
|
558
558
|
|
|
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
|
+
showToast('cmd-toast', 'Plan approved — work will begin on next engine tick', true);
|
|
561
562
|
try {
|
|
562
563
|
const res = await fetch('/api/plans/approve', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ file }) });
|
|
563
564
|
if (res.ok) {
|
|
564
|
-
showToast('cmd-toast', 'Plan approved — work will begin on next engine tick', true);
|
|
565
565
|
refreshPlans();
|
|
566
566
|
refresh();
|
|
567
567
|
} else {
|
|
568
568
|
if (btn) { btn.textContent = btn.dataset.origText || 'Approve'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
569
569
|
const d = await res.json().catch(() => ({}));
|
|
570
|
-
|
|
570
|
+
showToast('cmd-toast', 'Approve failed: ' + (d.error || 'unknown'), false);
|
|
571
571
|
}
|
|
572
572
|
} catch (e) { if (btn) { btn.textContent = btn.dataset.origText || 'Approve'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
573
573
|
}
|
|
@@ -626,16 +626,16 @@ async function planArchive(file, btn) {
|
|
|
626
626
|
|
|
627
627
|
async function planPause(file, btn) {
|
|
628
628
|
if (btn) { btn.dataset.origText = btn.textContent; btn.textContent = 'Pausing...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
629
|
+
showToast('cmd-toast', 'Plan paused — no new items will be dispatched', true);
|
|
629
630
|
try {
|
|
630
631
|
const res = await fetch('/api/plans/pause', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ file }) });
|
|
631
632
|
if (res.ok) {
|
|
632
|
-
showToast('cmd-toast', 'Plan paused — no new items will be dispatched', true);
|
|
633
633
|
refreshPlans();
|
|
634
634
|
refresh();
|
|
635
635
|
} else {
|
|
636
636
|
if (btn) { btn.textContent = btn.dataset.origText || 'Pause'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
637
637
|
const d = await res.json().catch(() => ({}));
|
|
638
|
-
|
|
638
|
+
showToast('cmd-toast', 'Pause failed: ' + (d.error || 'unknown'), false);
|
|
639
639
|
}
|
|
640
640
|
} catch (e) { if (btn) { btn.textContent = btn.dataset.origText || 'Pause'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
641
641
|
}
|
|
@@ -643,14 +643,14 @@ async function planPause(file, btn) {
|
|
|
643
643
|
async function planReject(file) {
|
|
644
644
|
if (!confirm('Reject this plan? It will not be executed.')) return;
|
|
645
645
|
const reason = prompt('Reason for rejection (optional):') || '';
|
|
646
|
+
showToast('cmd-toast', 'Plan rejected', true);
|
|
646
647
|
try {
|
|
647
648
|
const res = await fetch('/api/plans/reject', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ file, reason }) });
|
|
648
649
|
if (res.ok) {
|
|
649
|
-
showToast('cmd-toast', 'Plan rejected', true);
|
|
650
650
|
refreshPlans();
|
|
651
651
|
} else {
|
|
652
652
|
const d = await res.json().catch(() => ({}));
|
|
653
|
-
|
|
653
|
+
showToast('cmd-toast', 'Reject failed: ' + (d.error || 'unknown'), false);
|
|
654
654
|
}
|
|
655
655
|
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
656
656
|
}
|
|
@@ -762,6 +762,7 @@ async function openVerifyGuide(file) {
|
|
|
762
762
|
|
|
763
763
|
async function triggerVerify(file, btn) {
|
|
764
764
|
if (btn) { btn.dataset.origText = btn.textContent; btn.textContent = 'Verifying...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
765
|
+
showToast('cmd-toast', 'Verify task queued', true);
|
|
765
766
|
try {
|
|
766
767
|
const res = await fetch('/api/plans/trigger-verify', {
|
|
767
768
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
@@ -771,7 +772,6 @@ async function triggerVerify(file, btn) {
|
|
|
771
772
|
if (res.ok && d.ok) {
|
|
772
773
|
try { closeModal(); } catch { /* may not be open */ }
|
|
773
774
|
refresh();
|
|
774
|
-
showToast('cmd-toast', d.verifyId ? 'Verify task ' + d.verifyId + ' created' : (d.message || 'Done'), true);
|
|
775
775
|
} else {
|
|
776
776
|
if (btn) { btn.textContent = btn.dataset.origText || 'Verify'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
777
777
|
alert('Failed: ' + (d.error || 'unknown'));
|
|
@@ -713,20 +713,22 @@ async function prdItemEdit(source, itemId) {
|
|
|
713
713
|
|
|
714
714
|
async function prdItemSave(source, itemId) {
|
|
715
715
|
var btn = event?.target; if (btn) { btn.disabled = true; btn.textContent = 'Saving...'; }
|
|
716
|
+
const body = {
|
|
717
|
+
source, itemId,
|
|
718
|
+
name: document.getElementById('prd-edit-name').value,
|
|
719
|
+
description: document.getElementById('prd-edit-desc').value,
|
|
720
|
+
priority: document.getElementById('prd-edit-priority').value,
|
|
721
|
+
estimated_complexity: document.getElementById('prd-edit-complexity').value,
|
|
722
|
+
};
|
|
723
|
+
closeModal(); showToast('cmd-toast', 'Item updated', true);
|
|
716
724
|
try {
|
|
717
725
|
const res = await fetch('/api/prd-items/update', {
|
|
718
726
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
719
|
-
body: JSON.stringify(
|
|
720
|
-
source, itemId,
|
|
721
|
-
name: document.getElementById('prd-edit-name').value,
|
|
722
|
-
description: document.getElementById('prd-edit-desc').value,
|
|
723
|
-
priority: document.getElementById('prd-edit-priority').value,
|
|
724
|
-
estimated_complexity: document.getElementById('prd-edit-complexity').value,
|
|
725
|
-
})
|
|
727
|
+
body: JSON.stringify(body)
|
|
726
728
|
});
|
|
727
|
-
if (res.ok) {
|
|
728
|
-
else {
|
|
729
|
-
} catch (e) {
|
|
729
|
+
if (res.ok) { refresh(); }
|
|
730
|
+
else { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Save failed: ' + (d.error || 'unknown'), false); }
|
|
731
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
730
732
|
}
|
|
731
733
|
|
|
732
734
|
async function prdItemRemove(source, itemId) {
|
|
@@ -775,19 +777,17 @@ async function prdItemRequeue(workItemId, source, prdFile) {
|
|
|
775
777
|
|
|
776
778
|
async function prdItemReopen(source, itemId) {
|
|
777
779
|
if (!confirm('Re-open this item? It will be set to "updated" and the engine will re-dispatch it on the existing branch.')) return;
|
|
780
|
+
showToast('cmd-toast', 'Item re-opened — will dispatch on next tick', true);
|
|
778
781
|
try {
|
|
779
|
-
// Set item to "updated" + clear stale flag + approve so materializer picks it up
|
|
780
782
|
const res = await fetch('/api/prd-items/update', {
|
|
781
783
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
782
784
|
body: JSON.stringify({ source, itemId, status: 'updated' })
|
|
783
785
|
});
|
|
784
786
|
if (res.ok) {
|
|
785
|
-
// Also approve the plan (clears planStale so materializer runs)
|
|
786
787
|
await fetch('/api/plans/approve', {
|
|
787
788
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
788
789
|
body: JSON.stringify({ file: source, skipRegen: true })
|
|
789
790
|
});
|
|
790
|
-
showToast('cmd-toast', 'Item re-opened — will dispatch on next tick', true);
|
|
791
791
|
refresh();
|
|
792
792
|
} else {
|
|
793
793
|
const d = await res.json().catch(() => ({}));
|
|
@@ -798,19 +798,19 @@ async function prdItemReopen(source, itemId) {
|
|
|
798
798
|
|
|
799
799
|
async function _planApproveAction(prdFile, skipRegen, confirmMsg, successMsg) {
|
|
800
800
|
if (!confirm(confirmMsg)) return;
|
|
801
|
+
showToast('cmd-toast', successMsg || (skipRegen ? 'Plan resumed' : 'PRD regeneration queued'), true);
|
|
801
802
|
try {
|
|
802
803
|
const res = await fetch('/api/plans/approve', {
|
|
803
804
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
804
805
|
body: JSON.stringify({ file: prdFile, skipRegen: skipRegen || undefined })
|
|
805
806
|
});
|
|
806
|
-
const d = await res.json();
|
|
807
807
|
if (res.ok) {
|
|
808
|
-
showToast('cmd-toast', successMsg || (d.diffAwareUpdate ? 'Diff-aware PRD update queued' : 'Plan approved'), true);
|
|
809
808
|
refresh();
|
|
810
809
|
} else {
|
|
811
|
-
|
|
810
|
+
const d = await res.json().catch(() => ({}));
|
|
811
|
+
showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false);
|
|
812
812
|
}
|
|
813
|
-
} catch (e) {
|
|
813
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
814
814
|
}
|
|
815
815
|
|
|
816
816
|
function prdRegenerate(prdFile) {
|
|
@@ -198,13 +198,14 @@ async function deleteWorkItem(id, source) {
|
|
|
198
198
|
markDeleted('wi:' + id);
|
|
199
199
|
var wiTable = document.getElementById('work-items-content');
|
|
200
200
|
(wiTable || document).querySelectorAll('tr').forEach(function(r) { if (r.textContent.includes(id)) r.remove(); });
|
|
201
|
+
showToast('cmd-toast', 'Work item deleted', true);
|
|
201
202
|
try {
|
|
202
203
|
const res = await fetch('/api/work-items/delete', {
|
|
203
204
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
204
205
|
body: JSON.stringify({ id, source: source || undefined })
|
|
205
206
|
});
|
|
206
|
-
if (!res.ok) { const d = await res.json().catch(() => ({}));
|
|
207
|
-
} catch (e) {
|
|
207
|
+
if (!res.ok) { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Delete failed: ' + (d.error || 'unknown'), false); refresh(); }
|
|
208
|
+
} catch (e) { showToast('cmd-toast', 'Delete error: ' + e.message, false); refresh(); }
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
async function archiveWorkItem(id, source) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.840",
|
|
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"
|