clay-server 2.31.0 → 2.32.0-beta.2

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.
Files changed (74) hide show
  1. package/lib/browser-mcp-server.js +32 -44
  2. package/lib/debate-mcp-server.js +14 -31
  3. package/lib/mcp-local.js +31 -1
  4. package/lib/project-connection.js +4 -2
  5. package/lib/project-filesystem.js +47 -1
  6. package/lib/project-http.js +75 -8
  7. package/lib/project-mcp.js +4 -0
  8. package/lib/project-sessions.js +88 -51
  9. package/lib/project-user-message.js +12 -7
  10. package/lib/project.js +204 -90
  11. package/lib/public/app.js +123 -448
  12. package/lib/public/codex-avatar.png +0 -0
  13. package/lib/public/css/debate.css +3 -2
  14. package/lib/public/css/filebrowser.css +91 -1
  15. package/lib/public/css/icon-strip.css +21 -5
  16. package/lib/public/css/input.css +181 -100
  17. package/lib/public/css/mates.css +43 -0
  18. package/lib/public/css/mention.css +48 -4
  19. package/lib/public/css/menus.css +1 -1
  20. package/lib/public/css/messages.css +2 -0
  21. package/lib/public/css/notifications-center.css +19 -0
  22. package/lib/public/index.html +46 -24
  23. package/lib/public/modules/app-connection.js +138 -37
  24. package/lib/public/modules/app-cursors.js +18 -17
  25. package/lib/public/modules/app-debate-ui.js +9 -9
  26. package/lib/public/modules/app-dm.js +170 -131
  27. package/lib/public/modules/app-favicon.js +28 -26
  28. package/lib/public/modules/app-header.js +79 -68
  29. package/lib/public/modules/app-home-hub.js +55 -47
  30. package/lib/public/modules/app-loop-ui.js +34 -18
  31. package/lib/public/modules/app-loop-wizard.js +6 -6
  32. package/lib/public/modules/app-messages.js +195 -152
  33. package/lib/public/modules/app-misc.js +23 -12
  34. package/lib/public/modules/app-notifications.js +97 -3
  35. package/lib/public/modules/app-panels.js +203 -49
  36. package/lib/public/modules/app-projects.js +159 -150
  37. package/lib/public/modules/app-rate-limit.js +5 -4
  38. package/lib/public/modules/app-rendering.js +149 -101
  39. package/lib/public/modules/app-skills-install.js +4 -4
  40. package/lib/public/modules/context-sources.js +12 -41
  41. package/lib/public/modules/dom-refs.js +21 -0
  42. package/lib/public/modules/filebrowser.js +173 -2
  43. package/lib/public/modules/input.js +86 -0
  44. package/lib/public/modules/mate-sidebar.js +38 -0
  45. package/lib/public/modules/mention.js +24 -6
  46. package/lib/public/modules/scheduler.js +1 -1
  47. package/lib/public/modules/sidebar-mates.js +66 -34
  48. package/lib/public/modules/sidebar-mobile.js +34 -30
  49. package/lib/public/modules/sidebar-projects.js +60 -57
  50. package/lib/public/modules/sidebar-sessions.js +75 -69
  51. package/lib/public/modules/sidebar.js +12 -20
  52. package/lib/public/modules/skills.js +8 -9
  53. package/lib/public/modules/sticky-notes.js +1 -2
  54. package/lib/public/modules/store.js +9 -2
  55. package/lib/public/modules/stt.js +4 -1
  56. package/lib/public/modules/tools.js +14 -9
  57. package/lib/sdk-bridge.js +511 -1113
  58. package/lib/sdk-message-processor.js +123 -134
  59. package/lib/sdk-worker.js +4 -0
  60. package/lib/server-dm.js +1 -0
  61. package/lib/server.js +86 -1
  62. package/lib/sessions.js +47 -36
  63. package/lib/ws-schema.js +2 -0
  64. package/lib/yoke/adapters/claude-worker.js +559 -0
  65. package/lib/yoke/adapters/claude.js +1418 -0
  66. package/lib/yoke/adapters/codex.js +968 -0
  67. package/lib/yoke/adapters/gemini.js +668 -0
  68. package/lib/yoke/codex-app-server.js +307 -0
  69. package/lib/yoke/index.js +199 -0
  70. package/lib/yoke/instructions.js +62 -0
  71. package/lib/yoke/interface.js +92 -0
  72. package/lib/yoke/mcp-bridge-server.js +294 -0
  73. package/lib/yoke/package.json +7 -0
  74. package/package.json +3 -1
@@ -6,8 +6,12 @@ import { iconHtml, refreshIcons } from './icons.js';
6
6
  import { openProjectSettings } from './project-settings.js';
7
7
  import { triggerShare } from './qrcode.js';
8
8
  import { parseEmojis } from './markdown.js';
9
-
10
- var _ctx = null;
9
+ import { store } from './store.js';
10
+ import { getWs } from './ws-ref.js';
11
+ import { closeSidebar } from './sidebar.js';
12
+ import { showIconTooltip, hideIconTooltip, closeUserCtxMenu, getCurrentDmUserId } from './sidebar-mates.js';
13
+ import { switchProject, openAddProjectModal, getCachedProjects } from './app-projects.js';
14
+ import { showHomeHub } from './app-home-hub.js';
11
15
 
12
16
  // --- Project state ---
13
17
  var cachedProjectList = [];
@@ -236,8 +240,7 @@ var EMOJI_CATEGORIES = [
236
240
  ]},
237
241
  ];
238
242
 
239
- export function initSidebarProjects(ctx) {
240
- _ctx = ctx;
243
+ export function initSidebarProjects() {
241
244
 
242
245
  // Close project ctx menu and emoji picker on document click
243
246
  document.addEventListener("click", function () {
@@ -249,35 +252,35 @@ export function initSidebarProjects(ctx) {
249
252
  var addBtn = document.getElementById("icon-strip-add");
250
253
  if (addBtn) {
251
254
  addBtn.addEventListener("click", function () {
252
- if (_ctx.openAddProjectModal) {
253
- _ctx.openAddProjectModal();
255
+ if (openAddProjectModal) {
256
+ openAddProjectModal();
254
257
  } else {
255
- var modal = _ctx.$("add-project-modal");
258
+ var modal = document.getElementById("add-project-modal");
256
259
  if (modal) modal.classList.remove("hidden");
257
260
  }
258
261
  });
259
- addBtn.addEventListener("mouseenter", function () { _ctx.showIconTooltip(addBtn, "Add project"); });
260
- addBtn.addEventListener("mouseleave", _ctx.hideIconTooltip);
262
+ addBtn.addEventListener("mouseenter", function () { showIconTooltip(addBtn, "Add project"); });
263
+ addBtn.addEventListener("mouseleave", hideIconTooltip);
261
264
  }
262
265
 
263
266
  var exploreBtn = document.getElementById("icon-strip-explore");
264
267
  if (exploreBtn) {
265
268
  exploreBtn.addEventListener("click", function () {
266
- var fileBrowserBtn = _ctx.$("file-browser-btn");
269
+ var fileBrowserBtn = document.getElementById("file-browser-btn");
267
270
  if (fileBrowserBtn) fileBrowserBtn.click();
268
271
  });
269
- exploreBtn.addEventListener("mouseenter", function () { _ctx.showIconTooltip(exploreBtn, "File browser"); });
270
- exploreBtn.addEventListener("mouseleave", _ctx.hideIconTooltip);
272
+ exploreBtn.addEventListener("mouseenter", function () { showIconTooltip(exploreBtn, "File browser"); });
273
+ exploreBtn.addEventListener("mouseleave", hideIconTooltip);
271
274
  }
272
275
 
273
276
  // Tooltip + click for home icon
274
277
  var homeIcon = document.querySelector(".icon-strip-home");
275
278
  if (homeIcon) {
276
- homeIcon.addEventListener("mouseenter", function () { _ctx.showIconTooltip(homeIcon, "Clay"); });
277
- homeIcon.addEventListener("mouseleave", _ctx.hideIconTooltip);
279
+ homeIcon.addEventListener("mouseenter", function () { showIconTooltip(homeIcon, "Clay"); });
280
+ homeIcon.addEventListener("mouseleave", hideIconTooltip);
278
281
  homeIcon.addEventListener("click", function (e) {
279
282
  e.preventDefault();
280
- if (_ctx.showHomeHub) _ctx.showHomeHub();
283
+ if (showHomeHub) showHomeHub();
281
284
  });
282
285
  homeIcon.style.cursor = "pointer";
283
286
  }
@@ -490,7 +493,7 @@ export function closeProjectCtxMenu() {
490
493
 
491
494
  function showIconCtxMenu(anchorEl, slug, name) {
492
495
  closeProjectCtxMenu();
493
- if (_ctx.closeUserCtxMenu) _ctx.closeUserCtxMenu();
496
+ if (closeUserCtxMenu) closeUserCtxMenu();
494
497
  closeEmojiPicker();
495
498
 
496
499
  var menu = document.createElement("div");
@@ -515,8 +518,8 @@ function showIconCtxMenu(anchorEl, slug, name) {
515
518
  removeWtItem.addEventListener("click", function (e) {
516
519
  e.stopPropagation();
517
520
  closeProjectCtxMenu();
518
- if (_ctx.ws && _ctx.connected) {
519
- _ctx.ws.send(JSON.stringify({ type: "remove_project_check", slug: slug, name: name || slug }));
521
+ if (getWs() && store.get('connected')) {
522
+ getWs().send(JSON.stringify({ type: "remove_project_check", slug: slug, name: name || slug }));
520
523
  }
521
524
  });
522
525
  menu.appendChild(removeWtItem);
@@ -553,7 +556,7 @@ function showIconCtxMenu(anchorEl, slug, name) {
553
556
 
554
557
  function showProjectCtxMenu(anchorEl, slug, name, icon, position) {
555
558
  closeProjectCtxMenu();
556
- if (_ctx.closeUserCtxMenu) _ctx.closeUserCtxMenu();
559
+ if (closeUserCtxMenu) closeUserCtxMenu();
557
560
  closeEmojiPicker();
558
561
 
559
562
  var menu = document.createElement("div");
@@ -571,14 +574,14 @@ function showProjectCtxMenu(anchorEl, slug, name, icon, position) {
571
574
  menu.appendChild(iconItem);
572
575
 
573
576
  // --- Project Settings ---
574
- if (!_ctx.permissions || _ctx.permissions.projectSettings !== false) {
577
+ if (!store.get('permissions') || store.get('permissions').projectSettings !== false) {
575
578
  var settingsItem = document.createElement("button");
576
579
  settingsItem.className = "project-ctx-item";
577
580
  settingsItem.innerHTML = iconHtml("settings") + " <span>Project Settings</span>";
578
581
  settingsItem.addEventListener("click", function (e) {
579
582
  e.stopPropagation();
580
583
  closeProjectCtxMenu();
581
- openProjectSettings(slug, { slug: slug, name: name, icon: icon, projectOwnerId: _ctx.projectOwnerId, ownerLocked: _ctx.ownerLocked });
584
+ openProjectSettings(slug, { slug: slug, name: name, icon: icon, projectOwnerId: store.get('currentProjectOwnerId'), ownerLocked: store.get('ownerLocked') });
582
585
  });
583
586
  menu.appendChild(settingsItem);
584
587
  }
@@ -599,9 +602,9 @@ function showProjectCtxMenu(anchorEl, slug, name, icon, position) {
599
602
  menu.appendChild(shareItem);
600
603
 
601
604
  // --- Manage Access ---
602
- if (_ctx.multiUser && slug.indexOf("--") === -1) {
603
- var isProjectOwner = _ctx.myUserId && _ctx.projectOwnerId && _ctx.myUserId === _ctx.projectOwnerId;
604
- var isAdmin = _ctx.permissions && _ctx.permissions.projectSettings !== false;
605
+ if (store.get('isMultiUserMode') && slug.indexOf("--") === -1) {
606
+ var isProjectOwner = store.get('myUserId') && store.get('currentProjectOwnerId') && store.get('myUserId') === store.get('currentProjectOwnerId');
607
+ var isAdmin = store.get('permissions') && store.get('permissions').projectSettings !== false;
605
608
  if (isProjectOwner || isAdmin) {
606
609
  var accessItem = document.createElement("button");
607
610
  accessItem.className = "project-ctx-item";
@@ -630,7 +633,7 @@ function showProjectCtxMenu(anchorEl, slug, name, icon, position) {
630
633
  });
631
634
  menu.appendChild(wtItem);
632
635
 
633
- if (!_ctx.permissions || _ctx.permissions.deleteProject !== false) {
636
+ if (!store.get('permissions') || store.get('permissions').deleteProject !== false) {
634
637
  var sep3 = document.createElement("div");
635
638
  sep3.className = "project-ctx-separator";
636
639
  menu.appendChild(sep3);
@@ -641,8 +644,8 @@ function showProjectCtxMenu(anchorEl, slug, name, icon, position) {
641
644
  deleteItem.addEventListener("click", function (e) {
642
645
  e.stopPropagation();
643
646
  closeProjectCtxMenu();
644
- if (_ctx.ws && _ctx.connected) {
645
- _ctx.ws.send(JSON.stringify({ type: "remove_project_check", slug: slug, name: name }));
647
+ if (getWs() && store.get('connected')) {
648
+ getWs().send(JSON.stringify({ type: "remove_project_check", slug: slug, name: name }));
646
649
  }
647
650
  });
648
651
  menu.appendChild(deleteItem);
@@ -698,8 +701,8 @@ function showEmojiPicker(slug, anchorEl) {
698
701
  removeBtn.addEventListener("click", function (e) {
699
702
  e.stopPropagation();
700
703
  closeEmojiPicker();
701
- if (_ctx.ws && _ctx.connected) {
702
- _ctx.ws.send(JSON.stringify({ type: "set_project_icon", slug: slug, icon: null }));
704
+ if (getWs() && store.get('connected')) {
705
+ getWs().send(JSON.stringify({ type: "set_project_icon", slug: slug, icon: null }));
703
706
  }
704
707
  });
705
708
  header.appendChild(removeBtn);
@@ -744,8 +747,8 @@ function showEmojiPicker(slug, anchorEl) {
744
747
  btn.addEventListener("click", function (e) {
745
748
  e.stopPropagation();
746
749
  closeEmojiPicker();
747
- if (_ctx.ws && _ctx.connected) {
748
- _ctx.ws.send(JSON.stringify({ type: "set_project_icon", slug: slug, icon: emoji }));
750
+ if (getWs() && store.get('connected')) {
751
+ getWs().send(JSON.stringify({ type: "set_project_icon", slug: slug, icon: emoji }));
749
752
  }
750
753
  });
751
754
  grid.appendChild(btn);
@@ -803,8 +806,8 @@ function showProjectRename(slug, currentName) {
803
806
  if (committed) return;
804
807
  committed = true;
805
808
  var newName = input.value.trim();
806
- if (newName && newName !== currentName && _ctx.ws && _ctx.connected) {
807
- _ctx.ws.send(JSON.stringify({ type: "set_project_title", slug: slug, title: newName }));
809
+ if (newName && newName !== currentName && getWs() && store.get('connected')) {
810
+ getWs().send(JSON.stringify({ type: "set_project_title", slug: slug, title: newName }));
808
811
  nameEl.textContent = newName;
809
812
  } else {
810
813
  nameEl.textContent = originalText;
@@ -837,8 +840,8 @@ function showTrashZone() {
837
840
  addBtn.parentNode.insertBefore(trash, addBtn.nextSibling);
838
841
  refreshIcons();
839
842
 
840
- trash.addEventListener("mouseenter", function () { _ctx.showIconTooltip(trash, "Remove project"); });
841
- trash.addEventListener("mouseleave", _ctx.hideIconTooltip);
843
+ trash.addEventListener("mouseenter", function () { showIconTooltip(trash, "Remove project"); });
844
+ trash.addEventListener("mouseleave", hideIconTooltip);
842
845
 
843
846
  trash.addEventListener("dragover", function (e) {
844
847
  e.preventDefault();
@@ -852,8 +855,8 @@ function showTrashZone() {
852
855
  e.preventDefault();
853
856
  trash.classList.remove("drag-hover");
854
857
  var slug = e.dataTransfer.getData("text/plain");
855
- if (slug && _ctx.ws && _ctx.connected) {
856
- _ctx.ws.send(JSON.stringify({ type: "remove_project_check", slug: slug }));
858
+ if (slug && getWs() && store.get('connected')) {
859
+ getWs().send(JSON.stringify({ type: "remove_project_check", slug: slug }));
857
860
  }
858
861
  });
859
862
  }
@@ -891,7 +894,7 @@ function setupDragHandlers(el, slug) {
891
894
  setTimeout(function () { ghost.remove(); }, 0);
892
895
 
893
896
  setTimeout(function () { el.classList.add("dragging"); }, 0);
894
- _ctx.hideIconTooltip();
897
+ hideIconTooltip();
895
898
  showTrashZone();
896
899
  });
897
900
 
@@ -935,8 +938,8 @@ function setupDragHandlers(el, slug) {
935
938
  if (!insertBefore) targetIdx++;
936
939
  slugs.splice(targetIdx, 0, draggedSlug);
937
940
 
938
- if (_ctx.ws && _ctx.connected) {
939
- _ctx.ws.send(JSON.stringify({ type: "reorder_projects", slugs: slugs }));
941
+ if (getWs() && store.get('connected')) {
942
+ getWs().send(JSON.stringify({ type: "reorder_projects", slugs: slugs }));
940
943
  }
941
944
  });
942
945
 
@@ -974,7 +977,7 @@ function groupProjects(projects) {
974
977
  // --- Icon item creation ---
975
978
 
976
979
  function createIconItem(p, currentSlug) {
977
- var currentDmUserId = _ctx.getCurrentDmUserId ? _ctx.getCurrentDmUserId() : null;
980
+ var currentDmUserId = getCurrentDmUserId ? getCurrentDmUserId() : null;
978
981
  var el = document.createElement("a");
979
982
  var isActive = p.slug === currentSlug && !currentDmUserId;
980
983
  el.className = "icon-strip-item" + (isActive ? " active" : "");
@@ -1013,14 +1016,14 @@ function createIconItem(p, currentSlug) {
1013
1016
  }
1014
1017
 
1015
1018
  (function (name, elem) {
1016
- elem.addEventListener("mouseenter", function () { _ctx.showIconTooltip(elem, name); });
1017
- elem.addEventListener("mouseleave", _ctx.hideIconTooltip);
1019
+ elem.addEventListener("mouseenter", function () { showIconTooltip(elem, name); });
1020
+ elem.addEventListener("mouseleave", hideIconTooltip);
1018
1021
  })(p.name, el);
1019
1022
 
1020
1023
  (function (slug) {
1021
1024
  el.addEventListener("click", function (e) {
1022
1025
  e.preventDefault();
1023
- if (_ctx.switchProject) _ctx.switchProject(slug);
1026
+ if (switchProject) switchProject(slug);
1024
1027
  });
1025
1028
  })(p.slug);
1026
1029
 
@@ -1127,8 +1130,8 @@ function showWorktreeModal(parentSlug, parentName) {
1127
1130
  createBtn.textContent = "Creating...";
1128
1131
  errorDiv.classList.remove("visible");
1129
1132
 
1130
- if (_ctx.ws && _ctx.connected) {
1131
- _ctx.ws.send(JSON.stringify({
1133
+ if (getWs() && store.get('connected')) {
1134
+ getWs().send(JSON.stringify({
1132
1135
  type: "create_worktree",
1133
1136
  branch: branch,
1134
1137
  dirName: dirName,
@@ -1140,10 +1143,10 @@ function showWorktreeModal(parentSlug, parentName) {
1140
1143
  var msg;
1141
1144
  try { msg = JSON.parse(event.data); } catch (e) { return; }
1142
1145
  if (msg.type === "create_worktree_result") {
1143
- _ctx.ws.removeEventListener("message", handler);
1146
+ getWs().removeEventListener("message", handler);
1144
1147
  if (msg.ok) {
1145
1148
  closeModal();
1146
- if (msg.slug && _ctx.switchProject) _ctx.switchProject(msg.slug);
1149
+ if (msg.slug && switchProject) switchProject(msg.slug);
1147
1150
  } else {
1148
1151
  createBtn.disabled = false;
1149
1152
  createBtn.textContent = "Create";
@@ -1152,7 +1155,7 @@ function showWorktreeModal(parentSlug, parentName) {
1152
1155
  }
1153
1156
  }
1154
1157
  };
1155
- _ctx.ws.addEventListener("message", handler);
1158
+ getWs().addEventListener("message", handler);
1156
1159
  }
1157
1160
 
1158
1161
  overlay.addEventListener("click", closeModal);
@@ -1178,7 +1181,7 @@ export function renderIconStrip(projects, currentSlug) {
1178
1181
  if (!container) return;
1179
1182
  container.innerHTML = "";
1180
1183
 
1181
- var currentDmUserId = _ctx.getCurrentDmUserId ? _ctx.getCurrentDmUserId() : null;
1184
+ var currentDmUserId = getCurrentDmUserId ? getCurrentDmUserId() : null;
1182
1185
  var grouped = groupProjects(projects);
1183
1186
 
1184
1187
  for (var i = 0; i < grouped.parents.length; i++) {
@@ -1269,15 +1272,15 @@ export function renderIconStrip(projects, currentSlug) {
1269
1272
  tooltipText += " (outside project path, cannot be accessed)";
1270
1273
  }
1271
1274
  (function (text, elem) {
1272
- elem.addEventListener("mouseenter", function () { _ctx.showIconTooltip(elem, text); });
1273
- elem.addEventListener("mouseleave", _ctx.hideIconTooltip);
1275
+ elem.addEventListener("mouseenter", function () { showIconTooltip(elem, text); });
1276
+ elem.addEventListener("mouseleave", hideIconTooltip);
1274
1277
  })(tooltipText, wtEl);
1275
1278
 
1276
1279
  if (isAccessible) {
1277
1280
  (function (slug) {
1278
1281
  wtEl.addEventListener("click", function (e) {
1279
1282
  e.preventDefault();
1280
- if (_ctx.switchProject) _ctx.switchProject(slug);
1283
+ if (switchProject) switchProject(slug);
1281
1284
  });
1282
1285
  })(wt.slug);
1283
1286
  } else {
@@ -1324,8 +1327,8 @@ export function renderIconStrip(projects, currentSlug) {
1324
1327
  e.stopPropagation();
1325
1328
  showWorktreeModal(parentSlug, parentName);
1326
1329
  });
1327
- btn.addEventListener("mouseenter", function () { _ctx.showIconTooltip(btn, "New worktree"); });
1328
- btn.addEventListener("mouseleave", _ctx.hideIconTooltip);
1330
+ btn.addEventListener("mouseenter", function () { showIconTooltip(btn, "New worktree"); });
1331
+ btn.addEventListener("mouseleave", hideIconTooltip);
1329
1332
  })(p.slug, p.name, addBtn);
1330
1333
  itemsContainer.appendChild(addBtn);
1331
1334
 
@@ -1425,8 +1428,8 @@ function createMobileProjectItem(p, currentSlug, isWorktree) {
1425
1428
  }
1426
1429
 
1427
1430
  el.addEventListener("click", function () {
1428
- if (_ctx.switchProject) _ctx.switchProject(p.slug);
1429
- if (_ctx.closeSidebar) _ctx.closeSidebar();
1431
+ if (switchProject) switchProject(p.slug);
1432
+ if (closeSidebar) closeSidebar();
1430
1433
  });
1431
1434
 
1432
1435
  return el;