🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

分支工作台 ryanportfolio/dsh-branchline

DeepSeek Harness
ryanportfolio12 天前有提交已提供中文文档扫描:含敏感能力

DSH Branchline 是面向 DeepSeek Harness 的人工操作 Git worktree…

30.6/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ryanportfolio/dsh-branchline
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · dev
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/11/02·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 12 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/11/2) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-branchline(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 07:37:16

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 53 处,展示前 53 条)
  • 执行外部命令来自配置/变量
    packages/dsh-command-guard/lib/inspector-worker.js:23
    const child = spawn(exe, ['-NoLogo', '-NoProfile', '-NonInteractive', '-File', helper, '-Serve'], { windowsHide: true, stdio: ['pipe', 'pipe', 'ignore
  • 读取本地文件
    packages/dsh-command-guard/lib/policy.js:250
    try { lines = readFileSync(file, 'utf8').split(/ ? /) } catch (error) {
  • 执行外部命令来自配置/变量
    packages/dsh-command-guard/lib/policy.js:333
    execFile(exe, ['-NoLogo', '-NoProfile', '-NonInteractive', '-File', protector, '-ProcessId', String(pid)], { windowsHide: true, timeout: 60_000 }, (er
  • 发起网络请求
    packages/dsh-openrouter-route/lib/client.cjs:15
    const response = await fetch(ROUTE + "?op=status&model=" + encodeURIComponent(model), { method: "GET" });
  • 发起网络请求
    packages/dsh-openrouter-route/lib/client.cjs:30
    const response = await fetch(ROUTE, {
  • 读取本地文件
    packages/dsh-openrouter-route/lib/index.js:96
    const raw = await readFile(statePath(), "utf8")
  • 写入本地文件
    packages/dsh-openrouter-route/lib/index.js:116
    await mkdir(dirname(statePath()), { recursive: true })
  • 写入本地文件
    packages/dsh-openrouter-route/lib/index.js:117
    await writeFile(statePath(), JSON.stringify(snapshot, null, 2), "utf8")
  • 发起网络请求
    packages/dsh-openrouter-route/lib/index.js:262
    const response = await fetch(`${UPSTREAM}/models/${modelId}/endpoints`, {
  • 写入本地文件
    packages/dsh-openrouter-route/lib/index.js:548
    await mkdir(dshHomeDir(), { recursive: true })
  • 写入本地文件
    packages/dsh-openrouter-route/lib/index.js:549
    await appendFile(diagnosticsPath(), line, { encoding: "utf8", mode: 0o600 })
  • 发起网络请求
    packages/dsh-openrouter-route/lib/index.js:692
    upstream = await fetch(UPSTREAM + suffix + (url.search ?? ""), {
  • 发起网络请求
    packages/dsh-openrouter-sync/lib/client.cjs:15
    const response = await fetch(ROUTE, {
  • 发起网络请求
    packages/dsh-openrouter-sync/lib/client.cjs:34
    const response = await fetch(ROUTE + "?op=status", { method: "GET" });
  • 读取本地文件
    packages/dsh-openrouter-sync/lib/index.js:64
    const raw = await readFile(statePath(), "utf8")
  • 写入本地文件
    packages/dsh-openrouter-sync/lib/index.js:75
    await mkdir(dirname(statePath()), { recursive: true })
  • 写入本地文件
    packages/dsh-openrouter-sync/lib/index.js:76
    await writeFile(statePath(), JSON.stringify(state, null, 2), "utf8")
  • 发起网络请求
    packages/dsh-openrouter-sync/lib/index.js:295
    return fetch(ENDPOINT, {
  • 发起网络请求
    packages/dsh-rtk/lib/index.js:58
    return approval.approver.request({
  • 发起网络请求
    packages/dsh-session-delete/lib/client.cjs:16
    const response = await fetch(ROUTE, {
  • 读取本地文件
    packages/dsh-session-delete/lib/index.js:435
    parents = await readdir(sessionsRoot, { withFileTypes: true })
  • 读取本地文件
    packages/dsh-session-delete/lib/index.js:450
    children = await readdir(join(sessionsRoot, parent.name), { withFileTypes: true })
  • 读取本地文件
    packages/dsh-session-delete/lib/index.js:465
    entries = await readdir(candidate, { withFileTypes: true })
  • 删除本地文件递归
    packages/dsh-session-delete/lib/index.js:490
    await rm(dir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 })
  • 删除本地文件
    packages/dsh-session-delete/lib/index.js:494
    await rmdir(dirname(dir)).catch(() => undefined)
  • 读取本地文件
    packages/dsh-session-delete/lib/index.js:582
    const text = await readFile(filename, 'utf8')
  • 写入本地文件
    packages/dsh-session-delete/lib/index.js:588
    await writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`, 'utf8')
  • 写入本地文件
    packages/dsh-session-delete/lib/index.js:589
    await rename(temporary, filename)
  • 读取本地文件
    packages/dsh-session-delete/lib/index.js:598
    return canonicalKey(await realpath(path))
  • 发起网络请求
    packages/dsh-session-extras/lib/client.cjs:16
    const response = await fetch(ROUTE, {
  • 发起网络请求
    packages/dsh-session-extras/lib/client.cjs:47
    const response = await fetch(DELETE_ROUTE, {
  • 发起网络请求
    packages/dsh-session-extras/lib/client.cjs:100
    const response = await fetch(OR_SYNC_ROUTE + "?op=costs", { method: "GET" });
  • 发起网络请求
    packages/dsh-session-pins/lib/client.cjs:15
    const response = await fetch(ROUTE, {
  • 读取本地文件
    packages/dsh-session-pins/lib/index.js:109
    raw = await readFile(STORE_FILE, 'utf8')
  • 写入本地文件
    packages/dsh-session-pins/lib/index.js:123
    await mkdir(STORE_DIR, { recursive: true })
  • 写入本地文件
    packages/dsh-session-pins/lib/index.js:125
    await writeFile(tmp, JSON.stringify(pins, null, 2) + '\n', 'utf8')
  • 写入本地文件
    packages/dsh-session-pins/lib/index.js:126
    await rename(tmp, STORE_FILE)
  • 发起网络请求
    src/client/api.ts:109
    const response = await fetch(url, { ...init, ...(signal === undefined ? {} : { signal }) })
  • 读取本地文件
    src/git.ts:248
    const topLevel = await realpath(topLevelRaw.stdout.trim())
  • 读取本地文件
    src/git.ts:250
    const commonDirectory = await realpath(isAbsolute(commonValue) ? commonValue : resolve(absolute, commonValue))
  • 读取本地文件
    src/git.ts:679
    const info = await lstat(absolute)
  • 读取本地文件
    src/git.ts:683
    hash.update(await readlink(absolute))
  • 读取本地文件
    src/git.ts:685
    for await (const chunk of createReadStream(absolute)) hash.update(chunk as Buffer)
  • 写入本地文件
    src/github.ts:157
    await mkdir(this.options.cloneRoot, { recursive: true })
  • 读取本地文件
    src/github.ts:232
    await access(path)
  • 写入本地文件
    src/manager.ts:164
    await mkdir(resolve(path, '..'), { recursive: true, mode: 0o700 })
  • 删除本地文件递归
    src/manager.ts:443
    await rm(task.path, { recursive: true, force: true, maxRetries: 2 })
  • 删除本地文件
    src/manager.ts:446
    await rmdir(dirname(task.path)).catch(() => undefined)
  • 读取本地文件
    src/manager.ts:571
    const actualPath = await realpath(task.path)
  • 读取本地文件
    src/manager.ts:881
    await access(path)
  • 读取本地文件
    src/store.ts:27
    const text = await readFile(this.filename, 'utf8')
  • 写入本地文件
    src/store.ts:43
    await mkdir(dirname(this.filename), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/store.ts:54
    await mkdir(dirname(this.filename), { recursive: true, mode: 0o700 })
扫描于 2026/11/4(1 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-commands@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-test-runtime@deepseek-ai/dsh-client-ui-conversation@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-ui-sidebar@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-invariants
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 创建隔离工作树
  • Windows启动器
  • 任务看板

为 DeepSeek Harness 提供全新隔离的工作树。Windows 启动器、任务看板、只读交接。

README

由 DeepSeek 最新模型翻译生成
DSH Branchline DSH Branchline 是面向 DeepSeek Harness 的人工操作 Git worktree 任务工作台。它会先 fetch origin,解析远程仓库当前的默认分支,再从该分支的精确 commit 创建任务。独立 checkout 随后会作为原生 DSH Workspace 与 Session 打开。 插件不注册模型工具,不修改 System Prompt,也不增加工具 Schema。工作台和 /worktree-studio 命令都不进入模型上下文,因此安装后不会增加 Prompt token,也不会改变前缀缓存行为。 界面截图 Worktree 任务工作台 验证与交付检查 适用场景 当用户希望同时打开并监督多个隔离编码会话,并由自己掌握最终交付决定时,可以使用 Branchline。它不是子代理编排器:插件负责创建检出目录和 Session,具体工作由用户或已有 Agent 工作流决定。 - 一个任务对应一个分支、linked worktree、DSH Workspace 和 Session。 - Base ref 留空时使用刚刚 fetch 的 origin 默认分支;特殊任务仍可显式指定 base ref。 - 侧边栏工作台集中显示多个仓库的提交、暂存、未暂存和未跟踪状态。
展开完整文档(README 剩余 1 节)
DSH Branchline

DSH Branchline 是面向 DeepSeek Harness 的人工操作 Git worktree 任务工作台。它会先 fetch origin,解析远程仓库当前的默认分支,再从该分支的精确 commit 创建任务。独立 checkout 随后会作为原生 DSH Workspace 与 Session 打开。

插件不注册模型工具,不修改 System Prompt,也不增加工具 Schema。工作台和 /worktree-studio 命令都不进入模型上下文,因此安装后不会增加 Prompt token,也不会改变前缀缓存行为。

界面截图

Worktree 任务工作台

验证与交付检查

适用场景

当用户希望同时打开并监督多个隔离编码会话,并由自己掌握最终交付决定时,可以使用 Branchline。它不是子代理编排器:插件负责创建检出目录和 Session,具体工作由用户或已有 Agent 工作流决定。

- 一个任务对应一个分支、linked worktree、DSH Workspace 和 Session。
- Base ref 留空时使用刚刚 fetch 的 origin 默认分支;特殊任务仍可显式指定 base ref。
- 侧边栏工作台集中显示多个仓库的提交、暂存、未暂存和未跟踪状态。
- 改动审阅包含有界 diff、stat 摘要和未跟踪路径。
- 验证结果绑定 SHA-256 token;token 覆盖 HEAD、Git 状态、tracked diff 字节和未忽略的 untracked 文件内容。
- 合并预检使用 git merge-tree,不修改目标 checkout 或 index。
- 默认关闭本地交付。任务分支会保留,供审阅和外部集成。
- 归档保留任务记录;丢弃必须明确确认任务 ID。
- 原子状态写入、跨进程变更锁和启动恢复标记会暴露中断操作。

环境要求

- DeepSeek Harness 0.1.0-rc.7 或兼容的 0.1.x 版本。
- 带标准本地 subprocess provider 的 DSH Web profile。
- Node.js 22.19.0 或更高版本。
- 支持 merge-tree --write-tree 的 Git;建议使用 Git 2.38 或更高版本。
- 至少包含一个提交的本地 Git 仓库。

安装

npm 包发布后安装预构建版本:

dsh plugin --profile web add dsh-branchline
dsh web

npm 发布前可以安装仓库构建:

dsh plugin --profile web add github:ryanportfolio/dsh-branchline
dsh web

本地开发时,在插件 checkout 中执行:

pnpm install
pnpm run build
dsh plugin --profile web add .

安装后,Web 侧边栏底部会出现 Worktree 任务入口。移除插件不会删除已管理的 worktree 或状态文件:

dsh plugin --profile web remove dsh-branchline

工作流程

1. 打开 Worktree 任务,选择已注册的仓库并新建任务——或在创建表单中把来源切换为 GitHub,从 gh 账号的仓库列表中挑选(或粘贴 owner/name 与 URL):Branchline 会在缺失时克隆仓库,已存在时复用本地检出。
2. Branchline 运行 git fetch origin --prune,读取远程仓库声明的默认分支,并记录对应的 remote-tracking commit。然后在 managed root 下从该 commit 创建 dsh/<task>-<id>。所选仓库的分支、index 和工作文件不会改变。
3. 插件把新路径注册为 DSH Workspace,在其中启动 Session,然后关闭工作台。在任何以仓库为工作区的 Session 里,composer 工具行的 worktree 按钮可以一键重复第 2–3 步。
4. 在该 Session 中完成并提交改动。工作台会报告 committed、staged、unstaged 和 untracked 状态。
5. 使用 查看改动 检查有界 diff。合并检查 仍可用于本地兼容性检查。
6. Review-only 模式保留分支和 worktree。通过常用 GitHub 流程推送或集成该分支。
7. 归档 会移除干净的 linked worktree 并保留记录。丢弃 只有在独立风险确认和 Host 端精确任务 ID 确认后,才会强制移除 checkout。

在 起点引用(可选) 中输入值,可以为单个任务跳过远程默认分支解析。例如,origin/release 会直接使用该本地 ref,不先 fetch origin。

命令

人工命令在本地处理,不会发给模型:

/branchline list
/branchline create
/branchline inspect <id>
/branchline validate <id> <command...>
/branchline preview <id>
/branchline deliver <id>
/branchline archive <id>
/branchline recover

丢弃只在 Web 工作台提供,因为那里会展示风险确认。命令使用当前 Session workspace 作为仓库或交付目标。

配置

Bundle 会插入使用 Schema 默认值的 Host 和命令条目。部署需要修改路径或限制时,在 Web profile 最后应用的 cordis.patch.yml 中覆盖 dsh-branchline 条目。

| 字段 | 默认值 | 含义 |
| managedRoot | $DSH_HOME/plugins/dsh-branchline/worktrees | 插件创建 worktree 的父目录。 |
| statePath | $DSH_HOME/plugins/dsh-branchline/tasks.json | 原子 JSON 任务状态;不得位于 managedRoot 内。 |
| gitTimeoutMs | 60000 | 单次 Git 操作的截止时间。 |
| terminationGraceMs | 3000 | 受管进程树从 TERM 升级到 KILL 的等待时间。 |
| validationTimeoutMs | 600000 | 单次验证命令的截止时间。 |
| maxOutputBytes | 1048576 | Git 诊断和验证各输出流保留的最大字节数。 |
| reviewMaxBytes | 524288 | 审阅时保留的 diff 和未跟踪路径最大字节数。 |
| requireValidation | true | 交付前要求验证通过且结果绑定当前内容 token。 |
| allowDelivery | false | 显示并允许本地合并交付。通过其他流程审阅或集成分支时应保持关闭。 |

Host 加载时会解析相对路径。空路径、非正数限制,以及位于 managed worktree root 内的状态文件都会导致插件启动失败。

安全模型

Host 路由只接受 loopback 连接、loopback Host authority 和同源浏览器标记。它是执行边界,不是身份认证:以同一用户运行的本地进程仍可访问 loopback 服务,就像它可以直接运行 Git 一样。

Git 和验证命令通过 DSH 的受管 subprocess 服务运行。插件只传入启动程序所需的少量白名单环境变量,再为 Git 加入非交互变量,或为验证加入 CI。Token 和 secret 变量不会被传给子进程;POSIX 保留 SSH_AUTH_SOCK,让 Git 使用用户已配置的 agent。Provider 管理完整进程树,升级终止超时进程,并等待进程树退出。

启用 allowDelivery 后,交付仍不信任浏览器结果。Manager 会跨进程序列化变更,检查当前内容 token,要求任务改动已提交,在启用时核对验证 token,执行新的合并预检,持久化 pending operation,并在 git merge 前再次检查目标 HEAD 和干净状态。

如果合并失败后无法确认目标已恢复到原 HEAD 和干净状态,任务会进入 recovery-needed,而不是报告普通冲突。recover 会核对持久化标记与 Git worktree metadata,但不会删除身份不明的路径。

漏洞报告和信任假设见 SECURITY.md,状态与生命周期细节见 docs/architecture.md。

当前限制

- Branchline 只管理本地仓库,不推送分支,也不创建 Pull Request。
- 交付合并已提交改动,不会把未提交 working tree 复制到目标 checkout。
- ignored 文件不进入 change token;验证可以生成普通 ignored 构建产物而不让自身结果失效。
- Web 工作台默认以任务创建时记录的仓库 checkout 为目标;Manager API 和命令适配器可以指定同一 Git common directory 下的其他 checkout。
- git merge-tree --write-tree 不修改目标 checkout 或 index,但 Git 可能向共享对象数据库写入临时对象。
- 已归档和已丢弃的记录会保留在 tasks.json;当前版本不会自动清理历史记录。

开发

pnpm install
pnpm run typecheck
pnpm test
pnpm run build
pnpm run pack:check

测试使用真实临时 Git 仓库、真实 DSH Web server 和本地 subprocess provider,覆盖任务生命周期、内容 token 失效、验证、合并预检与交付、恢复、有界输出、凭据清理、Windows 命令 shim 和 loopback 请求信任。

许可证与署名

MIT。派生代码边界和保留的上游署名见 NOTICE。
预览分享卡片长什么样 ↓ryanportfolio/dsh-branchline
分享 · DeepSeek Harness Hub
ryanportfolio/dsh-branchline

DSH Branchline 是面向 DeepSeek Harness 的人工操作 Git worktree…

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部