dsh-browser-takeover
Manifest validBrowser takeover for sign-in-gated sites: keeps a list of addresses that need a login (URL and date only, no credentials), answers before a visit whether an address is already on it, reports whether t
浏览器网址接管 · dsh-browser-takeover
让 DSH 里的模型在你已经登录的浏览器里走过去:打开网址、按页面上的可见文字点一个入口; 同时维护一份「要登录的网址」清单——Agent 访问网址前先查这份清单,清单里的优先走这个插件。
0.9.1 修了什么
- GitHub 登录后仍显示"未登录":原来的登录判定只认学习通/B 站那套 cookie 名字
(
SESSDATA、JSESSIONID、UID…),GitHub 用的是user_session/logged_in/dotcom_user, 一个都不在白名单里。现在白名单补齐了 GitHub、Google、Microsoft、知乎、微博等常见名字, 并加了一条通用规则兜底。 - 判定分两档:命中已知名字 →
confidence: 'certain'(界面显示"已登录"); 只命中通用规则(名字里有 session / sso / auth / token / ticket 且值不为空)→'likely'(界面显示"可能已登录",不冒充确定)。logged_in这类开关型 cookie 按值判断,logged_in=no不算登录。 - 反例也钉住了:GitHub 未登录时同样有
_gh_sess,所以通用规则刻意不收sess, 否则会把没登录的 GitHub 说成"可能已登录"。
0.9.0 改了什么
- 清单从空开始:不再预置任何网址,也不读别的插件留下的
video-storyboard-sites.json。 装好之后清单是空的,要加什么由你自己加(设置页,或web_open({ …, remember: true }))。 - CDP 收成一个小模块
src/cdp.js:只留这个插件真正用到的几件事——找页面目标、 在页面/每个 iframe 上下文里求值、读 cookie、回答端口状态、按端口拉起浏览器。 视频时代的位置读取、封面/转码 cookie 导出等全部删掉。 - 浏览器状态只有四种:
open(端口已开)/closed(端口不通)/unconfigured(没配端口)/error。 设置页不再出现"页面里没有视频"这类词。 - 端口只认
~/.dsh/browser.json(不再读video.json)。 - 许可证正文保留,版权声明行已删除。
0.8.0 新增了什么
web_sites:访问网址前先查一次清单——这条地址存过没有、那个浏览器此刻登录着没有。 零副作用,不启动浏览器、不打开页面。web_open带上判断:返回里始终有site(清单命中:完全一致 / 同主机 / 同域名) 与signIn(登录态);新参数remember先记进清单再打开,launch端口没开就自己拉起浏览器。- 系统提示里的约定:Agent 访问网址时会先
web_sites,清单里的用web_open, 不用web_fetch抓 HTML 顶替(抓不到登录后的内容)。 - 清单匹配独立成
src/lookup.js(纯函数),登录态判断抽到src/session.js; 新增test/下的单元测试。升级后需重启一次 DSH Desktop,工具与提示词才会重新组装。
0.9.2 做了什么
把登录判定表从"认得几个站点"扩成三层表,覆盖市面上常见平台、框架与单点登录:
| 层 | 含义 | 界面 | 例子 |
|---|---|---|---|
| 身份 cookie | 只有登录后才出现 | 已登录 | user_session · SESSDATA · BDUSS · z_c0 · _tb_token_ · pt_key · li_at · ESTSAUTH · KEYCLOAK_IDENTITY · __Secure-next-auth.session-token |
| 框架会话 | 匿名访客也会拿到 | 可能已登录 | PHPSESSID · JSESSIONID · laravel_session · connect.sid · MoodleSession · sid |
| 匿名噪音 | 与登录无关,永不计数 | 不计入 | _gh_sess · csrftoken · _ga · _hjSessionUser_* · AWSALB · NID · datr · color_mode |
| 兜底规则 | 名字含 session / sso / auth / token / ticket… 且值不短 | 可能已登录 | 表里没有的站点靠它 |
表在 src/session-cookies.js,一个名字一行;遇到"登录了却显示未登录",
把该站的 cookie 名字加进 IDENTITY_COOKIES 即可(npm test 会顺手验证没把别人带歪)。
功能
| 能力 | 入口 | 说明 |
|---|---|---|
| 查清单 | 工具 web_sites | 零副作用:这条网址存过没有、那个浏览器此刻登录着没有。不启动浏览器、不打开页面 |
| 页面导航 / 按文字点击 | 工具 web_open | 在带调试端口的浏览器里打开地址,按可见文字点一个元素;会搜所有 iframe |
| 网址清单 | 设置 → 浏览器网址接管 | 只存 URL 与添加时间,不存账号密码 |
| 登录状态 | 同上 | 依据该站点的会话 cookie 名字判断(三层表 + 兜底规则),cookie 的值不离开宿主进程 |
| 打开登录页 | 同上 | 端口开着就开新标签,没开就带调试参数启动浏览器 |
一次调用最多点一个元素;不做循环点击、不批量爬取。
Agent 访问网址的顺序
插件往系统提示里写了一段约定(src/prompt.js),所以「去访问某个网址」时 Agent 会:
- 先调
web_sites({ url })—— 零成本,回答这条网址在不在清单里; - 在清单里(
saved: true,或hostSite命中同一站点)→ 用web_open打开, 而不是web_fetch抓 HTML(抓不到登录后的内容); - 清单里没有 → 也优先
web_open;需要登录的站点先让你在那个窗口里登录一次, 再用remember: true记进清单,下次就自动算"清单里的网址"。
web_open 的返回里一直带着这些判断,所以即使 Agent 直接开了工具,也看得到
「这条网址存过没有、登录着没有」:
{
"ok": true,
"saved": true,
"site": {
"asked": "https://hdu.fanya.chaoxing.com/portal",
"saved": true,
"match": "exact",
"hostSite": null,
"domainSite": null,
"note": "清单里有这条网址(…)——用 web_open 在插件浏览器里打开,那里是用户已登录的会话。"
},
"signIn": { "conclusive": true, "signedIn": true, "sessionCookieNames": ["JSESSIONID"] }
}
匹配规则:完全一样 > 同一主机(登录态同样适用)> 同注册域名(只作提示)。
比较时忽略 www.、末尾斜杠、query 和 hash;差异会原样回显,不替你拍板。
安装
git clone git@github.com:L1818346/dsh-browser-takeover.git
cd dsh-browser-takeover
node scripts/install-dev.mjs # 用 junction 挂进 desktop profile 并注册 bundle
然后重启 DSH Desktop(插件树与系统提示都在进程启动时组装;工具与提示词的改动 不重启不会生效)。装好之后清单是空的,没有任何预置网址——第一条要你自己加。
要求:
- Node.js ≥ 20
- Edge 或 Chrome(要能开
--remote-debugging-port,即 CDP)
浏览器准备
插件不会读你的主浏览器 profile —— Chromium 136 起明确禁止在默认 profile 上开调试端口
(官方说明),而换路径去看同一份
profile 又会因为 App-Bound Encryption 拿不到已登录的 cookie。所以它要的是一只带调试端口
的独立窗口,默认端口 9333:
scripts\start-edge-debug.cmd
脚本用 ~/.dsh/edge-watch 作为独立 profile 启动 Edge,并打开调试端口。
在这个窗口里登录一次,之后插件都复用这份登录态;你平时的 Edge 可以照常开着。
也可以自己起:
msedge.exe --remote-debugging-port=9333 --user-data-dir="%USERPROFILE%\.dsh\edge-watch"
配置
~/.dsh/browser.json:
{
"browserPort": 9333,
"launchBrowser": true
}
| 键 | 默认 | 说明 |
|---|---|---|
browserPort | 无 | 调试端口;工具里显式传 browserPort 优先,其次这个文件,最后落到 9333 |
launchBrowser | false | 清单里的站点在端口没开时,是否允许插件自己拉起浏览器。打开后"优先走插件"才真的不用你动手 |
端口只该有一个说法。
用法
清单初始是空的:第一条网址要么在设置页点「添加」,要么打开时顺手用 remember: true 记下来。
// 1. 先查:这条网址存过没有?(零成本)
web_sites({ url: "https://hdu.fanya.chaoxing.com/portal" })
// 2. 再开:清单里的网址直接走插件浏览器(带登录态)
web_open({ url: "https://hdu.fanya.chaoxing.com/portal", match: "学习空间" })
// 3. 需要登录的新站点:先登录,再记进清单
web_open({ url: "https://example.com/app", match: "我的课程", remember: true })
// 4. 端口没开时,让插件自己拉起浏览器再打开
web_open({ url: "https://example.com/app", launch: true })
// 5. 先看看页面把入口叫什么(不点击)
web_open({ match: "国家安全教育", listOnly: true })
// 6. 同名元素不止一个时用 index 选
web_open({ match: "国家安全教育", index: 0 })
匹配规则:完全相同 > 以它开头 > 包含;<a> 链接在平手时优先。
匹配不到时会把候选列出来,而不是猜一个。
数据与隐私
- 网址清单在
~/.dsh/browser-takeover-sites.json,只存 URL 和时间戳;初始为空, 插件不预置、也不从别的文件名里捞。 - 不读、不填账号密码输入框;不导出 cookie 的值。设置页和
web_sites只回显会话 cookie 的 名字(如SESSDATA、user_session)。唯一的例外是logged_in这类开关型 cookie: 只拿yes/no做判断,值本身不外传。 - 登录状态分三档:已登录(命中身份 cookie)/ 可能已登录(框架会话或兜底规则)/ 未登录;端口没开时是「无法判断」,而不是冒充「未登录」。判定表在 src/session-cookies.js,名字可以自己往里加。
故障排查
| 现象 | 原因 | 处理 |
|---|---|---|
no-debug-port | 浏览器没带调试参数启动 | 跑 scripts\start-edge-debug.cmd,或 web_open({ …, launch: true }) |
| Agent 没先查清单 | 插件是在加这段提示之前加载的 | 重启 DSH Desktop |
| 设置页显示「端口未开」 | 同上,或端口不是 9333 | 检查 browser.json |
| 点了没反应 | 站点用 window.open,被弹窗拦截 | 对 <a href> 插件会直接导航;其余元素只能真点 |
| 登录状态「无法判断」 | 浏览器没开,读不到 cookie | 先启动调试浏览器 |
| 明明登录了却显示「未登录」 | 该站的登录 cookie 名字不在 src/session-cookies.js 的 IDENTITY_COOKIES 里 | 把名字加进那个数组;兜底规则一般会先兜成「可能已登录」 |
| 显示「可能已登录」 | 只命中框架会话(PHPSESSID 等)或兜底规则 | 一般就是登录了;想更确定就把名字加进 IDENTITY_COOKIES |
| 没登录却说「已登录」 | 某个匿名 cookie 被当成了身份 cookie | 把名字挪进 ANONYMOUS_COOKIES,并补一条测试 |
开发
npm run check # 逐文件 node --check(含 client.js 与 test/)
npm test # node --test:清单匹配与系统提示段的单元测试
npm run smoke # 用假的 defineTool 跑一遍 apply(),并真的执行两个工具(不碰浏览器)
npm test 会 fork 子进程;如果你的环境禁止 fork(某些沙箱),直接跑
node test/lookup.test.mjs 也能执行(同一进程内)。
许可
MIT。条款见 LICENSE。
Versions
| Latest version | Published | Size |
|---|---|---|
| 0.9.2 | — | — |
Comments
Loading…
From the same category
DeepSeek Harness plugin for Reactive Resume: bridges your resumes and job applications into a Harness session over MCP.
★ 41.7k
↓ 215/wk
MIT
Aug 24, 2026
dsh plugin --profile web add dsh-plugin-reactive-resumeby dsh-market
The plugin market inside DeepSeek Harness — browse, search, one-click install · DSH 可视化插件市场
★ 10.1k
↓ 361.7k/wk
MIT
TypeScript
Nov 1, 2026
dsh plugin --profile web add dshmarketby Tencent
Let AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.
★ 9.9k
↓ 12.3k/wk
MIT
TypeScript
Nov 1, 2026
dsh plugin --profile terminal add @wxg-prc-cpg/browser-skill-dsh-pluginby yjh051108
dsh-routing-suite — injector + router-standard kit: install the runtime injector first, then the task-aware reasoning-mode router preset (measured P1-P23).
★ 7k
MIT
JavaScript
Sep 18, 2026
dsh plugin --profile web add @dsh-external/dsh-super-injectorby superdesigndev
OpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn
★ 7k
NOASSERTION
Python
Nov 1, 2026
dsh plugin --profile web add treg-dshby Q00
Agent OS: the agent gets smarter on its own. We just hold the line: Interview-gated, staged evaluation, budgeted evolution loop. MCP server, 14 runtimes: Claude Code, Codex CLI, Gemini CLI, OpenCode,
★ 6.3k
MIT
Python
Nov 1, 2026