6.3 KiB
6.3 KiB
DSH 预设就地化(取消独立 bundle 包)设计
日期:2026-10-12 状态:已获用户批准(2026-10-12 逐节确认)
1. 总览
目标:把 rev-skills 的 DSH 独立预设从「仓库内第二个 npm 包」改为「根包自带的 bundle 声明」,去掉重复的包壳与随之而来的同步点;预设行为(预设 id、技能根解析顺序、bin/dsh.mjs 子命令)完全不变。
来源:PR #5(dnfme:feat/dsh-preset)。本设计在该 PR 的分支上追加提交,就地更新 PR。
产出:新增 1 个文件(dsh.patch.yml),删除 dsh/ 整个目录(4 个文件),其余为常量、断言与文档同步。
2. 实测依据
下列结论均在本机 dsh 0.2.0-rc.2 上实测得出,非文档推断:
| 结论 | 证据 |
|---|---|
bundle = 任意 npm 包 + dsh.bundle.patch;profile 的 dsh.profile.bundles 填包名 |
以根包充当 bundle 搭临时 profile,dsh --profile t3 --dump-config 退出 0,preset-rev-skills 出现在末层,customSkillDirs 表达式解析到该包 .claude/skills(122 项) |
| patch 文件名任意,路径由 bundle manifest 声明 | 由 cordis.patch.yml 改名 dsh.patch.yml 后重装并启动,行为不变 |
patch 文件必须列进该包的 files |
漏列时 dsh plugin add 被拒:failed to read overlay …/node_modules/rev-skills/cordis.patch.yml: ENOENT,随后还原 package.json / lock / node_modules |
dsh plugin --profile <p> add <pkg> 会自动追加 dsh.profile.bundles 行 |
实测 manifest 由 ["@deepseek-ai/dsh-base"] 变为 ["@deepseek-ai/dsh-base", "rev-skills"] |
bundle 的兼容性校验对无 @deepseek-ai/* 依赖的包不构成障碍 |
根包 manifest(含 bin / scripts / engines)直接通过校验并加载 |
dsh.bundle.patch 用 link: / file: 本地规格与从 registry 安装都走同一套解析(resolveBundleDir 先查 dsh 安装锚点,再查 profile 目录)。
3. 新布局
rev-skills/
dsh.patch.yml ← 新增(唯一新文件,仓库根)
package.json ← 增加 dsh.bundle、files 换条目
bin/dsh.mjs ← 两个常量
docs/dsh-integration.md← 路线二与同步点表重写
(删除)dsh/package.json、dsh/LICENSE、dsh/README.md、dsh/cordis.patch.yml
dsh/README.md 的面向 DSH 侧说明并入 docs/dsh-integration.md 第 2 节;dsh/LICENSE 不再需要(补丁文件与 bin/ 同属工具代码一侧,由仓库根 LICENSE 覆盖 Apache-2.0)。
4. 根 package.json
- 新增
"dsh": { "bundle": { "patch": "./dsh.patch.yml" } } files:删除"dsh",新增"dsh.patch.yml"(必需,见第 2 节第 3 行)- 版本:沿用 PR 的
0.1.0,与.claude-plugin/marketplace.json成对 - 不变:
bin的rev-skills-dsh、scripts.dsh、keywords、description
5. dsh.patch.yml
- 预设行与 18 个子插件配置照旧(补丁内本无包名,
config.id仍为rev-skills) customSkillDirs表达式:删除第 4 候选(rev-skills-dsh-preset/package.json的..join);原第 3 候选「包目录」即本包自身,语义不变- 头部注释按「本包即 bundle」重写;技能根解析顺序说明保留(
REV_SKILLS_DIR→<DSH_HOME>/skills→ 本包)
6. bin/dsh.mjs
BUNDLE_DIR:join(REPO_ROOT, 'dsh')→REPO_ROOTBUNDLE_PACKAGE:'rev-skills-dsh-preset'→'rev-skills'resolveLocalSkillRoot的候选说明文案:从 rev-skills / rev-skills-dsh-preset 的 package.json 反解→ 单包- 其余逻辑(
check与四个preset子命令、dry-run、备份、原子替换)一行不动
7. 测试
tests/dsh.test.mjs、tests/dsh-preset.test.mjs:导入常量与断言随包名/目录改名同步;夹具里的假node_modules/rev-skills-dsh-preset改为rev-skillsdsh/package.json 是合法 bundle 清单改为根 manifest 断言:name为rev-skills、dsh.bundle.patch指向存在的文件- 新增回归断言:
dsh.bundle.patch指向的文件必须出现在根package.json的files列表中(把第 2 节的坑固化;漏列即测试失败) - CLAUDE.md 的测试计数(
npm test = validate + 202 项测试)按实际数同步
8. 文档
docs/dsh-integration.md:第 2 节路线二重写(bundle 名为rev-skills;安装命令dsh plugin --profile <p> add rev-skills,本地路径用link:/file:;说明add会自动登记bundles行);技能根候选表删除第 4 行;第 6 节同步点表把「版本号 ↔dsh/package.json」两行替换为「dsh.bundle.patch↔dsh.patch.yml实际路径 + 该路径必须列进files」README.md/README_EN.md/AGENTS.md/CLAUDE.md的 DSH 段落同步(涉及dsh/目录与包名rev-skills-dsh-preset的表述全部改写)
9. 验证清单
node validate.mjs→OK: 122 skills validatednpm test→ 全绿,计数与 CLAUDE.md 一致node bin/dsh.mjs check→OK: 122 skills DSH-compatible (32 warning(s))- 临时 profile:
dsh plugin --profile <p> add <本仓绝对路径>→ manifest 自动出现rev-skillsbundle 行 →dsh --profile <p> --dump-config退出 0 且含preset-rev-skills node bin/dsh.mjs preset spec|status|install --apply|uninstall --apply往返(dry-run 先行、apply 后 status 为 ok、uninstall 后复原)npm pack --dry-run输出中包含dsh.patch.yml
10. 不做
- 不改
.claude/skills/下任何技能内容 - 不改 PR 中与该目标无关的改动:
.gitattributes、lib/frontmatter.mjs的 CRLF 容忍与键文法放宽、bin/install.mjs的--target dsh、新增测试文件 - 不删除
bin/dsh.mjs的preset子命令(用户明确保留,尽管宿主dsh plugin add已覆盖安装路径)
11. 风险
| 风险 | 处置 |
|---|---|
| 根包被当作 bundle 后,兼容性校验要求声明 DSH peer 版本范围 | 实测无 @deepseek-ai/* 依赖即通过;若 DSH 后续收紧,退回独立包即可(本设计不改变补丁内容,两形态可互换) |
files 漏列 patch 文件 → 安装期才报错 |
测试固化为回归断言(第 7 节) |
使用 link: 安装时 profile 直接引用工作区,改补丁立即生效、改后未重启则不生效 |
文档排错表保留「预设改完没生效」一行,处置改为重载/重启会话 |