clay-server 5.1.0-beta.2 → 5.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 (101) hide show
  1. package/bin/cli.js +9 -91
  2. package/lib/builtin-mates.js +7 -7
  3. package/lib/daemon-settings.js +11 -0
  4. package/lib/daemon.js +8 -37
  5. package/lib/linear-store.js +35 -8
  6. package/lib/mate-identity-file.js +39 -0
  7. package/lib/mate-knowledge-sync.js +1 -1
  8. package/lib/mate-ready-creation.js +2 -1
  9. package/lib/mates-identity.js +4 -4
  10. package/lib/mates-prompts.js +4 -3
  11. package/lib/mates.js +12 -11
  12. package/lib/os-users.js +5 -16
  13. package/lib/project-connection.js +0 -7
  14. package/lib/project-debate.js +3 -2
  15. package/lib/project-filesystem.js +21 -39
  16. package/lib/project-mate-interaction.js +7 -6
  17. package/lib/project-server-settings.js +31 -0
  18. package/lib/project-sessions.js +57 -184
  19. package/lib/project.js +3 -3
  20. package/lib/public/app.js +6 -37
  21. package/lib/public/css/input.css +3 -1
  22. package/lib/public/css/menus.css +3 -0
  23. package/lib/public/css/overlays.css +7 -0
  24. package/lib/public/css/project-settings-modal.css +56 -0
  25. package/lib/public/css/server-settings-system.css +125 -0
  26. package/lib/public/css/session-github.css +25 -16
  27. package/lib/public/css/settings-ui.css +247 -22
  28. package/lib/public/css/shared-browser.css +7 -3
  29. package/lib/public/css/title-bar.css +5 -1
  30. package/lib/public/index.html +173 -447
  31. package/lib/public/modules/account-island.js +9 -7
  32. package/lib/public/modules/admin-settings-email.js +197 -0
  33. package/lib/public/modules/admin-settings-invitations.js +183 -0
  34. package/lib/public/modules/admin-settings-projects.js +198 -0
  35. package/lib/public/modules/admin-settings-ui.js +100 -0
  36. package/lib/public/modules/admin-settings-users.js +331 -0
  37. package/lib/public/modules/admin.js +19 -949
  38. package/lib/public/modules/app-dm.js +0 -2
  39. package/lib/public/modules/app-messages.js +13 -52
  40. package/lib/public/modules/app-rate-limit.js +70 -12
  41. package/lib/public/modules/avatar.js +6 -1
  42. package/lib/public/modules/context-sources.js +27 -18
  43. package/lib/public/modules/default-ai.js +14 -7
  44. package/lib/public/modules/header-tui-font.js +10 -20
  45. package/lib/public/modules/home-mate-avatar-editor.js +2 -2
  46. package/lib/public/modules/linear-settings.js +3 -2
  47. package/lib/public/modules/markdown.js +5 -6
  48. package/lib/public/modules/notification-settings.js +81 -0
  49. package/lib/public/modules/notifications.js +44 -28
  50. package/lib/public/modules/personal-settings-dialog.js +51 -0
  51. package/lib/public/modules/profile.js +15 -6
  52. package/lib/public/modules/project-settings-environment.js +106 -0
  53. package/lib/public/modules/project-settings.js +72 -628
  54. package/lib/public/modules/server-settings-controls.js +316 -0
  55. package/lib/public/modules/server-settings-environment.js +194 -0
  56. package/lib/public/modules/server-settings-navigation.js +39 -0
  57. package/lib/public/modules/server-settings-state.js +54 -0
  58. package/lib/public/modules/server-settings.js +116 -788
  59. package/lib/public/modules/server-storage-settings.js +84 -0
  60. package/lib/public/modules/session-github.js +2 -1
  61. package/lib/public/modules/session-presence-ui.js +1 -1
  62. package/lib/public/modules/settings-env-values.js +34 -0
  63. package/lib/public/modules/settings-select.js +121 -0
  64. package/lib/public/modules/shared-browser.js +22 -12
  65. package/lib/public/modules/stt-picker.js +14 -5
  66. package/lib/public/modules/terminal-prefs.js +22 -0
  67. package/lib/public/modules/theme.js +88 -52
  68. package/lib/public/modules/user-settings-account.js +318 -0
  69. package/lib/public/modules/user-settings-appearance.js +55 -0
  70. package/lib/public/modules/user-settings-editors.js +24 -0
  71. package/lib/public/modules/user-settings-integrations.js +104 -0
  72. package/lib/public/modules/user-settings-layout.js +80 -0
  73. package/lib/public/modules/user-settings-preferences.js +48 -0
  74. package/lib/public/modules/user-settings-profile.js +53 -0
  75. package/lib/public/modules/user-settings-themes.js +38 -0
  76. package/lib/public/modules/user-settings-voice.js +75 -0
  77. package/lib/public/modules/user-settings.js +53 -480
  78. package/lib/public/style.css +4 -0
  79. package/lib/sdk-message-processor.js +16 -4
  80. package/lib/sdk-quota-snapshot.js +37 -0
  81. package/lib/server-appearance-settings.js +71 -0
  82. package/lib/server-linear.js +14 -8
  83. package/lib/server-mate-instructions.js +2 -2
  84. package/lib/server-mates.js +2 -1
  85. package/lib/server-notification-settings.js +67 -0
  86. package/lib/server-settings.js +4 -0
  87. package/lib/server-storage.js +57 -0
  88. package/lib/server.js +10 -2
  89. package/lib/sessions.js +3 -4
  90. package/lib/startup-projects.js +40 -0
  91. package/lib/storage-native-walk.js +85 -0
  92. package/lib/storage-usage.js +144 -0
  93. package/lib/users-preferences.js +0 -74
  94. package/lib/users.js +0 -4
  95. package/lib/ws-schema.js +2 -4
  96. package/lib/yoke/acp-process-manager.js +2 -2
  97. package/lib/yoke/adapters/codex.js +12 -52
  98. package/lib/yoke/codex-app-server.js +2 -2
  99. package/lib/yoke/codex-model-catalog.js +52 -0
  100. package/lib/yoke/codex-rate-limits.js +26 -0
  101. package/package.json +3 -3
package/lib/public/app.js CHANGED
@@ -42,8 +42,8 @@ import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated,
42
42
  import { initNotesBrowser, openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen, renderNotesBrowser } from './modules/sticky-notes-browser.js';
43
43
  import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentTheme, getChatLayout } from './modules/theme.js';
44
44
  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';
45
- import { initServerSettings, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './modules/server-settings.js';
46
- import { initProjectSettings, handleInstructionsRead, handleInstructionsWrite, handleProjectEnv, handleProjectEnvSaved, isProjectSettingsOpen, handleProjectSharedEnv, handleProjectSharedEnvSaved, handleProjectOwnerChanged } from './modules/project-settings.js';
45
+ import { initServerSettings, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved } from './modules/server-settings.js';
46
+ import { initProjectSettings } from './modules/project-settings.js';
47
47
  import { initSkills, handleSkillInstalled, handleSkillUninstalled } from './modules/skills.js';
48
48
  import { initMcp } from './modules/mcp-ui.js';
49
49
  import { initScheduler, resetScheduler, handleLoopRegistryUpdated, handleScheduleRunStarted, handleScheduleRunFinished, handleLoopScheduled, openSchedulerToTab, isSchedulerOpen, closeScheduler, enterCraftingMode, exitCraftingMode, handleLoopRegistryFiles, getUpcomingSchedules } from './modules/scheduler.js';
@@ -554,7 +554,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
554
554
  cachedMatesList: [],
555
555
  cachedDmFavorites: [],
556
556
  cachedAvailableBuiltins: [],
557
- projectMateDmsEnabled: false,
557
+ projectMateDmsEnabled: true,
558
558
  returningFromMateDm: false,
559
559
  pendingMateInterview: null,
560
560
  pendingTermCommand: null,
@@ -602,10 +602,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
602
602
  vendorInfo: {},
603
603
  // Rate-limit data is projected only for the displayed session/vendor.
604
604
  rateLimitState: {},
605
- // How Claude sessions open: "gui" (default) or "tui". The server sends
606
- // claude_open_mode_changed on connect; this seeds it beforehand so the
607
- // new-session menu doesn't flash the TUI-only entry.
608
- claudeOpenMode: "gui",
609
605
  currentMode: "default",
610
606
  effectivePermissionMode: null,
611
607
  permissionCapabilities: { auto: false, mcpOverride: false },
@@ -1133,9 +1129,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
1133
1129
 
1134
1130
  // --- Admin (multi-user mode) ---
1135
1131
  // isMultiUserMode, isHeadlessMode, myUserId -> store
1136
- initAdmin({
1137
- get projectList() { return getCachedProjects(); },
1138
- });
1132
+ initAdmin();
1139
1133
  fetch("/api/me").then(function (r) { return r.json(); }).then(function (d) {
1140
1134
  if (d.multiUser) {
1141
1135
  store.set({ isMultiUserMode: true });
@@ -1217,35 +1211,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
1217
1211
  });
1218
1212
 
1219
1213
  // --- Server Settings ---
1220
- initServerSettings({
1221
- get ws() { return _getWsRef(); },
1222
- get projectName() { return store.get('projectName'); },
1223
- get currentSlug() { return store.get('currentSlug'); },
1224
- wsPath: wsPath,
1225
- get currentModels() { return store.get('currentModels'); },
1226
- set currentModels(v) { store.set({ currentModels: v }); },
1227
- get currentModel() { return store.get('currentModel'); },
1228
- get currentMode() { return store.get('currentMode'); },
1229
- get currentEffort() { return store.get('currentEffort'); },
1230
- get currentBetas() { return store.get('currentBetas'); },
1231
- get currentThinking() { return store.get('currentThinking'); },
1232
- get currentThinkingBudget() { return store.get('currentThinkingBudget'); },
1233
- setContextView: function (v) { _panSetContextView(v); },
1234
- applyContextView: function (v) { _panApplyContextView(v); },
1235
- });
1214
+ initServerSettings();
1236
1215
 
1237
1216
  // --- Project Settings ---
1238
- initProjectSettings({
1239
- get ws() { return _getWsRef(); },
1240
- get connected() { return store.get('connected'); },
1241
- get currentModels() { return store.get('currentModels'); },
1242
- get currentModel() { return store.get('currentModel'); },
1243
- get currentMode() { return store.get('currentMode'); },
1244
- get currentEffort() { return store.get('currentEffort'); },
1245
- get currentBetas() { return store.get('currentBetas'); },
1246
- get currentThinking() { return store.get('currentThinking'); },
1247
- get currentThinkingBudget() { return store.get('currentThinkingBudget'); },
1248
- }, getEmojiCategories());
1217
+ initProjectSettings(getEmojiCategories());
1249
1218
 
1250
1219
  // --- QR code ---
1251
1220
  initQrCode();
@@ -742,7 +742,9 @@
742
742
  }
743
743
 
744
744
  #input-wrapper {
745
- max-width: var(--content-width);
745
+ /* Writing follows the pane width independently of transcript layout.
746
+ Mate workspaces provide their own bounded composer override. */
747
+ max-width: 100%;
746
748
  margin: 0 auto;
747
749
  position: relative;
748
750
  }
@@ -226,6 +226,7 @@
226
226
 
227
227
  /* --- Terminal toggle button (mobile only) --- */
228
228
  #footer-status,
229
+ #shared-browser-toggle-btn,
229
230
  #terminal-toggle-btn {
230
231
  display: flex;
231
232
  align-items: center;
@@ -239,8 +240,10 @@
239
240
  transition: color 0.15s, background 0.15s, border-color 0.15s;
240
241
  }
241
242
  #footer-status .lucide,
243
+ #shared-browser-toggle-btn .lucide,
242
244
  #terminal-toggle-btn .lucide { width: 15px; height: 15px; }
243
245
  #footer-status:hover,
246
+ #shared-browser-toggle-btn:hover,
244
247
  #terminal-toggle-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
245
248
  #terminal-toggle-btn { position: relative; }
246
249
  #terminal-count {
@@ -1357,6 +1357,13 @@ button.top-bar-pill.pill-accent:hover { background: color-mix(in srgb, var(--acc
1357
1357
  filter: drop-shadow(0 12px 28px rgb(88 87 252 / 0.12));
1358
1358
  }
1359
1359
 
1360
+ .connect-wordmark {
1361
+ display: block;
1362
+ width: clamp(142px, 15vw, 184px);
1363
+ height: auto;
1364
+ filter: brightness(0);
1365
+ }
1366
+
1360
1367
  #connect-overlay-msg {
1361
1368
  color: var(--text-dimmer);
1362
1369
  font-family: var(--font-mono);
@@ -0,0 +1,56 @@
1
+ /* Project settings shares the focused Mate dialog shell and compact settings interior. */
2
+ #project-settings {
3
+ position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center;
4
+ width: auto; padding: 24px; border: 0; background: rgba(0, 0, 0, .38); backdrop-filter: blur(2px);
5
+ }
6
+ #project-settings.hidden { display: none; }
7
+ #project-settings .ps-modal {
8
+ display: flex; flex-direction: column; width: min(920px, 100%); height: min(720px, calc(100dvh - 48px));
9
+ border: 1px solid var(--border); border-radius: 14px; background: var(--bg); overflow: hidden;
10
+ box-shadow: 0 16px 48px rgba(0, 0, 0, .18);
11
+ }
12
+ #project-settings .ps-modal-header { display: flex; align-items: center; justify-content: space-between; min-height: 72px; padding: 14px 18px 13px 22px; border-bottom: 1px solid var(--border-subtle); }
13
+ #project-settings .ps-modal-header h2 { margin: 0; font-size: 16px; line-height: 22px; }
14
+ #project-settings #ps-nav-title { display: block; font-size: 12px; color: var(--text-muted); max-width: 65vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
15
+ #project-settings #project-settings-close { width: 32px; height: 32px; padding: 0; display: grid; place-items: center; }
16
+ #project-settings #project-settings-close svg { width: 16px; height: 16px; }
17
+ #project-settings .project-settings-layout { flex: 1; min-height: 0; height: auto; justify-content: initial; }
18
+ #project-settings .project-settings-layout::after { display: none; }
19
+ #project-settings .project-settings-nav { width: 180px; justify-content: initial; border-right: 1px solid var(--border-subtle); }
20
+ #project-settings .project-settings-nav-inner { width: 100%; box-sizing: border-box; padding: 14px 8px; }
21
+ #project-settings .settings-nav-item { height: 32px; min-height: 32px; border-left: 0; }
22
+ #project-settings .project-settings-content { max-width: none; }
23
+ #project-settings .project-settings-content-inner { padding: 24px 28px; }
24
+ #project-settings .ps-section h2 { margin: 0 0 20px; font-size: 20px; }
25
+ #project-settings .settings-card { background: none; border: 0; border-radius: 0; padding: 0; box-shadow: none; }
26
+ #project-settings .settings-field + .settings-field { border-top: 1px solid var(--border-subtle); padding-top: 20px; margin-top: 20px; }
27
+ #project-settings .settings-nav-dropdown { display: none; }
28
+ #project-settings :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
29
+ @media (max-width: 768px) {
30
+ #project-settings { padding: 12px; }
31
+ #project-settings .ps-modal { height: min(720px, calc(100dvh - 24px)); }
32
+ #project-settings .project-settings-layout { flex-direction: column; }
33
+ #project-settings .project-settings-nav { width: 100%; flex-shrink: 0; overflow: visible; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
34
+ #project-settings .project-settings-nav-inner { padding: 8px 16px; }
35
+ #project-settings .server-settings-nav-items { display: none; }
36
+ #project-settings .settings-nav-dropdown { display: block; width: 100%; height: 36px; margin: 0; }
37
+ #project-settings .project-settings-content-inner { padding: 20px 16px; }
38
+ }
39
+ #project-settings [hidden], #project-settings .hidden { display: none !important; }
40
+ @media (prefers-reduced-motion: reduce) {
41
+ #project-settings *, #project-settings *::before, #project-settings *::after { transition: none !important; animation: none !important; }
42
+ }
43
+
44
+ #project-settings .ps-project-identity { display: flex; align-items: flex-start; gap: 20px; padding: 8px 0 24px; }
45
+ #project-settings .ps-project-mark { flex: 0 0 64px; text-align: center; }
46
+ #project-settings .ps-project-icon { position: relative; width: 64px; height: 64px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-alt); color: var(--text); cursor: pointer; }
47
+ #project-settings .ps-project-icon > svg { position: absolute; width: 12px; height: 12px; right: 4px; bottom: 4px; padding: 2px; border-radius: 4px; background: var(--bg); }
48
+ #project-settings .ps-icon-reset { padding: 6px 0; border: 0; background: none; color: var(--text-muted); font: inherit; font-size: 11px; cursor: pointer; }
49
+ #project-settings .ps-project-identity-copy { flex: 1; min-width: 0; }
50
+ #project-settings .ps-name-row { justify-content: space-between; gap: 12px; }
51
+ #project-settings #ps-project-name { font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }
52
+ #project-settings .ps-project-location { border-top: 1px solid var(--border-subtle); padding-top: 20px; }
53
+ #project-settings .ps-project-location h3 { margin: 0 0 8px; }
54
+ #project-settings .ps-project-path { font-size: 13px; font-family: var(--font-mono, monospace); overflow-wrap: anywhere; margin: 0 0 8px; color: var(--text); user-select: text; }
55
+
56
+ #project-settings .ps-project-icon .ps-icon-preview svg { width: 28px; height: 28px; color: var(--text-muted); }
@@ -0,0 +1,125 @@
1
+ /* Server settings: compact navigation, flat sections and deliberate actions. */
2
+ #server-settings .server-settings-layout { background: var(--sidebar-bg); justify-content: center; }
3
+ #server-settings .server-settings-layout::after { display: block; }
4
+ #server-settings .server-settings-nav { width: 196px; justify-content: stretch; border-right: 1px solid var(--border-subtle); }
5
+ #server-settings .server-settings-nav-inner { width: 100%; padding: calc(var(--safe-top) + 24px) 10px 24px; }
6
+ #server-settings .server-settings-nav-header { color: var(--text); font-size: 13px; padding: 0 8px 16px; }
7
+ #settings-server-name { display: block; color: var(--text-muted); font-size: 11px; font-weight: 400; margin-top: 5px; }
8
+ #server-settings .settings-nav-category { text-transform: none; letter-spacing: 0; padding: 18px 8px 5px; font-size: 11px; font-weight: 500; }
9
+ #server-settings .settings-nav-item { min-height: 32px; padding: 6px 8px; font-size: 13px; border-left: 0; border-radius: var(--sui-radius-control, 8px); }
10
+ #settings-personal-link { margin-top: 24px; font-size: 11px !important; }
11
+ #server-settings .server-settings-content { max-width: 764px; }
12
+ #server-settings .server-settings-content-inner { max-width: 764px; padding: calc(var(--safe-top) + 28px) 32px 48px; margin: 0 auto; }
13
+ #server-settings .server-settings-section h2 { font-size: 20px; line-height: 1.3; font-weight: 600; margin: 0 0 8px; }
14
+ #server-settings .server-settings-section h2:focus { outline: none; }
15
+ #server-settings .server-settings-section h3 { text-transform: none; letter-spacing: 0; font-size: 14px; margin: 26px 0 10px; }
16
+ #server-settings .settings-page-description { color: var(--text-muted); font-size: 13px; line-height: 1.6; margin: 0 0 24px; }
17
+ #server-settings .settings-card { background: none; border: 0; border-radius: 0; padding: 0; margin-bottom: 20px; box-shadow: none; }
18
+ #server-settings .settings-field, #server-settings .settings-field-row, #server-settings .settings-toggle-row { padding: 10px 0; }
19
+ #server-settings .settings-field-row, #server-settings .settings-toggle-row { min-height: 44px; border-bottom: 1px solid var(--border-subtle); }
20
+ #server-settings .settings-field-row + .settings-field-row { border-top: 0; }
21
+ #server-settings .settings-label { font-size: 13px; font-weight: 500; }
22
+ #server-settings .settings-value { font-size: 13px; max-width: 55%; overflow-wrap: anywhere; }
23
+ #server-settings .settings-hint { font-size: 12px; line-height: 1.55; }
24
+ #server-settings .settings-btn-sm, #server-settings .admin-action-btn { min-height: 32px; padding: 5px 10px; font-size: 13px; border-radius: var(--sui-radius-control, 8px); box-shadow: none; }
25
+ #server-settings input:not([type=checkbox]), #server-settings select, #server-settings .admin-smtp-input { height: 36px; min-height: 36px; font-size: 13px; border-radius: var(--sui-radius-control, 8px); }
26
+ #server-settings textarea { font-size: 13px; border-radius: var(--sui-radius-control, 8px); padding: 10px; }
27
+ #server-settings .server-settings-close-col { top: calc(var(--safe-top) + 20px); right: 16px; }
28
+ #server-settings .server-settings-close-btn { width: 32px; height: 32px; border: 1px solid var(--border-subtle); border-radius: 6px; }
29
+ #server-settings .server-settings-close-btn span { display: none; }
30
+ #server-settings .settings-operation { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--border-subtle); }
31
+ #server-settings .settings-operation > h3 { margin-top: 0; }
32
+ #server-settings .settings-operation > .settings-card { margin-bottom: 0; }
33
+ #server-settings .settings-operation .settings-field { padding-bottom: 0; }
34
+ #server-settings .settings-operation .settings-hint.hidden { display: none; }
35
+ #server-settings .settings-platform-section { margin-top: 24px; }
36
+ #server-settings .admin-user-item, #server-settings .admin-project-item, #server-settings .admin-invite-item { background: none; border: 0; border-bottom: 1px solid var(--border-subtle); border-radius: 0; padding: 10px 0; }
37
+ /* Reserve the access action column even when a public project has no action. */
38
+ #server-settings .admin-project-controls {
39
+ display: grid;
40
+ grid-template-columns: minmax(0, 200px) minmax(0, 200px) 28px;
41
+ flex: 0 0 auto;
42
+ width: 444px;
43
+ max-width: 100%;
44
+ }
45
+ #server-settings .admin-project-controls :is(.settings-picker, select) { width: 100%; min-width: 0; max-width: 100%; }
46
+ #server-settings .admin-manage-users-btn { grid-column: 3; width: 28px; height: 28px; }
47
+ #server-settings .admin-smtp-form { max-width: 560px; }
48
+ #server-settings .admin-smtp-status { background: none; border: 0; padding: 0; font-size: 12px; }
49
+ #server-settings .admin-smtp-row label { font-size: 13px; text-transform: none; letter-spacing: 0; }
50
+ #server-settings .admin-smtp-fields { gap: 14px; }
51
+ #server-settings .ps-env-row { gap: 8px; }
52
+ #server-settings .ps-env-key { width: 38%; }
53
+ #server-settings .ps-env-val { min-width: 0; }
54
+ #settings-access-status:empty { display: none; }
55
+ #server-settings :is(button, input, select, textarea):focus-visible, .settings-confirm button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
56
+ #server-settings button:active:not(:disabled) { transform: translateY(1px); }
57
+ #server-settings button:disabled { opacity: .5; cursor: not-allowed; }
58
+ #server-settings [hidden], .settings-picker [hidden] { display: none !important; }
59
+ .settings-confirm { position: fixed; inset: 0; z-index: 20000; display: grid; place-items: center; padding: 20px; background: rgba(0,0,0,.3); }
60
+ .settings-confirm > div { width: min(440px,100%); padding: 20px; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 8px; }
61
+ .settings-confirm h3 { margin: 0 0 10px; font-size: 16px; }
62
+ .settings-confirm p { font-size: 13px; line-height: 1.6; }
63
+ .settings-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
64
+ @media (max-width: 800px) {
65
+ #server-settings .server-settings-layout { display: flex; flex-direction: column; justify-content: flex-start; }
66
+ #server-settings .server-settings-layout::after { display: none; }
67
+ #server-settings .server-settings-nav { width: 100%; flex-shrink: 0; overflow: visible; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
68
+ #server-settings .server-settings-nav-inner { padding: calc(var(--safe-top) + 12px) 56px 12px 16px; }
69
+ #server-settings .server-settings-nav-header { padding: 0; border: 0; margin: 0 0 8px; }
70
+ #server-settings #settings-server-name { display: none; }
71
+ #server-settings .server-settings-nav-items { display: none; }
72
+ #server-settings .settings-nav-dropdown { display: block; width: 100%; margin: 0; }
73
+ #server-settings #settings-personal-link { margin-top: 6px; min-height: 26px; padding-left: 0; }
74
+ #server-settings .server-settings-content-inner { padding: 24px 16px 40px; }
75
+ #server-settings .server-settings-content { width: 100%; max-width: none; }
76
+ #server-settings .server-settings-close-col { top: calc(var(--safe-top) + 12px); }
77
+ #server-settings .ps-env-header { flex-wrap: wrap; }
78
+ #server-settings #ss-env-save-status { flex-basis: 100%; margin: 0; }
79
+ #server-settings .admin-project-item { flex-wrap: wrap; gap: 8px; }
80
+ #server-settings .admin-project-info { flex: 0 0 100%; }
81
+ #server-settings .admin-project-controls { flex-wrap: wrap; }
82
+ #server-settings .settings-value { min-width: 0; }
83
+ }
84
+ @media (prefers-reduced-motion: reduce) {
85
+ #server-settings, #server-settings *, .settings-confirm * { animation: none !important; transition: none !important; }
86
+ #server-settings button:active:not(:disabled) { transform: none; }
87
+ }
88
+
89
+ .admin-modal-overlay .admin-smtp-row label { text-transform: none; letter-spacing: 0; font-size: 13px; }
90
+ .admin-modal-overlay .admin-smtp-row { margin-bottom: 12px; }
91
+ .admin-modal-overlay .admin-smtp-input { height: 36px; font-size: 13px; }
92
+ .admin-modal-overlay .admin-modal :is(button, input, select):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
93
+ @media (prefers-reduced-motion: reduce) { .admin-modal-overlay, .admin-modal-overlay * { animation: none !important; transition: none !important; } }
94
+
95
+ #server-settings .settings-section-heading,
96
+ #server-settings .settings-storage-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
97
+ #server-settings .settings-section-heading h3,
98
+ #server-settings .settings-storage-heading h3 { margin: 0; }
99
+ #server-settings .settings-storage-table-wrap { overflow-x: auto; }
100
+ #server-settings .settings-storage-table { width: 100%; border-collapse: collapse; font-size: 13px; }
101
+ #server-settings .settings-storage-table :is(th, td) { padding: 10px 8px; border-bottom: 1px solid var(--border-subtle); text-align: left; overflow-wrap: anywhere; }
102
+ #server-settings .settings-storage-table th { font-weight: 500; }
103
+ #server-settings .settings-storage-table thead { color: var(--text-muted); font-size: 12px; }
104
+ #server-settings .settings-storage-table :is(th, td):first-child { padding-left: 0; }
105
+ #server-settings .settings-storage-table :is(th, td):nth-last-child(-n+2) { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
106
+
107
+ #server-settings .settings-section-divider { border-top: 1px solid var(--border-subtle); padding-top: 24px; margin-top: 28px; }
108
+ /* Section boundaries own Operations dividers; leaf rows must not double them. */
109
+ #server-settings [data-section="operations"] :is(.settings-toggle-row, .settings-field-row) { border-bottom: 0; }
110
+ #server-settings [data-section="operations"] .settings-platform-section { border-top: 1px solid var(--border-subtle); padding-top: 24px; }
111
+ #server-settings [data-section="operations"] .settings-platform-section h3 { margin-top: 0; }
112
+
113
+ #server-settings .settings-summary { margin: 16px 0; }
114
+ #server-settings .settings-summary dd { margin: 0; text-align: right; }
115
+
116
+ #server-settings .settings-summary dd { overflow-wrap: anywhere; min-width: 0; }
117
+
118
+ /* Match the Mate settings deletion row: consequence copy and a local danger action. */
119
+ #server-settings .settings-danger-entry { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
120
+ #server-settings .settings-danger-entry-copy { flex: 1; min-width: 180px; }
121
+ #server-settings .settings-danger-entry-copy h3 { color: var(--error); margin: 0 0 6px; }
122
+ #server-settings .settings-danger-entry-copy p { margin: 0; font-size: 12px; line-height: 1.5; color: var(--text-muted); }
123
+ #server-settings .settings-danger-entry .settings-btn-danger { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
124
+ #server-settings .settings-danger-entry .lucide { width: 14px; height: 14px; }
125
+ #server-settings #settings-shutdown-flow { margin-top: 16px; }
@@ -27,22 +27,23 @@
27
27
  font-size: 11px;
28
28
  line-height: 18px;
29
29
  }
30
- .session-work-column .session-row-github-links {
30
+ .session-work-links-slot .session-row-github-links {
31
31
  flex-wrap: nowrap;
32
32
  gap: 3px;
33
33
  overflow: hidden;
34
34
  line-height: 16px;
35
35
  }
36
+ .session-work-links-slot { display: block; min-width: 0; }
36
37
  .session-row-github-links .session-github-link {
37
38
  min-width: 0;
38
39
  height: 18px;
39
40
  box-sizing: border-box;
40
- gap: 3px;
41
- padding: 0 4px;
41
+ gap: 2px;
42
+ padding: 0 3px;
42
43
  font-size: 10.5px;
43
44
  }
44
45
  .session-row-github-links .session-linear-link {
45
- flex: 1 1 0;
46
+ flex: 0 1 auto;
46
47
  min-width: 0;
47
48
  max-width: 100%;
48
49
  overflow: hidden;
@@ -50,9 +51,9 @@
50
51
  .session-row-github-links:has(.github-kind-pr, .github-kind-issue) .session-linear-link { max-width: calc(100% - 76px); }
51
52
  .linear-work-state-compact { display: none; }
52
53
  .session-row-github-links .linear-work-id {
53
- flex: 0 1 auto;
54
+ flex: 0 0 auto;
54
55
  min-width: 0;
55
- max-width: 52%;
56
+ max-width: 76%;
56
57
  overflow: hidden;
57
58
  text-overflow: ellipsis;
58
59
  white-space: nowrap;
@@ -81,6 +82,7 @@
81
82
  text-overflow: ellipsis;
82
83
  white-space: nowrap;
83
84
  }
85
+ .session-row-github-links .linear-work-title:empty { display: none; }
84
86
  .session-row-github-links .github-kind-pr,
85
87
  .session-row-github-links .github-kind-issue { flex: 0 0 auto; }
86
88
  .session-row-github-links .github-work-brand { display: none; }
@@ -88,7 +90,7 @@
88
90
  .session-row-github-links .github-work-status svg { width: 11px; height: 11px; }
89
91
  .session-row-github-links .github-work-more { height: 18px; line-height: 16px; padding: 0 3px; font-size: 10.5px; }
90
92
  .session-row-github-links .linear-work-brand svg { width: 11px; height: 11px; }
91
- .session-row-github-links .linear-work-brand { flex: none; }
93
+ .session-row-github-links .linear-work-brand { flex: none; padding-right: 0; border-right: 0; }
92
94
  .session-row-github-links .session-linear-link,
93
95
  .session-row-github-links .session-github-link,
94
96
  .session-row-github-links .github-work-more { touch-action: manipulation; }
@@ -123,6 +125,11 @@
123
125
  .session-item:has(.session-work-column) {
124
126
  position: relative;
125
127
  container-type: inline-size;
128
+ display: grid;
129
+ grid-template-columns: minmax(0, 1fr) auto auto;
130
+ grid-template-rows: 25px 18px;
131
+ gap: 0 7px;
132
+ align-items: start;
126
133
  height: auto;
127
134
  min-height: 46px;
128
135
  contain: layout;
@@ -134,12 +141,11 @@
134
141
  .session-item:has(.session-work-column) > .session-work-column,
135
142
  .session-item:has(.session-work-column) > .session-presence,
136
143
  .session-item:has(.session-work-column) > .session-row-trailing { align-self: flex-start; margin-top: 5px; }
137
- .session-item:has(.session-work-column) .session-row-github-links {
138
- position: absolute;
139
- left: 30px;
140
- right: 44px;
141
- bottom: 3px;
142
- }
144
+ .session-item:has(.session-work-column) > .session-vendor-mark { grid-column: 1; grid-row: 1; }
145
+ .session-item:has(.session-work-column) > .session-work-column { grid-column: 1; grid-row: 1; }
146
+ .session-item:has(.session-work-column) > .session-presence { grid-column: 2; grid-row: 1; }
147
+ .session-item:has(.session-work-column) > .session-row-trailing { grid-column: 3; grid-row: 1; }
148
+ .session-item:has(.session-work-column) > .session-work-links-slot { grid-column: 1 / 3; grid-row: 2; }
143
149
 
144
150
  .github-kind-pr.github-state-closed .github-work-status svg { color: #f85149; }
145
151
  @media (max-width: 600px) {
@@ -193,9 +199,12 @@
193
199
  .github-work-entry-meta { color: var(--text-muted, #888); font-size: 11px; overflow-wrap: anywhere; }
194
200
  @media (max-width: 600px) {
195
201
  #header-github-links { max-width: 120px; }
196
- .mobile-session-item:has(.session-work-column) { position: relative; container-type: inline-size; align-items: flex-start; min-height: 70px; padding-block: 8px; }
197
- .mobile-session-item:has(.session-work-column) .session-work-column { position: static; }
198
- .mobile-session-item:has(.session-work-column) .session-row-github-links { position: absolute; left: 44px; right: 54px; bottom: 8px; }
202
+ .mobile-session-item:has(.session-work-column) { position: relative; container-type: inline-size; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-rows: 26px 28px; gap: 0 10px; align-items: start; min-height: 70px; padding-block: 8px; }
203
+ .mobile-session-item:has(.session-work-column) > .mobile-session-vendor-icon { grid-column: 1; grid-row: 1; }
204
+ .mobile-session-item:has(.session-work-column) > .session-work-column { grid-column: 1; grid-row: 1; }
205
+ .mobile-session-item:has(.session-work-column) > .session-presence { grid-column: 2; grid-row: 1; }
206
+ .mobile-session-item:has(.session-work-column) > .mobile-session-actions { grid-column: 3; grid-row: 1; }
207
+ .mobile-session-item:has(.session-work-column) > .session-work-links-slot { grid-column: 1 / 3; grid-row: 2; }
199
208
  .mobile-session-item .session-row-github-links .session-github-link,
200
209
  .mobile-session-item .session-row-github-links .github-work-more { min-height: 28px; height: 28px; }
201
210
  .mobile-session-item .session-row-github-links .github-work-more { padding-inline: 2px; }