clay-server 3.8.1 → 4.0.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 (189) hide show
  1. package/lib/ask-user-mcp-server.js +5 -119
  2. package/lib/builtin-mates.js +6 -6
  3. package/lib/claude-hook-installer.js +15 -0
  4. package/lib/clay-history-mcp-server.js +62 -297
  5. package/lib/daemon.js +1 -1
  6. package/lib/debate-model-selection.js +119 -0
  7. package/lib/home-debate-tool-policy.js +164 -0
  8. package/lib/home-response-notifications.js +26 -0
  9. package/lib/mate-creation-mcp-server.js +55 -0
  10. package/lib/mate-ready-creation.js +95 -0
  11. package/lib/mates.js +2 -0
  12. package/lib/notes.js +2 -1
  13. package/lib/project-ask-user.js +64 -0
  14. package/lib/project-capsule-catalog.js +101 -0
  15. package/lib/project-connection.js +4 -0
  16. package/lib/project-debate-proposal.js +133 -17
  17. package/lib/project-debate.js +214 -110
  18. package/lib/project-delegated-follow-up.js +84 -0
  19. package/lib/project-delegated-session.js +53 -0
  20. package/lib/project-filesystem.js +7 -9
  21. package/lib/project-knowledge.js +1 -0
  22. package/lib/project-mate-creation-proposal.js +120 -0
  23. package/lib/project-memory.js +14 -7
  24. package/lib/project-models.js +157 -32
  25. package/lib/project-session-notes.js +2 -2
  26. package/lib/project-session-pair.js +8 -8
  27. package/lib/project-sessions.js +66 -51
  28. package/lib/project-vendor-login.js +397 -0
  29. package/lib/project-worker-proposal.js +25 -25
  30. package/lib/project-workspace-query.js +144 -0
  31. package/lib/project.js +349 -102
  32. package/lib/public/app.js +85 -42
  33. package/lib/public/css/avatar-imprints.css +0 -1
  34. package/lib/public/css/base.css +4 -0
  35. package/lib/public/css/capsule-ui.css +389 -0
  36. package/lib/public/css/command-palette.css +306 -6
  37. package/lib/public/css/home-capsule-library.css +243 -0
  38. package/lib/public/css/home-capsule-source.css +192 -0
  39. package/lib/public/css/home-debate-live.css +146 -0
  40. package/lib/public/css/home-debate-planning.css +125 -0
  41. package/lib/public/css/home-debates-archive.css +281 -0
  42. package/lib/public/css/home-hub.css +896 -405
  43. package/lib/public/css/home-mate-creation.css +34 -0
  44. package/lib/public/css/home-mate-model-picker.css +131 -0
  45. package/lib/public/css/home-mate-settings.css +344 -0
  46. package/lib/public/css/home-session-actions.css +265 -0
  47. package/lib/public/css/home-sidebar.css +667 -0
  48. package/lib/public/css/icon-strip.css +1 -2
  49. package/lib/public/css/mates.css +7 -34
  50. package/lib/public/css/pane.css +1 -1
  51. package/lib/public/css/playbook.css +0 -80
  52. package/lib/public/css/sticky-notes.css +53 -117
  53. package/lib/public/css/tui-attention.css +0 -44
  54. package/lib/public/css/workspace-assignment.css +45 -0
  55. package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
  56. package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
  57. package/lib/public/index.html +93 -74
  58. package/lib/public/modules/app-connection.js +10 -1
  59. package/lib/public/modules/app-dm.js +43 -160
  60. package/lib/public/modules/app-home-hub.js +328 -585
  61. package/lib/public/modules/app-message-cards.js +242 -0
  62. package/lib/public/modules/app-message-router.js +84 -0
  63. package/lib/public/modules/app-messages.js +102 -37
  64. package/lib/public/modules/app-notifications.js +8 -119
  65. package/lib/public/modules/app-projects.js +9 -1
  66. package/lib/public/modules/app-rendering.js +21 -602
  67. package/lib/public/modules/avatar-imprint.js +11 -8
  68. package/lib/public/modules/chat-bubble-renderer.js +152 -0
  69. package/lib/public/modules/chat-render-runtime.js +198 -0
  70. package/lib/public/modules/command-palette.js +225 -436
  71. package/lib/public/modules/dm-render.js +82 -0
  72. package/lib/public/modules/home-capsule-creation-intent.js +31 -0
  73. package/lib/public/modules/home-capsule-library.js +146 -0
  74. package/lib/public/modules/home-capsule-source.js +383 -0
  75. package/lib/public/modules/home-chat-identity.js +35 -0
  76. package/lib/public/modules/home-chat-scroll.js +77 -0
  77. package/lib/public/modules/home-chat-stream-state.js +34 -0
  78. package/lib/public/modules/home-composer-focus.js +25 -0
  79. package/lib/public/modules/home-conversations-sheet.js +179 -0
  80. package/lib/public/modules/home-debate-activity.js +48 -0
  81. package/lib/public/modules/home-debate-controls.js +295 -0
  82. package/lib/public/modules/home-debate-launch.js +41 -0
  83. package/lib/public/modules/home-debate-live.js +284 -0
  84. package/lib/public/modules/home-debate-models.js +73 -0
  85. package/lib/public/modules/home-debate-planning.js +335 -0
  86. package/lib/public/modules/home-debates-archive.js +279 -0
  87. package/lib/public/modules/home-dock-resize.js +74 -0
  88. package/lib/public/modules/home-dock.js +446 -0
  89. package/lib/public/modules/home-mate-chat.js +496 -0
  90. package/lib/public/modules/home-mate-creation.js +109 -0
  91. package/lib/public/modules/home-mate-model-picker.js +281 -0
  92. package/lib/public/modules/home-mate-selection.js +38 -0
  93. package/lib/public/modules/home-mate-settings-menu.js +131 -0
  94. package/lib/public/modules/home-mate-settings.js +383 -0
  95. package/lib/public/modules/home-session-actions.js +373 -0
  96. package/lib/public/modules/home-session-model-confirmation.js +13 -0
  97. package/lib/public/modules/home-shell.js +9 -0
  98. package/lib/public/modules/home-sidebar-chat-list.js +63 -0
  99. package/lib/public/modules/home-sidebar.js +158 -0
  100. package/lib/public/modules/home-sub-surface.js +19 -0
  101. package/lib/public/modules/home-surface-boot.js +68 -0
  102. package/lib/public/modules/home-surface.js +141 -0
  103. package/lib/public/modules/home-tools.js +271 -0
  104. package/lib/public/modules/markdown.js +50 -2
  105. package/lib/public/modules/mate-management.js +86 -0
  106. package/lib/public/modules/mate-wizard.js +0 -7
  107. package/lib/public/modules/mention.js +17 -19
  108. package/lib/public/modules/pane-bridge.js +9 -0
  109. package/lib/public/modules/profile.js +4 -5
  110. package/lib/public/modules/project-settings.js +34 -28
  111. package/lib/public/modules/project-switcher.js +11 -5
  112. package/lib/public/modules/project-workspace-assignment.js +23 -0
  113. package/lib/public/modules/search-clay-chat.js +402 -0
  114. package/lib/public/modules/server-settings.js +14 -12
  115. package/lib/public/modules/session-actions.js +1 -1
  116. package/lib/public/modules/sidebar-mates.js +56 -552
  117. package/lib/public/modules/sidebar-mobile.js +7 -64
  118. package/lib/public/modules/sidebar-presence.js +37 -0
  119. package/lib/public/modules/split-pair-ui.js +13 -13
  120. package/lib/public/modules/split-view.js +7 -0
  121. package/lib/public/modules/sticky-notes.js +7 -6
  122. package/lib/public/modules/tool-input-composition.js +48 -0
  123. package/lib/public/modules/tool-llm-status.js +167 -0
  124. package/lib/public/modules/tool-renderer-advanced.js +285 -0
  125. package/lib/public/modules/tool-renderer-chart.js +158 -0
  126. package/lib/public/modules/tool-renderer-semantics.js +35 -0
  127. package/lib/public/modules/tool-renderer.js +464 -0
  128. package/lib/public/modules/tool-runtime.js +309 -0
  129. package/lib/public/modules/tool-ui-evaluator.js +97 -0
  130. package/lib/public/modules/tool-ui-tree.js +21 -0
  131. package/lib/public/modules/tui-attention.js +10 -0
  132. package/lib/public/modules/user-settings.js +16 -23
  133. package/lib/public/modules/vendor-login.js +287 -0
  134. package/lib/public/modules/worker-proposal.js +2 -2
  135. package/lib/public/modules/workspace-assignment-card.js +149 -0
  136. package/lib/public/modules/workspace-assignment-routing.js +4 -0
  137. package/lib/public/style.css +13 -2
  138. package/lib/runtime-env.js +65 -0
  139. package/lib/sdk-bridge.js +120 -32
  140. package/lib/sdk-message-processor.js +10 -6
  141. package/lib/server-home-capsule-creation.js +36 -0
  142. package/lib/server-home-chat-events.js +287 -0
  143. package/lib/server-home-chat.js +518 -0
  144. package/lib/server-home-clay-entry.js +65 -0
  145. package/lib/server-home-clay-session-links.js +26 -0
  146. package/lib/server-home-debate-planning.js +214 -0
  147. package/lib/server-home-debates.js +137 -0
  148. package/lib/server-home-mate-creation.js +261 -0
  149. package/lib/server-home-models.js +241 -0
  150. package/lib/server-home-preferences.js +61 -0
  151. package/lib/server-mates.js +37 -0
  152. package/lib/server-tools.js +377 -0
  153. package/lib/server.js +111 -59
  154. package/lib/session-pair-mcp-server.js +6 -6
  155. package/lib/sessions.js +18 -3
  156. package/lib/tool-capsule-source.js +142 -0
  157. package/lib/tool-control-mcp-server.js +126 -0
  158. package/lib/tool-llm.js +48 -0
  159. package/lib/tool-storage.js +77 -0
  160. package/lib/tool-ui-spec-advanced.js +82 -0
  161. package/lib/tool-ui-spec.js +261 -0
  162. package/lib/tools-registry.js +286 -0
  163. package/lib/users-home-dock-preferences.js +77 -0
  164. package/lib/users-home-surface-preferences.js +99 -0
  165. package/lib/users-preferences.js +4 -7
  166. package/lib/users.js +12 -0
  167. package/lib/whats-new-content.js +3 -3
  168. package/lib/workspace-assignment-service.js +420 -0
  169. package/lib/workspace-query-mcp-server.js +154 -0
  170. package/lib/workspace-query-service.js +492 -0
  171. package/lib/ws-schema.js +93 -12
  172. package/lib/yoke/adapters/acp.js +2 -1
  173. package/lib/yoke/adapters/antigravity.js +2 -1
  174. package/lib/yoke/adapters/claude-worker.js +11 -4
  175. package/lib/yoke/adapters/claude.js +73 -43
  176. package/lib/yoke/adapters/codex.js +40 -10
  177. package/lib/yoke/adapters/kiro.js +2 -1
  178. package/lib/yoke/claude-user-input.js +38 -0
  179. package/lib/yoke/codex-app-server.js +20 -2
  180. package/lib/yoke/codex-user-input.js +64 -0
  181. package/lib/yoke/complete-once.js +164 -0
  182. package/lib/yoke/index.js +5 -1
  183. package/lib/yoke/interface.js +19 -0
  184. package/lib/yoke/mcp-bridge-server.js +2 -6
  185. package/lib/yoke/user-input.js +254 -0
  186. package/package.json +3 -2
  187. package/lib/public/css/home-chat.css +0 -380
  188. package/lib/public/modules/home-chat.js +0 -438
  189. package/lib/server-clay-home.js +0 -245
@@ -102,27 +102,25 @@ function buildMentionCandidates() {
102
102
  candidates.push(PLAIN_MENTION_CANDIDATES[pi]);
103
103
  }
104
104
 
105
- // Mates: only when the Mates UI is enabled
106
- if (store.get('matesEnabled') !== false) {
107
- var mates = ctx.matesList ? ctx.matesList() : [];
108
- for (var mi = 0; mi < mates.length; mi++) {
109
- var m = mates[mi];
110
- if (m.status === "interviewing") continue;
111
- candidates.push({
112
- kind: "mate",
113
- id: m.id,
114
- name: (m.profile && m.profile.displayName) || m.name || "Mate",
115
- color: (m.profile && m.profile.avatarColor) || "#5857fc",
116
- avatarSrc: mateAvatarUrl(m, 24),
117
- vendor: m.vendor || "claude",
118
- bio: m.bio || (m.profile && m.profile.bio) || "",
119
- primary: !!m.primary,
120
- raw: m,
121
- });
122
- }
105
+ // Mate mentions are a project collaboration capability, not a Mate DM.
106
+ var mates = ctx.matesList ? ctx.matesList() : [];
107
+ for (var mi = 0; mi < mates.length; mi++) {
108
+ var m = mates[mi];
109
+ if (m.status === "interviewing") continue;
110
+ candidates.push({
111
+ kind: "mate",
112
+ id: m.id,
113
+ name: (m.profile && m.profile.displayName) || m.name || "Mate",
114
+ color: (m.profile && m.profile.avatarColor) || "#5857fc",
115
+ avatarSrc: mateAvatarUrl(m, 24),
116
+ vendor: m.vendor || "claude",
117
+ bio: m.bio || (m.profile && m.profile.bio) || "",
118
+ primary: !!m.primary,
119
+ raw: m,
120
+ });
123
121
  }
124
122
 
125
- // Users: every other signed-in user (always available, even if Mates UI is off).
123
+ // Users: every other signed-in user.
126
124
  // We use the cached user list pushed by the server in projects_updated.
127
125
  var allUsers = ctx.allUsers ? ctx.allUsers() : [];
128
126
  var myId = ctx.myUserId ? ctx.myUserId() : null;
@@ -23,6 +23,15 @@ export function reportPaneContext(data) {
23
23
  }, window.location.origin);
24
24
  }
25
25
 
26
+ // A pane has no banner surface and no login modal of its own, so both panes
27
+ // hitting auth_required would otherwise race to start their own login flow.
28
+ // Hand the event to the parent shell, which owns the single flow.
29
+ export function forwardPaneAuthRequired(message) {
30
+ if (!store.get('paneMode') || window.parent === window) return false;
31
+ window.parent.postMessage({ type: "clay-pane-auth-required", message: message }, window.location.origin);
32
+ return true;
33
+ }
34
+
26
35
  export function forwardPaneMarkdownPresentation(message) {
27
36
  if (!store.get('paneMode') || window.parent === window) return false;
28
37
  window.parent.postMessage({ type: "clay-pane-present-markdown", message: message }, window.location.origin);
@@ -531,12 +531,11 @@ export function initProfile(_ctx) {
531
531
  applyTerminalFont(data.terminalFont.family, data.terminalFont.size);
532
532
  }
533
533
 
534
- // Apply Mates UI gate at boot so the sidebar avatars / DM picker
535
- // entry / home-hub strip are hidden before the user opens settings.
536
- // Default OFF: Mates is opt-in, so only enable when explicitly true.
534
+ // Apply the project-only Mate DM shortcut preference at boot. Home and
535
+ // the rest of the Mate capability surface remain available.
537
536
  var matesOn = data.matesEnabled === true;
538
- store.set({ matesEnabled: matesOn });
539
- if (document.body) document.body.classList.toggle('mates-disabled', !matesOn);
537
+ store.set({ projectMateDmsEnabled: matesOn });
538
+ if (document.body) document.body.classList.toggle('project-mate-dms-disabled', !matesOn);
540
539
  }).catch(function(err) {
541
540
  console.warn('[Profile] Failed to load:', err);
542
541
  });
@@ -560,6 +560,15 @@ export function handleInstructionsWrite(msg) {
560
560
 
561
561
  // ===== Environment (key-value list) =====
562
562
  var envSaveTimer = null;
563
+ var envStatusTimer = null;
564
+
565
+ function showEnvSaveStatus(elementId, text, duration) {
566
+ var saveStatus = document.getElementById(elementId);
567
+ if (!saveStatus) return;
568
+ if (envStatusTimer) clearTimeout(envStatusTimer);
569
+ saveStatus.textContent = text;
570
+ envStatusTimer = setTimeout(function () { saveStatus.textContent = ""; }, duration);
571
+ }
563
572
 
564
573
  function loadEnvironment() {
565
574
  var saveStatus = document.getElementById("ps-env-save-status");
@@ -571,9 +580,6 @@ function loadEnvironment() {
571
580
  }
572
581
 
573
582
  export function handleProjectEnv(msg) {
574
- var notice = document.getElementById("ps-env-override-notice");
575
- if (notice) notice.classList.toggle("hidden", !msg.hasEnvrc);
576
-
577
583
  // Parse envrc string into key-value pairs
578
584
  var list = document.getElementById("ps-env-list");
579
585
  if (!list) return;
@@ -606,9 +612,10 @@ export function parseEnvString(str) {
606
612
  if (eq === -1) continue;
607
613
  var key = line.substring(0, eq).trim();
608
614
  var val = line.substring(eq + 1).trim();
609
- // Strip surrounding quotes
610
- if ((val.charAt(0) === '"' && val.charAt(val.length - 1) === '"') ||
611
- (val.charAt(0) === "'" && val.charAt(val.length - 1) === "'")) {
615
+ // Saved values are JSON-quoted so shell metacharacters remain data.
616
+ if (val.charAt(0) === '"' && val.charAt(val.length - 1) === '"') {
617
+ try { val = JSON.parse(val); } catch (e) { val = val.substring(1, val.length - 1); }
618
+ } else if (val.charAt(0) === "'" && val.charAt(val.length - 1) === "'") {
612
619
  val = val.substring(1, val.length - 1);
613
620
  }
614
621
  if (key) pairs.push({ key: key, value: val });
@@ -616,6 +623,10 @@ export function parseEnvString(str) {
616
623
  return pairs;
617
624
  }
618
625
 
626
+ export function serializeEnvValue(value) {
627
+ return JSON.stringify(value == null ? "" : String(value));
628
+ }
629
+
619
630
  function buildEnvString() {
620
631
  var list = document.getElementById("ps-env-list");
621
632
  if (!list) return "";
@@ -626,7 +637,7 @@ function buildEnvString() {
626
637
  var valInput = rows[i].querySelector(".ps-env-val");
627
638
  var key = keyInput ? keyInput.value.trim() : "";
628
639
  var val = valInput ? valInput.value : "";
629
- if (key) lines.push("export " + key + "=" + val);
640
+ if (key) lines.push("export " + key + "=" + serializeEnvValue(val));
630
641
  }
631
642
  return lines.join("\n");
632
643
  }
@@ -719,28 +730,30 @@ function autoSaveEnv() {
719
730
  var envrc = buildEnvString();
720
731
  if (ctx.ws && ctx.connected) {
721
732
  ctx.ws.send(JSON.stringify({ type: "set_project_env", slug: currentSlug, envrc: envrc }));
722
- var saveStatus = document.getElementById("ps-env-save-status");
723
- if (saveStatus) {
724
- saveStatus.textContent = "Saved";
725
- setTimeout(function () { saveStatus.textContent = ""; }, 2000);
726
- }
733
+ showEnvSaveStatus("ps-env-save-status", "Saving...", 2000);
727
734
  }
728
735
  }, 800);
729
736
  }
730
737
 
731
738
  export function handleProjectEnvSaved(msg) {
732
- var saveStatus = document.getElementById("ps-env-save-status");
733
- if (!saveStatus) return;
734
739
  if (msg.ok) {
735
- saveStatus.textContent = "Saved";
736
- setTimeout(function () { saveStatus.textContent = ""; }, 2000);
740
+ showEnvSaveStatus("ps-env-save-status", msg.timing || "Saved", 5000);
737
741
  } else {
738
- saveStatus.textContent = "Error: " + (msg.error || "Failed to save");
742
+ showEnvSaveStatus("ps-env-save-status", "Error: " + (msg.error || "Failed to save"), 5000);
739
743
  }
740
744
  }
741
745
 
742
746
  // ===== Shared Environment (via tabs) =====
743
747
  var sharedEnvSaveTimer = null;
748
+ var sharedEnvStatusTimer = null;
749
+
750
+ function showSharedEnvSaveStatus(text, duration) {
751
+ var saveStatus = document.getElementById("ps-shared-env-save-status");
752
+ if (!saveStatus) return;
753
+ if (sharedEnvStatusTimer) clearTimeout(sharedEnvStatusTimer);
754
+ saveStatus.textContent = text;
755
+ sharedEnvStatusTimer = setTimeout(function () { saveStatus.textContent = ""; }, duration);
756
+ }
744
757
 
745
758
  function loadSharedEnv() {
746
759
  var saveStatus = document.getElementById("ps-shared-env-save-status");
@@ -764,13 +777,10 @@ export function handleProjectSharedEnv(msg) {
764
777
  }
765
778
 
766
779
  export function handleProjectSharedEnvSaved(msg) {
767
- var saveStatus = document.getElementById("ps-shared-env-save-status");
768
- if (!saveStatus) return;
769
780
  if (msg.ok) {
770
- saveStatus.textContent = "Saved";
771
- setTimeout(function () { saveStatus.textContent = ""; }, 2000);
781
+ showSharedEnvSaveStatus(msg.timing || "Saved", 5000);
772
782
  } else {
773
- saveStatus.textContent = "Error: " + (msg.error || "Failed to save");
783
+ showSharedEnvSaveStatus("Error: " + (msg.error || "Failed to save"), 5000);
774
784
  }
775
785
  }
776
786
 
@@ -784,7 +794,7 @@ function buildSharedEnvString() {
784
794
  var valInput = rows[i].querySelector(".ps-env-val");
785
795
  var key = keyInput ? keyInput.value.trim() : "";
786
796
  var val = valInput ? valInput.value : "";
787
- if (key) lines.push("export " + key + "=" + val);
797
+ if (key) lines.push("export " + key + "=" + serializeEnvValue(val));
788
798
  }
789
799
  return lines.join("\n");
790
800
  }
@@ -873,11 +883,7 @@ function autoSaveSharedEnv() {
873
883
  var envrc = buildSharedEnvString();
874
884
  if (ctx.ws && ctx.connected) {
875
885
  ctx.ws.send(JSON.stringify({ type: "set_shared_env", envrc: envrc }));
876
- var saveStatus = document.getElementById("ps-shared-env-save-status");
877
- if (saveStatus) {
878
- saveStatus.textContent = "Saved";
879
- setTimeout(function () { saveStatus.textContent = ""; }, 2000);
880
- }
886
+ showSharedEnvSaveStatus("Saving...", 2000);
881
887
  }
882
888
  }, 800);
883
889
  }
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // Two modes share the same overlay:
4
4
  // Cmd/Ctrl+E → projects only (non-Mate), activates via switchProject
5
- // Cmd/Ctrl+M → Mates only, activates via openDm
5
+ // Cmd/Ctrl+M → Mates only, activates in the home conversation pane
6
6
  //
7
7
  // While the modifier is still held, repeating the same shortcut cycles
8
8
  // forward and Shift cycles back. Releasing the modifier commits —
@@ -16,7 +16,8 @@
16
16
  import { store } from './store.js';
17
17
  import { refreshIcons } from './icons.js';
18
18
  import { getCachedProjects, switchProject } from './app-projects.js';
19
- import { openDm } from './app-dm.js';
19
+ import { showHomeHub } from './app-home-hub.js';
20
+ import { openHomeChat } from './home-mate-chat.js';
20
21
  import { mateAvatarUrl } from './avatar.js';
21
22
  import { parseEmojis } from './markdown.js';
22
23
  import { isExternalWorktree, externalWorktreeTooltip, appendExternalWorktreeBadge } from './worktree-location.js';
@@ -33,6 +34,7 @@ var _entries = [];
33
34
 
34
35
  export function openSwitcherForMode(mode) {
35
36
  if (mode !== 'project' && mode !== 'mate') return;
37
+ if (mode === 'mate' && store.get('projectMateDmsEnabled') === false) return;
36
38
  if (_open) closeSwitcher(false);
37
39
  openSwitcher(mode);
38
40
  }
@@ -93,11 +95,11 @@ export function initProjectSwitcher() {
93
95
  function refreshMateHintVisibility() {
94
96
  if (!mateHint) return;
95
97
  var mates = store.get('cachedMatesList') || [];
96
- mateHint.classList.toggle('hidden', mates.length === 0);
98
+ mateHint.classList.toggle('hidden', mates.length === 0 || store.get('projectMateDmsEnabled') === false);
97
99
  }
98
100
  refreshMateHintVisibility();
99
101
  store.subscribe(function (state, prev) {
100
- if (state.cachedMatesList !== prev.cachedMatesList) refreshMateHintVisibility();
102
+ if (state.cachedMatesList !== prev.cachedMatesList || state.projectMateDmsEnabled !== prev.projectMateDmsEnabled) refreshMateHintVisibility();
101
103
  });
102
104
  }
103
105
 
@@ -143,6 +145,7 @@ function handleKeyDown(e) {
143
145
  // same shortcut cycles.
144
146
  if (isMod && (k === 'e' || k === 'm')) {
145
147
  var requestedMode = k === 'e' ? 'project' : 'mate';
148
+ if (requestedMode === 'mate' && store.get('projectMateDmsEnabled') === false) return;
146
149
  e.preventDefault();
147
150
  e.stopPropagation();
148
151
  if (!_open) {
@@ -298,7 +301,10 @@ function closeSwitcher(commit) {
298
301
  var entry = _entries[_highlightedIndex];
299
302
  if (!entry || entry.disabled) return;
300
303
  if (_mode === 'mate') {
301
- if (entry.key !== currentActiveKey()) openDm(entry.key);
304
+ if (entry.key !== currentActiveKey()) {
305
+ showHomeHub();
306
+ openHomeChat(entry.key);
307
+ }
302
308
  } else {
303
309
  if (entry.key !== store.get('currentSlug')) switchProject(entry.key);
304
310
  }
@@ -0,0 +1,23 @@
1
+ import { addToMessages, scrollToBottom } from './app-rendering.js';
2
+ import { createWorkspaceAssignmentCard, showWorkspaceAssignmentError } from './workspace-assignment-card.js';
3
+
4
+ function findCard(assignmentId) {
5
+ var cards = document.querySelectorAll(".workspace-assignment-card:not(.home-workspace-assignment)");
6
+ for (var i = 0; i < cards.length; i++) if (cards[i].dataset.assignmentId === assignmentId) return cards[i];
7
+ return null;
8
+ }
9
+
10
+ export function renderProjectWorkspaceAssignment(msg) {
11
+ var assignment = msg && msg.assignment;
12
+ if (!assignment || !assignment.assignmentId) return false;
13
+ var previous = findCard(assignment.assignmentId);
14
+ var card = createWorkspaceAssignmentCard(assignment, { home: false });
15
+ if (previous && previous.parentNode) previous.parentNode.replaceChild(card, previous);
16
+ else addToMessages(card);
17
+ scrollToBottom();
18
+ return true;
19
+ }
20
+
21
+ export function showProjectWorkspaceAssignmentError(msg) {
22
+ return showWorkspaceAssignmentError(findCard(msg && msg.assignmentId), msg || {});
23
+ }