sentienceapi 0.92.0 → 0.92.2
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/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +2 -1
- package/dist/agent.js.map +1 -1
- package/dist/browser.d.ts +18 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +23 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/tracing/tracer-factory.d.ts +13 -0
- package/dist/tracing/tracer-factory.d.ts.map +1 -1
- package/dist/tracing/tracer-factory.js +14 -2
- package/dist/tracing/tracer-factory.js.map +1 -1
- package/dist/tracing/tracer.d.ts +18 -1
- package/dist/tracing/tracer.d.ts.map +1 -1
- package/dist/tracing/tracer.js +23 -1
- package/dist/tracing/tracer.js.map +1 -1
- package/dist/tracing/types.d.ts +1 -0
- package/dist/tracing/types.d.ts.map +1 -1
- package/dist/utils/element-filter.d.ts.map +1 -1
- package/dist/utils/element-filter.js +7 -3
- package/dist/utils/element-filter.js.map +1 -1
- package/dist/utils/llm-interaction-handler.d.ts +3 -1
- package/dist/utils/llm-interaction-handler.d.ts.map +1 -1
- package/dist/utils/llm-interaction-handler.js +89 -18
- package/dist/utils/llm-interaction-handler.js.map +1 -1
- package/dist/utils/trace-event-builder.d.ts.map +1 -1
- package/dist/utils/trace-event-builder.js +34 -0
- package/dist/utils/trace-event-builder.js.map +1 -1
- package/dist/visual-agent.d.ts +115 -0
- package/dist/visual-agent.d.ts.map +1 -0
- package/dist/visual-agent.js +747 -0
- package/dist/visual-agent.js.map +1 -0
- package/package.json +1 -1
- package/src/extension/background.js +56 -185
- package/src/extension/content.js +117 -289
- package/src/extension/injected_api.js +799 -1374
- package/src/extension/manifest.json +1 -1
- package/src/extension/pkg/README.md +136 -19
- package/src/extension/pkg/sentience_core.js +190 -396
- package/src/extension/pkg/sentience_core_bg.wasm +0 -0
- package/src/extension/release.json +47 -47
- package/src/extension/test-content.js +0 -4
package/src/extension/content.js
CHANGED
|
@@ -1,298 +1,126 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
switch (event.data.type) {
|
|
20
|
-
case 'SENTIENCE_SCREENSHOT_REQUEST':
|
|
21
|
-
handleScreenshotRequest(event.data);
|
|
22
|
-
break;
|
|
23
|
-
|
|
24
|
-
case 'SENTIENCE_SNAPSHOT_REQUEST':
|
|
25
|
-
handleSnapshotRequest(event.data);
|
|
26
|
-
break;
|
|
27
|
-
|
|
28
|
-
case 'SENTIENCE_SHOW_OVERLAY':
|
|
29
|
-
handleShowOverlay(event.data);
|
|
1
|
+
!function() {
|
|
2
|
+
"use strict";
|
|
3
|
+
window, window.top;
|
|
4
|
+
document.documentElement.dataset.sentienceExtensionId = chrome.runtime.id, window.addEventListener("message", event => {
|
|
5
|
+
var data;
|
|
6
|
+
if (event.source === window) switch (event.data.type) {
|
|
7
|
+
case "SENTIENCE_SCREENSHOT_REQUEST":
|
|
8
|
+
data = event.data, chrome.runtime.sendMessage({
|
|
9
|
+
action: "captureScreenshot",
|
|
10
|
+
options: data.options
|
|
11
|
+
}, response => {
|
|
12
|
+
window.postMessage({
|
|
13
|
+
type: "SENTIENCE_SCREENSHOT_RESULT",
|
|
14
|
+
requestId: data.requestId,
|
|
15
|
+
screenshot: response?.success ? response.screenshot : null,
|
|
16
|
+
error: response?.error
|
|
17
|
+
}, "*");
|
|
18
|
+
});
|
|
30
19
|
break;
|
|
31
20
|
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
case "SENTIENCE_SNAPSHOT_REQUEST":
|
|
22
|
+
!function(data) {
|
|
23
|
+
const startTime = performance.now();
|
|
24
|
+
let responded = !1;
|
|
25
|
+
const timeoutId = setTimeout(() => {
|
|
26
|
+
if (!responded) {
|
|
27
|
+
responded = !0;
|
|
28
|
+
const duration = performance.now() - startTime;
|
|
29
|
+
window.postMessage({
|
|
30
|
+
type: "SENTIENCE_SNAPSHOT_RESULT",
|
|
31
|
+
requestId: data.requestId,
|
|
32
|
+
error: "WASM processing timeout - background script may be unresponsive",
|
|
33
|
+
duration: duration
|
|
34
|
+
}, "*");
|
|
35
|
+
}
|
|
36
|
+
}, 2e4);
|
|
37
|
+
try {
|
|
38
|
+
chrome.runtime.sendMessage({
|
|
39
|
+
action: "processSnapshot",
|
|
40
|
+
rawData: data.rawData,
|
|
41
|
+
options: data.options
|
|
42
|
+
}, response => {
|
|
43
|
+
if (responded) return;
|
|
44
|
+
responded = !0, clearTimeout(timeoutId);
|
|
45
|
+
const duration = performance.now() - startTime;
|
|
46
|
+
chrome.runtime.lastError ? window.postMessage({
|
|
47
|
+
type: "SENTIENCE_SNAPSHOT_RESULT",
|
|
48
|
+
requestId: data.requestId,
|
|
49
|
+
error: `Chrome runtime error: ${chrome.runtime.lastError.message}`,
|
|
50
|
+
duration: duration
|
|
51
|
+
}, "*") : response?.success ? window.postMessage({
|
|
52
|
+
type: "SENTIENCE_SNAPSHOT_RESULT",
|
|
53
|
+
requestId: data.requestId,
|
|
54
|
+
elements: response.result.elements,
|
|
55
|
+
raw_elements: response.result.raw_elements,
|
|
56
|
+
duration: duration
|
|
57
|
+
}, "*") : window.postMessage({
|
|
58
|
+
type: "SENTIENCE_SNAPSHOT_RESULT",
|
|
59
|
+
requestId: data.requestId,
|
|
60
|
+
error: response?.error || "Processing failed",
|
|
61
|
+
duration: duration
|
|
62
|
+
}, "*");
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (!responded) {
|
|
66
|
+
responded = !0, clearTimeout(timeoutId);
|
|
67
|
+
const duration = performance.now() - startTime;
|
|
68
|
+
window.postMessage({
|
|
69
|
+
type: "SENTIENCE_SNAPSHOT_RESULT",
|
|
70
|
+
requestId: data.requestId,
|
|
71
|
+
error: `Failed to send message: ${error.message}`,
|
|
72
|
+
duration: duration
|
|
73
|
+
}, "*");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}(event.data);
|
|
34
77
|
break;
|
|
35
78
|
|
|
36
|
-
|
|
37
|
-
|
|
79
|
+
case "SENTIENCE_SHOW_OVERLAY":
|
|
80
|
+
!function(data) {
|
|
81
|
+
const {elements: elements, targetElementId: targetElementId} = data;
|
|
82
|
+
if (!elements || !Array.isArray(elements)) return;
|
|
83
|
+
removeOverlay();
|
|
84
|
+
const host = document.createElement("div");
|
|
85
|
+
host.id = OVERLAY_HOST_ID, host.style.cssText = "\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n width: 100vw !important;\n height: 100vh !important;\n pointer-events: none !important;\n z-index: 2147483647 !important;\n margin: 0 !important;\n padding: 0 !important;\n ",
|
|
86
|
+
document.body.appendChild(host);
|
|
87
|
+
const shadow = host.attachShadow({
|
|
88
|
+
mode: "closed"
|
|
89
|
+
}), maxImportance = Math.max(...elements.map(e => e.importance || 0), 1);
|
|
90
|
+
elements.forEach(element => {
|
|
91
|
+
const bbox = element.bbox;
|
|
92
|
+
if (!bbox) return;
|
|
93
|
+
const isTarget = element.id === targetElementId, isPrimary = element.visual_cues?.is_primary || !1, importance = element.importance || 0;
|
|
94
|
+
let color;
|
|
95
|
+
color = isTarget ? "#FF0000" : isPrimary ? "#0066FF" : "#00FF00";
|
|
96
|
+
const importanceRatio = maxImportance > 0 ? importance / maxImportance : .5, borderOpacity = isTarget ? 1 : isPrimary ? .9 : Math.max(.4, .5 + .5 * importanceRatio), fillOpacity = .2 * borderOpacity, borderWidth = isTarget ? 2 : isPrimary ? 1.5 : Math.max(.5, Math.round(2 * importanceRatio)), hexOpacity = Math.round(255 * fillOpacity).toString(16).padStart(2, "0"), box = document.createElement("div");
|
|
97
|
+
if (box.style.cssText = `\n position: absolute;\n left: ${bbox.x}px;\n top: ${bbox.y}px;\n width: ${bbox.width}px;\n height: ${bbox.height}px;\n border: ${borderWidth}px solid ${color};\n background-color: ${color}${hexOpacity};\n box-sizing: border-box;\n opacity: ${borderOpacity};\n pointer-events: none;\n `,
|
|
98
|
+
importance > 0 || isPrimary) {
|
|
99
|
+
const badge = document.createElement("span");
|
|
100
|
+
badge.textContent = isPrimary ? `⭐${importance}` : `${importance}`, badge.style.cssText = `\n position: absolute;\n top: -18px;\n left: 0;\n background: ${color};\n color: white;\n font-size: 11px;\n font-weight: bold;\n padding: 2px 6px;\n font-family: Arial, sans-serif;\n border-radius: 3px;\n opacity: 0.95;\n white-space: nowrap;\n pointer-events: none;\n `,
|
|
101
|
+
box.appendChild(badge);
|
|
102
|
+
}
|
|
103
|
+
if (isTarget) {
|
|
104
|
+
const targetIndicator = document.createElement("span");
|
|
105
|
+
targetIndicator.textContent = "🎯", targetIndicator.style.cssText = "\n position: absolute;\n top: -18px;\n right: 0;\n font-size: 16px;\n pointer-events: none;\n ",
|
|
106
|
+
box.appendChild(targetIndicator);
|
|
107
|
+
}
|
|
108
|
+
shadow.appendChild(box);
|
|
109
|
+
}), overlayTimeout = setTimeout(() => {
|
|
110
|
+
removeOverlay();
|
|
111
|
+
}, 5e3);
|
|
112
|
+
}(event.data);
|
|
38
113
|
break;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
114
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
function handleScreenshotRequest(data) {
|
|
46
|
-
chrome.runtime.sendMessage(
|
|
47
|
-
{ action: 'captureScreenshot', options: data.options },
|
|
48
|
-
(response) => {
|
|
49
|
-
window.postMessage({
|
|
50
|
-
type: 'SENTIENCE_SCREENSHOT_RESULT',
|
|
51
|
-
requestId: data.requestId,
|
|
52
|
-
screenshot: response?.success ? response.screenshot : null,
|
|
53
|
-
error: response?.error
|
|
54
|
-
}, '*');
|
|
115
|
+
case "SENTIENCE_CLEAR_OVERLAY":
|
|
116
|
+
removeOverlay();
|
|
55
117
|
}
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Handle snapshot processing requests (NEW!)
|
|
61
|
-
* Sends raw DOM data to background worker for WASM processing
|
|
62
|
-
* Includes timeout protection to prevent extension crashes
|
|
63
|
-
*/
|
|
64
|
-
function handleSnapshotRequest(data) {
|
|
65
|
-
const startTime = performance.now();
|
|
66
|
-
const TIMEOUT_MS = 20000; // 20 seconds (longer than injected_api timeout)
|
|
67
|
-
let responded = false;
|
|
68
|
-
|
|
69
|
-
// Timeout protection: if background doesn't respond, send error
|
|
70
|
-
const timeoutId = setTimeout(() => {
|
|
71
|
-
if (!responded) {
|
|
72
|
-
responded = true;
|
|
73
|
-
const duration = performance.now() - startTime;
|
|
74
|
-
console.error(`[Sentience Bridge] ⚠️ WASM processing timeout after ${duration.toFixed(1)}ms`);
|
|
75
|
-
window.postMessage({
|
|
76
|
-
type: 'SENTIENCE_SNAPSHOT_RESULT',
|
|
77
|
-
requestId: data.requestId,
|
|
78
|
-
error: 'WASM processing timeout - background script may be unresponsive',
|
|
79
|
-
duration: duration
|
|
80
|
-
}, '*');
|
|
81
|
-
}
|
|
82
|
-
}, TIMEOUT_MS);
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
chrome.runtime.sendMessage(
|
|
86
|
-
{
|
|
87
|
-
action: 'processSnapshot',
|
|
88
|
-
rawData: data.rawData,
|
|
89
|
-
options: data.options
|
|
90
|
-
},
|
|
91
|
-
(response) => {
|
|
92
|
-
if (responded) return; // Already responded via timeout
|
|
93
|
-
responded = true;
|
|
94
|
-
clearTimeout(timeoutId);
|
|
95
|
-
|
|
96
|
-
const duration = performance.now() - startTime;
|
|
97
|
-
|
|
98
|
-
// Handle Chrome extension errors (e.g., background script crashed)
|
|
99
|
-
if (chrome.runtime.lastError) {
|
|
100
|
-
console.error('[Sentience Bridge] Chrome runtime error:', chrome.runtime.lastError.message);
|
|
101
|
-
window.postMessage({
|
|
102
|
-
type: 'SENTIENCE_SNAPSHOT_RESULT',
|
|
103
|
-
requestId: data.requestId,
|
|
104
|
-
error: `Chrome runtime error: ${chrome.runtime.lastError.message}`,
|
|
105
|
-
duration: duration
|
|
106
|
-
}, '*');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (response?.success) {
|
|
111
|
-
console.log(`[Sentience Bridge] ✓ WASM processing complete in ${duration.toFixed(1)}ms`);
|
|
112
|
-
window.postMessage({
|
|
113
|
-
type: 'SENTIENCE_SNAPSHOT_RESULT',
|
|
114
|
-
requestId: data.requestId,
|
|
115
|
-
elements: response.result.elements,
|
|
116
|
-
raw_elements: response.result.raw_elements,
|
|
117
|
-
duration: duration
|
|
118
|
-
}, '*');
|
|
119
|
-
} else {
|
|
120
|
-
console.error('[Sentience Bridge] WASM processing failed:', response?.error);
|
|
121
|
-
window.postMessage({
|
|
122
|
-
type: 'SENTIENCE_SNAPSHOT_RESULT',
|
|
123
|
-
requestId: data.requestId,
|
|
124
|
-
error: response?.error || 'Processing failed',
|
|
125
|
-
duration: duration
|
|
126
|
-
}, '*');
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
);
|
|
130
|
-
} catch (error) {
|
|
131
|
-
if (!responded) {
|
|
132
|
-
responded = true;
|
|
133
|
-
clearTimeout(timeoutId);
|
|
134
|
-
const duration = performance.now() - startTime;
|
|
135
|
-
console.error('[Sentience Bridge] Exception sending message:', error);
|
|
136
|
-
window.postMessage({
|
|
137
|
-
type: 'SENTIENCE_SNAPSHOT_RESULT',
|
|
138
|
-
requestId: data.requestId,
|
|
139
|
-
error: `Failed to send message: ${error.message}`,
|
|
140
|
-
duration: duration
|
|
141
|
-
}, '*');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// ============================================================================
|
|
147
|
-
// Visual Overlay - Shadow DOM Implementation
|
|
148
|
-
// ============================================================================
|
|
149
|
-
|
|
150
|
-
const OVERLAY_HOST_ID = 'sentience-overlay-host';
|
|
151
|
-
let overlayTimeout = null;
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Show visual overlay highlighting elements using Shadow DOM
|
|
155
|
-
* @param {Object} data - Message data with elements and targetElementId
|
|
156
|
-
*/
|
|
157
|
-
function handleShowOverlay(data) {
|
|
158
|
-
const { elements, targetElementId } = data;
|
|
159
|
-
|
|
160
|
-
if (!elements || !Array.isArray(elements)) {
|
|
161
|
-
console.warn('[Sentience Bridge] showOverlay: elements must be an array');
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
removeOverlay();
|
|
166
|
-
|
|
167
|
-
// Create host with Shadow DOM for CSS isolation
|
|
168
|
-
const host = document.createElement('div');
|
|
169
|
-
host.id = OVERLAY_HOST_ID;
|
|
170
|
-
host.style.cssText = `
|
|
171
|
-
position: fixed !important;
|
|
172
|
-
top: 0 !important;
|
|
173
|
-
left: 0 !important;
|
|
174
|
-
width: 100vw !important;
|
|
175
|
-
height: 100vh !important;
|
|
176
|
-
pointer-events: none !important;
|
|
177
|
-
z-index: 2147483647 !important;
|
|
178
|
-
margin: 0 !important;
|
|
179
|
-
padding: 0 !important;
|
|
180
|
-
`;
|
|
181
|
-
document.body.appendChild(host);
|
|
182
|
-
|
|
183
|
-
// Attach shadow root (closed mode for security and CSS isolation)
|
|
184
|
-
const shadow = host.attachShadow({ mode: 'closed' });
|
|
185
|
-
|
|
186
|
-
// Calculate max importance for scaling
|
|
187
|
-
const maxImportance = Math.max(...elements.map(e => e.importance || 0), 1);
|
|
188
|
-
|
|
189
|
-
elements.forEach((element) => {
|
|
190
|
-
const bbox = element.bbox;
|
|
191
|
-
if (!bbox) return;
|
|
192
|
-
|
|
193
|
-
const isTarget = element.id === targetElementId;
|
|
194
|
-
const isPrimary = element.visual_cues?.is_primary || false;
|
|
195
|
-
const importance = element.importance || 0;
|
|
196
|
-
|
|
197
|
-
// Color: Red (target), Blue (primary), Green (regular)
|
|
198
|
-
let color;
|
|
199
|
-
if (isTarget) color = '#FF0000';
|
|
200
|
-
else if (isPrimary) color = '#0066FF';
|
|
201
|
-
else color = '#00FF00';
|
|
202
|
-
|
|
203
|
-
// Scale opacity and border width based on importance
|
|
204
|
-
const importanceRatio = maxImportance > 0 ? importance / maxImportance : 0.5;
|
|
205
|
-
const borderOpacity = isTarget ? 1.0 : (isPrimary ? 0.9 : Math.max(0.4, 0.5 + importanceRatio * 0.5));
|
|
206
|
-
const fillOpacity = borderOpacity * 0.2;
|
|
207
|
-
const borderWidth = isTarget ? 2 : (isPrimary ? 1.5 : Math.max(0.5, Math.round(importanceRatio * 2)));
|
|
208
|
-
|
|
209
|
-
// Convert fill opacity to hex for background-color
|
|
210
|
-
const hexOpacity = Math.round(fillOpacity * 255).toString(16).padStart(2, '0');
|
|
211
|
-
|
|
212
|
-
// Create box with semi-transparent fill
|
|
213
|
-
const box = document.createElement('div');
|
|
214
|
-
box.style.cssText = `
|
|
215
|
-
position: absolute;
|
|
216
|
-
left: ${bbox.x}px;
|
|
217
|
-
top: ${bbox.y}px;
|
|
218
|
-
width: ${bbox.width}px;
|
|
219
|
-
height: ${bbox.height}px;
|
|
220
|
-
border: ${borderWidth}px solid ${color};
|
|
221
|
-
background-color: ${color}${hexOpacity};
|
|
222
|
-
box-sizing: border-box;
|
|
223
|
-
opacity: ${borderOpacity};
|
|
224
|
-
pointer-events: none;
|
|
225
|
-
`;
|
|
226
|
-
|
|
227
|
-
// Add badge showing importance score
|
|
228
|
-
if (importance > 0 || isPrimary) {
|
|
229
|
-
const badge = document.createElement('span');
|
|
230
|
-
badge.textContent = isPrimary ? `⭐${importance}` : `${importance}`;
|
|
231
|
-
badge.style.cssText = `
|
|
232
|
-
position: absolute;
|
|
233
|
-
top: -18px;
|
|
234
|
-
left: 0;
|
|
235
|
-
background: ${color};
|
|
236
|
-
color: white;
|
|
237
|
-
font-size: 11px;
|
|
238
|
-
font-weight: bold;
|
|
239
|
-
padding: 2px 6px;
|
|
240
|
-
font-family: Arial, sans-serif;
|
|
241
|
-
border-radius: 3px;
|
|
242
|
-
opacity: 0.95;
|
|
243
|
-
white-space: nowrap;
|
|
244
|
-
pointer-events: none;
|
|
245
|
-
`;
|
|
246
|
-
box.appendChild(badge);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Add target emoji for target element
|
|
250
|
-
if (isTarget) {
|
|
251
|
-
const targetIndicator = document.createElement('span');
|
|
252
|
-
targetIndicator.textContent = '🎯';
|
|
253
|
-
targetIndicator.style.cssText = `
|
|
254
|
-
position: absolute;
|
|
255
|
-
top: -18px;
|
|
256
|
-
right: 0;
|
|
257
|
-
font-size: 16px;
|
|
258
|
-
pointer-events: none;
|
|
259
|
-
`;
|
|
260
|
-
box.appendChild(targetIndicator);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
shadow.appendChild(box);
|
|
264
118
|
});
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
console.log('[Sentience Bridge] Overlay auto-cleared after 5 seconds');
|
|
272
|
-
}, 5000);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Clear overlay manually
|
|
277
|
-
*/
|
|
278
|
-
function handleClearOverlay() {
|
|
279
|
-
removeOverlay();
|
|
280
|
-
console.log('[Sentience Bridge] Overlay cleared manually');
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Remove overlay from DOM
|
|
285
|
-
*/
|
|
286
|
-
function removeOverlay() {
|
|
287
|
-
const existing = document.getElementById(OVERLAY_HOST_ID);
|
|
288
|
-
if (existing) {
|
|
289
|
-
existing.remove();
|
|
119
|
+
const OVERLAY_HOST_ID = "sentience-overlay-host";
|
|
120
|
+
let overlayTimeout = null;
|
|
121
|
+
function removeOverlay() {
|
|
122
|
+
const existing = document.getElementById(OVERLAY_HOST_ID);
|
|
123
|
+
existing && existing.remove(), overlayTimeout && (clearTimeout(overlayTimeout),
|
|
124
|
+
overlayTimeout = null);
|
|
290
125
|
}
|
|
291
|
-
|
|
292
|
-
if (overlayTimeout) {
|
|
293
|
-
clearTimeout(overlayTimeout);
|
|
294
|
-
overlayTimeout = null;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// console.log('[Sentience Bridge] Ready - Extension ID:', chrome.runtime.id);
|
|
126
|
+
}();
|