插件元信息

# 插件元信息

插件元信息包括名称、描述、作者、版本、图标等。这些信息决定了插件在宿主应用中的展示方式——插件列表、设置页、插件商店都会用到。

# 元信息来源

插件的元信息来自两个地方:

来源 用途
package.json 基础元数据:id、版本号、作者、仓库地址、许可证
resources/lang/*.json 可翻译的展示文本:名称、描述、作者名(覆盖 package.json 中的值)

名称和描述支持国际化。插件列表会根据用户当前语言自动切换。

# package.json 字段

package.json 是插件的唯一配置文件。以下是插件系统识别的字段:

{
  "name": "@myplugins/my-toolkit",
  "version": "1.2.0",
  "description": "A powerful toolkit for Android devices",
  "author": "Your Name",
  "license": "MIT",
  "repository": "https://github.com/you/my-toolkit"
}
字段 必须 说明
name 插件唯一标识(pluginPackageName)。推荐使用 npm 包名格式,如 @myplugins/toolkitautumnbox.my-toolkit
version 语义化版本号,用于版本管理和更新检查
description 插件描述。未在语言文件中覆盖时作为显示文本
author 作者名。未在语言文件中覆盖时作为显示文本
license 开源许可证标识(如 MITApache-2.0
repository 源码仓库地址。支持字符串或 { type, url } 格式

name 字段一旦发布就不应更改。它是插件的唯一标识,更改后会被视为一个全新的插件。

# 可翻译的元信息

插件的展示名称和描述可以在语言文件中覆盖,实现多语言支持。在 resources/lang/*.json 中使用特殊前缀键:

实际开发中推荐使用 <name> / <description> / <author> 语法糖。构建工具 autumnbox-sdk package 会自动把它们替换为带 namespace 的 key,避免多插件冲突:

// resources/lang/zh-CN.json(开发者编写)
{
  "<name>": "我的工具箱",
  "<description>": "一个强大的 Android 设备工具集",
  "<author>": "张三",

  "app.name.my-tool": "工具",
  "card.name.status": "状态卡片"
}
// resources/lang/en-US.json
{
  "<name>": "My Toolkit",
  "<description>": "A powerful toolkit for Android devices",
  "<author>": "Zhang San"
}

打包后,.atmb 内的实际 JSON 会变为:

开发者写的 打包后变成 用途
"<name>" "plugin.name.{pluginPackageName}" 插件显示名称
"<description>" "plugin.description.{pluginPackageName}" 插件描述
"<author>" "plugin.author.{pluginPackageName}" 作者名

其他自定义 key(如 app.name.*card.name.*)原样保留,不会被转换。

解析规则: 宿主首先查找语言文件中对应 key 的翻译。如果找不到(即翻译值与 key 相同),则回退到 package.json 中的字段值。

为什么需要 namespace?

多个插件的翻译内容共享同一个 LanguageService。如果所有插件都用 "name" 作 key 会互相覆盖。<name> 糖在编译时自动加前缀,开发者写起来简洁,运行时又不冲突。

即使不在语言文件中覆盖,也建议在 package.json 中填写 descriptionauthor。这样在未提供翻译的语言环境下仍有展示内容。

# 插件图标(resources/icon.png)

插件可以定义一个专属图标,用于插件列表、设置页等位置的展示。

# 约定

将 PNG 格式的图标文件放在 resources/icon.png

my-plugin/
├── resources/
│   ├── icon.png       ← 插件图标(建议 128×128 或 256×256)
│   └── lang/
│       └── ...
├── src/
└── package.json

构建时 autumnbox-sdk package 会将 resources/ 目录整体打包进 .atmb 文件。运行时可通过 PluginService 访问:

const iconBlob = pluginService.getPluginResource(pluginPackageName, 'icon.png');

# 图标规范

属性 建议
格式 PNG(透明背景)
尺寸 128×128 或 256×256 像素
文件大小 建议不超过 100KB
风格 圆角矩形(rx 约 22-28),与秋之盒桌面图标风格统一

# 与 App 图标的区别

插件有两个层级的图标,不要混淆:

图标类型 定义位置 用途 格式
插件图标 resources/icon.png 插件列表、设置页、插件商店 PNG 文件
App 图标 AutumnApp.icon 字段 桌面图标、Tab 图标、应用列表 SVG data URI 或 PNG data URI

插件图标代表整个插件包,App 图标代表单个功能页面。一个插件可以有多个 App,每个 App 有自己的图标,但插件只有一个图标。

# App 图标

App 图标通过 AutumnApp 定义的 icon 字段指定,在桌面和应用列表中展示。

# 方式一:内联 SVG data URI(推荐)

最常用、最灵活的方式。直接在 TypeScript 中定义 SVG:

const myIcon = `data:image/svg+xml,${encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
  <defs>
    <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
      <stop offset="0%" stop-color="#6366f1"/>
      <stop offset="100%" stop-color="#8b5cf6"/>
    </linearGradient>
  </defs>
  <rect width="128" height="128" rx="28" fill="url(#bg)"/>
  <text x="64" y="80" text-anchor="middle" font-size="48" fill="white"
        font-family="system-ui" font-weight="bold">TK</text>
</svg>
`)}`;

export const MyApp: AutumnApp = {
  id: 'my-toolkit',
  name: 'app.name.my-toolkit',
  icon: myIcon,
  component: MyComponent,
};

优势:

  • 矢量图,任何尺寸都清晰
  • 文件体积小
  • 支持渐变、滤镜等高级效果
  • 不需要额外文件

# 方式二:导入 PNG 文件

将 PNG 放在 src/assets/ 目录,通过 import 导入。Vite 构建时会将其转为 data URI:

import myIcon from '~/assets/my-icon.png';

export const MyApp: AutumnApp = {
  id: 'my-app',
  name: 'app.name.my-app',
  icon: myIcon,  // Vite 自动转为 data:image/png;base64,...
  component: MyComponent,
};

注意:小于 100KB 的 PNG 会被内联为 data URI,超过的会作为外部文件引用。

# 方式三:运行时从 resources/ 加载

.atmb 包内懒加载图标资源:

import { usePluginResource } from '@autumnbox/sdk/hooks';

const MyAppView: React.FC = () => {
  const { data: iconBlob, loading } = usePluginResource('icons/my-icon.png');

  if (loading) return <Spin />;
  const iconUrl = iconBlob ? URL.createObjectURL(iconBlob) : '';

  return <img src={iconUrl} alt="My Icon" />;
};

适用于大尺寸图标或不需要立即展示的场景。

# iconFit 模式

默认情况下,App 图标在桌面图标中会保持原始比例。设置 iconFit: true 可以让图标填满整个圆角矩形区域(类似 CSS object-fit: cover):

export const MyApp: AutumnApp = {
  id: 'photo-viewer',
  name: 'app.name.photo-viewer',
  icon: myPhotoIcon,
  iconFit: true,  // 图标填满整个圆角矩形,不保留边距
  component: PhotoViewer,
};

适合照片、截图等需要铺满展示的图标。对于文字+背景色的图标,通常不需要开启。

# 完整示例

一个完整的插件元信息配置:

my-toolkit/
├── src/
│   ├── apps/
│   │   └── ToolkitApp.tsx      ← 定义 icon 字段(App 图标)
│   └── main.ts
├── resources/
│   ├── icon.png                ← 插件图标(128×128 PNG)
│   └── lang/
│       ├── zh-CN.json
│       └── en-US.json
└── package.json
// package.json
{
  "name": "@myplugins/toolkit",
  "version": "1.0.0",
  "description": "A toolkit for Android",
  "author": "Developer",
  "license": "MIT",
  "repository": "https://github.com/dev/toolkit"
}
// resources/lang/zh-CN.json
{
  "<name>": "工具箱",
  "<description>": "Android 设备工具集",
  "app.name.toolkit": "工具箱"
}
// resources/lang/en-US.json
{
  "<name>": "Toolkit",
  "<description>": "Android device toolkit",
  "app.name.toolkit": "Toolkit"
}
// src/apps/ToolkitApp.tsx
import { defineApp } from '@autumnbox/sdk';

const toolkitIcon = `data:image/svg+xml,${encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
  <rect width="128" height="128" rx="28" fill="#4f46e5"/>
  <text x="64" y="80" text-anchor="middle" font-size="48" fill="white"
        font-family="system-ui" font-weight="bold">TK</text>
</svg>
`)}`;

export const ToolkitApp = defineApp({
  id: 'toolkit',
  name: 'app.name.toolkit',
  icon: toolkitIcon,
  tags: ['tools'],
  component: ToolkitView,
});

# 下一步