dsh-site-bridge 0.7.2 → 0.7.4
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/extension/manifest.json +1 -1
- package/extension/popup.js +15 -4
- package/extension/sw.js +24 -11
- package/lib/index.js +4 -4
- package/package.json +1 -1
package/extension/manifest.json
CHANGED
package/extension/popup.js
CHANGED
|
@@ -206,12 +206,23 @@ async function currentBrowserTab() {
|
|
|
206
206
|
{ active: true, currentWindow: true }
|
|
207
207
|
]
|
|
208
208
|
for (const scope of scopes) {
|
|
209
|
+
let tabs = []
|
|
209
210
|
try {
|
|
210
|
-
|
|
211
|
-
if (!Array.isArray(tabs) || tabs.length === 0) continue
|
|
212
|
-
return tabs.find((tab) => scheme(tab) === 'web') ?? tabs[0]
|
|
211
|
+
tabs = await chrome.tabs.query(scope)
|
|
213
212
|
} catch {
|
|
214
|
-
|
|
213
|
+
continue
|
|
214
|
+
}
|
|
215
|
+
if (!Array.isArray(tabs) || tabs.length === 0) continue
|
|
216
|
+
const ordered = [...tabs.filter((tab) => scheme(tab) === 'web'), ...tabs.filter((tab) => scheme(tab) !== 'web')]
|
|
217
|
+
for (const tab of ordered) {
|
|
218
|
+
// Ask Chrome whether this tab is readable at all: tabs in app windows of
|
|
219
|
+
// other extensions are listed but cannot be touched.
|
|
220
|
+
try {
|
|
221
|
+
await chrome.tabs.get(tab.id)
|
|
222
|
+
return tab
|
|
223
|
+
} catch {
|
|
224
|
+
// not ours to read — try the next candidate
|
|
225
|
+
}
|
|
215
226
|
}
|
|
216
227
|
}
|
|
217
228
|
return null
|
package/extension/sw.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* host, which redacts and never writes it to disk.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
const EXT_VERSION =
|
|
18
|
+
const EXT_VERSION = chrome.runtime.getManifest().version
|
|
19
19
|
const NET_CAP = 600
|
|
20
20
|
// Bodies are kept up to this size in the worker, then marked as truncated.
|
|
21
21
|
// Raise it per machine with chrome.storage.local.set({ maxBodyChars }): the
|
|
@@ -297,7 +297,11 @@ async function claimTab(tabId, attachedBy = 'agent') {
|
|
|
297
297
|
} catch (error) {
|
|
298
298
|
// Chrome refuses to read pages of other extensions and its own service
|
|
299
299
|
// pages; say that in words a person can act on.
|
|
300
|
-
|
|
300
|
+
const detail = String(error?.message ?? error)
|
|
301
|
+
const hint = /chrome-extension:\/\//.test(detail)
|
|
302
|
+
? ' Похоже, вкладка открыта в окне-приложении другого расширения — откройте её как обычную вкладку.'
|
|
303
|
+
: ''
|
|
304
|
+
throw new Error(`эту вкладку нельзя подключить: ${detail}${hint}`)
|
|
301
305
|
}
|
|
302
306
|
if (!/^https?:|^file:/.test(tab.url ?? '')) {
|
|
303
307
|
const scheme = String(tab.url ?? '').split(':')[0] || 'неизвестная схема'
|
|
@@ -1502,17 +1506,26 @@ async function dispatch(op, args) {
|
|
|
1502
1506
|
return { ok: true, version: EXT_VERSION }
|
|
1503
1507
|
case 'tabs.list': {
|
|
1504
1508
|
const tabs = await chrome.tabs.query({})
|
|
1509
|
+
// Window type explains why a tab can be listed but not read: app windows
|
|
1510
|
+
// belong to another extension, and Chrome refuses access to them.
|
|
1511
|
+
const windows = await chrome.windows.getAll({}).catch(() => [])
|
|
1512
|
+
const windowType = new Map(windows.map((window) => [window.id, window.type ?? 'normal']))
|
|
1505
1513
|
const list = tabs
|
|
1506
1514
|
.filter((tab) => /^https?:|^file:/.test(tab.url ?? ''))
|
|
1507
|
-
.map((tab) =>
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1515
|
+
.map((tab) => {
|
|
1516
|
+
const type = windowType.get(tab.windowId) ?? 'unknown'
|
|
1517
|
+
return {
|
|
1518
|
+
id: tab.id,
|
|
1519
|
+
title: tab.title,
|
|
1520
|
+
url: tab.url,
|
|
1521
|
+
active: tab.active,
|
|
1522
|
+
windowId: tab.windowId,
|
|
1523
|
+
windowType: type,
|
|
1524
|
+
readable: type === 'normal',
|
|
1525
|
+
attached: state.sessions.has(tab.id),
|
|
1526
|
+
target: tab.id === state.activeTabId
|
|
1527
|
+
}
|
|
1528
|
+
})
|
|
1516
1529
|
await evt('tabs', { tabs: list })
|
|
1517
1530
|
return { tabs: list }
|
|
1518
1531
|
}
|
package/lib/index.js
CHANGED
|
@@ -332,10 +332,10 @@ export function apply(ctx, config) {
|
|
|
332
332
|
}
|
|
333
333
|
const result = await instance.enqueue('tabs.list', {}, { timeout: 20000 })
|
|
334
334
|
const tabs = Array.isArray(result?.tabs) ? result.tabs : []
|
|
335
|
-
const lines = tabs.map(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
)
|
|
335
|
+
const lines = tabs.map((tab) => {
|
|
336
|
+
const window = tab.windowType && tab.windowType !== 'normal' ? ` [окно: ${tab.windowType}, недоступно]` : ''
|
|
337
|
+
return `${tab.target ? '*' : tab.attached ? '+' : ' '} [${tab.id}] ${tab.title || '(без названия)'} — ${tab.url}${window}`
|
|
338
|
+
})
|
|
339
339
|
return ok(
|
|
340
340
|
tabs.length === 0
|
|
341
341
|
? 'Нет доступных вкладок (нужны http(s)/file://).'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-site-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "Chrome/Edge MV3 bridge for DeepSeek Harness: capture page markup (DOM, styles, selectors) and BFF traffic (xhr/fetch with headers and bodies) into a workspace snapshot bundle, drive the page with trusted CDP input, and verify injected scripts. Authorization never leaves the browser and is never written to disk.",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"type": "module",
|