clay-server 2.31.0 → 2.32.0-beta.1
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/browser-mcp-server.js +32 -44
- package/lib/debate-mcp-server.js +14 -31
- package/lib/mcp-local.js +31 -1
- package/lib/project-connection.js +4 -2
- package/lib/project-filesystem.js +47 -1
- package/lib/project-http.js +75 -8
- package/lib/project-mcp.js +4 -0
- package/lib/project-sessions.js +88 -51
- package/lib/project-user-message.js +12 -7
- package/lib/project.js +204 -90
- package/lib/public/app.js +123 -448
- package/lib/public/codex-avatar.png +0 -0
- package/lib/public/css/debate.css +3 -2
- package/lib/public/css/filebrowser.css +91 -1
- package/lib/public/css/icon-strip.css +21 -5
- package/lib/public/css/input.css +181 -100
- package/lib/public/css/mates.css +43 -0
- package/lib/public/css/mention.css +48 -4
- package/lib/public/css/menus.css +1 -1
- package/lib/public/css/messages.css +2 -0
- package/lib/public/css/notifications-center.css +19 -0
- package/lib/public/index.html +46 -24
- package/lib/public/modules/app-connection.js +138 -37
- package/lib/public/modules/app-cursors.js +18 -17
- package/lib/public/modules/app-debate-ui.js +9 -9
- package/lib/public/modules/app-dm.js +170 -131
- package/lib/public/modules/app-favicon.js +28 -26
- package/lib/public/modules/app-header.js +79 -68
- package/lib/public/modules/app-home-hub.js +55 -47
- package/lib/public/modules/app-loop-ui.js +34 -18
- package/lib/public/modules/app-loop-wizard.js +6 -6
- package/lib/public/modules/app-messages.js +195 -152
- package/lib/public/modules/app-misc.js +23 -12
- package/lib/public/modules/app-notifications.js +91 -3
- package/lib/public/modules/app-panels.js +203 -49
- package/lib/public/modules/app-projects.js +159 -150
- package/lib/public/modules/app-rate-limit.js +5 -4
- package/lib/public/modules/app-rendering.js +149 -101
- package/lib/public/modules/app-skills-install.js +4 -4
- package/lib/public/modules/context-sources.js +12 -41
- package/lib/public/modules/dom-refs.js +21 -0
- package/lib/public/modules/filebrowser.js +173 -2
- package/lib/public/modules/input.js +86 -0
- package/lib/public/modules/mate-sidebar.js +38 -0
- package/lib/public/modules/mention.js +24 -6
- package/lib/public/modules/scheduler.js +1 -1
- package/lib/public/modules/sidebar-mates.js +66 -34
- package/lib/public/modules/sidebar-mobile.js +34 -30
- package/lib/public/modules/sidebar-projects.js +60 -57
- package/lib/public/modules/sidebar-sessions.js +75 -69
- package/lib/public/modules/sidebar.js +12 -20
- package/lib/public/modules/skills.js +8 -9
- package/lib/public/modules/sticky-notes.js +1 -2
- package/lib/public/modules/store.js +9 -2
- package/lib/public/modules/stt.js +4 -1
- package/lib/public/modules/tools.js +14 -9
- package/lib/sdk-bridge.js +511 -1113
- package/lib/sdk-message-processor.js +123 -134
- package/lib/sdk-worker.js +4 -0
- package/lib/server-dm.js +1 -0
- package/lib/server.js +86 -1
- package/lib/sessions.js +47 -36
- package/lib/ws-schema.js +2 -0
- package/lib/yoke/adapters/claude-worker.js +559 -0
- package/lib/yoke/adapters/claude.js +1418 -0
- package/lib/yoke/adapters/codex.js +968 -0
- package/lib/yoke/adapters/gemini.js +668 -0
- package/lib/yoke/codex-app-server.js +307 -0
- package/lib/yoke/index.js +199 -0
- package/lib/yoke/instructions.js +62 -0
- package/lib/yoke/interface.js +92 -0
- package/lib/yoke/mcp-bridge-server.js +294 -0
- package/lib/yoke/package.json +7 -0
- package/package.json +3 -1
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// Extracted from app.js (PR-34)
|
|
3
3
|
|
|
4
4
|
import { refreshIcons } from './icons.js';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { store } from './store.js';
|
|
6
|
+
import { getSendBtn, getStatusDot } from './dom-refs.js';
|
|
7
|
+
import { onThemeChange } from './theme.js';
|
|
8
|
+
import { getActivityEl, setActivityEl, addToMessages, scrollToBottom } from './app-rendering.js';
|
|
7
9
|
|
|
8
10
|
// --- Module-owned state ---
|
|
9
11
|
var faviconLink, faviconOrigHref, faviconCanvas, faviconCtx, faviconImg, faviconImgReady;
|
|
@@ -14,9 +16,7 @@ var ioTimer = null;
|
|
|
14
16
|
var sessionIoTimers = {};
|
|
15
17
|
var crossProjectBlinkTimer = null;
|
|
16
18
|
|
|
17
|
-
export function initFavicon(
|
|
18
|
-
_ctx = ctx;
|
|
19
|
-
|
|
19
|
+
export function initFavicon() {
|
|
20
20
|
faviconLink = document.querySelector('link[rel="icon"]');
|
|
21
21
|
faviconCanvas = document.createElement("canvas");
|
|
22
22
|
faviconCanvas.width = 32;
|
|
@@ -29,11 +29,11 @@ export function initFavicon(ctx) {
|
|
|
29
29
|
(function () {
|
|
30
30
|
faviconImg = new Image();
|
|
31
31
|
faviconImg.onload = function () { faviconImgReady = true; };
|
|
32
|
-
faviconImg.src =
|
|
32
|
+
faviconImg.src = (store.get('basePath') || "") + "favicon-banded.png";
|
|
33
33
|
})();
|
|
34
34
|
|
|
35
35
|
// Reset cached favicon href on theme change
|
|
36
|
-
|
|
36
|
+
onThemeChange(function () { faviconOrigHref = null; });
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function updateFavicon(bgColor) {
|
|
@@ -84,21 +84,22 @@ export function drawFaviconAnimFrame() {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
export function setSendBtnMode(mode) {
|
|
87
|
+
var sendBtn = getSendBtn();
|
|
87
88
|
if (mode === "stop") {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
sendBtn.disabled = false;
|
|
90
|
+
sendBtn.classList.add("stop");
|
|
91
|
+
sendBtn.innerHTML = '<i data-lucide="square"></i>';
|
|
91
92
|
} else {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
sendBtn.disabled = false;
|
|
94
|
+
sendBtn.classList.remove("stop");
|
|
95
|
+
sendBtn.innerHTML = '<i data-lucide="arrow-up"></i>';
|
|
95
96
|
}
|
|
96
97
|
refreshIcons();
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
export function blinkIO() {
|
|
100
|
-
if (!
|
|
101
|
-
var dot =
|
|
101
|
+
if (!store.get('connected')) return;
|
|
102
|
+
var dot = getStatusDot();
|
|
102
103
|
if (dot) dot.classList.add("io");
|
|
103
104
|
// Also blink the active session's processing dot in sidebar (project or mate)
|
|
104
105
|
var sessionDot = document.querySelector(".session-item.active .session-processing") ||
|
|
@@ -114,17 +115,18 @@ export function blinkIO() {
|
|
|
114
115
|
}
|
|
115
116
|
// Mobile chat chip dot + mobile session dot
|
|
116
117
|
var mobileChipDot = null;
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
var _s = store.snap();
|
|
119
|
+
if (_s.dmMode && _s.dmTargetUser && _s.dmTargetUser.isMate) {
|
|
120
|
+
mobileChipDot = document.querySelector('.mobile-chat-chip[data-mate-id="' + _s.dmTargetUser.id + '"] .mobile-chat-chip-dot');
|
|
119
121
|
} else {
|
|
120
|
-
mobileChipDot = document.querySelector('.mobile-chat-chip[data-slug="' +
|
|
122
|
+
mobileChipDot = document.querySelector('.mobile-chat-chip[data-slug="' + _s.currentSlug + '"] .mobile-chat-chip-dot');
|
|
121
123
|
}
|
|
122
124
|
if (mobileChipDot) mobileChipDot.classList.add("io");
|
|
123
125
|
var mobileSessionDot = document.querySelector('.mobile-session-item.active .mobile-session-dot');
|
|
124
126
|
if (mobileSessionDot) mobileSessionDot.classList.add("io");
|
|
125
127
|
clearTimeout(ioTimer);
|
|
126
128
|
ioTimer = setTimeout(function () {
|
|
127
|
-
var d =
|
|
129
|
+
var d = getStatusDot();
|
|
128
130
|
if (d) d.classList.remove("io");
|
|
129
131
|
var sd = document.querySelector(".session-item.active .session-processing.io") ||
|
|
130
132
|
document.querySelector(".mate-session-item.active .session-processing.io");
|
|
@@ -194,19 +196,19 @@ export function stopUrgentBlink() {
|
|
|
194
196
|
|
|
195
197
|
export function setActivity(text) {
|
|
196
198
|
if (text) {
|
|
197
|
-
if (!
|
|
199
|
+
if (!getActivityEl()) {
|
|
198
200
|
var _actEl = document.createElement("div");
|
|
199
201
|
_actEl.className = "activity-inline";
|
|
200
202
|
_actEl.innerHTML =
|
|
201
203
|
'<div class="mate-thinking-dots"><span></span><span></span><span></span></div>';
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
setActivityEl(_actEl);
|
|
205
|
+
addToMessages(_actEl);
|
|
204
206
|
}
|
|
205
|
-
|
|
207
|
+
scrollToBottom();
|
|
206
208
|
} else {
|
|
207
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
if (getActivityEl()) {
|
|
210
|
+
getActivityEl().remove();
|
|
211
|
+
setActivityEl(null);
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
214
|
}
|
|
@@ -3,41 +3,49 @@
|
|
|
3
3
|
|
|
4
4
|
import { refreshIcons, iconHtml } from './icons.js';
|
|
5
5
|
import { escapeHtml, copyToClipboard } from './utils.js';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { store } from './store.js';
|
|
7
|
+
import { getWs } from './ws-ref.js';
|
|
8
|
+
import { getMessagesEl } from './dom-refs.js';
|
|
9
|
+
import { getActivityEl, setActivityEl, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, finalizeAssistantBlock } from './app-rendering.js';
|
|
10
|
+
import { processMessage } from './app-messages.js';
|
|
11
|
+
import { saveToolState, resetToolState, restoreToolState } from './tools.js';
|
|
12
|
+
import { getSessionUsage, setSessionUsage, getContextData, setContextData, updateContextPanel, updateUsagePanel } from './app-panels.js';
|
|
13
|
+
import { onHistoryPrepended as onSessionSearchHistoryPrepended } from './session-search.js';
|
|
8
14
|
|
|
9
15
|
// --- Module-owned state ---
|
|
10
16
|
var sessionInfoPopover = null;
|
|
11
17
|
var historySentinelObserver = null;
|
|
12
18
|
|
|
13
|
-
export function initHeader(
|
|
14
|
-
|
|
19
|
+
export function initHeader() {
|
|
20
|
+
var headerRenameBtn = document.getElementById("header-rename-btn");
|
|
21
|
+
var headerTitleEl = document.getElementById("header-title");
|
|
22
|
+
var headerInfoBtn = document.getElementById("header-info-btn");
|
|
15
23
|
|
|
16
24
|
// --- Header session rename ---
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
if (!
|
|
20
|
-
var currentText =
|
|
25
|
+
if (headerRenameBtn) {
|
|
26
|
+
headerRenameBtn.addEventListener("click", function () {
|
|
27
|
+
if (!store.get('activeSessionId')) return;
|
|
28
|
+
var currentText = headerTitleEl.textContent;
|
|
21
29
|
var input = document.createElement("input");
|
|
22
30
|
input.type = "text";
|
|
23
31
|
input.className = "header-rename-input";
|
|
24
32
|
input.value = currentText;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
headerTitleEl.style.display = "none";
|
|
34
|
+
headerRenameBtn.style.display = "none";
|
|
35
|
+
headerTitleEl.parentNode.insertBefore(input, headerTitleEl.nextSibling);
|
|
28
36
|
input.focus();
|
|
29
37
|
input.select();
|
|
30
38
|
|
|
31
39
|
function commit() {
|
|
32
40
|
var newTitle = input.value.trim();
|
|
33
|
-
var ws =
|
|
41
|
+
var ws = getWs();
|
|
34
42
|
if (newTitle && newTitle !== currentText && ws && ws.readyState === 1) {
|
|
35
|
-
ws.send(JSON.stringify({ type: "rename_session", id:
|
|
36
|
-
|
|
43
|
+
ws.send(JSON.stringify({ type: "rename_session", id: store.get('activeSessionId'), title: newTitle }));
|
|
44
|
+
headerTitleEl.textContent = newTitle;
|
|
37
45
|
}
|
|
38
46
|
input.remove();
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
headerTitleEl.style.display = "";
|
|
48
|
+
headerRenameBtn.style.display = "";
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
input.addEventListener("keydown", function (e) {
|
|
@@ -45,8 +53,8 @@ export function initHeader(ctx) {
|
|
|
45
53
|
if (e.key === "Escape") {
|
|
46
54
|
e.preventDefault();
|
|
47
55
|
input.remove();
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
headerTitleEl.style.display = "";
|
|
57
|
+
headerRenameBtn.style.display = "";
|
|
50
58
|
}
|
|
51
59
|
});
|
|
52
60
|
input.addEventListener("blur", commit);
|
|
@@ -54,8 +62,8 @@ export function initHeader(ctx) {
|
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
// --- Session info popover ---
|
|
57
|
-
if (
|
|
58
|
-
|
|
65
|
+
if (headerInfoBtn) {
|
|
66
|
+
headerInfoBtn.addEventListener("click", function (e) {
|
|
59
67
|
e.stopPropagation();
|
|
60
68
|
if (sessionInfoPopover) { closeSessionInfoPopover(); return; }
|
|
61
69
|
|
|
@@ -81,15 +89,16 @@ export function initHeader(ctx) {
|
|
|
81
89
|
pop.appendChild(row);
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
if (
|
|
92
|
+
var s = store.snap();
|
|
93
|
+
if (s.cliSessionId) addRow("Session ID", s.cliSessionId);
|
|
94
|
+
if (s.activeSessionId) addRow("Local ID", s.activeSessionId);
|
|
95
|
+
if (s.cliSessionId) addRow("Resume", "claude --resume " + s.cliSessionId);
|
|
87
96
|
|
|
88
97
|
document.body.appendChild(pop);
|
|
89
98
|
sessionInfoPopover = pop;
|
|
90
99
|
refreshIcons();
|
|
91
100
|
|
|
92
|
-
var btnRect =
|
|
101
|
+
var btnRect = headerInfoBtn.getBoundingClientRect();
|
|
93
102
|
pop.style.top = (btnRect.bottom + 6) + "px";
|
|
94
103
|
pop.style.left = btnRect.left + "px";
|
|
95
104
|
var popRect = pop.getBoundingClientRect();
|
|
@@ -114,8 +123,9 @@ export function closeSessionInfoPopover() {
|
|
|
114
123
|
}
|
|
115
124
|
|
|
116
125
|
export function updateHistorySentinel() {
|
|
117
|
-
var
|
|
118
|
-
|
|
126
|
+
var messagesEl = getMessagesEl();
|
|
127
|
+
var existing = messagesEl.querySelector(".history-sentinel");
|
|
128
|
+
if (store.get('historyFrom') > 0) {
|
|
119
129
|
if (!existing) {
|
|
120
130
|
var sentinel = document.createElement("div");
|
|
121
131
|
sentinel.className = "history-sentinel";
|
|
@@ -123,15 +133,15 @@ export function updateHistorySentinel() {
|
|
|
123
133
|
sentinel.querySelector(".load-more-btn").addEventListener("click", function () {
|
|
124
134
|
requestMoreHistory();
|
|
125
135
|
});
|
|
126
|
-
|
|
136
|
+
messagesEl.insertBefore(sentinel, messagesEl.firstChild);
|
|
127
137
|
|
|
128
138
|
// Auto-load when sentinel scrolls into view
|
|
129
139
|
if (historySentinelObserver) historySentinelObserver.disconnect();
|
|
130
140
|
historySentinelObserver = new IntersectionObserver(function (entries) {
|
|
131
|
-
if (entries[0].isIntersecting && !
|
|
141
|
+
if (entries[0].isIntersecting && !store.get('loadingMore') && store.get('historyFrom') > 0) {
|
|
132
142
|
requestMoreHistory();
|
|
133
143
|
}
|
|
134
|
-
}, { root:
|
|
144
|
+
}, { root: messagesEl, rootMargin: "200px 0px 0px 0px" });
|
|
135
145
|
historySentinelObserver.observe(sentinel);
|
|
136
146
|
}
|
|
137
147
|
} else {
|
|
@@ -141,89 +151,90 @@ export function updateHistorySentinel() {
|
|
|
141
151
|
}
|
|
142
152
|
|
|
143
153
|
export function requestMoreHistory() {
|
|
144
|
-
var ws =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
var ws = getWs();
|
|
155
|
+
var s = store.snap();
|
|
156
|
+
if (s.loadingMore || s.historyFrom <= 0 || !ws || !s.connected) return;
|
|
157
|
+
store.set({ loadingMore: true });
|
|
158
|
+
var messagesEl = getMessagesEl();
|
|
159
|
+
var btn = messagesEl.querySelector(".load-more-btn");
|
|
148
160
|
if (btn) btn.classList.add("loading");
|
|
149
|
-
ws.send(JSON.stringify({ type: "load_more_history", before:
|
|
161
|
+
ws.send(JSON.stringify({ type: "load_more_history", before: s.historyFrom }));
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
export function prependOlderHistory(items, meta) {
|
|
165
|
+
var messagesEl = getMessagesEl();
|
|
166
|
+
|
|
153
167
|
// Save current rendering state
|
|
154
|
-
var savedMsgEl =
|
|
155
|
-
var savedActivity =
|
|
156
|
-
var savedFullText =
|
|
157
|
-
var savedTurnCounter =
|
|
158
|
-
var savedToolsState =
|
|
168
|
+
var savedMsgEl = store.get('currentMsgEl');
|
|
169
|
+
var savedActivity = getActivityEl();
|
|
170
|
+
var savedFullText = store.get('currentFullText');
|
|
171
|
+
var savedTurnCounter = getTurnCounter();
|
|
172
|
+
var savedToolsState = saveToolState();
|
|
159
173
|
// Save context & usage so old result messages don't overwrite current values
|
|
160
|
-
var savedContext = JSON.parse(JSON.stringify(
|
|
161
|
-
var savedUsage = JSON.parse(JSON.stringify(
|
|
174
|
+
var savedContext = JSON.parse(JSON.stringify(getContextData()));
|
|
175
|
+
var savedUsage = JSON.parse(JSON.stringify(getSessionUsage()));
|
|
162
176
|
|
|
163
177
|
// Reset to initial values for clean rendering
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
_ctx.resetToolState();
|
|
178
|
+
store.set({ currentMsgEl: null, currentFullText: "" });
|
|
179
|
+
setActivityEl(null);
|
|
180
|
+
setTurnCounter(0);
|
|
181
|
+
resetToolState();
|
|
169
182
|
|
|
170
183
|
// Set prepend anchor to insert before existing content
|
|
171
184
|
// Skip the sentinel itself when setting anchor
|
|
172
|
-
var firstReal =
|
|
173
|
-
|
|
185
|
+
var firstReal = messagesEl.querySelector(".history-sentinel");
|
|
186
|
+
setPrependAnchor(firstReal ? firstReal.nextSibling : messagesEl.firstChild);
|
|
174
187
|
|
|
175
188
|
// Remember the first existing content element and its position
|
|
176
|
-
var anchorEl =
|
|
189
|
+
var anchorEl = getPrependAnchor();
|
|
177
190
|
var anchorOffset = anchorEl ? anchorEl.getBoundingClientRect().top : 0;
|
|
178
191
|
|
|
179
192
|
// Process each item through the rendering pipeline
|
|
180
193
|
for (var i = 0; i < items.length; i++) {
|
|
181
|
-
|
|
194
|
+
processMessage(items[i]);
|
|
182
195
|
}
|
|
183
196
|
|
|
184
197
|
// Finalize any open assistant block from the batch
|
|
185
|
-
|
|
198
|
+
finalizeAssistantBlock();
|
|
186
199
|
|
|
187
200
|
// Clear prepend mode
|
|
188
|
-
|
|
201
|
+
setPrependAnchor(null);
|
|
189
202
|
|
|
190
203
|
// Restore saved state
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
_ctx.restoreToolState(savedToolsState);
|
|
204
|
+
store.set({ currentMsgEl: savedMsgEl, currentFullText: savedFullText });
|
|
205
|
+
setActivityEl(savedActivity);
|
|
206
|
+
setTurnCounter(savedTurnCounter);
|
|
207
|
+
restoreToolState(savedToolsState);
|
|
196
208
|
// Restore context & usage (old result messages must not overwrite current values)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
setContextData(savedContext);
|
|
210
|
+
setSessionUsage(savedUsage);
|
|
211
|
+
updateContextPanel();
|
|
212
|
+
updateUsagePanel();
|
|
201
213
|
|
|
202
214
|
// Fix scroll: restore anchor element to same visual position
|
|
203
215
|
if (anchorEl) {
|
|
204
216
|
var newTop = anchorEl.getBoundingClientRect().top;
|
|
205
|
-
|
|
217
|
+
messagesEl.scrollTop += (newTop - anchorOffset);
|
|
206
218
|
}
|
|
207
219
|
|
|
208
220
|
// Update state
|
|
209
|
-
|
|
210
|
-
_ctx.loadingMore = false;
|
|
221
|
+
store.set({ historyFrom: meta.from, loadingMore: false });
|
|
211
222
|
|
|
212
223
|
// Renumber data-turn attributes in DOM order
|
|
213
|
-
var turnEls =
|
|
224
|
+
var turnEls = messagesEl.querySelectorAll("[data-turn]");
|
|
214
225
|
for (var t = 0; t < turnEls.length; t++) {
|
|
215
226
|
turnEls[t].dataset.turn = t + 1;
|
|
216
227
|
}
|
|
217
|
-
|
|
228
|
+
setTurnCounter(turnEls.length);
|
|
218
229
|
|
|
219
230
|
// Update sentinel
|
|
220
231
|
if (meta.hasMore) {
|
|
221
|
-
var btn =
|
|
232
|
+
var btn = messagesEl.querySelector(".load-more-btn");
|
|
222
233
|
if (btn) btn.classList.remove("loading");
|
|
223
234
|
} else {
|
|
224
235
|
updateHistorySentinel();
|
|
225
236
|
}
|
|
226
237
|
|
|
227
238
|
// Notify in-session search that history was prepended (for pending scroll targets)
|
|
228
|
-
|
|
239
|
+
onSessionSearchHistoryPrepended();
|
|
229
240
|
}
|