# AstrBot 插件市场 JSON 规范 规范版本:2026-06-27 插件市场 JSON Schema Version:1 ## 1. 范围 本文定义 AstrBot 插件市场源的 JSON 格式。 ## 2. 术语 - `PluginRecord`:插件市场源中的一个插件记录。 - `MarketMetadata`:插件市场源自身的元数据。 - `plugin_id`:全局插件包标识。 - `metadata.yaml`:已安装插件包内的插件元数据文件。 本文中的“必须”“不得”“应该”“不应该”“可以”均为规范性要求。 ## 3. 文档格式 插件市场源必须是 UTF-8 JSON 对象。 根对象必须包含保留 key `$meta`。 除 `$meta` 外,所有根 key 必须是以下之一: - `plugin_id` 字符串 - 第 5 节兼容例外中的 `name` 字符串 除 `$meta` 外,每个根 key 必须映射到一个 `PluginRecord` 对象: ```json { "$meta": { "schema_version": 1, "name": "AstrBot Official Plugin Market", "version": "2026-06-27", "homepage": "https://astrbot.app", "repository": "https://github.com/AstrBotDevs/AstrBot_Plugins_Collection" }, "owner/astrbot_plugin_foo": { "author": "owner", "name": "astrbot_plugin_foo", "version": "1.0.0", "repo": "https://github.com/owner/astrbot_plugin_foo", "desc": "Plugin description" }, "astrbot_plugin_bar": { "author": "owner", "version": "1.0.0", "repo": "https://github.com/owner/astrbot_plugin_bar", "desc": "Compatibility record using the root key as name" } } ``` 根对象不得包含 `$meta` 之外的顶层元数据字段。 ## 4. 市场元数据 `$meta` 不得被解释为 `PluginRecord`。 `$meta` 必须是 `MarketMetadata` 对象。 `MarketMetadata` 必须包含: | 字段 | 类型 | 要求 | | --- | --- | --- | | `schema_version` | integer | 插件市场 JSON schema 版本。本规范中必须为 `1`。 | `MarketMetadata` 可以包含: | 字段 | 类型 | 要求 | | --- | --- | --- | | `name` | string | 插件市场源的人类可读名称。 | | `version` | string | 插件市场源数据版本。不得用作 schema 版本。 | | `homepage` | string | HTTPS 主页 URL。 | | `repository` | string | 插件市场源数据的 HTTPS 仓库 URL。 | | `description` | string | 插件市场源描述。 | | `updated_at` | string | ISO 8601 时间戳。 | `$meta` 不得用于: - 插件身份 - 安装源解析 - 更新源解析 - 插件安全校验 ## 5. 插件身份 `plugin_id` 定义为: ```text metadata.author + "/" + metadata.name ``` 对每个 `PluginRecord`: - 根 key 应该等于 `${author}/${name}`。 - 根 key 可以在下方兼容例外中等于 `name`。 - `author` 必须等于 `metadata.yaml.author`。 - `name` 必须等于 `metadata.yaml.name`。 - `plugin_id` 必须在 AstrBot 插件生态内全局唯一。 - 两个按小写归一化后相等的 `plugin_id` 不得同时存在。 - `repo` 不得用作插件身份。 - `root_dir_name`、本地目录名、展示名、registry 名称不得用作插件身份。 `author` 和 `name`: - 必须是非空字符串。 - 必须去除首尾空白。 - 不得包含 `/`。 - 不得包含 ASCII 控制字符。 - 应该是稳定的包身份值,而不是展示名。 ### 5.1. Name Key 兼容例外 根 key 可以等于 `metadata.yaml.name`,而不是 `${author}/${name}`。 使用该例外时: - 根 key 不得包含 `/`。 - `author` 必须存在。 - `name` 可以省略。 - 如果 `name` 存在,必须等于根 key。 - 根 key 必须等于 `metadata.yaml.name`。 - 消费者必须将 `plugin_id` 构造为 `${author}/${root_key}`。 ## 6. 必填字段 每个 `PluginRecord` 必须包含: | 字段 | 类型 | 要求 | | --- | --- | --- | | `author` | string | 插件作者命名空间。必须匹配 `metadata.yaml.author`。 | | `name` | string | 插件包名。必须匹配 `metadata.yaml.name`。仅当根 key 等于 `metadata.yaml.name` 时可以省略。 | | `version` | string | 插件版本。必须匹配 `metadata.yaml.version`。 | | `repo` | string | 用于来源归属和安装的 HTTPS GitHub 仓库 URL。 | | `desc` | string | 默认插件描述。 | ## 7. 可选字段 | 字段 | 类型 | 要求 | | --- | --- | --- | | `display_name` | string | 人类可读插件名称。 | | `short_desc` | string | 紧凑 UI 使用的短描述。 | | `download_url` | string | HTTPS ZIP 下载 URL。已安装包身份仍必须匹配 `author/name`。 | | `logo` | string | HTTPS 图片 URL 或相对静态资源路径。 | | `tags` | string[] | 标签列表。 | | `category` | string | 市场分类 key。 | | `support_platforms` | string[] | 支持的平台 key。 | | `astrbot_version` | string | AstrBot 版本要求表达式。 | | `social_link` | string | 作者或项目 HTTPS URL。 | | `updated_at` | string | ISO 8601 时间戳。 | | `i18n` | object | 本地化展示字段。 | | `pinned` | boolean | 市场推荐标记。 | | `stars` | integer | 非负 star 数或排序信号。 | | `download_count` | integer | 非负下载数。 | ### 7.1. 仓库 URL `repo` 必须是以下之一: ```text https://github.com/{owner}/{repository} https://github.com/{owner}/{repository}.git https://github.com/{owner}/{repository}/tree/{branch} ``` `owner`、`repository`、`branch` 必须匹配: ```text [A-Za-z0-9_-]+ ``` `repo` 不得是: - HTTP URL - SSH URL - 非 GitHub URL - GitHub Enterprise URL - GitHub 文件、release、pull request、issue 或子目录 URL `download_url` 可以指向任意 HTTPS ZIP URL。 ### 7.2. 本地化字段 `i18n` key 应该是 BCP 47 locale tag。 每个 locale 对象可以包含: ```json { "display_name": "Localized name", "desc": "Localized description", "short_desc": "Localized short description" } ``` ## 8. 保留字段 插件市场源不得在 `PluginRecord` 对象中使用这些字段: | 字段 | 原因 | | --- | --- | | `plugin_id` | 由 `author/name` 派生。 | | `market_plugin_id` | 运行时/客户端兼容字段,不是市场数据。 | | `market_plugin_identifier` | 已弃用的运行时/客户端兼容字段。 | | `root_dir_name` | 本地安装字段。 | | `local_plugin_name` | 本地安装字段。 | | `install_method` | 本地安装字段。 | | `registry_url` | 本地安装字段。 | | `registry_name` | 本地安装字段。 | | `installed_at` | 本地安装字段。 | 消费者不得使用保留字段作为插件身份。 根 key `$meta` 保留给 `MarketMetadata`。 ## 9. 已弃用字段 迁移期间客户端可以接受这些字段,但新的市场源不得输出它们: | 已弃用字段 | 替代字段 | | --- | --- | | `support_platform` | `support_platforms` | | `platform` | `support_platforms` | ## 10. 未知字段 消费者可以保留未知字段。 消费者不得将未知字段用于: - 插件身份 - 安装源解析 - 更新源解析 - 安全校验 ## 11. 校验规则 市场源仅在所有规则通过时有效: 1. 根 JSON 值是对象。 2. `$meta` 存在。 3. `$meta` 是对象。 4. `$meta.schema_version` 是整数 `1`。 5. 除 `$meta` 外,每个根 key 是 `plugin_id` 或 `name` key。 6. 除 `$meta` 外,每个根 value 是 `PluginRecord` 对象。 7. 每条记录包含所有必填字段;仅当根 key 是 `name` key 时,`name` 可以省略。 8. 每个必填字符串字段去除首尾空白后非空。 9. `author` 和存在的 `name` 不包含 `/`。 10. 根 key 精确等于 `${author}/${name}`,或在兼容例外下精确等于 `name`。 11. 不存在两个小写归一化后相等的 ID。 12. `repo` 是 HTTPS GitHub 仓库 URL。 13. 如果存在,`download_url` 是 HTTPS URL。 14. 如果存在,`tags` 是字符串数组。 15. 如果存在,`support_platforms` 是字符串数组。 16. 如果存在,`stars` 是非负整数。 17. 如果存在,`download_count` 是非负整数。 18. 如果存在,`updated_at` 是 ISO 8601 时间戳。 19. 如果存在,`$meta.homepage` 是 HTTPS URL。 20. 如果存在,`$meta.repository` 是 HTTPS URL。 21. 如果存在,`$meta.updated_at` 是 ISO 8601 时间戳。 22. 从 `repo` 或 `download_url` 解析出的包包含 `metadata.yaml`。 23. `metadata.yaml.author` 等于 `author`。 24. `metadata.yaml.name` 等于 `name`。 25. `metadata.yaml.version` 等于 `version`。 ## 12. 安装规则 市场安装: 1. 客户端向后端发送选中的 `plugin_id` 和 registry source。 2. 后端从该 registry source 中按 `plugin_id` 解析 `PluginRecord`。 3. 如果 `download_url` 存在,后端使用 `download_url` 安装;否则使用 `repo` 安装。 4. 安装后,后端读取已安装的 `metadata.yaml`。 5. 已安装的 `metadata.yaml.author/name` 必须等于选中的 `plugin_id`。 6. 如果身份校验失败,安装必须失败。 7. 市场安装成功后,可以在本地状态中持久化 `repo`、`download_url`、registry 信息和安装时间。 ## 13. 更新规则 市场安装的插件: 1. 更新检测必须使用安装时记录的 registry source。 2. 更新检测必须按 `plugin_id` 解析市场记录。 3. 版本比较必须使用已安装 metadata 版本和市场记录 `version`。 4. 执行更新必须使用解析出的市场记录 `repo/download_url`。 非市场安装: 1. URL 安装、Git 安装、上传安装不得被视为市场安装。 2. 可以从已安装的 `metadata.yaml` 持久化 `plugin_id`。 3. 除非显式绑定到市场源,否则不得启用市场更新检测。 ## 14. 源绑定规则 将已安装的非市场插件绑定到市场源时: 1. 必须从已安装的 `metadata.yaml` 读取插件身份。 2. 候选市场记录必须具有相同 `plugin_id`。 3. 候选市场记录应该具有相同仓库身份。 4. 绑定必须持久化选中的 registry source 和 `plugin_id`。 ## 15. 兼容性 迁移期间,消费者可以读取旧版市场源。 对于旧版源: - 迁移期间,消费者可以接受没有 `$meta.schema_version` 的源。 - 消费者应该从 `author/name` 构造 `plugin_id`。 - 消费者应该拒绝缺少 `author` 或 `name` 的记录用于市场安装。 - 消费者可以仅将旧版根 key 用于展示。 - 除非 key 等于 `${author}/${name}`,消费者不得将旧版根 key 用作插件身份。 新的市场源必须包含 `$meta.schema_version`。