插件 API 参考
插件是一个包含 manifest.json和已构建 ES 模块的文件夹。完整的公开 TypeScript 契约以 types/plugin-api.d.ts in the readaware-plugins 仓库发布。本页说明各部分如何配合。
软件包结构
my-plugin/
manifest.json
main.js
src/main.ts # 推荐提交以供审核
assets/ # 可选,市场安装时需明确列出main.js 默认导出一个生命周期对象。ReadAware 在专用模块 Worker 中运行它,并向activate提供 actor 作用域的上下文。
export default {
activate(ctx) {
// 检查并注册。此阶段会阻止副作用。
},
migrate(storageCtx, change) {
// 可选:转换插件私有 KV 和文档。
},
deactivate() {
// 可选:释放插件自己的外部资源。
},
};Manifest 清单
{
"id": "theme-schedule",
"name": "主题计划",
"version": "0.1.0",
"schemaVersion": 1,
"minAppVersion": "0.3.0",
"requires": {
"domains": { "settings": "^1.0.0" },
"contributions": {
"commands": "^1.0.0",
"settingsOptions": "^1.0.0"
},
"services": {
"storage": "^1.0.0",
"schedules": "^1.0.0",
"ui": "^1.0.0"
},
"schemas": { "settings": "^1.0.0" }
},
"settingsAccess": {
"discover": ["appearance.theme", "reading.theme"],
"write": ["appearance.theme", "reading.theme"]
},
"main": "main.js"
}| 字段 | 契约 |
|---|---|
id | 小写字母、数字和连字符,最长 64 个字符。它是永久命名空间,且必须与文件夹名一致。 |
name, version | 面向用户的名称和软件包版本。 |
schemaVersion | 插件私有 KV 和文档数据所需的正整数。独立于软件包版本。 |
requires | 按领域、贡献、服务和 schema 分组的能力 ID 到 semver 范围的必填映射。 |
permissions | 可选的语义授权请求,需经用户同意。未知值会导致校验失败。 |
settingsAccess | 可选的 discover/read/write 授权,用于精确设置路径或明确的 section.* 分组。 |
minAppVersion | 可选的最低应用版本。软件包依赖新发布能力时使用。 |
settings | 可选的由宿主渲染的插件设置字段。 |
schedules | 可选的周期任务,在绑定处理器前声明。 |
themes, fonts | 可选的声明式主题和字体贡献;需要 ui:themes. |
main | 相对于文件夹的入口模块;默认为 main.js. |
使用能力浏览器 查看完整清单和权限词汇。要求始终是兼容性声明,绝不会授予权限。
运行时上下文
| 命名空间 | 包含 |
|---|---|
ctx.manifest | 经过校验的只读 manifest。 |
ctx.appVersion, ctx.locale | 宿主版本和当前 UI 区域设置。 |
ctx.lifecycle.phase | activating, migrating, 或 active. |
ctx.capabilities | 仅对此插件 actor 可见的能力版本。 |
ctx.domains | 已授予的 ReadAware 状态和行为。 |
ctx.contributions | 插件可以向其中提供实现的注册表。 |
ctx.services | 受限的宿主操作和插件私有基础设施。 |
未获授权时,受权限控制的命名空间不会出现。每次 Worker 调用也会在宿主侧授权;隐藏方法不是唯一检查。注册会返回可释放对象,激活失败或插件停用时按相反顺序回收。
领域
领域公开 queries,可选 commands,以及已提交的 events.subscribe。命令使用与 ReadAware 相同的事件溯源写入路径,并归属于 plugin:<id>. 写入权限包含读取权限。
| 领域 | 查询和命令 | 权限 |
|---|---|---|
library | 书籍、元数据、原始章节文本、目录、集合;导入、编辑、加星、移除、虚拟书籍和集合命令。 | library:read / library:write |
reading | 按书籍和汇总的阅读统计;标记完成、打开书籍并导航到 CFI 或 href。 | reading:read / reading:write |
annotations | 筛选高亮、笔记和被动提问轨迹;创建、编辑、重新着色并移除高亮或笔记。 | annotations:read / annotations:write |
conversations | 读取书籍线程、列出全局线程并读取线程。写入仍由聊天运行时负责。 | conversations:read |
settings | 发现获准的目录条目、读取解析后的值、更新受支持的目标并订阅已提交的变更。 | 精确 settingsAccess grants |
没有 shelf 或 appearance 领域。 书库数据和当前阅读行为彼此分离。外观是设置中的一个分区。
设置访问
discover、read 和 write彼此独立。尽可能授予精确路径;仅在功能确实需要整个分区时,才使用例如 appearance.*。更新会经过目录校验、目标策略、持久化和提交后效果。
const entries = await ctx.domains.settings.queries.discover({
section: "appearance",
});
await ctx.domains.settings.commands.update([
{
path: "appearance.theme",
value: "dark",
target: { kind: "global" },
},
]);贡献
| 注册表 | 插件提供 | 权限 |
|---|---|---|
selectionActions | 选区动作及返回提示或宿主渲染视图的处理器。 | 无 |
headerActions | 阅读器或书库动作、位置元数据和视图回调。 | 无 |
commands | 命令元数据和处理器。 | 无 |
settingsOptions | 一个已声明插件字段的动态选项。 | 无 |
voiceProviders | 声音列表和编码音频合成。 | 无 |
contentProviders | 虚拟书籍键的章节。 | 无 |
readerModes | 受限阅读器分段模式;目前仅限内置插件。 | reader:modes |
agentTools | 工具 schema、用户可读标签、描述和执行器。 | agent:tools |
agentContextProviders | 受限的当前轮次参考区块。 | agent:context |
agentRetrievalProviders | 来自插件数据的搜索结果。 | agent:retrieval |
memoryCandidateProviders | 可能持久化的事实、偏好、洞察或摘要。 | agent:memory |
themes, fonts | manifest 声明的语义主题和字体数据。 | ui:themes |
syncTransports | 同步后端会话:把密封事件批次、密封 blob 与 meta 对象存到插件选择的远端。 | sync:transport |
每个贡献 ID 都按插件划分命名空间,每次注册都有归属且可检查,过期的可释放对象不能移除较新的替代项。新的贡献类型仍需宿主有意提供消费者;之后任何兼容插件都能注册,无需在应用中逐一列出。
助手扩展边界
- 上下文提供方运行一轮。宿主添加来源、限制大小,并将输出序列化为不可信参考数据。
- 检索提供方成为命名空间工具,带有宿主拥有的
query/limitschema 和裁剪后的结果。 - 记忆候选提供方在一轮之后提出受限候选;宿主校验范围、去重并执行任何持久写入。
插件永远不会收到 Memory 端口,不能注入系统规则,也不能直接写入长期记忆。
同步传输
syncTransports 注册提供另一种同步后端——一个由应用同步引擎推送和拉取的远端邮筒(第一方 WebDAV Sync 插件就是这样对接 WebDAV 的)。边界画在密文:引擎在插件看到任何数据之前就完成密封,传输层搬运的只是不透明信封及其路由字段(事件 id、HLC 时间戳),永远看不到事件类型、书籍字节或密钥。契约是「哑存储」——每设备稠密的事件批次、引擎信封格式的 blob 对象、以及用于「首写者胜」密钥材料的 create-only meta 对象。排序、游标、合并、口令仪式与调度全部留在宿主侧;连接传输后端与 ReadAware 账号互斥。失败时抛出携带稳定 sync/* 错误码的 Error 来分类;未带码的错误按瞬时失败处理并指数退避重试。
宿主服务
| 服务 | 契约 | 权限 |
|---|---|---|
storage | 命名空间 KV、文档集合和外部变更通知。 | 无 |
secrets | 命名空间加密凭据槽。 | 无 |
ui | 宿主提示和保存/导出流程。 | 无 |
schedules | 将处理器绑定到 manifest 声明的频率。 | 无 |
session | 订阅受限的阅读会话事实。 | 无 |
network | 宿主中介的 HTTP。 | service:network |
llm | 使用用户配置进行一次性文本或 JSON schema 约束的模型调用。 | service:llm |
clipboard | 向系统剪贴板写入文本。 | service:clipboard |
存储
使用 KV 存储小型设置和检查点。使用命名文档集合保存具有稳定 ID 且可选包含 bookId/anchor来源信息的插件记录。来源信息是索引而非所有权;引用书籍被删除后文档仍可保留。卸载会清空文档集合,但保留 KV、密钥槽和已提交的 schema 元数据,以便重新安装和迁移。
定时任务
manifest 声明 { id, label, everyMinutes },激活通过ctx.services.schedules.bind绑定处理器。最短频率为 15 分钟。应用打开时至少按此频率运行,逾期会在启动后补跑,任务不会重叠。这不是持久后台任务,也不保证精确时间。
声明式 UI 和设置
插件返回版本化的视图数据,而不是可执行 UI。视图语法包括 markdown、可搜索列表、表单、详情布局、词典结果和受限区块树。处理器可以保留界面、显示提示、打开或替换视图、重置导航、关闭界面或返回字段错误。宿主负责 promise 的加载和失败状态。
Manifest 设置使用宿主控件支持文本、文本域、数字、时间、选择、选项、复选框、开关和密钥字段。条件字段使用 visibleWhen;动态选择使用已注册的 settingsOptions 提供方。密钥字段直接写入加密密钥槽,永远不会进入普通设置对象或助手可见目录。
主题和字体
主题插件在 manifest 中声明语义数据。应用主题覆盖固定的宿主令牌词汇;阅读器主题提供所需的六色页面调色板和可选排版默认值。宿主校验值、生成 CSS、加载获批准的本地字体文件,并在用户选择前不应用任何内容。
提供选项需要 ui:themes。选择主题需要精确的设置写入授权,例如 appearance.theme 或 reading.theme。二者并不相互推导。
生命周期阶段
- 激活中: 可使用查询和插件私有读取;注册会暂存;副作用被阻止。
- 迁移中: 只能使用插件 KV 和文档集合。
- 已激活: 已晋升的处理器可以使用获准的领域、贡献和服务。
宿主会排空激活 RPC、检查 Worker 健康状态、运行数据迁移,然后在一个明确的时点晋升全部暂存项。激活失败会释放暂存工作,不替换当前运行时。
Worker 环境
没有 React、Jotai、DOM、WebView、Tauri、SQLite、文件系统或进程访问。环境中的 fetch、WebSocket、EventSource、XMLHttpRequest、BroadcastChannel、IndexedDB 和 Cache Storage 均已禁用。网络、持久化和所有宿主交互都必须使用类型化上下文。
兼容性和稳定性
领域、贡献、服务和声明式 schema 各自拥有独立的语义版本。未知 ID、无效 semver 范围、无法访问的必需能力和不兼容的宿主版本都会阻止激活。兼容的新增内容提升所属能力的版本,而不是一个全局插件 API 编号。
当前生态是官方插件,因此当前由注册表支持的契约就是基线。不要依赖早期的 shelf, appearance 或注册表之前的形态。