clay-server 4.1.0-beta.9 → 4.1.0

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 (111) hide show
  1. package/lib/context-usage.js +47 -0
  2. package/lib/issues-mcp-server.js +1 -1
  3. package/lib/issues-service.js +3 -1
  4. package/lib/loop-registry-occurrence.js +1 -0
  5. package/lib/notes.js +20 -3
  6. package/lib/os-users.js +6 -0
  7. package/lib/project-connection.js +14 -3
  8. package/lib/project-file-path.js +13 -0
  9. package/lib/project-file-watch.js +19 -8
  10. package/lib/project-filesystem.js +10 -16
  11. package/lib/project-http.js +53 -48
  12. package/lib/project-logs-mcp-server.js +8 -8
  13. package/lib/project-logs-schema.js +1 -1
  14. package/lib/project-logs-service.js +46 -13
  15. package/lib/project-logs-store.js +17 -15
  16. package/lib/project-logs.js +70 -0
  17. package/lib/project-loop.js +1 -0
  18. package/lib/project-notifications.js +1 -1
  19. package/lib/project-scheduled-result-store.js +131 -0
  20. package/lib/project-scheduled-task-execution.js +35 -2
  21. package/lib/project-session-notes.js +11 -4
  22. package/lib/project-sessions.js +7 -0
  23. package/lib/project-user-message.js +47 -0
  24. package/lib/project.js +53 -3
  25. package/lib/public/app.js +26 -9
  26. package/lib/public/css/avatar-imprints.css +1 -1
  27. package/lib/public/css/command-palette.css +20 -0
  28. package/lib/public/css/git-panel.css +13 -12
  29. package/lib/public/css/git-placard.css +4 -4
  30. package/lib/public/css/issues.css +78 -31
  31. package/lib/public/css/mobile-nav.css +7 -0
  32. package/lib/public/css/notifications-center.css +3 -3
  33. package/lib/public/css/project-logs.css +15 -0
  34. package/lib/public/css/sidebar.css +7 -0
  35. package/lib/public/css/sticky-notes.css +29 -0
  36. package/lib/public/modules/app-connection.js +9 -1
  37. package/lib/public/modules/app-favicon.js +10 -0
  38. package/lib/public/modules/app-messages.js +43 -12
  39. package/lib/public/modules/app-notifications.js +2 -0
  40. package/lib/public/modules/app-panels.js +77 -23
  41. package/lib/public/modules/app-projects.js +2 -0
  42. package/lib/public/modules/app-rate-limit.js +148 -61
  43. package/lib/public/modules/avatar-imprint.js +25 -70
  44. package/lib/public/modules/avatar.js +12 -4
  45. package/lib/public/modules/chat-render-runtime.js +20 -0
  46. package/lib/public/modules/clay-issue-links.js +23 -2
  47. package/lib/public/modules/clay-log-links.js +11 -1
  48. package/lib/public/modules/context-view-preference.js +143 -0
  49. package/lib/public/modules/default-vendor.js +116 -0
  50. package/lib/public/modules/filebrowser-tabs.js +1 -0
  51. package/lib/public/modules/filebrowser.js +45 -18
  52. package/lib/public/modules/issues-render.js +36 -10
  53. package/lib/public/modules/issues.js +95 -13
  54. package/lib/public/modules/markdown.js +3 -1
  55. package/lib/public/modules/pane-bridge.js +14 -8
  56. package/lib/public/modules/pane-issue-bridge.js +27 -0
  57. package/lib/public/modules/permission-hints.js +13 -0
  58. package/lib/public/modules/profile.js +9 -9
  59. package/lib/public/modules/project-activation.js +49 -0
  60. package/lib/public/modules/project-logs-render.js +13 -3
  61. package/lib/public/modules/project-logs.js +45 -15
  62. package/lib/public/modules/right-workbench.js +44 -0
  63. package/lib/public/modules/scheduled-result-client.js +33 -0
  64. package/lib/public/modules/scheduled-result-display.js +50 -0
  65. package/lib/public/modules/scheduled-result-notification.js +31 -0
  66. package/lib/public/modules/scheduled-task-presentation.js +15 -0
  67. package/lib/public/modules/scheduled-tasks.js +9 -21
  68. package/lib/public/modules/sidebar-mobile.js +51 -3
  69. package/lib/public/modules/sidebar-sessions.js +65 -5
  70. package/lib/public/modules/split-session-boundary.js +28 -0
  71. package/lib/public/modules/split-view.js +42 -7
  72. package/lib/public/modules/sticky-notes-browser.js +130 -18
  73. package/lib/public/modules/sticky-notes.js +2 -3
  74. package/lib/public/modules/terminal.js +4 -4
  75. package/lib/public/modules/thinking-lifecycle.js +4 -1
  76. package/lib/public/modules/tools.js +5 -1
  77. package/lib/scheduled-run-state.js +10 -2
  78. package/lib/scheduler.js +1 -0
  79. package/lib/sdk-bridge.js +97 -61
  80. package/lib/sdk-message-processor.js +44 -13
  81. package/lib/sdk-skill-discovery.js +6 -28
  82. package/lib/sdk-turn-queue.js +14 -0
  83. package/lib/server-context-view.js +53 -0
  84. package/lib/server-default-vendor.js +60 -0
  85. package/lib/server.js +23 -6
  86. package/lib/session-notes-mcp-server.js +3 -5
  87. package/lib/session-pair-factory.js +2 -2
  88. package/lib/session-title-generator.js +89 -0
  89. package/lib/session-title-policy.js +8 -2
  90. package/lib/sessions.js +26 -1
  91. package/lib/user-presence.js +6 -0
  92. package/lib/users-context-view-preferences.js +65 -0
  93. package/lib/users-default-vendor-preferences.js +80 -0
  94. package/lib/users.js +12 -0
  95. package/lib/ws-schema.js +11 -0
  96. package/lib/yoke/acp-agent-profiles.js +15 -2
  97. package/lib/yoke/adapters/acp.js +3 -2
  98. package/lib/yoke/adapters/antigravity.js +2 -2
  99. package/lib/yoke/adapters/claude-worker.js +11 -12
  100. package/lib/yoke/adapters/claude.js +75 -22
  101. package/lib/yoke/adapters/codex.js +216 -29
  102. package/lib/yoke/adapters/kiro.js +6 -5
  103. package/lib/yoke/claude-context-usage.js +57 -0
  104. package/lib/yoke/claude-message-correlation.js +31 -0
  105. package/lib/yoke/claude-model-switch.js +15 -0
  106. package/lib/yoke/index.js +5 -1
  107. package/lib/yoke/mcp-bridge-server.js +18 -5
  108. package/lib/yoke/session-skill-catalog.js +45 -0
  109. package/lib/yoke/skill-discovery.js +60 -20
  110. package/lib/yoke/vendor-registry.js +1 -1
  111. package/package.json +5 -7
@@ -6,6 +6,7 @@ var { CODEX_DEFAULTS, getCodexConfig } = require("./codex-defaults");
6
6
  var updateSnooze = require("./update-snooze");
7
7
  var yoke = require("./yoke");
8
8
  var sessionVisibility = require("./session-visibility");
9
+ var contextUsageModule = require("./context-usage");
9
10
 
10
11
  function vendorSupportsTui(vendor) {
11
12
  var info = yoke.getVendorInfo(vendor);
@@ -82,6 +83,7 @@ function formatAskUserAnswerAsMessage(input, answers) {
82
83
  * getLatestVersion, setLatestVersion
83
84
  */
84
85
  function attachSessions(ctx) {
86
+ var contextUsage = contextUsageModule.attachContextUsage(ctx);
85
87
  var cwd = ctx.cwd;
86
88
  var slug = ctx.slug;
87
89
  var isMate = ctx.isMate;
@@ -108,6 +110,7 @@ function attachSessions(ctx) {
108
110
  var getLinuxUserForSession = ctx.getLinuxUserForSession;
109
111
  var ensureProjectAccessForSession = ctx.ensureProjectAccessForSession;
110
112
  var getOsUserInfoForWs = ctx.getOsUserInfoForWs;
113
+ var hydrateSkillCatalog = ctx.hydrateSkillCatalog || function () { return []; };
111
114
  function stopSession(session, actor) {
112
115
  if (!session) return false;
113
116
  session._pendingMessageDrainPaused = true;
@@ -568,6 +571,7 @@ function attachSessions(ctx) {
568
571
  }
569
572
 
570
573
  function handleSessionsMessage(ws, msg) {
574
+ if (contextUsage.handleMessage(ws, msg)) return true;
571
575
 
572
576
  if (msg.type === "push_subscribe") {
573
577
  var _pushUserId = ws._clayUser ? ws._clayUser.id : null;
@@ -981,6 +985,8 @@ function attachSessions(ctx) {
981
985
  if (msg.id && sm.sessions.has(msg.id) && msg.title) {
982
986
  var s = sm.sessions.get(msg.id);
983
987
  s.title = String(msg.title).substring(0, 100);
988
+ s.titleProvisional = false;
989
+ s.titleAutoGenerated = false;
984
990
  s.titleManuallySet = true;
985
991
  sm.saveSessionFile(s);
986
992
  sm.notifySessionRenamed(s.localId);
@@ -1679,6 +1685,7 @@ function attachSessions(ctx) {
1679
1685
  return true;
1680
1686
  }
1681
1687
 
1688
+ if (decision === "allow_always" && pending.suppressAlwaysAllowRule) decision = "allow";
1682
1689
  if (decision === "allow" || decision === "allow_always") {
1683
1690
  if (decision === "allow_always") {
1684
1691
  if (!session.allowedTools) session.allowedTools = {};
@@ -24,6 +24,7 @@ var fs = require("fs");
24
24
  * pendingMessageQueue,
25
25
  * loadContextSources, saveContextSources,
26
26
  * digestDmTurn, gateMemory,
27
+ * getProjectAccess, canAccessProjectSlug,
27
28
  * adapter - YOKE adapter instance
28
29
  */
29
30
  function attachUserMessage(ctx) {
@@ -55,6 +56,8 @@ function attachUserMessage(ctx) {
55
56
  var getLinuxUserForSession = ctx.getLinuxUserForSession;
56
57
  var ensureProjectAccessForSession = ctx.ensureProjectAccessForSession;
57
58
  var getOsUserInfoForWs = ctx.getOsUserInfoForWs;
59
+ var getProjectAccess = ctx.getProjectAccess;
60
+ var canAccessProjectSlug = ctx.canAccessProjectSlug;
58
61
 
59
62
  var hydrateImageRefs = ctx.hydrateImageRefs;
60
63
  var saveImageFile = ctx.saveImageFile;
@@ -99,6 +102,21 @@ function attachUserMessage(ctx) {
99
102
  }
100
103
  }
101
104
 
105
+ function canHumanManageNotes(ws) {
106
+ if (!usersModule.isMultiUser()) return true;
107
+ if (!ws || !ws._clayUser || !ws._clayUser.id) return false;
108
+ var actor = usersModule.findUserById(ws._clayUser.id);
109
+ if (!actor) return false;
110
+ if (typeof canAccessProjectSlug === "function" && !canAccessProjectSlug(actor.id, slug)) return false;
111
+ var access = typeof getProjectAccess === "function" ? getProjectAccess() : null;
112
+ return !!(access && !access.error && usersModule.canAccessProject(actor.id, access));
113
+ }
114
+
115
+ function noteDeleteResult(ws, msg, ok, error) {
116
+ sendTo(ws, { type: "note_delete_result", projectSlug: slug, noteId: msg.id || null,
117
+ requestId: msg.requestId || null, ok: !!ok, error: error || null });
118
+ }
119
+
102
120
  // --------------- Main handler ---------------
103
121
 
104
122
  function handleUserMessage(ws, msg, forcedSession, internal) {
@@ -171,6 +189,31 @@ function attachUserMessage(ctx) {
171
189
  return true;
172
190
  }
173
191
 
192
+ if (msg.type === "note_delete_permanently") {
193
+ if (!msg.id || !canHumanManageNotes(ws)) {
194
+ noteDeleteResult(ws, msg, false, "You are not authorized to delete notes in this project.");
195
+ return true;
196
+ }
197
+ var current = nm.list().filter(function (item) { return item && item.id === msg.id; })[0];
198
+ if (!current) {
199
+ noteDeleteResult(ws, msg, false, "Note not found.");
200
+ return true;
201
+ }
202
+ if (!notesLifecycle.isClosed(current)) {
203
+ noteDeleteResult(ws, msg, false, "Only closed notes can be permanently deleted.");
204
+ return true;
205
+ }
206
+ var removed = nm.removeClosed(msg.id);
207
+ if (!removed) {
208
+ noteDeleteResult(ws, msg, false, "The note changed before it could be deleted.");
209
+ return true;
210
+ }
211
+ send({ type: "note_deleted", id: removed.id });
212
+ noteDeleteResult(ws, msg, true, null);
213
+ syncNotesKnowledge();
214
+ return true;
215
+ }
216
+
174
217
  if (msg.type === "note_list_request") {
175
218
  sendTo(ws, { type: "notes_list", notes: nm.list() });
176
219
  return true;
@@ -479,6 +522,10 @@ function attachUserMessage(ctx) {
479
522
  function recordSessionTitle() {
480
523
  if (!session.title) {
481
524
  session.title = (msg.text || "Image").substring(0, 50);
525
+ // This title is an optimistic first-message label, not a semantic or
526
+ // explicit title. Persist its provenance so startQuery can preserve
527
+ // eligibility for model generation after this function returns.
528
+ session.titleProvisional = true;
482
529
  sm.saveSessionFile(session);
483
530
  sm.broadcastSessionList();
484
531
  // Sync auto-title to SDK
package/lib/project.js CHANGED
@@ -46,6 +46,7 @@ var { attachVendorLogin } = require("./project-vendor-login");
46
46
  var { attachConnection } = require("./project-connection");
47
47
  var { attachProjectScheduledMessages } = require("./project-scheduled-messages");
48
48
  var { attachMcp } = require("./project-mcp");
49
+ var { createSessionSkillCatalog } = require("./yoke/session-skill-catalog");
49
50
  var { createLocalMcp } = require("./mcp-local");
50
51
  var { attachEmail: attachEmailModule } = require("./project-email");
51
52
  var { attachSessionSpawn } = require("./project-session-spawn");
@@ -256,11 +257,20 @@ function createProjectContext(opts) {
256
257
  var serverPort = opts.port || 2633;
257
258
  var serverTls = opts.tls || false;
258
259
  var serverAuthToken = opts.authToken || null;
260
+ var mcpBridgeToken = opts.mcpBridgeToken || crypto.randomBytes(32).toString("hex");
259
261
  var latestVersion = null;
260
262
  var sessionTitleMigrationScheduled = false;
261
263
 
262
264
  // --- YOKE adapters (multi-vendor, lazy init) ---
263
- var _yokeState = yoke.createAdapters({ cwd: cwd, slug: slug, osUsers: osUsers });
265
+ var _yokeState = yoke.createAdapters({
266
+ cwd: cwd,
267
+ slug: slug,
268
+ osUsers: osUsers,
269
+ clayPort: serverPort,
270
+ clayTls: serverTls,
271
+ clayAuthToken: serverAuthToken,
272
+ clayBridgeToken: mcpBridgeToken,
273
+ });
264
274
  var adapters = _yokeState.adapters;
265
275
  // A new project has no remembered vendor. Select the first installed
266
276
  // provider by the shared Claude -> Codex -> Kiro preference order.
@@ -555,6 +565,7 @@ function createProjectContext(opts) {
555
565
  // --- File/directory watcher engine (delegated to project-file-watch.js) ---
556
566
  var _fileWatch = attachFileWatch({
557
567
  requestAccess: _requestAccess, fsAsUser: fsAsUser,
568
+ osUsers: osUsers,
558
569
  cwd: cwd,
559
570
  send: send,
560
571
  sendTo: sendTo,
@@ -717,6 +728,15 @@ function createProjectContext(opts) {
717
728
  var nm = createNotesManager({ cwd: cwd, send: send, sendTo: sendTo });
718
729
  var _sessionNotes = attachSessionNotes({
719
730
  nm: nm,
731
+ canUseSession: function (session) {
732
+ if (!session || sm.sessions.get(session.localId) !== session) return false;
733
+ if (!usersModule.isMultiUser()) return true;
734
+ var owner = session.ownerId && usersModule.findUserById(session.ownerId);
735
+ if (!owner) return false;
736
+ var access = opts.getProjectAccess ? opts.getProjectAccess() : { visibility: "public", ownerId: projectOwnerId || null };
737
+ if (opts.canAccessProjectSlug && !opts.canAccessProjectSlug(owner.id, slug)) return false;
738
+ return usersModule.canAccessSession(owner.id, session, access) && (!osUsers || !!getLinuxUserForSession(session));
739
+ },
720
740
  send: send,
721
741
  isMate: isMate,
722
742
  broadcastWritten: function (message) {
@@ -1217,6 +1237,7 @@ function createProjectContext(opts) {
1217
1237
  clayPort: serverPort,
1218
1238
  clayTls: serverTls,
1219
1239
  clayAuthToken: serverAuthToken,
1240
+ clayBridgeToken: mcpBridgeToken,
1220
1241
  getWorkerPermissionRouter: function () {
1221
1242
  return isMate ? null : _sessionPair.workerPermission;
1222
1243
  },
@@ -1413,6 +1434,9 @@ function createProjectContext(opts) {
1413
1434
  canExecuteScheduledTask: function (record) {
1414
1435
  return !!(_scheduledTaskExecution && _scheduledTaskExecution.runnable(record).ok);
1415
1436
  },
1437
+ onScheduledRunTerminal: function (record, run) {
1438
+ if (_scheduledTaskExecution) _scheduledTaskExecution.recordTerminal(record, run);
1439
+ },
1416
1440
  onProcessingChanged: onProcessingChanged,
1417
1441
  hydrateImageRefs: hydrateImageRefs,
1418
1442
  });
@@ -1428,6 +1452,7 @@ function createProjectContext(opts) {
1428
1452
  getSdk: function () { return sdk; }, getLinuxUserForSession: getLinuxUserForSession,
1429
1453
  requiresLinuxUser: function () { return osUsers; },
1430
1454
  onProcessingChanged: onProcessingChanged,
1455
+ recordResult: function (result) { return _projectLogs.recordScheduledResult(result); },
1431
1456
  authorize: function (record) {
1432
1457
  return authorizeStoredOwner(record, {
1433
1458
  usersModule: usersModule, osUsers: osUsers,
@@ -1437,6 +1462,7 @@ function createProjectContext(opts) {
1437
1462
  });
1438
1463
  },
1439
1464
  });
1465
+ setTimeout(function () { _scheduledTaskExecution.syncTerminalResults(); }, 0);
1440
1466
 
1441
1467
  _scheduledTasks = attachScheduledTasks({
1442
1468
  cwd: cwd,
@@ -1583,8 +1609,8 @@ function createProjectContext(opts) {
1583
1609
  }
1584
1610
 
1585
1611
  // --- DM messages (delegated to server-level handler) ---
1586
- if (msg.type === "home_debate_question_response" || msg.type === "home_debate_control" || msg.type === "home_mate_creation_question_response" || msg.type === "default_ai_get" || msg.type === "default_ai_catalog_get" || msg.type === "default_ai_set" || msg.type === "cursor_sharing_get" || msg.type === "cursor_sharing_set") {
1587
- if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg);
1612
+ if (msg.type === "home_debate_question_response" || msg.type === "home_debate_control" || msg.type === "home_mate_creation_question_response" || msg.type === "default_ai_get" || msg.type === "default_ai_catalog_get" || msg.type === "default_ai_set" || msg.type === "default_vendor_get" || msg.type === "default_vendor_set" || msg.type === "context_view_get" || msg.type === "context_view_set" || msg.type === "cursor_sharing_get" || msg.type === "cursor_sharing_set") {
1613
+ if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg, slug);
1588
1614
  return;
1589
1615
  }
1590
1616
  if (msg.type === "issue_reference_resolve" || msg.type === "home_clay_ask" || msg.type === "home_clay_session_resolve" || msg.type === "home_clay_log_resolve") {
@@ -1863,6 +1889,12 @@ function createProjectContext(opts) {
1863
1889
  }
1864
1890
 
1865
1891
  // --- Sessions/config/project handler (delegated to project-sessions.js) ---
1892
+ var _sessionSkillCatalog = createSessionSkillCatalog({
1893
+ cwd: cwd,
1894
+ osUsers: osUsers,
1895
+ getLinuxUser: getLinuxUserForSession,
1896
+ });
1897
+ sm.setSessionHydrator(_sessionSkillCatalog.hydrate);
1866
1898
  var _sessions = attachSessions({
1867
1899
  cwd: cwd,
1868
1900
  slug: slug,
@@ -1902,6 +1934,7 @@ function createProjectContext(opts) {
1902
1934
  getLinuxUserForSession: getLinuxUserForSession,
1903
1935
  ensureProjectAccessForSession: ensureProjectAccessForSession,
1904
1936
  getOsUserInfoForWs: getOsUserInfoForWs,
1937
+ hydrateSkillCatalog: _sessionSkillCatalog.hydrate,
1905
1938
  hydrateImageRefs: hydrateImageRefs,
1906
1939
  onProcessingChanged: onProcessingChanged,
1907
1940
  broadcastPresence: broadcastPresence,
@@ -1931,6 +1964,7 @@ function createProjectContext(opts) {
1931
1964
  saveContextSources: saveContextSources,
1932
1965
  _email: _email,
1933
1966
  _notifications: _notifications,
1967
+ _projectLogs: _projectLogs,
1934
1968
  });
1935
1969
 
1936
1970
  var _models = attachModels({
@@ -2030,6 +2064,8 @@ function createProjectContext(opts) {
2030
2064
  getSessionForWs: getSessionForWs,
2031
2065
  getLinuxUserForSession: getLinuxUserForSession,
2032
2066
  ensureProjectAccessForSession: ensureProjectAccessForSession,
2067
+ getProjectAccess: function () { return opts.getProjectAccess ? opts.getProjectAccess() : { visibility: "public", ownerId: projectOwnerId || null }; },
2068
+ canAccessProjectSlug: opts.canAccessProjectSlug || function () { return !usersModule.isMultiUser(); },
2033
2069
  getOsUserInfoForWs: getOsUserInfoForWs,
2034
2070
  hydrateImageRefs: hydrateImageRefs,
2035
2071
  saveImageFile: saveImageFile,
@@ -2112,6 +2148,12 @@ function createProjectContext(opts) {
2112
2148
  function getMcpBridgeHandler(sessionId, sessionOnly, queryGeneration) {
2113
2149
  var boundSession = Number.isInteger(sessionId) ? sm.sessions.get(sessionId) : null;
2114
2150
  var queryToolBridge = createSessionQueryToolBridge({ session: boundSession, sdk: sdk });
2151
+ function sessionQueryValid() {
2152
+ return !!boundSession
2153
+ && Number.isInteger(queryGeneration)
2154
+ && sm.sessions.get(boundSession.localId) === boundSession
2155
+ && Number(boundSession._sdkQueryGeneration || 0) === queryGeneration;
2156
+ }
2115
2157
  // Build set of local MCP server names to exclude (Codex handles these natively)
2116
2158
  var localMcpNames = {};
2117
2159
  try {
@@ -2126,6 +2168,7 @@ function createProjectContext(opts) {
2126
2168
  return {
2127
2169
  listTools: function () {
2128
2170
  var tools = [];
2171
+ if (sessionOnly && !sessionQueryValid()) return Promise.resolve(tools);
2129
2172
  var toJSONSchema;
2130
2173
  var zod;
2131
2174
  try { zod = require("zod"); toJSONSchema = zod.toJSONSchema; } catch (e) { /* fallback */ }
@@ -2251,6 +2294,9 @@ function createProjectContext(opts) {
2251
2294
  return Promise.resolve(tools);
2252
2295
  },
2253
2296
  callTool: function (serverName, toolName, args) {
2297
+ if (sessionOnly && !sessionQueryValid()) {
2298
+ return Promise.reject(new Error("Session tool unavailable or older query: " + serverName + "/" + toolName));
2299
+ }
2254
2300
  var queryCall = queryToolBridge.callTool(queryGeneration, serverName, toolName, args);
2255
2301
  if (queryCall) return queryCall;
2256
2302
  if (boundSession && serverName === "clay-sessions") {
@@ -2409,6 +2455,7 @@ function createProjectContext(opts) {
2409
2455
  getLatestVersion: function () { return latestVersion; },
2410
2456
  getTitle: function () { return title; },
2411
2457
  getProject: function () { return project; },
2458
+ hydrateSkillCatalog: _sessionSkillCatalog.hydrate,
2412
2459
  // Exposed so the first websocket connection can lazily warm up the
2413
2460
  // adapters for this project (see project-connection handleConnection).
2414
2461
  warmup: function (linuxUser) {
@@ -2633,6 +2680,9 @@ function createProjectContext(opts) {
2633
2680
  handleDisconnection: handleDisconnection,
2634
2681
  handleHTTP: handleHTTP,
2635
2682
  getMcpBridgeHandler: getMcpBridgeHandler,
2683
+ isMcpBridgeAuthenticated: function (req) {
2684
+ return !!(req && req.headers && req.headers["x-clay-bridge-token"] && req.headers["x-clay-bridge-token"] === mcpBridgeToken);
2685
+ },
2636
2686
  getStatus: getStatus,
2637
2687
  getSessionManager: function () { return sm; },
2638
2688
  createDelegatedSession: _delegatedSession.createDelegatedSession,
package/lib/public/app.js CHANGED
@@ -28,7 +28,7 @@ import { initRewind, setRewindMode, showRewindModal, clearPendingRewindUuid, add
28
28
  import { initNotifications, showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundEnabled } from './modules/notifications.js';
29
29
  import { initInput, clearPendingImages, handleInputSync, autoResize, builtinCommands, sendMessage, hasSendableContent, setScheduleBtnDisabled, setScheduleDelayMs, clearScheduleDelay } from './modules/input.js';
30
30
  import { initQrCode, triggerShare } from './modules/qrcode.js';
31
- import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
31
+ import { initFileBrowser, loadRootDirectory, reopenFileViewer, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
32
32
  import { initGitPanel } from './modules/git-panel.js';
33
33
  import { initWorkerPaneLock } from './modules/worker-pane-lock.js';
34
34
  import { initAutonomousRun } from './modules/autonomous-run.js';
@@ -36,7 +36,7 @@ import { initLoopInterview } from './modules/loop-interview.js';
36
36
  import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
37
37
  import { initContextSources, updateTerminalList, updateBrowserTabList, handleContextSourcesState, getActiveSources, hasActiveSources } from './modules/context-sources.js';
38
38
  import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, hideNotes, showNotes, isNotesVisible, createNote, setBrowserRefresh, toggleNotesTemporaryVisibility } from './modules/sticky-notes.js';
39
- import { initNotesBrowser, openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen, renderNotesBrowser, registerExclusiveClosers } from './modules/sticky-notes-browser.js';
39
+ import { initNotesBrowser, openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen, renderNotesBrowser } from './modules/sticky-notes-browser.js';
40
40
  import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentTheme, getChatLayout } from './modules/theme.js';
41
41
  import { initTools, resetToolState, saveToolState, restoreToolState, renderAskUserQuestion, markAskUserAnswered, renderPermissionRequest, markPermissionResolved, markPermissionCancelled, renderElicitationRequest, markElicitationResolved, renderPlanBanner, renderPlanCard, handleTodoWrite, handleTaskCreate, handleTaskUpdate, startThinking, appendThinking, stopThinking, resetThinkingGroup, createToolItem, updateToolExecuting, updateToolResult, markAllToolsDone, addTurnMeta, resetTurnMetaCost, enableMainInput, getTools, getPlanContent, setPlanContent, isPlanFilePath, getTodoTools, updateSubagentActivity, addSubagentToolEntry, markSubagentDone, updateSubagentProgress, initSubagentStop, closeToolGroup, removeToolFromGroup } from './modules/tools.js';
42
42
  import { initServerSettings, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './modules/server-settings.js';
@@ -71,6 +71,7 @@ import { rememberHomePrimarySurface } from './modules/home-surface.js';
71
71
  import { initRateLimit, handleRateLimitEvent as _rlHandleRateLimitEvent, updateRateLimitUsage as _rlUpdateRateLimitUsage, handleFastModeState as _rlHandleFastModeState, resetRateLimitState } from './modules/app-rate-limit.js';
72
72
  import { initCursors, handleRemoteCursorMove as _curHandleRemoteCursorMove, handleRemoteCursorLeave as _curHandleRemoteCursorLeave, handleRemoteSelection as _curHandleRemoteSelection, clearRemoteCursors as _curClearRemoteCursors, initCursorToggle } from './modules/app-cursors.js';
73
73
  import { initDefaultAi } from './modules/default-ai.js';
74
+ import { requestDefaultVendor } from './modules/default-vendor.js';
74
75
  import { initFavicon, updateFavicon as _favUpdateFavicon, setSendBtnMode as _favSetSendBtnMode, blinkIO as _favBlinkIO, blinkSessionDot as _favBlinkSessionDot, updateCrossProjectBlink as _favUpdateCrossProjectBlink, startUrgentBlink as _favStartUrgentBlink, stopUrgentBlink as _favStopUrgentBlink, setActivity as _favSetActivity } from './modules/app-favicon.js';
75
76
  import { initHeader, closeSessionInfoPopover as _hdrCloseSessionInfoPopover, updateHistorySentinel as _hdrUpdateHistorySentinel, requestMoreHistory as _hdrRequestMoreHistory, prependOlderHistory as _hdrPrependOlderHistory } from './modules/app-header.js';
76
77
  import { initSessionActions } from './modules/session-actions.js';
@@ -286,6 +287,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
286
287
  currentSlug: currentSlug,
287
288
  activeProjectSlug: null,
288
289
  sessionActivatedProjectSlug: null,
290
+ sessionListProjectSlug: null,
291
+ splitGroupsProjectSlug: null,
289
292
  socketPath: null,
290
293
  pendingHomeProjectSlug: null,
291
294
  currentProjectOwnerId: null,
@@ -323,6 +326,9 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
323
326
  connected: false,
324
327
  fileReadRequest: null,
325
328
  pendingFileNavigation: null,
329
+ rightWorkbenchOwner: null,
330
+ rightWorkbenchRevision: 0,
331
+ fileViewerOpenRevision: 0,
326
332
  cursorSharingEnabled: false,
327
333
  cursorSharingHydrated: false,
328
334
  pendingOutboundMessages: [],
@@ -381,6 +387,12 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
381
387
  projectLogsCanDelete: false,
382
388
  projectLogsUnread: 0,
383
389
  projectLogsSeenRevisions: {},
390
+ scheduledResultUnread: 0,
391
+ scheduledResultAutoFocusHandled: false,
392
+ scheduledResultFocusRef: null,
393
+ scheduledResultPendingReadRef: null,
394
+ scheduledResultSeenRefs: {},
395
+ scheduledResultSessionRequestId: null,
384
396
  issuesOpen: false,
385
397
  issuesView: "list",
386
398
  issuesSelected: null,
@@ -388,6 +400,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
388
400
  issuesRequests: {},
389
401
  issuesViewRequest: null,
390
402
  issuesViewGeneration: 0,
403
+ issuesUpdateAvailable: null,
391
404
  issuesCache: {},
392
405
  issuesEpoch: 0,
393
406
  issuesSearchTimer: null,
@@ -418,6 +431,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
418
431
  defaultAiState: { loading: false, saving: false, refreshRequestId: null, saveRequestId: null, catalogRequestIds: {}, catalogs: {}, preference: null, selection: null, installedVendors: [], accountAvailable: true, accountId: null, serverEpoch: null, canonicalRevision: 0, error: "" },
419
432
  defaultAiDraft: { vendor: "", model: "", effort: "" },
420
433
  defaultAiDraftDirty: false,
434
+ defaultVendorState: { loading: false, saving: false, getRequestId: null, saveRequestId: null, preference: null, preferencePresent: false, installedVendors: [], accountId: null, projectSlug: null, serverEpoch: null, canonicalRevision: 0, error: "" },
421
435
 
422
436
  // dm
423
437
  dmTargetUser: null,
@@ -434,6 +448,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
434
448
  pendingShellCommandId: null,
435
449
  mateProjectSlug: null,
436
450
  myUserId: null,
451
+ contextViewPreferenceState: { mode: "off", canonicalMode: "off", preferencePresent: false, loading: false, saving: false, requestId: null, saveRequestId: null, pendingSaves: [], accountId: null, serverEpoch: null, rejectedEpoch: null, canonicalRevision: 0, error: "" },
452
+ contextViewOverride: null,
437
453
  isMultiUserMode: false,
438
454
  dmUnread: {},
439
455
  dmRemovedUsers: {},
@@ -469,6 +485,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
469
485
  lastVendor: "",
470
486
  // Static adapter metadata sent before any vendor is initialized.
471
487
  vendorInfo: {},
488
+ // Rate-limit data is projected only for the displayed session/vendor.
489
+ rateLimitState: {},
472
490
  // How Claude sessions open: "gui" (default) or "tui". The server sends
473
491
  // claude_open_mode_changed on connect; this seeds it beforehand so the
474
492
  // new-session menu doesn't flash the TUI-only entry.
@@ -544,7 +562,11 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
544
562
  newSessionBtn: newSessionBtn,
545
563
  headerTitleEl: headerTitleEl,
546
564
  showConfirm: showConfirm,
547
- onFilesTabOpen: function () { loadRootDirectory(); },
565
+ onFilesTabOpen: function () {
566
+ reopenFileViewer();
567
+ loadRootDirectory();
568
+ if (isSchedulerOpen()) closeScheduler();
569
+ },
548
570
  requestKnowledgeList: function () { requestKnowledgeList(); },
549
571
  switchProject: function (slug) { switchProject(slug); },
550
572
  openTerminal: function () { openTerminal(); },
@@ -1009,7 +1031,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
1009
1031
  // the project Mate DM preference therefore hides only Mate shortcuts.
1010
1032
  if (document.body) document.body.classList.add('is-multi-user');
1011
1033
  }
1012
- if (d.user && d.user.id) { store.set({ myUserId: d.user.id }); }
1034
+ if (d.user && d.user.id) { store.set({ myUserId: d.user.id }); requestDefaultVendor(); }
1013
1035
  if (d.permissions) store.set({ permissions: d.permissions });
1014
1036
  if (d.mustChangePin) showForceChangePinOverlay();
1015
1037
  // Single-user mode: clear user strip skeletons immediately (no presence message will arrive)
@@ -1188,9 +1210,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
1188
1210
  // The browser refreshes from note messages without the canvas module having
1189
1211
  // to import it, which would be a cycle.
1190
1212
  setBrowserRefresh(function () { if (isNotesBrowserOpen()) renderNotesBrowser(); });
1191
- // Opening the browser claims the single right workbench slot. Registered here
1192
- // so the browser module never imports the other tools.
1193
- registerExclusiveClosers([closeIssues, closeProjectLogs, closeScheduledTasks, closeFileViewer, closeTerminal]);
1194
1213
 
1195
1214
  // --- Sticky Notes sidebar button (create new note) ---
1196
1215
  var stickyNotesSidebarBtn = $("sticky-notes-sidebar-btn");
@@ -1229,10 +1248,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
1229
1248
  }
1230
1249
 
1231
1250
  // Close the notes browser / scheduler panel when switching to other sidebar panels
1232
- var fileBrowserBtn = $("file-browser-btn");
1233
1251
  var gitPlacardMoreBtn = $("git-placard-more");
1234
1252
  var terminalSidebarBtn = $("terminal-sidebar-btn");
1235
- if (fileBrowserBtn) fileBrowserBtn.addEventListener("click", function () { closeIssues(); closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
1236
1253
  if (gitPlacardMoreBtn) gitPlacardMoreBtn.addEventListener("click", function () { closeIssues(); closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
1237
1254
  if (terminalSidebarBtn) terminalSidebarBtn.addEventListener("click", function () { closeIssues(); closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
1238
1255
 
@@ -1,4 +1,4 @@
1
- /* Clay Imprints use one consistent, pressed-square silhouette everywhere. */
1
+ /* Local pixel avatars use one consistent, pressed-square silhouette everywhere. */
2
2
  .activity-inline-avatar,
3
3
  .ask-mate-avatar,
4
4
  .client-avatar,
@@ -513,6 +513,7 @@ body.mate-dm-active .search-clay-transcript .search-clay-message-user .bubble,
513
513
  @keyframes searchClaySpin { to { transform: rotate(360deg); } }
514
514
 
515
515
  .clayos-session-link,
516
+ .clayos-issue-link,
516
517
  .clayos-log-link {
517
518
  display: inline-flex;
518
519
  align-items: center;
@@ -531,6 +532,7 @@ body.mate-dm-active .search-clay-transcript .search-clay-message-user .bubble,
531
532
  cursor: pointer;
532
533
  }
533
534
  .clayos-session-link::before,
535
+ .clayos-issue-link::before,
534
536
  .clayos-log-link::before {
535
537
  content: "\2197";
536
538
  display: grid;
@@ -542,20 +544,28 @@ body.mate-dm-active .search-clay-transcript .search-clay-message-user .bubble,
542
544
  color: var(--accent);
543
545
  font-size: 12px;
544
546
  }
547
+ .clayos-issue-link::before,
545
548
  .clayos-log-link::before { content: "\2261"; }
546
549
  .clayos-session-link > span,
550
+ .clayos-issue-link > span,
547
551
  .clayos-log-link > span { font-weight: 620; }
548
552
  .clayos-session-link > small,
553
+ .clayos-issue-link > small,
549
554
  .clayos-log-link > small { color: var(--text-muted); font-size: 10px; }
550
555
  .clayos-session-link:hover,
556
+ .clayos-issue-link:hover,
551
557
  .clayos-log-link:hover { border-color: color-mix(in srgb, var(--accent) 52%, var(--border)); background: color-mix(in srgb, var(--accent) 11%, var(--bg-alt)); }
552
558
  .clayos-session-link:focus-visible,
559
+ .clayos-issue-link:focus-visible,
553
560
  .clayos-log-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
554
561
  .clayos-session-link.is-loading,
562
+ .clayos-issue-link.is-loading,
555
563
  .clayos-log-link.is-loading { opacity: 0.62; cursor: progress; }
556
564
  .clayos-session-link.is-loading::before,
565
+ .clayos-issue-link.is-loading::before,
557
566
  .clayos-log-link.is-loading::before { animation: searchClaySpin 1.2s linear infinite; }
558
567
  .clayos-session-link.is-error,
568
+ .clayos-issue-link.is-error,
559
569
  .clayos-log-link.is-error { border-color: color-mix(in srgb, var(--warning) 48%, var(--border)); }
560
570
 
561
571
  .search-clay-pending {
@@ -913,3 +923,13 @@ body.mate-dm-active .search-clay-transcript .search-clay-message-user .bubble,
913
923
  font-family: inherit;
914
924
  color: var(--text-muted);
915
925
  }
926
+
927
+ .clayos-issue-link { max-width: min(100%, 30em); box-sizing: border-box; }
928
+ .clayos-issue-link::before { content: "\25CE"; flex: 0 0 17px; }
929
+ .clayos-issue-link[data-status="in_progress"]::before { color: #bd923f; }
930
+ .clayos-issue-link[data-status="resolved"]::before { content: "\2713"; color: var(--brand-green); }
931
+ .clayos-issue-link[data-status="closed"]::before { content: "\00D7"; color: var(--text-dimmer); }
932
+ .clayos-issue-link > span { flex-shrink: 0; }
933
+ .clayos-issue-link > small { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
934
+ .clayos-log-link { max-width: 100%; box-sizing: border-box; }
935
+ .clayos-log-link > small { min-width: 0; overflow-wrap: anywhere; line-height: 1.35; }
@@ -25,7 +25,7 @@
25
25
  border-bottom: 1px solid var(--filebrowser-border);
26
26
  color: var(--text-secondary);
27
27
  font-size: 12px;
28
- font-weight: 700;
28
+ font-weight: 600;
29
29
  text-align: center;
30
30
  flex-shrink: 0;
31
31
  }
@@ -106,7 +106,7 @@
106
106
  }
107
107
 
108
108
  .git-repo-primary > svg { width: 15px; height: 15px; color: var(--accent); flex-shrink: 0; }
109
- .git-repo-name { color: var(--text); font-size: 12px; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
109
+ .git-repo-name { color: var(--text); font-size: 12px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
110
110
  .git-branch-name { color: var(--text-muted); font-size: 11px; font-weight: 500; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
111
111
 
112
112
  .git-badges { display: flex; gap: 4px; margin: 7px 0 0 22px; flex-wrap: wrap; }
@@ -117,7 +117,7 @@
117
117
  color: var(--text-dimmer);
118
118
  background: var(--bg);
119
119
  font-size: 9px;
120
- font-weight: 700;
120
+ font-weight: 500;
121
121
  letter-spacing: 0.02em;
122
122
  text-transform: uppercase;
123
123
  }
@@ -149,7 +149,7 @@
149
149
  background: var(--bg-alt);
150
150
  color: var(--text-muted);
151
151
  font-size: 11px;
152
- font-weight: 700;
152
+ font-weight: 500;
153
153
  display: inline-flex;
154
154
  align-items: center;
155
155
  justify-content: center;
@@ -160,7 +160,7 @@
160
160
  .git-action-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--text); }
161
161
  .git-action-btn:disabled { opacity: 0.42; cursor: default; }
162
162
  .git-action-btn svg { width: 13px; height: 13px; }
163
- .git-sync-count { color: var(--accent); font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
163
+ .git-sync-count { color: var(--accent); font-size: 10px; font-weight: 500; font-variant-numeric: tabular-nums; }
164
164
 
165
165
  .git-review-all {
166
166
  width: 100%;
@@ -180,6 +180,7 @@
180
180
  }
181
181
  .git-review-all:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg)); }
182
182
  .git-review-all > span { display: inline-flex; align-items: center; gap: 6px; }
183
+ .git-review-all strong { font-weight: 500; }
183
184
  .git-review-all svg { width: 12px; height: 12px; color: var(--accent); }
184
185
  .git-review-count { color: var(--text-dimmer); font-size: 9px; font-weight: 600; font-variant-numeric: tabular-nums; }
185
186
  .git-review-count svg { width: 9px; height: 9px; color: currentColor; }
@@ -201,12 +202,12 @@
201
202
  padding: 0 2px;
202
203
  color: var(--text-secondary);
203
204
  font-size: 10px;
204
- font-weight: 800;
205
+ font-weight: 600;
205
206
  letter-spacing: 0.055em;
206
207
  text-transform: uppercase;
207
208
  flex-shrink: 0;
208
209
  }
209
- .git-section-count { color: var(--text-dimmer); font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums; }
210
+ .git-section-count { color: var(--text-dimmer); font-size: 9px; font-weight: 500; font-variant-numeric: tabular-nums; }
210
211
  .git-section-header .git-action-btn { min-height: 22px; margin-left: auto; padding: 2px 7px; font-size: 9px; }
211
212
 
212
213
  .git-file-list {
@@ -239,7 +240,7 @@
239
240
  color: var(--text-dimmer);
240
241
  font-family: inherit;
241
242
  font-size: 9px;
242
- font-weight: 750;
243
+ font-weight: 600;
243
244
  line-height: 1;
244
245
  letter-spacing: -0.02em;
245
246
  }
@@ -247,7 +248,7 @@
247
248
  .git-file-status.conflicted { color: var(--danger, #d85b5b); }
248
249
  .git-file-main { min-width: 0; padding: 5px 2px; cursor: pointer; outline: none; }
249
250
  .git-file-main:focus-visible { border-radius: 4px; box-shadow: 0 0 0 1px var(--accent); }
250
- .git-file-name { color: var(--text); font-size: 11px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
251
+ .git-file-name { color: var(--text); font-size: 11px; font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
251
252
  .git-file-subline {
252
253
  display: flex;
253
254
  align-items: center;
@@ -257,7 +258,7 @@
257
258
  height: 14px;
258
259
  color: var(--text-dimmer);
259
260
  font-size: 9px;
260
- font-weight: 450;
261
+ font-weight: 400;
261
262
  line-height: 1.2;
262
263
  }
263
264
  .git-file-dir { min-width: 24px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -327,7 +328,7 @@
327
328
  justify-content: center;
328
329
  gap: 4px;
329
330
  font-size: 10px;
330
- font-weight: 550;
331
+ font-weight: 500;
331
332
  cursor: pointer;
332
333
  white-space: nowrap;
333
334
  }
@@ -405,7 +406,7 @@
405
406
  background: color-mix(in srgb, var(--accent) 8%, var(--bg));
406
407
  }
407
408
  .git-agent-commit-icon svg { width: 14px; height: 14px; }
408
- .git-agent-commit-copy strong { display: block; color: var(--text); font-size: 11px; line-height: 1.3; }
409
+ .git-agent-commit-copy strong { display: block; color: var(--text); font-size: 11px; font-weight: 600; line-height: 1.3; }
409
410
  .git-agent-commit-copy span:not(.git-agent-commit-icon) { display: block; color: var(--text-dimmer); font-size: 9px; line-height: 1.4; margin-top: 2px; }
410
411
  .git-agent-commit-btn { width: 100%; background: var(--accent); border-color: var(--accent); color: #fff; }
411
412
  .git-agent-commit-btn:hover:not(:disabled) { color: #fff; filter: brightness(1.05); }
@@ -45,7 +45,7 @@
45
45
  display: block;
46
46
  color: var(--text);
47
47
  font-size: 11px;
48
- font-weight: 700;
48
+ font-weight: 600;
49
49
  line-height: 1.3;
50
50
  overflow: hidden;
51
51
  text-overflow: ellipsis;
@@ -78,7 +78,7 @@
78
78
  background: var(--bg);
79
79
  color: var(--text-dimmer);
80
80
  font-size: 9px;
81
- font-weight: 700;
81
+ font-weight: 500;
82
82
  letter-spacing: 0.02em;
83
83
  text-transform: uppercase;
84
84
  white-space: nowrap;
@@ -94,7 +94,7 @@
94
94
  gap: 2px;
95
95
  color: var(--text-dimmer);
96
96
  font-size: 9px;
97
- font-weight: 600;
97
+ font-weight: 500;
98
98
  font-variant-numeric: tabular-nums;
99
99
  white-space: nowrap;
100
100
  }
@@ -133,7 +133,7 @@
133
133
  color: var(--text-dimmer);
134
134
  font-family: inherit;
135
135
  font-size: 9px;
136
- font-weight: 700;
136
+ font-weight: 500;
137
137
  letter-spacing: 0.02em;
138
138
  text-transform: uppercase;
139
139
  cursor: pointer;