clay-server 2.13.0-beta.7 → 2.13.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/app.js CHANGED
@@ -634,6 +634,13 @@ import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } fro
634
634
  var mateColor = (targetUser.profile && targetUser.profile.avatarColor) || targetUser.avatarColor || "#7c3aed";
635
635
  document.body.style.setProperty("--mate-color", mateColor);
636
636
  document.body.classList.add("mate-dm-active");
637
+ // Build mate avatar URL for DM bubble injection
638
+ var mp = targetUser.profile || {};
639
+ var mateAvatarUrl = "https://api.dicebear.com/9.x/" + (mp.avatarStyle || targetUser.avatarStyle || "bottts") + "/svg?seed=" + encodeURIComponent(mp.avatarSeed || targetUser.avatarSeed || targetUser.id) + "&size=36";
640
+ var myUser = cachedAllUsers.find(function (u) { return u.id === myUserId; });
641
+ var myAvatarUrl = "https://api.dicebear.com/9.x/" + ((myUser && myUser.avatarStyle) || "thumbs") + "/svg?seed=" + encodeURIComponent((myUser && (myUser.avatarSeed || myUser.username)) || myUserId) + "&size=36";
642
+ document.body.dataset.mateAvatarUrl = mateAvatarUrl;
643
+ document.body.dataset.myAvatarUrl = myAvatarUrl;
637
644
  var titleBarContent = document.querySelector(".title-bar-content");
638
645
  if (titleBarContent) {
639
646
  titleBarContent.style.background = mateColor;
@@ -720,6 +727,11 @@ import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } fro
720
727
  // Reset chat title bar and mate color
721
728
  document.body.style.removeProperty("--mate-color");
722
729
  document.body.classList.remove("mate-dm-active");
730
+ delete document.body.dataset.mateAvatarUrl;
731
+ delete document.body.dataset.myAvatarUrl;
732
+ // Remove injected DM bubble avatars
733
+ var bubbleAvatars = messagesEl.querySelectorAll(".dm-bubble-avatar");
734
+ for (var ba = 0; ba < bubbleAvatars.length; ba++) bubbleAvatars[ba].remove();
723
735
  var titleBarContent = document.querySelector(".title-bar-content");
724
736
  if (titleBarContent) {
725
737
  titleBarContent.style.background = "";
@@ -2547,7 +2559,34 @@ import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } fro
2547
2559
  }
2548
2560
 
2549
2561
 
2550
- div.appendChild(bubble);
2562
+ // Mate DM: wrap avatar + header + bubble in DM-like layout
2563
+ if (document.body.classList.contains("mate-dm-active") && document.body.dataset.myAvatarUrl) {
2564
+ var avi = document.createElement("img");
2565
+ avi.className = "dm-bubble-avatar dm-bubble-avatar-me";
2566
+ avi.src = document.body.dataset.myAvatarUrl;
2567
+ div.appendChild(avi);
2568
+
2569
+ var contentWrap = document.createElement("div");
2570
+ contentWrap.className = "dm-bubble-content";
2571
+
2572
+ var header = document.createElement("div");
2573
+ header.className = "dm-bubble-header";
2574
+ var myU = cachedAllUsers.find(function (u) { return u.id === myUserId; });
2575
+ var nameSpan = document.createElement("span");
2576
+ nameSpan.className = "dm-bubble-name";
2577
+ nameSpan.textContent = myU ? myU.displayName : "Me";
2578
+ header.appendChild(nameSpan);
2579
+ var timeSpan = document.createElement("span");
2580
+ timeSpan.className = "dm-bubble-time";
2581
+ var nowH = new Date();
2582
+ timeSpan.textContent = String(nowH.getHours()).padStart(2, "0") + ":" + String(nowH.getMinutes()).padStart(2, "0");
2583
+ header.appendChild(timeSpan);
2584
+ contentWrap.appendChild(header);
2585
+ contentWrap.appendChild(bubble);
2586
+ div.appendChild(contentWrap);
2587
+ } else {
2588
+ div.appendChild(bubble);
2589
+ }
2551
2590
 
2552
2591
  // Action bar below bubble (icons visible on hover)
2553
2592
  var actions = document.createElement("div");
@@ -2581,7 +2620,40 @@ import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } fro
2581
2620
  currentMsgEl = document.createElement("div");
2582
2621
  currentMsgEl.className = "msg-assistant";
2583
2622
  currentMsgEl.dataset.turn = turnCounter;
2584
- currentMsgEl.innerHTML = '<div class="md-content" dir="auto"></div>';
2623
+ // Inject mate avatar + header for DM bubble style
2624
+ if (document.body.classList.contains("mate-dm-active") && document.body.dataset.mateAvatarUrl) {
2625
+ var avi = document.createElement("img");
2626
+ avi.className = "dm-bubble-avatar dm-bubble-avatar-mate";
2627
+ avi.src = document.body.dataset.mateAvatarUrl;
2628
+ currentMsgEl.appendChild(avi);
2629
+
2630
+ var contentWrap = document.createElement("div");
2631
+ contentWrap.className = "dm-bubble-content";
2632
+
2633
+ var header = document.createElement("div");
2634
+ header.className = "dm-bubble-header";
2635
+ var nameSpan = document.createElement("span");
2636
+ nameSpan.className = "dm-bubble-name";
2637
+ nameSpan.textContent = (dmTargetUser && dmTargetUser.displayName) || "Mate";
2638
+ header.appendChild(nameSpan);
2639
+ var timeSpan = document.createElement("span");
2640
+ timeSpan.className = "dm-bubble-time";
2641
+ var nowA = new Date();
2642
+ timeSpan.textContent = String(nowA.getHours()).padStart(2, "0") + ":" + String(nowA.getMinutes()).padStart(2, "0");
2643
+ header.appendChild(timeSpan);
2644
+ contentWrap.appendChild(header);
2645
+
2646
+ var mdDiv = document.createElement("div");
2647
+ mdDiv.className = "md-content";
2648
+ mdDiv.dir = "auto";
2649
+ contentWrap.appendChild(mdDiv);
2650
+ currentMsgEl.appendChild(contentWrap);
2651
+ } else {
2652
+ var mdDiv = document.createElement("div");
2653
+ mdDiv.className = "md-content";
2654
+ mdDiv.dir = "auto";
2655
+ currentMsgEl.appendChild(mdDiv);
2656
+ }
2585
2657
  addToMessages(currentMsgEl);
2586
2658
  currentFullText = "";
2587
2659
  }
@@ -151,6 +151,20 @@
151
151
  font-size: 48px;
152
152
  line-height: 1;
153
153
  }
154
+ .mate-intro-experimental {
155
+ display: inline-block;
156
+ font-size: 10px;
157
+ font-weight: 700;
158
+ letter-spacing: 0.05em;
159
+ text-transform: uppercase;
160
+ color: #f59e0b;
161
+ background: rgba(245, 158, 11, 0.12);
162
+ border: 1px solid rgba(245, 158, 11, 0.25);
163
+ border-radius: 10px;
164
+ padding: 2px 7px;
165
+ vertical-align: middle;
166
+ margin-right: 4px;
167
+ }
154
168
  .mate-intro-title {
155
169
  font-size: 22px;
156
170
  font-weight: 700;
@@ -1216,3 +1230,110 @@ body.mate-dm-active .notes-archive-header button:hover {
1216
1230
  color: #fff;
1217
1231
  background: rgba(255, 255, 255, 0.15);
1218
1232
  }
1233
+
1234
+ /* ==========================================================================
1235
+ Mate DM: Chat bubble style (messenger feel)
1236
+ ========================================================================== */
1237
+
1238
+ /* --- Avatar (injected by JS into .msg-user / .msg-assistant) --- */
1239
+ .dm-bubble-avatar {
1240
+ width: 36px;
1241
+ height: 36px;
1242
+ border-radius: 6px;
1243
+ flex-shrink: 0;
1244
+ display: none;
1245
+ object-fit: cover;
1246
+ margin-top: 2px;
1247
+ }
1248
+ body.mate-dm-active .dm-bubble-avatar {
1249
+ display: block;
1250
+ }
1251
+
1252
+ /* --- DM bubble header (name + time) --- */
1253
+ .dm-bubble-content {
1254
+ flex: 1;
1255
+ min-width: 0;
1256
+ }
1257
+ .dm-bubble-header {
1258
+ display: flex;
1259
+ align-items: baseline;
1260
+ gap: 8px;
1261
+ }
1262
+ .dm-bubble-name {
1263
+ font-weight: 700;
1264
+ font-size: 15px;
1265
+ color: var(--text);
1266
+ }
1267
+ .dm-bubble-time {
1268
+ font-size: 12px;
1269
+ color: var(--text-dimmer);
1270
+ }
1271
+
1272
+ /* --- Shared: Slack-style flat layout for both user & assistant --- */
1273
+ body.mate-dm-active .msg-user,
1274
+ body.mate-dm-active .msg-assistant {
1275
+ display: flex;
1276
+ flex-direction: row;
1277
+ align-items: flex-start;
1278
+ gap: 8px;
1279
+ max-width: 100%;
1280
+ padding: 4px 16px;
1281
+ margin: 0;
1282
+ border-radius: 0;
1283
+ }
1284
+ body.mate-dm-active .msg-user:hover,
1285
+ body.mate-dm-active .msg-assistant:hover {
1286
+ background: var(--bg-alt);
1287
+ }
1288
+
1289
+ /* --- User messages --- */
1290
+ body.mate-dm-active .msg-user {
1291
+ justify-content: flex-start; /* left-aligned like DM */
1292
+ }
1293
+ body.mate-dm-active .msg-user .dm-bubble-avatar-me {
1294
+ order: -1; /* avatar first (left) */
1295
+ }
1296
+ body.mate-dm-active .msg-user .bubble {
1297
+ background: none;
1298
+ border-radius: 0;
1299
+ padding: 0;
1300
+ max-width: 100%;
1301
+ font-size: 15px;
1302
+ line-height: 1.46;
1303
+ white-space: pre-wrap;
1304
+ word-wrap: break-word;
1305
+ }
1306
+ body.mate-dm-active .msg-user .msg-actions {
1307
+ display: none;
1308
+ }
1309
+
1310
+ /* --- Assistant messages --- */
1311
+ body.mate-dm-active .msg-assistant .dm-bubble-content {
1312
+ flex: 1;
1313
+ min-width: 0;
1314
+ }
1315
+ body.mate-dm-active .msg-assistant .md-content {
1316
+ background: none;
1317
+ border-radius: 0;
1318
+ padding: 0;
1319
+ }
1320
+
1321
+ /* Hide turn meta in mate DM */
1322
+ body.mate-dm-active .turn-meta {
1323
+ display: none;
1324
+ }
1325
+
1326
+ /* --- Interstitial elements: indent to align with message content (16px pad + 36px avatar + 8px gap = 60px) --- */
1327
+ body.mate-dm-active .thinking-item,
1328
+ body.mate-dm-active .tool-item,
1329
+ body.mate-dm-active .tool-group,
1330
+ body.mate-dm-active .plan-card,
1331
+ body.mate-dm-active .permission-container,
1332
+ body.mate-dm-active .ask-user-container,
1333
+ body.mate-dm-active .subagent-log,
1334
+ body.mate-dm-active .conflict-msg,
1335
+ body.mate-dm-active .context-overflow-msg,
1336
+ body.mate-dm-active .sys-msg,
1337
+ body.mate-dm-active .activity-inline {
1338
+ padding-left: 60px;
1339
+ }
@@ -1320,7 +1320,7 @@
1320
1320
  <div class="mate-intro-step"><span class="mate-intro-step-num">2</span> Have a short interview where your Mate gets to know you</div>
1321
1321
  <div class="mate-intro-step"><span class="mate-intro-step-num">3</span> Start talking</div>
1322
1322
  </div>
1323
- <p class="mate-intro-privacy">Mates run on Claude Code. No separate API keys or external services needed. Your conversations stay on your Clay server and are never stored elsewhere.</p>
1323
+ <p class="mate-intro-privacy">Mates run on Claude Code. No separate API keys or external services needed. Your conversations stay on your Clay server and are never stored elsewhere. <span class="mate-intro-experimental">Experimental</span></p>
1324
1324
  </div>
1325
1325
  </div>
1326
1326
  <!-- Step 1: Relationship -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.13.0-beta.7",
3
+ "version": "2.13.0-beta.9",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",