dsh-git-forge
项目级 Git 凭据:forge 账号(GitHub、Gitea、GitLab、Bitbucket 或自定义域名)在右侧栏「Git 凭据」标签页里管理并可按项目授权,再由生成的凭据 helper 交给 agent 走 HTTPS 推送,token 不进对话;未授权 host 的推送会被拦截器直接拒绝。
安装
dsh plugin --profile web add dsh-git-forge
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
<p align="center"><strong>简体中文</strong> | <a href="README_en.md">English</a></p>
<div align="center">
<img src="https://raw.githubusercontent.com/OMSociety/dsh-git-forge/main/docs/logo.png" alt="DSH Git Forge" width="160">
<h1>DSH Git Forge</h1>
<p>DeepSeek Harness 的 Git 凭据与推送权限管理器:哪个项目能用哪个账号、允许推到哪些 host,一处说清。</p>
<p>账号库与 token 只落在宿主侧。<strong>按项目授权</strong>决定 agent 用哪个账号,<strong>push 拦截</strong>决定这个项目允许推到哪。</p>
<p>
<a href="https://www.npmjs.com/package/dsh-git-forge"><img src="https://img.shields.io/npm/v/dsh-git-forge?label=version&color=4f6ef7" alt="Version"></a>
<a href="https://github.com/deepseek-ai/dsh"><img src="https://img.shields.io/badge/DSH-%3E%3D0.2.0--rc.2_%3C0.3.0--0-4f6ef7" alt="DSH"></a>
<a href="LICENSE"><img src="https://img.shields.io/github/license/OMSociety/dsh-git-forge?color=4f6ef7" alt="License"></a>
<a href="https://github.com/OMSociety/dsh-git-forge/stargazers"><img src="https://img.shields.io/github/stars/OMSociety/dsh-git-forge?color=4f6ef7" alt="Stars"></a>
<a href="https://github.com/OMSociety/dsh-git-forge/issues"><img src="https://img.shields.io/github/issues/OMSociety/dsh-git-forge?color=4f6ef7" alt="Issues"></a>
</p>
<a href="#这是什么">这是什么</a> • <a href="#核心特性">核心特性</a> • <a href="#效果">效果</a> • <a href="#安装方式">安装方式</a> • <a href="#侧栏">侧栏</a> • <a href="#模型工具">模型工具</a> • <a href="#数据放在哪">数据放在哪</a> • <a href="#安全">安全</a> • <a href="#环境要求">环境要求</a> • <a href="#开发">开发</a> • <a href="#支持与致谢">支持与致谢</a> • <a href="#许可证与作者">许可证与作者</a>
</div>
这是什么
DSH Git Forge 是 DeepSeek Harness 的社区插件,在 DSH 官方右侧栏里给你一个 Forge 账号库 + 按项目授权 + 推送策略 的管理面。
它管两件事:
- agent 用哪份凭据:在侧栏给项目授权账号之后,agent shell 里的 HTTPS
git fetch/git push由本插件的 credential helper 自动取用对应 token,token 只在宿主侧读,不进模型上下文。 - 这个项目允许推到哪:未授权 host 会被 push 拦截器在工具层直接拒绝;裸
git push与git push origin会先解析 remote URL 再判定。
SSH 远程与系统 gh auth 不受影响,仍走本机 SSH / gh;本插件只补 DSH agent shell 下的 HTTPS 这一段。
核心特性
特性 · 说明
账号库 · 账号按 gitHost 归集,界面给出 github.com / gitee.com / gitlab.com / bitbucket.org 常用选项,自建 Forge 直接填自己的域名;侧栏内可增删改并探测 API token
按项目授权 · 授权 key 是 DSH 会话工作区(projectPathKey,agent shell 里即 DSH_GIT_FORGE_PROJECT),不是子仓路径
push 拦截 · 命令里的 URL、裸 git push、git remote add / set-url 都在 Host tools.guard 里按授权判定
agent HTTPS git · 同一 host 恰好 1 个已授权 token 账号时(R1)helper 才自动注入;多账号时不猜号,宁可不注入
token 落盘 · $DSH_HOME/git-forge/secrets.json(0600);API 与工具结果一律不回传 token
模型工具 GitForge · 四个只读动作:看账号库、看某项目授权、看策略、校验某个 remote 是否被允许
UI 对齐 · 与同门的 dsh-ssh-tunnel 共用一套侧栏交互
效果
<table>
<tr>
<td width="55%" align="center"><a href="https://raw.githubusercontent.com/OMSociety/dsh-git-forge/main/docs/panel-grants.png"><img src="https://raw.githubusercontent.com/OMSociety/dsh-git-forge/main/docs/panel-grants.png" alt="侧栏项目授权页:勾选本项目可用的 forge 账号,并决定是否启用 push 拦截" width="560"></a></td>
<td width="45%" align="center"><a href="https://raw.githubusercontent.com/OMSociety/dsh-git-forge/main/docs/panel-policy.png"><img src="https://raw.githubusercontent.com/OMSociety/dsh-git-forge/main/docs/panel-policy.png" alt="侧栏策略状态页:当前项目允许的 gitHost 与未绑定项目的全局策略" width="460"></a></td>
</tr>
<tr>
<td align="center">项目授权:勾选本项目可用的 forge 账号,并决定是否启用 push 拦截</td>
<td align="center">策略状态:当前项目允许的 gitHost,以及未绑定项目的全局策略</td>
</tr>
</table>
安装方式
从 npm 安装
# 先停掉正在运行的 DSH(运行中的服务会锁住依赖,装完再起) dsh plugin --profile <profile> add "dsh-git-forge"
提示:装好后刷新一下浏览器页面,「Git 凭据」从右侧栏的引导页打开——只重启宿主不够,客户端产物是页面加载时取的。
装完怎么用
1. 打开右侧栏「Git 凭据」→ 账号库 加一个账号(token 只在侧栏里填,不进对话)
2. 点探测确认这个 token 有效
3. 切到 项目授权 → 勾上该账号并保存,当前工作区就拿到了推送凭据
4. 让 agent 在项目里跑 HTTPS 的 git fetch / git push,凭据由 helper 自动注入,模型看不到 token
5. 反过来试一个未授权的 host:让 agent 推过去,应当被 push 拦截器直接拒绝
侧栏
侧栏只有一个 Tab,内部三页:
页面 · 作用
项目授权 · 当前项目可用的账号,以及是否 enforcePush
账号库 · 账号增删改、探测 API token、查看绑定的 gitHost
策略状态 · 当前允许的 gitHost,以及未绑定项目的默认策略
模型工具
动作 · 作用 · 参数
GitForge action=list_accounts · 列出账号库(不含 token) · 无
GitForge action=list_project_accounts · 列出某项目已授权的账号 · project_path
GitForge action=get_policy · 看该项目策略:授权账号、是否 enforcePush、未绑定项目默认 · project_path
GitForge action=check_remote · 校验某个 remote URL 是否被允许推送(不推送) · url(必填)
Agent HTTPS 与项目路径
- 授权 key = DSH 会话工作区(agent shell 里注入
DSH_GIT_FORGE_PROJECT),不是子仓路径;工作区路径按磁盘实态归一(realpath),Windows 8.3 短名与符号链接折叠到同一 key - helper 找项目:
env→ cwd 精确匹配 → 向父目录 walk(cwd 在/workspace下时上界为/workspace,否则走到根) - R1:同一 host 仅当恰好 1 个已授权 token 账号时才自动注入凭据
- agent shell 的
GIT_CONFIG_GLOBAL指向$DSH_HOME/git-forge/gitconfig;文件第一行include回接你的用户级 gitconfig(user.name/user.email/http.proxy等照常生效),随后一条空credential.helper清掉系统级 helper,再挂本插件 helper——系统凭据管理器的弹窗不会卡住无头 shell,用户自己配的 helper 也会被同样清掉
数据放在哪
$DSH_HOME/git-forge/(目录 0700;0600/0700 权限仅在 POSIX(Linux/macOS)生效,Windows 无等效收紧):
文件 · 内容
accounts.json · 账号元数据(不含 token)
secrets.json · token(0600)
grants.json · projectPathKey → accountIds[] 与 enforce / unbound 策略
gitconfig · 注入给 agent shell 的 credential helper 配置(不含凭据)
注意:accounts.json/secrets.json/grants.json若解析失败,坏文件会被改名保留为<原名>.corrupt-<时间戳>并回退默认值,不会覆盖丢失现场。
安全
- token 不出现在 API 结果、工具结果与模型上下文里
- push 策略在 Host
tools.guard中硬拦截,不依赖模型自觉 - 未给项目配置任何授权时,push 拦截器默认不拦截(便于渐进启用),helper 也不会凭空给出凭据
- token 只落在宿主侧数据目录
secrets.json;helper 是由 git 拉起的独立进程,按需读取;token 不进模型上下文。secrets.json疑似泄露请立即轮换 token - 侧栏 API 做同源校验:
Sec-Fetch-Site: cross-site一律拒绝;请求缺该头时校验Origin与Host是否一致,不一致拒绝;两者皆缺的非浏览器客户端放行(宽松策略) - push 检测基于命令文本启发式,已知绕过面(env 变量改名 git、git alias、路径经变量拼接、非 bash/sh 包装器、
time/nice等未覆盖前缀);这一边界是明示的检测口径,不是放行依据 - 配置了授权的项目里,裸
git push的 remote 解析失败会重试一次,仍失败即拒绝(fail-closed)
环境要求
- DSH profile(desktop 与服务器自建均可),DSH 版本 `>=0.2.0-rc.2
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:6,最后更新 2026-11-01