plugin-init

star 129

初始化 Zhin.js 插件项目。Use when asked to create a new plugin, scaffold plugin structure, or set up a plugin project. 引导生成符合 Zhin 规范的目录结构、package.json、tsconfig、入口文件和 README。

zhinjs By zhinjs schedule Updated 6/17/2026

name: plugin-init description: "初始化 Zhin.js 插件项目。Use when asked to create a new plugin, scaffold plugin structure, or set up a plugin project. 引导生成符合 Zhin 规范的目录结构、package.json、tsconfig、入口文件和 README。" keywords: - 创建插件 - 新建插件 - 初始化 - scaffold - 脚手架 - plugin init - new plugin tags: - development - plugin - scaffold

Zhin 插件初始化

引导创建一个符合 Zhin.js 规范的新插件,确保目录结构、命名、配置和入口代码全部合规。

适用场景

  • 用户说"帮我创建一个插件"、"新建插件"、"初始化一个 xxx 插件"
  • 需要从零搭建插件包结构

优先路径(二选一)

场景 命令 / 动作 输出
已有 Zhin 项目 zhin new <name>(仓库根或项目根) 官方 npm 包结构 + skills/
全新应用 pnpm create zhin-app 完整 bot 项目(含 skills/ 目录)

仅当用户明确要求「手写目录」或 zhin new 不可用时,才走下方 7 步手工流程。

初始化流程

第 1 步:确认插件信息

向用户确认:

  1. 插件名称:kebab-case,如 my-plugingroup-manager
  2. 插件类型:普通插件 / 服务插件 / 适配器插件
  3. 核心功能:命令、中间件、事件、定时任务、AI 工具、Web 页面
  4. 是否需要数据库
  5. 是否需要控制台前端

第 2 步:生成目录结构

命名规范:

  • npm 包名:社区插件 zhin.js-{name},官方插件 @zhin.js/{name}
  • 目录位于 plugins/{name}/

最小结构(单文件插件):

plugins/{name}/
├── package.json
├── tsconfig.json
├── README.md
├── CHANGELOG.md
├── src/
│   └── index.ts
├── tests/
│   └── index.test.ts
└── skills/
    └── {name}/
        └── SKILL.md

模块化结构(多功能插件):

plugins/{name}/
├── package.json
├── tsconfig.json
├── README.md
├── CHANGELOG.md
├── src/
│   ├── index.ts          # 入口装配(只做注册,不堆业务)
│   ├── commands/          # 命令处理
│   ├── middlewares/        # 中间件
│   ├── events/            # 事件监听
│   ├── services/          # 业务服务 / Context 注册
│   ├── models/            # 数据库模型
│   └── crons/             # 定时任务
├── client/                # 控制台前端(可选)
│   ├── index.tsx
│   ├── tsconfig.json
│   └── pages/
├── tests/
│   ├── index.test.ts
│   ├── commands.test.ts
│   └── services.test.ts
├── tools/                 # AI 工具声明(可选,*.tool.md)
├── skills/
│   └── {name}/
│       └── SKILL.md
└── lib/                   # 编译产物(gitignore)

第 3 步:生成 package.json

{
  "name": "zhin.js-{name}",
  "version": "0.1.0",
  "type": "module",
  "main": "./lib/index.js",
  "types": "./lib/index.d.ts",
  "exports": {
    ".": {
      "types": "./lib/index.d.ts",
      "development": "./src/index.ts",
      "import": "./lib/index.js"
    },
    "./package.json": "./package.json"
  },
  "files": ["src", "lib", "client", "dist", "skills", "tools", "README.md"],
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "test": "vitest run",
    "test:watch": "vitest",
    "test:coverage": "vitest run --coverage",
    "prepublishOnly": "pnpm build"
  },
  "keywords": ["zhin.js", "plugin", "{name}"],
  "peerDependencies": {
    "zhin.js": "latest"
  }
}

第 4 步:生成入口文件

入口 src/index.ts 只做装配,不堆业务:

import { usePlugin } from 'zhin.js'

const plugin = usePlugin()
const { addCommand, useContext, logger, root } = plugin

// 配置声明
// const getConfig = plugin.declareConfig('my-plugin', Schema.object({...}))

// 注册命令、中间件(root.addMiddleware)、事件等
// import './commands/index.js'
// import './services/index.js'

logger.info('{Name} 插件已加载')

关键约定:

  • usePlugin() 只在模块顶层调用
  • TS 文件间互导使用 .js 扩展名
  • zhin.js 统一导入 IM 框架 API(Plugin、命令、ZhinTool 注册)
  • 使用 ctx.ai / ZhinAgent 类型时从 zhin.js/agent 引入;项目 package.json 须含 @zhin.js/agentzodai 与所选 @ai-sdk/*zhin doctor 可诊断)
  • useContext() 回调返回清理函数

第 5 步:生成 tsconfig.json

IM 消息组件(命令回复、<image> 等)默认使用 zhin.js JSX:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "zhin.js"
  }
}

Satori 出图卡片(HTML 字符串 → segment.html / htmlToSvg)与 IM JSX 分离:在卡片 .tsx 文件顶加注释,或单独目录配置 jsxImportSource: "@zhin.js/satori"

/** @jsxImportSource @zhin.js/satori */
import { Card, CardHeader, wrapCardHtml } from '@zhin.js/satori'

export function buildMyCard(): string {
  const body = (
    <Card>
      <CardHeader title="标题" />
    </Card>
  )
  return wrapCardHtml(body, '#d8dce3')
}

完整 tsconfig.json 示例:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "outDir": "./lib",
    "rootDir": "./src",
    "strict": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "jsx": "react-jsx",
    "jsxImportSource": "zhin.js"
  },
  "include": ["src/**/*"],
  "exclude": ["lib", "node_modules", "client", "tests"]
}

依赖:pnpm add @zhin.js/satori(可选 @zhin.js/html-renderer 自动 HTML→PNG)。

第 6 步:生成测试文件

tests/index.test.ts 中生成基础测试骨架:

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { Plugin } from '@zhin.js/core'

describe('{Name} Plugin', () => {
  let plugin: Plugin
  let root: Plugin

  beforeEach(() => {
    root = new Plugin('/test/root.ts')
    plugin = new Plugin('/plugins/{name}/src/index.ts', root)
  })

  afterEach(async () => {
    if (plugin?.started) await plugin.stop()
  })

  it('should create instance', () => {
    expect(plugin).toBeInstanceOf(Plugin)
  })

  it('should start and stop', async () => {
    await plugin.start()
    expect(plugin.started).toBe(true)
    await plugin.stop()
    expect(plugin.started).toBe(false)
  })
})

第 7 步:生成 README.md

包含:安装、配置、使用示例、命令列表、AI 工具列表、开发说明。

失败与兜底

触发条件 一线处理 仍失败
包名与目录不一致 统一 kebab-case;官方 @zhin.js/adapter-* 社区 zhin.js-* docs/contributing/repo-structure.md
pnpm build 失败 检查 tsconfig rootDir/outDir、导入 .js 对照 plugins/utils/repeater 最小插件
测试无法加载插件 Plugin 路径指向 src/index.tsafterEachstop() 见下方测试骨架
用户未给插件名 列出 3 个候选名 + 功能摘要,🔴 暂停生成 等用户确认名称与类型

🔴 CHECKPOINT · 生成前

确认:插件名、类型(普通/服务/适配器)、是否需要 client/ 与数据库,再写 package.json

不要做什么

  • 不要用 zhin new 能完成的流程手写重复脚手架(优先 zhin new / create-zhin-app
  • 不要把业务逻辑写进 src/index.ts 装配层
  • 不要省略 tests/skills/{name}/SKILL.md(发布与 Agent 发现需要)
  • 不要在入口里从 @zhin.js/core import(用 zhin.js
  • 不要把适配器骨架当普通插件模板下发

检查清单

  • 包名符合 zhin.js-{name}@zhin.js/{name} 格式
  • type: "module" 已设置
  • exports 字段包含 development 条件导出
  • files 包含 srclibskills
  • peerDependencies 包含 zhin.js
  • 入口文件使用 usePlugin() 且在模块顶层
  • 测试文件存在且可运行
  • README 包含安装和使用说明

延伸阅读

文档 路径
CLI 插件命令 basic/cli/README.md
仓库插件规范 .github/instructions/zhin-plugin.instructions.md
脚手架模板源 packages/toolkit/create-zhin/template/skills/
Install via CLI
npx skills add https://github.com/zhinjs/zhin --skill plugin-init
Repository Details
star Stars 129
call_split Forks 17
navigation Branch main
article Path SKILL.md
More from Creator