# dsh-ui-web

> 为 DSH Web 对话框提供 git 分支选择器和 Git 提交图谱面板，host 进程真实执行 git switch/create。

## Metadata

- Author: [@CAPTAIN1275](https://github.com/CAPTAIN1275)
- Repo: <https://github.com/CAPTAIN1275/dsh-ui-web.git>
- GitHub: [CAPTAIN1275/dsh-ui-web](https://github.com/CAPTAIN1275/dsh-ui-web)
- Stars: 34
- Language: TypeScript
- License: [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)
- Topics: `dsh-plugin`, `dsh-plugin-market`, `dsh-plugins`
- Forks: 2
- Open Issues: 0
- Last push: 2026-08-16T18:08:27.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:CAPTAIN1275/dsh-ui-web/packages/dsh-git-graph
```

## Wiki

## 一句话定位
为 DSH Web 在输入框上方加一个 git 分支选择器和 Git 提交图谱面板，git 操作在 host 进程的真实工作树上执行，UI 跑在浏览器里。

## 核心能力
- 在对话输入框上方挂一个分支胶囊，显示当前分支名（含未提交改动数）
- 弹出可搜索的本地分支列表，一键切换到任意本地分支
- 创建并立即切换到新分支（基于当前 HEAD）
- 打开 Git 图谱面板，按拓扑顺序查看跨分支/标签/远程的提交历史，支持分页加载
- 通过 SSE 实时接收工作区分支状态变更，外部 git 操作后自动刷新
- 切换守卫：拒绝未解决冲突、进行中的 git 操作、目标分支已被其他 worktree 检出等情况

## 技术实现
- **语言**: TypeScript + React (TSX)
- **关键依赖**: @deepseek-ai/dsh-host-webserver、@deepseek-ai/dsh-subprocess、@deepseek-ai/dsh-workspace、@deepseek-ai/dsh-client-ui-slots、@deepseek-ai/dsh-client-ui-primitives、@deepseek-ai/cordis
- **架构模式**: cordis 双面插件，host half（git 服务 + `/git/*` HTTP 路由 + SSE 推送）+ browser half（React 组件 + 路由客户端）；通过 `cordis.patch.yml` 作为 profile bundle 激活，浏览器侧声明注入 `@deepseek-ai/dsh-client-locale`、`@deepseek-ai/dsh-client-runtime`、`@deepseek-ai/dsh-client-ui-conversation`
- **入口文件**: `src/index.ts`（host 主入口）、`src/client/index.ts`（browser 主入口）、`src/invariant.ts`（不变式导出）

## 适用场景
在 DSH Web 中需要频繁切分支做对比实验、想随手查看当前仓库的提交图谱、又不想离开 IDE 去敲命令行的人。例如在 `feature/x` 分支调试时，想切到 `main` 看看某个改动是否存在，但又懒得开终端；同时希望通过图形化的提交图谱回顾近期合并历史。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH (peerDependencies) | ^0.1.0-rc.6 | 需要 host-webserver、subprocess、workspace、client-ui-conversation 等官方 SDK |
| Node | ^22.19.0 或 >=24.0.0 | 由 package.json engines 声明 |
| 工作区 | 必须是已注册的 DSH workspace | host 路由以 realpath 比对 workspaceRegistry 作为安全边界 |
| 系统 git | 二进制可用 | 通过 ctx.subprocess 调用 git 命令，依赖机器 PATH 中有 git |

## 安装方式
```bash
dsh plugin --profile web add github:CAPTAIN1275/dsh-ui-web/packages/dsh-git-graph
```

## 配置项
本插件无需额外配置。host 路由硬编码仅接受注册工作区路径，git 操作目录来自当前会话 cwd；分支胶囊只在 git 仓库内自动出现。

## 常见问题
**Q: 切换分支会不会影响其他会话？**

A: 会。切换作用于工作区根目录的磁盘工作树（`git switch --no-guess <branch>`），同一工作区所有会话都看到新分支；插件不会给已有会话单独换工作目录。

**Q: 切换时弹出"unresolved conflicts"之类的错误怎么办？**

A: 这是 host 的守卫在工作。打开终端在仓库根目录跑 `git status` 处理冲突、rebase/cherry-pick，或切到别的干净分支即可；插件检测到工作区存在未解决冲突或进行中操作时会拒绝切换。

**Q: 切换按钮点了没反应？**

A: 常见原因：目标分支不存在（已被删除）、重名分支恰好拼错、目标分支被其他 worktree 检出。胶囊会显示对应的中英错误文案，可以先在终端 `git branch -a` 确认分支名。

**Q: 工作区不是 git 仓库时会怎样？**

A: 分支胶囊直接隐藏，不渲染占位控件；插件不会误报"非仓库"错误；切换到 git 目录后下次刷新即出现。

**Q: Git 图谱面板能查看多远的历史？**

A: 默认一次拉取最近 200 条提交（`/git/graph` 接口 limit），底部出现"加载更多"时分页再加 100 条；超出返回 hasMore=true。面板仅展示当前仓库能看到的 refs（本地分支 + 标签 + 远程），不修改历史。

**Q: 卸载会影响已有的 git 状态吗？**

A: 不会。插件只是 UI + 路由层，git 操作直接走 git 二进制；卸载只是去掉分支胶囊和图谱面板，工作树原样保留。

## 上手难度
入门 — 安装一行命令，无需配置；切换和创建分支遵循 git 原生语义，工作区已是 git 仓库即可看见分支胶囊。

## 已知问题与限制
- 分支胶囊只在工作区是 git 仓库时出现；非仓库目录打开 DSH Web 不会有胶囊
- 浏览器端通过 host 的 `/git/*` 路由访问 git，路径必须命中已注册工作区（realpath 校验），任意目录无法直接执行 git
- 切换是工作区级的，没有"为单个会话单独换分支"的能力；既有会话不会换 cwd
- Git 图谱面板的提交信息以最近一次拉取为准；外部对仓库的改动通过 SSE 每 2 秒轮询一次反映（见 src/host/routes.ts:34）
- 请求体大小上限 1 MiB（src/host/routes.ts:38-39），超大请求会被直接销毁而不解析

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-ui-web](https://deepseek-plugin.org/plugins/CAPTAIN1275/dsh-ui-web/packages/dsh-git-graph)
Wiki generated by AI (model: `MiniMax-M3`)
