@opentabs-dev/browser-extension 0.0.35 → 0.0.37
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/background-message-handlers.d.ts.map +1 -1
- package/dist/background-message-handlers.js +4 -2
- package/dist/background-message-handlers.js.map +1 -1
- package/dist/background.js +196 -77
- package/dist/browser-commands/extension-commands.d.ts +2 -0
- package/dist/browser-commands/extension-commands.d.ts.map +1 -1
- package/dist/browser-commands/extension-commands.js +38 -24
- package/dist/browser-commands/extension-commands.js.map +1 -1
- package/dist/browser-commands/interaction-commands.d.ts.map +1 -1
- package/dist/browser-commands/interaction-commands.js +24 -18
- package/dist/browser-commands/interaction-commands.js.map +1 -1
- package/dist/confirmation-badge.d.ts +10 -0
- package/dist/confirmation-badge.d.ts.map +1 -1
- package/dist/confirmation-badge.js +36 -0
- package/dist/confirmation-badge.js.map +1 -1
- package/dist/network-capture.d.ts.map +1 -1
- package/dist/network-capture.js +86 -41
- package/dist/network-capture.js.map +1 -1
- package/dist/offscreen/index.js +23 -2
- package/dist/offscreen/index.js.map +1 -1
- package/dist/side-panel/components/PluginCard.d.ts.map +1 -1
- package/dist/side-panel/components/PluginCard.js +9 -2
- package/dist/side-panel/components/PluginCard.js.map +1 -1
- package/dist/side-panel/side-panel.js +9 -2
- package/package.json +1 -1
package/dist/background.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// dist/
|
|
1
|
+
// dist/confirmation-badge.js
|
|
2
2
|
var pendingConfirmationCount = 0;
|
|
3
3
|
var confirmationTimeouts = /* @__PURE__ */ new Map();
|
|
4
|
+
var clearedConfirmationIds = /* @__PURE__ */ new Set();
|
|
4
5
|
var CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS = 2e3;
|
|
5
6
|
var CONFIRMATION_FALLBACK_TIMEOUT_MS = 3e4;
|
|
6
7
|
var updateConfirmationBadge = () => {
|
|
@@ -23,6 +24,7 @@ var notifyConfirmationRequest = (params) => {
|
|
|
23
24
|
if (existingTimeoutId !== void 0) {
|
|
24
25
|
clearTimeout(existingTimeoutId);
|
|
25
26
|
} else {
|
|
27
|
+
clearedConfirmationIds.delete(id);
|
|
26
28
|
pendingConfirmationCount++;
|
|
27
29
|
updateConfirmationBadge();
|
|
28
30
|
}
|
|
@@ -30,6 +32,7 @@ var notifyConfirmationRequest = (params) => {
|
|
|
30
32
|
const bgTimeoutId = setTimeout(() => {
|
|
31
33
|
confirmationTimeouts.delete(id);
|
|
32
34
|
clearConfirmationBadge(id);
|
|
35
|
+
clearedConfirmationIds.delete(id);
|
|
33
36
|
}, effectiveTimeoutMs + CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS);
|
|
34
37
|
confirmationTimeouts.set(id, bgTimeoutId);
|
|
35
38
|
chrome.notifications.create(`opentabs-confirm-${id}`, {
|
|
@@ -44,17 +47,25 @@ var notifyConfirmationRequest = (params) => {
|
|
|
44
47
|
};
|
|
45
48
|
var clearConfirmationBadge = (id) => {
|
|
46
49
|
if (id !== void 0) {
|
|
50
|
+
if (clearedConfirmationIds.has(id)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
clearedConfirmationIds.add(id);
|
|
47
54
|
chrome.notifications.clear(`opentabs-confirm-${id}`).catch(() => {
|
|
48
55
|
});
|
|
49
56
|
}
|
|
50
57
|
pendingConfirmationCount = Math.max(0, pendingConfirmationCount - 1);
|
|
51
58
|
updateConfirmationBadge();
|
|
59
|
+
if (id !== void 0 && !confirmationTimeouts.has(id)) {
|
|
60
|
+
clearedConfirmationIds.delete(id);
|
|
61
|
+
}
|
|
52
62
|
};
|
|
53
63
|
var clearConfirmationBackgroundTimeout = (id) => {
|
|
54
64
|
const timeoutId = confirmationTimeouts.get(id);
|
|
55
65
|
if (timeoutId !== void 0) {
|
|
56
66
|
clearTimeout(timeoutId);
|
|
57
67
|
confirmationTimeouts.delete(id);
|
|
68
|
+
clearedConfirmationIds.delete(id);
|
|
58
69
|
}
|
|
59
70
|
};
|
|
60
71
|
var clearAllConfirmationBadges = () => {
|
|
@@ -64,6 +75,7 @@ var clearAllConfirmationBadges = () => {
|
|
|
64
75
|
});
|
|
65
76
|
}
|
|
66
77
|
confirmationTimeouts.clear();
|
|
78
|
+
clearedConfirmationIds.clear();
|
|
67
79
|
pendingConfirmationCount = 0;
|
|
68
80
|
updateConfirmationBadge();
|
|
69
81
|
};
|
|
@@ -82,6 +94,8 @@ var initConfirmationBadge = () => {
|
|
|
82
94
|
}
|
|
83
95
|
});
|
|
84
96
|
};
|
|
97
|
+
|
|
98
|
+
// dist/constants.js
|
|
85
99
|
var KEEPALIVE_ALARM = "opentabs-keepalive";
|
|
86
100
|
var KEEPALIVE_INTERVAL_MINUTES = 0.5;
|
|
87
101
|
var PLUGINS_META_KEY = "plugins_meta";
|
|
@@ -109,11 +123,15 @@ var DEFAULT_LOG_LIMIT = 100;
|
|
|
109
123
|
var VALID_PLUGIN_NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
110
124
|
var isValidPluginName = (name) => VALID_PLUGIN_NAME.test(name);
|
|
111
125
|
var buildWsUrl = (port) => `ws://localhost:${port}/ws`;
|
|
126
|
+
|
|
127
|
+
// dist/json-rpc-errors.js
|
|
112
128
|
var JSONRPC_METHOD_NOT_FOUND = -32601;
|
|
113
129
|
var JSONRPC_INVALID_PARAMS = -32602;
|
|
114
130
|
var JSONRPC_INTERNAL_ERROR = -32603;
|
|
115
131
|
var JSONRPC_NO_USABLE_TAB = -32001;
|
|
116
132
|
var JSONRPC_ADAPTER_NOT_READY = -32002;
|
|
133
|
+
|
|
134
|
+
// dist/messaging.js
|
|
117
135
|
var sendToServer = (data) => {
|
|
118
136
|
const method = data.method ?? "unknown";
|
|
119
137
|
chrome.runtime.sendMessage({ type: "ws:send", data }).catch((err2) => {
|
|
@@ -147,6 +165,8 @@ var sendTabStateNotification = (pluginName, stateInfo) => {
|
|
|
147
165
|
}
|
|
148
166
|
});
|
|
149
167
|
};
|
|
168
|
+
|
|
169
|
+
// dist/sanitize-error.js
|
|
150
170
|
var MAX_LENGTH = 500;
|
|
151
171
|
var sanitizeErrorMessage = (message) => {
|
|
152
172
|
let sanitized = message.replace(/[a-z]:[/\\][^\s,;)}\]]+/gi, "[PATH]").replace(/\/[a-z0-9._-]+(?:\/[a-z0-9._-]+)+/gi, "[PATH]").replace(/https?:\/\/[^\s,;)}\]]+/gi, "[URL]").replace(/localhost:\d+/gi, "[LOCALHOST]").replace(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g, "[IP]");
|
|
@@ -155,7 +175,11 @@ var sanitizeErrorMessage = (message) => {
|
|
|
155
175
|
}
|
|
156
176
|
return sanitized;
|
|
157
177
|
};
|
|
178
|
+
|
|
179
|
+
// ../shared/dist/error.js
|
|
158
180
|
var toErrorMessage = (err2) => err2 instanceof Error ? err2.message : String(err2);
|
|
181
|
+
|
|
182
|
+
// ../shared/dist/index.js
|
|
159
183
|
var BLOCKED_URL_SCHEMES = [
|
|
160
184
|
"javascript:",
|
|
161
185
|
"data:",
|
|
@@ -172,6 +196,8 @@ var isBlockedUrlScheme = (url) => {
|
|
|
172
196
|
return true;
|
|
173
197
|
}
|
|
174
198
|
};
|
|
199
|
+
|
|
200
|
+
// dist/browser-commands/helpers.js
|
|
175
201
|
var requireTabId = (params, id) => {
|
|
176
202
|
const tabId = params.tabId;
|
|
177
203
|
if (typeof tabId !== "number") {
|
|
@@ -264,6 +290,8 @@ var sendValidationError = (id, message) => {
|
|
|
264
290
|
var sendSuccessResult = (id, result) => {
|
|
265
291
|
sendToServer({ jsonrpc: "2.0", result, id });
|
|
266
292
|
};
|
|
293
|
+
|
|
294
|
+
// dist/browser-commands/content-commands.js
|
|
267
295
|
var handleBrowserGetTabContent = async (params, id) => {
|
|
268
296
|
try {
|
|
269
297
|
const tabId = requireTabId(params, id);
|
|
@@ -402,6 +430,8 @@ var handleBrowserScreenshotTab = async (params, id) => {
|
|
|
402
430
|
sendErrorResult(id, err2);
|
|
403
431
|
}
|
|
404
432
|
};
|
|
433
|
+
|
|
434
|
+
// dist/browser-commands/cookie-commands.js
|
|
405
435
|
var handleBrowserGetCookies = async (params, id) => {
|
|
406
436
|
try {
|
|
407
437
|
const url = requireUrl(params, id);
|
|
@@ -486,6 +516,8 @@ var handleBrowserDeleteCookies = async (params, id) => {
|
|
|
486
516
|
sendErrorResult(id, err2);
|
|
487
517
|
}
|
|
488
518
|
};
|
|
519
|
+
|
|
520
|
+
// dist/log-collector.js
|
|
489
521
|
var MAX_MESSAGE_LENGTH = 2e3;
|
|
490
522
|
var DEFAULT_MAX_ENTRIES = 500;
|
|
491
523
|
var formatArg = (arg) => {
|
|
@@ -572,10 +604,15 @@ var installLogCollector = (source, maxEntries) => {
|
|
|
572
604
|
}
|
|
573
605
|
return collector;
|
|
574
606
|
};
|
|
607
|
+
|
|
608
|
+
// dist/background-log-state.js
|
|
575
609
|
var bgLogCollector = installLogCollector("background");
|
|
610
|
+
|
|
611
|
+
// dist/network-capture.js
|
|
576
612
|
var MAX_BODY_LENGTH = 102400;
|
|
577
613
|
var PENDING_REQUEST_TTL_MS = 6e4;
|
|
578
614
|
var PRUNE_INTERVAL_MS = 3e4;
|
|
615
|
+
var WS_TTL_MS = 5 * 6e4;
|
|
579
616
|
var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
580
617
|
"authorization",
|
|
581
618
|
"cookie",
|
|
@@ -607,6 +644,7 @@ var scrubHeaders = (headers) => {
|
|
|
607
644
|
return scrubbed;
|
|
608
645
|
};
|
|
609
646
|
var captures = /* @__PURE__ */ new Map();
|
|
647
|
+
var pendingCaptures = /* @__PURE__ */ new Map();
|
|
610
648
|
var headersToRecord = (raw) => {
|
|
611
649
|
if (!raw)
|
|
612
650
|
return void 0;
|
|
@@ -674,6 +712,12 @@ chrome.debugger.onEvent.addListener((source, method, params) => {
|
|
|
674
712
|
state.requestIdToRequest.delete(id);
|
|
675
713
|
}
|
|
676
714
|
}
|
|
715
|
+
for (const [id, createdAt] of state.wsCreatedAt) {
|
|
716
|
+
if (now - createdAt > WS_TTL_MS) {
|
|
717
|
+
state.wsFramesByRequestId.delete(id);
|
|
718
|
+
state.wsCreatedAt.delete(id);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
677
721
|
const url = stringProp(request, "url", "");
|
|
678
722
|
if (state.urlFilter && !url.includes(state.urlFilter))
|
|
679
723
|
return;
|
|
@@ -763,6 +807,7 @@ chrome.debugger.onEvent.addListener((source, method, params) => {
|
|
|
763
807
|
return;
|
|
764
808
|
if (requestId) {
|
|
765
809
|
state.wsFramesByRequestId.set(requestId, url);
|
|
810
|
+
state.wsCreatedAt.set(requestId, Date.now());
|
|
766
811
|
}
|
|
767
812
|
const completed = {
|
|
768
813
|
url,
|
|
@@ -796,6 +841,7 @@ chrome.debugger.onEvent.addListener((source, method, params) => {
|
|
|
796
841
|
const requestId = paramsRecord?.requestId;
|
|
797
842
|
if (requestId) {
|
|
798
843
|
state.wsFramesByRequestId.delete(requestId);
|
|
844
|
+
state.wsCreatedAt.delete(requestId);
|
|
799
845
|
}
|
|
800
846
|
} else if (method === "Runtime.consoleAPICalled") {
|
|
801
847
|
const type = paramsRecord?.type;
|
|
@@ -841,48 +887,67 @@ chrome.debugger.onDetach.addListener((source, _reason) => {
|
|
|
841
887
|
}
|
|
842
888
|
});
|
|
843
889
|
var startCapture = async (tabId, maxRequests = 100, urlFilter, maxConsoleLogs = 500, maxWsFrames = 200) => {
|
|
890
|
+
const inFlightCapture = pendingCaptures.get(tabId);
|
|
891
|
+
if (inFlightCapture) {
|
|
892
|
+
return inFlightCapture;
|
|
893
|
+
}
|
|
844
894
|
if (captures.has(tabId)) {
|
|
845
895
|
throw new Error(`Network capture already active for tab ${tabId}. Call stopCapture first.`);
|
|
846
896
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
try {
|
|
853
|
-
await chrome.debugger.sendCommand({ tabId }, "Network.enable");
|
|
854
|
-
await chrome.debugger.sendCommand({ tabId }, "Runtime.enable");
|
|
855
|
-
} catch (err2) {
|
|
856
|
-
await chrome.debugger.detach({ tabId }).catch(() => {
|
|
857
|
-
});
|
|
858
|
-
throw err2;
|
|
859
|
-
}
|
|
860
|
-
const captureState = {
|
|
861
|
-
requests: [],
|
|
862
|
-
consoleLogs: [],
|
|
863
|
-
wsFrames: [],
|
|
864
|
-
maxRequests,
|
|
865
|
-
maxConsoleLogs,
|
|
866
|
-
maxWsFrames,
|
|
867
|
-
urlFilter,
|
|
868
|
-
pendingRequests: /* @__PURE__ */ new Map(),
|
|
869
|
-
requestIdToRequest: /* @__PURE__ */ new Map(),
|
|
870
|
-
wsFramesByRequestId: /* @__PURE__ */ new Map()
|
|
871
|
-
};
|
|
872
|
-
captureState.pruneIntervalId = setInterval(() => {
|
|
873
|
-
const now = Date.now();
|
|
874
|
-
for (const [id, pending] of captureState.pendingRequests) {
|
|
875
|
-
if (pending.timestamp !== void 0 && now - pending.timestamp > PENDING_REQUEST_TTL_MS) {
|
|
876
|
-
captureState.pendingRequests.delete(id);
|
|
877
|
-
}
|
|
897
|
+
const capturePromise = (async () => {
|
|
898
|
+
try {
|
|
899
|
+
await chrome.debugger.attach({ tabId }, CDP_VERSION);
|
|
900
|
+
} catch (err2) {
|
|
901
|
+
throw new Error(`Failed to attach debugger to tab ${tabId}: ${toErrorMessage(err2)}. Another debugger (e.g., DevTools) may already be attached.`);
|
|
878
902
|
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
903
|
+
try {
|
|
904
|
+
await chrome.debugger.sendCommand({ tabId }, "Network.enable");
|
|
905
|
+
await chrome.debugger.sendCommand({ tabId }, "Runtime.enable");
|
|
906
|
+
} catch (err2) {
|
|
907
|
+
await chrome.debugger.detach({ tabId }).catch(() => {
|
|
908
|
+
});
|
|
909
|
+
throw err2;
|
|
910
|
+
}
|
|
911
|
+
const captureState = {
|
|
912
|
+
requests: [],
|
|
913
|
+
consoleLogs: [],
|
|
914
|
+
wsFrames: [],
|
|
915
|
+
maxRequests,
|
|
916
|
+
maxConsoleLogs,
|
|
917
|
+
maxWsFrames,
|
|
918
|
+
urlFilter,
|
|
919
|
+
pendingRequests: /* @__PURE__ */ new Map(),
|
|
920
|
+
requestIdToRequest: /* @__PURE__ */ new Map(),
|
|
921
|
+
wsFramesByRequestId: /* @__PURE__ */ new Map(),
|
|
922
|
+
wsCreatedAt: /* @__PURE__ */ new Map()
|
|
923
|
+
};
|
|
924
|
+
captureState.pruneIntervalId = setInterval(() => {
|
|
925
|
+
const now = Date.now();
|
|
926
|
+
for (const [id, pendingReq] of captureState.pendingRequests) {
|
|
927
|
+
if (pendingReq.timestamp !== void 0 && now - pendingReq.timestamp > PENDING_REQUEST_TTL_MS) {
|
|
928
|
+
captureState.pendingRequests.delete(id);
|
|
929
|
+
}
|
|
882
930
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
931
|
+
for (const [id, req] of captureState.requestIdToRequest) {
|
|
932
|
+
if (now - req.timestamp > PENDING_REQUEST_TTL_MS) {
|
|
933
|
+
captureState.requestIdToRequest.delete(id);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
for (const [id, createdAt] of captureState.wsCreatedAt) {
|
|
937
|
+
if (now - createdAt > WS_TTL_MS) {
|
|
938
|
+
captureState.wsFramesByRequestId.delete(id);
|
|
939
|
+
captureState.wsCreatedAt.delete(id);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}, PRUNE_INTERVAL_MS);
|
|
943
|
+
captures.set(tabId, captureState);
|
|
944
|
+
})();
|
|
945
|
+
pendingCaptures.set(tabId, capturePromise);
|
|
946
|
+
try {
|
|
947
|
+
await capturePromise;
|
|
948
|
+
} finally {
|
|
949
|
+
pendingCaptures.delete(tabId);
|
|
950
|
+
}
|
|
886
951
|
};
|
|
887
952
|
var stopCapture = (tabId) => {
|
|
888
953
|
const state = captures.get(tabId);
|
|
@@ -890,6 +955,7 @@ var stopCapture = (tabId) => {
|
|
|
890
955
|
return;
|
|
891
956
|
clearInterval(state.pruneIntervalId);
|
|
892
957
|
state.wsFramesByRequestId.clear();
|
|
958
|
+
state.wsCreatedAt.clear();
|
|
893
959
|
void chrome.debugger.detach({ tabId }).catch(() => {
|
|
894
960
|
});
|
|
895
961
|
captures.delete(tabId);
|
|
@@ -906,7 +972,6 @@ var getRequests = (tabId, clear = false) => {
|
|
|
906
972
|
if (clear) {
|
|
907
973
|
state.requests = [];
|
|
908
974
|
state.requestIdToRequest.clear();
|
|
909
|
-
state.pendingRequests.clear();
|
|
910
975
|
}
|
|
911
976
|
return requests;
|
|
912
977
|
};
|
|
@@ -937,7 +1002,6 @@ var getWsFrames = (tabId, clear = false) => {
|
|
|
937
1002
|
const frames = [...state.wsFrames];
|
|
938
1003
|
if (clear) {
|
|
939
1004
|
state.wsFrames = [];
|
|
940
|
-
state.wsFramesByRequestId.clear();
|
|
941
1005
|
}
|
|
942
1006
|
return frames;
|
|
943
1007
|
};
|
|
@@ -946,6 +1010,8 @@ var getActiveCapturesSummary = () => Array.from(captures.entries()).map(([tabId,
|
|
|
946
1010
|
requestCount: state.requests.length,
|
|
947
1011
|
isCapturing: true
|
|
948
1012
|
}));
|
|
1013
|
+
|
|
1014
|
+
// dist/plugin-storage.js
|
|
949
1015
|
var metaCache = null;
|
|
950
1016
|
var writeMutex = Promise.resolve();
|
|
951
1017
|
var serialize = (fn) => {
|
|
@@ -1022,6 +1088,8 @@ var getPluginMeta = async (pluginName) => {
|
|
|
1022
1088
|
var invalidatePluginCache = () => {
|
|
1023
1089
|
metaCache = null;
|
|
1024
1090
|
};
|
|
1091
|
+
|
|
1092
|
+
// dist/tab-matching.js
|
|
1025
1093
|
var urlMatchesPatterns = (url, patterns) => {
|
|
1026
1094
|
for (const pattern of patterns) {
|
|
1027
1095
|
if (matchPattern(url, pattern))
|
|
@@ -1112,6 +1180,8 @@ var findAllMatchingTabs = async (plugin) => {
|
|
|
1112
1180
|
};
|
|
1113
1181
|
return allMatches.slice().sort((a, b) => rank(b) - rank(a));
|
|
1114
1182
|
};
|
|
1183
|
+
|
|
1184
|
+
// dist/tab-state.js
|
|
1115
1185
|
var lastKnownState = /* @__PURE__ */ new Map();
|
|
1116
1186
|
var pluginLocks = /* @__PURE__ */ new Map();
|
|
1117
1187
|
var withPluginLock = (pluginName, fn) => {
|
|
@@ -1292,6 +1362,8 @@ var checkTabChanged = async (changedTabId, changeInfo) => {
|
|
|
1292
1362
|
return;
|
|
1293
1363
|
await notifyAffectedPlugins(affectedPlugins);
|
|
1294
1364
|
};
|
|
1365
|
+
|
|
1366
|
+
// dist/browser-commands/extension-commands.js
|
|
1295
1367
|
var handleExtensionGetState = async (id) => {
|
|
1296
1368
|
try {
|
|
1297
1369
|
const sessionData = await chrome.storage.session.get(WS_CONNECTED_KEY).catch(() => ({}));
|
|
@@ -1551,7 +1623,11 @@ var handleBrowserExecuteScript = async (params, id) => {
|
|
|
1551
1623
|
sendValidationError(id, "Invalid execFile format");
|
|
1552
1624
|
return;
|
|
1553
1625
|
}
|
|
1626
|
+
const execUuid = execFile.replace(/^__exec-/, "").replace(/\.js$/, "");
|
|
1627
|
+
const resultKey = `__execResult_${execUuid}`;
|
|
1628
|
+
const asyncKey = `__execAsync_${execUuid}`;
|
|
1554
1629
|
let timeoutId;
|
|
1630
|
+
const cancelled = { value: false };
|
|
1555
1631
|
const injectPromise = (async () => {
|
|
1556
1632
|
await chrome.scripting.executeScript({
|
|
1557
1633
|
target: { tabId },
|
|
@@ -1560,15 +1636,17 @@ var handleBrowserExecuteScript = async (params, id) => {
|
|
|
1560
1636
|
});
|
|
1561
1637
|
let elapsed = 0;
|
|
1562
1638
|
while (elapsed <= EXEC_MAX_ASYNC_WAIT_MS) {
|
|
1639
|
+
if (cancelled.value)
|
|
1640
|
+
return;
|
|
1563
1641
|
const results = await chrome.scripting.executeScript({
|
|
1564
1642
|
target: { tabId },
|
|
1565
1643
|
world: "MAIN",
|
|
1566
|
-
func: (truncLimit) => {
|
|
1644
|
+
func: (truncLimit, rKey, aKey) => {
|
|
1567
1645
|
const ot = globalThis.__openTabs;
|
|
1568
1646
|
if (!ot)
|
|
1569
1647
|
return { pending: false, result: { error: "__openTabs not found" } };
|
|
1570
|
-
const result2 = ot
|
|
1571
|
-
const isAsync = ot
|
|
1648
|
+
const result2 = ot[rKey];
|
|
1649
|
+
const isAsync = ot[aKey] === true;
|
|
1572
1650
|
if (result2 && ("value" in result2 || "error" in result2)) {
|
|
1573
1651
|
const captured = { ...result2 };
|
|
1574
1652
|
if (captured.value === void 0)
|
|
@@ -1581,15 +1659,15 @@ var handleBrowserExecuteScript = async (params, id) => {
|
|
|
1581
1659
|
captured.value = String(captured.value);
|
|
1582
1660
|
}
|
|
1583
1661
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1662
|
+
Reflect.deleteProperty(ot, rKey);
|
|
1663
|
+
Reflect.deleteProperty(ot, aKey);
|
|
1586
1664
|
return { pending: false, result: captured };
|
|
1587
1665
|
}
|
|
1588
1666
|
if (isAsync)
|
|
1589
1667
|
return { pending: true };
|
|
1590
1668
|
return { pending: false, result: { error: "No result captured" } };
|
|
1591
1669
|
},
|
|
1592
|
-
args: [EXEC_RESULT_TRUNCATION_LIMIT]
|
|
1670
|
+
args: [EXEC_RESULT_TRUNCATION_LIMIT, resultKey, asyncKey]
|
|
1593
1671
|
});
|
|
1594
1672
|
const first = results[0];
|
|
1595
1673
|
const data = first?.result;
|
|
@@ -1599,18 +1677,21 @@ var handleBrowserExecuteScript = async (params, id) => {
|
|
|
1599
1677
|
await new Promise((resolve) => setTimeout(resolve, EXEC_POLL_INTERVAL_MS));
|
|
1600
1678
|
elapsed += EXEC_POLL_INTERVAL_MS;
|
|
1601
1679
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1680
|
+
if (!cancelled.value) {
|
|
1681
|
+
await chrome.scripting.executeScript({
|
|
1682
|
+
target: { tabId },
|
|
1683
|
+
world: "MAIN",
|
|
1684
|
+
func: (rKey, aKey) => {
|
|
1685
|
+
const ot = globalThis.__openTabs;
|
|
1686
|
+
if (ot) {
|
|
1687
|
+
Reflect.deleteProperty(ot, rKey);
|
|
1688
|
+
Reflect.deleteProperty(ot, aKey);
|
|
1689
|
+
}
|
|
1690
|
+
},
|
|
1691
|
+
args: [resultKey, asyncKey]
|
|
1692
|
+
}).catch(() => {
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1614
1695
|
return { value: { error: `Async code did not resolve within ${EXEC_MAX_ASYNC_WAIT_MS}ms` } };
|
|
1615
1696
|
})();
|
|
1616
1697
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
@@ -1623,12 +1704,15 @@ var handleBrowserExecuteScript = async (params, id) => {
|
|
|
1623
1704
|
result = await Promise.race([injectPromise, timeoutPromise]);
|
|
1624
1705
|
} finally {
|
|
1625
1706
|
clearTimeout(timeoutId);
|
|
1707
|
+
cancelled.value = true;
|
|
1626
1708
|
}
|
|
1627
1709
|
sendSuccessResult(id, result);
|
|
1628
1710
|
} catch (err2) {
|
|
1629
1711
|
sendErrorResult(id, err2);
|
|
1630
1712
|
}
|
|
1631
1713
|
};
|
|
1714
|
+
|
|
1715
|
+
// dist/browser-commands/resource-commands.js
|
|
1632
1716
|
var TEXT_MIME_PREFIXES = ["text/"];
|
|
1633
1717
|
var TEXT_MIME_EXACT = /* @__PURE__ */ new Set([
|
|
1634
1718
|
"application/javascript",
|
|
@@ -1754,6 +1838,8 @@ var handleBrowserGetResourceContent = async (params, id) => {
|
|
|
1754
1838
|
sendErrorResult(id, err2);
|
|
1755
1839
|
}
|
|
1756
1840
|
};
|
|
1841
|
+
|
|
1842
|
+
// dist/browser-commands/interaction-commands.js
|
|
1757
1843
|
var handleBrowserClickElement = async (params, id) => {
|
|
1758
1844
|
try {
|
|
1759
1845
|
const tabId = requireTabId(params, id);
|
|
@@ -1925,25 +2011,30 @@ var handleBrowserWaitForElement = async (params, id) => {
|
|
|
1925
2011
|
func: (sel, tmo, vis, maxPreview, pollMs) => new Promise((resolve) => {
|
|
1926
2012
|
let elapsed = 0;
|
|
1927
2013
|
const poll = setInterval(() => {
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
2014
|
+
try {
|
|
2015
|
+
const el = document.querySelector(sel);
|
|
2016
|
+
if (el) {
|
|
2017
|
+
const htmlEl = el;
|
|
2018
|
+
const style = getComputedStyle(htmlEl);
|
|
2019
|
+
const isVisible = !vis || style.display !== "none" && style.visibility !== "hidden" && (htmlEl.offsetParent !== null || style.position === "fixed" || style.position === "sticky");
|
|
2020
|
+
if (isVisible) {
|
|
2021
|
+
clearInterval(poll);
|
|
2022
|
+
resolve({
|
|
2023
|
+
found: true,
|
|
2024
|
+
tagName: el.tagName.toLowerCase(),
|
|
2025
|
+
text: (el.textContent || "").trim().slice(0, maxPreview)
|
|
2026
|
+
});
|
|
2027
|
+
return;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
elapsed += pollMs;
|
|
2031
|
+
if (elapsed >= tmo) {
|
|
1934
2032
|
clearInterval(poll);
|
|
1935
|
-
resolve({
|
|
1936
|
-
found: true,
|
|
1937
|
-
tagName: el.tagName.toLowerCase(),
|
|
1938
|
-
text: (el.textContent || "").trim().slice(0, maxPreview)
|
|
1939
|
-
});
|
|
1940
|
-
return;
|
|
2033
|
+
resolve({ error: `Timeout waiting for element: ${sel} (${tmo}ms)` });
|
|
1941
2034
|
}
|
|
1942
|
-
}
|
|
1943
|
-
elapsed += pollMs;
|
|
1944
|
-
if (elapsed >= tmo) {
|
|
2035
|
+
} catch (err2) {
|
|
1945
2036
|
clearInterval(poll);
|
|
1946
|
-
resolve({ error: `
|
|
2037
|
+
resolve({ error: `Error checking element: ${err2 instanceof Error ? err2.message : String(err2)}` });
|
|
1947
2038
|
}
|
|
1948
2039
|
}, pollMs);
|
|
1949
2040
|
}),
|
|
@@ -2074,6 +2165,8 @@ var handleBrowserHandleDialog = async (params, id) => {
|
|
|
2074
2165
|
sendErrorResult(id, err2);
|
|
2075
2166
|
}
|
|
2076
2167
|
};
|
|
2168
|
+
|
|
2169
|
+
// dist/browser-commands/key-press-command.js
|
|
2077
2170
|
var handleBrowserPressKey = async (params, id) => {
|
|
2078
2171
|
try {
|
|
2079
2172
|
const tabId = requireTabId(params, id);
|
|
@@ -2205,6 +2298,8 @@ var handleBrowserPressKey = async (params, id) => {
|
|
|
2205
2298
|
sendErrorResult(id, err2);
|
|
2206
2299
|
}
|
|
2207
2300
|
};
|
|
2301
|
+
|
|
2302
|
+
// dist/browser-commands/scroll-command.js
|
|
2208
2303
|
var handleBrowserScroll = async (params, id) => {
|
|
2209
2304
|
try {
|
|
2210
2305
|
const tabId = requireTabId(params, id);
|
|
@@ -2318,6 +2413,8 @@ var handleBrowserScroll = async (params, id) => {
|
|
|
2318
2413
|
sendErrorResult(id, err2);
|
|
2319
2414
|
}
|
|
2320
2415
|
};
|
|
2416
|
+
|
|
2417
|
+
// dist/browser-commands/network-commands.js
|
|
2321
2418
|
var handleBrowserEnableNetworkCapture = async (params, id) => {
|
|
2322
2419
|
try {
|
|
2323
2420
|
const tabId = requireTabId(params, id);
|
|
@@ -2392,6 +2489,8 @@ var handleBrowserGetWebSocketFrames = (params, id) => {
|
|
|
2392
2489
|
sendErrorResult(id, err2);
|
|
2393
2490
|
}
|
|
2394
2491
|
};
|
|
2492
|
+
|
|
2493
|
+
// dist/browser-commands/tab-commands.js
|
|
2395
2494
|
var handleBrowserListTabs = async (id) => {
|
|
2396
2495
|
try {
|
|
2397
2496
|
const tabs = await chrome.tabs.query({});
|
|
@@ -2479,6 +2578,8 @@ var handleBrowserGetTabInfo = async (params, id) => {
|
|
|
2479
2578
|
sendErrorResult(id, err2);
|
|
2480
2579
|
}
|
|
2481
2580
|
};
|
|
2581
|
+
|
|
2582
|
+
// dist/iife-injection.js
|
|
2482
2583
|
var RESERVED_NAMES = /* @__PURE__ */ new Set(["system", "browser", "opentabs", "extension", "config", "plugin", "tool", "mcp"]);
|
|
2483
2584
|
var isSafePluginName = (name) => isValidPluginName(name) && !RESERVED_NAMES.has(name);
|
|
2484
2585
|
var isAdapterPresent = async (tabId, pluginName) => {
|
|
@@ -2790,6 +2891,8 @@ var reinjectStoredPlugins = async () => {
|
|
|
2790
2891
|
}
|
|
2791
2892
|
}
|
|
2792
2893
|
};
|
|
2894
|
+
|
|
2895
|
+
// dist/rate-limiter.js
|
|
2793
2896
|
var METHOD_LIMITS = /* @__PURE__ */ new Map([
|
|
2794
2897
|
// Expensive operations — tight limits
|
|
2795
2898
|
["browser.screenshotTab", { maxRequests: 2, windowMs: 1e3 }],
|
|
@@ -2818,6 +2921,8 @@ var checkRateLimit = (method, now = Date.now()) => {
|
|
|
2818
2921
|
methodTimestamps.set(method, timestamps);
|
|
2819
2922
|
return true;
|
|
2820
2923
|
};
|
|
2924
|
+
|
|
2925
|
+
// dist/dispatch-helpers.js
|
|
2821
2926
|
var isAdapterNotReady = (result) => result.type === "error" && result.code === JSONRPC_ADAPTER_NOT_READY;
|
|
2822
2927
|
var resolvePlugin = async (pluginName, id) => {
|
|
2823
2928
|
const plugin = await getPluginMeta(pluginName);
|
|
@@ -2924,6 +3029,8 @@ var dispatchWithTabFallback = async (config) => {
|
|
|
2924
3029
|
});
|
|
2925
3030
|
}
|
|
2926
3031
|
};
|
|
3032
|
+
|
|
3033
|
+
// dist/resource-prompt-dispatch.js
|
|
2927
3034
|
var executeResourceReadOnTab = async (tabId, pluginName, resourceUri) => {
|
|
2928
3035
|
const scriptPromise = chrome.scripting.executeScript({
|
|
2929
3036
|
target: { tabId },
|
|
@@ -3090,6 +3197,8 @@ var handlePromptGet = async (params, id) => {
|
|
|
3090
3197
|
executeOnTab: (tabId) => executePromptGetOnTab(tabId, pluginName, promptName, promptArgs)
|
|
3091
3198
|
});
|
|
3092
3199
|
};
|
|
3200
|
+
|
|
3201
|
+
// dist/tool-dispatch.js
|
|
3093
3202
|
var progressCallbacks = /* @__PURE__ */ new Map();
|
|
3094
3203
|
var notifyDispatchProgress = (dispatchId) => {
|
|
3095
3204
|
const cb = progressCallbacks.get(dispatchId);
|
|
@@ -3347,6 +3456,8 @@ var handleToolDispatch = async (params, id) => {
|
|
|
3347
3456
|
}
|
|
3348
3457
|
});
|
|
3349
3458
|
};
|
|
3459
|
+
|
|
3460
|
+
// dist/message-router.js
|
|
3350
3461
|
var wrapAsync = (method, fn) => (params, id) => {
|
|
3351
3462
|
if (id !== void 0) {
|
|
3352
3463
|
fn(params, id).catch((err2) => console.warn(`[opentabs] ${method} handler failed:`, err2));
|
|
@@ -3613,6 +3724,8 @@ var handleServerMessage = (message) => {
|
|
|
3613
3724
|
}
|
|
3614
3725
|
};
|
|
3615
3726
|
var methodHandlerNames = Array.from(methodHandlers.keys());
|
|
3727
|
+
|
|
3728
|
+
// dist/background-message-handlers.js
|
|
3616
3729
|
var wsConnected = false;
|
|
3617
3730
|
var lastDisconnectReason;
|
|
3618
3731
|
var restoreWsConnectedState = () => {
|
|
@@ -3639,7 +3752,6 @@ var handleOffscreenGetUrl = (_message, sendResponse) => {
|
|
|
3639
3752
|
});
|
|
3640
3753
|
};
|
|
3641
3754
|
var handleWsState = (message, sendResponse) => {
|
|
3642
|
-
const wasConnected = wsConnected;
|
|
3643
3755
|
const nowConnected = message.connected;
|
|
3644
3756
|
persistWsConnected(nowConnected);
|
|
3645
3757
|
lastDisconnectReason = nowConnected ? void 0 : message.disconnectReason;
|
|
@@ -3650,7 +3762,7 @@ var handleWsState = (message, sendResponse) => {
|
|
|
3650
3762
|
disconnectReason: lastDisconnectReason
|
|
3651
3763
|
}
|
|
3652
3764
|
});
|
|
3653
|
-
if (!nowConnected
|
|
3765
|
+
if (!nowConnected) {
|
|
3654
3766
|
clearTabStateCache();
|
|
3655
3767
|
clearAllConfirmationBadges();
|
|
3656
3768
|
}
|
|
@@ -3761,7 +3873,10 @@ var EXTENSION_ONLY_TYPES = /* @__PURE__ */ new Set([
|
|
|
3761
3873
|
"ws:message",
|
|
3762
3874
|
"bg:send",
|
|
3763
3875
|
"bg:getConnectionState",
|
|
3764
|
-
"offscreen:getLogs"
|
|
3876
|
+
"offscreen:getLogs",
|
|
3877
|
+
"sp:confirmationResponse",
|
|
3878
|
+
"sp:confirmationTimeout",
|
|
3879
|
+
"port-changed"
|
|
3765
3880
|
]);
|
|
3766
3881
|
var initBackgroundMessageHandlers = () => {
|
|
3767
3882
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
@@ -3778,6 +3893,8 @@ var initBackgroundMessageHandlers = () => {
|
|
|
3778
3893
|
});
|
|
3779
3894
|
};
|
|
3780
3895
|
var backgroundHandlerNames = [...backgroundHandlers.keys()];
|
|
3896
|
+
|
|
3897
|
+
// dist/side-panel-toggle.js
|
|
3781
3898
|
var openWindows = /* @__PURE__ */ new Set();
|
|
3782
3899
|
var initSidePanelToggle = () => {
|
|
3783
3900
|
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: false }).catch(() => {
|
|
@@ -3814,6 +3931,8 @@ var initSidePanelToggle = () => {
|
|
|
3814
3931
|
})();
|
|
3815
3932
|
});
|
|
3816
3933
|
};
|
|
3934
|
+
|
|
3935
|
+
// dist/background.js
|
|
3817
3936
|
initSidePanelToggle();
|
|
3818
3937
|
restoreWsConnectedState();
|
|
3819
3938
|
var creatingOffscreen = null;
|
|
@@ -5,6 +5,8 @@ export declare const handleExtensionCheckAdapter: (params: Record<string, unknow
|
|
|
5
5
|
export declare const handleExtensionForceReconnect: (id: string | number) => Promise<void>;
|
|
6
6
|
/**
|
|
7
7
|
* Executes a pre-written JavaScript file in a tab's MAIN world, supporting both sync and async code.
|
|
8
|
+
* Each execution uses namespaced keys (`__execResult_<uuid>`, `__execAsync_<uuid>`) on
|
|
9
|
+
* `globalThis.__openTabs` so concurrent executions on the same tab do not collide.
|
|
8
10
|
* @param params - Expects `{ tabId: number, execFile: string }` where execFile matches the `__exec-<uuid>.js` pattern.
|
|
9
11
|
* @returns The script's return value, serialized as JSON. Async scripts are polled until resolved or timed out.
|
|
10
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-commands.d.ts","sourceRoot":"","sources":["../../src/browser-commands/extension-commands.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,uBAAuB,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAqD/E,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CA8D/G,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CA0BnF,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,MAAM,GAAG,MAAM,KAClB,OAAO,CAAC,IAAI,CAkJd,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBrF,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"extension-commands.d.ts","sourceRoot":"","sources":["../../src/browser-commands/extension-commands.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,uBAAuB,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAqD/E,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CA8D/G,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CA0BnF,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,MAAM,GAAG,MAAM,KAClB,OAAO,CAAC,IAAI,CAkJd,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAU,IAAI,MAAM,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAiBrF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GACrC,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,MAAM,GAAG,MAAM,KAClB,OAAO,CAAC,IAAI,CA+Hd,CAAC"}
|