clay-server 5.1.0-beta.1 → 5.1.0-beta.3

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 (231) hide show
  1. package/LICENSES/README.md +4 -0
  2. package/LICENSES/dicebear-avatars.md +16 -0
  3. package/bin/cli.js +9 -91
  4. package/lib/builtin-mates.js +7 -7
  5. package/lib/daemon-project-access.js +7 -1
  6. package/lib/daemon-settings.js +11 -0
  7. package/lib/daemon.js +10 -37
  8. package/lib/dicebear-avatar.js +62 -0
  9. package/lib/knowledge-db-service.js +175 -0
  10. package/lib/knowledge-db-validation.js +0 -0
  11. package/lib/knowledge-document-index.js +49 -0
  12. package/lib/knowledge-draft-store.js +56 -0
  13. package/lib/knowledge-file-store.js +199 -0
  14. package/lib/knowledge-markdown.js +128 -0
  15. package/lib/linear-store.js +35 -8
  16. package/lib/mate-identity-file.js +39 -0
  17. package/lib/mate-knowledge-mcp-server.js +29 -6
  18. package/lib/mate-knowledge-service.js +23 -2
  19. package/lib/mate-knowledge-sync.js +37 -22
  20. package/lib/mate-ready-creation.js +2 -1
  21. package/lib/mate-workspace-color.js +4 -0
  22. package/lib/mates-identity.js +4 -4
  23. package/lib/mates-prompts.js +4 -3
  24. package/lib/mates.js +30 -11
  25. package/lib/os-users.js +5 -16
  26. package/lib/project-connection.js +36 -9
  27. package/lib/project-debate-proposal.js +6 -0
  28. package/lib/project-debate-workspace.js +43 -0
  29. package/lib/project-debate.js +4 -2
  30. package/lib/project-filesystem.js +21 -39
  31. package/lib/project-knowledge.js +315 -136
  32. package/lib/project-mate-creation-proposal.js +1 -0
  33. package/lib/project-mate-interaction.js +7 -6
  34. package/lib/project-server-settings.js +31 -0
  35. package/lib/project-sessions.js +92 -182
  36. package/lib/project-user-knowledge.js +60 -0
  37. package/lib/project.js +62 -21
  38. package/lib/public/app.js +79 -71
  39. package/lib/public/clay-studio-wordmark-bold.svg +20 -0
  40. package/lib/public/css/clay-workspace.css +105 -0
  41. package/lib/public/css/debates-workbench.css +47 -0
  42. package/lib/public/css/home-debate-live.css +26 -0
  43. package/lib/public/css/home-hub.css +3 -1
  44. package/lib/public/css/home-mate-model-picker.css +15 -131
  45. package/lib/public/css/home-mate-settings.css +168 -16
  46. package/lib/public/css/icon-strip.css +249 -32
  47. package/lib/public/css/input.css +3 -1
  48. package/lib/public/css/mate-conversation.css +176 -0
  49. package/lib/public/css/mate-knowledge-workbench.css +118 -0
  50. package/lib/public/css/mate-workspace-color.css +16 -0
  51. package/lib/public/css/mates.css +28 -28
  52. package/lib/public/css/menus.css +3 -0
  53. package/lib/public/css/messages.css +1 -114
  54. package/lib/public/css/mobile-nav.css +16 -16
  55. package/lib/public/css/overlays.css +15 -0
  56. package/lib/public/css/project-logs.css +7 -0
  57. package/lib/public/css/project-mate-creation.css +105 -0
  58. package/lib/public/css/project-settings-modal.css +56 -0
  59. package/lib/public/css/right-workbench.css +3 -3
  60. package/lib/public/css/server-settings-system.css +125 -0
  61. package/lib/public/css/session-folders.css +80 -21
  62. package/lib/public/css/session-github.css +25 -16
  63. package/lib/public/css/settings-ui.css +247 -22
  64. package/lib/public/css/shared-browser.css +7 -3
  65. package/lib/public/css/sidebar.css +183 -107
  66. package/lib/public/css/title-bar.css +156 -1
  67. package/lib/public/css/worker-delegation.css +47 -0
  68. package/lib/public/css/worker-proposal.css +72 -150
  69. package/lib/public/css/you.css +74 -0
  70. package/lib/public/index.html +206 -548
  71. package/lib/public/modules/account-island.js +232 -0
  72. package/lib/public/modules/admin-settings-email.js +197 -0
  73. package/lib/public/modules/admin-settings-invitations.js +183 -0
  74. package/lib/public/modules/admin-settings-projects.js +198 -0
  75. package/lib/public/modules/admin-settings-ui.js +100 -0
  76. package/lib/public/modules/admin-settings-users.js +331 -0
  77. package/lib/public/modules/admin.js +19 -949
  78. package/lib/public/modules/app-cursors.js +19 -43
  79. package/lib/public/modules/app-debate-ui.js +4 -3
  80. package/lib/public/modules/app-dm.js +0 -2
  81. package/lib/public/modules/app-header.js +106 -0
  82. package/lib/public/modules/app-message-router.js +12 -3
  83. package/lib/public/modules/app-messages.js +47 -61
  84. package/lib/public/modules/app-notifications.js +4 -7
  85. package/lib/public/modules/app-projects.js +5 -38
  86. package/lib/public/modules/app-rate-limit.js +70 -12
  87. package/lib/public/modules/app-rendering.js +12 -13
  88. package/lib/public/modules/avatar.js +30 -9
  89. package/lib/public/modules/chat-render-runtime.js +16 -4
  90. package/lib/public/modules/command-palette.js +2 -15
  91. package/lib/public/modules/context-sources.js +27 -18
  92. package/lib/public/modules/cursor-sharing-preference.js +3 -3
  93. package/lib/public/modules/debate-controls.js +299 -0
  94. package/lib/public/modules/debate.js +2 -0
  95. package/lib/public/modules/debates-workbench.js +339 -0
  96. package/lib/public/modules/default-ai.js +88 -65
  97. package/lib/public/modules/header-tui-font.js +10 -20
  98. package/lib/public/modules/home-debate-controls.js +18 -289
  99. package/lib/public/modules/home-mate-avatar-editor.js +228 -0
  100. package/lib/public/modules/home-mate-color-picker.js +66 -0
  101. package/lib/public/modules/home-mate-creation.js +1 -1
  102. package/lib/public/modules/home-mate-instructions.js +90 -0
  103. package/lib/public/modules/home-mate-model-picker.js +80 -271
  104. package/lib/public/modules/home-mate-profile-editor.js +72 -0
  105. package/lib/public/modules/home-mate-settings.js +118 -125
  106. package/lib/public/modules/home-shell.js +3 -0
  107. package/lib/public/modules/home-surface-boot.js +1 -9
  108. package/lib/public/modules/icon-strip-tooltip.js +95 -0
  109. package/lib/public/modules/knowledge-db-edit-state.js +35 -0
  110. package/lib/public/modules/knowledge-db-workbench.js +234 -0
  111. package/lib/public/modules/knowledge-history-state.js +55 -0
  112. package/lib/public/modules/knowledge-markdown-editor.js +57 -0
  113. package/lib/public/modules/knowledge-preview-links.js +70 -0
  114. package/lib/public/modules/knowledge-workbench-shell.js +21 -0
  115. package/lib/public/modules/linear-settings.js +3 -2
  116. package/lib/public/modules/markdown.js +5 -6
  117. package/lib/public/modules/mate-knowledge-workbench-state.js +174 -0
  118. package/lib/public/modules/mate-knowledge-workbench.js +500 -0
  119. package/lib/public/modules/mate-knowledge.js +11 -3
  120. package/lib/public/modules/mate-management.js +54 -10
  121. package/lib/public/modules/mate-sidebar.js +11 -1
  122. package/lib/public/modules/mate-workspace-color.js +33 -0
  123. package/lib/public/modules/mention.js +5 -13
  124. package/lib/public/modules/notification-settings.js +81 -0
  125. package/lib/public/modules/notifications.js +44 -28
  126. package/lib/public/modules/personal-settings-dialog.js +51 -0
  127. package/lib/public/modules/profile.js +66 -24
  128. package/lib/public/modules/project-chat-identity.js +79 -0
  129. package/lib/public/modules/project-debate-planning-workspace.js +250 -0
  130. package/lib/public/modules/project-debate-workspace.js +185 -0
  131. package/lib/public/modules/project-header-identity.js +127 -0
  132. package/lib/public/modules/project-logs-render.js +9 -4
  133. package/lib/public/modules/project-mate-creation-workspace.js +414 -0
  134. package/lib/public/modules/project-mate-navigation.js +238 -0
  135. package/lib/public/modules/project-session-navigation.js +29 -0
  136. package/lib/public/modules/project-settings-environment.js +106 -0
  137. package/lib/public/modules/project-settings.js +72 -628
  138. package/lib/public/modules/project-switcher.js +6 -8
  139. package/lib/public/modules/projects-hub-view.js +5 -6
  140. package/lib/public/modules/projects-hub.js +2 -6
  141. package/lib/public/modules/qrcode.js +27 -8
  142. package/lib/public/modules/search-clay-chat.js +8 -11
  143. package/lib/public/modules/server-settings-controls.js +316 -0
  144. package/lib/public/modules/server-settings-environment.js +194 -0
  145. package/lib/public/modules/server-settings-navigation.js +39 -0
  146. package/lib/public/modules/server-settings-state.js +54 -0
  147. package/lib/public/modules/server-settings.js +116 -788
  148. package/lib/public/modules/server-storage-settings.js +84 -0
  149. package/lib/public/modules/session-activity-tooltip.js +12 -0
  150. package/lib/public/modules/session-create-form.js +86 -14
  151. package/lib/public/modules/session-create.js +50 -7
  152. package/lib/public/modules/session-github.js +2 -1
  153. package/lib/public/modules/session-list-visibility.js +41 -0
  154. package/lib/public/modules/session-presence-ui.js +3 -0
  155. package/lib/public/modules/session-title-marquee.js +51 -0
  156. package/lib/public/modules/settings-env-values.js +34 -0
  157. package/lib/public/modules/settings-select.js +121 -0
  158. package/lib/public/modules/shared-browser.js +22 -12
  159. package/lib/public/modules/sidebar-mates.js +3 -50
  160. package/lib/public/modules/sidebar-mobile.js +63 -60
  161. package/lib/public/modules/sidebar-projects.js +84 -97
  162. package/lib/public/modules/sidebar-session-folders-ui.js +2 -2
  163. package/lib/public/modules/sidebar-session-hierarchy.js +149 -70
  164. package/lib/public/modules/sidebar-sessions.js +49 -50
  165. package/lib/public/modules/sidebar.js +11 -13
  166. package/lib/public/modules/stt-picker.js +14 -5
  167. package/lib/public/modules/terminal-prefs.js +22 -0
  168. package/lib/public/modules/theme.js +88 -52
  169. package/lib/public/modules/thinking-lifecycle.js +7 -6
  170. package/lib/public/modules/tool-palette-order.js +4 -3
  171. package/lib/public/modules/tool-palette.js +13 -3
  172. package/lib/public/modules/tools.js +22 -22
  173. package/lib/public/modules/user-settings-account.js +318 -0
  174. package/lib/public/modules/user-settings-appearance.js +55 -0
  175. package/lib/public/modules/user-settings-editors.js +24 -0
  176. package/lib/public/modules/user-settings-integrations.js +104 -0
  177. package/lib/public/modules/user-settings-layout.js +80 -0
  178. package/lib/public/modules/user-settings-preferences.js +48 -0
  179. package/lib/public/modules/user-settings-profile.js +53 -0
  180. package/lib/public/modules/user-settings-themes.js +38 -0
  181. package/lib/public/modules/user-settings-voice.js +75 -0
  182. package/lib/public/modules/user-settings.js +53 -480
  183. package/lib/public/modules/worker-proposal.js +42 -8
  184. package/lib/public/modules/worker-runtime-picker.js +115 -0
  185. package/lib/public/modules/you-activity.js +121 -0
  186. package/lib/public/modules/you.js +251 -0
  187. package/lib/public/style.css +20 -8
  188. package/lib/public/vendor/codemirror/LICENSE +21 -0
  189. package/lib/public/vendor/codemirror/codemirror.css +344 -0
  190. package/lib/public/vendor/codemirror/codemirror.js +9884 -0
  191. package/lib/public/vendor/codemirror/continuelist.js +101 -0
  192. package/lib/public/vendor/codemirror/markdown.js +886 -0
  193. package/lib/public/vendor/codemirror/show-hint.css +37 -0
  194. package/lib/public/vendor/codemirror/show-hint.js +523 -0
  195. package/lib/sdk-bridge.js +15 -3
  196. package/lib/sdk-message-processor.js +16 -4
  197. package/lib/sdk-quota-snapshot.js +37 -0
  198. package/lib/server-admin.js +11 -0
  199. package/lib/server-appearance-settings.js +71 -0
  200. package/lib/server-home-chat-events.js +1 -1
  201. package/lib/server-home-chat.js +25 -3
  202. package/lib/server-home-debate-planning.js +4 -1
  203. package/lib/server-home-debates.js +2 -0
  204. package/lib/server-home-mate-creation.js +4 -1
  205. package/lib/server-linear.js +14 -8
  206. package/lib/server-mate-instructions.js +44 -0
  207. package/lib/server-mates.js +14 -4
  208. package/lib/server-notification-settings.js +67 -0
  209. package/lib/server-palette.js +1 -1
  210. package/lib/server-settings.js +69 -1
  211. package/lib/server-storage.js +57 -0
  212. package/lib/server-user-knowledge.js +119 -0
  213. package/lib/server.js +31 -3
  214. package/lib/session-visibility.js +7 -2
  215. package/lib/sessions.js +35 -10
  216. package/lib/startup-projects.js +40 -0
  217. package/lib/storage-native-walk.js +85 -0
  218. package/lib/storage-usage.js +144 -0
  219. package/lib/user-knowledge-service.js +167 -0
  220. package/lib/users-permissions.js +7 -0
  221. package/lib/users-preferences.js +0 -74
  222. package/lib/users-project-mate-filter-preferences.js +39 -0
  223. package/lib/users.js +6 -4
  224. package/lib/workspace-query-access.js +4 -1
  225. package/lib/ws-schema.js +52 -4
  226. package/lib/yoke/acp-process-manager.js +2 -2
  227. package/lib/yoke/adapters/codex.js +12 -52
  228. package/lib/yoke/codex-app-server.js +2 -2
  229. package/lib/yoke/codex-model-catalog.js +52 -0
  230. package/lib/yoke/codex-rate-limits.js +26 -0
  231. package/package.json +12 -3
@@ -199,50 +199,26 @@ function findClosestTurn(clientY) {
199
199
 
200
200
  // Cursor sharing toggle button in user island (multi-user only)
201
201
  export function initCursorToggle() {
202
- if (!store.get('isMultiUserMode')) return;
203
- var actionsEl = document.querySelector(".user-island-actions");
204
- if (!actionsEl) return;
205
- if (document.getElementById("cursor-share-toggle")) return;
206
-
207
- var btn = document.createElement("button");
208
- btn.id = "cursor-share-toggle";
209
- btn.className = "cursor-share-btn";
210
- btn.innerHTML = '<i data-lucide="mouse-pointer-2"></i>';
211
- var settingsBtn = document.getElementById("user-settings-btn");
212
- if (settingsBtn) {
213
- actionsEl.insertBefore(btn, settingsBtn);
214
- } else {
215
- actionsEl.appendChild(btn);
216
- }
217
-
218
- function updateToggleStyle() {
219
- if (store.get("cursorSharingHydrated") && store.get("cursorSharingEnabled")) {
220
- btn.classList.remove("off");
221
- btn.classList.add("on");
222
- registerTooltip(btn, "Cursor sharing on");
223
- } else {
224
- btn.classList.remove("on");
225
- btn.classList.add("off");
226
- registerTooltip(btn, "Cursor sharing off");
227
- }
228
- }
229
-
230
- store.subscribe(function (state, prev) {
231
- if (state.cursorSharingEnabled !== prev.cursorSharingEnabled || state.cursorSharingHydrated !== prev.cursorSharingHydrated) {
232
- updateToggleStyle();
233
- }
234
- });
202
+ // The labeled rail control is owned by account-island.js.
203
+ return;
204
+ }
235
205
 
236
- updateToggleStyle();
237
- lucide.createIcons({ nodes: [btn] });
206
+ export function setCursorSharing(enabled) {
207
+ if (!store.get('cursorSharingHydrated') || store.get('cursorSharingPending') !== null && store.get('cursorSharingPending') !== undefined) return false;
208
+ if (enabled === true && store.get('isMultiUserMode') !== true) return false;
209
+ var ws = getWs();
210
+ if (!ws || ws.readyState !== 1) return false;
211
+ store.set({ cursorSharingPending: enabled });
212
+ ws.send(JSON.stringify({ type: 'cursor_sharing_set', enabled: enabled === true, requestId: 'cursor-sharing-' + Date.now() }));
213
+ return true;
214
+ }
238
215
 
239
- btn.addEventListener("click", function () {
240
- if (!store.get("cursorSharingHydrated")) return;
241
- var next = !store.get("cursorSharingEnabled");
242
- var ws = getWs();
243
- if (!ws || ws.readyState !== 1) return;
244
- ws.send(JSON.stringify({ type: "cursor_sharing_set", enabled: next, requestId: "cursor-sharing-" + Date.now() }));
245
- });
216
+ export function requestCursorSharingState() {
217
+ var ws = getWs();
218
+ if (!ws || ws.readyState !== 1) return false;
219
+ store.set({ cursorSharingPending: 'refresh' });
220
+ ws.send(JSON.stringify({ type: 'cursor_sharing_get', requestId: 'cursor-sharing-refresh-' + Date.now() }));
221
+ return true;
246
222
  }
247
223
 
248
224
  // --- Exported functions ---
@@ -393,7 +369,7 @@ export function initCursors() {
393
369
  if (cursorThrottleTimer) { clearTimeout(cursorThrottleTimer); cursorThrottleTimer = null; }
394
370
  if (selectionThrottleTimer) { clearTimeout(selectionThrottleTimer); selectionThrottleTimer = null; }
395
371
  lastSelectionKey = "";
396
- store.set({ cursorSharingEnabled: false, cursorSharingHydrated: false, cursorSharingAccountId: null });
372
+ store.set({ cursorSharingEnabled: false, cursorSharingHydrated: false, cursorSharingAccountId: null, cursorSharingPending: null, cursorSharingError: disconnected ? "disconnected" : "account-changed" });
397
373
  if (identityChanged && state.myUserId && state.connected) {
398
374
  var ws = getWs();
399
375
  if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: "cursor_sharing_get", requestId: "cursor-sharing-refresh-" + Date.now() }));
@@ -6,6 +6,7 @@ import { store } from './store.js';
6
6
  import { getWs } from './ws-ref.js';
7
7
  import { scrollToBottom } from './app-rendering.js';
8
8
  import { exportDebateAsPdf } from './debate.js';
9
+ import { getProjectAssistantPlaceholder } from './project-chat-identity.js';
9
10
 
10
11
  // Module-internal UI var (not in store)
11
12
  var debateHandRaiseOpen = false;
@@ -64,7 +65,7 @@ export function exitDebateConcludeMode() {
64
65
  if (banner) banner.remove();
65
66
  var inputEl = document.getElementById("input");
66
67
  if (inputEl && inputEl._origPlaceholder) {
67
- inputEl.placeholder = inputEl._origPlaceholder;
68
+ inputEl.placeholder = getProjectAssistantPlaceholder(store.snap(), store.get('currentVendor'));
68
69
  delete inputEl._origPlaceholder;
69
70
  }
70
71
  }
@@ -129,7 +130,7 @@ export function exitDebateEndedMode() {
129
130
  if (banner) banner.remove();
130
131
  var inputEl2 = document.getElementById("input");
131
132
  if (inputEl2 && inputEl2._origPlaceholder) {
132
- inputEl2.placeholder = inputEl2._origPlaceholder;
133
+ inputEl2.placeholder = getProjectAssistantPlaceholder(store.snap(), store.get('currentVendor'));
133
134
  delete inputEl2._origPlaceholder;
134
135
  }
135
136
  }
@@ -191,7 +192,7 @@ export function exitDebateFloorMode() {
191
192
  if (banner) banner.remove();
192
193
  var inputEl = document.getElementById("input");
193
194
  if (inputEl && inputEl._origPlaceholder) {
194
- inputEl.placeholder = inputEl._origPlaceholder;
195
+ inputEl.placeholder = getProjectAssistantPlaceholder(store.snap(), store.get('currentVendor'));
195
196
  delete inputEl._origPlaceholder;
196
197
  }
197
198
  }
@@ -80,7 +80,6 @@ export function openDm(targetUserId, opts) {
80
80
  if (mates[i] && mates[i].id === targetUserId) isMateTarget = true;
81
81
  }
82
82
  if (isMateTarget) {
83
- if (store.get('projectMateDmsEnabled') === false) return;
84
83
  showHomeHub();
85
84
  openHomeChat(targetUserId);
86
85
  return;
@@ -152,7 +151,6 @@ function showMateOnboarding(callback) {
152
151
  export function enterDmMode(key, targetUser, messages) {
153
152
  console.log("[DEBUG enterDmMode] key=" + key, "isMate=" + (targetUser && targetUser.isMate), "messages=" + (messages ? messages.length : 0));
154
153
  if (targetUser && targetUser.isMate) {
155
- if (store.get('projectMateDmsEnabled') === false) return;
156
154
  showHomeHub();
157
155
  openHomeChat(targetUser.id);
158
156
  return;
@@ -1,3 +1,4 @@
1
+ import { beginProjectDebatePrepend, endProjectDebatePrepend } from './project-debate-workspace.js';
1
2
  // app-header.js - Session rename, session info popover, progressive history loading
2
3
  // Extracted from app.js (PR-34)
3
4
 
@@ -12,6 +13,9 @@ import { saveToolState, resetToolState, restoreToolState } from './tools.js';
12
13
  import { getSessionUsage, setSessionUsage, getContextData, setContextData, updateContextPanel, updateUsagePanel } from './app-panels.js';
13
14
  import { onHistoryPrepended as onSessionSearchHistoryPrepended } from './session-search.js';
14
15
  import { getCachedSessions } from './sidebar-sessions.js';
16
+ import { buildSessionHierarchy } from './session-hierarchy.js';
17
+ import { splitGroupRoles } from './split-group-helpers.js';
18
+ import { createWorkerHistoryControl } from './sidebar-session-hierarchy.js';
15
19
  import { bindPermissionControl, renderPermissionControl } from './permission-control.js';
16
20
  import { startHeaderSessionInlineRename } from './session-context-menu.js';
17
21
 
@@ -19,11 +23,104 @@ import { startHeaderSessionInlineRename } from './session-context-menu.js';
19
23
  var sessionInfoPopover = null;
20
24
  var historySentinelObserver = null;
21
25
 
26
+ function splitHistoryOwner(state, sessions) {
27
+ var split = state.splitPanes;
28
+ if (!split || !Array.isArray(split.panes)) return null;
29
+ var groups = state.splitGroups || [];
30
+ var group = null;
31
+ var roles = null;
32
+ for (var gi = 0; gi < groups.length; gi++) {
33
+ var candidateRoles = splitGroupRoles(groups[gi]);
34
+ if (!candidateRoles) continue;
35
+ var matches = false;
36
+ for (var pi = 0; pi < split.panes.length; pi++) {
37
+ if (candidateRoles.orderedIds.indexOf(split.panes[pi].sessionId) !== -1) matches = true;
38
+ }
39
+ if (matches) { group = groups[gi]; roles = candidateRoles; break; }
40
+ }
41
+ if (!group || !roles) return null;
42
+ var hierarchy = buildSessionHierarchy(sessions || []);
43
+ for (var hi = 0; hi < hierarchy.roots.length; hi++) {
44
+ var root = hierarchy.roots[hi];
45
+ if (root.driver.id === roles.driverId && root.workers.length) return { root: root, group: group, roles: roles };
46
+ }
47
+ return null;
48
+ }
49
+
50
+ function splitPaneHistoryUrl(slug, sessionId) {
51
+ return "/p/" + encodeURIComponent(slug) + "/?pane=1&session=" + encodeURIComponent(sessionId);
52
+ }
53
+
54
+ function createHeaderWorkerHistoryControl(root, context) {
55
+ var capturedWs = context.ws;
56
+ var capturedSlug = context.slug;
57
+ var capturedMateId = context.mateId;
58
+ var capturedActiveSessionId = context.activeSessionId;
59
+ var capturedSplit = context.split;
60
+ var historyControl = createWorkerHistoryControl(root.driver, root.workers, {
61
+ className: "header-worker-history-btn",
62
+ label: "Show Split Worker history",
63
+ validate: function (driver) {
64
+ var current = store.snap();
65
+ var ws = getWs();
66
+ if (!ws || ws !== capturedWs || ws.readyState !== 1 || !current.connected || current.currentSlug !== capturedSlug ||
67
+ (current.activeProjectMateId || null) !== capturedMateId || current.dmMode) return false;
68
+ if (!capturedSplit) return current.activeSessionId === driver.id && !current.splitPanes;
69
+ var split = current.splitPanes;
70
+ if (!split || split.groupId !== capturedSplit.groupId || !Array.isArray(split.panes) || split.panes.length !== capturedSplit.panes.length) return false;
71
+ if (current.activeSessionId !== capturedActiveSessionId) return false;
72
+ for (var i = 0; i < split.panes.length; i++) {
73
+ if (split.panes[i].sessionId !== capturedSplit.panes[i].sessionId || split.panes[i].slug !== capturedSplit.panes[i].slug) return false;
74
+ }
75
+ return true;
76
+ },
77
+ navigate: capturedSplit ? function (worker) {
78
+ var opened = window.open(splitPaneHistoryUrl(capturedSlug, worker.id), "_blank", "noopener");
79
+ return !!opened;
80
+ } : null,
81
+ });
82
+ return historyControl;
83
+ }
84
+
22
85
  export function initHeader() {
23
86
  var headerRenameBtn = document.getElementById("header-rename-btn");
24
87
  var headerTitleEl = document.getElementById("header-title");
25
88
  var headerInfoBtn = document.getElementById("header-info-btn");
26
89
  var headerFullAccessBtn = document.getElementById("header-full-access-btn");
90
+ var headerSearchBtn = document.getElementById("find-in-session-btn");
91
+ var headerWorkerHistoryBtn = null;
92
+
93
+ function refreshHeaderWorkerHistory() {
94
+ if (!headerSearchBtn) return;
95
+ if (headerWorkerHistoryBtn) {
96
+ headerWorkerHistoryBtn.remove();
97
+ headerWorkerHistoryBtn = null;
98
+ }
99
+ var state = store.snap();
100
+ var sessions = getCachedSessions() || [];
101
+ var hierarchy = buildSessionHierarchy(sessions);
102
+ var owner = null;
103
+ var context = null;
104
+ if (state.splitPanes && state.splitPanes.panes) {
105
+ var splitOwner = splitHistoryOwner(state, sessions);
106
+ owner = splitOwner ? splitOwner.root : null;
107
+ if (owner) {
108
+ context = {
109
+ ws: getWs(), slug: state.currentSlug, mateId: state.activeProjectMateId || null,
110
+ activeSessionId: state.activeSessionId,
111
+ split: { groupId: state.splitPanes.groupId, panes: state.splitPanes.panes.map(function (pane) { return { sessionId: pane.sessionId, slug: pane.slug }; }) },
112
+ };
113
+ }
114
+ } else {
115
+ for (var hi = 0; hi < hierarchy.roots.length; hi++) {
116
+ if (hierarchy.roots[hi].driver.id === state.activeSessionId && hierarchy.roots[hi].workers.length) { owner = hierarchy.roots[hi]; break; }
117
+ }
118
+ if (owner) context = { ws: getWs(), slug: state.currentSlug, mateId: state.activeProjectMateId || null, activeSessionId: state.activeSessionId, split: null };
119
+ }
120
+ if (!owner || !context) return;
121
+ headerWorkerHistoryBtn = createHeaderWorkerHistoryControl(owner, context);
122
+ if (headerWorkerHistoryBtn) headerSearchBtn.insertAdjacentElement("afterend", headerWorkerHistoryBtn);
123
+ }
27
124
 
28
125
  function permissionControlState() {
29
126
  var s = store.snap();
@@ -121,6 +218,12 @@ export function initHeader() {
121
218
 
122
219
  // --- Session info popover ---
123
220
  if (headerInfoBtn) {
221
+ store.subscribe(function (state, prev) {
222
+ if (state.activeSessionId !== prev.activeSessionId || state.currentSlug !== prev.currentSlug || state.activeProjectMateId !== prev.activeProjectMateId || state.splitPanes !== prev.splitPanes) {
223
+ closeSessionInfoPopover();
224
+ refreshHeaderWorkerHistory();
225
+ }
226
+ });
124
227
  headerInfoBtn.addEventListener("click", function (e) {
125
228
  e.stopPropagation();
126
229
  if (sessionInfoPopover) { closeSessionInfoPopover(); return; }
@@ -193,6 +296,7 @@ export function initHeader() {
193
296
  }
194
297
  });
195
298
  }
299
+ refreshHeaderWorkerHistory();
196
300
  }
197
301
 
198
302
  export function closeSessionInfoPopover() {
@@ -269,11 +373,13 @@ export function prependOlderHistory(items, meta) {
269
373
  var anchorEl = getPrependAnchor();
270
374
  var anchorOffset = anchorEl ? anchorEl.getBoundingClientRect().top : 0;
271
375
 
376
+ beginProjectDebatePrepend();
272
377
  // Process each item through the rendering pipeline
273
378
  for (var i = 0; i < items.length; i++) {
274
379
  processMessage(items[i]);
275
380
  }
276
381
 
382
+ endProjectDebatePrepend();
277
383
  // Finalize any open assistant block from the batch
278
384
  finalizeAssistantBlock();
279
385
 
@@ -2,11 +2,11 @@ import { handleIssueReference } from './clay-issue-links.js';
2
2
  // Narrow pre-router for Home and Capsule protocol responses kept out of the legacy router.
3
3
 
4
4
  import { processMessage as processAppMessage } from './app-messages.js';
5
- import { handleHomeMateModelsState, handleHomeMateModelResult } from './home-mate-settings.js';
5
+ import { handleMateInstructionsResult, handleHomeMateModelsState, handleHomeMateModelResult } from './home-mate-settings.js';
6
6
  import { handleHomeMateSessionIdentity, handleHomeDebateTranscript, handleHomeWorkspaceAssignment } from './home-mate-chat.js';
7
7
  import { handleToolLlmConfigState } from './tool-llm-status.js';
8
8
  import { handleToolSourceState, handleToolMateAccessState } from './home-tools.js';
9
- import { handleHomeDebatesState } from './home-debates-archive.js';
9
+ import { handleDebatesWorkbenchState } from './debates-workbench.js';
10
10
  import { renderProjectWorkspaceAssignment, showProjectWorkspaceAssignmentError } from './project-workspace-assignment.js';
11
11
  import { isHomeWorkspaceAssignmentMessage } from './workspace-assignment-routing.js';
12
12
  import { handleSearchClayMessage } from './search-clay-chat.js';
@@ -15,6 +15,8 @@ import { handleDefaultAiMessage } from './default-ai.js';
15
15
  import { handleCursorSharingMessage } from './cursor-sharing-preference.js';
16
16
  import { handlePendingMessageQueueMessage } from './pending-message-queue.js';
17
17
  import { receiveHistoryReplay } from './history-replay-batch.js';
18
+ import { handleProjectMateCreationMessage } from './project-mate-creation-workspace.js';
19
+ import { handleProjectDebatePlanningMessage } from './project-debate-planning-workspace.js';
18
20
 
19
21
  export function handleHomeProtocolMessage(msg) {
20
22
  if (handleIssueReference(msg)) return true;
@@ -32,9 +34,10 @@ export function handleHomeProtocolMessage(msg) {
32
34
  return true;
33
35
  }
34
36
  if (msg.type === "home_debates_state") {
35
- handleHomeDebatesState(msg);
37
+ handleDebatesWorkbenchState(msg);
36
38
  return true;
37
39
  }
40
+ if (msg.type === "mate_instructions_result") { handleMateInstructionsResult(msg); return true; }
38
41
  if (msg.type === "home_mate_models_state") {
39
42
  handleHomeMateModelsState(msg);
40
43
  return true;
@@ -87,6 +90,12 @@ export function processMessage(msg) {
87
90
  }
88
91
 
89
92
  function dispatchMessage(msg) {
93
+ if (typeof handleProjectDebatePlanningMessage === "function" && handleProjectDebatePlanningMessage(msg)) return;
94
+ if (msg.type === "home_debate_event" && msg.eventType) {
95
+ processAppMessage(Object.assign({}, msg, { type: msg.eventType, mateId: msg.speakerMateId || null }));
96
+ return;
97
+ }
98
+ if (handleProjectMateCreationMessage(msg)) return;
90
99
  if (handlePendingMessageQueueMessage(msg)) return;
91
100
  if (handleDefaultAiMessage(msg)) return;
92
101
  if (handleCursorSharingMessage(msg)) return;
@@ -1,3 +1,10 @@
1
+ import { handlePersonalSettingsMessage } from './user-settings-preferences.js';
2
+ import { handleServerUpdate } from './server-settings-controls.js';
3
+ import { handleYouMessage } from './you.js';
4
+ import { handleYouActivity } from './you-activity.js';
5
+ import { handleProjectDebateMessage } from './project-debate-workspace.js';
6
+ import { openMateWorkspace, renderProjectMates } from './project-mate-navigation.js';
7
+ import { refreshProjectAssistantIdentities } from './project-chat-identity.js';
1
8
  import { handleLinearResult } from './linear-panel.js';
2
9
  import { handleSharedBrowserMessage } from './shared-browser.js';
3
10
  import { openWireframe } from './wireframe-workbench.js';
@@ -25,12 +32,13 @@ import { updateDmBadge, setMentionActive, renderUserStrip } from './sidebar-mate
25
32
  import { renderSidebarPresence } from './sidebar-presence.js';
26
33
  import { refreshMobileChatSheet } from './sidebar-mobile.js';
27
34
  import { renderMateSessionList, handleMateSearchResults, updateMateSidebarProfile } from './mate-sidebar.js';
28
- import { openHomeChat, handleHomeMateHistory, handleHomeMateDelta, handleHomeMateSegment, handleHomeMateDone, handleHomeMateError, handleHomeMateSessionsState } from './home-mate-chat.js';
35
+ import { handleHomeMateHistory, handleHomeMateDelta, handleHomeMateSegment, handleHomeMateDone, handleHomeMateError, handleHomeMateSessionsState } from './home-mate-chat.js';
29
36
  import { handleHomeSurfaceState } from './home-surface.js';
30
37
  import { handleDefaultVendorMessage } from './default-vendor.js';
31
38
  import { handleContextViewMessage } from './context-view-preference.js';
32
- import { handleHomeMateMemoryState, handleHomeMateKnowledgeState } from './home-mate-settings.js';
33
- import { renderKnowledgeList, handleKnowledgeContent } from './mate-knowledge.js';
39
+ import { handleHomeMateMemoryState, handleHomeMateKnowledgeState, syncHomeMateSettingsTarget, handleHomeMateAvatarError } from './home-mate-settings.js';
40
+ import { renderKnowledgeList, handleKnowledgeContent, handleKnowledgeMutation } from './mate-knowledge.js';
41
+ import { handleKnowledgeWorkbenchMessage } from './mate-knowledge-workbench.js';
34
42
  import { renderMemoryList } from './mate-memory.js';
35
43
  import { handlePaletteSessionSwitch, setPaletteVersion } from './command-palette.js';
36
44
  import { handleFindInSessionResults } from './session-search.js';
@@ -47,9 +55,10 @@ import { showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundE
47
55
  import { handleFsList, handleFsRead, handleFileChanged, handleDirChanged, handleFileHistory, handleGitDiff, handleFileAt, refreshIfOpen, getPendingNavigate, handleFsSearch, presentMarkdownEdit } from './filebrowser.js';
48
56
  import { beginMarkdownTurn, finishMarkdownTurn, markdownPathFromToolInput } from './markdown-live-edit.js';
49
57
  import { forwardPaneMarkdownPresentation } from './pane-bridge.js';
50
- import { isProjectSettingsOpen, handleInstructionsRead, handleInstructionsWrite, handleProjectEnv, handleProjectEnvSaved, handleProjectSharedEnv, handleProjectSharedEnvSaved, handleProjectOwnerChanged } from './project-settings.js';
58
+ import { handleProjectOwnerChanged } from './project-settings.js';
59
+ import { handleProjectEnv, handleProjectEnvSaved } from './project-settings-environment.js';
51
60
  import { handleProjectSessionVisibilityDefault, refreshProjectSessionVisibilitySettings } from './project-session-visibility-settings.js';
52
- import { updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleInheritGroupsChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './server-settings.js';
61
+ import { updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleServerSettingResult } from './server-settings.js';
53
62
  import { handleTermList, handleTermCreated, sendTerminalCommand, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed } from './terminal.js';
54
63
  import { attachTuiView, detachTuiView, setTuiSuspendedView, tuiHandleTermOutput, tuiHandleTermResized, tuiHandleTermExited, tuiHandleTermClosed } from './session-tui-view.js';
55
64
  import { handleTuiTranscriptState } from './tui-grab.js';
@@ -83,7 +92,6 @@ import { getModelInfoUpdate, modelEntryValue, modelEntryMatches, handleModelSele
83
92
  import { getModelEffortLevels, accumulateUsage, updateUsagePanel, accumulateContext, updateContextPanel, renderCtxPopover, updateStatusPanel, markContextUnavailable } from './app-panels.js';
84
93
  import { updateProjectList, resetClientState, showUpdateAvailable, handleRemoveProjectCheckResult, handleRemoveProjectResult, handleBrowseDirResult, handleAddProjectResult, handleCloneProgress, finishProjectSessionActivation } from './app-projects.js';
85
94
  import { updateHistorySentinel, prependOlderHistory } from './app-header.js';
86
- import { hideHomeHub, showHomeHub } from './app-home-hub.js';
87
95
  import { handleToolsState, handleToolInstalled, handleToolRemoved, handleToolStorageResult, handleToolLlmResult, handleToolsError, handleToolControlRequest, handleToolServerState, handleToolServerEvent, handleCapsuleGameSession } from './home-tools.js';
88
96
  import { handleHomeDockState } from './home-dock.js';
89
97
  import { handleToolFrameUrlState } from './home-tool-frame.js';
@@ -110,6 +118,9 @@ var connectOverlay = document.getElementById("connect-overlay");
110
118
  initMessageDeliveryUi();
111
119
 
112
120
  export function processMessage(msg) {
121
+ if (["update_available", "up_to_date", "update_started", "update_check_failed"].indexOf(msg.type) !== -1) handleServerUpdate(msg);
122
+ if (/^(set_pin|set_keep_awake|set_inherit_groups|set_image_retention|set_update_channel|restart_server|shutdown_server)_result$/.test(msg.type)) handleServerSettingResult(msg);
123
+ if (handleProjectDebateMessage(msg)) return;
113
124
  if (handleMcpConnectionMessage(msg)) return;
114
125
  if (handleSharedBrowserMessage(msg)) return;
115
126
  if (msg.type === "vendor_login_browser_frame" || msg.type === "vendor_login_browser_status") {
@@ -120,6 +131,7 @@ export function processMessage(msg) {
120
131
  if (handleAutonomousRunMessage(msg)) return;
121
132
  if (handleLoopInterviewMessage(msg)) return;
122
133
  if (handleScheduledTaskMessage(msg)) return;
134
+ if (handleKnowledgeWorkbenchMessage(msg)) return;
123
135
  if (handleSessionCreateMessage(msg)) return;
124
136
  if (msg && msg.type === "new_session_result" && handleNewSessionResult(msg)) return;
125
137
  if (handleDefaultVendorMessage(msg)) return;
@@ -172,6 +184,7 @@ export function processMessage(msg) {
172
184
  return;
173
185
  }
174
186
  if (msg.type === "knowledge_saved" || msg.type === "knowledge_deleted" || msg.type === "knowledge_promoted" || msg.type === "knowledge_depromoted") {
187
+ handleKnowledgeMutation(msg);
175
188
  return;
176
189
  }
177
190
  if (msg.type === "memory_list") {
@@ -338,8 +351,7 @@ export function processMessage(msg) {
338
351
  store.set({ dmMode: false });
339
352
  }
340
353
  messagesEl.innerHTML = "";
341
- showHomeHub();
342
- openHomeChat(msg.mateId);
354
+ openMateWorkspace(msg.mateId);
343
355
  }
344
356
  // Clear the flag and notify server that mate DM is closed
345
357
  if (store.get('returningFromMateDm')) {
@@ -363,7 +375,12 @@ export function processMessage(msg) {
363
375
  clearProjectSplitState();
364
376
  }
365
377
  detachTuiView();
366
- store.set({ projectName: msg.project || msg.cwd, vendorInfo: msg.vendors || {} });
378
+ store.set({
379
+ projectName: msg.project || msg.cwd,
380
+ vendorInfo: msg.vendors || {},
381
+ activeProjectMateId: msg.isMate && msg.mateId ? msg.mateId : null,
382
+ activeProjectMateName: msg.isMate ? (msg.mateDisplayName || msg.project || "Mate") : "",
383
+ });
367
384
  if (msg.cwd) store.set({ cwd: msg.cwd });
368
385
  if (msg.slug) store.set({ currentSlug: msg.slug, activeProjectSlug: msg.slug, sessionListProjectSlug: null, splitGroupsProjectSlug: null });
369
386
  try { var _is = store.snap(); localStorage.setItem("clay-project-name-" + (_is.currentSlug || "default"), _is.projectName); } catch (e) {}
@@ -397,6 +414,7 @@ export function processMessage(msg) {
397
414
  var spBanner = document.getElementById("skip-perms-pill");
398
415
  if (spBanner) spBanner.classList.toggle("hidden", msg.dangerouslySkipPermissions !== true);
399
416
  updateProjectList(msg);
417
+ renderProjectMates();
400
418
  refreshProjectSessionVisibilitySettings(msg.projects);
401
419
  break;
402
420
 
@@ -868,16 +886,14 @@ export function processMessage(msg) {
868
886
  } else if (_prevSid) {
869
887
  delete store.get('sessionDrafts')[_prevSid];
870
888
  }
871
- // runtimeMode/runtimeTerminalId take precedence over the session's
872
- // born mode so the user's current claudeOpenMode preference applies
873
- // to existing sessions too (born-GUI viewed under TUI pref runs
874
- // claude --resume in xterm; born-TUI viewed under GUI pref was
875
- // in-place converted to GUI by the server before this message).
889
+ // Live legacy terminals keep their runtime presentation. Idle legacy
890
+ // sessions are hydrated into chat by the server before this message.
876
891
  var _effectiveMode = msg.runtimeMode || msg.mode || "gui";
877
892
  var _effectiveTerminalId = (typeof msg.runtimeTerminalId === "number")
878
893
  ? msg.runtimeTerminalId
879
894
  : (typeof msg.terminalId === "number" ? msg.terminalId : null);
880
- store.set({ activeSessionId: msg.id, sessionOriginId: msg.sessionOriginId || null, cliSessionId: msg.cliSessionId || null, currentModel: msg.model || "", currentEffort: msg.effort || store.get('currentEffort'), vendorCapabilities: msg.capabilities || {}, sessionIsProcessing: !!msg.isProcessing, activeSessionMode: _effectiveMode, activeTerminalId: _effectiveTerminalId, sessionHasHistory: !!msg.hasHistory, sessionVendorBound: !!msg.vendor || !!msg.hasHistory, sessionFullAccess: msg.permissionMode === "bypassPermissions", currentMode: msg.permissionMode || store.get('currentMode'), effectivePermissionMode: msg.effectivePermissionMode || null, permissionCapabilities: msg.permissionCapabilities || { auto: false, mcpOverride: false }, mcpPermissionModeOverrides: msg.mcpPermissionModeOverrides || {} });
895
+ var _sessionRole = msg.sessionRole === "worker" ? "worker" : "driver";
896
+ store.set({ activeSessionId: msg.id, sessionOriginId: msg.sessionOriginId || null, cliSessionId: msg.cliSessionId || null, currentModel: msg.model || "", currentEffort: msg.effort || store.get('currentEffort'), vendorCapabilities: msg.capabilities || {}, sessionIsProcessing: !!msg.isProcessing, activeSessionMode: _effectiveMode, activeTerminalId: _effectiveTerminalId, sessionHasHistory: !!msg.hasHistory, sessionVendorBound: !!msg.vendor || !!msg.hasHistory, sessionFullAccess: msg.permissionMode === "bypassPermissions", currentMode: msg.permissionMode || store.get('currentMode'), effectivePermissionMode: msg.effectivePermissionMode || null, permissionCapabilities: msg.permissionCapabilities || { auto: false, mcpOverride: false }, mcpPermissionModeOverrides: msg.mcpPermissionModeOverrides || {}, activeSessionMateId: _sessionRole === "worker" ? null : (store.get('activeProjectMateId') || null), activeSessionMateName: _sessionRole === "worker" ? "" : (store.get('activeProjectMateName') || "") });
881
897
  handleScheduledTaskSessionSwitched(msg);
882
898
  requestLoopInterviewState();
883
899
  activateDeliverySession(msg.id, msg.cliSessionId || null, msg.sessionOriginId || null);
@@ -958,7 +974,7 @@ export function processMessage(msg) {
958
974
  }
959
975
  // Reload survival: a restored active session that is a split-group
960
976
  // member reopens its group (no-op when a split is already open).
961
- if (finishProjectSessionActivation()) hideHomeHub();
977
+ finishProjectSessionActivation();
962
978
  maybeRestoreSplitGroup();
963
979
  break;
964
980
 
@@ -1558,15 +1574,10 @@ export function processMessage(msg) {
1558
1574
  break;
1559
1575
 
1560
1576
  case "fs_read_result":
1561
- if (msg.path === "CLAUDE.md" && isProjectSettingsOpen()) {
1562
- handleInstructionsRead(msg);
1563
- } else {
1564
- handleFsRead(msg);
1565
- }
1577
+ handleFsRead(msg);
1566
1578
  break;
1567
1579
 
1568
1580
  case "fs_write_result":
1569
- handleInstructionsWrite(msg);
1570
1581
  break;
1571
1582
 
1572
1583
  case "project_env_result":
@@ -1577,22 +1588,12 @@ export function processMessage(msg) {
1577
1588
  handleProjectEnvSaved(msg);
1578
1589
  break;
1579
1590
 
1580
- case "global_claude_md_result":
1581
- handleGlobalClaudeMdRead(msg);
1582
- break;
1583
-
1584
- case "write_global_claude_md_result":
1585
- handleGlobalClaudeMdWrite(msg);
1586
- break;
1587
-
1588
1591
  case "shared_env_result":
1589
1592
  handleSharedEnv(msg);
1590
- handleProjectSharedEnv(msg);
1591
1593
  break;
1592
1594
 
1593
1595
  case "set_shared_env_result":
1594
1596
  handleSharedEnvSaved(msg);
1595
- handleProjectSharedEnvSaved(msg);
1596
1597
  break;
1597
1598
 
1598
1599
  case "fs_file_changed":
@@ -1745,6 +1746,13 @@ export function processMessage(msg) {
1745
1746
  handleNoteDeleteResult(msg);
1746
1747
  break;
1747
1748
 
1749
+ case "you_result":
1750
+ case "you_changed":
1751
+ case "you_reviewed":
1752
+ handleYouMessage(msg);
1753
+ handleYouActivity(msg);
1754
+ break;
1755
+
1748
1756
  case "project_logs_state":
1749
1757
  handleProjectLogsState(msg);
1750
1758
  break;
@@ -1930,6 +1938,8 @@ export function processMessage(msg) {
1930
1938
  }
1931
1939
  }
1932
1940
  store.set({ cachedMatesList: _cml });
1941
+ refreshProjectAssistantIdentities(messagesEl);
1942
+ syncHomeMateSettingsTarget(msg);
1933
1943
  // renderUserStrip is handled by the store subscriber
1934
1944
  // Update mate sidebar if currently viewing this mate
1935
1945
  if (store.get('dmMode') && store.get('dmTargetUser') && store.get('dmTargetUser').isMate && store.get('dmTargetUser').id === msg.mate.id) {
@@ -1966,6 +1976,7 @@ export function processMessage(msg) {
1966
1976
 
1967
1977
  case "mate_list":
1968
1978
  store.set({ cachedMatesList: msg.mates || [], cachedAvailableBuiltins: msg.availableBuiltins || [] });
1979
+ refreshProjectAssistantIdentities(messagesEl);
1969
1980
  // renderUserStrip is handled by the store subscriber
1970
1981
  break;
1971
1982
 
@@ -1974,6 +1985,7 @@ export function processMessage(msg) {
1974
1985
  break;
1975
1986
 
1976
1987
  case "mate_error":
1988
+ handleHomeMateAvatarError(msg);
1977
1989
  showToast(msg.error || "Mate operation failed", "error");
1978
1990
  break;
1979
1991
 
@@ -2162,30 +2174,16 @@ export function processMessage(msg) {
2162
2174
  handleKeepAwakeChanged(msg);
2163
2175
  break;
2164
2176
 
2165
- case "set_inherit_groups_result":
2166
- case "inherit_groups_changed":
2167
- handleInheritGroupsChanged(msg);
2168
- break;
2169
-
2170
2177
  case "set_auto_continue_result":
2171
2178
  case "auto_continue_changed":
2172
2179
  handleAutoContinueChanged(msg);
2173
2180
  break;
2174
2181
 
2175
- case "set_claude_open_mode_result":
2176
- case "claude_open_mode_changed":
2177
- if (msg.claudeOpenMode === "tui" || msg.claudeOpenMode === "gui") {
2178
- store.set({ claudeOpenMode: msg.claudeOpenMode });
2179
- // Reflect into the user-settings toggle if it's already in the DOM.
2180
- var _comToggle = document.getElementById("us-claude-open-mode");
2181
- if (_comToggle) _comToggle.checked = msg.claudeOpenMode === "tui";
2182
- }
2183
- break;
2184
-
2185
2182
  case "claude_allow_list":
2183
+ handlePersonalSettingsMessage(msg);
2186
2184
  // Initial state for the user-settings allow-list editor.
2187
2185
  var _alTa = document.getElementById("us-claude-allow-list");
2188
- if (_alTa && Array.isArray(msg.user)) {
2186
+ if (_alTa && Array.isArray(msg.user) && !store.get("userAllowDirty")) {
2189
2187
  _alTa.value = msg.user.join("\n");
2190
2188
  }
2191
2189
  var _alManaged = document.getElementById("us-claude-allow-managed");
@@ -2201,19 +2199,7 @@ export function processMessage(msg) {
2201
2199
  break;
2202
2200
 
2203
2201
  case "set_claude_user_allow_list_result":
2204
- var _alStatus = document.getElementById("us-claude-allow-status");
2205
- if (_alStatus) {
2206
- if (msg.ok) {
2207
- _alStatus.textContent = "Saved (applies on next claude invocation)";
2208
- _alStatus.classList.remove("error");
2209
- setTimeout(function () {
2210
- if (_alStatus.textContent.indexOf("Saved") === 0) _alStatus.textContent = "";
2211
- }, 4000);
2212
- } else {
2213
- _alStatus.textContent = "Save failed: " + (msg.error || "unknown");
2214
- _alStatus.classList.add("error");
2215
- }
2216
- }
2202
+ handlePersonalSettingsMessage(msg);
2217
2203
  break;
2218
2204
 
2219
2205
  case "restart_server_result":
@@ -7,8 +7,8 @@ import { refreshIcons, iconHtml } from './icons.js';
7
7
  import { escapeHtml } from './utils.js';
8
8
  import { store } from './store.js';
9
9
  import { getWs } from './ws-ref.js';
10
- import { showHomeHub } from './app-home-hub.js';
11
- import { openHomeChat } from './home-mate-chat.js';
10
+ import { openProjectSession } from './project-session-navigation.js';
11
+ import { openMateWorkspace } from './project-mate-navigation.js';
12
12
  import { getCachedProjects, switchProject, renderProjectList } from './app-projects.js';
13
13
  import { mateAvatarUrl, userAvatarUrl } from './avatar.js';
14
14
  import { openTuiModal } from './tui-attention.js';
@@ -618,11 +618,8 @@ function navigateToNotification(notif) {
618
618
 
619
619
  var mateId = notif.mateId || deriveMateIdFromNotification(notif);
620
620
  if (mateId) {
621
- if (notif.sessionId) {
622
- try { sessionStorage.setItem("pending-notif-session", notif.sessionId); } catch (e) {}
623
- }
624
- showHomeHub();
625
- openHomeChat(mateId);
621
+ if (notif.sessionId) openProjectSession(notif.slug || 'mate-' + mateId, notif.sessionId);
622
+ else openMateWorkspace(mateId);
626
623
  return;
627
624
  }
628
625