ReadAware

插件 API 参考

插件是一个包含 manifest.json和已构建 ES 模块的文件夹。完整的公开 TypeScript 契约以 types/plugin-api.d.ts in the readaware-plugins 仓库发布。本页说明各部分如何配合。

软件包结构

tree
my-plugin/
  manifest.json
  main.js
  src/main.ts       # 推荐提交以供审核
  assets/           # 可选,市场安装时需明确列出

main.js 默认导出一个生命周期对象。ReadAware 在专用模块 Worker 中运行它,并向activate提供 actor 作用域的上下文。

typescript
export default {
  activate(ctx) {
    // 检查并注册。此阶段会阻止副作用。
  },
  migrate(storageCtx, change) {
    // 可选:转换插件私有 KV 和文档。
  },
  deactivate() {
    // 可选:释放插件自己的外部资源。
  },
};

Manifest 清单

json
{
  "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.phaseactivating, 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

没有 shelfappearance 领域。 书库数据和当前阅读行为彼此分离。外观是设置中的一个分区。

设置访问

discoverreadwrite彼此独立。尽可能授予精确路径;仅在功能确实需要整个分区时,才使用例如 appearance.*。更新会经过目录校验、目标策略、持久化和提交后效果。

typescript
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, fontsmanifest 声明的语义主题和字体数据。ui:themes
syncTransports同步后端会话:把密封事件批次、密封 blob 与 meta 对象存到插件选择的远端。sync:transport

每个贡献 ID 都按插件划分命名空间,每次注册都有归属且可检查,过期的可释放对象不能移除较新的替代项。新的贡献类型仍需宿主有意提供消费者;之后任何兼容插件都能注册,无需在应用中逐一列出。

助手扩展边界

  • 上下文提供方运行一轮。宿主添加来源、限制大小,并将输出序列化为不可信参考数据。
  • 检索提供方成为命名空间工具,带有宿主拥有的 query/limit schema 和裁剪后的结果。
  • 记忆候选提供方在一轮之后提出受限候选;宿主校验范围、去重并执行任何持久写入。

插件永远不会收到 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.themereading.theme。二者并不相互推导。

生命周期阶段

  1. 激活中: 可使用查询和插件私有读取;注册会暂存;副作用被阻止。
  2. 迁移中: 只能使用插件 KV 和文档集合。
  3. 已激活: 已晋升的处理器可以使用获准的领域、贡献和服务。

宿主会排空激活 RPC、检查 Worker 健康状态、运行数据迁移,然后在一个明确的时点晋升全部暂存项。激活失败会释放暂存工作,不替换当前运行时。

Worker 环境

没有 React、Jotai、DOM、WebView、Tauri、SQLite、文件系统或进程访问。环境中的 fetch、WebSocket、EventSource、XMLHttpRequest、BroadcastChannel、IndexedDB 和 Cache Storage 均已禁用。网络、持久化和所有宿主交互都必须使用类型化上下文。

兼容性和稳定性

领域、贡献、服务和声明式 schema 各自拥有独立的语义版本。未知 ID、无效 semver 范围、无法访问的必需能力和不兼容的宿主版本都会阻止激活。兼容的新增内容提升所属能力的版本,而不是一个全局插件 API 编号。

当前生态是官方插件,因此当前由注册表支持的契约就是基线。不要依赖早期的 shelf, appearance 或注册表之前的形态。