# @caozeal/dsh-next-git 中文文档

规范地址：https://npmcn.com/package/%40caozeal/dsh-next-git/

版本：0\.1\.10
npm 元数据更新时间：2026-10-29T08:32:45.042Z
中文译文更新时间：2026-11-09T18:12:35.301Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40caozeal/dsh-next-git
原文对照：https://npmcn.com/package/%40caozeal/dsh-next-git/?lang=original
项目主页：https://github.com/caozeal/dsh-plugins/tree/main/dsh-next-git#readme
源码仓库：https://github.com/caozeal/dsh-plugins

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.5 MB，22 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=22
- 运行依赖：0 个
- 首次发布：2026-10-23T11:43:24.754Z
- 最新版本发布：2026-10-29T08:32:44.711Z
- 近 30 天下载量：1995（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：10（近 12 个月 10 个）

## 中文简介

DSH Git 管理插件：分支切换、变更暂存、提交/推送/拉取、AI 提交信息、提交图与 diff 查看

## 安装

```sh
npm install @caozeal/dsh-next-git
```

也可以使用：`pnpm add @caozeal/dsh-next-git`、`yarn add @caozeal/dsh-next-git`、`bun add @caozeal/dsh-next-git`

## README

# dsh-next-git — DSH Web 右侧边栏 Git 管理面板

> npm: [https://www.npmjs.com/package/@caozeal/dsh-next-git](https://www.npmjs.com/package/@caozeal/dsh-next-git)
> 
> 原名 `dsh-plugin-git-manager`，2026-10 起包名改为 `@caozeal/dsh-next-git`（目录仍为 `dsh-next-git/`，功能不变）。

## 45 秒介绍片

[https://github.com/user-attachments/assets/c57169b4-df00-450d-b4f0-7a2c64db03b6](https://github.com/user-attachments/assets/c57169b4-df00-450d-b4f0-7a2c64db03b6)

_全片界面为渲染示意，不含真实会话；[完整播放页](https://dsh.caozeal.cn/next-git/) 另有下载版。_

**不想先装再看？** [在线 Demo](https://dsh.caozeal.cn/next-git/demo/) 可以直接点—— 它加载的是发布包里同一份 `lib/client.js`，只补了一个最小假宿主和一份真实仓库的录制快照 （详见 [`demo/README.md`](https://github.com/caozeal/dsh-plugins/blob/main/dsh-next-git/demo/README.md)）。写操作在 Demo 里是禁用的，会明确提示。

在 DSH Web GUI **会话的右侧边栏**加一个 Git tab（2026-10-22 从左侧全局面板迁移而来）： 会话头部点 **Git 图标**直接打开（会自动展开右栏），或在右栏的「+ → 开始」指南页里 选「Git 管理」。面板内容：

-   **便捷分支切换**：顶栏下拉出全部本地/远程分支（含 ahead/behind 与最近提交）， 一键切换；点远程分支自动建同名跟踪分支；支持新建、删除分支。
-   **变更管理**：staged / unstaged / untracked / conflicted 四组文件列表， 单文件或全部暂存/取消暂存，点击文件看 diff。每行还带**丢弃**按钮： 未暂存回到 HEAD、未跟踪直接删除、已暂存连暂存区一起回退（都会二次确认）。 冲突文件不给丢弃——那等于放弃冲突解决状态，容易误伤。
-   **Stash**：分支页底部可直接 stash 当前改动（有未跟踪文件时自动带 `-u`）， 列出全部 stash，一键恢复（pop）或删除（drop）。
-   **AI 解决冲突**：冲突文件点「解决」，AI 读索引里的 base / ours / theirs 三份版本， 给出一份合并后的完整文件——**只生成建议，确认后才写盘**；确认时再校验一遍有没有 残留 `<<<<<<<` 才 `git add`。机械场景可以直接「取当前分支 / 取对方分支」。 冲突文件刻意不提供「暂存」按钮：`git add` 会把带冲突标记的文件直接标记为已解决。
-   **删除/改名冲突也能解**：某一侧在索引里没有 stage（被删除或改名）时，面板不再让模型 去猜「空文件」，而是直接给出「删除该文件 / 保留另一侧版本」两个选择；AI 也会拿到 「该侧已删除这个文件」的明确标注，判断该删时返回一行 `<<<DELETE_FILE>>>`， 确认后用 `git rm` 收掉冲突条目。存活侧与 base 完全相同时直接判定删除，不浪费一次模型调用。 生成结果撞到 maxTokens 上限（半份文件）会直接报错，不会写回工作区。
-   **提交 / 推送 / 拉取**：Fetch、Pull、Push 按钮，提交信息输入框， 支持「提交」「提交并推送」；无 upstream 时自动 `push -u origin <branch>`。 Pull 若因当前分支没有上游跟踪失败，面板会就地弹出「拉取选项」，让你从远端分支里 选一个并一键 `pull --set-upstream` 建立跟踪，不用再去命令行。
-   **AI 提交信息**：读取已暂存 diff + 最近提交风格，调用当前默认模型生成 Conventional Commits 提交信息（标题 + 可选正文，正文用来说清动机与影响面）， 填入输入框供编辑；模型不可用时降级为 `chore: 更新 N 个文件`。
-   **可自定义的提交提示词**：提交区齿轮按钮可改写系统提示词，存在 `git config dsh.commitPrompt`（本地优先、可全局兜底，不产生工作区文件）。 自定义只改「怎么写」，diff 与变更文件列表始终由 Host 装配后传给模型—— 提示词写坏也不会让模型凭空编造。
-   **彩色提交图（graph）**：`git log --graph --all` 的图形化渲染。每条分支线一种颜色， 跨行保持同色；分支名徽章与它自己的线条严格同色，滚到哪都认得出。同一屏出现过的 分支保证互不撞色（按首次出现顺序分配，不是对名字取哈希——8 色槽下取模约 1/8 会撞）。 可点击任意提交查看该 commit 的 diff。
-   **词级高亮 Diff**：hunk 逐行渲染，带旧/新行号、文件头与统计。真正变化的**词** 才有深色底，其余行内文字只是浅底——「改了什么」不用再靠眼力逐字比对。 增删配色直接复用平台自己的 `--dsw-alias-file-diff-*` token，深浅主题自动跟随， 和 GUI 里的代码块看起来是同一套东西。

面板跟随当前会话的工作目录：切换会话即切换仓库；非 Git 仓库 / 无会话 / 目录被删 时显示对应空态。右侧栏可以全屏（自带的「全屏」控件），窄列下是单列 tab 布局： `变更 | 提交图 | 分支 | 差异`，提交区固定在底部。

打开方式：

1.  会话头部工具栏的 **Git 图标**（aria-label「打开 Git 管理」）——最快；
2.  右侧栏的 **\+ → 开始** 指南页 →「Git 管理」；
3.  右侧栏已打开本 tab 时直接点 tab 切换。

## 目录

```
dsh-next-git/
  PROTOCOL.md         # Host ↔ Client 冻结协议（RPC 形状与 UI 约定）
  package.json        # dsh.bundle.patch + dsh.client
  cordis.patch.yml    # 插入 git-manager 行
  index.js            # Host 入口：注册 POST /api/git-manager
  src/git.js          # git 执行环境 + 输出解析（纯函数）
  src/operations.js   # 12 个 op 的实现
  src/ai-commit.js    # AI 提交信息（llm + 降级）
  lib/client.js       # 浏览器 bundle（单文件，无构建；右栏 tab + 头部按钮）
  locale/{zh,en}.json # 插件市场/设置页展示文案
  icon.svg            # 插件图标
  test/               # 解析 / op / 真实仓库集成测试
```

## 安装

```bash
# 在 dsh-plugins 仓库内
dsh plugin --profile web add /Users/caozeal/projects/dsh-plugins/dsh-next-git
# 或从 npm 安装：
dsh plugin --profile web add @caozeal/dsh-next-git
```

或由 agent 用 `plugin_manager` 的 `install_bundle` 安装（推荐，profile 配置由 插件管理器写入，不手改 `~/.dsh/profiles/web`）：

```
plugin_manager: action=install_bundle, target=/Users/caozeal/projects/dsh-plugins/dsh-next-git
```

安装后刷新/重开 Web 页面，左侧栏出现 Git 图标（在搜索/会话图标附近）。 Host 半区（`/api/git-manager` 路由）随 Loader 生效；若页面已加载但图标未出现， 刷新一次页面即可。

## 手动挂载（不装 bundle 时）

1.  把插件目录加入 profile 依赖（`file:` 或 `link:`），`pnpm install`。
2.  在 `~/.dsh/profiles/web/cordis.patch.yml` 末尾追加：
    
    ```yaml
    - id: git-manager
      name: "@caozeal/dsh-next-git"
    ```
    
3.  重启 Web 服务。

## 测试

```bash
cd git-manager
npm test          # = node --test test/*.test.mjs
```

-   `test/parsers.test.mjs`：porcelain / 分支头 / for-each-ref / graph / unified diff 解析， `cleanGitEnv` 的 undefined 墓碑（删除继承自父进程的坏 `GIT_CONFIG_*`），以及 `diffInline`（词级切分 + CJK 逐字 + 超长退化）与 `assignGraphColors` （跨行同色、同屏分支不撞色的回归用例）。
-   `test/operations.test.mjs`：12 个 op 的假 exec 单测（含超时、非法参数、非仓库、降级）。
-   `test/ai-commit.test.mjs`：AI 提交信息清理、截断/半句话回退、模型流错误转 `ai-unavailable`、 中文仓库的降级文案（单测合计 39 条，全绿）。
-   `test/integration.test.mjs`：临时真实仓库跑 snapshot → diff → stage → commit → graph → 建/切/删分支 → AI 降级；不依赖 dsh 运行时。
-   `test/live/`：真实 Web GUI 的验证清单、smoke 脚本、截图证据与验证报告 （由独立验证员维护）。

## 界面改版说明（2026-10-22）

最初版本把面板放在左侧「全局面板」位（`sidebar.panellist` + keyed `main`）。按用户 反馈「左侧是全局的，不适合放仓库级 Git 面板」，已改为**右侧边栏 tab**： `sidebarRightTabs` 注册 tab 类型 → keyed `sidebar.right.pane.tab` 注册 body → `conversation.session.header.utilities` 放入口按钮，左侧全局栏恢复原样。

`test/live/` 下 V1–V17 的截图对应**旧版左侧面板布局**（RPC 协议、Host 行为与功能 结论仍然有效）；新版右栏界面的实测证据是 `test/live/artifacts/V18-*.png`， 说明见 `test/live/REPORT-v2-right-sidebar.md`。所有截图已打码（会话列表/对话区模糊）， 处理规则见 [`test/live/artifacts/README.md`](https://npmcn.com/package/%40caozeal/dsh-next-git/test/live/artifacts/README.md)。

## 协议摘要

浏览器 → `POST /api/git-manager`（connection 层做同源凭据认证）：

```json
{ "op": "snapshot", "cwd": "/abs/repo" }
→ { "ok": true, "data": { "repo": {...}, "branches": [...], "status": {...} } }
```

op 一览：`snapshot` `graph` `diff` `stage` `unstage` `switchBranch` `deleteBranch` `commit` `fetch` `pull` `push` `aiCommit`。完整字段见 `PROTOCOL.md`。

## 设计要点

-   **Host 只做数据**：所有 git 操作在 Host 半区用 `ctx.subprocess` 执行， 参数校验（绝对路径、ref/hash 白名单、`--` 分隔）在 `src/operations.js`。
-   **图标 / 形象**：插件图标与空态形象是用 `custom-imagine` 生图技能生成的 Q 版 鲸鱼娘（蓝色渐变长发、呆毛、鲸鳍耳、抱着白饭碗），参考社区 DeepSeek 鲸鱼娘与 dsh-pet「蓝色大肥鱼」风格；prompt 与处理流程见 [`icon-prompt.md`](https://npmcn.com/package/%40caozeal/dsh-next-git/icon-prompt.md)。 `icon.svg` 内嵌 256px PNG 以满足 DSH 图标约束，空态用 224px WebP 内嵌；顶栏/ 提交卡片的小鲸鱼也是生图产出（128px WebP），不再用手绘 SVG。
-   **Client 只做展示**：单文件 classic script + 组件内 `<style>`（class 前缀 `gm-`， 卸载即移除；窄列容器查询收按钮为图标），向 `ctx.sidebarRightTabs` 注册 tab 类型、向 keyed `sidebar.right.pane.tab` 注册 body、向 `conversation.session.header.utilities` 注册入口按钮；文案走 Client locale 服务 （zh/en 108 个 key）。视觉以 DeepSeek 蓝为基调 + 胖鲸鱼吉祥物：圆角胶囊 tab、 渐变主按钮、鲸鱼空态（bob 动画 + 气泡）、状态药丸、diff/commit 卡片，全部是 组件内 CSS + 主题 token（见 `lib/client.js` 里的 `PANEL_CSS`）。提交图用 SVG lane 渲染（20px 行高、最多 10 lane），长历史/多分支下不会挤掉文字。
-   **失败可见**：git 非 0 退出把 stderr 摘要带回 UI，在底部状态条展示； 只读操作（snapshot/graph/diff）不会阻断面板。
-   **配色跟随宿主**：diff 增删底色与 gutter 用 `--dsw-alias-file-diff-*`，词级高亮 用它算出的 34% 透明叠加；两张主题各自的值由平台提供，插件不写死颜色。 提交图的 8 色 lane 调色板是本插件自己的 `--gm-lane-*`（平台没有这个 token）。
-   **词级算法在 Host 算、Client 只渲染**：`diffInline` 是纯函数（token LCS）， 跟解析器一起单测；Client 拿到的 `inline` 片段拼接后必须精确等于原行文本， 所以渲染层不需要任何对齐逻辑。
-   **AI 是可选能力**：缺少 `llm` / `agentDefaultModel` 时 `aiCommit` 自动降级， 不影响提交本身。

## 实现要点（踩过的坑）

-   **删除继承环境变量必须用 `undefined` 墓碑**：Host 的 subprocess provider 把显式 `env` 合并到父进程环境之上，只“不写这个键”删不掉继承值。本机父环境里有坏的 `GIT_CONFIG_COUNT`（缺 `KEY_*`），最初导致所有 git 命令 fatal、snapshot 误报 “不是仓库”。现在 `cleanGitEnv()` 对 `GIT_CONFIG_COUNT` / `KEY_*` / `VALUE_*` 一律传 `undefined`。
-   **右侧栏 tab 是 session scope**：body 的标准 props 直接带 `sessionId`， `cwd` 从 `ctx.sessions.list.getSnapshot().byId[sessionId]` 取。不要再依赖 root-scoped `main` 槽的 standard hooks（那套是旧方案，实测取不到）。右栏折叠时 seat 仍挂载，`ctx.sidebarRight.openTab()` 能直接展开并定位到本 tab。
-   **AI 提交信息用 600 output tokens**：reasoning 模型会先花思考 token，200 会截断成 `fix:` 之类半句话；再加 `looksLikeSubject()` 校验，不合格就回退确定性文案并置 `fallback: true`（UI 显示「模型输出不可用，已生成降级文案」）。
-   **错误码分层**：`invalid-params`（含未知 op）HTTP 400；git 业务失败 HTTP 200 + `ok:false`，UI 统一按 body 判定。
-   **文案全部走 Client locale**（zh/en 共 134 个 key），tab 标题与头部按钮都是 「Git 管理 / 打开 Git 管理」；面板只用 `--dsw-alias-*` 主题 token。

## 已知限制

-   Pull 默认使用 `git pull`（遵循仓库配置）；无上游时可在面板「拉取选项」里选择远端分支 并建立跟踪。不做冲突自动处理；冲突会在变更列表的 conflicted 组里以红色显示。
-   大仓库的 graph 默认取 80 条（上限 300）；diff 超过 400k 字符会截断。
-   会话的工作目录被删除/不可访问时，面板显示「工作目录不存在或无法访问」空态 （Host 返回 `cwd-unavailable`），不会展示原始 spawn 错误。
-   AI 解决冲突按「单个文件」处理，不提供「一次性解决全部冲突」的批量操作； 多个文件仍要逐个确认（这是有意的，批量自动落盘风险太高）。
-   AI 解决冲突的提示词**不可自定义**（与 AI 提交信息的 `dsh.commitPrompt` 不同）： 冲突装配的三份内容与删除协议由 Host 固定，避免自定义提示词把「删除」判断改坏。
-   网络操作超时 180s；无凭据的私有仓库会失败并把 git stderr 显示出来。

## 常见问题

### @caozeal/dsh-next-git 是什么？

DSH Git 管理插件：分支切换、变更暂存、提交/推送/拉取、AI 提交信息、提交图与 diff 查看

### 如何安装 @caozeal/dsh-next-git？

在项目目录运行 npm install @caozeal/dsh-next-git，或使用 pnpm add / yarn add / bun add。

### @caozeal/dsh-next-git 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/caozeal\_\_dsh-next-git 是否存在。

### @caozeal/dsh-next-git 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @caozeal/dsh-next-git 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @caozeal/dsh-next-git 可以商用吗？

@caozeal/dsh-next-git 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @caozeal/dsh-next-git 的下载量有多少？

根据 npm 官方下载统计，@caozeal/dsh-next-git 在 2026/10/09 – 2026/11/07 这 30 天内被下载 1,995 次，日均约 67 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @caozeal/dsh-next-git 还在维护吗？

最新版本 0\.1\.10 发布于 2026/10/29（11 天前）；至今共发布 10 个版本，其中过去 12 个月发布了 10 个；首次发布于 2026/10/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

