dsh-site-bridge 0.7.4 → 0.8.0

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.
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "default_locale": "en",
4
4
  "name": "__MSG_appName__",
5
- "version": "0.7.4",
5
+ "version": "0.8.0",
6
6
  "description": "__MSG_appDesc__",
7
7
  "minimum_chrome_version": "116",
8
8
  "permissions": [
package/extension/sw.js CHANGED
@@ -254,7 +254,11 @@ async function attach(tabId, attachedBy = 'agent') {
254
254
  await evt('active', { tabId })
255
255
  return existing.target
256
256
  }
257
- await chrome.debugger.attach({ tabId }, '1.3')
257
+ try {
258
+ await chrome.debugger.attach({ tabId }, '1.3')
259
+ } catch (error) {
260
+ throw new Error(`chrome.debugger.attach отказал: ${String(error?.message ?? error)}`)
261
+ }
258
262
  await chrome.debugger.sendCommand({ tabId }, 'Network.enable', {
259
263
  maxTotalBufferSize: 64_000_000,
260
264
  maxResourceBufferSize: 16_000_000,
@@ -1581,6 +1585,41 @@ async function dispatch(op, args) {
1581
1585
  if (tab.windowId != null) await chrome.windows.update(tab.windowId, { focused: true }).catch(() => {})
1582
1586
  return { focused: session.tabId }
1583
1587
  }
1588
+ case 'tab.diagnose': {
1589
+ const id = Number(args.tabId)
1590
+ if (!Number.isFinite(id)) throw new Error('нужен tabId')
1591
+ const info = await chrome.tabs.get(id).catch((error) => ({ error: String(error?.message ?? error) }))
1592
+ const windows = await chrome.windows.getAll({}).catch(() => [])
1593
+ const window = windows.find((item) => item.id === info?.windowId) ?? null
1594
+ const targets = await chrome.debugger.getTargets().catch(() => [])
1595
+ const mine = targets
1596
+ .filter((target) => target.tabId === id)
1597
+ .map((target) => ({
1598
+ id: target.id,
1599
+ type: target.type,
1600
+ url: String(target.url ?? '').slice(0, 300),
1601
+ title: String(target.title ?? '').slice(0, 120),
1602
+ attached: target.attached === true
1603
+ }))
1604
+ return {
1605
+ tab: info
1606
+ ? {
1607
+ id: info.id,
1608
+ url: String(info.url ?? '').slice(0, 300),
1609
+ pendingUrl: String(info.pendingUrl ?? '').slice(0, 300),
1610
+ title: String(info.title ?? '').slice(0, 120),
1611
+ status: info.status,
1612
+ active: info.active,
1613
+ discarded: info.discarded,
1614
+ windowId: info.windowId,
1615
+ index: info.index
1616
+ }
1617
+ : { error: info?.error },
1618
+ window: window ? { id: window.id, type: window.type, state: window.state } : null,
1619
+ targets: mine,
1620
+ targetCount: targets.length
1621
+ }
1622
+ }
1584
1623
  case 'snapshot.compact': {
1585
1624
  const session = requireSession(args.tabId)
1586
1625
  const { result } = await cdp('Runtime.evaluate', {
package/lib/index.js CHANGED
@@ -263,7 +263,7 @@ export function apply(ctx, config) {
263
263
  'ПРАВИЛО: подключать вкладку, которую пользователь не подключал сам, можно только с его явного ' +
264
264
  'разрешения. Без confirmed:true вызов claim отклоняется — сначала спросите пользователя.',
265
265
  {
266
- action: { type: 'string', description: 'list | claim | use | release | open | close | focus' },
266
+ action: { type: 'string', description: 'list | claim | use | release | open | close | focus | diagnose' },
267
267
  tabId: { type: 'number', description: 'id вкладки для claim / use / release / focus / close (из action=list)' },
268
268
  url: { type: 'string', description: 'адрес для action=open (по умолчанию about:blank)' },
269
269
  confirmed: {
@@ -306,6 +306,12 @@ export function apply(ctx, config) {
306
306
  await instance.enqueue('tab.focus', { tabId }, { timeout: 20000 })
307
307
  return ok(`Вкладка ${tabId} на переднем плане.`, { tabId })
308
308
  }
309
+ if (action === 'diagnose') {
310
+ const tabId = Number(args.tabId ?? instance.state().activeTabId)
311
+ if (!Number.isFinite(tabId)) throw new Error('нужен tabId')
312
+ const info = await instance.enqueue('tab.diagnose', { tabId }, { timeout: 20000 })
313
+ return ok(JSON.stringify(info, null, 2), { diagnose: info })
314
+ }
309
315
  if (action === 'claim' || action === 'use' || action === 'release') {
310
316
  const tabId = Number(args.tabId)
311
317
  if (!Number.isFinite(tabId)) throw new Error(`tabId is required for action=${action}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-site-bridge",
3
- "version": "0.7.4",
3
+ "version": "0.8.0",
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",