clay-server 5.0.0-beta.2 → 5.0.0-beta.4

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 (58) hide show
  1. package/lib/daemon.js +9 -0
  2. package/lib/new-session-default.js +45 -0
  3. package/lib/project-connection.js +4 -2
  4. package/lib/project-session-creation.js +107 -0
  5. package/lib/project-session-delete.js +21 -3
  6. package/lib/project-session-folder-delete.js +169 -0
  7. package/lib/project-session-folders.js +272 -0
  8. package/lib/project-sessions.js +46 -26
  9. package/lib/project.js +2 -0
  10. package/lib/public/app.js +12 -0
  11. package/lib/public/css/filebrowser.css +3 -3
  12. package/lib/public/css/fonts.css +6 -0
  13. package/lib/public/css/home-hub.css +52 -0
  14. package/lib/public/css/mates.css +1 -1
  15. package/lib/public/css/mobile-nav.css +0 -128
  16. package/lib/public/css/session-folders.css +402 -0
  17. package/lib/public/css/sidebar.css +28 -545
  18. package/lib/public/index.html +13 -22
  19. package/lib/public/modules/app-favicon.js +5 -4
  20. package/lib/public/modules/app-home-hub.js +60 -7
  21. package/lib/public/modules/app-messages.js +13 -0
  22. package/lib/public/modules/home-project-empty-access.js +44 -0
  23. package/lib/public/modules/input.js +3 -0
  24. package/lib/public/modules/project-activation.js +11 -0
  25. package/lib/public/modules/project-switcher.js +4 -4
  26. package/lib/public/modules/session-create-form.js +428 -0
  27. package/lib/public/modules/session-create.js +340 -0
  28. package/lib/public/modules/session-date-group-header.js +57 -0
  29. package/lib/public/modules/session-date-groups.js +84 -0
  30. package/lib/public/modules/session-folder-collapse.js +192 -0
  31. package/lib/public/modules/session-folder-context.js +215 -0
  32. package/lib/public/modules/session-folder-delete.js +339 -0
  33. package/lib/public/modules/session-folder-dialogs.js +173 -0
  34. package/lib/public/modules/session-folder-dnd.js +214 -0
  35. package/lib/public/modules/session-folder-draft.js +184 -0
  36. package/lib/public/modules/session-folder-layout.js +133 -0
  37. package/lib/public/modules/session-folder-toolbar.js +185 -0
  38. package/lib/public/modules/session-folder-view-menu.js +187 -0
  39. package/lib/public/modules/session-folders.js +97 -0
  40. package/lib/public/modules/session-list-search.js +108 -0
  41. package/lib/public/modules/session-presence-ui.js +44 -0
  42. package/lib/public/modules/sidebar-creation-effect.js +130 -0
  43. package/lib/public/modules/sidebar-mobile.js +39 -182
  44. package/lib/public/modules/sidebar-session-folders-ui.js +394 -0
  45. package/lib/public/modules/sidebar-sessions.js +142 -718
  46. package/lib/public/modules/sidebar.js +30 -7
  47. package/lib/public/modules/terminal.js +2 -2
  48. package/lib/public/modules/tool-palette.js +37 -219
  49. package/lib/public/style.css +1 -0
  50. package/lib/server.js +4 -0
  51. package/lib/session-folders.js +414 -0
  52. package/lib/sessions.js +7 -5
  53. package/lib/users-session-folder-preferences.js +69 -0
  54. package/lib/users.js +6 -0
  55. package/lib/ws-schema.js +11 -0
  56. package/package.json +1 -1
  57. package/lib/public/modules/session-creation-cta.js +0 -46
  58. package/lib/public/modules/tool-palette-overlays.js +0 -159
@@ -137,7 +137,16 @@
137
137
  </aside>
138
138
  <div id="home-workspace" class="home-workspace">
139
139
  <button id="home-sidebar-expand" class="home-sidebar-expand" type="button" title="Show sidebar" aria-label="Show Home sidebar" aria-describedby="home-sidebar-expand-brand-label"><i data-lucide="panel-left-open"></i><span id="home-sidebar-expand-brand-label" class="home-sidebar-brand-wordmark home-sidebar-expand-wordmark">Clay Studio</span></button>
140
- <button id="home-close-control" class="home-close-control" type="button" title="Projects" aria-label="Projects"><i data-lucide="folder" aria-hidden="true"></i><span>Projects</span></button>
140
+ <button id="home-close-control" class="home-close-control" type="button" title="Return to project" aria-label="Return to project"><i data-lucide="folder" aria-hidden="true"></i><span>Project</span></button>
141
+ <section id="home-project-empty" class="home-project-empty" aria-labelledby="home-project-empty-title" hidden>
142
+ <div class="home-project-empty-content">
143
+ <span class="home-project-empty-icon" aria-hidden="true"><i data-lucide="folder-plus"></i></span>
144
+ <p class="home-project-empty-eyebrow">PROJECT WORKSPACE</p>
145
+ <h1 id="home-project-empty-title" tabindex="-1">Start a new project</h1>
146
+ <p id="home-project-empty-status" class="home-project-empty-status" role="status">Create an empty project, then continue in its workspace.</p>
147
+ <button id="home-project-empty-create" type="button">Start a new project</button>
148
+ </div>
149
+ </section>
141
150
  <div id="home-conversation-region" class="home-conversation-region">
142
151
  <div id="home-mate-chat" class="home-mate-chat">
143
152
  <div class="home-mate-chat-stage">
@@ -208,13 +217,7 @@
208
217
  </div>
209
218
  <div id="sidebar">
210
219
  <div id="sidebar-tools">
211
- <div class="sidebar-tools-header">
212
- <span class="sidebar-section-label">Tools</span>
213
- <span class="sidebar-tools-hint" data-palette="session" title="Show keyboard hotkeys"></span>
214
- <button type="button" class="tool-palette-edit-btn" data-palette="session" aria-label="Edit tool palette" title="Edit palette"><i data-lucide="pencil"></i></button>
215
- </div>
216
- <div id="session-actions"></div>
217
- <div id="session-actions-hidden" class="tool-palette-hidden-section hidden"></div>
220
+ <div id="session-actions" role="group" aria-label="Tools"></div>
218
221
  <!-- Repository placard. Hidden until a real Git repository is
219
222
  confirmed, so non-Git projects and pending detection show
220
223
  nothing rather than an empty block. -->
@@ -228,13 +231,7 @@
228
231
  <div id="sidebar-sessions-header">
229
232
  <div id="sessions-header-content">
230
233
  <div class="sidebar-sessions-header-row">
231
- <span class="sidebar-section-label">Sessions</span>
232
- <span id="session-filter-count" class="session-filter-count hidden"></span>
233
- <div id="session-header-search-inline" class="sidebar-sessions-search-inline hidden">
234
- <input id="session-header-search-input" type="text" placeholder="Search sessions..." autocomplete="off" spellcheck="false" />
235
- <button id="session-header-search-clear" type="button" aria-label="Clear search"><i data-lucide="x"></i></button>
236
- </div>
237
- <button id="session-header-search-btn" type="button" aria-label="Search sessions" title="Search sessions"><i data-lucide="search"></i></button>
234
+ <span class="sidebar-section-label sidebar-label-sr">Sessions</span>
238
235
  </div>
239
236
  </div>
240
237
  <div id="files-header-content" class="hidden"></div>
@@ -294,13 +291,7 @@
294
291
  <button id="mate-sidebar-toggle-btn" class="sidebar-collapse-btn" title="Collapse sidebar"><i data-lucide="panel-left-close"></i></button>
295
292
  </div>
296
293
  <div id="mate-sidebar-tools-wrap">
297
- <div class="sidebar-tools-header">
298
- <span class="sidebar-section-label">Tools</span>
299
- <span class="sidebar-tools-hint" data-palette="mate" title="Show keyboard hotkeys"></span>
300
- <button type="button" class="tool-palette-edit-btn" data-palette="mate" aria-label="Edit tool palette" title="Edit palette"><i data-lucide="pencil"></i></button>
301
- </div>
302
- <div id="mate-sidebar-tools"></div>
303
- <div id="mate-sidebar-tools-hidden" class="tool-palette-hidden-section hidden"></div>
294
+ <div id="mate-sidebar-tools" role="group" aria-label="Tools"></div>
304
295
  </div>
305
296
  <div id="mate-sidebar-conversations">
306
297
  <div class="mate-sidebar-sessions-header">
@@ -137,12 +137,13 @@ export function blinkIO() {
137
137
  }
138
138
 
139
139
  export function blinkSessionDot(sessionId) {
140
- var el = document.querySelector('.session-item[data-session-id="' + sessionId + '"] .session-processing');
141
- if (!el) return;
142
- el.classList.add("io");
140
+ // A favorite is on screen twice; blink every copy.
141
+ var els = document.querySelectorAll('.session-item[data-session-id="' + sessionId + '"] .session-processing');
142
+ if (!els.length) return;
143
+ for (var i = 0; i < els.length; i++) els[i].classList.add("io");
143
144
  clearTimeout(sessionIoTimers[sessionId]);
144
145
  sessionIoTimers[sessionId] = setTimeout(function () {
145
- el.classList.remove("io");
146
+ for (var j = 0; j < els.length; j++) els[j].classList.remove("io");
146
147
  delete sessionIoTimers[sessionId];
147
148
  }, 80);
148
149
  }
@@ -3,8 +3,8 @@
3
3
  import { showProjectsHub, hideProjectsHub } from './projects-hub.js';
4
4
  import { store } from './store.js';
5
5
  import { getWs } from './ws-ref.js';
6
- import { getCachedProjects, switchProject } from './app-projects.js';
7
- import { chooseProjectActivationTarget } from './project-activation.js';
6
+ import { getCachedProjects, openAddProjectModal, switchProject } from './app-projects.js';
7
+ import { chooseProjectActivationTarget, homeProjectCreationState } from './project-activation.js';
8
8
  import { mateAvatarUrl } from './avatar.js';
9
9
  import { exitDmMode } from './app-dm.js';
10
10
  import { closeHomeDock, initHomeDock, renderDock, requestHomeDockPreference } from './home-dock.js';
@@ -22,6 +22,7 @@ import { disposeHomeSessionActions } from './home-session-actions.js';
22
22
  import { initHomeDebatesArchive, restoreHomeDebatesArchive } from './home-debates-archive.js';
23
23
  import { isHomeDebatesSurface } from './home-sub-surface.js';
24
24
  import { HOME_CAPSULE_CREATION_EVENT } from './home-capsule-creation-intent.js';
25
+ import { bindHomeProjectEmptyDismissal, setHomeProjectEmptyCoverage } from './home-project-empty-access.js';
25
26
 
26
27
  var homeHub = null;
27
28
  var homeHubVisible = false;
@@ -44,6 +45,13 @@ function syncHomeCloseControl() {
44
45
  var close = document.getElementById("home-close-control");
45
46
  if (!close) return;
46
47
  close.classList.remove("hidden");
48
+ var loaded = store.get('projectListLoaded') === true;
49
+ var slug = loaded ? getHomeReturnSlug() : null;
50
+ var label = close.querySelector("span");
51
+ close.disabled = !loaded;
52
+ close.title = !loaded ? "Loading projects" : (slug ? "Return to project" : "Project options");
53
+ close.setAttribute("aria-label", close.title);
54
+ if (label) label.textContent = loaded ? "Project" : "Loading…";
47
55
  }
48
56
 
49
57
  function getHomeReturnSlug() {
@@ -53,6 +61,34 @@ function getHomeReturnSlug() {
53
61
  );
54
62
  }
55
63
 
64
+ function syncHomeProjectEmptyState() {
65
+ var empty = document.getElementById("home-project-empty");
66
+ if (!empty) return;
67
+ var requested = store.get('homeProjectEmptyVisible') === true;
68
+ var loaded = store.get('projectListLoaded') === true;
69
+ var returnSlug = loaded ? getHomeReturnSlug() : null;
70
+ var visible = homeHubVisible && requested && loaded && !returnSlug;
71
+ setHomeProjectEmptyCoverage(document, visible);
72
+ empty.hidden = !visible;
73
+ if (requested && loaded && returnSlug) store.set({ homeProjectEmptyVisible: false });
74
+ if (!visible) return;
75
+ var availability = homeProjectCreationState(store.snap());
76
+ var action = document.getElementById("home-project-empty-create");
77
+ var status = document.getElementById("home-project-empty-status");
78
+ action.disabled = !availability.enabled;
79
+ if (status) status.textContent = availability.message;
80
+ }
81
+
82
+ function dismissHomeProjectEmpty() {
83
+ if (store.get('homeProjectEmptyVisible')) store.set({ homeProjectEmptyVisible: false });
84
+ }
85
+
86
+ function openHomeProjectCreation() {
87
+ var availability = homeProjectCreationState(store.snap());
88
+ if (!availability.enabled || getHomeReturnSlug()) return;
89
+ openAddProjectModal("create");
90
+ }
91
+
56
92
  function getVisibleMates() {
57
93
  var mates = (store.get('cachedMatesList') || []).filter(function (mate) {
58
94
  return !!mate && !mate.archived;
@@ -100,6 +136,7 @@ function isMateBusy(mate, projectStatus, mentionActive) {
100
136
  }
101
137
 
102
138
  function selectHomeMate(mateId) {
139
+ if (store.get('homeProjectEmptyVisible')) store.set({ homeProjectEmptyVisible: false });
103
140
  if (mateId !== store.get('homeChatMateId') || isHomeDebatesSurface()) openHomeChat(mateId);
104
141
  closeHomeSidebarAfterSelection();
105
142
  }
@@ -246,14 +283,20 @@ export function initHomeHub() {
246
283
  initHomeDock();
247
284
  initHomeDebatesArchive();
248
285
  document.getElementById("home-mate-list").addEventListener("keydown", handleMateListKeydown);
249
- document.getElementById("home-close-control").addEventListener("click", function () { showProjectsHub(); });
286
+ bindHomeProjectEmptyDismissal(document.getElementById("home-sidebar"), dismissHomeProjectEmpty);
287
+ document.getElementById("home-close-control").addEventListener("click", minimizeHomeHub);
288
+ document.getElementById("home-project-empty-create").addEventListener("click", openHomeProjectCreation);
250
289
  document.getElementById("home-nav-projects").addEventListener("click", function () { showProjectsHub(); });
251
290
  window.addEventListener("clay:home-debate", function () { hideHomeHub(); });
252
291
  document.addEventListener("visibilitychange", syncHomePresentation);
253
292
 
254
293
  store.subscribe(function (state, prev) {
255
294
  if (state.connected !== prev.connected && state.connected && homeHubVisible) syncHomePresentation();
256
- if (state.currentSlug !== prev.currentSlug) syncHomeCloseControl();
295
+ if (state.currentSlug !== prev.currentSlug || state.homeSurfaceProjectSlug !== prev.homeSurfaceProjectSlug ||
296
+ state.projectListLoaded !== prev.projectListLoaded || state.projectsHubList !== prev.projectsHubList) syncHomeCloseControl();
297
+ if (state.homeProjectEmptyVisible !== prev.homeProjectEmptyVisible || state.projectListLoaded !== prev.projectListLoaded ||
298
+ state.projectsHubList !== prev.projectsHubList || state.projectsAccessLoaded !== prev.projectsAccessLoaded ||
299
+ state.permissions !== prev.permissions || state.connected !== prev.connected) syncHomeProjectEmptyState();
257
300
  if (state.homeChatMateId !== prev.homeChatMateId || state.cachedMatesList !== prev.cachedMatesList) renderHomeMateSwitcher();
258
301
  if (state.homeSidebarCollapsed !== prev.homeSidebarCollapsed && !state.homeSidebarCollapsed) {
259
302
  requestAnimationFrame(renderHomeMateSwitcher);
@@ -352,7 +395,7 @@ export function updateHomeIconBadge() {
352
395
 
353
396
  export function showHomeHub(fromHistory) {
354
397
  hideProjectsHub();
355
- store.set({ pendingHomeProjectSlug: null });
398
+ store.set({ pendingHomeProjectSlug: null, homeProjectEmptyVisible: false });
356
399
  if (store.get('dmMode')) exitDmMode();
357
400
  var activeMateId = store.get('homeChatMateId');
358
401
  var resume = homeHubSuspended || homeHubVisible;
@@ -363,6 +406,7 @@ export function showHomeHub(fromHistory) {
363
406
  rememberHomePrimarySurface("home");
364
407
  syncHomePresentation();
365
408
  syncHomeCloseControl();
409
+ syncHomeProjectEmptyState();
366
410
  renderHomeMateSwitcher();
367
411
  if (activeMateId && !resume && !isHomeDebatesSurface()) openHomeChat(activeMateId);
368
412
  if (isHomeDebatesSurface()) restoreHomeDebatesArchive();
@@ -392,6 +436,7 @@ export function hideHomeHub() {
392
436
  disposeHomeSessionActions();
393
437
  homeHubVisible = false;
394
438
  homeHubSuspended = true;
439
+ if (store.get('homeProjectEmptyVisible')) store.set({ homeProjectEmptyVisible: false });
395
440
  hideHomeShell();
396
441
  homeHub.classList.add("hidden");
397
442
  syncHomePresentation();
@@ -402,9 +447,17 @@ export function hideHomeHub() {
402
447
  }
403
448
 
404
449
  export function minimizeHomeHub() {
405
- var slug = getHomeReturnSlug();
406
450
  if (!homeHubVisible) return;
407
- if (!slug) { showProjectsHub(); return; }
451
+ if (store.get('projectListLoaded') !== true) return;
452
+ var slug = getHomeReturnSlug();
453
+ if (!slug) {
454
+ store.set({ homeProjectEmptyVisible: true });
455
+ syncHomeProjectEmptyState();
456
+ var title = document.getElementById("home-project-empty-title");
457
+ if (title) title.focus({ preventScroll: true });
458
+ return;
459
+ }
460
+ if (store.get('homeProjectEmptyVisible')) store.set({ homeProjectEmptyVisible: false });
408
461
  switchProject(slug);
409
462
  var projectInput = document.getElementById("input");
410
463
  if (projectInput && !projectInput.disabled) projectInput.focus({ preventScroll: true });
@@ -17,6 +17,9 @@ import { showToast } from './utils.js';
17
17
  import { refreshIcons, iconHtml } from './icons.js';
18
18
  import { renderMarkdown, highlightCodeBlocks, renderMermaidBlocks } from './markdown.js';
19
19
  import { updatePageTitle } from './sidebar.js';
20
+ import { handleSessionFoldersState } from './session-folders.js';
21
+ import { handleFolderDeletePreview, handleFolderDeleteState } from './session-folder-delete.js';
22
+ import { handleSessionCreateMessage, handleNewSessionResult } from './session-create.js';
20
23
  import { renderSessionList, updateSessionPresence, handleSearchResults, updateSessionBadge } from './sidebar-sessions.js';
21
24
  import { updateDmBadge, setMentionActive, renderUserStrip } from './sidebar-mates.js';
22
25
  import { renderSidebarPresence } from './sidebar-presence.js';
@@ -117,6 +120,8 @@ export function processMessage(msg) {
117
120
  if (handleAutonomousRunMessage(msg)) return;
118
121
  if (handleLoopInterviewMessage(msg)) return;
119
122
  if (handleScheduledTaskMessage(msg)) return;
123
+ if (handleSessionCreateMessage(msg)) return;
124
+ if (msg && msg.type === "new_session_result" && handleNewSessionResult(msg)) return;
120
125
  if (handleDefaultVendorMessage(msg)) return;
121
126
  if (handleContextViewMessage(msg)) return;
122
127
  if (msg && msg.type === "set_project_session_visibility_default_result") {
@@ -718,6 +723,14 @@ export function processMessage(msg) {
718
723
  if (!store.get('dmMode')) handleInputSync(msg.text);
719
724
  break;
720
725
 
726
+ case "session_folders_delete_preview_result":
727
+ handleFolderDeletePreview(msg);
728
+ break;
729
+ case "session_folders_state":
730
+ handleSessionFoldersState(msg);
731
+ handleFolderDeleteState(msg);
732
+ break;
733
+
721
734
  case "session_list":
722
735
  markProjectSessionListHydrated();
723
736
  renderMateSessionList(msg.sessions || []);
@@ -0,0 +1,44 @@
1
+ // Accessibility boundary for the Home no-project overlay.
2
+
3
+ var coveredIds = ["home-conversation-region", "home-dock-backdrop", "home-dock-divider", "home-tool-workbench"];
4
+ var priorStates = new WeakMap();
5
+
6
+ function remember(element) {
7
+ if (priorStates.has(element)) return;
8
+ priorStates.set(element, {
9
+ inert: element.inert === true,
10
+ inertAttribute: element.hasAttribute("inert"),
11
+ ariaHidden: element.getAttribute("aria-hidden"),
12
+ });
13
+ }
14
+
15
+ function restore(element) {
16
+ var prior = priorStates.get(element);
17
+ if (!prior) return;
18
+ element.inert = prior.inert;
19
+ if (prior.inertAttribute) element.setAttribute("inert", "");
20
+ else element.removeAttribute("inert");
21
+ if (prior.ariaHidden === null) element.removeAttribute("aria-hidden");
22
+ else element.setAttribute("aria-hidden", prior.ariaHidden);
23
+ priorStates.delete(element);
24
+ }
25
+
26
+ export function setHomeProjectEmptyCoverage(doc, covered) {
27
+ for (var i = 0; i < coveredIds.length; i++) {
28
+ var element = doc.getElementById(coveredIds[i]);
29
+ if (!element) continue;
30
+ if (!covered) { restore(element); continue; }
31
+ remember(element);
32
+ element.inert = true;
33
+ element.setAttribute("inert", "");
34
+ element.setAttribute("aria-hidden", "true");
35
+ }
36
+ }
37
+
38
+ export function bindHomeProjectEmptyDismissal(sidebar, dismiss) {
39
+ sidebar.addEventListener("click", function (event) {
40
+ var control = event.target.closest("#home-sidebar-new, #home-sidebar-all, #home-sidebar-debate, #home-tools-btn, .home-mate-list-row, .home-sidebar-recent-list button");
41
+ if (!control || control.disabled) return;
42
+ dismiss();
43
+ }, true);
44
+ }
@@ -1,4 +1,5 @@
1
1
  import { stopSTT } from './stt-controller.js';
2
+ import { expectCreatedSession } from './session-create.js';
2
3
  import { hasRecordedSpeechFor, requestRecordedSend } from './stt-recording.js';
3
4
  import { iconHtml, refreshIcons } from './icons.js';
4
5
  import { setRewindMode, isRewindMode } from './rewind.js';
@@ -184,6 +185,8 @@ export function sendMessage() {
184
185
  autoResize();
185
186
  if (ctx.ws && ctx.connected) {
186
187
  ctx.ws.send(JSON.stringify({ type: "new_session" }));
188
+ // The fresh session lands in Unfiled; expand and reveal it there.
189
+ expectCreatedSession("unfiled");
187
190
  }
188
191
  return;
189
192
  }
@@ -19,6 +19,17 @@ export function chooseProjectActivationTarget(projects, candidates) {
19
19
  return null;
20
20
  }
21
21
 
22
+ export function homeProjectCreationState(state) {
23
+ var current = state || {};
24
+ if (current.projectListLoaded !== true) return { ready: false, enabled: false, message: "Loading projects…" };
25
+ if (current.projectsAccessLoaded !== true) return { ready: false, enabled: false, message: "Checking project access…" };
26
+ if (current.permissions && current.permissions.createProject !== true) {
27
+ return { ready: true, enabled: false, message: "Ask an administrator to create or share a project with you." };
28
+ }
29
+ if (current.connected !== true) return { ready: true, enabled: false, message: "Reconnect to start a project." };
30
+ return { ready: true, enabled: true, message: "Create an empty project, then continue in its workspace." };
31
+ }
32
+
22
33
  export function isProjectActivationPending(state, slug, socket) {
23
34
  var target = projectWsPath(slug);
24
35
  return !!target
@@ -16,7 +16,7 @@
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 { showHomeHub } from './app-home-hub.js';
19
+ import { showHomeHub, isHomeHubVisible } from './app-home-hub.js';
20
20
  import { openHomeChat } from './home-mate-chat.js';
21
21
  import { mateAvatarUrl } from './avatar.js';
22
22
  import { parseEmojis } from './markdown.js';
@@ -34,7 +34,7 @@ var _entries = [];
34
34
 
35
35
  export function openSwitcherForMode(mode) {
36
36
  if (mode !== 'project' && mode !== 'mate') return;
37
- if (mode === 'mate' && store.get('projectMateDmsEnabled') === false) return;
37
+ if (mode === 'mate' && !isHomeHubVisible()) return;
38
38
  if (_open) closeSwitcher(false);
39
39
  openSwitcher(mode);
40
40
  }
@@ -95,7 +95,7 @@ export function initProjectSwitcher() {
95
95
  function refreshMateHintVisibility() {
96
96
  if (!mateHint) return;
97
97
  var mates = store.get('cachedMatesList') || [];
98
- mateHint.classList.toggle('hidden', mates.length === 0 || store.get('projectMateDmsEnabled') === false);
98
+ mateHint.classList.toggle('hidden', mates.length === 0);
99
99
  }
100
100
  refreshMateHintVisibility();
101
101
  store.subscribe(function (state, prev) {
@@ -145,7 +145,7 @@ function handleKeyDown(e) {
145
145
  // same shortcut cycles.
146
146
  if (isMod && (k === 'e' || k === 'm')) {
147
147
  var requestedMode = k === 'e' ? 'project' : 'mate';
148
- if (requestedMode === 'mate' && store.get('projectMateDmsEnabled') === false) return;
148
+ if (requestedMode === 'mate' && !isHomeHubVisible()) return;
149
149
  e.preventDefault();
150
150
  e.stopPropagation();
151
151
  if (!_open) {