clay-server 3.8.1 → 4.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/lib/ask-user-mcp-server.js +5 -119
  2. package/lib/builtin-mates.js +6 -6
  3. package/lib/claude-hook-installer.js +15 -0
  4. package/lib/clay-history-mcp-server.js +62 -297
  5. package/lib/daemon.js +1 -1
  6. package/lib/debate-model-selection.js +119 -0
  7. package/lib/home-debate-tool-policy.js +164 -0
  8. package/lib/home-response-notifications.js +26 -0
  9. package/lib/mate-creation-mcp-server.js +55 -0
  10. package/lib/mate-ready-creation.js +95 -0
  11. package/lib/mates.js +2 -0
  12. package/lib/notes.js +2 -1
  13. package/lib/project-ask-user.js +64 -0
  14. package/lib/project-capsule-catalog.js +101 -0
  15. package/lib/project-connection.js +4 -0
  16. package/lib/project-debate-proposal.js +133 -17
  17. package/lib/project-debate.js +214 -110
  18. package/lib/project-delegated-follow-up.js +84 -0
  19. package/lib/project-delegated-session.js +53 -0
  20. package/lib/project-filesystem.js +7 -9
  21. package/lib/project-knowledge.js +1 -0
  22. package/lib/project-mate-creation-proposal.js +120 -0
  23. package/lib/project-memory.js +14 -7
  24. package/lib/project-models.js +157 -32
  25. package/lib/project-session-notes.js +2 -2
  26. package/lib/project-session-pair.js +8 -8
  27. package/lib/project-sessions.js +66 -51
  28. package/lib/project-vendor-login.js +397 -0
  29. package/lib/project-worker-proposal.js +25 -25
  30. package/lib/project-workspace-query.js +144 -0
  31. package/lib/project.js +349 -102
  32. package/lib/public/app.js +85 -42
  33. package/lib/public/css/avatar-imprints.css +0 -1
  34. package/lib/public/css/base.css +4 -0
  35. package/lib/public/css/capsule-ui.css +389 -0
  36. package/lib/public/css/command-palette.css +306 -6
  37. package/lib/public/css/home-capsule-library.css +243 -0
  38. package/lib/public/css/home-capsule-source.css +192 -0
  39. package/lib/public/css/home-debate-live.css +146 -0
  40. package/lib/public/css/home-debate-planning.css +125 -0
  41. package/lib/public/css/home-debates-archive.css +281 -0
  42. package/lib/public/css/home-hub.css +896 -405
  43. package/lib/public/css/home-mate-creation.css +34 -0
  44. package/lib/public/css/home-mate-model-picker.css +131 -0
  45. package/lib/public/css/home-mate-settings.css +344 -0
  46. package/lib/public/css/home-session-actions.css +265 -0
  47. package/lib/public/css/home-sidebar.css +667 -0
  48. package/lib/public/css/icon-strip.css +1 -2
  49. package/lib/public/css/mates.css +7 -34
  50. package/lib/public/css/pane.css +1 -1
  51. package/lib/public/css/playbook.css +0 -80
  52. package/lib/public/css/sticky-notes.css +53 -117
  53. package/lib/public/css/tui-attention.css +0 -44
  54. package/lib/public/css/workspace-assignment.css +45 -0
  55. package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
  56. package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
  57. package/lib/public/index.html +93 -74
  58. package/lib/public/modules/app-connection.js +10 -1
  59. package/lib/public/modules/app-dm.js +43 -160
  60. package/lib/public/modules/app-home-hub.js +328 -585
  61. package/lib/public/modules/app-message-cards.js +242 -0
  62. package/lib/public/modules/app-message-router.js +84 -0
  63. package/lib/public/modules/app-messages.js +102 -37
  64. package/lib/public/modules/app-notifications.js +8 -119
  65. package/lib/public/modules/app-projects.js +9 -1
  66. package/lib/public/modules/app-rendering.js +21 -602
  67. package/lib/public/modules/avatar-imprint.js +11 -8
  68. package/lib/public/modules/chat-bubble-renderer.js +152 -0
  69. package/lib/public/modules/chat-render-runtime.js +198 -0
  70. package/lib/public/modules/command-palette.js +225 -436
  71. package/lib/public/modules/dm-render.js +82 -0
  72. package/lib/public/modules/home-capsule-creation-intent.js +31 -0
  73. package/lib/public/modules/home-capsule-library.js +146 -0
  74. package/lib/public/modules/home-capsule-source.js +383 -0
  75. package/lib/public/modules/home-chat-identity.js +35 -0
  76. package/lib/public/modules/home-chat-scroll.js +77 -0
  77. package/lib/public/modules/home-chat-stream-state.js +34 -0
  78. package/lib/public/modules/home-composer-focus.js +25 -0
  79. package/lib/public/modules/home-conversations-sheet.js +179 -0
  80. package/lib/public/modules/home-debate-activity.js +48 -0
  81. package/lib/public/modules/home-debate-controls.js +295 -0
  82. package/lib/public/modules/home-debate-launch.js +41 -0
  83. package/lib/public/modules/home-debate-live.js +284 -0
  84. package/lib/public/modules/home-debate-models.js +73 -0
  85. package/lib/public/modules/home-debate-planning.js +335 -0
  86. package/lib/public/modules/home-debates-archive.js +279 -0
  87. package/lib/public/modules/home-dock-resize.js +74 -0
  88. package/lib/public/modules/home-dock.js +446 -0
  89. package/lib/public/modules/home-mate-chat.js +496 -0
  90. package/lib/public/modules/home-mate-creation.js +109 -0
  91. package/lib/public/modules/home-mate-model-picker.js +281 -0
  92. package/lib/public/modules/home-mate-selection.js +38 -0
  93. package/lib/public/modules/home-mate-settings-menu.js +131 -0
  94. package/lib/public/modules/home-mate-settings.js +383 -0
  95. package/lib/public/modules/home-session-actions.js +373 -0
  96. package/lib/public/modules/home-session-model-confirmation.js +13 -0
  97. package/lib/public/modules/home-shell.js +9 -0
  98. package/lib/public/modules/home-sidebar-chat-list.js +63 -0
  99. package/lib/public/modules/home-sidebar.js +158 -0
  100. package/lib/public/modules/home-sub-surface.js +19 -0
  101. package/lib/public/modules/home-surface-boot.js +68 -0
  102. package/lib/public/modules/home-surface.js +141 -0
  103. package/lib/public/modules/home-tools.js +271 -0
  104. package/lib/public/modules/markdown.js +50 -2
  105. package/lib/public/modules/mate-management.js +86 -0
  106. package/lib/public/modules/mate-wizard.js +0 -7
  107. package/lib/public/modules/mention.js +17 -19
  108. package/lib/public/modules/pane-bridge.js +9 -0
  109. package/lib/public/modules/profile.js +4 -5
  110. package/lib/public/modules/project-settings.js +34 -28
  111. package/lib/public/modules/project-switcher.js +11 -5
  112. package/lib/public/modules/project-workspace-assignment.js +23 -0
  113. package/lib/public/modules/search-clay-chat.js +402 -0
  114. package/lib/public/modules/server-settings.js +14 -12
  115. package/lib/public/modules/session-actions.js +1 -1
  116. package/lib/public/modules/sidebar-mates.js +56 -552
  117. package/lib/public/modules/sidebar-mobile.js +7 -64
  118. package/lib/public/modules/sidebar-presence.js +37 -0
  119. package/lib/public/modules/split-pair-ui.js +13 -13
  120. package/lib/public/modules/split-view.js +7 -0
  121. package/lib/public/modules/sticky-notes.js +7 -6
  122. package/lib/public/modules/tool-input-composition.js +48 -0
  123. package/lib/public/modules/tool-llm-status.js +167 -0
  124. package/lib/public/modules/tool-renderer-advanced.js +285 -0
  125. package/lib/public/modules/tool-renderer-chart.js +158 -0
  126. package/lib/public/modules/tool-renderer-semantics.js +35 -0
  127. package/lib/public/modules/tool-renderer.js +464 -0
  128. package/lib/public/modules/tool-runtime.js +309 -0
  129. package/lib/public/modules/tool-ui-evaluator.js +97 -0
  130. package/lib/public/modules/tool-ui-tree.js +21 -0
  131. package/lib/public/modules/tui-attention.js +10 -0
  132. package/lib/public/modules/user-settings.js +16 -23
  133. package/lib/public/modules/vendor-login.js +287 -0
  134. package/lib/public/modules/worker-proposal.js +2 -2
  135. package/lib/public/modules/workspace-assignment-card.js +149 -0
  136. package/lib/public/modules/workspace-assignment-routing.js +4 -0
  137. package/lib/public/style.css +13 -2
  138. package/lib/runtime-env.js +65 -0
  139. package/lib/sdk-bridge.js +120 -32
  140. package/lib/sdk-message-processor.js +10 -6
  141. package/lib/server-home-capsule-creation.js +36 -0
  142. package/lib/server-home-chat-events.js +287 -0
  143. package/lib/server-home-chat.js +518 -0
  144. package/lib/server-home-clay-entry.js +65 -0
  145. package/lib/server-home-clay-session-links.js +26 -0
  146. package/lib/server-home-debate-planning.js +214 -0
  147. package/lib/server-home-debates.js +137 -0
  148. package/lib/server-home-mate-creation.js +261 -0
  149. package/lib/server-home-models.js +241 -0
  150. package/lib/server-home-preferences.js +61 -0
  151. package/lib/server-mates.js +37 -0
  152. package/lib/server-tools.js +377 -0
  153. package/lib/server.js +111 -59
  154. package/lib/session-pair-mcp-server.js +6 -6
  155. package/lib/sessions.js +18 -3
  156. package/lib/tool-capsule-source.js +142 -0
  157. package/lib/tool-control-mcp-server.js +126 -0
  158. package/lib/tool-llm.js +48 -0
  159. package/lib/tool-storage.js +77 -0
  160. package/lib/tool-ui-spec-advanced.js +82 -0
  161. package/lib/tool-ui-spec.js +261 -0
  162. package/lib/tools-registry.js +286 -0
  163. package/lib/users-home-dock-preferences.js +77 -0
  164. package/lib/users-home-surface-preferences.js +99 -0
  165. package/lib/users-preferences.js +4 -7
  166. package/lib/users.js +12 -0
  167. package/lib/whats-new-content.js +3 -3
  168. package/lib/workspace-assignment-service.js +420 -0
  169. package/lib/workspace-query-mcp-server.js +154 -0
  170. package/lib/workspace-query-service.js +492 -0
  171. package/lib/ws-schema.js +93 -12
  172. package/lib/yoke/adapters/acp.js +2 -1
  173. package/lib/yoke/adapters/antigravity.js +2 -1
  174. package/lib/yoke/adapters/claude-worker.js +11 -4
  175. package/lib/yoke/adapters/claude.js +73 -43
  176. package/lib/yoke/adapters/codex.js +40 -10
  177. package/lib/yoke/adapters/kiro.js +2 -1
  178. package/lib/yoke/claude-user-input.js +38 -0
  179. package/lib/yoke/codex-app-server.js +20 -2
  180. package/lib/yoke/codex-user-input.js +64 -0
  181. package/lib/yoke/complete-once.js +164 -0
  182. package/lib/yoke/index.js +5 -1
  183. package/lib/yoke/interface.js +19 -0
  184. package/lib/yoke/mcp-bridge-server.js +2 -6
  185. package/lib/yoke/user-input.js +254 -0
  186. package/package.json +3 -2
  187. package/lib/public/css/home-chat.css +0 -380
  188. package/lib/public/modules/home-chat.js +0 -438
  189. package/lib/server-clay-home.js +0 -245
package/lib/project.js CHANGED
@@ -5,18 +5,22 @@ var crypto = require("crypto");
5
5
  var { createSessionManager } = require("./sessions");
6
6
  var { attachGitSessionAttribution } = require("./git-session-attribution");
7
7
  var { createSDKBridge, createMessageQueue } = require("./sdk-bridge");
8
+ var runtimeEnv = require("./runtime-env");
8
9
  var { createTerminalManager } = require("./terminal-manager");
9
10
  var { createNotesManager } = require("./notes");
10
11
  var { fetchLatestVersion, fetchVersion, isNewer } = require("./updater");
11
12
  var { execFileSync, spawn } = require("child_process");
12
13
  var usersModule = require("./users");
13
14
  var { resolveOsUserInfo, fsAsUser, grantProjectAccess } = require("./os-users");
15
+ var { buildUserEnv } = require("./build-user-env");
14
16
  var crisisSafety = require("./crisis-safety");
15
17
  var matesModule = require("./mates");
16
18
  var sessionSearch = require("./session-search");
17
19
  var userPresence = require("./user-presence");
18
20
  var { attachDebate } = require("./project-debate");
19
21
  var { attachDebateProposal } = require("./project-debate-proposal");
22
+ var { attachMateCreationProposal } = require("./project-mate-creation-proposal");
23
+ var { attachAskUser } = require("./project-ask-user");
20
24
  var { attachMemory } = require("./project-memory");
21
25
  var { attachMateInteraction } = require("./project-mate-interaction");
22
26
  var { attachUserMention } = require("./project-user-mention");
@@ -30,18 +34,74 @@ var { attachSessions } = require("./project-sessions");
30
34
  var { attachModels } = require("./project-models");
31
35
  var { attachUserMessage } = require("./project-user-message");
32
36
  var { attachShellCommand } = require("./project-shell-command");
37
+ var { attachVendorLogin } = require("./project-vendor-login");
33
38
  var { attachConnection } = require("./project-connection");
34
39
  var { attachMcp } = require("./project-mcp");
35
40
  var { createLocalMcp } = require("./mcp-local");
36
41
  var { attachEmail: attachEmailModule } = require("./project-email");
37
42
  var { attachSessionSpawn } = require("./project-session-spawn");
43
+ var { attachDelegatedSession } = require("./project-delegated-session");
44
+ var { attachDelegatedFollowUp } = require("./project-delegated-follow-up");
45
+ var workspaceSessionRef = require("./workspace-query-service").sessionRef;
38
46
  var { attachSessionPair } = require("./project-session-pair");
39
47
  var { attachSessionHandoff } = require("./project-session-handoff");
40
48
  var { attachSessionNotes, composeSystemPrompts } = require("./project-session-notes");
41
49
  var { attachSessionDocument } = require("./project-session-document");
50
+ var { attachCapsuleCatalog } = require("./project-capsule-catalog");
51
+ var { attachProjectWorkspaceQuery } = require("./project-workspace-query");
42
52
  var { attachSplitGroups } = require("./session-split-groups");
53
+ var toolControlMcp = require("./tool-control-mcp-server");
54
+ var toolLlm = require("./tool-llm");
43
55
  // project-notifications is attached globally in server.js, passed via opts.notificationsModule
44
56
 
57
+ function createMateToolControlMcp(adapter, config) {
58
+ if (!adapter || typeof adapter.createToolServer !== "function") return null;
59
+ var handlers = {
60
+ list: function () {
61
+ var manifests = config.list(config.userId) || [];
62
+ var tools = [];
63
+ for (var i = 0; i < manifests.length; i++) {
64
+ tools.push({
65
+ id: manifests[i].id,
66
+ name: manifests[i].name,
67
+ description: manifests[i].description || "",
68
+ useWhen: manifests[i].useWhen || "",
69
+ runtime: manifests[i].runtime || "worker",
70
+ permissions: manifests[i].permissions || [],
71
+ skills: manifests[i].skills || "",
72
+ });
73
+ }
74
+ return tools;
75
+ },
76
+ snapshot: function (toolId) {
77
+ return config.control(config.userId, config.mateId, toolId, "snapshot", {});
78
+ },
79
+ act: function (toolId, actionId, args) {
80
+ return config.control(config.userId, config.mateId, toolId, "act", { actionId: actionId, args: args });
81
+ },
82
+ set: function (toolId, controlId, value) {
83
+ return config.control(config.userId, config.mateId, toolId, "set", { controlId: controlId, value: value });
84
+ },
85
+ source: function (toolId) {
86
+ return config.source(config.userId, toolId);
87
+ },
88
+ install: function (input) {
89
+ return config.install(config.userId, input);
90
+ },
91
+ update: function (toolId, input) {
92
+ return config.update(config.userId, toolId, input);
93
+ },
94
+ uninstall: function (toolId) {
95
+ return config.remove(config.userId, toolId);
96
+ },
97
+ };
98
+ return adapter.createToolServer({
99
+ name: "clay-tools",
100
+ version: "1.0.0",
101
+ tools: toolControlMcp.getToolDefs(handlers),
102
+ });
103
+ }
104
+
45
105
  // --- Context Sources persistence ---
46
106
  var _ctxSrcConfig = require("./config");
47
107
  var _ctxSrcDir = path.join(_ctxSrcConfig.CONFIG_DIR, "context-sources");
@@ -73,26 +133,7 @@ function saveContextSources(slug, sessionId, activeIds) {
73
133
  // Validate environment variable string (KEY=VALUE per line)
74
134
  // Returns null if valid, or an error string if invalid
75
135
  function validateEnvString(str) {
76
- if (!str || !str.trim()) return null;
77
- var lines = str.split("\n");
78
- for (var i = 0; i < lines.length; i++) {
79
- var line = lines[i].trim();
80
- if (!line || line.charAt(0) === "#") continue;
81
- // Must be KEY=VALUE format
82
- var eqIdx = line.indexOf("=");
83
- if (eqIdx < 1) return "Invalid format at line " + (i + 1) + ": expected KEY=VALUE";
84
- var key = line.substring(0, eqIdx);
85
- // Key must be valid env var name (no shell metacharacters)
86
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
87
- return "Invalid variable name at line " + (i + 1) + ": " + key;
88
- }
89
- // Value must not contain shell injection characters
90
- var value = line.substring(eqIdx + 1);
91
- if (/[`$\\;|&><(){}\n]/.test(value) && !/^["'].*["']$/.test(value)) {
92
- return "Potentially unsafe value at line " + (i + 1) + ": shell metacharacters detected";
93
- }
94
- }
95
- return null;
136
+ return runtimeEnv.validateEnvString(str);
96
137
  }
97
138
 
98
139
  // YOKE adapter (replaces direct SDK access)
@@ -153,8 +194,6 @@ function createProjectContext(opts) {
153
194
  var lanHost = opts.lanHost || null;
154
195
  var getProjectCount = opts.getProjectCount || function () { return 1; };
155
196
  var getProjectList = opts.getProjectList || function () { return []; };
156
- var getAllProjectSessions = opts.getAllProjectSessions || function () { return []; };
157
- var getAllProjectsWithSessions = opts.getAllProjectsWithSessions || function () { return []; };
158
197
  var isHostAgent = !!opts.isHostAgent;
159
198
  var getHubSchedules = opts.getHubSchedules || function () { return []; };
160
199
  var moveScheduleToProject = opts.moveScheduleToProject || function () { return { ok: false, error: "Not supported" }; };
@@ -168,6 +207,23 @@ function createProjectContext(opts) {
168
207
  var projectOwnerId = opts.projectOwnerId || null;
169
208
  var worktreeMeta = opts.worktreeMeta || null; // { parentSlug, branch, external }
170
209
  var isMate = opts.isMate || false;
210
+ var mateId = opts.mateId || (isMate ? path.basename(cwd) : null);
211
+ var listControllableTools = opts.listControllableTools || function () { return []; };
212
+ var controlToolForMate = opts.controlToolForMate || function () {
213
+ return Promise.reject(new Error("Tool control is unavailable."));
214
+ };
215
+ var installToolForMate = opts.installToolForMate || function () {
216
+ return Promise.reject(new Error("Tool installation is unavailable."));
217
+ };
218
+ var sourceToolForMate = opts.sourceToolForMate || function () {
219
+ return Promise.reject(new Error("Capsule source access is unavailable."));
220
+ };
221
+ var updateToolForMate = opts.updateToolForMate || function () {
222
+ return Promise.reject(new Error("Capsule source updates are unavailable."));
223
+ };
224
+ var removeToolForMate = opts.removeToolForMate || function () {
225
+ return Promise.reject(new Error("Tool removal is unavailable."));
226
+ };
171
227
  var onCreateWorktree = opts.onCreateWorktree || null;
172
228
  var serverPort = opts.port || 2633;
173
229
  var serverTls = opts.tls || false;
@@ -219,8 +275,7 @@ function createProjectContext(opts) {
219
275
 
220
276
  // Cache resolved OS user info to avoid repeated getent calls
221
277
  var osUserInfoCache = {};
222
- function getOsUserInfoForWs(ws) {
223
- var linuxUser = getLinuxUserForWs(ws);
278
+ function getOsUserInfoForLinuxUser(linuxUser) {
224
279
  if (!linuxUser) return null;
225
280
  if (osUserInfoCache[linuxUser]) return osUserInfoCache[linuxUser];
226
281
  try {
@@ -233,23 +288,34 @@ function createProjectContext(opts) {
233
288
  }
234
289
  }
235
290
 
291
+ function getOsUserInfoForWs(ws) {
292
+ var linuxUser = getLinuxUserForWs(ws);
293
+ return getOsUserInfoForLinuxUser(linuxUser);
294
+ }
295
+
236
296
  function getOsUserInfoForReq(req) {
237
297
  if (!osUsers) return null;
238
298
  if (!req._clayUser || !req._clayUser.linuxUser) return null;
239
299
  var linuxUser = req._clayUser.linuxUser;
240
- if (osUserInfoCache[linuxUser]) return osUserInfoCache[linuxUser];
241
- try {
242
- var info = resolveOsUserInfo(linuxUser);
243
- osUserInfoCache[linuxUser] = info;
244
- return info;
245
- } catch (e) {
246
- console.error("[project] Failed to resolve OS user info for " + linuxUser + ":", e.message);
247
- return null;
248
- }
300
+ return getOsUserInfoForLinuxUser(linuxUser);
301
+ }
302
+
303
+ function getRuntimeEnvForSession(session) {
304
+ var linuxUser = (session && session.linuxUser) || getLinuxUserForSession(session);
305
+ var osUserInfo = getOsUserInfoForLinuxUser(linuxUser);
306
+ var baseEnv = osUserInfo ? buildUserEnv(osUserInfo) : process.env;
307
+ var shared = typeof opts.onGetSharedEnv === "function" ? opts.onGetSharedEnv() : null;
308
+ var projectEnv = typeof opts.onGetProjectEnv === "function" ? opts.onGetProjectEnv(slug) : null;
309
+ return runtimeEnv.resolveRuntimeEnv({
310
+ baseEnv: baseEnv,
311
+ sharedEnvrc: shared && shared.envrc,
312
+ projectEnvrc: projectEnv && projectEnv.envrc,
313
+ });
249
314
  }
250
315
 
251
316
  // --- Per-project clients ---
252
317
  var clients = new Set();
318
+ var homeDebateClients = new Set();
253
319
 
254
320
  // --- Browser extension state (shared mutable object) ---
255
321
  var _extToken = crypto.randomUUID(); // Auth token for MCP server bridge
@@ -369,6 +435,10 @@ function createProjectContext(opts) {
369
435
  ws.send(data);
370
436
  }
371
437
  }
438
+ homeDebateClients.forEach(function (ws) {
439
+ if (ws.readyState !== 1) { homeDebateClients.delete(ws); return; }
440
+ if (!clients.has(ws) && ws._clayHomeDebateSlug === slug && ws._clayActiveSession === sessionId) ws.send(data);
441
+ });
372
442
  }
373
443
 
374
444
  function sendToSessionOthers(sender, sessionId, obj) {
@@ -537,6 +607,23 @@ function createProjectContext(opts) {
537
607
  },
538
608
  fsAsUser: fsAsUser,
539
609
  });
610
+ var _capsuleCatalog = attachCapsuleCatalog({
611
+ isMate: isMate,
612
+ listManifests: listControllableTools,
613
+ getUserId: function (session) {
614
+ return (session && session.ownerId) || projectOwnerId || "default";
615
+ },
616
+ getSdk: function () { return sdk; },
617
+ getSessions: function () { return sm.sessions; },
618
+ });
619
+ var _workspaceQuery = attachProjectWorkspaceQuery({
620
+ service: opts.workspaceQueryService || null,
621
+ sm: sm,
622
+ projectSlug: slug,
623
+ getProjectOwnerId: function () { return projectOwnerId; },
624
+ isMate: isMate,
625
+ mateId: mateId,
626
+ });
540
627
 
541
628
  // The SDK bridge is created after local MCP servers. Session spawning uses
542
629
  // a getter so tool handlers see the initialized bridge when they run.
@@ -587,15 +674,46 @@ function createProjectContext(opts) {
587
674
  var _debateProposal = attachDebateProposal({
588
675
  cwd: cwd,
589
676
  isMate: isMate,
677
+ isHostAgent: isHostAgent,
590
678
  sendTo: sendTo,
591
679
  buildMateCtx: matesModule.buildMateCtx,
592
680
  getMate: matesModule.getMate,
593
681
  getProjectOwnerId: function () { return projectOwnerId; },
682
+ getVendorModelCatalog: function (ws, vendor) { return _models.getVendorCatalog(ws, vendor); },
683
+ getVendorModelCatalogForSession: function (session, vendor) {
684
+ var user = session && session.ownerId ? usersModule.findUserById(session.ownerId) : null;
685
+ return _models.getVendorCatalog({ _clayUser: user || null }, vendor);
686
+ },
594
687
  startDebate: function (session, briefData, moderatorId, ws) {
595
688
  if (!_debate) return { error: "The debate engine is unavailable." };
596
689
  return _debate.handleMcpDebateApproval(session, briefData, moderatorId, ws);
597
690
  },
691
+ recordSessionEvent: function (session, event) { sm.sendAndRecord(session, event); },
598
692
  });
693
+ var _mateCreationProposal = attachMateCreationProposal({
694
+ isMate: isMate,
695
+ isHostAgent: isHostAgent,
696
+ isMultiUser: usersModule.isMultiUser,
697
+ getProjectOwnerId: function () { return projectOwnerId; },
698
+ recordSessionEvent: function (session, event) { sm.sendAndRecord(session, event); },
699
+ getVendorModelCatalog: function (ws, vendor) { return _models.getVendorCatalog(ws, vendor); },
700
+ createReadyMate: opts.createReadyMate,
701
+ });
702
+ var _askUser = attachAskUser({ record: function (session, event) { sm.sendAndRecord(session, event); } });
703
+
704
+ function createToolControlMcpServer() {
705
+ if (!isMate || !adapter || typeof adapter.createToolServer !== "function") return null;
706
+ return createMateToolControlMcp(adapter, {
707
+ userId: projectOwnerId || "default",
708
+ mateId: path.basename(cwd),
709
+ list: listControllableTools,
710
+ control: controlToolForMate,
711
+ source: sourceToolForMate,
712
+ install: installToolForMate,
713
+ update: updateToolForMate,
714
+ remove: removeToolForMate,
715
+ });
716
+ }
599
717
 
600
718
  // --- MCP tool servers (created via YOKE adapter) ---
601
719
  var mcpServers = (function () {
@@ -649,77 +767,39 @@ function createProjectContext(opts) {
649
767
  console.error("[project] Failed to create debate MCP server:", e.message);
650
768
  }
651
769
 
652
- // Clay-history MCP server (host agent only — Clay mate)
653
- // Gives Clay BM25 search + targeted reads across the user's full
654
- // workspace. Read-only. Other Mates and project sessions never see
655
- // these tools because the gate is the isHostAgent project flag.
656
- if (isHostAgent) {
770
+ if (isMate && isHostAgent) {
657
771
  try {
658
- var clayHistoryMcp = require("./clay-history-mcp-server");
659
- var clayHistoryToolDefs = clayHistoryMcp.getToolDefs({
660
- getAllProjectsWithSessions: getAllProjectsWithSessions,
661
- });
662
- var clayHistoryMcpConfig = adapter.createToolServer({ name: "clay-history", version: "1.0.0", tools: clayHistoryToolDefs });
663
- if (clayHistoryMcpConfig) servers[clayHistoryMcpConfig.name || "clay-history"] = clayHistoryMcpConfig;
772
+ var mateCreationMcpConfig = _mateCreationProposal.createMcpServer(adapter, null);
773
+ if (mateCreationMcpConfig) servers[mateCreationMcpConfig.name || "clay-mate-creation"] = mateCreationMcpConfig;
664
774
  } catch (e) {
665
- console.error("[project] Failed to create clay-history MCP server:", e.message);
775
+ console.error("[project] Failed to create Mate creation MCP server:", e.message);
666
776
  }
667
777
  }
668
778
 
669
- // Ask-user MCP server (mates only)
779
+ // Owner-bound workspace inspection is available only inside Mate
780
+ // projects. The server-side Mate registry decides whether the wider
781
+ // builtin Clay tools are present; project flags and tool arguments do not.
670
782
  if (isMate) {
671
783
  try {
672
- var askUserMcp = require("./ask-user-mcp-server");
673
- var askUserToolDefs = askUserMcp.getToolDefs(function onAsk(input) {
674
- // Stateless: the tool's job is to *post* the question card.
675
- // We do NOT hold a promise open waiting for the user. When the
676
- // user answers, the answer is injected as a fresh user message
677
- // on the next turn (see project-sessions.js ask_user_response).
678
- // This avoids HTTP long-poll timeouts on the MCP bridge and
679
- // matches the natural multi-turn agent loop.
680
- var session = sm.getActiveSession();
681
- if (!session) {
682
- // No active session means we have no way to show a card or
683
- // route the answer. Fail closed rather than pretend success.
684
- return Promise.resolve({
685
- content: [{ type: "text", text: "Error: no active session in " + slug + "; cannot display question card." }],
686
- isError: true,
687
- });
688
- }
689
- if (session.loop && session.loop.active && session.loop.role !== "crafting") {
690
- return Promise.resolve({
691
- content: [{ type: "text", text: "Error: Autonomous mode. Make your own decision." }],
692
- isError: true,
693
- });
694
- }
784
+ var workspaceMcpConfig = _workspaceQuery.createMcpServer(adapter, null);
785
+ if (workspaceMcpConfig) servers[workspaceMcpConfig.name || "clay-workspace"] = workspaceMcpConfig;
786
+ } catch (e) {
787
+ console.error("[project] Failed to create clay-workspace MCP server:", e.message);
788
+ }
789
+ try {
790
+ var clayHistoryMcpConfig = _workspaceQuery.createHistoryMcpServer(adapter, null);
791
+ if (clayHistoryMcpConfig) servers[clayHistoryMcpConfig.name || "clay-history"] = clayHistoryMcpConfig;
792
+ } catch (e) {
793
+ console.error("[project] Failed to create Clay history compatibility server:", e.message);
794
+ }
795
+ }
695
796
 
696
- var toolId = "ask_" + Date.now() + "_" + crypto.randomUUID().slice(0, 8);
697
- // Track for UI card lifecycle + answer routing. No resolve function.
698
- session.pendingAskUser[toolId] = {
699
- input: input,
700
- mode: "mcp",
701
- sessionId: session.localId,
702
- postedAt: Date.now(),
703
- };
704
-
705
- sm.sendAndRecord(session, {
706
- type: "tool_executing",
707
- id: toolId,
708
- name: "AskUserQuestion",
709
- input: input,
710
- });
711
-
712
- return Promise.resolve({
713
- content: [{
714
- type: "text",
715
- text: "The question card has been posted to the user. End this turn now without further commentary; the user's answer will arrive as the next user message, prefixed with \"[Answer to your AskUserQuestion]\" so you can recognize it.",
716
- }],
717
- });
718
- });
719
- var askUserMcpConfig = adapter.createToolServer({ name: "clay-ask-user", version: "1.0.0", tools: askUserToolDefs });
720
- if (askUserMcpConfig) servers[askUserMcpConfig.name || "clay-ask-user"] = askUserMcpConfig;
797
+ if (isMate) {
798
+ try {
799
+ var toolControlMcpConfig = createToolControlMcpServer();
800
+ if (toolControlMcpConfig) servers[toolControlMcpConfig.name || "clay-tools"] = toolControlMcpConfig;
721
801
  } catch (e) {
722
- console.error("[project] Failed to create ask-user MCP server:", e.message);
802
+ console.error("[project] Failed to create clay-tools MCP server:", e.message);
723
803
  }
724
804
  }
725
805
 
@@ -805,6 +885,33 @@ function createProjectContext(opts) {
805
885
  var name = keys[i];
806
886
  if (name === "clay-browser" && !extConnected) continue;
807
887
  if (name === "clay-email" && !emailAvailable) continue;
888
+ if (name === "clay-workspace" && forSession) {
889
+ try {
890
+ var boundWorkspace = _workspaceQuery.createMcpServer(adapter, forSession);
891
+ if (boundWorkspace) { filtered[name] = boundWorkspace; hasAny = true; }
892
+ } catch (e) {
893
+ console.error("[project] Failed to bind clay-workspace MCP server:", e.message);
894
+ }
895
+ continue;
896
+ }
897
+ if (name === "clay-history" && forSession) {
898
+ try {
899
+ var boundHistory = _workspaceQuery.createHistoryMcpServer(adapter, forSession);
900
+ if (boundHistory) { filtered[name] = boundHistory; hasAny = true; }
901
+ } catch (e) {
902
+ console.error("[project] Failed to bind Clay history compatibility server:", e.message);
903
+ }
904
+ continue;
905
+ }
906
+ if (name === "clay-tools" && forSession) {
907
+ try {
908
+ var boundToolControl = createToolControlMcpServer();
909
+ if (boundToolControl) { filtered[name] = boundToolControl; hasAny = true; }
910
+ } catch (e) {
911
+ console.error("[project] Failed to bind clay-tools MCP server:", e.message);
912
+ }
913
+ continue;
914
+ }
808
915
  if (name === "clay-sessions" && forSession) {
809
916
  try {
810
917
  var boundSpawn = _sessionSpawn.createMcpServer(adapter, forSession);
@@ -850,6 +957,15 @@ function createProjectContext(opts) {
850
957
  }
851
958
  continue;
852
959
  }
960
+ if (name === "clay-mate-creation" && forSession) {
961
+ try {
962
+ var boundMateCreation = _mateCreationProposal.createMcpServer(adapter, forSession);
963
+ if (boundMateCreation) { filtered[name] = boundMateCreation; hasAny = true; }
964
+ } catch (e) {
965
+ console.error("[project] Failed to bind Mate creation MCP server:", e.message);
966
+ }
967
+ continue;
968
+ }
853
969
  filtered[name] = mcpServers[name];
854
970
  hasAny = true;
855
971
  }
@@ -866,6 +982,7 @@ function createProjectContext(opts) {
866
982
  adapter: adapter,
867
983
  adapters: adapters,
868
984
  getNotificationsModule: function () { return _notifications; },
985
+ shouldSuppressResponseNotification: opts.shouldSuppressResponseNotification,
869
986
  mateDisplayName: opts.mateDisplayName || "",
870
987
  isMate: isMate,
871
988
  osUsers: osUsers,
@@ -879,6 +996,7 @@ function createProjectContext(opts) {
879
996
  onTurnDone: function (session, preview) {
880
997
  if (isMate) digestDmTurn(session, preview);
881
998
  else _sessionPair.handleTurnDone(session);
999
+ if (session && typeof session.onTurnDone === "function") session.onTurnDone(session, preview);
882
1000
  },
883
1001
  scheduleMessage: function (session, text, resetsAt) {
884
1002
  scheduleMessage(session, text, resetsAt);
@@ -902,13 +1020,22 @@ function createProjectContext(opts) {
902
1020
  _sessionNotes.getSystemPrompt(session),
903
1021
  _sessionHandoff.getSystemPrompt(session),
904
1022
  _sessionDocument.getSystemPrompt(session),
1023
+ _capsuleCatalog.getSystemPrompt(session),
905
1024
  ]);
906
1025
  },
1026
+ getRuntimeEnv: getRuntimeEnvForSession,
1027
+ onUserInputRequest: function (session, request, respond) {
1028
+ return _askUser.createHandler(session)(request, respond);
1029
+ },
907
1030
  getSessionToolDefs: function (session) {
908
1031
  return _sessionPair.getToolDefs(session)
909
1032
  .concat(_sessionNotes.getToolDefs(session))
910
1033
  .concat(_sessionHandoff.getToolDefs(session))
911
- .concat(_sessionDocument.getToolDefs(session));
1034
+ .concat(_sessionDocument.getToolDefs(session))
1035
+ .concat(_debateProposal.getToolDefs(session))
1036
+ .concat(_mateCreationProposal.getToolDefs(session))
1037
+ .concat(_workspaceQuery.getDynamicToolDefs(session))
1038
+ .concat(_workspaceQuery.getHistoryDynamicToolDefs(session));
912
1039
  },
913
1040
  });
914
1041
 
@@ -1042,6 +1169,11 @@ function createProjectContext(opts) {
1042
1169
  }
1043
1170
 
1044
1171
  function handleMessage(ws, msg) {
1172
+ if (ws._clayHomeDebateSlug && ws._clayHomeDebateSlug !== slug && /^debate_(hand_raise|comment|stop|conclude_response|user_floor_response)$/.test(msg.type || "") && opts.getProject) {
1173
+ var homeDebateCtx = opts.getProject(ws._clayHomeDebateSlug);
1174
+ if (homeDebateCtx) homeDebateCtx.handleMessage(ws, msg);
1175
+ return;
1176
+ }
1045
1177
  // --- Cross-project routing (e.g. permission_response from notification banner) ---
1046
1178
  if (msg.targetSlug && msg.targetSlug !== slug && opts.getProject) {
1047
1179
  var targetCtx = opts.getProject(msg.targetSlug);
@@ -1052,9 +1184,17 @@ function createProjectContext(opts) {
1052
1184
  }
1053
1185
 
1054
1186
  // --- DM messages (delegated to server-level handler) ---
1055
- if (msg.type === "dm_open" || msg.type === "dm_send" || msg.type === "dm_list" || msg.type === "dm_typing" || msg.type === "dm_add_favorite" || msg.type === "dm_remove_favorite" || msg.type === "mate_create" || msg.type === "mate_list" || msg.type === "mate_delete" || msg.type === "mate_update" || msg.type === "mate_readd_builtin" || msg.type === "mate_list_available_builtins" || msg.type === "email_accounts_list" || msg.type === "email_account_add" || msg.type === "email_account_remove" || msg.type === "email_account_test" || msg.type === "home_clay_open" || msg.type === "home_clay_send" || msg.type === "home_clay_new_session" || msg.type === "home_clay_close") {
1187
+ if (msg.type === "home_debate_question_response" || msg.type === "home_debate_control" || msg.type === "home_mate_creation_question_response") {
1188
+ if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg);
1189
+ return;
1190
+ }
1191
+ if (msg.type === "home_clay_ask" || msg.type === "home_clay_session_resolve") {
1192
+ if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg, slug);
1193
+ return;
1194
+ }
1195
+ if (msg.type === "project_assignment_response" || msg.type === "dm_open" || msg.type === "dm_send" || msg.type === "dm_list" || msg.type === "dm_typing" || msg.type === "dm_add_favorite" || msg.type === "dm_remove_favorite" || msg.type === "mate_create" || msg.type === "mate_list" || msg.type === "mate_delete" || msg.type === "mate_update" || msg.type === "mate_readd_builtin" || msg.type === "mate_list_available_builtins" || msg.type === "email_accounts_list" || msg.type === "email_account_add" || msg.type === "email_account_remove" || msg.type === "email_account_test" || msg.type === "home_debates_list" || msg.type === "home_mate_present" || msg.type === "home_mate_open" || msg.type === "home_mate_sessions_list" || msg.type === "home_mate_session_open" || msg.type === "home_mate_send" || msg.type === "home_mate_new_session" || msg.type === "home_mate_debate_plan" || msg.type === "home_debate_proposal_response" || msg.type === "home_mate_creation_plan" || msg.type === "home_mate_creation_proposal_response" || msg.type === "home_mate_close" || msg.type === "home_mate_memory_list" || msg.type === "home_mate_knowledge_list" || msg.type === "home_mate_models_get" || msg.type === "home_mate_model_set" || msg.type === "home_dock_get" || msg.type === "home_dock_set" || msg.type === "home_surface_get" || msg.type === "home_surface_set" || msg.type === "tools_list" || msg.type === "tool_get" || msg.type === "tool_install" || msg.type === "tool_remove" || msg.type === "tool_storage_op" || msg.type === "tool_llm_op" || msg.type === "tool_llm_config_get" || msg.type === "tool_control_response" || msg.type === "tool_source_get" || msg.type === "tool_mate_access_set") {
1056
1196
  if (typeof opts.onDmMessage === "function") {
1057
- opts.onDmMessage(ws, msg);
1197
+ opts.onDmMessage(ws, msg, slug);
1058
1198
  }
1059
1199
  return;
1060
1200
  }
@@ -1147,6 +1287,9 @@ function createProjectContext(opts) {
1147
1287
  // --- Shell command context ---
1148
1288
  if (_shellCommand.handleShellCommand(ws, msg)) return;
1149
1289
 
1290
+ // --- Vendor login flow (delegated to project-vendor-login.js) ---
1291
+ if (_vendorLogin.handleVendorLoginMessage(ws, msg)) return;
1292
+
1150
1293
  // --- Notes, terminals, context, user message (delegated to project-user-message.js) ---
1151
1294
  if (_userMessage.handleUserMessage(ws, msg)) return;
1152
1295
  }
@@ -1165,7 +1308,12 @@ function createProjectContext(opts) {
1165
1308
  sendTo: sendTo,
1166
1309
  matesModule: matesModule,
1167
1310
  sessionSearch: sessionSearch,
1168
- getAllProjectSessions: getAllProjectSessions,
1311
+ getWorkspaceMemorySessions: function () { return _workspaceQuery.getMemorySessions(true); },
1312
+ getOwnedCurrentSessions: function () {
1313
+ return _workspaceQuery.getMemorySessions(false).filter(function (session) {
1314
+ return session._projectSlug === slug;
1315
+ });
1316
+ },
1169
1317
  projectOwnerId: projectOwnerId,
1170
1318
  handleMessage: handleMessage,
1171
1319
  });
@@ -1246,6 +1394,8 @@ function createProjectContext(opts) {
1246
1394
  getSessionForWs: getSessionForWs,
1247
1395
  updateMemorySummary: updateMemorySummary,
1248
1396
  initMemorySummary: initMemorySummary,
1397
+ registerHomeDebateClient: function (ws) { if (ws) homeDebateClients.add(ws); },
1398
+ unregisterHomeDebateClient: function (ws) { homeDebateClients.delete(ws); },
1249
1399
  });
1250
1400
  var handleDebateStart = _debate.handleDebateStart;
1251
1401
  var handleDebateHandRaise = _debate.handleDebateHandRaise;
@@ -1294,6 +1444,11 @@ function createProjectContext(opts) {
1294
1444
  browserState._extensionId = null;
1295
1445
  if (_mcp) _mcp.handleExtensionDisconnect();
1296
1446
  }
1447
+ homeDebateClients.delete(ws);
1448
+ if (ws._clayHomeDebateSlug && ws._clayHomeDebateSlug !== slug && opts.getProject) {
1449
+ var debateProject = opts.getProject(ws._clayHomeDebateSlug);
1450
+ if (debateProject && typeof debateProject.unregisterHomeDebateClient === "function") debateProject.unregisterHomeDebateClient(ws);
1451
+ }
1297
1452
  _connection.handleDisconnection(ws);
1298
1453
  }
1299
1454
 
@@ -1317,6 +1472,7 @@ function createProjectContext(opts) {
1317
1472
  sendToSessionOthers: sendToSessionOthers,
1318
1473
  opts: opts,
1319
1474
  usersModule: usersModule,
1475
+ getProjectAccess: opts.getProjectAccess || function () { return { visibility: "public", ownerId: projectOwnerId || null }; },
1320
1476
  userPresence: userPresence,
1321
1477
  matesModule: matesModule,
1322
1478
  pushModule: pushModule,
@@ -1365,6 +1521,28 @@ function createProjectContext(opts) {
1365
1521
  serverTls: serverTls,
1366
1522
  serverAuthToken: serverAuthToken,
1367
1523
  });
1524
+ var _delegatedSession = attachDelegatedSession({
1525
+ sm: sm,
1526
+ getSdk: function () { return sdk; },
1527
+ getLinuxUserForSession: getLinuxUserForSession,
1528
+ resolveModel: function (principal) {
1529
+ var user = principal && principal.userId ? usersModule.findUserById(principal.userId) : null;
1530
+ return _models.resolveConfiguredModel({ _clayUser: user || null }, "standard");
1531
+ },
1532
+ });
1533
+ var _delegatedFollowUp = attachDelegatedFollowUp({
1534
+ sm: sm,
1535
+ getSdk: function () { return sdk; },
1536
+ getLinuxUserForSession: getLinuxUserForSession,
1537
+ onProcessingChanged: onProcessingChanged,
1538
+ isMultiUser: function () { return usersModule.isMultiUser(); },
1539
+ sessionRef: function (session) { return workspaceSessionRef(slug, session); },
1540
+ isPairedSession: function (session) { return !!_splitGroups.store.groupForMember(session.localId); },
1541
+ canResumeVendor: function (vendor) {
1542
+ var capabilities = sm.capabilitiesByVendor && sm.capabilitiesByVendor[vendor];
1543
+ return !!(capabilities && capabilities.sessionResume === true);
1544
+ },
1545
+ });
1368
1546
 
1369
1547
  // --- User message handler (delegated to project-user-message.js) ---
1370
1548
  var _userMessage = attachUserMessage({
@@ -1419,6 +1597,21 @@ function createProjectContext(opts) {
1419
1597
  getOsUserInfoForWs: getOsUserInfoForWs,
1420
1598
  });
1421
1599
 
1600
+ // --- Vendor login flow (delegated to project-vendor-login.js) ---
1601
+ var _vendorLogin = attachVendorLogin({
1602
+ slug: slug,
1603
+ osUsers: osUsers,
1604
+ sm: sm,
1605
+ tm: tm,
1606
+ adapters: adapters,
1607
+ send: send,
1608
+ sendTo: sendTo,
1609
+ usersModule: usersModule,
1610
+ getOsUserInfoForWs: getOsUserInfoForWs,
1611
+ getOsUserInfoForLinuxUser: getOsUserInfoForLinuxUser,
1612
+ getLinuxUserForSession: getLinuxUserForSession,
1613
+ });
1614
+
1422
1615
  // --- Filesystem handler (delegated to project-filesystem.js) ---
1423
1616
  var _filesystem = attachFilesystem({
1424
1617
  cwd: cwd,
@@ -1436,6 +1629,7 @@ function createProjectContext(opts) {
1436
1629
  usersModule: usersModule,
1437
1630
  fsAsUser: fsAsUser,
1438
1631
  validateEnvString: validateEnvString,
1632
+ onEnvironmentChanged: function () { return sdk.refreshEnvironmentRuntime(); },
1439
1633
  opts: opts,
1440
1634
  IGNORED_DIRS: IGNORED_DIRS,
1441
1635
  BINARY_EXTS: BINARY_EXTS,
@@ -1531,6 +1725,14 @@ function createProjectContext(opts) {
1531
1725
  inputSchema: normalizeToolSchema(documentTools[dti].inputSchema),
1532
1726
  });
1533
1727
  }
1728
+ var debateTools = _debateProposal.getBridgeTools(boundSession, normalizeToolSchema);
1729
+ for (var dbti = 0; dbti < debateTools.length; dbti++) tools.push(debateTools[dbti]);
1730
+ var mateCreationTools = _mateCreationProposal.getBridgeTools(boundSession, normalizeToolSchema);
1731
+ for (var mcti = 0; mcti < mateCreationTools.length; mcti++) tools.push(mateCreationTools[mcti]);
1732
+ var workspaceTools = _workspaceQuery.getBridgeTools(boundSession, normalizeToolSchema);
1733
+ for (var wqti = 0; wqti < workspaceTools.length; wqti++) tools.push(workspaceTools[wqti]);
1734
+ var historyTools = _workspaceQuery.getHistoryBridgeTools(boundSession, normalizeToolSchema);
1735
+ for (var cht = 0; cht < historyTools.length; cht++) tools.push(historyTools[cht]);
1534
1736
  }
1535
1737
 
1536
1738
  if (sessionOnly) return Promise.resolve(tools);
@@ -1543,6 +1745,10 @@ function createProjectContext(opts) {
1543
1745
  var inAppNames = Object.keys(localMcp);
1544
1746
  for (var i = 0; i < inAppNames.length; i++) {
1545
1747
  if (inAppNames[i] === "clay-sessions" || inAppNames[i] === "clay-notes" || inAppNames[i] === "clay-handoff" || inAppNames[i] === "clay-documents") continue;
1748
+ // Debate tools were added above only when this request had an
1749
+ // exact session. Never duplicate them or advertise the static,
1750
+ // intentionally unbound proposal server.
1751
+ if (inAppNames[i] === "clay-debate" || inAppNames[i] === "clay-mate-creation" || inAppNames[i] === "clay-workspace" || inAppNames[i] === "clay-history") continue;
1546
1752
  extractServerTools(inAppNames[i], localMcp[inAppNames[i]]);
1547
1753
  }
1548
1754
  }
@@ -1593,7 +1799,19 @@ function createProjectContext(opts) {
1593
1799
  }
1594
1800
  }
1595
1801
  }
1596
- if (serverName === "clay-sessions" || serverName === "clay-notes" || serverName === "clay-handoff" || serverName === "clay-documents") {
1802
+ if (boundSession && serverName === "clay-debate") {
1803
+ return _debateProposal.callBridgeTool(boundSession, toolName, args);
1804
+ }
1805
+ if (boundSession && serverName === "clay-mate-creation") {
1806
+ return _mateCreationProposal.callBridgeTool(boundSession, toolName, args);
1807
+ }
1808
+ if (boundSession && serverName === "clay-workspace") {
1809
+ return _workspaceQuery.callBridgeTool(boundSession, toolName, args);
1810
+ }
1811
+ if (boundSession && serverName === "clay-history") {
1812
+ return _workspaceQuery.callHistoryBridgeTool(boundSession, toolName, args);
1813
+ }
1814
+ if (serverName === "clay-sessions" || serverName === "clay-notes" || serverName === "clay-handoff" || serverName === "clay-documents" || serverName === "clay-debate" || serverName === "clay-mate-creation" || serverName === "clay-workspace" || serverName === "clay-history") {
1597
1815
  return Promise.reject(new Error("Session-bound tool requires a valid Clay session: " + serverName + "/" + toolName));
1598
1816
  }
1599
1817
  if (sessionOnly) return Promise.reject(new Error("Session tool not found: " + serverName + "/" + toolName));
@@ -1667,6 +1885,7 @@ function createProjectContext(opts) {
1667
1885
  _mcp: _mcp,
1668
1886
  _notifications: _notifications,
1669
1887
  _splitGroups: _splitGroups,
1888
+ _vendorLogin: _vendorLogin,
1670
1889
  resolveSessionForView: _sessions.resolveSessionForView,
1671
1890
  hydrateImageRefs: hydrateImageRefs,
1672
1891
  broadcastClientCount: broadcastClientCount,
@@ -1807,7 +2026,7 @@ function createProjectContext(opts) {
1807
2026
  };
1808
2027
  if (isMate) {
1809
2028
  status.isMate = true;
1810
- status.mateId = path.basename(cwd);
2029
+ status.mateId = mateId;
1811
2030
  }
1812
2031
  if (worktreeMeta) {
1813
2032
  status.isWorktree = true;
@@ -1908,6 +2127,19 @@ function createProjectContext(opts) {
1908
2127
  getMcpBridgeHandler: getMcpBridgeHandler,
1909
2128
  getStatus: getStatus,
1910
2129
  getSessionManager: function () { return sm; },
2130
+ createDelegatedSession: _delegatedSession.createDelegatedSession,
2131
+ inspectDelegatedFollowUp: _delegatedFollowUp.inspectDelegatedFollowUp,
2132
+ dispatchDelegatedFollowUp: _delegatedFollowUp.dispatchDelegatedFollowUp,
2133
+ unregisterHomeDebateClient: function (ws) { homeDebateClients.delete(ws); },
2134
+ handleHomeDebateProposalResponse: function (ws, msg, session) { return _debateProposal.handleHomeMessage(ws, msg, session); },
2135
+ handleHomeMateCreationProposalResponse: function (ws, msg, session) { return _mateCreationProposal.handleHomeMessage(ws, msg, session); },
2136
+ handleHomeAskUserResponse: function (msg, session) { return _sessions.respondToAskUser(session, msg); },
2137
+ handleHomeDebateControl: function (ws, msg, session) { return _debate.handleHomeControl(ws, msg, session); },
2138
+ getVendorModelCatalog: _models.getVendorCatalog,
2139
+ getVendorModelAvailability: _models.getVendorAvailability,
2140
+ getMemoryState: _memory.readMemoryState,
2141
+ listKnowledgeFiles: _knowledge.listKnowledgeFiles,
2142
+ refreshCapsuleCatalog: _capsuleCatalog.refreshSessions,
1911
2143
  getNotificationsModule: function () { return _notifications; },
1912
2144
  getSchedules: _loop.getSchedules,
1913
2145
  importSchedule: _loop.importSchedule,
@@ -1916,6 +2148,21 @@ function createProjectContext(opts) {
1916
2148
  setIcon: setIcon,
1917
2149
  setProjectOwner: function (ownerId) { projectOwnerId = ownerId; },
1918
2150
  getProjectOwner: function () { return projectOwnerId; },
2151
+ getToolLlmConfig: function (ws, alias) {
2152
+ return _models.resolveConfiguredModel(ws, alias);
2153
+ },
2154
+ completeToolLlm: async function (ws, args) {
2155
+ var owner = projectOwnerId ? usersModule.findUserById(projectOwnerId) : null;
2156
+ var selection = await _models.resolveConfiguredModel(ws, args.model);
2157
+ return toolLlm.complete({
2158
+ adapters: adapters,
2159
+ cwd: cwd,
2160
+ linuxUser: owner && owner.linuxUser ? owner.linuxUser : null,
2161
+ args: args,
2162
+ selection: selection,
2163
+ timeoutMs: 60000,
2164
+ });
2165
+ },
1919
2166
  refreshUserProfile: function (userId) {
1920
2167
  var user = usersModule.findUserById(userId);
1921
2168
  if (!user) return;
@@ -1934,4 +2181,4 @@ function createProjectContext(opts) {
1934
2181
  };
1935
2182
  }
1936
2183
 
1937
- module.exports = { createProjectContext: createProjectContext, safePath: safePath, validateEnvString: validateEnvString };
2184
+ module.exports = { createProjectContext: createProjectContext, createMateToolControlMcp: createMateToolControlMcp, safePath: safePath, validateEnvString: validateEnvString };