01 插件对外 API 契约


文档摘要

01 插件对外 API 契约 本节摘要:四类扩展点里,插件(plugin)是最重的——它是包级全能扩展,能注册工具、适配器、Provider、界面扩展、终端环境,还能挂各种事件钩子。本节讲清插件的对外 API 契约:插件本质是个「函数 → 钩子集合」,它用模式校验(zod)定义工具(降低作者门槛),有哪些钩子能挂。理解了本节,你才知道插件能干什么、怎么写。 一、插件是什么:函数 → 钩子集合 先钉死插件的本质。一个插件就是一个函数——它接收输入,返回一组钩子(hooks)。钩子是「在特定时机被调用的回调」,OpenCode 在运行时按需触发这些钩子,让插件能介入各种环节。 插件函数拿到输入(让它知道运行环境),返回它想挂的钩子(告诉 OpenCode「在这些时机叫我」)。

01 插件对外 API 契约

本节摘要:四类扩展点里,**插件(plugin)**是最重的——它是包级全能扩展,能注册工具、适配器、Provider、界面扩展、终端环境,还能挂各种事件钩子。本节讲清插件的对外 API 契约:插件本质是个「函数 → 钩子集合」,它用模式校验(zod)定义工具(降低作者门槛),有哪些钩子能挂。理解了本节,你才知道插件能干什么、怎么写。

一、插件是什么:函数 → 钩子集合

先钉死插件的本质。一个插件就是一个函数——它接收输入,返回一组钩子(hooks)。钩子是「在特定时机被调用的回调」,OpenCode 在运行时按需触发这些钩子,让插件能介入各种环节。

插件 = (输入) => { 返回钩子集合 } │ ▼ 输入包含 客户端、项目、目录、工作区、服务端URL、shell 工具等 │ ▼ 返回钩子集合 { tool, auth, provider, event, permission.ask, tool.execute.before, ... }

插件函数拿到输入(让它知道运行环境),返回它想挂的钩子(告诉 OpenCode「在这些时机叫我」)。OpenCode 在对应时机触发钩子,插件就介入了。

二、插件输入:运行环境

插件函数接收的输入,提供了插件可能需要的「运行环境」信息:

输入项 作用
客户端 调 OpenCode API 的客户端(让插件能反向调)
项目 / 目录 / 工作区 插件所在的项目环境
服务端 URL 让插件能调服务端
shell 工具($) 让插件能执行 shell 命令
实验性工作区注册 高级用法

这些输入让插件不是「孤立运行」,而是能与 OpenCode 环境互动——调 API、执行命令、感知项目。

三、钩子:插件能挂的时机

钩子是插件的核心能力。OpenCode 提供了大量钩子,覆盖工具、认证、Provider、事件、权限、会话等:

钩子类别 举例 作用
tool 注册工具定义字典 让插件提供新工具
auth 认证钩子 让插件接管认证
provider Provider 钩子 让插件注册新 Provider
event 事件钩子 让插件响应事件
permission.ask 权限询问钩子 让插件介入权限判定
tool.execute.before/after 工具执行前后 让插件在工具执行前后做事
tool.definition 工具定义钩子 让插件改工具定义
shell.env shell 环境 让插件改终端环境变量
chat.* 聊天相关 让插件介入消息/参数/头
experimental.* 实验性 含会话压缩等高级介入

💡 钩子的威力:钩子让插件几乎能介入 OpenCode 的任何环节——从「加个工具」到「改权限判定」到「介入会话压缩」。这是插件被称为「全能扩展」的原因。

四、插件工具用 zod 定义

插件如果要注册工具(通过 tool 钩子),它用**模式校验(zod)**定义工具参数,而不是 OpenCode 内部用的效应 Schema。这是个有意的降低门槛选择:

插件工具定义(用 zod,门槛低): { name: "my_tool", description: "...", args: { path: zod.string(), count: zod.number() }, // zod 定义 execute: async ({ path, count }) => { ... } }

为什么用 zod?因为 zod 是 TS 生态里更普及的模式校验库,大多数开发者熟悉。用 zod 定义工具,插件作者不用学效应 Schema,门槛更低。第 5 章说过,注册表会做适配——把插件的 zod 定义转成统一格式。

五、插件 vs 其他扩展点

把插件和其他三类扩展点对比,定位就清楚:

扩展点 定位 重量级
插件 包级全能扩展(工具/适配器/Provider/钩子)
技能 模型按需加载的指令(第 02 节)
斜杠命令 用户快捷方式(第 03 节)
自定义工具 代码级补一个工具(第 04 节)

插件是「全能但重」——它什么都能做,但写起来也最复杂(要写包、定义钩子)。简单需求用技能/命令/自定义工具就够,复杂需求才上插件。

六、插件的生命周期

插件作为「包」,有自己的生命周期——安装、加载、卸载。OpenCode 启动时加载已安装的插件,调用它们的函数拿钩子,把钩子挂到各环节。插件变更(装/卸)会触发重载(OpenWork 教程第 8 章的 Reload 机制)。

七、本节要点回顾

  1. 插件本质:函数 → 钩子集合;函数拿运行环境输入,返回想挂的钩子。
  2. 输入给运行环境:客户端/项目/目录/工作区/服务端URL/shell,让插件能互动。
  3. 钩子覆盖全环节:tool/auth/provider/event/permission/tool.execute/shell.env/chat/experimental 等。
  4. 插件工具用 zod 定义:降低作者门槛(不用学效应 Schema),注册表做适配。
  5. 插件是全能但重:什么都能做但写起来复杂;简单需求用技能/命令/自定义工具。
  6. 插件有生命周期:安装/加载/卸载,变更触发重载。

插件讲清了,下一节讲最精巧的扩展点——技能(Skill)的渐进式披露。


发布者: 作者: 灏天文库 转发
评论区 (0)
U