dsh-web-ui/packages/dsh-git-graph

5.1kStar311Fork49Issue5Watching

为 dsh web GUI 空白会话加一个工作区分支选择胶囊与 Git 图谱面板:搜分支、切换、新建分支、查看泳道提交图,git 操作在 host 端执行。

机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科

此插件是大仓库 zhu1090093659/dsh-web-ui 的子包,星数与活跃度统计的是整个仓库。

语言
TypeScript
License
Apache-2.0
分支
dev
deepseek-harnessdshdsh-pluginweb-ui

安装

$ dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/dsh-git-graph

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 zhu1090093659/dsh-web-ui/packages/dsh-git-graph:先查看仓库 https://github.com/zhu1090093659/dsh-web-ui.git 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

为 dsh web GUI 空白会话加上一个工作区分支选择胶囊与 Git 图谱面板:搜索本地分支、查看当前 HEAD、创建并切换、查看泳道式提交历史,所有 git 操作在 host 进程的真实工作树上执行。

核心能力

  • 在空白会话输入区右侧提供一个分支胶囊,点开是可搜索弹层:当前分支打勾、按名搜索、底部「创建并检出新分支…」与「Git 图谱」两个动作
  • 切换分支作用于工作区级真实 git switch --no-guess:影响该工作区所有会话;守卫覆盖未解决冲突、进行中的 git 操作、目标分支已被其他 worktree 检出三类情况
  • 新建分支走 git switch --no-guess -c,支持创建对话框:客户端先做即时校验(不允许以 - 开头、不含 .. / ~^:?*[\ 等),host 再用 git check-ref-format --branch 做权威校验
  • Git 图谱面板按泳道渲染提交历史(topo-order + parents),每行带作者、时间、相对时间(刚刚 / N 分钟前 / N 小时前 / N 天前),支持加载更多
  • 状态刷新三路叠加:胶囊挂载 / 弹层打开 / 切换成功各拉一次;订阅期间 host 每 30 秒轮询 workspace(仅推送变化、15 秒超时兜底);窗口聚焦额外拉一次(5 秒节流)
  • SSE 长连接经跨标签页选主中继(Web Locks + BroadcastChannel),同一 URL 全浏览器只保留一条 EventSource,避免多开标签页挤占 HTTP/1.1 同源连接池

技术实现

  • 语言: TypeScript(host 半区)+ TypeScript + React 18 + CSS Modules(browser 半区)
  • 关键依赖: react ^18.2.0(peer,宿主运行时注入)、@deepseek-ai/dsh-client-ui-conversation(提供 SlotMap 与输入区槽位)、@deepseek-ai/dsh-client-ui-slots(slot 注册)、@deepseek-ai/dsh-host-webserver(host 路由与 SSE 框架)
  • 架构模式: 双半区 cordis bundle。src/index.ts 是 host 半区(mountOnce 单实例 guard + 注册 /git/* 路由 + 挂载 GitService);src/client/index.ts 是 browser 半区(声明感知挂载:先等 2 秒看 shell 是否声明 conversation.input.selector.context 槽位,迟到则永久回退到 conversation.input.dock 的 hero 相位;active 会话不挂)。git 调用全部走 host 的 subprocess 服务(生产用 /git/* HTTP + SSE,测试用 plain child_process)
  • 入口文件: packages/dsh-git-graph/src/index.ts(host 入口,cordis apply)、packages/dsh-git-graph/src/client/index.ts(browser 入口,cordis client apply);cordis bundle 声明在 packages/dsh-git-graph/cordis.patch.yml:1-12(插入 id ui-git-graph),浏览器依赖在 packages/dsh-git-graph/package.json:34-46(注入 3 个官方 @deepseek-ai/dsh-client-* 模块 + platform: web

适用场景

  • 在 dsh web 上做多分支并行开发的用户:开新会话前先在空白面板点开分支胶囊,搜/切到当前想用的分支,避免每个会话都手动 git switch 一遍;
  • 想可视化看自己工作区提交历史的用户:点胶囊底部「Git 图谱」打开泳道图谱面板,看一眼哪个分支走在哪条线、有没有分叉,比 git log --graph 直观;
  • 习惯用对话驱动开发、希望工具栏风格与官方工作区胶囊对齐的用户:本插件的胶囊与官方 WorkspaceChip / AgentPresetSeat 走同一套 28px 透明胶囊配方与 --dsw-* 主题 token,安装后视觉风格不跳。

前置依赖与兼容性

依赖最低版本说明
DSH 宿主0.1.0-rc.6+ 推荐package.json 未在 dsh.engines 声明;devDependencies 统一锁到 @deepseek-ai/dsh-* ^0.1.0-rc.8
Node.js^22.19.0>=24.0.0package.json engines.node
平台跨平台(host 端 PATH 需可解析 git;Windows 显式走 git.exehost 半区跑在 Node.js、client 半区跑在浏览器,无 OS 限制
原生模块无(运行时)通过 host 的 subprocess 服务 spawn git 二进制,不引入 native 绑定
Git 二进制系统 PATH 可达host 端 git --version 需可用;Windows 推荐 Git for Windows
React^18.2.0peerDependency,由宿主注入

安装方式

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

配置项

本插件无需用户配置。

host 端在源码内有几处可调常量(如轮询节奏、回退等待、请求体上限),但均无暴露给 DSH 设置面板的入口,调整需改源码后重新构建:

内部常量位置默认值作用
POLL_INTERVAL_MShost/routes.ts:4930000 msSSE 订阅期间 host 端轮询 workspace 状态的时间间隔
HEARTBEAT_INTERVAL_MShost/routes.ts:5115000 msSSE 心跳注释间隔(防代理丢空连接)
STATUS_TIMEOUT_MShost/routes.ts:5815000 ms单次 git status 的超时兜底,超时后用 AbortController 杀掉子进程
BODY_CAP_BYTEShost/routes.ts:751 MiB/git/* 请求体上限,超出直接销毁连接
CONTEXT_FALLBACK_MSclient/index.ts:942000 ms客户端等待 shell 声明 conversation.input.selector.context 槽位的时长,超时后回退到 conversation.input.dock
FOCUS_REFRESH_MIN_MSclient/chips/BranchChip.tsx:325000 ms浏览器窗口聚焦时重新拉取分支状态的节流间隔

常见问题

Q: 安装之后分支胶囊没出现在输入区怎么办?

A: 三步排查。第一,确认 dsh web 重启过,bundle 激活是启动时一次性做的,刷新浏览器不足以触发;第二,看一眼浏览器控制台是否有 [dsh-git-graph] / 槽位声明相关的报错;第三,等大约 2 秒——本插件会等 shell 声明 conversation.input.selector.context 槽位 2 秒后才回退到 dock hero 相位,如果 shell 没声明这个洞,胶囊会自动出现在 hero 行 agent-preset 座位右侧(迟到声明会被忽略)。packages/dsh-git-graph/src/client/index.ts:184-199

Q: 切分支时被 tracked-changes-would-be-overwritten 挡住怎么办?

A: 这是 git 自己的保护:已跟踪的本地修改会被目标分支覆盖。报错里会列出前两个阻塞文件路径 + 其余文件计数。本插件不做自动 stash(避免意外吞掉你的修改),请先 git stashgit commit 后再切。错误分类在 packages/dsh-git-graph/src/host/git-service.ts:87-152,文案见 packages/dsh-git-graph/src/client/locales.ts:30-35

Q: 我工作区里有多个 Git 仓库,这个胶囊管哪个?

A: 管当前会话 cwd 所在的那个。它会读 sessions baseline 的 cwd,解析成 git rev-parse --show-toplevel 拿到的 repoRoot,所有 git switch 都作用在那个 repoRoot 上。切换工作区 = 激活目标工作区并打开它的(复用或新建的)空白会话,不会去改其他会话的 cwd。语义在 packages/dsh-git-graph/src/client/index.ts:122-132packages/dsh-git-graph/README.zh.md:74

Q: 切分支会影响已经在跑的其他会话吗?

A: 会,因为切的是工作区级磁盘树——所有会话共享同一份 checkout。如果你只是想让某个会话在另一个分支上工作,正确做法是在输入区的工作区胶囊里切到目标工作区(或新建空白会话),不是用本插件的分支胶囊。packages/dsh-git-graph/src/host/git-service.ts:204-225 / packages/dsh-git-graph/README.zh.md:74

Q: 每次切换都能成功吗?什么情况会被拒?

A: 三类守卫挡路:未解决的合并冲突(conflicts-present)、正在进行的 git 操作(merge / rebase / cherry-pick / revert / bisect 任一标记存在 → operation-in-progress)、目标分支已被其他 worktree 检出(branch-in-other-worktree)。这三种直接拒绝并给可读报错,不会偷偷强切。守卫在 packages/dsh-git-graph/src/host/git-service.ts:323-340,错误文案见 packages/dsh-git-graph/src/client/locales.ts:27-29

Q: 同一个 URL 开两个标签页,会不会吃光浏览器的 HTTP 连接数?

A: 不会。SSE 长连接走跨标签页选主(Web Locks + BroadcastChannel),同一 URL 全浏览器只保留一条 EventSource,其它标签页通过 BroadcastChannel 收事件,HTTP/1.1 同源连接池不被挤占。浏览器既不支持 Web Locks 也不支持 BroadcastChannel 时自动降级为每个订阅开一条(旧行为)。代码在 packages/dsh-git-graph/src/client/sse-leader.ts:45-122(对应 issue #383)。

Q: 在非 Git 目录里新建会话会怎样?

A: 胶囊直接不显示——host 端 git rev-parse --show-toplevel 失败时 RepoStatus 返回 null,前端拿 null 后不渲染控件;不会报错、不会留空块。逻辑在 packages/dsh-git-graph/src/host/git-service.ts:281-286packages/dsh-git-graph/src/client/index.ts:134-138

Q: 卸载插件之后 git 状态会变吗?

A: 不会。本插件不在 host 上写任何持久文件,分支切换走的就是磁盘 git switch,状态全部由 git 自己管理。卸载 dsh plugin --profile web remove @linxin666/dsh-client-ui-git-graph 不会有插件自留的状态。卸载命令见 packages/dsh-git-graph/README.zh.md:65-67

上手难度

入门 — 一行命令安装,重启 dsh web 即可见分支胶囊;非 Git 目录自动隐藏,无需额外配置。

已知问题与限制

  • 客户端等待 conversation.input.selector.context 槽位声明只有 2 秒,超时后永久回退到 conversation.input.dock 的 hero 相位;迟到声明会被忽略,host 重启前不会重试(packages/dsh-git-graph/src/client/index.ts:191-199
  • active 会话不显示分支选择控件,分支切换需要新建空白会话或重启 host(packages/dsh-git-graph/src/client/index.ts:7-9
  • 切换分支前不做自动 stash,工作树脏时会被 git 自己拒绝(packages/dsh-git-graph/src/host/git-service.ts:207-225
  • Windows 强制走 git.exe(避开 .cmd shim,避免 --format 字符串里的 % 被 cmd.exe 展开),无法在配置里覆盖(packages/dsh-git-graph/src/host/git-service.ts:41-43、60-63
  • 路径必须在 host 已注册工作区列表里,任意目录无法触发 git 操作;realpath 不存在或不在注册表里返回 workspace-unknownpackages/dsh-git-graph/src/host/git-service.ts:30-43packages/dsh-git-graph/src/index.ts:30-43
  • /git/* 请求体超过 1 MiB 直接销毁连接,不解析(packages/dsh-git-graph/src/host/routes.ts:75、90-95
  • SSE 轮询每 30 秒一次,每个订阅者跑一次 git status;多工作区同时订阅时进程数 = 订阅者数;目前没有聚合或采样(packages/dsh-git-graph/src/host/routes.ts:49、188-206
  • 单次 git status 超时 15 秒(STATUS_TIMEOUT_MS),超时用 AbortController 杀掉子进程,UI 拿到的是 timeout 报错而非部分结果(packages/dsh-git-graph/src/host/routes.ts:58-69、171-186
  • 切换分支作用在工作区级(git switch 影响所有会话),不是 per-session 副本;想并行在多个分支上工作的用户需用「切换工作区」语义而不是分支胶囊(packages/dsh-git-graph/README.zh.md:74 / packages/dsh-git-graph/src/host/git-service.ts:196-203

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/zhu1090093659/dsh-web-ui/packages/dsh-git-graph)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录