agentgui 1.0.145 → 1.0.146

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.145",
3
+ "version": "1.0.146",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/static/index.html CHANGED
@@ -524,12 +524,17 @@
524
524
  }
525
525
 
526
526
  .streaming-block-tool-use {
527
- margin: 0.5rem 0;
527
+ margin: 0.25rem 0;
528
528
  border-left: 3px solid #06b6d4;
529
529
  background: rgba(6,182,212,0.06);
530
530
  border-radius: 0 0.375rem 0.375rem 0;
531
531
  overflow: hidden;
532
532
  }
533
+ .streaming-block-tool-use.folded-tool {
534
+ border-left: none;
535
+ border-radius: 0.375rem;
536
+ margin: 0.125rem 0;
537
+ }
533
538
 
534
539
  .tool-use-header {
535
540
  padding: 0.5rem 0.75rem;
@@ -582,7 +587,7 @@
582
587
  html.dark .tool-input-pre { background: rgba(255,255,255,0.03); }
583
588
 
584
589
  .streaming-block-tool-result {
585
- margin: 0.25rem 0 0.5rem 0;
590
+ margin: 0.125rem 0 0.25rem 0;
586
591
  border-radius: 0.375rem;
587
592
  background: var(--color-bg-code);
588
593
  overflow: hidden;
@@ -1218,7 +1223,7 @@
1218
1223
 
1219
1224
  /* --- Tool Use Block --- */
1220
1225
  .block-tool-use {
1221
- margin-bottom: 0.75rem;
1226
+ margin-bottom: 0.25rem;
1222
1227
  border-radius: 0.5rem;
1223
1228
  background: #ecfeff;
1224
1229
  overflow: hidden;
@@ -1227,10 +1232,10 @@
1227
1232
  html.dark .block-tool-use { background: #0c1a24; }
1228
1233
 
1229
1234
  .block-tool-use .tool-header {
1230
- padding: 0.625rem 1rem;
1235
+ padding: 0.375rem 0.75rem;
1231
1236
  display: flex;
1232
1237
  align-items: center;
1233
- gap: 0.5rem;
1238
+ gap: 0.375rem;
1234
1239
  background: #cffafe;
1235
1240
  }
1236
1241
 
@@ -1263,7 +1268,7 @@
1263
1268
  html.dark .block-tool-use .tool-header .tool-name code { background: #164e63; }
1264
1269
 
1265
1270
  .block-tool-use .tool-params {
1266
- padding: 0.75rem 1rem;
1271
+ padding: 0.5rem 0.75rem;
1267
1272
  }
1268
1273
 
1269
1274
  .block-tool-use .tool-params .param-label {
@@ -1458,9 +1463,94 @@
1458
1463
  text-align: center;
1459
1464
  }
1460
1465
 
1466
+ /* --- Folded Tool Use (compact success-style bar) --- */
1467
+ .folded-tool {
1468
+ margin: 0.25rem 0;
1469
+ border-radius: 0.375rem;
1470
+ overflow: hidden;
1471
+ background: #f0fdf4;
1472
+ border: 1px solid #bbf7d0;
1473
+ }
1474
+ html.dark .folded-tool {
1475
+ background: #0a1f0f;
1476
+ border-color: #166534;
1477
+ }
1478
+ .folded-tool-bar {
1479
+ display: flex;
1480
+ align-items: center;
1481
+ gap: 0.375rem;
1482
+ padding: 0.3rem 0.625rem;
1483
+ cursor: pointer;
1484
+ user-select: none;
1485
+ list-style: none;
1486
+ font-size: 0.75rem;
1487
+ line-height: 1.3;
1488
+ background: #dcfce7;
1489
+ transition: background 0.15s;
1490
+ }
1491
+ html.dark .folded-tool-bar {
1492
+ background: #0f2b1a;
1493
+ }
1494
+ .folded-tool-bar::-webkit-details-marker { display: none; }
1495
+ .folded-tool-bar::marker { display: none; content: ''; }
1496
+ .folded-tool-bar::before {
1497
+ content: '\25b6';
1498
+ font-size: 0.5rem;
1499
+ margin-right: 0.125rem;
1500
+ display: inline-block;
1501
+ transition: transform 0.15s;
1502
+ color: #16a34a;
1503
+ flex-shrink: 0;
1504
+ }
1505
+ html.dark .folded-tool-bar::before { color: #4ade80; }
1506
+ .folded-tool[open] > .folded-tool-bar::before { transform: rotate(90deg); }
1507
+ .folded-tool-bar:hover { background: #bbf7d0; }
1508
+ html.dark .folded-tool-bar:hover { background: #14532d; }
1509
+ .folded-tool-icon {
1510
+ display: flex;
1511
+ align-items: center;
1512
+ color: #16a34a;
1513
+ width: 0.875rem;
1514
+ height: 0.875rem;
1515
+ flex-shrink: 0;
1516
+ }
1517
+ html.dark .folded-tool-icon { color: #4ade80; }
1518
+ .folded-tool-icon svg { width: 0.875rem; height: 0.875rem; }
1519
+ .folded-tool-name {
1520
+ font-weight: 600;
1521
+ color: #166534;
1522
+ font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
1523
+ font-size: 0.7rem;
1524
+ flex-shrink: 0;
1525
+ }
1526
+ html.dark .folded-tool-name { color: #86efac; }
1527
+ .folded-tool-desc {
1528
+ color: #15803d;
1529
+ font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
1530
+ font-size: 0.7rem;
1531
+ overflow: hidden;
1532
+ text-overflow: ellipsis;
1533
+ white-space: nowrap;
1534
+ flex: 1;
1535
+ min-width: 0;
1536
+ opacity: 0.8;
1537
+ }
1538
+ html.dark .folded-tool-desc { color: #4ade80; }
1539
+ .folded-tool-body {
1540
+ padding: 0.5rem 0.75rem;
1541
+ font-size: 0.75rem;
1542
+ border-top: 1px solid #bbf7d0;
1543
+ }
1544
+ html.dark .folded-tool-body { border-top-color: #166534; }
1545
+ .folded-tool-body .tool-input-pre {
1546
+ margin: 0;
1547
+ padding: 0.375rem 0.5rem;
1548
+ font-size: 0.7rem;
1549
+ }
1550
+
1461
1551
  /* --- Tool Result Block --- */
1462
1552
  .block-tool-result {
1463
- margin-bottom: 0.75rem;
1553
+ margin-bottom: 0.25rem;
1464
1554
  border-radius: 0.5rem;
1465
1555
  overflow: hidden;
1466
1556
  }
@@ -1471,7 +1561,7 @@
1471
1561
  html.dark .block-tool-result.result-error { background: #1c0f0f; }
1472
1562
 
1473
1563
  .block-tool-result .result-header {
1474
- padding: 0.5rem 1rem;
1564
+ padding: 0.3rem 0.75rem;
1475
1565
  display: flex;
1476
1566
  align-items: center;
1477
1567
  justify-content: space-between;
@@ -790,12 +790,14 @@ class AgentGUIClient {
790
790
  let inputHtml = '';
791
791
  if (block.input && Object.keys(block.input).length > 0) {
792
792
  const inputStr = JSON.stringify(block.input, null, 2);
793
- inputHtml = `<details class="tool-input-details"><summary class="tool-input-summary">Input</summary><pre class="tool-input-pre">${this.escapeHtml(inputStr)}</pre></details>`;
793
+ inputHtml = `<div class="folded-tool-body"><pre class="tool-input-pre">${this.escapeHtml(inputStr)}</pre></div>`;
794
794
  }
795
795
  const tn = block.name || 'unknown';
796
796
  const foldable = tn.startsWith('mcp__') || tn === 'Edit';
797
797
  if (foldable) {
798
- html += `<details class="streaming-block-tool-use"><summary class="tool-use-header" style="cursor:pointer;user-select:none;list-style:none;"><span class="tool-use-icon">&#9881;</span> <span class="tool-use-name">${this.escapeHtml(tn)}</span></summary>${inputHtml}</details>`;
798
+ const dName = typeof StreamingRenderer !== 'undefined' ? StreamingRenderer.getToolDisplayName(tn) : tn;
799
+ const tTitle = typeof StreamingRenderer !== 'undefined' && block.input ? StreamingRenderer.getToolTitle(tn, block.input) : '';
800
+ html += `<details class="streaming-block-tool-use folded-tool"><summary class="folded-tool-bar"><span class="folded-tool-name">${this.escapeHtml(dName)}</span>${tTitle ? `<span class="folded-tool-desc">${this.escapeHtml(tTitle)}</span>` : ''}</summary>${inputHtml}</details>`;
799
801
  } else {
800
802
  html += `<div class="streaming-block-tool-use"><div class="tool-use-header"><span class="tool-use-icon">&#9881;</span> <span class="tool-use-name">${this.escapeHtml(tn)}</span></div>${inputHtml}</div>`;
801
803
  }
@@ -1437,12 +1439,14 @@ class AgentGUIClient {
1437
1439
  let inputHtml = '';
1438
1440
  if (block.input && Object.keys(block.input).length > 0) {
1439
1441
  const inputStr = JSON.stringify(block.input, null, 2);
1440
- inputHtml = `<details class="tool-input-details"><summary class="tool-input-summary">Input</summary><pre class="tool-input-pre">${this.escapeHtml(inputStr)}</pre></details>`;
1442
+ inputHtml = `<div class="folded-tool-body"><pre class="tool-input-pre">${this.escapeHtml(inputStr)}</pre></div>`;
1441
1443
  }
1442
1444
  const tn2 = block.name || 'unknown';
1443
1445
  const foldable2 = tn2.startsWith('mcp__') || tn2 === 'Edit';
1444
1446
  if (foldable2) {
1445
- contentHtml += `<details class="streaming-block-tool-use"><summary class="tool-use-header" style="cursor:pointer;user-select:none;list-style:none;"><span class="tool-use-icon">&#9881;</span> <span class="tool-use-name">${this.escapeHtml(tn2)}</span></summary>${inputHtml}</details>`;
1447
+ const dName2 = typeof StreamingRenderer !== 'undefined' ? StreamingRenderer.getToolDisplayName(tn2) : tn2;
1448
+ const tTitle2 = typeof StreamingRenderer !== 'undefined' && block.input ? StreamingRenderer.getToolTitle(tn2, block.input) : '';
1449
+ contentHtml += `<details class="streaming-block-tool-use folded-tool"><summary class="folded-tool-bar"><span class="folded-tool-name">${this.escapeHtml(dName2)}</span>${tTitle2 ? `<span class="folded-tool-desc">${this.escapeHtml(tTitle2)}</span>` : ''}</summary>${inputHtml}</details>`;
1446
1450
  } else {
1447
1451
  contentHtml += `<div class="streaming-block-tool-use"><div class="tool-use-header"><span class="tool-use-icon">&#9881;</span> <span class="tool-use-name">${this.escapeHtml(tn2)}</span></div>${inputHtml}</div>`;
1448
1452
  }
@@ -623,6 +623,53 @@ class StreamingRenderer {
623
623
  /**
624
624
  * Render tool use block with smart parameter display
625
625
  */
626
+ getToolUseTitle(toolName, input) {
627
+ const normalizedName = toolName.replace(/^mcp__[^_]+__/, '');
628
+ if (normalizedName === 'Edit' && input.file_path) {
629
+ const parts = input.file_path.split('/');
630
+ const fileName = parts.pop();
631
+ const dir = parts.slice(-2).join('/');
632
+ return dir ? `${dir}/${fileName}` : fileName;
633
+ }
634
+ if (normalizedName === 'Read' && input.file_path) {
635
+ const parts = input.file_path.split('/');
636
+ return parts.pop();
637
+ }
638
+ if (normalizedName === 'Write' && input.file_path) {
639
+ const parts = input.file_path.split('/');
640
+ return parts.pop();
641
+ }
642
+ if (normalizedName === 'Bash' || normalizedName === 'bash') {
643
+ const cmd = input.command || input.commands || '';
644
+ const cmdText = typeof cmd === 'string' ? cmd : JSON.stringify(cmd);
645
+ return cmdText.length > 60 ? cmdText.substring(0, 57) + '...' : cmdText;
646
+ }
647
+ if (normalizedName === 'Glob' && input.pattern) return input.pattern;
648
+ if (normalizedName === 'Grep' && input.pattern) return input.pattern;
649
+ if (normalizedName === 'WebFetch' && input.url) {
650
+ try { return new URL(input.url).hostname; } catch (e) { return input.url.substring(0, 40); }
651
+ }
652
+ if (normalizedName === 'WebSearch' && input.query) return input.query.substring(0, 50);
653
+ if (input.file_path) return input.file_path.split('/').pop();
654
+ if (input.command) {
655
+ const c = typeof input.command === 'string' ? input.command : JSON.stringify(input.command);
656
+ return c.length > 50 ? c.substring(0, 47) + '...' : c;
657
+ }
658
+ if (input.query) return input.query.substring(0, 50);
659
+ return '';
660
+ }
661
+
662
+ getToolUseDisplayName(toolName) {
663
+ const normalized = toolName.replace(/^mcp__[^_]+__/, '');
664
+ const knownTools = ['Read','Write','Edit','Bash','Glob','Grep','WebFetch','WebSearch','TodoWrite','Task','NotebookEdit'];
665
+ if (knownTools.includes(normalized)) return normalized;
666
+ if (toolName.startsWith('mcp__')) {
667
+ const parts = toolName.split('__');
668
+ return parts.length >= 3 ? parts[2] : parts[parts.length - 1];
669
+ }
670
+ return normalized || toolName;
671
+ }
672
+
626
673
  renderBlockToolUse(block, context) {
627
674
  const toolName = block.name || 'unknown';
628
675
  const input = block.input || {};
@@ -630,17 +677,20 @@ class StreamingRenderer {
630
677
 
631
678
  if (shouldFold) {
632
679
  const details = document.createElement('details');
633
- details.className = 'block-tool-use';
680
+ details.className = 'block-tool-use folded-tool';
634
681
  const summary = document.createElement('summary');
635
- summary.className = 'tool-header';
636
- summary.style.cssText = 'cursor:pointer;user-select:none;list-style:none;';
682
+ summary.className = 'folded-tool-bar';
683
+ const displayName = this.getToolUseDisplayName(toolName);
684
+ const titleInfo = this.getToolUseTitle(toolName, input);
637
685
  summary.innerHTML = `
638
- <span class="tool-icon">${this.getToolIcon(toolName)}</span>
639
- <span class="tool-name"><code>${this.escapeHtml(toolName)}</code></span>
686
+ <span class="folded-tool-icon">${this.getToolIcon(toolName)}</span>
687
+ <span class="folded-tool-name">${this.escapeHtml(displayName)}</span>
688
+ ${titleInfo ? `<span class="folded-tool-desc">${this.escapeHtml(titleInfo)}</span>` : ''}
640
689
  `;
641
690
  details.appendChild(summary);
642
691
  if (Object.keys(input).length > 0) {
643
692
  const paramsDiv = document.createElement('div');
693
+ paramsDiv.className = 'folded-tool-body';
644
694
  paramsDiv.innerHTML = this.renderSmartParams(toolName, input);
645
695
  details.appendChild(paramsDiv);
646
696
  }
@@ -1004,6 +1054,33 @@ class StreamingRenderer {
1004
1054
  return `<details class="collapsible-code"><summary class="collapsible-code-summary">${summaryLabel}</summary>${codeHtml}</details>`;
1005
1055
  }
1006
1056
 
1057
+ static getToolDisplayName(toolName) {
1058
+ const normalized = toolName.replace(/^mcp__[^_]+__/, '');
1059
+ const knownTools = ['Read','Write','Edit','Bash','Glob','Grep','WebFetch','WebSearch','TodoWrite','Task','NotebookEdit'];
1060
+ if (knownTools.includes(normalized)) return normalized;
1061
+ if (toolName.startsWith('mcp__')) {
1062
+ const parts = toolName.split('__');
1063
+ return parts.length >= 3 ? parts[2] : parts[parts.length - 1];
1064
+ }
1065
+ return normalized || toolName;
1066
+ }
1067
+
1068
+ static getToolTitle(toolName, input) {
1069
+ const n = toolName.replace(/^mcp__[^_]+__/, '');
1070
+ if (n === 'Edit' && input.file_path) { const p = input.file_path.split('/'); const f = p.pop(); const d = p.slice(-2).join('/'); return d ? d+'/'+f : f; }
1071
+ if (n === 'Read' && input.file_path) return input.file_path.split('/').pop();
1072
+ if (n === 'Write' && input.file_path) return input.file_path.split('/').pop();
1073
+ if ((n === 'Bash' || n === 'bash') && (input.command || input.commands)) { const c = typeof (input.command||input.commands) === 'string' ? (input.command||input.commands) : JSON.stringify(input.command||input.commands); return c.length > 60 ? c.substring(0,57)+'...' : c; }
1074
+ if (n === 'Glob' && input.pattern) return input.pattern;
1075
+ if (n === 'Grep' && input.pattern) return input.pattern;
1076
+ if (n === 'WebFetch' && input.url) { try { return new URL(input.url).hostname; } catch(e) { return input.url.substring(0,40); } }
1077
+ if (n === 'WebSearch' && input.query) return input.query.substring(0,50);
1078
+ if (input.file_path) return input.file_path.split('/').pop();
1079
+ if (input.command) { const c = typeof input.command === 'string' ? input.command : JSON.stringify(input.command); return c.length > 50 ? c.substring(0,47)+'...' : c; }
1080
+ if (input.query) return input.query.substring(0,50);
1081
+ return '';
1082
+ }
1083
+
1007
1084
  /**
1008
1085
  * Static HTML version of parameter rendering
1009
1086
  */
package/static/styles.css CHANGED
@@ -281,10 +281,10 @@ html, body {
281
281
  .chat-messages {
282
282
  flex: 1;
283
283
  overflow-y: auto;
284
- padding: 2rem;
284
+ padding: 1rem 2rem;
285
285
  display: flex;
286
286
  flex-direction: column;
287
- gap: 1.5rem;
287
+ gap: 0.5rem;
288
288
  }
289
289
 
290
290
  .chat-context-header {
@@ -593,7 +593,7 @@ html, body {
593
593
  .message {
594
594
  display: flex;
595
595
  flex-wrap: wrap;
596
- gap: 1rem;
596
+ gap: 0.375rem;
597
597
  animation: slideUp 0.2s ease;
598
598
  width: 100%;
599
599
  }
@@ -631,7 +631,7 @@ html, body {
631
631
  max-width: 70%;
632
632
  display: flex;
633
633
  flex-direction: column;
634
- gap: 0.5rem;
634
+ gap: 0.25rem;
635
635
  }
636
636
 
637
637
  .stream-text-block {
@@ -788,7 +788,7 @@ html, body {
788
788
  border-radius: 0.5rem;
789
789
  overflow: visible;
790
790
  background: var(--bg-secondary);
791
- margin: 0.75rem 0;
791
+ margin: 0.25rem 0;
792
792
  }
793
793
 
794
794
  .html-header {
@@ -810,7 +810,7 @@ html, body {
810
810
  border-radius: 0.5rem;
811
811
  overflow-x: auto;
812
812
  background: var(--bg-tertiary);
813
- margin: 0.75rem 0;
813
+ margin: 0.25rem 0;
814
814
  font-family: 'Monaco', 'Courier New', monospace;
815
815
  font-size: 0.8rem;
816
816
  }
@@ -828,7 +828,7 @@ html, body {
828
828
  .collapsible-code {
829
829
  border-radius: 0.375rem;
830
830
  overflow: hidden;
831
- margin: 0.5rem 0;
831
+ margin: 0.25rem 0;
832
832
  border: 1px solid #334155;
833
833
  background: #1e293b;
834
834
  }
@@ -1271,7 +1271,7 @@ html, body {
1271
1271
  }
1272
1272
 
1273
1273
  .chat-messages {
1274
- padding: 1.5rem;
1274
+ padding: 0.75rem 1rem;
1275
1275
  }
1276
1276
 
1277
1277
  .chat-input-section {
@@ -1363,8 +1363,8 @@ html, body {
1363
1363
  /* Small height viewports */
1364
1364
  @media (max-height: 600px) {
1365
1365
  .chat-messages {
1366
- padding: 1rem;
1367
- gap: 0.75rem;
1366
+ padding: 0.75rem;
1367
+ gap: 0.375rem;
1368
1368
  }
1369
1369
 
1370
1370
  .chat-input-section {
@@ -1421,8 +1421,8 @@ html, body {
1421
1421
 
1422
1422
  @media (max-height: 500px) {
1423
1423
  .chat-messages {
1424
- padding: 0.75rem;
1425
- gap: 0.5rem;
1424
+ padding: 0.5rem;
1425
+ gap: 0.25rem;
1426
1426
  }
1427
1427
 
1428
1428
  .chat-input-section {
@@ -1663,8 +1663,8 @@ p code {
1663
1663
  .segment-tool-use {
1664
1664
  background: #f0f8ff;
1665
1665
  border-left: 4px solid #007acc;
1666
- padding: 1rem;
1667
- margin: 1rem 0;
1666
+ padding: 0.5rem;
1667
+ margin: 0.25rem 0;
1668
1668
  border-radius: 4px;
1669
1669
  }
1670
1670
 
@@ -1690,8 +1690,8 @@ p code {
1690
1690
  .segment-tool-result {
1691
1691
  background: #fff9e6;
1692
1692
  border-left: 4px solid #ffb300;
1693
- padding: 1rem;
1694
- margin: 1rem 0;
1693
+ padding: 0.5rem;
1694
+ margin: 0.25rem 0;
1695
1695
  border-radius: 4px;
1696
1696
  }
1697
1697
 
@@ -1744,12 +1744,12 @@ p code {
1744
1744
  .execution-blocks {
1745
1745
  display: flex;
1746
1746
  flex-direction: column;
1747
- gap: 0.75rem;
1747
+ gap: 0.25rem;
1748
1748
  width: 100%;
1749
1749
  }
1750
1750
 
1751
1751
  .message-block {
1752
- padding: 0.75rem 1rem;
1752
+ padding: 0.5rem 0.75rem;
1753
1753
  border-radius: 0.5rem;
1754
1754
  background: var(--bg-secondary);
1755
1755
  word-wrap: break-word;
@@ -1819,7 +1819,11 @@ p code {
1819
1819
  .block-tool-use {
1820
1820
  background: rgba(59, 130, 246, 0.05);
1821
1821
  border-radius: 0.5rem;
1822
- padding: 0.75rem;
1822
+ padding: 0.5rem;
1823
+ }
1824
+ .block-tool-use.folded-tool {
1825
+ padding: 0;
1826
+ background: none;
1823
1827
  }
1824
1828
 
1825
1829
  .tool-name {
@@ -1858,7 +1862,7 @@ p code {
1858
1862
  .block-tool-result {
1859
1863
  background: rgba(16, 185, 129, 0.05);
1860
1864
  border-radius: 0.5rem;
1861
- padding: 0.75rem;
1865
+ padding: 0.5rem;
1862
1866
  }
1863
1867
 
1864
1868
  .block-tool-result strong {