clay-server 2.31.0 → 2.32.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/lib/browser-mcp-server.js +32 -44
  2. package/lib/codex-defaults.js +18 -0
  3. package/lib/debate-mcp-server.js +14 -31
  4. package/lib/mcp-local.js +31 -1
  5. package/lib/project-connection.js +9 -6
  6. package/lib/project-debate.js +8 -0
  7. package/lib/project-filesystem.js +47 -1
  8. package/lib/project-http.js +75 -8
  9. package/lib/project-mate-interaction.js +102 -16
  10. package/lib/project-mcp.js +4 -0
  11. package/lib/project-notifications.js +9 -0
  12. package/lib/project-sessions.js +94 -51
  13. package/lib/project-user-message.js +12 -7
  14. package/lib/project.js +234 -99
  15. package/lib/public/app.js +135 -454
  16. package/lib/public/codex-avatar.png +0 -0
  17. package/lib/public/css/debate.css +3 -2
  18. package/lib/public/css/filebrowser.css +91 -1
  19. package/lib/public/css/icon-strip.css +21 -5
  20. package/lib/public/css/input.css +338 -104
  21. package/lib/public/css/mates.css +43 -0
  22. package/lib/public/css/mention.css +48 -4
  23. package/lib/public/css/menus.css +1 -1
  24. package/lib/public/css/messages.css +2 -0
  25. package/lib/public/css/notifications-center.css +26 -0
  26. package/lib/public/css/tooltip.css +47 -0
  27. package/lib/public/index.html +78 -26
  28. package/lib/public/modules/app-connection.js +138 -37
  29. package/lib/public/modules/app-cursors.js +18 -17
  30. package/lib/public/modules/app-debate-ui.js +9 -9
  31. package/lib/public/modules/app-dm.js +175 -131
  32. package/lib/public/modules/app-favicon.js +28 -26
  33. package/lib/public/modules/app-header.js +79 -68
  34. package/lib/public/modules/app-home-hub.js +55 -47
  35. package/lib/public/modules/app-loop-ui.js +34 -18
  36. package/lib/public/modules/app-loop-wizard.js +6 -6
  37. package/lib/public/modules/app-messages.js +199 -153
  38. package/lib/public/modules/app-misc.js +23 -12
  39. package/lib/public/modules/app-notifications.js +119 -9
  40. package/lib/public/modules/app-panels.js +203 -49
  41. package/lib/public/modules/app-projects.js +161 -150
  42. package/lib/public/modules/app-rate-limit.js +5 -4
  43. package/lib/public/modules/app-rendering.js +149 -101
  44. package/lib/public/modules/app-skills-install.js +4 -4
  45. package/lib/public/modules/context-sources.js +102 -66
  46. package/lib/public/modules/dom-refs.js +21 -0
  47. package/lib/public/modules/filebrowser.js +173 -2
  48. package/lib/public/modules/input.js +122 -0
  49. package/lib/public/modules/markdown.js +5 -1
  50. package/lib/public/modules/mate-sidebar.js +38 -0
  51. package/lib/public/modules/mention.js +24 -6
  52. package/lib/public/modules/scheduler.js +1 -1
  53. package/lib/public/modules/sidebar-mates.js +79 -35
  54. package/lib/public/modules/sidebar-mobile.js +34 -30
  55. package/lib/public/modules/sidebar-projects.js +60 -57
  56. package/lib/public/modules/sidebar-sessions.js +75 -69
  57. package/lib/public/modules/sidebar.js +12 -20
  58. package/lib/public/modules/skills.js +8 -9
  59. package/lib/public/modules/sticky-notes.js +1 -2
  60. package/lib/public/modules/store.js +9 -2
  61. package/lib/public/modules/stt.js +4 -1
  62. package/lib/public/modules/terminal.js +12 -0
  63. package/lib/public/modules/tools.js +18 -13
  64. package/lib/public/modules/tooltip.js +32 -5
  65. package/lib/sdk-bridge.js +562 -1114
  66. package/lib/sdk-message-processor.js +150 -135
  67. package/lib/sdk-worker.js +4 -0
  68. package/lib/server-dm.js +1 -0
  69. package/lib/server.js +86 -1
  70. package/lib/sessions.js +81 -37
  71. package/lib/ws-schema.js +2 -0
  72. package/lib/yoke/adapters/claude-worker.js +559 -0
  73. package/lib/yoke/adapters/claude.js +1483 -0
  74. package/lib/yoke/adapters/codex.js +1121 -0
  75. package/lib/yoke/adapters/gemini.js +709 -0
  76. package/lib/yoke/codex-app-server.js +307 -0
  77. package/lib/yoke/index.js +199 -0
  78. package/lib/yoke/instructions.js +62 -0
  79. package/lib/yoke/interface.js +98 -0
  80. package/lib/yoke/mcp-bridge-server.js +294 -0
  81. package/lib/yoke/package.json +7 -0
  82. package/package.json +3 -1
package/lib/sessions.js CHANGED
@@ -3,6 +3,7 @@ var path = require("path");
3
3
  var config = require("./config");
4
4
  var utils = require("./utils");
5
5
  var users = require("./users");
6
+ var { CODEX_DEFAULTS } = require("./codex-defaults");
6
7
 
7
8
  function createSessionManager(opts) {
8
9
  var cwd = opts.cwd;
@@ -16,10 +17,16 @@ function createSessionManager(opts) {
16
17
  var nextLocalId = 1;
17
18
  var sessions = new Map(); // localId -> session object
18
19
  var activeSessionId = null; // currently active local ID
19
- var slashCommands = null; // shared across sessions
20
+ var slashCommands = null; // shared across sessions (deprecated, use slashCommandsByVendor)
21
+ var slashCommandsByVendor = {}; // vendor -> array of slash commands
20
22
  var skillNames = null; // Claude-only skills to filter from slash menu
21
23
  var singleUserUnread = {}; // sessionLocalId -> unread count (single-user mode)
22
24
  var permissionRequestIndex = {}; // requestId -> sessionLocalId (O(1) lookup)
25
+ var capabilitiesByVendor = null; // set by sdk-bridge after adapter init
26
+ var defaultVendor = null; // set by sdk-bridge
27
+ var codexApproval = CODEX_DEFAULTS.approval;
28
+ var codexSandbox = CODEX_DEFAULTS.sandbox;
29
+ var codexWebSearch = CODEX_DEFAULTS.webSearch;
23
30
 
24
31
  // --- Session persistence (centralized in ~/.clay/sessions/{encoded-cwd}/) ---
25
32
  var sessionsBase = path.join(config.CONFIG_DIR, "sessions");
@@ -86,6 +93,7 @@ function createSessionManager(opts) {
86
93
  createdAt: session.createdAt,
87
94
  };
88
95
  if (session.ownerId) metaObj.ownerId = session.ownerId;
96
+ if (session.vendor) metaObj.vendor = session.vendor;
89
97
  if (session.sessionVisibility) metaObj.sessionVisibility = session.sessionVisibility;
90
98
  if (session.lastRewindUuid) metaObj.lastRewindUuid = session.lastRewindUuid;
91
99
  if (session.loop) metaObj.loop = session.loop;
@@ -186,6 +194,7 @@ function createSessionManager(opts) {
186
194
  messageUUIDs: messageUUIDs,
187
195
  lastRewindUuid: m.lastRewindUuid || null,
188
196
  };
197
+ if (m.vendor) session.vendor = m.vendor;
189
198
  if (m.loop) session.loop = m.loop;
190
199
  if (m.debateState) session.debateState = m.debateState;
191
200
  if (m.debateSetupMode) session.debateSetupMode = true;
@@ -230,6 +239,7 @@ function createSessionManager(opts) {
230
239
  ownerId: s.ownerId || null,
231
240
  sessionVisibility: s.sessionVisibility || "shared",
232
241
  unread: unreadMap[s.localId] || 0,
242
+ vendor: s.vendor || null,
233
243
  };
234
244
  }
235
245
 
@@ -281,12 +291,15 @@ function createSessionManager(opts) {
281
291
  allowedTools: {},
282
292
  isProcessing: false,
283
293
  title: "",
294
+ titleAutoGenerated: false,
295
+ turnCount: 0,
284
296
  createdAt: Date.now(),
285
297
  lastActivity: Date.now(),
286
298
  history: [],
287
299
  messageUUIDs: [],
288
300
  ownerId: (sessionOpts && sessionOpts.ownerId) || null,
289
301
  sessionVisibility: (sessionOpts && sessionOpts.sessionVisibility) || "shared",
302
+ vendor: (sessionOpts && sessionOpts.vendor) || null,
290
303
  };
291
304
  sessions.set(localId, session);
292
305
  switchSession(localId, targetWs);
@@ -308,12 +321,15 @@ function createSessionManager(opts) {
308
321
  allowedTools: {},
309
322
  isProcessing: false,
310
323
  title: "",
324
+ titleAutoGenerated: false,
325
+ turnCount: 0,
311
326
  createdAt: Date.now(),
312
327
  lastActivity: Date.now(),
313
328
  history: [],
314
329
  messageUUIDs: [],
315
330
  ownerId: (sessionOpts && sessionOpts.ownerId) || null,
316
331
  sessionVisibility: (sessionOpts && sessionOpts.sessionVisibility) || "shared",
332
+ vendor: (sessionOpts && sessionOpts.vendor) || null,
317
333
  };
318
334
  sessions.set(localId, session);
319
335
  return session;
@@ -343,6 +359,8 @@ function createSessionManager(opts) {
343
359
 
344
360
  for (var i = fromIndex; i < total; i++) {
345
361
  var _item = session.history[i];
362
+ // Skip internal bookkeeping entries not meant for the UI
363
+ if (_item && _item.type === "digest_checkpoint") continue;
346
364
  if (_item && (_item.type === "mention_user" || _item.type === "mention_response")) {
347
365
  console.log("[DEBUG replayHistory] sending mention at index=" + i + " from=" + fromIndex + " total=" + total + " type=" + _item.type + " mate=" + (_item.mateName || ""));
348
366
  }
@@ -389,7 +407,13 @@ function createSessionManager(opts) {
389
407
  // In multi-user mode with a specific client, only send to that client
390
408
  var _send = (targetWs && sendTo) ? function (obj) { sendTo(targetWs, obj); } : send;
391
409
 
392
- _send({ type: "session_switched", id: localId, cliSessionId: session.cliSessionId || null, loop: session.loop || null });
410
+ var _capsByVendor = capabilitiesByVendor || {};
411
+ var _sessionVendor = session.vendor || defaultVendor || "claude";
412
+ var _vendorCaps = _capsByVendor[_sessionVendor] || {};
413
+ _send({ type: "session_switched", id: localId, cliSessionId: session.cliSessionId || null, loop: session.loop || null, vendor: session.vendor || null, hasHistory: (session.history && session.history.length > 0), capabilities: _vendorCaps });
414
+ // Send vendor-specific slash commands
415
+ var _vendorCmds = slashCommandsByVendor[_sessionVendor] || slashCommands || [];
416
+ _send({ type: "slash_commands", commands: _vendorCmds, vendor: _sessionVendor });
393
417
  broadcastSessionList();
394
418
  replayHistory(session, undefined, targetWs, transform);
395
419
 
@@ -410,6 +434,11 @@ function createSessionManager(opts) {
410
434
  decisionReason: p.decisionReason,
411
435
  });
412
436
  }
437
+
438
+ // Re-send active mention indicator so returning clients restore the mate avatar state
439
+ if (session._mentionInProgress && session._mentionActiveMateId) {
440
+ _send({ type: "mention_processing", mateId: session._mentionActiveMateId, active: true });
441
+ }
413
442
  }
414
443
 
415
444
  function cleanupMentionSessions(session) {
@@ -677,7 +706,7 @@ function createSessionManager(opts) {
677
706
  }
678
707
 
679
708
  var _migrationFailedIds = {};
680
- function migrateSessionTitles(getSDK, migrateCwd) {
709
+ function migrateSessionTitles(adapter, migrateCwd) {
681
710
  var candidates = [];
682
711
  sessions.forEach(function(s) {
683
712
  if (s.cliSessionId && s.title && s.title !== "New Session" && s.title !== "Resumed session"
@@ -686,43 +715,41 @@ function createSessionManager(opts) {
686
715
  }
687
716
  });
688
717
  if (candidates.length === 0) return;
689
- getSDK().then(function(sdkMod) {
690
- return sdkMod.listSessions({ dir: migrateCwd }).then(function(sdkSessions) {
691
- var sdkTitles = {};
692
- for (var i = 0; i < sdkSessions.length; i++) {
693
- if (sdkSessions[i].customTitle) {
694
- sdkTitles[sdkSessions[i].sessionId] = sdkSessions[i].customTitle;
695
- }
718
+ adapter.listSessions({ dir: migrateCwd }).then(function(sdkSessions) {
719
+ var sdkTitles = {};
720
+ for (var i = 0; i < sdkSessions.length; i++) {
721
+ if (sdkSessions[i].customTitle) {
722
+ sdkTitles[sdkSessions[i].sessionId] = sdkSessions[i].customTitle;
696
723
  }
697
- var toMigrate = candidates.filter(function(item) {
698
- return sdkTitles[item.cliSessionId] !== item.title;
699
- });
700
- if (toMigrate.length === 0) return;
701
- var migrated = 0;
702
- var failed = 0;
703
- var chain = Promise.resolve();
704
- for (var j = 0; j < toMigrate.length; j++) {
705
- (function(item) {
706
- chain = chain.then(function() {
707
- return sdkMod.renameSession(item.cliSessionId, item.title, { dir: migrateCwd }).then(function() {
708
- migrated++;
709
- }).catch(function(e) {
710
- failed++;
711
- _migrationFailedIds[item.cliSessionId] = true;
712
- });
724
+ }
725
+ var toMigrate = candidates.filter(function(item) {
726
+ return sdkTitles[item.cliSessionId] !== item.title;
727
+ });
728
+ if (toMigrate.length === 0) return;
729
+ var migrated = 0;
730
+ var failed = 0;
731
+ var chain = Promise.resolve();
732
+ for (var j = 0; j < toMigrate.length; j++) {
733
+ (function(item) {
734
+ chain = chain.then(function() {
735
+ return adapter.renameSession(item.cliSessionId, item.title, { dir: migrateCwd }).then(function() {
736
+ migrated++;
737
+ }).catch(function(e) {
738
+ failed++;
739
+ _migrationFailedIds[item.cliSessionId] = true;
713
740
  });
714
- })(toMigrate[j]);
741
+ });
742
+ })(toMigrate[j]);
743
+ }
744
+ chain.then(function() {
745
+ if (migrated > 0) {
746
+ console.log("[session] Migrated " + migrated + " session title(s) to SDK format");
715
747
  }
716
- chain.then(function() {
717
- if (migrated > 0) {
718
- console.log("[session] Migrated " + migrated + " session title(s) to SDK format");
719
- }
720
- if (failed > 0) {
721
- console.log("[session] Skipped " + failed + " session(s) (CLI session not found for current user)");
722
- }
723
- }).catch(function(e) {
724
- console.error("[session] Migration chain failed:", e.message || e);
725
- });
748
+ if (failed > 0) {
749
+ console.log("[session] Skipped " + failed + " session(s) (CLI session not found for current user)");
750
+ }
751
+ }).catch(function(e) {
752
+ console.error("[session] Migration chain failed:", e.message || e);
726
753
  });
727
754
  }).catch(function() {});
728
755
  }
@@ -732,8 +759,25 @@ function createSessionManager(opts) {
732
759
  get nextLocalId() { return nextLocalId; },
733
760
  get slashCommands() { return slashCommands; },
734
761
  set slashCommands(v) { slashCommands = v; },
762
+ get slashCommandsByVendor() { return slashCommandsByVendor; },
763
+ setSlashCommandsForVendor: function(vendor, cmds) {
764
+ slashCommandsByVendor[vendor] = cmds || [];
765
+ },
766
+ getSlashCommandsForVendor: function(vendor) {
767
+ return slashCommandsByVendor[vendor] || [];
768
+ },
735
769
  get skillNames() { return skillNames; },
736
770
  set skillNames(v) { skillNames = v; },
771
+ get capabilitiesByVendor() { return capabilitiesByVendor; },
772
+ set capabilitiesByVendor(v) { capabilitiesByVendor = v; },
773
+ get defaultVendor() { return defaultVendor; },
774
+ set defaultVendor(v) { defaultVendor = v; },
775
+ get codexApproval() { return codexApproval; },
776
+ set codexApproval(v) { codexApproval = v; },
777
+ get codexSandbox() { return codexSandbox; },
778
+ set codexSandbox(v) { codexSandbox = v; },
779
+ get codexWebSearch() { return codexWebSearch; },
780
+ set codexWebSearch(v) { codexWebSearch = v; },
737
781
  sessions: sessions,
738
782
  sessionsDir: sessionsDir,
739
783
  HISTORY_PAGE_SIZE: HISTORY_PAGE_SIZE,
package/lib/ws-schema.js CHANGED
@@ -256,6 +256,8 @@ var schema = {
256
256
  // -----------------------------------------------------------------------
257
257
  "fs_list": { direction: "c2s", handler: "lib/project-filesystem.js", description: "List directory contents" },
258
258
  "fs_list_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Directory listing result" },
259
+ "fs_search": { direction: "c2s", handler: "lib/project-filesystem.js", description: "Search files by name" },
260
+ "fs_search_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "File search results" },
259
261
  "fs_read": { direction: "c2s", handler: "lib/project-filesystem.js", description: "Read file contents" },
260
262
  "fs_read_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "File content result" },
261
263
  "fs_write": { direction: "c2s", handler: "lib/project-filesystem.js", description: "Write file contents" },