前言¶
在 DSH(DeepSeek Harness)的对话区里,助手回复会包含大量仓库链接与裸 URL,普通浏览需要先复制、再在浏览器打开,再回到 DSH 找到右侧栏的浏览器标签页,流程较繁琐。本插件为这些链接补上悬停卡片与右侧栏打开能力,仅作用于对话正文,不干扰菜单、会话列表等其它区域。
插件定位¶
- 插件名:dsh-github-link
- 维护者:zengxiaolou
- 类型:DSH 插件
- 核心价值:把对话区内的 GitHub / GitLab / Gitee 仓库链接变成可悬停的信息卡片,点击在 DSH 右侧栏浏览器打开
核心功能¶
悬停卡片与信息展示¶
插件会在对话正文(包括 GenUI 块、工具卡片)内的 GitHub / GitLab / Gitee 链接上触发悬停,显示以下信息:
- 仓库全名与来源(GitHub / GitLab / Gitee)
- 公开 / 私有 / 归档标记
- 简介摘要(截断 3 行)
- 星标数、复刻数、开放议题数
- 主编程语言、许可证
- Topics 标签
- 最近活动
- 底部一行
git clone命令,一键复制
点击打开与行为区分¶
插件会拦截对话区内的部分点击,将其导向 DSH 右侧栏的内置浏览器:
- 对话区内 GenUI 块里的链接(带
data-genui属性) - 对话区内回复正文里的裸 URL(如
https://github.com/a/b)
对于普通 markdown 链接(由宿主渲染),插件不拦截,交还给宿主的 linkOpening 设置。
对话区外的链接(菜单、会话列表、工作区、右侧栏标签页)完全不受影响。
额外行为¶
Issue / PR / MR 卡片¶
当 URL 指向 issue、PR 或 MR 时,卡片会额外显示:
- 仓库全名
- 议题 / PR 编号
- 标题
- 状态(开启中 / 已关闭 / 已合并)
- 作者
示例:
https://github.com/facebook/react/issues/1
→ react/react · 议题 #1 · [已关闭] Run each test in its own <iframe> · 由 benjamn
右侧栏 PR 面板按钮¶
卡片底部会出现「在 DSH 打开 PR」按钮,但仅当以下条件同时满足时渲染:
- URL 为
github.com的 PR dsh-github-flow的github-prtab 已注册(通过sidebarRightTabs.get('github-pr')判定)
点击该按钮会调用:
sidebarRight.openTab('github-pr', { params: { repo, number } })
layout.openRightbar(true, false)
复制 clone 按钮¶
卡片底部会显示「复制 clone」按钮,行为为写入 git clone https://<host>/<fullName>.git 到剪贴板。
作用范围与限制¶
作用范围¶
- 只在对话正文里生效(
[data-conversation-content]) - 不装饰菜单、会话列表、左侧工作区树、右侧栏标签页里的链接
客户端生效¶
client 半通过页面 boot payload 注入,改完 client.js 后需要刷新 GUI 页面,新模块才会在下次 boot 注入。
Desktop 应用限制¶
右侧栏浏览器在 Desktop 应用中走 Electron <webview>,正常显示。如果用普通浏览器打开 dsh web 的地址,那里是 sandboxed <iframe>,github.com 会返回 x-frame-options: deny,页面被拦截,内容为空。此时点击仍算成功打开,但内容为空。
安装与启用¶
从插件市场安装:
dsh plugin add zengxiaolou/dsh-github-link
启用方式:
- client 半:刷新 GUI 页面
- host 半:在插件市场里把「GitHub 链接卡片」关一次再开,或重启 DSH
数据来源与缓存¶
主机映射¶
插件通过 /github-link/card?url=<encoded> 获取卡片数据,按主机分派上游:
| 主机 | 上游 | 认证方式 |
|---|---|---|
| github.com | api.github.com |
GITHUB_TOKEN / GH_TOKEN,否则用 gh auth token(60/h → 5000/h) |
| gitlab.com | gitlab.com/api/v4 |
匿名即可 |
| gitee.com | gitee.com/api/v5 |
匿名即可 |
缓存与限制¶
- 成功结果缓存 10 分钟,失败缓存 60 秒
- 缓存上限 400 条
- 只接受上述三个主机的仓库形 URL,忽略
/marketplace、/explore、/orgs等路径 - issue/PR 明细为 best-effort:拉不到时只显示仓库卡片,不导致整张卡片失败
- 拒绝
sec-fetch-site: cross-site请求,避免被其它网页当成查询代理
自检与调试¶
插件通过以下路由自检 client 半是否加载:
| 路由 | 用途 |
|---|---|
GET /github-link/status |
检查 client.loaded 是否为真、最近一次 hello 的时间/协议/UA、打开与回退计数、缓存大小 |
POST /github-link/hello |
client 半每次页面加载上报,带 location.protocol |
POST /github-link/event |
client 半在打开链接时上报 open 或 fallback |
示例:
curl -s http://127.0.0.1:50845/github-link/status | jq .
loaded 只认真正的页面(dsh-app: 或 http(s):),用 curl 直接 POST 不带 protocol 的 hello 会返回 loaded: false 并提示这是探测,不会被误判成已生效。
桌面壳与同源请求¶
Desktop 主窗口加载 dsh-app://app/,preload 在同源主框架下才暴露完整的 window.dshDesktop(protocolVersion: 1 + browser 桥)。侧栏浏览器据此选择 Electron <webview> 而不是 <iframe>,所以 github.com 的 x-frame-options: deny 不影响它。
插件的请求按这个前提解析,走 document.baseURI 的相对路径(github-link/card),由壳的非静态路径转发送到 Host,保持同源;不使用 __DSH_TRANSPORT__.streamBaseUrl(那是另一个 origin,会变成跨域 POST)。
卸载¶
在插件市场里停用或移除 dsh-github-link 即可;profile 只是把它软链到本目录。
生态背景¶
DSH 的设计理念是「一切皆插件」,社区目录是独立站点,与 DeepSeek / 幻方无官方从属关系。
适用场景与注意¶
- 适合需要在 DSH 对话区快速查看仓库信息、打开 PR 或 MR 的开发者
- 务必检查源码与许可证后再安装,插件以当前 dsh 进程权限运行