@yemi33/minions 0.1.790 → 0.1.791

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.790 (2026-04-10)
3
+ ## 0.1.791 (2026-04-10)
4
4
 
5
5
  ### Features
6
6
  - add open-source community sources to agentic research pipeline
@@ -8,6 +8,8 @@
8
8
  - cap review→fix cycles at evalMaxIterations (default 3)
9
9
 
10
10
  ### Fixes
11
+ - repair invalid JSON in daily-arch-improvement pipeline
12
+ - flush queued CC messages as single combined request
11
13
  - human feedback fixes are never capped (only minion review→fix loop is)
12
14
  - 5 bugs from comprehensive audit
13
15
  - stale ADO build detection + merge conflict auto-fix for both platforms
@@ -161,6 +161,7 @@ function ccSwitchTab(id) {
161
161
  ccAddMessage('assistant', _restoreStreamHtml(), true);
162
162
  var restoreDiv = el.lastElementChild;
163
163
  restoreDiv.id = 'cc-restore-thinking';
164
+ restoreDiv.setAttribute('data-stream-tab', tab.id);
164
165
  el.scrollTop = el.scrollHeight;
165
166
  // Live update — stops when tab switches away or request completes
166
167
  var restoreInterval = setInterval(function() {
@@ -324,7 +325,8 @@ function ccUpdateSessionIndicator() {
324
325
 
325
326
  function ccAddMessage(role, html, skipSave, targetTabId) {
326
327
  var isUser = role === 'user';
327
- var isAssistant = !isUser;
328
+ var isSystem = role === 'system';
329
+ var isAssistant = !isUser && !isSystem;
328
330
  var targetTab = targetTabId ? _ccTabs.find(function(t) { return t.id === targetTabId; }) : _ccActiveTab();
329
331
  // Only render to DOM if this message is for the currently visible tab
330
332
  var isVisible = !targetTabId || targetTabId === _ccActiveTabId;
@@ -333,7 +335,7 @@ function ccAddMessage(role, html, skipSave, targetTabId) {
333
335
  var div = document.createElement('div');
334
336
  div.className = isAssistant ? 'cc-msg-assistant' : '';
335
337
  div.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:12px;line-height:1.6;max-width:95%;' +
336
- (isUser ? 'background:var(--blue);color:#fff;align-self:flex-end' : 'background:var(--surface2);color:var(--text);align-self:flex-start;border:1px solid var(--border);position:relative');
338
+ (isUser ? 'background:var(--blue);color:#fff;align-self:flex-end' : isSystem ? 'align-self:center;max-width:100%' : 'background:var(--surface2);color:var(--text);align-self:flex-start;border:1px solid var(--border);position:relative');
337
339
  div.innerHTML = (isAssistant && !html.includes('color:var(--red)') && !html.includes('cc-queued-pill') ? llmCopyBtn() : '') + html;
338
340
  var wasNearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 150;
339
341
  el.appendChild(div);
@@ -376,16 +378,11 @@ async function ccSend() {
376
378
  }
377
379
  var wasAborted = await _ccDoSend(message);
378
380
 
379
- // Drain this tab's queue send each queued message in order
380
- while (tab._queue && tab._queue.length > 0) {
381
- if (wasAborted) {
382
- tab._sending = true;
383
- await new Promise(function(r) { setTimeout(r, 500); });
384
- tab._sending = false;
385
- }
386
- var next = tab._queue.shift();
381
+ // Flush queued messagescombine into single request
382
+ if (tab._queue && tab._queue.length > 0 && !wasAborted) {
383
+ var combined = tab._queue.splice(0).join('\n\n');
387
384
  _renderQueueIndicator();
388
- wasAborted = await _ccDoSend(next);
385
+ wasAborted = await _ccDoSend(combined);
389
386
  }
390
387
  }
391
388
 
@@ -466,15 +463,23 @@ async function _ccDoSend(message, skipUserMsg) {
466
463
  if (activeTab) { activeTab._streamedText = ''; activeTab._toolsUsed = []; }
467
464
 
468
465
  // Get active tab's sessionId to send with request
469
- var activeTab = _ccActiveTab();
470
466
  var tabSessionId = activeTab ? activeTab.sessionId : null;
471
- var activeTabId = _ccActiveTabId;
472
467
 
473
468
  // Show thinking immediately — before fetch starts
474
469
  addMsg('assistant', '<span style="color:var(--muted);font-size:11px">Thinking...</span>', true);
475
470
  var msgs = document.getElementById('cc-messages');
476
471
  var streamDiv = msgs.lastElementChild;
477
- var dotPulse = '<span style="display:inline-flex;gap:3px;margin-left:6px;vertical-align:middle"><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.2s"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.4s"></span></span>';
472
+ if (streamDiv) streamDiv.setAttribute('data-stream-tab', activeTabId);
473
+ function _cleanupStreamDiv() {
474
+ clearInterval(phaseTimer);
475
+ if (streamDiv && streamDiv.parentNode) streamDiv.remove();
476
+ // Only remove restore-thinking if it belongs to this tab (check data-stream-tab)
477
+ var re = document.getElementById('cc-restore-thinking');
478
+ if (re && re.getAttribute('data-stream-tab') === activeTabId) re.remove();
479
+ var ds = document.querySelector('[data-stream-tab="' + activeTabId + '"]');
480
+ if (ds) ds.remove();
481
+ }
482
+ var dotPulse = '<span style="display:inline-flex;gap:3px;margin-left:6px;vertical-align:middle"><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.2s"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.4s"></span></span>';
478
483
  function _getThinkingHtml() {
479
484
  var elapsed = Date.now() - ccStartTime;
480
485
  var label = 'Thinking...';
@@ -490,7 +495,7 @@ async function _ccDoSend(message, skipUserMsg) {
490
495
  if (_ccActiveTabId !== activeTabId) return;
491
496
  // Re-acquire streamDiv if it was detached (tab switch and back)
492
497
  if (!streamDiv.parentNode) {
493
- var re = document.getElementById('cc-restore-thinking');
498
+ var re = document.getElementById('cc-restore-thinking') || document.querySelector('[data-stream-tab="' + activeTabId + '"]');
494
499
  if (re) { streamDiv = re; re.removeAttribute('id'); } else return;
495
500
  }
496
501
  var html = '';
@@ -523,7 +528,7 @@ async function _ccDoSend(message, skipUserMsg) {
523
528
  });
524
529
 
525
530
  if (!res.ok) {
526
- clearInterval(phaseTimer); streamDiv.remove();
531
+ _cleanupStreamDiv();
527
532
  var errText = await res.text();
528
533
  addMsg('assistant', '<span style="color:var(--red)">' + escHtml(errText || 'CC error') + '</span>' +
529
534
  (errText.includes('busy') ? ' <button onclick="ccNewTab()" style="margin-top:4px;padding:3px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--blue);cursor:pointer;font-size:10px">Reset CC</button>' : ''));
@@ -555,22 +560,26 @@ async function _ccDoSend(message, skipUserMsg) {
555
560
  updateStreamDiv();
556
561
  if (msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight < 150) msgs.scrollTop = msgs.scrollHeight;
557
562
  } else if (evt.type === 'done') {
558
- // Replace streaming div with a proper ccAddMessage
559
- clearInterval(phaseTimer); streamDiv.remove();
563
+ _cleanupStreamDiv();
564
+ // If system prompt changed, show a notice before the response
565
+ if (evt.sessionReset) {
566
+ addMsg('system', '<div style="text-align:center;padding:6px 12px;font-size:11px;color:var(--muted);background:var(--surface2);border-radius:6px;margin:4px 0">Minions was updated — started a fresh session with latest context.</div>', false, activeTabId);
567
+ }
560
568
  // placeholder was added with skipSave=true — nothing to pop
561
569
  var ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
562
570
  var rendered = renderMd(evt.text || streamedText || '');
563
571
  addMsg('assistant', rendered + '<div style="font-size:9px;color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">' + ccElapsed + 's</div>');
564
572
  if (evt.sessionId !== undefined) {
565
- var currentTab = _ccActiveTab();
566
- if (currentTab) { currentTab.sessionId = evt.sessionId || null; }
573
+ // Save session to the originating tab, not whichever tab is active now
574
+ var originTab = _ccTabs.find(function(t) { return t.id === activeTabId; });
575
+ if (originTab) { originTab.sessionId = evt.sessionId || null; }
567
576
  ccSaveState(); ccUpdateSessionIndicator();
568
577
  }
569
578
  if (evt.actions && evt.actions.length > 0) {
570
579
  for (var ai = 0; ai < evt.actions.length; ai++) { await ccExecuteAction(evt.actions[ai]); }
571
580
  }
572
581
  } else if (evt.type === 'error') {
573
- clearInterval(phaseTimer); streamDiv.remove();
582
+ _cleanupStreamDiv();
574
583
  // placeholder was skipSave — no pop needed
575
584
  addMsg('assistant', '<span style="color:var(--red)">' + escHtml(evt.error) + '</span>');
576
585
  }
@@ -586,14 +595,14 @@ async function _ccDoSend(message, skipUserMsg) {
586
595
  try {
587
596
  var revt = JSON.parse(rline.slice(6));
588
597
  if (revt.type === 'done') {
589
- clearInterval(phaseTimer); streamDiv.remove();
598
+ _cleanupStreamDiv();
590
599
  // placeholder was skipSave — no pop needed
591
600
  var ccElapsed2 = Math.round((Date.now() - ccStartTime) / 1000);
592
601
  var rendered2 = renderMd(revt.text || streamedText || '');
593
602
  addMsg('assistant', rendered2 + '<div style="font-size:9px;color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">' + ccElapsed2 + 's</div>');
594
603
  if (revt.sessionId !== undefined) {
595
- var currentTab2 = _ccActiveTab();
596
- if (currentTab2) { currentTab2.sessionId = revt.sessionId || null; }
604
+ var originTab2 = _ccTabs.find(function(t) { return t.id === activeTabId; });
605
+ if (originTab2) { originTab2.sessionId = revt.sessionId || null; }
597
606
  ccSaveState(); ccUpdateSessionIndicator();
598
607
  }
599
608
  if (revt.actions && revt.actions.length > 0) {
@@ -607,15 +616,15 @@ async function _ccDoSend(message, skipUserMsg) {
607
616
  }
608
617
  }
609
618
  // If stream ended without a 'done' event, finalize with whatever we have
610
- if (streamDiv.parentNode) {
611
- clearInterval(phaseTimer); streamDiv.remove();
619
+ if (streamDiv.parentNode || document.getElementById('cc-restore-thinking') || document.querySelector('[data-stream-tab="' + activeTabId + '"]')) {
620
+ _cleanupStreamDiv();
612
621
  if (streamedText) {
613
622
  var ccElapsed3 = Math.round((Date.now() - ccStartTime) / 1000);
614
623
  addMsg('assistant', renderMd(streamedText) + '<div style="font-size:9px;color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">' + ccElapsed3 + 's</div>');
615
624
  }
616
625
  }
617
626
  } catch (e) {
618
- if (streamDiv?.parentNode) { clearInterval(phaseTimer); streamDiv.remove(); }
627
+ _cleanupStreamDiv();
619
628
  if (e.name === 'AbortError') {
620
629
  _wasAborted = true;
621
630
  if (streamedText) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.790",
3
+ "version": "0.1.791",
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"