mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-07 11:28:40 +02:00
Add files via upload
This commit is contained in:
+35
-23
@@ -564,6 +564,18 @@ function escapeHtmlLocal(text) {
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function escapeJsString(text) {
|
||||
return JSON.stringify(String(text == null ? '' : text));
|
||||
}
|
||||
|
||||
function escapeAttrLocal(text) {
|
||||
return escapeHtmlLocal(text).replace(/"/g, '"').replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function escapeJsStringAttr(text) {
|
||||
return escapeAttrLocal(escapeJsString(text));
|
||||
}
|
||||
|
||||
function formatTimelinePlainTextHtml(text) {
|
||||
return '<pre class="timeline-plain-text">' + escapeHtml(text == null ? '' : String(text)) + '</pre>';
|
||||
}
|
||||
@@ -5786,7 +5798,7 @@ function buildMcpTimelineSvg(points, rangeKey) {
|
||||
const isPeak = c.i === peakIdx && (c.p.total || 0) > 0;
|
||||
const dotClass = 'mcp-stats-timeline-dot' + (isPeak ? ' mcp-stats-timeline-dot--peak' : '');
|
||||
return `<circle class="${dotClass}" cx="${c.x.toFixed(2)}" cy="${c.y.toFixed(2)}" r="${isPeak ? 2 : 1.5}"
|
||||
data-time="${escapeHtml(tipTime)}"
|
||||
data-time="${escapeAttrLocal(tipTime)}"
|
||||
data-total="${c.p.total || 0}"
|
||||
data-failed="${c.p.failed || 0}" />`;
|
||||
}).join('');
|
||||
@@ -5800,9 +5812,9 @@ function buildMcpTimelineSvg(points, rangeKey) {
|
||||
const tipTime = formatMcpTimelineLabel(c.p.t, rangeKey, locale);
|
||||
return `<g class="mcp-stats-timeline-bar-group">
|
||||
<rect class="mcp-stats-timeline-bar${total > 0 ? ' is-active' : ''}" x="${(c.x - barW / 2).toFixed(2)}" y="${y.toFixed(2)}" width="${barW.toFixed(2)}" height="${h.toFixed(2)}" rx="1.6"
|
||||
data-time="${escapeHtml(tipTime)}" data-total="${total}" data-failed="${failed}" />
|
||||
data-time="${escapeAttrLocal(tipTime)}" data-total="${total}" data-failed="${failed}" />
|
||||
${failedH > 0 ? `<rect class="mcp-stats-timeline-bar-fail" x="${(c.x - barW / 2).toFixed(2)}" y="${(baseY - failedH).toFixed(2)}" width="${barW.toFixed(2)}" height="${failedH.toFixed(2)}" rx="1.6"
|
||||
data-time="${escapeHtml(tipTime)}" data-total="${total}" data-failed="${failed}" />` : ''}
|
||||
data-time="${escapeAttrLocal(tipTime)}" data-total="${total}" data-failed="${failed}" />` : ''}
|
||||
</g>`;
|
||||
}).join('');
|
||||
|
||||
@@ -6421,11 +6433,11 @@ function renderMcpStatsInsightPanel(topTools, totals, activeToolFilter = '', opt
|
||||
|| `${s.name},${s.calls} 次调用,占 ${s.pct}%`;
|
||||
return `<li class="mcp-stats-dist-legend-item-wrap">
|
||||
<button type="button" class="mcp-stats-dist-legend-item${isActive ? ' is-active' : ''}"
|
||||
data-tool-name="${escapeHtml(s.name)}"
|
||||
data-tool-name="${escapeAttrLocal(s.name)}"
|
||||
data-pct="${s.pct}"
|
||||
data-calls="${s.calls}"
|
||||
data-is-others="0"
|
||||
aria-label="${escapeHtml(rowAria)}"
|
||||
aria-label="${escapeAttrLocal(rowAria)}"
|
||||
aria-pressed="${isActive ? 'true' : 'false'}">${inner}</button>
|
||||
</li>`;
|
||||
}).join('');
|
||||
@@ -6452,8 +6464,8 @@ function renderMcpStatsInsightPanel(topTools, totals, activeToolFilter = '', opt
|
||||
</div>`;
|
||||
|
||||
return `
|
||||
<div class="mcp-stats-dist-panel${embedded ? ' mcp-stats-dist-panel--embedded' : ''}" aria-label="${escapeHtml(distTitle)}"
|
||||
data-center-label="${escapeHtml(centerLabel)}"
|
||||
<div class="mcp-stats-dist-panel${embedded ? ' mcp-stats-dist-panel--embedded' : ''}" aria-label="${escapeAttrLocal(distTitle)}"
|
||||
data-center-label="${escapeAttrLocal(centerLabel)}"
|
||||
data-center-value="${top6SharePct}"
|
||||
data-center-suffix="%">
|
||||
${headerHtml}
|
||||
@@ -6664,13 +6676,13 @@ function renderMcpStatsToolTable(topTools, totals, activeToolFilter = '') {
|
||||
|| `${name},${total} 次调用,成功率 ${toolRate}%`;
|
||||
rowsHtml += `
|
||||
<tr class="mcp-stats-tool-row${isActive ? ' is-active' : ''}"
|
||||
data-tool-name="${escapeHtml(rawName)}"
|
||||
data-tool-name="${escapeAttrLocal(rawName)}"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
aria-label="${escapeHtml(rowAria)}"
|
||||
aria-label="${escapeAttrLocal(rowAria)}"
|
||||
aria-pressed="${isActive ? 'true' : 'false'}">
|
||||
<td class="col-rank"><span class="mcp-stats-rank${rankClass}">${index + 1}</span></td>
|
||||
<td class="col-tool" title="${escapeHtml(name)}">
|
||||
<td class="col-tool" title="${escapeAttrLocal(name)}">
|
||||
<span class="mcp-stats-tool-dot" style="background:${dotColor}" aria-hidden="true"></span>
|
||||
<span class="mcp-stats-tool-label">${escapeHtml(name)}</span>
|
||||
</td>
|
||||
@@ -6719,8 +6731,8 @@ function renderMcpStatsToolsPanel(topTools, totals, activeToolFilter = '') {
|
||||
const segAria = mcpMonitorT('distSegmentAria', { name: displayName, pct: s.pct, calls: s.calls })
|
||||
|| `${displayName},占 ${s.pct}%,${s.calls} 次`;
|
||||
return `<span class="mcp-stats-proportion-seg${isActive ? ' is-active' : ''}"
|
||||
data-tool-name="${escapeHtml(s.name)}" data-pct="${s.pct}" data-calls="${s.calls}" data-is-others="0"
|
||||
role="button" tabindex="0" aria-label="${escapeHtml(segAria)}"
|
||||
data-tool-name="${escapeAttrLocal(s.name)}" data-pct="${s.pct}" data-calls="${s.calls}" data-is-others="0"
|
||||
role="button" tabindex="0" aria-label="${escapeAttrLocal(segAria)}"
|
||||
style="flex:${s.pctNum} 1 0;background:${s.color}" title="${escapeHtml(title)}"></span>`;
|
||||
}).join('');
|
||||
|
||||
@@ -6748,12 +6760,12 @@ function renderMcpStatsToolsPanel(topTools, totals, activeToolFilter = '') {
|
||||
const successLabel = mcpMonitorT('successCount', { n: success }) || `成功 ${success}`;
|
||||
const failedLabel = mcpMonitorT('failedCount', { n: failed }) || `失败 ${failed}`;
|
||||
return `<li class="mcp-stats-tool-item${isActive ? ' is-active' : ''}"
|
||||
data-tool-name="${escapeHtml(rawName)}" tabindex="0" role="button"
|
||||
aria-label="${escapeHtml(rowAria)}" aria-pressed="${isActive ? 'true' : 'false'}">
|
||||
data-tool-name="${escapeAttrLocal(rawName)}" tabindex="0" role="button"
|
||||
aria-label="${escapeAttrLocal(rowAria)}" aria-pressed="${isActive ? 'true' : 'false'}">
|
||||
<div class="mcp-stats-tool-item__top">
|
||||
<span class="mcp-stats-tool-item__rank mcp-stats-rank${rankClass}">${index + 1}</span>
|
||||
<span class="mcp-stats-tool-item__dot" style="background:${color}" aria-hidden="true"></span>
|
||||
<span class="mcp-stats-tool-item__name" title="${escapeHtml(name)}">${escapeHtml(name)}</span>
|
||||
<span class="mcp-stats-tool-item__name" title="${escapeAttrLocal(name)}">${escapeHtml(name)}</span>
|
||||
<span class="mcp-stats-tool-item__share">${sharePct}%</span>
|
||||
</div>
|
||||
<div class="mcp-stats-tool-item__middle">
|
||||
@@ -6813,8 +6825,8 @@ function renderMcpStatsChartAside(topTools, totals, activeToolFilter = '') {
|
||||
|
||||
return `
|
||||
<div class="mcp-stats-dist-panel mcp-stats-dist-panel--compact"
|
||||
aria-label="${escapeHtml(distTitle)}"
|
||||
data-center-label="${escapeHtml(centerLabel)}"
|
||||
aria-label="${escapeAttrLocal(distTitle)}"
|
||||
data-center-label="${escapeAttrLocal(centerLabel)}"
|
||||
data-center-value="${top6SharePct}"
|
||||
data-center-suffix="%">
|
||||
<p class="mcp-stats-panel__aside-title">${escapeHtml(distTitle)}</p>
|
||||
@@ -6975,11 +6987,11 @@ function renderMonitorExecutions(executions = [], statusFilter = 'all') {
|
||||
const duration = formatExecutionDuration(exec.startTime, exec.endTime);
|
||||
const toolName = escapeHtml(formatMonitorToolName(exec.toolName) || unknownToolLabel);
|
||||
const rawExecId = exec.id || '';
|
||||
const executionId = escapeHtml(rawExecId);
|
||||
const executionId = escapeAttrLocal(rawExecId);
|
||||
const jsExecId = escapeJsStringAttr(rawExecId);
|
||||
const terminateBtn = status === 'running'
|
||||
? `<button type="button" class="btn-secondary btn-monitor-abort" data-require-permission="monitor:write" onclick="cancelMCPToolExecution('${rawExecId.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}')">${escapeHtml(terminateLabel)}</button>`
|
||||
? `<button type="button" class="btn-secondary btn-monitor-abort" data-require-permission="monitor:write" onclick="cancelMCPToolExecution(${jsExecId})">${escapeHtml(terminateLabel)}</button>`
|
||||
: '';
|
||||
const jsExecId = rawExecId.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
||||
const isSelected = monitorState.selectedExecutions.has(rawExecId);
|
||||
const rowKey = monitorRenderKey([exec, isSelected, locale || 'en-US']);
|
||||
return {
|
||||
@@ -6988,7 +7000,7 @@ function renderMonitorExecutions(executions = [], statusFilter = 'all') {
|
||||
html: `
|
||||
<tr data-execution-id="${executionId}">
|
||||
<td>
|
||||
<input type="checkbox" class="monitor-execution-checkbox theme-checkbox" value="${executionId}" ${isSelected ? 'checked' : ''} onchange="toggleExecutionSelection('${jsExecId}', this.checked)" />
|
||||
<input type="checkbox" class="monitor-execution-checkbox theme-checkbox" value="${executionId}" ${isSelected ? 'checked' : ''} onchange="toggleExecutionSelection(${jsExecId}, this.checked)" />
|
||||
</td>
|
||||
<td>${toolName}</td>
|
||||
<td><span class="${statusClass}">${escapeHtml(statusLabel)}</span></td>
|
||||
@@ -6996,9 +7008,9 @@ function renderMonitorExecutions(executions = [], statusFilter = 'all') {
|
||||
<td class="monitor-execution-duration">${escapeHtml(duration)}</td>
|
||||
<td>
|
||||
<div class="monitor-execution-actions">
|
||||
<button class="btn-secondary" onclick="showMCPDetail('${executionId}')">${escapeHtml(viewDetailLabel)}</button>
|
||||
<button class="btn-secondary" onclick="showMCPDetail(${jsExecId})">${escapeHtml(viewDetailLabel)}</button>
|
||||
${terminateBtn}
|
||||
<button class="btn-secondary btn-delete" data-require-permission="monitor:delete" onclick="deleteExecution('${executionId}')" title="${escapeHtml(deleteExecTitle)}">${escapeHtml(deleteLabel)}</button>
|
||||
<button class="btn-secondary btn-delete" data-require-permission="monitor:delete" onclick="deleteExecution(${jsExecId})" title="${escapeHtml(deleteExecTitle)}">${escapeHtml(deleteLabel)}</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user