clay-server 2.14.0-beta.8 → 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 +76 -33
- package/lib/public/modules/tools.js +111 -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) --- */
|
|
@@ -1475,20 +1532,6 @@ body.mate-dm-active .ask-user-mate-header {
|
|
|
1475
1532
|
margin-bottom: 8px;
|
|
1476
1533
|
}
|
|
1477
1534
|
|
|
1478
|
-
/* --- Mate Permission: avatar + name header --- */
|
|
1479
|
-
body.mate-dm-active .mate-permission .permission-header {
|
|
1480
|
-
display: flex;
|
|
1481
|
-
align-items: center;
|
|
1482
|
-
gap: 10px;
|
|
1483
|
-
padding: 12px 16px 8px;
|
|
1484
|
-
}
|
|
1485
|
-
.mate-permission-avatar {
|
|
1486
|
-
width: 24px;
|
|
1487
|
-
height: 24px;
|
|
1488
|
-
border-radius: 6px;
|
|
1489
|
-
flex-shrink: 0;
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
1535
|
/* --- Interstitial elements: indent to align with message content (16px pad + 36px avatar + 8px gap = 60px) --- */
|
|
1493
1536
|
body.mate-dm-active .thinking-item,
|
|
1494
1537
|
body.mate-dm-active .tool-item,
|
|
@@ -398,25 +398,22 @@ export function renderPermissionRequest(requestId, toolName, toolInput, decision
|
|
|
398
398
|
return;
|
|
399
399
|
}
|
|
400
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
|
+
|
|
401
407
|
var container = document.createElement("div");
|
|
402
408
|
container.className = "permission-container";
|
|
403
|
-
if (ctx.isMateDm()) container.classList.add("mate-permission");
|
|
404
409
|
container.dataset.requestId = requestId;
|
|
405
410
|
|
|
406
411
|
// Header
|
|
407
412
|
var header = document.createElement("div");
|
|
408
413
|
header.className = "permission-header";
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
header.innerHTML =
|
|
413
|
-
'<img class="mate-permission-avatar" src="' + escapeHtml(mateAvatar) + '" alt="">' +
|
|
414
|
-
'<span class="permission-title">' + escapeHtml(mateName) + ' wants to do something</span>';
|
|
415
|
-
} else {
|
|
416
|
-
header.innerHTML =
|
|
417
|
-
'<span class="permission-icon">' + iconHtml("shield") + '</span>' +
|
|
418
|
-
'<span class="permission-title">Permission Required</span>';
|
|
419
|
-
}
|
|
414
|
+
header.innerHTML =
|
|
415
|
+
'<span class="permission-icon">' + iconHtml("shield") + '</span>' +
|
|
416
|
+
'<span class="permission-title">Permission Required</span>';
|
|
420
417
|
|
|
421
418
|
// Body
|
|
422
419
|
var body = document.createElement("div");
|
|
@@ -642,6 +639,108 @@ function sendPlanResponse(container, requestId, decision, feedback) {
|
|
|
642
639
|
delete pendingPermissions[requestId];
|
|
643
640
|
}
|
|
644
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
|
+
|
|
645
744
|
function sendPermissionResponse(container, requestId, decision) {
|
|
646
745
|
if (container.classList.contains("resolved")) return;
|
|
647
746
|
container.classList.add("resolved");
|