dsh-inner-browser-use 0.11.44 → 0.13.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.
package/locale/en.json CHANGED
@@ -1,26 +1,15 @@
1
1
  {
2
2
  "meta": {
3
- "title": "Inner Browser Use",
4
- "description": "Drive the sidebar browser itself: a visible agent pointer, click and type, and a two-way channel to the chat."
3
+ "title": "Background browser",
4
+ "description": "A browser the agent drives behind the chat, mirrored into the right column."
5
5
  },
6
- "type.label": "Inner browser",
7
- "guide.title": "Inner browser",
8
- "guide.description": "Let the assistant drive a page in the sidebar",
9
- "phase.opening": "Opening…",
10
- "phase.ready": "Connected",
11
- "phase.closed": "Closed",
12
- "error.desktopOnly": "Requires the desktop app",
13
- "error.lease": "Could not open the browser panel",
14
- "pane.address": "Type an address",
15
- "error.background": "This chat is not open on screen — open it to drive its page.",
16
- "phase.act.navigate": "Opening the page",
17
- "phase.act.click": "Clicking",
18
- "phase.act.read": "Reading the page",
19
- "phase.act.type": "Typing",
20
- "phase.act.scroll": "Scrolling",
21
- "phase.act.shot": "Taking an image",
22
- "phase.act.download": "Saving a file",
23
- "phase.act.upload": "Uploading",
24
- "phase.act.eval": "Working on the page",
25
- "phase.act.select": "Choosing"
6
+ "side.label": "Background browser",
7
+ "side.empty": "No page open",
8
+ "side.connecting": "Connecting…",
9
+ "side.failed": "The picture did not connect",
10
+ "side.back": "Back",
11
+ "side.forward": "Forward",
12
+ "side.reload": "Reload",
13
+ "side.address": "Enter an address",
14
+ "side.type": "Type here"
26
15
  }
package/locale/zh.json CHANGED
@@ -1,26 +1,15 @@
1
1
  {
2
2
  "meta": {
3
- "title": "内置浏览器",
4
- "description": "直接操作侧边栏里的浏览器:看得见的助手指针、点击与输入,以及与聊天互通的数据通道。"
3
+ "title": "后台浏览器",
4
+ "description": "助手在后台操作的浏览器,画面镜像到右栏。"
5
5
  },
6
- "type.label": "内置浏览器",
7
- "guide.title": "内置浏览器",
8
- "guide.description": "让助手在侧边栏里操作页面",
9
- "phase.opening": "正在打开…",
10
- "phase.ready": "已连接",
11
- "phase.closed": "已关闭",
12
- "error.desktopOnly": "需要在桌面版中使用",
13
- "error.lease": "无法打开浏览器面板",
14
- "pane.address": "输入网址",
15
- "error.background": "这个会话没在当前屏幕,切到它才能操作页面。",
16
- "phase.act.navigate": "正在打开页面",
17
- "phase.act.click": "正在点击",
18
- "phase.act.read": "正在读取页面",
19
- "phase.act.type": "正在输入",
20
- "phase.act.scroll": "正在滚动",
21
- "phase.act.shot": "正在截图",
22
- "phase.act.download": "正在下载",
23
- "phase.act.upload": "正在上传",
24
- "phase.act.eval": "正在操作页面",
25
- "phase.act.select": "正在选择"
6
+ "side.label": "后台浏览器",
7
+ "side.empty": "还没有打开的页面",
8
+ "side.connecting": "正在连接…",
9
+ "side.failed": "画面没有连上",
10
+ "side.back": "后退",
11
+ "side.forward": "前进",
12
+ "side.reload": "刷新",
13
+ "side.address": "输入地址",
14
+ "side.type": "输入文字"
26
15
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-inner-browser-use",
3
- "version": "0.11.44",
4
- "description": "Drive the DeepSeek Harness sidebar browser itself: a leased inner-browser tab with a visible agent pointer, click and type, and a two-way data channel to the chat.",
3
+ "version": "0.13.0",
4
+ "description": "An agent-owned Chromium sidecar mirrored into the DeepSeek Harness right column: the agent drives it, the person watches and can take the mouse, and logins survive restarts.",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "exports": {
@@ -13,10 +13,12 @@
13
13
  },
14
14
  "files": [
15
15
  "index.js",
16
+ "sidecar.js",
16
17
  "client.js",
17
18
  "locale/*.json",
18
19
  "cordis.patch.yml",
19
20
  "icon.svg",
21
+ "scripts/doctor.mjs",
20
22
  "docs/",
21
23
  "README.md",
22
24
  "README.zh.md",
@@ -28,8 +30,9 @@
28
30
  "dsh-plugin",
29
31
  "browser-use",
30
32
  "computer-use",
31
- "sidebar-browser",
32
- "webview",
33
+ "chrome",
34
+ "cdp",
35
+ "screencast",
33
36
  "deepseek"
34
37
  ],
35
38
  "engines": {
@@ -38,7 +41,8 @@
38
41
  },
39
42
  "scripts": {
40
43
  "test": "node --test test/*.test.mjs",
41
- "doctor": "node scripts/doctor.mjs"
44
+ "doctor": "node scripts/doctor.mjs",
45
+ "breadth": "node scripts/breadth.mjs"
42
46
  },
43
47
  "license": "MIT",
44
48
  "author": "regrevia",
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Report what the sidecar browser is doing right now: whether the Host answers,
4
+ * whether a Chromium is attached, which profile it uses, and whether that
5
+ * profile is outside the Host so logins outlive a restart. Reads only; nothing
6
+ * is started, attached, or closed.
7
+ *
8
+ * node scripts/doctor.mjs
9
+ */
10
+
11
+ import { execFile } from 'node:child_process'
12
+ import { existsSync, readFileSync } from 'node:fs'
13
+ import { homedir } from 'node:os'
14
+ import { join } from 'node:path'
15
+ import { promisify } from 'node:util'
16
+
17
+ const run = promisify(execFile)
18
+ const ROUTE = '/dsh-inner-browser-use'
19
+ const PROFILES = join(homedir(), '.dsh', 'inner-browser-use', 'chrome')
20
+
21
+ /**
22
+ * The Host picks its port each time it starts, so try the asked-for address
23
+ * first and then whatever the running app is listening on.
24
+ * @returns {Promise<string[]>} candidate addresses, without trailing slash.
25
+ */
26
+ async function addresses() {
27
+ const asked = (process.env.DSH_BRIDGE ?? '').trim().replace(/\/+$/, '')
28
+ const found = asked === '' ? [] : [asked]
29
+ found.push('http://127.0.0.1:60930')
30
+ try {
31
+ const { stdout } = await run('lsof', ['-nP', '-iTCP', '-sTCP:LISTEN', '-a', '-c', 'DeepSeek'], { timeout: 4_000 })
32
+ for (const line of String(stdout).split('\n')) {
33
+ const hit = /127\.0\.0\.1:(\d{4,5})\s/.exec(line)
34
+ if (hit === null) continue
35
+ const address = `http://127.0.0.1:${hit[1]}`
36
+ if (found.includes(address) === false) found.push(address)
37
+ }
38
+ } catch {
39
+ /* no lsof, or nothing listening: the default address is all that is left */
40
+ }
41
+ return found
42
+ }
43
+
44
+ let base = ''
45
+
46
+ /**
47
+ * @param {string} path - route under this plugin.
48
+ * @returns {Promise<any>} parsed body, or null when no address answers.
49
+ */
50
+ async function get(path) {
51
+ const tried = base === '' ? await addresses() : [base]
52
+ for (const address of tried) {
53
+ try {
54
+ const response = await fetch(address + path, { signal: AbortSignal.timeout(4_000) })
55
+ if (response.ok !== true) continue
56
+ base = address
57
+ return await response.json()
58
+ } catch {
59
+ /* the next address may be the one this app is on */
60
+ }
61
+ }
62
+ return null
63
+ }
64
+
65
+ const state = await get(`${ROUTE}/sidecar/state`)
66
+ console.log(`host ${state === null ? `not answering under ${ROUTE}` : base}`)
67
+ if (state === null) {
68
+ console.log(' start the app, or set DSH_BRIDGE to the app address')
69
+ process.exit(0)
70
+ }
71
+
72
+ console.log(`browser ${state.alive === true ? `attached, ${state.headless === true ? 'headless' : 'with a window'}` : 'not running'}`)
73
+ const profileDir = join(PROFILES, String(state.profile ?? ''))
74
+ console.log(`profile ${state.profile} in ${profileDir}`)
75
+ console.log(`stored ${existsSync(profileDir) ? 'on disk, so cookies and logins survive a restart' : 'not created yet'}`)
76
+ if (state.alive === true) {
77
+ console.log(`page ${String(state.title ?? '') === '' ? String(state.url ?? '') : state.title}`)
78
+ console.log(`viewers ${state.viewers} | frames ${state.frames} | pointer ${state.pointer === null ? 'none' : `${state.pointer.x},${state.pointer.y}`}`)
79
+ }
80
+
81
+ const portFile = join(profileDir, 'DevToolsActivePort')
82
+ if (existsSync(portFile)) {
83
+ const [port = '', path = ''] = readFileSync(portFile, 'utf8').trim().split('\n')
84
+ console.log(`control port ${port}, ${path.startsWith('/devtools/') ? 'endpoint file present' : 'endpoint file odd'}`)
85
+ } else {
86
+ console.log('control no DevToolsActivePort yet')
87
+ }
88
+
89
+ if (String(state.error ?? '') !== '') console.log(`error ${state.error}`)