@opentabs-dev/browser-extension 0.0.61 → 0.0.62

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.
Files changed (87) hide show
  1. package/dist/background-message-handlers.d.ts +8 -14
  2. package/dist/background-message-handlers.d.ts.map +1 -1
  3. package/dist/background-message-handlers.js +50 -156
  4. package/dist/background-message-handlers.js.map +1 -1
  5. package/dist/background.js +173 -216
  6. package/dist/confirmation-badge.d.ts +3 -24
  7. package/dist/confirmation-badge.d.ts.map +1 -1
  8. package/dist/confirmation-badge.js +13 -98
  9. package/dist/confirmation-badge.js.map +1 -1
  10. package/dist/extension-messages.d.ts +17 -34
  11. package/dist/extension-messages.d.ts.map +1 -1
  12. package/dist/message-router.d.ts +2 -2
  13. package/dist/message-router.d.ts.map +1 -1
  14. package/dist/message-router.js +22 -10
  15. package/dist/message-router.js.map +1 -1
  16. package/dist/offscreen/index.js +3 -5
  17. package/dist/offscreen/index.js.map +1 -1
  18. package/dist/plugin-storage.js +3 -3
  19. package/dist/plugin-storage.js.map +1 -1
  20. package/dist/server-state-cache.d.ts +12 -6
  21. package/dist/server-state-cache.d.ts.map +1 -1
  22. package/dist/server-state-cache.js +51 -21
  23. package/dist/server-state-cache.js.map +1 -1
  24. package/dist/side-panel/App.d.ts.map +1 -1
  25. package/dist/side-panel/App.js +19 -25
  26. package/dist/side-panel/App.js.map +1 -1
  27. package/dist/side-panel/bridge.d.ts +13 -18
  28. package/dist/side-panel/bridge.d.ts.map +1 -1
  29. package/dist/side-panel/bridge.js +9 -13
  30. package/dist/side-panel/bridge.js.map +1 -1
  31. package/dist/side-panel/components/BrowserToolsCard.d.ts +5 -1
  32. package/dist/side-panel/components/BrowserToolsCard.d.ts.map +1 -1
  33. package/dist/side-panel/components/BrowserToolsCard.js +40 -22
  34. package/dist/side-panel/components/BrowserToolsCard.js.map +1 -1
  35. package/dist/side-panel/components/ConfirmationDialog.d.ts +4 -11
  36. package/dist/side-panel/components/ConfirmationDialog.d.ts.map +1 -1
  37. package/dist/side-panel/components/ConfirmationDialog.js +23 -34
  38. package/dist/side-panel/components/ConfirmationDialog.js.map +1 -1
  39. package/dist/side-panel/components/NpmPluginCard.d.ts.map +1 -1
  40. package/dist/side-panel/components/NpmPluginCard.js +1 -1
  41. package/dist/side-panel/components/NpmPluginCard.js.map +1 -1
  42. package/dist/side-panel/components/PluginCard.d.ts +2 -1
  43. package/dist/side-panel/components/PluginCard.d.ts.map +1 -1
  44. package/dist/side-panel/components/PluginCard.js +18 -40
  45. package/dist/side-panel/components/PluginCard.js.map +1 -1
  46. package/dist/side-panel/components/PluginIcon.d.ts +1 -2
  47. package/dist/side-panel/components/PluginIcon.d.ts.map +1 -1
  48. package/dist/side-panel/components/PluginIcon.js +36 -41
  49. package/dist/side-panel/components/PluginIcon.js.map +1 -1
  50. package/dist/side-panel/components/PluginList.d.ts +2 -1
  51. package/dist/side-panel/components/PluginList.d.ts.map +1 -1
  52. package/dist/side-panel/components/PluginList.js +2 -2
  53. package/dist/side-panel/components/PluginList.js.map +1 -1
  54. package/dist/side-panel/components/PluginMenu.d.ts.map +1 -1
  55. package/dist/side-panel/components/PluginMenu.js +1 -1
  56. package/dist/side-panel/components/PluginMenu.js.map +1 -1
  57. package/dist/side-panel/components/SearchResults.d.ts +2 -1
  58. package/dist/side-panel/components/SearchResults.d.ts.map +1 -1
  59. package/dist/side-panel/components/SearchResults.js +2 -2
  60. package/dist/side-panel/components/SearchResults.js.map +1 -1
  61. package/dist/side-panel/components/ToolIcon.d.ts.map +1 -1
  62. package/dist/side-panel/components/ToolIcon.js +9 -2
  63. package/dist/side-panel/components/ToolIcon.js.map +1 -1
  64. package/dist/side-panel/components/ToolRow.d.ts +14 -4
  65. package/dist/side-panel/components/ToolRow.d.ts.map +1 -1
  66. package/dist/side-panel/components/ToolRow.js +13 -3
  67. package/dist/side-panel/components/ToolRow.js.map +1 -1
  68. package/dist/side-panel/components/retro/Select.d.ts +13 -0
  69. package/dist/side-panel/components/retro/Select.d.ts.map +1 -0
  70. package/dist/side-panel/components/retro/Select.js +27 -0
  71. package/dist/side-panel/components/retro/Select.js.map +1 -0
  72. package/dist/side-panel/constants.d.ts +0 -2
  73. package/dist/side-panel/constants.d.ts.map +1 -1
  74. package/dist/side-panel/constants.js +0 -2
  75. package/dist/side-panel/constants.js.map +1 -1
  76. package/dist/side-panel/hooks/useServerNotifications.d.ts +1 -3
  77. package/dist/side-panel/hooks/useServerNotifications.d.ts.map +1 -1
  78. package/dist/side-panel/hooks/useServerNotifications.js +13 -41
  79. package/dist/side-panel/hooks/useServerNotifications.js.map +1 -1
  80. package/dist/side-panel/side-panel.js +5715 -4723
  81. package/dist/side-panel/styles.css +1 -1
  82. package/dist/tool-dispatch.d.ts +2 -1
  83. package/dist/tool-dispatch.d.ts.map +1 -1
  84. package/dist/tool-dispatch.js +4 -6
  85. package/dist/tool-dispatch.js.map +1 -1
  86. package/manifest.json +1 -1
  87. package/package.json +2 -1
@@ -1,3 +1,70 @@
1
+ /**
2
+ * Dev reload client for the background service worker.
3
+ *
4
+ * Connects to the dev reload WebSocket relay server and triggers a full
5
+ * extension reload (chrome.runtime.reload()) when a DO_UPDATE signal with
6
+ * id 'extension' is received. Ignores 'side-panel' updates — the side
7
+ * panel has its own reload client that handles those.
8
+ *
9
+ * Before reloading, clears the 'wsConnected' session storage key to prevent
10
+ * the restarted background script from reading stale connection state.
11
+ *
12
+ * This file is plain JS (not TypeScript) because it is read at build time
13
+ * and prepended to the background bundle via esbuild's banner option. The
14
+ * 18515 placeholder is replaced by string substitution in
15
+ * the build script with the actual port number.
16
+ */
17
+ (() => {
18
+ const port = 18515;
19
+ const url = `ws://localhost:${port}`;
20
+ const prefix = '[dev-reload:bg]';
21
+ let backoff = 500;
22
+ const maxBackoff = 10000;
23
+
24
+ const connect = () => {
25
+ const ws = new WebSocket(url);
26
+
27
+ ws.addEventListener('open', () => {
28
+ console.log(prefix, 'Connected to', url);
29
+ backoff = 500;
30
+ });
31
+
32
+ ws.addEventListener('message', event => {
33
+ try {
34
+ const msg = JSON.parse(event.data);
35
+ if (msg.type === 'do_update' && msg.id === 'extension') {
36
+ console.log(prefix, 'Reloading extension (full)');
37
+ // Clear wsConnected from session storage before reload to prevent
38
+ // the restarted background script from reading stale state.
39
+ chrome.storage.session
40
+ .set({ wsConnected: false })
41
+ .catch(() => {})
42
+ .then(() => {
43
+ setTimeout(() => {
44
+ chrome.runtime.reload();
45
+ }, 100);
46
+ });
47
+ }
48
+ } catch (_) {
49
+ // Ignore malformed messages
50
+ }
51
+ });
52
+
53
+ ws.addEventListener('close', () => {
54
+ console.log(prefix, 'Disconnected — reconnecting in', `${backoff}ms`);
55
+ setTimeout(connect, backoff);
56
+ backoff = Math.min(backoff * 2, maxBackoff);
57
+ });
58
+
59
+ ws.addEventListener('error', () => {
60
+ // onclose fires after onerror, so reconnect logic is handled there
61
+ });
62
+ };
63
+
64
+ connect();
65
+ })();
66
+
67
+
1
68
  // dist/constants.js
2
69
  var KEEPALIVE_ALARM = "opentabs-keepalive";
3
70
  var KEEPALIVE_INTERVAL_MINUTES = 0.5;
@@ -94,10 +161,6 @@ var initSidePanelToggle = () => {
94
161
  var pendingConfirmationCount = 0;
95
162
  var NOTIFICATION_ID = "opentabs-confirmation";
96
163
  var pendingConfirmations = /* @__PURE__ */ new Map();
97
- var confirmationTimeouts = /* @__PURE__ */ new Map();
98
- var clearedConfirmationIds = /* @__PURE__ */ new Set();
99
- var CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS = 2e3;
100
- var CONFIRMATION_FALLBACK_TIMEOUT_MS = 3e4;
101
164
  var updateConfirmationBadge = () => {
102
165
  if (pendingConfirmationCount > 0) {
103
166
  chrome.action.setBadgeText({ text: String(pendingConfirmationCount) }).catch(() => {
@@ -118,7 +181,7 @@ var syncConfirmationNotification = () => {
118
181
  let message;
119
182
  if (pendingConfirmationCount === 1 && pendingConfirmations.size === 1) {
120
183
  const info = pendingConfirmations.values().next().value;
121
- message = info.domain ? `${info.tool} on ${info.domain}` : info.tool;
184
+ message = `${info.plugin}: ${info.tool}`;
122
185
  } else if (pendingConfirmationCount > 1) {
123
186
  message = `${pendingConfirmationCount} tools awaiting approval`;
124
187
  } else {
@@ -136,59 +199,32 @@ var syncConfirmationNotification = () => {
136
199
  };
137
200
  var notifyConfirmationRequest = (params) => {
138
201
  const tool = typeof params.tool === "string" ? params.tool : "unknown tool";
139
- const domain = typeof params.domain === "string" ? params.domain : null;
202
+ const plugin = typeof params.plugin === "string" ? params.plugin : "unknown";
140
203
  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 : "";
143
- const timeoutMs = typeof params.timeoutMs === "number" ? params.timeoutMs : 0;
204
+ const rawParams = typeof params.params === "object" && params.params !== null ? params.params : {};
144
205
  const receivedAt = Date.now();
145
- const existingTimeoutId = confirmationTimeouts.get(id);
146
- if (existingTimeoutId !== void 0) {
147
- clearTimeout(existingTimeoutId);
148
- } else {
149
- clearedConfirmationIds.delete(id);
150
- pendingConfirmationCount++;
151
- updateConfirmationBadge();
152
- }
153
- pendingConfirmations.set(id, { id, tool, domain, tabId, paramsPreview, timeoutMs, receivedAt });
154
- const effectiveTimeoutMs = timeoutMs > 0 ? timeoutMs : CONFIRMATION_FALLBACK_TIMEOUT_MS;
155
- const bgTimeoutId = setTimeout(() => {
156
- confirmationTimeouts.delete(id);
157
- clearConfirmationBadge(id);
158
- clearedConfirmationIds.delete(id);
159
- }, effectiveTimeoutMs + CONFIRMATION_BACKGROUND_TIMEOUT_BUFFER_MS);
160
- confirmationTimeouts.set(id, bgTimeoutId);
206
+ if (pendingConfirmations.has(id)) {
207
+ pendingConfirmations.set(id, { id, tool, plugin, params: rawParams, receivedAt });
208
+ syncConfirmationNotification();
209
+ return;
210
+ }
211
+ pendingConfirmationCount++;
212
+ updateConfirmationBadge();
213
+ pendingConfirmations.set(id, { id, tool, plugin, params: rawParams, receivedAt });
161
214
  syncConfirmationNotification();
162
215
  };
163
216
  var clearConfirmationBadge = (id) => {
164
217
  if (id !== void 0) {
165
- if (clearedConfirmationIds.has(id)) {
218
+ if (!pendingConfirmations.has(id)) {
166
219
  return;
167
220
  }
168
- clearedConfirmationIds.add(id);
169
221
  pendingConfirmations.delete(id);
170
222
  }
171
223
  pendingConfirmationCount = Math.max(0, pendingConfirmationCount - 1);
172
224
  updateConfirmationBadge();
173
225
  syncConfirmationNotification();
174
- if (id !== void 0 && !confirmationTimeouts.has(id)) {
175
- clearedConfirmationIds.delete(id);
176
- }
177
- };
178
- var clearConfirmationBackgroundTimeout = (id) => {
179
- const timeoutId = confirmationTimeouts.get(id);
180
- if (timeoutId !== void 0) {
181
- clearTimeout(timeoutId);
182
- confirmationTimeouts.delete(id);
183
- clearedConfirmationIds.delete(id);
184
- }
185
226
  };
186
227
  var clearAllConfirmationBadges = () => {
187
- for (const [, timeoutId] of confirmationTimeouts.entries()) {
188
- clearTimeout(timeoutId);
189
- }
190
- confirmationTimeouts.clear();
191
- clearedConfirmationIds.clear();
192
228
  pendingConfirmations.clear();
193
229
  pendingConfirmationCount = 0;
194
230
  updateConfirmationBadge();
@@ -1151,12 +1187,12 @@ var removePluginsBatch = (pluginNames) => serialize(async () => {
1151
1187
  await chrome.storage.local.set({ [PLUGINS_META_KEY]: filtered });
1152
1188
  metaCache = filtered;
1153
1189
  });
1154
- var VALID_TRUST_TIERS = /* @__PURE__ */ new Set(["official", "community", "local"]);
1190
+ var VALID_PERMISSIONS = /* @__PURE__ */ new Set(["off", "ask", "auto"]);
1155
1191
  var isValidPluginMeta = (value) => {
1156
1192
  if (typeof value !== "object" || value === null)
1157
1193
  return false;
1158
1194
  const obj = value;
1159
- return typeof obj.name === "string" && typeof obj.version === "string" && Array.isArray(obj.urlPatterns) && typeof obj.trustTier === "string" && VALID_TRUST_TIERS.has(obj.trustTier) && Array.isArray(obj.tools);
1195
+ return typeof obj.name === "string" && typeof obj.version === "string" && Array.isArray(obj.urlPatterns) && typeof obj.permission === "string" && VALID_PERMISSIONS.has(obj.permission) && Array.isArray(obj.tools);
1160
1196
  };
1161
1197
  var getAllPluginMeta = async () => {
1162
1198
  if (metaCache !== null) {
@@ -3246,46 +3282,67 @@ var EMPTY_CACHE = {
3246
3282
  plugins: [],
3247
3283
  failedPlugins: [],
3248
3284
  browserTools: [],
3249
- serverVersion: void 0
3285
+ browserPermission: void 0,
3286
+ serverVersion: void 0,
3287
+ skipPermissions: void 0
3250
3288
  };
3251
3289
  var cache = { ...EMPTY_CACHE };
3252
3290
  var pendingPluginToolUpdates = /* @__PURE__ */ new Map();
3291
+ var pendingPluginPermissionUpdates = /* @__PURE__ */ new Map();
3253
3292
  var pendingBrowserToolUpdates = /* @__PURE__ */ new Map();
3254
3293
  var reapplyPendingOptimisticUpdates = () => {
3255
- if (pendingPluginToolUpdates.size > 0) {
3294
+ if (pendingPluginToolUpdates.size > 0 || pendingPluginPermissionUpdates.size > 0) {
3256
3295
  cache = {
3257
3296
  ...cache,
3258
3297
  plugins: cache.plugins.map((plugin) => {
3298
+ const permOverride = pendingPluginPermissionUpdates.get(plugin.name);
3259
3299
  const toolOverrides = pendingPluginToolUpdates.get(plugin.name);
3260
- if (!toolOverrides)
3300
+ if (permOverride === void 0 && !toolOverrides)
3261
3301
  return plugin;
3262
- return {
3263
- ...plugin,
3264
- tools: plugin.tools.map((tool) => {
3265
- const override = toolOverrides.get(tool.name);
3266
- return override !== void 0 ? { ...tool, enabled: override } : tool;
3267
- })
3268
- };
3302
+ let updated = plugin;
3303
+ if (permOverride !== void 0) {
3304
+ updated = { ...updated, permission: permOverride };
3305
+ }
3306
+ if (toolOverrides) {
3307
+ updated = {
3308
+ ...updated,
3309
+ tools: updated.tools.map((tool) => {
3310
+ const override = toolOverrides.get(tool.name);
3311
+ return override !== void 0 ? { ...tool, permission: override } : tool;
3312
+ })
3313
+ };
3314
+ }
3315
+ return updated;
3269
3316
  })
3270
3317
  };
3271
3318
  }
3319
+ const browserPermOverride = pendingPluginPermissionUpdates.get("browser");
3320
+ if (browserPermOverride !== void 0) {
3321
+ cache = { ...cache, browserPermission: browserPermOverride };
3322
+ }
3272
3323
  if (pendingBrowserToolUpdates.size > 0) {
3273
3324
  cache = {
3274
3325
  ...cache,
3275
3326
  browserTools: cache.browserTools.map((bt) => {
3276
3327
  const override = pendingBrowserToolUpdates.get(bt.name);
3277
- return override !== void 0 ? { ...bt, enabled: override } : bt;
3328
+ return override !== void 0 ? { ...bt, permission: override } : bt;
3278
3329
  })
3279
3330
  };
3280
3331
  }
3281
3332
  };
3282
- var addPendingPluginToolUpdate = (plugin, tool, enabled) => {
3333
+ var addPendingPluginPermissionUpdate = (plugin, permission) => {
3334
+ pendingPluginPermissionUpdates.set(plugin, permission);
3335
+ };
3336
+ var removePendingPluginPermissionUpdate = (plugin) => {
3337
+ pendingPluginPermissionUpdates.delete(plugin);
3338
+ };
3339
+ var addPendingPluginToolUpdate = (plugin, tool, permission) => {
3283
3340
  let toolMap = pendingPluginToolUpdates.get(plugin);
3284
3341
  if (!toolMap) {
3285
3342
  toolMap = /* @__PURE__ */ new Map();
3286
3343
  pendingPluginToolUpdates.set(plugin, toolMap);
3287
3344
  }
3288
- toolMap.set(tool, enabled);
3345
+ toolMap.set(tool, permission);
3289
3346
  };
3290
3347
  var removePendingPluginToolUpdate = (plugin, tool) => {
3291
3348
  const toolMap = pendingPluginToolUpdates.get(plugin);
@@ -3295,14 +3352,14 @@ var removePendingPluginToolUpdate = (plugin, tool) => {
3295
3352
  if (toolMap.size === 0)
3296
3353
  pendingPluginToolUpdates.delete(plugin);
3297
3354
  };
3298
- var addPendingPluginAllToolsUpdate = (plugin, toolNames, enabled) => {
3355
+ var addPendingPluginAllToolsUpdate = (plugin, toolNames, permission) => {
3299
3356
  let toolMap = pendingPluginToolUpdates.get(plugin);
3300
3357
  if (!toolMap) {
3301
3358
  toolMap = /* @__PURE__ */ new Map();
3302
3359
  pendingPluginToolUpdates.set(plugin, toolMap);
3303
3360
  }
3304
3361
  for (const name of toolNames) {
3305
- toolMap.set(name, enabled);
3362
+ toolMap.set(name, permission);
3306
3363
  }
3307
3364
  };
3308
3365
  var removePendingPluginAllToolsUpdate = (plugin, toolNames) => {
@@ -3315,22 +3372,6 @@ var removePendingPluginAllToolsUpdate = (plugin, toolNames) => {
3315
3372
  if (toolMap.size === 0)
3316
3373
  pendingPluginToolUpdates.delete(plugin);
3317
3374
  };
3318
- var addPendingBrowserToolUpdate = (tool, enabled) => {
3319
- pendingBrowserToolUpdates.set(tool, enabled);
3320
- };
3321
- var removePendingBrowserToolUpdate = (tool) => {
3322
- pendingBrowserToolUpdates.delete(tool);
3323
- };
3324
- var addPendingAllBrowserToolsUpdate = (toolNames, enabled) => {
3325
- for (const name of toolNames) {
3326
- pendingBrowserToolUpdates.set(name, enabled);
3327
- }
3328
- };
3329
- var removePendingAllBrowserToolsUpdate = (toolNames) => {
3330
- for (const name of toolNames) {
3331
- pendingBrowserToolUpdates.delete(name);
3332
- }
3333
- };
3334
3375
  var cachesInitialized = false;
3335
3376
  var persistTimer;
3336
3377
  var persistToSession = () => {
@@ -3362,6 +3403,7 @@ var clearServerStateCache = () => {
3362
3403
  cache = { ...EMPTY_CACHE };
3363
3404
  cachesInitialized = false;
3364
3405
  pendingPluginToolUpdates.clear();
3406
+ pendingPluginPermissionUpdates.clear();
3365
3407
  pendingBrowserToolUpdates.clear();
3366
3408
  if (persistTimer !== void 0) {
3367
3409
  clearTimeout(persistTimer);
@@ -3379,7 +3421,9 @@ var loadServerStateCacheFromSession = async () => {
3379
3421
  plugins: Array.isArray(stored.plugins) ? stored.plugins : [],
3380
3422
  failedPlugins: Array.isArray(stored.failedPlugins) ? stored.failedPlugins : [],
3381
3423
  browserTools: Array.isArray(stored.browserTools) ? stored.browserTools : [],
3382
- serverVersion: typeof stored.serverVersion === "string" ? stored.serverVersion : void 0
3424
+ browserPermission: stored.browserPermission === "off" || stored.browserPermission === "ask" || stored.browserPermission === "auto" ? stored.browserPermission : void 0,
3425
+ serverVersion: typeof stored.serverVersion === "string" ? stored.serverVersion : void 0,
3426
+ skipPermissions: typeof stored.skipPermissions === "boolean" ? stored.skipPermissions : void 0
3383
3427
  };
3384
3428
  }
3385
3429
  if (typeof data[CACHES_INITIALIZED_KEY] === "boolean") {
@@ -3540,13 +3584,10 @@ var notifyDispatchProgress = (dispatchId) => {
3540
3584
  cb();
3541
3585
  };
3542
3586
  var getPluginLink = (plugin) => {
3543
- if (plugin.trustTier === "local" && plugin.sourcePath) {
3587
+ if (plugin.sourcePath) {
3544
3588
  return plugin.sourcePath;
3545
3589
  }
3546
- if (plugin.trustTier === "official") {
3547
- return `https://npmjs.com/package/@opentabs-dev/plugin-${plugin.name}`;
3548
- }
3549
- return `https://npmjs.com/package/opentabs-plugin-${plugin.name}`;
3590
+ return `https://npmjs.com/package/${plugin.name}`;
3550
3591
  };
3551
3592
  var injectToolInvocationLog = async (tabId, pluginName, toolName, link) => {
3552
3593
  try {
@@ -3834,7 +3875,7 @@ var toPluginMeta = (p) => ({
3834
3875
  version: p.version,
3835
3876
  displayName: p.displayName,
3836
3877
  urlPatterns: p.urlPatterns,
3837
- trustTier: p.trustTier,
3878
+ permission: p.permission,
3838
3879
  sourcePath: p.sourcePath,
3839
3880
  adapterHash: p.adapterHash,
3840
3881
  adapterFile: p.adapterFile,
@@ -3860,16 +3901,17 @@ var validatePluginPayload = (raw) => {
3860
3901
  }
3861
3902
  const urlPatterns = Array.isArray(obj.urlPatterns) ? obj.urlPatterns.filter((p) => typeof p === "string") : [];
3862
3903
  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) => {
3863
- if (typeof t.enabled !== "boolean") {
3864
- 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.`);
3904
+ if (t.permission !== "off" && t.permission !== "ask" && t.permission !== "auto") {
3905
+ console.warn(`[opentabs] Tool "${t.name}" in plugin "${obj.name}" has invalid "permission" field \u2014 defaulting to permission='off'. This is a server-side bug.`);
3865
3906
  }
3866
3907
  return {
3867
3908
  name: t.name,
3868
3909
  displayName: typeof t.displayName === "string" ? t.displayName : t.name,
3869
3910
  description: t.description,
3911
+ ...typeof t.summary === "string" ? { summary: t.summary } : {},
3870
3912
  icon: typeof t.icon === "string" ? t.icon : "wrench",
3871
3913
  ...typeof t.group === "string" ? { group: t.group } : {},
3872
- enabled: typeof t.enabled === "boolean" ? t.enabled : true
3914
+ permission: t.permission === "off" || t.permission === "ask" || t.permission === "auto" ? t.permission : "off"
3873
3915
  };
3874
3916
  }) : [];
3875
3917
  return {
@@ -3877,7 +3919,7 @@ var validatePluginPayload = (raw) => {
3877
3919
  version: typeof obj.version === "string" ? obj.version : "0.0.0",
3878
3920
  displayName: typeof obj.displayName === "string" ? obj.displayName : obj.name,
3879
3921
  urlPatterns,
3880
- trustTier: obj.trustTier === "official" || obj.trustTier === "community" || obj.trustTier === "local" ? obj.trustTier : "local",
3922
+ permission: obj.permission === "off" || obj.permission === "ask" || obj.permission === "auto" ? obj.permission : "off",
3881
3923
  sourcePath: typeof obj.sourcePath === "string" ? obj.sourcePath : void 0,
3882
3924
  adapterHash: typeof obj.adapterHash === "string" ? obj.adapterHash : void 0,
3883
3925
  adapterFile: typeof obj.adapterFile === "string" ? obj.adapterFile : void 0,
@@ -3951,7 +3993,7 @@ var handleSyncFull = async (params) => {
3951
3993
  name: p.name,
3952
3994
  displayName: p.displayName,
3953
3995
  version: p.version,
3954
- trustTier: p.trustTier,
3996
+ permission: p.permission,
3955
3997
  source: raw?.source === "npm" || raw?.source === "local" ? raw.source : "local",
3956
3998
  tabState: "closed",
3957
3999
  urlPatterns: p.urlPatterns,
@@ -3969,11 +4011,16 @@ var handleSyncFull = async (params) => {
3969
4011
  const rawFailedPlugins = Array.isArray(params.failedPlugins) ? params.failedPlugins : void 0;
3970
4012
  const rawBrowserTools = Array.isArray(params.browserTools) ? params.browserTools : void 0;
3971
4013
  const rawServerVersion = typeof params.serverVersion === "string" ? params.serverVersion : void 0;
4014
+ const rawBrowserPermission = params.browserPermission;
4015
+ const browserPermission = rawBrowserPermission === "off" || rawBrowserPermission === "ask" || rawBrowserPermission === "auto" ? rawBrowserPermission : void 0;
4016
+ const rawSkipPermissions = typeof params.skipPermissions === "boolean" ? params.skipPermissions : void 0;
3972
4017
  updateServerStateCache({
3973
4018
  plugins: cachePlugins,
3974
4019
  ...rawFailedPlugins ? { failedPlugins: rawFailedPlugins } : {},
3975
4020
  ...rawBrowserTools ? { browserTools: rawBrowserTools } : {},
3976
- ...rawServerVersion !== void 0 ? { serverVersion: rawServerVersion } : {}
4021
+ ...browserPermission !== void 0 ? { browserPermission } : {},
4022
+ ...rawServerVersion !== void 0 ? { serverVersion: rawServerVersion } : {},
4023
+ ...rawSkipPermissions !== void 0 ? { skipPermissions: rawSkipPermissions } : {}
3977
4024
  });
3978
4025
  setCachesInitialized(true);
3979
4026
  flushServerStateCacheToSession();
@@ -4001,7 +4048,7 @@ var handlePluginUpdate = async (params) => {
4001
4048
  name: validated.name,
4002
4049
  displayName: validated.displayName,
4003
4050
  version: validated.version,
4004
- trustTier: validated.trustTier,
4051
+ permission: validated.permission,
4005
4052
  source: params.source === "npm" || params.source === "local" ? params.source : "local",
4006
4053
  tabState: newState.state,
4007
4054
  urlPatterns: validated.urlPatterns,
@@ -4144,7 +4191,9 @@ var handleServerMessage = (message) => {
4144
4191
  ...payload.plugins ? { plugins: payload.plugins } : {},
4145
4192
  ...payload.failedPlugins ? { failedPlugins: payload.failedPlugins } : {},
4146
4193
  ...payload.browserTools ? { browserTools: payload.browserTools } : {},
4147
- ...payload.serverVersion !== void 0 ? { serverVersion: payload.serverVersion } : {}
4194
+ ...payload.browserPermission !== void 0 ? { browserPermission: payload.browserPermission } : {},
4195
+ ...payload.serverVersion !== void 0 ? { serverVersion: payload.serverVersion } : {},
4196
+ ...payload.skipPermissions !== void 0 ? { skipPermissions: payload.skipPermissions } : {}
4148
4197
  });
4149
4198
  }
4150
4199
  if (method && SIDE_PANEL_METHODS.has(method)) {
@@ -4278,12 +4327,13 @@ var handleBgGetFullState = (_message, sendResponse) => {
4278
4327
  const serverTool = serverPlugin?.tools.find((st) => st.name === metaTool.name);
4279
4328
  return {
4280
4329
  ...metaTool,
4281
- enabled: serverTool?.enabled ?? true
4330
+ permission: serverTool?.permission ?? metaTool.permission
4282
4331
  };
4283
4332
  });
4284
4333
  const { tools: _metaTools, sourcePath: _sourcePath, adapterHash: _adapterHash, adapterFile: _adapterFile, ...metaFields } = meta;
4285
4334
  return {
4286
4335
  ...metaFields,
4336
+ permission: serverPlugin?.permission ?? meta.permission,
4287
4337
  tools,
4288
4338
  tabState,
4289
4339
  source: serverPlugin?.source ?? "local",
@@ -4297,7 +4347,9 @@ var handleBgGetFullState = (_message, sendResponse) => {
4297
4347
  plugins,
4298
4348
  failedPlugins: serverCache.failedPlugins,
4299
4349
  browserTools: serverCache.browserTools,
4350
+ browserPermission: serverCache.browserPermission,
4300
4351
  serverVersion: serverCache.serverVersion,
4352
+ skipPermissions: serverCache.skipPermissions,
4301
4353
  pendingConfirmations: getPendingConfirmations()
4302
4354
  });
4303
4355
  })().catch(() => {
@@ -4366,38 +4418,27 @@ var handleSpConfirmationResponse = (message, sendResponse) => {
4366
4418
  }
4367
4419
  const data = message.data;
4368
4420
  const id = typeof data?.id === "string" ? data.id : void 0;
4369
- if (id !== void 0) {
4370
- clearConfirmationBackgroundTimeout(id);
4371
- }
4372
4421
  clearConfirmationBadge(id);
4373
4422
  sendResponse({ ok: true });
4374
4423
  };
4375
- var handleSpConfirmationTimeout = (message, sendResponse) => {
4376
- const id = typeof message.id === "string" ? message.id : void 0;
4377
- if (id !== void 0) {
4378
- clearConfirmationBackgroundTimeout(id);
4379
- }
4380
- clearConfirmationBadge(id);
4381
- sendResponse({ ok: true });
4382
- };
4383
- var handleBgSetToolEnabled = (message, sendResponse) => {
4424
+ var handleBgSetToolPermission = (message, sendResponse) => {
4384
4425
  const plugin = message.plugin;
4385
4426
  const tool = message.tool;
4386
- const enabled = message.enabled;
4427
+ const permission = message.permission;
4387
4428
  const cache2 = getServerStateCache();
4388
4429
  const pluginEntry = cache2.plugins.find((p) => p.name === plugin);
4389
- const originalEnabled = pluginEntry?.tools.find((t) => t.name === tool)?.enabled ?? !enabled;
4430
+ const originalPermission = pluginEntry?.tools.find((t) => t.name === tool)?.permission ?? "auto";
4390
4431
  const updatedPlugins = cache2.plugins.map((p) => {
4391
4432
  if (p.name !== plugin)
4392
4433
  return p;
4393
4434
  return {
4394
4435
  ...p,
4395
- tools: p.tools.map((t) => t.name === tool ? { ...t, enabled } : t)
4436
+ tools: p.tools.map((t) => t.name === tool ? { ...t, permission } : t)
4396
4437
  };
4397
4438
  });
4398
- addPendingPluginToolUpdate(plugin, tool, enabled);
4439
+ addPendingPluginToolUpdate(plugin, tool, permission);
4399
4440
  updateServerStateCache({ plugins: updatedPlugins });
4400
- sendServerRequest("config.setToolEnabled", { plugin, tool, enabled }).then((result) => {
4441
+ sendServerRequest("config.setToolPermission", { plugin, tool, permission }).then((result) => {
4401
4442
  removePendingPluginToolUpdate(plugin, tool);
4402
4443
  sendResponse(result);
4403
4444
  }).catch((err2) => {
@@ -4408,23 +4449,23 @@ var handleBgSetToolEnabled = (message, sendResponse) => {
4408
4449
  return p;
4409
4450
  return {
4410
4451
  ...p,
4411
- tools: p.tools.map((t) => t.name === tool ? { ...t, enabled: originalEnabled } : t)
4452
+ tools: p.tools.map((t) => t.name === tool ? { ...t, permission: originalPermission } : t)
4412
4453
  };
4413
4454
  });
4414
4455
  updateServerStateCache({ plugins: revertedPlugins });
4415
4456
  sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
4416
4457
  });
4417
4458
  };
4418
- var handleBgSetAllToolsEnabled = (message, sendResponse) => {
4459
+ var handleBgSetAllToolsPermission = (message, sendResponse) => {
4419
4460
  const plugin = message.plugin;
4420
- const enabled = message.enabled;
4461
+ const permission = message.permission;
4421
4462
  const cache2 = getServerStateCache();
4422
4463
  const pluginEntry = cache2.plugins.find((p) => p.name === plugin);
4423
4464
  const toolNames = pluginEntry ? pluginEntry.tools.map((t) => t.name) : [];
4424
4465
  const originalToolStates = /* @__PURE__ */ new Map();
4425
4466
  if (pluginEntry) {
4426
4467
  for (const t of pluginEntry.tools) {
4427
- originalToolStates.set(t.name, t.enabled);
4468
+ originalToolStates.set(t.name, t.permission);
4428
4469
  }
4429
4470
  }
4430
4471
  const updatedPlugins = cache2.plugins.map((p) => {
@@ -4432,12 +4473,12 @@ var handleBgSetAllToolsEnabled = (message, sendResponse) => {
4432
4473
  return p;
4433
4474
  return {
4434
4475
  ...p,
4435
- tools: p.tools.map((t) => ({ ...t, enabled }))
4476
+ tools: p.tools.map((t) => ({ ...t, permission }))
4436
4477
  };
4437
4478
  });
4438
- addPendingPluginAllToolsUpdate(plugin, toolNames, enabled);
4479
+ addPendingPluginAllToolsUpdate(plugin, toolNames, permission);
4439
4480
  updateServerStateCache({ plugins: updatedPlugins });
4440
- sendServerRequest("config.setAllToolsEnabled", { plugin, enabled }).then((result) => {
4481
+ sendServerRequest("config.setAllToolsPermission", { plugin, permission }).then((result) => {
4441
4482
  removePendingPluginAllToolsUpdate(plugin, toolNames);
4442
4483
  sendResponse(result);
4443
4484
  }).catch((err2) => {
@@ -4450,7 +4491,7 @@ var handleBgSetAllToolsEnabled = (message, sendResponse) => {
4450
4491
  ...p,
4451
4492
  tools: p.tools.map((t) => ({
4452
4493
  ...t,
4453
- enabled: originalToolStates.get(t.name) ?? t.enabled
4494
+ permission: originalToolStates.get(t.name) ?? t.permission
4454
4495
  }))
4455
4496
  };
4456
4497
  });
@@ -4458,104 +4499,26 @@ var handleBgSetAllToolsEnabled = (message, sendResponse) => {
4458
4499
  sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
4459
4500
  });
4460
4501
  };
4461
- var handleBgSetToolsEnabled = (message, sendResponse) => {
4502
+ var handleBgSetPluginPermission = (message, sendResponse) => {
4462
4503
  const plugin = message.plugin;
4463
- const toolNames = message.tools;
4464
- const enabled = message.enabled;
4504
+ const permission = message.permission;
4465
4505
  const cache2 = getServerStateCache();
4466
4506
  const pluginEntry = cache2.plugins.find((p) => p.name === plugin);
4467
- const originalToolStates = /* @__PURE__ */ new Map();
4468
- if (pluginEntry) {
4469
- const toolNameSet2 = new Set(toolNames);
4470
- for (const t of pluginEntry.tools) {
4471
- if (toolNameSet2.has(t.name)) {
4472
- originalToolStates.set(t.name, t.enabled);
4473
- }
4474
- }
4475
- }
4476
- const toolNameSet = new Set(toolNames);
4477
- const updatedPlugins = cache2.plugins.map((p) => {
4478
- if (p.name !== plugin)
4479
- return p;
4480
- return {
4481
- ...p,
4482
- tools: p.tools.map((t) => toolNameSet.has(t.name) ? { ...t, enabled } : t)
4483
- };
4484
- });
4485
- addPendingPluginAllToolsUpdate(plugin, toolNames, enabled);
4507
+ const originalPermission = pluginEntry?.permission ?? "off";
4508
+ const updatedPlugins = cache2.plugins.map((p) => p.name === plugin ? { ...p, permission } : p);
4509
+ addPendingPluginPermissionUpdate(plugin, permission);
4486
4510
  updateServerStateCache({ plugins: updatedPlugins });
4487
- sendServerRequest("config.setToolsEnabled", {
4488
- plugin,
4489
- tools: toolNames,
4490
- enabled
4491
- }).then((result) => {
4492
- removePendingPluginAllToolsUpdate(plugin, toolNames);
4511
+ sendServerRequest("config.setPluginPermission", { plugin, permission }).then((result) => {
4512
+ removePendingPluginPermissionUpdate(plugin);
4493
4513
  sendResponse(result);
4494
4514
  }).catch((err2) => {
4495
- removePendingPluginAllToolsUpdate(plugin, toolNames);
4515
+ removePendingPluginPermissionUpdate(plugin);
4496
4516
  const currentCache = getServerStateCache();
4497
- const revertedPlugins = currentCache.plugins.map((p) => {
4498
- if (p.name !== plugin)
4499
- return p;
4500
- return {
4501
- ...p,
4502
- tools: p.tools.map((t) => ({
4503
- ...t,
4504
- enabled: originalToolStates.get(t.name) ?? t.enabled
4505
- }))
4506
- };
4507
- });
4517
+ const revertedPlugins = currentCache.plugins.map((p) => p.name === plugin ? { ...p, permission: originalPermission } : p);
4508
4518
  updateServerStateCache({ plugins: revertedPlugins });
4509
4519
  sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
4510
4520
  });
4511
4521
  };
4512
- var handleBgSetBrowserToolEnabled = (message, sendResponse) => {
4513
- const tool = message.tool;
4514
- const enabled = message.enabled;
4515
- const cache2 = getServerStateCache();
4516
- const originalEnabled = cache2.browserTools.find((bt) => bt.name === tool)?.enabled ?? !enabled;
4517
- const updatedBrowserTools = cache2.browserTools.map((bt) => bt.name === tool ? { ...bt, enabled } : bt);
4518
- addPendingBrowserToolUpdate(tool, enabled);
4519
- updateServerStateCache({ browserTools: updatedBrowserTools });
4520
- sendServerRequest("config.setBrowserToolEnabled", { tool, enabled }).then((result) => {
4521
- removePendingBrowserToolUpdate(tool);
4522
- sendResponse(result);
4523
- }).catch((err2) => {
4524
- removePendingBrowserToolUpdate(tool);
4525
- const currentCache = getServerStateCache();
4526
- const revertedBrowserTools = currentCache.browserTools.map((bt) => bt.name === tool ? { ...bt, enabled: originalEnabled } : bt);
4527
- updateServerStateCache({ browserTools: revertedBrowserTools });
4528
- sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
4529
- });
4530
- };
4531
- var handleBgSetAllBrowserToolsEnabled = (message, sendResponse) => {
4532
- const enabled = message.enabled;
4533
- const cache2 = getServerStateCache();
4534
- const toolNames = cache2.browserTools.map((bt) => bt.name);
4535
- const originalToolStates = /* @__PURE__ */ new Map();
4536
- for (const bt of cache2.browserTools) {
4537
- originalToolStates.set(bt.name, bt.enabled);
4538
- }
4539
- const updatedBrowserTools = cache2.browserTools.map((bt) => ({
4540
- ...bt,
4541
- enabled
4542
- }));
4543
- addPendingAllBrowserToolsUpdate(toolNames, enabled);
4544
- updateServerStateCache({ browserTools: updatedBrowserTools });
4545
- sendServerRequest("config.setAllBrowserToolsEnabled", { enabled }).then((result) => {
4546
- removePendingAllBrowserToolsUpdate(toolNames);
4547
- sendResponse(result);
4548
- }).catch((err2) => {
4549
- removePendingAllBrowserToolsUpdate(toolNames);
4550
- const currentCache = getServerStateCache();
4551
- const revertedBrowserTools = currentCache.browserTools.map((bt) => ({
4552
- ...bt,
4553
- enabled: originalToolStates.get(bt.name) ?? bt.enabled
4554
- }));
4555
- updateServerStateCache({ browserTools: revertedBrowserTools });
4556
- sendResponse({ error: err2 instanceof Error ? err2.message : String(err2) });
4557
- });
4558
- };
4559
4522
  var handleBgSearchPlugins = (message, sendResponse) => {
4560
4523
  const query = message.query;
4561
4524
  sendServerRequest("plugin.search", { query }).then((result) => {
@@ -4598,11 +4561,9 @@ var backgroundHandlers = /* @__PURE__ */ new Map([
4598
4561
  ["ws:state", handleWsState],
4599
4562
  ["ws:message", handleWsMessage],
4600
4563
  ["bg:getFullState", handleBgGetFullState],
4601
- ["bg:setToolEnabled", handleBgSetToolEnabled],
4602
- ["bg:setAllToolsEnabled", handleBgSetAllToolsEnabled],
4603
- ["bg:setToolsEnabled", handleBgSetToolsEnabled],
4604
- ["bg:setBrowserToolEnabled", handleBgSetBrowserToolEnabled],
4605
- ["bg:setAllBrowserToolsEnabled", handleBgSetAllBrowserToolsEnabled],
4564
+ ["bg:setToolPermission", handleBgSetToolPermission],
4565
+ ["bg:setAllToolsPermission", handleBgSetAllToolsPermission],
4566
+ ["bg:setPluginPermission", handleBgSetPluginPermission],
4606
4567
  ["bg:searchPlugins", handleBgSearchPlugins],
4607
4568
  ["bg:installPlugin", handleBgInstallPlugin],
4608
4569
  ["bg:removePlugin", handleBgRemovePlugin],
@@ -4610,7 +4571,6 @@ var backgroundHandlers = /* @__PURE__ */ new Map([
4610
4571
  ["plugin:logs", handlePluginLogs],
4611
4572
  ["tool:progress", handleToolProgress],
4612
4573
  ["sp:confirmationResponse", handleSpConfirmationResponse],
4613
- ["sp:confirmationTimeout", handleSpConfirmationTimeout],
4614
4574
  ["port-changed", handlePortChanged]
4615
4575
  ]);
4616
4576
  var EXTENSION_ONLY_TYPES = /* @__PURE__ */ new Set([
@@ -4618,18 +4578,15 @@ var EXTENSION_ONLY_TYPES = /* @__PURE__ */ new Set([
4618
4578
  "ws:state",
4619
4579
  "ws:message",
4620
4580
  "bg:getFullState",
4621
- "bg:setToolEnabled",
4622
- "bg:setAllToolsEnabled",
4623
- "bg:setToolsEnabled",
4624
- "bg:setBrowserToolEnabled",
4625
- "bg:setAllBrowserToolsEnabled",
4581
+ "bg:setToolPermission",
4582
+ "bg:setAllToolsPermission",
4583
+ "bg:setPluginPermission",
4626
4584
  "bg:searchPlugins",
4627
4585
  "bg:installPlugin",
4628
4586
  "bg:removePlugin",
4629
4587
  "bg:updatePlugin",
4630
4588
  "offscreen:getLogs",
4631
4589
  "sp:confirmationResponse",
4632
- "sp:confirmationTimeout",
4633
4590
  "port-changed"
4634
4591
  ]);
4635
4592
  var initBackgroundMessageHandlers = () => {