dsh-git-workspace
面向 DeepSeek Harness(DSH)Web UI 的单 workspace 多 Git 仓库工作台。
一个 DSH workspace 下可以同时发现和维护多个彼此独立的 Git 仓库,并在同一界面完成状态查看、暂存、提交、历史查看、分支与 Remote 维护、Fetch、Pull、Push 和批量网络操作。Remote 可按实际目标主机选择代理、直连、继承 Host 环境或阻止访问。
支持 DSH >=0.2.0-rc.2 <0.3.0-0(插件源码版本 0.3.2)。升级前必须核对旧设置数据;详情见 0.2.1 迁移说明。
兼容性完整复查见 DSH 0.2.1 兼容性审计,包含已核对接口、已修复的测试和仍需运行的验收项目。
最新版本适配(0.3.2)
目标版本为 DSH 0.2.1-rc.2(官方标签 dsh-v0.2.1-rc.2,提交 687f282e)。
- 通信服务优先读取新版
browserPeer(浏览器连接主体),兼容旧版 operator(操作主体),避免请求携带空主体。
- 真实浏览器通信测试按包导出的
browser 条件选择入口,兼容新版服务器模块与浏览器模块分离的发布结构。
- 开发依赖固定为已发布的
0.2.1-rc.1,Cordis 为 4.0.5,Schemastery 为 3.18.5;附带重新生成的锁文件。核对时 rc.2 的依赖包尚未同步至包仓库;本插件使用的接口源码在 rc.1 与 rc.2 标签间没有差异。
- 保留宿主兼容范围
>=0.2.0-rc.2 <0.3.0-0,没有提高最低版本。
- 已通过新版依赖下的全部 87 项测试、类型检查、构建和构建产物冒烟检查;最低版本另执行关键接口验证,详见 本次适配说明。完整桌面端和网页宿主人工验收仍需在实际使用环境完成。
升级源码目录后执行:
pnpm install --frozen-lockfile
pnpm check
node scripts/smoke-built.mjs
dsh plugin --profile web add ./
安装或更新后,支持热重载的环境按 DSH 提示刷新或重新加载;若提示无法热重载则重启。已有安装目录必须先更新源码并重新安装依赖、构建,单纯停用再启用插件不会替代这些步骤。
当前兼容基线
- 最低宿主版本:DSH
0.2.0-rc.2;本次目标:0.2.1-rc.2。
- 网络设置入口:插件管理 →
dsh-git-workspace 详情页,配置绑定 git-workspace 条目。
- 使用可动态编辑的配置引用和插件配置扩展点;不会调用已移除的
ctx.settings.register。
- 新版 DSH 优先按顶层
engines.dsh(宿主版本声明)判断兼容性;旧版还会校验 DSH 宿主依赖,两个声明范围保持一致。
能力
- 在当前 DSH workspace 内有限深度扫描多个独立 Git 仓库。
- 仓库总览:分支、ahead/behind、staged/unstaged、冲突和 Remote 数量。
- 文件级 Diff、Stage、Unstage、Stage All、Unstage All。
- Diff 使用带新旧行号、hunk 和增删颜色的可读视图;未跟踪新文件直接展示新增内容。
- Commit 只提交 staged 内容,绝不隐式执行
git add -A。
- 最近 100 条提交记录,并可查看完整消息、作者、时间、父提交、变更文件及每个文件在该提交中的 Diff。
- 本地与 Remote 分支分组展示;选择 Remote 分支时明确创建同名本地跟踪分支。支持分支创建和安全删除(
git branch -d)。
- Remote 添加、删除和 Fetch URL 修改。
- Fetch、Pull、Push 独立操作;Pull 使用
--ff-only --no-rebase --no-autostash,允许不冲突的本地修改。
- 工作台、Diff、批量弹窗和网络设置跟随 DSH 亮色/深色主题及其颜色变量。
- 批量 Fetch/Pull 最多 4 个仓库并行,Push 顺序执行;弹窗内实时显示等待、执行中、成功、失败和阻止状态,并可仅重试失败项。
- 仓库批量范围支持全选、反选和逐项选择。
- 仓库栏、主操作区和 Diff/提交详情栏之间可拖拽调整宽度;详情栏未使用时不占空间。
- DSH 插件管理(旧版称 DSH Settings)内的简化代理配置:走代理、强制直连、禁止访问三组主机列表。
- Fetch URL 与 Push URL 分别决策;代理失败不会静默回退直连。
- Windows、macOS 和 Linux 的 Node.js 原生子进程调用,不经 shell 拼接用户输入。
环境要求
- DSH
>=0.2.0-rc.2 <0.3.0-0;本次核对的官方源代码提交为 687f282e。
- Node.js
^22.19.0 或 >=24;pnpm 11.7.0。
- Git 命令行;建议 Git
>=2.31(代理策略依赖 git --config-env)。
@deepseek-ai/schemastery 精确版本 3.18.5,使用随包提供的新锁文件。
安装和本地验证
在本仓库目录中执行:
pnpm install --no-frozen-lockfile
pnpm check
node scripts/smoke-built.mjs
dsh plugin --profile web add ./
pnpm check 依次执行类型检查、单元与集成测试、打包;smoke-built.mjs 则直接导入构建后的宿主模块并验证前端模块注册格式。
构建后包含:
lib/index.js # DSH Host 插件入口
lib/client.js # DSH Web 客户端入口
安装到隔离测试配置(例如 test)时可将 web 替换为 test,具体以已创建的 profile 为准;直接运行 dsh plugin add ./ 在需要 --profile 的发行版中会被拒绝。
升级原源码目录时,先备份 profile 的配置文件。现有 Git 工作区不会被清空,但旧 settings.yaml 中的代理策略不能保证自动迁移。详细说明见 升级迁移。
使用
插件加载后,DSH 左侧原生全局面板列表中出现“Git 工作台”入口,折叠侧栏时显示图标。入口排序由 DSH 管理,不再依赖其他插件的 DOM 结构。
- 点击“Git 工作台”。
- 选择 DSH workspace;插件会扫描其中的 Git 仓库。
- 在左栏选择仓库,在中栏查看修改、历史或 Remotes;批量范围可使用全选和反选。
- 修改文件时,先明确 Stage,再填写提交信息并确认 Commit。
- Fetch、Pull、Push 都有独立入口;批量操作在同一弹窗完成预检、实时进度和失败重试。
- 点击“关闭并返回会话”返回 DSH 当前会话。导航由 DSH 原生 layout 管理,不改变当前 Session 身份;页面挂载与卸载遵循 DSH 原生 main slot 生命周期。
工作台每次打开都会重新读取 DSH 的 workspace 注册表,因此刚新增但尚未创建会话的 workspace 也会出现在选择器中;打开期间列表每 5 秒同步一次。
更完整的操作说明见 docs/USAGE.md。
Remote 代理设置
进入:
DSH 左侧 Plugins(插件管理)→ dsh-git-workspace → Git 工作台网络
配置项:
| 配置 | 作用 |
|---|
| 代理地址 | HTTP(S) 代理,例如 http://127.0.0.1:7890;按 secret 处理,保存后不回显 |
| 走代理的主机 | 命中后为本次 HTTP(S) Git 子进程注入代理 |
| 强制直连的主机 | 清除本次子进程继承的代理环境并覆盖 Git HTTP proxy |
| 禁止访问的主机 | 在启动 Git 网络命令前阻止 |
| 未命中时 | inherit、direct 或 block |
每行一个主机,也可用逗号分隔。支持 * 通配符:
github.com
*.githubusercontent.com
git.company.local
决策优先级固定为:
禁止访问 → 强制直连 → 走代理 → 默认动作
示例:
github.com 放入“走代理的主机”。
git.company.local 放入“强制直连的主机”。
- 默认动作选择“阻止访问”,使未知目标失败关闭。
代理只作用于当前一次 Git 子进程,不写 git config --global,也不修改仓库配置。当前版本只为 HTTP(S) Remote 注入 HTTP 代理;SSH Remote 可继承、直连或阻止,但不会把 HTTP 代理错误套到 SSH 上。
安全语义
- 浏览器 RPC 只传
workspaceId 和 repoId,不传可执行绝对 cwd。
- Host 通过 DSH
workspaceRegistry 解析 workspace,并用 canonical path 验证仓库仍位于 workspace 内。
- 文件操作只接受当前
git status 中实际出现的路径。
- Git 通过
spawn('git', args, { shell: false }) 执行,分支、路径、URL 和提交信息不进入 shell 字符串。
- Commit 不会自动暂存。
- Pull 允许不妨碍快进的本地修改,使用
--ff-only --no-rebase --no-autostash;覆盖风险、已有冲突或分叉时停止。失败时 fetch 可能已更新远端跟踪引用,本地内容和 HEAD 由 Git 原生保护,不自动 stash、merge 或 rebase。
- 代理凭据使用 DSH settings secret 字段;浏览器读取不到保存值。
- 代理或认证失败不会自动尝试直连。
- 插件 RPC 使用
/api/git-workspace/<endpoint> 精确路由,不会与 DSH API Gateway 的共享 /api interceptor 冲突。
详细边界见 docs/SECURITY.md。
扫描规则
默认从 workspace 根目录扫描 4 层,识别 .git 目录和 worktree/submodule 使用的 .git 文件。以下目录默认跳过:
.git node_modules .pnpm-store .cache .next .nuxt .turbo
dist build coverage target vendor .venv venv __pycache__
Host 会对候选目录运行 git rev-parse --show-toplevel,canonical path 去重后再生成稳定 repoId。符号链接目录不会被递归跟随。
扫描深度和额外忽略目录属于插件 settings schema,默认安装无需配置。
批量操作
批量操作分为两段:
- 客户端预检:无 Remote、存在未解决冲突的 Pull、Detached HEAD、未发布 Push 等会被标为“阻止”。
- 客户端发起单仓库操作:Fetch/Pull 使用最多 4 个 worker 并行,Push 保持顺序执行;当前行显示“执行中”,完成后立即在列表右侧显示“成功”或“失败”,阻止项不会发送请求。
弹窗在执行期间保持打开且不能误关闭;完成后可关闭,失败项可单独重试。工作台不再提供独立“操作中心”。
Git 不提供跨多个独立仓库的原子事务,本插件不会在部分成功后尝试危险的自动回滚。
开发与验证
pnpm typecheck
pnpm test
pnpm build
一次执行全部门禁:
pnpm check
测试包含:
- Porcelain v2 状态解析。
- Remote URL 与代理策略匹配。
- 临时 Git 仓库集成测试:多仓库发现、staged-only commit、unborn branch unstage、过期路径拒绝、Remote 分支跟踪切换、非首条提交详情和提交文件 Diff。
- Host/Client 独立 RPC channel 契约,防止回退到共享
/api interceptor。
- Fetch/Pull 并发与批量实时进度、workspace 重新同步、可调整栏宽、本地/Remote 分支切换、工作区/历史提交文件 Diff 和可读 Diff 行号。
源码结构
src/
├── index.ts Host 插件入口、Settings 与 RPC
├── host/
│ ├── repository-service.ts 仓库注册表和 Git 业务语义
│ ├── git-process.ts 无 shell 的 Git 子进程封装
│ ├── proxy-policy.ts Remote 主机决策和单进程代理注入
│ └── status-parser.ts porcelain v2 -z 解析
├── client/
│ ├── index.tsx Web 客户端入口
│ ├── Workbench.tsx 多仓库工作台
│ ├── DiffViewer.tsx 带行号和增删语义的 Diff 视图
│ ├── CommitDetailView.tsx 提交详情与变更文件
│ ├── NetworkSettingsCard.tsx DSH Settings 卡片
│ ├── native-panel.tsx 原生面板图标与 main slot 内容
│ └── panel-controller.ts 工作台显示生命周期
└── shared/protocol.ts Host/Client 共享协议
完整架构和 UCD 见 docs/DESIGN.md。
已知边界
- 不提供交互式凭据输入;凭据由 Git credential helper、SSH agent 或系统凭据管理器处理。
- HTTP 代理不转换 SSH Remote;结构化
ProxyJump 不在当前版本范围内。
- 不自动执行 merge、rebase、force push、hard reset、clean 或冲突解决。
- Diff 主要面向文本差异;未跟踪普通文件会生成 new-file patch,二进制文件只展示 Git 可提供的元数据。
- 左侧主入口使用与 dsh-web“任务看板”相同的宿主适配方式;当 DSH 提供正式 workspace 级导航 slot 后,只需替换该适配层。
设计参考
License
Apache-2.0。第三方实现模式的来源说明见 NOTICE。