clay-server 2.32.1-beta.1 → 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.
@@ -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
- return sdkTitles[item.cliSessionId] !== item.title;
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++;
@@ -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 path = require("path");
88
- var codexBin = path.join(__dirname, "../../node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/codex/codex");
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 codexBin = path.join(__dirname, "../../node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/codex/codex");
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.32.1-beta.1",
3
+ "version": "2.32.1-beta.2",
4
4
  "description": "Self-hosted Claude Code in your browser. Multi-session, multi-user, push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",