Skill Converter(跨客户端技能转换)
把一个来自其他 agent 客户端的技能目录,转成可直接放入 DSH 技能根目录并通过校验的 DSH 技能。转换只做格式与目录适配,不改业务语义,源目录保持原样。
When to Use
- 用户给了一个技能目录 / zip 并说“转成当前客户端 / 这里的技能”
- 迁移
~/.claude/skills/*、~/.codex/skills/*、~/.codebuddy/plugins/*、技能市场 bundle 中的技能 - 把一个多技能插件 / marketplace 拆成多个独立 DSH 技能
- 一个技能在别的客户端能加载、在当前客户端加载失败或元数据报错时
不在本范围:从零新建技能(走 skill-creator);来源不明技能的安全审查——来源不可信时,转换前必须先走 skill-vetter 审查协议,本技能不替代审查。
Workflow
1. Locate & inventory(定位与盘点)
- 明确 source:单一技能目录、含多个
SKILL.md的插件 bundle、.zip归档、或指向技能目录的符号链接。 - 递归找出全部
SKILL.md;每个SKILL.md的父目录 = 一个待转换技能。 .zip先解压到临时目录再处理;符号链接resolve()真实路径后复制实际文件(不要复制成链接)。- 不修改源目录,转换总是在副本 / 新目录上进行。
2. Detect dialect(判定来源方言)
看 frontmatter 键 + 目录特征(字段对照见 references/skill-formats.md,遇到陌生布局时加载它):
| 特征 | 方言 |
|---|---|
有 type: 或 parent: |
OpenAI Codex |
有 agent_created / disable,或存在 .codebuddy-plugin/ |
CodeBuddy 插件 |
有 allowed-tools,或存在 .claude-plugin/ |
Claude Code / Anthropic Skills |
| 都没有,只有 name/description | 已兼容格式(仍要归一化 + 校验) |
同一技能多种特征并存时,按 Codex → CodeBuddy → Claude 的优先级判定。
3. Safety gate(安全闸门)
- 来源不明 / 他人分享的技能:先按 skill-vetter 完成审查,通过后再转换。
- 转换全程永不执行源目录里的任何脚本;转换后也不得未经用户同意运行其中的代码。
- 只复制,不在原地改动源文件;不顺手改写、重构原技能内容。
4. Convert(转换)
优先用 python3 scripts/convert_skill.py <source> [--out <root>] [--name <new>] [--force] [--dry-run];无 Python 或只需微调时,手工执行同一映射:
| 外来字段 | DSH 处理 |
|---|---|
name |
保留,归一化为小写 kebab-case(≤64 字符);无法归一化(如中文名)时回退到目录名(剥掉 __skillhub 后缀)并记录原名 |
description |
保留(含 \| / > 多行块标量) |
whenToUse |
保留 |
disable-model-invocation / user-invocable |
保留,布尔值合法化 |
metadata |
保留 |
allowed-tools |
DSH 无法表达工具白名单 → 删除,并把原约束改写进正文(如“本技能只应运行 tvly”)并记入转换说明 |
type / parent(Codex) |
删除;子技能摊平成独立技能,父子关系记入转换说明 |
disable / agent_created(CodeBuddy) |
删除 |
其他外来字段(version license display_name visibility tags compatibility description_zh 等) |
删除并记入转换说明;description 缺失时用 description_zh 兜底 |
plugin.json / openai.yaml / hooks |
不迁入 DSH;内容摘要进转换说明 |
- 复制
scripts/、references/、assets/及技能根下其余文件;排除.git、node_modules、.venv、__pycache__、锁文件、.DS_Store、外客户端插件目录(.codebuddy-plugin/、.claude-plugin/)和openai.yaml等清单文件;保留文件可执行位。 - 正文/description 里的跨技能相对引用(如
../tavily-cli/SKILL.md)转换后可能悬空:逐条列出为“待人工检查”,要么把被引用技能一并转换,要么在正文注明依赖。 - 多技能 bundle 逐个生成独立 DSH 技能目录;目标名冲突时报错,用户明确同意才用
--force覆盖。
5. Install(落盘)
- 默认目标:
$DSH_HOME/skills/(DSH_HOME 未设置则~/.dsh/skills/);用户要求项目级时用<工作区根>/.dsh/skills/。 - 绝不静默覆盖已有同名技能。
- 写入被文件沙箱拒绝时:落到工作区临时目录并告知用户,经用户确认后再以更高权限重试;不得自行升级权限。
6. Validate & report(校验与交付)
- 用 skill-creator 的
scripts/quick_validate.py <新技能目录>校验(frontmatter 闭合、name/description、无 TODO 模板、无外客户端字段)。 - 失败则按输出修正后重跑;通过后如实报告:安装范围、绝对路径、被剥离字段与文件清单、待人工检查项。
- 结构性校验 ≠ 行为验证:如验收要求真实行为,做一次实际调用(例如拿一个真实外来技能目录跑一遍完整转换并检查产物)。
- DSH 文件监听用户/项目技能根,落盘后技能即进入技能目录(picker 重开可见;用户技能同时出现在 mos-agent-market 的已安装列表,由开关控制可见性)。
约束(记住)
- 转换 ≠ 审查:来源不清先 skill-vetter。
- 转换 ≠ 语义改写:不要“顺手改进”原技能内容。
- 被删字段是能力损失,必须在转换说明里如实记录,不得假装等价实现。
- 若某项能力(工具白名单、hooks、父子技能)在当前客户端无法表达,如实告知用户。
Resources
references/skill-formats.md— 各客户端技能磁盘布局与 frontmatter 字段对照表;判定方言或遇到字段拿不准时加载。scripts/convert_skill.py— 确定性转换器(仅标准库,无 PyYAML 也能解析常见 frontmatter),支持目录 / bundle / zip / 符号链接输入。