clay-server 2.14.0-beta.7 → 2.14.0-beta.9
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/lib/public/css/mates.css +87 -19
- package/lib/public/modules/tools.js +124 -12
- package/package.json +1 -1
package/lib/public/css/mates.css
CHANGED
|
@@ -1431,32 +1431,89 @@ body.mate-dm-active .mate-tool-group .tool-name {
|
|
|
1431
1431
|
color: var(--text-muted);
|
|
1432
1432
|
}
|
|
1433
1433
|
|
|
1434
|
-
/* --- Mate Permission: conversational
|
|
1434
|
+
/* --- Mate Permission: conversational chat bubble --- */
|
|
1435
1435
|
body.mate-dm-active .mate-permission {
|
|
1436
|
-
border
|
|
1437
|
-
border:
|
|
1436
|
+
border: none;
|
|
1437
|
+
border-radius: 0;
|
|
1438
|
+
background: none;
|
|
1439
|
+
box-shadow: none;
|
|
1440
|
+
padding: 4px 16px;
|
|
1441
|
+
}
|
|
1442
|
+
body.mate-dm-active .mate-permission:hover {
|
|
1438
1443
|
background: var(--bg-alt);
|
|
1439
|
-
overflow: hidden;
|
|
1440
1444
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
padding:
|
|
1445
|
+
.mate-permission-ask {
|
|
1446
|
+
font-size: 15px;
|
|
1447
|
+
line-height: 1.46;
|
|
1448
|
+
color: var(--text);
|
|
1449
|
+
padding-left: 36px; /* align with name (avatar 28px + gap 8px) */
|
|
1450
|
+
margin-bottom: 8px;
|
|
1446
1451
|
}
|
|
1447
|
-
.mate-permission-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
+
.mate-permission-details {
|
|
1453
|
+
padding-left: 36px;
|
|
1454
|
+
margin-bottom: 8px;
|
|
1455
|
+
font-size: 12px;
|
|
1456
|
+
color: var(--text-muted);
|
|
1452
1457
|
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1458
|
+
.mate-permission-details summary {
|
|
1459
|
+
cursor: pointer;
|
|
1460
|
+
user-select: none;
|
|
1456
1461
|
}
|
|
1457
|
-
|
|
1458
|
-
|
|
1462
|
+
.mate-permission-details pre {
|
|
1463
|
+
font-size: 11px;
|
|
1464
|
+
margin: 4px 0 0;
|
|
1465
|
+
padding: 8px;
|
|
1466
|
+
background: rgba(var(--overlay-rgb), 0.04);
|
|
1467
|
+
border-radius: 6px;
|
|
1468
|
+
overflow-x: auto;
|
|
1469
|
+
max-height: 200px;
|
|
1470
|
+
}
|
|
1471
|
+
.mate-permission-actions {
|
|
1472
|
+
display: flex;
|
|
1459
1473
|
gap: 6px;
|
|
1474
|
+
padding-left: 36px;
|
|
1475
|
+
padding-bottom: 4px;
|
|
1476
|
+
}
|
|
1477
|
+
.mate-permission-reply {
|
|
1478
|
+
padding: 5px 14px;
|
|
1479
|
+
border-radius: 16px;
|
|
1480
|
+
font-size: 13px;
|
|
1481
|
+
font-weight: 500;
|
|
1482
|
+
font-family: inherit;
|
|
1483
|
+
cursor: pointer;
|
|
1484
|
+
border: 1px solid var(--border);
|
|
1485
|
+
background: var(--bg-alt);
|
|
1486
|
+
color: var(--text);
|
|
1487
|
+
transition: background 0.15s, border-color 0.15s;
|
|
1488
|
+
}
|
|
1489
|
+
.mate-permission-reply:hover {
|
|
1490
|
+
border-color: var(--text-dimmer);
|
|
1491
|
+
background: rgba(var(--overlay-rgb), 0.06);
|
|
1492
|
+
}
|
|
1493
|
+
.mate-permission-allow {
|
|
1494
|
+
background: var(--accent, #6c5ce7);
|
|
1495
|
+
color: #fff;
|
|
1496
|
+
border-color: var(--accent, #6c5ce7);
|
|
1497
|
+
}
|
|
1498
|
+
.mate-permission-allow:hover {
|
|
1499
|
+
opacity: 0.9;
|
|
1500
|
+
background: var(--accent, #6c5ce7);
|
|
1501
|
+
border-color: var(--accent, #6c5ce7);
|
|
1502
|
+
}
|
|
1503
|
+
.mate-permission-deny {
|
|
1504
|
+
color: var(--text-muted);
|
|
1505
|
+
}
|
|
1506
|
+
/* Resolved state */
|
|
1507
|
+
body.mate-dm-active .mate-permission.resolved .mate-permission-actions {
|
|
1508
|
+
pointer-events: none;
|
|
1509
|
+
}
|
|
1510
|
+
body.mate-dm-active .mate-permission.resolved .mate-permission-reply {
|
|
1511
|
+
display: none;
|
|
1512
|
+
}
|
|
1513
|
+
body.mate-dm-active .mate-permission.resolved .permission-decision-label {
|
|
1514
|
+
font-size: 12px;
|
|
1515
|
+
color: var(--text-dimmer);
|
|
1516
|
+
padding-left: 36px;
|
|
1460
1517
|
}
|
|
1461
1518
|
|
|
1462
1519
|
/* --- Mate Activity: avatar + text (hidden, dots row is enough) --- */
|
|
@@ -1464,6 +1521,17 @@ body.mate-dm-active .activity-inline {
|
|
|
1464
1521
|
display: none;
|
|
1465
1522
|
}
|
|
1466
1523
|
|
|
1524
|
+
/* --- Mate AskUserQuestion: avatar + name header --- */
|
|
1525
|
+
.ask-user-mate-header {
|
|
1526
|
+
display: none;
|
|
1527
|
+
}
|
|
1528
|
+
body.mate-dm-active .ask-user-mate-header {
|
|
1529
|
+
display: flex;
|
|
1530
|
+
align-items: center;
|
|
1531
|
+
gap: 8px;
|
|
1532
|
+
margin-bottom: 8px;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1467
1535
|
/* --- Interstitial elements: indent to align with message content (16px pad + 36px avatar + 8px gap = 60px) --- */
|
|
1468
1536
|
body.mate-dm-active .thinking-item,
|
|
1469
1537
|
body.mate-dm-active .tool-item,
|
|
@@ -189,6 +189,19 @@ export function renderAskUserQuestion(toolId, input) {
|
|
|
189
189
|
container.className = "ask-user-container";
|
|
190
190
|
container.dataset.toolId = toolId;
|
|
191
191
|
|
|
192
|
+
// Mate DM: inject avatar + name header into ask-user container
|
|
193
|
+
if (ctx.isMateDm && ctx.isMateDm()) {
|
|
194
|
+
var mateName = ctx.getMateName();
|
|
195
|
+
var mateAvatar = ctx.getMateAvatarUrl();
|
|
196
|
+
var mateHeader = document.createElement("div");
|
|
197
|
+
mateHeader.className = "dm-bubble-header ask-user-mate-header";
|
|
198
|
+
mateHeader.innerHTML =
|
|
199
|
+
'<img class="dm-bubble-avatar" src="' + escapeHtml(mateAvatar) + '" alt="" style="display:block;width:28px;height:28px;border-radius:6px">' +
|
|
200
|
+
'<span class="dm-bubble-name">' + escapeHtml(mateName) + '</span>' +
|
|
201
|
+
'<span class="dm-bubble-time">' + String(new Date().getHours()).padStart(2, "0") + ":" + String(new Date().getMinutes()).padStart(2, "0") + '</span>';
|
|
202
|
+
container.appendChild(mateHeader);
|
|
203
|
+
}
|
|
204
|
+
|
|
192
205
|
var answers = {};
|
|
193
206
|
var multiSelections = {};
|
|
194
207
|
|
|
@@ -385,25 +398,22 @@ export function renderPermissionRequest(requestId, toolName, toolInput, decision
|
|
|
385
398
|
return;
|
|
386
399
|
}
|
|
387
400
|
|
|
401
|
+
// Mate DM: render as conversational chat bubble instead of formal dialog
|
|
402
|
+
if (ctx.isMateDm && ctx.isMateDm()) {
|
|
403
|
+
renderMatePermission(requestId, toolName, toolInput);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
388
407
|
var container = document.createElement("div");
|
|
389
408
|
container.className = "permission-container";
|
|
390
|
-
if (ctx.isMateDm()) container.classList.add("mate-permission");
|
|
391
409
|
container.dataset.requestId = requestId;
|
|
392
410
|
|
|
393
411
|
// Header
|
|
394
412
|
var header = document.createElement("div");
|
|
395
413
|
header.className = "permission-header";
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
header.innerHTML =
|
|
400
|
-
'<img class="mate-permission-avatar" src="' + escapeHtml(mateAvatar) + '" alt="">' +
|
|
401
|
-
'<span class="permission-title">' + escapeHtml(mateName) + ' wants to do something</span>';
|
|
402
|
-
} else {
|
|
403
|
-
header.innerHTML =
|
|
404
|
-
'<span class="permission-icon">' + iconHtml("shield") + '</span>' +
|
|
405
|
-
'<span class="permission-title">Permission Required</span>';
|
|
406
|
-
}
|
|
414
|
+
header.innerHTML =
|
|
415
|
+
'<span class="permission-icon">' + iconHtml("shield") + '</span>' +
|
|
416
|
+
'<span class="permission-title">Permission Required</span>';
|
|
407
417
|
|
|
408
418
|
// Body
|
|
409
419
|
var body = document.createElement("div");
|
|
@@ -629,6 +639,108 @@ function sendPlanResponse(container, requestId, decision, feedback) {
|
|
|
629
639
|
delete pendingPermissions[requestId];
|
|
630
640
|
}
|
|
631
641
|
|
|
642
|
+
function matePermissionVerb(toolName) {
|
|
643
|
+
switch (toolName) {
|
|
644
|
+
case "Write": return "write to";
|
|
645
|
+
case "Edit": return "edit";
|
|
646
|
+
case "Read": return "read";
|
|
647
|
+
case "Bash": return "run a command on";
|
|
648
|
+
case "Grep": return "search";
|
|
649
|
+
case "Glob": return "search for files in";
|
|
650
|
+
case "WebFetch": return "fetch";
|
|
651
|
+
case "WebSearch": return "search the web for";
|
|
652
|
+
default: return "use " + toolName + " on";
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
function matePermissionTarget(toolName, toolInput) {
|
|
657
|
+
if (!toolInput || typeof toolInput !== "object") return "";
|
|
658
|
+
switch (toolName) {
|
|
659
|
+
case "Write": case "Edit": case "Read": return shortPath(toolInput.file_path);
|
|
660
|
+
case "Bash": return toolInput.description || (toolInput.command || "").substring(0, 60);
|
|
661
|
+
case "Grep": return toolInput.pattern || "";
|
|
662
|
+
case "Glob": return toolInput.pattern || "";
|
|
663
|
+
case "WebFetch": return toolInput.url || "";
|
|
664
|
+
case "WebSearch": return toolInput.query || "";
|
|
665
|
+
default: return "";
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
function renderMatePermission(requestId, toolName, toolInput) {
|
|
670
|
+
var mateName = ctx.getMateName();
|
|
671
|
+
var mateAvatar = ctx.getMateAvatarUrl();
|
|
672
|
+
var verb = matePermissionVerb(toolName);
|
|
673
|
+
var target = matePermissionTarget(toolName, toolInput);
|
|
674
|
+
|
|
675
|
+
var container = document.createElement("div");
|
|
676
|
+
container.className = "permission-container mate-permission";
|
|
677
|
+
container.dataset.requestId = requestId;
|
|
678
|
+
|
|
679
|
+
// Chat bubble: avatar + name + time
|
|
680
|
+
var headerRow = document.createElement("div");
|
|
681
|
+
headerRow.className = "dm-bubble-header";
|
|
682
|
+
headerRow.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:6px";
|
|
683
|
+
headerRow.innerHTML =
|
|
684
|
+
'<img class="dm-bubble-avatar" src="' + escapeHtml(mateAvatar) + '" alt="" style="display:block;width:28px;height:28px;border-radius:6px">' +
|
|
685
|
+
'<span class="dm-bubble-name">' + escapeHtml(mateName) + '</span>' +
|
|
686
|
+
'<span class="dm-bubble-time">' + String(new Date().getHours()).padStart(2, "0") + ":" + String(new Date().getMinutes()).padStart(2, "0") + '</span>';
|
|
687
|
+
container.appendChild(headerRow);
|
|
688
|
+
|
|
689
|
+
// Conversational ask text
|
|
690
|
+
var askText = document.createElement("div");
|
|
691
|
+
askText.className = "mate-permission-ask";
|
|
692
|
+
var askMsg = "Can I " + verb + (target ? " " : "") + (target ? target : "") + "?";
|
|
693
|
+
askText.textContent = askMsg;
|
|
694
|
+
container.appendChild(askText);
|
|
695
|
+
|
|
696
|
+
// Collapsible details (subtle)
|
|
697
|
+
var details = document.createElement("details");
|
|
698
|
+
details.className = "mate-permission-details";
|
|
699
|
+
var detailsSummary = document.createElement("summary");
|
|
700
|
+
detailsSummary.textContent = "Details";
|
|
701
|
+
var detailsPre = document.createElement("pre");
|
|
702
|
+
detailsPre.textContent = JSON.stringify(toolInput, null, 2);
|
|
703
|
+
details.appendChild(detailsSummary);
|
|
704
|
+
details.appendChild(detailsPre);
|
|
705
|
+
container.appendChild(details);
|
|
706
|
+
|
|
707
|
+
// Quick reply buttons (chat-style)
|
|
708
|
+
var actions = document.createElement("div");
|
|
709
|
+
actions.className = "permission-actions mate-permission-actions";
|
|
710
|
+
|
|
711
|
+
var allowBtn = document.createElement("button");
|
|
712
|
+
allowBtn.className = "mate-permission-reply mate-permission-allow";
|
|
713
|
+
allowBtn.textContent = "Sure";
|
|
714
|
+
allowBtn.addEventListener("click", function () {
|
|
715
|
+
sendPermissionResponse(container, requestId, "allow");
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
var alwaysBtn = document.createElement("button");
|
|
719
|
+
alwaysBtn.className = "mate-permission-reply mate-permission-always";
|
|
720
|
+
alwaysBtn.textContent = "Always allow this";
|
|
721
|
+
alwaysBtn.addEventListener("click", function () {
|
|
722
|
+
sendPermissionResponse(container, requestId, "allow_always");
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
var denyBtn = document.createElement("button");
|
|
726
|
+
denyBtn.className = "mate-permission-reply mate-permission-deny";
|
|
727
|
+
denyBtn.textContent = "No";
|
|
728
|
+
denyBtn.addEventListener("click", function () {
|
|
729
|
+
sendPermissionResponse(container, requestId, "deny");
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
actions.appendChild(allowBtn);
|
|
733
|
+
actions.appendChild(alwaysBtn);
|
|
734
|
+
actions.appendChild(denyBtn);
|
|
735
|
+
container.appendChild(actions);
|
|
736
|
+
|
|
737
|
+
ctx.addToMessages(container);
|
|
738
|
+
pendingPermissions[requestId] = container;
|
|
739
|
+
refreshIcons();
|
|
740
|
+
ctx.setActivity(null);
|
|
741
|
+
ctx.scrollToBottom();
|
|
742
|
+
}
|
|
743
|
+
|
|
632
744
|
function sendPermissionResponse(container, requestId, decision) {
|
|
633
745
|
if (container.classList.contains("resolved")) return;
|
|
634
746
|
container.classList.add("resolved");
|