@bainianzzz/dsh-fork-worktree
Manifest validDeepSeek Harness plugin: fork a workspace row into a git worktree, or delete the workspace folder
dsh-fork-worktree
给 dsh 侧边栏的工作区行加两个按钮(在 … 和 + 之间,fork 在左、垃圾桶在右):
- fork:确认后基于该工作区所在的 git 仓库建一个新 worktree,并把 worktree 目录注册成新的 dsh 工作区(并在新工作区里开会话)。
- 垃圾桶:确认后删掉该工作区的目录,并移除它的登记。
两个按钮都不会在点击时直接动手,都必须先在弹窗里确认。
位置与实现
- 两个按钮都只在行 hover 时显示(和
+一样)。 - dsh 的工作区行没有 slot 扩展点(
…、+都是 ui-workspace 写死的行内 UI),所以按钮是通过shell.overlay里挂一个 React 组件、再用createPortalportal 进行动区的(见client.js的WorkspaceRowActions)。用data-row-key="workspace:<id>"找行、data-slot="sidebar.workspaces"作为只监听侧边栏的 MutationObserver 根(不监听整帧,流式输出不会触发重扫)。 - 图标取自 Lucide(ISC):fork 用
git-fork(v1.57.0),垃圾桶用trash的无竖线画法(v0.400.0)、描边 1.8 —— v1.57.0 里trash与trash-2的 path 相同,那两道内线在 16px 下挤成一块、看着比 fork 粗,所以取无竖线版本并把描边调到 1.8,两个图标视觉粗细一致(约 1.2px)。都按原样的 24 单位 viewBox、currentColor、round caps/joins 内联在client.js里(本 bundle 不引入图标包),显示尺寸 16px。 - 风险:dsh 改版若改了这两个 DOM 钩子,按钮会消失(不会报错);那时需要跟着改选择器。
fork 流程
- 点 fork:只弹确认框。
- 确认 →
POST dsh-fork-worktree/fork {source, init:false}(Host 的forkRoute):- 是 git 仓库 →
git worktree add -b wt/<label> <仓库名>-wt-<label> HEAD,注册工作区。 - 不是 git 仓库 → 返回
not-a-git-repo,同一个弹窗切成"初始化"模式。
- 是 git 仓库 →
- 初始化模式确认 →
init:true:git init+ 把目录当前内容提交成第一个提交(空目录则空提交),再建 worktree。 - 成功 →
ctx.workspaces.create({path})(幂等,把新工作区并进 Client 模型)→ctx.uiWorkspace.startSession(id)在新工作区打开会话 → toast 显示路径。
/fork-worktree [name] [--init] 命令是同一套逻辑的第二个入口,可在该工作区的会话里手敲。
垃圾桶流程与删除语义
- 点垃圾桶:只弹确认框,写明将删除的确切路径(还会写明会话记录保留)。
- 确认 →
POST dsh-fork-worktree/remove {source, force:false}(Host 的removeRoute→removeWorkspaceFolder):- linked worktree(
.git是文件)→ 走git worktree remove,仓库的worktrees/元数据跟着走(不留脏数据)。 - 有未提交修改或未跟踪文件 → 返回
worktree-dirty,弹窗切成"强制删除"模式,再确认才--force。 - 其他目录 → 直接
rm -rf。 - 删完移除工作区登记;即使这一步失败,2 秒后的扫描也会把登记收掉。
- linked worktree(
- 护栏:拒绝删除
$HOME和文件系统根;目录不存在/不是目录都返回明确错误码。 - 删除故意没有命令入口:命令会默认取当前会话的工作区,删掉自己正在用的目录不该只是一条命令的距离。
worktree 命名
- 目录:与仓库根同级,
<仓库名>-wt-<label>;label是<name>(若给)或 6 位随机 hex。 - 分支:
wt/<label>,基于当前 HEAD。
工作区自动消失
Host 每 2 秒扫一次注册表(watchRemovedWorktrees):
- 目录存在且
.git是文件(linked worktree)→ 记为跟踪对象。 - 被跟踪对象连续两次扫描都目录缺失 → 静默删除该工作区注册(不动文件和会话,不报错)。
- 进程重启后不丢:目录已消失、但名字是
*-wt-<6位hex>,或同级还有同名仓库目录时,同样会被清掉。 - 不动普通目录、不动
bg-switcher--worktrees/xxx--worktree这类别的命名。
开发迭代
改 Host 侧(impl.js)后,让这一行重新加载即可,不用重启 dsh:插件页把 fork-worktree 关掉再打开,或调 plugin_manager 的 set_plugin(target: include:fork-worktree,先 enabled:false 再 enabled:true)。
原理:ES 模块按解析后的 URL 缓存,所以 Loader 那一行导入的 index.js 是个极小且不再改动的壳,它的 apply 里用 ?load=<时间戳> 动态 import 真正的实现 impl.js——每次重新加载都拿到新副本。
client.js 改了要刷新页面(F5)才生效。bundle 是 link: 安装时,pnpm 层面不用重装。
node verify-host.mjs:不依赖 dsh 的 Host 侧验证(61 项),覆盖 worktree 创建/分支/初始化、两种删除(worktree / 普通目录)、dirty 拒绝与强删、路径护栏、两个路由的信任校验与 JSON 契约、以及自动清理的各分支。临时仓库建在系统临时目录并在结束时删除,不会污染本目录。
安装
dsh plugin add github:Bainianzzz/dsh-fork-worktree
或者用 GitHub Release 上的预构建 tarball:
dsh plugin add https://github.com/Bainianzzz/dsh-fork-worktree/releases/latest/download/dsh-fork-worktree.tgz
装好后侧边栏的工作区行 hover 即出现两个按钮。本插件只用 Node 内置模块,不需要构建授权。
文件
index.js:包入口,也是 Loader 那一行导入的壳(name/inject/apply)。impl.js:Host 实现——createWorktreeFork、removeWorkspaceFolder、两个路由、/fork-worktree命令、工作区清理扫描。client.js:浏览器侧——工作区行两个按钮(React portal)、四种弹窗、toast。cordis.patch.yml:bundle 的 patch,插入 id 为fork-worktree的这一行。verify-host.mjs:Host 侧离线验证脚本。- 依赖:只用 Node 内置模块,不 import 任何
@deepseek-ai/*包,所以dependencies与peerDependencies都是空的。
Comments
Loading…
From the same category
by ccch1mneyyy
DSH 官方公众号收录的 TUI 补位插件:Claude Code 风,鲸鱼顶栏/实时状态/流式思考/双击 Esc 回滚/上下文进度+TPS。npm 一键装。 DSH official WeChat featured TUI plugin — Claude Code style: whale bar, live status, streaming thoughts, double-Esc rol
★ 4.6k
↓ 11.9k/wk
MIT
TypeScript
Oct 16, 2026
dsh plugin --profile terminal add @deepseek-harness-tui/dsh-tuiby strukto-ai
The World's First Virtual Terminal for AI Agents
★ 3.7k
↓ 374/wk
Apache-2.0
TypeScript
Oct 16, 2026
dsh plugin --profile agent add @struktoai/mirage-dshby bowenliang123
The best DeepSeek Harness plugin for context insight and management, with context dashboard / browser / sidebar and context command, for context statistics, composition, breakdown, evolution details,
★ 2.2k
↓ 52.1k/wk
Apache-2.0
TypeScript
Oct 16, 2026
dsh plugin --profile web add dsh-contextby huiliyi37
官方 DeepSeek Harness 的交互式终端 UI 插件:自研 ANSI 极简交互渲染、流式 Markdown/工具卡、16+ 主题、slash 命令与选择器、输入历史与本地偏好持久化、LSP 诊断、memory记忆,很丝滑的开发体验。
★ 286
↓ 486/wk
Apache-2.0
TypeScript
Sep 30, 2026
dsh plugin --profile terminal add @huiliyi37/dsh-tianshu-tuiby Hilbert-beinghappy
面向 DeepSeek Harness 的 Claude Code 风格终端界面,支持 Windows、macOS 与 Linux,兼容透明终端、VS Code 主题和自定义配色。
★ 196
↓ 108/wk
MIT
TypeScript
Oct 13, 2026
dsh plugin --profile web add seekttyby c3cvld7aag
富江DSH完美破甲|富江破甲 DSH 本地插件,内置提示词规则,支持 Windows 一键安装、环境自动准备与一键卸载,全中文使用说明。
★ 94
JavaScript
Oct 3, 2026
dsh plugin --profile web add fujiang-armor