clay-server 3.6.0-beta.1 → 3.6.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 (58) hide show
  1. package/README.md +54 -196
  2. package/bin/cli.js +7 -42
  3. package/lib/builtin-mates.js +1 -1
  4. package/lib/cli-wordmark.js +32 -0
  5. package/lib/pages.js +47 -35
  6. package/lib/public/app.js +2 -10
  7. package/lib/public/apple-touch-icon.png +0 -0
  8. package/lib/public/clay-studio-favicon-32.png +0 -0
  9. package/lib/public/clay-studio-symbol.png +0 -0
  10. package/lib/public/clay-studio-wordmark.svg +20 -0
  11. package/lib/public/css/base.css +143 -61
  12. package/lib/public/css/filebrowser.css +54 -8
  13. package/lib/public/css/icon-strip.css +33 -19
  14. package/lib/public/css/input.css +15 -5
  15. package/lib/public/css/messages.css +17 -14
  16. package/lib/public/css/mobile-nav.css +5 -5
  17. package/lib/public/css/overlays.css +58 -6
  18. package/lib/public/css/pane.css +0 -1
  19. package/lib/public/css/session-actions.css +9 -3
  20. package/lib/public/css/sidebar.css +104 -161
  21. package/lib/public/css/title-bar.css +51 -18
  22. package/lib/public/css/user-settings.css +114 -8
  23. package/lib/public/icon-192.png +0 -0
  24. package/lib/public/icon-512.png +0 -0
  25. package/lib/public/index.html +32 -76
  26. package/lib/public/manifest.json +1 -6
  27. package/lib/public/modules/app-connection.js +0 -3
  28. package/lib/public/modules/app-favicon.js +22 -29
  29. package/lib/public/modules/app-messages.js +1 -2
  30. package/lib/public/modules/app-notifications.js +3 -3
  31. package/lib/public/modules/command-palette.js +1 -1
  32. package/lib/public/modules/server-settings.js +0 -77
  33. package/lib/public/modules/sidebar-projects.js +1 -1
  34. package/lib/public/modules/sidebar-sessions.js +18 -5
  35. package/lib/public/modules/sidebar.js +2 -2
  36. package/lib/public/modules/theme.js +88 -249
  37. package/lib/public/modules/user-settings.js +2 -3
  38. package/lib/public/style.css +10 -10
  39. package/lib/public/sw.js +4 -2
  40. package/lib/themes/clay-dark.json +11 -0
  41. package/lib/themes/clay-light.json +11 -0
  42. package/package.json +1 -1
  43. package/lib/public/apple-touch-icon-dark.png +0 -0
  44. package/lib/public/clay-logo.png +0 -0
  45. package/lib/public/favicon-banded-32.png +0 -0
  46. package/lib/public/favicon-banded.png +0 -0
  47. package/lib/public/favicon-dark.svg +0 -1
  48. package/lib/public/favicon.svg +0 -1
  49. package/lib/public/icon-192-dark.png +0 -0
  50. package/lib/public/icon-512-dark.png +0 -0
  51. package/lib/public/icon-banded-76.png +0 -0
  52. package/lib/public/icon-banded-96.png +0 -0
  53. package/lib/public/icon-mono.svg +0 -1
  54. package/lib/public/modules/ascii-logo.js +0 -442
  55. package/lib/public/wordmark-banded-20.png +0 -0
  56. package/lib/public/wordmark-banded-32.png +0 -0
  57. package/lib/public/wordmark-banded-64.png +0 -0
  58. package/lib/public/wordmark-banded-80.png +0 -0
@@ -30,7 +30,7 @@ import { handleFsList, handleFsRead, handleFileChanged, handleDirChanged, handle
30
30
  import { beginMarkdownTurn, finishMarkdownTurn, markdownPathFromToolInput } from './markdown-live-edit.js';
31
31
  import { forwardPaneMarkdownPresentation } from './pane-bridge.js';
32
32
  import { isProjectSettingsOpen, handleInstructionsRead, handleInstructionsWrite, handleProjectEnv, handleProjectEnvSaved, handleProjectSharedEnv, handleProjectSharedEnvSaved, handleProjectOwnerChanged } from './project-settings.js';
33
- import { updateSettingsModels, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleInheritGroupsChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './server-settings.js';
33
+ import { updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleInheritGroupsChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './server-settings.js';
34
34
  import { handleTermList, handleTermCreated, sendTerminalCommand, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed } from './terminal.js';
35
35
  import { attachTuiView, detachTuiView, setTuiSuspendedView, tuiHandleTermOutput, tuiHandleTermResized, tuiHandleTermExited, tuiHandleTermClosed } from './session-tui-view.js';
36
36
  import { handleTuiTranscriptState } from './tui-grab.js';
@@ -467,7 +467,6 @@ export function processMessage(msg) {
467
467
  if (msg.vendor && !store.get('vendorSelectionLocked')) _miUpdate.currentVendor = msg.vendor;
468
468
  if (msg.capabilities) _miUpdate.vendorCapabilities = msg.capabilities;
469
469
  store.set(_miUpdate);
470
- updateSettingsModels(_modelVal, msg.models || []);
471
470
  break;
472
471
  }
473
472
 
@@ -138,11 +138,11 @@ function showBanner(notif, autoDismissMs) {
138
138
  : mate
139
139
  ? '<img class="notif-banner-avatar" src="' + escapeHtml(mateAvatarUrl(mate, 32)) + '" alt="' + escapeHtml(mate.displayName || mate.name || "Mate") + '">'
140
140
  : isAuthRequired
141
- ? '<img src="/icon-banded-76.png" width="32" height="32" alt="Clay" style="border-radius:8px">'
141
+ ? '<img src="/clay-studio-symbol.png" width="32" height="32" alt="Clay Studio">'
142
142
  : projectIcon
143
143
  ? '<span class="notif-banner-emoji">' + projectIcon + '</span>'
144
144
  : isEmpty
145
- ? '<img src="/icon-banded-76.png" width="32" height="32" alt="Clay" style="border-radius:8px">'
145
+ ? '<img src="/clay-studio-symbol.png" width="32" height="32" alt="Clay Studio">'
146
146
  : iconHtml("folder");
147
147
 
148
148
  // Format permission title as "Can I ..." style
@@ -828,7 +828,7 @@ export function showUpdateBanner(msg) {
828
828
  }
829
829
 
830
830
  banner.innerHTML =
831
- '<div class="notif-banner-icon"><img src="/icon-banded-76.png" width="32" height="32" alt="Clay" style="border-radius:8px"></div>' +
831
+ '<div class="notif-banner-icon"><img src="/clay-studio-symbol.png" width="32" height="32" alt="Clay Studio"></div>' +
832
832
  '<div class="notif-banner-body">' +
833
833
  '<div class="notif-banner-project">CLAY</div>' +
834
834
  '<div class="notif-banner-title">v' + escapeHtml(msg.version) + ' is available</div>' +
@@ -195,7 +195,7 @@ function updateFooter() {
195
195
  '<span><kbd>Enter</kbd> select</span>';
196
196
  var versionText = cachedVersion ? "v" + cachedVersion : "";
197
197
  footerEl.innerHTML =
198
- '<a href="https://github.com/chadbyte/clay" target="_blank" rel="noopener" class="cmd-palette-brand"><img src="favicon-banded.png" width="13" height="13" alt="">Clay ' + versionText + '</a>' +
198
+ '<a href="https://github.com/chadbyte/clay" target="_blank" rel="noopener" class="cmd-palette-brand"><img src="clay-studio-symbol.png" width="13" height="13" alt="">Clay Studio ' + versionText + '</a>' +
199
199
  '<span class="cmd-palette-footer-shortcuts">' + shortcuts + '</span>';
200
200
  }
201
201
 
@@ -4,7 +4,6 @@ import { showToast, copyToClipboard } from './utils.js';
4
4
  import { parseEnvString, looksLikeEnv } from './project-settings.js';
5
5
  import { checkAdminAccess, loadAdminSection } from './admin.js';
6
6
  import { closeFileViewer } from './filebrowser.js';
7
- import { renderModelList, renderModeList, renderEffortBar, renderThinkingBar, renderBetaCard, isSonnetModel } from './settings-defaults.js';
8
7
 
9
8
  var ctx = null;
10
9
  var settingsEl = null;
@@ -111,18 +110,6 @@ export function initServerSettings(appCtx) {
111
110
  });
112
111
  }
113
112
 
114
- // Model item click
115
- settingsEl.addEventListener("click", function (e) {
116
- var modelItem = e.target.closest(".settings-model-item");
117
- if (!modelItem) return;
118
- var model = modelItem.dataset.model;
119
- if (!model) return;
120
- var ws = ctx.ws;
121
- if (ws && ws.readyState === 1) {
122
- ws.send(JSON.stringify({ type: "set_server_default_model", model: model }));
123
- }
124
- });
125
-
126
113
  // PIN buttons
127
114
  var pinSetBtn = document.getElementById("settings-pin-set-btn");
128
115
  var pinRemoveBtn = document.getElementById("settings-pin-remove-btn");
@@ -348,12 +335,6 @@ function populateSettings() {
348
335
  // Sync notification toggles
349
336
  syncNotifToggles();
350
337
 
351
- // Session defaults
352
- updateModelList();
353
- updateModeList();
354
- updateEffortBar();
355
- updateThinkingBar();
356
- updateSsBetaCard();
357
338
  }
358
339
 
359
340
  function syncNotifToggles() {
@@ -369,51 +350,6 @@ function syncNotifToggles() {
369
350
  }
370
351
  }
371
352
 
372
- function ssSendMsg(type, data) {
373
- var ws = ctx.ws;
374
- if (ws && ws.readyState === 1) {
375
- var msg = Object.assign({ type: type }, data);
376
- ws.send(JSON.stringify(msg));
377
- }
378
- }
379
-
380
- function ssDefaultsOpts() {
381
- return {
382
- models: ctx.currentModels || [],
383
- currentModel: ctx.currentModel || ctx._currentModelValue || "",
384
- currentMode: ctx.currentMode || "default",
385
- currentEffort: ctx.currentEffort || "medium",
386
- currentThinking: ctx.currentThinking || "adaptive",
387
- currentThinkingBudget: ctx.currentThinkingBudget || 10000,
388
- currentBetas: ctx.currentBetas || [],
389
- sendMsg: ssSendMsg,
390
- modelMsgType: "set_model",
391
- modeMsgType: "set_server_default_mode",
392
- effortMsgType: "set_server_default_effort",
393
- onModelSelect: function (model) { updateSsBetaCard(model); },
394
- };
395
- }
396
-
397
- function updateModelList() {
398
- renderModelList("ss", ssDefaultsOpts());
399
- }
400
-
401
- function updateModeList() {
402
- renderModeList("ss", ssDefaultsOpts());
403
- }
404
-
405
- function updateEffortBar() {
406
- renderEffortBar("ss", ssDefaultsOpts());
407
- }
408
-
409
- function updateThinkingBar() {
410
- renderThinkingBar("ss", ssDefaultsOpts());
411
- }
412
-
413
- function updateSsBetaCard(overrideModel) {
414
- renderBetaCard("ss", Object.assign(ssDefaultsOpts(), { overrideModel: overrideModel }));
415
- }
416
-
417
353
  export function updateSettingsStats(data) {
418
354
  if (!isSettingsOpen()) return;
419
355
  var pid = document.getElementById("settings-status-pid");
@@ -429,19 +365,6 @@ export function updateSettingsStats(data) {
429
365
  if (clients) clients.textContent = String(data.clients);
430
366
  }
431
367
 
432
- export function updateSettingsModels(current, models) {
433
- if (!ctx) return;
434
- ctx.currentModels = models;
435
- ctx._currentModelValue = current;
436
- if (isSettingsOpen()) {
437
- updateModelList();
438
- updateModeList();
439
- updateEffortBar();
440
- updateThinkingBar();
441
- updateSsBetaCard();
442
- }
443
- }
444
-
445
368
  // --- Daemon config ---
446
369
  function requestDaemonConfig() {
447
370
  var ws = ctx.ws;
@@ -275,7 +275,7 @@ export function initSidebarProjects() {
275
275
  // Tooltip + click for home icon
276
276
  var homeIcon = document.querySelector(".icon-strip-home");
277
277
  if (homeIcon) {
278
- homeIcon.addEventListener("mouseenter", function () { showIconTooltip(homeIcon, "Clay"); });
278
+ homeIcon.addEventListener("mouseenter", function () { showIconTooltip(homeIcon, "Clay Studio"); });
279
279
  homeIcon.addEventListener("mouseleave", hideIconTooltip);
280
280
  homeIcon.addEventListener("click", function (e) {
281
281
  e.preventDefault();
@@ -1252,14 +1252,19 @@ function renderSessionItem(s) {
1252
1252
  el.className = "session-item" + (s.active ? " active" : "") + (isMatch ? " search-match" : "");
1253
1253
  el.dataset.sessionId = s.id;
1254
1254
 
1255
+ // Keep agent identity separate from the title so each row has a stable
1256
+ // visual anchor instead of mixing a tiny inline logo into the text.
1257
+ var itemVendor = s.vendor || "claude";
1258
+ var vendorIcon = document.createElement("img");
1259
+ vendorIcon.className = "session-vendor-icon session-vendor-mark";
1260
+ vendorIcon.src = VENDOR_AVATARS[itemVendor] || VENDOR_AVATARS.claude;
1261
+ vendorIcon.alt = "";
1262
+ vendorIcon.title = VENDOR_NAMES[itemVendor] || itemVendor;
1263
+ el.appendChild(vendorIcon);
1264
+
1255
1265
  var textSpan = document.createElement("span");
1256
1266
  textSpan.className = "session-item-text";
1257
1267
  var textHtml = "";
1258
- // Which agent runtime this session ran on. Legacy sessions without a
1259
- // recorded vendor are Claude (pre-multi-vendor era).
1260
- var itemVendor = s.vendor || "claude";
1261
- textHtml += '<img class="session-vendor-icon" src="' + (VENDOR_AVATARS[itemVendor] || VENDOR_AVATARS.claude) +
1262
- '" alt="" title="' + escapeHtml(VENDOR_NAMES[itemVendor] || itemVendor) + '">';
1263
1268
  if (s.isProcessing) {
1264
1269
  textHtml += '<span class="session-processing"></span>';
1265
1270
  }
@@ -1276,6 +1281,14 @@ function renderSessionItem(s) {
1276
1281
  textSpan.innerHTML = textHtml;
1277
1282
  el.appendChild(textSpan);
1278
1283
 
1284
+ var ageText = relativeTime(s.lastActivity || 0);
1285
+ if (ageText) {
1286
+ var age = document.createElement("span");
1287
+ age.className = "session-item-age";
1288
+ age.textContent = ageText;
1289
+ el.appendChild(age);
1290
+ }
1291
+
1279
1292
  // Right-click / long-press: context menu
1280
1293
  el.addEventListener("contextmenu", (function(id, title, cliSid, anchor, sData) {
1281
1294
  return function(e) {
@@ -46,9 +46,9 @@ export function updatePageTitle() {
46
46
  if (ctx.projectName && sessionTitle) {
47
47
  document.title = sessionTitle + " - " + ctx.projectName;
48
48
  } else if (ctx.projectName) {
49
- document.title = ctx.projectName + " - Clay";
49
+ document.title = ctx.projectName + " - Clay Studio";
50
50
  } else {
51
- document.title = "Clay";
51
+ document.title = "Clay Studio";
52
52
  }
53
53
  }
54
54