DeepSeek Harness 插件

zhu1090093659/dsh-web#packages/dsh-git-graph

Star 数 ★ 8275 下载量(近 30 天) 157,962 分类 Git 与代码评审 收录于 2026-09-24 npm @linxin666/dsh-client-ui-git-graph

输入框上方提供 Git 分支选择器,并把分支泳道与提交历史画成图谱,沿着时间线找到任意变更。

安装

# npm 包(预构建)

dsh plugin --profile web add @linxin666/dsh-client-ui-git-graph

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:zhu1090093659/dsh-web#path:/packages/dsh-git-graph

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 中文

外部 DeepSeek Harness(DSH)Web GUI 与官方桌面客户端插件:Git 分支选择器与交互式 Git 提交历史图谱面板。分支选择器只在空白会话显示,挂在官方输入选择器行的 context 洞(conversation.input.selector.context,session-maybe list 槽位)中,与官方工作区选择胶囊并排。若运行 shell 未声明该槽位(npm SDK rc.6 删除了它),等待 CONTEXT_FALLBACK_MS 后回退到 conversation.input.dock;在其空白会话 hero 相位,chip 会提升进官方 hero 行,紧贴 agent-preset 座位右侧,采用与官方工作区/预设胶囊一致的透明 28px 胶囊配方和 --dsw-* 主题 token。active 会话不提供分支选择控件。Git 能力在 host 进程执行(磁盘工作树 git switch),UI 在浏览器 React;工作区选择保留官方入口。

行为对齐 ZCode 的 GitBranchSwitcher:可搜索弹层、当前项打勾、「创建并检出新分支… / Git 图谱」底部操作、切换守卫(未解决冲突 / 进行中操作 / 目标分支被其他 worktree 检出)与可读报错。

仓库布局与构建

本包是 dsh-web 全家桶仓库内的自包含 cordis 插件包(见下文「通用安装」),不涉及 DeepSeek Harness 源码 checkout。所有 peer API 来自 devDependencies 声明的官方 @deepseek-ai/* NPM SDK、由 node_modules 解析,类型门是 pnpm run typecheck(tsc -b,只构建本包自己的 host 与 client program)。

pnpm install
pnpm run typecheck   # tsc -b(host + client program)
pnpm test            # vitest(core 纯函数 / 真实 git 服务 / jsdom 组件)
pnpm run build       # tsc -b && tsdown(lib/index.js + lib/invariant.js + lib/client.js)

lib/client.js 是浏览器 bundle(闭包工厂产物,window.__ModuleLoader__.load),由 host 的 client-modules 按 /plugins/<id>/client.js 伺服;tsdown.config.ts 与 tsdown.prepare.config.ts 都 import 唯一的共享客户端预设 shared/tsdown.client.ts(及其读取的浏览器平台种子表),包内不保留副本。

git 安装走 prepare 脚本:tsdown --config tsdown.prepare.config.ts 从 src 直接 transpile,不做类型检查(tsconfig.prepare.json 自包含)。

激活

本包是 dsh profile bundle(package.json 声明 "dsh": { "bundle": { "patch": "./cordis.patch.yml" } })。激活后,下次启动 dsh web(或对应 profile)时,bundle patch 的 insert 行把 ui-git-graph(host half:git 服务 + /git/* 路由)与浏览器 half(dsh.client 声明)一起装进 Web 组合;页面刷新后,空白会话的分支胶囊显示在 hero 行的 agent-preset 座位右侧,active 会话不显示该控件。

通用安装(任何机器)

本插件已并入 dsh-web 全家桶仓库(github.com/zhu1090093659/dsh-web)。插件已发布到 npm,推荐一行安装:

dsh plugin --profile web add @linxin666/dsh-client-ui-git-graph@latest

或直接安装全家桶聚合包 @linxin666/dsh-web-all 一次到位(同样一行 dsh plugin --profile web add @linxin666/dsh-web-all@latest)。

需要改代码调试时再从仓库安装:

git clone https://github.com/zhu1090093659/dsh-web.git
cd dsh-web
pnpm install && pnpm -r build
dsh plugin --profile web add link:$(pwd)/packages/dsh-git-graph

github: 安装方式适用于包位于仓库根部的独立仓库(prepare 脚本自包含构建;pnpm ≥10 首次会被拒绝,需按报错提示把包 key 加进 profile 的 pnpm-workspace.yaml allowBuilds 后重试)。monorepo 内的子包请用上面的 link: 方式。

本地开发循环(本仓库 checkout)

dsh plugin --profile <name> add link:/absolute/path/to/dsh-git-graph

link: 安装直接引用本地目录,重建后立即生效、无需重装(改完 pnpm run build 后刷新页面即可)。注意 link: 后跟的是绝对路径(~ 由 shell 展开,不是 pnpm 语义)。

Worktree 隔离

分支弹层底部有两个 worktree 入口(worktree 是共享仓库历史、但文件与分支各自独立的链接检出,并行会话互不触碰对方的工作树):

  • 在 worktree 中开始新会话… 打开对话框:命名 worktree 并选择基线分支(默认预填当前分支)。host 在 $DSH_HOME/worktrees/<repo-key>/<名称>/ 创建 worktree,携带新分支 wt/<名称>(git 不允许同一分支两处检出),随即注册为 workspace 并打开其空白会话。当前检出不受影响。
  • 管理 worktree… 列出仓库的全部链接 worktree(分支/HEAD)。托管的 worktree 可删除:有未提交更改时先拒绝一次,随后给出行内强制确认;wt/ 分支默认保留,勾选该行的“同时删除分支”才会一并删除。主检出行只读。

插件设置卡里有两个开关(默认都关闭):

  • 自动隔离(autoIsolate):git 工作区的“新会话”动作会静默创建全新托管 worktree 并在其中开会话——Claude 桌面版式的自动形态。autoBaseline 选择基线:当前检出 HEAD(current)或远程默认分支(default,解析为 origin/HEAD,无远程时回退 HEAD)。已在托管目录下的工作区不会被二次隔离;任何失败都降级回官方新会话行为。实现上是浏览器半区对 workspaces 服务的运行时包装(形状探测过的 patch,不改 DSH 源码)——SDK 升级若改变该服务形状,功能自动关闭并打印诊断,不会硬崩。
  • Agent 工具(agentTool):注册模型可见的 git_worktree 工具(对同一托管目录做 create/list/remove,以调用会话的 cwd 做工作区门卫)。这是对“git 能力不进模型可见面”既定规则的有意豁免,仅对开启者生效。注意沙盒边界:会话 cwd 不可变,当前会话无法迁入 worktree;workspace-write 沙盒下 agent 也不能写会话根之外——所以 create 会同时把 worktree 注册成 workspace,工具回复会提示模型在其上开新会话。danger-full-access 模式下 agent 可直接在返回路径里工作。

删除只针对仓库托管目录的直接子级(双侧 canonical 路径包含校验),且在磁盘删除成功后才注销关联的 workspace。

卸载

dsh plugin --profile web remove @linxin666/dsh-client-ui-git-graph

设计要点

  • 边界与加载链调研、关键决策见 docs/ADR-001-plugin-boundary.md。
  • host half 的 /git/* 只接受已注册 workspace 的路径(realpath 校验)与受信任客户端(loopback socket + loopback Host,与 dsh-ssh 相同的 fence,同时装了 dsh-remote-web-ui 时有效的已配对设备 cookie 也是放行路径);浏览器无法对任意目录执行 git,LAN 暴露的 dsh web 对未配对的非 loopback 客户端返回 403。
  • 切换语义是工作区级:git switch --no-guess <branch> 作用于 repoRoot 磁盘树,影响该工作区所有会话;项目切换 = 激活目标工作区并打开其(复用或新建的)空白会话,不给既有会话换 cwd。
  • 挂载 seam:conversation.input.selector.context(官方声明的 session-maybe list 槽位)是输入选择器行的 context 洞,与官方工作区胶囊并排。分支胶囊只在空白会话显示;无会话 cwd 或非 Git 工作区时自行隐藏。声明感知回退会等待该槽位声明 CONTEXT_FALLBACK_MS(npm SDK rc.6 的 shell 已删除此声明);超时未声明时,改在 conversation.input.dock 的空白会话 hero 相位挂载。此时 chip 重新定位到官方 hero 行 agent-preset 座位右侧(官方 2px 行间距、垂直居中,胶囊尺寸与 token 对齐官方工作区/预设胶囊),弹层向下打开、对齐官方工作区菜单。active 会话没有分支选择控件。只挂一个座位,回退后迟到的 context 声明被忽略。
  • 工作区选择不在此插件内:官方工作区胶囊(conversation.input.selector.workspace)是唯一入口,本插件只提供 git 分支上下文。
  • 分支状态刷新:空白会话 chip 挂载、弹层打开、切换成功后拉取,加上 host SSE(/git/events,订阅期间每 30s 轮询 workspace 状态,单次探测有 15s 超时兜底,挂起的 git 不会卡死推送流)推送外部变更和 window focus 刷新(5s 节流)。active 会话不订阅。SSE 流经跨标签页选主中继共享(Web Locks + BroadcastChannel),同一 URL 全浏览器只保留一条流,多开标签页不会挤占同源 HTTP 连接池(#383)。

检查链

pnpm run typecheck
pnpm test
pnpm run build

数据遥测

浏览器半区每个 UTC 日向 dsh-market.com 发送一次匿名安装心跳:仅含一个 localStorage 随机 ID 与本包名,无其他数据。服务端只存储该 ID 的加盐哈希,不存 IP,且只暴露聚合计数。完整契约见 docs/telemetry.md。

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。