opencode v2 skill create

本文档介绍 opencode2-skill-creator 如何从 OpenCode 1(V1)迁移到 OpenCode 2(V2),

包括迁移动因、插件 API 变化、配置与安装方式、评测流程的兼容性,以及用户侧升级步骤。

面向读者:使用本插件的用户、维护者,以及希望对照移植自己插件的 OpenCode 插件作者。


1. 背景:为什么必须适配 V2

OpenCode 2 有三处有意为之的破坏性变更(来自官方迁移指南):

  • 插件使用全新的插件 API。V1 插件实现无法在 V2 中运行,仅仅移动文件或改配置项名称是不够的。
  • 服务器 API 与客户端采用新契约。
  • 终端客户端配置从分层的 tui.json(c) 迁移为全局 cli.json。

本项目的核心产物是一个 OpenCode 插件(注册技能校验、评测、描述优化、基准测试、评审等工具),

因此插件 API 的破坏性变更直接决定了适配工作。

对插件而言最关键的两条:

维度 V1 V2
配置键 plugin plugins
包 @opencode-ai/plugin @opencode/plugin
入口形态 export const Plugin: Plugin = async (ctx) => ({ tool: {...} }) export default Plugin.define({ id, setup(ctx) })
注册工具 返回 tool 映射(tool() 辅助函数) ctx.tool.transform((editor) => editor.add(...))
工具入参 schema tool.schema 参数表 JSON Schema input
工具返回值 直接返回字符串 { content } 结构化内容

官方结论:V1 plugin implementations do not run in V2.


2. 版本与兼容策略

项目 值
适配版本 opencode2-skill-creator@0.3.0(V2)
插件 API 依赖 @opencode/plugin peer >=2.0.0(开发依赖 ^2.0.18)
V1 兼容 不再支持;V1 用户应停留在 opencode-skill-creator@0.2.x
配置键 plugins(原生 V2);已存在的 V1 plugin 数组会被保留并继续追加
本地插件目录 .opencode/plugins/ 与 .opencode/plugin/ 均会被 V2 发现

兼容策略是「V2 专用」而非「单入口同时支持 V1/V2」 。

官方允许一个包同时导出 setup()(V2)与 server()(V1),但本项目选择直接切到 V2:

通过包名与主版本(0.2.x / 0.3.x)区分,避免在同一个入口里维护两套生命周期语义。


3. 插件入口迁移

3.1 V1 形态

ts 复制代码
import { type Plugin, tool } from "@opencode-ai/plugin"

export const SkillCreatorPlugin: Plugin = async (ctx) => {
  ensureBundledSkillInstalled({ /* ... */ })
  void maybeAutoRefreshPluginCache()

  return {
    tool: {
      skill_validate: tool({
        description: "Validate a skill directory.",
        args: {
          skillPath: tool.schema.string().describe("Path to the skill directory"),
        },
        async execute(args) {
          return JSON.stringify(validateSkill(args.skillPath), null, 2)
        },
      }),
      // ...其余工具
    },
  }
}

export default SkillCreatorPlugin

3.2 V2 形态

ts 复制代码
import { Plugin } from "@opencode/plugin"

export const SkillCreatorPlugin = Plugin.define({
  id: "opencode2-skill-creator",
  async setup(ctx) {
    ensureBundledSkillInstalled({ /* ... */ })
    void maybeAutoRefreshPluginCache()

    await ctx.tool.transform((editor) => {
      editor.add(
        defineTool({
          name: "skill_validate",
          description: "Validate a skill directory.",
          properties: {
            skillPath: { type: "string", description: "Path to the skill directory" },
          },
          required: ["skillPath"],
          async execute(args) {
            return JSON.stringify(validateSkill(args.skillPath), null, 2)
          },
        }) as never,
      )
    })
  },
})

export default SkillCreatorPlugin

3.3 工具定义适配层

V2 的 input 是 JSON Schema,execute 返回 { content }。项目用 defineTool 统一封装:

ts 复制代码
function defineTool(spec: ToolSpec) {
  return {
    name: spec.name,
    description: spec.description,
    input: {
      type: "object",
      properties: spec.properties ?? {},
      required: spec.required ?? [],
      additionalProperties: false,
    },
    // 只有显式声明 codemode: true,工具才会进入 Code Mode 的工具目录,
    // 智能体才能通过 search 发现并调用它们。
    options: { codemode: true },
    execute: async (input: unknown) => ({
      content: await spec.execute((input ?? {}) as Record<string, any>),
    }),
  }
}

要点:

  • id 必须稳定:V2 用它标识插件、划分存储作用域,并出现在状态与诊断中。
  • ctx.tool.transform 的回调保持同步 :它是可重放的「状态编辑」,不应有一次性副作用;
    需要外部数据时先在 setup 中加载,再在回调里引用。
  • codemode: true:这是 V2 Code Mode 的行为开关。本项目所有工具都是给 Code Mode 下的智能体调用的。
  • runtime-entry.ts 只做一件事------把 skill-creator.ts 的默认导出转发出去,
    让发布入口保持单一默认导出,而 skill-creator.ts 仍保留命名导出供测试使用。

4. 上下文能力迁移

V2 的 ctx 既是 OpenCode 客户端,也是插件扩展 API,能力按域组织。本插件用到的关键差异:

用途 V1 做法 V2 做法
检测已安装技能名冲突 执行 opencode debug skill 并解析输出 ctx.skill.list()
技能列表结构 CLI 文本 { data: [{ name, path }] }

V1 的冲突检测依赖 shell 调用 opencode debug skill;该命令在 V2 中已不存在。

现在改为直接调用 ctx.skill.list(),读取返回的 data:

ts 复制代码
const listAvailableSkills = async () => {
  const result = await ctx.skill.list()
  return result?.data ?? []
}

await assertNoInstalledSkillConflict(meta.name, listAvailableSkills)

冲突检测的语义保持不变:评测会创建一个名为 <skill>-skill-<id> 的合成技能,

如果已安装技能与待测技能同名 ,它可能「抢走」触发,导致假阴性。

因此 skill_eval / skill_optimize_loop 在运行前仍会先检查同名技能并直接报错。


5. 配置与安装适配

5.1 原生 plugins 数组

安装器(bin/opencode2-skill-creator.js)写入 V2 原生的 plugins 数组:

jsonc 复制代码
{
  "plugins": ["opencode2-skill-creator"]
}

同时兼容旧配置:

  • 若检测到 V1 的 plugin 数组(且没有 plugins),则继续追加到 plugin,
    以保留已有条目并避免被 V2 归一化覆盖。
  • 支持 opencode.jsonc,并使用 jsonc-parser 增量编辑以保留注释与格式。
  • 全局安装时清理过期的 OpenCode 包缓存目录
    (~/.cache/opencode/packages/opencode2-skill-creator@latest),
    并清理桌面端因旧插件加载失败留下的错误通知。

5.2 本地插件目录

V2 从 .opencode/plugin/ 与 .opencode/plugins/ 两处发现本地插件。

推荐把 V2 文件放在 .opencode/plugins/。

5.3 技能目录

技能发现规则在 V2 中不变,仍在 .opencode/skills/<name>/SKILL.md 与全局

~/.config/opencode/skills/<name>/SKILL.md。插件首次启动会把内置技能复制到:

text 复制代码
~/.config/opencode/skills/opencode2-skill-creator/

6. 重命名与旧版本清理

本次适配同时把项目从 opencode-skill-creator 重命名为 opencode2-skill-creator,

涉及包名、bin、插件 id、技能名/目录、版本标记文件、npm 缓存路径、状态文件与自动更新环境变量。

旧文件夹处理:启动时若发现旧目录且带有插件自有的版本标记

(.opencode-skill-creator-version 或 .opencode2-skill-creator-version),

会将其重命名为非活跃备份,并把 SKILL.md 改为 SKILL.md.backup:

  • ~/.config/opencode/skills/opencode-skill-creator/
  • ~/.config/opencode/skills/skill-creator/

若目录没有该标记,则视为第三方或用户手动安装的技能,保持不动。

其它兼容点:

  • 旧的环境变量 OPENCODE_SKILL_CREATOR_AUTO_UPDATE 仍然生效(新变量为
    OPENCODE2_SKILL_CREATOR_AUTO_UPDATE)。
  • 安装技能时先复制后安装 ,不用 rename,规避 Windows 上的 EPERM。

7. 构建与打包

plugin/scripts/build.mjs 用 Bun 打包为单文件 ESM(dist/skill-creator.js):

bash 复制代码
bun build ./runtime-entry.ts \
  --target=bun \
  --format=esm \
  --outfile=dist/skill-creator.js \
  --external @opencode/plugin

关键点:

  • 外部化必须用空格形式 --external @opencode/plugin;
    Bun 的 --external:<pkg> 冒号形式会静默地把依赖打进产物。
  • 发布产物是编译后的 JS ,并且会复制 templates/、skill/、package.json,
    使 OpenCode 无需在 node_modules 下剥离 TypeScript。
  • 生成 dist/build-manifest.json,记录源码哈希,用于校验 dist/ 是否由当前源码构建。

8. 评测流程在 V2 中的行为

lib/run-eval.ts 通过 shell 调用 opencode run --format json 执行触发评测。

V2 中这条链路仍然成立:

  • V2 的 opencode run --format json 仍然输出 tool_use 事件;技能仍以
    tool_use 且 tool === "skill" 的形式出现(同时兼容 read)。
  • 评测会为每个查询创建独立的临时项目根,并用 PWD 固定到该临时目录。
    原因:opencode 依据 $PWD 解析项目根与项目级技能,
    若继承调用方的 PWD,真实项目技能可能被加载并抢占触发,导致假 0 分。
  • V2 同时从 .opencode/skills/ 与 .opencode/skill/ 发现技能,
    评测镜像项目 .opencode 配置时会覆盖这两个目录名。
  • 触发评测使用显式智能体(默认 build),避免默认智能体委派导致的假 0 分;
    若所有 should-trigger 查询零触发且无运行错误,会给出对应告警。

9. 跨平台修复

适配过程中一并修复了若干跨平台问题:

  • 校验器容忍 CRLF 的 SKILL.md frontmatter。
  • 技能安装用复制替代重命名(Windows EPERM)。
  • 打开评审查看器的浏览器失败时不再崩溃。
  • 安装器与编译入口点测试在 Windows 上可移植运行。

10. 安装与升级

10.1 全新安装(OpenCode V2)

推荐方式(全局安装,一条命令):

bash 复制代码
npx opencode2-skill-creator install --global

只想在单个项目启用:

bash 复制代码
npx opencode2-skill-creator install --project

可选的自检命令:

bash 复制代码
npx opencode2-skill-creator --version
npx opencode2-skill-creator --help
npx opencode2-skill-creator --about

安装器做了什么:

  1. 优先更新已存在的 opencode.jsonc,否则创建/更新 opencode.json;
  2. 把 "opencode2-skill-creator" 加入 V2 原生的 plugins 数组;
  3. 若检测到旧的 V1 plugin 数组(且没有 plugins),则追加到 plugin 以保留已有条目;
  4. 使用 JSONC 增量编辑,保留注释与格式;
  5. 全局安装时清理过期的 OpenCode 包缓存与桌面端旧插件错误通知。

等价的纯手工配置(全局路径 ~/.config/opencode/opencode.json(c),

项目路径 <项目根>/opencode.json(c)):

jsonc 复制代码
{
  "plugins": ["opencode2-skill-creator"]
}

已有其它插件时,追加而不是替换:

jsonc 复制代码
{
  "plugins": [
    "your-existing-plugin",
    "opencode2-skill-creator"
  ]
}

然后重启 OpenCode(插件配置只在启动时加载),并验证:

bash 复制代码
ls ~/.config/opencode/skills/opencode2-skill-creator/SKILL.md
text 复制代码
使用 opencode2-skill-creator 创建一个帮助编写 API 文档的技能。

首次启动时,插件会把内置技能自动复制到

~/.config/opencode/skills/opencode2-skill-creator/。

10.2 从 V1(0.2.x)升级到 V2

关键点:包名从 opencode-skill-creator 变成了 opencode2-skill-creator,
旧的 V1 插件条目必须移除
------V2 无法运行 V1 插件实现,保留旧条目会导致加载失败。

  1. 确认已安装 OpenCode 2 。V1 与 V2 默认不再并行安装,二者可执行文件都叫 opencode。

  2. 删除旧条目 :从配置里去掉 "opencode-skill-creator"。

    jsonc 复制代码
    // 升级前(V1)
    {
      "plugin": ["opencode-skill-creator"]
    }
  3. 安装新版本 (会写入 V2 的 plugins 键):

    bash 复制代码
    npx opencode2-skill-creator install --global
    jsonc 复制代码
    // 升级后(V2)
    {
      "plugins": ["opencode2-skill-creator"]
    }
  4. 重启 OpenCode。

  5. 旧技能目录自动归档 :若 ~/.config/opencode/skills/ 下存在带插件标记的

    opencode-skill-creator/ 或 skill-creator/,启动时会重命名为

    *.opencode2-skill-creator-backup-<时间戳>/ 并把 SKILL.md 改为 SKILL.md.backup,

    使其不再被加载(详见第 6 节)。

  6. 清理 npm 缓存(可选):若升级后仍加载旧版本,删除 OpenCode 包缓存后重启:

    bash 复制代码
    rm -rf ~/.cache/opencode/packages/opencode2-skill-creator@latest

提示:V2 在内存中归一化受支持的 V1 配置,不会自动改写源文件。

因此 plugin 与 plugins 可以暂时共存,但转换后不要让 V1 再读取该文件。

10.3 升级到新版本(0.3.x 及以后)

插件内置了自动更新检查:启动时最多每 24 小时查询一次 npm registry,

发现新版本会清理本地包缓存,使下次启动安装最新版。手动升级或强制刷新:

bash 复制代码
# 重新执行安装器
npx opencode2-skill-creator install --global

# 干净重装技能文件
rm -rf ~/.config/opencode/skills/opencode2-skill-creator/
# 然后重启 OpenCode

关闭自动更新检查:

bash 复制代码
export OPENCODE2_SKILL_CREATOR_AUTO_UPDATE=0
# 旧变量 OPENCODE_SKILL_CREATOR_AUTO_UPDATE=0 仍然生效

10.4 手动安装(离线 / 不使用 npm)

bash 复制代码
git clone https://github.com/wqs-base/opencode2-skill-creator.git
cd opencode2-skill-creator

# 安装技能(全局)
cp -r opencode2-skill-creator/ ~/.config/opencode/skills/opencode2-skill-creator/

# 安装插件(全局)
cp -r plugin/ ~/.config/opencode/plugins/skill-creator/

按需创建 ~/.config/opencode/package.json:

json 复制代码
{
  "dependencies": {
    "@opencode/plugin": ">=2.0.0"
  }
}

10.5 卸载与回滚

  • 卸载 :从 plugins 数组删除 "opencode2-skill-creator",并删除
    ~/.config/opencode/skills/opencode2-skill-creator/,然后重启 OpenCode。
  • 回滚到 V1 :安装 opencode-skill-creator@0.2.x,
    并在配置的 plugin 数组中使用旧包名。注意 V1 与 V2 不能共用同一份已转换为原生 V2 形态的配置。

10.6 常见问题

  • 改完配置没反应:完整重启 OpenCode,插件配置只在启动时加载。
  • 仍有另一个 skill-creator 技能 :若
    ~/.config/opencode/skills/skill-creator/ 没有 .opencode2-skill-creator-version
    或 .opencode-skill-creator-version 标记,则它不属于本插件,需单独处理。
  • npx 命令失败 :先运行 npx opencode2-skill-creator --help,
    再使用 install 或 install --global。
  • 想彻底重装 :删除 ~/.config/opencode/skills/opencode2-skill-creator/ 后重启。

11. 兼容性速查

维度 V1(0.2.x) V2(0.3.x)
包名 opencode-skill-creator opencode2-skill-creator
插件 API @opencode-ai/plugin @opencode/plugin
配置键 plugin plugins
入口 Plugin 函数返回 tool 映射 Plugin.define({ id, setup })
工具注册 tool() + tool.schema ctx.tool.transform + JSON Schema
工具返回 字符串 { content }
技能冲突检测 opencode debug skill ctx.skill.list()
技能目录 .opencode/skills/ .opencode/skills/、.opencode/skill/
本地插件目录 .opencode/plugins/ .opencode/plugins/、.opencode/plugin/

12. 参考

项目:

https://github.com/wqs-base/opencode2-skill-creator

相关推荐
codeGoogle9 小时前
Vue3 UIKit 实战:把聊天、会话、主题和移动端适配全部封装好
前端
大龄秃头程序员9 小时前
iOS Method Swizzling 的工程化实践:如何处理多重交换与第三方冲突
前端
liangshanbo121510 小时前
Webpack 文件指纹面试题整理
前端·webpack·node.js
xieter10 小时前
【技术精选】Node.js 核心事件循环机制与异步 I/O 深度剖析 (2026-10-02)
前端·javascript
计算机魔术师10 小时前
Ethan Mollick 谈点与群:智能体自组织为何让管理假设失效
前端
想吃火锅100510 小时前
【leetcode】238.除了自身以外数组的乘积js
javascript·算法·leetcode
故七月11 小时前
GEO 信源评估体系:如何判断一条网页信源能否被大模型采信
前端·网络·人工智能
liangshanbo121511 小时前
Webpack 常见 Plugin 面试题
前端·webpack·node.js
xxwl58511 小时前
vue3的入门学习
前端·vue.js·学习
用户8471721028411 小时前
.shot 文件格式规范
前端·后端