跳到主要内容
TABTAB

导航

快速开始

自一个空目录,至一个可在 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 多了一层」,容易查半天。

下一步