@yemi33/minions 0.1.2110 → 0.1.2111
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/dashboard/js/command-center.js +36 -36
- package/dashboard/js/detail-panel.js +12 -12
- package/dashboard/js/fre.js +9 -9
- package/dashboard/js/live-stream.js +2 -2
- package/dashboard/js/modal-qa.js +17 -17
- package/dashboard/js/qa.js +3 -3
- package/dashboard/js/refresh.js +8 -8
- package/dashboard/js/render-agents.js +12 -12
- package/dashboard/js/render-dispatch.js +8 -8
- package/dashboard/js/render-inbox.js +5 -5
- package/dashboard/js/render-managed.js +16 -16
- package/dashboard/js/render-meetings.js +36 -36
- package/dashboard/js/render-other.js +23 -23
- package/dashboard/js/render-pinned.js +1 -1
- package/dashboard/js/render-pipelines.js +36 -36
- package/dashboard/js/render-plans.js +23 -23
- package/dashboard/js/render-prd.js +100 -100
- package/dashboard/js/render-prs.js +10 -10
- package/dashboard/js/render-schedules.js +23 -23
- package/dashboard/js/render-skills.js +7 -7
- package/dashboard/js/render-utils.js +22 -22
- package/dashboard/js/render-watches.js +37 -37
- package/dashboard/js/render-work-items.js +34 -34
- package/dashboard/js/utils.js +8 -8
- package/dashboard/layout.html +20 -20
- package/dashboard/pages/engine.html +4 -4
- package/dashboard/pages/home.html +4 -4
- package/dashboard/pages/inbox.html +3 -3
- package/dashboard/pages/meetings.html +2 -2
- package/dashboard/pages/pipelines.html +2 -2
- package/dashboard/pages/plans.html +3 -3
- package/dashboard/pages/prs.html +2 -2
- package/dashboard/pages/schedule.html +2 -2
- package/dashboard/pages/tools.html +1 -1
- package/dashboard/pages/watches.html +2 -2
- package/dashboard/pages/work.html +3 -3
- package/dashboard/styles.css +38 -38
- package/package.json +1 -1
|
@@ -555,8 +555,8 @@ function ccSwitchTab(id) {
|
|
|
555
555
|
var label = 'Thinking...';
|
|
556
556
|
for (var pi = phases.length - 1; pi >= 0; pi--) { if (ms >= phases[pi][0]) { label = phases[pi][1]; break; } }
|
|
557
557
|
var secs = Math.floor(ms / 1000);
|
|
558
|
-
html += '<div style="margin-top:' + (text ? '6px' : '0') + ';display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:
|
|
559
|
-
'<button onclick="ccAbort()" style="font-size:
|
|
558
|
+
html += '<div style="margin-top:' + (text ? '6px' : '0') + ';display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:var(--text-base)">' + label + '</span>' + dotPulse + '<span style="margin-left:auto;font-size:var(--text-sm);color:var(--muted)">' + secs + 's</span>' +
|
|
559
|
+
'<button onclick="ccAbort()" style="font-size:var(--text-xs);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>';
|
|
560
560
|
return html;
|
|
561
561
|
}
|
|
562
562
|
ccAddMessage('assistant', _restoreStreamHtml(), true);
|
|
@@ -742,10 +742,10 @@ function ccRestoreMessages() {
|
|
|
742
742
|
var elapsed = Date.now() - sendingState.startedAt;
|
|
743
743
|
var thinking = document.createElement('div');
|
|
744
744
|
thinking.id = 'cc-thinking';
|
|
745
|
-
thinking.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:
|
|
745
|
+
thinking.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:var(--text-base);color:var(--muted);align-self:flex-start;display:flex;align-items:center;gap:8px';
|
|
746
746
|
// eslint-disable-next-line no-unsanitized/property -- reason: composed from elapsed timer and compile-time thinking UI strings (no user data flows in)
|
|
747
|
-
thinking.innerHTML = '<span class="dot-pulse" style="display:inline-flex;gap:3px"><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> <span id="cc-thinking-text">Still working...</span> <span id="cc-thinking-time" style="font-size:
|
|
748
|
-
' <button onclick="ccNewTab()" style="font-size:
|
|
747
|
+
thinking.innerHTML = '<span class="dot-pulse" style="display:inline-flex;gap:3px"><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> <span id="cc-thinking-text">Still working...</span> <span id="cc-thinking-time" style="font-size:var(--text-sm);color:var(--border)">' + Math.floor(elapsed / 1000) + 's</span>' +
|
|
748
|
+
' <button onclick="ccNewTab()" style="font-size:var(--text-xs);padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer">Reset</button>';
|
|
749
749
|
el.appendChild(thinking);
|
|
750
750
|
el.scrollTop = el.scrollHeight;
|
|
751
751
|
// Update timer
|
|
@@ -831,7 +831,7 @@ function ccAddMessage(role, html, skipSave, targetTabId, meta) {
|
|
|
831
831
|
div.setAttribute('data-cc-message-id', messageId);
|
|
832
832
|
}
|
|
833
833
|
if (meta && meta.retryId) div.setAttribute('data-cc-retry-id', meta.retryId);
|
|
834
|
-
div.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:
|
|
834
|
+
div.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:var(--text-md);line-height:1.6;max-width:95%;' +
|
|
835
835
|
(isUser ? 'background:var(--blue);color:#fff;align-self:flex-end' : isSystem ? 'align-self:center;max-width:100%' : isAction ? 'align-self:flex-start;padding:2px 0' : 'background:var(--surface2);color:var(--text);align-self:flex-start;border:1px solid var(--border);position:relative');
|
|
836
836
|
// eslint-disable-next-line no-unsanitized/property -- reason: renderMd()/escHtml() call sites escape user-controlled message HTML before ccAddMessage() assigns it (see dashboard/js/utils.js)
|
|
837
837
|
div.innerHTML = (isAssistant && !html.includes('color:var(--red)') && !html.includes('cc-queued-pill') ? llmCopyBtn() : '') + html;
|
|
@@ -908,9 +908,9 @@ function _renderQueueIndicator() {
|
|
|
908
908
|
queue.forEach(function(m) {
|
|
909
909
|
var el = document.createElement('div');
|
|
910
910
|
el.className = 'cc-queue-item';
|
|
911
|
-
el.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:
|
|
911
|
+
el.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:var(--text-md);line-height:1.6;max-width:95%;align-self:flex-end;background:var(--blue);color:#fff;opacity:0.5;order:9999';
|
|
912
912
|
// eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; queued message text wrapped in escHtml() (fields: m.message)
|
|
913
|
-
el.innerHTML = escHtml(typeof m === 'string' ? m : m.message) + '<div style="font-size:
|
|
913
|
+
el.innerHTML = escHtml(typeof m === 'string' ? m : m.message) + '<div style="font-size:var(--text-xs);opacity:0.7;font-style:italic;margin-top:2px">queued</div>';
|
|
914
914
|
msgs.appendChild(el);
|
|
915
915
|
});
|
|
916
916
|
if (msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight < 150) msgs.scrollTop = msgs.scrollHeight;
|
|
@@ -983,7 +983,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
983
983
|
var tabSessionId = activeTab ? activeTab.sessionId : null;
|
|
984
984
|
|
|
985
985
|
// Show thinking immediately — before fetch starts
|
|
986
|
-
addMsg('assistant', '<span style="color:var(--muted);font-size:
|
|
986
|
+
addMsg('assistant', '<span style="color:var(--muted);font-size:var(--text-base)">Thinking...</span>', true);
|
|
987
987
|
var msgs = document.getElementById('cc-messages');
|
|
988
988
|
var streamDiv = msgs.lastElementChild;
|
|
989
989
|
if (streamDiv) streamDiv.setAttribute('data-stream-tab', activeTabId);
|
|
@@ -1004,8 +1004,8 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1004
1004
|
if (elapsed >= phases[pi][0]) { label = phases[pi][1]; break; }
|
|
1005
1005
|
}
|
|
1006
1006
|
var secs = Math.floor(elapsed / 1000);
|
|
1007
|
-
return '<div style="display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:
|
|
1008
|
-
'<button onclick="ccAbort()" style="font-size:
|
|
1007
|
+
return '<div style="display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:var(--text-base)">' + label + '</span>' + dotPulse + '<span style="margin-left:auto;font-size:var(--text-sm);color:var(--muted)">' + secs + 's</span>' +
|
|
1008
|
+
'<button onclick="ccAbort()" style="font-size:var(--text-xs);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>';
|
|
1009
1009
|
}
|
|
1010
1010
|
function updateStreamDiv() {
|
|
1011
1011
|
// Skip DOM updates if user switched to a different tab (restore interval handles that tab)
|
|
@@ -1023,7 +1023,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1023
1023
|
html += renderMd(streamedText);
|
|
1024
1024
|
}
|
|
1025
1025
|
if (streamStatusNote) {
|
|
1026
|
-
html += '<div style="margin-top:6px;font-size:
|
|
1026
|
+
html += '<div style="margin-top:6px;font-size:var(--text-sm);color:var(--muted)">' + escHtml(streamStatusNote) + '</div>';
|
|
1027
1027
|
}
|
|
1028
1028
|
html += '<div style="margin-top:' + (streamedText ? '6px' : '0') + '">' + _getThinkingHtml() + '</div>';
|
|
1029
1029
|
// eslint-disable-next-line no-unsanitized/property -- reason: renderMd() and renderToolChip() escape streamed text/tool fields before assembling live stream HTML
|
|
@@ -1034,15 +1034,15 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1034
1034
|
}
|
|
1035
1035
|
function _ccElapsedFooter(label) {
|
|
1036
1036
|
var seconds = Math.round((Date.now() - ccStartTime) / 1000);
|
|
1037
|
-
return '<div style="font-size:
|
|
1037
|
+
return '<div style="font-size:var(--text-xs);color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">' + label.replace('{seconds}', seconds) + '</div>';
|
|
1038
1038
|
}
|
|
1039
1039
|
function _ccRetryControls(retryRequest, extraHtml, showReload) {
|
|
1040
1040
|
var retryTabId = retryRequest && retryRequest.tabId ? retryRequest.tabId : activeTabId;
|
|
1041
1041
|
var retryId = retryRequest && retryRequest.id ? retryRequest.id : '';
|
|
1042
1042
|
return (extraHtml || '') +
|
|
1043
|
-
'<button onclick="ccRetryLast(' + _ccJsArg(retryTabId) + ',' + _ccJsArg(retryId) + ')" 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:
|
|
1044
|
-
(showReload ? ' <button onclick="ccRestartMinions(this)" style="margin-top:6px;padding:4px 12px;background:var(--orange);color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:
|
|
1045
|
-
' <button onclick="ccNewTab()" style="margin-top:6px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--muted);cursor:pointer;font-size:
|
|
1043
|
+
'<button onclick="ccRetryLast(' + _ccJsArg(retryTabId) + ',' + _ccJsArg(retryId) + ')" 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:var(--text-base)">Retry</button>' +
|
|
1044
|
+
(showReload ? ' <button onclick="ccRestartMinions(this)" style="margin-top:6px;padding:4px 12px;background:var(--orange);color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:var(--text-base)">Restart Minions</button>' : '') +
|
|
1045
|
+
' <button onclick="ccNewTab()" style="margin-top:6px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--muted);cursor:pointer;font-size:var(--text-base)">New Session</button>';
|
|
1046
1046
|
}
|
|
1047
1047
|
// Start phase timer immediately so thinking text updates while waiting for SSE
|
|
1048
1048
|
var phaseTimer = setInterval(updateStreamDiv, 1000);
|
|
@@ -1125,7 +1125,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1125
1125
|
} else {
|
|
1126
1126
|
resetText = 'Minions was updated — started a fresh session with latest context.';
|
|
1127
1127
|
}
|
|
1128
|
-
addMsg('system', '<div style="text-align:center;padding:6px 12px;font-size:
|
|
1128
|
+
addMsg('system', '<div style="text-align:center;padding:6px 12px;font-size:var(--text-base);color:var(--muted);background:var(--surface2);border-radius:6px;margin:4px 0">' + resetText + '</div>', false, activeTabId);
|
|
1129
1129
|
}
|
|
1130
1130
|
var finalText = _ccMergeStreamText(streamedText, evt.text || '');
|
|
1131
1131
|
if (evt.actions && evt.actions.length > 0) _tagServerExecuted(evt.actions, evt.actionResults);
|
|
@@ -1159,7 +1159,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1159
1159
|
// Issue #1834: server saw ===ACTIONS=== but couldn't parse the JSON.
|
|
1160
1160
|
// Surface as an inline warning so the user knows actions were dropped
|
|
1161
1161
|
// (was previously silent — appeared as "actions failed" with no signal).
|
|
1162
|
-
addMsg('system', '<div style="padding:6px 12px;font-size:
|
|
1162
|
+
addMsg('system', '<div style="padding:6px 12px;font-size:var(--text-base);color:var(--red);background:var(--surface2);border-radius:6px;margin:4px 0">⚠️ Actions block emitted but JSON could not be parsed — no actions were executed. Resend or rephrase. (' + escHtml(String(evt.actionParseError).slice(0, 200)) + ')</div>', false, activeTabId);
|
|
1163
1163
|
}
|
|
1164
1164
|
} else if (evt.type === 'error') {
|
|
1165
1165
|
terminalEventSeen = true;
|
|
@@ -1174,12 +1174,12 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1174
1174
|
var ccErrCode = typeof evt.code === 'string' ? evt.code : '';
|
|
1175
1175
|
var ccRetry = _ccStoreRetryRequest(activeTab, activeTabId, message);
|
|
1176
1176
|
var codeChip = ccErrCode
|
|
1177
|
-
? '<span style="display:inline-block;margin-left:6px;padding:1px 6px;font-size:
|
|
1177
|
+
? '<span style="display:inline-block;margin-left:6px;padding:1px 6px;font-size:var(--text-xs);color:var(--muted);background:var(--surface2);border:1px solid var(--border);border-radius:3px;font-family:monospace">' + escHtml(ccErrCode) + '</span>'
|
|
1178
1178
|
: '';
|
|
1179
1179
|
var availList = Array.isArray(evt.availableModels) && evt.availableModels.length
|
|
1180
|
-
? '<div style="font-size:
|
|
1180
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:6px">Available models: ' + escHtml(evt.availableModels.slice(0, 8).join(', ')) + (evt.availableModels.length > 8 ? '…' : '') + '</div>'
|
|
1181
1181
|
: '';
|
|
1182
|
-
var errorBubble = '<div class="cc-error" role="alert" aria-live="assertive" style="padding:8px 12px;background:rgba(220,80,80,0.08);border-left:3px solid var(--red);border-radius:4px;color:var(--red);font-size:
|
|
1182
|
+
var errorBubble = '<div class="cc-error" role="alert" aria-live="assertive" style="padding:8px 12px;background:rgba(220,80,80,0.08);border-left:3px solid var(--red);border-radius:4px;color:var(--red);font-size:var(--text-md)"><strong>Error</strong>' + codeChip + '<div style="margin-top:4px;color:var(--text)">' + escHtml(ccErrMsg) + '</div>' + availList + '</div>';
|
|
1183
1183
|
addMsg('assistant', errorBubble + _ccRetryControls(ccRetry, '', false), false, { retryId: ccRetry.id });
|
|
1184
1184
|
}
|
|
1185
1185
|
}
|
|
@@ -1261,7 +1261,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1261
1261
|
if (!consume.interrupted) break;
|
|
1262
1262
|
if (!consume.reconnectable || reconnectAttempts >= 2) {
|
|
1263
1263
|
_cleanupStreamDiv();
|
|
1264
|
-
var streamEndedHint = '<div style="font-size:
|
|
1264
|
+
var streamEndedHint = '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">The response stream ended before completion. Retry to resend the interrupted message.</div>';
|
|
1265
1265
|
var streamEndedRetry = _ccStoreRetryRequest(activeTab, activeTabId, message);
|
|
1266
1266
|
if (streamedText) {
|
|
1267
1267
|
addMsg('assistant', renderMd(streamedText) + _ccElapsedFooter('Stream interrupted after {seconds}s') + _ccRetryControls(streamEndedRetry, streamEndedHint, false), false, { retryId: streamEndedRetry.id });
|
|
@@ -1274,8 +1274,8 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1274
1274
|
if (!reconnectHealth.reachable || reconnectHealth.restarted) {
|
|
1275
1275
|
_cleanupStreamDiv();
|
|
1276
1276
|
var reconnectHint = reconnectHealth.restarted
|
|
1277
|
-
? '<div style="font-size:
|
|
1278
|
-
: '<div style="font-size:
|
|
1277
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">Dashboard restarted while this response was streaming. Restart Minions to reconnect to the new instance.</div>'
|
|
1278
|
+
: '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">The request stream was interrupted, but the dashboard is still reachable. Retry or start a new session.</div>';
|
|
1279
1279
|
var reconnectRetry = _ccStoreRetryRequest(activeTab, activeTabId, message);
|
|
1280
1280
|
addMsg('assistant', (streamedText ? renderMd(streamedText) + _ccElapsedFooter('Stream interrupted after {seconds}s') : '') +
|
|
1281
1281
|
_ccRetryControls(reconnectRetry, reconnectHint, reconnectHealth.restarted), false, { retryId: reconnectRetry.id });
|
|
@@ -1296,7 +1296,7 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1296
1296
|
if (streamedText) {
|
|
1297
1297
|
addMsg('assistant', renderMd(streamedText) + _ccElapsedFooter('Stopped after {seconds}s'));
|
|
1298
1298
|
} else {
|
|
1299
|
-
addMsg('assistant', '<span style="color:var(--red);font-size:
|
|
1299
|
+
addMsg('assistant', '<span style="color:var(--red);font-size:var(--text-base)">Stopped</span>');
|
|
1300
1300
|
}
|
|
1301
1301
|
} else {
|
|
1302
1302
|
var isNetworkError = _ccIsReconnectableStreamError(e);
|
|
@@ -1304,10 +1304,10 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1304
1304
|
var connectionHint = '';
|
|
1305
1305
|
if (isNetworkError) {
|
|
1306
1306
|
connectionHint = dashboardHealth.restarted
|
|
1307
|
-
? '<div style="font-size:
|
|
1307
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">Dashboard restarted while this response was streaming. Restart Minions to reconnect to the new instance.</div>'
|
|
1308
1308
|
: dashboardHealth.reachable
|
|
1309
|
-
? '<div style="font-size:
|
|
1310
|
-
: '<div style="font-size:
|
|
1309
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">The request stream was interrupted, but the dashboard is still reachable. Retry or start a new session.</div>'
|
|
1310
|
+
: '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">Dashboard connection lost. Restart Minions to reconnect.</div>';
|
|
1311
1311
|
}
|
|
1312
1312
|
var errorRetry = _ccStoreRetryRequest(activeTab, activeTabId, message);
|
|
1313
1313
|
// W-mpmwxni2000c25c7-d — if the thrower attached a parsed CC error
|
|
@@ -1319,12 +1319,12 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
|
|
|
1319
1319
|
var errorRendered;
|
|
1320
1320
|
if (ccEnv) {
|
|
1321
1321
|
var ccCodeChip = ccEnv.code
|
|
1322
|
-
? '<span style="display:inline-block;margin-left:6px;padding:1px 6px;font-size:
|
|
1322
|
+
? '<span style="display:inline-block;margin-left:6px;padding:1px 6px;font-size:var(--text-xs);color:var(--muted);background:var(--surface2);border:1px solid var(--border);border-radius:3px;font-family:monospace">' + escHtml(ccEnv.code) + '</span>'
|
|
1323
1323
|
: '';
|
|
1324
1324
|
var ccAvail = Array.isArray(ccEnv.availableModels) && ccEnv.availableModels.length
|
|
1325
|
-
? '<div style="font-size:
|
|
1325
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:6px">Available models: ' + escHtml(ccEnv.availableModels.slice(0, 8).join(', ')) + (ccEnv.availableModels.length > 8 ? '…' : '') + '</div>'
|
|
1326
1326
|
: '';
|
|
1327
|
-
errorRendered = '<div class="cc-error" role="alert" aria-live="assertive" style="padding:8px 12px;background:rgba(220,80,80,0.08);border-left:3px solid var(--red);border-radius:4px;color:var(--red);font-size:
|
|
1327
|
+
errorRendered = '<div class="cc-error" role="alert" aria-live="assertive" style="padding:8px 12px;background:rgba(220,80,80,0.08);border-left:3px solid var(--red);border-radius:4px;color:var(--red);font-size:var(--text-md)"><strong>Error</strong>' + ccCodeChip + '<div style="margin-top:4px;color:var(--text)">' + escHtml(ccEnv.message) + '</div>' + ccAvail + '</div>';
|
|
1328
1328
|
} else {
|
|
1329
1329
|
errorRendered = '<span style="color:var(--red)">Error: ' + escHtml(e.message) + '</span>';
|
|
1330
1330
|
}
|
|
@@ -1421,7 +1421,7 @@ function _ccActionResultType(action, result) {
|
|
|
1421
1421
|
return String((result && result.type) || (action && action.type) || 'action').trim() || 'action';
|
|
1422
1422
|
}
|
|
1423
1423
|
|
|
1424
|
-
var CC_ACTION_CHIP_STYLE = 'display:block;width:fit-content;max-width:100%;padding:4px 10px;margin:4px 0 0 0;border-radius:4px;font-size:
|
|
1424
|
+
var CC_ACTION_CHIP_STYLE = 'display:block;width:fit-content;max-width:100%;padding:4px 10px;margin:4px 0 0 0;border-radius:4px;font-size:var(--text-sm);border:1px dashed var(--border);background:var(--surface)';
|
|
1425
1425
|
|
|
1426
1426
|
function _ccActionResultLine(action, result) {
|
|
1427
1427
|
var type = _ccActionResultType(action, result);
|
|
@@ -1486,7 +1486,7 @@ function _tagServerExecuted(actions, actionResults) {
|
|
|
1486
1486
|
async function ccExecuteAction(action, targetTabId, opts) {
|
|
1487
1487
|
action = _ccNormalizeDispatchAction(action);
|
|
1488
1488
|
var status = document.createElement('div');
|
|
1489
|
-
status.style.cssText = 'padding:4px 10px;border-radius:4px;font-size:
|
|
1489
|
+
status.style.cssText = 'padding:4px 10px;border-radius:4px;font-size:var(--text-sm);align-self:flex-start;border:1px dashed var(--border);color:var(--muted)';
|
|
1490
1490
|
|
|
1491
1491
|
// Server-executed actions: just show status, don't re-fire the API
|
|
1492
1492
|
if (action._serverExecuted) {
|
|
@@ -1501,8 +1501,8 @@ async function ccExecuteAction(action, targetTabId, opts) {
|
|
|
1501
1501
|
var successLabel = serverActionType === 'dispatch' ? 'Dispatched' : serverActionType;
|
|
1502
1502
|
// eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; label and warning wrapped in escHtml(), success label is a normalized server action type (fields: label, action._serverWarning)
|
|
1503
1503
|
status.innerHTML = '✓ ' + escHtml(successLabel) + ': <strong>' + label + '</strong>' +
|
|
1504
|
-
(action._serverDuplicate ? '<div style="font-size:
|
|
1505
|
-
(action._serverWarning ? '<div style="font-size:
|
|
1504
|
+
(action._serverDuplicate ? '<div style="font-size:var(--text-sm);color:var(--orange);margin-top:2px">Already existed from a previous request; no duplicate work item was created.</div>' : '') +
|
|
1505
|
+
(action._serverWarning ? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:2px">' + escHtml(action._serverWarning) + '</div>' : '');
|
|
1506
1506
|
status.style.color = 'var(--green)';
|
|
1507
1507
|
}
|
|
1508
1508
|
if (opts && opts.originMessageId && _ccAppendHtmlToMessage(targetTabId || _ccActiveTabId, opts.originMessageId, status.outerHTML)) {
|
|
@@ -1832,7 +1832,7 @@ async function ccExecuteAction(action, targetTabId, opts) {
|
|
|
1832
1832
|
var prLinkData = await prLinkRes.json().catch(function() { return {}; });
|
|
1833
1833
|
// eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; PR URL and server message wrapped in escHtml() (fields: action.url, prLinkData.message)
|
|
1834
1834
|
status.innerHTML = '✓ PR linked: <strong>' + escHtml(action.url) + '</strong>' +
|
|
1835
|
-
(prLinkData.message ? '<div style="font-size:
|
|
1835
|
+
(prLinkData.message ? '<div style="font-size:var(--text-base);color:var(--muted);margin-top:4px">' + escHtml(prLinkData.message) + '</div>' : '');
|
|
1836
1836
|
status.style.color = 'var(--green)';
|
|
1837
1837
|
break;
|
|
1838
1838
|
}
|
|
@@ -98,17 +98,17 @@ function renderDetailContent(detail, tab) {
|
|
|
98
98
|
el.innerHTML =
|
|
99
99
|
'<div id="live-chat" style="display:flex;flex-direction:column;height:60vh">' +
|
|
100
100
|
'<div id="live-terminal-banner"></div>' +
|
|
101
|
-
'<div id="live-messages" style="flex:1;overflow-y:auto;padding:8px;font-size:
|
|
101
|
+
'<div id="live-messages" style="flex:1;overflow-y:auto;padding:8px;font-size:var(--text-base);line-height:1.6;display:flex;flex-direction:column"></div>' +
|
|
102
102
|
'<div id="live-status-bar" style="padding:4px 8px;display:flex;align-items:center;gap:8px;border-top:1px solid var(--border)">' +
|
|
103
|
-
'<span class="pulse"></span><span id="live-status-label" style="font-size:
|
|
104
|
-
'<span id="live-runtime" style="font-size:
|
|
105
|
-
'<button class="pr-pager-btn" onclick="refreshLiveOutput()" style="font-size:
|
|
103
|
+
'<span class="pulse"></span><span id="live-status-label" style="font-size:var(--text-base);color:var(--green)">Streaming live</span>' +
|
|
104
|
+
'<span id="live-runtime" style="font-size:var(--text-sm);color:var(--muted)" data-started="' + (startedAt || '') + '"></span>' +
|
|
105
|
+
'<button class="pr-pager-btn" onclick="refreshLiveOutput()" style="font-size:var(--text-sm)">Refresh</button>' +
|
|
106
106
|
'</div>' +
|
|
107
107
|
'<div id="live-steer-bar" style="display:flex;gap:8px;padding:8px;border-top:1px solid var(--border)">' +
|
|
108
108
|
'<input id="live-steer-input" type="text" placeholder="Message this agent — ask for status, give context, or redirect..." ' +
|
|
109
|
-
'style="flex:1;padding:6px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:
|
|
109
|
+
'style="flex:1;padding:6px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:var(--text-md);font-family:inherit" ' +
|
|
110
110
|
'onkeydown="if(event.key===\'Enter\')sendSteering()" />' +
|
|
111
|
-
'<button onclick="sendSteering()" style="padding:6px 12px;background:var(--blue);color:#fff;border:none;border-radius:var(--radius-sm);cursor:pointer;font-size:
|
|
111
|
+
'<button onclick="sendSteering()" style="padding:6px 12px;background:var(--blue);color:#fff;border:none;border-radius:var(--radius-sm);cursor:pointer;font-size:var(--text-base)">Send</button>' +
|
|
112
112
|
'</div>' +
|
|
113
113
|
'</div>';
|
|
114
114
|
startLiveStream(currentAgentId);
|
|
@@ -117,12 +117,12 @@ function renderDetailContent(detail, tab) {
|
|
|
117
117
|
// eslint-disable-next-line no-unsanitized/property -- reason: renderMd() escapes charter display content and escHtml() escapes textarea content before assembling HTML (see dashboard/js/utils.js)
|
|
118
118
|
el.innerHTML =
|
|
119
119
|
'<div style="display:flex;gap:6px;margin-bottom:8px">' +
|
|
120
|
-
'<button class="pr-pager-btn" id="charter-edit-btn" style="font-size:
|
|
121
|
-
'<button class="pr-pager-btn" id="charter-save-btn" style="font-size:
|
|
122
|
-
'<button class="pr-pager-btn" id="charter-cancel-btn" style="font-size:
|
|
120
|
+
'<button class="pr-pager-btn" id="charter-edit-btn" style="font-size:var(--text-sm);padding:2px 10px" onclick="_toggleCharterEdit()">Edit</button>' +
|
|
121
|
+
'<button class="pr-pager-btn" id="charter-save-btn" style="font-size:var(--text-sm);padding:2px 10px;color:var(--green);border-color:var(--green);display:none" onclick="_saveCharter()">Save</button>' +
|
|
122
|
+
'<button class="pr-pager-btn" id="charter-cancel-btn" style="font-size:var(--text-sm);padding:2px 10px;display:none" onclick="_cancelCharterEdit()">Cancel</button>' +
|
|
123
123
|
'</div>' +
|
|
124
124
|
'<div id="charter-view" class="section">' + renderMd(charterContent || 'No charter found. Click Edit to create one.') + '</div>' +
|
|
125
|
-
'<textarea id="charter-editor" style="display:none;width:100%;min-height:300px;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-family:Consolas,monospace;font-size:
|
|
125
|
+
'<textarea id="charter-editor" style="display:none;width:100%;min-height:300px;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-family:Consolas,monospace;font-size:var(--text-md);resize:vertical">' + escHtml(charterContent) + '</textarea>';
|
|
126
126
|
_charterRawCache = charterContent;
|
|
127
127
|
} else if (tab === 'history') {
|
|
128
128
|
let html = '';
|
|
@@ -136,8 +136,8 @@ function renderDetailContent(detail, tab) {
|
|
|
136
136
|
html += '<tr>' +
|
|
137
137
|
'<td style="max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escHtml(d.task) + '">' + escHtml(d.task.slice(0, 80)) + '</td>' +
|
|
138
138
|
'<td><span class="dispatch-type ' + d.type + '">' + escHtml(d.type) + '</span></td>' +
|
|
139
|
-
'<td style="color:' + color + '"' + reason + '>' + escHtml(d.result) + (isError && d.reason ? ' <span style="font-size:
|
|
140
|
-
'<td style="font-size:
|
|
139
|
+
'<td style="color:' + color + '"' + reason + '>' + escHtml(d.result) + (isError && d.reason ? ' <span style="font-size:var(--text-sm);color:var(--muted)">(' + escHtml(d.reason.slice(0, 50)) + ')</span>' : '') + '</td>' +
|
|
140
|
+
'<td style="font-size:var(--text-sm);color:var(--muted)">' + (d.completed_at ? formatLocalDateTime(d.completed_at) : '') + '</td>' +
|
|
141
141
|
'</tr>';
|
|
142
142
|
});
|
|
143
143
|
html += '</tbody></table>';
|
package/dashboard/js/fre.js
CHANGED
|
@@ -92,7 +92,7 @@ function renderFre(statusOrProjects) {
|
|
|
92
92
|
'border:1px solid var(--blue)',
|
|
93
93
|
'border-radius:var(--radius-lg)',
|
|
94
94
|
'color:var(--text)',
|
|
95
|
-
'font-size:
|
|
95
|
+
'font-size:var(--text-lg)',
|
|
96
96
|
'box-shadow:var(--shadow-md)',
|
|
97
97
|
].join(';');
|
|
98
98
|
|
|
@@ -116,7 +116,7 @@ function renderFre(statusOrProjects) {
|
|
|
116
116
|
'background:var(--blue)',
|
|
117
117
|
'color:#fff',
|
|
118
118
|
'font-weight:700',
|
|
119
|
-
'font-size:
|
|
119
|
+
'font-size:var(--text-base)',
|
|
120
120
|
'flex-shrink:0',
|
|
121
121
|
].join(';');
|
|
122
122
|
|
|
@@ -127,7 +127,7 @@ function renderFre(statusOrProjects) {
|
|
|
127
127
|
'border:none',
|
|
128
128
|
'border-radius:var(--radius-sm)',
|
|
129
129
|
'cursor:pointer',
|
|
130
|
-
'font-size:
|
|
130
|
+
'font-size:var(--text-md)',
|
|
131
131
|
'font-weight:600',
|
|
132
132
|
'margin-top:8px',
|
|
133
133
|
].join(';');
|
|
@@ -139,7 +139,7 @@ function renderFre(statusOrProjects) {
|
|
|
139
139
|
'border:1px solid var(--blue)',
|
|
140
140
|
'border-radius:var(--radius-sm)',
|
|
141
141
|
'cursor:pointer',
|
|
142
|
-
'font-size:
|
|
142
|
+
'font-size:var(--text-md)',
|
|
143
143
|
'font-weight:600',
|
|
144
144
|
'margin-top:8px',
|
|
145
145
|
].join(';');
|
|
@@ -149,7 +149,7 @@ function renderFre(statusOrProjects) {
|
|
|
149
149
|
'border:none',
|
|
150
150
|
'color:var(--muted)',
|
|
151
151
|
'cursor:pointer',
|
|
152
|
-
'font-size:
|
|
152
|
+
'font-size:var(--text-base)',
|
|
153
153
|
'padding:2px 8px',
|
|
154
154
|
].join(';');
|
|
155
155
|
|
|
@@ -162,17 +162,17 @@ function renderFre(statusOrProjects) {
|
|
|
162
162
|
mount.innerHTML =
|
|
163
163
|
'<div id="fre-card" style="' + cardStyle + '">' +
|
|
164
164
|
'<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px">' +
|
|
165
|
-
'<div style="font-size:
|
|
165
|
+
'<div style="font-size:var(--text-xl);font-weight:700;color:var(--blue)">👋 Welcome to Minions</div>' +
|
|
166
166
|
'<button onclick="dismissFre()" style="' + dismissBtn + '" title="Hide this banner — clear localStorage.minions_fre_dismissed to re-show">Dismiss</button>' +
|
|
167
167
|
'</div>' +
|
|
168
|
-
'<div style="color:var(--muted);font-size:
|
|
168
|
+
'<div style="color:var(--muted);font-size:var(--text-md);margin-bottom:12px">Two quick steps to get your fleet ready.</div>' +
|
|
169
169
|
'<div style="display:flex;flex-direction:column;gap:10px">' +
|
|
170
170
|
|
|
171
171
|
'<div style="' + stepBox + '">' +
|
|
172
172
|
'<span style="' + stepNum + '">1</span>' +
|
|
173
173
|
'<div style="flex:1">' +
|
|
174
174
|
'<div style="font-weight:600;margin-bottom:2px">Pick your runtime CLI</div>' +
|
|
175
|
-
'<div style="color:var(--muted);font-size:
|
|
175
|
+
'<div style="color:var(--muted);font-size:var(--text-md);line-height:1.5">' +
|
|
176
176
|
'Minions spawns agents through this CLI. Switch via Settings → Engine → Default CLI (<code>claude</code> or <code>copilot</code>). ' +
|
|
177
177
|
'Currently: <code style="background:var(--bg);padding:1px 6px;border-radius:3px;color:var(--text)">' + safeRuntime + '</code>' +
|
|
178
178
|
'</div>' +
|
|
@@ -184,7 +184,7 @@ function renderFre(statusOrProjects) {
|
|
|
184
184
|
'<span style="' + stepNum + '">2</span>' +
|
|
185
185
|
'<div style="flex:1">' +
|
|
186
186
|
'<div style="font-weight:600;margin-bottom:2px">Add your first project</div>' +
|
|
187
|
-
'<div style="color:var(--muted);font-size:
|
|
187
|
+
'<div style="color:var(--muted);font-size:var(--text-md);line-height:1.5">' +
|
|
188
188
|
'Projects map a local git worktree to a remote repo. Without a project, agents have nowhere to run.' +
|
|
189
189
|
'</div>' +
|
|
190
190
|
'<button onclick="addProject()" style="' + btnPrimary + '">+ Add Project</button>' +
|
|
@@ -160,8 +160,8 @@ async function sendSteering() {
|
|
|
160
160
|
const el = document.getElementById('live-messages');
|
|
161
161
|
if (el) {
|
|
162
162
|
// eslint-disable-next-line no-unsanitized/method -- reason: structural HTML is a string literal; all user data wrapped in escHtml() (fields: steering message)
|
|
163
|
-
el.insertAdjacentHTML('beforeend', '<div style="align-self:flex-end;background:var(--blue);color:#fff;padding:6px 12px;border-radius:12px 12px 2px 12px;max-width:80%;margin:4px 0;font-size:
|
|
164
|
-
'<div id="steer-pending" style="font-size:
|
|
163
|
+
el.insertAdjacentHTML('beforeend', '<div style="align-self:flex-end;background:var(--blue);color:#fff;padding:6px 12px;border-radius:12px 12px 2px 12px;max-width:80%;margin:4px 0;font-size:var(--text-md)">' + escHtml(message) +
|
|
164
|
+
'<div id="steer-pending" style="font-size:var(--text-xs);opacity:0.7;margin-top:2px">\u2197 Sending...</div></div>');
|
|
165
165
|
el.scrollTop = el.scrollHeight;
|
|
166
166
|
}
|
|
167
167
|
showToast('cmd-toast', 'Steering message sent to ' + currentAgentId, true);
|
package/dashboard/js/modal-qa.js
CHANGED
|
@@ -297,16 +297,16 @@ function _qaBuildUserMessageHtml(message, selection) {
|
|
|
297
297
|
|
|
298
298
|
function _qaBuildQueuedHtml(message) {
|
|
299
299
|
const preview = escHtml(message.length > 60 ? message.slice(0, 57) + '...' : message);
|
|
300
|
-
return '<div class="qa-queued-item" style="color:var(--muted);font-size:
|
|
300
|
+
return '<div class="qa-queued-item" style="color:var(--muted);font-size:var(--text-sm);padding:4px 8px">Queued: "' + preview + '"</div>';
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
function _qaBuildLoadingHtml(loadingId, queueCount) {
|
|
304
|
-
const qaQueueBadge = queueCount > 0 ? ' <span style="font-size:
|
|
304
|
+
const qaQueueBadge = queueCount > 0 ? ' <span style="font-size:var(--text-xs);color:var(--muted);background:var(--surface);padding:1px 5px;border-radius:8px;border:1px solid var(--border)">+' + queueCount + ' queued</span>' : '';
|
|
305
305
|
return '<div class="modal-qa-loading" id="' + loadingId + '">' +
|
|
306
306
|
'<div class="dot-pulse"><span></span><span></span><span></span></div> ' +
|
|
307
307
|
'<span id="' + loadingId + '-text">Thinking...</span> ' +
|
|
308
|
-
'<span id="' + loadingId + '-time" style="font-size:
|
|
309
|
-
' <button onclick="qaAbort()" style="font-size:
|
|
308
|
+
'<span id="' + loadingId + '-time" style="font-size:var(--text-sm);color:var(--muted)"></span>' +
|
|
309
|
+
' <button onclick="qaAbort()" style="font-size:var(--text-xs);padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer">Stop</button>' +
|
|
310
310
|
qaQueueBadge + '</div>';
|
|
311
311
|
}
|
|
312
312
|
|
|
@@ -320,17 +320,17 @@ function _qaBuildRawErrorHtml(err) {
|
|
|
320
320
|
if (err.errorClass) meta.push('class: ' + escHtml(String(err.errorClass)));
|
|
321
321
|
if (err.code !== null && err.code !== undefined) meta.push('exit: ' + escHtml(String(err.code)));
|
|
322
322
|
const metaLine = meta.length
|
|
323
|
-
? '<div style="font-size:
|
|
323
|
+
? '<div style="font-size:var(--text-sm);color:var(--muted);margin-bottom:4px">' + meta.join(' · ') + '</div>'
|
|
324
324
|
: '';
|
|
325
325
|
const adapterMessage = err.errorMessage
|
|
326
|
-
? '<div style="font-size:
|
|
326
|
+
? '<div style="font-size:var(--text-base);color:var(--text);margin-bottom:6px;white-space:pre-wrap">' + escHtml(String(err.errorMessage)) + '</div>'
|
|
327
327
|
: '';
|
|
328
328
|
const stderrText = err.stderr ? String(err.stderr) : '';
|
|
329
329
|
const stderrBlock = stderrText
|
|
330
|
-
? '<pre style="margin:0;padding:6px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;font-size:
|
|
331
|
-
: '<div style="font-size:
|
|
330
|
+
? '<pre style="margin:0;padding:6px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;font-size:var(--text-base);white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto">' + escHtml(stderrText) + '</pre>'
|
|
331
|
+
: '<div style="font-size:var(--text-base);color:var(--muted)">(no stderr captured)</div>';
|
|
332
332
|
return '<details class="modal-qa-raw-error" style="margin:6px 0 12px;padding:6px 8px;border:1px solid var(--red);border-radius:4px;background:var(--surface)">' +
|
|
333
|
-
'<summary style="cursor:pointer;font-size:
|
|
333
|
+
'<summary style="cursor:pointer;font-size:var(--text-base);color:var(--red)">Raw error output</summary>' +
|
|
334
334
|
'<div style="margin-top:6px">' + metaLine + adapterMessage + stderrBlock + '</div>' +
|
|
335
335
|
'</details>';
|
|
336
336
|
}
|
|
@@ -344,7 +344,7 @@ function _qaBuildAssistantHtml(text, opts) {
|
|
|
344
344
|
return '<div class="modal-qa-a" style="' + style + '">' +
|
|
345
345
|
(opts?.isError ? '' : llmCopyBtn()) +
|
|
346
346
|
body +
|
|
347
|
-
'<div style="font-size:
|
|
347
|
+
'<div style="font-size:var(--text-xs);color:var(--muted);margin-top:4px;text-align:right;' + pad + '">' + opts.elapsed + 's</div>' +
|
|
348
348
|
'</div>';
|
|
349
349
|
}
|
|
350
350
|
|
|
@@ -366,20 +366,20 @@ function _qaBuildActionFeedbackHtml(actionFeedback) {
|
|
|
366
366
|
if (!Array.isArray(actionFeedback) || actionFeedback.length === 0) return '';
|
|
367
367
|
return actionFeedback.map(function(item) {
|
|
368
368
|
const type = escHtml(item.type || 'dispatch');
|
|
369
|
-
const baseStyle = 'padding:4px 10px;border-radius:4px;font-size:
|
|
369
|
+
const baseStyle = 'padding:4px 10px;border-radius:4px;font-size:var(--text-sm);align-self:flex-start;border:1px dashed var(--border);margin:4px 0;';
|
|
370
370
|
if (item.error) {
|
|
371
371
|
return '<div class="modal-qa-action-feedback" style="' + baseStyle + 'color:var(--red)">✗ ' + type + ' failed: ' + escHtml(item.error) + '</div>';
|
|
372
372
|
}
|
|
373
373
|
const label = escHtml(item.id || item.duplicateOf || '');
|
|
374
374
|
const verb = item.type === 'dispatch' ? 'Dispatched' : type;
|
|
375
|
-
const duplicate = item.duplicate ? '<div style="font-size:
|
|
376
|
-
const warning = item.warning ? '<div style="font-size:
|
|
375
|
+
const duplicate = item.duplicate ? '<div style="font-size:var(--text-sm);color:var(--orange);margin-top:2px">Already existed from a previous request; no duplicate work item was created.</div>' : '';
|
|
376
|
+
const warning = item.warning ? '<div style="font-size:var(--text-sm);color:var(--muted);margin-top:2px">' + escHtml(item.warning) + '</div>' : '';
|
|
377
377
|
return '<div class="modal-qa-action-feedback" style="' + baseStyle + 'color:var(--green)">✓ ' + verb + ': <strong>' + label + '</strong>' + duplicate + warning + '</div>';
|
|
378
378
|
}).join('');
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
function _qaBuildLiveProgressHtml(loadingId, label, elapsedSeconds, streamedText, toolsUsed, queueCount) {
|
|
382
|
-
const qaQueueBadge = queueCount > 0 ? ' <span style="font-size:
|
|
382
|
+
const qaQueueBadge = queueCount > 0 ? ' <span style="font-size:var(--text-xs);color:var(--muted);background:var(--surface);padding:1px 5px;border-radius:8px;border:1px solid var(--border)">+' + queueCount + ' queued</span>' : '';
|
|
383
383
|
// Wrap in a column-flex container so chain-of-thought (tool calls) stack
|
|
384
384
|
// vertically on top and the progress block sits at the bottom. Overrides the
|
|
385
385
|
// parent .modal-qa-loading row-flex (which is right for the simple
|
|
@@ -390,7 +390,7 @@ function _qaBuildLiveProgressHtml(loadingId, label, elapsedSeconds, streamedText
|
|
|
390
390
|
toolsUsed.forEach(function(t) {
|
|
391
391
|
const name = typeof t === 'string' ? t : t.name;
|
|
392
392
|
const input = typeof t === 'string' ? {} : (t.input || {});
|
|
393
|
-
html += '<div style="color:var(--muted);font-size:
|
|
393
|
+
html += '<div style="color:var(--muted);font-size:var(--text-sm);font-family:monospace;display:flex;align-items:flex-start;gap:6px"><span style="flex-shrink:0">●</span><span style="word-break:break-all">' + formatToolSummary(name, input) + '</span></div>';
|
|
394
394
|
});
|
|
395
395
|
html += '</div>';
|
|
396
396
|
}
|
|
@@ -398,8 +398,8 @@ function _qaBuildLiveProgressHtml(loadingId, label, elapsedSeconds, streamedText
|
|
|
398
398
|
html += '<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">' +
|
|
399
399
|
'<span class="dot-pulse"><span></span><span></span><span></span></span>' +
|
|
400
400
|
'<span id="' + loadingId + '-text">' + escHtml(label) + '</span>' +
|
|
401
|
-
'<span id="' + loadingId + '-time" style="font-size:
|
|
402
|
-
'<button onclick="qaAbort()" style="font-size:
|
|
401
|
+
'<span id="' + loadingId + '-time" style="font-size:var(--text-sm);color:var(--muted)">' + elapsedSeconds + 's</span>' +
|
|
402
|
+
'<button onclick="qaAbort()" style="font-size:var(--text-xs);padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer">Stop</button>' +
|
|
403
403
|
qaQueueBadge +
|
|
404
404
|
'</div>';
|
|
405
405
|
html += '</div>';
|
package/dashboard/js/qa.js
CHANGED
|
@@ -1133,17 +1133,17 @@ function _qaInstallModalStyle() {
|
|
|
1133
1133
|
' padding: 12px 16px; border-bottom: 1px solid var(--border, #ddd);',
|
|
1134
1134
|
'}',
|
|
1135
1135
|
'.qa-modal-title { font-weight: 600; }',
|
|
1136
|
-
'.qa-modal-close { font-size:
|
|
1136
|
+
'.qa-modal-close { font-size:var(--text-stat); padding: 0 8px; }',
|
|
1137
1137
|
'.qa-modal-meta {',
|
|
1138
1138
|
' display: flex; gap: 12px; flex-wrap: wrap;',
|
|
1139
1139
|
' padding: 8px 16px; border-bottom: 1px solid var(--border, #ddd);',
|
|
1140
|
-
' font-size:
|
|
1140
|
+
' font-size:var(--text-md); color: var(--muted, #666);',
|
|
1141
1141
|
'}',
|
|
1142
1142
|
'.qa-modal-meta-item { white-space: nowrap; }',
|
|
1143
1143
|
'.qa-modal-body { flex: 1; overflow: auto; padding: 12px 16px; }',
|
|
1144
1144
|
'.qa-modal-code {',
|
|
1145
1145
|
' font-family: ui-monospace, Menlo, Consolas, monospace;',
|
|
1146
|
-
' font-size:
|
|
1146
|
+
' font-size:var(--text-md); line-height: 1.5;',
|
|
1147
1147
|
' background: var(--surface2, #f6f6f6);',
|
|
1148
1148
|
' border: 1px solid var(--border, #ddd);',
|
|
1149
1149
|
' border-radius: 4px; padding: 12px;',
|
package/dashboard/js/refresh.js
CHANGED
|
@@ -414,7 +414,7 @@ function _processStatusUpdate(data, opts) {
|
|
|
414
414
|
const autoEl = document.getElementById('auto-approve-badge');
|
|
415
415
|
// eslint-disable-next-line no-unsanitized/property -- reason: composed from compile-time constants (no user data flows in)
|
|
416
416
|
if (autoEl) autoEl.innerHTML = data.autoMode?.approvePlans
|
|
417
|
-
? '<span style="font-size:
|
|
417
|
+
? '<span style="font-size:var(--text-xs);font-weight:600;padding:1px 6px;border-radius:3px;background:rgba(63,185,80,0.15);color:var(--green);border:1px solid rgba(63,185,80,0.3)">AUTO-APPROVE</span>'
|
|
418
418
|
: '';
|
|
419
419
|
const ccLabelEl = document.getElementById('cmd-powered-by');
|
|
420
420
|
if (ccLabelEl) ccLabelEl.textContent = _formatCcPowerLabel(data.autoMode);
|
|
@@ -1338,7 +1338,7 @@ window.MinionsRefresh = { refresh };
|
|
|
1338
1338
|
chip.title = 'Open dashboard refresh diagnostics';
|
|
1339
1339
|
// Bottom-LEFT (not right) to avoid overlapping the Command Center Send
|
|
1340
1340
|
// button when the CC drawer is open (the drawer covers the right edge).
|
|
1341
|
-
chip.style.cssText = 'position:fixed;left:12px;bottom:12px;z-index:9999;background:var(--surface,#222);color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:10px;padding:3px 8px;font-size:
|
|
1341
|
+
chip.style.cssText = 'position:fixed;left:12px;bottom:12px;z-index:9999;background:var(--surface,#222);color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:10px;padding:3px 8px;font-size:var(--text-sm);font-family:inherit;cursor:pointer;opacity:0.75';
|
|
1342
1342
|
chip.addEventListener('click', _openRefreshDiagModal);
|
|
1343
1343
|
document.body.appendChild(chip);
|
|
1344
1344
|
} catch { /* DOM may not be ready in unusual test embeds */ }
|
|
@@ -1354,18 +1354,18 @@ function _openRefreshDiagModal() {
|
|
|
1354
1354
|
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:10000;display:flex;align-items:center;justify-content:center;padding:24px';
|
|
1355
1355
|
overlay.addEventListener('click', function(e) { if (e.target === overlay) overlay.remove(); });
|
|
1356
1356
|
const panel = document.createElement('div');
|
|
1357
|
-
panel.style.cssText = 'background:var(--surface,#1c1c1c);color:var(--text,#ddd);border:1px solid var(--border,#444);border-radius:8px;max-width:1200px;max-height:80vh;width:100%;display:flex;flex-direction:column;overflow:hidden;font-family:inherit;font-size:
|
|
1357
|
+
panel.style.cssText = 'background:var(--surface,#1c1c1c);color:var(--text,#ddd);border:1px solid var(--border,#444);border-radius:8px;max-width:1200px;max-height:80vh;width:100%;display:flex;flex-direction:column;overflow:hidden;font-family:inherit;font-size:var(--text-base)';
|
|
1358
1358
|
const head = document.createElement('div');
|
|
1359
1359
|
head.style.cssText = 'padding:10px 14px;border-bottom:1px solid var(--border,#444);display:flex;align-items:center;justify-content:space-between;gap:8px';
|
|
1360
1360
|
const title = document.createElement('div');
|
|
1361
|
-
title.style.cssText = 'font-weight:700;color:var(--blue,#58a6ff);font-size:
|
|
1361
|
+
title.style.cssText = 'font-weight:700;color:var(--blue,#58a6ff);font-size:var(--text-lg)';
|
|
1362
1362
|
title.textContent = 'Refresh diagnostics — ' + entries.length + ' / ' + _DIAG_RING_SIZE + ' entries';
|
|
1363
1363
|
const actions = document.createElement('div');
|
|
1364
1364
|
actions.style.cssText = 'display:flex;gap:6px';
|
|
1365
1365
|
const sendBtn = document.createElement('button');
|
|
1366
1366
|
sendBtn.type = 'button';
|
|
1367
1367
|
sendBtn.textContent = 'Send to engine';
|
|
1368
|
-
sendBtn.style.cssText = 'background:var(--blue,#1f6feb);color:#fff;border:none;border-radius:4px;padding:4px 10px;font-size:
|
|
1368
|
+
sendBtn.style.cssText = 'background:var(--blue,#1f6feb);color:#fff;border:none;border-radius:4px;padding:4px 10px;font-size:var(--text-base);cursor:pointer';
|
|
1369
1369
|
sendBtn.addEventListener('click', function() {
|
|
1370
1370
|
sendBtn.disabled = true;
|
|
1371
1371
|
sendBtn.textContent = 'Sending…';
|
|
@@ -1384,12 +1384,12 @@ function _openRefreshDiagModal() {
|
|
|
1384
1384
|
const clearBtn = document.createElement('button');
|
|
1385
1385
|
clearBtn.type = 'button';
|
|
1386
1386
|
clearBtn.textContent = 'Clear';
|
|
1387
|
-
clearBtn.style.cssText = 'background:none;color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:4px;padding:4px 10px;font-size:
|
|
1387
|
+
clearBtn.style.cssText = 'background:none;color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:4px;padding:4px 10px;font-size:var(--text-base);cursor:pointer';
|
|
1388
1388
|
clearBtn.addEventListener('click', function() { window._refreshDiagnosticsClear(); overlay.remove(); });
|
|
1389
1389
|
const closeBtn = document.createElement('button');
|
|
1390
1390
|
closeBtn.type = 'button';
|
|
1391
1391
|
closeBtn.textContent = 'Close';
|
|
1392
|
-
closeBtn.style.cssText = 'background:none;color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:4px;padding:4px 10px;font-size:
|
|
1392
|
+
closeBtn.style.cssText = 'background:none;color:var(--muted,#aaa);border:1px solid var(--border,#444);border-radius:4px;padding:4px 10px;font-size:var(--text-base);cursor:pointer';
|
|
1393
1393
|
closeBtn.addEventListener('click', function() { overlay.remove(); });
|
|
1394
1394
|
actions.appendChild(sendBtn);
|
|
1395
1395
|
actions.appendChild(clearBtn);
|
|
@@ -1407,7 +1407,7 @@ function _openRefreshDiagModal() {
|
|
|
1407
1407
|
|
|
1408
1408
|
function _renderRefreshDiagTable(entries) {
|
|
1409
1409
|
const table = document.createElement('table');
|
|
1410
|
-
table.style.cssText = 'width:100%;border-collapse:collapse;font-family:monospace;font-size:
|
|
1410
|
+
table.style.cssText = 'width:100%;border-collapse:collapse;font-family:monospace;font-size:var(--text-base)';
|
|
1411
1411
|
const cols = ['ts', 'kind', 'gap', 'vis', 'status', 'etag↓', 'bytes', 'cacheV', 'wi', 'wiΔ', 'changed', 'render(ms)', 'note'];
|
|
1412
1412
|
const thead = document.createElement('thead');
|
|
1413
1413
|
const trh = document.createElement('tr');
|