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/project-mate-interaction.js +760 -0
- package/lib/project-memory.js +677 -0
- package/lib/project.js +192 -1371
- package/lib/public/app.js +192 -13
- package/lib/public/css/input.css +173 -59
- package/lib/public/css/menus.css +7 -0
- package/lib/public/css/sidebar.css +10 -0
- package/lib/public/css/title-bar.css +186 -0
- package/lib/public/index.html +7 -0
- package/lib/public/modules/context-sources.js +226 -0
- package/lib/sdk-bridge.js +19 -0
- package/lib/sdk-worker.js +13 -1
- package/lib/sessions.js +16 -1
- package/lib/terminal-manager.js +20 -4
- package/package.json +2 -2
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
|
-
|
|
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-
|
|
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
|
|
package/lib/public/css/input.css
CHANGED
|
@@ -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:
|
|
525
|
-
padding:
|
|
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:
|
|
539
|
-
|
|
540
|
-
|
|
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(--
|
|
701
|
+
background: rgba(var(--overlay-rgb), 0.08);
|
|
543
702
|
color: var(--text-secondary);
|
|
544
|
-
font-size:
|
|
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.
|
|
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:
|
|
560
|
-
height:
|
|
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
|
========================================================================== */
|
package/lib/public/css/menus.css
CHANGED
|
@@ -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;
|