Claude Science-style research workbench: ReAct research-loop engine (research_* tools), versioned artifacts with provenance (artifact_* tools), and 10 science skills for genomics/pathogens/bioinformatics.
- Language
- JavaScript
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add dsh-scienceRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin biociao/dsh-science for me: review the repository at https://github.com/biociao/dsh-science first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
一句话定位
把 Claude Science 的整套科研工作台带到 DeepSeek Harness 上:维护一个 ReAct 式研究循环的状态机、把重要结果保存为带 SHA-256 校验与溯源的版本化工件、通过 SSH 把生信长时作业提交到实验室工作站或 HPC 集群并持续监控,再附带 11 个科研技能(文献/评审/论文撰写/并行委派/conda 环境等)。
核心能力
- 持久化研究循环:在项目根生成
research-manifest.json并维护"问题 → 假设 → 实验 → 观察 → 分析 → 结论 → 下一轮问题"的状态机,假设状态机强制经过testing才能得出supported/refuted/inconclusive结论;阶段只能前进,回退需显式开启allowPhaseRewind - 版本化工件与溯源:把分析结果(数据表、图、模型输出)保存到
artifacts/<name>/v<N>/,流式计算 SHA-256、相同内容去重(硬链接,跨设备降级为复制)、记录命令/输入/环境/envFile 哈希到provenance.md,可重算校验或生成复现指引 - SSH 远程计算(16 个工具):通过
~/.ssh/config别名连接工作站或 HPC 集群,注册时自动只读探测(CPU/内存/GPU/CUDA/conda/sbatch/SLURM 分区),长时任务以 detached 进程或 sbatch 提交,断连不杀,状态自动迁移 succeeded/failed/killed;输出按大小阈值分流(≤100MB 拉回本地,超大文件留在主机并记录路径) - 项目级主机访问白名单:首次在某个项目使用某台主机会弹审批,批准后写入项目自己的
.dsh/remotes/allowlist.json,同工作区里的多个研究项目彼此独立、不互相授权 - 远程主机设置页:浏览器里以页面形式增删改查 SSH 主机,宿主侧走
/dsh-science/remote-hosts/*REST API,与远程引擎共享同一份hosts.json/allowlist.json/jobs.json - 配套模型分档路由(独立 bundle
dsh-model-tier,按会话 opt-in):在会话模型选择器里注册虚拟 provider「智能分档」,把辅助请求(标题/压缩)与子任务分流到轻量档、复杂任务升级到强档,每档可指向不同 provider;未选中的会话零路由 - 11 个科研技能:研究循环、项目初始化、工件溯源、科学评审(子代理对照执行记录核查论断)、文献连接、并行委派、论文撰写、生物信息工具箱、conda 环境、数据清单、远程计算
技术实现
- 语言: Node.js ESM(
.mjs),零第三方 npm 依赖的引擎源码;客户端用 React 18 - 关键依赖: 无 npm 原生模块;宿主侧仅用
node:fs/node:path/node:os/node:crypto/node:child_process;远程能力依赖本机系统 OpenSSH 客户端(ssh/scp/ 可选sbatch/squeue/sacct/scancel) - 架构模式: DSH Cordis bundle —— 通过
cordis.patch.yml在 profile 层插入 4 个 science 引擎(science-research-loop/science-artifact-registry/science-remote-compute/science-remote-hosts-ui)+ 配套的model-tier/model-tier-ui,每个引擎都导出name和inject(如tools/webServer/llm)并通过ctx.tools.register注册工具;客户端 bundle 通过package.json#dsh.client注入;同一份源码另存为 agent preset(preset/engines/)用于"科学模式"会话 - 入口文件:
engines/remote-hosts-ui.mjs(作为 package.json 的main,是 web 侧最先加载的入口);其余引擎engines/research-loop.mjs、engines/artifact-registry.mjs、engines/remote-compute.mjs由 cordis patch 装载
适用场景
做基因组、病原体、生物信息类研究的用户希望把"提问题 → 设计实验 → 跑分析 → 沉淀结果 → 引用与复现"这条工作流交由 AI 主导:插件负责把每一步的状态、文件、命令和环境哈希落盘,让会话中断后能恢复上下文,让长时生信作业能在工作站或 HPC 集群上无人值守跑完并归档结果。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.6(已实验验证) | 仓库 README 与 CI 均固定此版本做 bundle 验证;更高小版本一般兼容,破坏性变更需重新验证 |
| Node.js | >=18 | package.json#engines.node 声明 18+;冒烟/稳定性测试在 node 18/20 跑,bundle 验证用 node 22(dsh 0.1.0-rc.6 内部依赖 node:sqlite) |
| 平台 | 跨平台 | 引擎本身是纯 Node;远程计算额外依赖本机 OpenSSH 客户端(macOS/Linux 自带,Windows 需 WSL 或 Git for Windows 的 ssh)和可用的 ~/.ssh/config 别名;远程主机侧零安装 |
| 原生模块 | 无 | 不依赖 npm 上的原生模块;远程能力仅复用系统已装的 ssh/scp/sbatch 等二进制 |
安装方式
dsh plugin --profile web add github:biociao/dsh-science
安装后需要在 profile 层重启(或刷新 Web GUI)让 4 个 science 引擎 + model-tier 引擎被装载。
配置项
插件的所有可调项都在 cordis.patch.yml 的引擎 config 块里——通过覆盖 profile 的 cordis.patch.yml(用 - update: [{id, config}])即可改写。常用项:
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
science-remote-compute.requireApproval | 布尔 | 每次 remote_run 提交作业时是否弹审批 | true |
science-remote-compute.requireHostAccess | 布尔 | 首次在某项目使用某主机时是否弹授权审批 | true |
science-remote-compute.hostsDir | 字符串 | 主机注册表所在目录(hosts.json) | $DSH_HOME/remotes |
science-remote-compute.execTimeoutMs | 数字(毫秒) | remote_exec 默认超时 | 120000 |
science-remote-compute.markers | 字符串数组 | 项目根识别标记(按优先级) | ["research-manifest.json",".dsh",".git"] |
science-research-loop.allowPhaseRewind | 布尔 | 是否允许回退循环阶段(默认只许前进) | false |
science-research-loop.markers | 字符串数组 | 项目根识别标记 | [".dsh",".git"] |
science-artifact-registry.maxFileBytes | 数字(字节) | 单个工件文件大小上限(超出会报错) | 8589934592(8 GiB) |
science-artifact-registry.allowHardlink | 布尔 | 相同内容是否用硬链接去重(跨设备自动降级为复制) | true |
*.lock.timeoutMs / *.lock.staleMs | 数字(毫秒) | 文件锁等待与陈旧锁回收阈值 | 10000 / 30000 |
model-tier.tiers.{strong,default,light} | {provider, model, reasoningEffort?} | 三个档位对应的真实模型,可跨 provider | 见 cordis.patch.yml 示例 |
model-tier.routing.auxiliary | 字符串数组 | 视为"辅助请求"的 purpose 列表 | ["session-title","compaction"] |
model-tier.routing.subagents | 字符串 | 子任务路由档位(如 "light")或不路由 | "light" |
model-tier.routing.subagentDepthStrong | 数字 | 深链子任务升级强档的深度阈值 | null(关闭) |
model-tier.routing.escalateOnChars | 数字 | 单步用户输入超过多少字符升级强档 | null(关闭) |
model-tier.routing.classify | 布尔/对象 | 是否启用 LLM 前置分类器(按复杂度再分档) | null(关闭) |
model-tier.enabled | 布尔 | 总开关,关闭则选择器里不出现「智能分档」 | true |
注册主机时还可以针对单台机器覆盖
scratch(作业根目录)、maxConcurrent(并发作业上限,默认 100)、timeoutMinutes(默认作业超时,默认 30)、bigFileThresholdBytes(超过此大小的文件不被拉回本地,默认 100 MB)等参数,详见remote_host_add工具说明。
常见问题
Q: 安装后 DSH 必须重启吗?
A: 需要重启 profile(或刷新 Web GUI)才能让 cordis.patch.yml 里的 4 个 science 引擎以及 model-tier / model-tier-ui 引擎生效;之后改 artifacts、改研究状态、跑作业都不需要再重启。远程主机设置页(science-remote-hosts-ui)首次启用也需要一次重启,让客户端 bundle 被注入到 Web UI。
Q: 远程主机设置页看不到怎么办?
A: 对应 science-remote-hosts-ui 引擎。检查两点:1)cordis.patch.yml 里 science-remote-hosts-ui 行的 name 必须是包根名 dsh-science(客户端 bundle 按此定位 dsh.client 声明);2)profile 重启后才会出现在设置侧栏。宿主侧 REST API 在 /dsh-science/remote-hosts/*,POST-only 且要求同源。
Q: remote_run 提交后连接断开,作业会丢吗?
A: 不会。工作站模式用 nohup + setsid 启动 detached 进程(断连不杀),SLURM 集群用 sbatch 提交;作业目录在主机的 scratch 下,本地 remote_status 通过 ssh/squeue/sacct 重探测并把状态写回 <项目根>/.dsh/remotes/jobs.json,跨会话持续。remote_pull 结束后标准动作链是:remote_status(确认终态)→ remote_pull → artifact_save → research_findings。
Q: SSH 主机需要装什么额外软件吗?
A: 不需要。引擎只依赖本机的 ssh/scp/可选 sbatch/squeue/sacct/scancel 二进制(系统 OpenSSH),主机侧零安装。但本机必须先在 ~/.ssh/config 里配好别名(或用 user@host),并确保密钥已配好(推荐 ssh-agent + BatchMode=yes);不要把密码写进任何工具参数。
Q: 怎么避免每次都弹审批?
A: 首次在某项目使用某主机(注册/探测/exec/run)会弹一次授权审批,批准后该主机写入项目自己的 .dsh/remotes/allowlist.json(按项目隔离),同项目不再询问;之后每次 remote_run 仍默认弹"Run this job on cordis.patch.yml 的 science-remote-compute 引擎 config 里把 requireApproval 与 requireHostAccess 都设为 false 即可同时关掉两道审批。
Q: research_* 工具什么时候该用?
A: 进入一个科研项目时先调 research_init(创建 research-manifest.json + 项目目录骨架,包括 experiments/、literature/、artifacts/、analyses/、figures/、manuscript/、reviews/、data/、envs/)。之后每轮迭代按 research_hypothesis(H1/H2/…)→ research_experiment(自动分配 E01、E02…,关联假设进入 testing)→ 写代码跑实验 → research_findings(追加观察日志、可推进假设状态、设下一轮问题开启新 iteration)。research_state 任何会话开始先看一次可恢复上下文。
Q: 工件和实验日志有什么区别?
A: 实验目录 experiments/E0X/{design.md,log.md,code/,results/} 记录一次实验的完整执行;artifact_save 则把"值得引用或复现"的结果归档到 artifacts/<name>/v<N>/,每个版本带流式 SHA-256、相同内容自动去重(硬链接)、溯源信息(命令/输入/输入哈希/环境/envFile 哈希)追加到 provenance.md,可随时 artifact_verify 重算校验或用 artifact_reproduce 输出复现指引。
Q: 卸载会影响现有项目数据吗?
A: 引擎只读写 research-manifest.json、artifacts/、.dsh/remotes/ 这些目录与文件;从 cordis.patch.yml 移除插件行并重启后,项目数据原样保留;想彻底清理可用 dsh plugin remove 后手动删除项目里的 .dsh/、artifacts/ 等目录。
上手难度
进阶 — 安装一行命令就能用默认档位,但要真正发挥作用需要:先在 ~/.ssh/config 配好 SSH 别名与免密登录,理解项目级白名单与作业审批的"按项目隔离"语义,并根据团队实际 provider 替换 model-tier 示例档位;首次跑通一次完整的"研究循环 + 远程作业 + 工件归档"流程后才算熟悉。
已知问题与限制
- 远程能力依赖本机系统 OpenSSH 客户端(
ssh/scp/可选 SLURM 命令),Windows 需 WSL 或 Git for Windows 提供 ssh;主机侧零安装但不提供图形化的 SLURM 队列管理,所有 SLURM 操作经 ssh 调用squeue/sacct/scancel - 拿不到会话工作目录(
agent.session.header.cwd)时,远程工具要求显式传root=;否则走"项目根不可解析"分支并 fail-closed(不会回退到process.cwd(),避免跨项目共享白名单/作业) - 刚提交 20 秒内的作业在
remote_status里会被宽容处理,不会被误报为unknown;之后状态机才会自动迁移running → succeeded/failed/killed remote_run的作业超时默认 30 分钟、最长 10080 分钟(7 天);timeoutMinutes必须为 1–10080 的整数,超长任务需显式给超时- 拉回本地的输出按 100 MB 阈值分流:小于等于阈值的文件
scp拉回本地并写入pulled-manifest.json,超过的文件路径记录在bigFiles,需要时可用remote_exec手动下载 - 单个工件文件大小上限 8 GiB(
maxFileBytes),超过会报ERR_QUOTA;同内容默认用硬链接去重,跨设备自动降级为复制(allowHardlink: false可关闭) - 模型分档路由的分类器目标建议选非 thinking 模型:thinking 模型的推理内容同样消耗
maxTokens额度(默认 512),曾出现把额度用光导致拿不到分类词的情况 - 跨档位混用历史时,若 thinking 模式目标因历史工具调用消息缺
reasoning_content拒绝请求,引擎会自动补占位推理块透明重试一次(日志有 warn) - 模型分档路由在选中「智能分档」后的极短窗口内新建会话可能"继承"分档(平台把会话模型选择写到了全局默认模型),属已知 best-effort 限制;其他时刻未选中的会话零路由
- 远程主机设置页的客户端 bundle 由
scripts/build-client-bundle.mjs打包到client/remote-hosts-ui/lib/client.js,发布前需运行npm run build:client,否则设置页可能不出现
A Claude Science–style research workbench for DeepSeek Harness — for genomics / pathogens / human health / bioinformatics projects.
One-liner: dsh-science — Claude Science-style research workbench for DSH: ReAct research-loop engine (research_* tools), versioned artifacts with provenance (artifact_* tools), an SSH remote-compute engine (remote_* tools, mirroring Claude Science's Computer / Remote compute clusters), and 11 science skills for genomics / pathogens / bioinformatics.
- ReAct research loop engine —
research_init/research_state/research_hypothesis/research_experiment/research_findings/research_phase/research_review/research_report, persisted in aresearch-manifest.jsonstate machine (Question → Hypothesis → Experiment → Observe → Analyze → Conclude → Next Question). - Versioned artifacts with provenance —
artifact_save/artifact_list/artifact_show/artifact_diff/artifact_verify/artifact_deprecate/artifact_reproduce: every result saved asartifacts/<name>/v<N>/with per-file SHA-256,artifact.jsonprovenance (command / inputs / environment / envFile) and an append-onlyprovenance.md. - Remote compute engine (SSH / HPC clusters) — 16 tools:
remote_host_add/remote_host_probe/remote_host_notes/remote_run/remote_status/remote_logs/remote_pull/remote_cancel/remote_execetc. Connect lab workstations or HPC clusters via~/.ssh/configaliases (nothing installed on the host, zero third-party deps). Long bioinformatics jobs run as detached processes on workstations or viasbatchon SLURM — they survive connection loss; submission asks for approval by default;remote_statusbatch-monitors and auto-transitions state (running → succeeded/failed/killed);remote_pullfetches outputs back (files over the size threshold stay on the host with their paths recorded). - Remote Hosts config UI (bundle/profile-level) — a Settings > 远程主机 page (the analog of Claude Science's Settings > Compute > SSH hosts): list/add/probe/edit/remove hosts, plus each project's access allowlist and job summary. Host-side REST API (
webServerroute/dsh-science/remote-hosts/*,engines/remote-hosts-ui.mjs) + client bundle (client/remote-hosts-ui/, built byscripts/build-client-bundle.mjs) sharing the same data files as the remote engine. Requires a web-process restart to activate (see docs/remote-hosts-ui.md). - Model Tier router (tiered, cross-provider) — via the companion bundle
dsh-model-tier: within one session, automatically routes auxiliary requests (session titles, compaction summaries) and subagent/background tasks to a light tier, keeps the main conversation on the default tier, and escalates complex work (deep subagent chains, very long inputs) to a strong tier — each tier may point at a different provider (e.g. strong GLM-5.3 / default deepseek-v4-flash / light minimax-M3), mirroring Claude Code's Opus/Sonnet/Haiku strategy. Built on DSH's nativeagent/request+llm/streamwaterfall extension points; a no-op when the tier's provider is unregistered. Installed automatically with dsh-science, but also standalone-installable into any profile (dsh plugin add dsh-model-tier). - 11 science skills — research-loop, science-project-setup, artifact-provenance, scientific-reviewer, literature-connector, parallel-delegation, manuscript-writing, bioinformatics-toolkit, conda-environments, data-inventory, remote-compute.
All in-repo engine plugins are zero-dependency (Node built-ins + the system OpenSSH binaries, sharing engines/core.mjs) and register plain cordis tools; the companion dsh-model-tier router is likewise zero-dependency. Installable either as a profile bundle (dsh plugin add) or as an agent preset (科学模式).
v0.2.0: Model Tier router (new, companion bundle)
Mirrors Claude Code's Opus/Sonnet/Haiku tiering: within one session, auxiliary requests (purpose ∈ {session-title, compaction}) and subagents (session.meta.origin === 'subagent') are routed to the light tier; the main conversation keeps its own per-session model selection (never overridden); deep subagent chains (delegationDepth ≥ subagentDepthStrong) and very long inputs (escalateOnChars, opt-in) escalate to the strong tier. An optional LLM pre-classifier (routing.classify) grades each user prompt / subtask dispatch by complexity (light / default / strong) before routing. Each tier is {provider, model, reasoningEffort?} and may span providers.
Ships as the standalone bundle dsh-model-tier — dsh-science depends on it and mounts it in its cordis.patch.yml, but it can equally be installed on its own into any profile (dsh plugin add dsh-model-tier):
- id: model-tier
name: dsh-model-tier
config:
tiers:
strong: { provider: zai-coding-cn, model: glm-5.3 }
default: { provider: deepseek-official, model: deepseek-v4-flash }
light: { provider: opencode-go, model: minimax-m2.7 }
routing:
auxiliary: [session-title, compaction]
subagents: light
subagentDepthStrong: 3
- Host plane — mounted in the profile bundle (
cordis.patch.yml), not the agent preset, so it applies to every session and subagent on the profile. - Safety rails — no
tiersconfigured → inert no-op; target provider unregistered → no routing; a failing light-tier call automatically falls back to the original route (auxiliary features never break). - Verified —
node packages/dsh-model-tier/test/model-tier.test.mjs(zero-dependency unit matrix) +bash packages/dsh-model-tier/scripts/test-model-tier.sh(E2E: light tier pointed at a local mock LLM; asserts the title request is actually routed).
v0.2.0: Remote compute (new)
Mirrors Claude Science's Remote compute clusters / Computer capability, following its documented mechanism:
- Host registration + read-only probe —
remote_host_addtakes a~/.ssh/configalias (oruser@host; ProxyJump etc. handled by OpenSSH), with optional port/identityFile overrides; probing records CPUs, memory, GPUs, CUDA driver, conda/module/Apptainer presence, scratch dirs,sbatchand SLURM partitions (remote_host_probere-runs it). Host registry:$DSH_HOME/remotes/hosts.json. - Job submission —
remote_runcopies script + inputs into<scratch>/<jobId>/(default~/dsh-scratch); workstations run it as a detachednohup+setsidprocess (connection-loss safe), SLURM clusters getsbatch(with--time); default job timeout 30 min; submission asks for approval by default (the analog of Claude Science's "Run this job on?" card). - Monitoring & reaction —
remote_statusbatch-probes (ps / squeue+sacct / done+exitcode markers) and auto-transitions state;remote_logstails logs;remote_pullfetches outputs and writespulled-manifest.json(files > 100 MB stay on the host with recorded paths);remote_cancelkills (process group / scancel). Job registry:<project>/.dsh/remotes/jobs.json, persists across sessions. - Host Details document —
remote_host_notesmaintains per-host notes (environment activation, partitions/account, conventions) that the model reads before submitting jobs. - Per-project access allowlist (allowed servers, isolated per project) — every host-connecting action (add/probe,
remote_host_probe,remote_exec,remote_run) requires the host to be in the project's allowlist (.dsh/remotes/allowlist.json) by default; first use pops an approval dialog and, on approval, persists the grant at project scope (the analog of Claude Science's "This project" approval scope). The project root resolves by priority:research-manifest.json(research project) →.dsh(workspace) →.git→ session cwd — multiple research projects in one workspace keep separate allowlists; grants never leak across projects (authorization paths fail closed when no session cwd is available). Review withremote_host_allowlist, revoke withremote_host_revoke, pre-grant withremote_host_allow(approval-gated); disable withrequireHostAccess: falsefor unattended runs.
v0.1.1 hardening (robustness update)
- Concurrency-safe state: all manifest/artifact writes go through a lightweight file lock (O_EXCL + stale reclaim) and atomic tmp+rename — parallel subagents can no longer corrupt or lose updates on
research-manifest.json/artifacts.json. - Structured error codes (
ERR_NOT_INIT/ERR_NOT_FOUND/ERR_VALIDATION/ERR_PATH/ERR_QUOTA/ERR_LOCK_TIMEOUT/ERR_IO) instead of opaque strings. - Hypothesis state machine (proposed → testing → supported/refuted/inconclusive) and forward-only phase transitions (rewind requires config).
- manifest ↔ artifacts linked:
research_statemerges the artifact index;artifact_savewrites back to the manifest. - Manifest schema v1→v2 migration on load, persisted on next write.
- Artifact upgrades: streaming SHA-256 (big files), identical-content dedup via hardlink,
artifact_diff/artifact_verify/artifact_deprecate, envFile + input hashes in provenance. - Structured JSON outputs (
research_report,artifact_diff,artifact_verify) and an audit log at<root>/.science.log.
Install
Option A — profile bundle (community standard)
dsh plugin --profile web add dsh-science # after npm publish
# or straight from GitHub:
dsh plugin --profile web add "github:biociao/dsh-science"
Restart the profile (or refresh the Web GUI). The bundle inserts the three engines
into the profile layer stack; the research_* / artifact_* / remote_* tools
become available to every agent on that profile.
Option B — agent preset (full 科学模式 experience, per-agent)
git clone https://github.com/biociao/dsh-science ~/.dsh/.agent-presets/science
# or from a local checkout:
bash scripts/install.sh # copy (or: bash scripts/install.sh link)
Then create a session in the DSH Web GUI and pick the 科学模式 preset — the preset carries the research persona + engines with per-agent scoping.
Skills
The 11 skills are discovered automatically from a project's .dsh/skills/
(drop this repo's skills/ into your project), or install them machine-wide:
bash scripts/install-skills.sh # -> ~/.dsh/skills (respects $DSH_HOME)
Quick start (first session)
research_init— createresearch-manifest.json+ the project skeleton (experiments/ literature/ artifacts/ analyses/ figures/ manuscript/ reviews/ data/ envs/).- Read
research_stateat the start of every session; the loop state persists across sessions. - Run the loop:
research_hypothesis(H1/H2/…) →research_experiment(E01/…, createsexperiments/<id>/{design.md,log.md,code/,results/}) → run code →research_findings(appends to log.md, updates hypothesis status, advances the loop) →artifact_savefor anything worth citing or reproducing. - When GPU/cluster/specialized environments are needed:
remote_host_addthe host →remote_runa background job (approval required) → pollremote_status/remote_logs→remote_pulloutputs when done →artifact_saveto archive. See docs/remote-compute.md and theremote-computeskill. - For key claims: extract the claim, have a review subagent check it against the
execution records (see the
scientific-reviewerskill), archive withresearch_review(writesreviews/R0n/report.md).
Repository layout
dsh-science/
├── package.json # dsh.bundle.patch -> ./cordis.patch.yml (+ dsh.client + exports)
├── cordis.patch.yml # bundle patch: inserts the engines by subpath export + mounts dsh-model-tier
├── packages/
│ └── dsh-model-tier/ # 配套独立 bundle:模型分档路由(可单独 dsh plugin add)
├── engines/ # canonical engine sources (bundle form)
│ ├── core.mjs # shared core: locks, atomic writes, error codes, streaming sha256, structured tools, audit
│ ├── research-loop.mjs
│ ├── artifact-registry.mjs
│ ├── remote-compute.mjs# SSH/local transports, host registry + probe, job submit/monitor/pull/cancel
│ └── remote-hosts-ui.mjs# Remote Hosts 设置页的宿主 REST API(webServer 路由)
├── client/ # client 插件(设置页 UI,bundle/profile 级)
│ └── remote-hosts-ui/ # src/index.js 源码 · lib/client.js 打包产物(build-client-bundle.mjs)
├── preset/ # agent-preset form (mirrors engines/ via sync-engines.sh)
│ ├── agent.cordis.yml # references ./engines/*.mjs (relative, preset mount)
│ ├── preset.yml
│ └── engines/ # mirror — keep in sync: bash scripts/sync-engines.sh
├── skills/ # 11 SKILL.md skills
├── scripts/
│ ├── install.sh # install preset -> ~/.dsh/.agent-presets/science
│ ├── install-skills.sh # install skills -> ~/.dsh/skills
│ ├── sync-engines.sh # mirror engines/ -> preset/engines/
│ ├── init-project.sh # project skeleton without a science session
│ ├── build-client-bundle.mjs # wrap client src -> __ModuleLoader__ bundle (lib/client.js)
│ ├── smoke-test.mjs # 125 checks against a temp workspace (node >= 18)
│ └── stability-test.mjs# 25 concurrency/atomicity/stress checks (locks, lost-update, soak, migration)
└── test/verify-bundle.sh # isolated end-to-end bundle install + boot + client scan check
Verification
node scripts/smoke-test.mjs # engine logic + end-to-end loop + error codes + migration
node scripts/stability-test.mjs # concurrency / atomicity / lock / stress stability checks
bash test/verify-bundle.sh # pnpm pack -> isolated profile -> install -> boot check
All are part of the release checklist and are safe to run in CI (both test scripts
write only to a temp workspace; the bundle test uses an isolated $DSH_HOME).
FAQ
Why subpath exports and not relative paths in the bundle?
dsh plugin add installs the package into the profile and its cordis.patch.yml
rows join the profile composition. The profile loader resolves a row name
relative to the profile directory (not the package), so ./engines/x.mjs
fails with ERR_MODULE_NOT_FOUND. Referencing dsh-science/engines/x.mjs
(subpath export, exports in package.json) resolves from the profile's
node_modules and works — verified experimentally on dsh 0.1.0-rc.6.
The agent-preset mount, by contrast, resolves relative names from the preset
directory, which is why preset/agent.cordis.yml can use ./engines/*.mjs.
Bundle or preset — which should I use?
- Bundle: tools available to every agent on the profile; one command to install.
- Preset: the full 科学模式 experience (research persona, per-agent scoping).
The persona row in
cordis.patch.ymlis commented out because a profile-wide persona would apply to all agents — uncomment it before publishing if that is what you want.
Where do the skills come from?
A project's .dsh/skills/ is auto-discovered; scripts/install-skills.sh puts
them machine-wide in ~/.dsh/skills (respecting $DSH_HOME).
Development
Branching model & release workflow (main = release, dev = integration, feat/* = features,
tag-triggered npm publish + GitHub Release via Actions): see
docs/branching.md.
bash scripts/sync-engines.sh # after editing engines/*.mjs — keeps preset/engines in sync
node scripts/smoke-test.mjs # logic + static package checks
node scripts/stability-test.mjs # concurrency / atomicity / lock stability checks
bash test/verify-bundle.sh # end-to-end bundle install + boot
Workspace-isolation patch — DSH's New Session used to fall back to the most
recently used Workspace, letting automation spawn sessions into unrelated
projects. scripts/patch-session-isolation.mjs applies the one-line guard
(idempotent, backs up first; re-apply after every dsh upgrade). See
docs/workspace-isolation.md.
node scripts/patch-session-isolation.mjs apply # idempotent, backs up first
node scripts/patch-session-isolation.mjs status # check current state
node scripts/patch-session-isolation.mjs revert # restore pristine file
Community
- Topic: github.com/topics/dsh-plugin
- Curated lists: awesome-dsh-plugin · awesome-deepseek-harness
License
MIT — see LICENSE.
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/biociao/dsh-science)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.