DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-workspace-merge

Workspace Merge

将多个本地项目根目录合并为一个命名工作区组,使单个 DSH 会话能够读取、比较和编辑所有项目中的相同相对路径。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:LoserForLoser/dsh-workspace-merge#cc2d167dceabbf6c1f9a4bd1aa659e023db140fb
README兼容性版本

兼容性与来源证明

Workspace Merge 以 dsh-workspace-merge 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

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

版本

0.1.0stable
2026/9/11

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/11
查看源码 ↗
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-workspace-merge

One DSH session, several project roots.

A DSH session is rooted at exactly one working directory — that directory is the sandbox boundary, the workspace key, and the base for every relative path. That default is right almost always, but it makes a very common layout awkward: the PC and mobile clients of one product, an iOS and a HarmonyOS app that must stay in step, a shared library and its consumers. They live in sibling directories, and "change the same file in both places" degenerates into absolute paths and repeated calls that quietly drift apart.

This bundle adds a named workspace group — an ordered set of local project roots — and eight ws_* tools that treat one relative path across every root of the group as a single operation, with a per-root outcome instead of one opaque failure.

            one call: ws_edit src/components/AmountInput.vue
                                │
        ┌───────────────────────┼───────────────────────┐
        ▼                       ▼                       ▼
  [pc]  ecam-ui           [mobile] ecam-mobile     [shared] lib-ui
  changed · 1 replacement changed · 1 replacement  not-found

Install

dsh plugin add dsh-workspace-merge

Or add it to a profile by hand: install the package under $DSH_HOME/profiles/web and list dsh-workspace-merge in dsh.profile.bundles.

Configure

A group is a name plus roots. id is the short label every other tool uses; path may be absolute or ~-prefixed.

// ws_group_set {group:"ecam", description:"PC + mobile", roots:[
//   {id:"pc",     path:"~/Desktop/JLXY/ecam-ui"},
//   {id:"mobile", path:"~/Desktop/JLXY/ecam-mobile-ui"}
// ]}

That writes $DSH_HOME/workspace-groups.json:

{
  "version": 1,
  "groups": {
    "ecam": {
      "description": "PC + mobile",
      "roots": [
        { "id": "pc", "path": "/Users/you/Desktop/JLXY/ecam-ui" },
        { "id": "mobile", "path": "/Users/you/Desktop/JLXY/ecam-mobile-ui" }
      ]
    }
  }
}

The file is plain JSON — hand-edit it if you prefer.

Group selection. A call may pass group explicitly. Otherwise the group whose root contains the session directory wins (the longest matching root breaks a tie between nested roots); with no match, a single defined group is unambiguous, and any other count requires an explicit name.

Tools

ToolPurpose
ws_groupsList groups, their root ids, and the active group for this session.
ws_group_set / ws_group_removeMaintain the registry (project files are never touched).
ws_lsList one relative directory across every root — locate the same component everywhere at once.
ws_readRead the same relative path from every root and return each copy.
ws_diffLine-diff the copies (first root is the baseline) before editing anything.
ws_editApply ONE literal replacement to every root, per-root outcome.
ws_writeWrite the SAME full content to every root — new shared file, or force copies back in sync.

ws_edit follows the built-in edit rule: old_string must occur exactly once unless replace_all is set. ws_edit and ws_write accept dry_run to preview, and roots: ["pc"] to narrow a call to one project. Per-root statuses are explicit — changed / unchanged / not-found / ambiguous / missing / invalid / denied — so a partial application is visible, never silent.

Sandbox behaviour

Every mutation resolves the session's sandboxPolicy first, and this bundle does not widen it:

  • danger-full-access — writes resolve unfenced, as everywhere else.
  • workspace-write — each target is canonicalized (a missing file is re-anchored under its nearest existing ancestor, so a symlinked parent cannot smuggle the write out) and must fall inside the policy's writable roots.
  • read-only — all mutations are refused.

A target outside the standing roots is refused with the official [sandbox: file access denied under … mode] marker plus the escalation hint, and can be retried once with sandbox_permissions + justification, exactly like the built-in write and edit tools. The group registry itself (ws_group_set, ws_group_remove) obeys the same policy — a read-only session cannot quietly reconfigure groups.

Notes and limits

  • A group is not a monorepo. It changes where the ws_* tools point; it does not change the session's working directory, so the built-in read / edit / write / bash still resolve against the session root only. Use a group when one change must land in several projects in the same step.
  • Writes go through the harness filesystem service (ctx.fs): the pre-write version is registered with the official fs/observed event, so the fs-observation policy issues replaceIfVersion rather than refusing the write as FS_NOT_OBSERVED, and other plugins can veto through fs/write-intent. When that service is not mounted, the plain node:fs path is used after the same policy decision — and the result says so (via: node:fs (fs service failed: …)) instead of hiding it, so an integration problem is visible rather than silent.
  • ws_ls skips .git and node_modules, and caps output at 200 paths per root.
  • ws_diff aligns lines up to 4000 per side; larger files get a size summary instead of a diff.

Test

npm test

31 assertions over a throwaway DSH home and two throwaway roots: registration, registry CRUD, group selection, read/diff/list, dry-run, per-root mutation statuses, path-escape refusal, root-id validation, and the sandbox cases (danger-full-access, workspace-write deny, read-only deny, registry-write policy). The test links the harness's own @deepseek-ai/dsh-tools and @deepseek-ai/dsh-sandbox from the DevEco/DSH install (see node_modules), so npm test expects a local DSH installation.

The stub context reproduces two cordis rules that cost this bundle a real boot each, and fails loudly if a future edit breaks them again:

  • a service not declared in inject is not a readable property — ctx.systemPrompt throws rather than returning undefined, which takes the whole row (and every tool registered before the throw) down with it, silently; optional services must be read with ctx.get(name);
  • section placement is centrally allocated — getSectionOrder() returns undefined for a name the harness does not know, and a section with a non-finite order throws. This bundle uses the TOOLS_SDK placement with a numeric fallback.

Diagnostics

WSM_DEBUG=1 records the plugin's startup phases (module evaluated → apply → tools service available → registration result) to stderr and <tmpdir>/dsh-workspace-merge-debug.log. Use it when a row is in the composed profile but its tools never appear in a session.

License

MIT © 宋朝阳