# FlyonDeckPluginConfig

插件在清单顶层声明 `configPage`，即可在“拓展 → 详情 → 插件设置”提供自定义 HTML 表单。页面只编辑当前插件公开字段的草稿；用户点击宿主的“保存设置”后才持久化，插件后台随后收到设置变更通知。

```json
{
  "hostCapabilities": { "required": { "settings.global": 1, "settings.configPage": 1 } },
  "configPage": "pages/settings/index.html",
  "settingsSchema": { "properties": {
    "label": { "type": "string", "title": "标签", "default": "飞块" }
  } }
}
```

`configPage` 相对插件包根目录；同目录内的 CSS、JavaScript、图片和字体可使用相对路径加载。页面和静态资源在桌面专用协议中加载，不依赖设备 HTTP 服务，也不要求插件后台运行。没有声明时继续使用通用表单。入口不存在时安装或打包失败；页面加载失败或未加载 SDK 时，编辑器回退到通用表单。

```html
<!doctype html>
<html><head><meta charset="utf-8"></head><body>
<label for="label">标签</label><input id="label">
<script src="/api/plugin-sdk/i18n-v1.js"></script>
<script src="/api/plugin-sdk/plugin-config-page-v1.js"></script>
<script>
FlyonDeckPluginConfig.onSettings(settings => {
  document.querySelector('#label').value = settings.label ?? '';
});
document.querySelector('#label').oninput = event => {
  FlyonDeckPluginConfig.update({ label: event.target.value });
};
</script>
</body></html>
```

完整可下载示例见[示例插件](../guides/examples.md)。字段限制见[插件全局设置](./plugin-settings.md)。

## version

只读值 `1`，表示插件全局配置页面协议版本。

## onSettings()

```ts
FlyonDeckPluginConfig.onSettings(listener: (settings: Readonly<Record<string, string | number | boolean>>) => void): () => void
```

订阅宿主校验后的公开草稿。已有草稿时注册后立即回放，返回取消订阅函数。包括初始配置、接受修改后的结果、拒绝修改时的上一份有效草稿、保存和恢复默认值后的结果。监听器只更新界面，不要在回调中无条件调用 update。快照只读，监听器异常不影响其他监听器。

## getSettings()

```ts
FlyonDeckPluginConfig.getSettings(): Readonly<Record<string, string | number | boolean>> | null
```

同步返回最新公开草稿，首次初始化前为 null。未保存且无默认值的字段缺省。不会返回私密字段、Schema 或其他插件设置。

## update()

```ts
FlyonDeckPluginConfig.update(changes: Record<string, string | number | boolean | null>): void
```

提出部分字段修改。仅允许当前插件顶层 settingsSchema 声明的公开字段；null 表示恢复该字段默认值，没有默认值时删除覆盖值。值需满足字段类型、范围与长度约束。单次最多 32 字段、64 KiB。宿主原子校验整批修改，含未知、私密或无效字段时整批拒绝，并回传上一份有效草稿。

调用不保存，也不提前改变 SDK 中的本地快照；通过 onSettings 接收宿主的确认结果。尚未初始化时不提交。用户保存期间提交的修改不会被接受。

## getLocale()

返回宿主当前传来的页面语言。

## t()

`t(key, values?)` 使用当前插件的包内词典翻译。先加载 `/api/plugin-sdk/i18n-v1.js`，宿主在插件脚本执行前注入词典；缺失翻译回退到插件默认语言和键名。详见[国际化](./i18n.md)。

## 私密字段与隔离

页面运行在 `sandbox="allow-scripts"` 的 iframe 中，无桌面 preload、Node.js 或文件系统 API。页面只能加载包内公开配置资源与宿主 SDK，不能直接联网、提交表单或控制顶层页面。宿主核对消息发送窗口、插件 ID 和字段声明后才接收修改。

`visibility: "private"` 与 password 字段不进入页面初始化或回传结果，也不接受页面提出的修改。这些字段继续显示在 iframe 下方的宿主表单中，和公开草稿一起保存。配置资源目录中的文件是公开内容，不要存放秘密。
