agentgui 1.0.610 → 1.0.612
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/package.json +1 -1
- package/static/index.html +26 -1
- package/static/js/client.js +8 -8
- package/static/js/streaming-renderer.js +36 -36
- package/static/js/ui-components.js +31 -42
- package/static/templates/agent-metadata-panel.html +2 -2
- package/static/templates/code-suggestion-panel.html +1 -1
- package/static/templates/error-recovery-options.html +1 -1
- package/static/templates/error-stack-trace.html +1 -1
- package/static/templates/error-summary.html +1 -1
- package/static/templates/file-diff-viewer.html +1 -1
- package/static/templates/file-read-panel.html +1 -1
- package/static/templates/file-write-panel.html +1 -1
- package/static/templates/git-diff-list.html +1 -1
- package/static/templates/git-status-panel.html +1 -1
- package/static/templates/terminal-output-panel.html +1 -1
- package/static/templates/test-results-display.html +2 -2
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -3007,7 +3007,32 @@
|
|
|
3007
3007
|
.toast-success { background: var(--color-success); color: white; }
|
|
3008
3008
|
.toast-error { background: var(--color-error); color: white; }
|
|
3009
3009
|
.toast-warning { background: var(--color-warning); color: white; }
|
|
3010
|
-
|
|
3010
|
+
|
|
3011
|
+
.inline-code {
|
|
3012
|
+
background: #f3f4f6;
|
|
3013
|
+
padding: 0.125rem 0.375rem;
|
|
3014
|
+
border-radius: 0.25rem;
|
|
3015
|
+
font-size: 0.875rem;
|
|
3016
|
+
font-family: ui-monospace, monospace;
|
|
3017
|
+
color: #dc2626;
|
|
3018
|
+
}
|
|
3019
|
+
|
|
3020
|
+
html.dark .inline-code {
|
|
3021
|
+
background: #1f2937;
|
|
3022
|
+
color: #f87171;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
.html-rendered-container {
|
|
3026
|
+
border-radius: 0.5rem;
|
|
3027
|
+
overflow: hidden;
|
|
3028
|
+
border: 1px solid #e5e7eb;
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
html.dark .html-rendered-container {
|
|
3032
|
+
border-color: #1f2937;
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
</style>
|
|
3011
3036
|
<link rel="stylesheet" href="/gm/css/tools-popup.css">
|
|
3012
3037
|
</head>
|
|
3013
3038
|
<body>
|
package/static/js/client.js
CHANGED
|
@@ -960,7 +960,7 @@ class AgentGUIClient {
|
|
|
960
960
|
if (block.type === 'text' && block.text) {
|
|
961
961
|
const text = block.text;
|
|
962
962
|
if (this.isHtmlContent(text)) {
|
|
963
|
-
return `<div class="html-content
|
|
963
|
+
return `<div class="html-content">${this.sanitizeHtml(text)}</div>`;
|
|
964
964
|
}
|
|
965
965
|
const parts = this.parseMarkdownCodeBlocks(text);
|
|
966
966
|
if (parts.length === 1 && parts[0].type === 'text') {
|
|
@@ -968,7 +968,7 @@ class AgentGUIClient {
|
|
|
968
968
|
}
|
|
969
969
|
return parts.map(part => {
|
|
970
970
|
if (part.type === 'html') {
|
|
971
|
-
return `<div class="html-content
|
|
971
|
+
return `<div class="html-content">${this.sanitizeHtml(part.content)}</div>`;
|
|
972
972
|
} else if (part.type === 'code') {
|
|
973
973
|
return this.renderCodeBlock(part.language, part.code);
|
|
974
974
|
}
|
|
@@ -1422,10 +1422,10 @@ class AgentGUIClient {
|
|
|
1422
1422
|
if (language.toLowerCase() === 'html') {
|
|
1423
1423
|
return `
|
|
1424
1424
|
<div class="message-code">
|
|
1425
|
-
<div class="html-rendered-label
|
|
1425
|
+
<div class="html-rendered-label">
|
|
1426
1426
|
Rendered HTML
|
|
1427
1427
|
</div>
|
|
1428
|
-
<div class="html-content
|
|
1428
|
+
<div class="html-content">
|
|
1429
1429
|
${this.sanitizeHtml(code)}
|
|
1430
1430
|
</div>
|
|
1431
1431
|
</div>
|
|
@@ -1442,7 +1442,7 @@ class AgentGUIClient {
|
|
|
1442
1442
|
renderMessageContent(content) {
|
|
1443
1443
|
if (typeof content === 'string') {
|
|
1444
1444
|
if (this.isHtmlContent(content)) {
|
|
1445
|
-
return `<div class="message-text"><div class="html-content
|
|
1445
|
+
return `<div class="message-text"><div class="html-content">${this.sanitizeHtml(content)}</div></div>`;
|
|
1446
1446
|
}
|
|
1447
1447
|
return `<div class="message-text">${this.escapeHtml(content)}</div>`;
|
|
1448
1448
|
} else if (content && typeof content === 'object' && content.type === 'claude_execution') {
|
|
@@ -1458,7 +1458,7 @@ class AgentGUIClient {
|
|
|
1458
1458
|
const parts = this.parseMarkdownCodeBlocks(block.text);
|
|
1459
1459
|
parts.forEach(part => {
|
|
1460
1460
|
if (part.type === 'html') {
|
|
1461
|
-
html += `<div class="message-text"><div class="html-content
|
|
1461
|
+
html += `<div class="message-text"><div class="html-content">${this.sanitizeHtml(part.content)}</div></div>`;
|
|
1462
1462
|
} else if (part.type === 'text') {
|
|
1463
1463
|
html += `<div class="message-text">${this.escapeHtml(part.content)}</div>`;
|
|
1464
1464
|
} else if (part.type === 'code') {
|
|
@@ -1470,10 +1470,10 @@ class AgentGUIClient {
|
|
|
1470
1470
|
if (block.language === 'html') {
|
|
1471
1471
|
html += `
|
|
1472
1472
|
<div class="message-code">
|
|
1473
|
-
<div class="html-rendered-label
|
|
1473
|
+
<div class="html-rendered-label">
|
|
1474
1474
|
Rendered HTML
|
|
1475
1475
|
</div>
|
|
1476
|
-
<div class="html-content
|
|
1476
|
+
<div class="html-content">
|
|
1477
1477
|
${this.sanitizeHtml(block.code)}
|
|
1478
1478
|
</div>
|
|
1479
1479
|
</div>
|
|
@@ -453,17 +453,17 @@ class StreamingRenderer {
|
|
|
453
453
|
let html = this.escapeHtml(text);
|
|
454
454
|
|
|
455
455
|
// Render markdown bold: **text** -> <strong>text</strong>
|
|
456
|
-
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong class="font-semibold text-
|
|
456
|
+
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong class="font-semibold text-base-content">$1</strong>');
|
|
457
457
|
|
|
458
458
|
// Render markdown italic: *text* or _text_
|
|
459
|
-
html = html.replace(/\*([^*]+)\*/g, '<em class="italic text-
|
|
460
|
-
html = html.replace(/_([^_]+)_/g, '<em class="italic text-
|
|
459
|
+
html = html.replace(/\*([^*]+)\*/g, '<em class="italic text-base-content/70">$1</em>');
|
|
460
|
+
html = html.replace(/_([^_]+)_/g, '<em class="italic text-base-content/70">$1</em>');
|
|
461
461
|
|
|
462
462
|
// Render inline code: `code`
|
|
463
|
-
html = html.replace(/`([^`]+)`/g, '<code class="inline-code
|
|
463
|
+
html = html.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>');
|
|
464
464
|
|
|
465
465
|
// Render markdown links: [text](url)
|
|
466
|
-
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" class="
|
|
466
|
+
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" class="link link-primary" target="_blank">$1</a>');
|
|
467
467
|
|
|
468
468
|
// Convert line breaks
|
|
469
469
|
html = html.replace(/\n/g, '<br>');
|
|
@@ -1565,20 +1565,20 @@ class StreamingRenderer {
|
|
|
1565
1565
|
*/
|
|
1566
1566
|
renderStreamingStart(event) {
|
|
1567
1567
|
const div = document.createElement('div');
|
|
1568
|
-
div.className = 'event-streaming-start card mb-3 p-4
|
|
1568
|
+
div.className = 'event-streaming-start card mb-3 p-4 alert alert-info';
|
|
1569
1569
|
div.dataset.eventId = event.id || event.sessionId || '';
|
|
1570
1570
|
div.dataset.eventType = 'streaming_start';
|
|
1571
1571
|
|
|
1572
1572
|
const time = new Date(event.timestamp).toLocaleTimeString();
|
|
1573
1573
|
div.innerHTML = `
|
|
1574
1574
|
<div class="flex items-center gap-2">
|
|
1575
|
-
<svg class="w-5 h-5 text-
|
|
1575
|
+
<svg class="w-5 h-5 text-info animate-spin" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
1576
1576
|
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" opacity="0.25"></circle>
|
|
1577
1577
|
<path d="M4 12a8 8 0 018-8" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
|
|
1578
1578
|
</svg>
|
|
1579
1579
|
<div class="flex-1">
|
|
1580
|
-
<h4 class="font-semibold text-
|
|
1581
|
-
<p class="text-sm text-
|
|
1580
|
+
<h4 class="font-semibold text-info-content">Streaming Started</h4>
|
|
1581
|
+
<p class="text-sm text-info-content/70">${time}</p>
|
|
1582
1582
|
</div>
|
|
1583
1583
|
</div>
|
|
1584
1584
|
`;
|
|
@@ -1604,8 +1604,8 @@ class StreamingRenderer {
|
|
|
1604
1604
|
div.innerHTML = `
|
|
1605
1605
|
<div class="flex items-center gap-2 text-sm">
|
|
1606
1606
|
<span class="text-secondary">${percentage}%</span>
|
|
1607
|
-
<div class="
|
|
1608
|
-
<div class="
|
|
1607
|
+
<div class="progress progress-primary flex-1">
|
|
1608
|
+
<div class="progress-bar" style="width: ${percentage}%"></div>
|
|
1609
1609
|
</div>
|
|
1610
1610
|
</div>
|
|
1611
1611
|
`;
|
|
@@ -1617,7 +1617,7 @@ class StreamingRenderer {
|
|
|
1617
1617
|
*/
|
|
1618
1618
|
renderStreamingComplete(event) {
|
|
1619
1619
|
const div = document.createElement('div');
|
|
1620
|
-
div.className = 'event-streaming-complete card mb-3 p-4
|
|
1620
|
+
div.className = 'event-streaming-complete card mb-3 p-4 alert alert-success rounded-lg';
|
|
1621
1621
|
div.dataset.eventId = event.id || event.sessionId || '';
|
|
1622
1622
|
div.dataset.eventType = 'streaming_complete';
|
|
1623
1623
|
|
|
@@ -1627,19 +1627,19 @@ class StreamingRenderer {
|
|
|
1627
1627
|
div.innerHTML = `
|
|
1628
1628
|
<div class="flex items-start gap-3">
|
|
1629
1629
|
<div class="flex-shrink-0 mt-0.5">
|
|
1630
|
-
<svg class="w-6 h-6 text-
|
|
1630
|
+
<svg class="w-6 h-6 text-success animate-bounce" fill="currentColor" viewBox="0 0 20 20">
|
|
1631
1631
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
|
|
1632
1632
|
</svg>
|
|
1633
1633
|
</div>
|
|
1634
1634
|
<div class="flex-1">
|
|
1635
|
-
<h4 class="font-bold text-lg text-
|
|
1635
|
+
<h4 class="font-bold text-lg text-success-content">✨ Execution Complete</h4>
|
|
1636
1636
|
<div class="mt-2 grid grid-cols-2 gap-3 text-sm">
|
|
1637
1637
|
<div>
|
|
1638
|
-
<span class="text-
|
|
1639
|
-
<span class="text-
|
|
1638
|
+
<span class="text-success font-semibold">${eventCount}</span>
|
|
1639
|
+
<span class="text-success/70">events processed</span>
|
|
1640
1640
|
</div>
|
|
1641
1641
|
<div class="text-right">
|
|
1642
|
-
<span class="text-
|
|
1642
|
+
<span class="text-success/70">${time}</span>
|
|
1643
1643
|
</div>
|
|
1644
1644
|
</div>
|
|
1645
1645
|
</div>
|
|
@@ -1764,7 +1764,7 @@ class StreamingRenderer {
|
|
|
1764
1764
|
|
|
1765
1765
|
div.innerHTML = `
|
|
1766
1766
|
<div class="flex items-center gap-3 mb-2">
|
|
1767
|
-
<svg class="w-4 h-4 text-
|
|
1767
|
+
<svg class="w-4 h-4 text-warning" fill="currentColor" viewBox="0 0 20 20">
|
|
1768
1768
|
<path fill-rule="evenodd" d="M9.243 3.03a1 1 0 01.727 1.155L9.53 6h2.94l.56-2.243a1 1 0 111.94.486L14.53 6H17a1 1 0 110 2h-2.97l-.5 2H17a1 1 0 110 2h-3.03l-.56 2.243a1 1 0 11-1.94-.486L12.47 14H9.53l-.56 2.243a1 1 0 11-1.94-.486L7.47 14H4a1 1 0 110-2h3.03l.5-2H4a1 1 0 110-2h2.97l.56-2.243a1 1 0 011.155-.727zM9.03 8l.5 2h2.94l-.5-2H9.03z" clip-rule="evenodd"></path>
|
|
1769
1769
|
</svg>
|
|
1770
1770
|
<div class="flex-1">
|
|
@@ -1773,9 +1773,9 @@ class StreamingRenderer {
|
|
|
1773
1773
|
</div>
|
|
1774
1774
|
</div>
|
|
1775
1775
|
<div class="flex gap-4 text-xs">
|
|
1776
|
-
${changes.added ? `<span class="text-
|
|
1777
|
-
${changes.modified ? `<span class="text-
|
|
1778
|
-
${changes.deleted ? `<span class="text-
|
|
1776
|
+
${changes.added ? `<span class="text-success">+${changes.added}</span>` : ''}
|
|
1777
|
+
${changes.modified ? `<span class="text-info">~${changes.modified}</span>` : ''}
|
|
1778
|
+
${changes.deleted ? `<span class="text-error">-${changes.deleted}</span>` : ''}
|
|
1779
1779
|
${total === 0 ? '<span class="text-secondary">no changes</span>' : ''}
|
|
1780
1780
|
</div>
|
|
1781
1781
|
`;
|
|
@@ -1895,28 +1895,28 @@ class StreamingRenderer {
|
|
|
1895
1895
|
let html = '';
|
|
1896
1896
|
parts.forEach(part => {
|
|
1897
1897
|
if (part.type === 'html') {
|
|
1898
|
-
html += `<div class="html-content
|
|
1898
|
+
html += `<div class="html-content mb-3">${part.content}</div>`;
|
|
1899
1899
|
} else if (part.type === 'text') {
|
|
1900
|
-
html += `<div class="
|
|
1900
|
+
html += `<div class="card card-body mb-3 leading-relaxed text-sm">${this.parseAndRenderMarkdown(part.content)}</div>`;
|
|
1901
1901
|
} else if (part.type === 'code') {
|
|
1902
1902
|
if (part.language.toLowerCase() === 'html') {
|
|
1903
|
-
html += `<div class="html-rendered-container mb-3
|
|
1904
|
-
<div class="html-rendered-label
|
|
1905
|
-
<div class="html-content bg-
|
|
1903
|
+
html += `<div class="html-rendered-container mb-3">
|
|
1904
|
+
<div class="html-rendered-label">Rendered HTML</div>
|
|
1905
|
+
<div class="html-content bg-base-100 p-4 overflow-x-auto">${part.code}</div>
|
|
1906
1906
|
</div>`;
|
|
1907
1907
|
} else {
|
|
1908
1908
|
const partLineCount = part.code.split('\n').length;
|
|
1909
|
-
html += `<div class="mb-3 rounded-lg overflow-hidden
|
|
1909
|
+
html += `<div class="card mb-3 rounded-lg overflow-hidden">
|
|
1910
1910
|
<details class="collapsible-code">
|
|
1911
1911
|
<summary class="collapsible-code-summary">
|
|
1912
1912
|
<span>${this.escapeHtml(part.language)} - ${partLineCount} line${partLineCount !== 1 ? 's' : ''}</span>
|
|
1913
|
-
<button class="copy-code-btn
|
|
1913
|
+
<button class="copy-code-btn" title="Copy code" onclick="event.preventDefault();event.stopPropagation();navigator.clipboard.writeText(this.closest('.collapsible-code').querySelector('code').textContent)">
|
|
1914
1914
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1915
1915
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
|
|
1916
1916
|
</svg>
|
|
1917
1917
|
</button>
|
|
1918
1918
|
</summary>
|
|
1919
|
-
<pre class="bg-
|
|
1919
|
+
<pre class="bg-base-300 text-base-content p-4 overflow-x-auto" style="margin:0;border-radius:0 0 0.375rem 0.375rem"><code class="language-${this.escapeHtml(part.language)}">${this.escapeHtml(part.code)}</code></pre>
|
|
1920
1920
|
</details>
|
|
1921
1921
|
</div>`;
|
|
1922
1922
|
}
|
|
@@ -1957,10 +1957,10 @@ class StreamingRenderer {
|
|
|
1957
1957
|
// Render HTML code blocks as actual HTML elements
|
|
1958
1958
|
if (language === 'html') {
|
|
1959
1959
|
div.innerHTML = `
|
|
1960
|
-
<div class="html-rendered-container
|
|
1960
|
+
<div class="html-rendered-container alert alert-info text-xs mb-2">
|
|
1961
1961
|
Rendered HTML
|
|
1962
1962
|
</div>
|
|
1963
|
-
<div class="html-content
|
|
1963
|
+
<div class="html-content">
|
|
1964
1964
|
${code}
|
|
1965
1965
|
</div>
|
|
1966
1966
|
`;
|
|
@@ -1969,7 +1969,7 @@ class StreamingRenderer {
|
|
|
1969
1969
|
div.innerHTML = `
|
|
1970
1970
|
<details class="collapsible-code">
|
|
1971
1971
|
<summary class="collapsible-code-summary">${this.escapeHtml(language)} - ${codeLineCount} line${codeLineCount !== 1 ? 's' : ''}</summary>
|
|
1972
|
-
<pre class="bg-
|
|
1972
|
+
<pre class="bg-base-300 text-base-content p-4 overflow-x-auto" style="margin:0;border-radius:0 0 0.375rem 0.375rem"><code class="language-${this.escapeHtml(language)}">${this.escapeHtml(code)}</code></pre>
|
|
1973
1973
|
</details>
|
|
1974
1974
|
`;
|
|
1975
1975
|
}
|
|
@@ -1981,15 +1981,15 @@ class StreamingRenderer {
|
|
|
1981
1981
|
*/
|
|
1982
1982
|
renderThinking(event) {
|
|
1983
1983
|
const div = document.createElement('div');
|
|
1984
|
-
div.className = 'event-thinking mb-3 p-4
|
|
1984
|
+
div.className = 'event-thinking mb-3 p-4 alert rounded';
|
|
1985
1985
|
div.dataset.eventId = event.id || '';
|
|
1986
1986
|
div.dataset.eventType = 'thinking_block';
|
|
1987
1987
|
|
|
1988
1988
|
const text = event.thinking || event.content || '';
|
|
1989
1989
|
div.innerHTML = `
|
|
1990
1990
|
<details>
|
|
1991
|
-
<summary class="cursor-pointer font-semibold text-
|
|
1992
|
-
<p class="mt-3 text-sm text-
|
|
1991
|
+
<summary class="cursor-pointer font-semibold text-base-content">Thinking</summary>
|
|
1992
|
+
<p class="mt-3 text-sm text-base-content/80 whitespace-pre-wrap">${this.escapeHtml(text)}</p>
|
|
1993
1993
|
</details>
|
|
1994
1994
|
`;
|
|
1995
1995
|
return div;
|
|
@@ -2024,7 +2024,7 @@ class StreamingRenderer {
|
|
|
2024
2024
|
}
|
|
2025
2025
|
|
|
2026
2026
|
const div = document.createElement('div');
|
|
2027
|
-
div.className = 'event-generic mb-3 p-3 bg-
|
|
2027
|
+
div.className = 'event-generic mb-3 p-3 bg-base-200 rounded text-sm';
|
|
2028
2028
|
div.dataset.eventId = event.id || '';
|
|
2029
2029
|
div.dataset.eventType = event.type;
|
|
2030
2030
|
|
|
@@ -27,15 +27,15 @@ class UIComponents {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
modal.innerHTML = `
|
|
30
|
-
<div class="modal-content ${sizeClasses[size] || sizeClasses['medium']}
|
|
31
|
-
<div class="
|
|
30
|
+
<div class="modal-content card ${sizeClasses[size] || sizeClasses['medium']}">
|
|
31
|
+
<div class="card-header flex justify-between items-center">
|
|
32
32
|
<h2 class="text-xl font-bold">${UIComponents.escapeHtml(title)}</h2>
|
|
33
|
-
<button class="
|
|
33
|
+
<button class="btn btn-ghost btn-sm modal-close">×</button>
|
|
34
34
|
</div>
|
|
35
|
-
<div class="
|
|
35
|
+
<div class="card-body modal-body">
|
|
36
36
|
${typeof content === 'string' ? UIComponents.escapeHtml(content) : ''}
|
|
37
37
|
</div>
|
|
38
|
-
<div class="
|
|
38
|
+
<div class="card-footer flex gap-2 justify-end">
|
|
39
39
|
${buttons.map(btn => `
|
|
40
40
|
<button class="btn btn-${btn.variant || 'secondary'}" data-action="${btn.action || 'close'}">
|
|
41
41
|
${UIComponents.escapeHtml(btn.label)}
|
|
@@ -93,11 +93,7 @@ class UIComponents {
|
|
|
93
93
|
|
|
94
94
|
tabs.forEach((tab, index) => {
|
|
95
95
|
const btn = document.createElement('button');
|
|
96
|
-
btn.className = `tab
|
|
97
|
-
index === activeTab
|
|
98
|
-
? 'border-b-2 border-blue-500 text-blue-600 dark:text-blue-400'
|
|
99
|
-
: 'text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200'
|
|
100
|
-
}`;
|
|
96
|
+
btn.className = `tab tab-underline tab-button ${index === activeTab ? 'tab-active' : ''}`;
|
|
101
97
|
btn.textContent = tab.label;
|
|
102
98
|
btn.dataset.tabIndex = index;
|
|
103
99
|
|
|
@@ -105,11 +101,9 @@ class UIComponents {
|
|
|
105
101
|
// Update active button
|
|
106
102
|
tabButtons.querySelectorAll('.tab-button').forEach((b, i) => {
|
|
107
103
|
if (i === index) {
|
|
108
|
-
b.classList.add('
|
|
109
|
-
b.classList.remove('text-gray-600', 'dark:text-gray-400');
|
|
104
|
+
b.classList.add('tab-active');
|
|
110
105
|
} else {
|
|
111
|
-
b.classList.remove('
|
|
112
|
-
b.classList.add('text-gray-600', 'dark:text-gray-400');
|
|
106
|
+
b.classList.remove('tab-active');
|
|
113
107
|
}
|
|
114
108
|
});
|
|
115
109
|
|
|
@@ -155,13 +149,13 @@ class UIComponents {
|
|
|
155
149
|
|
|
156
150
|
const alert = document.createElement('div');
|
|
157
151
|
const typeClasses = {
|
|
158
|
-
'info': '
|
|
159
|
-
'success': '
|
|
160
|
-
'warning': '
|
|
161
|
-
'error': '
|
|
152
|
+
'info': 'alert-info',
|
|
153
|
+
'success': 'alert-success',
|
|
154
|
+
'warning': 'alert-warning',
|
|
155
|
+
'error': 'alert-error'
|
|
162
156
|
};
|
|
163
157
|
|
|
164
|
-
alert.className = `alert
|
|
158
|
+
alert.className = `alert ${typeClasses[type] || typeClasses['info']}`;
|
|
165
159
|
alert.innerHTML = `
|
|
166
160
|
<div class="flex justify-between items-center">
|
|
167
161
|
<span>${UIComponents.escapeHtml(message)}</span>
|
|
@@ -191,19 +185,16 @@ class UIComponents {
|
|
|
191
185
|
} = config;
|
|
192
186
|
|
|
193
187
|
const sizeClasses = {
|
|
194
|
-
'small': '
|
|
195
|
-
'medium': '
|
|
196
|
-
'large': '
|
|
188
|
+
'small': 'spinner-xs',
|
|
189
|
+
'medium': 'spinner-sm',
|
|
190
|
+
'large': 'spinner-md'
|
|
197
191
|
};
|
|
198
192
|
|
|
199
193
|
const container = document.createElement('div');
|
|
200
194
|
container.className = 'flex items-center gap-3 justify-center p-4';
|
|
201
195
|
container.innerHTML = `
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
<path d="M4 12a8 8 0 018-8" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
|
|
205
|
-
</svg>
|
|
206
|
-
<span class="text-gray-700 dark:text-gray-300">${UIComponents.escapeHtml(text)}</span>
|
|
196
|
+
<div class="spinner-simple spinner-primary ${sizeClasses[size] || sizeClasses['medium']}"></div>
|
|
197
|
+
<span class="text-base-content">${UIComponents.escapeHtml(text)}</span>
|
|
207
198
|
`;
|
|
208
199
|
return container;
|
|
209
200
|
}
|
|
@@ -227,9 +218,7 @@ class UIComponents {
|
|
|
227
218
|
}
|
|
228
219
|
|
|
229
220
|
html += `
|
|
230
|
-
<
|
|
231
|
-
<div class="progress-fill bg-blue-500 h-full transition-all" style="width: ${Math.min(100, Math.max(0, percentage))}%"></div>
|
|
232
|
-
</div>
|
|
221
|
+
<progress class="progress progress-primary progress-xs w-full" value="${Math.min(100, Math.max(0, percentage))}" max="100"></progress>
|
|
233
222
|
`;
|
|
234
223
|
|
|
235
224
|
container.innerHTML = html;
|
|
@@ -251,7 +240,7 @@ class UIComponents {
|
|
|
251
240
|
|
|
252
241
|
container.innerHTML = `
|
|
253
242
|
<details ${isOpen ? 'open' : ''}>
|
|
254
|
-
<summary class="cursor-pointer font-semibold hover:bg-
|
|
243
|
+
<summary class="cursor-pointer font-semibold hover:bg-base-200 px-2 py-1 rounded transition-colors">
|
|
255
244
|
${UIComponents.escapeHtml(title)}
|
|
256
245
|
</summary>
|
|
257
246
|
<div class="content mt-2 ml-4">
|
|
@@ -291,7 +280,7 @@ class UIComponents {
|
|
|
291
280
|
placeholder="${UIComponents.escapeHtml(placeholder)}"
|
|
292
281
|
value="${UIComponents.escapeHtml(value)}"
|
|
293
282
|
${required ? 'required' : ''}
|
|
294
|
-
class="
|
|
283
|
+
class="input input-block input-solid"
|
|
295
284
|
/>
|
|
296
285
|
`;
|
|
297
286
|
|
|
@@ -323,7 +312,7 @@ class UIComponents {
|
|
|
323
312
|
<select
|
|
324
313
|
name="${name}"
|
|
325
314
|
${required ? 'required' : ''}
|
|
326
|
-
class="
|
|
315
|
+
class="select select-block select-solid"
|
|
327
316
|
>
|
|
328
317
|
${options.map(opt => `
|
|
329
318
|
<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>
|
|
@@ -373,21 +362,21 @@ class UIComponents {
|
|
|
373
362
|
} = config;
|
|
374
363
|
|
|
375
364
|
const sizeClasses = {
|
|
376
|
-
'small': '
|
|
377
|
-
'medium': '
|
|
378
|
-
'large': '
|
|
365
|
+
'small': 'badge-sm',
|
|
366
|
+
'medium': 'badge-md',
|
|
367
|
+
'large': 'badge-lg'
|
|
379
368
|
};
|
|
380
369
|
|
|
381
370
|
const variantClasses = {
|
|
382
|
-
'default': '
|
|
383
|
-
'primary': '
|
|
384
|
-
'success': '
|
|
385
|
-
'warning': '
|
|
386
|
-
'error': '
|
|
371
|
+
'default': 'badge-flat',
|
|
372
|
+
'primary': 'badge-flat-primary',
|
|
373
|
+
'success': 'badge-flat-success',
|
|
374
|
+
'warning': 'badge-flat-warning',
|
|
375
|
+
'error': 'badge-flat-error'
|
|
387
376
|
};
|
|
388
377
|
|
|
389
378
|
const badge = document.createElement('span');
|
|
390
|
-
badge.className = `badge
|
|
379
|
+
badge.className = `badge ${sizeClasses[size] || sizeClasses['medium']} ${variantClasses[variant] || variantClasses['default']}`;
|
|
391
380
|
badge.textContent = label;
|
|
392
381
|
return badge;
|
|
393
382
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- Agent Metadata Panel with Status Badge -->
|
|
2
2
|
<div class="agent-metadata-card card" role="region" aria-label="Agent Status and Metadata">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header gap-3">
|
|
4
4
|
<div class="flex items-center gap-3">
|
|
5
|
-
<div class="
|
|
5
|
+
<div class="avatar avatar-ring avatar-square bg-primary text-white" aria-hidden="true">
|
|
6
6
|
{{ agentIcon }}
|
|
7
7
|
</div>
|
|
8
8
|
<div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Code Suggestion Panel with Before/After -->
|
|
2
2
|
<div class="code-suggestion-panel card" role="region" aria-label="Code suggestion">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<div class="flex-1">
|
|
5
5
|
<h4 class="font-semibold">{{ suggestionTitle }}</h4>
|
|
6
6
|
<p class="text-xs text-secondary mt-1">In {{ fileName }} at line {{ lineNumber }}</p>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</div>
|
|
41
41
|
|
|
42
42
|
<!-- Recovery Info -->
|
|
43
|
-
<div class="recovery-info text-xs text-secondary mt-3 pt-3
|
|
43
|
+
<div class="recovery-info text-xs text-secondary mt-3 pt-3 divider-y space-y-1">
|
|
44
44
|
<p><strong>Error ID:</strong> <code class="font-mono">{{ errorId }}</code></p>
|
|
45
45
|
<p><strong>Last Checkpoint:</strong> {{ checkpointTime }}</p>
|
|
46
46
|
{{ if suggestedAction }}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Error Stack Trace Display (Collapsible) -->
|
|
2
2
|
<div class="error-stack-trace">
|
|
3
3
|
<details class="stack-trace-accordion card">
|
|
4
|
-
<summary class="cursor-pointer font-semibold py-3 px-4 border-b flex items-center gap-2 hover:bg-
|
|
4
|
+
<summary class="cursor-pointer font-semibold py-3 px-4 border-b flex items-center gap-2 hover:bg-base-200">
|
|
5
5
|
<svg class="w-4 h-4 chevron" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
6
6
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"/>
|
|
7
7
|
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Error Summary Card -->
|
|
2
2
|
<div class="error-summary card" role="region" aria-label="Error summary">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<div class="flex-1">
|
|
5
5
|
<h4 class="font-semibold">Error: {{ errorType }}</h4>
|
|
6
6
|
<p class="text-sm text-secondary mt-1">{{ errorCode }}</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- File Diff Visualization Panel -->
|
|
2
2
|
<div class="file-diff-viewer card" role="region" aria-label="Code diff viewer">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<h4 class="font-semibold">Changes in {{ fileName }}</h4>
|
|
5
5
|
<div class="flex gap-2">
|
|
6
6
|
<button class="btn-icon" data-view="unified" title="Unified diff view" aria-label="Show unified diff">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- File Read Operation Display -->
|
|
2
2
|
<div class="file-read-panel card" role="region" aria-label="File read operation: {{ filePath }}">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header gap-3 mb-3 pb-3 border-b">
|
|
4
4
|
<div class="flex items-center gap-2 flex-1 min-w-0">
|
|
5
5
|
<svg class="w-4 h-4 text-primary flex-shrink-0" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
6
6
|
<path d="M5.5 13a3 3 0 01.369-1.618l1.83-1.83a3 3 0 015.604 0l.83 1.83A3 3 0 0113.5 13H11V9.413l1.293 1.293a1 1 0 001.414-1.414l-3-3a1 1 0 00-1.414 0l-3 3a1 1 0 001.414 1.414L9 9.414V13H5.5z"/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- File Write Operation Display with Before/After Comparison -->
|
|
2
2
|
<div class="file-write-panel card" role="region" aria-label="File write operation: {{ filePath }}">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header gap-3 mb-3 pb-3 border-b">
|
|
4
4
|
<div class="flex items-center gap-2 flex-1 min-w-0">
|
|
5
5
|
<svg class="w-4 h-4 text-primary flex-shrink-0" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
6
6
|
<path d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM15.657 14.243a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM11 17a1 1 0 102 0v-1a1 1 0 10-2 0v1zM5.757 15.657a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414l-.707.707zM2 10a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.757 4.343a1 1 0 00-1.414 1.414l.707.707a1 1 0 001.414-1.414l-.707-.707z"/>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<div class="diff-items space-y-3">
|
|
9
9
|
{{ for file in diffs }}
|
|
10
10
|
<details class="diff-item">
|
|
11
|
-
<summary class="cursor-pointer font-medium py-2 px-3 bg-
|
|
11
|
+
<summary class="cursor-pointer font-medium py-2 px-3 bg-base-200 hover:bg-base-300 rounded flex items-center justify-between">
|
|
12
12
|
<div class="flex items-center gap-2 flex-1 min-w-0">
|
|
13
13
|
<svg class="w-4 h-4 chevron" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
14
14
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Git Status Panel -->
|
|
2
2
|
<div class="git-status-panel card" role="region" aria-label="Git repository status">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<div>
|
|
5
5
|
<h4 class="font-semibold">{{ repoName }}</h4>
|
|
6
6
|
<p class="text-xs text-secondary">{{ currentBranch }} @ {{ commitHash }}</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Terminal-like Output Panel with ANSI Color Support -->
|
|
2
2
|
<div class="terminal-output-panel card" role="region" aria-label="Terminal output">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<div>
|
|
5
5
|
<h4 class="font-semibold text-sm">{{ commandName }}</h4>
|
|
6
6
|
<p class="text-xs text-secondary font-mono">$ {{ command }}</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Test Results Display -->
|
|
2
2
|
<div class="test-results-display card" role="region" aria-label="Test execution results">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header mb-3 pb-3 border-b">
|
|
4
4
|
<h4 class="font-semibold">Test Results</h4>
|
|
5
5
|
<div class="test-summary flex gap-2">
|
|
6
6
|
<span class="badge-result passed" aria-label="Passed tests">{{ passedCount }}</span>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<div class="test-list space-y-1">
|
|
34
34
|
{{ for suite in testSuites }}
|
|
35
35
|
<details class="test-suite">
|
|
36
|
-
<summary class="cursor-pointer py-2 px-3 rounded hover:bg-
|
|
36
|
+
<summary class="cursor-pointer py-2 px-3 rounded hover:bg-base-200 flex items-center gap-2">
|
|
37
37
|
<svg class="w-4 h-4 chevron" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
38
38
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"/>
|
|
39
39
|
</svg>
|