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.
- 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-connection.js +4 -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-vendor-login.js +397 -0
- package/lib/project-worker-proposal.js +25 -25
- package/lib/project-workspace-query.js +144 -0
- package/lib/project.js +349 -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 +102 -37
- package/lib/public/modules/app-notifications.js +8 -119
- 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/pane-bridge.js +9 -0
- 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/split-view.js +7 -0
- 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/tui-attention.js +10 -0
- package/lib/public/modules/user-settings.js +16 -23
- package/lib/public/modules/vendor-login.js +287 -0
- 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 +286 -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 +93 -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 +40 -10
- package/lib/yoke/adapters/kiro.js +2 -1
- package/lib/yoke/claude-user-input.js +38 -0
- package/lib/yoke/codex-app-server.js +20 -2
- 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 +3 -2
- 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");
|
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
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
|
|
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;
|
|
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
|
|
775
|
+
console.error("[project] Failed to create Mate creation MCP server:", e.message);
|
|
666
776
|
}
|
|
667
777
|
}
|
|
668
778
|
|
|
669
|
-
//
|
|
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
|
|
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
|
-
}
|
|
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
|
-
|
|
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;
|
|
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
|
|
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 === "
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
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 };
|