@caozeal/dsh-next-git
DSH Web 右侧边栏的 Git tab,跟随当前会话的仓库:下拉切换本地/远程分支(带 ahead/behind),按 staged/unstaged/untracked/conflicted 分组暂存,提交、fetch、pull、push(无 upstream 时自动建跟踪分支),用默认模型按已暂存 diff 起草约定式提交信息(模型不可用时降级为普通 chore 文案),并以每条分支一种颜色的形式渲染 git log --graph 和词级高亮的 diff。
安装
dsh plugin --profile web add @caozeal/dsh-next-git
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
dsh-next-git — DSH Web 右侧边栏 Git 管理面板
npm: <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
全片界面为渲染示意,不含真实会话;完整播放页 另有下载版。
不想先装再看? 在线 Demo 可以直接点——
它加载的是发布包里同一份 lib/client.js,只补了一个最小假宿主和一份真实仓库的录制快照
(详见 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 / 真实仓库集成测试
安装
# 在 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 末尾追加:
- id: git-manager
name: "@caozeal/dsh-next-git"
3. 重启 Web 服务。
测试
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](test/live/artifacts/README.md)。
协议摘要
浏览器 → POST /api/git-manager(connection 层做同源凭据认证):
{ "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](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
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:10,最后更新 2026-10-29