DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-jujutsu

Jujutsu

在 Jujutsu 工作区中拒绝使用 Git,转而将 jj 命令交给模型。包含 11 个 jj 工具、提示词教学,以及面向 DeepSeek Harness 的 jj-hunk 桥接工具。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:viztor/dsh-jujutsu#2acb0ce19d9c0be6545a8ef18ee4c639c5e0faab
README兼容性版本

兼容性与来源证明

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

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/18

版本

0.2.0stable
2026/10/18

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 1
周下载
0
最近提交
2026/10/19
查看源码 ↗
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 服务和进程生命周期管理Experimental Inspector@deepseek-ai/dsh-experimental-inspector用于 Host 调试和 Client Runtime 检查的实验性跨 realm CDP hub

README

Jujutsu on DeepSeek Harness

dsh-jujutsu

Jujutsu for DeepSeek Harness
Makes the harness jj-native — the agent uses jj instead of Git, and is told why.


Inside a Jujutsu workspace the agent stops reaching for Git and uses jj instead — and it is told why, rather than just being blocked.

  • Refuses Git where it would mislead. git status in a colocated repo reports a different state than jj status. The guard catches that and hands back the command to run instead.
  • Eleven jj tools, so the model can read and write history without shelling out and parsing output.
  • Teaches the model what jj is: no staging area, @ is always a commit, change IDs survive rewrites.
  • A settings panel, on the plugin's own page.

The plugin is invisible outside a Jujutsu workspace. In a plain Git repo it does nothing at all.

Install

Install from the harness Plugins page, or:

dsh plugin install dsh-jujutsu

Then open Plugins → Jujutsu to configure it. It works out of the box; the defaults are chosen to be safe.

Requirements

jjRequired. 0.46.0 or newer. brew install jj
jj-hunkOptional. Adds hunk-level split/squash. Without it those two tools report unavailable rather than failing. cargo install --git https://github.com/laulauland/jj-hunk --tag v0.5.1 jj-hunk
Node24 or newer

What it does

Refuses Git, and says what to run instead

The refusal is translated, not templated: the guard parses the command you actually typed and hands back the exact jj command it maps to.

You runWhat happens
git log --oneline -6Refused: git log --oneline -6. Run: jj log -r ::@ --limit 6 --no-graph
git diff HEAD~1Refused: git diff HEAD~1. Run: jj diff --from @-
git push origin mainRefused: git push origin main. Run: jj git push --remote origin --bookmark main
git statusRefused: git status. Run: jj status
git add src/a.tsRefused with the reason instead of a command: there is no staging area to add to
git status --porcelainThe catalogue wording — flags that change the command are never silently dropped
git rebase -iRefused — it needs a terminal. Suggests jj rebase, jj squash, jj absorb
rm -rf .gitRefused, and explains that jj's commit objects live there
jj status, jj log, …Run normally
echo "git commit"Runs — it never touched Git

Three rules make the translation safe to paste: Git revisions are rewritten into revsets (HEAD~2 → @--, because HEAD is not a jj revset), anything that does not map exactly falls back to the catalogue wording rather than a half-translated command, and every argument is shell-quoted.

Reads and writes are configured separately. A user who is happy to let the model look with Git has not thereby agreed to let it write.

Eleven jj tools

ToolWhat it does
jj_statusThe working copy, including whether it is conflicted
jj_log, jj_diff, jj_op_logHistory, changes, and the operation log
jj_new, jj_describe, jj_squashStart, describe and fold changes
jj_bookmark, jj_op_restoreName revisions; undo anything
jj_hunk_list, jj_hunk_applySelect and apply individual hunks

All of them return structured JSON, never prose. Revisions are addressed by change ID, which survives a rewrite — a commit ID does not.

Teaches the model

The model is told, in its system prompt, that version control here is Jujutsu and what that implies. The rule is withheld where it would be false: in a plain Git repo, or in a directory with no repository at all.

In a directory with no version control, the plugin says so — so the agent can offer to initialise one, suggesting jj git init (colocated, so Git tooling still works).

Depth is deferred rather than paid for. The rule and the workspace state ride the system prompt because they must be in force before the model's first Git command; the manual — the working-copy model, the Git→jj verb map, what each of the eleven tools returns — is registered as a jujutsu runtime skill, so its cost is one catalog line until the model actually needs it. Turn it off with Offer the jj manual. Why the split is drawn there, and why the manual is not an MCP server, is docs/36.

Configuration

Open Plugins → Jujutsu. Most settings are on that page:

SettingDefaultWhat it changes
GuardonOff leaves the guard mounted but inert — useful to see what it would have caught
Read-only GitaskWhat to do with git status, git log, …
Writing GitaskWhat to do with git commit, git push, …
Remember approvalsonStop re-asking about a verb you already approved, for this session
Mention missing version controlonTell the model when a directory has no repository
Prefer JujutsuonSuggest jj git init rather than git init
Explain Jujutsu in the promptonOff means the guard still refuses Git but the model is not told why
Offer the jj manualonShip the jj manual as an on-demand skill

Advanced: where the binaries are found

Three settings are not on the page, because only an unusual install needs them and showing them would ask everyone else to decide about them. Set them in the profile's config instead — they are ordinary Config fields:

SettingDefaultWhat it changes
jjPathjjSet when jj is not on PATH, or to pin a specific build
jjHunkPathjj-hunkSame, for jj-hunk
hunkInstallaskWhat to do when jj-hunk is missing: ask, never, or auto

Turning it off for one project

Drop a .dsh-jujutsu.json in the project root:

{ "enabled": false }

The nearest marker walking up from the working directory wins, so you can disable a monorepo and re-enable one vendored jj repo inside it with {"enabled": true}.

The file is yours to place — add it to .gitignore if the switch should stay local, or commit it to share the behaviour with your team. A malformed marker is ignored rather than obeyed, so a typo cannot silently disable the guard.

Troubleshooting

"Refused" when I wanted Git. That is the plugin working. Set Read-only Git or Writing Git to allow, or add a .dsh-jujutsu.json with {"enabled": false} for that project.

Nothing happens at all. The plugin only acts inside a Jujutsu workspace — a directory with a .jj directory, in it or any parent. Check with jj status; if that says "There is no jj repo in '.'", the plugin is correctly inactive. jj git init creates one (colocated by default).

The hunk tools say unavailable. jj-hunk is not installed or not on PATH. Set jj-hunk executable to an absolute path, or install it:

cargo install --git https://github.com/laulauland/jj-hunk --tag v0.5.1 jj-hunk

Do not run cargo install jj-hunk. The published crate is the same project but two minor versions behind, and its CLI is different — it rejects the query interface these tools use. Installing from crates.io gives you a jj-hunk that fails on every call with unexpected argument '--query' found, which is a confusing way to learn this. The pinned git install above is what the plugin is tested against.

jj new or jj commit is refused. The plugin refuses commit-creating commands when jj has no identity configured, because jj would create a commit with an empty author that cannot be pushed:

jj config set --user user.name "Your Name"
jj config set --user user.email "you@example.com"

Commands that preserve an author — jj describe, jj squash — are not affected.

For developers

The rest of this file is about building and verifying the plugin itself.

Build and test

pnpm run build           # tsc -> lib/   then   vp pack -> lib/client.js
pnpm run ci              # vp check, build, suite, package checks — the whole gate
pnpm run package-check   # just the tarball and release-wiring checks

lib/ is not optional and not committed. The published entry is emitted JavaScript, because Node refuses to strip types for files under node_modules (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING). That is why the plugin works from a link: install and would not work from a tarball: a link resolves to the working tree, where stripping is allowed.

Two artifacts, built two ways, because they are loaded two ways:

lib/index.jsthe host half. tsc -p tsconfig.build.json, ESM, with rewriteRelativeImportExtensions so the ./foo.ts specifiers the source uses become ./foo.js
lib/client.jsthe browser half. vp pack from src/client/panel.ts, CommonJS wrapped in window.__ModuleLoader__.load

The client half cannot be plain tsc output: the web client does not import a bundle, it evaluates one as a script and hands the factory a require. That wrapper is the bundler's banner/footer in vite.config.ts. The route serves ${package}/client.js and accepts only /^client\..*\.js$/, so scripts/name-client-bundle.ts renames what vp pack emits as client.cjs.

Releases do not go through a local pnpm publish. The registry entry is created by CI through npm's OIDC trusted publishing, so there is no token to hold and provenance is automatic; a hand-published version would be the one release with no provenance and no tag check. Three ways to trigger it, and the one-time setup each needs, are in CONTRIBUTING.md.

npm publish --dry-run   # what a publish would upload, from the working tree

Layout

src/The host half — guard, tools, prompt, detection. See src/README.md.
src/client/The panel, built to lib/client.js by vp pack. Harness primitives only.
locale/Display name and one-liner, per language.
SPEC.mdThe build specification.
docs/37 documents: verified contracts, measurements, decisions.
research/digest.mdThe durable record of the conversation that seeded the design.

What is verified, and how

Every claim about the harness was read from the 0.2.0-rc.2 source with line citations (docs/11); every claim about jj was measured against the installed 0.46.0 (docs/13). Both documents record what the sweeps did not find, and what remains open.

The guard, the eleven tools, the prompt injection and the panel have all been observed working in a live session. 269 tests, pnpm run ci green.

Where this came from

The design conversation happened in a Google AI Mode thread, shared as a public link, and was scraped through an anti-bot proxy. The transcript is not kept verbatim — it carried a personal share link and a private conversation. It was distilled into research/digest.md and the raw scrape deleted. The digest is safe to publish; the thread was not.

License

MIT — see LICENSE.