Chuyển đến nội dung chính

dsh-desktop-web-access

Đã xác minh

dsh-desktop-web-access · v0.1.0 · MIT · Giao diện web

DSH desktop plugin: surface and copy the Web GUI launch-token URL (loopback + LAN) so the desktop app's built-in Web server can be opened from another device.

Cài đặt

dsh plugin add dsh-desktop-web-access

Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.

Mã nguồn

Phát hành lên npm mà không có repository công khai. Hãy kiểm tra nội dung package trước khi cài.

Thẻ

Tác giả

Readme

dsh-desktop-web-access

一个 DSH 插件:把桌面端 Web 服务的启动令牌找出来,并放到你能复制到的地方。

关于包名:npm 上的 dsh-web-access 已被另一个项目占用(NexusAgentX/dsh-web-access,做的是 ctx.web 搜索/抓取,与本插件无关),所以本包注册为 dsh-desktop-web-access。

要解决的问题

DeepSeek Harness 桌面端启动时会拉起内置 Web 服务(默认 127.0.0.1:19387)。这个服务要求带启动令牌才能打开:

http://127.0.0.1:19387/?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

问题在于:dsh-web-app 确实把这行 URL 打印到了标准输出,但桌面端是 GUI 程序、stdout 没有人看得到,日志里也没有。于是令牌拿不到 —— 而后面这个 Web 界面却会返回 401,提示 dsh web authentication required。

令牌每次启动都会重新随机生成,并且只能用来换取一次 cookie(cookie 有效期 30 天,绑定到 host:port,换取成功后浏览器就不再需要令牌了)。

插件做了什么

位置 作用
设置 → Web 访问 完整链接、单独的令牌、局域网/虚拟网卡地址、当前绑定与可达性说明,每项都能单独复制或直接打开
web_access_url 工具 直接问 Agent「给我 Web 访问链接」即可,URL 出现在对话里就能复制
$DSH_HOME/web-access-url.txt 便利文件;插件激活时写入,之后每次读取链接都会刷新

复制按钮把文本放进当前浏览器所在设备的剪贴板里 —— 所以哪怕你是从另一台设备远程连进来的,复制到的也是那台设备的剪贴板,这正是远程场景需要的。

为什么不放侧边栏:侧边栏底部行动区、品牌标记与名称、shell.leading 都是单占用座位,且已被官方 wordmark 与账号菜单占据;在那里常驻一个图标,等于为"每次启动只查一次"的东西付每天的视觉成本。所以链接只放在设置页里,需要时打开即可。

实现要点

  • 令牌本身不落盘(便利文件除外,可用 writeFile: false 关闭)、不进页面:宿主半边通过 ctx.connection.authenticatedUrl() 重新推导出与桌面端完全一致的 URL,再经一条受认证保护的路由提供出去:

    GET /x-dsh-web-access/url   ->   JSON
    
  • 该路由用 ctx.connection.admit() 做与 /api 相同的 Host/Origin 围栏 + 浏览器 cookie 校验,未认证请求只会得到 401,不会看到令牌。插件也不会把令牌注入 index.html。

  • token 字段独立给出,方便只要令牌本身的场景。

安装

从 npm(发布后):

# 在桌面端 profile 目录($DSH_HOME/profiles/desktop)里
pnpm add dsh-desktop-web-access

或者更省事:在桌面端 Web GUI 里让 Agent 用 plugin_manager → install_bundle 装(本地目录、tarball、npm 包名都行)。

本地开发时用 link: 即可,源码改动无需重装:

pnpm add link:/path/to/dsh-desktop-web-access

然后把包名加进 package.json 的 dsh.profile.bundles(plugin_manager 会自动做这一步)。本仓库的 cordis.patch.yml 负责把宿主半边挂到 Loader 上,随包一起安装。

安装后是热生效的,无需重启桌面端。

改宿主半边(src/host.js)后需要重启桌面端:客户端包每次请求都从磁盘重新读取,所以 lib/client.js 的改动刷新页面即可;但宿主半边由 Loader 按模块缓存,实测连 disable/enable 都不会重新执行 —— 想立刻看到宿主改动,重启桌面端最稳。

从另一台设备访问

插件会明确告诉你当前是否可达:

  • 绑定 0.0.0.0(dsh web --bind 0.0.0.0,或桌面端 profile 里配置)→ 直接用「局域网链接」,同一网络的设备打开即可。

  • 只绑定 127.0.0.1(桌面端默认)→ 任何设备都无法通过 IP 直接访问。需要先做端口转发,例如:

    ssh -L 19387:127.0.0.1:19387 <user>@<跑着桌面端的机器>
    

    然后在另一台设备上打开插件给出的那条 127.0.0.1:19387 链接即可(令牌照常有效)。

安全说明

  • 令牌等同于登录凭据:拿到它的任何人只要能连到这个端口,就能拿到 30 天的 cookie。请只发给你信任的设备/通道。
  • 令牌随进程重启变化;旧令牌在新一次启动后立即失效。
  • 插件不写日志、不上传任何东西;唯一写入的文件是 $DSH_HOME/web-access-url.txt(可用配置 writeFile: false 关闭,或用 file 指定路径)。

配置

宿主半边支持三个可选配置项:

- id: dsh-desktop-web-access
  name: dsh-desktop-web-access
  config:
    tool: true          # 注册 web_access_url 工具(默认 true)
    writeFile: true     # 写 $DSH_HOME/web-access-url.txt(默认 true)
    file: ""            # 自定义便利文件路径

配置项之外的说明

  • 插件只依赖 webServer 与 connection 两个服务,不引入任何 npm 依赖。
  • 浏览器半边只 require("react")(平台模块表已提供),无额外 external。

构建

node build.mjs

产出两个文件:

  • lib/client.js —— 浏览器半边(CJS + ModuleLoader 握手;由 Web 宿主作为 dsh-desktop-web-access 这一行提供给浏览器,实际请求形如 /plugins/??dsh-desktop-web-access/client.js&rev=...)
  • lib/index.js —— 宿主半边(由 src/host.js 打包而来)

build.mjs 从 package.json 的 name 推导插件标识,并同时写进 Loader 行名、name 导出与 ModuleLoader bundle id —— 改名时只需改 package.json,三处不会走偏。发布前 prepublishOnly 会自动构建。

License

MIT