SDK 与打包脚手架
SDK 与打包脚手架
Section titled “SDK 与打包脚手架”@termii/plugin-sdk 是插件系统的
官方 SDK(独立仓库,不发 npm,经 git 依赖安装)。给插件作者提供:
- 宿主 API 类型面(
PluginContext/PluginManifest/ 各贡献点与数据结构类型) definePlugin()—— 类型收窄与入口约定validateManifest()—— 清单校验(手写,零依赖)termii-plugin-sdk—— esbuild 打包脚手架(单文件 ESM 产物,共享宿主 React / lucide)
在插件项目内安装(git 依赖;prepare 自动构建 dist/,dist 也已提交
进仓库双保险):
npm i -D github:Termii-App/plugin-sdk插件代码里引用:
import { definePlugin, validateManifest, type PluginContext } from "@termii/plugin-sdk";SDK 不 import 宿主任何源码,独立可编译。类型面由宿主侧自动生成同步 (见下文「类型同步」):写插件时以 SDK 导出的类型为准,两者不应分叉。 当前 SDK
2.2.x已包含ctx.config/ctx.paths/ctx.vault批量 /ctx.dialog.pickDirectory等新 API 的类型。
definePlugin
Section titled “definePlugin”definePlugin(plugin) 原样返回插件对象,不做任何运行时包装;作用是
类型收窄——让 TypeScript 以 PluginContext 为上下文检查
activate(ctx) 的实现,并作为打包脚手架 / loader 的入口约定:
import { definePlugin, type PluginContext } from "@termii/plugin-sdk";
export default definePlugin({ manifest: { id: "my-plugin", name: "My Plugin", version: "0.1.0", apiVersion: 3, // 缺省按 1 处理;> 宿主支持版本会被 loader 拒绝 capabilities: ["process"], // L1:信任弹窗会列出并警示 }, activate(ctx: PluginContext) { // …注册贡献点、订阅事件…… }, deactivate() { // 可选:额外的清理(定时器、自建的连接等) },});.jsx 模板(官方模板的 hello/)只用运行时导入
import { definePlugin } from "@termii/plugin-sdk"——esbuild 的 JSX 解析
不支持 TS 语法;.tsx 模板里再补 import type 即可获得完整类型上下文。
validateManifest
Section titled “validateManifest”手写清单校验(零依赖,不引入 zod)。错误为中文、逐条收集;
ok: true 时返回规范化后的 manifest(apiVersion 缺省已按 1 填入):
import { validateManifest } from "@termii/plugin-sdk";
const result = validateManifest(raw);if (result.ok) { // result.manifest:可直接使用的 PluginManifest} else { console.error(result.errors.join("\n"));}校验规则见 plugin.json 规范 → 校验,字段参考见 manifest schema 参考。
打包:termii-plugin-sdk
Section titled “打包:termii-plugin-sdk”npx termii-plugin-sdk build src/main.jsx --outfile main.js --minify- 产物是单文件 ES module(
--format=esm);.js文件按 JSX 解析。 --minify压缩产物;--external <name>可重复传,把指定包 external 化 (不打包、不 alias 到 shim);--help查看完整用法。- esbuild 缺失时脚手架给出友好报错(先在插件项目
npm install)。
共享运行时(默认行为)
Section titled “共享运行时(默认行为)”宿主通过 window.__termii.shared 暴露共享的 React / ReactDOM / lucide。
打包脚手架默认把 react、react/jsx-runtime、react-dom、lucide-react
alias 到 SDK 包的 shims/(运行时从共享实例取),并把 @termii/plugin-sdk
alias 到 SDK 包的 src/index.ts——否则每个插件都会各自打包一份 React
(上下文冲突、体积膨胀):
# 等价于 plugin-template 的 hello/build.shnpx termii-plugin-sdk build src/main.jsx --outfile main.js --minify- 传
--external react --external lucide-react会把共享包改回 external;--external @termii/plugin-sdk同理。 - i18next / react-i18next 不提供 shim,必须自带:SDK 主入口会引用
共享 i18n 运行时,因此插件项目构建前需要
npm i i18next react-i18next(官方插件 termii-docker 的src/i18n.ts即此模式:副作用 import 初始化插件自身的 i18n 实例)。模板项目已在package.json内置。 - 其余第三方依赖同理,打包进
main.js即可。
main.css 约定
Section titled “main.css 约定”插件目录根放 main.css 时,宿主读取主脚本时会把它的内容一并返回并注入
一个 <style data-plugin-css> 节点;插件去激活 / 卸载时该节点被移除。
样式只作用于插件自身视图(可结合宿主暴露的主题 CSS 变量,见
贡献点 → 主题)。
类型同步(维护者须知)
Section titled “类型同步(维护者须知)”SDK 的 host-types.ts 自动生成,勿手改:由宿主主仓库
scripts/gen-sdk-types.mjs 从 src/lib/plugins/types.ts +
src/lib/types.ts(镜像类型段)生成,经 sync-sdk-types CD(main push)
自动推送到 SDK 仓库;SDK 的 index.ts 以 export * 全部转发。
- 插件作者直接消费自动生成的类型,无需手工同步。
- 若发现 SDK 与宿主签名分叉,以宿主实现为准,并检查同步流程
(本地可手动跑
node scripts/gen-sdk-types.mjs生成对照)。
不想从零搭工程?直接以 plugin-template
为起点:hello/ 是纯 JS 入门模板,sidecar-sysinfo/ 是原生能力模板。
见 快速开始。