dsh-jj
已验证 · 实测可装 LosEcher
功能简介
DSH bundle: jj (Jujutsu) version control via a zero-dependency MCP stdio server — mcp__jj__* tools for DeepSeek Harness, Claude Code, Codex
可用 — 实测通过,早期项目
DSH bundle: jj (Jujutsu) version control via a zero-dependency MCP stdio server — mcp__jj__* tools for DeepSeek Harness, Claude Code, Codex 实测能干净安装、正常启动。早期项目,但功能可用。
「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-jj — jj (Jujutsu) 版本控制 DSH 插件
把本机 jj CLI 通过零依赖 MCP stdio server 暴露成 DSH 工具(mcp__jj__*),
让模型在 jj 仓库里用 jj 语义做版本控制(status / log / diff / describe / new /
commit / edit / abandon / undo / rebase / fetch / push / bookmark / run),
而不是用 git 思维硬套。
前置条件
- jj ≥ 0.2x,可用
brew install jujutsu安装(macOS)或按
官方文档 安装 - Node ≥ 18(server 零依赖,纯 stdlib)
安装
dsh plugin --profile web add github:LosEcher/dsh-jj#main
本地开发(改源码时):
dsh plugin --profile web add link:/path/to/dsh-jj
新 bundle 安装后必须重启 dsh web(HMR 只覆盖 config 编辑):
~/.dsh/scripts/dsh-web-restart.sh # 或手动重启 dsh web
关于 command: jj-mcp
bundle patch 用 command: jj-mcp(包的 bin 入口)。pnpm 在安装时会把该
bin 链接到 profile 的 node_modules/.bin;若你的 dsh 进程 PATH 不含该
目录(launchd 等托管场景常见),MCP 行会 spawn 失败——此时在你的用户
patch 层用 id-targeted 配置覆盖为绝对路径:
- id: mcp-jj
config:
serverName: jj
transport: stdio
command: node
args: ['/absolute/path/to/dsh-jj/server.mjs']
env:
JJ_MCP_BIN: '/path/to/jj' # 可选
failOnStartupError: false
toolCallTimeoutMs: 120000
验证
# 1. 配置组合
pnpm dsh --profile web --dump-config | grep mcp-jj
# 2. 插件树 active(fiberPhase)
curl -s -X POST http://127.0.0.1:3080/api/pluginInventory/list \
-H "Content-Type: application/json" \
-d '{"type":"client-request","rpcId":"v1","method":"pluginInventory/list","payload":{"args":{}}}' \
| grep -A2 'mcp-jj'
# 3. 功能:新会话里应出现 mcp__jj__* 工具(已有会话的工具 schema 快照不含新
# MCP 工具是已知时序行为,以插件树为准)
工具(serverName jj → mcp__jj__<tool>)
| 工具 | 作用 | 关键参数 |
|---|---|---|
jj_status |
当前 change 摘要 + 工作区改动 | change (-r) |
jj_log |
change 图(替代 git log) | limit/revset/noGraph |
jj_diff |
当前 change 或指定 change 的 diff | change/files |
jj_describe |
设置/更新描述(提交信息) | message/change |
jj_new |
开新空 change(无 add/commit 仪式) | message/base/insertBefore |
jj_commit |
封存当前 change 并开新(describe+new) | message |
jj_edit |
跳到已有 change 继续编辑(后代自动 rebase) | change |
jj_abandon |
丢弃 change(可 undo) | change/keepDescendants |
jj_undo |
撤销上一次 jj 操作 | — |
jj_rebase |
移动 change 到新父节点 | destination/source/after |
jj_fetch |
git fetch(远程分支→bookmark) | remote |
jj_push |
推送 bookmark 到远程 | bookmark[]/deleted/all |
jj_bookmark |
bookmark(=git 分支)管理 | action create/set/track/untrack/delete/move/list |
jj_run |
通用透传(split/workspace/op restore 等) | args[](禁止 --config*) |
所有工具支持可选 repo 参数;缺省解析顺序:repo 参数 →JJ_MCP_DEFAULT_REPO → 从 server 进程 cwd 向上找 .jj。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
JJ_MCP_BIN |
/opt/homebrew/bin/jj(不存在则 jj) |
jj 二进制路径 |
JJ_MCP_TIMEOUT_MS |
60000 |
单次调用超时 |
JJ_MCP_DEFAULT_REPO |
空 | 默认仓库目录 |
JJ_MCP_LOG |
1 |
0 关闭 stderr 启动横幅 |
server 会自动探测常见 jj 安装位置;JJ_MCP_BIN 仅在自动探测失败时必要。
安全设计
- 所有工具经
spawn数组参数调jj,无 shell,参数注入免疫; jj_run过滤--config/--config-toml/--config-file(防通过 jj
配置项如ui.editor执行任意命令);- jj 本身所有操作可
jj undo/jj op restore,破坏性风险天然低。
独立使用(非 DSH)
server 是标准 MCP stdio server,可直接给 Claude Code / Codex 用:
npx -y jj-mcp # 或
node /path/to/dsh-jj/server.mjs
测试
node test/test-client.mjs /path/to/a/jj/repo # 完整冒烟套件(真实仓库)
node test/test-client.mjs --list # 只列工具
node test/test-client.mjs <repo> --tool jj_log --args '{"limit":5}'
测试在仓库上做 new/describe/commit/undo 等操作——用临时仓库
(jj git init /tmp/jj-test-repo),别在正式仓库上跑。
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-jj」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:LosEcher/dsh-jj Headless(CLI)profile:
dsh plugin --profile headless add github:LosEcher/dsh-jj 实测报告
验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。