clay-server 3.8.1 → 4.0.0-beta.10

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 (222) hide show
  1. package/lib/ask-user-mcp-server.js +5 -119
  2. package/lib/background-task-timing.js +105 -0
  3. package/lib/builtin-mates.js +6 -6
  4. package/lib/claude-hook-installer.js +15 -0
  5. package/lib/clay-history-mcp-server.js +62 -297
  6. package/lib/daemon.js +23 -1
  7. package/lib/debate-model-selection.js +119 -0
  8. package/lib/home-debate-tool-policy.js +164 -0
  9. package/lib/home-response-notifications.js +26 -0
  10. package/lib/knowledge-import.js +436 -0
  11. package/lib/knowledge-record-store.js +188 -0
  12. package/lib/knowledge-search.js +224 -0
  13. package/lib/mate-creation-mcp-server.js +55 -0
  14. package/lib/mate-knowledge-mcp-server.js +151 -0
  15. package/lib/mate-knowledge-migration.js +283 -0
  16. package/lib/mate-knowledge-service.js +488 -0
  17. package/lib/mate-knowledge-sync.js +482 -0
  18. package/lib/mate-ready-creation.js +95 -0
  19. package/lib/mates.js +2 -0
  20. package/lib/notes.js +2 -1
  21. package/lib/project-ask-user.js +64 -0
  22. package/lib/project-capsule-catalog.js +101 -0
  23. package/lib/project-connection.js +17 -0
  24. package/lib/project-debate-proposal.js +133 -17
  25. package/lib/project-debate.js +214 -110
  26. package/lib/project-delegated-follow-up.js +84 -0
  27. package/lib/project-delegated-session.js +53 -0
  28. package/lib/project-filesystem.js +7 -9
  29. package/lib/project-knowledge.js +23 -0
  30. package/lib/project-logs-comments.js +137 -0
  31. package/lib/project-logs-mcp-server.js +290 -0
  32. package/lib/project-logs-query.js +167 -0
  33. package/lib/project-logs-root.js +67 -0
  34. package/lib/project-logs-schema.js +259 -0
  35. package/lib/project-logs-service.js +357 -0
  36. package/lib/project-logs-snapshot.js +202 -0
  37. package/lib/project-logs-store.js +498 -0
  38. package/lib/project-logs-versioning.js +128 -0
  39. package/lib/project-logs.js +347 -0
  40. package/lib/project-mate-creation-proposal.js +120 -0
  41. package/lib/project-mate-interaction.js +14 -0
  42. package/lib/project-mate-knowledge.js +110 -0
  43. package/lib/project-memory.js +36 -7
  44. package/lib/project-models.js +157 -32
  45. package/lib/project-session-notes.js +2 -2
  46. package/lib/project-session-pair.js +8 -8
  47. package/lib/project-sessions.js +66 -51
  48. package/lib/project-vendor-login.js +414 -0
  49. package/lib/project-worker-proposal.js +25 -25
  50. package/lib/project-workspace-query.js +144 -0
  51. package/lib/project.js +433 -102
  52. package/lib/public/app.js +109 -48
  53. package/lib/public/css/avatar-imprints.css +0 -1
  54. package/lib/public/css/base.css +4 -0
  55. package/lib/public/css/capsule-ui.css +389 -0
  56. package/lib/public/css/command-palette.css +306 -6
  57. package/lib/public/css/home-capsule-library.css +243 -0
  58. package/lib/public/css/home-capsule-source.css +192 -0
  59. package/lib/public/css/home-debate-live.css +146 -0
  60. package/lib/public/css/home-debate-planning.css +125 -0
  61. package/lib/public/css/home-debates-archive.css +281 -0
  62. package/lib/public/css/home-hub.css +896 -405
  63. package/lib/public/css/home-mate-creation.css +34 -0
  64. package/lib/public/css/home-mate-model-picker.css +131 -0
  65. package/lib/public/css/home-mate-settings.css +344 -0
  66. package/lib/public/css/home-session-actions.css +265 -0
  67. package/lib/public/css/home-sidebar.css +667 -0
  68. package/lib/public/css/icon-strip.css +1 -2
  69. package/lib/public/css/input.css +79 -25
  70. package/lib/public/css/mates.css +7 -34
  71. package/lib/public/css/pane.css +1 -1
  72. package/lib/public/css/playbook.css +0 -80
  73. package/lib/public/css/project-logs.css +234 -0
  74. package/lib/public/css/scheduler.css +1 -1
  75. package/lib/public/css/sticky-notes.css +53 -117
  76. package/lib/public/css/tui-attention.css +0 -44
  77. package/lib/public/css/workspace-assignment.css +45 -0
  78. package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
  79. package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
  80. package/lib/public/index.html +96 -74
  81. package/lib/public/modules/app-connection.js +100 -5
  82. package/lib/public/modules/app-dm.js +43 -160
  83. package/lib/public/modules/app-home-hub.js +328 -585
  84. package/lib/public/modules/app-message-cards.js +242 -0
  85. package/lib/public/modules/app-message-router.js +84 -0
  86. package/lib/public/modules/app-messages.js +124 -38
  87. package/lib/public/modules/app-notifications.js +8 -119
  88. package/lib/public/modules/app-panels.js +43 -2
  89. package/lib/public/modules/app-projects.js +9 -1
  90. package/lib/public/modules/app-rendering.js +21 -602
  91. package/lib/public/modules/avatar-imprint.js +11 -8
  92. package/lib/public/modules/background-tasks-ui.js +139 -16
  93. package/lib/public/modules/chat-bubble-renderer.js +152 -0
  94. package/lib/public/modules/chat-render-runtime.js +198 -0
  95. package/lib/public/modules/command-palette.js +225 -436
  96. package/lib/public/modules/dm-render.js +82 -0
  97. package/lib/public/modules/home-capsule-creation-intent.js +31 -0
  98. package/lib/public/modules/home-capsule-library.js +146 -0
  99. package/lib/public/modules/home-capsule-source.js +383 -0
  100. package/lib/public/modules/home-chat-identity.js +35 -0
  101. package/lib/public/modules/home-chat-scroll.js +77 -0
  102. package/lib/public/modules/home-chat-stream-state.js +34 -0
  103. package/lib/public/modules/home-composer-focus.js +25 -0
  104. package/lib/public/modules/home-conversations-sheet.js +179 -0
  105. package/lib/public/modules/home-debate-activity.js +48 -0
  106. package/lib/public/modules/home-debate-controls.js +295 -0
  107. package/lib/public/modules/home-debate-launch.js +41 -0
  108. package/lib/public/modules/home-debate-live.js +284 -0
  109. package/lib/public/modules/home-debate-models.js +73 -0
  110. package/lib/public/modules/home-debate-planning.js +335 -0
  111. package/lib/public/modules/home-debates-archive.js +279 -0
  112. package/lib/public/modules/home-dock-resize.js +74 -0
  113. package/lib/public/modules/home-dock.js +446 -0
  114. package/lib/public/modules/home-mate-chat.js +496 -0
  115. package/lib/public/modules/home-mate-creation.js +109 -0
  116. package/lib/public/modules/home-mate-model-picker.js +281 -0
  117. package/lib/public/modules/home-mate-selection.js +38 -0
  118. package/lib/public/modules/home-mate-settings-menu.js +131 -0
  119. package/lib/public/modules/home-mate-settings.js +383 -0
  120. package/lib/public/modules/home-session-actions.js +373 -0
  121. package/lib/public/modules/home-session-model-confirmation.js +13 -0
  122. package/lib/public/modules/home-shell.js +9 -0
  123. package/lib/public/modules/home-sidebar-chat-list.js +63 -0
  124. package/lib/public/modules/home-sidebar.js +165 -0
  125. package/lib/public/modules/home-sub-surface.js +19 -0
  126. package/lib/public/modules/home-surface-boot.js +68 -0
  127. package/lib/public/modules/home-surface.js +141 -0
  128. package/lib/public/modules/home-tools.js +271 -0
  129. package/lib/public/modules/markdown.js +50 -2
  130. package/lib/public/modules/mate-management.js +86 -0
  131. package/lib/public/modules/mate-sidebar.js +0 -8
  132. package/lib/public/modules/mate-wizard.js +0 -7
  133. package/lib/public/modules/mention.js +17 -19
  134. package/lib/public/modules/pane-bridge.js +9 -0
  135. package/lib/public/modules/profile.js +4 -5
  136. package/lib/public/modules/project-logs-ambient.js +238 -0
  137. package/lib/public/modules/project-logs-render.js +359 -0
  138. package/lib/public/modules/project-logs.js +328 -0
  139. package/lib/public/modules/project-settings.js +34 -28
  140. package/lib/public/modules/project-switcher.js +11 -5
  141. package/lib/public/modules/project-workspace-assignment.js +23 -0
  142. package/lib/public/modules/scheduler.js +17 -3
  143. package/lib/public/modules/search-clay-chat.js +402 -0
  144. package/lib/public/modules/server-settings.js +14 -12
  145. package/lib/public/modules/session-actions.js +1 -1
  146. package/lib/public/modules/sidebar-mates.js +56 -552
  147. package/lib/public/modules/sidebar-mobile.js +12 -73
  148. package/lib/public/modules/sidebar-presence.js +37 -0
  149. package/lib/public/modules/sidebar-sessions.js +25 -1
  150. package/lib/public/modules/split-pair-ui.js +13 -13
  151. package/lib/public/modules/split-view.js +7 -0
  152. package/lib/public/modules/sticky-notes.js +106 -53
  153. package/lib/public/modules/tool-input-composition.js +48 -0
  154. package/lib/public/modules/tool-llm-status.js +167 -0
  155. package/lib/public/modules/tool-palette.js +76 -4
  156. package/lib/public/modules/tool-renderer-advanced.js +285 -0
  157. package/lib/public/modules/tool-renderer-chart.js +158 -0
  158. package/lib/public/modules/tool-renderer-semantics.js +35 -0
  159. package/lib/public/modules/tool-renderer.js +464 -0
  160. package/lib/public/modules/tool-runtime.js +309 -0
  161. package/lib/public/modules/tool-ui-evaluator.js +97 -0
  162. package/lib/public/modules/tool-ui-tree.js +21 -0
  163. package/lib/public/modules/tui-attention.js +10 -0
  164. package/lib/public/modules/user-settings.js +16 -23
  165. package/lib/public/modules/vendor-login.js +287 -0
  166. package/lib/public/modules/worker-proposal.js +2 -2
  167. package/lib/public/modules/workspace-assignment-card.js +149 -0
  168. package/lib/public/modules/workspace-assignment-routing.js +4 -0
  169. package/lib/public/style.css +14 -2
  170. package/lib/runtime-env.js +65 -0
  171. package/lib/sdk-bridge.js +120 -32
  172. package/lib/sdk-message-processor.js +34 -13
  173. package/lib/server-home-capsule-creation.js +36 -0
  174. package/lib/server-home-chat-events.js +287 -0
  175. package/lib/server-home-chat.js +518 -0
  176. package/lib/server-home-clay-entry.js +65 -0
  177. package/lib/server-home-clay-session-links.js +26 -0
  178. package/lib/server-home-debate-planning.js +214 -0
  179. package/lib/server-home-debates.js +137 -0
  180. package/lib/server-home-mate-creation.js +261 -0
  181. package/lib/server-home-models.js +241 -0
  182. package/lib/server-home-preferences.js +61 -0
  183. package/lib/server-mates.js +37 -0
  184. package/lib/server-tools.js +377 -0
  185. package/lib/server.js +166 -59
  186. package/lib/session-pair-mcp-server.js +6 -6
  187. package/lib/sessions.js +22 -4
  188. package/lib/tool-capsule-source.js +142 -0
  189. package/lib/tool-control-mcp-server.js +126 -0
  190. package/lib/tool-llm.js +48 -0
  191. package/lib/tool-storage.js +77 -0
  192. package/lib/tool-ui-spec-advanced.js +82 -0
  193. package/lib/tool-ui-spec.js +261 -0
  194. package/lib/tools-registry.js +286 -0
  195. package/lib/users-home-dock-preferences.js +77 -0
  196. package/lib/users-home-surface-preferences.js +99 -0
  197. package/lib/users-preferences.js +4 -7
  198. package/lib/users.js +12 -0
  199. package/lib/whats-new-content.js +3 -3
  200. package/lib/workspace-assignment-service.js +420 -0
  201. package/lib/workspace-query-mcp-server.js +154 -0
  202. package/lib/workspace-query-service.js +492 -0
  203. package/lib/ws-schema.js +107 -12
  204. package/lib/yoke/adapters/acp.js +2 -1
  205. package/lib/yoke/adapters/antigravity.js +2 -1
  206. package/lib/yoke/adapters/claude-worker.js +11 -4
  207. package/lib/yoke/adapters/claude.js +141 -46
  208. package/lib/yoke/adapters/codex.js +79 -11
  209. package/lib/yoke/adapters/kiro.js +2 -1
  210. package/lib/yoke/claude-user-input.js +38 -0
  211. package/lib/yoke/codex-app-server.js +20 -2
  212. package/lib/yoke/codex-background-tasks.js +8 -2
  213. package/lib/yoke/codex-user-input.js +64 -0
  214. package/lib/yoke/complete-once.js +164 -0
  215. package/lib/yoke/index.js +5 -1
  216. package/lib/yoke/interface.js +19 -0
  217. package/lib/yoke/mcp-bridge-server.js +2 -6
  218. package/lib/yoke/user-input.js +254 -0
  219. package/package.json +4 -3
  220. package/lib/public/css/home-chat.css +0 -380
  221. package/lib/public/modules/home-chat.js +0 -438
  222. 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';
@@ -34,10 +37,11 @@ import { updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeep
34
37
  import { handleTermList, handleTermCreated, sendTerminalCommand, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed } from './terminal.js';
35
38
  import { attachTuiView, detachTuiView, setTuiSuspendedView, tuiHandleTermOutput, tuiHandleTermResized, tuiHandleTermExited, tuiHandleTermClosed } from './session-tui-view.js';
36
39
  import { handleTuiTranscriptState } from './tui-grab.js';
37
- import { tuiModalHandleTermOutput, tuiModalHandleTermResized, tuiModalHandleTermExited, tuiModalHandleTermClosed, openTuiModal } from './tui-attention.js';
40
+ import { tuiModalHandleTermOutput, tuiModalHandleTermResized, tuiModalHandleTermExited, tuiModalHandleTermClosed } from './tui-attention.js';
38
41
  import { updateTerminalList, handleContextSourcesState, updateEmailAccountList, updateEmailUnreadCounts, handleEmailTestResult, handleEmailAddResult, handleEmailRemoveResult } from './context-sources.js';
39
42
  import { refreshEmailSettings } from './user-settings.js';
40
43
  import { handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, handleNoteWritten } from './sticky-notes.js';
44
+ import { handleProjectLogsState, handleProjectLogEntry, handleProjectLogCommented, handleProjectLogUpdated, handleProjectLogsError } from './project-logs.js';
41
45
  import { handleSkillInstalled, handleSkillUninstalled } from './skills.js';
42
46
  import { showRewindModal, onRewindComplete, setRewindMode, onRewindError, clearPendingRewindUuid, addRewindButton } from './rewind.js';
43
47
  import { checkAdminAccess } from './admin.js';
@@ -60,14 +64,17 @@ import { getModelInfoUpdate, modelEntryValue, modelEntryMatches, handleModelSele
60
64
  import { getModelEffortLevels, accumulateUsage, updateUsagePanel, accumulateContext, updateContextPanel, renderCtxPopover, updateStatusPanel } from './app-panels.js';
61
65
  import { updateProjectList, resetClientState, showUpdateAvailable, handleRemoveProjectCheckResult, handleRemoveProjectResult, handleBrowseDirResult, handleAddProjectResult, handleCloneProgress } from './app-projects.js';
62
66
  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';
67
+ import { hideHomeHub, showHomeHub } from './app-home-hub.js';
68
+ import { handleToolsState, handleToolInstalled, handleToolRemoved, handleToolStorageResult, handleToolLlmResult, handleToolsError, handleToolControlRequest } from './home-tools.js';
69
+ import { handleHomeDockState } from './home-dock.js';
70
+ import { enterDmMode, exitDmMode, handleMateCreatedInApp, updateMateIconStatus, appendDmMessage, showDmTypingIndicator, buildMateInterviewPrompt } from './app-dm.js';
65
71
  import { handleRateLimitEvent, updateRateLimitUsage, addScheduledMessageBubble, removeScheduledMessageBubble, handleFastModeState } from './app-rate-limit.js';
66
72
  import { handleRemoteCursorMove, handleRemoteCursorLeave, handleRemoteSelection, clearRemoteCursors } from './app-cursors.js';
67
73
  import { showLoopBanner, updateLoopBanner, updateLoopInputVisibility, showRalphApprovalBar, updateRalphApprovalStatus, openRalphPreviewModal, showExecModal, updateExecModalStatus } from './app-loop-ui.js';
68
74
  import { showDebateSticky, showDebateConcludeConfirm, showDebateUserFloor, exitDebateFloorMode, exitDebateConcludeMode, exitDebateEndedMode, updateDebateRound, renderDebateUserFloorDone } from './app-debate-ui.js';
69
75
  import { handleSkillInstallWs } from './app-skills-install.js';
70
- import { handleNotificationsState, handleNotificationCreated, handleNotificationDismissed, handleNotificationDismissedAll, showUpdateBanner, autoStartLoginIfNeeded } from './app-notifications.js';
76
+ import { handleNotificationsState, handleNotificationCreated, handleNotificationDismissed, handleNotificationDismissedAll, showUpdateBanner } from './app-notifications.js';
77
+ import { autoStartLoginIfNeeded, handleVendorLoginReady, handleVendorLoginState, handleVendorLoginError, handleAuthRefreshed } from './vendor-login.js';
71
78
  import { handleDebatePreparing, handleDebateBriefReady, renderDebateBriefReady, handleDebateStarted, renderDebateStarted, handleDebateTurn, handleDebateActivity, handleDebateStream, handleDebateTurnDone, handleDebateCommentQueued, handleDebateCommentInjected, renderDebateCommentInjected, handleDebateResumed, handleDebateEnded, renderDebateEnded, handleDebateError, isDebateActive, renderMcpDebateProposal, renderDebateUserResume } from './debate.js';
72
79
  import { handleMentionStart, handleMentionActivity, handleMentionStream, handleMentionDone, handleMentionError, renderMentionUser, renderMentionResponse, renderUserMention } from './mention.js';
73
80
 
@@ -259,15 +266,12 @@ export function processMessage(msg) {
259
266
 
260
267
  case "restore_mate_dm":
261
268
  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
269
  if (store.get('dmMode')) {
267
270
  store.set({ dmMode: false });
268
271
  }
269
272
  messagesEl.innerHTML = "";
270
- openDm(msg.mateId);
273
+ showHomeHub();
274
+ openHomeChat(msg.mateId);
271
275
  }
272
276
  // Clear the flag and notify server that mate DM is closed
273
277
  if (store.get('returningFromMateDm')) {
@@ -376,20 +380,32 @@ export function processMessage(msg) {
376
380
  connectOverlay.classList.remove("hidden");
377
381
  break;
378
382
 
379
- case "home_clay_history":
380
- handleHomeClayHistory(msg);
383
+ case "home_mate_history":
384
+ handleHomeMateHistory(msg);
381
385
  break;
382
386
 
383
- case "home_clay_delta":
384
- handleHomeClayDelta(msg);
387
+ case "home_mate_sessions_state":
388
+ handleHomeMateSessionsState(msg);
385
389
  break;
386
390
 
387
- case "home_clay_done":
388
- handleHomeClayDone();
391
+ case "home_mate_delta":
392
+ handleHomeMateDelta(msg);
389
393
  break;
390
394
 
391
- case "home_clay_error":
392
- handleHomeClayError(msg);
395
+ case "home_mate_done":
396
+ handleHomeMateDone(msg);
397
+ break;
398
+
399
+ case "home_mate_error":
400
+ handleHomeMateError(msg);
401
+ break;
402
+
403
+ case "home_mate_memory_state":
404
+ handleHomeMateMemoryState(msg);
405
+ break;
406
+
407
+ case "home_mate_knowledge_state":
408
+ handleHomeMateKnowledgeState(msg);
393
409
  break;
394
410
 
395
411
  case "slash_commands":
@@ -568,8 +584,40 @@ export function processMessage(msg) {
568
584
  handleRemoveProjectCheckResult(msg);
569
585
  break;
570
586
 
571
- case "hub_schedules":
572
- handleHubSchedules(msg);
587
+ case "tools_state":
588
+ handleToolsState(msg);
589
+ break;
590
+
591
+ case "home_dock_state":
592
+ handleHomeDockState(msg);
593
+ break;
594
+
595
+ case "home_surface_state":
596
+ handleHomeSurfaceState(msg);
597
+ break;
598
+
599
+ case "tool_installed":
600
+ handleToolInstalled(msg);
601
+ break;
602
+
603
+ case "tool_removed":
604
+ handleToolRemoved(msg);
605
+ break;
606
+
607
+ case "tool_storage_result":
608
+ handleToolStorageResult(msg);
609
+ break;
610
+
611
+ case "tool_llm_result":
612
+ handleToolLlmResult(msg);
613
+ break;
614
+
615
+ case "tools_error":
616
+ handleToolsError(msg);
617
+ break;
618
+
619
+ case "tool_control_request":
620
+ handleToolControlRequest(msg);
573
621
  break;
574
622
 
575
623
  case "input_sync":
@@ -811,7 +859,7 @@ export function processMessage(msg) {
811
859
  } else {
812
860
  addUserMessage(msg.text, msg.images || null, msg.pastes || null, msg.from, msg.fromName, msg.delegated ? msg : null);
813
861
  }
814
- // Worker pane: a delegated instruction starts (or replays into) a
862
+ // Split Worker pane: a delegated instruction starts (or replays into) a
815
863
  // driven turn; surface the composer notice. Cleared on "done".
816
864
  if (msg.delegated) showWorkerDelegationNotice(msg.delegatedByTitle || null);
817
865
  break;
@@ -1253,9 +1301,26 @@ export function processMessage(msg) {
1253
1301
  appendDelta((msg.text || "Authentication required.") + "\n");
1254
1302
  setStatus("connected");
1255
1303
  if (!store.get('loopActive')) enableMainInput();
1256
- // Auto-open the login modal terminal when the session can self-login.
1257
- // No-op otherwise (the auth_required banner remains the manual path).
1258
- autoStartLoginIfNeeded(msg);
1304
+ // Open the login flow only for a live auth failure. Older Clay
1305
+ // versions recorded this transient event in session history; replaying
1306
+ // one must not reopen a login terminal after the user signed in.
1307
+ if (!store.get('replayingHistory')) autoStartLoginIfNeeded(msg);
1308
+ break;
1309
+
1310
+ case "vendor_login_ready":
1311
+ handleVendorLoginReady(msg);
1312
+ break;
1313
+
1314
+ case "vendor_login_state":
1315
+ handleVendorLoginState(msg);
1316
+ break;
1317
+
1318
+ case "vendor_login_error":
1319
+ handleVendorLoginError(msg);
1320
+ break;
1321
+
1322
+ case "auth_refreshed":
1323
+ handleAuthRefreshed(msg);
1259
1324
  break;
1260
1325
 
1261
1326
  case "rate_limit":
@@ -1446,19 +1511,8 @@ export function processMessage(msg) {
1446
1511
  break;
1447
1512
 
1448
1513
  case "term_created":
1449
- // Login-modal path: the terminal was created with the login command as
1450
- // its initial input; attach the modal dialog to it (replays scrollback
1451
- // so the login URL is visible) instead of the sidebar terminal.
1452
- if (store.get('pendingLoginModal')) {
1453
- var _lm = store.get('pendingLoginModal');
1454
- store.set({ pendingLoginModal: null });
1455
- openTuiModal(msg.id, _lm.slug, {
1456
- sessionTitle: (VENDOR_NAMES[_lm.vendor] || "Claude Code") + " login",
1457
- projectName: _lm.slug,
1458
- compact: true,
1459
- });
1460
- break;
1461
- }
1514
+ // Login terminals never come through here: they are created by the
1515
+ // server-owned flow and announced with vendor_login_ready instead.
1462
1516
  handleTermCreated(msg);
1463
1517
  if (store.get('pendingTermCommand')) {
1464
1518
  var cmd = store.get('pendingTermCommand');
@@ -1514,6 +1568,26 @@ export function processMessage(msg) {
1514
1568
  handleNoteDeleted(msg);
1515
1569
  break;
1516
1570
 
1571
+ case "project_logs_state":
1572
+ handleProjectLogsState(msg);
1573
+ break;
1574
+
1575
+ case "project_log_entry":
1576
+ handleProjectLogEntry(msg);
1577
+ break;
1578
+
1579
+ case "project_log_commented":
1580
+ handleProjectLogCommented(msg);
1581
+ break;
1582
+
1583
+ case "project_log_updated":
1584
+ handleProjectLogUpdated(msg);
1585
+ break;
1586
+
1587
+ case "project_logs_error":
1588
+ handleProjectLogsError(msg);
1589
+ break;
1590
+
1517
1591
  case "process_stats":
1518
1592
  updateStatusPanel(msg);
1519
1593
  updateSettingsStats(msg);
@@ -1810,6 +1884,18 @@ export function processMessage(msg) {
1810
1884
  handleDebateTurnDone(msg);
1811
1885
  break;
1812
1886
 
1887
+ case "debate_tool_decision":
1888
+ addSystemMessage((msg.action || "Use " + (msg.toolName || "tool")) + " · " + (msg.decision === "allowed" ? "Allowed" : "Blocked") + (msg.reason ? " — " + msg.reason : "") + (msg.command ? "\n$ " + msg.command : ""), msg.decision !== "allowed");
1889
+ break;
1890
+
1891
+ case "debate_stop_requested":
1892
+ addSystemMessage("Debate will stop after the current speaker finishes.", false);
1893
+ break;
1894
+
1895
+ case "debate_stop_cancelled":
1896
+ addSystemMessage("Debate stop cancelled.", false);
1897
+ break;
1898
+
1813
1899
  case "debate_hand_raised":
1814
1900
  // Visual feedback: hand is raised, waiting for floor
1815
1901
  break;