DeepSeek Harness(DSH)的声明式定制仓 —— 一份 manifest 管理全部定制,幂等物化到 ~/.dsh
本仓库是 DSH(DeepSeek Harness)的定制仓:总配置统一管理,各项定制可插拔、独立版本、独立维护,但都在同一仓库内。
手工维护 AI agent 运行时的插件、版本和配置很容易变成一堆"改过但没人记得为什么"的本地状态。ohmydsh 用一份声明式 manifest 把这些收敛成可复现、可审查、可回滚的工程资产:
- 🎛 单一开关面 ——
dsh.yaml管住 DSH 版本、第三方插件、自研 package、patch、skill 与环境级指令。 - 🔁 幂等物化 ——
dsh build把仓库状态同步到~/.dsh,重复执行结果一致,失败 fail closed。 - 🔌 可插拔 —— 每项定制独立启用、禁用、升级、移除;
enabled: false≠ 删除。 - 📌 精确 pin,不 vendor —— 第三方只存版本 pin、覆盖片段与审查记录,信任面清晰可查。
- 🚀 自动跟版 ——
autoUpdate检测新版 DSH 后阻塞式升级、重跑 sync 并自动提交,工作区不干净时不动手。 - 📐 规范驱动 —— 行为变化先过 OpenSpec(proposal → design → spec → tasks),再落实现。
- 仓库是唯一真相源。
dsh.yaml+ 各定制目录 +instructions/dsh-home.md= 完整配置;~/.dsh是物化产物。 - 根
package-lock.json是全部 npm workspace 的唯一依赖锁;TypeScript local package 只提交src/,gitignoredlib/由根 build/sync 生成。 cordis.patch.yml、presets/skills 与$DSH_HOME/AGENTS.md都应从仓库修改后重新 sync。AGENTS.md有 ownership/hash 漂移防护:发现未托管文件或本地改动时会报错并保留,不会静默覆盖或删除。- OpenSpec checking 长期只提交报告、trail、gate、复现脚本或显式审核的 test fixture;raw history/baseline 和批量截图应放外部 artifact,或在报告中声明仅临时留存。
- 提交前运行
npm test与npm run check:artifacts,防止生成产物、nested lock、raw evidence 或重复架构图进入 Git。 - 禁用 ≠ 删除:
enabled: false只表示不物化,仓库内容保留,随时可重新启用。
dsh.yaml # 总配置(唯一开关面)
BACKLOG.md # 想法池
openspec/ # spec-driven 变更流程
scripts/bootstrap.sh # clone 后初始化:检查 Node 环境 + 安装依赖(幂等)
scripts/install.sh # 一键安装:bin/dsh → ~/.local/bin(幂等,可卸载)
scripts/sync.mjs # manifest → ~/.dsh 物化
instructions/dsh-home.md # 工作环境级模型指令源文件
packages/<name>/ # 自研 bundle 插件(见 packages/README.md)
presets/<id>/ # agent preset(见 presets/README.md)
patches/<id>.yml # 纯 composition 片段 / 对 remote 包的覆盖(见 patches/README.md)
skills/<name>/ # skill(见 skills/README.md)
docs/notes/ # 可长期检索的问题与决策记录
tests/ # sync 黑盒回归测试
展示资产为
archify-out/ohmydsh-architecture.dual.svg(单文件,自带明暗主题适配); 可编辑图源为archify-out/ohmydsh-architecture.json,架构变化时更新图源并重新导出该 SVG。
从零开始(clone 以后到能用的完整流程;macOS / Linux / WSL / Git Bash 通用,bin/dsh 是 bash 脚本,Windows 原生不支持):
git clone <仓库地址> && cd ohmydsh
./scripts/bootstrap.sh # ① 初始化:检查 Node 环境 + 安装依赖(只需一次,幂等)
./scripts/install.sh # ② 安装 dsh 命令到 ~/.local/bin
dsh build && dsh # ③ 物化定制配置并启动,UI 自动打开- 前置要求:Node.js >= 22 + npm >= 10(推荐
.nvmrc中的版本);根package.json的engines声明最低版本,bootstrap 只在低于最低版本时报错,更高版本仅提示不阻塞; - 依赖出问题想重装:
./scripts/bootstrap.sh --force; - install.sh 默认装到
~/.local/bin/dsh(想换目录:DSH_BIN_DIR=/opt/bin ./scripts/install.sh);重复执行可覆盖更新,不影响~/.dsh物化产物; - 装的是相对符号链接,仓库整体移动后命令依然可用,无需重装;
- 若
~/.local/bin不在 PATH,脚本会打印各 shell(bash/zsh)的配置提示; - 卸载:
./scripts/install.sh uninstall; - 跳过脚本?在仓库根执行等价的原始命令也行:
ln -s "$PWD/bin/dsh" "$HOME/.local/bin/dsh"
快速上手(命令已装好;还没装?先看上面「从零开始」):
dsh build # 1. 首次:按 dsh.yaml 把定制物化到 ~/.dsh(改了配置后也要重跑)
dsh # 2. 启动:自动在后台拉起(是否就绪后自动打开 UI 由 web.open 决定,默认开;本仓库默认关)
dsh stop # 3. 停止服务- 想一步到位?"构建 + 启动"用
dsh -b; - 启动后 UI 在 **http://127.0.0.1:3080**(换端口:`dsh -p 8080`);
- 每次启动/停止,终端都会打印当前加载的插件清单,一眼看清生效了哪些定制;
- 重复执行
dsh不会起第二个实例:已在运行就只是帮你把 UI 打开。
日常命令(按场景查):
| 场景 | 命令 | 说明 |
|---|---|---|
| 启动 | dsh |
未运行 → 后台拉起 + 打开 UI;已运行 → 打开 UI;UI 也已打开 → 提示"已在运行"。UI 打开策略:显式 DSH_OPEN_APP(PWA/应用)优先;未配置时自动探测已安装的 DeepSeek Harness PWA,命中即只开 PWA;否则浏览器。dsh.yaml 置 web.open: false(本仓库默认)则不自动打开,需要时 dsh --open |
| 构建 + 启动 | dsh -b |
改过 dsh.yaml 或插件后,先重新物化再启动 |
| 只构建 | dsh build |
只把配置物化到 ~/.dsh,不启动 |
| 停止 | dsh stop |
按监听端口验证并停掉 DSH server,同时关闭 PWA 与 Chrome 中同端口的 DSH 标签;非 DSH 进程占端口时拒绝误杀 |
| 重启 | dsh restart |
停 server → 关闭全部 UI → 确认端口释放 → 启动 server → 按 web.open 只打开 PWA(存在时),一步到位 |
| 看历史 | dsh history |
历次启动的时间 / DSH 版本 / 端口 / 插件清单(记录在 ~/.dsh/dsh-startup.log) |
| 一键清空定制 | dsh reset |
移除自定义插件、preset、skill,并安全撤销托管的 $DSH_HOME/AGENTS.md(反悔了?dsh build 就能恢复) |
| 统一升级插件 | dsh plugin-update |
检测远端插件新版本(兼容性/稳定性判定)→ 逐条确认 → 改 dsh.yaml + sync + 自动提交;--dry-run 只预览,--yes 跳过确认;needs-review 条目永远等人工 |
| 调试 | dsh --foreground |
前台运行,日志直接打在终端 |
| 换端口 | dsh -p 8080 |
默认 3080 |
| 不弹 UI | dsh --no-open |
启动/检测时不自动打开 UI(优先级最高;dsh --open 反方向强制打开) |
小知识:"build" 就是按 dsh.yaml 物化到 ~/.dsh(即 node scripts/sync.mjs,幂等可重跑);DSH_HOME 未设置或只含空白时默认 ~/.dsh,也支持 DSH_HOME=~/...;DSH 版本单一来源是 dsh.yaml 的 dshVersion,启动时动态读取。
自动升级 DSH 运行体(autoUpdate,默认开):
dsh(未运行)/dsh -b/dsh build/dsh restart前置会检测@deepseek-ai/dsh在 registry 目标频道(latest或next)的最新版本;低于最新即阻塞式自动升级再继续:改dsh.yaml的dshVersion+ 同族@deepseek-ai/dsh-*pin → 重跑 sync 物化 →git commit --no-verify(chore(dsh): auto-bump <旧> → <新>)→ 再启动;- 只会自动改写名字匹配
@deepseek-ai/dsh-*且 pin 等于旧运行体的条目,第三方插件与刻意钉住的其他版本不动;改写前留dsh.yaml.bak,sync 失败即从备份回滚并报错不启动; - 前提是工作区干净:仓库有未提交改动时不升级,输出会说明原因(提交后下次启动自动跟上);检测失败/离线时按当前版本继续,不阻塞;
- 逃生门 & 频道:想钉在旧版,
dsh.yaml置autoUpdate.enabled: false或临时DSH_SKIP_UPDATE=1 dsh;追next(前夜版)用DSH_UPDATE_CHANNEL=next dsh(或改autoUpdate.channel); - 升级/跳过/离线事件记录在
~/.dsh/dsh-startup.log,dsh history可见。
临时 rc.2 运行体防卡死策略(默认启用):
@deepseek-ai/dsh@0.1.1-rc.2已有精确版本的 npx 或 ohmydsh pnpm 缓存时,启动、build 和官方 CLI 都直接执行缓存入口,不重复运行 npx 计算预发布 peer 依赖;- 两级缓存都缺失时,rc.2 默认跳过已观察到可能长期卡死的 npm/libnpmexec 通道,改用有超时、临时 staging 和完整性校验的 pnpm 固定缓存;失败不会换用其他 DSH 版本,也不会覆盖已有可用缓存;
- 仅用于隔离诊断或验证上游修复时,可单次运行
DSH_ALLOW_NPX_PROVISION=1 dsh ...恢复 npx-first,但仍受超时保护;它与只控制版本检测的DSH_SKIP_UPDATE=1含义不同; dsh stop始终只做本地进程/UI 清理,不触发 npm/npx/pnpm。临时策略的删除 gate:隔离冷 npx install、连续 build、重复 restart 均能在超时内稳定通过后,删除scripts/lib/dsh-cli.mjs中唯一的 rc.2 策略项及对应测试。
UI 打开方式(web.open 开关 + DSH_OPEN_APP 选目标,不用改 shell 配置):
- 默认:就绪后自动打开,目标=系统默认浏览器打开
http://127.0.0.1:3080; - 不想自动弹任何 UI:
dsh.yaml置web.open: false(本仓库默认关)后dsh build,或临时dsh --no-open;需要时dsh --open强制打开; - 官方
dsh web自身默认也会打开浏览器;ohmydsh 启动官方进程时固定传--no-open,只保留本启动器一个 UI opener,避免一次命令打开两个 tab; - 想用 PWA 窗口 / 指定 App 打开:仓库根
.env.local(gitignored,模板见.env.local.example)写DSH_OPEN_APP=...,启动时自动生效;也可以临时DSH_OPEN_APP="xxx.app" dsh(行内优先); - 注意:自定义端口(
dsh -p)时 PWA 打开的是自己的 start_url,可能对不上,这种情况用--no-open手动开。
sync 行为按定制类型:
| 类型 | source | 物化动作 |
|---|---|---|
| package | local | dsh plugin add file:<packages/<id>>(自动进 profile bundles) |
| package | remote | dsh plugin add <spec>(自动进 profile bundles) |
| preset | — | copy 到 ~/.dsh/.agent-presets/<id> |
| patch | — | 按 manifest 顺序合并生成 profile cordis.patch.yml |
| skill | — | copy 到 ~/.dsh/skills/<id> |
顶层 dependencies: = 无 bundle 的支撑包(如 remote 定制缺失的 peer),精确版本 pin 装为 plain dependency、不进 bundle 层;定制条目用 deps: 引用其包名声明归属(安装仍以顶层列表为唯一入口,sync 校验引用,悬空引用报错)。
定制项按需开关(enabledEnv,可选字段,任意 customizations 条目都能声明):声明后同名 DSH_ 环境变量覆盖该条目的 enabled,作用范围是单条定制而不是整个 profile——用于"仓库里默认关闭,但在有权限/有需要的机器上用环境变量按需打开"的场景,例如内部专属包:公开分享这份仓库时它不该默认安装,但在有权限的机器上不想手改 dsh.yaml。写法:
- id: some-internal-plugin
enabled: false # 仓库默认关闭
enabledEnv: DSH_SOME_PLUGIN # 同名 env 覆盖上面的 enabled;必须是大写 DSH_ 前缀DSH_SOME_PLUGIN=1(或 true/yes/on)在该机器上启用,=0(或 false/no/off)禁用;不设置或取值无法识别时回退到 enabled 字段。enabledEnv 名字不合法(不是大写 DSH_ 前缀)时 sync 直接报错并中止,避免拼错后"开关看起来没生效"却毫无提示。改动后同样需要 dsh build 才生效。仓库内 dsh-traex-bridge(内部包)就是这个模式的实例,见下方「第三方定制」。
顶层 agentInstructions 不是一种 customization type。启用时,sync 校验 source 是仓库内相对文件,加 GENERATED/provenance 头后原子写入 $DSH_HOME/AGENTS.md,并在 .dsh-sync-state.json 记录来源与部署哈希。连续 build 幂等;禁用、删除字段或 dsh reset 时,只会删除仍匹配已部署哈希的目标。目标若已有未托管内容,或托管后被修改,sync 会保留文件并报错,要求人工决定如何处理。
DSH 官方 standard preset 会自动加载,无需复制出 ohmydsh preset。$DSH_HOME/AGENTS.md 给该 DSH 工作环境提供前馈模型指导;它不是权限授予,也不是强制安全边界,实际能力始终由最新 runtime context 与工具执行策略决定。dsh-sandbox-notes skill 继续保留,用于需要时查阅完整背景与恢复细节。
现象、迁移原因、错误恢复规则与验证步骤见 docs/notes/dsh-home-agent-instructions.md。
- 只存三样:精确版本 pin、个人覆盖片段(
patches/<id>.yml)、条目说明(note/审查记录);不 vendor 源码。 - 升级 = 改 pin 重跑 sync(默认由
autoUpdate自动完成,见上方「自动升级」;DSH_SKIP_UPDATE=1恢复纯手工改 pin 模式)。 - 安全提醒:插件即第三方代码(社区列表明示警告),安装前先看源码,
note记录来源与审查结论。 dsh-traex-bridge(内部专属包):来自 bnpm/内网(code.byted.org),鉴权与推理流量走 ByteDance 内网服务,仓库默认enabled: false+enabledEnv: DSH_TRAEX_BRIDGE(见上方「定制项按需开关」)。克隆本仓库的机器默认不装它;有内网权限时,本机.env.local(gitignored)加一行DSH_TRAEX_BRIDGE=1后dsh build即可启用,详见dsh.yaml条目note。llm-subscriptions订阅 provider 插件(dsh-plugin-subscriptions,当前 pin0.5.2+pr40.d927e3a= 上游 PR #40「按模型默认推理档」临时 fork tarball,设置页每模型默认档列表收起,详见dsh.yaml条目 note;上游合并发版后切回 npm):Claude 登录 = 导入本机 Claude Code 凭据(秒登录,不弹 OAuth),升级与选型细见 changeopenspec/changes/2026-08-20-llm-subscriptions-upgrade(含 ADR-0001)。回滚:dsh.yaml该条目spec/version改回dsh-plugin-subscriptions@0.5.2/0.5.2(或删除临时条目) →dsh build→ 重启;codex 会话不受影响,可无损回滚。
- 新想法 →
BACKLOG.md;单项实施 → openspec change(openspec new change <name>); - 自研 package 改代码后要 bump 版本(manifest 同步),sync 才会重装;
- DSH 运行体由
autoUpdate自动升级并重跑 sync 恢复全部定制;手工升级同样 = 改dshVersion后重跑 sync。
提交前请运行:
npm test # sync 黑盒回归测试
npm run check:artifacts # 防止产物 / nested lock / raw evidence 入库欢迎 Issue 与 PR。动手前请先读 CONTRIBUTING.md,它说明了阅读顺序、OpenSpec 规范驱动流程、验证要求与提交规范。
参与本项目需遵守行为准则。安全问题请勿开公开 Issue,按 SECURITY.md 私下报告。
| 文档 | 说明 |
|---|---|
| CONTRIBUTING.md | 贡献流程、开发环境与验证要求 |
| SECURITY.md | 漏洞报告渠道与本项目特有的安全考量 |
| CHANGELOG.md | 仓库级变更记录 |
| CODE_OF_CONDUCT.md | 社区行为准则 |
openspec/specs/ |
系统当前应满足的行为规范 |
docs/adr/ |
已接受的长期架构决策 |
docs/notes/ |
实现背景、运行约束与验证方法 |
BACKLOG.md |
想法池 |
- DeepSeek Harness (DSH) —— 本仓库定制的运行体本体。
- 各第三方插件作者;来源、许可与审查结论记录在
dsh.yaml对应条目的note中。
本项目基于 MIT License 发布。
第三方定制以 pin 方式引用、不 vendor 源码,各自遵循其原始许可;packages/worktree-session 的交互概念参考详见该目录下的 NOTICE。