clay-server 2.32.0 → 2.32.1-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/daemon.js +18 -0
- package/lib/project-email.js +16 -0
- package/lib/project.js +38 -8
- package/lib/public/app.js +11 -0
- package/lib/public/css/command-palette.css +186 -0
- package/lib/public/css/filebrowser.css +73 -49
- package/lib/public/css/icon-strip.css +44 -2
- package/lib/public/css/input.css +10 -5
- package/lib/public/css/mates.css +18 -29
- package/lib/public/css/notifications-center.css +32 -0
- package/lib/public/css/overlays.css +5 -22
- package/lib/public/css/sidebar.css +288 -27
- package/lib/public/index.html +24 -23
- package/lib/public/modules/app-notifications.js +52 -0
- package/lib/public/modules/app-rendering.js +1 -1
- package/lib/public/modules/filebrowser.js +171 -0
- package/lib/public/modules/input.js +12 -11
- package/lib/public/modules/markdown.js +12 -0
- package/lib/public/modules/project-switcher.js +404 -0
- package/lib/public/modules/sidebar.js +14 -10
- package/lib/public/modules/terminal.js +8 -3
- package/lib/public/modules/tool-palette.js +561 -0
- package/lib/sdk-bridge.js +20 -7
- package/lib/server-settings.js +53 -0
- package/lib/sessions.js +4 -2
- package/lib/users-preferences.js +48 -0
- package/lib/users.js +4 -0
- package/lib/yoke/index.js +4 -3
- package/package.json +1 -1
package/lib/sdk-bridge.js
CHANGED
|
@@ -107,7 +107,14 @@ function createSDKBridge(opts) {
|
|
|
107
107
|
var mateDisplayName = opts.mateDisplayName || "";
|
|
108
108
|
var isMate = opts.isMate || (slug.indexOf("mate-") === 0);
|
|
109
109
|
var dangerouslySkipPermissions = opts.dangerouslySkipPermissions || false;
|
|
110
|
-
|
|
110
|
+
// mcpServers may be either a static object or a getter function. The
|
|
111
|
+
// getter form lets callers gate individual servers at call time (e.g.
|
|
112
|
+
// clay-browser is only exposed while the Chrome extension is connected).
|
|
113
|
+
var _mcpServersSrc = opts.mcpServers || null;
|
|
114
|
+
function getMcpServers() {
|
|
115
|
+
if (typeof _mcpServersSrc === "function") return _mcpServersSrc() || null;
|
|
116
|
+
return _mcpServersSrc;
|
|
117
|
+
}
|
|
111
118
|
var getRemoteMcpServers = opts.getRemoteMcpServers || null;
|
|
112
119
|
var clayPort = opts.clayPort || 2633;
|
|
113
120
|
var clayTls = opts.clayTls || false;
|
|
@@ -921,7 +928,7 @@ function createSDKBridge(opts) {
|
|
|
921
928
|
type: "auth_required",
|
|
922
929
|
text: vendorName + " is not logged in.",
|
|
923
930
|
vendor: session.vendor,
|
|
924
|
-
loginCommand: session.vendor === "codex" ? "codex
|
|
931
|
+
loginCommand: session.vendor === "codex" ? "codex login" : session.vendor + " login",
|
|
925
932
|
linuxUser: authLinuxUser,
|
|
926
933
|
canAutoLogin: canAutoLogin,
|
|
927
934
|
});
|
|
@@ -1004,7 +1011,10 @@ function createSDKBridge(opts) {
|
|
|
1004
1011
|
if (dangerouslySkipPermissions) {
|
|
1005
1012
|
claudeOpts.allowDangerouslySkipPermissions = true;
|
|
1006
1013
|
}
|
|
1007
|
-
var
|
|
1014
|
+
var globalMode = sm.currentPermissionMode || "default";
|
|
1015
|
+
var loopFloor = session.acceptEditsAfterStart ? "acceptEdits" : "default";
|
|
1016
|
+
var effectiveDefault = globalMode === "bypassPermissions" ? globalMode : (loopFloor !== "default" ? loopFloor : globalMode);
|
|
1017
|
+
var modeToApply = session._loopPermissionMode || effectiveDefault;
|
|
1008
1018
|
if (session.acceptEditsAfterStart) delete session.acceptEditsAfterStart;
|
|
1009
1019
|
if (modeToApply && modeToApply !== "default") {
|
|
1010
1020
|
claudeOpts.permissionMode = modeToApply;
|
|
@@ -1043,7 +1053,7 @@ function createSDKBridge(opts) {
|
|
|
1043
1053
|
cwd: cwd,
|
|
1044
1054
|
model: queryModel,
|
|
1045
1055
|
effort: ls.effort || sm.currentEffort || undefined,
|
|
1046
|
-
toolServers: mergeMcpServers(
|
|
1056
|
+
toolServers: mergeMcpServers(getMcpServers(), getRemoteMcpServers) || undefined,
|
|
1047
1057
|
resumeSessionId: session.cliSessionId || undefined,
|
|
1048
1058
|
abortController: linuxUser ? undefined : session.abortController,
|
|
1049
1059
|
canUseTool: function(toolName, input, toolOpts) {
|
|
@@ -1201,8 +1211,11 @@ function createSDKBridge(opts) {
|
|
|
1201
1211
|
if (tryExec("which claude")) result.push("claude");
|
|
1202
1212
|
|
|
1203
1213
|
// Codex: check bundled binary or PATH
|
|
1204
|
-
var codexBin =
|
|
1205
|
-
|
|
1214
|
+
var codexBin = null;
|
|
1215
|
+
try {
|
|
1216
|
+
codexBin = require("./yoke/codex-app-server").findCodexPath();
|
|
1217
|
+
} catch (e) {}
|
|
1218
|
+
if ((codexBin && fs.existsSync(codexBin)) || tryExec("which codex")) result.push("codex");
|
|
1206
1219
|
|
|
1207
1220
|
return result;
|
|
1208
1221
|
}
|
|
@@ -1386,7 +1399,7 @@ function createSDKBridge(opts) {
|
|
|
1386
1399
|
cwd: cwd,
|
|
1387
1400
|
systemPrompt: opts.claudeMd,
|
|
1388
1401
|
model: opts.model || undefined,
|
|
1389
|
-
toolServers: opts.includeMcpServers ? (mergeMcpServers(
|
|
1402
|
+
toolServers: opts.includeMcpServers ? (mergeMcpServers(getMcpServers(), getRemoteMcpServers) || undefined) : undefined,
|
|
1390
1403
|
abortController: abortController,
|
|
1391
1404
|
canUseTool: opts.canUseTool || function (toolName, input) {
|
|
1392
1405
|
var whitelisted = checkToolWhitelist(toolName, input);
|
package/lib/server-settings.js
CHANGED
|
@@ -450,6 +450,59 @@ function attachSettings(ctx) {
|
|
|
450
450
|
return true;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
+
// GET /api/user/tool-palettes
|
|
454
|
+
if (req.method === "GET" && fullUrl === "/api/user/tool-palettes") {
|
|
455
|
+
var muGet = getMultiUserFromReq(req);
|
|
456
|
+
var palettes = {};
|
|
457
|
+
if (!muGet) {
|
|
458
|
+
if (typeof opts.onGetToolPalettes === "function") {
|
|
459
|
+
palettes = opts.onGetToolPalettes() || {};
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
palettes = users.getToolPalettes(muGet.id) || {};
|
|
463
|
+
}
|
|
464
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
465
|
+
res.end(JSON.stringify(palettes));
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// PUT /api/user/tool-palettes
|
|
470
|
+
if (req.method === "PUT" && fullUrl === "/api/user/tool-palettes") {
|
|
471
|
+
var muPut = getMultiUserFromReq(req);
|
|
472
|
+
var bodyTp = "";
|
|
473
|
+
req.on("data", function (chunk) { bodyTp += chunk; });
|
|
474
|
+
req.on("end", function () {
|
|
475
|
+
try {
|
|
476
|
+
var dataTp = JSON.parse(bodyTp);
|
|
477
|
+
var paletteName = dataTp.palette;
|
|
478
|
+
var order = dataTp.order;
|
|
479
|
+
var hidden = dataTp.hidden;
|
|
480
|
+
var result;
|
|
481
|
+
if (!muPut) {
|
|
482
|
+
if (typeof opts.onSetToolPalette !== "function") {
|
|
483
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
484
|
+
res.end('{"error":"Not supported"}');
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
result = opts.onSetToolPalette(paletteName, order, hidden);
|
|
488
|
+
} else {
|
|
489
|
+
result = users.setToolPalette(muPut.id, paletteName, order, hidden);
|
|
490
|
+
}
|
|
491
|
+
if (result && result.error) {
|
|
492
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
493
|
+
res.end(JSON.stringify({ error: result.error }));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
497
|
+
res.end(JSON.stringify(result));
|
|
498
|
+
} catch (e) {
|
|
499
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
500
|
+
res.end('{"error":"Invalid request"}');
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
return true;
|
|
504
|
+
}
|
|
505
|
+
|
|
453
506
|
// GET /api/user/auto-continue
|
|
454
507
|
if (req.method === "GET" && fullUrl === "/api/user/auto-continue") {
|
|
455
508
|
var mu = getMultiUserFromReq(req);
|
package/lib/sessions.js
CHANGED
|
@@ -723,7 +723,9 @@ function createSessionManager(opts) {
|
|
|
723
723
|
}
|
|
724
724
|
}
|
|
725
725
|
var toMigrate = candidates.filter(function(item) {
|
|
726
|
-
|
|
726
|
+
var relayTitle = (item.title || "").trim();
|
|
727
|
+
var sdkTitle = (sdkTitles[item.cliSessionId] || "").trim();
|
|
728
|
+
return sdkTitle !== relayTitle;
|
|
727
729
|
});
|
|
728
730
|
if (toMigrate.length === 0) return;
|
|
729
731
|
var migrated = 0;
|
|
@@ -732,7 +734,7 @@ function createSessionManager(opts) {
|
|
|
732
734
|
for (var j = 0; j < toMigrate.length; j++) {
|
|
733
735
|
(function(item) {
|
|
734
736
|
chain = chain.then(function() {
|
|
735
|
-
return adapter.renameSession(item.cliSessionId, item.title, { dir: migrateCwd }).then(function() {
|
|
737
|
+
return adapter.renameSession(item.cliSessionId, item.title.trim(), { dir: migrateCwd }).then(function() {
|
|
736
738
|
migrated++;
|
|
737
739
|
}).catch(function(e) {
|
|
738
740
|
failed++;
|
package/lib/users-preferences.js
CHANGED
|
@@ -175,6 +175,52 @@ function attachPreferences(deps) {
|
|
|
175
175
|
return { error: "User not found" };
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
// --- Per-user tool palette preferences ---
|
|
179
|
+
//
|
|
180
|
+
// Each user can customize the sidebar tool grid by reordering or
|
|
181
|
+
// hiding individual tools. Stored as an object keyed by palette name
|
|
182
|
+
// ("session" or "mate"), each holding { order: [...ids], hidden: [...ids] }.
|
|
183
|
+
// Missing ids are treated as "use registry default at the end", so new
|
|
184
|
+
// tools added in future releases show up for existing users without a
|
|
185
|
+
// migration.
|
|
186
|
+
|
|
187
|
+
var VALID_PALETTES = { session: true, mate: true };
|
|
188
|
+
|
|
189
|
+
function getToolPalettes(userId) {
|
|
190
|
+
var data = loadUsers();
|
|
191
|
+
for (var i = 0; i < data.users.length; i++) {
|
|
192
|
+
if (data.users[i].id === userId) {
|
|
193
|
+
return data.users[i].toolPalettes || {};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return {};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function setToolPalette(userId, paletteName, order, hidden) {
|
|
200
|
+
if (!VALID_PALETTES[paletteName]) {
|
|
201
|
+
return { error: "Unknown palette" };
|
|
202
|
+
}
|
|
203
|
+
var safeOrder = Array.isArray(order)
|
|
204
|
+
? order.filter(function (s) { return typeof s === "string"; })
|
|
205
|
+
: [];
|
|
206
|
+
var safeHidden = Array.isArray(hidden)
|
|
207
|
+
? hidden.filter(function (s) { return typeof s === "string"; })
|
|
208
|
+
: [];
|
|
209
|
+
var data = loadUsers();
|
|
210
|
+
for (var i = 0; i < data.users.length; i++) {
|
|
211
|
+
if (data.users[i].id === userId) {
|
|
212
|
+
if (!data.users[i].toolPalettes) data.users[i].toolPalettes = {};
|
|
213
|
+
data.users[i].toolPalettes[paletteName] = {
|
|
214
|
+
order: safeOrder,
|
|
215
|
+
hidden: safeHidden,
|
|
216
|
+
};
|
|
217
|
+
saveUsers(data);
|
|
218
|
+
return { ok: true, palette: paletteName, order: safeOrder, hidden: safeHidden };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return { error: "User not found" };
|
|
222
|
+
}
|
|
223
|
+
|
|
178
224
|
// --- Mate onboarding ---
|
|
179
225
|
|
|
180
226
|
function setMateOnboarded(userId) {
|
|
@@ -203,6 +249,8 @@ function attachPreferences(deps) {
|
|
|
203
249
|
setChatLayout: setChatLayout,
|
|
204
250
|
getAutoContinue: getAutoContinue,
|
|
205
251
|
setAutoContinue: setAutoContinue,
|
|
252
|
+
getToolPalettes: getToolPalettes,
|
|
253
|
+
setToolPalette: setToolPalette,
|
|
206
254
|
setMateOnboarded: setMateOnboarded,
|
|
207
255
|
};
|
|
208
256
|
}
|
package/lib/users.js
CHANGED
|
@@ -416,6 +416,8 @@ var getChatLayout = preferences.getChatLayout;
|
|
|
416
416
|
var setChatLayout = preferences.setChatLayout;
|
|
417
417
|
var getAutoContinue = preferences.getAutoContinue;
|
|
418
418
|
var setAutoContinue = preferences.setAutoContinue;
|
|
419
|
+
var getToolPalettes = preferences.getToolPalettes;
|
|
420
|
+
var setToolPalette = preferences.setToolPalette;
|
|
419
421
|
var setMateOnboarded = preferences.setMateOnboarded;
|
|
420
422
|
|
|
421
423
|
module.exports = {
|
|
@@ -473,6 +475,8 @@ module.exports = {
|
|
|
473
475
|
setMateOnboarded: setMateOnboarded,
|
|
474
476
|
getAutoContinue: getAutoContinue,
|
|
475
477
|
setAutoContinue: setAutoContinue,
|
|
478
|
+
getToolPalettes: getToolPalettes,
|
|
479
|
+
setToolPalette: setToolPalette,
|
|
476
480
|
getDeletedBuiltinKeys: getDeletedBuiltinKeys,
|
|
477
481
|
addDeletedBuiltinKey: addDeletedBuiltinKey,
|
|
478
482
|
removeDeletedBuiltinKey: removeDeletedBuiltinKey,
|
package/lib/yoke/index.js
CHANGED
|
@@ -84,8 +84,8 @@ function checkAuth() {
|
|
|
84
84
|
|
|
85
85
|
function checkCodex() {
|
|
86
86
|
try {
|
|
87
|
-
var
|
|
88
|
-
var codexBin =
|
|
87
|
+
var findCodexPath = require("./codex-app-server").findCodexPath;
|
|
88
|
+
var codexBin = findCodexPath();
|
|
89
89
|
execSync(codexBin + " login status", { timeout: 5000, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
|
|
90
90
|
return true;
|
|
91
91
|
} catch (e) {
|
|
@@ -111,7 +111,8 @@ function checkInstalled() {
|
|
|
111
111
|
result.claude = true;
|
|
112
112
|
} catch (e) {}
|
|
113
113
|
try {
|
|
114
|
-
var
|
|
114
|
+
var findCodexPath = require("./codex-app-server").findCodexPath;
|
|
115
|
+
var codexBin = findCodexPath();
|
|
115
116
|
if (fs.existsSync(codexBin)) result.codex = true;
|
|
116
117
|
} catch (e) {}
|
|
117
118
|
return result;
|