Skip to content
dsh.fish
Bundle

dsh-git-graph

DeepSeek Harness 集成 Git 视图插件(当前为 Git 专用:文件浏览/编辑暂时停用):宿主半提供 /git JSON API(status/branch/diff/stage/commit/log/blame/cat 等),浏览器半提供 Git 页签 UI。Git plugin for DeepSeek Harness (currently Git-only; the file browser is temporarily disabled): host /git JSON API + browser Git tab UI.

Source
enoughpower
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-git-graph

> DeepSeek Harness 集成 **Git** 视图的插件。

`dsh-git-graph` 把 Git 操作(状态 / 分支 / 差异 / 提交 / 推送拉取 / 提交图 / 溯源)打包成一个可直接安装的
dsh 插件。宿主半注册 `/git` JSON API,浏览器半在会话区域加一个 **Git** 页签,打开与当前会话工作目录
绑定的面板(分支栏 + 提交图 + 变更文件 + 差异视图)。界面文案中英双语(跟随 dsh locale 服务)。

> **移动端适配**:Git 页签在手机(dsh-pocket 代理)上也可见,窄屏下自动**单列堆叠**(历史图 → 变更文件 →
> 差异)、压缩顶栏与字号、放大触控目标;桌面宽屏保持三栏布局。

---

## 特性

### Git 操作(`/git`)
- **工作区状态**:`status` 返回分支信息 + 已暂存 / 未暂存 / 未跟踪三类文件,逐文件标注状态码(`XY`)。
- **分支管理**:列出本地/远程分支(`branches`)、切换(`switchBranch`)、新建(`newBranch`)、
  删除(`deleteBranch`)、重命名(`renameBranch`)、合并(`merge`,可选 `--no-ff`)。
- **差异与提交**:`diff`(工作区 / 已暂存)、`stage` / `unstage` / `discard` / `remove`、
  `commit`(提交选中文件或全部)、`amend`。
- **历史与溯源**:`log`(oneline 列表)、`graphLog`(带父提交的提交图)、`fileLog`(单文件历史)、
  `blame`(逐行溯源)、`show` / `showStat` / `showFiles` / `showFileDiff`(提交详情与单文件差异)、
  `catFile`(读指定 ref 或工作区文件内容)。
- **远程与标签**:`push` / `pull` / `fetch`(可 `prune`)、`remotes`、`tags`、`conflicts`。

> 大 diff 截断到 2 MiB,避免超大差异冻结传输与前端渲染。

---

## 界面截图

![Git 面板:分支栏 + 提交历史 + 变更文件 + 差异视图](./docs/screenshots/git-panel.png)

---

## 兼容性

| 项 | 要求 |
|---|---|
| dsh(宿主) | `>= 0.1.0-rc.5` |
| Node.js | `>= 20` |
| git | `>= 2.28`(`git init -b` 需要;分支/合并/日志等日常操作 2.x 均可) |
| 平台 | 宿主(Node)+ Web(浏览器) |

---

## 安装

该插件是 **bundle 插件**(`package.json` 声明 `dsh.bundle` + `cordis.patch.yml`,并声明 `dsh.client`),
装好后宿主层与浏览器层都会被自动激活。

```sh
# 本地目录
dsh plugin --profile web add /path/to/dsh-git-graph

# 或已发布的 npm 包
dsh plugin --profile web add dsh-git-graph
```

---

## 使用

1. 装好插件并在会话内打开一个工作区(仓库目录)。
2. 会话区域出现 **Git** 页签(对话轨迹右侧),点击进入 Git 面板。
3. 面板内:顶部分支栏 + 提交图;选中一个提交看详情(变更文件 / 差异);选中工作区文件可暂存 /
   提交 / 丢弃。
4. 面板绑定「当前会话工作目录」。

---

## JSON API

所有请求都是 `POST`,`content-type: application/json`。通用响应:

```jsonc
// 成功
{ "ok": true, "value": { /* 结果 */ } }
// 失败
{ "ok": false, "error": { "code": "git-error", "message": "..." } }
```

### `/git` 操作

| op | 请求 | 说明 |
|---|---|---|
| `status` | `{ path }` | 分支 + staged / unstaged / untracked 文件 |
| `staged` | `{ path }` | 仅已暂存(index vs HEAD)文件 |
| `branches` | `{ path }` | 本地/远程分支(当前、track 信息、ahead/behind) |
| `switchBranch` | `{ path, name }` | 切换分支(远程名自动退化为本地短名) |
| `newBranch` | `{ path, name, base?, switch? }` | 新建分支,`switch` 为真时切过去 |
| `deleteBranch` | `{ path, name, force? }` | 删除分支(`force` → `-D`) |
| `renameBranch` | `{ path, name, oldName? }` | 重命名当前/指定分支 |
| `merge` | `{ path, name, noFf? }` | 合并分支,冲突时返回 `conflicts: true` |
| `diff` | `{ path, file?, staged? }` | 差异(截断到 2MiB) |
| `stage` | `{ path, files[] }` | 暂存指定文件 |
| `unstage` | `{ path, files[] }` | 取消暂存 |
| `discard` | `{ path, files[] }` | 丢弃工作区改动 |
| `remove` | `{ path, files[] }` | 物理删除(含未跟踪) |
| `log` | `{ path, n? }` | 最近提交列表 |
| `graphLog` | `{ path, n? }` | 提交图(含父提交、作者、日期、refs) |
| `fileLog` | `{ path, file, n? }` | 单文件历史 |
| `blame` | `{ path, file }` | 逐行溯源 |
| `catFile` | `{ path, file, ref?, workingTree? }` | 读某 ref 或工作区文件内容 |
| `commit` | `{ path, message, files[]? }` | 提交选中文件(缺省提交全部) |
| `amend` | `{ path, message? }` | 追加到上一提交 |
| `show` | `{ path, hash }` | 提交补丁 |
| `showStat` | `{ path, hash }` | 提交元信息 + stat + 补丁 |
| `showFiles` | `{ path, hash }` | 提交变更的文件名 |
| `showFileDiff` | `{ path, hash, file }` | 提交内单文件差异 |
| `push` | `{ path, branch?, setUpstream? }` | 推送 |
| `pull` | `{ path, rebase? }` | 拉取(`--ff-only`) |
| `fetch` | `{ path, prune? }` | 抓取远端 |
| `remotes` | `{ path }` | 远端列表(fetch/push URL) |
| `tags` | `{ path }` | 标签列表 |
| `conflicts` | `{ path }` | 冲突文件列表 |

---

## 目录结构

```
dsh-git-graph/
├── package.json        # 插件清单:dsh.bundle + dsh.client + 发布元数据
├── cordis.patch.yml    # 宿主激活 row(id=git-graph)
├── lib/
│   ├── index.js        # 宿主半:/git 路由 + 纯函数导出(可测)
│   └── client.js       # 浏览器半:Git 页签 UI(预编译单文件 bundle)
├── test/
│   ├── parse.test.js       # 纯函数单测(porcelain / 分支头解析)
│   └── integration.test.js # 真实仓库 + HTTP 端到端烟测
├── .github/workflows/  # CI + npm 发布(provenance)
├── README.md           # 中文文档
├── README.en.md        # English docs
└── LICENSE             # MIT
```

---

## 开发

```sh
# 运行测试(node 内置 test runner,无需额外依赖)
npm test

# 单跑某文件
node --test test/parse.test.js
node --test test/integration.test.js
```

- `test/integration.test.js` 会真实 `git init` 一个临时仓库、启动 `apply()`、用 HTTP 驱动 `/git`
  做端到端冒烟,结束后清理临时目录。要求 `git` 在 `PATH` 中。
- `lib/client.js` 是预编译产物(esbuild 单文件 bundle),本仓库直接复用桌面版已编译 bundle,
  宿主/浏览器两半用同一包名在 dsh 客户端模块系统里注册
  (`window.__ModuleLoader__.load({ id: "dsh-git-graph", factory })`)。
- CI(`.github/workflows/`):push/PR 跑测试(Node 20/22);打 `v*` 标签自动 `npm publish --provenance`
  (需 `NPM_TOKEN` secret,标签版本号须与 package.json 一致)。

---

## 安全

- 每个 `/git` 操作都限定在请求的 `path` 目录内执行,不引入任意 shell(走 `execFile` 参数数组)。
- 请求体上限 1MiB、`git` 输出缓冲 64MiB、diff 截断 2MiB,避免超大内容拖垮进程。

---

## 许可证

[MIT](LICENSE)

更新说明见 [CHANGELOG.md](CHANGELOG.md)。

Install

dsh plugin --profile web add github:enoughpower/dsh-git-graph

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source