@yemi33/minions 0.1.303 → 0.1.305
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 +10 -0
- package/dashboard/js/command-center.js +23 -5
- package/dashboard/js/modal-qa.js +18 -2
- package/engine.js +9 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.305 (2026-04-03)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- normalize acceptanceCriteria to array (string from doc-chat crashed tick)
|
|
7
|
+
|
|
8
|
+
## 0.1.304 (2026-04-03)
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
- add Stop button to CC and doc-chat to abort in-flight requests
|
|
12
|
+
|
|
3
13
|
## 0.1.303 (2026-04-03)
|
|
4
14
|
|
|
5
15
|
### Fixes
|
|
@@ -9,6 +9,13 @@ let _ccAbortController = null;
|
|
|
9
9
|
// Clear stale sending state on page load — SSE streams don't survive refresh
|
|
10
10
|
try { localStorage.removeItem('cc-sending'); } catch {}
|
|
11
11
|
|
|
12
|
+
function ccAbort() {
|
|
13
|
+
if (_ccAbortController) {
|
|
14
|
+
_ccAbortController.abort();
|
|
15
|
+
_ccAbortController = null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
function toggleCommandCenter() {
|
|
13
20
|
_ccOpen = !_ccOpen;
|
|
14
21
|
const drawer = document.getElementById('cc-drawer');
|
|
@@ -181,7 +188,8 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
181
188
|
if (elapsed >= phases[pi][0]) { label = phases[pi][1]; break; }
|
|
182
189
|
}
|
|
183
190
|
var secs = Math.floor(elapsed / 1000);
|
|
184
|
-
return '<div style="display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:11px">' + label + '</span>' + dotPulse + '<span style="margin-left:auto;font-size:10px;color:var(--muted)">' + secs + 's</span
|
|
191
|
+
return '<div style="display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:11px">' + label + '</span>' + dotPulse + '<span style="margin-left:auto;font-size:10px;color:var(--muted)">' + secs + 's</span>' +
|
|
192
|
+
'<button onclick="ccAbort()" style="font-size:9px;padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer;margin-left:4px">Stop</button></div>';
|
|
185
193
|
}
|
|
186
194
|
function updateStreamDiv() {
|
|
187
195
|
var html = '';
|
|
@@ -293,9 +301,19 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
293
301
|
}
|
|
294
302
|
}
|
|
295
303
|
} catch (e) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
304
|
+
if (streamDiv?.parentNode) { clearInterval(phaseTimer); streamDiv.remove(); }
|
|
305
|
+
if (e.name === 'AbortError') {
|
|
306
|
+
if (streamedText) {
|
|
307
|
+
const ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
|
|
308
|
+
ccAddMessage('assistant', renderMd(streamedText) + '<div style="font-size:9px;color:var(--muted);margin-top:6px">Stopped after ' + ccElapsed + 's</div>');
|
|
309
|
+
} else {
|
|
310
|
+
ccAddMessage('assistant', '<span style="color:var(--muted);font-size:11px">Stopped</span>');
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
const retryId = 'cc-retry-' + Date.now();
|
|
314
|
+
ccAddMessage('assistant', '<span style="color:var(--red)">Error: ' + escHtml(e.message) + '</span>' +
|
|
315
|
+
'<button id="' + retryId + '" onclick="ccRetryLast()" style="margin-top:6px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--blue);cursor:pointer;font-size:11px">Retry</button>');
|
|
316
|
+
}
|
|
299
317
|
} finally {
|
|
300
318
|
_ccSending = false;
|
|
301
319
|
_ccAbortController = null;
|
|
@@ -718,4 +736,4 @@ if (document.readyState === 'loading') {
|
|
|
718
736
|
ccInitResize();
|
|
719
737
|
}
|
|
720
738
|
|
|
721
|
-
window.MinionsCC = { toggleCommandCenter, ccNewSession, ccRestoreMessages, ccSaveState, ccUpdateSessionIndicator, ccAddMessage, ccSend, ccExecuteAction };
|
|
739
|
+
window.MinionsCC = { toggleCommandCenter, ccNewSession, ccRestoreMessages, ccSaveState, ccUpdateSessionIndicator, ccAddMessage, ccSend, ccAbort, ccExecuteAction };
|
package/dashboard/js/modal-qa.js
CHANGED
|
@@ -22,6 +22,7 @@ function _qaNotifySidebar(filePath) {
|
|
|
22
22
|
}
|
|
23
23
|
let _qaHistory = []; // multi-turn conversation history [{role:'user',text:''},{role:'assistant',text:''}]
|
|
24
24
|
let _qaProcessing = false; // true while waiting for response
|
|
25
|
+
let _qaAbortController = null;
|
|
25
26
|
let _qaQueue = []; // queued messages while processing
|
|
26
27
|
let _qaSessionKey = ''; // key for current conversation (title or filePath)
|
|
27
28
|
const _qaSessions = new Map(); // persist conversations across modal open/close {key → {history, threadHtml}}
|
|
@@ -172,10 +173,12 @@ async function _processQaMessage(message, selection) {
|
|
|
172
173
|
|
|
173
174
|
const loadingId = 'chat-loading-' + Date.now();
|
|
174
175
|
const qaQueueBadge = _qaQueue.length > 0 ? ' <span style="font-size:9px;color:var(--muted);background:var(--surface);padding:1px 5px;border-radius:8px;border:1px solid var(--border)">+' + _qaQueue.length + ' queued</span>' : '';
|
|
176
|
+
_qaAbortController = new AbortController();
|
|
175
177
|
thread.innerHTML += '<div class="modal-qa-loading" id="' + loadingId + '">' +
|
|
176
178
|
'<div class="dot-pulse"><span></span><span></span><span></span></div> ' +
|
|
177
179
|
'<span id="' + loadingId + '-text">Thinking...</span> ' +
|
|
178
180
|
'<span id="' + loadingId + '-time" style="font-size:10px;color:var(--muted)"></span>' +
|
|
181
|
+
' <button onclick="qaAbort()" style="font-size:9px;padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer">Stop</button>' +
|
|
179
182
|
qaQueueBadge + '</div>';
|
|
180
183
|
thread.scrollTop = thread.scrollHeight;
|
|
181
184
|
|
|
@@ -196,6 +199,7 @@ async function _processQaMessage(message, selection) {
|
|
|
196
199
|
const res = await fetch('/api/doc-chat', {
|
|
197
200
|
method: 'POST',
|
|
198
201
|
headers: { 'Content-Type': 'application/json' },
|
|
202
|
+
signal: _qaAbortController ? _qaAbortController.signal : undefined,
|
|
199
203
|
body: JSON.stringify({
|
|
200
204
|
message,
|
|
201
205
|
document: capturedDocContext.content,
|
|
@@ -265,10 +269,15 @@ async function _processQaMessage(message, selection) {
|
|
|
265
269
|
const loadingEl = document.getElementById(loadingId);
|
|
266
270
|
if (loadingEl) loadingEl.remove();
|
|
267
271
|
const qaElapsedExc = Math.round((Date.now() - qaStartTime) / 1000);
|
|
268
|
-
|
|
272
|
+
if (e.name === 'AbortError') {
|
|
273
|
+
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--muted)">Stopped<div style="font-size:9px;margin-top:4px;text-align:right">' + qaElapsedExc + 's</div></div>';
|
|
274
|
+
} else {
|
|
275
|
+
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(e.message) + '<div style="font-size:9px;color:var(--muted);margin-top:4px;text-align:right">' + qaElapsedExc + 's</div></div>';
|
|
276
|
+
}
|
|
269
277
|
}
|
|
270
278
|
|
|
271
279
|
_qaProcessing = false;
|
|
280
|
+
_qaAbortController = null;
|
|
272
281
|
thread.scrollTop = thread.scrollHeight;
|
|
273
282
|
|
|
274
283
|
// Save session (persists even if modal was closed during processing)
|
|
@@ -305,4 +314,11 @@ async function _processQaMessage(message, selection) {
|
|
|
305
314
|
}
|
|
306
315
|
}
|
|
307
316
|
|
|
308
|
-
|
|
317
|
+
function qaAbort() {
|
|
318
|
+
if (_qaAbortController) {
|
|
319
|
+
_qaAbortController.abort();
|
|
320
|
+
_qaAbortController = null;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
window.MinionsQA = { showModalQa, modalAskAboutSelection, clearQaSelection, clearQaConversation, modalSend, qaAbort };
|
package/engine.js
CHANGED
|
@@ -1484,7 +1484,7 @@ function discoverFromWorkItems(config, project) {
|
|
|
1484
1484
|
'- [' + (r.title || r.url) + '](' + r.url + ')' + (r.type ? ' (' + r.type + ')' : '')
|
|
1485
1485
|
).join('\n');
|
|
1486
1486
|
vars.references = refs ? '## References\n\n' + refs : '';
|
|
1487
|
-
const ac = (item.acceptanceCriteria
|
|
1487
|
+
const ac = normalizeAc(item.acceptanceCriteria).map(c => '- [ ] ' + c).join('\n');
|
|
1488
1488
|
vars.acceptance_criteria = ac ? '## Acceptance Criteria\n\n' + ac : '';
|
|
1489
1489
|
|
|
1490
1490
|
// Inject checkpoint context if agent left a checkpoint.json from a prior run
|
|
@@ -1585,6 +1585,12 @@ function discoverFromWorkItems(config, project) {
|
|
|
1585
1585
|
* Build the multi-project context section for central work items.
|
|
1586
1586
|
* Inserted into the playbook via {{scope_section}}.
|
|
1587
1587
|
*/
|
|
1588
|
+
function normalizeAc(ac) {
|
|
1589
|
+
if (Array.isArray(ac)) return ac;
|
|
1590
|
+
if (typeof ac === 'string') return ac.split('\n').map(s => s.replace(/^[-*]\s*/, '').trim()).filter(Boolean);
|
|
1591
|
+
return [];
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1588
1594
|
function buildProjectContext(projects, assignedProject, isFanOut, agentName, agentRole) {
|
|
1589
1595
|
const projectList = projects.map(p => {
|
|
1590
1596
|
let line = `### ${p.name}\n`;
|
|
@@ -1811,7 +1817,7 @@ function discoverCentralWorkItems(config) {
|
|
|
1811
1817
|
'- [' + (r.title || r.url) + '](' + r.url + ')' + (r.type ? ' (' + r.type + ')' : '')
|
|
1812
1818
|
).join('\n');
|
|
1813
1819
|
vars.references = fanRefs ? '## References\n\n' + fanRefs : '';
|
|
1814
|
-
const fanAc = (item.acceptanceCriteria
|
|
1820
|
+
const fanAc = normalizeAc(item.acceptanceCriteria).map(c => '- [ ] ' + c).join('\n');
|
|
1815
1821
|
vars.acceptance_criteria = fanAc ? '## Acceptance Criteria\n\n' + fanAc : '';
|
|
1816
1822
|
|
|
1817
1823
|
if (workType === 'ask') {
|
|
@@ -1887,7 +1893,7 @@ function discoverCentralWorkItems(config) {
|
|
|
1887
1893
|
'- [' + (r.title || r.url) + '](' + r.url + ')' + (r.type ? ' (' + r.type + ')' : '')
|
|
1888
1894
|
).join('\n');
|
|
1889
1895
|
vars.references = normRefs ? '## References\n\n' + normRefs : '';
|
|
1890
|
-
const normAc = (item.acceptanceCriteria
|
|
1896
|
+
const normAc = normalizeAc(item.acceptanceCriteria).map(c => '- [ ] ' + c).join('\n');
|
|
1891
1897
|
vars.acceptance_criteria = normAc ? '## Acceptance Criteria\n\n' + normAc : '';
|
|
1892
1898
|
|
|
1893
1899
|
// Inject checkpoint context if agent left a checkpoint.json from a prior run
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.305",
|
|
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"
|