@yemi33/minions 0.1.844 → 0.1.846
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.
|
|
3
|
+
## 0.1.846 (2026-04-11)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- optimistic UI updates for all remaining dashboard pages
|
|
6
7
|
- optimistic UI updates for all dashboard actions
|
|
7
8
|
- per-item Re-open button on done PRD items (deterministic fallback)
|
|
8
9
|
- stale PRD shows Regenerate PRD + Resume as-is buttons
|
|
@@ -123,6 +123,14 @@ async function modalSaveEdit() {
|
|
|
123
123
|
const body = document.getElementById('modal-body');
|
|
124
124
|
const content = body.innerText;
|
|
125
125
|
|
|
126
|
+
body.contentEditable = 'false';
|
|
127
|
+
body.style.border = '';
|
|
128
|
+
body.style.padding = '';
|
|
129
|
+
document.getElementById('modal-edit-btn').style.display = '';
|
|
130
|
+
document.getElementById('modal-save-btn').style.display = 'none';
|
|
131
|
+
document.getElementById('modal-cancel-edit-btn').style.display = 'none';
|
|
132
|
+
_modalDocContext.content = content;
|
|
133
|
+
showToast('cmd-toast', 'Team Notes saved', true);
|
|
126
134
|
try {
|
|
127
135
|
const res = await fetch('/api/notes-save', {
|
|
128
136
|
method: 'POST',
|
|
@@ -130,18 +138,9 @@ async function modalSaveEdit() {
|
|
|
130
138
|
body: JSON.stringify({ file: _modalEditable, content }),
|
|
131
139
|
});
|
|
132
140
|
const data = await res.json();
|
|
133
|
-
if (!res.ok)
|
|
134
|
-
|
|
135
|
-
body.contentEditable = 'false';
|
|
136
|
-
body.style.border = '';
|
|
137
|
-
body.style.padding = '';
|
|
138
|
-
document.getElementById('modal-edit-btn').style.display = '';
|
|
139
|
-
document.getElementById('modal-save-btn').style.display = 'none';
|
|
140
|
-
document.getElementById('modal-cancel-edit-btn').style.display = 'none';
|
|
141
|
-
_modalDocContext.content = content;
|
|
142
|
-
showToast('cmd-toast', 'Team Notes saved', true);
|
|
141
|
+
if (!res.ok) showToast('cmd-toast', 'Save failed: ' + (data.error || 'unknown'), false);
|
|
143
142
|
} catch (e) {
|
|
144
|
-
showToast('cmd-toast', '
|
|
143
|
+
showToast('cmd-toast', 'Save error: ' + e.message, false);
|
|
145
144
|
}
|
|
146
145
|
}
|
|
147
146
|
|
|
@@ -161,13 +160,14 @@ async function deleteInboxItem(name) {
|
|
|
161
160
|
markDeleted('inbox:' + name);
|
|
162
161
|
const card = document.querySelector('.inbox-item[data-file="notes/inbox/' + CSS.escape(name) + '"]');
|
|
163
162
|
if (card) card.remove();
|
|
163
|
+
showToast('cmd-toast', 'Inbox item deleted', true);
|
|
164
164
|
try {
|
|
165
165
|
const res = await fetch('/api/inbox/delete', {
|
|
166
166
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
167
167
|
body: JSON.stringify({ name })
|
|
168
168
|
});
|
|
169
|
-
if (!res.ok) { const d = await res.json().catch(() => ({}));
|
|
170
|
-
} catch (e) {
|
|
169
|
+
if (!res.ok) { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Delete failed: ' + (d.error || 'unknown'), false); refresh(); }
|
|
170
|
+
} catch (e) { showToast('cmd-toast', 'Delete error: ' + e.message, false); refresh(); }
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
async function openInboxInExplorer(name) {
|
|
@@ -217,8 +217,8 @@ async function submitQuickNote() {
|
|
|
217
217
|
if (link && !link.querySelector('.notif-badge')) showNotifBadge(link);
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
else { const d = await res.json().catch(() => ({}));
|
|
221
|
-
} catch (e) {
|
|
220
|
+
else { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Note failed: ' + (d.error || 'unknown'), false); openQuickNoteModal(); }
|
|
221
|
+
} catch (e) { showToast('cmd-toast', 'Error saving note: ' + e.message, false); openQuickNoteModal(); }
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
async function doPromoteToKB(name, category) {
|
|
@@ -234,8 +234,8 @@ async function doPromoteToKB(name, category) {
|
|
|
234
234
|
});
|
|
235
235
|
const data = await res.json();
|
|
236
236
|
if (res.ok) { refreshKnowledgeBase(); }
|
|
237
|
-
else {
|
|
238
|
-
} catch (e) {
|
|
237
|
+
else { showToast('cmd-toast', 'Promote failed: ' + (data.error || 'unknown'), false); refresh(); }
|
|
238
|
+
} catch (e) { showToast('cmd-toast', 'Promote error: ' + e.message, false); refresh(); }
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
window.MinionsInbox = { renderInbox, promoteToKB, renderNotes, openNotesModal, modalToggleEdit, modalSaveEdit, modalCancelEdit, deleteInboxItem, openInboxInExplorer, openQuickNoteModal, submitQuickNote, doPromoteToKB };
|
|
@@ -143,12 +143,12 @@ async function kbSweep() {
|
|
|
143
143
|
btn.textContent = 'sweeping...';
|
|
144
144
|
btn.style.color = 'var(--blue)';
|
|
145
145
|
try {
|
|
146
|
+
showToast('cmd-toast', 'KB sweep started', true);
|
|
146
147
|
const res = await fetch('/api/knowledge/sweep', { method: 'POST', signal: AbortSignal.timeout(300000), headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pinnedKeys: getPinnedItems().filter(function(k) { return k.startsWith('knowledge/'); }) }) });
|
|
147
148
|
const data = await res.json();
|
|
148
149
|
if (data.ok) {
|
|
149
150
|
btn.textContent = 'done';
|
|
150
151
|
btn.style.color = 'var(--green)';
|
|
151
|
-
showToast('cmd-toast', 'KB sweep: ' + (data.summary || 'complete'), true);
|
|
152
152
|
refreshKnowledgeBase();
|
|
153
153
|
} else {
|
|
154
154
|
btn.style.color = 'var(--red)';
|
|
@@ -202,13 +202,14 @@ async function submitKbEntry() {
|
|
|
202
202
|
const content = document.getElementById('kb-new-content').value;
|
|
203
203
|
if (!title || !content) { if (btn) { btn.disabled = false; btn.textContent = 'Create'; } alert('Title and content are required'); return; }
|
|
204
204
|
try {
|
|
205
|
+
showToast('cmd-toast', 'KB entry created', true);
|
|
205
206
|
const res = await fetch('/api/knowledge', {
|
|
206
207
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
207
208
|
body: JSON.stringify({ category, title, content })
|
|
208
209
|
});
|
|
209
|
-
if (res.ok) { closeModal(); refreshKnowledgeBase();
|
|
210
|
-
else { const d = await res.json().catch(() => ({}));
|
|
211
|
-
} catch (e) {
|
|
210
|
+
if (res.ok) { closeModal(); refreshKnowledgeBase(); }
|
|
211
|
+
else { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'KB create failed: ' + (d.error || 'unknown'), false); }
|
|
212
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
212
213
|
}
|
|
213
214
|
|
|
214
215
|
async function kbOpenItem(category, file) {
|
|
@@ -277,8 +277,8 @@ async function _submitCreateMeeting() {
|
|
|
277
277
|
});
|
|
278
278
|
const data = await res.json();
|
|
279
279
|
if (res.ok) { wakeEngine(); refresh(); }
|
|
280
|
-
else {
|
|
281
|
-
} catch (e) {
|
|
280
|
+
else { showToast('cmd-toast', 'Failed: ' + (data.error || 'unknown'), false); openCreateMeetingModal(); }
|
|
281
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); openCreateMeetingModal(); }
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
async function _submitMeetingNote(id, btn) {
|
|
@@ -287,52 +287,53 @@ async function _submitMeetingNote(id, btn) {
|
|
|
287
287
|
const note = input.value.trim();
|
|
288
288
|
input.value = '';
|
|
289
289
|
if (btn) { btn.textContent = 'Adding...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
290
|
+
showToast('cmd-toast', 'Note added', true);
|
|
290
291
|
try {
|
|
291
292
|
const res = await fetch('/api/meetings/note', {
|
|
292
293
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
293
294
|
body: JSON.stringify({ id, note })
|
|
294
295
|
});
|
|
295
|
-
if (res.ok) {
|
|
296
|
-
else { input.value = note;
|
|
297
|
-
} catch (e) { input.value = note;
|
|
296
|
+
if (res.ok) { /* already toasted */ }
|
|
297
|
+
else { input.value = note; showToast('cmd-toast', 'Failed to add note', false); }
|
|
298
|
+
} catch (e) { input.value = note; showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
298
299
|
if (btn) { btn.textContent = 'Add Note'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
299
300
|
}
|
|
300
301
|
|
|
301
302
|
async function _advanceMeeting(id, btn) {
|
|
302
303
|
if (!confirm('Skip to next round? Agents that haven\'t finished will be skipped.')) return;
|
|
303
304
|
if (btn) { btn.textContent = 'Advancing...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
305
|
+
showToast('cmd-toast', 'Advanced to next round', true);
|
|
304
306
|
try {
|
|
305
307
|
const res = await fetch('/api/meetings/advance', {
|
|
306
308
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
307
309
|
body: JSON.stringify({ id })
|
|
308
310
|
});
|
|
309
311
|
if (res.ok) {
|
|
310
|
-
showToast('cmd-toast', 'Advanced to next round', true);
|
|
311
312
|
wakeEngine();
|
|
312
313
|
} else {
|
|
313
314
|
const d = await res.json().catch(function() { return {}; });
|
|
314
|
-
|
|
315
|
+
showToast('cmd-toast', 'Advance failed: ' + (d.error || 'unknown'), false);
|
|
315
316
|
}
|
|
316
|
-
} catch (e) {
|
|
317
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
317
318
|
if (btn) { btn.textContent = 'Skip to Next Round'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
async function _endMeeting(id, btn) {
|
|
321
322
|
if (!confirm('End this meeting? Current round will be stopped.')) return;
|
|
322
323
|
if (btn) { btn.textContent = 'Ending...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
324
|
+
showToast('cmd-toast', 'Meeting ended', true);
|
|
323
325
|
try {
|
|
324
326
|
const res = await fetch('/api/meetings/end', {
|
|
325
327
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
326
328
|
body: JSON.stringify({ id })
|
|
327
329
|
});
|
|
328
|
-
if (res.ok) {
|
|
329
|
-
|
|
330
|
-
} else {
|
|
330
|
+
if (res.ok) { /* already toasted */ }
|
|
331
|
+
else {
|
|
331
332
|
const d = await res.json().catch(function() { return {}; });
|
|
332
|
-
|
|
333
|
+
showToast('cmd-toast', 'End failed: ' + (d.error || 'unknown'), false);
|
|
333
334
|
if (btn) { btn.textContent = 'End Meeting'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
334
335
|
}
|
|
335
|
-
} catch (e) {
|
|
336
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); if (btn) { btn.textContent = 'End Meeting'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } }
|
|
336
337
|
}
|
|
337
338
|
|
|
338
339
|
async function _archiveMeeting(id) {
|
|
@@ -345,8 +346,8 @@ async function _archiveMeeting(id) {
|
|
|
345
346
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
346
347
|
body: JSON.stringify({ id })
|
|
347
348
|
});
|
|
348
|
-
if (!res.ok) { _deletedIds.delete('mtg:' + id); const d = await res.json().catch(() => ({}));
|
|
349
|
-
} catch (e) { _deletedIds.delete('mtg:' + id);
|
|
349
|
+
if (!res.ok) { _deletedIds.delete('mtg:' + id); const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false); refresh(); }
|
|
350
|
+
} catch (e) { _deletedIds.delete('mtg:' + id); showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
350
351
|
}
|
|
351
352
|
|
|
352
353
|
async function _unarchiveMeeting(id) {
|
|
@@ -358,8 +359,8 @@ async function _unarchiveMeeting(id) {
|
|
|
358
359
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
359
360
|
body: JSON.stringify({ id })
|
|
360
361
|
});
|
|
361
|
-
if (!res.ok) { const d = await res.json().catch(() => ({}));
|
|
362
|
-
} catch (e) {
|
|
362
|
+
if (!res.ok) { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Unarchive failed: ' + (d.error || 'unknown'), false); refresh(); }
|
|
363
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
363
364
|
}
|
|
364
365
|
|
|
365
366
|
function _viewPlanWithBack(file, meetingId) {
|
|
@@ -404,7 +405,7 @@ async function _createPlanFromMeeting(id, btn) {
|
|
|
404
405
|
try {
|
|
405
406
|
const res = await fetch('/api/meetings/' + encodeURIComponent(id));
|
|
406
407
|
const data = await res.json();
|
|
407
|
-
if (!data.meeting) { resetBtn();
|
|
408
|
+
if (!data.meeting) { resetBtn(); showToast('cmd-toast', 'Meeting not found', false); return; }
|
|
408
409
|
const m = data.meeting;
|
|
409
410
|
|
|
410
411
|
// Check if a plan already exists for this meeting
|
|
@@ -415,6 +416,7 @@ async function _createPlanFromMeeting(id, btn) {
|
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
if (btn) btn.textContent = 'Generating plan...';
|
|
419
|
+
showToast('cmd-toast', 'Generating plan from meeting...', true);
|
|
418
420
|
|
|
419
421
|
// Use doc-chat to generate a structured plan from the meeting
|
|
420
422
|
const transcript = (m.transcript || []).map(function(t) {
|
|
@@ -439,7 +441,7 @@ async function _createPlanFromMeeting(id, btn) {
|
|
|
439
441
|
})
|
|
440
442
|
});
|
|
441
443
|
const genData = await genRes.json();
|
|
442
|
-
if (!genRes.ok || !genData.ok) { resetBtn();
|
|
444
|
+
if (!genRes.ok || !genData.ok) { resetBtn(); showToast('cmd-toast', 'Failed to generate plan: ' + (genData.error || 'unknown'), false); return; }
|
|
443
445
|
|
|
444
446
|
const planContent = genData.answer || '';
|
|
445
447
|
const title = 'Meeting follow-up: ' + (m.title || id);
|
|
@@ -464,9 +466,9 @@ async function _createPlanFromMeeting(id, btn) {
|
|
|
464
466
|
}
|
|
465
467
|
} else {
|
|
466
468
|
resetBtn();
|
|
467
|
-
|
|
469
|
+
showToast('cmd-toast', 'Failed: ' + (planData.error || 'unknown'), false);
|
|
468
470
|
}
|
|
469
|
-
} catch (e) { resetBtn();
|
|
471
|
+
} catch (e) { resetBtn(); showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
470
472
|
}
|
|
471
473
|
|
|
472
474
|
async function _deleteMeeting(id) {
|
|
@@ -474,13 +476,14 @@ async function _deleteMeeting(id) {
|
|
|
474
476
|
markDeleted('mtg:' + id);
|
|
475
477
|
try { closeModal(); } catch { /* may not be open */ }
|
|
476
478
|
document.querySelectorAll('[onclick*="openMeetingDetail(\'' + id + '\')"]').forEach(function(el) { el.remove(); });
|
|
479
|
+
showToast('cmd-toast', 'Meeting deleted', true);
|
|
477
480
|
try {
|
|
478
481
|
const res = await fetch('/api/meetings/delete', {
|
|
479
482
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
480
483
|
body: JSON.stringify({ id })
|
|
481
484
|
});
|
|
482
|
-
if (!res.ok) { const d = await res.json().catch(() => ({}));
|
|
483
|
-
} catch (e) {
|
|
485
|
+
if (!res.ok) { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false); refresh(); }
|
|
486
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
484
487
|
}
|
|
485
488
|
|
|
486
489
|
window.MinionsMeetings = { renderMeetings, openMeetingDetail, openCreateMeetingModal };
|
|
@@ -45,18 +45,19 @@ async function submitPinnedNote(e) {
|
|
|
45
45
|
showToast('cmd-toast', 'Note pinned', true);
|
|
46
46
|
try {
|
|
47
47
|
const res = await fetch('/api/pinned', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title, content, level }) });
|
|
48
|
-
if (res.ok) { refresh(); } else { const d = await res.json().catch(() => ({}));
|
|
49
|
-
} catch (e) {
|
|
48
|
+
if (res.ok) { refresh(); } else { const d = await res.json().catch(() => ({})); showToast('cmd-toast', 'Pin failed: ' + (d.error || 'unknown'), false); openPinNoteModal(); }
|
|
49
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); openPinNoteModal(); }
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
async function removePinnedNote(title) {
|
|
53
53
|
if (!confirm('Unpin "' + title + '"?')) return;
|
|
54
54
|
markDeleted('pin:' + title);
|
|
55
55
|
const btn = (window.event)?.target; if (btn) { const card = btn.closest('.pinned-card') || btn.parentElement?.parentElement; if (card) card.remove(); }
|
|
56
|
+
showToast('cmd-toast', 'Note unpinned', true);
|
|
56
57
|
try {
|
|
57
58
|
const res = await fetch('/api/pinned/remove', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title }) });
|
|
58
|
-
if (!res.ok) {
|
|
59
|
-
} catch (e) {
|
|
59
|
+
if (!res.ok) { showToast('cmd-toast', 'Unpin failed', false); refresh(); }
|
|
60
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
function openPinnedView(idx) {
|
|
@@ -446,67 +446,66 @@ async function _refreshPipelineDetail(id) {
|
|
|
446
446
|
|
|
447
447
|
async function _triggerPipeline(id, btn) {
|
|
448
448
|
if (btn) { btn.textContent = 'Starting...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
449
|
+
showToast('cmd-toast', 'Pipeline triggered', true);
|
|
449
450
|
try {
|
|
450
451
|
var res = await fetch('/api/pipelines/trigger', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) });
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
} catch (e) { if (btn) { btn.textContent = 'Run Now'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } alert('Error: ' + e.message); }
|
|
452
|
+
if (res.ok) { refresh(); await _refreshPipelineDetail(id); }
|
|
453
|
+
else { var d = await res.json().catch(function() { return {}; }); if (btn) { btn.textContent = 'Run Now'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false); }
|
|
454
|
+
} catch (e) { if (btn) { btn.textContent = 'Run Now'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
async function _abortPipeline(id, btn) {
|
|
458
458
|
if (!confirm('Abort the active run for "' + id + '"?')) return;
|
|
459
459
|
if (btn) { btn.textContent = 'Aborting...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
460
|
+
showToast('cmd-toast', 'Pipeline aborted', true);
|
|
460
461
|
try {
|
|
461
462
|
var res = await fetch('/api/pipelines/abort', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) });
|
|
462
463
|
if (res.ok) {
|
|
463
|
-
var d = await res.json().catch(function() { return {}; });
|
|
464
|
-
showToast('cmd-toast', 'Pipeline aborted — ' + (d.cancelledWorkItems || 0) + ' work items cancelled', true);
|
|
465
464
|
refresh();
|
|
466
465
|
await _refreshPipelineDetail(id);
|
|
467
|
-
} else { var d = await res.json().catch(function() { return {}; });
|
|
468
|
-
} catch (e) {
|
|
466
|
+
} else { var d = await res.json().catch(function() { return {}; }); showToast('cmd-toast', 'Abort failed: ' + (d.error || 'unknown'), false); if (btn) { btn.textContent = 'Abort'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } }
|
|
467
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); if (btn) { btn.textContent = 'Abort'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } }
|
|
469
468
|
}
|
|
470
469
|
|
|
471
470
|
async function _retriggerPipeline(id, btn) {
|
|
472
471
|
if (!confirm('Abort current run and start a fresh one for "' + id + '"?')) return;
|
|
473
472
|
if (btn) { btn.textContent = 'Retriggering...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
473
|
+
showToast('cmd-toast', 'Pipeline retriggered', true);
|
|
474
474
|
try {
|
|
475
475
|
var res = await fetch('/api/pipelines/retrigger', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) });
|
|
476
|
-
var d = await res.json();
|
|
477
476
|
if (res.ok) {
|
|
478
|
-
showToast('cmd-toast', 'Pipeline retriggered: ' + (d.runId || ''), true);
|
|
479
477
|
refresh();
|
|
480
478
|
await _refreshPipelineDetail(id);
|
|
481
|
-
} else {
|
|
482
|
-
} catch (e) {
|
|
479
|
+
} else { var d = await res.json().catch(function() { return {}; }); showToast('cmd-toast', 'Retrigger failed: ' + (d.error || 'unknown'), false); if (btn) { btn.textContent = 'Retrigger'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } }
|
|
480
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); if (btn) { btn.textContent = 'Retrigger'; btn.style.pointerEvents = ''; btn.style.opacity = ''; } }
|
|
483
481
|
}
|
|
484
482
|
|
|
485
483
|
async function _togglePipelineEnabled(id, enabled, btn) {
|
|
486
484
|
if (btn) { btn.textContent = enabled ? 'Enabling...' : 'Disabling...'; btn.style.pointerEvents = 'none'; }
|
|
485
|
+
showToast('cmd-toast', enabled ? 'Pipeline enabled' : 'Pipeline disabled', true);
|
|
487
486
|
try {
|
|
488
487
|
var res = await fetch('/api/pipelines/update', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id, enabled: enabled }) });
|
|
489
|
-
if (res.ok) {
|
|
490
|
-
else {
|
|
491
|
-
} catch (e) {
|
|
488
|
+
if (res.ok) { refresh(); }
|
|
489
|
+
else { showToast('cmd-toast', 'Failed to ' + (enabled ? 'enable' : 'disable') + ' pipeline', false); }
|
|
490
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
492
491
|
if (btn) { btn.textContent = enabled ? 'Disable' : 'Enable'; btn.style.pointerEvents = ''; }
|
|
493
492
|
}
|
|
494
493
|
|
|
495
494
|
async function _continuePipeline(id, stageId, btn) {
|
|
496
495
|
if (btn) { btn.textContent = 'Continuing...'; btn.style.pointerEvents = 'none'; btn.style.opacity = '0.6'; }
|
|
496
|
+
showToast('cmd-toast', 'Stage continued — dispatching next tick', true);
|
|
497
497
|
try {
|
|
498
498
|
var res = await fetch('/api/pipelines/continue', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id, stageId: stageId }) });
|
|
499
499
|
if (res.ok) {
|
|
500
|
-
showToast('cmd-toast', 'Stage continued — dispatching next tick', true);
|
|
501
500
|
if (btn) { btn.textContent = '\u2713 Continued'; btn.style.color = 'var(--green)'; btn.style.borderColor = 'var(--green)'; btn.style.opacity = '1'; }
|
|
502
501
|
// Immediate refresh — no waiting for 4s poll
|
|
503
502
|
await _refreshPipelineDetail(id);
|
|
504
503
|
} else {
|
|
505
|
-
var d = await res.json().catch(function() { return {}; });
|
|
504
|
+
var d = await res.json().catch(function() { return {}; }); showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false);
|
|
506
505
|
if (btn) { btn.textContent = 'Continue'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
507
506
|
}
|
|
508
507
|
} catch (e) {
|
|
509
|
-
|
|
508
|
+
showToast('cmd-toast', 'Error: ' + e.message, false);
|
|
510
509
|
if (btn) { btn.textContent = 'Continue'; btn.style.pointerEvents = ''; btn.style.opacity = ''; }
|
|
511
510
|
}
|
|
512
511
|
}
|
|
@@ -515,10 +514,11 @@ async function _deletePipelineConfirm(id) {
|
|
|
515
514
|
if (!confirm('Delete pipeline "' + id + '"?')) return;
|
|
516
515
|
markDeleted('pipeline:' + id);
|
|
517
516
|
try { closeModal(); } catch {}
|
|
517
|
+
showToast('cmd-toast', 'Pipeline deleted', true);
|
|
518
518
|
try {
|
|
519
519
|
var res = await fetch('/api/pipelines/delete', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) });
|
|
520
|
-
if (!res.ok) {
|
|
521
|
-
} catch (e) {
|
|
520
|
+
if (!res.ok) { showToast('cmd-toast', 'Delete failed', false); refresh(); }
|
|
521
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
522
522
|
}
|
|
523
523
|
|
|
524
524
|
function openCreatePipelineModal() {
|
|
@@ -613,8 +613,8 @@ async function _submitCreatePipeline() {
|
|
|
613
613
|
showToast('cmd-toast', 'Pipeline created', true);
|
|
614
614
|
try {
|
|
615
615
|
var res = await fetch('/api/pipelines', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
|
616
|
-
if (res.ok) { refresh(); } else { var d = await res.json().catch(function() { return {}; });
|
|
617
|
-
} catch (e) {
|
|
616
|
+
if (res.ok) { refresh(); } else { var d = await res.json().catch(function() { return {}; }); showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false); openCreatePipelineModal(); }
|
|
617
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); openCreatePipelineModal(); }
|
|
618
618
|
}
|
|
619
619
|
|
|
620
620
|
function openEditPipelineModal(id) {
|
|
@@ -694,11 +694,13 @@ async function _submitEditPipeline() {
|
|
|
694
694
|
if (!Array.isArray(stages) || stages.length === 0) { alert('Stages must be a non-empty array'); return; }
|
|
695
695
|
|
|
696
696
|
var body = { id: id, title: title, stages: stages, trigger: cron ? { cron: cron } : null };
|
|
697
|
+
closeModal();
|
|
698
|
+
showToast('cmd-toast', 'Pipeline updated', true);
|
|
697
699
|
try {
|
|
698
700
|
var res = await fetch('/api/pipelines/update', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
|
699
|
-
if (res.ok) {
|
|
700
|
-
else { var d = await res.json().catch(function() { return {}; });
|
|
701
|
-
} catch (e) {
|
|
701
|
+
if (res.ok) { refresh(); }
|
|
702
|
+
else { var d = await res.json().catch(function() { return {}; }); showToast('cmd-toast', 'Failed: ' + (d.error || 'unknown'), false); }
|
|
703
|
+
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); }
|
|
702
704
|
}
|
|
703
705
|
|
|
704
706
|
window.MinionsPipelines = { renderPipelines, openPipelineDetail, openCreatePipelineModal, openEditPipelineModal };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.846",
|
|
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"
|