DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Git — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
G

@dsh-plugins/dsh-git

Git

DeepSeek Harness Web GUI 的完整 Git 管理:切换分支、基于基础分支新建分支、fetch、pull、stage-all、提交(由 AI 起草提交消息)、push、状态查看,以及点击打开差异查看器(已暂存/未暂存,可调整大小)——作为可折叠浮动面板,跟随当前会话的工作区

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:xia-sc/dsh-git#8216c209792ecf694dd8ab49401785e9017bd3ea
README兼容性版本

说明

DeepSeek Harness Web GUI 的完整 Git 管理:切换分支、基于基础分支新建分支、fetch、pull、stage-all、提交(由 AI 起草提交消息)、push、状态查看,以及点击打开差异查看器(已暂存/未暂存,可调整大小)——作为可折叠浮动面板,跟随当前会话的工作区。

兼容性与来源证明

Git 以 @dsh-plugins/dsh-git 发布,当前版本为 0.5.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/15

版本

0.5.0stable
2026/9/15
0.4.1stable
2026/9/11
0.3.1stable
2026/9/10

相关插件

正在加载相关插件…

最新版
0.5.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 1
周下载
0
最近提交
2026/9/18
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

@dsh-plugins/dsh-git

English | 中文

DeepSeek Harness Web GUI 的完整 Git 管理插件,形态为一个可折叠的悬浮面板, 实时跟随当前会话的工作区——在侧边栏点击不同的会话/工作区,面板会瞬间 重新绑定到对应仓库。

支持的工作流: 分支切换 · 拉取更新(fetch) · 拉取合并(pull,仅快进) · 暂存全部 · 提交(commit,可用 AI 起草提交信息) · 推送(push) · 状态(status) · 最近提交 · 未提交文件列表 · 点击变更看差异 · 基于某分支新建分支。

界面

  • 悬浮面板(shell.overlay):折叠时不渲染任何元素(不会遮挡输入框); 展开后是完整的 Git 工作台(状态行、带 脏树预检 的分支切换器——在有 未提交修改时选择分支,会先显示受影响文件列表警告而不是直接切换,并提供 "仍要切换"按钮;fetch/pull 操作;提交区——"暂存全部"按钮、AI 生成依据 选择器、"✨ AI 生成"按钮、提交信息输入框(多行文本框,回车换行、 Ctrl/Cmd+Enter 提交)与提交按钮;可折叠的变更列表与 最近提交列表;上次操作输出)。面板可通过顶栏拖动(按住带 Git 标题的 那一行,拖到哪里就停在哪里,不会拖出视口;顶栏上的按钮/输入框不会触发 拖动;双击顶栏回到居中位置)。 分支切换器旁边的"+ 新建分支"按钮会展开一个内联表单:新分支名 + 基分支 选择器(本地分支或 origin/feature/x 这样的完整远端引用)——确认后从 该基分支创建新分支并切换过去。
  • 点击变更看差异:点变更列表里的任意一行,面板会从 400px 的单栏展开成 两栏——左边照旧是完整工作台,右边是该文件的 unified diff(见下文 「差异查看」)。再点同一行、或点差异标题栏的 ×,就收回单栏。
  • 输入框胶囊(conversation.input.dock):输入框左上角的紧凑型左对齐 状态胶囊(分支摘要,或"当前工作区不是 Git 仓库");点击它展开/收起悬浮面板。
  • 两处界面共享同一个 store,状态永远一致,并都会随当前会话(及其 cwd) 切换而重新绑定。切换工作区会清空已选中的文件——绝不让面板显示别的仓库的内容。

差异查看

点变更列表里的一行,就在右侧显示该文件的 git diff。左侧列表是它的导航: 行高亮表示"正在看这一个",首次点击会自动把变更列表展开成完整列表。

  • 可拖拽调宽:拖动面板最右侧那条边即改差异栏宽度——左栏(工作台)宽度不变, 面板整体变宽、差异栏跟着长;双击这条边复位。面板始终留在视口内,窗口变窄时 会自动收回;拖动时面板会就地锚定左边缘,所以指针与这条边是 1:1 跟手的。
  • 未暂存 / 已暂存:默认自动跟随数据——未暂存有内容就显示未暂存,否则显示 已暂存;顶部两个 chip 可手动切换,空的一侧置灰。同一个文件两边都有改动时, 一次点击看到的是最关心的那一侧,另一侧一键可达。
  • 自动刷新:暂存、提交、切分支、刷新之后,打开的差异会自己重读——未暂存 变空时会自动落到已暂存。
  • 行号与配色:左右两列行号(旧/新)取自每个 hunk 头,+/- 行走主题的 成功/错误色,hunk 头单独一行,\ No newline at end of file 灰显。
  • 边界都有明确提示:这一侧没有改动 / 二进制文件没有文本差异 / 差异过大只 显示开头一段 / 未跟踪目录里还有 N 个文件未展开 / 读取失败。超过 1500 行的 差异先渲染前 1500 行,按钮可展开全部(避免一次渲染几万个节点)。
  • 未跟踪文件:与空文件对比,显示成 new file mode 的新增 diff;未跟踪 目录会把里面的文件逐个展开(上限 50 个,其余计入提示)。
  • 重命名:同时把旧名与新名作为 pathspec 交给 git,否则 git 无法配对,会把 一次重命名报成整文件新增。

提交区与 AI 起草

提交区按真实操作顺序排列:暂存全部 → AI 生成 → 提交。

  • 暂存全部:git add --all(含删除与未跟踪文件)。工作区干净时置灰。 这是"只有未暂存改动、点提交却报错"的正解——提交本身依然不会隐式暂存。
  • AI 生成依据:三选一,决定把哪一部分改动交给模型: 已暂存(默认)、未暂存、全部。默认 已暂存,因为只有它是本次 提交真正会记录的内容——用其他依据生成的描述可能与实际提交不符。
  • ✨ AI 生成:把选中的改动(diffstat + diff,截断后)交给当前会话所选 模型,生成的提交信息直接填入输入框;不满意可改,也可以直接手写。

生成用的模型路由取当前会话的 modelSelection 投影(待生效的选择优先, 其次是上次实际使用),取不到时回落到宿主注册的第一条路由。失败会以 本地化文案显示在"上次操作输出"里(无可用改动 / 未配置模型 / 生成失败等)。

架构

一个双面 npm 包:

半边文件职责
宿主lib/index.jsCordis 插件(bundle 行 dsh-git),在自己的 ctx.webServer 上注册 /dsh-git-rpc 前缀路由,收发浏览器 connection.rpc.call 的同一套 Connection RPC 信封,并复用 connection 服务的 Host/Origin + 浏览器会话围栏(connection.requestRejection)。端点:status、branches、checkout、createBranch、fetch、pull、stage、diff、commit、push、log、generateMessage。所有 git 调用都走 execFile(无 shell)、带超时(本地 30s / 网络 120s)、严格入参校验。AI 生成走注入的 llm 服务。
浏览器lib/client.jsdsh.client bundle(服务于 /plugins/@dsh-plugins/dsh-git/client.js):悬浮面板 + dock 行 + 共享 store,对照模块表手写(仅依赖 react)。

为什么自持 HTTP 路由(dsh ≥ 0.1.5-rc.1)

dsh 0.1.5-rc.1 起,外部插件不能再调用 ctx.connection.rpc.handle(): HostConnectionService.rpc 闭包持有的是 connection 插件自己的 Context(inject 只有 ["credentials"]),注册时执行 owner.effect(() => owner.webServer.register(route)),而该插件只在内部的 ctx.inject(["webServer"], …) 作用域里取得到 webServer。于是无论调用方 inject 了 什么,这一行都会以 cannot get property "webServer" without inject 挂载失败 (0.3.0 正是如此,插件在 0.1.5-rc.1 上装不起来)。本插件因此改为自己注册 /dsh-git-rpc 路由、自己实现同一套 RPC 信封;请求围栏仍交给 connection 服务的 requestRejection,安全等级与 /api 完全一致。test/host-mount.mjs 在真实 Cordis + 真实 Connection 服务上守护这一点。

安装

dsh plugin --profile web add https://github.com/xia-sc/dsh-git

然后重启 dsh web(bundle 行与浏览器 roster 在启动时组合)。刷新后, 当前会话工作区是 git 仓库时,输入框上方会出现 dock 胶囊,点击即可展开面板。

要求 dsh ≥ 0.1.5-rc.1(宿主半自持 /dsh-git-rpc 路由,见上文架构说明)。

卸载:

dsh plugin --profile web remove @dsh-plugins/dsh-git

RPC 约定(/dsh-git-rpc)

浏览器侧通过 ctx.connection.rpc.call("/dsh-git-rpc", endpoint, { args }) 调用;宿主侧 是本插件自持的 /dsh-git-rpc/* 前缀路由,收发与 /api 相同的 Connection 信封:

  • 请求:POST /dsh-git-rpc/<endpoint>,content-type: application/json, { type: "client-request", rpcId, method: <endpoint>, payload: { args } }
  • 响应:{ type: "server-response", rpcId, result: { ok: true, value } | { ok: false, error } }
  • 围栏:connection.requestRejection(Host/Origin + 浏览器会话 Cookie);非 POST → 405, 非 JSON → 415,请求体超限 → 413,路径不属于本通道 → 404。

载荷使用 { args } 约定。cwd 必须是绝对路径;branch 匹配 ^[A-Za-z0-9][A-Za-z0-9._/-]*$(不允许前导 -、..、@{、\、空白、 控制字符);remote 为普通单段。提交信息是真正的提交信息:一行主题 + 可选的多行正文。CRLF 会归一为 LF,逐行去掉行尾空白,去掉首尾空行并把连续 空行折叠为一行(因此主题与正文之间那一行空行会保留);空、超长(>10000 字符)、含控制字符的信息报 invalid-message。信息经 stdin 以 git commit --cleanup=whitespace --file=- 传入,因此空格、引号、换行、shell 元字符、前导 - 都会被原样记录。

端点参数结果(value)
status{ cwd }{ repo, branch, detached, oid, upstream, ahead, behind, dirty, changes: [{status, path, index, worktree, file, origFile}] }。path 是展示串(重命名读作 old → new),file/origFile 是交给 diff 的 pathspec,index/worktree 是 porcelain-v2 的两个字母。
branches{ cwd }{ repo, current, local: [{name, current, upstream, sha}], remote: [{name, short}] }
checkout{ cwd, branch }{ branch, detached, oid, message? },经 git switch --guess;浏览器会预检脏树并提前警告;因"本地修改会被覆盖"被拒绝时会带上可读前缀。
createBranch{ cwd, branch, base? }{ branch, detached, oid, message? },经 git switch --create <branch> <base>(缺省 base 即 HEAD);从基分支创建新分支并切换过去。
fetch{ cwd, remote? }{ message }(120s 超时)
pull{ cwd }{ message },经 git pull --ff-only(绝不隐式合并)
stage{ cwd }{ message },经 git add --all
diff{ cwd, path, origPath? }{ repo, path, origPath, untracked, skipped, worktree: {diff, binary, truncated}, index: {…} }。两侧一次读回(git diff [--cached] --no-ext-diff --no-color -- <path> [<origPath>]);path 必须是仓库内相对路径(拒绝绝对路径、..、前导 -、控制字符、首尾空白),非法时报 invalid-path。未跟踪路径用 git diff --no-index -- /dev/null <path>(容忍退出码 1),未跟踪目录用 git ls-files --others --exclude-standard 展开(上限 50 个,其余计入 skipped)。单侧超过 40 万字符在行边界截断并置 truncated;二进制置 binary。只读,不碰 index / 工作区 / 配置。
commit{ cwd, message };未配置 时报 错误

失败结果的 error.code 在线路上固定为 "internal"(Connection 信封只要求它是字符串), 插件自己的诊断码放在 error.details.code;客户端按该码做本地化文案。

设计决策与边界

  • pull 固定 --ff-only:不产生意外的合并提交;冲突以错误形式呈现, 由用户在自己的工具里解决。
  • commit 不暂存:只提交已暂存的内容。想一次提交全部改动,用提交区的 "暂存全部"按钮(git add --all),而不是让提交隐式暂存。
  • AI 生成会把改动的 diff 发给你配置的模型提供方——可能是第三方网关。 这是显式点击"✨ AI 生成"才会发生的联网行为;插件本身不联网。diff 截断到 12000 字符后发送,且不发送任何仓库外的内容。
  • push/pull 凭据来自系统(Git Credential Manager / SSH agent);插件 绝不碰凭据存储。AI 生成同样不接触凭据——API key 由模型适配器自己解析。
  • 插件绝不修改 git config;缺 author 时给出明确错误而不是悄悄补写。
  • 差异查看是纯只读的:diff 端点只跑 git diff / git ls-files,不写 index、不动工作区、不改配置;它不依赖宿主右侧 Sidebar 那套标签页 API (那部分还在快速迭代),而是面板内自带两栏——左侧工作台照旧,右侧差异栏。 差异渲染也是自己写的(本 bundle 只依赖 react):解析统一 diff、双行号、 +/- 配色,不引任何语法高亮依赖。
  • 重命名必须同时传旧名与新名:git 只在旧名也在 pathspec 里时才配对,只给 新名会把一次重命名报成整文件新增(test/diff.mjs 守护这一点)。
  • status 的 porcelain-v2 解析:2(rename/copy)记录的路径在第 10 个字段、 与旧名以 TAB 分隔,u(冲突)记录的路径在第 11 个字段且状态恒为冲突——这 两处曾按 slice(8) / slice(9) 取值而错位,现在由 changeEntry() 统一构造。
  • 插件不导入任何 @deepseek-ai/* 运行时包(只用 node: 内置模块和 @deepseek-ai/cordis)。以 pnpm link: 方式安装时,宿主包无法从插件的真实 源码路径解析,声明这类导入会让插件在加载期就崩溃;生成所需的请求构造与流 式拼装因此就近实现。test/generate.mjs 直接测这些单元。
  • 面板操作是普通 UI 行为(和 Cordis 面板一样),不会写入会话日志 / 模型提示词。AI 生成只填输入框,不会自动提交。

开发说明

  • 浏览器 bundle 为手写(无构建步骤);改 lib/client.js 刷新即生效 (no-cache),改宿主半需要重启 dsh web。
  • 测试:
    • node test/smoke.mjs —— 路由/信封/端点分发/入参校验(不 spawn git:会话沙箱 拦截子进程管道 stdio);
    • node test/host-mount.mjs —— 在真实 Cordis + 真实 dsh-client-connection 上挂载插件行(从 DSH_HOME 的 profile 解析 DSH 包,找不到则 SKIP);
    • node test/generate.mjs —— AI 生成单元测试:路由解析、prompt 组装、截断、 流式拼装(block-end 与纯 delta 两条路径)、终止失败/取消/空输出;
    • node test/render.mjs —— 双界面真实 React SSR 渲染,含提交区三个控件、 diff 解析器(行号 / 分类 / -- 开头的删除行)、行渲染、差异面板标题栏与 act() 的结果回传/本地化(需要一份 react/react-dom,可用 DSH_GIT_REACT_ROOT 指定,找不到则 SKIP)。
    • 也提供 npm test(依次跑四个)。
    • npm run test:commit —— 端到端:在临时仓库里真起 git,走插件的 /dsh-git-rpc/commit 路由提交,再用 git log --format=%B 逐字节比对提交 信息(多行、CRLF、中文、前导 -、shell 元字符等),并确认非法信息被拒且 不产生提交。
    • npm run test:diff —— 端到端:临时仓库里逐个验证 diff 端点:工作区 / 已暂存两侧、未跟踪文件与未跟踪目录、重命名配对、删除、二进制、 40 万字符截断、以及路径校验与非仓库目录。
    • 后两个都必须 spawn git 的管道 stdio,故不在 npm test 内——请在没有 该限制的环境(普通终端)单独运行。 git 命令集对照运行中的服务端做端到端验证。
{ message }
user.name/email
missing-author
push{ cwd }{ message }(120s 超时)
log{ cwd, count? }{ repo, commits: [{sha, author, subject, refs}] }(钳制 1..50)
generateMessage{ cwd, mode?, provider?, model? }{ message, mode, provider, model }。mode 为 staged(默认)/unstaged/all,非法值报 invalid-mode;失败码见 error.details.code:no-changes、no-provider、no-model、llm-empty、cancelled、llm-failed。