让 Claude Code、Codex、OpenCode、Pi 或任何其他智能体并行运行 DeepSeek…
38.3/100
综合分
10
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add nicremo/dsh-cli该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · ui
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 25 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-cli(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/27 23:41:36
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 114 处,展示前 94 条)
- 读取本地文件src/cli.mjs:25
const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version - 读取本地文件src/cli.mjs:90
return readFileSync(0, 'utf8') - 读取本地文件src/cli.mjs:97
if (file) return readFileSync(resolve(file), 'utf8') - 读取本地文件src/cli.mjs:116
if (existsSync(join(current, WORKSPACE_MARKER))) return true - 写入本地文件src/cli.mjs:126
mkdirSync(abs, { recursive: true }) - 写入本地文件src/cli.mjs:128
writeFileSync(join(abs, WORKSPACE_MARKER), JSON.stringify({ kind, createdAt: new Date().toISOString() }) + '\n') - 读取本地文件src/cli.mjs:130
if (force || !existsSync(agents)) writeFileSync(agents, workspaceAgentsMd({ name: basename(abs), kind, description })) - 写入本地文件src/cli.mjs:130
if (force || !existsSync(agents)) writeFileSync(agents, workspaceAgentsMd({ name: basename(abs), kind, description })) - 读取本地文件src/cli.mjs:138
if (!existsSync(abs)) ensureWorkspace(abs, { kind }) - 执行外部命令来自配置/变量src/cli.mjs:789
const res = spawnSync(python, [CAPTURE_PY, ...argv.filter((a) => a !== '--json')], { stdio: 'inherit' }) - 执行外部命令来自配置/变量src/cli.mjs:796
spawnSync(opener, [url], { stdio: 'ignore' }) - 读取本地文件src/collect.mjs:17
entries = readdirSync(current, { withFileTypes: true }) - 读取本地文件src/collect.mjs:26
const st = statSync(full) - 读取本地文件src/collect.mjs:31
if (existsSync(dir)) walk(dir) - 读取本地文件src/collect.mjs:45
return existsSync(file) ? readFileSync(file, 'utf8') : null - 读取本地文件src/collect.mjs:45
return existsSync(file) ? readFileSync(file, 'utf8') : null - 写入本地文件src/collect.mjs:106
writeFileSync(indexPath, index) - 写入本地文件src/collect.mjs:111
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n') - 写入本地文件src/collect.mjs:115
writeFileSync(sourcesPath, JSON.stringify([...sources.values()], null, 2) + '\n') - 读取本地文件src/dsh.mjs:40
accessSync(candidate, constants.X_OK) - 读取本地文件src/dsh.mjs:59
const isCheckout = (repo) => existsSync(join(repo, 'apps', 'cli', 'src', 'bin.ts')) && existsSync(join(repo, 'node_modules', 'tsx')) - 读取本地文件src/dsh.mjs:89
if (!existsSync(file)) return {} - 读取本地文件src/dsh.mjs:90
return yaml.load(readFileSync(file, 'utf8')) ?? {} - 读取本地文件src/dsh.mjs:94
return existsSync(join(profileDir(PROFILE), 'package.json')) ? PROFILE : 'headless' - 写入本地文件src/dsh.mjs:112
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', { mode: 0o600 }) - 写入本地文件src/dsh.mjs:114
writeFileSync(patchPath, `# dsh-cli: per-job settings with a model override\n- id: settings\n config:\n path: ${JSON.stringify(settingsPath)}\n - 写入本地文件src/profile.mjs:85
mkdirSync(dir, { recursive: true }) - 读取本地文件src/profile.mjs:90
if (!existsSync(source)) continue - 读取本地文件src/profile.mjs:93
lstatSync(target) - 写入本地文件src/profile.mjs:115
mkdirSync(home(), { recursive: true }) - 读取本地文件src/profile.mjs:116
if (!existsSync(join(dir, 'package.json'))) { - 执行外部命令来自配置/变量src/profile.mjs:119
const res = spawnSync(c.cmd, c.args, { env: c.env, cwd: home(), encoding: 'utf8', timeout: 180000 }) - 读取本地文件src/profile.mjs:120
if (res.status !== 0 || !existsSync(join(dir, 'package.json'))) { - 读取本地文件src/profile.mjs:134
if (existsSync(sourcePatch)) { - 读取本地文件src/profile.mjs:135
;({ rows, dump } = extractRows(readFileSync(sourcePatch, 'utf8'), mcpFilter(mcp))) - 写入本地文件src/profile.mjs:142
writeFileSync(patchFile, renderPatch({ rows, dump, skillsDir, sourceProfile: from }), { mode: 0o600 }) - 写入本地文件src/profile.mjs:144
chmodSync(patchFile, 0o600) - 执行外部命令来自配置/变量src/profile.mjs:148
const check = spawnSync(c.cmd, c.args, { env: c.env, cwd: home(), encoding: 'utf8', timeout: 180000 }) - 执行外部命令来自配置/变量src/profile.mjs:166
const res = spawnSync(python, ['-c', 'import importlib.metadata as m; print(m.version("playwright"))'], { encoding: 'utf8', timeout: 15000 }) - 读取密钥环境变量src/profile.mjs:195
const hasCreds = existsSync(join(dshHome(), '.credentials.yaml')) || Boolean(process.env.DEEPSEEK_API_KEY) - 执行外部命令来自配置/变量src/profile.mjs:201
const res = spawnSync(c.cmd, c.args, { env: c.env, cwd: home(), encoding: 'utf8', timeout: 120000 }) - 写入本地文件src/profile.mjs:212
mkdirSync(home(), { recursive: true }) - 写入本地文件src/runner.mjs:29
writeFileSync(taskFile(job.id), taskText) - 读取本地文件src/runner.mjs:34
return existsSync(taskFile(id)) ? readFileSync(taskFile(id), 'utf8') : '' - 读取本地文件src/runner.mjs:34
return existsSync(taskFile(id)) ? readFileSync(taskFile(id), 'utf8') : '' - 读取本地文件src/runner.mjs:51
if (!existsSync(file)) return '' - 读取本地文件src/runner.mjs:52
return readFileSync(file, 'utf8') - 写入本地文件src/runner.mjs:65
writeFileSync(cancelMarker(id), nowIso()) - 读取本地文件src/runner.mjs:84
if (existsSync(cancelMarker(id))) return updateJob(id, { status: 'cancelled', endedAt: nowIso() }) - 写入本地文件src/runner.mjs:89
mkdirSync(job.cwd, { recursive: true }) - 写入本地文件src/runner.mjs:90
if (job.outDir) mkdirSync(job.outDir, { recursive: true }) - 执行外部命令来自配置/变量src/runner.mjs:100
const child = spawn(spec.cmd, spec.args, { - 写入本地文件src/runner.mjs:135
appendFileSync(eventsPath, chunk) - 读取本地文件src/runner.mjs:162
if (existsSync(cancelMarker(id))) { - 写入本地文件src/runner.mjs:170
appendFileSync(stderrPath, `dsho: spawn failed: ${err.message}\n`) - 执行外部命令来自配置/变量src/runner.mjs:365
const child = spawn(process.execPath, [BIN, ...args], { - 读取本地文件src/skills.mjs:15
const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version - 读取本地文件src/skills.mjs:30
const st = lstatSync(path) - 读取本地文件src/skills.mjs:32
return existsSync(join(path, MARKER)) ? 'ours' : 'foreign' - 读取本地文件src/skills.mjs:45
if (!existsSync(join(BUNDLED, 'SKILL.md'))) throw new DshoError(`bundled skill missing at ${BUNDLED}`, 5) - 删除本地文件src/skills.mjs:51
if (kind === 'link') rmSync(canonical) - 删除本地文件递归src/skills.mjs:52
if (kind === 'ours') rmSync(canonical, { recursive: true, force: true }) - 写入本地文件src/skills.mjs:53
mkdirSync(agentsSkillsDir(), { recursive: true }) - 写入本地文件src/skills.mjs:55
writeFileSync(join(canonical, MARKER), `dsh-cli ${VERSION}\n`) - 读取本地文件src/skills.mjs:61
if (!wanted && !existsSync(t.parent)) { - 删除本地文件src/skills.mjs:71
if (existing === 'link') rmSync(target) - 删除本地文件递归src/skills.mjs:72
if (existing === 'ours') rmSync(target, { recursive: true, force: true }) - 写入本地文件src/skills.mjs:73
mkdirSync(t.dir, { recursive: true }) - 写入本地文件src/store.mjs:24
mkdirSync(jobDir(id), { recursive: true }) - 读取本地文件src/store.mjs:73
if (!existsSync(dir)) return [] - 读取本地文件src/store.mjs:74
return readdirSync(dir).filter((name) => !name.startsWith('.')).sort().reverse() - 写入本地文件src/store.mjs:87
mkdirSync(batchDir(id), { recursive: true }) - 读取本地文件src/supervisor.mjs:26
if (existsSync(batchCancelMarker(id)) && !existsSync(cancelMarker(jid))) writeFileSync(cancelMarker(jid), nowIso()) - 写入本地文件src/supervisor.mjs:26
if (existsSync(batchCancelMarker(id)) && !existsSync(cancelMarker(jid))) writeFileSync(cancelMarker(jid), nowIso()) - 写入本地文件src/supervisor.mjs:42
writeFileSync(batchCancelMarker(id), nowIso()) - 写入本地文件src/util.mjs:44
mkdirSync(dirname(file), { recursive: true }) - 写入本地文件src/util.mjs:46
writeFileSync(tmp, JSON.stringify(value, null, 2) + '\n') - 写入本地文件src/util.mjs:47
renameSync(tmp, file) - 读取本地文件src/util.mjs:53
return JSON.parse(readFileSync(file, 'utf8')) - 读取密钥环境变量src/web.mjs:27
process.env.DSHO_WEB_TOKEN_FILE, - 读取密钥环境变量src/web.mjs:32
const urls = process.env.DSHO_WEB_TOKEN_URL ? [process.env.DSHO_WEB_TOKEN_URL] : [] - 读取本地文件src/web.mjs:34
if (!existsSync(file)) continue - 读取本地文件src/web.mjs:35
const raw = readFileSync(file, 'utf8').trim() - 写入本地文件src/web.mjs:52
mkdirSync(home(), { recursive: true }) - 写入本地文件src/web.mjs:53
writeFileSync(tokenUrlFile(), parsed.href + '\n', { mode: 0o600 }) - 发起网络请求src/web.mjs:71
res = await fetch(t, { redirect: 'manual', signal: AbortSignal.timeout(5000) }) - 写入本地文件src/web.mjs:78
mkdirSync(home(), { recursive: true }) - 写入本地文件src/web.mjs:79
writeFileSync(authFile(), JSON.stringify({ origin: baseUrl(), cookie, savedAt: new Date().toISOString() }) + '\n', { mode: 0o600 }) - 发起网络请求src/web.mjs:111
res = await fetch(`${baseUrl()}/api/${method}`, { - 发起网络请求src/web.mjs:135
let res = await fetch(`${baseUrl()}/`, { headers: { cookie: c }, redirect: 'manual', signal: AbortSignal.timeout(2500) }) - 发起网络请求src/web.mjs:139
res = await fetch(`${baseUrl()}/`, { headers: { cookie: fresh }, redirect: 'manual', signal: AbortSignal.timeout(2500) }) - 写入本地文件src/web.mjs:278
mkdirSync(logsDir(), { recursive: true }) - 执行外部命令来自配置/变量src/web.mjs:281
const child = spawn(cmd, args, { detached: true, stdio: ['ignore', fd, fd], env, cwd: homedir() }) - 读取本地文件src/web.mjs:287
const text = readFileSync(logFile, 'utf8')
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
1 张 · 点击查看大图功能亮点
- 批量派发会话
- 并行运行智能体
- 实时显示网页界面
让 Claude Code、Codex、OpenCode、Pi 等智能体并行跑 DeepSeek Harness(dsh)会话:批量调研、素材收集,实时显示在 DSH 网页界面里。非官方社区工具。
README
由 DeepSeek 最新模型翻译生成dsh-cli
让 Claude Code、Codex、OpenCode、Pi 或任何其他智能体并行运行 DeepSeek Harness 会话。
deepseekharnesscli.nicremo.de
非官方社区项目。 dsh-cli 与 DeepSeek 没有关联,也未获其认可或赞助。「DeepSeek Harness」是 DeepSeek 的商标,此处仅用于说明兼容性。
为什么做这个
我用 DeepSeek Harness(dsh)主要做研究,也用来跑大量并行会话:一次问十个研究问题、收集文章截图、博客长文的滚动视频、素材视频。DeepSeek 又快又便宜,很适合当工作池。缺的是让主编程智能体驱动它的办法:启动会话、等它跑完、读结果、继续追问。dsh-cli 就是干这个的。
dsh-cli 以智能体为先。每条命令都非交互、立即返回,输出紧凑文本或 --json,退出码稳定。它附带一份 Agent Skill,教 Claude Code、Codex、OpenCode、Pi 等 harness 什么时候、怎样把活交给 DeepSeek Harness。
展开完整文档(README 剩余 1 节)
dsh-cli
让 Claude Code、Codex、OpenCode、Pi 或任何其他智能体并行运行 DeepSeek Harness 会话。
deepseekharnesscli.nicremo.de
非官方社区项目。 dsh-cli 与 DeepSeek 没有关联,也未获其认可或赞助。「DeepSeek Harness」是 DeepSeek 的商标,此处仅用于说明兼容性。
为什么做这个
我用 DeepSeek Harness(dsh)主要做研究,也用来跑大量并行会话:一次问十个研究问题、收集文章截图、博客长文的滚动视频、素材视频。DeepSeek 又快又便宜,很适合当工作池。缺的是让主编程智能体驱动它的办法:启动会话、等它跑完、读结果、继续追问。dsh-cli 就是干这个的。
dsh-cli 以智能体为先。每条命令都非交互、立即返回,输出紧凑文本或 --json,退出码稳定。它附带一份 Agent Skill,教 Claude Code、Codex、OpenCode、Pi 等 harness 什么时候、怎样把活交给 DeepSeek Harness。
功能
- 并行研究批次:dsho research "q1" "q2" ... 每个问题跑一个 worker;各自写出 report.md 和 sources.json,dsho collect 把它们合并成一个 INDEX.md。
- 素材收集:dsho materials "brief" 每种素材跑一个 worker(截图、滚动视频、新闻文章、素材视频、素材照片),并用 manifest.json 记录每个文件的来源和许可。
- 在 DSH web UI 里实时可见:dsh web 运行时,每个任务都是该 UI 里的真实会话。一个批次自成一个工作区,每个会话都有可读的标题,你可以围观,也可以随时介入。
- 无界面兜底:没有 UI 时,每个任务在独立的 headless dsh 进程里跑,使用精简配置档(orchestra),复用你的研究 MCP 服务器。
- 像人一样操控:wait、status、logs -f、result、files、continue(同一会话、同一文件夹)、cancel。
- 确定性捕获:dsho capture shot|scroll <url> 用 Playwright 拍干净的截图和流畅的 1080p 滚动视频(关掉 cookie 横幅、隐藏浮层、拦截广告网络、看门狗处理卡死页面)。
- 无守护进程:状态就是 ~/.dsho/ 里的普通 JSON;分离的 runner 进程让任务在调用它的 shell 退出后继续存活。
工作原理
flowchart LR
A["Your agent(Claude Code, Codex, OpenCode, Pi)"] -- "dsho research ... --json" --> C[dsh-cli]
C -- "DSH web UI running" --> W["dsh websessions in one workspace"]
C -- "otherwise" --> H["headless dshone process per job"]
W --> F[("workspace folderreport.md, manifest.json, ...")]
H --> F
C -- "dsho wait / collect" --> F
F -- "INDEX.md" --> A
1. 你的智能体调用 dsho(通常通过内置技能)。
2. dsh-cli 创建工作区文件夹,每个任务对应一个 job,然后把每个 job 交给分离的 runner,并立即返回 id。
3. runner 要么在运行中的 DSH web UI 里创建会话(通过它的 HTTP API),要么启动 dsh --profile orchestra --json -,把任务放到 stdin。
4. 事件记录在 ~/.dsho/jobs/<id>/events.jsonl,进度记录在 job.json,最终答案记录在 result.md。
5. 你的智能体用 dsho wait 等待,读取 dsho result 或 dsho collect,再用 dsho continue 继续会话。
环境要求
- Node.js >=22.19
- DeepSeek Harness,用 npm install -g @deepseek-ai/dsh 安装(或从源码检出),并登录一次
- 可选,供 dsho capture 使用:Python 3 加 Playwright(pip install playwright && python3 -m playwright install chromium)和 ffmpeg
- macOS 或 Linux
安装
npm install -g dsh-cli && dsho setup
dsho setup 会创建无头 dsh 配置档 orchestra,并把 dsh-orchestration 技能安装到 ~/.agents/skills(OpenCode 和其他 harness 会读取这个目录),同时为已安装的 Claude Code、Codex 和 Pi 建立链接。运行 dsho doctor 检查一切是否就绪。
只想要技能?npx skills add nicremo/dsh-cli 也可以,但技能需要命令行。
安装后会得到两个命令:dsh-cli 和短别名 dsho。
快速开始
dsho ui start # optional: start the DSH web UI to watch jobs live
dsho research "AI agent pricing 2026" "State of MCP servers" "Prompt caching strategies" \
--depth standard -C ~/dsh-workspaces/ai-2026
dsho wait last-batch --timeout 9m # exit code 4: still running, wait again
dsho collect last-batch # writes ~/dsh-workspaces/ai-2026/INDEX.md
dsho run -w "Summarize the release notes of Astro 6" # one task, print the answer
dsho materials "Electric cars in Europe, neutral tone" --kinds screenshots,articles,stock-video
dsho continue last "Add three sources from 2026 and update report.md"
dsho capture scroll https://example.com/blog/post -o post.mp4 --duration 12
在你的智能体里使用
运行 dsho setup 之后,你的智能体就认识这个技能了。用自然语言提问即可:
Use DeepSeek Harness to research these 10 topics in parallel and give me a summary.
帮我找一些近期新闻文章的截图,再找一些关于太阳能的素材视频,用在我的视频里。
技能会告诉智能体:先启动一个批次,再按 shell 超时时间分步等待,读取 INDEX.md,抽查结果,并在需要的地方跟进。dsho guide 会打印同一份手册,供不支持技能的智能体使用。
命令
| 命令 | 作用 |
| dsho run <task> | 在后台跑一个任务(-w 等待并打印答案) |
| dsho batch -f tasks.txt | 并行跑多个任务,每个任务一个文件夹(.txt、按 --- 分块、.json、.jsonl) |
| dsho research ... | 并行调研工作进程(--depth quick\|standard\|deep、--focus) |
| dsho materials <brief> | 每种素材一个工作进程(--kinds、--count、--url) |
| dsho status [ref] | 查看总览,或某个任务、批次的详情 |
| dsho ls [--batches] | 列出任务或批次 |
| dsho wait <ref>... | 阻塞直到完成(--timeout、--any) |
| dsho result <ref> | 最终答案(--files) |
| dsho logs <job> | 工具调用时间线(-f、--full、--raw、--stderr) |
| dsho files <ref> | 任务创建的文件 |
| dsho continue <job> <text> | 继续同一个会话 |
| dsho cancel <ref> | 停止一个任务或整个批次 |
| dsho collect <batch> | 写入 INDEX.md,合并 manifest.json 和 sources.json |
| dsho capture shot\|scroll <url> | 截图和滚动视频 |
| dsho ws init <dir> | 创建工作区,并在 AGENTS.md 中写入约定 |
| dsho ui [start\|login] | 打开、启动或登录 DSH web UI |
| dsho skill install | 安装或刷新智能体技能 |
| dsho setup / dsho doctor | 一次性设置 / 环境检查 |
| dsho config [set\|unset] | 持久化设置 |
| dsho guide | 给智能体的手册 |
引用方式:任务 id、批次 id、唯一前缀、名称、last、last-batch。常用选项:-C <dir> 工作区文件夹,-m flash|pro|v4-flash|vision,--effort off|low|high|max,-t <duration> 时间限制,-p <n> 并行度,-b auto|web|headless 后端。每个命令都有 --help。
JSON 与退出码
每个命令都接受 --json,并打印一个对象:{ "ok": true, ... } 或 { "ok": false, "error", "code", "hint" }。
| 退出码 | 含义 |
| 0 | 成功 |
| 1 | 任务失败、超时或被取消 |
| 2 | 用法错误 |
| 3 | 找不到任务或批次 |
| 4 | 等待超时,或任务尚未完成 |
| 5 | 环境问题(缺少 dsh、UI 无法访问、缺少 Playwright) |
DSH web UI 后端
web UI 可访问时,dsh-cli 会与它的 HTTP API 通信(POST /api/<namespace>/<method>):注册工作区文件夹,在其中创建会话,给会话命名,可选地选择模型,发送任务,然后轮询会话日志,直到回答该任务的那一轮结束。会话日志会转换成 headless 模式产生的同一种事件格式,因此 logs、status 和 result 在任何地方行为一致。
- dsho ui start 在后台启动 dsh web,抓取它打印的 token URL 并登录。
- 如果你自己启动 dsh web,把打印的 URL 传一次:dsho ui login "http://127.0.0.1:3080/?token=..."。得到的 cookie 存在 ~/.dsho/web-auth.json(权限 0600),30 天内有效,重启后也仍然有效。
- -b web 让缺失的 UI 直接报错,而不是回退到 headless。
headless 后端与 dsho setup
headless 任务在任务文件夹里运行 dsh --profile orchestra --json -。dsho setup 用随附的 headless 模板构建这个配置档,再加上:
- 从另一个配置档(默认 web)复制的 MCP 服务器:--mcp research(firecrawl、Brave、context7、Exa、Tavily、Perplexity、Jina 等;默认)、all、none,或逗号分隔的 id 列表。复制的行可能含 API key,所以配置档文件以 0600 权限写入,且不打印任何内容。
- 精选的技能文件夹(~/.dsh/skills-orchestra,符号链接到 ~/.agents/skills),而不是你的整个技能池,这样 worker 提示词大约小三分之一。--skills a,b,c 选其他技能,--skills all 保留 dsh 默认值。
- .dsho-workspace 作为额外的项目根标记,这样批量子文件夹里的 worker 仍会加载工作区的 AGENTS.md。
配置
dsho config set <key> <value> 把设置存到 ~/.dsho/config.json。环境变量优先于文件。
| 键 | 环境变量 | 含义 |
| dshRepo | DSHO_DSH_REPO | 使用 dsh 源码检出(优先于 dshBin) |
| dshBin | DSHO_DSH_BIN | dsh 可执行文件路径(默认:PATH 上的 dsh) |
| webUrl | DSHO_WEB_URL | DSH web UI 的源(默认 http://127.0.0.1:3080) |
| backend | DSHO_BACKEND | auto、web 或 headless |
| workspaces | DSHO_WORKSPACES | 新工作区的根目录(默认 ~/dsh-workspaces) |
| python | DSHO_PYTHON | 带 Playwright 的 Python,用于截图 |
其他变量:DSHO_HOME(状态文件夹,默认 ~/.dsho)、DSH_HOME(dsh 主目录,默认 ~/.dsh)、DSHO_WEB_TOKEN_URL / DSHO_WEB_TOKEN_FILE(web UI 的 token URL)。
文件
~/.dsho/
config.json settings
web-auth.json cookie for the DSH web UI (0600)
jobs/<id>/ job.json, task.md, events.jsonl, stderr.log, result.md
batches/<id>/ batch.json
logs/ runner logs
<workspace>/
AGENTS.md, .dsho-workspace
<nn-job>/ one folder per batch job
INDEX.md after dsho collect
故障排查
| 症状 | 修复 |
| dsh not found | npm install -g @deepseek-ai/dsh,或 dsho config set dshBin <path> |
| 任务不在 UI 里显示 | dsho doctor;dsho ui start 或 dsho ui login <url>;用 -b web 启动任务 |
| 任务状态为 lost | 它的 runner 进程已死(重启、被杀);重新启动它 |
| headless worker 卡住 | 把 dsh 的权限预设设为完全访问,用于无人值守运行(dsho doctor 会显示) |
| dsho capture 失败 | pip install playwright && python3 -m playwright install chromium;滚动视频需要 ffmpeg |
| 抓取时页面卡住 | 看门狗在 --max-time 后终止它(截图默认 90 秒) |
安全
dsh worker 能运行 shell 命令;很多环境里 dsh 以完整权限运行,没有沙箱。把任务限制在工作区内,绝不要委派删除、部署、git push 或任何涉及密钥的操作。worker 找到的素材不自动归你发布:在 manifest.json 里核对许可和来源。报告漏洞见 SECURITY.md。
开发
git clone https://github.com/nicremo/dsh-cli && cd dsh-cli
npm install
npm test # node:test with a fake dsh and a fake web UI; never touches your real setup
node bin/dsho.mjs help
架构说明:docs/architecture.md。欢迎贡献,见 CONTRIBUTING.md。
许可
MIT。演示动画里的 logo 归各自所有者(Anthropic、OpenAI、OpenCode、Pi、DeepSeek),仅用于标识兼容工具。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
nicremo/dsh-cli
让 Claude Code、Codex、OpenCode、Pi 或任何其他智能体并行运行 DeepSeek…
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,344已汉化DSH
71.5
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,045已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,202已汉化DSH
71.1
这是你的仓库?认领条目