clay-server 2.26.0-beta.3 → 2.26.0-beta.5

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.
package/lib/public/app.js CHANGED
@@ -12,6 +12,7 @@ import { initInput, clearPendingImages, handleInputSync, autoResize, builtinComm
12
12
  import { initQrCode, triggerShare } from './modules/qrcode.js';
13
13
  import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
14
14
  import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
15
+ import { initContextSources, updateTerminalList, handleContextSourcesState, getActiveSources, hasActiveSources } from './modules/context-sources.js';
15
16
  import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, openArchive, closeArchive, isArchiveOpen, hideNotes, showNotes, isNotesVisible } from './modules/sticky-notes.js';
16
17
  import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentTheme } from './modules/theme.js';
17
18
  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';
@@ -2598,6 +2599,9 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
2598
2599
  var contextMiniLabel = $("context-mini-label");
2599
2600
  var contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0 };
2600
2601
  var headerContextEl = null;
2602
+ var richContextUsage = null;
2603
+ var ctxPopoverEl = null;
2604
+ var ctxPopoverVisible = false;
2601
2605
 
2602
2606
  // Known context window sizes per model (fallback when SDK omits feature flag)
2603
2607
  var KNOWN_CONTEXT_WINDOWS = {
@@ -2645,6 +2649,14 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
2645
2649
  headerContextEl.className = "header-context";
2646
2650
  headerContextEl.innerHTML = '<div class="header-context-bar"><div class="header-context-fill"></div></div><span class="header-context-label"></span>';
2647
2651
  statusArea.insertBefore(headerContextEl, statusArea.firstChild);
2652
+ headerContextEl.addEventListener("mouseenter", function() {
2653
+ if (richContextUsage) {
2654
+ showCtxPopover();
2655
+ }
2656
+ });
2657
+ headerContextEl.addEventListener("mouseleave", function() {
2658
+ ctxHoverTimer = setTimeout(hideCtxPopover, 120);
2659
+ });
2648
2660
  }
2649
2661
  if (headerContextEl) {
2650
2662
  var hFill = headerContextEl.querySelector(".header-context-fill");
@@ -2652,7 +2664,12 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
2652
2664
  hFill.style.width = pct.toFixed(1) + "%";
2653
2665
  hFill.className = "header-context-fill" + cls;
2654
2666
  hLabel.textContent = pct.toFixed(0) + "%";
2655
- headerContextEl.dataset.tip = "Context window " + pct.toFixed(0) + "% used (" + formatTokens(used) + " / " + formatTokens(win) + " tokens)";
2667
+ // Use data-tip as fallback when rich data is not yet loaded
2668
+ if (richContextUsage) {
2669
+ headerContextEl.removeAttribute("data-tip");
2670
+ } else {
2671
+ headerContextEl.dataset.tip = "Context window " + pct.toFixed(0) + "% used (" + formatTokens(used) + " / " + formatTokens(win) + " tokens)";
2672
+ }
2656
2673
  }
2657
2674
  }
2658
2675
  contextUsedEl.textContent = formatTokens(used);
@@ -2717,9 +2734,158 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
2717
2734
 
2718
2735
  function resetContextData() {
2719
2736
  contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0 };
2737
+ richContextUsage = null;
2738
+ hideCtxPopover();
2720
2739
  updateContextPanel();
2721
2740
  }
2722
2741
 
2742
+ // --- Rich context usage popover ---
2743
+
2744
+ var ctxHoverTimer = null;
2745
+
2746
+ function ensureCtxPopover() {
2747
+ if (ctxPopoverEl) return;
2748
+ ctxPopoverEl = document.createElement("div");
2749
+ ctxPopoverEl.className = "context-usage-popover hidden";
2750
+ // Keep popover open when hovering over it
2751
+ ctxPopoverEl.addEventListener("mouseenter", function() {
2752
+ if (ctxHoverTimer) { clearTimeout(ctxHoverTimer); ctxHoverTimer = null; }
2753
+ });
2754
+ ctxPopoverEl.addEventListener("mouseleave", function() {
2755
+ hideCtxPopover();
2756
+ });
2757
+ }
2758
+
2759
+ function showCtxPopover() {
2760
+ if (!headerContextEl || !richContextUsage) return;
2761
+ if (ctxHoverTimer) { clearTimeout(ctxHoverTimer); ctxHoverTimer = null; }
2762
+ ensureCtxPopover();
2763
+ headerContextEl.appendChild(ctxPopoverEl);
2764
+ renderCtxPopover();
2765
+ ctxPopoverEl.classList.remove("hidden");
2766
+ ctxPopoverVisible = true;
2767
+ }
2768
+
2769
+ function hideCtxPopover() {
2770
+ if (!ctxPopoverEl) return;
2771
+ ctxPopoverEl.classList.add("hidden");
2772
+ ctxPopoverVisible = false;
2773
+ }
2774
+
2775
+ // Categories to hide from the legend (noise, not actionable)
2776
+ var CTX_HIDDEN_CATS = { "Free space": 1, "Autocompact buffer": 1 };
2777
+
2778
+ function renderCtxPopover() {
2779
+ if (!ctxPopoverEl || !richContextUsage) return;
2780
+ var d = richContextUsage;
2781
+ var cats = d.categories || [];
2782
+ var total = d.totalTokens || 0;
2783
+ var max = d.maxTokens || 0;
2784
+ var pct = d.percentage != null ? d.percentage : (max > 0 ? (total / max) * 100 : 0);
2785
+
2786
+ var html = "";
2787
+
2788
+ // Header
2789
+ html += '<div class="ctx-pop-header">';
2790
+ html += '<span class="ctx-pop-model">' + escHtml(d.model || contextData.model || "-") + '</span>';
2791
+ html += '<span class="ctx-pop-pct">' + pct.toFixed(0) + '%';
2792
+ html += '<span class="ctx-pop-tokens">' + formatTokens(total) + ' / ' + formatTokens(max) + '</span>';
2793
+ html += '</span>';
2794
+ html += '</div>';
2795
+
2796
+ // Category emoji map
2797
+ var CTX_EMOJI = {
2798
+ "System prompt": "\ud83d\udcdc", "System tools": "\ud83d\udee0\ufe0f",
2799
+ "Memory files": "\ud83d\udcc1", "Skills": "\u26a1", "Messages": "\ud83d\udcac",
2800
+ "MCP tools": "\ud83d\udd0c", "Agents": "\ud83e\udd16", "Deferred tools": "\ud83d\udce6"
2801
+ };
2802
+
2803
+ // Stacked bar
2804
+ if (cats.length > 0 && max > 0) {
2805
+ html += '<div class="ctx-cat-bar">';
2806
+ for (var i = 0; i < cats.length; i++) {
2807
+ var cat = cats[i];
2808
+ if (cat.isDeferred || !cat.tokens || CTX_HIDDEN_CATS[cat.name]) continue;
2809
+ var w = Math.max(0.3, (cat.tokens / max) * 100);
2810
+ html += '<div style="width:' + w.toFixed(2) + '%;background:' + escHtml(cat.color) + '"></div>';
2811
+ }
2812
+ html += '</div>';
2813
+
2814
+ // Legend
2815
+ html += '<div class="ctx-cat-legend">';
2816
+ for (var j = 0; j < cats.length; j++) {
2817
+ var c = cats[j];
2818
+ if (c.isDeferred || !c.tokens || CTX_HIDDEN_CATS[c.name]) continue;
2819
+ var emoji = CTX_EMOJI[c.name] || "\ud83d\udcca";
2820
+ html += '<div class="ctx-cat-item">';
2821
+ html += '<span class="ctx-cat-name">' + em(emoji) + ' ' + escHtml(c.name) + '</span>';
2822
+ html += '<span class="ctx-cat-value">' + formatTokens(c.tokens) + '</span>';
2823
+ html += '</div>';
2824
+ }
2825
+ html += '</div>';
2826
+ }
2827
+
2828
+ // Message breakdown
2829
+ var mb = d.messageBreakdown;
2830
+ if (mb) {
2831
+ html += '<div class="ctx-pop-divider"></div>';
2832
+ html += '<div class="ctx-pop-section-label">' + em("\ud83d\udcac") + ' Messages</div>';
2833
+ if (mb.userMessageTokens) {
2834
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83d\udc64") + ' User</span><span class="ctx-pop-row-value">' + formatTokens(mb.userMessageTokens) + '</span></div>';
2835
+ }
2836
+ if (mb.assistantMessageTokens) {
2837
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83e\udd16") + ' Assistant</span><span class="ctx-pop-row-value">' + formatTokens(mb.assistantMessageTokens) + '</span></div>';
2838
+ }
2839
+ if (mb.toolCallTokens) {
2840
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83d\udee0\ufe0f") + ' Tool calls</span><span class="ctx-pop-row-value">' + formatTokens(mb.toolCallTokens) + '</span></div>';
2841
+ }
2842
+ if (mb.toolResultTokens) {
2843
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83d\udccb") + ' Tool results</span><span class="ctx-pop-row-value">' + formatTokens(mb.toolResultTokens) + '</span></div>';
2844
+ }
2845
+ if (mb.attachmentTokens) {
2846
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83d\udcce") + ' Attachments</span><span class="ctx-pop-row-value">' + formatTokens(mb.attachmentTokens) + '</span></div>';
2847
+ }
2848
+ }
2849
+
2850
+ // Memory files
2851
+ var mf = d.memoryFiles;
2852
+ if (mf && mf.length > 0) {
2853
+ html += '<div class="ctx-pop-divider"></div>';
2854
+ html += '<div class="ctx-pop-section-label">' + em("\ud83d\udcc1") + ' Memory Files</div>';
2855
+ var baseCount = {};
2856
+ for (var mc = 0; mc < mf.length; mc++) {
2857
+ var bn = mf[mc].path.split("/").pop() || mf[mc].path;
2858
+ baseCount[bn] = (baseCount[bn] || 0) + 1;
2859
+ }
2860
+ for (var mi = 0; mi < mf.length; mi++) {
2861
+ var fpath = mf[mi].path;
2862
+ var fname = fpath.split("/").pop() || fpath;
2863
+ if (baseCount[fname] > 1) {
2864
+ var parts = fpath.split("/");
2865
+ fname = parts.length >= 2 ? parts[parts.length - 2] + "/" + fname : fpath;
2866
+ }
2867
+ html += '<div class="ctx-pop-row"><span class="ctx-pop-row-label">' + em("\ud83d\udcc4") + ' ' + escHtml(fname) + '</span><span class="ctx-pop-row-value">' + formatTokens(mf[mi].tokens) + '</span></div>';
2868
+ }
2869
+ }
2870
+
2871
+ // Auto-compact note
2872
+ if (d.isAutoCompactEnabled && d.autoCompactThreshold) {
2873
+ html += '<div class="ctx-pop-note">' + em("\u267b\ufe0f") + ' Auto-compact at ' + formatTokens(d.autoCompactThreshold) + '</div>';
2874
+ }
2875
+
2876
+ ctxPopoverEl.innerHTML = html;
2877
+ }
2878
+
2879
+ function escHtml(s) {
2880
+ var div = document.createElement("div");
2881
+ div.textContent = s;
2882
+ return div.innerHTML;
2883
+ }
2884
+
2885
+ function em(emoji) {
2886
+ return '<span class="ctx-emoji">' + emoji + '</span>';
2887
+ }
2888
+
2723
2889
  function resetContext() {
2724
2890
  resetContextData();
2725
2891
  // Keep view state, just reset data
@@ -3663,23 +3829,13 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
3663
3829
  suggestionChipsEl.innerHTML = "";
3664
3830
  var chip = document.createElement("button");
3665
3831
  chip.className = "suggestion-chip";
3666
- chip.innerHTML =
3667
- '<span class="suggestion-chip-send">' + iconHtml("sparkles") +
3668
- '<span class="suggestion-chip-text">' + escapeHtml(suggestion) + '</span></span>' +
3669
- '<span class="suggestion-chip-edit">' + iconHtml("pencil") + '</span>';
3832
+ chip.innerHTML = iconHtml("sparkles") +
3833
+ '<span class="suggestion-chip-text">' + escapeHtml(suggestion) + '</span>';
3670
3834
  chip.addEventListener("click", function () {
3671
3835
  inputEl.value = suggestion;
3672
3836
  hideSuggestionChips();
3673
3837
  sendMessage();
3674
3838
  });
3675
- chip.querySelector(".suggestion-chip-edit").addEventListener("click", function (e) {
3676
- e.stopPropagation();
3677
- inputEl.value = suggestion;
3678
- inputEl.focus();
3679
- inputEl.select();
3680
- autoResize();
3681
- hideSuggestionChips();
3682
- });
3683
3839
  suggestionChipsEl.appendChild(chip);
3684
3840
  suggestionChipsEl.classList.remove("hidden");
3685
3841
  refreshIcons();
@@ -4061,6 +4217,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
4061
4217
 
4062
4218
  case "history_done":
4063
4219
  replayingHistory = false;
4220
+ // Restore cached rich context usage BEFORE updateContextPanel runs
4221
+ if (msg.contextUsage) {
4222
+ richContextUsage = msg.contextUsage;
4223
+ }
4064
4224
  // Restore accurate context data from the last result in full history
4065
4225
  if (msg.lastUsage || msg.lastModelUsage) {
4066
4226
  accumulateContext(msg.lastCost, msg.lastUsage, msg.lastModelUsage, msg.lastStreamInputTokens);
@@ -4623,6 +4783,14 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
4623
4783
  accumulateContext(msg.cost, msg.usage, msg.modelUsage, msg.lastStreamInputTokens);
4624
4784
  break;
4625
4785
 
4786
+ case "context_usage":
4787
+ if (msg.data && !replayingHistory) {
4788
+ richContextUsage = msg.data;
4789
+ if (headerContextEl) headerContextEl.removeAttribute("data-tip");
4790
+ if (ctxPopoverVisible) renderCtxPopover();
4791
+ }
4792
+ break;
4793
+
4626
4794
  case "done":
4627
4795
  setActivity(null);
4628
4796
  stopThinking();
@@ -4797,6 +4965,11 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
4797
4965
 
4798
4966
  case "term_list":
4799
4967
  handleTermList(msg);
4968
+ updateTerminalList(msg.terminals);
4969
+ break;
4970
+
4971
+ case "context_sources_state":
4972
+ handleContextSourcesState(msg);
4800
4973
  break;
4801
4974
 
4802
4975
  case "term_created":
@@ -5763,6 +5936,12 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
5763
5936
  fileViewerEl: $("file-viewer"),
5764
5937
  });
5765
5938
 
5939
+ // --- Context Sources ---
5940
+ initContextSources({
5941
+ get ws() { return ws; },
5942
+ get connected() { return connected; },
5943
+ });
5944
+
5766
5945
  // --- Playbook Engine ---
5767
5946
  initPlaybook();
5768
5947
 
@@ -271,6 +271,165 @@
271
271
  border-color: var(--error);
272
272
  }
273
273
 
274
+ /* ==========================================================================
275
+ Context Sources — chips above input
276
+ ========================================================================== */
277
+
278
+ #context-sources-bar {
279
+ display: flex;
280
+ align-items: center;
281
+ flex-wrap: wrap;
282
+ gap: 4px;
283
+ padding: 0 8px 4px;
284
+ position: relative;
285
+ }
286
+
287
+ #context-sources-add {
288
+ display: inline-flex;
289
+ align-items: center;
290
+ gap: 6px;
291
+ padding: 6px 12px;
292
+ border-radius: 6px;
293
+ border: 1px dashed var(--border);
294
+ background: transparent;
295
+ color: var(--text-dimmer);
296
+ font-family: inherit;
297
+ font-size: 12px;
298
+ font-weight: 500;
299
+ cursor: pointer;
300
+ transition: color 0.15s, border-color 0.15s, background 0.15s;
301
+ }
302
+
303
+ #context-sources-add .lucide { width: 12px; height: 12px; }
304
+
305
+ #context-sources-add:hover {
306
+ color: var(--text-secondary);
307
+ border-color: var(--text-dimmer);
308
+ background: var(--sidebar-hover);
309
+ }
310
+
311
+ #context-sources-chips {
312
+ display: flex;
313
+ align-items: center;
314
+ flex-wrap: wrap;
315
+ gap: 4px;
316
+ }
317
+
318
+ .context-chip {
319
+ display: inline-flex;
320
+ align-items: stretch;
321
+ padding: 0;
322
+ border-radius: 8px;
323
+ background: var(--bg-alt);
324
+ color: var(--text);
325
+ font-size: 13px;
326
+ font-weight: 500;
327
+ line-height: 1;
328
+ white-space: nowrap;
329
+ border: 1px solid var(--border);
330
+ transition: border-color 0.15s;
331
+ }
332
+
333
+ .context-chip-label {
334
+ display: inline-flex;
335
+ align-items: center;
336
+ gap: 6px;
337
+ padding: 6px 10px 6px 12px;
338
+ }
339
+
340
+ .context-chip-label .lucide { width: 14px; height: 14px; flex-shrink: 0; color: var(--accent); }
341
+
342
+ .context-chip-remove {
343
+ display: inline-flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ width: 30px;
347
+ border: none;
348
+ border-left: 1px solid var(--border);
349
+ background: transparent;
350
+ color: var(--text-muted);
351
+ cursor: pointer;
352
+ padding: 0;
353
+ border-radius: 0 8px 8px 0;
354
+ transition: color 0.15s, background 0.15s;
355
+ }
356
+
357
+ .context-chip-remove:hover {
358
+ color: var(--text);
359
+ background: rgba(var(--overlay-rgb), 0.08);
360
+ }
361
+
362
+ .context-chip-remove .lucide { width: 14px; height: 14px; }
363
+
364
+ #context-sources-picker.hidden { display: none; }
365
+
366
+ #context-sources-picker {
367
+ position: absolute;
368
+ bottom: calc(100% + 4px);
369
+ left: 0;
370
+ min-width: 200px;
371
+ background: var(--sidebar-bg);
372
+ border: 1px solid var(--border);
373
+ border-radius: 10px;
374
+ padding: 4px 0;
375
+ box-shadow: 0 4px 12px rgba(var(--shadow-rgb), 0.15);
376
+ z-index: 200;
377
+ animation: ctxPickerAppear 0.12s ease-out;
378
+ }
379
+
380
+ @keyframes ctxPickerAppear {
381
+ from { opacity: 0; transform: scale(0.95); }
382
+ to { opacity: 1; transform: scale(1); }
383
+ }
384
+
385
+ .context-picker-section-label {
386
+ font-size: 10px;
387
+ font-weight: 600;
388
+ color: var(--text-dimmer);
389
+ text-transform: uppercase;
390
+ letter-spacing: 0.5px;
391
+ padding: 8px 12px 4px;
392
+ }
393
+
394
+ .context-picker-item {
395
+ display: flex;
396
+ align-items: center;
397
+ gap: 8px;
398
+ width: 100%;
399
+ padding: 8px 12px;
400
+ font-size: 13px;
401
+ color: var(--text-secondary);
402
+ background: none;
403
+ border: none;
404
+ cursor: pointer;
405
+ transition: background 0.15s;
406
+ }
407
+
408
+ .context-picker-item:hover {
409
+ background: rgba(var(--overlay-rgb), 0.05);
410
+ }
411
+
412
+ .context-picker-item .lucide { width: 14px; height: 14px; flex-shrink: 0; }
413
+
414
+ .context-picker-check {
415
+ margin-left: auto;
416
+ width: 14px;
417
+ height: 14px;
418
+ color: var(--accent);
419
+ display: none;
420
+ }
421
+
422
+ .context-picker-item.active .context-picker-check {
423
+ display: block;
424
+ }
425
+
426
+ .context-picker-empty {
427
+ padding: 12px;
428
+ color: var(--text-dimmer);
429
+ font-size: 13px;
430
+ text-align: center;
431
+ }
432
+
274
433
  /* ==========================================================================
275
434
  Input Area — Claude-style unified container
276
435
  ========================================================================== */
@@ -521,98 +680,53 @@
521
680
  #suggestion-chips {
522
681
  display: flex;
523
682
  flex-wrap: wrap;
524
- gap: 6px;
525
- padding: 8px 6px;
683
+ gap: 4px;
684
+ padding: 4px 6px;
526
685
  position: absolute;
527
686
  bottom: 100%;
528
687
  left: 0;
529
688
  right: 0;
530
689
  z-index: 5;
531
- background: transparent;
532
690
  }
533
691
 
534
692
  #suggestion-chips.hidden { display: none; }
535
693
 
536
694
  .suggestion-chip {
537
695
  display: inline-flex;
538
- align-items: stretch;
539
- padding: 0;
540
- border-radius: 16px;
696
+ align-items: center;
697
+ gap: 5px;
698
+ padding: 4px 10px 4px 8px;
699
+ border-radius: 6px;
541
700
  border: 1px solid var(--border);
542
- background: var(--bg-alt);
701
+ background: rgba(var(--overlay-rgb), 0.08);
543
702
  color: var(--text-secondary);
544
- font-size: 13px;
703
+ font-size: 12px;
545
704
  font-family: inherit;
546
705
  cursor: pointer;
547
- transition: border-color 0.15s;
706
+ transition: border-color 0.15s, background 0.15s, color 0.15s;
548
707
  text-align: left;
549
708
  max-width: 100%;
550
- line-height: 1.3;
551
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
709
+ line-height: 1.2;
552
710
  }
553
711
 
554
712
  .suggestion-chip:hover {
555
713
  border-color: var(--accent);
714
+ background: var(--accent-bg);
715
+ color: var(--accent);
556
716
  }
557
717
 
558
718
  .suggestion-chip .lucide {
559
- width: 14px;
560
- height: 14px;
719
+ width: 12px;
720
+ height: 12px;
561
721
  flex-shrink: 0;
562
722
  color: var(--accent);
563
723
  }
564
724
 
565
- .suggestion-chip-send {
566
- display: inline-flex;
567
- align-items: center;
568
- gap: 5px;
569
- flex: 1;
570
- min-width: 0;
571
- padding: 8px 10px 8px 14px;
572
- border-radius: 16px 0 0 16px;
573
- transition: background 0.15s, color 0.15s;
574
- }
575
-
576
- .suggestion-chip-send:hover {
577
- background: var(--accent-bg);
578
- color: var(--accent);
579
- }
580
-
581
725
  .suggestion-chip-text {
582
726
  flex: 1;
583
727
  min-width: 0;
584
728
  }
585
729
 
586
- .suggestion-chip-edit {
587
- display: inline-flex;
588
- align-items: center;
589
- justify-content: center;
590
- padding: 8px 12px;
591
- border-left: 1px solid var(--border);
592
- border-radius: 0 16px 16px 0;
593
- background: rgba(128, 128, 128, 0.07);
594
- cursor: pointer;
595
- transition: background 0.15s, border-color 0.15s;
596
- }
597
-
598
- .suggestion-chip:hover .suggestion-chip-edit {
599
- border-left-color: var(--accent);
600
- }
601
-
602
- .suggestion-chip-edit:hover {
603
- background: var(--accent-bg);
604
- }
605
-
606
- .suggestion-chip-edit .lucide {
607
- width: 14px;
608
- height: 14px;
609
- color: var(--text-secondary);
610
- }
611
-
612
- .suggestion-chip-edit:hover .lucide {
613
- color: var(--accent);
614
- }
615
-
616
730
  /* ==========================================================================
617
731
  Animations
618
732
  ========================================================================== */
@@ -474,6 +474,13 @@
474
474
 
475
475
  #config-chip .lucide { width: 10px; height: 10px; }
476
476
  #config-chip .config-chip-icon { display: none; }
477
+
478
+ @media (max-width: 1000px) {
479
+ #config-chip .config-chip-icon { display: inline-flex; width: 16px; height: 16px; }
480
+ #config-chip-label { display: none; }
481
+ #config-chip .lucide:last-child { display: none; }
482
+ #config-chip { padding: 0 6px; }
483
+ }
477
484
  #config-chip:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.06); }
478
485
  #config-chip.active { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.06); }
479
486
 
@@ -257,6 +257,16 @@
257
257
  letter-spacing: 0.5px;
258
258
  }
259
259
 
260
+ /* --- Section labels --- */
261
+ .sidebar-section-label {
262
+ font-size: 11px;
263
+ font-weight: 600;
264
+ color: var(--text-dimmer);
265
+ text-transform: uppercase;
266
+ letter-spacing: 0.5px;
267
+ padding: 4px 12px 2px;
268
+ }
269
+
260
270
  /* --- Tools section --- */
261
271
  #sidebar-tools {
262
272
  flex-shrink: 0;