clay-server 3.8.1 → 4.0.0-beta.1

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 (182) 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-debate-proposal.js +133 -17
  16. package/lib/project-debate.js +214 -110
  17. package/lib/project-delegated-follow-up.js +84 -0
  18. package/lib/project-delegated-session.js +53 -0
  19. package/lib/project-filesystem.js +7 -9
  20. package/lib/project-knowledge.js +1 -0
  21. package/lib/project-mate-creation-proposal.js +120 -0
  22. package/lib/project-memory.js +14 -7
  23. package/lib/project-models.js +157 -32
  24. package/lib/project-session-notes.js +2 -2
  25. package/lib/project-session-pair.js +8 -8
  26. package/lib/project-sessions.js +66 -51
  27. package/lib/project-worker-proposal.js +25 -25
  28. package/lib/project-workspace-query.js +144 -0
  29. package/lib/project.js +329 -102
  30. package/lib/public/app.js +85 -42
  31. package/lib/public/css/avatar-imprints.css +0 -1
  32. package/lib/public/css/base.css +4 -0
  33. package/lib/public/css/capsule-ui.css +389 -0
  34. package/lib/public/css/command-palette.css +306 -6
  35. package/lib/public/css/home-capsule-library.css +243 -0
  36. package/lib/public/css/home-capsule-source.css +192 -0
  37. package/lib/public/css/home-debate-live.css +146 -0
  38. package/lib/public/css/home-debate-planning.css +125 -0
  39. package/lib/public/css/home-debates-archive.css +281 -0
  40. package/lib/public/css/home-hub.css +896 -405
  41. package/lib/public/css/home-mate-creation.css +34 -0
  42. package/lib/public/css/home-mate-model-picker.css +131 -0
  43. package/lib/public/css/home-mate-settings.css +344 -0
  44. package/lib/public/css/home-session-actions.css +265 -0
  45. package/lib/public/css/home-sidebar.css +667 -0
  46. package/lib/public/css/icon-strip.css +1 -2
  47. package/lib/public/css/mates.css +7 -34
  48. package/lib/public/css/pane.css +1 -1
  49. package/lib/public/css/playbook.css +0 -80
  50. package/lib/public/css/sticky-notes.css +53 -117
  51. package/lib/public/css/tui-attention.css +0 -44
  52. package/lib/public/css/workspace-assignment.css +45 -0
  53. package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
  54. package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
  55. package/lib/public/index.html +93 -74
  56. package/lib/public/modules/app-connection.js +10 -1
  57. package/lib/public/modules/app-dm.js +43 -160
  58. package/lib/public/modules/app-home-hub.js +328 -585
  59. package/lib/public/modules/app-message-cards.js +242 -0
  60. package/lib/public/modules/app-message-router.js +84 -0
  61. package/lib/public/modules/app-messages.js +78 -20
  62. package/lib/public/modules/app-notifications.js +4 -2
  63. package/lib/public/modules/app-projects.js +9 -1
  64. package/lib/public/modules/app-rendering.js +21 -602
  65. package/lib/public/modules/avatar-imprint.js +11 -8
  66. package/lib/public/modules/chat-bubble-renderer.js +152 -0
  67. package/lib/public/modules/chat-render-runtime.js +198 -0
  68. package/lib/public/modules/command-palette.js +225 -436
  69. package/lib/public/modules/dm-render.js +82 -0
  70. package/lib/public/modules/home-capsule-creation-intent.js +31 -0
  71. package/lib/public/modules/home-capsule-library.js +146 -0
  72. package/lib/public/modules/home-capsule-source.js +383 -0
  73. package/lib/public/modules/home-chat-identity.js +35 -0
  74. package/lib/public/modules/home-chat-scroll.js +77 -0
  75. package/lib/public/modules/home-chat-stream-state.js +34 -0
  76. package/lib/public/modules/home-composer-focus.js +25 -0
  77. package/lib/public/modules/home-conversations-sheet.js +179 -0
  78. package/lib/public/modules/home-debate-activity.js +48 -0
  79. package/lib/public/modules/home-debate-controls.js +295 -0
  80. package/lib/public/modules/home-debate-launch.js +41 -0
  81. package/lib/public/modules/home-debate-live.js +284 -0
  82. package/lib/public/modules/home-debate-models.js +73 -0
  83. package/lib/public/modules/home-debate-planning.js +335 -0
  84. package/lib/public/modules/home-debates-archive.js +279 -0
  85. package/lib/public/modules/home-dock-resize.js +74 -0
  86. package/lib/public/modules/home-dock.js +446 -0
  87. package/lib/public/modules/home-mate-chat.js +496 -0
  88. package/lib/public/modules/home-mate-creation.js +109 -0
  89. package/lib/public/modules/home-mate-model-picker.js +281 -0
  90. package/lib/public/modules/home-mate-selection.js +38 -0
  91. package/lib/public/modules/home-mate-settings-menu.js +131 -0
  92. package/lib/public/modules/home-mate-settings.js +383 -0
  93. package/lib/public/modules/home-session-actions.js +373 -0
  94. package/lib/public/modules/home-session-model-confirmation.js +13 -0
  95. package/lib/public/modules/home-shell.js +9 -0
  96. package/lib/public/modules/home-sidebar-chat-list.js +63 -0
  97. package/lib/public/modules/home-sidebar.js +158 -0
  98. package/lib/public/modules/home-sub-surface.js +19 -0
  99. package/lib/public/modules/home-surface-boot.js +68 -0
  100. package/lib/public/modules/home-surface.js +141 -0
  101. package/lib/public/modules/home-tools.js +271 -0
  102. package/lib/public/modules/markdown.js +50 -2
  103. package/lib/public/modules/mate-management.js +86 -0
  104. package/lib/public/modules/mate-wizard.js +0 -7
  105. package/lib/public/modules/mention.js +17 -19
  106. package/lib/public/modules/profile.js +4 -5
  107. package/lib/public/modules/project-settings.js +34 -28
  108. package/lib/public/modules/project-switcher.js +11 -5
  109. package/lib/public/modules/project-workspace-assignment.js +23 -0
  110. package/lib/public/modules/search-clay-chat.js +402 -0
  111. package/lib/public/modules/server-settings.js +14 -12
  112. package/lib/public/modules/session-actions.js +1 -1
  113. package/lib/public/modules/sidebar-mates.js +56 -552
  114. package/lib/public/modules/sidebar-mobile.js +7 -64
  115. package/lib/public/modules/sidebar-presence.js +37 -0
  116. package/lib/public/modules/split-pair-ui.js +13 -13
  117. package/lib/public/modules/sticky-notes.js +7 -6
  118. package/lib/public/modules/tool-input-composition.js +48 -0
  119. package/lib/public/modules/tool-llm-status.js +167 -0
  120. package/lib/public/modules/tool-renderer-advanced.js +285 -0
  121. package/lib/public/modules/tool-renderer-chart.js +158 -0
  122. package/lib/public/modules/tool-renderer-semantics.js +35 -0
  123. package/lib/public/modules/tool-renderer.js +464 -0
  124. package/lib/public/modules/tool-runtime.js +309 -0
  125. package/lib/public/modules/tool-ui-evaluator.js +97 -0
  126. package/lib/public/modules/tool-ui-tree.js +21 -0
  127. package/lib/public/modules/user-settings.js +16 -23
  128. package/lib/public/modules/worker-proposal.js +2 -2
  129. package/lib/public/modules/workspace-assignment-card.js +149 -0
  130. package/lib/public/modules/workspace-assignment-routing.js +4 -0
  131. package/lib/public/style.css +13 -2
  132. package/lib/runtime-env.js +65 -0
  133. package/lib/sdk-bridge.js +120 -32
  134. package/lib/sdk-message-processor.js +10 -6
  135. package/lib/server-home-capsule-creation.js +36 -0
  136. package/lib/server-home-chat-events.js +287 -0
  137. package/lib/server-home-chat.js +518 -0
  138. package/lib/server-home-clay-entry.js +65 -0
  139. package/lib/server-home-clay-session-links.js +26 -0
  140. package/lib/server-home-debate-planning.js +214 -0
  141. package/lib/server-home-debates.js +137 -0
  142. package/lib/server-home-mate-creation.js +261 -0
  143. package/lib/server-home-models.js +241 -0
  144. package/lib/server-home-preferences.js +61 -0
  145. package/lib/server-mates.js +37 -0
  146. package/lib/server-tools.js +377 -0
  147. package/lib/server.js +111 -59
  148. package/lib/session-pair-mcp-server.js +6 -6
  149. package/lib/sessions.js +18 -3
  150. package/lib/tool-capsule-source.js +142 -0
  151. package/lib/tool-control-mcp-server.js +126 -0
  152. package/lib/tool-llm.js +48 -0
  153. package/lib/tool-storage.js +77 -0
  154. package/lib/tool-ui-spec-advanced.js +82 -0
  155. package/lib/tool-ui-spec.js +261 -0
  156. package/lib/tools-registry.js +276 -0
  157. package/lib/users-home-dock-preferences.js +77 -0
  158. package/lib/users-home-surface-preferences.js +99 -0
  159. package/lib/users-preferences.js +4 -7
  160. package/lib/users.js +12 -0
  161. package/lib/whats-new-content.js +3 -3
  162. package/lib/workspace-assignment-service.js +420 -0
  163. package/lib/workspace-query-mcp-server.js +154 -0
  164. package/lib/workspace-query-service.js +492 -0
  165. package/lib/ws-schema.js +86 -12
  166. package/lib/yoke/adapters/acp.js +2 -1
  167. package/lib/yoke/adapters/antigravity.js +2 -1
  168. package/lib/yoke/adapters/claude-worker.js +11 -4
  169. package/lib/yoke/adapters/claude.js +73 -43
  170. package/lib/yoke/adapters/codex.js +37 -6
  171. package/lib/yoke/adapters/kiro.js +2 -1
  172. package/lib/yoke/claude-user-input.js +38 -0
  173. package/lib/yoke/codex-user-input.js +64 -0
  174. package/lib/yoke/complete-once.js +164 -0
  175. package/lib/yoke/index.js +5 -1
  176. package/lib/yoke/interface.js +19 -0
  177. package/lib/yoke/mcp-bridge-server.js +2 -6
  178. package/lib/yoke/user-input.js +254 -0
  179. package/package.json +2 -1
  180. package/lib/public/css/home-chat.css +0 -380
  181. package/lib/public/modules/home-chat.js +0 -438
  182. package/lib/server-clay-home.js +0 -245
@@ -0,0 +1,242 @@
1
+ // app-message-cards.js - Non-stream project message and notice rendering.
2
+
3
+ import { store } from './store.js';
4
+ import { getWs } from './ws-ref.js';
5
+ import { escapeHtml, copyToClipboard } from './utils.js';
6
+ import { renderMarkdown, highlightCodeBlocks } from './markdown.js';
7
+ import { iconHtml, refreshIcons } from './icons.js';
8
+ import { userAvatarUrl } from './avatar.js';
9
+ import { showImageModal, showPasteModal } from './app-misc.js';
10
+ import { addToMessages, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, setTurnCounter, VENDOR_AVATARS } from './chat-render-runtime.js';
11
+
12
+ export function addUserMessage(text, images, pastes, fromUserId, fromUserName, delegatedMeta) {
13
+ if (!text && (!images || images.length === 0) && (!pastes || pastes.length === 0)) return;
14
+ var myUserId = store.get('myUserId');
15
+ var isDelegated = !!delegatedMeta;
16
+ var isOtherUser = isDelegated || (fromUserId && fromUserId !== myUserId);
17
+ var div = document.createElement("div");
18
+ div.className = "msg-user" + (isOtherUser ? " msg-user-other" : "");
19
+ if (isDelegated) div.classList.add("msg-user-delegated");
20
+ var turn = getTurnCounter() + 1;
21
+ setTurnCounter(turn);
22
+ div.dataset.turn = turn;
23
+ if (shouldGroupMessage("msg-user")) div.classList.add("grouped");
24
+ var bubble = document.createElement("div");
25
+ bubble.className = "bubble";
26
+ bubble.dir = "auto";
27
+
28
+ if (isDelegated) {
29
+ var cardHead = document.createElement("div");
30
+ cardHead.className = "delegated-card-head";
31
+ var cardAvi = document.createElement("img");
32
+ cardAvi.className = "delegated-card-avatar";
33
+ cardAvi.src = VENDOR_AVATARS[delegatedMeta.delegatedByVendor] || VENDOR_AVATARS.claude;
34
+ cardAvi.alt = "";
35
+ cardHead.appendChild(cardAvi);
36
+ var cardHeadText = document.createElement("div");
37
+ cardHeadText.className = "delegated-card-headtext";
38
+ var eyebrow = document.createElement("span");
39
+ eyebrow.className = "delegated-card-eyebrow";
40
+ eyebrow.textContent = "Delegated task";
41
+ cardHeadText.appendChild(eyebrow);
42
+ var cardFrom = document.createElement("span");
43
+ cardFrom.className = "delegated-card-from";
44
+ cardFrom.textContent = delegatedMeta.delegatedByTitle || "Driver";
45
+ cardHeadText.appendChild(cardFrom);
46
+ cardHead.appendChild(cardHeadText);
47
+ var cardTime = document.createElement("span");
48
+ cardTime.className = "delegated-card-time";
49
+ cardTime.textContent = getMsgTime();
50
+ cardHead.appendChild(cardTime);
51
+ bubble.appendChild(cardHead);
52
+ }
53
+
54
+ if (images && images.length > 0) {
55
+ var imgRow = document.createElement("div");
56
+ imgRow.className = "bubble-images";
57
+ for (var i = 0; i < images.length; i++) {
58
+ var img = document.createElement("img");
59
+ if (images[i].url) img.src = images[i].url;
60
+ else if (images[i].data) img.src = "data:" + images[i].mediaType + ";base64," + images[i].data;
61
+ img.loading = "lazy";
62
+ img.className = "bubble-img";
63
+ img.addEventListener("click", function () { showImageModal(this.src); });
64
+ img.addEventListener("error", function () {
65
+ var placeholder = document.createElement("div");
66
+ placeholder.className = "bubble-img-expired";
67
+ placeholder.textContent = "Image deleted";
68
+ this.parentNode.replaceChild(placeholder, this);
69
+ });
70
+ imgRow.appendChild(img);
71
+ }
72
+ bubble.appendChild(imgRow);
73
+ }
74
+
75
+ if (pastes && pastes.length > 0) {
76
+ var pasteRow = document.createElement("div");
77
+ pasteRow.className = "bubble-pastes";
78
+ for (var p = 0; p < pastes.length; p++) {
79
+ (function (pasteText) {
80
+ var chip = document.createElement("div");
81
+ chip.className = "bubble-paste";
82
+ var preview = pasteText.substring(0, 60).replace(/\n/g, " ");
83
+ if (pasteText.length > 60) preview += "...";
84
+ chip.innerHTML = '<span class="bubble-paste-preview">' + escapeHtml(preview) + '</span><span class="bubble-paste-label">PASTED</span>';
85
+ chip.addEventListener("click", function (event) {
86
+ event.stopPropagation();
87
+ showPasteModal(pasteText);
88
+ });
89
+ pasteRow.appendChild(chip);
90
+ })(pastes[p]);
91
+ }
92
+ bubble.appendChild(pasteRow);
93
+ }
94
+
95
+ if (text) {
96
+ if (isDelegated) {
97
+ var mdEl = document.createElement("div");
98
+ mdEl.className = "md-content delegated-brief";
99
+ mdEl.innerHTML = renderMarkdown(text);
100
+ highlightCodeBlocks(mdEl);
101
+ bubble.appendChild(mdEl);
102
+ } else {
103
+ var textEl = document.createElement("span");
104
+ textEl.textContent = text;
105
+ bubble.appendChild(textEl);
106
+ }
107
+ }
108
+
109
+ var cachedAllUsers = store.get('cachedAllUsers');
110
+ var targetUser;
111
+ var displayName;
112
+ if (isDelegated) {
113
+ targetUser = null;
114
+ displayName = "from " + (delegatedMeta.delegatedByTitle || "Driver");
115
+ } else if (isOtherUser) {
116
+ targetUser = cachedAllUsers.find(function (user) { return user.id === fromUserId; });
117
+ displayName = fromUserName || (targetUser && (targetUser.displayName || targetUser.username)) || "User";
118
+ } else {
119
+ targetUser = cachedAllUsers.find(function (user) { return user.id === myUserId; });
120
+ displayName = document.body.dataset.myDisplayName || "";
121
+ if (!displayName) displayName = (targetUser && (targetUser.displayName || targetUser.username)) || "Me";
122
+ }
123
+
124
+ var avatar = document.createElement("img");
125
+ avatar.className = "dm-bubble-avatar" + (isOtherUser ? " dm-bubble-avatar-other" : " dm-bubble-avatar-me");
126
+ avatar.src = isDelegated
127
+ ? (VENDOR_AVATARS[delegatedMeta.delegatedByVendor] || VENDOR_AVATARS.claude)
128
+ : isOtherUser
129
+ ? userAvatarUrl(targetUser || { id: fromUserId }, 36)
130
+ : (document.body.dataset.myAvatarUrl || userAvatarUrl(targetUser || { id: myUserId }, 36));
131
+ div.appendChild(avatar);
132
+
133
+ var contentWrap = document.createElement("div");
134
+ contentWrap.className = "dm-bubble-content";
135
+ var header = document.createElement("div");
136
+ header.className = "dm-bubble-header";
137
+ var nameSpan = document.createElement("span");
138
+ nameSpan.className = "dm-bubble-name";
139
+ nameSpan.textContent = displayName;
140
+ header.appendChild(nameSpan);
141
+ var timeSpan = document.createElement("span");
142
+ timeSpan.className = "dm-bubble-time";
143
+ timeSpan.textContent = getMsgTime();
144
+ header.appendChild(timeSpan);
145
+ contentWrap.appendChild(header);
146
+ contentWrap.appendChild(bubble);
147
+ div.appendChild(contentWrap);
148
+
149
+ var actions = document.createElement("div");
150
+ actions.className = "msg-actions";
151
+ actions.innerHTML =
152
+ '<span class="msg-action-time">' + getMsgTime() + '</span>' +
153
+ '<button class="msg-action-btn msg-action-copy" type="button" title="Copy">' + iconHtml("copy") + '</button>' +
154
+ '<button class="msg-action-btn msg-action-fork" type="button" title="Fork">' + iconHtml("git-branch") + '</button>' +
155
+ (((store.get('vendorCapabilities') || {}).rewind !== false) ? '<button class="msg-action-btn msg-action-rewind msg-user-rewind-btn" type="button" title="Rewind">' + iconHtml("rotate-ccw") + '</button>' : '') +
156
+ '<button class="msg-action-btn msg-action-hidden msg-action-edit" type="button" title="Edit">' + iconHtml("pencil") + '</button>';
157
+ div.appendChild(actions);
158
+ actions.querySelector(".msg-action-copy").addEventListener("click", function () {
159
+ var self = this;
160
+ copyToClipboard(text || "");
161
+ self.innerHTML = iconHtml("check");
162
+ refreshIcons();
163
+ setTimeout(function () { self.innerHTML = iconHtml("copy"); refreshIcons(); }, 1200);
164
+ });
165
+
166
+ addToMessages(div);
167
+ refreshIcons();
168
+ forceScrollToBottom();
169
+ }
170
+
171
+ export function addSystemMessage(text, isError) {
172
+ var div = document.createElement("div");
173
+ div.className = "sys-msg" + (isError ? " error" : "");
174
+ div.innerHTML = '<span class="sys-text"></span>';
175
+ div.querySelector(".sys-text").textContent = text;
176
+ addToMessages(div);
177
+ scrollToBottom();
178
+ }
179
+
180
+ export function addConflictMessage(msg) {
181
+ var div = document.createElement("div");
182
+ div.className = "conflict-msg";
183
+ var header = document.createElement("div");
184
+ header.className = "conflict-header";
185
+ header.textContent = msg.text || "Another Claude Code process is already running.";
186
+ div.appendChild(header);
187
+ var hint = document.createElement("div");
188
+ hint.className = "conflict-hint";
189
+ hint.textContent = "Kill the conflicting process to continue, or use the existing Claude Code session.";
190
+ div.appendChild(hint);
191
+
192
+ for (var i = 0; i < msg.processes.length; i++) {
193
+ var process = msg.processes[i];
194
+ var row = document.createElement("div");
195
+ row.className = "conflict-process";
196
+ var info = document.createElement("span");
197
+ info.className = "conflict-pid";
198
+ info.textContent = "PID " + process.pid;
199
+ row.appendChild(info);
200
+ var command = document.createElement("code");
201
+ command.className = "conflict-cmd";
202
+ command.textContent = process.command.length > 80 ? process.command.substring(0, 80) + "..." : process.command;
203
+ command.title = process.command;
204
+ row.appendChild(command);
205
+ var killBtn = document.createElement("button");
206
+ killBtn.className = "conflict-kill-btn";
207
+ killBtn.textContent = "Kill Process";
208
+ killBtn.setAttribute("data-pid", process.pid);
209
+ killBtn.addEventListener("click", function () {
210
+ var pid = parseInt(this.getAttribute("data-pid"), 10);
211
+ getWs().send(JSON.stringify({ type: "kill_process", pid: pid }));
212
+ this.disabled = true;
213
+ this.textContent = "Killing...";
214
+ });
215
+ row.appendChild(killBtn);
216
+ div.appendChild(row);
217
+ }
218
+ addToMessages(div);
219
+ scrollToBottom();
220
+ }
221
+
222
+ export function addContextOverflowMessage(msg) {
223
+ var div = document.createElement("div");
224
+ div.className = "context-overflow-msg";
225
+ var header = document.createElement("div");
226
+ header.className = "context-overflow-header";
227
+ header.textContent = msg.text || "Conversation too long to continue.";
228
+ div.appendChild(header);
229
+ var hint = document.createElement("div");
230
+ hint.className = "context-overflow-hint";
231
+ hint.textContent = "The conversation has exceeded the model's context limit. Please start a new conversation to continue.";
232
+ div.appendChild(hint);
233
+ var button = document.createElement("button");
234
+ button.className = "context-overflow-btn";
235
+ button.textContent = "New Conversation";
236
+ button.addEventListener("click", function () {
237
+ getWs().send(JSON.stringify({ type: "new_session" }));
238
+ });
239
+ div.appendChild(button);
240
+ addToMessages(div);
241
+ scrollToBottom();
242
+ }
@@ -0,0 +1,84 @@
1
+ // Narrow pre-router for Home and Capsule protocol responses kept out of the legacy router.
2
+
3
+ import { processMessage as processAppMessage } from './app-messages.js';
4
+ import { handleHomeMateModelsState, handleHomeMateModelResult } from './home-mate-settings.js';
5
+ import { handleHomeMateSessionIdentity, handleHomeDebateTranscript, handleHomeWorkspaceAssignment } from './home-mate-chat.js';
6
+ import { handleToolLlmConfigState } from './tool-llm-status.js';
7
+ import { handleToolSourceState, handleToolMateAccessState } from './home-tools.js';
8
+ import { handleHomeDebatesState } from './home-debates-archive.js';
9
+ import { renderProjectWorkspaceAssignment, showProjectWorkspaceAssignmentError } from './project-workspace-assignment.js';
10
+ import { isHomeWorkspaceAssignmentMessage } from './workspace-assignment-routing.js';
11
+ import { handleSearchClayMessage } from './search-clay-chat.js';
12
+ import { handleClaySessionTarget } from './command-palette.js';
13
+
14
+ export function handleHomeProtocolMessage(msg) {
15
+ if (handleClaySessionTarget(msg)) return true;
16
+ if (isHomeWorkspaceAssignmentMessage(msg)) {
17
+ handleHomeWorkspaceAssignment(msg);
18
+ return true;
19
+ }
20
+ if (msg.type === "project_assignment_proposal" || msg.type === "project_assignment_status") {
21
+ renderProjectWorkspaceAssignment(msg);
22
+ return true;
23
+ }
24
+ if (msg.type === "project_assignment_error") {
25
+ showProjectWorkspaceAssignmentError(msg);
26
+ return true;
27
+ }
28
+ if (msg.type === "home_debates_state") {
29
+ handleHomeDebatesState(msg);
30
+ return true;
31
+ }
32
+ if (msg.type === "home_mate_models_state") {
33
+ handleHomeMateModelsState(msg);
34
+ return true;
35
+ }
36
+ if (msg.type === "home_mate_model_result") {
37
+ handleHomeMateModelResult(msg);
38
+ return true;
39
+ }
40
+ if (msg.type === "home_mate_session_identity") {
41
+ handleHomeMateSessionIdentity(msg);
42
+ return true;
43
+ }
44
+ if (msg.type === "home_debate_proposal") {
45
+ handleHomeDebateTranscript(msg);
46
+ return true;
47
+ }
48
+ if (msg.type === "home_debate_proposal_resolved") {
49
+ handleHomeDebateTranscript(msg);
50
+ return true;
51
+ }
52
+ if (msg.type === "home_debate_question" || msg.type === "home_debate_question_resolved" || msg.type === "home_debate_event") {
53
+ handleHomeDebateTranscript(msg);
54
+ return true;
55
+ }
56
+ if (msg.type === "home_mate_creation_question" || msg.type === "home_mate_creation_question_resolved" || msg.type === "home_mate_creation_proposal" || msg.type === "home_mate_creation_proposal_resolved") {
57
+ handleHomeDebateTranscript(msg);
58
+ return true;
59
+ }
60
+ if (msg.type === "home_mate_error" && /^question_/.test(msg.code || "")) {
61
+ handleHomeDebateTranscript(msg);
62
+ return true;
63
+ }
64
+ if (msg.type === "tool_llm_config_state") {
65
+ handleToolLlmConfigState(msg);
66
+ return true;
67
+ }
68
+ if (msg.type === "tool_source_state") {
69
+ handleToolSourceState(msg);
70
+ return true;
71
+ }
72
+ if (msg.type === "tool_mate_access_state") {
73
+ handleToolMateAccessState(msg);
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+
79
+ export function processMessage(msg) {
80
+ var searchHandled = handleSearchClayMessage(msg);
81
+ if (searchHandled && msg.type === "home_clay_activity") return;
82
+ if (handleHomeProtocolMessage(msg)) return;
83
+ processAppMessage(msg);
84
+ }
@@ -11,10 +11,13 @@ import { refreshIcons, iconHtml } from './icons.js';
11
11
  import { renderMarkdown, highlightCodeBlocks, renderMermaidBlocks } from './markdown.js';
12
12
  import { updatePageTitle } from './sidebar.js';
13
13
  import { renderSessionList, updateSessionPresence, handleSearchResults, updateSessionBadge } from './sidebar-sessions.js';
14
- import { updateDmBadge, renderSidebarPresence, setMentionActive, renderUserStrip } from './sidebar-mates.js';
14
+ import { updateDmBadge, setMentionActive, renderUserStrip } from './sidebar-mates.js';
15
+ import { renderSidebarPresence } from './sidebar-presence.js';
15
16
  import { refreshMobileChatSheet } from './sidebar-mobile.js';
16
17
  import { renderMateSessionList, handleMateSearchResults, updateMateSidebarProfile } from './mate-sidebar.js';
17
- import { handleHomeClayHistory, handleHomeClayDelta, handleHomeClayDone, handleHomeClayError } from './home-chat.js';
18
+ import { openHomeChat, handleHomeMateHistory, handleHomeMateDelta, handleHomeMateDone, handleHomeMateError, handleHomeMateSessionsState } from './home-mate-chat.js';
19
+ import { handleHomeSurfaceState } from './home-surface.js';
20
+ import { handleHomeMateMemoryState, handleHomeMateKnowledgeState } from './home-mate-settings.js';
18
21
  import { renderKnowledgeList, handleKnowledgeContent } from './mate-knowledge.js';
19
22
  import { renderMemoryList } from './mate-memory.js';
20
23
  import { handlePaletteSessionSwitch, setPaletteVersion } from './command-palette.js';
@@ -60,8 +63,10 @@ import { getModelInfoUpdate, modelEntryValue, modelEntryMatches, handleModelSele
60
63
  import { getModelEffortLevels, accumulateUsage, updateUsagePanel, accumulateContext, updateContextPanel, renderCtxPopover, updateStatusPanel } from './app-panels.js';
61
64
  import { updateProjectList, resetClientState, showUpdateAvailable, handleRemoveProjectCheckResult, handleRemoveProjectResult, handleBrowseDirResult, handleAddProjectResult, handleCloneProgress } from './app-projects.js';
62
65
  import { updateHistorySentinel, prependOlderHistory } from './app-header.js';
63
- import { hideHomeHub, handleHubSchedules } from './app-home-hub.js';
64
- import { openDm, enterDmMode, exitDmMode, handleMateCreatedInApp, updateMateIconStatus, appendDmMessage, showDmTypingIndicator, buildMateInterviewPrompt } from './app-dm.js';
66
+ import { hideHomeHub, showHomeHub } from './app-home-hub.js';
67
+ import { handleToolsState, handleToolInstalled, handleToolRemoved, handleToolStorageResult, handleToolLlmResult, handleToolsError, handleToolControlRequest } from './home-tools.js';
68
+ import { handleHomeDockState } from './home-dock.js';
69
+ import { enterDmMode, exitDmMode, handleMateCreatedInApp, updateMateIconStatus, appendDmMessage, showDmTypingIndicator, buildMateInterviewPrompt } from './app-dm.js';
65
70
  import { handleRateLimitEvent, updateRateLimitUsage, addScheduledMessageBubble, removeScheduledMessageBubble, handleFastModeState } from './app-rate-limit.js';
66
71
  import { handleRemoteCursorMove, handleRemoteCursorLeave, handleRemoteSelection, clearRemoteCursors } from './app-cursors.js';
67
72
  import { showLoopBanner, updateLoopBanner, updateLoopInputVisibility, showRalphApprovalBar, updateRalphApprovalStatus, openRalphPreviewModal, showExecModal, updateExecModalStatus } from './app-loop-ui.js';
@@ -259,15 +264,12 @@ export function processMessage(msg) {
259
264
 
260
265
  case "restore_mate_dm":
261
266
  if (msg.mateId && !store.get('returningFromMateDm')) {
262
- // Server-driven mate DM restore on reconnect
263
- // Note: do NOT remove mate-dm-active here; openDm is async (skill check)
264
- // and removing the class causes a flash where mate UI is lost.
265
- // enterDmMode will properly set/reset the class when DM is entered.
266
267
  if (store.get('dmMode')) {
267
268
  store.set({ dmMode: false });
268
269
  }
269
270
  messagesEl.innerHTML = "";
270
- openDm(msg.mateId);
271
+ showHomeHub();
272
+ openHomeChat(msg.mateId);
271
273
  }
272
274
  // Clear the flag and notify server that mate DM is closed
273
275
  if (store.get('returningFromMateDm')) {
@@ -376,20 +378,32 @@ export function processMessage(msg) {
376
378
  connectOverlay.classList.remove("hidden");
377
379
  break;
378
380
 
379
- case "home_clay_history":
380
- handleHomeClayHistory(msg);
381
+ case "home_mate_history":
382
+ handleHomeMateHistory(msg);
381
383
  break;
382
384
 
383
- case "home_clay_delta":
384
- handleHomeClayDelta(msg);
385
+ case "home_mate_sessions_state":
386
+ handleHomeMateSessionsState(msg);
385
387
  break;
386
388
 
387
- case "home_clay_done":
388
- handleHomeClayDone();
389
+ case "home_mate_delta":
390
+ handleHomeMateDelta(msg);
389
391
  break;
390
392
 
391
- case "home_clay_error":
392
- handleHomeClayError(msg);
393
+ case "home_mate_done":
394
+ handleHomeMateDone(msg);
395
+ break;
396
+
397
+ case "home_mate_error":
398
+ handleHomeMateError(msg);
399
+ break;
400
+
401
+ case "home_mate_memory_state":
402
+ handleHomeMateMemoryState(msg);
403
+ break;
404
+
405
+ case "home_mate_knowledge_state":
406
+ handleHomeMateKnowledgeState(msg);
393
407
  break;
394
408
 
395
409
  case "slash_commands":
@@ -568,8 +582,40 @@ export function processMessage(msg) {
568
582
  handleRemoveProjectCheckResult(msg);
569
583
  break;
570
584
 
571
- case "hub_schedules":
572
- handleHubSchedules(msg);
585
+ case "tools_state":
586
+ handleToolsState(msg);
587
+ break;
588
+
589
+ case "home_dock_state":
590
+ handleHomeDockState(msg);
591
+ break;
592
+
593
+ case "home_surface_state":
594
+ handleHomeSurfaceState(msg);
595
+ break;
596
+
597
+ case "tool_installed":
598
+ handleToolInstalled(msg);
599
+ break;
600
+
601
+ case "tool_removed":
602
+ handleToolRemoved(msg);
603
+ break;
604
+
605
+ case "tool_storage_result":
606
+ handleToolStorageResult(msg);
607
+ break;
608
+
609
+ case "tool_llm_result":
610
+ handleToolLlmResult(msg);
611
+ break;
612
+
613
+ case "tools_error":
614
+ handleToolsError(msg);
615
+ break;
616
+
617
+ case "tool_control_request":
618
+ handleToolControlRequest(msg);
573
619
  break;
574
620
 
575
621
  case "input_sync":
@@ -811,7 +857,7 @@ export function processMessage(msg) {
811
857
  } else {
812
858
  addUserMessage(msg.text, msg.images || null, msg.pastes || null, msg.from, msg.fromName, msg.delegated ? msg : null);
813
859
  }
814
- // Worker pane: a delegated instruction starts (or replays into) a
860
+ // Split Worker pane: a delegated instruction starts (or replays into) a
815
861
  // driven turn; surface the composer notice. Cleared on "done".
816
862
  if (msg.delegated) showWorkerDelegationNotice(msg.delegatedByTitle || null);
817
863
  break;
@@ -1810,6 +1856,18 @@ export function processMessage(msg) {
1810
1856
  handleDebateTurnDone(msg);
1811
1857
  break;
1812
1858
 
1859
+ case "debate_tool_decision":
1860
+ addSystemMessage((msg.action || "Use " + (msg.toolName || "tool")) + " · " + (msg.decision === "allowed" ? "Allowed" : "Blocked") + (msg.reason ? " — " + msg.reason : "") + (msg.command ? "\n$ " + msg.command : ""), msg.decision !== "allowed");
1861
+ break;
1862
+
1863
+ case "debate_stop_requested":
1864
+ addSystemMessage("Debate will stop after the current speaker finishes.", false);
1865
+ break;
1866
+
1867
+ case "debate_stop_cancelled":
1868
+ addSystemMessage("Debate stop cancelled.", false);
1869
+ break;
1870
+
1813
1871
  case "debate_hand_raised":
1814
1872
  // Visual feedback: hand is raised, waiting for floor
1815
1873
  break;
@@ -6,7 +6,8 @@ import { refreshIcons, iconHtml } from './icons.js';
6
6
  import { escapeHtml } from './utils.js';
7
7
  import { store } from './store.js';
8
8
  import { getWs } from './ws-ref.js';
9
- import { openDm } from './app-dm.js';
9
+ import { showHomeHub } from './app-home-hub.js';
10
+ import { openHomeChat } from './home-mate-chat.js';
10
11
  import { getCachedProjects, switchProject, renderProjectList } from './app-projects.js';
11
12
  import { mateAvatarUrl, userAvatarUrl } from './avatar.js';
12
13
  import { openTerminal } from './terminal.js';
@@ -726,7 +727,8 @@ function navigateToNotification(notif) {
726
727
  if (notif.sessionId) {
727
728
  try { sessionStorage.setItem("pending-notif-session", notif.sessionId); } catch (e) {}
728
729
  }
729
- openDm(mateId);
730
+ showHomeHub();
731
+ openHomeChat(mateId);
730
732
  return;
731
733
  }
732
734
 
@@ -413,6 +413,7 @@ export function resetClientState() {
413
413
 
414
414
  export function switchProject(slug) {
415
415
  if (!slug) return;
416
+ document.cookie = "clay_last_project=" + encodeURIComponent(slug) + "; Path=/; SameSite=Strict; Max-Age=31536000";
416
417
  var st = store.snap();
417
418
  var wasDm = st.dmMode;
418
419
  var wasMate = st.dmMode && st.dmTargetUser && st.dmTargetUser.isMate;
@@ -420,7 +421,14 @@ export function switchProject(slug) {
420
421
  closeWhatsNewArticle();
421
422
  if (isHomeHubVisible()) {
422
423
  hideHomeHub();
423
- if (slug === store.get('currentSlug')) return;
424
+ if (slug === store.get('currentSlug')) {
425
+ if (document.documentElement.classList.contains("pwa-standalone")) {
426
+ history.replaceState(null, "", "/p/" + slug + "/");
427
+ } else {
428
+ history.pushState(null, "", "/p/" + slug + "/");
429
+ }
430
+ return;
431
+ }
424
432
  }
425
433
  if (slug === store.get('currentSlug')) {
426
434
  var ws = getWs();