clay-server 2.11.0-beta.2 → 2.11.0-beta.4

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.
@@ -340,9 +340,9 @@ function renderSmtpTab(body, cfg) {
340
340
 
341
341
  var emailEnabled = !!(cfg && cfg.emailLoginEnabled);
342
342
  if (hasConfig) {
343
- html += '<div class="admin-smtp-status admin-smtp-status-ok">' + iconHtml("check-circle") + ' SMTP configured</div>';
343
+ html += '<div class="admin-smtp-status admin-smtp-status-ok">' + iconHtml("check-circle") + ' SMTP configured. Invite links and one-time login codes are sent via email.</div>';
344
344
  } else {
345
- html += '<div class="admin-smtp-status admin-smtp-status-off">' + iconHtml("mail-x") + ' SMTP not configured using PIN-based login</div>';
345
+ html += '<div class="admin-smtp-status admin-smtp-status-off">' + iconHtml("mail-x") + ' SMTP not configured. Users log in with a PIN instead of email codes.</div>';
346
346
  }
347
347
 
348
348
  html += '<div class="admin-smtp-fields">';
@@ -371,13 +371,12 @@ function renderSmtpTab(body, cfg) {
371
371
  '<label>From Address</label>' +
372
372
  '<input type="text" id="smtp-from" class="admin-smtp-input" placeholder="Clay <noreply@example.com>" value="' + escapeHtml((cfg && cfg.from) || "") + '">' +
373
373
  '</div>';
374
- html += '</div>';
375
-
376
- html += '<div class="admin-smtp-row" style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color,#e5e7eb)">' +
374
+ html += '<div class="admin-smtp-row admin-smtp-row-otp">' +
377
375
  '<label>Email Login (OTP)</label>' +
378
376
  '<label class="admin-smtp-toggle"><input type="checkbox" id="smtp-email-login"' + (emailEnabled ? " checked" : "") + (hasConfig ? "" : " disabled") + '>' +
379
377
  '<span>' + (hasConfig ? "Require email for user registration and enable OTP login" : "Configure SMTP first to enable") + '</span></label>' +
380
378
  '</div>';
379
+ html += '</div>';
381
380
 
382
381
  html += '<div class="admin-smtp-actions">';
383
382
  html += '<button class="admin-action-btn" id="smtp-save">' + iconHtml("save") + ' Save</button>';
@@ -92,7 +92,9 @@ export function initNotifications(_ctx) {
92
92
  if (copyBtn) {
93
93
  copyBtn.addEventListener("click", function (e) {
94
94
  e.stopPropagation();
95
- copyToClipboard("npx clay-server@latest").then(function () {
95
+ var cmdEl = document.getElementById("update-manual-cmd");
96
+ var cmdText = cmdEl ? cmdEl.textContent : "npx clay-server@latest";
97
+ copyToClipboard(cmdText).then(function () {
96
98
  copyBtn.classList.add("copied");
97
99
  copyBtn.innerHTML = iconHtml("check");
98
100
  refreshIcons();
@@ -2,6 +2,8 @@
2
2
  import { refreshIcons } from './icons.js';
3
3
  import { showToast } from './utils.js';
4
4
  import { parseEmojis } from './markdown.js';
5
+ import { closeFileViewer } from './filebrowser.js';
6
+ import { renderModelList, renderModeList, renderEffortBar, renderThinkingBar, renderBetaCard } from './settings-defaults.js';
5
7
 
6
8
  var ctx = null;
7
9
  var panelEl = null;
@@ -13,25 +15,6 @@ var currentProject = null; // { slug, name, icon }
13
15
  // Emoji categories (reuse from sidebar)
14
16
  var EMOJI_CATEGORIES = null;
15
17
 
16
- var MODE_OPTIONS = [
17
- { value: "default", label: "Default", desc: "Claude asks for permission before running tools and editing files." },
18
- { value: "plan", label: "Plan", desc: "Claude creates a plan first and asks for approval before making changes." },
19
- { value: "acceptEdits", label: "Auto-accept edits", desc: "File edits are applied automatically. Claude still asks before running commands." },
20
- ];
21
-
22
- var EFFORT_LEVELS = [
23
- { value: "low", desc: "Quick, concise responses. Best for simple questions." },
24
- { value: "medium", desc: "Balanced responses with moderate reasoning. Good for most tasks." },
25
- { value: "high", desc: "Thorough responses with deeper analysis. Good for complex tasks." },
26
- { value: "max", desc: "Maximum reasoning depth. Best for the most difficult problems." },
27
- ];
28
-
29
- var MODEL_DESCRIPTIONS = {
30
- "default": "Automatically selects the best model for the task.",
31
- "sonnet": "Fast and capable. Great balance of speed and intelligence.",
32
- "haiku": "Fastest model. Best for quick tasks and simple questions.",
33
- "opus": "Most powerful model. Best for complex reasoning and analysis.",
34
- };
35
18
 
36
19
  // ===== Init =====
37
20
  export function initProjectSettings(appCtx, emojiCategories) {
@@ -169,6 +152,9 @@ export function openProjectSettings(slug, project) {
169
152
  // Populate profile
170
153
  populateProfile();
171
154
 
155
+ // Close file viewer if open (prevent split-screen)
156
+ closeFileViewer();
157
+
172
158
  // Show panel
173
159
  panelEl.classList.remove("hidden");
174
160
  refreshIcons();
@@ -358,158 +344,40 @@ function showPsEmojiPicker() {
358
344
  }
359
345
 
360
346
  // ===== Defaults =====
361
- function getModelDesc(model) {
362
- if (!model) return "";
363
- var lower = (model.value || model).toLowerCase();
364
- for (var key in MODEL_DESCRIPTIONS) {
365
- if (lower.indexOf(key) !== -1) return MODEL_DESCRIPTIONS[key];
366
- }
367
- return "";
368
- }
369
-
370
- function isSonnetModel(model) {
371
- if (!model) return false;
372
- return model.toLowerCase().indexOf("sonnet") !== -1;
347
+ function psSendMsg(type, data) {
348
+ var ws = ctx.ws;
349
+ if (ws && ws.readyState === 1) {
350
+ var msg = Object.assign({ type: type }, data);
351
+ ws.send(JSON.stringify(msg));
352
+ }
353
+ }
354
+
355
+ function psDefaultsOpts() {
356
+ return {
357
+ models: ctx.currentModels || [],
358
+ currentModel: ctx.currentModel || "",
359
+ currentMode: ctx.currentMode || "default",
360
+ currentEffort: ctx.currentEffort || "medium",
361
+ currentThinking: ctx.currentThinking || "adaptive",
362
+ currentThinkingBudget: ctx.currentThinkingBudget || 10000,
363
+ currentBetas: ctx.currentBetas || [],
364
+ sendMsg: psSendMsg,
365
+ modelMsgType: "set_project_default_model",
366
+ modeMsgType: "set_project_default_mode",
367
+ effortMsgType: "set_project_default_effort",
368
+ onModelSelect: function (model) {
369
+ renderBetaCard("ps", Object.assign({}, psDefaultsOpts(), { overrideModel: model }));
370
+ },
371
+ };
373
372
  }
374
373
 
375
374
  function populateDefaults() {
376
- var models = ctx.currentModels || [];
377
- var model = ctx.currentModel || "";
378
- var mode = ctx.currentMode || "default";
379
- var effort = ctx.currentEffort || "medium";
380
- var betas = ctx.currentBetas || [];
381
-
382
- // Model list
383
- var modelList = document.getElementById("ps-model-list");
384
- if (modelList) {
385
- modelList.innerHTML = "";
386
- for (var i = 0; i < models.length; i++) {
387
- (function (m) {
388
- var item = document.createElement("div");
389
- item.className = "settings-model-item" + (m.value === model ? " active" : "");
390
-
391
- var nameSpan = document.createElement("span");
392
- nameSpan.className = "settings-model-name";
393
- nameSpan.textContent = m.displayName || m.value;
394
- item.appendChild(nameSpan);
395
-
396
- var desc = getModelDesc(m.value);
397
- if (desc) {
398
- var descSpan = document.createElement("span");
399
- descSpan.className = "settings-model-desc";
400
- descSpan.textContent = desc;
401
- item.appendChild(descSpan);
402
- }
403
-
404
- item.addEventListener("click", function () {
405
- if (ctx.ws && ctx.connected) {
406
- ctx.ws.send(JSON.stringify({ type: "set_project_default_model", model: m.value }));
407
- }
408
- var items = modelList.querySelectorAll(".settings-model-item");
409
- for (var j = 0; j < items.length; j++) items[j].classList.remove("active");
410
- item.classList.add("active");
411
- // Show/hide beta card based on Sonnet
412
- updateBetaCard("ps", m.value);
413
- });
414
- modelList.appendChild(item);
415
- })(models[i]);
416
- }
417
- }
418
-
419
- // Beta 1M toggle
420
- updateBetaCard("ps", model);
421
- var beta1m = document.getElementById("ps-beta-1m");
422
- if (beta1m) {
423
- var hasBeta = false;
424
- for (var bi = 0; bi < betas.length; bi++) {
425
- if (betas[bi].indexOf("context-1m") !== -1) { hasBeta = true; break; }
426
- }
427
- beta1m.checked = hasBeta;
428
- beta1m.onchange = function () {
429
- toggleBeta1m(this.checked);
430
- };
431
- }
432
-
433
- // Mode list
434
- var modeList = document.getElementById("ps-mode-list");
435
- if (modeList) {
436
- modeList.innerHTML = "";
437
- for (var k = 0; k < MODE_OPTIONS.length; k++) {
438
- (function (opt) {
439
- var item = document.createElement("div");
440
- item.className = "settings-model-item" + (opt.value === mode ? " active" : "");
441
-
442
- var nameSpan = document.createElement("span");
443
- nameSpan.className = "settings-model-name";
444
- nameSpan.textContent = opt.label;
445
- item.appendChild(nameSpan);
446
-
447
- var descSpan = document.createElement("span");
448
- descSpan.className = "settings-model-desc";
449
- descSpan.textContent = opt.desc;
450
- item.appendChild(descSpan);
451
-
452
- item.addEventListener("click", function () {
453
- if (ctx.ws && ctx.connected) {
454
- ctx.ws.send(JSON.stringify({ type: "set_project_default_mode", mode: opt.value }));
455
- }
456
- var items = modeList.querySelectorAll(".settings-model-item");
457
- for (var j = 0; j < items.length; j++) items[j].classList.remove("active");
458
- item.classList.add("active");
459
- });
460
- modeList.appendChild(item);
461
- })(MODE_OPTIONS[k]);
462
- }
463
- }
464
-
465
- // Effort bar
466
- var effortBar = document.getElementById("ps-effort-bar");
467
- if (effortBar) {
468
- effortBar.innerHTML = "";
469
- for (var e = 0; e < EFFORT_LEVELS.length; e++) {
470
- (function (lvl) {
471
- var btn = document.createElement("button");
472
- btn.className = "settings-btn-option" + (lvl.value === effort ? " active" : "");
473
- btn.textContent = lvl.value.charAt(0).toUpperCase() + lvl.value.slice(1);
474
- btn.title = lvl.desc;
475
- btn.addEventListener("click", function () {
476
- if (ctx.ws && ctx.connected) {
477
- ctx.ws.send(JSON.stringify({ type: "set_project_default_effort", effort: lvl.value }));
478
- }
479
- var btns = effortBar.querySelectorAll(".settings-btn-option");
480
- for (var j = 0; j < btns.length; j++) btns[j].classList.remove("active");
481
- btn.classList.add("active");
482
- });
483
- effortBar.appendChild(btn);
484
- })(EFFORT_LEVELS[e]);
485
- }
486
- }
487
- }
488
-
489
- function updateBetaCard(prefix, model) {
490
- var card = document.getElementById(prefix + "-beta-card");
491
- if (card) {
492
- card.style.display = isSonnetModel(model) ? "" : "none";
493
- }
494
- }
495
-
496
- function toggleBeta1m(enable) {
497
- var betas = ctx.currentBetas || [];
498
- var newBetas;
499
- if (enable) {
500
- newBetas = betas.slice();
501
- newBetas.push("context-1m-2025-08-07");
502
- } else {
503
- newBetas = [];
504
- for (var i = 0; i < betas.length; i++) {
505
- if (betas[i].indexOf("context-1m") === -1) {
506
- newBetas.push(betas[i]);
507
- }
508
- }
509
- }
510
- if (ctx.ws && ctx.connected) {
511
- ctx.ws.send(JSON.stringify({ type: "set_betas", betas: newBetas }));
512
- }
375
+ var opts = psDefaultsOpts();
376
+ renderModelList("ps", opts);
377
+ renderBetaCard("ps", opts);
378
+ renderModeList("ps", opts);
379
+ renderEffortBar("ps", opts);
380
+ renderThinkingBar("ps", opts);
513
381
  }
514
382
 
515
383
  // ===== Instructions (CLAUDE.md) =====
@@ -3,6 +3,8 @@ import { refreshIcons } from './icons.js';
3
3
  import { showToast, copyToClipboard } from './utils.js';
4
4
  import { parseEnvString, looksLikeEnv } from './project-settings.js';
5
5
  import { checkAdminAccess, loadAdminSection } from './admin.js';
6
+ import { closeFileViewer } from './filebrowser.js';
7
+ import { renderModelList, renderModeList, renderEffortBar, renderThinkingBar, renderBetaCard, isSonnetModel } from './settings-defaults.js';
6
8
 
7
9
  var ctx = null;
8
10
  var settingsEl = null;
@@ -12,26 +14,6 @@ var navItems = null;
12
14
  var sections = null;
13
15
  var statsTimer = null;
14
16
 
15
- var SS_MODE_OPTIONS = [
16
- { value: "default", label: "Default", desc: "Claude asks for permission before running tools and editing files." },
17
- { value: "plan", label: "Plan", desc: "Claude creates a plan first and asks for approval before making changes." },
18
- { value: "acceptEdits", label: "Auto-accept edits", desc: "File edits are applied automatically. Claude still asks before running commands." },
19
- ];
20
-
21
- var SS_EFFORT_LEVELS = [
22
- { value: "low", desc: "Quick, concise responses. Best for simple questions." },
23
- { value: "medium", desc: "Balanced responses with moderate reasoning. Good for most tasks." },
24
- { value: "high", desc: "Thorough responses with deeper analysis. Good for complex tasks." },
25
- { value: "max", desc: "Maximum reasoning depth. Best for the most difficult problems." },
26
- ];
27
-
28
- var SS_MODEL_DESCRIPTIONS = {
29
- "default": "Automatically selects the best model for the task.",
30
- "sonnet": "Fast and capable. Great balance of speed and intelligence.",
31
- "haiku": "Fastest model. Best for quick tasks and simple questions.",
32
- "opus": "Most powerful model. Best for complex reasoning and analysis.",
33
- };
34
-
35
17
  export function initServerSettings(appCtx) {
36
18
  ctx = appCtx;
37
19
  settingsEl = document.getElementById("server-settings");
@@ -257,6 +239,7 @@ function switchSection(sectionName) {
257
239
  }
258
240
 
259
241
  function openSettings() {
242
+ closeFileViewer();
260
243
  settingsEl.classList.remove("hidden");
261
244
  settingsBtn.classList.add("active");
262
245
  refreshIcons(settingsEl);
@@ -281,7 +264,7 @@ function openSettings() {
281
264
  function resetRestartButton() {
282
265
  var btn = document.getElementById("settings-restart-btn");
283
266
  var errorEl = document.getElementById("settings-restart-error");
284
- if (btn) { btn.disabled = false; btn.innerHTML = '<i data-lucide="refresh-cw" style="width:14px;height:14px;vertical-align:-2px;margin-right:4px;"></i>Restart Server'; }
267
+ if (btn) { btn.disabled = false; btn.innerHTML = '<i data-lucide="refresh-cw" style="width:14px;height:14px;vertical-align:-2px;margin-right:4px;"></i>Restart'; }
285
268
  if (errorEl) errorEl.classList.add("hidden");
286
269
  }
287
270
 
@@ -315,19 +298,14 @@ function requestStats() {
315
298
  }
316
299
 
317
300
  function populateSettings() {
318
- // Server name
319
301
  var nameEl = document.getElementById("settings-server-name");
320
- var projNameEl = document.getElementById("settings-project-name");
321
- var cwdEl = document.getElementById("settings-project-cwd");
322
302
  var versionEl = document.getElementById("settings-server-version");
323
303
  var slugEl = document.getElementById("settings-project-slug");
324
304
  var wsPathEl = document.getElementById("settings-ws-path");
325
305
  var skipPermsEl = document.getElementById("settings-skip-perms");
326
306
 
327
- var projectName = ctx.projectName || "-";
328
- if (nameEl) nameEl.textContent = projectName;
329
- if (projNameEl) projNameEl.textContent = projectName;
330
- if (cwdEl) cwdEl.textContent = ctx.projectName || "-";
307
+ // Nav header defaults to hostname (updated by updateDaemonConfig)
308
+ if (nameEl && !nameEl.textContent) nameEl.textContent = "Server";
331
309
 
332
310
  var footerVersion = document.getElementById("footer-version");
333
311
  if (versionEl && footerVersion) {
@@ -352,6 +330,7 @@ function populateSettings() {
352
330
  updateModelList();
353
331
  updateModeList();
354
332
  updateEffortBar();
333
+ updateThinkingBar();
355
334
  updateSsBetaCard();
356
335
  }
357
336
 
@@ -368,174 +347,49 @@ function syncNotifToggles() {
368
347
  }
369
348
  }
370
349
 
371
- function ssGetModelDesc(model) {
372
- if (!model) return "";
373
- var lower = model.toLowerCase();
374
- for (var key in SS_MODEL_DESCRIPTIONS) {
375
- if (lower.indexOf(key) !== -1) return SS_MODEL_DESCRIPTIONS[key];
350
+ function ssSendMsg(type, data) {
351
+ var ws = ctx.ws;
352
+ if (ws && ws.readyState === 1) {
353
+ var msg = Object.assign({ type: type }, data);
354
+ ws.send(JSON.stringify(msg));
376
355
  }
377
- return "";
378
356
  }
379
357
 
380
- function ssIsSonnetModel(model) {
381
- if (!model) return false;
382
- return model.toLowerCase().indexOf("sonnet") !== -1;
358
+ function ssDefaultsOpts() {
359
+ return {
360
+ models: ctx.currentModels || [],
361
+ currentModel: ctx.currentModel || ctx._currentModelValue || "",
362
+ currentMode: ctx.currentMode || "default",
363
+ currentEffort: ctx.currentEffort || "medium",
364
+ currentThinking: ctx.currentThinking || "adaptive",
365
+ currentThinkingBudget: ctx.currentThinkingBudget || 10000,
366
+ currentBetas: ctx.currentBetas || [],
367
+ sendMsg: ssSendMsg,
368
+ modelMsgType: "set_model",
369
+ modeMsgType: "set_server_default_mode",
370
+ effortMsgType: "set_server_default_effort",
371
+ onModelSelect: function (model) { updateSsBetaCard(model); },
372
+ };
383
373
  }
384
374
 
385
375
  function updateModelList() {
386
- var listEl = document.getElementById("settings-model-list");
387
- if (!listEl) return;
388
-
389
- var models = ctx.currentModels || [];
390
- var currentModel = ctx.currentModel || ctx._currentModelValue || "";
391
-
392
- listEl.innerHTML = "";
393
- if (models.length === 0) {
394
- listEl.innerHTML = '<div style="font-size:13px;color:var(--text-dimmer);">No models available</div>';
395
- return;
396
- }
397
-
398
- for (var i = 0; i < models.length; i++) {
399
- (function (m) {
400
- var value = m.value || "";
401
- var label = m.displayName || value;
402
- var item = document.createElement("div");
403
- item.className = "settings-model-item";
404
- if (value === currentModel) item.classList.add("active");
405
- item.dataset.model = value;
406
-
407
- var nameSpan = document.createElement("span");
408
- nameSpan.className = "settings-model-name";
409
- nameSpan.textContent = label;
410
- item.appendChild(nameSpan);
411
-
412
- var desc = ssGetModelDesc(value);
413
- if (desc) {
414
- var descSpan = document.createElement("span");
415
- descSpan.className = "settings-model-desc";
416
- descSpan.textContent = desc;
417
- item.appendChild(descSpan);
418
- }
419
-
420
- item.addEventListener("click", function () {
421
- var ws = ctx.ws;
422
- if (ws && ws.readyState === 1) {
423
- ws.send(JSON.stringify({ type: "set_model", model: value }));
424
- }
425
- var items = listEl.querySelectorAll(".settings-model-item");
426
- for (var j = 0; j < items.length; j++) items[j].classList.remove("active");
427
- item.classList.add("active");
428
- updateSsBetaCard(value);
429
- });
430
-
431
- listEl.appendChild(item);
432
- })(models[i]);
433
- }
376
+ renderModelList("ss", ssDefaultsOpts());
434
377
  }
435
378
 
436
379
  function updateModeList() {
437
- var listEl = document.getElementById("ss-mode-list");
438
- if (!listEl) return;
439
-
440
- var currentMode = ctx.currentMode || "default";
441
- listEl.innerHTML = "";
442
-
443
- for (var i = 0; i < SS_MODE_OPTIONS.length; i++) {
444
- (function (opt) {
445
- var item = document.createElement("div");
446
- item.className = "settings-model-item" + (opt.value === currentMode ? " active" : "");
447
-
448
- var nameSpan = document.createElement("span");
449
- nameSpan.className = "settings-model-name";
450
- nameSpan.textContent = opt.label;
451
- item.appendChild(nameSpan);
452
-
453
- var descSpan = document.createElement("span");
454
- descSpan.className = "settings-model-desc";
455
- descSpan.textContent = opt.desc;
456
- item.appendChild(descSpan);
457
-
458
- item.addEventListener("click", function () {
459
- var ws = ctx.ws;
460
- if (ws && ws.readyState === 1) {
461
- ws.send(JSON.stringify({ type: "set_server_default_mode", mode: opt.value }));
462
- }
463
- var items = listEl.querySelectorAll(".settings-model-item");
464
- for (var j = 0; j < items.length; j++) items[j].classList.remove("active");
465
- item.classList.add("active");
466
- });
467
-
468
- listEl.appendChild(item);
469
- })(SS_MODE_OPTIONS[i]);
470
- }
380
+ renderModeList("ss", ssDefaultsOpts());
471
381
  }
472
382
 
473
383
  function updateEffortBar() {
474
- var bar = document.getElementById("ss-effort-bar");
475
- if (!bar) return;
476
-
477
- var currentEffort = ctx.currentEffort || "medium";
478
- bar.innerHTML = "";
479
-
480
- for (var i = 0; i < SS_EFFORT_LEVELS.length; i++) {
481
- (function (lvl) {
482
- var btn = document.createElement("button");
483
- btn.className = "settings-btn-option" + (lvl.value === currentEffort ? " active" : "");
484
- btn.textContent = lvl.value.charAt(0).toUpperCase() + lvl.value.slice(1);
485
- btn.title = lvl.desc;
486
- btn.addEventListener("click", function () {
487
- var ws = ctx.ws;
488
- if (ws && ws.readyState === 1) {
489
- ws.send(JSON.stringify({ type: "set_server_default_effort", effort: lvl.value }));
490
- }
491
- var btns = bar.querySelectorAll(".settings-btn-option");
492
- for (var j = 0; j < btns.length; j++) btns[j].classList.remove("active");
493
- btn.classList.add("active");
494
- });
495
- bar.appendChild(btn);
496
- })(SS_EFFORT_LEVELS[i]);
497
- }
384
+ renderEffortBar("ss", ssDefaultsOpts());
498
385
  }
499
386
 
500
- function updateSsBetaCard(overrideModel) {
501
- var model = overrideModel || ctx.currentModel || ctx._currentModelValue || "";
502
- var card = document.getElementById("ss-beta-card");
503
- if (card) {
504
- card.style.display = ssIsSonnetModel(model) ? "" : "none";
505
- }
506
-
507
- var toggle = document.getElementById("ss-beta-1m");
508
- if (toggle) {
509
- var betas = ctx.currentBetas || [];
510
- var hasBeta = false;
511
- for (var i = 0; i < betas.length; i++) {
512
- if (betas[i].indexOf("context-1m") !== -1) { hasBeta = true; break; }
513
- }
514
- toggle.checked = hasBeta;
515
- toggle.onchange = function () {
516
- ssToggleBeta1m(this.checked);
517
- };
518
- }
387
+ function updateThinkingBar() {
388
+ renderThinkingBar("ss", ssDefaultsOpts());
519
389
  }
520
390
 
521
- function ssToggleBeta1m(enable) {
522
- var betas = ctx.currentBetas || [];
523
- var newBetas;
524
- if (enable) {
525
- newBetas = betas.slice();
526
- newBetas.push("context-1m-2025-08-07");
527
- } else {
528
- newBetas = [];
529
- for (var i = 0; i < betas.length; i++) {
530
- if (betas[i].indexOf("context-1m") === -1) {
531
- newBetas.push(betas[i]);
532
- }
533
- }
534
- }
535
- var ws = ctx.ws;
536
- if (ws && ws.readyState === 1) {
537
- ws.send(JSON.stringify({ type: "set_betas", betas: newBetas }));
538
- }
391
+ function updateSsBetaCard(overrideModel) {
392
+ renderBetaCard("ss", Object.assign(ssDefaultsOpts(), { overrideModel: overrideModel }));
539
393
  }
540
394
 
541
395
  export function updateSettingsStats(data) {
@@ -561,6 +415,7 @@ export function updateSettingsModels(current, models) {
561
415
  updateModelList();
562
416
  updateModeList();
563
417
  updateEffortBar();
418
+ updateThinkingBar();
564
419
  updateSsBetaCard();
565
420
  }
566
421
  }
@@ -574,6 +429,20 @@ function requestDaemonConfig() {
574
429
  }
575
430
 
576
431
  export function updateDaemonConfig(config) {
432
+ // Nav header: show hostname (strip .local suffix, lowercase)
433
+ var nameEl = document.getElementById("settings-server-name");
434
+ if (nameEl && config.hostname) {
435
+ var displayHost = config.hostname.replace(/\.local$/i, "").toLowerCase();
436
+ nameEl.textContent = displayHost;
437
+ nameEl.title = config.hostname;
438
+ }
439
+
440
+ // Host
441
+ var hostnameEl = document.getElementById("settings-hostname");
442
+ var lanIpEl = document.getElementById("settings-lan-ip");
443
+ if (hostnameEl) hostnameEl.textContent = config.hostname || "-";
444
+ if (lanIpEl) lanIpEl.textContent = config.lanIp || "";
445
+
577
446
  // Port
578
447
  var portEl = document.getElementById("settings-port");
579
448
  if (portEl) portEl.textContent = String(config.port || "-");
@@ -599,14 +468,34 @@ export function updateDaemonConfig(config) {
599
468
  var keepAwakeToggle = document.getElementById("settings-keep-awake");
600
469
  if (keepAwakeToggle) keepAwakeToggle.checked = !!config.keepAwake;
601
470
 
602
- // Show keep awake card only on macOS
603
- var keepAwakeCard = document.getElementById("settings-keep-awake-card");
604
- if (keepAwakeCard) {
605
- if (config.platform === "darwin") {
606
- keepAwakeCard.classList.remove("hidden");
607
- } else {
608
- keepAwakeCard.classList.add("hidden");
609
- }
471
+ // Early Access toggle
472
+ var channelToggle = document.getElementById("settings-update-channel");
473
+ if (channelToggle) {
474
+ channelToggle.checked = (config.updateChannel === "beta");
475
+ channelToggle.onchange = function () {
476
+ var channel = channelToggle.checked ? "beta" : "stable";
477
+ if (ctx.ws && ctx.ws.readyState === 1) {
478
+ ctx.ws.send(JSON.stringify({ type: "set_update_channel", channel: channel }));
479
+ // Auto-trigger update check after channel change
480
+ setTimeout(function () {
481
+ ctx.ws.send(JSON.stringify({ type: "check_update" }));
482
+ }, 200);
483
+ }
484
+ };
485
+ }
486
+
487
+ // Show keep awake section/nav only on macOS
488
+ var keepAwakeSection = document.getElementById("settings-keep-awake-section");
489
+ var keepAwakeNav = document.getElementById("settings-keep-awake-nav");
490
+ var keepAwakeOpt = document.getElementById("settings-keep-awake-opt");
491
+ if (config.platform === "darwin") {
492
+ if (keepAwakeSection) keepAwakeSection.classList.remove("hidden");
493
+ if (keepAwakeNav) keepAwakeNav.classList.remove("hidden");
494
+ if (keepAwakeOpt) keepAwakeOpt.classList.remove("hidden");
495
+ } else {
496
+ if (keepAwakeSection) keepAwakeSection.classList.add("hidden");
497
+ if (keepAwakeNav) keepAwakeNav.classList.add("hidden");
498
+ if (keepAwakeOpt) keepAwakeOpt.classList.add("hidden");
610
499
  }
611
500
  }
612
501
 
@@ -632,7 +521,7 @@ export function handleRestartResult(msg) {
632
521
  showToast("Server is restarting...");
633
522
  } else {
634
523
  if (restartBtn) {
635
- restartBtn.textContent = "Restart Server";
524
+ restartBtn.textContent = "Restart";
636
525
  restartBtn.disabled = false;
637
526
  }
638
527
  if (errorEl) {