@opentabs-dev/browser-extension 0.0.52 → 0.0.54
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 +33 -6
- package/dist/background-message-handlers.d.ts.map +1 -1
- package/dist/background-message-handlers.js +335 -20
- package/dist/background-message-handlers.js.map +1 -1
- package/dist/background.js +859 -365
- package/dist/background.js.map +1 -1
- package/dist/browser-commands/extension-commands.d.ts.map +1 -1
- package/dist/browser-commands/extension-commands.js +5 -2
- package/dist/browser-commands/extension-commands.js.map +1 -1
- package/dist/browser-commands/key-press-command.d.ts +2 -0
- package/dist/browser-commands/key-press-command.d.ts.map +1 -1
- package/dist/browser-commands/key-press-command.js +42 -4
- package/dist/browser-commands/key-press-command.js.map +1 -1
- package/dist/confirmation-badge.d.ts +17 -3
- package/dist/confirmation-badge.d.ts.map +1 -1
- package/dist/confirmation-badge.js +55 -18
- package/dist/confirmation-badge.js.map +1 -1
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -1
- package/dist/dispatch-helpers.d.ts +1 -1
- package/dist/extension-messages.d.ts +48 -21
- package/dist/extension-messages.d.ts.map +1 -1
- package/dist/known-methods.d.ts +2 -2
- package/dist/known-methods.d.ts.map +1 -1
- package/dist/known-methods.js +1 -2
- package/dist/known-methods.js.map +1 -1
- package/dist/message-router.d.ts.map +1 -1
- package/dist/message-router.js +163 -24
- package/dist/message-router.js.map +1 -1
- package/dist/offscreen/index.js +17 -7
- package/dist/offscreen/index.js.map +1 -1
- package/dist/server-request.d.ts +19 -0
- package/dist/server-request.d.ts.map +1 -0
- package/dist/server-request.js +79 -0
- package/dist/server-request.js.map +1 -0
- package/dist/server-state-cache.d.ts +68 -0
- package/dist/server-state-cache.d.ts.map +1 -0
- package/dist/server-state-cache.js +208 -0
- package/dist/server-state-cache.js.map +1 -0
- package/dist/side-panel/App.d.ts.map +1 -1
- package/dist/side-panel/App.js +60 -58
- package/dist/side-panel/App.js.map +1 -1
- package/dist/side-panel/bridge.d.ts +31 -34
- package/dist/side-panel/bridge.d.ts.map +1 -1
- package/dist/side-panel/bridge.js +27 -91
- package/dist/side-panel/bridge.js.map +1 -1
- package/dist/side-panel/components/BrowserToolsCard.d.ts.map +1 -1
- package/dist/side-panel/components/BrowserToolsCard.js +2 -1
- package/dist/side-panel/components/BrowserToolsCard.js.map +1 -1
- package/dist/side-panel/components/ConfirmationDialog.d.ts +7 -2
- package/dist/side-panel/components/ConfirmationDialog.d.ts.map +1 -1
- package/dist/side-panel/components/ConfirmationDialog.js.map +1 -1
- package/dist/side-panel/components/PluginCard.d.ts.map +1 -1
- package/dist/side-panel/components/PluginCard.js +2 -1
- package/dist/side-panel/components/PluginCard.js.map +1 -1
- package/dist/side-panel/components/PluginIcon.d.ts +2 -1
- package/dist/side-panel/components/PluginIcon.d.ts.map +1 -1
- package/dist/side-panel/components/PluginIcon.js +23 -5
- package/dist/side-panel/components/PluginIcon.js.map +1 -1
- package/dist/side-panel/components/ToolIcon.d.ts +2 -1
- package/dist/side-panel/components/ToolIcon.d.ts.map +1 -1
- package/dist/side-panel/components/ToolIcon.js +17 -3
- package/dist/side-panel/components/ToolIcon.js.map +1 -1
- package/dist/side-panel/components/ToolRow.d.ts.map +1 -1
- package/dist/side-panel/components/ToolRow.js +1 -2
- package/dist/side-panel/components/ToolRow.js.map +1 -1
- package/dist/side-panel/components/retro/Button.d.ts +1 -1
- package/dist/side-panel/hooks/useServerNotifications.d.ts +1 -3
- package/dist/side-panel/hooks/useServerNotifications.d.ts.map +1 -1
- package/dist/side-panel/hooks/useServerNotifications.js +15 -11
- package/dist/side-panel/hooks/useServerNotifications.js.map +1 -1
- package/dist/side-panel/side-panel.js +1254 -1218
- package/dist/side-panel/styles.css +1 -1
- package/dist/side-panel-toggle.d.ts +6 -0
- package/dist/side-panel-toggle.d.ts.map +1 -1
- package/dist/side-panel-toggle.js +6 -0
- package/dist/side-panel-toggle.js.map +1 -1
- package/dist/tab-state.d.ts +26 -1
- package/dist/tab-state.d.ts.map +1 -1
- package/dist/tab-state.js +163 -11
- package/dist/tab-state.js.map +1 -1
- package/dist/tool-dispatch.d.ts.map +1 -1
- package/dist/tool-dispatch.js +3 -2
- package/dist/tool-dispatch.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +1 -1
package/dist/background.js
CHANGED
|
@@ -1,5 +1,99 @@
|
|
|
1
|
+
// dist/constants.js
|
|
2
|
+
var KEEPALIVE_ALARM = "opentabs-keepalive";
|
|
3
|
+
var KEEPALIVE_INTERVAL_MINUTES = 0.5;
|
|
4
|
+
var PLUGINS_META_KEY = "plugins_meta";
|
|
5
|
+
var WS_CONNECTED_KEY = "wsConnected";
|
|
6
|
+
var SIDE_PANEL_OPEN_WINDOWS_KEY = "sidePanelOpenWindows";
|
|
7
|
+
var SCRIPT_TIMEOUT_MS = 25e3;
|
|
8
|
+
var MAX_SCRIPT_TIMEOUT_MS = 295e3;
|
|
9
|
+
var IS_READY_TIMEOUT_MS = 5e3;
|
|
10
|
+
var READINESS_POLL_INTERVAL_MS = 3e4;
|
|
11
|
+
var RELOAD_FLUSH_DELAY_MS = 100;
|
|
12
|
+
var INJECTION_RETRY_DELAY_MS = 200;
|
|
13
|
+
var SCREENSHOT_RENDER_DELAY_MS = 100;
|
|
14
|
+
var WS_FLUSH_DELAY_MS = 50;
|
|
15
|
+
var SERVER_PORT_KEY = "serverPort";
|
|
16
|
+
var DEFAULT_SERVER_PORT = 9515;
|
|
17
|
+
var TEXT_PREVIEW_MAX_LENGTH = 200;
|
|
18
|
+
var DEFAULT_WAIT_TIMEOUT_MS = 1e4;
|
|
19
|
+
var POLL_INTERVAL_MS = 100;
|
|
20
|
+
var DEFAULT_QUERY_LIMIT = 100;
|
|
21
|
+
var MAX_INPUT_SIZE = 10 * 1024 * 1024;
|
|
22
|
+
var SIDE_PANEL_TIMEOUT_MS = 3e3;
|
|
23
|
+
var CDP_VERSION = "1.3";
|
|
24
|
+
var EXEC_MAX_ASYNC_WAIT_MS = 1e4;
|
|
25
|
+
var EXEC_POLL_INTERVAL_MS = 50;
|
|
26
|
+
var EXEC_RESULT_TRUNCATION_LIMIT = 5e4;
|
|
27
|
+
var DEFAULT_LOG_LIMIT = 100;
|
|
28
|
+
var VALID_PLUGIN_NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
29
|
+
var isValidPluginName = (name) => VALID_PLUGIN_NAME.test(name);
|
|
30
|
+
var buildWsUrl = (port) => `ws://localhost:${port}/ws`;
|
|
31
|
+
|
|
32
|
+
// dist/side-panel-toggle.js
|
|
33
|
+
var openWindows = /* @__PURE__ */ new Set();
|
|
34
|
+
var persistOpenWindows = () => {
|
|
35
|
+
chrome.storage.session.set({ [SIDE_PANEL_OPEN_WINDOWS_KEY]: Array.from(openWindows) }).catch(() => {
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
var restoreOpenWindows = () => {
|
|
39
|
+
chrome.storage.session.get(SIDE_PANEL_OPEN_WINDOWS_KEY).then((data) => {
|
|
40
|
+
const stored = data[SIDE_PANEL_OPEN_WINDOWS_KEY];
|
|
41
|
+
if (Array.isArray(stored)) {
|
|
42
|
+
for (const id of stored) {
|
|
43
|
+
if (typeof id === "number") {
|
|
44
|
+
openWindows.add(id);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}).catch(() => {
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
var isSidePanelOpen = () => openWindows.size > 0;
|
|
52
|
+
var initSidePanelToggle = () => {
|
|
53
|
+
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: false }).catch(() => {
|
|
54
|
+
});
|
|
55
|
+
const canToggle = "onOpened" in chrome.sidePanel;
|
|
56
|
+
if (canToggle) {
|
|
57
|
+
restoreOpenWindows();
|
|
58
|
+
chrome.sidePanel.onOpened.addListener(({ windowId }) => {
|
|
59
|
+
openWindows.add(windowId);
|
|
60
|
+
persistOpenWindows();
|
|
61
|
+
});
|
|
62
|
+
chrome.sidePanel.onClosed.addListener(({ windowId }) => {
|
|
63
|
+
openWindows.delete(windowId);
|
|
64
|
+
persistOpenWindows();
|
|
65
|
+
});
|
|
66
|
+
chrome.windows.onRemoved.addListener((windowId) => {
|
|
67
|
+
openWindows.delete(windowId);
|
|
68
|
+
persistOpenWindows();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
chrome.action.onClicked.addListener(({ windowId }) => {
|
|
72
|
+
void (async () => {
|
|
73
|
+
if (canToggle && openWindows.has(windowId)) {
|
|
74
|
+
try {
|
|
75
|
+
await chrome.windows.get(windowId);
|
|
76
|
+
} catch {
|
|
77
|
+
openWindows.delete(windowId);
|
|
78
|
+
persistOpenWindows();
|
|
79
|
+
await chrome.sidePanel.open({ windowId }).catch(() => {
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
chrome.sidePanel.close({ windowId }).catch(() => {
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
chrome.sidePanel.open({ windowId }).catch(() => {
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
})();
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
1
93
|
// dist/confirmation-badge.js
|
|
2
94
|
var pendingConfirmationCount = 0;
|
|
95
|
+
var NOTIFICATION_ID = "opentabs-confirmation";
|
|
96
|
+
var pendingConfirmations = /* @__PURE__ */ new Map();
|
|
3
97
|
var confirmationTimeouts = /* @__PURE__ */ new Map();
|
|
4
98
|
var clearedConfirmationIds = /* @__PURE__ */ new Set();
|
|
5
99
|
var CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS = 2e3;
|
|
@@ -15,11 +109,39 @@ var updateConfirmationBadge = () => {
|
|
|
15
109
|
});
|
|
16
110
|
}
|
|
17
111
|
};
|
|
112
|
+
var syncConfirmationNotification = () => {
|
|
113
|
+
if (pendingConfirmationCount <= 0 || isSidePanelOpen()) {
|
|
114
|
+
chrome.notifications.clear(NOTIFICATION_ID).catch(() => {
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
let message;
|
|
119
|
+
if (pendingConfirmationCount === 1 && pendingConfirmations.size === 1) {
|
|
120
|
+
const info = pendingConfirmations.values().next().value;
|
|
121
|
+
message = info.domain ? `${info.tool} on ${info.domain}` : info.tool;
|
|
122
|
+
} else if (pendingConfirmationCount > 1) {
|
|
123
|
+
message = `${pendingConfirmationCount} tools awaiting approval`;
|
|
124
|
+
} else {
|
|
125
|
+
message = "1 tool awaiting approval";
|
|
126
|
+
}
|
|
127
|
+
chrome.notifications.create(NOTIFICATION_ID, {
|
|
128
|
+
type: "basic",
|
|
129
|
+
iconUrl: chrome.runtime.getURL("icons/icon-128.png"),
|
|
130
|
+
title: "OpenTabs \u2014 Approval Required",
|
|
131
|
+
message,
|
|
132
|
+
priority: 2,
|
|
133
|
+
requireInteraction: true
|
|
134
|
+
}).catch(() => {
|
|
135
|
+
});
|
|
136
|
+
};
|
|
18
137
|
var notifyConfirmationRequest = (params) => {
|
|
19
138
|
const tool = typeof params.tool === "string" ? params.tool : "unknown tool";
|
|
20
|
-
const domain = typeof params.domain === "string" ? params.domain :
|
|
139
|
+
const domain = typeof params.domain === "string" ? params.domain : null;
|
|
21
140
|
const id = typeof params.id === "string" ? params.id : String(Date.now());
|
|
141
|
+
const tabId = typeof params.tabId === "number" ? params.tabId : void 0;
|
|
142
|
+
const paramsPreview = typeof params.paramsPreview === "string" ? params.paramsPreview : "";
|
|
22
143
|
const timeoutMs = typeof params.timeoutMs === "number" ? params.timeoutMs : 0;
|
|
144
|
+
const receivedAt = Date.now();
|
|
23
145
|
const existingTimeoutId = confirmationTimeouts.get(id);
|
|
24
146
|
if (existingTimeoutId !== void 0) {
|
|
25
147
|
clearTimeout(existingTimeoutId);
|
|
@@ -28,6 +150,7 @@ var notifyConfirmationRequest = (params) => {
|
|
|
28
150
|
pendingConfirmationCount++;
|
|
29
151
|
updateConfirmationBadge();
|
|
30
152
|
}
|
|
153
|
+
pendingConfirmations.set(id, { id, tool, domain, tabId, paramsPreview, timeoutMs, receivedAt });
|
|
31
154
|
const effectiveTimeoutMs = timeoutMs > 0 ? timeoutMs : CONFIRMATION_FALLBACK_TIMEOUT_MS;
|
|
32
155
|
const bgTimeoutId = setTimeout(() => {
|
|
33
156
|
confirmationTimeouts.delete(id);
|
|
@@ -35,15 +158,7 @@ var notifyConfirmationRequest = (params) => {
|
|
|
35
158
|
clearedConfirmationIds.delete(id);
|
|
36
159
|
}, effectiveTimeoutMs + CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS);
|
|
37
160
|
confirmationTimeouts.set(id, bgTimeoutId);
|
|
38
|
-
|
|
39
|
-
type: "basic",
|
|
40
|
-
iconUrl: chrome.runtime.getURL("icons/icon-128.png"),
|
|
41
|
-
title: "OpenTabs: Approval Required",
|
|
42
|
-
message: `${tool} on ${domain} \u2014 Click to open side panel`,
|
|
43
|
-
priority: 2,
|
|
44
|
-
requireInteraction: true
|
|
45
|
-
}).catch(() => {
|
|
46
|
-
});
|
|
161
|
+
syncConfirmationNotification();
|
|
47
162
|
};
|
|
48
163
|
var clearConfirmationBadge = (id) => {
|
|
49
164
|
if (id !== void 0) {
|
|
@@ -51,11 +166,11 @@ var clearConfirmationBadge = (id) => {
|
|
|
51
166
|
return;
|
|
52
167
|
}
|
|
53
168
|
clearedConfirmationIds.add(id);
|
|
54
|
-
|
|
55
|
-
});
|
|
169
|
+
pendingConfirmations.delete(id);
|
|
56
170
|
}
|
|
57
171
|
pendingConfirmationCount = Math.max(0, pendingConfirmationCount - 1);
|
|
58
172
|
updateConfirmationBadge();
|
|
173
|
+
syncConfirmationNotification();
|
|
59
174
|
if (id !== void 0 && !confirmationTimeouts.has(id)) {
|
|
60
175
|
clearedConfirmationIds.delete(id);
|
|
61
176
|
}
|
|
@@ -69,19 +184,20 @@ var clearConfirmationBackgroundTimeout = (id) => {
|
|
|
69
184
|
}
|
|
70
185
|
};
|
|
71
186
|
var clearAllConfirmationBadges = () => {
|
|
72
|
-
for (const [
|
|
187
|
+
for (const [, timeoutId] of confirmationTimeouts.entries()) {
|
|
73
188
|
clearTimeout(timeoutId);
|
|
74
|
-
chrome.notifications.clear(`opentabs-confirm-${id}`).catch(() => {
|
|
75
|
-
});
|
|
76
189
|
}
|
|
77
190
|
confirmationTimeouts.clear();
|
|
78
191
|
clearedConfirmationIds.clear();
|
|
192
|
+
pendingConfirmations.clear();
|
|
79
193
|
pendingConfirmationCount = 0;
|
|
80
194
|
updateConfirmationBadge();
|
|
195
|
+
chrome.notifications.clear(NOTIFICATION_ID).catch(() => {
|
|
196
|
+
});
|
|
81
197
|
};
|
|
82
198
|
var initConfirmationBadge = () => {
|
|
83
199
|
chrome.notifications.onClicked.addListener((notificationId) => {
|
|
84
|
-
if (notificationId
|
|
200
|
+
if (notificationId === NOTIFICATION_ID) {
|
|
85
201
|
chrome.windows.getCurrent().then((w) => {
|
|
86
202
|
if (w.id !== void 0) {
|
|
87
203
|
chrome.sidePanel.open({ windowId: w.id }).catch(() => {
|
|
@@ -94,36 +210,7 @@ var initConfirmationBadge = () => {
|
|
|
94
210
|
}
|
|
95
211
|
});
|
|
96
212
|
};
|
|
97
|
-
|
|
98
|
-
// dist/constants.js
|
|
99
|
-
var KEEPALIVE_ALARM = "opentabs-keepalive";
|
|
100
|
-
var KEEPALIVE_INTERVAL_MINUTES = 0.5;
|
|
101
|
-
var PLUGINS_META_KEY = "plugins_meta";
|
|
102
|
-
var WS_CONNECTED_KEY = "wsConnected";
|
|
103
|
-
var SIDE_PANEL_OPEN_WINDOWS_KEY = "sidePanelOpenWindows";
|
|
104
|
-
var SCRIPT_TIMEOUT_MS = 25e3;
|
|
105
|
-
var MAX_SCRIPT_TIMEOUT_MS = 295e3;
|
|
106
|
-
var IS_READY_TIMEOUT_MS = 5e3;
|
|
107
|
-
var RELOAD_FLUSH_DELAY_MS = 100;
|
|
108
|
-
var INJECTION_RETRY_DELAY_MS = 200;
|
|
109
|
-
var SCREENSHOT_RENDER_DELAY_MS = 100;
|
|
110
|
-
var WS_FLUSH_DELAY_MS = 50;
|
|
111
|
-
var SERVER_PORT_KEY = "serverPort";
|
|
112
|
-
var DEFAULT_SERVER_PORT = 9515;
|
|
113
|
-
var TEXT_PREVIEW_MAX_LENGTH = 200;
|
|
114
|
-
var DEFAULT_WAIT_TIMEOUT_MS = 1e4;
|
|
115
|
-
var POLL_INTERVAL_MS = 100;
|
|
116
|
-
var DEFAULT_QUERY_LIMIT = 100;
|
|
117
|
-
var MAX_INPUT_SIZE = 10 * 1024 * 1024;
|
|
118
|
-
var SIDE_PANEL_TIMEOUT_MS = 3e3;
|
|
119
|
-
var CDP_VERSION = "1.3";
|
|
120
|
-
var EXEC_MAX_ASYNC_WAIT_MS = 1e4;
|
|
121
|
-
var EXEC_POLL_INTERVAL_MS = 50;
|
|
122
|
-
var EXEC_RESULT_TRUNCATION_LIMIT = 5e4;
|
|
123
|
-
var DEFAULT_LOG_LIMIT = 100;
|
|
124
|
-
var VALID_PLUGIN_NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
125
|
-
var isValidPluginName = (name) => VALID_PLUGIN_NAME.test(name);
|
|
126
|
-
var buildWsUrl = (port) => `ws://localhost:${port}/ws`;
|
|
213
|
+
var getPendingConfirmations = () => [...pendingConfirmations.values()];
|
|
127
214
|
|
|
128
215
|
// dist/json-rpc-errors.js
|
|
129
216
|
var JSONRPC_METHOD_NOT_FOUND = -32601;
|
|
@@ -1185,6 +1272,20 @@ var findAllMatchingTabs = async (plugin) => {
|
|
|
1185
1272
|
// dist/tab-state.js
|
|
1186
1273
|
var serializeTabState = (info) => JSON.stringify({ state: info.state, tabs: info.tabs });
|
|
1187
1274
|
var lastKnownState = /* @__PURE__ */ new Map();
|
|
1275
|
+
var LAST_KNOWN_STATE_SESSION_KEY = "lastKnownState";
|
|
1276
|
+
var lastKnownStatePersistTimer;
|
|
1277
|
+
var persistLastKnownStateToSession = () => {
|
|
1278
|
+
chrome.storage.session.set({ [LAST_KNOWN_STATE_SESSION_KEY]: Object.fromEntries(lastKnownState) }).catch(() => {
|
|
1279
|
+
});
|
|
1280
|
+
};
|
|
1281
|
+
var scheduleLastKnownStatePersist = () => {
|
|
1282
|
+
if (lastKnownStatePersistTimer !== void 0)
|
|
1283
|
+
clearTimeout(lastKnownStatePersistTimer);
|
|
1284
|
+
lastKnownStatePersistTimer = setTimeout(() => {
|
|
1285
|
+
lastKnownStatePersistTimer = void 0;
|
|
1286
|
+
persistLastKnownStateToSession();
|
|
1287
|
+
}, 500);
|
|
1288
|
+
};
|
|
1188
1289
|
var pluginLocks = /* @__PURE__ */ new Map();
|
|
1189
1290
|
var withPluginLock = (pluginName, fn) => {
|
|
1190
1291
|
const prev = pluginLocks.get(pluginName) ?? Promise.resolve();
|
|
@@ -1238,33 +1339,45 @@ var computePluginTabState = async (plugin) => {
|
|
|
1238
1339
|
if (matchingTabs.length === 0) {
|
|
1239
1340
|
return { state: "closed", tabs: [] };
|
|
1240
1341
|
}
|
|
1241
|
-
const
|
|
1242
|
-
|
|
1243
|
-
if (tab.id === void 0)
|
|
1244
|
-
continue;
|
|
1342
|
+
const validTabs = matchingTabs.filter((tab) => tab.id !== void 0);
|
|
1343
|
+
const results = await Promise.allSettled(validTabs.map(async (tab) => {
|
|
1245
1344
|
let ready = false;
|
|
1246
1345
|
try {
|
|
1247
1346
|
ready = await probeTabReadiness(tab.id, plugin.name);
|
|
1248
1347
|
} catch (err2) {
|
|
1249
1348
|
console.warn(`[opentabs] computePluginTabState failed for plugin ${plugin.name} in tab ${tab.id}:`, err2);
|
|
1250
1349
|
}
|
|
1251
|
-
|
|
1350
|
+
return {
|
|
1252
1351
|
tabId: tab.id,
|
|
1253
1352
|
url: tab.url ?? "",
|
|
1254
1353
|
title: tab.title ?? "",
|
|
1255
1354
|
ready
|
|
1256
|
-
}
|
|
1355
|
+
};
|
|
1356
|
+
}));
|
|
1357
|
+
const tabInfos = [];
|
|
1358
|
+
for (const result of results) {
|
|
1359
|
+
if (result.status === "fulfilled") {
|
|
1360
|
+
tabInfos.push(result.value);
|
|
1361
|
+
}
|
|
1257
1362
|
}
|
|
1258
1363
|
const hasReady = tabInfos.some((t) => t.ready);
|
|
1259
1364
|
const state = hasReady ? "ready" : "unavailable";
|
|
1260
1365
|
return { state, tabs: tabInfos };
|
|
1261
1366
|
};
|
|
1262
1367
|
var sendTabSyncAll = async () => {
|
|
1368
|
+
const syncAllStart = Date.now();
|
|
1369
|
+
console.log("[opentabs:timing] sendTabSyncAll started");
|
|
1263
1370
|
const index = await getAllPluginMeta();
|
|
1264
1371
|
const plugins = Object.values(index);
|
|
1265
1372
|
if (plugins.length === 0)
|
|
1266
1373
|
return;
|
|
1267
|
-
const settled = await Promise.allSettled(plugins.map(async (plugin) =>
|
|
1374
|
+
const settled = await Promise.allSettled(plugins.map(async (plugin) => {
|
|
1375
|
+
const t0 = Date.now();
|
|
1376
|
+
const result = [plugin.name, await computePluginTabState(plugin)];
|
|
1377
|
+
console.log(`[opentabs:timing] computePluginTabState(${plugin.name}): ${Date.now() - t0}ms`);
|
|
1378
|
+
return result;
|
|
1379
|
+
}));
|
|
1380
|
+
console.log(`[opentabs:timing] all probes done: +${Date.now() - syncAllStart}ms`);
|
|
1268
1381
|
const entries = [];
|
|
1269
1382
|
for (const result of settled) {
|
|
1270
1383
|
if (result.status === "fulfilled") {
|
|
@@ -1281,15 +1394,20 @@ var sendTabSyncAll = async () => {
|
|
|
1281
1394
|
pluginNamesInSync.add(pluginName);
|
|
1282
1395
|
return withPluginLock(pluginName, () => {
|
|
1283
1396
|
lastKnownState.set(pluginName, serializeTabState(stateInfo));
|
|
1397
|
+
scheduleLastKnownStatePersist();
|
|
1284
1398
|
return Promise.resolve();
|
|
1285
1399
|
});
|
|
1286
1400
|
}));
|
|
1401
|
+
let removedStale = false;
|
|
1287
1402
|
for (const key of lastKnownState.keys()) {
|
|
1288
1403
|
if (!pluginNamesInSync.has(key)) {
|
|
1289
1404
|
lastKnownState.delete(key);
|
|
1290
1405
|
pluginLocks.delete(key);
|
|
1406
|
+
removedStale = true;
|
|
1291
1407
|
}
|
|
1292
1408
|
}
|
|
1409
|
+
if (removedStale)
|
|
1410
|
+
scheduleLastKnownStatePersist();
|
|
1293
1411
|
sendToServer({
|
|
1294
1412
|
jsonrpc: "2.0",
|
|
1295
1413
|
method: "tab.syncAll",
|
|
@@ -1306,23 +1424,56 @@ var sendTabSyncAll = async () => {
|
|
|
1306
1424
|
});
|
|
1307
1425
|
}
|
|
1308
1426
|
};
|
|
1427
|
+
var flushLastKnownStateToSession = () => {
|
|
1428
|
+
if (lastKnownStatePersistTimer !== void 0) {
|
|
1429
|
+
clearTimeout(lastKnownStatePersistTimer);
|
|
1430
|
+
lastKnownStatePersistTimer = void 0;
|
|
1431
|
+
}
|
|
1432
|
+
persistLastKnownStateToSession();
|
|
1433
|
+
};
|
|
1309
1434
|
var clearTabStateCache = () => {
|
|
1310
1435
|
lastKnownState.clear();
|
|
1311
1436
|
pluginLocks.clear();
|
|
1437
|
+
if (lastKnownStatePersistTimer !== void 0) {
|
|
1438
|
+
clearTimeout(lastKnownStatePersistTimer);
|
|
1439
|
+
lastKnownStatePersistTimer = void 0;
|
|
1440
|
+
}
|
|
1441
|
+
chrome.storage.session.remove(LAST_KNOWN_STATE_SESSION_KEY).catch(() => {
|
|
1442
|
+
});
|
|
1312
1443
|
};
|
|
1313
1444
|
var clearPluginTabState = (pluginName) => {
|
|
1445
|
+
const had = lastKnownState.has(pluginName);
|
|
1314
1446
|
lastKnownState.delete(pluginName);
|
|
1315
1447
|
pluginLocks.delete(pluginName);
|
|
1448
|
+
if (had)
|
|
1449
|
+
scheduleLastKnownStatePersist();
|
|
1316
1450
|
};
|
|
1317
1451
|
var updateLastKnownState = (pluginName, stateInfo) => withPluginLock(pluginName, () => {
|
|
1318
1452
|
lastKnownState.set(pluginName, serializeTabState(stateInfo));
|
|
1453
|
+
scheduleLastKnownStatePersist();
|
|
1319
1454
|
return Promise.resolve();
|
|
1320
1455
|
});
|
|
1321
1456
|
var getLastKnownStates = () => lastKnownState;
|
|
1457
|
+
var loadLastKnownStateFromSession = async () => {
|
|
1458
|
+
lastKnownState.clear();
|
|
1459
|
+
try {
|
|
1460
|
+
const data = await chrome.storage.session.get(LAST_KNOWN_STATE_SESSION_KEY);
|
|
1461
|
+
const stored = data[LAST_KNOWN_STATE_SESSION_KEY];
|
|
1462
|
+
if (stored && typeof stored === "object" && !Array.isArray(stored)) {
|
|
1463
|
+
for (const [key, value] of Object.entries(stored)) {
|
|
1464
|
+
if (typeof value === "string") {
|
|
1465
|
+
lastKnownState.set(key, value);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
} catch {
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1322
1472
|
var getAggregateState = (serialized) => {
|
|
1323
1473
|
try {
|
|
1324
1474
|
const parsed = JSON.parse(serialized);
|
|
1325
|
-
|
|
1475
|
+
const validStates = /* @__PURE__ */ new Set(["closed", "unavailable", "ready"]);
|
|
1476
|
+
return validStates.has(parsed.state) ? parsed.state : "closed";
|
|
1326
1477
|
} catch {
|
|
1327
1478
|
return "closed";
|
|
1328
1479
|
}
|
|
@@ -1335,6 +1486,7 @@ var notifyAffectedPlugins = async (affectedPlugins) => {
|
|
|
1335
1486
|
if (previous === serialized)
|
|
1336
1487
|
return;
|
|
1337
1488
|
lastKnownState.set(plugin.name, serialized);
|
|
1489
|
+
scheduleLastKnownStatePersist();
|
|
1338
1490
|
sendTabStateNotification(plugin.name, newState);
|
|
1339
1491
|
})));
|
|
1340
1492
|
};
|
|
@@ -1382,6 +1534,46 @@ var checkTabChanged = async (changedTabId, changeInfo) => {
|
|
|
1382
1534
|
return;
|
|
1383
1535
|
await notifyAffectedPlugins(affectedPlugins);
|
|
1384
1536
|
};
|
|
1537
|
+
var readinessPollTimer;
|
|
1538
|
+
var readinessPollRunning = false;
|
|
1539
|
+
var runReadinessPoll = async () => {
|
|
1540
|
+
if (readinessPollRunning)
|
|
1541
|
+
return;
|
|
1542
|
+
readinessPollRunning = true;
|
|
1543
|
+
try {
|
|
1544
|
+
const index = await getAllPluginMeta();
|
|
1545
|
+
const plugins = Object.values(index);
|
|
1546
|
+
if (plugins.length === 0)
|
|
1547
|
+
return;
|
|
1548
|
+
const activePlugins = plugins.filter((p) => {
|
|
1549
|
+
const cached = lastKnownState.get(p.name);
|
|
1550
|
+
return cached !== void 0 && getAggregateState(cached) !== "closed";
|
|
1551
|
+
});
|
|
1552
|
+
if (activePlugins.length === 0)
|
|
1553
|
+
return;
|
|
1554
|
+
await notifyAffectedPlugins(activePlugins);
|
|
1555
|
+
} catch (err2) {
|
|
1556
|
+
console.warn("[opentabs] readiness poll failed:", err2);
|
|
1557
|
+
} finally {
|
|
1558
|
+
readinessPollRunning = false;
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
var startReadinessPoll = () => {
|
|
1562
|
+
if (readinessPollTimer !== void 0)
|
|
1563
|
+
return;
|
|
1564
|
+
readinessPollTimer = setInterval(() => {
|
|
1565
|
+
runReadinessPoll().catch((err2) => {
|
|
1566
|
+
console.warn("[opentabs] readiness poll tick failed:", err2);
|
|
1567
|
+
});
|
|
1568
|
+
}, READINESS_POLL_INTERVAL_MS);
|
|
1569
|
+
};
|
|
1570
|
+
var stopReadinessPoll = () => {
|
|
1571
|
+
if (readinessPollTimer !== void 0) {
|
|
1572
|
+
clearInterval(readinessPollTimer);
|
|
1573
|
+
readinessPollTimer = void 0;
|
|
1574
|
+
}
|
|
1575
|
+
readinessPollRunning = false;
|
|
1576
|
+
};
|
|
1385
1577
|
|
|
1386
1578
|
// dist/browser-commands/extension-commands.js
|
|
1387
1579
|
var handleExtensionGetState = async (id) => {
|
|
@@ -1450,7 +1642,8 @@ var handleExtensionGetLogs = async (params, id) => {
|
|
|
1450
1642
|
if (typeof params.since === "number") {
|
|
1451
1643
|
filterOptions.since = params.since;
|
|
1452
1644
|
}
|
|
1453
|
-
const
|
|
1645
|
+
const { limit: _, ...sourceOptions } = filterOptions;
|
|
1646
|
+
const bgEntries = bgLogCollector.getEntries(sourceOptions);
|
|
1454
1647
|
const bgStats = bgLogCollector.getStats();
|
|
1455
1648
|
let offscreenEntries = [];
|
|
1456
1649
|
let offscreenStats = {
|
|
@@ -1462,7 +1655,7 @@ var handleExtensionGetLogs = async (params, id) => {
|
|
|
1462
1655
|
try {
|
|
1463
1656
|
const raw = await chrome.runtime.sendMessage({
|
|
1464
1657
|
type: "offscreen:getLogs",
|
|
1465
|
-
options: Object.keys(
|
|
1658
|
+
options: Object.keys(sourceOptions).length > 0 ? sourceOptions : void 0
|
|
1466
1659
|
});
|
|
1467
1660
|
const response = raw;
|
|
1468
1661
|
if (response && Array.isArray(response.entries)) {
|
|
@@ -2222,6 +2415,42 @@ var handleBrowserHandleDialog = async (params, id) => {
|
|
|
2222
2415
|
};
|
|
2223
2416
|
|
|
2224
2417
|
// dist/browser-commands/key-press-command.js
|
|
2418
|
+
var SHIFTED_PUNCTUATION_CODES = {
|
|
2419
|
+
"!": "Digit1",
|
|
2420
|
+
"@": "Digit2",
|
|
2421
|
+
"#": "Digit3",
|
|
2422
|
+
$: "Digit4",
|
|
2423
|
+
"%": "Digit5",
|
|
2424
|
+
"^": "Digit6",
|
|
2425
|
+
"&": "Digit7",
|
|
2426
|
+
"*": "Digit8",
|
|
2427
|
+
"(": "Digit9",
|
|
2428
|
+
")": "Digit0",
|
|
2429
|
+
_: "Minus",
|
|
2430
|
+
"+": "Equal",
|
|
2431
|
+
"{": "BracketLeft",
|
|
2432
|
+
"}": "BracketRight",
|
|
2433
|
+
"|": "Backslash",
|
|
2434
|
+
":": "Semicolon",
|
|
2435
|
+
'"': "Quote",
|
|
2436
|
+
"<": "Comma",
|
|
2437
|
+
">": "Period",
|
|
2438
|
+
"?": "Slash",
|
|
2439
|
+
"~": "Backquote"
|
|
2440
|
+
};
|
|
2441
|
+
var UNSHIFTED_PUNCTUATION_CODES = {
|
|
2442
|
+
"-": "Minus",
|
|
2443
|
+
"=": "Equal",
|
|
2444
|
+
"[": "BracketLeft",
|
|
2445
|
+
"]": "BracketRight",
|
|
2446
|
+
"\\": "Backslash",
|
|
2447
|
+
";": "Semicolon",
|
|
2448
|
+
"'": "Quote",
|
|
2449
|
+
",": "Comma",
|
|
2450
|
+
".": "Period",
|
|
2451
|
+
"/": "Slash",
|
|
2452
|
+
"`": "Backquote"
|
|
2453
|
+
};
|
|
2225
2454
|
var handleBrowserPressKey = async (params, id) => {
|
|
2226
2455
|
try {
|
|
2227
2456
|
const tabId = requireTabId(params, id);
|
|
@@ -2239,7 +2468,7 @@ var handleBrowserPressKey = async (params, id) => {
|
|
|
2239
2468
|
const results = await chrome.scripting.executeScript({
|
|
2240
2469
|
target: { tabId },
|
|
2241
2470
|
world: "MAIN",
|
|
2242
|
-
func: (k, sel, shift, ctrl, alt, meta) => {
|
|
2471
|
+
func: (k, sel, shift, ctrl, alt, meta, shiftedPunct, unshiftedPunct) => {
|
|
2243
2472
|
let target = null;
|
|
2244
2473
|
if (sel) {
|
|
2245
2474
|
target = document.querySelector(sel);
|
|
@@ -2258,7 +2487,7 @@ var handleBrowserPressKey = async (params, id) => {
|
|
|
2258
2487
|
return `Digit${k2}`;
|
|
2259
2488
|
if (k2 === " ")
|
|
2260
2489
|
return "Space";
|
|
2261
|
-
return k2;
|
|
2490
|
+
return shiftedPunct[k2] ?? unshiftedPunct[k2] ?? k2;
|
|
2262
2491
|
}
|
|
2263
2492
|
return k2;
|
|
2264
2493
|
};
|
|
@@ -2343,7 +2572,7 @@ var handleBrowserPressKey = async (params, id) => {
|
|
|
2343
2572
|
}
|
|
2344
2573
|
};
|
|
2345
2574
|
},
|
|
2346
|
-
args: [key, selector, shiftKey, ctrlKey, altKey, metaKey]
|
|
2575
|
+
args: [key, selector, shiftKey, ctrlKey, altKey, metaKey, SHIFTED_PUNCTUATION_CODES, UNSHIFTED_PUNCTUATION_CODES]
|
|
2347
2576
|
});
|
|
2348
2577
|
const result = extractScriptResult(results, id);
|
|
2349
2578
|
if (!result)
|
|
@@ -2954,6 +3183,208 @@ var checkRateLimit = (method, now = Date.now()) => {
|
|
|
2954
3183
|
return true;
|
|
2955
3184
|
};
|
|
2956
3185
|
|
|
3186
|
+
// dist/server-request.js
|
|
3187
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
3188
|
+
var pendingRequests = /* @__PURE__ */ new Map();
|
|
3189
|
+
var nextId = 1;
|
|
3190
|
+
var sendServerRequest = (method, params = {}) => {
|
|
3191
|
+
const id = nextId++;
|
|
3192
|
+
const data = { jsonrpc: "2.0", method, params, id };
|
|
3193
|
+
return new Promise((resolve, reject) => {
|
|
3194
|
+
const timerId = setTimeout(() => {
|
|
3195
|
+
if (pendingRequests.has(id)) {
|
|
3196
|
+
pendingRequests.delete(id);
|
|
3197
|
+
reject(new Error(`Request ${method} timed out after ${REQUEST_TIMEOUT_MS}ms`));
|
|
3198
|
+
}
|
|
3199
|
+
}, REQUEST_TIMEOUT_MS);
|
|
3200
|
+
pendingRequests.set(id, { resolve, reject, timerId });
|
|
3201
|
+
sendToServer(data);
|
|
3202
|
+
});
|
|
3203
|
+
};
|
|
3204
|
+
var consumeServerResponse = (data) => {
|
|
3205
|
+
if (data.method !== void 0)
|
|
3206
|
+
return false;
|
|
3207
|
+
const rawId = data.id;
|
|
3208
|
+
if (rawId === void 0 || rawId === null)
|
|
3209
|
+
return false;
|
|
3210
|
+
const id = typeof rawId === "number" ? rawId : void 0;
|
|
3211
|
+
if (id === void 0)
|
|
3212
|
+
return false;
|
|
3213
|
+
const pending = pendingRequests.get(id);
|
|
3214
|
+
if (!pending)
|
|
3215
|
+
return false;
|
|
3216
|
+
pendingRequests.delete(id);
|
|
3217
|
+
clearTimeout(pending.timerId);
|
|
3218
|
+
if (data.error !== void 0 && data.error !== null) {
|
|
3219
|
+
const err2 = data.error;
|
|
3220
|
+
pending.reject(new Error(err2.message ?? "Unknown server error"));
|
|
3221
|
+
} else {
|
|
3222
|
+
pending.resolve(data.result);
|
|
3223
|
+
}
|
|
3224
|
+
return true;
|
|
3225
|
+
};
|
|
3226
|
+
var rejectAllPendingServerRequests = () => {
|
|
3227
|
+
for (const [id, pending] of pendingRequests) {
|
|
3228
|
+
pendingRequests.delete(id);
|
|
3229
|
+
clearTimeout(pending.timerId);
|
|
3230
|
+
pending.reject(new Error("Server disconnected"));
|
|
3231
|
+
}
|
|
3232
|
+
};
|
|
3233
|
+
|
|
3234
|
+
// dist/server-state-cache.js
|
|
3235
|
+
var SESSION_KEY = "serverStateCache";
|
|
3236
|
+
var CACHES_INITIALIZED_KEY = "cachesInitialized";
|
|
3237
|
+
var EMPTY_CACHE = {
|
|
3238
|
+
plugins: [],
|
|
3239
|
+
failedPlugins: [],
|
|
3240
|
+
browserTools: [],
|
|
3241
|
+
serverVersion: void 0
|
|
3242
|
+
};
|
|
3243
|
+
var cache = { ...EMPTY_CACHE };
|
|
3244
|
+
var pendingPluginToolUpdates = /* @__PURE__ */ new Map();
|
|
3245
|
+
var pendingBrowserToolUpdates = /* @__PURE__ */ new Map();
|
|
3246
|
+
var reapplyPendingOptimisticUpdates = () => {
|
|
3247
|
+
if (pendingPluginToolUpdates.size > 0) {
|
|
3248
|
+
cache = {
|
|
3249
|
+
...cache,
|
|
3250
|
+
plugins: cache.plugins.map((plugin) => {
|
|
3251
|
+
const toolOverrides = pendingPluginToolUpdates.get(plugin.name);
|
|
3252
|
+
if (!toolOverrides)
|
|
3253
|
+
return plugin;
|
|
3254
|
+
return {
|
|
3255
|
+
...plugin,
|
|
3256
|
+
tools: plugin.tools.map((tool) => {
|
|
3257
|
+
const override = toolOverrides.get(tool.name);
|
|
3258
|
+
return override !== void 0 ? { ...tool, enabled: override } : tool;
|
|
3259
|
+
})
|
|
3260
|
+
};
|
|
3261
|
+
})
|
|
3262
|
+
};
|
|
3263
|
+
}
|
|
3264
|
+
if (pendingBrowserToolUpdates.size > 0) {
|
|
3265
|
+
cache = {
|
|
3266
|
+
...cache,
|
|
3267
|
+
browserTools: cache.browserTools.map((bt) => {
|
|
3268
|
+
const override = pendingBrowserToolUpdates.get(bt.name);
|
|
3269
|
+
return override !== void 0 ? { ...bt, enabled: override } : bt;
|
|
3270
|
+
})
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3273
|
+
};
|
|
3274
|
+
var addPendingPluginToolUpdate = (plugin, tool, enabled) => {
|
|
3275
|
+
let toolMap = pendingPluginToolUpdates.get(plugin);
|
|
3276
|
+
if (!toolMap) {
|
|
3277
|
+
toolMap = /* @__PURE__ */ new Map();
|
|
3278
|
+
pendingPluginToolUpdates.set(plugin, toolMap);
|
|
3279
|
+
}
|
|
3280
|
+
toolMap.set(tool, enabled);
|
|
3281
|
+
};
|
|
3282
|
+
var removePendingPluginToolUpdate = (plugin, tool) => {
|
|
3283
|
+
const toolMap = pendingPluginToolUpdates.get(plugin);
|
|
3284
|
+
if (!toolMap)
|
|
3285
|
+
return;
|
|
3286
|
+
toolMap.delete(tool);
|
|
3287
|
+
if (toolMap.size === 0)
|
|
3288
|
+
pendingPluginToolUpdates.delete(plugin);
|
|
3289
|
+
};
|
|
3290
|
+
var addPendingPluginAllToolsUpdate = (plugin, toolNames, enabled) => {
|
|
3291
|
+
let toolMap = pendingPluginToolUpdates.get(plugin);
|
|
3292
|
+
if (!toolMap) {
|
|
3293
|
+
toolMap = /* @__PURE__ */ new Map();
|
|
3294
|
+
pendingPluginToolUpdates.set(plugin, toolMap);
|
|
3295
|
+
}
|
|
3296
|
+
for (const name of toolNames) {
|
|
3297
|
+
toolMap.set(name, enabled);
|
|
3298
|
+
}
|
|
3299
|
+
};
|
|
3300
|
+
var removePendingPluginAllToolsUpdate = (plugin, toolNames) => {
|
|
3301
|
+
const toolMap = pendingPluginToolUpdates.get(plugin);
|
|
3302
|
+
if (!toolMap)
|
|
3303
|
+
return;
|
|
3304
|
+
for (const name of toolNames) {
|
|
3305
|
+
toolMap.delete(name);
|
|
3306
|
+
}
|
|
3307
|
+
if (toolMap.size === 0)
|
|
3308
|
+
pendingPluginToolUpdates.delete(plugin);
|
|
3309
|
+
};
|
|
3310
|
+
var addPendingBrowserToolUpdate = (tool, enabled) => {
|
|
3311
|
+
pendingBrowserToolUpdates.set(tool, enabled);
|
|
3312
|
+
};
|
|
3313
|
+
var removePendingBrowserToolUpdate = (tool) => {
|
|
3314
|
+
pendingBrowserToolUpdates.delete(tool);
|
|
3315
|
+
};
|
|
3316
|
+
var addPendingAllBrowserToolsUpdate = (toolNames, enabled) => {
|
|
3317
|
+
for (const name of toolNames) {
|
|
3318
|
+
pendingBrowserToolUpdates.set(name, enabled);
|
|
3319
|
+
}
|
|
3320
|
+
};
|
|
3321
|
+
var removePendingAllBrowserToolsUpdate = (toolNames) => {
|
|
3322
|
+
for (const name of toolNames) {
|
|
3323
|
+
pendingBrowserToolUpdates.delete(name);
|
|
3324
|
+
}
|
|
3325
|
+
};
|
|
3326
|
+
var cachesInitialized = false;
|
|
3327
|
+
var persistTimer;
|
|
3328
|
+
var persistToSession = () => {
|
|
3329
|
+
chrome.storage.session.set({ [SESSION_KEY]: cache, [CACHES_INITIALIZED_KEY]: cachesInitialized }).catch(() => {
|
|
3330
|
+
});
|
|
3331
|
+
};
|
|
3332
|
+
var schedulePersist = () => {
|
|
3333
|
+
if (persistTimer !== void 0)
|
|
3334
|
+
clearTimeout(persistTimer);
|
|
3335
|
+
persistTimer = setTimeout(() => {
|
|
3336
|
+
persistTimer = void 0;
|
|
3337
|
+
persistToSession();
|
|
3338
|
+
}, 500);
|
|
3339
|
+
};
|
|
3340
|
+
var getServerStateCache = () => structuredClone(cache);
|
|
3341
|
+
var updateServerStateCache = (partial) => {
|
|
3342
|
+
cache = { ...cache, ...partial };
|
|
3343
|
+
reapplyPendingOptimisticUpdates();
|
|
3344
|
+
schedulePersist();
|
|
3345
|
+
};
|
|
3346
|
+
var flushServerStateCacheToSession = () => {
|
|
3347
|
+
if (persistTimer !== void 0) {
|
|
3348
|
+
clearTimeout(persistTimer);
|
|
3349
|
+
persistTimer = void 0;
|
|
3350
|
+
}
|
|
3351
|
+
persistToSession();
|
|
3352
|
+
};
|
|
3353
|
+
var clearServerStateCache = () => {
|
|
3354
|
+
cache = { ...EMPTY_CACHE };
|
|
3355
|
+
cachesInitialized = false;
|
|
3356
|
+
pendingPluginToolUpdates.clear();
|
|
3357
|
+
pendingBrowserToolUpdates.clear();
|
|
3358
|
+
if (persistTimer !== void 0) {
|
|
3359
|
+
clearTimeout(persistTimer);
|
|
3360
|
+
persistTimer = void 0;
|
|
3361
|
+
}
|
|
3362
|
+
chrome.storage.session.remove([SESSION_KEY, CACHES_INITIALIZED_KEY]).catch(() => {
|
|
3363
|
+
});
|
|
3364
|
+
};
|
|
3365
|
+
var loadServerStateCacheFromSession = async () => {
|
|
3366
|
+
try {
|
|
3367
|
+
const data = await chrome.storage.session.get([SESSION_KEY, CACHES_INITIALIZED_KEY]);
|
|
3368
|
+
const stored = data[SESSION_KEY];
|
|
3369
|
+
if (stored && typeof stored === "object") {
|
|
3370
|
+
cache = {
|
|
3371
|
+
plugins: Array.isArray(stored.plugins) ? stored.plugins : [],
|
|
3372
|
+
failedPlugins: Array.isArray(stored.failedPlugins) ? stored.failedPlugins : [],
|
|
3373
|
+
browserTools: Array.isArray(stored.browserTools) ? stored.browserTools : [],
|
|
3374
|
+
serverVersion: typeof stored.serverVersion === "string" ? stored.serverVersion : void 0
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3377
|
+
if (typeof data[CACHES_INITIALIZED_KEY] === "boolean") {
|
|
3378
|
+
cachesInitialized = data[CACHES_INITIALIZED_KEY];
|
|
3379
|
+
}
|
|
3380
|
+
} catch {
|
|
3381
|
+
}
|
|
3382
|
+
};
|
|
3383
|
+
var getCachesInitialized = () => cachesInitialized;
|
|
3384
|
+
var setCachesInitialized = (value) => {
|
|
3385
|
+
cachesInitialized = value;
|
|
3386
|
+
};
|
|
3387
|
+
|
|
2957
3388
|
// dist/dispatch-helpers.js
|
|
2958
3389
|
var isAdapterNotReady = (result) => result.type === "error" && result.code === JSONRPC_ADAPTER_NOT_READY;
|
|
2959
3390
|
var resolvePlugin = async (pluginName, id) => {
|
|
@@ -2968,26 +3399,6 @@ var resolvePlugin = async (pluginName, id) => {
|
|
|
2968
3399
|
}
|
|
2969
3400
|
return plugin;
|
|
2970
3401
|
};
|
|
2971
|
-
var executeWithTimeout = async (scriptPromise, timeoutMs, fallbackMessage) => {
|
|
2972
|
-
let timeoutId;
|
|
2973
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
2974
|
-
timeoutId = setTimeout(() => {
|
|
2975
|
-
reject(new Error(`Script execution timed out after ${timeoutMs}ms`));
|
|
2976
|
-
}, timeoutMs);
|
|
2977
|
-
});
|
|
2978
|
-
let results;
|
|
2979
|
-
try {
|
|
2980
|
-
results = await Promise.race([scriptPromise, timeoutPromise]);
|
|
2981
|
-
} finally {
|
|
2982
|
-
clearTimeout(timeoutId);
|
|
2983
|
-
}
|
|
2984
|
-
const firstResult = results[0];
|
|
2985
|
-
const result = firstResult?.result;
|
|
2986
|
-
if (!result || typeof result !== "object" || !("type" in result)) {
|
|
2987
|
-
return { type: "error", code: JSONRPC_INTERNAL_ERROR, message: fallbackMessage };
|
|
2988
|
-
}
|
|
2989
|
-
return result;
|
|
2990
|
-
};
|
|
2991
3402
|
var dispatchWithTabFallback = async (config) => {
|
|
2992
3403
|
const { id, pluginName, plugin, operationName, executeOnTab } = config;
|
|
2993
3404
|
const matchingTabs = await findAllMatchingTabs(plugin);
|
|
@@ -3113,202 +3524,6 @@ var dispatchToTargetedTab = async (config) => {
|
|
|
3113
3524
|
}
|
|
3114
3525
|
};
|
|
3115
3526
|
|
|
3116
|
-
// dist/resource-prompt-dispatch.js
|
|
3117
|
-
var executeResourceReadOnTab = async (tabId, pluginName, resourceUri) => {
|
|
3118
|
-
const scriptPromise = chrome.scripting.executeScript({
|
|
3119
|
-
target: { tabId },
|
|
3120
|
-
world: "MAIN",
|
|
3121
|
-
func: async (pName, uri) => {
|
|
3122
|
-
const ot = globalThis.__openTabs;
|
|
3123
|
-
const adapter = ot?.adapters?.[pName];
|
|
3124
|
-
if (!adapter || typeof adapter !== "object") {
|
|
3125
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" not injected or not ready` };
|
|
3126
|
-
}
|
|
3127
|
-
if (!Object.isFrozen(adapter)) {
|
|
3128
|
-
return {
|
|
3129
|
-
type: "error",
|
|
3130
|
-
code: -32002,
|
|
3131
|
-
message: `Adapter "${pName}" failed integrity check (not frozen)`
|
|
3132
|
-
};
|
|
3133
|
-
}
|
|
3134
|
-
if (typeof adapter.isReady !== "function") {
|
|
3135
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" has no isReady function` };
|
|
3136
|
-
}
|
|
3137
|
-
let ready;
|
|
3138
|
-
try {
|
|
3139
|
-
ready = await adapter.isReady();
|
|
3140
|
-
} catch {
|
|
3141
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" isReady() threw an error` };
|
|
3142
|
-
}
|
|
3143
|
-
if (!ready) {
|
|
3144
|
-
return {
|
|
3145
|
-
type: "error",
|
|
3146
|
-
code: -32002,
|
|
3147
|
-
message: `Plugin "${pName}" is not ready (state: unavailable)`
|
|
3148
|
-
};
|
|
3149
|
-
}
|
|
3150
|
-
if (!Array.isArray(adapter.resources)) {
|
|
3151
|
-
return { type: "error", code: -32603, message: `Adapter "${pName}" has no resources array` };
|
|
3152
|
-
}
|
|
3153
|
-
const resource = adapter.resources.find((r) => r.uri === uri);
|
|
3154
|
-
if (!resource || typeof resource.read !== "function") {
|
|
3155
|
-
return { type: "error", code: -32603, message: `Resource "${uri}" not found in adapter "${pName}"` };
|
|
3156
|
-
}
|
|
3157
|
-
try {
|
|
3158
|
-
const output = await resource.read(uri);
|
|
3159
|
-
return { type: "success", output };
|
|
3160
|
-
} catch (err2) {
|
|
3161
|
-
const caughtError = err2;
|
|
3162
|
-
return {
|
|
3163
|
-
type: "error",
|
|
3164
|
-
code: -32603,
|
|
3165
|
-
message: caughtError.message ?? "Resource read failed"
|
|
3166
|
-
};
|
|
3167
|
-
}
|
|
3168
|
-
},
|
|
3169
|
-
args: [pluginName, resourceUri]
|
|
3170
|
-
});
|
|
3171
|
-
return executeWithTimeout(scriptPromise, SCRIPT_TIMEOUT_MS, "No result from resource read");
|
|
3172
|
-
};
|
|
3173
|
-
var executePromptGetOnTab = async (tabId, pluginName, promptName, promptArgs) => {
|
|
3174
|
-
const scriptPromise = chrome.scripting.executeScript({
|
|
3175
|
-
target: { tabId },
|
|
3176
|
-
world: "MAIN",
|
|
3177
|
-
func: async (pName, pPromptName, pArgs) => {
|
|
3178
|
-
const ot = globalThis.__openTabs;
|
|
3179
|
-
const adapter = ot?.adapters?.[pName];
|
|
3180
|
-
if (!adapter || typeof adapter !== "object") {
|
|
3181
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" not injected or not ready` };
|
|
3182
|
-
}
|
|
3183
|
-
if (!Object.isFrozen(adapter)) {
|
|
3184
|
-
return {
|
|
3185
|
-
type: "error",
|
|
3186
|
-
code: -32002,
|
|
3187
|
-
message: `Adapter "${pName}" failed integrity check (not frozen)`
|
|
3188
|
-
};
|
|
3189
|
-
}
|
|
3190
|
-
if (typeof adapter.isReady !== "function") {
|
|
3191
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" has no isReady function` };
|
|
3192
|
-
}
|
|
3193
|
-
let ready;
|
|
3194
|
-
try {
|
|
3195
|
-
ready = await adapter.isReady();
|
|
3196
|
-
} catch {
|
|
3197
|
-
return { type: "error", code: -32002, message: `Adapter "${pName}" isReady() threw an error` };
|
|
3198
|
-
}
|
|
3199
|
-
if (!ready) {
|
|
3200
|
-
return {
|
|
3201
|
-
type: "error",
|
|
3202
|
-
code: -32002,
|
|
3203
|
-
message: `Plugin "${pName}" is not ready (state: unavailable)`
|
|
3204
|
-
};
|
|
3205
|
-
}
|
|
3206
|
-
if (!Array.isArray(adapter.prompts)) {
|
|
3207
|
-
return { type: "error", code: -32603, message: `Adapter "${pName}" has no prompts array` };
|
|
3208
|
-
}
|
|
3209
|
-
const prompt = adapter.prompts.find((p) => p.name === pPromptName);
|
|
3210
|
-
if (!prompt || typeof prompt.render !== "function") {
|
|
3211
|
-
return {
|
|
3212
|
-
type: "error",
|
|
3213
|
-
code: -32603,
|
|
3214
|
-
message: `Prompt "${pPromptName}" not found in adapter "${pName}"`
|
|
3215
|
-
};
|
|
3216
|
-
}
|
|
3217
|
-
try {
|
|
3218
|
-
const output = await prompt.render(pArgs);
|
|
3219
|
-
return { type: "success", output };
|
|
3220
|
-
} catch (err2) {
|
|
3221
|
-
const caughtError = err2;
|
|
3222
|
-
return {
|
|
3223
|
-
type: "error",
|
|
3224
|
-
code: -32603,
|
|
3225
|
-
message: caughtError.message ?? "Prompt render failed"
|
|
3226
|
-
};
|
|
3227
|
-
}
|
|
3228
|
-
},
|
|
3229
|
-
args: [pluginName, promptName, promptArgs]
|
|
3230
|
-
});
|
|
3231
|
-
return executeWithTimeout(scriptPromise, SCRIPT_TIMEOUT_MS, "No result from prompt render");
|
|
3232
|
-
};
|
|
3233
|
-
var handleResourceRead = async (params, id) => {
|
|
3234
|
-
const pluginName = requireStringParam(params, "plugin", id);
|
|
3235
|
-
if (!pluginName)
|
|
3236
|
-
return;
|
|
3237
|
-
const resourceUri = requireStringParam(params, "uri", id);
|
|
3238
|
-
if (!resourceUri)
|
|
3239
|
-
return;
|
|
3240
|
-
const rawTabId = params.tabId;
|
|
3241
|
-
const targetTabId = typeof rawTabId === "number" && Number.isInteger(rawTabId) && rawTabId > 0 ? rawTabId : void 0;
|
|
3242
|
-
const plugin = await resolvePlugin(pluginName, id);
|
|
3243
|
-
if (!plugin)
|
|
3244
|
-
return;
|
|
3245
|
-
const executeOnTab = (tid) => executeResourceReadOnTab(tid, pluginName, resourceUri);
|
|
3246
|
-
if (targetTabId !== void 0) {
|
|
3247
|
-
await dispatchToTargetedTab({
|
|
3248
|
-
id,
|
|
3249
|
-
pluginName,
|
|
3250
|
-
plugin,
|
|
3251
|
-
tabId: targetTabId,
|
|
3252
|
-
operationName: "resource read",
|
|
3253
|
-
executeOnTab
|
|
3254
|
-
});
|
|
3255
|
-
} else {
|
|
3256
|
-
await dispatchWithTabFallback({
|
|
3257
|
-
id,
|
|
3258
|
-
pluginName,
|
|
3259
|
-
plugin,
|
|
3260
|
-
operationName: "resource read",
|
|
3261
|
-
executeOnTab
|
|
3262
|
-
});
|
|
3263
|
-
}
|
|
3264
|
-
};
|
|
3265
|
-
var handlePromptGet = async (params, id) => {
|
|
3266
|
-
const pluginName = requireStringParam(params, "plugin", id);
|
|
3267
|
-
if (!pluginName)
|
|
3268
|
-
return;
|
|
3269
|
-
const promptName = requireStringParam(params, "prompt", id);
|
|
3270
|
-
if (!promptName)
|
|
3271
|
-
return;
|
|
3272
|
-
const rawArgs = params.arguments;
|
|
3273
|
-
if (rawArgs !== void 0 && rawArgs !== null && (typeof rawArgs !== "object" || Array.isArray(rawArgs))) {
|
|
3274
|
-
sendToServer({
|
|
3275
|
-
jsonrpc: "2.0",
|
|
3276
|
-
error: { code: JSONRPC_INVALID_PARAMS, message: 'Invalid "arguments" param (expected object)' },
|
|
3277
|
-
id
|
|
3278
|
-
});
|
|
3279
|
-
return;
|
|
3280
|
-
}
|
|
3281
|
-
const rawObj = rawArgs ?? {};
|
|
3282
|
-
const promptArgs = {};
|
|
3283
|
-
for (const [key, val] of Object.entries(rawObj)) {
|
|
3284
|
-
promptArgs[key] = String(val);
|
|
3285
|
-
}
|
|
3286
|
-
const rawTabId = params.tabId;
|
|
3287
|
-
const targetTabId = typeof rawTabId === "number" && Number.isInteger(rawTabId) && rawTabId > 0 ? rawTabId : void 0;
|
|
3288
|
-
const plugin = await resolvePlugin(pluginName, id);
|
|
3289
|
-
if (!plugin)
|
|
3290
|
-
return;
|
|
3291
|
-
const executeOnTab = (tid) => executePromptGetOnTab(tid, pluginName, promptName, promptArgs);
|
|
3292
|
-
if (targetTabId !== void 0) {
|
|
3293
|
-
await dispatchToTargetedTab({
|
|
3294
|
-
id,
|
|
3295
|
-
pluginName,
|
|
3296
|
-
plugin,
|
|
3297
|
-
tabId: targetTabId,
|
|
3298
|
-
operationName: "prompt get",
|
|
3299
|
-
executeOnTab
|
|
3300
|
-
});
|
|
3301
|
-
} else {
|
|
3302
|
-
await dispatchWithTabFallback({
|
|
3303
|
-
id,
|
|
3304
|
-
pluginName,
|
|
3305
|
-
plugin,
|
|
3306
|
-
operationName: "prompt get",
|
|
3307
|
-
executeOnTab
|
|
3308
|
-
});
|
|
3309
|
-
}
|
|
3310
|
-
};
|
|
3311
|
-
|
|
3312
3527
|
// dist/tool-dispatch.js
|
|
3313
3528
|
var progressCallbacks = /* @__PURE__ */ new Map();
|
|
3314
3529
|
var notifyDispatchProgress = (dispatchId) => {
|
|
@@ -3505,7 +3720,7 @@ var executeToolOnTab = async (tabId, pluginName, toolName, input, dispatchId) =>
|
|
|
3505
3720
|
return result;
|
|
3506
3721
|
};
|
|
3507
3722
|
var handleToolDispatch = async (params, id) => {
|
|
3508
|
-
const dispatchId = typeof params.
|
|
3723
|
+
const dispatchId = typeof params.__opentabs_dispatchId === "string" ? params.__opentabs_dispatchId : String(id);
|
|
3509
3724
|
const pluginName = requireStringParam(params, "plugin", id);
|
|
3510
3725
|
if (!pluginName)
|
|
3511
3726
|
return;
|
|
@@ -3601,7 +3816,6 @@ var wrapNotification = (method, fn) => (params) => {
|
|
|
3601
3816
|
fn(params).catch((err2) => console.warn(`[opentabs] ${method} handler failed:`, err2));
|
|
3602
3817
|
};
|
|
3603
3818
|
var SIDE_PANEL_METHODS = /* @__PURE__ */ new Set([
|
|
3604
|
-
"tab.stateChanged",
|
|
3605
3819
|
"tool.invocationStart",
|
|
3606
3820
|
"tool.invocationEnd",
|
|
3607
3821
|
"plugins.changed",
|
|
@@ -3635,13 +3849,18 @@ var validatePluginPayload = (raw) => {
|
|
|
3635
3849
|
return null;
|
|
3636
3850
|
}
|
|
3637
3851
|
const urlPatterns = Array.isArray(obj.urlPatterns) ? obj.urlPatterns.filter((p) => typeof p === "string") : [];
|
|
3638
|
-
const tools = Array.isArray(obj.tools) ? obj.tools.filter((t) => typeof t === "object" && t !== null && typeof t.name === "string" && typeof t.description === "string"
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3852
|
+
const tools = Array.isArray(obj.tools) ? obj.tools.filter((t) => typeof t === "object" && t !== null && typeof t.name === "string" && typeof t.description === "string").map((t) => {
|
|
3853
|
+
if (typeof t.enabled !== "boolean") {
|
|
3854
|
+
console.warn(`[opentabs] Tool "${t.name}" in plugin "${obj.name}" is missing the "enabled" field \u2014 defaulting to enabled=true. This is a server-side bug.`);
|
|
3855
|
+
}
|
|
3856
|
+
return {
|
|
3857
|
+
name: t.name,
|
|
3858
|
+
displayName: typeof t.displayName === "string" ? t.displayName : t.name,
|
|
3859
|
+
description: t.description,
|
|
3860
|
+
icon: typeof t.icon === "string" ? t.icon : "wrench",
|
|
3861
|
+
enabled: typeof t.enabled === "boolean" ? t.enabled : true
|
|
3862
|
+
};
|
|
3863
|
+
}) : [];
|
|
3645
3864
|
return {
|
|
3646
3865
|
name: obj.name,
|
|
3647
3866
|
version: typeof obj.version === "string" ? obj.version : "0.0.0",
|
|
@@ -3668,6 +3887,8 @@ var handleExtensionReload = (_params, id) => {
|
|
|
3668
3887
|
});
|
|
3669
3888
|
};
|
|
3670
3889
|
var handleSyncFull = async (params) => {
|
|
3890
|
+
const syncStart = Date.now();
|
|
3891
|
+
console.log("[opentabs:timing] handleSyncFull started");
|
|
3671
3892
|
const rawPlugins = params.plugins;
|
|
3672
3893
|
if (!Array.isArray(rawPlugins))
|
|
3673
3894
|
return;
|
|
@@ -3701,17 +3922,58 @@ var handleSyncFull = async (params) => {
|
|
|
3701
3922
|
}
|
|
3702
3923
|
const metas = uniquePlugins.map(toPluginMeta);
|
|
3703
3924
|
await storePluginsBatch(metas);
|
|
3925
|
+
console.log(`[opentabs:timing] storePluginsBatch done: +${Date.now() - syncStart}ms`);
|
|
3704
3926
|
const injectionResults = await Promise.allSettled(metas.map((meta) => injectPluginIntoMatchingTabs(meta.name, meta.urlPatterns, true, meta.adapterHash, meta.adapterFile, meta.adapterHash)));
|
|
3705
3927
|
for (const result of injectionResults) {
|
|
3706
3928
|
if (result.status === "rejected") {
|
|
3707
3929
|
console.warn("[opentabs] Plugin injection failed during sync.full:", result.reason);
|
|
3708
3930
|
}
|
|
3709
3931
|
}
|
|
3710
|
-
|
|
3932
|
+
console.log(`[opentabs:timing] injection done: +${Date.now() - syncStart}ms`);
|
|
3933
|
+
const rawPluginMap = /* @__PURE__ */ new Map();
|
|
3934
|
+
for (const raw of rawPlugins) {
|
|
3935
|
+
if (typeof raw === "object" && raw !== null && typeof raw.name === "string") {
|
|
3936
|
+
rawPluginMap.set(raw.name, raw);
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
const cachePlugins = uniquePlugins.map((p) => {
|
|
3940
|
+
const raw = rawPluginMap.get(p.name);
|
|
3941
|
+
return {
|
|
3942
|
+
name: p.name,
|
|
3943
|
+
displayName: p.displayName,
|
|
3944
|
+
version: p.version,
|
|
3945
|
+
trustTier: p.trustTier,
|
|
3946
|
+
source: raw?.source === "npm" || raw?.source === "local" ? raw.source : "local",
|
|
3947
|
+
tabState: "closed",
|
|
3948
|
+
urlPatterns: p.urlPatterns,
|
|
3949
|
+
tools: p.tools,
|
|
3950
|
+
iconSvg: p.iconSvg,
|
|
3951
|
+
iconInactiveSvg: p.iconInactiveSvg,
|
|
3952
|
+
...typeof raw?.sdkVersion === "string" ? { sdkVersion: raw.sdkVersion } : {},
|
|
3953
|
+
...raw?.update && typeof raw.update === "object" ? { update: raw.update } : {}
|
|
3954
|
+
};
|
|
3955
|
+
});
|
|
3956
|
+
const rawFailedPlugins = Array.isArray(params.failedPlugins) ? params.failedPlugins : void 0;
|
|
3957
|
+
const rawBrowserTools = Array.isArray(params.browserTools) ? params.browserTools : void 0;
|
|
3958
|
+
const rawServerVersion = typeof params.serverVersion === "string" ? params.serverVersion : void 0;
|
|
3959
|
+
updateServerStateCache({
|
|
3960
|
+
plugins: cachePlugins,
|
|
3961
|
+
...rawFailedPlugins ? { failedPlugins: rawFailedPlugins } : {},
|
|
3962
|
+
...rawBrowserTools ? { browserTools: rawBrowserTools } : {},
|
|
3963
|
+
...rawServerVersion !== void 0 ? { serverVersion: rawServerVersion } : {}
|
|
3964
|
+
});
|
|
3965
|
+
setCachesInitialized(true);
|
|
3966
|
+
flushServerStateCacheToSession();
|
|
3967
|
+
console.log(`[opentabs:timing] cache + flush done: +${Date.now() - syncStart}ms`);
|
|
3711
3968
|
forwardToSidePanel({
|
|
3712
3969
|
type: "sp:serverMessage",
|
|
3713
3970
|
data: { jsonrpc: "2.0", method: "plugins.changed" }
|
|
3714
3971
|
});
|
|
3972
|
+
console.log(`[opentabs:timing] plugins.changed sent to side panel: +${Date.now() - syncStart}ms`);
|
|
3973
|
+
void sendTabSyncAll().then(() => {
|
|
3974
|
+
flushLastKnownStateToSession();
|
|
3975
|
+
startReadinessPoll();
|
|
3976
|
+
});
|
|
3715
3977
|
};
|
|
3716
3978
|
var handlePluginUpdate = async (params) => {
|
|
3717
3979
|
const validated = validatePluginPayload(params);
|
|
@@ -3723,6 +3985,23 @@ var handlePluginUpdate = async (params) => {
|
|
|
3723
3985
|
const newState = await computePluginTabState(meta);
|
|
3724
3986
|
await updateLastKnownState(meta.name, newState);
|
|
3725
3987
|
sendTabStateNotification(meta.name, newState);
|
|
3988
|
+
const existingCache = getServerStateCache();
|
|
3989
|
+
const updatedPlugin = {
|
|
3990
|
+
name: validated.name,
|
|
3991
|
+
displayName: validated.displayName,
|
|
3992
|
+
version: validated.version,
|
|
3993
|
+
trustTier: validated.trustTier,
|
|
3994
|
+
source: params.source === "npm" || params.source === "local" ? params.source : "local",
|
|
3995
|
+
tabState: newState.state,
|
|
3996
|
+
urlPatterns: validated.urlPatterns,
|
|
3997
|
+
tools: validated.tools,
|
|
3998
|
+
iconSvg: validated.iconSvg,
|
|
3999
|
+
iconInactiveSvg: validated.iconInactiveSvg,
|
|
4000
|
+
...typeof params.sdkVersion === "string" ? { sdkVersion: params.sdkVersion } : {},
|
|
4001
|
+
...params.update && typeof params.update === "object" ? { update: params.update } : {}
|
|
4002
|
+
};
|
|
4003
|
+
const otherPlugins = existingCache.plugins.filter((p) => p.name !== validated.name);
|
|
4004
|
+
updateServerStateCache({ plugins: [...otherPlugins, updatedPlugin] });
|
|
3726
4005
|
forwardToSidePanel({
|
|
3727
4006
|
type: "sp:serverMessage",
|
|
3728
4007
|
data: { jsonrpc: "2.0", method: "plugins.changed" }
|
|
@@ -3757,20 +4036,40 @@ var handlePluginUninstall = async (params, id) => {
|
|
|
3757
4036
|
}
|
|
3758
4037
|
await removePlugin(pluginName);
|
|
3759
4038
|
clearPluginTabState(pluginName);
|
|
4039
|
+
const existingCache = getServerStateCache();
|
|
4040
|
+
updateServerStateCache({ plugins: existingCache.plugins.filter((p) => p.name !== pluginName) });
|
|
4041
|
+
forwardToSidePanel({
|
|
4042
|
+
type: "sp:serverMessage",
|
|
4043
|
+
data: { jsonrpc: "2.0", method: "plugins.changed" }
|
|
4044
|
+
});
|
|
3760
4045
|
sendToServer({
|
|
3761
4046
|
jsonrpc: "2.0",
|
|
3762
4047
|
result: { success: true },
|
|
3763
4048
|
id
|
|
3764
4049
|
});
|
|
3765
4050
|
};
|
|
4051
|
+
var handleExtensionGetTabState = async (_params, id) => {
|
|
4052
|
+
let states = getLastKnownStates();
|
|
4053
|
+
if (states.size === 0) {
|
|
4054
|
+
await loadLastKnownStateFromSession();
|
|
4055
|
+
states = getLastKnownStates();
|
|
4056
|
+
}
|
|
4057
|
+
const tabStates = {};
|
|
4058
|
+
for (const [pluginName, serialized] of states) {
|
|
4059
|
+
try {
|
|
4060
|
+
tabStates[pluginName] = JSON.parse(serialized);
|
|
4061
|
+
} catch {
|
|
4062
|
+
tabStates[pluginName] = { state: "closed", tabs: [] };
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
sendToServer({ jsonrpc: "2.0", result: { tabStates }, id });
|
|
4066
|
+
};
|
|
3766
4067
|
var methodHandlers = /* @__PURE__ */ new Map([
|
|
3767
4068
|
["extension.reload", handleExtensionReload],
|
|
3768
4069
|
["sync.full", wrapNotification("sync.full", handleSyncFull)],
|
|
3769
4070
|
["plugin.update", wrapNotification("plugin.update", handlePluginUpdate)],
|
|
3770
4071
|
["plugin.uninstall", wrapAsync("plugin.uninstall", handlePluginUninstall)],
|
|
3771
4072
|
["tool.dispatch", wrapAsync("tool.dispatch", handleToolDispatch)],
|
|
3772
|
-
["resource.read", wrapAsync("resource.read", handleResourceRead)],
|
|
3773
|
-
["prompt.get", wrapAsync("prompt.get", handlePromptGet)],
|
|
3774
4073
|
["browser.listTabs", wrapAsync("browser.listTabs", (_params, id) => handleBrowserListTabs(id))],
|
|
3775
4074
|
["browser.openTab", wrapAsync("browser.openTab", handleBrowserOpenTab)],
|
|
3776
4075
|
["browser.closeTab", wrapAsync("browser.closeTab", handleBrowserCloseTab)],
|
|
@@ -3809,14 +4108,26 @@ var methodHandlers = /* @__PURE__ */ new Map([
|
|
|
3809
4108
|
[
|
|
3810
4109
|
"extension.forceReconnect",
|
|
3811
4110
|
wrapAsync("extension.forceReconnect", (_params, id) => handleExtensionForceReconnect(id))
|
|
3812
|
-
]
|
|
4111
|
+
],
|
|
4112
|
+
["extension.getTabState", wrapAsync("extension.getTabState", handleExtensionGetTabState)]
|
|
3813
4113
|
]);
|
|
3814
4114
|
var handleServerMessage = (message) => {
|
|
3815
4115
|
const method = message.method;
|
|
3816
4116
|
const id = message.id;
|
|
3817
4117
|
const params = message.params ?? {};
|
|
3818
|
-
|
|
3819
|
-
|
|
4118
|
+
if (!method && consumeServerResponse(message)) {
|
|
4119
|
+
return;
|
|
4120
|
+
}
|
|
4121
|
+
if (method === "plugins.changed") {
|
|
4122
|
+
const payload = params;
|
|
4123
|
+
updateServerStateCache({
|
|
4124
|
+
...payload.plugins ? { plugins: payload.plugins } : {},
|
|
4125
|
+
...payload.failedPlugins ? { failedPlugins: payload.failedPlugins } : {},
|
|
4126
|
+
...payload.browserTools ? { browserTools: payload.browserTools } : {},
|
|
4127
|
+
...payload.serverVersion !== void 0 ? { serverVersion: payload.serverVersion } : {}
|
|
4128
|
+
});
|
|
4129
|
+
}
|
|
4130
|
+
if (method && SIDE_PANEL_METHODS.has(method)) {
|
|
3820
4131
|
forwardToSidePanel({ type: "sp:serverMessage", data: message });
|
|
3821
4132
|
}
|
|
3822
4133
|
if (method === "confirmation.request") {
|
|
@@ -3853,14 +4164,18 @@ var methodHandlerNames = Array.from(methodHandlers.keys());
|
|
|
3853
4164
|
// dist/background-message-handlers.js
|
|
3854
4165
|
var wsConnected = false;
|
|
3855
4166
|
var lastDisconnectReason;
|
|
4167
|
+
var wsConnectedRestorePromise;
|
|
3856
4168
|
var restoreWsConnectedState = () => {
|
|
3857
|
-
|
|
4169
|
+
if (wsConnectedRestorePromise !== void 0)
|
|
4170
|
+
return;
|
|
4171
|
+
wsConnectedRestorePromise = chrome.storage.session.get(WS_CONNECTED_KEY).then((data) => {
|
|
3858
4172
|
if (typeof data[WS_CONNECTED_KEY] === "boolean") {
|
|
3859
4173
|
wsConnected = data[WS_CONNECTED_KEY];
|
|
3860
4174
|
}
|
|
3861
4175
|
}).catch(() => {
|
|
3862
4176
|
});
|
|
3863
4177
|
};
|
|
4178
|
+
var waitForWsConnectedRestore = () => wsConnectedRestorePromise ?? Promise.resolve();
|
|
3864
4179
|
var persistWsConnected = (connected) => {
|
|
3865
4180
|
wsConnected = connected;
|
|
3866
4181
|
chrome.storage.session.set({ [WS_CONNECTED_KEY]: connected }).catch(() => {
|
|
@@ -3888,23 +4203,92 @@ var handleWsState = (message, sendResponse) => {
|
|
|
3888
4203
|
}
|
|
3889
4204
|
});
|
|
3890
4205
|
if (!nowConnected) {
|
|
4206
|
+
stopReadinessPoll();
|
|
3891
4207
|
clearTabStateCache();
|
|
4208
|
+
clearServerStateCache();
|
|
4209
|
+
rejectAllPendingServerRequests();
|
|
3892
4210
|
clearAllConfirmationBadges();
|
|
3893
4211
|
}
|
|
3894
4212
|
sendResponse({ ok: true });
|
|
3895
4213
|
};
|
|
3896
4214
|
var handleWsMessage = (message, sendResponse) => {
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
}
|
|
3900
|
-
|
|
3901
|
-
|
|
4215
|
+
try {
|
|
4216
|
+
handleServerMessage(message.data);
|
|
4217
|
+
} catch (err2) {
|
|
4218
|
+
console.error("[opentabs:background] handleServerMessage threw:", err2);
|
|
4219
|
+
}
|
|
3902
4220
|
sendResponse({ ok: true });
|
|
3903
4221
|
};
|
|
3904
|
-
var
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
4222
|
+
var handleBgGetFullState = (_message, sendResponse) => {
|
|
4223
|
+
(async () => {
|
|
4224
|
+
await waitForWsConnectedRestore();
|
|
4225
|
+
let tabStates = getLastKnownStates();
|
|
4226
|
+
let serverCache = getServerStateCache();
|
|
4227
|
+
if (wsConnected && tabStates.size === 0 && serverCache.plugins.length === 0) {
|
|
4228
|
+
await loadServerStateCacheFromSession();
|
|
4229
|
+
if (getCachesInitialized()) {
|
|
4230
|
+
await loadLastKnownStateFromSession();
|
|
4231
|
+
tabStates = getLastKnownStates();
|
|
4232
|
+
}
|
|
4233
|
+
serverCache = getServerStateCache();
|
|
4234
|
+
}
|
|
4235
|
+
const metaIndex = await getAllPluginMeta();
|
|
4236
|
+
const serverPluginMap = /* @__PURE__ */ new Map();
|
|
4237
|
+
for (const sp of serverCache.plugins) {
|
|
4238
|
+
serverPluginMap.set(sp.name, sp);
|
|
4239
|
+
}
|
|
4240
|
+
const plugins = Object.values(metaIndex).map((meta) => {
|
|
4241
|
+
const serverPlugin = serverPluginMap.get(meta.name);
|
|
4242
|
+
let tabState = "closed";
|
|
4243
|
+
const serialized = tabStates.get(meta.name);
|
|
4244
|
+
if (serialized) {
|
|
4245
|
+
try {
|
|
4246
|
+
const parsed = JSON.parse(serialized);
|
|
4247
|
+
tabState = parsed.state;
|
|
4248
|
+
} catch {
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
const tools = meta.tools.map((metaTool) => {
|
|
4252
|
+
const serverTool = serverPlugin?.tools.find((st) => st.name === metaTool.name);
|
|
4253
|
+
return {
|
|
4254
|
+
...metaTool,
|
|
4255
|
+
enabled: serverTool?.enabled ?? true
|
|
4256
|
+
};
|
|
4257
|
+
});
|
|
4258
|
+
return {
|
|
4259
|
+
name: meta.name,
|
|
4260
|
+
displayName: meta.displayName,
|
|
4261
|
+
version: meta.version,
|
|
4262
|
+
trustTier: meta.trustTier,
|
|
4263
|
+
urlPatterns: meta.urlPatterns,
|
|
4264
|
+
iconSvg: meta.iconSvg,
|
|
4265
|
+
iconInactiveSvg: meta.iconInactiveSvg,
|
|
4266
|
+
tools,
|
|
4267
|
+
tabState,
|
|
4268
|
+
source: serverPlugin?.source ?? "local",
|
|
4269
|
+
sdkVersion: serverPlugin?.sdkVersion,
|
|
4270
|
+
update: serverPlugin?.update
|
|
4271
|
+
};
|
|
4272
|
+
});
|
|
4273
|
+
sendResponse({
|
|
4274
|
+
connected: wsConnected,
|
|
4275
|
+
disconnectReason: wsConnected ? void 0 : lastDisconnectReason,
|
|
4276
|
+
plugins,
|
|
4277
|
+
failedPlugins: serverCache.failedPlugins,
|
|
4278
|
+
browserTools: serverCache.browserTools,
|
|
4279
|
+
serverVersion: serverCache.serverVersion,
|
|
4280
|
+
pendingConfirmations: getPendingConfirmations()
|
|
4281
|
+
});
|
|
4282
|
+
})().catch(() => {
|
|
4283
|
+
sendResponse({
|
|
4284
|
+
connected: wsConnected,
|
|
4285
|
+
disconnectReason: wsConnected ? void 0 : lastDisconnectReason,
|
|
4286
|
+
plugins: [],
|
|
4287
|
+
failedPlugins: [],
|
|
4288
|
+
browserTools: [],
|
|
4289
|
+
serverVersion: void 0,
|
|
4290
|
+
pendingConfirmations: []
|
|
4291
|
+
});
|
|
3908
4292
|
});
|
|
3909
4293
|
};
|
|
3910
4294
|
var handlePluginLogs = (message, sendResponse) => {
|
|
@@ -3975,6 +4359,160 @@ var handleSpConfirmationTimeout = (message, sendResponse) => {
|
|
|
3975
4359
|
clearConfirmationBadge(id);
|
|
3976
4360
|
sendResponse({ ok: true });
|
|
3977
4361
|
};
|
|
4362
|
+
var handleBgSetToolEnabled = (message, sendResponse) => {
|
|
4363
|
+
const plugin = message.plugin;
|
|
4364
|
+
const tool = message.tool;
|
|
4365
|
+
const enabled = message.enabled;
|
|
4366
|
+
const cache2 = getServerStateCache();
|
|
4367
|
+
const pluginEntry = cache2.plugins.find((p) => p.name === plugin);
|
|
4368
|
+
const originalEnabled = pluginEntry?.tools.find((t) => t.name === tool)?.enabled ?? !enabled;
|
|
4369
|
+
const updatedPlugins = cache2.plugins.map((p) => {
|
|
4370
|
+
if (p.name !== plugin)
|
|
4371
|
+
return p;
|
|
4372
|
+
return {
|
|
4373
|
+
...p,
|
|
4374
|
+
tools: p.tools.map((t) => t.name === tool ? { ...t, enabled } : t)
|
|
4375
|
+
};
|
|
4376
|
+
});
|
|
4377
|
+
addPendingPluginToolUpdate(plugin, tool, enabled);
|
|
4378
|
+
updateServerStateCache({ plugins: updatedPlugins });
|
|
4379
|
+
sendServerRequest("config.setToolEnabled", { plugin, tool, enabled }).then((result) => {
|
|
4380
|
+
removePendingPluginToolUpdate(plugin, tool);
|
|
4381
|
+
sendResponse(result);
|
|
4382
|
+
}).catch((err2) => {
|
|
4383
|
+
removePendingPluginToolUpdate(plugin, tool);
|
|
4384
|
+
const currentCache = getServerStateCache();
|
|
4385
|
+
const revertedPlugins = currentCache.plugins.map((p) => {
|
|
4386
|
+
if (p.name !== plugin)
|
|
4387
|
+
return p;
|
|
4388
|
+
return {
|
|
4389
|
+
...p,
|
|
4390
|
+
tools: p.tools.map((t) => t.name === tool ? { ...t, enabled: originalEnabled } : t)
|
|
4391
|
+
};
|
|
4392
|
+
});
|
|
4393
|
+
updateServerStateCache({ plugins: revertedPlugins });
|
|
4394
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4395
|
+
});
|
|
4396
|
+
};
|
|
4397
|
+
var handleBgSetAllToolsEnabled = (message, sendResponse) => {
|
|
4398
|
+
const plugin = message.plugin;
|
|
4399
|
+
const enabled = message.enabled;
|
|
4400
|
+
const cache2 = getServerStateCache();
|
|
4401
|
+
const pluginEntry = cache2.plugins.find((p) => p.name === plugin);
|
|
4402
|
+
const toolNames = pluginEntry ? pluginEntry.tools.map((t) => t.name) : [];
|
|
4403
|
+
const originalToolStates = /* @__PURE__ */ new Map();
|
|
4404
|
+
if (pluginEntry) {
|
|
4405
|
+
for (const t of pluginEntry.tools) {
|
|
4406
|
+
originalToolStates.set(t.name, t.enabled);
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
const updatedPlugins = cache2.plugins.map((p) => {
|
|
4410
|
+
if (p.name !== plugin)
|
|
4411
|
+
return p;
|
|
4412
|
+
return {
|
|
4413
|
+
...p,
|
|
4414
|
+
tools: p.tools.map((t) => ({ ...t, enabled }))
|
|
4415
|
+
};
|
|
4416
|
+
});
|
|
4417
|
+
addPendingPluginAllToolsUpdate(plugin, toolNames, enabled);
|
|
4418
|
+
updateServerStateCache({ plugins: updatedPlugins });
|
|
4419
|
+
sendServerRequest("config.setAllToolsEnabled", { plugin, enabled }).then((result) => {
|
|
4420
|
+
removePendingPluginAllToolsUpdate(plugin, toolNames);
|
|
4421
|
+
sendResponse(result);
|
|
4422
|
+
}).catch((err2) => {
|
|
4423
|
+
removePendingPluginAllToolsUpdate(plugin, toolNames);
|
|
4424
|
+
const currentCache = getServerStateCache();
|
|
4425
|
+
const revertedPlugins = currentCache.plugins.map((p) => {
|
|
4426
|
+
if (p.name !== plugin)
|
|
4427
|
+
return p;
|
|
4428
|
+
return {
|
|
4429
|
+
...p,
|
|
4430
|
+
tools: p.tools.map((t) => ({
|
|
4431
|
+
...t,
|
|
4432
|
+
enabled: originalToolStates.get(t.name) ?? t.enabled
|
|
4433
|
+
}))
|
|
4434
|
+
};
|
|
4435
|
+
});
|
|
4436
|
+
updateServerStateCache({ plugins: revertedPlugins });
|
|
4437
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4438
|
+
});
|
|
4439
|
+
};
|
|
4440
|
+
var handleBgSetBrowserToolEnabled = (message, sendResponse) => {
|
|
4441
|
+
const tool = message.tool;
|
|
4442
|
+
const enabled = message.enabled;
|
|
4443
|
+
const cache2 = getServerStateCache();
|
|
4444
|
+
const originalEnabled = cache2.browserTools.find((bt) => bt.name === tool)?.enabled ?? !enabled;
|
|
4445
|
+
const updatedBrowserTools = cache2.browserTools.map((bt) => bt.name === tool ? { ...bt, enabled } : bt);
|
|
4446
|
+
addPendingBrowserToolUpdate(tool, enabled);
|
|
4447
|
+
updateServerStateCache({ browserTools: updatedBrowserTools });
|
|
4448
|
+
sendServerRequest("config.setBrowserToolEnabled", { tool, enabled }).then((result) => {
|
|
4449
|
+
removePendingBrowserToolUpdate(tool);
|
|
4450
|
+
sendResponse(result);
|
|
4451
|
+
}).catch((err2) => {
|
|
4452
|
+
removePendingBrowserToolUpdate(tool);
|
|
4453
|
+
const currentCache = getServerStateCache();
|
|
4454
|
+
const revertedBrowserTools = currentCache.browserTools.map((bt) => bt.name === tool ? { ...bt, enabled: originalEnabled } : bt);
|
|
4455
|
+
updateServerStateCache({ browserTools: revertedBrowserTools });
|
|
4456
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4457
|
+
});
|
|
4458
|
+
};
|
|
4459
|
+
var handleBgSetAllBrowserToolsEnabled = (message, sendResponse) => {
|
|
4460
|
+
const enabled = message.enabled;
|
|
4461
|
+
const cache2 = getServerStateCache();
|
|
4462
|
+
const toolNames = cache2.browserTools.map((bt) => bt.name);
|
|
4463
|
+
const originalToolStates = /* @__PURE__ */ new Map();
|
|
4464
|
+
for (const bt of cache2.browserTools) {
|
|
4465
|
+
originalToolStates.set(bt.name, bt.enabled);
|
|
4466
|
+
}
|
|
4467
|
+
const updatedBrowserTools = cache2.browserTools.map((bt) => ({ ...bt, enabled }));
|
|
4468
|
+
addPendingAllBrowserToolsUpdate(toolNames, enabled);
|
|
4469
|
+
updateServerStateCache({ browserTools: updatedBrowserTools });
|
|
4470
|
+
sendServerRequest("config.setAllBrowserToolsEnabled", { enabled }).then((result) => {
|
|
4471
|
+
removePendingAllBrowserToolsUpdate(toolNames);
|
|
4472
|
+
sendResponse(result);
|
|
4473
|
+
}).catch((err2) => {
|
|
4474
|
+
removePendingAllBrowserToolsUpdate(toolNames);
|
|
4475
|
+
const currentCache = getServerStateCache();
|
|
4476
|
+
const revertedBrowserTools = currentCache.browserTools.map((bt) => ({
|
|
4477
|
+
...bt,
|
|
4478
|
+
enabled: originalToolStates.get(bt.name) ?? bt.enabled
|
|
4479
|
+
}));
|
|
4480
|
+
updateServerStateCache({ browserTools: revertedBrowserTools });
|
|
4481
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4482
|
+
});
|
|
4483
|
+
};
|
|
4484
|
+
var handleBgSearchPlugins = (message, sendResponse) => {
|
|
4485
|
+
const query = message.query;
|
|
4486
|
+
sendServerRequest("plugin.search", { query }).then((result) => {
|
|
4487
|
+
sendResponse(result);
|
|
4488
|
+
}).catch((err2) => {
|
|
4489
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4490
|
+
});
|
|
4491
|
+
};
|
|
4492
|
+
var handleBgInstallPlugin = (message, sendResponse) => {
|
|
4493
|
+
const name = message.name;
|
|
4494
|
+
sendServerRequest("plugin.install", { name }).then((result) => {
|
|
4495
|
+
sendResponse(result);
|
|
4496
|
+
}).catch((err2) => {
|
|
4497
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4498
|
+
});
|
|
4499
|
+
};
|
|
4500
|
+
var handleBgRemovePlugin = (message, sendResponse) => {
|
|
4501
|
+
const name = message.name;
|
|
4502
|
+
sendServerRequest("plugin.remove", { name }).then((result) => {
|
|
4503
|
+
sendResponse(result);
|
|
4504
|
+
}).catch((err2) => {
|
|
4505
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4506
|
+
});
|
|
4507
|
+
};
|
|
4508
|
+
var handleBgUpdatePlugin = (message, sendResponse) => {
|
|
4509
|
+
const name = message.name;
|
|
4510
|
+
sendServerRequest("plugin.updateFromRegistry", { name }).then((result) => {
|
|
4511
|
+
sendResponse(result);
|
|
4512
|
+
}).catch((err2) => {
|
|
4513
|
+
sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
|
|
4514
|
+
});
|
|
4515
|
+
};
|
|
3978
4516
|
var handlePortChanged = (message, sendResponse) => {
|
|
3979
4517
|
chrome.runtime.sendMessage(message).catch(() => {
|
|
3980
4518
|
});
|
|
@@ -3984,8 +4522,15 @@ var backgroundHandlers = /* @__PURE__ */ new Map([
|
|
|
3984
4522
|
["offscreen:getUrl", handleOffscreenGetUrl],
|
|
3985
4523
|
["ws:state", handleWsState],
|
|
3986
4524
|
["ws:message", handleWsMessage],
|
|
3987
|
-
["bg:
|
|
3988
|
-
["bg:
|
|
4525
|
+
["bg:getFullState", handleBgGetFullState],
|
|
4526
|
+
["bg:setToolEnabled", handleBgSetToolEnabled],
|
|
4527
|
+
["bg:setAllToolsEnabled", handleBgSetAllToolsEnabled],
|
|
4528
|
+
["bg:setBrowserToolEnabled", handleBgSetBrowserToolEnabled],
|
|
4529
|
+
["bg:setAllBrowserToolsEnabled", handleBgSetAllBrowserToolsEnabled],
|
|
4530
|
+
["bg:searchPlugins", handleBgSearchPlugins],
|
|
4531
|
+
["bg:installPlugin", handleBgInstallPlugin],
|
|
4532
|
+
["bg:removePlugin", handleBgRemovePlugin],
|
|
4533
|
+
["bg:updatePlugin", handleBgUpdatePlugin],
|
|
3989
4534
|
["plugin:logs", handlePluginLogs],
|
|
3990
4535
|
["tool:progress", handleToolProgress],
|
|
3991
4536
|
["sp:confirmationResponse", handleSpConfirmationResponse],
|
|
@@ -3996,8 +4541,15 @@ var EXTENSION_ONLY_TYPES = /* @__PURE__ */ new Set([
|
|
|
3996
4541
|
"offscreen:getUrl",
|
|
3997
4542
|
"ws:state",
|
|
3998
4543
|
"ws:message",
|
|
3999
|
-
"bg:
|
|
4000
|
-
"bg:
|
|
4544
|
+
"bg:getFullState",
|
|
4545
|
+
"bg:setToolEnabled",
|
|
4546
|
+
"bg:setAllToolsEnabled",
|
|
4547
|
+
"bg:setBrowserToolEnabled",
|
|
4548
|
+
"bg:setAllBrowserToolsEnabled",
|
|
4549
|
+
"bg:searchPlugins",
|
|
4550
|
+
"bg:installPlugin",
|
|
4551
|
+
"bg:removePlugin",
|
|
4552
|
+
"bg:updatePlugin",
|
|
4001
4553
|
"offscreen:getLogs",
|
|
4002
4554
|
"sp:confirmationResponse",
|
|
4003
4555
|
"sp:confirmationTimeout",
|
|
@@ -4019,66 +4571,6 @@ var initBackgroundMessageHandlers = () => {
|
|
|
4019
4571
|
};
|
|
4020
4572
|
var backgroundHandlerNames = [...backgroundHandlers.keys()];
|
|
4021
4573
|
|
|
4022
|
-
// dist/side-panel-toggle.js
|
|
4023
|
-
var openWindows = /* @__PURE__ */ new Set();
|
|
4024
|
-
var persistOpenWindows = () => {
|
|
4025
|
-
chrome.storage.session.set({ [SIDE_PANEL_OPEN_WINDOWS_KEY]: Array.from(openWindows) }).catch(() => {
|
|
4026
|
-
});
|
|
4027
|
-
};
|
|
4028
|
-
var restoreOpenWindows = () => {
|
|
4029
|
-
chrome.storage.session.get(SIDE_PANEL_OPEN_WINDOWS_KEY).then((data) => {
|
|
4030
|
-
const stored = data[SIDE_PANEL_OPEN_WINDOWS_KEY];
|
|
4031
|
-
if (Array.isArray(stored)) {
|
|
4032
|
-
for (const id of stored) {
|
|
4033
|
-
if (typeof id === "number") {
|
|
4034
|
-
openWindows.add(id);
|
|
4035
|
-
}
|
|
4036
|
-
}
|
|
4037
|
-
}
|
|
4038
|
-
}).catch(() => {
|
|
4039
|
-
});
|
|
4040
|
-
};
|
|
4041
|
-
var initSidePanelToggle = () => {
|
|
4042
|
-
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: false }).catch(() => {
|
|
4043
|
-
});
|
|
4044
|
-
const canToggle = "onOpened" in chrome.sidePanel;
|
|
4045
|
-
if (canToggle) {
|
|
4046
|
-
restoreOpenWindows();
|
|
4047
|
-
chrome.sidePanel.onOpened.addListener(({ windowId }) => {
|
|
4048
|
-
openWindows.add(windowId);
|
|
4049
|
-
persistOpenWindows();
|
|
4050
|
-
});
|
|
4051
|
-
chrome.sidePanel.onClosed.addListener(({ windowId }) => {
|
|
4052
|
-
openWindows.delete(windowId);
|
|
4053
|
-
persistOpenWindows();
|
|
4054
|
-
});
|
|
4055
|
-
chrome.windows.onRemoved.addListener((windowId) => {
|
|
4056
|
-
openWindows.delete(windowId);
|
|
4057
|
-
persistOpenWindows();
|
|
4058
|
-
});
|
|
4059
|
-
}
|
|
4060
|
-
chrome.action.onClicked.addListener(({ windowId }) => {
|
|
4061
|
-
void (async () => {
|
|
4062
|
-
if (canToggle && openWindows.has(windowId)) {
|
|
4063
|
-
try {
|
|
4064
|
-
await chrome.windows.get(windowId);
|
|
4065
|
-
} catch {
|
|
4066
|
-
openWindows.delete(windowId);
|
|
4067
|
-
persistOpenWindows();
|
|
4068
|
-
await chrome.sidePanel.open({ windowId }).catch(() => {
|
|
4069
|
-
});
|
|
4070
|
-
return;
|
|
4071
|
-
}
|
|
4072
|
-
chrome.sidePanel.close({ windowId }).catch(() => {
|
|
4073
|
-
});
|
|
4074
|
-
} else {
|
|
4075
|
-
chrome.sidePanel.open({ windowId }).catch(() => {
|
|
4076
|
-
});
|
|
4077
|
-
}
|
|
4078
|
-
})();
|
|
4079
|
-
});
|
|
4080
|
-
};
|
|
4081
|
-
|
|
4082
4574
|
// dist/background.js
|
|
4083
4575
|
initSidePanelToggle();
|
|
4084
4576
|
restoreWsConnectedState();
|
|
@@ -4108,7 +4600,9 @@ var setupKeepaliveAlarm = async () => {
|
|
|
4108
4600
|
}
|
|
4109
4601
|
};
|
|
4110
4602
|
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
4111
|
-
if (changeInfo.status === "
|
|
4603
|
+
if (changeInfo.status === "loading" && tab.url) {
|
|
4604
|
+
injectPluginsIntoTab(tabId, tab.url).catch((err2) => console.warn("[opentabs] early tab injection failed:", err2));
|
|
4605
|
+
} else if (changeInfo.status === "complete" && tab.url) {
|
|
4112
4606
|
injectPluginsIntoTab(tabId, tab.url).then(() => checkTabChanged(tabId, changeInfo)).catch((err2) => console.warn("[opentabs] tab injection failed:", err2));
|
|
4113
4607
|
} else if (changeInfo.url) {
|
|
4114
4608
|
checkTabChanged(tabId, changeInfo).catch((err2) => console.warn("[opentabs] tab state check failed:", err2));
|