快速开始
自一个空目录,至一个可在 TABTAB 面板中唤起的插件,中间只有三步。
第 1 步:拿到骨架
脚手架会生成一个能跑的最小插件 —— 一个 index.html、一个manifest.json、一份构建配置。改 manifest.json 里的 id 与指令,就开始了。
npx @tabtab/plugin-init my-plugin第 2 步:声明你是谁
manifest.json 是插件的唯一身份证明。它的 id必须与索引条目一致,否则宿主拒绝安装 —— 同一个 id 在用户认知中 始终应指向同一个插件,重复安装也必须解析为同一实体。
manifest.json
{
"$schema": "https://tabtab.dev/schema/plugin-manifest-1.json",
"id": "dev.example.hello",
"name": "你好",
"version": "1.0.0",
"minHostVersion": "0.1.0",
"description": "一句话说清它干什么。",
"icon": "icon.svg",
"main": "index.html",
"commands": [
{ "code": "main", "explain": "打开面板", "cmds": ["你好", "hello"] }
],
"permissions": ["storage"],
"ui": { "width": 640, "height": 480 }
}完整字段见 Manifest 规范。这里只强调一条:permissions 只写你真用到的 —— 多写一项,用户就要为一项 你根本用不上的能力点头。
第 3 步:调能力桥
页面里通过 window.__TABTAB__ 访问宿主能力, 或引入 SDK 获取类型定义。宿主会将其注入每个插件窗口, 并按你在 manifest 里声明的权限逐方法判定。
index.html
import { storage } from "@tabtab/plugin-sdk";
await storage.set("greeting", "你好");
const v = await storage.get("greeting"); // string | null
// 没声明 storage 权限时,上面这行会返回:
// { code: "PERMISSION_DENIED", … }SDK 的体积很小 —— 它只做类型声明与 window 门面转发,零运行时依赖, 会被打进每个插件。没有它也能写,直接用 window.__TABTAB__ 即可, 只是少了类型提示。
本地跑起来
开发模式下宿主会热加载插件目录:改完刷新面板就能看到效果。 生产构建需要走 Tauri 侧,浏览器里跑 pnpm dev 拿不到宿主能力。
pnpm dev打包与分发
插件包就是一个 zip,根目录里有 manifest.json。 发布后索引会从包本身生成 —— sha256、包内 manifest、下载地址 都不需要人再抄一遍。
pnpm build && pnpm pack压缩包的根目录就是 manifest 所在层级。多套一层目录的话,宿主解出来 会找不到入口 —— 报错是「包内没有 manifest.json」,而不是「你的 zip 多了一层」,容易查半天。