clay-server 2.17.0 → 2.18.0-beta.10
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/daemon.js +2 -2
- package/lib/mates.js +85 -6
- package/lib/project.js +409 -4
- package/lib/public/app.js +307 -18
- package/lib/public/css/base.css +1 -0
- package/lib/public/css/input.css +5 -0
- package/lib/public/css/mates.css +5 -6
- package/lib/public/css/mention.css +226 -0
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/index.html +1 -0
- package/lib/public/modules/input.js +41 -0
- package/lib/public/modules/mention.js +652 -0
- package/lib/public/modules/notifications.js +9 -3
- package/lib/public/modules/scheduler.js +47 -14
- package/lib/public/style.css +1 -0
- package/lib/sdk-bridge.js +191 -0
- package/lib/sessions.js +13 -0
- package/package.json +1 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
@Mention Autocomplete Dropdown
|
|
3
|
+
========================================================================== */
|
|
4
|
+
|
|
5
|
+
#mention-menu {
|
|
6
|
+
display: none;
|
|
7
|
+
position: absolute;
|
|
8
|
+
bottom: 100%;
|
|
9
|
+
left: 0;
|
|
10
|
+
right: 0;
|
|
11
|
+
max-height: 240px;
|
|
12
|
+
overflow-y: auto;
|
|
13
|
+
background: var(--bg-alt);
|
|
14
|
+
border: 1px solid var(--border);
|
|
15
|
+
border-radius: 14px;
|
|
16
|
+
margin-bottom: 8px;
|
|
17
|
+
box-shadow: 0 -4px 24px rgba(var(--shadow-rgb), 0.4);
|
|
18
|
+
z-index: 10;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#mention-menu.visible { display: block; }
|
|
22
|
+
|
|
23
|
+
.mention-item {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: 10px 16px;
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
gap: 10px;
|
|
29
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.mention-item:last-child { border-bottom: none; }
|
|
33
|
+
|
|
34
|
+
.mention-item:hover,
|
|
35
|
+
.mention-item.active {
|
|
36
|
+
background: rgba(var(--overlay-rgb), 0.05);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.mention-item-avatar {
|
|
40
|
+
width: 24px;
|
|
41
|
+
height: 24px;
|
|
42
|
+
border-radius: 50%;
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.mention-item-name {
|
|
47
|
+
font-size: 14px;
|
|
48
|
+
font-weight: 600;
|
|
49
|
+
color: var(--text);
|
|
50
|
+
flex: 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.mention-item-dot {
|
|
54
|
+
width: 8px;
|
|
55
|
+
height: 8px;
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
flex-shrink: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ==========================================================================
|
|
61
|
+
@Mention Chip (in user bubble)
|
|
62
|
+
========================================================================== */
|
|
63
|
+
|
|
64
|
+
.mention-chip {
|
|
65
|
+
display: inline;
|
|
66
|
+
color: var(--accent);
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
background: rgba(var(--accent-rgb, 124, 58, 237), 0.12);
|
|
69
|
+
padding: 1px 5px;
|
|
70
|
+
border-radius: 4px;
|
|
71
|
+
font-size: inherit;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* ==========================================================================
|
|
75
|
+
@Mention Chip (in input area)
|
|
76
|
+
========================================================================== */
|
|
77
|
+
|
|
78
|
+
#input-mention-chip {
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
gap: 5px;
|
|
82
|
+
padding: 3px 6px 3px 4px;
|
|
83
|
+
margin: 0 0 4px 0;
|
|
84
|
+
border-radius: 6px;
|
|
85
|
+
background: color-mix(in srgb, var(--chip-color, #6c5ce7) 12%, transparent);
|
|
86
|
+
border: 1px solid color-mix(in srgb, var(--chip-color, #6c5ce7) 25%, transparent);
|
|
87
|
+
cursor: default;
|
|
88
|
+
flex-shrink: 0;
|
|
89
|
+
width: fit-content;
|
|
90
|
+
animation: chip-in 0.15s ease-out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@keyframes chip-in {
|
|
94
|
+
from { opacity: 0; transform: scale(0.9); }
|
|
95
|
+
to { opacity: 1; transform: scale(1); }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.input-mention-chip-avatar {
|
|
99
|
+
width: 18px;
|
|
100
|
+
height: 18px;
|
|
101
|
+
border-radius: 50%;
|
|
102
|
+
flex-shrink: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.input-mention-chip-name {
|
|
106
|
+
font-size: 13px;
|
|
107
|
+
font-weight: 600;
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.input-mention-chip-remove {
|
|
112
|
+
background: none;
|
|
113
|
+
border: none;
|
|
114
|
+
padding: 0 2px;
|
|
115
|
+
margin: 0;
|
|
116
|
+
cursor: pointer;
|
|
117
|
+
font-size: 15px;
|
|
118
|
+
line-height: 1;
|
|
119
|
+
color: var(--text-dimmer);
|
|
120
|
+
opacity: 0.6;
|
|
121
|
+
transition: opacity 0.1s;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.input-mention-chip-remove:hover {
|
|
125
|
+
opacity: 1;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ==========================================================================
|
|
129
|
+
@Mention Response Block
|
|
130
|
+
========================================================================== */
|
|
131
|
+
|
|
132
|
+
.msg-mention {
|
|
133
|
+
position: relative;
|
|
134
|
+
max-width: var(--content-width);
|
|
135
|
+
margin: 0 auto 24px;
|
|
136
|
+
padding: 4px 20px;
|
|
137
|
+
border-radius: 12px;
|
|
138
|
+
background: color-mix(in srgb, var(--mention-color, #6c5ce7) 6%, transparent);
|
|
139
|
+
transition: background 0.15s;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.msg-mention:hover {
|
|
143
|
+
background: color-mix(in srgb, var(--mention-color, #6c5ce7) 10%, transparent);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.mention-header {
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
gap: 6px;
|
|
150
|
+
margin-bottom: 4px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.mention-avatar {
|
|
154
|
+
width: 22px;
|
|
155
|
+
height: 22px;
|
|
156
|
+
border-radius: 50%;
|
|
157
|
+
flex-shrink: 0;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.mention-name {
|
|
161
|
+
font-size: 13px;
|
|
162
|
+
font-weight: 700;
|
|
163
|
+
color: var(--mention-color, #6c5ce7);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.mention-content {
|
|
167
|
+
font-size: 15px;
|
|
168
|
+
line-height: 1.7;
|
|
169
|
+
word-break: break-word;
|
|
170
|
+
color: var(--text);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Activity bar inside mention block */
|
|
174
|
+
.msg-mention .mention-activity-bar {
|
|
175
|
+
margin: 4px 0;
|
|
176
|
+
padding: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Copy hint ("Click to grab this") for mention blocks in project chat */
|
|
180
|
+
.msg-mention:hover .msg-copy-hint { opacity: 1; }
|
|
181
|
+
.msg-mention.copy-primed .msg-copy-hint { opacity: 1; color: var(--accent); }
|
|
182
|
+
.msg-mention.copy-done .msg-copy-hint { opacity: 1; color: var(--success); }
|
|
183
|
+
|
|
184
|
+
/* ==========================================================================
|
|
185
|
+
@Mention in Mate DM (DM-style layout)
|
|
186
|
+
========================================================================== */
|
|
187
|
+
|
|
188
|
+
/* Badge next to mate name */
|
|
189
|
+
.mention-badge {
|
|
190
|
+
font-size: 10px;
|
|
191
|
+
font-weight: 700;
|
|
192
|
+
letter-spacing: 0.5px;
|
|
193
|
+
color: var(--text-dimmer);
|
|
194
|
+
background: rgba(var(--overlay-rgb), 0.08);
|
|
195
|
+
padding: 1px 5px;
|
|
196
|
+
border-radius: 4px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* DM-style mention: override the DM mate avatar so it uses the mentioned mate's avatar */
|
|
200
|
+
.msg-mention-dm .dm-bubble-avatar-mate {
|
|
201
|
+
/* Inherits dm-bubble-avatar styling from mates.css */
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Activity bar inside DM-style mention */
|
|
205
|
+
.msg-mention-dm .mention-activity-bar {
|
|
206
|
+
margin: 4px 0;
|
|
207
|
+
padding: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* Error state */
|
|
211
|
+
.mention-error {
|
|
212
|
+
color: var(--danger, #e74c3c);
|
|
213
|
+
font-size: 13px;
|
|
214
|
+
font-style: italic;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* ==========================================================================
|
|
218
|
+
Mobile adjustments
|
|
219
|
+
========================================================================== */
|
|
220
|
+
|
|
221
|
+
@media (max-width: 768px) {
|
|
222
|
+
.msg-mention {
|
|
223
|
+
max-width: 100%;
|
|
224
|
+
padding: 4px 12px;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -1041,6 +1041,13 @@
|
|
|
1041
1041
|
#layout.sidebar-collapsed #user-island .user-island-actions {
|
|
1042
1042
|
display: none;
|
|
1043
1043
|
}
|
|
1044
|
+
/* Keep user island expanded in mate DM mode regardless of sidebar state */
|
|
1045
|
+
body.mate-dm-active #layout.sidebar-collapsed #user-island .user-island-info {
|
|
1046
|
+
display: block;
|
|
1047
|
+
}
|
|
1048
|
+
body.mate-dm-active #layout.sidebar-collapsed #user-island .user-island-actions {
|
|
1049
|
+
display: flex;
|
|
1050
|
+
}
|
|
1044
1051
|
|
|
1045
1052
|
|
|
1046
1053
|
|
package/lib/public/index.html
CHANGED
|
@@ -384,6 +384,7 @@
|
|
|
384
384
|
<button id="new-msg-btn" class="hidden" aria-label="Scroll to bottom"></button>
|
|
385
385
|
<div id="input-area">
|
|
386
386
|
<div id="input-wrapper">
|
|
387
|
+
<div id="mention-menu"></div>
|
|
387
388
|
<div id="slash-menu"></div>
|
|
388
389
|
<div id="suggestion-chips" class="hidden"></div>
|
|
389
390
|
<div id="input-row">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
2
2
|
import { setRewindMode, isRewindMode } from './rewind.js';
|
|
3
|
+
import { checkForMention, showMentionMenu, hideMentionMenu, isMentionMenuVisible, mentionMenuKeydown, setMentionAtIdx, parseMentionFromInput, clearMentionState, sendMention, renderMentionUser, removeMentionChip } from './mention.js';
|
|
3
4
|
|
|
4
5
|
var ctx;
|
|
5
6
|
|
|
@@ -86,6 +87,24 @@ export function sendMessage() {
|
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
// Check for @mention: if a mate was selected, route to mention handler
|
|
91
|
+
var mention = parseMentionFromInput(text);
|
|
92
|
+
if (mention) {
|
|
93
|
+
hideMentionMenu();
|
|
94
|
+
if (ctx.hideSuggestionChips) ctx.hideSuggestionChips();
|
|
95
|
+
var mentionPastes = pendingPastes.map(function (p) { return p.text; });
|
|
96
|
+
// Render user message with mention chip (same as history replay)
|
|
97
|
+
renderMentionUser({ mateName: mention.mateName, text: mention.text });
|
|
98
|
+
sendMention(mention.mateId, mention.text, mentionPastes);
|
|
99
|
+
clearMentionState();
|
|
100
|
+
ctx.inputEl.value = "";
|
|
101
|
+
sendInputSync();
|
|
102
|
+
clearPendingImages();
|
|
103
|
+
autoResize();
|
|
104
|
+
ctx.inputEl.focus();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
89
108
|
// Prepend file paths to text
|
|
90
109
|
var files = pendingFiles.slice();
|
|
91
110
|
if (files.length > 0) {
|
|
@@ -603,10 +622,20 @@ export function initInput(_ctx) {
|
|
|
603
622
|
var val = ctx.inputEl.value;
|
|
604
623
|
if (val.startsWith("/") && !val.includes(" ") && val.length > 1) {
|
|
605
624
|
showSlashMenu(val.substring(1));
|
|
625
|
+
hideMentionMenu();
|
|
606
626
|
} else if (val === "/") {
|
|
607
627
|
showSlashMenu("");
|
|
628
|
+
hideMentionMenu();
|
|
608
629
|
} else {
|
|
609
630
|
hideSlashMenu();
|
|
631
|
+
// Check for @mention
|
|
632
|
+
var mentionCheck = checkForMention(val, ctx.inputEl.selectionStart);
|
|
633
|
+
if (mentionCheck.active) {
|
|
634
|
+
setMentionAtIdx(mentionCheck.startIdx);
|
|
635
|
+
showMentionMenu(mentionCheck.query);
|
|
636
|
+
} else {
|
|
637
|
+
hideMentionMenu();
|
|
638
|
+
}
|
|
610
639
|
}
|
|
611
640
|
// Toggle send/stop button based on input content during processing
|
|
612
641
|
if (ctx.processing && ctx.setSendBtnMode) {
|
|
@@ -618,6 +647,11 @@ export function initInput(_ctx) {
|
|
|
618
647
|
ctx.inputEl.addEventListener("compositionend", function () { isComposing = false; });
|
|
619
648
|
|
|
620
649
|
ctx.inputEl.addEventListener("keydown", function (e) {
|
|
650
|
+
// @Mention menu keyboard navigation
|
|
651
|
+
if (isMentionMenuVisible()) {
|
|
652
|
+
if (mentionMenuKeydown(e)) return;
|
|
653
|
+
}
|
|
654
|
+
|
|
621
655
|
if (slashFiltered.length > 0 && ctx.slashMenu.classList.contains("visible")) {
|
|
622
656
|
if (e.key === "ArrowDown") {
|
|
623
657
|
e.preventDefault();
|
|
@@ -643,6 +677,13 @@ export function initInput(_ctx) {
|
|
|
643
677
|
}
|
|
644
678
|
}
|
|
645
679
|
|
|
680
|
+
// Backspace on empty input: remove mention chip if present
|
|
681
|
+
if (e.key === "Backspace" && ctx.inputEl.value === "" && document.getElementById("input-mention-chip")) {
|
|
682
|
+
e.preventDefault();
|
|
683
|
+
removeMentionChip();
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
646
687
|
// Ctrl+J: insert newline (like Claude CLI)
|
|
647
688
|
if (e.key === "j" && e.ctrlKey && !e.metaKey) {
|
|
648
689
|
e.preventDefault();
|