---
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-plugin`、`group-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

```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 只做装配，不堆业务：**

```typescript
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/agent`、`zod`、`ai` 与所选 `@ai-sdk/*`（`zhin doctor` 可诊断）
- `useContext()` 回调返回清理函数

### 第 5 步：生成 tsconfig.json

**IM 消息组件**（命令回复、`<image>` 等）默认使用 `zhin.js` JSX：

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

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

```tsx
/** @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` 示例：

```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` 中生成基础测试骨架：

```typescript
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.ts`；`afterEach` 里 `stop()` | 见下方测试骨架 |
| 用户未给插件名 | 列出 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` 包含 `src`、`lib`、`skills`
- [ ] `peerDependencies` 包含 `zhin.js`
- [ ] 入口文件使用 `usePlugin()` 且在模块顶层
- [ ] 测试文件存在且可运行
- [ ] README 包含安装和使用说明

## 延伸阅读

| 文档 | 路径 |
|------|------|
| CLI 插件命令 | `basic/cli/README.md` |
| 仓库插件规范 | `.github/instructions/zhin-plugin.instructions.md` |
| 脚手架模板源 | `packages/toolkit/create-zhin/template/skills/` |
