1. 项目概述:AI技能跨平台迁移的痛点与解法

如果你和我一样,在团队里同时用着Claude Code、Cursor、GitHub Copilot这些AI编程工具,那你肯定遇到过这个让人头疼的问题:好不容易给Claude Code写了个好用的技能(Skill),想分享给用Cursor的同事,或者想在CI里用Codex CLI跑一下,结果发现每个工具的技能文件格式都不一样,功能支持也参差不齐。手动重写一遍?太费时,还容易出错。不写?那团队协作和自动化流程就卡住了。这个痛点,就是skillport这个项目要解决的。

简单说,skillport是一个AI编程技能转换器。它能把你在一个AI编程工具(比如Claude Code)里写的技能、规则和指令,自动转换成其他主流工具(如Cursor、Codex CLI、OpenClaw、GitHub Copilot、Windsurf)能识别的格式。它的核心思路很清晰:先把源格式解析成一个通用的中间表示(IR),然后再从这个IR生成目标格式。对于那些没法一对一直接转换的功能,它会用“垫片”(Shim)来模拟,或者明确地告诉你哪些功能丢了,绝不会悄悄地把你的核心逻辑给吞了。

这个工具特别适合跨团队协作的开发者和技术负责人。比如,你作为团队里的“AI工具布道师”,写了个代码审查技能,想让全团队都用上,但大家用的编辑器五花八门。又或者,你想把本地调试好的AI辅助流程,无缝集成到基于Codex CLI的持续集成流水线里。skillport能帮你省下大量重复劳动,让AI技能真正成为可移植、可复用的团队资产。

2. 核心设计思路:解析、转换与“诚实”的垫片

skillport的设计哲学可以概括为“解析、抽象、再生成”,同时秉持“不沉默丢弃”的原则。我们来拆解一下它的核心工作流和背后的考量。

2.1 三层架构:解析器、中间表示与发射器

整个转换过程分为清晰的三层,这保证了系统的可扩展性和可维护性。

第一层:解析器(Parsers) 这一层负责理解各种来源的“方言”。 src/parsers/ 目录下为每个支持的平台(Claude Code、Cursor等)都有一个独立的解析器。每个解析器的工作就是读取特定格式的文件(如Claude Code的 SKILL.md 、Cursor的 .mdc 文件),提取出结构化的信息。这里的关键挑战在于,每个平台的前端元数据(YAML头)和指令正文的约定都不一样。比如,Claude Code用 allowed-tools 字段来限制工具,而Cursor可能把这个信息放在全局配置里。解析器需要足够健壮,能处理各种边缘情况,比如缺失的字段、非标准的Markdown语法等。

第二层:中间表示(Intermediate Representation, IR) 这是skillport的大脑,定义在 src/ir.ts 中。IR是一个与任何具体平台都无关的、纯粹的数据结构,它抽象出了“一个AI编程技能”最核心的要素。通常包括:

  • 元信息 :技能名称、描述、作者等。
  • 触发条件 :这个技能在什么情况下会被激活?是基于文件路径(Glob模式)还是对话上下文?
  • 核心指令 :技能的主体内容,即告诉AI要做什么的Markdown文本。
  • 能力约束 :技能可以调用哪些工具(Bash, Read, Write等),是否有子代理(Subagent)调用。
  • 生命周期钩子 :技能在执行前、后,或者在工具调用前、后需要运行的脚本或逻辑。

将不同来源的信息统一映射到这个IR上,是实现转换的前提。设计IR时,团队必须做出取舍:是追求功能全集(可能导致IR过于复杂),还是聚焦核心交集(可能损失高级功能)。skillport显然选择了后者,并辅以“垫片”策略来弥补差距。

第三层:发射器(Emitters) 与解析器相对应, src/emitters/ 目录下的发射器负责将统一的IR“翻译”成目标平台的格式。这个过程不是简单的字段映射,因为目标平台可能不支持IR中的某些概念。发射器需要根据 src/adapters/ 目录下的适配器逻辑,来决定每个功能点如何落地——是原生支持、用垫片模拟,还是添加注释说明。

2.2 功能映射策略:原生、垫片与注释

这是skillport最体现工程智慧的部分。面对不同平台的能力差异,它采用了三种策略,优先级从高到低:

  1. 原生映射 :目标平台有完全对等的功能。这是最理想的情况,直接转换即可。例如,将Cursor技能的 globs: 字段映射到Copilot的 applyTo: 字段,因为它们语义几乎相同。

  2. 功能垫片 :目标平台没有直接对应的功能,但可以通过一些“曲线救国”的方式实现近似效果。这是skillport的亮点。

    • 指令文本化 :例如,Claude Code的 allowed-tools: [Bash, Read] 是一个强制约束。转换到Cursor时,Cursor没有同级别的强制约束机制。skillport的适配器就会在生成技能指令的开头,添加一行醒目的注释,比如 ## 注意:本技能设计为仅使用Bash和Read工具,请勿使用其他工具。 。这虽然无法从系统层面禁止,但给了AI一个明确的提示。
    • 包装脚本 :对于Claude Code的 PreToolUse 生命周期钩子(在每次工具调用前执行脚本),Codex CLI没有此概念。skillport会生成一个包装脚本放在 scripts/ 目录下。原始技能调用工具的命令,会被修改为先调用这个包装脚本。脚本里就包含了钩子逻辑。这相当于把平台功能“降维”到了脚本层面实现。
    • 上下文预计算 :Claude Code支持动态上下文注入,如 ! git status ``,能在技能运行时执行命令并注入结果。Cursor不支持。skillport会在转换时,生成一个 scripts/render-context.sh 脚本。在Cursor技能被激活前,手动或通过其他方式先运行这个脚本,将结果作为静态上下文提供给AI。
  3. 显式注释 :当某个功能既无法原生映射,也无法通过合理的垫片模拟时,skillport选择“诚实地告知”。它会在生成的文件中添加清晰的 ## 警告 ## 未支持的功能 区块,列出被丢弃的功能点及其原因。这确保了转换的透明性,避免了用户误以为技能完全兼容而踩坑。

注意 :这种“诚实”策略至关重要。在工程实践中,沉默的失败比明确的错误更可怕。skillport通过生成“奇偶校验报告”(Parity Report),让用户对转换后的技能能力有精准的预期。

2.3 项目结构设计的可扩展性

从项目结构可以看出,skillport为未来扩展留足了空间。

skillport/
├── src/
│   ├── parsers/  # 添加新解析器
│   ├── emitters/ # 添加新发射器
│   └── adapters/ # 功能映射逻辑集中管理

这种模块化设计意味着,如果要支持一个新的AI编程工具(比如一个新出的IDE插件),开发者基本上只需要做三件事:

  1. parsers/ 下写一个解析器,理解新工具的配置文件。
  2. emitters/ 下写一个发射器,知道如何生成新工具能懂的配置。
  3. adapters/ 下的各个模块中,补充新工具与其他工具之间的功能映射关系。

已有的 claude.ts cursor.ts 等文件就是最好的模板。这种设计极大地降低了社区贡献的门槛。

3. 实操指南:从安装到生成第一份转换报告

理论讲完了,我们动手把skillport用起来。假设你主要使用Claude Code,想把自己的技能分享给用Cursor的队友。

3.1 环境准备与安装

skillport本身是一个Node.js项目,所以你需要先确保系统里有Node.js(建议版本16+)和npm。

对于Claude Code用户(推荐方式): 这是最无缝的集成方式。因为skillport本身就被打包成了一个Claude Code技能,你可以直接把它“安装”到你的技能库里,然后在聊天窗口里用自然语言命令它。

# 1. 克隆项目到你的Claude Code技能目录
# 注意:将YOUR_USERNAME替换为你的GitHub用户名,或者直接使用项目路径
git clone https://github.com/eikonoikari1/skillport.git ~/.claude/skills/skillport

# 2. 进入目录并安装依赖
cd ~/.claude/skills/skillport && npm install

安装完成后,在你的Claude Code聊天窗口里,你就可以像使用其他技能一样使用它了。例如,直接输入:

@skillport 帮我把 clearshot 这个技能转换成 cursor 格式

或者用更明确的命令:

/skillport convert clearshot to cursor

这种方式非常直观,符合AI辅助工具的使用心智。

对于其他工具用户或CLI爱好者: skillport也提供了传统的命令行接口,不依赖特定编辑器。

# 1. 全局安装(方便在任何地方调用)
npm install -g @skillport/cli
# 或者使用npx直接运行(无需安装)
# npx tsx skillport项目路径/bin/skillport.ts ...

# 2. 转换一个技能
skillport convert ~/.claude/skills/my-awesome-skill --to cursor --output ./converted-skills

如果你不想全局安装,也可以克隆项目后,在项目目录里用 npx tsx bin/skillport.ts 来运行。

为其他工具预置的版本: 项目贴心地为Cursor、Codex CLI、OpenClaw预打包了转换好的技能包,分别放在 .cursor/skills/skillport/ .agents/skills/skillport/ skills/skillport/ 目录下。你可以直接复制这些目录到对应工具的默认技能加载路径。这相当于你拿到了一个“已经转换好的skillport技能”,可以在目标工具里直接使用它来转换其他技能——有点“自举”的味道。

3.2 核心CLI命令详解

安装好后,我们来看看命令行工具的几个核心用法,这些在自动化脚本中非常有用。

基本转换:

# 将Claude Code技能`my-skill`转换为Cursor格式
npx tsx bin/skillport.ts convert ~/.claude/skills/my-skill --to cursor

这个命令会:

  1. 自动检测 my-skill 目录下的文件,识别出它是Claude Code格式。
  2. 进行解析和转换。
  3. my-skill 同级目录(或当前目录)生成一个 .cursor/skills/my-skill/ 的文件夹,里面就是转换好的Cursor技能文件。

批量转换与预览:

# 一次性生成所有支持的格式
npx tsx bin/skillport.ts convert ~/.claude/skills/my-skill --to all
# 这会在输出目录生成 cursor/, codex/, openclaw/ 等多个子目录。

# 干跑模式:不实际写文件,只打印转换后的内容和报告到控制台
npx tsx bin/skillport.ts convert ~/.claude/skills/my-skill --to codex --dry-run
# 这在调试或查看转换效果时非常有用。

# 指定多个目标格式
npx tsx bin/skillport.ts convert ./my-skill --to cursor,codex,copilot

格式检测与指定:

# 检测一个项目目录使用了哪些AI工具的配置
npx tsx bin/skillport.ts detect /path/to/your/project
# 输出可能类似:Found: Claude Code (SKILL.md), Cursor (.cursor/rules/)

# 强制指定源格式,跳过自动检测
npx tsx bin/skillport.ts convert ./some-obscure-skill --from claude --to cursor
# 当你处理非标准位置或自定义命名的技能文件时有用。

3.3 理解转换报告:你的“技能体检单”

每次转换,skillport都会在控制台输出一份详细的“奇偶校验报告”。读懂这份报告,是评估转换效果的关键。报告通常分为三部分:

1. 转换摘要 这部分是概览,告诉你源技能、目标格式、处理了多少个功能字段,以及这些字段的映射情况(原生/垫片/丢弃)。

skillport: my-refactor-skill (Claude Code -> Cursor)
  Source:  ~/.claude/skills/my-refactor-skill
  Target:  .cursor/skills/my-refactor-skill/SKILL.md
  Fields:  5 total
    ✓  3 native   (name, description, body, globs, hooks.PreToolUse)
    ⚡  1 shimmed  (allowed-tools)
    ⚠  1 dropped  (context:fork)
  • ✓ native :完美转换。
  • ⚡ shimmed :功能被垫片模拟,效果可能打折扣。
  • ⚠ dropped :功能被丢弃,并添加了注释。

2. 奇偶校验评估 这是一个百分比分数和细分项,让你一目了然技能功能的保留程度。

Parity: 88% (High)
  Feature Coverage:
    ✓ Core instructions       100%  Markdown body preserved
    ✓ Activation trigger      100%  globs mapping successful
    ⚡ Tool restrictions        85%  Converted to instructional text
    ⚠ Subagent calls            0%  No equivalent in Cursor (annotated)
  • 95-100% (完全一致) :技能行为在两个平台上几乎无差别。
  • 80-94% (高度一致) :核心功能完好,次要功能有垫片。
  • 50-79% (部分一致) :关键功能有近似实现,需要留意差异。
  • <50% (低度一致) :差异很大,建议手动调整或重写。

3. 关键权衡点 这是最重要的部分,用通俗的语言告诉你转换带来了什么变化,使用时需要注意什么。

Key Points:
• allowed-tools [Bash, Write] 已转换为技能开头的指令文本,Cursor不会强制阻止使用其他工具,需依赖AI遵守。
• context:fork (子代理调用) 功能在Cursor中无对应概念,已在技能文件中添加“## 警告”区块说明。
• 生命周期钩子 PreToolUse 已映射到Cursor的 beforeShellExecution,行为一致。

实操心得 :不要只看总分。一定要仔细阅读“关键权衡点”。一个总分85%的技能,如果丢弃的功能恰好是你这个技能的核心(比如一个严重依赖动态上下文的技能),那这个转换版本可能根本不可用。反之,如果丢弃的只是些边缘配置,那这个转换就是成功的。

4. 功能映射深度解析与适配策略

不同AI编程工具的设计哲学不同,导致功能集有显著差异。skillport的 src/adapters/ 目录下的模块,就是专门处理这些差异的“翻译官”。我们深入看几个典型场景。

4.1 工具限制的“软”与“硬”

这是最常见的兼容性问题。Claude Code和Codex CLI可以对单个技能进行严格的工具权限控制(如 allowed-tools: [Bash, Read] ),这是一个“硬”限制,系统层面会阻止AI调用未授权的工具。

而Cursor、GitHub Copilot等工具,其工具权限通常是全局设置的,或者在会话级别管理,无法精细到单个技能。skillport的 adapters/tools.ts 处理这个差异的策略是“软化”。

转换示例:

  • 源 (Claude Code) :
    # SKILL.md 前端元数据
    allowed-tools: [Bash, Read]
    
  • 目标 (Cursor) :
    # SKILL.md
    ## 技能:仅使用Bash和Read工具
    **重要提示**:本技能设计为仅使用`Bash`和`Read`工具进行文件查看和脚本执行。请避免使用`Write`、`Search`或其他工具,以确保操作符合预期。
    
    (接下来的技能正文...)
    

策略分析 :适配器检测到目标平台(Cursor)不支持技能级工具限制,于是它做了两件事:

  1. allowed-tools 这个字段从YAML前端元数据中移除。
  2. 在生成的Markdown指令正文的最上方,插入一个强格式化的提示区块。它利用AI对自然语言和格式的理解,试图“说服”AI遵守这个约束。这是一种典型的“垫片”策略。

注意 :这种“软”限制的可靠性取决于AI模型的配合度。在复杂或冗长的对话中,AI可能会“忘记”这个初始提示。因此,对于安全性要求极高的操作(如生产环境数据库变更),即使转换后,也建议在目标平台上进行充分的测试,或考虑使用具备“硬”限制的平台。

4.2 动态上下文的“实时”与“预置”

Claude Code的 ! command ``语法是一个杀手级特性,它允许技能在运行时动态执行Shell命令并将其输出作为上下文。这能实现非常灵活的、环境感知的技能。

然而,大多数其他工具(包括早期的Cursor)不支持这种实时执行。skillport的 adapters/dynamic-context.ts 提供了两种垫片方案:

方案A:预计算脚本(针对Cursor等) 转换时,skillport会分析技能中所有 ! ... ``语句。

  1. 提取这些命令,生成一个独立的Shell脚本(如 scripts/render-context.sh )。
  2. 在技能指令中,将这些动态标记替换为指向脚本输出的说明,或直接移除。
  3. 用户在使用技能前,需要先手动运行这个脚本,或者将其集成到自己的工作流中(比如作为git hook或项目启动脚本)。

方案B:内联提示模式(针对OpenClaw等) 对于像OpenClaw这样支持在指令中嵌入代码块的工具,适配器会采用“Clearshot模式”:

请先执行以下命令获取上下文:
```bash
git status

然后将输出结果作为下文分析的依据。

(原技能指令...)

这相当于把动态执行的责任从平台转移给了用户或AI,要求他们在对话中手动执行并粘贴结果。

**实操心得**:动态上下文的丢失是转换中最大的功能折损之一。在转换依赖此特性的技能时,你必须评估:
1.  生成的预计算脚本是否能在目标环境中安全、正确地运行?
2.  要求用户手动预执行步骤,是否会破坏技能的流畅性和用户体验?
如果答案是肯定的,你可能需要重新设计这个技能,使其更少依赖运行时环境,或者仅为支持此特性的平台保留该技能。

### 4.3 生命周期钩子的映射与模拟

Claude Code提供了丰富的生命周期钩子(如`onActivate`, `PreToolUse`, `PostToolUse`),允许技能在特定时机插入自定义逻辑。

`adapters/hooks.ts`需要处理钩子到不同平台的映射:
*   **最佳情况(原生映射)**:Claude Code的`PreToolUse`可以直接映射到Cursor的`beforeShellExecution`,因为它们语义高度重合。
*   **垫片模拟**:对于Codex CLI这种没有钩子概念的,适配器会生成“包装器脚本”。例如,一个调用了`node script.js`的技能,会被改写成调用`scripts/wrapper.sh`,而这个包装器脚本内部会先执行`PreToolUse`的逻辑,再调用原始的`node script.js`。
*   **降级处理**:对于一些仅在特定阶段有效的钩子(如`onActivate`),如果目标平台完全无法支持,适配器可能会选择将其转换为技能正文开头的“初始化说明”,或者直接丢弃并添加注释。

### 4.4 子代理与全局/项目级规则

这是一个涉及多文件转换的复杂场景。
*   **子代理**:Claude Code的`context: fork`用于调用子技能。Codex CLI有类似的`fork`命令,但语法不同。适配器`adapters/subagents.ts`会尝试将调用语法进行转换,如果无法转换,则添加注释说明“此处需要手动调用子任务”。
*   **项目规则**:Claude Code的`CLAUDE.md`、Cursor的`.cursor/rules/`、Codex的`AGENTS.md`都是定义项目级AI行为规则的文件。skillport在转换时,如果检测到源技能关联了项目规则,它会尝试将这些规则内容提取、转换,并合并到目标格式的对应文件或位置中。这可能涉及复杂的合并逻辑,以避免与现有规则冲突。

## 5. 实战案例:将一个真实技能从Claude Code迁移到Cursor

让我们跟随一个具体的例子,把我在Claude Code中常用的“智能提交消息生成”技能`git-commit-helper`,转换到Cursor环境。

### 5.1 源技能分析

首先,看看这个技能在Claude Code中的样子(`~/.claude/skills/git-commit-helper/SKILL.md`):
```yaml
---
name: git-commit-helper
description: 分析git diff生成简洁、规范的提交消息。
author: me
version: 1.1
paths: "*.js,*.ts,*.py,*.go"
allowed-tools: [Read, Bash]
hooks:
  onActivate: |
    echo "Git提交助手已激活。将分析暂存区的更改。"
  PreToolUse: |
    # 检查是否在git仓库中
    if ! git rev-parse --git-dir > /dev/null 2>&1; then
      echo "错误:当前目录不是git仓库。"
      exit 1
    fi
---
# Git提交消息生成助手

请根据以下步骤生成提交消息:

1. **分析变更**:首先运行 `git diff --staged --name-status` 获取暂存文件列表,然后对关键文件运行 `git diff --staged -p` 查看具体改动。
2. **归纳类别**:将更改归类为 `feat`(新功能)、`fix`(修复)、`docs`(文档)、`style`(格式)、`refactor`(重构)、`test`(测试)、`chore`(构建/工具)等。
3. **生成消息**:遵循 Conventional Commits 规范,格式为 `<type>(<scope>): <subject>`。主题行不超过50字符,正文每行72字符。
4. **提供选项**:生成2-3个不同侧重点的选项供我选择。

**动态上下文**:当前分支是 `!`` `git branch --show-current` ``。

请开始分析。

这个技能有几个关键点:基于文件路径触发、有工具限制、有两个生命周期钩子( onActivate PreToolUse )、使用了动态上下文、核心指令是分步骤的Markdown。

5.2 执行转换并解读输出

在Claude Code中,我直接输入:

/skillport convert git-commit-helper to cursor

或者在命令行执行:

npx tsx bin/skillport.ts convert ~/.claude/skills/git-commit-helper --to cursor

转换完成后,skillport输出了详细的报告,并在 ~/.claude/skills/git-commit-helper/ 旁边(或当前目录)生成了 .cursor/skills/git-commit-helper/ 文件夹。

生成的Cursor技能文件( .cursor/skills/git-commit-helper/SKILL.md )如下:

# Git提交消息生成助手

**技能来源**:由skillport从Claude Code技能 `git-commit-helper` 转换而来。
**注意**:原始技能限制仅使用`Read`和`Bash`工具。请优先使用这些工具完成以下任务。

## 初始化提示
Git提交助手已激活。将分析暂存区的更改。

## 预检查脚本
在开始主要任务前,请先执行以下检查:
```bash
# 检查是否在git仓库中
if ! git rev-parse --git-dir > /dev/null 2>&1; then
  echo "错误:当前目录不是git仓库。"
  exit 1
fi

如果检查失败,请告知用户。

主要指令

请根据以下步骤生成提交消息:

  1. 分析变更 :首先运行 git diff --staged --name-status 获取暂存文件列表,然后对关键文件运行 git diff --staged -p 查看具体改动。
  2. 归纳类别 :将更改归类为 feat (新功能)、 fix (修复)、 docs (文档)、 style (格式)、 refactor (重构)、 test (测试)、 chore (构建/工具)等。
  3. 生成消息 :遵循 Conventional Commits 规范,格式为 <type>(<scope>): <subject> 。主题行不超过50字符,正文每行72字符。
  4. 提供选项 :生成2-3个不同侧重点的选项供我选择。

上下文获取 :为了获取当前分支信息,请先执行: git branch --show-current ,并将结果作为后续分析的依据。


转换说明:原始技能中的路径触发模式( paths: "*.js,*.ts,*.py,*.go" )已尝试映射到Cursor的发现机制。动态上下文执行( !`` ...` ``)已转换为手动执行指令。

同时,还生成了一个`scripts/`目录,里面可能包含用于预计算上下文的脚本(本例中动态上下文较简单,可能被直接内联处理了)。

### 5.3 报告分析与效果评估

控制台输出的报告是关键:

skillport: git-commit-helper (Claude Code -> Cursor)

Source: ~/.claude/skills/git-commit-helper Target: .cursor/skills/git-commit-helper/SKILL.md

Fields: 6 total ✓ 3 native (name, description, body, hooks.PreToolUse->beforeShellExecution) ⚡ 2 shimmed (allowed-tools, hooks.onActivate->instruction) ⚡ 1 adapted (paths -> description hint) ⚡ 1 shimmed (dynamic-context -> manual instruction)

Parity: 82% (High)

Feature Coverage: ✓ Core instructions 100% Step-by-step guide preserved ⚡ Tool restrictions 75% Converted to prominent instructional text ✓ Activation trigger 100% Path hint added to description for Cursor's discovery ⚡ Hooks 85% onActivate as text, PreToolUse natively mapped ⚡ Dynamic context 70% Converted to manual step, requires user/AI to run

Verdict: 该技能的核心工作流(分析git diff并生成消息)被完整保留。使用体验上的主要变化是:工具限制从“系统强制”变为“强烈建议”,动态分支信息需要手动获取一次。

Key Points: • allowed-tools [Read, Bash] 现在以加粗文本提示的形式存在,而非强制约束。在复杂对话中需注意AI可能使用其他工具。 • paths: "*.js,*.ts,*.py,*.go" 触发模式已作为描述的一部分,帮助Cursor的自动技能发现机制进行匹配,但非精确路径过滤。 • 动态上下文 !`` git branch --show-current `` 已转换为一个明确的“请先执行”的步骤。你需要(或要求AI)先运行该命令,然后将输出粘贴或告知AI。 • 钩子 onActivate 被转换为“初始化提示”部分。 PreToolUse 钩子已成功映射为Cursor的 beforeShellExecution` 等效逻辑(内嵌在指令开头的检查脚本中)。

**我的评估**:这个转换结果非常可用!82%的奇偶性属于“高度一致”。核心的、最有价值的“分析diff并生成规范提交消息”的指令被100%保留。最大的体验降级有两点:
1.  **工具限制软化**:在Claude Code中,AI绝对无法使用`Write`工具去修改文件。在Cursor中,这只是一个文本提示。对于这个技能,问题不大,因为它的本意就是只读分析。但如果是一个`git add`技能,软化限制就可能带来风险。
2.  **动态上下文手动化**:我需要先告诉AI“运行`git branch --show-current`”,或者自己运行然后把分支名贴进去。多了一步交互,流畅性下降,但功能无损。

**结论**:这个转换是成功的,我可以将这个生成的`.cursor/skills/git-commit-helper/`目录打包发给使用Cursor的同事,他直接放入自己的`.cursor/skills/`文件夹就能用了。我只需要提醒他注意上述两点变化。

## 6. 常见问题、排查与进阶技巧

在实际使用和贡献代码的过程中,我积累了一些问题和技巧。

### 6.1 转换失败或报错排查

| 问题现象 | 可能原因 | 解决方案 |
| :--- | :--- | :--- |
| `Error: Cannot detect source format` | 技能目录结构不符合预期,或缺少关键文件(如`SKILL.md`)。 | 使用`--from <format>`强制指定源格式。检查源技能是否完整。 |
| `Error: Parser error at line X` | 源技能文件的YAML前端元数据或Markdown语法有误。 | 用YAML校验器检查`SKILL.md`的`---`包围部分。确保Markdown格式正确。 |
| 转换后技能在目标平台不生效 | 1. 目标平台技能加载路径不正确。<br>2. 转换后的文件命名或格式不符合目标要求。<br>3. 垫片功能需要额外配置。 | 1. 对照目标平台文档,确认生成的文件放在了正确位置。<br>2. 检查生成的文件名和内容格式(如Cursor可能是`.mdc`)。<br>3. 阅读转换报告中的“Key Points”,完成所需的手动步骤(如运行预计算脚本)。 |
| 奇偶性报告分数过低 (<50%) | 源技能重度使用了目标平台不支持的核心特性(如复杂的动态上下文、独有的子代理调用)。 | 考虑是否为该目标平台重新设计一个简化版技能,或者接受部分功能缺失,并手动修改生成的技能文件进行补充。 |
| CLI命令执行缓慢 | 技能目录中包含`node_modules`等大型子目录,检测或解析时遍历了它们。 | 确保技能目录是干净的,或者使用更精确的源路径指向技能定义文件本身。 |

### 6.2 提升转换质量的技巧

1.  **编写“可移植”的技能**:如果你计划让技能跨平台使用,在最初编写时就有意识地进行设计。
    *   **慎用平台独有特性**:尽量避免完全依赖像Claude Code的动态上下文``!`` `...` ``这样的特性。如果要用,考虑提供一个备选的、基于静态分析的方案。
    *   **明确声明依赖**:在技能描述里写明“本技能需要获取当前git分支信息”,而不是隐式地使用动态上下文。这样即使转换后需要手动操作,逻辑也是清晰的。
    *   **工具限制合理化**:问自己“这个技能为什么不能使用XX工具?”。将原因写在技能描述里。这样当“硬限制”被转换成“软提示”时,提示信息会更准确,AI也更可能遵守。

2.  **转换后的手动优化**:skillport的转换是一个很好的起点,但并非终点。生成后,你应该:
    *   **通读生成的技能文件**:特别是skillport添加的注释和警告部分,理解功能差异。
    *   **测试核心流程**:在目标平台上实际运行转换后的技能,看核心任务是否能完成。
    *   **优化垫片**:例如,对于转换成的“预计算脚本”,你可以优化其错误处理,或者将其集成到你的项目Makefile或npm脚本中,实现自动化。

3.  **利用`--dry-run`进行预览**:在正式转换前,务必使用`--dry-run`参数。这能让你在不产生任何文件的情况下,看到完整的转换报告和生成的技能内容预览。根据预览结果,你可以决定是否调整源技能,或者是否接受当前的转换方案。

### 6.3 为skillport贡献代码

skillport是一个开源项目,生态的丰富度取决于社区贡献。如果你常用的某个AI工具不在支持列表,可以考虑为其添加支持。

**添加一个新平台(Harness)的步骤:**
1.  **研究目标平台**:仔细阅读其文档,找到定义技能/规则的文件格式(是单个Markdown文件,还是JSON配置,或是多个文件)。
2.  **创建解析器**:在`src/parsers/`下创建新文件,例如`mynewide.ts`。你需要实现一个函数,它能读取该平台的技能文件,并返回skillport定义的标准`IntermediateRepresentation`对象。参考`claude.ts`或`cursor.ts`的实现。
3.  **创建发射器**:在`src/emitters/`下创建新文件。实现一个函数,接收`IntermediateRepresentation`对象,并生成目标平台所需的文件结构和内容。
4.  **更新适配器逻辑**:在`src/adapters/`下的各个文件中,补充新平台与其他平台之间特定功能(钩子、工具、上下文等)的映射关系。思考哪些功能可以原生映射,哪些需要垫片,哪些只能丢弃并注释。
5.  **更新类型和注册表**:在相关的类型定义文件(如`ir.ts`)和工厂文件(如`parserFactory.ts`)中注册你的新解析器和发射器。
6.  **编写测试**:在`tests/`目录下为你的新平台添加测试用例,确保解析和发射的准确性,特别是边缘情况。
7.  **提交Pull Request**:附上清晰的说明和测试结果。

**贡献的核心在于理解“映射”思维**:不是追求100%的完美转换,而是在功能保留、用户体验和实现复杂度之间找到最佳的平衡点,并通过清晰的报告让用户知晓所有的权衡。

更多推荐