> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpertai.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 发布与使用

插件开发完成后，最后一步是发布到 npm 并在宿主系统（Xpert AI）中启用。

## 发布插件

在 monorepo 根目录执行：

```bash theme={null}
# 构建插件
npx nx build my-plugin

# 使用 monorepo 的 release 流程
npx nx release

# 或者手动发布到 npm
npx nx run @xpert-ai/my-plugin:nx-release-publish --access public --otp=<one-time-password-if-needed>
```

发布成功后，你会在 npm 上得到一个可安装的包，例如：

```
@xpert-ai/my-plugin
```

## 使用插件

在 Xpert AI 宿主系统中，通过环境变量 `PLUGINS` 来声明启用的插件列表。多个插件用逗号分隔：

```bash theme={null}
PLUGINS=@xpert-ai/my-plugin1,@xpert-ai/my-plugin2
```

当宿主启动时，会自动解析 `PLUGINS` 环境变量并按顺序加载这些插件。

**注意事项**：

* 宿主项目通过 npm/yarn/pnpm 安装（`npm install @xpert-ai/my-plugin`） 环境变量中配置插件包列表。
* 插件的 `meta.name` 必须与 npm package name 保持一致。
* 如果插件未能正确加载，请检查日志中是否有 `register` 或 `onPluginBootstrap` 的输出。
* 在启动XpertAI系统后在系统设置[插件页面](https://app.xpertai.cn/settings/plugins)中查看已加载的插件列表。

## 安装 Scope

已安装插件都有明确的 level 和 scope。Level 决定能力及生命周期，scope 决定安装位置：

| Level          | 安装 Scope                                  | 谁可以管理                        | 谁可以使用           |
| -------------- | ----------------------------------------- | ---------------------------- | --------------- |
| `organization` | 当前 organization，或当前 tenant 的 global scope | 对应作用域管理员                     | 当前组织，或当前 tenant |
| `tenant`       | `global` 或 `tenant:<tenantId>:global`     | 所属 tenant 的 Super Admin      | 仅所属 tenant      |
| `system`       | `system:global`                           | Default tenant 的 Super Admin | 所有 tenant       |

这里的 **tenant level** 不只是把普通插件安装到 tenant-global scope。它表示插件可以注册 Controller、TypeORM Entity 和进程级 Provider 等 system-level 技术能力，但产品归属和访问边界只限一个 tenant。

### 安装 Tenant-level 插件

安装前确认插件运行时 `meta` 与 `package.json` 都声明了相同的 level 和命名空间：

```json theme={null}
{
  "xpert": {
    "plugin": {
      "level": "tenant",
      "artifactNamespace": "contract_review"
    }
  }
}
```

安装流程：

1. 使用目标 tenant 的 Super Admin 登录。
2. 进入 tenant 管理作用域的插件页面并安装插件包。
3. 安装成功后按照页面提示重启 API 服务。
4. 重启后回到目标 tenant，确认插件状态、配置、工作台和 API 可用。
5. 切换到另一个 tenant，确认插件列表和业务入口不可见；直接访问插件 API 应返回无权访问。

Tenant-level 插件采用以下保护规则：

* 同名插件只能归属于一个 tenant，不能在另一个 tenant 再安装一份。
* 安装与更新只暂存制品，重启 API 后才会装载新的 Controller、Entity 和 Provider。
* 卸载先停用持久化注册，重启 API 后才完成运行时卸载。
* 已锁定到某个 tenant 的插件配置只能由该 tenant 的 Super Admin 管理。
* `artifactNamespace` 必须稳定，避免表名、路由和注册表标识与其他进程级插件冲突。

### 从 System Level 迁移到 Tenant Level

不能在旧 system 注册仍生效时直接把同一插件改成 tenant level，否则两份进程级模块可能同时注册。正确迁移顺序是：

1. 在 Default tenant 中由 Super Admin 卸载旧的 system 插件。
2. 重启 API，确认旧运行时模块已经卸载。
3. 发布或准备声明 `level = 'tenant'` 的新插件版本。
4. 使用目标 tenant 的 Super Admin 安装新版本。
5. 再次重启 API，完成 tenant-level 插件激活。
6. 在目标 tenant 验证业务数据和配置，并执行一次跨 tenant 隔离检查。

迁移前应备份旧插件配置。System 实例与 tenant 实例具有不同的归属和 scope，平台不会自动把所有 system 配置复制到目标 tenant。

运行时插件能力按以下顺序解析：

```text theme={null}
organization -> tenant-global -> system-global -> built-in
```

因此 organization 或 tenant 插件可以按需覆盖系统默认能力，但不会创建第二份 system 实例。

## 初始化插件资源

插件被宿主加载后，不只是“启用”这么简单，还可以把插件包内声明的资源初始化到对应运行时目标中。

在系统设置的插件页里，已安装插件卡片上会提供资源初始化入口。点击后会打开资源初始化弹窗，宿主会实时读取当前插件包中的资源定义，而不是依赖一份静态缓存列表。

资源目标分两类：

* **Workspace**：初始化到工作空间，可用于 `Skills`、`MCP` 和 `Apps`
* **Xpert**：初始化到已有的 Xpert，可用于 `Hooks`

初始化弹窗会按资源类型分组展示，并显示当前状态：

* 已初始化的资源会显示为已安装，不能重复选择
* 插件包内容更新后，若资源定义发生变化，系统会提示可更新状态
* `assets/` 只作为包元数据和展示内容，不作为可初始化资源

完成初始化后，宿主会把资源绑定到真实运行时对象，并在当前工作空间或 Xpert 中更新对应的中间件、工具集或连接配置。
