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.
- package/lib/ask-user-mcp-server.js +5 -119
- package/lib/builtin-mates.js +6 -6
- package/lib/claude-hook-installer.js +15 -0
- package/lib/clay-history-mcp-server.js +62 -297
- package/lib/daemon.js +1 -1
- package/lib/debate-model-selection.js +119 -0
- package/lib/home-debate-tool-policy.js +164 -0
- package/lib/home-response-notifications.js +26 -0
- package/lib/mate-creation-mcp-server.js +55 -0
- package/lib/mate-ready-creation.js +95 -0
- package/lib/mates.js +2 -0
- package/lib/notes.js +2 -1
- package/lib/project-ask-user.js +64 -0
- package/lib/project-capsule-catalog.js +101 -0
- package/lib/project-debate-proposal.js +133 -17
- package/lib/project-debate.js +214 -110
- package/lib/project-delegated-follow-up.js +84 -0
- package/lib/project-delegated-session.js +53 -0
- package/lib/project-filesystem.js +7 -9
- package/lib/project-knowledge.js +1 -0
- package/lib/project-mate-creation-proposal.js +120 -0
- package/lib/project-memory.js +14 -7
- package/lib/project-models.js +157 -32
- package/lib/project-session-notes.js +2 -2
- package/lib/project-session-pair.js +8 -8
- package/lib/project-sessions.js +66 -51
- package/lib/project-worker-proposal.js +25 -25
- package/lib/project-workspace-query.js +144 -0
- package/lib/project.js +329 -102
- package/lib/public/app.js +85 -42
- package/lib/public/css/avatar-imprints.css +0 -1
- package/lib/public/css/base.css +4 -0
- package/lib/public/css/capsule-ui.css +389 -0
- package/lib/public/css/command-palette.css +306 -6
- package/lib/public/css/home-capsule-library.css +243 -0
- package/lib/public/css/home-capsule-source.css +192 -0
- package/lib/public/css/home-debate-live.css +146 -0
- package/lib/public/css/home-debate-planning.css +125 -0
- package/lib/public/css/home-debates-archive.css +281 -0
- package/lib/public/css/home-hub.css +896 -405
- package/lib/public/css/home-mate-creation.css +34 -0
- package/lib/public/css/home-mate-model-picker.css +131 -0
- package/lib/public/css/home-mate-settings.css +344 -0
- package/lib/public/css/home-session-actions.css +265 -0
- package/lib/public/css/home-sidebar.css +667 -0
- package/lib/public/css/icon-strip.css +1 -2
- package/lib/public/css/mates.css +7 -34
- package/lib/public/css/pane.css +1 -1
- package/lib/public/css/playbook.css +0 -80
- package/lib/public/css/sticky-notes.css +53 -117
- package/lib/public/css/tui-attention.css +0 -44
- package/lib/public/css/workspace-assignment.css +45 -0
- package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
- package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
- package/lib/public/index.html +93 -74
- package/lib/public/modules/app-connection.js +10 -1
- package/lib/public/modules/app-dm.js +43 -160
- package/lib/public/modules/app-home-hub.js +328 -585
- package/lib/public/modules/app-message-cards.js +242 -0
- package/lib/public/modules/app-message-router.js +84 -0
- package/lib/public/modules/app-messages.js +78 -20
- package/lib/public/modules/app-notifications.js +4 -2
- package/lib/public/modules/app-projects.js +9 -1
- package/lib/public/modules/app-rendering.js +21 -602
- package/lib/public/modules/avatar-imprint.js +11 -8
- package/lib/public/modules/chat-bubble-renderer.js +152 -0
- package/lib/public/modules/chat-render-runtime.js +198 -0
- package/lib/public/modules/command-palette.js +225 -436
- package/lib/public/modules/dm-render.js +82 -0
- package/lib/public/modules/home-capsule-creation-intent.js +31 -0
- package/lib/public/modules/home-capsule-library.js +146 -0
- package/lib/public/modules/home-capsule-source.js +383 -0
- package/lib/public/modules/home-chat-identity.js +35 -0
- package/lib/public/modules/home-chat-scroll.js +77 -0
- package/lib/public/modules/home-chat-stream-state.js +34 -0
- package/lib/public/modules/home-composer-focus.js +25 -0
- package/lib/public/modules/home-conversations-sheet.js +179 -0
- package/lib/public/modules/home-debate-activity.js +48 -0
- package/lib/public/modules/home-debate-controls.js +295 -0
- package/lib/public/modules/home-debate-launch.js +41 -0
- package/lib/public/modules/home-debate-live.js +284 -0
- package/lib/public/modules/home-debate-models.js +73 -0
- package/lib/public/modules/home-debate-planning.js +335 -0
- package/lib/public/modules/home-debates-archive.js +279 -0
- package/lib/public/modules/home-dock-resize.js +74 -0
- package/lib/public/modules/home-dock.js +446 -0
- package/lib/public/modules/home-mate-chat.js +496 -0
- package/lib/public/modules/home-mate-creation.js +109 -0
- package/lib/public/modules/home-mate-model-picker.js +281 -0
- package/lib/public/modules/home-mate-selection.js +38 -0
- package/lib/public/modules/home-mate-settings-menu.js +131 -0
- package/lib/public/modules/home-mate-settings.js +383 -0
- package/lib/public/modules/home-session-actions.js +373 -0
- package/lib/public/modules/home-session-model-confirmation.js +13 -0
- package/lib/public/modules/home-shell.js +9 -0
- package/lib/public/modules/home-sidebar-chat-list.js +63 -0
- package/lib/public/modules/home-sidebar.js +158 -0
- package/lib/public/modules/home-sub-surface.js +19 -0
- package/lib/public/modules/home-surface-boot.js +68 -0
- package/lib/public/modules/home-surface.js +141 -0
- package/lib/public/modules/home-tools.js +271 -0
- package/lib/public/modules/markdown.js +50 -2
- package/lib/public/modules/mate-management.js +86 -0
- package/lib/public/modules/mate-wizard.js +0 -7
- package/lib/public/modules/mention.js +17 -19
- package/lib/public/modules/profile.js +4 -5
- package/lib/public/modules/project-settings.js +34 -28
- package/lib/public/modules/project-switcher.js +11 -5
- package/lib/public/modules/project-workspace-assignment.js +23 -0
- package/lib/public/modules/search-clay-chat.js +402 -0
- package/lib/public/modules/server-settings.js +14 -12
- package/lib/public/modules/session-actions.js +1 -1
- package/lib/public/modules/sidebar-mates.js +56 -552
- package/lib/public/modules/sidebar-mobile.js +7 -64
- package/lib/public/modules/sidebar-presence.js +37 -0
- package/lib/public/modules/split-pair-ui.js +13 -13
- package/lib/public/modules/sticky-notes.js +7 -6
- package/lib/public/modules/tool-input-composition.js +48 -0
- package/lib/public/modules/tool-llm-status.js +167 -0
- package/lib/public/modules/tool-renderer-advanced.js +285 -0
- package/lib/public/modules/tool-renderer-chart.js +158 -0
- package/lib/public/modules/tool-renderer-semantics.js +35 -0
- package/lib/public/modules/tool-renderer.js +464 -0
- package/lib/public/modules/tool-runtime.js +309 -0
- package/lib/public/modules/tool-ui-evaluator.js +97 -0
- package/lib/public/modules/tool-ui-tree.js +21 -0
- package/lib/public/modules/user-settings.js +16 -23
- package/lib/public/modules/worker-proposal.js +2 -2
- package/lib/public/modules/workspace-assignment-card.js +149 -0
- package/lib/public/modules/workspace-assignment-routing.js +4 -0
- package/lib/public/style.css +13 -2
- package/lib/runtime-env.js +65 -0
- package/lib/sdk-bridge.js +120 -32
- package/lib/sdk-message-processor.js +10 -6
- package/lib/server-home-capsule-creation.js +36 -0
- package/lib/server-home-chat-events.js +287 -0
- package/lib/server-home-chat.js +518 -0
- package/lib/server-home-clay-entry.js +65 -0
- package/lib/server-home-clay-session-links.js +26 -0
- package/lib/server-home-debate-planning.js +214 -0
- package/lib/server-home-debates.js +137 -0
- package/lib/server-home-mate-creation.js +261 -0
- package/lib/server-home-models.js +241 -0
- package/lib/server-home-preferences.js +61 -0
- package/lib/server-mates.js +37 -0
- package/lib/server-tools.js +377 -0
- package/lib/server.js +111 -59
- package/lib/session-pair-mcp-server.js +6 -6
- package/lib/sessions.js +18 -3
- package/lib/tool-capsule-source.js +142 -0
- package/lib/tool-control-mcp-server.js +126 -0
- package/lib/tool-llm.js +48 -0
- package/lib/tool-storage.js +77 -0
- package/lib/tool-ui-spec-advanced.js +82 -0
- package/lib/tool-ui-spec.js +261 -0
- package/lib/tools-registry.js +276 -0
- package/lib/users-home-dock-preferences.js +77 -0
- package/lib/users-home-surface-preferences.js +99 -0
- package/lib/users-preferences.js +4 -7
- package/lib/users.js +12 -0
- package/lib/whats-new-content.js +3 -3
- package/lib/workspace-assignment-service.js +420 -0
- package/lib/workspace-query-mcp-server.js +154 -0
- package/lib/workspace-query-service.js +492 -0
- package/lib/ws-schema.js +86 -12
- package/lib/yoke/adapters/acp.js +2 -1
- package/lib/yoke/adapters/antigravity.js +2 -1
- package/lib/yoke/adapters/claude-worker.js +11 -4
- package/lib/yoke/adapters/claude.js +73 -43
- package/lib/yoke/adapters/codex.js +37 -6
- package/lib/yoke/adapters/kiro.js +2 -1
- package/lib/yoke/claude-user-input.js +38 -0
- package/lib/yoke/codex-user-input.js +64 -0
- package/lib/yoke/complete-once.js +164 -0
- package/lib/yoke/index.js +5 -1
- package/lib/yoke/interface.js +19 -0
- package/lib/yoke/mcp-bridge-server.js +2 -6
- package/lib/yoke/user-input.js +254 -0
- package/package.json +2 -1
- package/lib/public/css/home-chat.css +0 -380
- package/lib/public/modules/home-chat.js +0 -438
- 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");
|
|
@@ -35,13 +39,68 @@ var { attachMcp } = require("./project-mcp");
|
|
|
35
39
|
var { createLocalMcp } = require("./mcp-local");
|
|
36
40
|
var { attachEmail: attachEmailModule } = require("./project-email");
|
|
37
41
|
var { attachSessionSpawn } = require("./project-session-spawn");
|
|
42
|
+
var { attachDelegatedSession } = require("./project-delegated-session");
|
|
43
|
+
var { attachDelegatedFollowUp } = require("./project-delegated-follow-up");
|
|
44
|
+
var workspaceSessionRef = require("./workspace-query-service").sessionRef;
|
|
38
45
|
var { attachSessionPair } = require("./project-session-pair");
|
|
39
46
|
var { attachSessionHandoff } = require("./project-session-handoff");
|
|
40
47
|
var { attachSessionNotes, composeSystemPrompts } = require("./project-session-notes");
|
|
41
48
|
var { attachSessionDocument } = require("./project-session-document");
|
|
49
|
+
var { attachCapsuleCatalog } = require("./project-capsule-catalog");
|
|
50
|
+
var { attachProjectWorkspaceQuery } = require("./project-workspace-query");
|
|
42
51
|
var { attachSplitGroups } = require("./session-split-groups");
|
|
52
|
+
var toolControlMcp = require("./tool-control-mcp-server");
|
|
53
|
+
var toolLlm = require("./tool-llm");
|
|
43
54
|
// project-notifications is attached globally in server.js, passed via opts.notificationsModule
|
|
44
55
|
|
|
56
|
+
function createMateToolControlMcp(adapter, config) {
|
|
57
|
+
if (!adapter || typeof adapter.createToolServer !== "function") return null;
|
|
58
|
+
var handlers = {
|
|
59
|
+
list: function () {
|
|
60
|
+
var manifests = config.list(config.userId) || [];
|
|
61
|
+
var tools = [];
|
|
62
|
+
for (var i = 0; i < manifests.length; i++) {
|
|
63
|
+
tools.push({
|
|
64
|
+
id: manifests[i].id,
|
|
65
|
+
name: manifests[i].name,
|
|
66
|
+
description: manifests[i].description || "",
|
|
67
|
+
useWhen: manifests[i].useWhen || "",
|
|
68
|
+
runtime: manifests[i].runtime || "worker",
|
|
69
|
+
permissions: manifests[i].permissions || [],
|
|
70
|
+
skills: manifests[i].skills || "",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return tools;
|
|
74
|
+
},
|
|
75
|
+
snapshot: function (toolId) {
|
|
76
|
+
return config.control(config.userId, config.mateId, toolId, "snapshot", {});
|
|
77
|
+
},
|
|
78
|
+
act: function (toolId, actionId, args) {
|
|
79
|
+
return config.control(config.userId, config.mateId, toolId, "act", { actionId: actionId, args: args });
|
|
80
|
+
},
|
|
81
|
+
set: function (toolId, controlId, value) {
|
|
82
|
+
return config.control(config.userId, config.mateId, toolId, "set", { controlId: controlId, value: value });
|
|
83
|
+
},
|
|
84
|
+
source: function (toolId) {
|
|
85
|
+
return config.source(config.userId, toolId);
|
|
86
|
+
},
|
|
87
|
+
install: function (input) {
|
|
88
|
+
return config.install(config.userId, input);
|
|
89
|
+
},
|
|
90
|
+
update: function (toolId, input) {
|
|
91
|
+
return config.update(config.userId, toolId, input);
|
|
92
|
+
},
|
|
93
|
+
uninstall: function (toolId) {
|
|
94
|
+
return config.remove(config.userId, toolId);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
return adapter.createToolServer({
|
|
98
|
+
name: "clay-tools",
|
|
99
|
+
version: "1.0.0",
|
|
100
|
+
tools: toolControlMcp.getToolDefs(handlers),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
45
104
|
// --- Context Sources persistence ---
|
|
46
105
|
var _ctxSrcConfig = require("./config");
|
|
47
106
|
var _ctxSrcDir = path.join(_ctxSrcConfig.CONFIG_DIR, "context-sources");
|
|
@@ -73,26 +132,7 @@ function saveContextSources(slug, sessionId, activeIds) {
|
|
|
73
132
|
// Validate environment variable string (KEY=VALUE per line)
|
|
74
133
|
// Returns null if valid, or an error string if invalid
|
|
75
134
|
function validateEnvString(str) {
|
|
76
|
-
|
|
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;
|
|
135
|
+
return runtimeEnv.validateEnvString(str);
|
|
96
136
|
}
|
|
97
137
|
|
|
98
138
|
// YOKE adapter (replaces direct SDK access)
|
|
@@ -153,8 +193,6 @@ function createProjectContext(opts) {
|
|
|
153
193
|
var lanHost = opts.lanHost || null;
|
|
154
194
|
var getProjectCount = opts.getProjectCount || function () { return 1; };
|
|
155
195
|
var getProjectList = opts.getProjectList || function () { return []; };
|
|
156
|
-
var getAllProjectSessions = opts.getAllProjectSessions || function () { return []; };
|
|
157
|
-
var getAllProjectsWithSessions = opts.getAllProjectsWithSessions || function () { return []; };
|
|
158
196
|
var isHostAgent = !!opts.isHostAgent;
|
|
159
197
|
var getHubSchedules = opts.getHubSchedules || function () { return []; };
|
|
160
198
|
var moveScheduleToProject = opts.moveScheduleToProject || function () { return { ok: false, error: "Not supported" }; };
|
|
@@ -168,6 +206,23 @@ function createProjectContext(opts) {
|
|
|
168
206
|
var projectOwnerId = opts.projectOwnerId || null;
|
|
169
207
|
var worktreeMeta = opts.worktreeMeta || null; // { parentSlug, branch, external }
|
|
170
208
|
var isMate = opts.isMate || false;
|
|
209
|
+
var mateId = opts.mateId || (isMate ? path.basename(cwd) : null);
|
|
210
|
+
var listControllableTools = opts.listControllableTools || function () { return []; };
|
|
211
|
+
var controlToolForMate = opts.controlToolForMate || function () {
|
|
212
|
+
return Promise.reject(new Error("Tool control is unavailable."));
|
|
213
|
+
};
|
|
214
|
+
var installToolForMate = opts.installToolForMate || function () {
|
|
215
|
+
return Promise.reject(new Error("Tool installation is unavailable."));
|
|
216
|
+
};
|
|
217
|
+
var sourceToolForMate = opts.sourceToolForMate || function () {
|
|
218
|
+
return Promise.reject(new Error("Capsule source access is unavailable."));
|
|
219
|
+
};
|
|
220
|
+
var updateToolForMate = opts.updateToolForMate || function () {
|
|
221
|
+
return Promise.reject(new Error("Capsule source updates are unavailable."));
|
|
222
|
+
};
|
|
223
|
+
var removeToolForMate = opts.removeToolForMate || function () {
|
|
224
|
+
return Promise.reject(new Error("Tool removal is unavailable."));
|
|
225
|
+
};
|
|
171
226
|
var onCreateWorktree = opts.onCreateWorktree || null;
|
|
172
227
|
var serverPort = opts.port || 2633;
|
|
173
228
|
var serverTls = opts.tls || false;
|
|
@@ -219,8 +274,7 @@ function createProjectContext(opts) {
|
|
|
219
274
|
|
|
220
275
|
// Cache resolved OS user info to avoid repeated getent calls
|
|
221
276
|
var osUserInfoCache = {};
|
|
222
|
-
function
|
|
223
|
-
var linuxUser = getLinuxUserForWs(ws);
|
|
277
|
+
function getOsUserInfoForLinuxUser(linuxUser) {
|
|
224
278
|
if (!linuxUser) return null;
|
|
225
279
|
if (osUserInfoCache[linuxUser]) return osUserInfoCache[linuxUser];
|
|
226
280
|
try {
|
|
@@ -233,23 +287,34 @@ function createProjectContext(opts) {
|
|
|
233
287
|
}
|
|
234
288
|
}
|
|
235
289
|
|
|
290
|
+
function getOsUserInfoForWs(ws) {
|
|
291
|
+
var linuxUser = getLinuxUserForWs(ws);
|
|
292
|
+
return getOsUserInfoForLinuxUser(linuxUser);
|
|
293
|
+
}
|
|
294
|
+
|
|
236
295
|
function getOsUserInfoForReq(req) {
|
|
237
296
|
if (!osUsers) return null;
|
|
238
297
|
if (!req._clayUser || !req._clayUser.linuxUser) return null;
|
|
239
298
|
var linuxUser = req._clayUser.linuxUser;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
299
|
+
return getOsUserInfoForLinuxUser(linuxUser);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function getRuntimeEnvForSession(session) {
|
|
303
|
+
var linuxUser = (session && session.linuxUser) || getLinuxUserForSession(session);
|
|
304
|
+
var osUserInfo = getOsUserInfoForLinuxUser(linuxUser);
|
|
305
|
+
var baseEnv = osUserInfo ? buildUserEnv(osUserInfo) : process.env;
|
|
306
|
+
var shared = typeof opts.onGetSharedEnv === "function" ? opts.onGetSharedEnv() : null;
|
|
307
|
+
var projectEnv = typeof opts.onGetProjectEnv === "function" ? opts.onGetProjectEnv(slug) : null;
|
|
308
|
+
return runtimeEnv.resolveRuntimeEnv({
|
|
309
|
+
baseEnv: baseEnv,
|
|
310
|
+
sharedEnvrc: shared && shared.envrc,
|
|
311
|
+
projectEnvrc: projectEnv && projectEnv.envrc,
|
|
312
|
+
});
|
|
249
313
|
}
|
|
250
314
|
|
|
251
315
|
// --- Per-project clients ---
|
|
252
316
|
var clients = new Set();
|
|
317
|
+
var homeDebateClients = new Set();
|
|
253
318
|
|
|
254
319
|
// --- Browser extension state (shared mutable object) ---
|
|
255
320
|
var _extToken = crypto.randomUUID(); // Auth token for MCP server bridge
|
|
@@ -369,6 +434,10 @@ function createProjectContext(opts) {
|
|
|
369
434
|
ws.send(data);
|
|
370
435
|
}
|
|
371
436
|
}
|
|
437
|
+
homeDebateClients.forEach(function (ws) {
|
|
438
|
+
if (ws.readyState !== 1) { homeDebateClients.delete(ws); return; }
|
|
439
|
+
if (!clients.has(ws) && ws._clayHomeDebateSlug === slug && ws._clayActiveSession === sessionId) ws.send(data);
|
|
440
|
+
});
|
|
372
441
|
}
|
|
373
442
|
|
|
374
443
|
function sendToSessionOthers(sender, sessionId, obj) {
|
|
@@ -537,6 +606,23 @@ function createProjectContext(opts) {
|
|
|
537
606
|
},
|
|
538
607
|
fsAsUser: fsAsUser,
|
|
539
608
|
});
|
|
609
|
+
var _capsuleCatalog = attachCapsuleCatalog({
|
|
610
|
+
isMate: isMate,
|
|
611
|
+
listManifests: listControllableTools,
|
|
612
|
+
getUserId: function (session) {
|
|
613
|
+
return (session && session.ownerId) || projectOwnerId || "default";
|
|
614
|
+
},
|
|
615
|
+
getSdk: function () { return sdk; },
|
|
616
|
+
getSessions: function () { return sm.sessions; },
|
|
617
|
+
});
|
|
618
|
+
var _workspaceQuery = attachProjectWorkspaceQuery({
|
|
619
|
+
service: opts.workspaceQueryService || null,
|
|
620
|
+
sm: sm,
|
|
621
|
+
projectSlug: slug,
|
|
622
|
+
getProjectOwnerId: function () { return projectOwnerId; },
|
|
623
|
+
isMate: isMate,
|
|
624
|
+
mateId: mateId,
|
|
625
|
+
});
|
|
540
626
|
|
|
541
627
|
// The SDK bridge is created after local MCP servers. Session spawning uses
|
|
542
628
|
// a getter so tool handlers see the initialized bridge when they run.
|
|
@@ -587,15 +673,46 @@ function createProjectContext(opts) {
|
|
|
587
673
|
var _debateProposal = attachDebateProposal({
|
|
588
674
|
cwd: cwd,
|
|
589
675
|
isMate: isMate,
|
|
676
|
+
isHostAgent: isHostAgent,
|
|
590
677
|
sendTo: sendTo,
|
|
591
678
|
buildMateCtx: matesModule.buildMateCtx,
|
|
592
679
|
getMate: matesModule.getMate,
|
|
593
680
|
getProjectOwnerId: function () { return projectOwnerId; },
|
|
681
|
+
getVendorModelCatalog: function (ws, vendor) { return _models.getVendorCatalog(ws, vendor); },
|
|
682
|
+
getVendorModelCatalogForSession: function (session, vendor) {
|
|
683
|
+
var user = session && session.ownerId ? usersModule.findUserById(session.ownerId) : null;
|
|
684
|
+
return _models.getVendorCatalog({ _clayUser: user || null }, vendor);
|
|
685
|
+
},
|
|
594
686
|
startDebate: function (session, briefData, moderatorId, ws) {
|
|
595
687
|
if (!_debate) return { error: "The debate engine is unavailable." };
|
|
596
688
|
return _debate.handleMcpDebateApproval(session, briefData, moderatorId, ws);
|
|
597
689
|
},
|
|
690
|
+
recordSessionEvent: function (session, event) { sm.sendAndRecord(session, event); },
|
|
691
|
+
});
|
|
692
|
+
var _mateCreationProposal = attachMateCreationProposal({
|
|
693
|
+
isMate: isMate,
|
|
694
|
+
isHostAgent: isHostAgent,
|
|
695
|
+
isMultiUser: usersModule.isMultiUser,
|
|
696
|
+
getProjectOwnerId: function () { return projectOwnerId; },
|
|
697
|
+
recordSessionEvent: function (session, event) { sm.sendAndRecord(session, event); },
|
|
698
|
+
getVendorModelCatalog: function (ws, vendor) { return _models.getVendorCatalog(ws, vendor); },
|
|
699
|
+
createReadyMate: opts.createReadyMate,
|
|
598
700
|
});
|
|
701
|
+
var _askUser = attachAskUser({ record: function (session, event) { sm.sendAndRecord(session, event); } });
|
|
702
|
+
|
|
703
|
+
function createToolControlMcpServer() {
|
|
704
|
+
if (!isMate || !adapter || typeof adapter.createToolServer !== "function") return null;
|
|
705
|
+
return createMateToolControlMcp(adapter, {
|
|
706
|
+
userId: projectOwnerId || "default",
|
|
707
|
+
mateId: path.basename(cwd),
|
|
708
|
+
list: listControllableTools,
|
|
709
|
+
control: controlToolForMate,
|
|
710
|
+
source: sourceToolForMate,
|
|
711
|
+
install: installToolForMate,
|
|
712
|
+
update: updateToolForMate,
|
|
713
|
+
remove: removeToolForMate,
|
|
714
|
+
});
|
|
715
|
+
}
|
|
599
716
|
|
|
600
717
|
// --- MCP tool servers (created via YOKE adapter) ---
|
|
601
718
|
var mcpServers = (function () {
|
|
@@ -649,77 +766,39 @@ function createProjectContext(opts) {
|
|
|
649
766
|
console.error("[project] Failed to create debate MCP server:", e.message);
|
|
650
767
|
}
|
|
651
768
|
|
|
652
|
-
|
|
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) {
|
|
769
|
+
if (isMate && isHostAgent) {
|
|
657
770
|
try {
|
|
658
|
-
var
|
|
659
|
-
|
|
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;
|
|
771
|
+
var mateCreationMcpConfig = _mateCreationProposal.createMcpServer(adapter, null);
|
|
772
|
+
if (mateCreationMcpConfig) servers[mateCreationMcpConfig.name || "clay-mate-creation"] = mateCreationMcpConfig;
|
|
664
773
|
} catch (e) {
|
|
665
|
-
console.error("[project] Failed to create
|
|
774
|
+
console.error("[project] Failed to create Mate creation MCP server:", e.message);
|
|
666
775
|
}
|
|
667
776
|
}
|
|
668
777
|
|
|
669
|
-
//
|
|
778
|
+
// Owner-bound workspace inspection is available only inside Mate
|
|
779
|
+
// projects. The server-side Mate registry decides whether the wider
|
|
780
|
+
// builtin Clay tools are present; project flags and tool arguments do not.
|
|
670
781
|
if (isMate) {
|
|
671
782
|
try {
|
|
672
|
-
var
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
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
|
-
}
|
|
783
|
+
var workspaceMcpConfig = _workspaceQuery.createMcpServer(adapter, null);
|
|
784
|
+
if (workspaceMcpConfig) servers[workspaceMcpConfig.name || "clay-workspace"] = workspaceMcpConfig;
|
|
785
|
+
} catch (e) {
|
|
786
|
+
console.error("[project] Failed to create clay-workspace MCP server:", e.message);
|
|
787
|
+
}
|
|
788
|
+
try {
|
|
789
|
+
var clayHistoryMcpConfig = _workspaceQuery.createHistoryMcpServer(adapter, null);
|
|
790
|
+
if (clayHistoryMcpConfig) servers[clayHistoryMcpConfig.name || "clay-history"] = clayHistoryMcpConfig;
|
|
791
|
+
} catch (e) {
|
|
792
|
+
console.error("[project] Failed to create Clay history compatibility server:", e.message);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
695
795
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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;
|
|
796
|
+
if (isMate) {
|
|
797
|
+
try {
|
|
798
|
+
var toolControlMcpConfig = createToolControlMcpServer();
|
|
799
|
+
if (toolControlMcpConfig) servers[toolControlMcpConfig.name || "clay-tools"] = toolControlMcpConfig;
|
|
721
800
|
} catch (e) {
|
|
722
|
-
console.error("[project] Failed to create
|
|
801
|
+
console.error("[project] Failed to create clay-tools MCP server:", e.message);
|
|
723
802
|
}
|
|
724
803
|
}
|
|
725
804
|
|
|
@@ -805,6 +884,33 @@ function createProjectContext(opts) {
|
|
|
805
884
|
var name = keys[i];
|
|
806
885
|
if (name === "clay-browser" && !extConnected) continue;
|
|
807
886
|
if (name === "clay-email" && !emailAvailable) continue;
|
|
887
|
+
if (name === "clay-workspace" && forSession) {
|
|
888
|
+
try {
|
|
889
|
+
var boundWorkspace = _workspaceQuery.createMcpServer(adapter, forSession);
|
|
890
|
+
if (boundWorkspace) { filtered[name] = boundWorkspace; hasAny = true; }
|
|
891
|
+
} catch (e) {
|
|
892
|
+
console.error("[project] Failed to bind clay-workspace MCP server:", e.message);
|
|
893
|
+
}
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
if (name === "clay-history" && forSession) {
|
|
897
|
+
try {
|
|
898
|
+
var boundHistory = _workspaceQuery.createHistoryMcpServer(adapter, forSession);
|
|
899
|
+
if (boundHistory) { filtered[name] = boundHistory; hasAny = true; }
|
|
900
|
+
} catch (e) {
|
|
901
|
+
console.error("[project] Failed to bind Clay history compatibility server:", e.message);
|
|
902
|
+
}
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
if (name === "clay-tools" && forSession) {
|
|
906
|
+
try {
|
|
907
|
+
var boundToolControl = createToolControlMcpServer();
|
|
908
|
+
if (boundToolControl) { filtered[name] = boundToolControl; hasAny = true; }
|
|
909
|
+
} catch (e) {
|
|
910
|
+
console.error("[project] Failed to bind clay-tools MCP server:", e.message);
|
|
911
|
+
}
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
808
914
|
if (name === "clay-sessions" && forSession) {
|
|
809
915
|
try {
|
|
810
916
|
var boundSpawn = _sessionSpawn.createMcpServer(adapter, forSession);
|
|
@@ -850,6 +956,15 @@ function createProjectContext(opts) {
|
|
|
850
956
|
}
|
|
851
957
|
continue;
|
|
852
958
|
}
|
|
959
|
+
if (name === "clay-mate-creation" && forSession) {
|
|
960
|
+
try {
|
|
961
|
+
var boundMateCreation = _mateCreationProposal.createMcpServer(adapter, forSession);
|
|
962
|
+
if (boundMateCreation) { filtered[name] = boundMateCreation; hasAny = true; }
|
|
963
|
+
} catch (e) {
|
|
964
|
+
console.error("[project] Failed to bind Mate creation MCP server:", e.message);
|
|
965
|
+
}
|
|
966
|
+
continue;
|
|
967
|
+
}
|
|
853
968
|
filtered[name] = mcpServers[name];
|
|
854
969
|
hasAny = true;
|
|
855
970
|
}
|
|
@@ -866,6 +981,7 @@ function createProjectContext(opts) {
|
|
|
866
981
|
adapter: adapter,
|
|
867
982
|
adapters: adapters,
|
|
868
983
|
getNotificationsModule: function () { return _notifications; },
|
|
984
|
+
shouldSuppressResponseNotification: opts.shouldSuppressResponseNotification,
|
|
869
985
|
mateDisplayName: opts.mateDisplayName || "",
|
|
870
986
|
isMate: isMate,
|
|
871
987
|
osUsers: osUsers,
|
|
@@ -879,6 +995,7 @@ function createProjectContext(opts) {
|
|
|
879
995
|
onTurnDone: function (session, preview) {
|
|
880
996
|
if (isMate) digestDmTurn(session, preview);
|
|
881
997
|
else _sessionPair.handleTurnDone(session);
|
|
998
|
+
if (session && typeof session.onTurnDone === "function") session.onTurnDone(session, preview);
|
|
882
999
|
},
|
|
883
1000
|
scheduleMessage: function (session, text, resetsAt) {
|
|
884
1001
|
scheduleMessage(session, text, resetsAt);
|
|
@@ -902,13 +1019,22 @@ function createProjectContext(opts) {
|
|
|
902
1019
|
_sessionNotes.getSystemPrompt(session),
|
|
903
1020
|
_sessionHandoff.getSystemPrompt(session),
|
|
904
1021
|
_sessionDocument.getSystemPrompt(session),
|
|
1022
|
+
_capsuleCatalog.getSystemPrompt(session),
|
|
905
1023
|
]);
|
|
906
1024
|
},
|
|
1025
|
+
getRuntimeEnv: getRuntimeEnvForSession,
|
|
1026
|
+
onUserInputRequest: function (session, request, respond) {
|
|
1027
|
+
return _askUser.createHandler(session)(request, respond);
|
|
1028
|
+
},
|
|
907
1029
|
getSessionToolDefs: function (session) {
|
|
908
1030
|
return _sessionPair.getToolDefs(session)
|
|
909
1031
|
.concat(_sessionNotes.getToolDefs(session))
|
|
910
1032
|
.concat(_sessionHandoff.getToolDefs(session))
|
|
911
|
-
.concat(_sessionDocument.getToolDefs(session))
|
|
1033
|
+
.concat(_sessionDocument.getToolDefs(session))
|
|
1034
|
+
.concat(_debateProposal.getToolDefs(session))
|
|
1035
|
+
.concat(_mateCreationProposal.getToolDefs(session))
|
|
1036
|
+
.concat(_workspaceQuery.getDynamicToolDefs(session))
|
|
1037
|
+
.concat(_workspaceQuery.getHistoryDynamicToolDefs(session));
|
|
912
1038
|
},
|
|
913
1039
|
});
|
|
914
1040
|
|
|
@@ -1042,6 +1168,11 @@ function createProjectContext(opts) {
|
|
|
1042
1168
|
}
|
|
1043
1169
|
|
|
1044
1170
|
function handleMessage(ws, msg) {
|
|
1171
|
+
if (ws._clayHomeDebateSlug && ws._clayHomeDebateSlug !== slug && /^debate_(hand_raise|comment|stop|conclude_response|user_floor_response)$/.test(msg.type || "") && opts.getProject) {
|
|
1172
|
+
var homeDebateCtx = opts.getProject(ws._clayHomeDebateSlug);
|
|
1173
|
+
if (homeDebateCtx) homeDebateCtx.handleMessage(ws, msg);
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1045
1176
|
// --- Cross-project routing (e.g. permission_response from notification banner) ---
|
|
1046
1177
|
if (msg.targetSlug && msg.targetSlug !== slug && opts.getProject) {
|
|
1047
1178
|
var targetCtx = opts.getProject(msg.targetSlug);
|
|
@@ -1052,9 +1183,17 @@ function createProjectContext(opts) {
|
|
|
1052
1183
|
}
|
|
1053
1184
|
|
|
1054
1185
|
// --- DM messages (delegated to server-level handler) ---
|
|
1055
|
-
if (msg.type === "
|
|
1186
|
+
if (msg.type === "home_debate_question_response" || msg.type === "home_debate_control" || msg.type === "home_mate_creation_question_response") {
|
|
1187
|
+
if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg);
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
if (msg.type === "home_clay_ask" || msg.type === "home_clay_session_resolve") {
|
|
1191
|
+
if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg, slug);
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
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
1195
|
if (typeof opts.onDmMessage === "function") {
|
|
1057
|
-
opts.onDmMessage(ws, msg);
|
|
1196
|
+
opts.onDmMessage(ws, msg, slug);
|
|
1058
1197
|
}
|
|
1059
1198
|
return;
|
|
1060
1199
|
}
|
|
@@ -1165,7 +1304,12 @@ function createProjectContext(opts) {
|
|
|
1165
1304
|
sendTo: sendTo,
|
|
1166
1305
|
matesModule: matesModule,
|
|
1167
1306
|
sessionSearch: sessionSearch,
|
|
1168
|
-
|
|
1307
|
+
getWorkspaceMemorySessions: function () { return _workspaceQuery.getMemorySessions(true); },
|
|
1308
|
+
getOwnedCurrentSessions: function () {
|
|
1309
|
+
return _workspaceQuery.getMemorySessions(false).filter(function (session) {
|
|
1310
|
+
return session._projectSlug === slug;
|
|
1311
|
+
});
|
|
1312
|
+
},
|
|
1169
1313
|
projectOwnerId: projectOwnerId,
|
|
1170
1314
|
handleMessage: handleMessage,
|
|
1171
1315
|
});
|
|
@@ -1246,6 +1390,8 @@ function createProjectContext(opts) {
|
|
|
1246
1390
|
getSessionForWs: getSessionForWs,
|
|
1247
1391
|
updateMemorySummary: updateMemorySummary,
|
|
1248
1392
|
initMemorySummary: initMemorySummary,
|
|
1393
|
+
registerHomeDebateClient: function (ws) { if (ws) homeDebateClients.add(ws); },
|
|
1394
|
+
unregisterHomeDebateClient: function (ws) { homeDebateClients.delete(ws); },
|
|
1249
1395
|
});
|
|
1250
1396
|
var handleDebateStart = _debate.handleDebateStart;
|
|
1251
1397
|
var handleDebateHandRaise = _debate.handleDebateHandRaise;
|
|
@@ -1294,6 +1440,11 @@ function createProjectContext(opts) {
|
|
|
1294
1440
|
browserState._extensionId = null;
|
|
1295
1441
|
if (_mcp) _mcp.handleExtensionDisconnect();
|
|
1296
1442
|
}
|
|
1443
|
+
homeDebateClients.delete(ws);
|
|
1444
|
+
if (ws._clayHomeDebateSlug && ws._clayHomeDebateSlug !== slug && opts.getProject) {
|
|
1445
|
+
var debateProject = opts.getProject(ws._clayHomeDebateSlug);
|
|
1446
|
+
if (debateProject && typeof debateProject.unregisterHomeDebateClient === "function") debateProject.unregisterHomeDebateClient(ws);
|
|
1447
|
+
}
|
|
1297
1448
|
_connection.handleDisconnection(ws);
|
|
1298
1449
|
}
|
|
1299
1450
|
|
|
@@ -1317,6 +1468,7 @@ function createProjectContext(opts) {
|
|
|
1317
1468
|
sendToSessionOthers: sendToSessionOthers,
|
|
1318
1469
|
opts: opts,
|
|
1319
1470
|
usersModule: usersModule,
|
|
1471
|
+
getProjectAccess: opts.getProjectAccess || function () { return { visibility: "public", ownerId: projectOwnerId || null }; },
|
|
1320
1472
|
userPresence: userPresence,
|
|
1321
1473
|
matesModule: matesModule,
|
|
1322
1474
|
pushModule: pushModule,
|
|
@@ -1365,6 +1517,28 @@ function createProjectContext(opts) {
|
|
|
1365
1517
|
serverTls: serverTls,
|
|
1366
1518
|
serverAuthToken: serverAuthToken,
|
|
1367
1519
|
});
|
|
1520
|
+
var _delegatedSession = attachDelegatedSession({
|
|
1521
|
+
sm: sm,
|
|
1522
|
+
getSdk: function () { return sdk; },
|
|
1523
|
+
getLinuxUserForSession: getLinuxUserForSession,
|
|
1524
|
+
resolveModel: function (principal) {
|
|
1525
|
+
var user = principal && principal.userId ? usersModule.findUserById(principal.userId) : null;
|
|
1526
|
+
return _models.resolveConfiguredModel({ _clayUser: user || null }, "standard");
|
|
1527
|
+
},
|
|
1528
|
+
});
|
|
1529
|
+
var _delegatedFollowUp = attachDelegatedFollowUp({
|
|
1530
|
+
sm: sm,
|
|
1531
|
+
getSdk: function () { return sdk; },
|
|
1532
|
+
getLinuxUserForSession: getLinuxUserForSession,
|
|
1533
|
+
onProcessingChanged: onProcessingChanged,
|
|
1534
|
+
isMultiUser: function () { return usersModule.isMultiUser(); },
|
|
1535
|
+
sessionRef: function (session) { return workspaceSessionRef(slug, session); },
|
|
1536
|
+
isPairedSession: function (session) { return !!_splitGroups.store.groupForMember(session.localId); },
|
|
1537
|
+
canResumeVendor: function (vendor) {
|
|
1538
|
+
var capabilities = sm.capabilitiesByVendor && sm.capabilitiesByVendor[vendor];
|
|
1539
|
+
return !!(capabilities && capabilities.sessionResume === true);
|
|
1540
|
+
},
|
|
1541
|
+
});
|
|
1368
1542
|
|
|
1369
1543
|
// --- User message handler (delegated to project-user-message.js) ---
|
|
1370
1544
|
var _userMessage = attachUserMessage({
|
|
@@ -1436,6 +1610,7 @@ function createProjectContext(opts) {
|
|
|
1436
1610
|
usersModule: usersModule,
|
|
1437
1611
|
fsAsUser: fsAsUser,
|
|
1438
1612
|
validateEnvString: validateEnvString,
|
|
1613
|
+
onEnvironmentChanged: function () { return sdk.refreshEnvironmentRuntime(); },
|
|
1439
1614
|
opts: opts,
|
|
1440
1615
|
IGNORED_DIRS: IGNORED_DIRS,
|
|
1441
1616
|
BINARY_EXTS: BINARY_EXTS,
|
|
@@ -1531,6 +1706,14 @@ function createProjectContext(opts) {
|
|
|
1531
1706
|
inputSchema: normalizeToolSchema(documentTools[dti].inputSchema),
|
|
1532
1707
|
});
|
|
1533
1708
|
}
|
|
1709
|
+
var debateTools = _debateProposal.getBridgeTools(boundSession, normalizeToolSchema);
|
|
1710
|
+
for (var dbti = 0; dbti < debateTools.length; dbti++) tools.push(debateTools[dbti]);
|
|
1711
|
+
var mateCreationTools = _mateCreationProposal.getBridgeTools(boundSession, normalizeToolSchema);
|
|
1712
|
+
for (var mcti = 0; mcti < mateCreationTools.length; mcti++) tools.push(mateCreationTools[mcti]);
|
|
1713
|
+
var workspaceTools = _workspaceQuery.getBridgeTools(boundSession, normalizeToolSchema);
|
|
1714
|
+
for (var wqti = 0; wqti < workspaceTools.length; wqti++) tools.push(workspaceTools[wqti]);
|
|
1715
|
+
var historyTools = _workspaceQuery.getHistoryBridgeTools(boundSession, normalizeToolSchema);
|
|
1716
|
+
for (var cht = 0; cht < historyTools.length; cht++) tools.push(historyTools[cht]);
|
|
1534
1717
|
}
|
|
1535
1718
|
|
|
1536
1719
|
if (sessionOnly) return Promise.resolve(tools);
|
|
@@ -1543,6 +1726,10 @@ function createProjectContext(opts) {
|
|
|
1543
1726
|
var inAppNames = Object.keys(localMcp);
|
|
1544
1727
|
for (var i = 0; i < inAppNames.length; i++) {
|
|
1545
1728
|
if (inAppNames[i] === "clay-sessions" || inAppNames[i] === "clay-notes" || inAppNames[i] === "clay-handoff" || inAppNames[i] === "clay-documents") continue;
|
|
1729
|
+
// Debate tools were added above only when this request had an
|
|
1730
|
+
// exact session. Never duplicate them or advertise the static,
|
|
1731
|
+
// intentionally unbound proposal server.
|
|
1732
|
+
if (inAppNames[i] === "clay-debate" || inAppNames[i] === "clay-mate-creation" || inAppNames[i] === "clay-workspace" || inAppNames[i] === "clay-history") continue;
|
|
1546
1733
|
extractServerTools(inAppNames[i], localMcp[inAppNames[i]]);
|
|
1547
1734
|
}
|
|
1548
1735
|
}
|
|
@@ -1593,7 +1780,19 @@ function createProjectContext(opts) {
|
|
|
1593
1780
|
}
|
|
1594
1781
|
}
|
|
1595
1782
|
}
|
|
1596
|
-
if (
|
|
1783
|
+
if (boundSession && serverName === "clay-debate") {
|
|
1784
|
+
return _debateProposal.callBridgeTool(boundSession, toolName, args);
|
|
1785
|
+
}
|
|
1786
|
+
if (boundSession && serverName === "clay-mate-creation") {
|
|
1787
|
+
return _mateCreationProposal.callBridgeTool(boundSession, toolName, args);
|
|
1788
|
+
}
|
|
1789
|
+
if (boundSession && serverName === "clay-workspace") {
|
|
1790
|
+
return _workspaceQuery.callBridgeTool(boundSession, toolName, args);
|
|
1791
|
+
}
|
|
1792
|
+
if (boundSession && serverName === "clay-history") {
|
|
1793
|
+
return _workspaceQuery.callHistoryBridgeTool(boundSession, toolName, args);
|
|
1794
|
+
}
|
|
1795
|
+
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
1796
|
return Promise.reject(new Error("Session-bound tool requires a valid Clay session: " + serverName + "/" + toolName));
|
|
1598
1797
|
}
|
|
1599
1798
|
if (sessionOnly) return Promise.reject(new Error("Session tool not found: " + serverName + "/" + toolName));
|
|
@@ -1807,7 +2006,7 @@ function createProjectContext(opts) {
|
|
|
1807
2006
|
};
|
|
1808
2007
|
if (isMate) {
|
|
1809
2008
|
status.isMate = true;
|
|
1810
|
-
status.mateId =
|
|
2009
|
+
status.mateId = mateId;
|
|
1811
2010
|
}
|
|
1812
2011
|
if (worktreeMeta) {
|
|
1813
2012
|
status.isWorktree = true;
|
|
@@ -1908,6 +2107,19 @@ function createProjectContext(opts) {
|
|
|
1908
2107
|
getMcpBridgeHandler: getMcpBridgeHandler,
|
|
1909
2108
|
getStatus: getStatus,
|
|
1910
2109
|
getSessionManager: function () { return sm; },
|
|
2110
|
+
createDelegatedSession: _delegatedSession.createDelegatedSession,
|
|
2111
|
+
inspectDelegatedFollowUp: _delegatedFollowUp.inspectDelegatedFollowUp,
|
|
2112
|
+
dispatchDelegatedFollowUp: _delegatedFollowUp.dispatchDelegatedFollowUp,
|
|
2113
|
+
unregisterHomeDebateClient: function (ws) { homeDebateClients.delete(ws); },
|
|
2114
|
+
handleHomeDebateProposalResponse: function (ws, msg, session) { return _debateProposal.handleHomeMessage(ws, msg, session); },
|
|
2115
|
+
handleHomeMateCreationProposalResponse: function (ws, msg, session) { return _mateCreationProposal.handleHomeMessage(ws, msg, session); },
|
|
2116
|
+
handleHomeAskUserResponse: function (msg, session) { return _sessions.respondToAskUser(session, msg); },
|
|
2117
|
+
handleHomeDebateControl: function (ws, msg, session) { return _debate.handleHomeControl(ws, msg, session); },
|
|
2118
|
+
getVendorModelCatalog: _models.getVendorCatalog,
|
|
2119
|
+
getVendorModelAvailability: _models.getVendorAvailability,
|
|
2120
|
+
getMemoryState: _memory.readMemoryState,
|
|
2121
|
+
listKnowledgeFiles: _knowledge.listKnowledgeFiles,
|
|
2122
|
+
refreshCapsuleCatalog: _capsuleCatalog.refreshSessions,
|
|
1911
2123
|
getNotificationsModule: function () { return _notifications; },
|
|
1912
2124
|
getSchedules: _loop.getSchedules,
|
|
1913
2125
|
importSchedule: _loop.importSchedule,
|
|
@@ -1916,6 +2128,21 @@ function createProjectContext(opts) {
|
|
|
1916
2128
|
setIcon: setIcon,
|
|
1917
2129
|
setProjectOwner: function (ownerId) { projectOwnerId = ownerId; },
|
|
1918
2130
|
getProjectOwner: function () { return projectOwnerId; },
|
|
2131
|
+
getToolLlmConfig: function (ws, alias) {
|
|
2132
|
+
return _models.resolveConfiguredModel(ws, alias);
|
|
2133
|
+
},
|
|
2134
|
+
completeToolLlm: async function (ws, args) {
|
|
2135
|
+
var owner = projectOwnerId ? usersModule.findUserById(projectOwnerId) : null;
|
|
2136
|
+
var selection = await _models.resolveConfiguredModel(ws, args.model);
|
|
2137
|
+
return toolLlm.complete({
|
|
2138
|
+
adapters: adapters,
|
|
2139
|
+
cwd: cwd,
|
|
2140
|
+
linuxUser: owner && owner.linuxUser ? owner.linuxUser : null,
|
|
2141
|
+
args: args,
|
|
2142
|
+
selection: selection,
|
|
2143
|
+
timeoutMs: 60000,
|
|
2144
|
+
});
|
|
2145
|
+
},
|
|
1919
2146
|
refreshUserProfile: function (userId) {
|
|
1920
2147
|
var user = usersModule.findUserById(userId);
|
|
1921
2148
|
if (!user) return;
|
|
@@ -1934,4 +2161,4 @@ function createProjectContext(opts) {
|
|
|
1934
2161
|
};
|
|
1935
2162
|
}
|
|
1936
2163
|
|
|
1937
|
-
module.exports = { createProjectContext: createProjectContext, safePath: safePath, validateEnvString: validateEnvString };
|
|
2164
|
+
module.exports = { createProjectContext: createProjectContext, createMateToolControlMcp: createMateToolControlMcp, safePath: safePath, validateEnvString: validateEnvString };
|