ReadAware

插件 API 参考

本页介绍的是开发契约,它可能领先于最新发布版本。文末的完整参考列出了每项能力及其开发版本、在最新发布版本中的版本号、所需权限,以及每个方法的最终签名和文档。能力浏览器以交互方式提供相同的目录。公开插件仓库中的类型与最新发布版本保持一致。

包与 manifest

插件包含 manifest.json 与一个自包含的 ES 模块,通常是 main.js。请将源码与所需资源与包一起保留以供审查。

栏位说明
id, name, version稳定命名空间、显示名称与包版本。ID 须与文件夹名称相符。
schemaVersion插件私有数据结构的正整数版本;与包版本无关。
requires能力 ID 与 semver 范围,分组为 domains、contributions、services 与 schemas。
permissions语义权限,例如 library:read 或 service:llm。
settingsAccess针对确切路径或明确的区段群组,分别授予 discover、read 与 write 权限。
networkAccessNetwork 2.x 允许的 HTTP(S) 来源;需与 service:network 同时声明。
minAppVersion选用的应用最低版本门槛,在能力需求之外额外设置。
main相对的入口模块;预设为 main.js。
settings, schedules, themes, fonts由宿主解读的声明。
services供跨插件调用的版本化、类型化模块服务汇出。

没有任何 manifest 栏位会授予任意的文件系统、SQL、DOM 或原生 IPC 访问权。

上下文与对象范围

宿主会调用 activate(ctx),并提供 ctx.domains、ctx.contributions、ctx.services,以及 manifest、locale、应用版本、生命周期阶段、能力版本与不可变的书籍授权。

ctx.grants.book 的值为 all、current 或指定的 book。宿主透过同意流程选取。读取、记忆、对话、指令与资源在调用与回调之间都会维持该范围。目前的书籍变更可能使未完成的读取、句柄、提案与观察结果失效。

领域写入权限包含读取权限。设置授予仍依操作个别独立。受权限控管的命名空间或方法可能不存在;宿主仍会在每次调用时执行检查。使用 ctx.services.session.operationAvailability(...) 进行支持的预先检查查询,且在取得肯定结果后仍须处理执行失败的情况。

领域

领域提供的功能限制
library书籍与收藏、目录、精确位置搜索、范围、参考与图片、导入、文字任务、中继数据、重复合并与移除。来源版本、书籍范围、受限读取、参与者拥有的任务,以及独立的文件清理回执。
reading工作阶段快照、导航、选取、播放与模式控制、进度、阅读时间与洞察。目前工作阶段保护、已定案与待处理状态、供应商可用性与取消。
annotations页面、检查与观察;建立划线或笔记;条件式编辑/删除批次。使用用户决定前的修订版本。撷取的范围也需要 Library 访问权。
conversations授权的对话纪录、存储的摘要、运行时与轮替要求状态;线程控制与提议的轮替。宿主核准后才会开始提议的轮替。全域线程操作需要全部书籍的访问权。插件不会取代聊天运行时。
settings目录探索、解析后快照、选项、模型中继数据、观察、更新与阅读重设。确切路径、目标政策,以及外部供应商工作的额外授权。
memory搜索与页面、检查、修正/遗忘、个人数据、实体、分类、图表与任务、内容封存。书籍授权与条件式修订。全域身分/个人数据操作需要全部书籍的访问权;产生内容也需要模型授权。

来源文字与导航

使用 library.queries.books.searchLocations 取得可导航的来源比对结果,使用 readRange 取得受限的来源文字。请保留返回的来源版本与位置。衍生的 searchText 命中结果仅供预览,不可互换作为导航锚点。明确的文字准备会返回一个任务,必须观察其进度与结果。

条件式写入

在显示编辑前检查目前对象并保留其修订版本。针对该修订版本送出条件式变更。若发生冲突,请重新读取并让用户决定;静默取代预期的修订版本会覆盖其他变更。

annotations.commands.applyChanges、记忆变更、私有文件提交与事务预览各自有其类型化接口约定。一般指令不会自动成为可复原或分散式事务。

观察与反应

使用授权的观察取得目前状态,使用已提交的订阅取得事件。序号可以排序传递项目,但它不是数据库游标或条件式写入的修订版本。失败的观察必须能与空结果区分。

使用 ctx.withEvent(delivery) 进行自动的后续工作,并在需要时于因果订阅上使用稳定的规则 ID。透过非同步调用维持绑定的内容。宿主会拒绝因果回圈与已过期的传递;独立的用户动作使用原始内容。

贡献

贡献插件提供的内容
selectionActions, headerActions, contextActions, commands, uriHandlers在类型化的宿主界面上的动作、指令面板指令与命名空间 URI 处理。
settingsOptions已声明插件设置的动态选项。
voiceProviders, contentProviders, readerModes语音合成、虚拟书籍内容与内建的阅读器分段模式。
agentTools, agentContextProviders, agentRetrievalProviders工具、受限的每轮内容,以及可搜索的插件自有来源。
memoryCandidateProviders供宿主验证与接受的候选记忆。
themes, fontsmanifest 声明的外观选项。
syncTransports不透明加密同步信封与元数据对象的存储。

动作可以在支持的地方更新其拥有的可见/启用/勾选状态。注册与可释放资源属于单次启用。返回视图不会授予回调额外的领域授权。

记忆候选与直接的 Memory 指令是不同路径:候选会经过宿主接受,而直接指令需要对应的 Memory 授权与修订版本。两者都不允许注入系统规则或取代核心代理程式。

宿主服务

服务用途主要限制
storage私有 KV、文件集合、条件式提交、页面、观察与使用政策。插件命名空间与配额;过期的游标需要重新取得基准。
resources用户挑选的文件/目录、密封的位元组句柄、汇出、图片与私有二进位资源。没有环境隐含路径。句柄有拥有者、限制与生命周期。
secrets插件私有的加密凭据插槽。无法访问其他插件的密码。
network来源范围的 HTTP、受限的缓冲请求与串流。每次重新导向都会检查;不会自动重送任意的写入。
llm文字或结构化推论、串流、图片资源、请求回执与预算。用户设置、隐私规则、取消与宿主/供应商限制。
clipboard写入文字或密封的图片。明确权限与支持的资源类型。
ui视图、提示消息、原生存储/开启流程、工作区与指令导航、阅读器面板与窗口。方法特定的领域授权与宿主拥有的呈现。
session非敏感的环境中继数据与操作可用性。没有旧的阅读工作阶段订阅;请使用 Reading 领域。
schedules声明的周期性处理函数与拥有的延迟要求。工作只在应用开启时执行;时间并非精确。
jobs支持的持久性计划、检查点、观察与控制。类型化的宿主操作,而非任意的 JavaScript 执行。
changes限范围的持久性变更游标。重新整理提示,而非原始事件记录或历史值。
transactions预览、提交、回执查询与条件式复原预览。受支持的本机操作与原始授权;未知结果需要查询回执。
plugins检查注册、观察变更、探索与调用类型化的插件服务。调用端/被调用端授权交集、范围、版本与隔离的服务执行。
maintenance状态与宿主拥有的备份、连线测试与更新流程。宿主保留凭据、文件对话框与重大确认。
sync授权的同步状态、积压与宿主管理的帐户或同步流程。没有加密金钥或原始帐户凭据。
diagnostics, logging经审查的诊断汇出与受限的结构化开发者事件。没有任意内容、密码或透过日志 API 的自动回报。

网络与推论

Network 2.x 需要同时具备语义权限与明确的来源:

json
{
  "requires": { "services": { "network": "^2.2.0" } },
  "permissions": ["service:network"],
  "networkAccess": { "origins": ["https://api.example.com"] }
}

将示例来源取代为你实际使用的端点。来源包含 scheme、主机与连接埠;它们不是 URL 路径或子网域万用字元。重新导向必须维持在授权范围内。串流调用端在完成后关闭其拥有的串流。选择性的安全重试仅限于回应送达前的受支持读取要求;取消不会复原远端副作用。

对于推论,使用 readingContext 取得书籍内容,以便宿主套用隐私与范围规则。使用密封的资源 ID 作为支持的图片。请求中继数据与输出预算有助于控制工作量;它们不是帐单明细,也不保证供应商合规。

背景工作与事务

使用 schedule 安排处理函数的调用,使用拥有的延迟要求在应用运行时间安排稍后的工作,并仅在类型化计划支持该操作时使用持久性 job。重新启动后的复原可能需要人工介入,而非盲目重复不确定的外部结果。

事务结合受支持的设置、私有文件与领域操作,并在原始授权下执行。预览会冻结提议的工作;提交会消耗该预览。在未知回应之后,先查询回执再重试。复原是条件式的,要求状态仍与先前结果相符。

跨插件服务

在提供者 manifest 中声明服务 ID、版本、范围、所需权限与输入/输出结构描述,并在模块的 services 对象中汇出其处理函数。透过 Plugins 服务探索并调用它。宿主会以交集后的授权执行全新的隔离服务环境;它不会为了该调用而启用提供者的一般 UI 运行时。代理程式发起的调用仍保留其核准要求。

视图、设置、主题与字体

插件返回声明式视图数据。宿主会呈现清单、表单、markdown、详细信息与支持的区块版面。使用类型明确的视图结果和实时视图更新;保持加载、冲突、空白与错误状态可区分。插件代码无法使用 React、DOM、iframe 或任意 CSS。

设置栏位由宿主呈现。密码栏位会写入加密的密码插槽,不会成为一般表单值或模型可见的设置。提供主题或字体需要 ui:themes;选取主题或字体会使用对应的 Settings 写入授权。

生命周期与兼容性

  1. 启用中: 支持的读取与注册;分阶段的贡献尚未可见。
  2. 迁移中: 仅限私有存储空间,在提交变更的结构描述之前。
  3. 启用完成: 升级的处理函数可以使用授予的能力。

宿主会在启用与任何迁移成功后进行健康检查并升级候选版本。失败时会还原先前的包与数据。卸载会释放注册、回调与拥有的资源;持久性数据遵循其独立的保留接口约定。在目前的开发阶段,解除安装会移除私有文件集合与二进位资源,但保留定义的 KV/密码/结构描述状态以供重新安装。

独立声明每个使用的能力与结构描述。版本号码证明接口约定兼容性,而非每个操作系统、供应商或失败案例都已通过端对端验收。请验证你实际发布的桌面工作流程。

建立插件 · 能力总览 · 发布

完整参考

开发契约中的每项能力,按类别分组。面向用户当前所用应用的插件,应要求最新正式版中列出的版本号。

领域

domains:library

查看书籍、来源文字、目录、精确位置、范围、图片与集合;导入、整理并管理文字工作。

  • 开发版:v1.35.0
  • ReadAware 0.6.8:v1.35.0
  • 授权: library:read / library:write
ctx.domains.library.commands.books.addVirtualBook
(input: { providerId: string; key: string; title: string; author?: string; }): Promise<BookSummary>
ctx.domains.library.commands.books.cancelImportTask
(taskId: string): Promise<BookImportTaskSnapshot>
ctx.domains.library.commands.books.cancelTextTask
(bookId: string, taskId: string): Promise<BookTextTaskSnapshot>

Cancels only this activation's request; shared work or dispatched writes may continue.

ctx.domains.library.commands.books.editMetadata
(bookId: string, patch: { title?: string; author?: string; }): Promise<void>
ctx.domains.library.commands.books.importBook
(input: { fileName: string; data: ArrayBuffer | Uint8Array; }, options?: PluginCallOptions): Promise<BookSummary>
ctx.domains.library.commands.books.importResource
(id: string, options?: PluginCallOptions): Promise<BookImportReceipt>

Library 1.19 adds per-call cancellation. Before the first durable write, cancellation prevents admission; afterward await the actual imported/duplicate receipt or failure. No whole-file transfer, opening or resource release.

ctx.domains.library.commands.books.invalidateVirtualBook
(input: { providerId: string; key: string; }): Promise<{ bookId: string; revision: string; }>

Announce already-saved source changes. Does not reload or move the reader. revision is a process-local invalidation fence, not a content hash. Library 1.15.

ctx.domains.library.commands.books.mergeDuplicates
(input: BookMergeRequest): Promise<BookMergeReceipt>

Conditional record merge with the host's deterministic keeper; not file deletion or undo.

ctx.domains.library.commands.books.pauseTextTask
(bookId: string, taskId: string): Promise<BookTextTaskSnapshot>
ctx.domains.library.commands.books.prepareText
(bookId: string, options?: BookTextPrepareOptions): Promise<BookTextTaskSnapshot>

Library 1.31: starts an actor-owned background request. A receipt is not completion. Current-book grants fence admission and the lease through pause/resume; switching books cancels only this request, without undoing accepted writes.

ctx.domains.library.commands.books.remove
(bookId: string): Promise<void>
ctx.domains.library.commands.books.removeMany
(bookIds: string[]): Promise<BookRemovalReceipt>

1-1000 IDs, deduplicated. Atomic record deletion; local file release is separately reported.

ctx.domains.library.commands.books.removeVirtualBook
(input: { providerId: string; key: string; expectedBookId?: string; }): Promise<void>
ctx.domains.library.commands.books.resumeTextTask
(bookId: string, taskId: string): Promise<BookTextTaskSnapshot>

Library 1.21: reacquires this paused request using saved checkpoints and the same handle.

ctx.domains.library.commands.books.retryEnrichment
(bookId: string): Promise<BookEnrichmentReceipt>

Retry unchecked covers and missing/filename-derived metadata using the shared queue, without forcing replacement or download.

ctx.domains.library.commands.books.retryRemovalCleanup
(bookIds: string[]): Promise<BookFileReleaseReceipt>

Retry file release only. Refuses any ID now present in the library; never deletes records.

ctx.domains.library.commands.books.setStarred
(bookId: string, starred: boolean): Promise<void>
ctx.domains.library.commands.books.setTextTaskPriority
(bookId: string, taskId: string, priority: BookTextPriority): Promise<BookTextTaskSnapshot>

Library 1.21: pauses only this request by releasing its lease; other consumers and dispatched I/O may continue.

ctx.domains.library.commands.books.startImport
(input: BookImportRequest, options?: PluginCallOptions): Promise<BookImportTaskSnapshot>

Start a task over owned sealed resources or <=64 MiB file bytes (wire limits still apply). Queued is not imported. options.signal cancels admission only; use cancelImportTask after the receipt. At most 2 physical task executions per activation, 4 in the app; direct imports/picker jobs are outside this task quota. Tasks do not resume after restart. Accepted writes finish despite cancellation.

ctx.domains.library.commands.collections.assignBooks
(bookIds: string[], collectionId: string | null): Promise<void>
ctx.domains.library.commands.collections.create
(name: string): Promise<CollectionSummary>
ctx.domains.library.commands.collections.remove
(collectionId: string): Promise<void>
ctx.domains.library.commands.collections.rename
(collectionId: string, name: string): Promise<void>
ctx.domains.library.events.observeContentState
(bookId: string, handler: PluginObservationHandler<BookContentObservation>, options?: { ruleId?: string; }): PluginDisposable
ctx.domains.library.events.observeEnrichment
(bookId: string, handler: PluginObservationHandler<BookEnrichmentObservation>, options?: { ruleId?: string; }): PluginDisposable
ctx.domains.library.events.observeImportTask
(taskId: string, handler: PluginObservationHandler<BookImportTaskSnapshot>, options?: { ruleId?: string; }): PluginDisposable

Initial snapshot and coalesced monotonic revisions, including terminal failures.

ctx.domains.library.events.observeInvalidation
(handler: PluginObservationHandler<ProjectionInvalidation>): PluginDisposable

Initial and coalesced reload hints, including remote projection changes. Re-query authorized data; not an event log or a conditional-write token.

ctx.domains.library.events.observeTextTask
(bookId: string, taskId: string, handler: PluginObservationHandler<BookTextTaskSnapshot>, options?: { ruleId?: string; }): PluginDisposable

Library 1.32: serial reaction deliveries retain task and history-write sources.

ctx.domains.library.events.subscribe
<K>(event: K, handler: (event: PluginDomainEvent<K>) => unknown, options?: { ignoreSelf?: boolean; ruleId?: string; }): PluginDisposable
ctx.domains.library.queries.books.get
(bookId: string): Promise<BookSummary | null>
ctx.domains.library.queries.books.getChapterText
(bookId: string, chapterIndex: number): Promise<string | null>
ctx.domains.library.queries.books.getContentState
(bookId: string, options?: PluginCallOptions): Promise<BookContentState>

Source metadata only; never loads a provider or reveals reading state. Library 1.16.

ctx.domains.library.queries.books.getEnrichment
(bookId: string): Promise<BookEnrichmentSnapshot>

Library 1.9: local cover/source state and the latest process-local enrichment attempt.

ctx.domains.library.queries.books.getImportTask
(taskId: string, waitMs?: number, options?: PluginCallOptions): Promise<BookImportTaskSnapshot>

waitMs (0..30000) waits for terminal state or returns current progress at the deadline. Cancelling this query stops observation only.

ctx.domains.library.queries.books.getNavigationToc
(bookId: string, options?: PluginCallOptions): Promise<BookNavigationToc>
ctx.domains.library.queries.books.getTextState
(bookId: string): Promise<BookTextSnapshot>

Read-only derived-text state. Never starts parsing, fetching, or extraction.

ctx.domains.library.queries.books.getTextTask
(bookId: string, taskId: string): Promise<BookTextTaskSnapshot>
ctx.domains.library.queries.books.getToc
(bookId: string): Promise<ChapterRef[]>
ctx.domains.library.queries.books.inspectResource
(id: string, options?: PluginCallOptions): Promise<BookInspection>

Initialize this activation's sealed resource with the reader parser; no import.

ctx.domains.library.queries.books.list
(): Promise<BookSummary[]>
ctx.domains.library.queries.books.listDuplicates
(query?: DuplicateBookQuery): Promise<DuplicateBookPage>

Library 1.10: same-content groups; live offset pages, limit 1-50.

ctx.domains.library.queries.books.listFormats
(): Promise<BookFormatCapability[]>

Library 1.11: import routing hints; extensions alone do not prove readability.

ctx.domains.library.queries.books.listImages
(input: BookReferencesQuery, options?: PluginCallOptions): Promise<BookImagesPage>

Library 1.29: section-local img/SVG, srcset/authored CSS and PDF image candidates. No remote fetch; PDF operator inspection can decode objects.

ctx.domains.library.queries.books.listImportTasks
(): Promise<BookImportTaskSnapshot[]>
ctx.domains.library.queries.books.listNavigationTargets
(input: BookNavigationTargetsQuery, options?: PluginCallOptions): Promise<BookNavigationTargetsPage>

Library 1.14: bounded source-section or author-supplied page-label catalog; not screen page counts.

ctx.domains.library.queries.books.listReferences
(input: BookReferencesQuery, options?: PluginCallOptions): Promise<BookReferencesPage>

Library 1.12: versioned section references, not extracted chapter indices.

ctx.domains.library.queries.books.listRemovalCleanup
(query?: BookRemovalCleanupQuery): Promise<BookRemovalCleanupPage>

Durable device-local pending file cleanup, including after view/plugin restart. Live keyset page, limit 1-100 (default 50).

ctx.domains.library.queries.books.listTextTaskHistory
(bookId: string, query?: BookTextTaskHistoryQuery): Promise<BookTextTaskHistoryPage>
ctx.domains.library.queries.books.listTextTasks
(bookId: string): Promise<BookTextTaskSnapshot[]>
ctx.domains.library.queries.books.openImageResource
(input: BookImageQuery): Promise<BookImageResource>

Seal an embedded image as this activation's ResourceRef; does not display it or decode pixels.

ctx.domains.library.queries.books.previewMerge
(bookId: string): Promise<BookMergePreview | null>
ctx.domains.library.queries.books.readRange
(input: BookRangeQuery, options?: PluginCallOptions): Promise<BookRangePage>
ctx.domains.library.queries.books.readReference
(input: BookReferenceQuery, options?: PluginCallOptions): Promise<BookReferencePreview>

Plain-text preview and resolved navigation location; never fetches or opens an external URL.

ctx.domains.library.queries.books.resolveId
(bookId: string): Promise<string | null>

Current book ID or merge redirect, null if neither points to a living book.

ctx.domains.library.queries.books.searchLocations
(input: BookLocationSearch, options?: PluginCallOptions): Promise<BookLocationSearchPage>
ctx.domains.library.queries.books.searchText
(input: BookTextSearch, options?: PluginCallOptions): Promise<BookTextHit[]>

Multi-query derived prose search. Single-book may prepare text; shelf search never does. Results are not navigation locations.

ctx.domains.library.queries.collections.booksIn
(collectionId: string): Promise<string[]>
ctx.domains.library.queries.collections.list
(): Promise<CollectionSummary[]>

domains:reading

观察阅读工作阶段、导航与选取文字、控制播放与模式,并查询进度、时间与洞察。

  • 开发版:v2.24.0
  • ReadAware 0.6.8:v2.24.0
  • 授权: reading:read / reading:write
ctx.domains.reading.commands.back
(guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>
ctx.domains.reading.commands.clearSelection
(expectedId: string, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingSelectionReceipt>

Clears only the observed selection ID; a replacement selection is never silently cleared.

ctx.domains.reading.commands.close
(guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<void>
ctx.domains.reading.commands.configureMode
(input: ReadingModeConfiguration, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingModeReceipt>

Configure the host mode; modeKey guards the current provider, selectModeKey selects from session().mode.availableModes. Resolves after real indexing (ready/empty) or deactivation. Failed indexing rejects. Disabling the caller cancels an unfinished change; completed mode preferences remain.

ctx.domains.reading.commands.controlPlayback
(action: "start" | "stop", guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingPlaybackReceipt>

Start resolves on actual audio start. Stop is idempotent; disabling the initiating plugin stops its playback.

ctx.domains.reading.commands.forward
(guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>
ctx.domains.reading.commands.goTo
(target: ReadingTarget, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>
ctx.domains.reading.commands.openBook
(bookId: string, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>
ctx.domains.reading.commands.putEmphasis
(input: ReadingEmphasisWrite, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingEmphasisReceipt>

Temporary owned marks, not annotations. No navigation; replacement requires an observed revision.

ctx.domains.reading.commands.reload
(guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>

Reading 2.21: reopen source; virtual sections with identical stable identity/content preserve their location across reorder. Stale/legacy virtual locators restart at the beginning; files still restart. Whole-book contentVersion guards remain strict.

ctx.domains.reading.commands.removeEmphasis
(input: ReadingEmphasisRef, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingEmphasisRemoval>
ctx.domains.reading.commands.returnToMode
(guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>

Return to the versioned resting unit; wait for renderer navigation and unit restoration before committing history.

ctx.domains.reading.commands.selectRange
(range: BookTextRange, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingSelectionReceipt>

Requires this book to be open; validates its source range, navigates, then waits for the selection overlay commit.

ctx.domains.reading.commands.setControls
(visible: boolean, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingControlsReceipt>

Set reader chrome visibility; completes after UI commit. Does not alter panel preferences or playback.

ctx.domains.reading.commands.setFinished
(bookId: string, finished: boolean): Promise<void>
ctx.domains.reading.commands.step
(direction: ReadingStep, guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingNavigationReceipt>

Reading 2.12: page, source-section and book-boundary navigation; section/boundary jumps enter history.

ctx.domains.reading.commands.stepMode
(direction: "next" | "previous", guard?: ReadingSessionGuard, options?: PluginCallOptions): Promise<ReadingModeStepReceipt>

Step one configured text unit, across sections if necessary; reports book boundaries explicitly.

ctx.domains.reading.events.observeEmphasis
(handler: (snapshot: ReadingEmphasisSnapshot[], delivery?: PluginReactionEvent) => void | Promise<void>): PluginDisposable
ctx.domains.reading.events.observeSession
(handler: (snapshot: ReadingSessionSnapshot, delivery?: PluginReactionEvent) => void | Promise<void>, options?: { ruleId?: string; }): PluginDisposable

Immediate and subsequent snapshots carry a live reaction lease. Use withEvent for automatic writes; keep the original context for later user actions. A stable ruleId can resume job causality across activations.

ctx.domains.reading.events.observeTime
(query: ReadingTimeQuery, handler: (event: ReadingTimeObservation, delivery?: PluginReactionEvent) => void | Promise<void>, options?: { ruleId?: string; }): PluginDisposable

Immediate sample then a 1s minimum gap after each delivery. Errors are explicit; dispose stops further delivery. Reading 2.24: delivery retains sampling subscription ancestry across timers. It does not identify historical writers of the aggregate.

ctx.domains.reading.events.subscribe
<K>(event: K, handler: (event: PluginDomainEvent<K>) => unknown, options?: { ignoreSelf?: boolean; ruleId?: string; }): PluginDisposable
ctx.domains.reading.queries.emphasis
(): Promise<ReadingEmphasisSnapshot[]>

This activation's temporary marks only; attached does not mean visible in the viewport.

ctx.domains.reading.queries.session
(): Promise<ReadingSessionSnapshot>
ctx.domains.reading.queries.stats.forBook
(bookId: string): Promise<BookStats | null>
ctx.domains.reading.queries.stats.insights
(query?: ReadingInsightsQuery): Promise<ReadingInsights>
ctx.domains.reading.queries.stats.list
(): Promise<BookStats[]>
ctx.domains.reading.queries.stats.overview
(): Promise<StatsOverview>
ctx.domains.reading.queries.stats.time
(query?: ReadingTimeQuery): Promise<ReadingTimeSnapshot>

Atomic settled + pending time, with native sampling clock. Reading >=2.7.

domains:annotations

分页、查看并观察荧光标示与笔记;建立标注,或套用经版本检查的编辑与删除。

  • 开发版:v2.2.0
  • ReadAware 0.6.8:v2.2.0
  • 授权: annotations:read / annotations:write
ctx.domains.annotations.commands.applyChanges
(changes: AnnotationMutation[]): Promise<AnnotationCommitResult>

Since 2.0 this is the only edit/delete entry. Use the revision observed before the user's decision; 1..100 distinct items, all commit or none.

ctx.domains.annotations.commands.createHighlight
(input: { range?: BookTextRange; bookId: string; text: string; anchor?: string | null; chapterHref?: string | null; color?: HighlightColor; style?: HighlightStyle; }): Promise<HighlightItem>

annotations >=2.1: range validates and preserves the captured source; requires library:read.

ctx.domains.annotations.commands.createNote
(input: { range?: BookTextRange; bookId: string; body: string; quotedText?: string; anchor?: string | null; chapterHref?: string | null; }): Promise<NoteItem>
ctx.domains.annotations.events.observe
(query: AnnotationObservationQuery, handler: PluginObservationHandler<AnnotationObservation>): PluginDisposable

Since 1.4. Initial authorized snapshot, then changed results/errors/recovery. Disposal ends polling.

ctx.domains.annotations.events.subscribe
<K>(event: K, handler: (event: PluginDomainEvent<K>) => unknown, options?: { ignoreSelf?: boolean; ruleId?: string; }): PluginDisposable
ctx.domains.annotations.queries.get
(annotationId: string): Promise<AnnotationItem | null>

annotations >=1.1.0. Missing IDs return null; read failures reject.

ctx.domains.annotations.queries.inspect
(annotationId: string): Promise<AnnotationSnapshot | null>

annotations >=1.3.0. Read an item and its conditional-write token atomically.

ctx.domains.annotations.queries.list
(filter?: { bookId?: string; kind?: "highlight" | "note" | "ask"; query?: string; }): Promise<AnnotationItem[]>
ctx.domains.annotations.queries.page
(input?: AnnotationPageQuery): Promise<AnnotationPage>

annotations >=1.2.0. Live keyset page, not a frozen snapshot across calls.

domains:conversations

读取经授权的对话记录、摘要与执行时状态;提出回合、管理讨论串,并使用核准的停止或清除控制项。

  • 开发版:v1.6.0
  • ReadAware 0.6.8:v1.6.0
  • 授权: conversations:read / conversations:write
ctx.domains.conversations.commands.cancelTurnRequest
(id: string): Promise<ConversationTurnRequestSnapshot>
ctx.domains.conversations.commands.clear
(target: ConversationTarget): Promise<ConversationControlReceipt>

Clears transcript/hidden thread state after draining turns, not long-term memory or event history.

ctx.domains.conversations.commands.createThread
(): Promise<ConversationControlReceipt & { draft: true; }>

Creates and selects a global draft; no transcript row until the first message. Does not navigate the app.

ctx.domains.conversations.commands.requestTurn
(request: ConversationTurnRequest): Promise<ConversationTurnRequestSnapshot>

Requires a mounted conversation. Only a host UI confirmation can adopt/send/retry; receipt is not a completed turn.

ctx.domains.conversations.commands.selectThread
(threadId: string): Promise<ConversationControlReceipt>
ctx.domains.conversations.commands.stop
(target: ConversationTarget): Promise<ConversationControlReceipt>

Stops live UI turns and waits for their final transcript writes. Does not undo tool effects.

ctx.domains.conversations.events.observeInvalidation
(handler: PluginObservationHandler<ProjectionInvalidation>): PluginDisposable
ctx.domains.conversations.events.observeRuntime
(handler: PluginObservationHandler<PluginConversationRuntimeSnapshot>, options?: { ruleId?: string; }): PluginDisposable

Conversations 1.6: serial reaction deliveries, with an optional stable rule ID.

ctx.domains.conversations.events.subscribe
<K>(event: K, handler: (event: PluginDomainEvent<K>) => unknown, options?: { ignoreSelf?: boolean; ruleId?: string; }): PluginDisposable
ctx.domains.conversations.queries.getBookThread
(bookId: string): Promise<ChatMessageSummary[]>
ctx.domains.conversations.queries.getInsights
(target: ConversationTarget): Promise<string | null>

Conversations 1.4: stored rolling summary of a book/global thread, or null. No generation, freshness guarantee, raw runtime state or summary writes.

ctx.domains.conversations.queries.getThread
(threadId: string): Promise<ChatMessageSummary[]>
ctx.domains.conversations.queries.listThreads
(): Promise<ThreadSummary[]>
ctx.domains.conversations.queries.runtime
(): Promise<PluginConversationRuntimeSnapshot>
ctx.domains.conversations.queries.turnRequests
(): Promise<ConversationTurnRequestSnapshot[]>

Up to 128 recently retained host requests, filtered to this actor; no text or other actors' requests.

domains:settings

探索精确设置路径与选项、读取稳定快照、观察变更并更新支持的目标。

  • 开发版:v1.11.0
  • ReadAware 0.6.8:v1.11.0
  • 授权: 无
ctx.domains.settings.commands.refreshModelCatalog
(provider: string, options?: PluginCallOptions): Promise<ModelCatalogPage>

Settings 1.9: additionally requires service:network. Shared native refresh, not a connection test.

ctx.domains.settings.commands.resetReading
(request: ReadingSettingsReset): Promise<SettingsUpdateResult>

Settings 1.7: reset the whole reader-preference bundle; every reading path must be writable. defaults restores built-ins; inherit deletes active and remembered book overrides.

ctx.domains.settings.commands.update
(changes: SettingChange[]): Promise<SettingsUpdateResult>
ctx.domains.settings.events.subscribe
(handler: (event: SettingsChangedEvent & PluginReactionEvent) => unknown, options?: { ignoreSelf?: boolean; ruleId?: string; }): PluginDisposable
ctx.domains.settings.queries.discover
(query?: SettingsQuery): Promise<SettingCatalogEntry[]>
ctx.domains.settings.queries.modelCatalog
(query: ModelCatalogQuery): Promise<ModelCatalogPage>

Settings 1.9: cached public model metadata; discover access to primaryModel or fastModel. No network.

ctx.domains.settings.queries.observe
(query: SettingsQuery, handler: PluginObservationHandler<SettingsObservation>): PluginDisposable

Settled snapshots after native, domain, remote, restore and catalog changes. Coalesces slow callbacks.

ctx.domains.settings.queries.options
(query: SettingsOptionsQuery): Promise<SettingsOptionsPage>

Settings 1.8: bounded options; same path grants as discover. Includes installed system families for reading/content fonts without font paths or bytes. Since 1.10, dynamicOptions fields invoke the registered owning provider with saved non-secret form values, never caller-supplied values. Network-enabled providers additionally require this caller's service:network permission. Results are cached for 60 seconds, at most 16 lists / 2000 options per list, 512 characters per label/value and 1 MiB of label/value JSON. Pages retain the returned revision; changed settings/provider or expiry require restart. Four provider loads host-wide, 10-second wait; already-started provider work is not cancelled by this deadline or caller retirement. No writes/synthesis. Plugin-owned option queries require the caller's active phase, not activation/migration. Empty results still allow manual values; provider failures remain failures.

ctx.domains.settings.queries.read
(path: string, target?: SettingsQueryTarget): Promise<SettingReadResult>
ctx.domains.settings.queries.snapshot
(query?: SettingsQuery): Promise<SettingsSnapshot>

Since settings 1.3: one host snapshot after prior queued writes settle, filtered by exact path grants.

domains:memory

搜索、分页、查看与修正记忆;处理个人数据、实体、分类、图谱与版本化上下文包。

  • 开发版:v2.8.0
  • ReadAware 0.6.8:v2.8.0
  • 授权: memory:read / memory:write
ctx.domains.memory.commands.cancelGraphTask
(bookId: string, taskId: string): Promise<BookGraphTaskSnapshot>
ctx.domains.memory.commands.classify
(input: BookClassificationChange): Promise<BookClassificationReceipt>
ctx.domains.memory.commands.completeOnboarding
(input: OnboardingChange, options?: PluginCallOptions): Promise<OnboardingReceipt>

Memory 2.5: confirm the full summary AND seeds before calling. Reuse the same owner-local submissionId and exact candidate after a lost receipt; a different candidate requires a new id and renewed confirmation. Atomic, event-backed.

ctx.domains.memory.commands.context.capture
(selector: ContextBundleSelector, options?: PluginCallOptions): Promise<ContextBundleCaptureReceipt>
ctx.domains.memory.commands.decideEntity
(input: EntityDecision, options?: PluginCallOptions): Promise<EntityDecisionReceipt>

Memory 2.1: resolve an original member or merge known resolved classes using an observed entities1 revision. Present the exact change for confirmation first. Retains original definitions/aliases, may sync to other devices. No blind conflict retry. Cancellation prevents dispatch only; dispatched writes drain to their actual receipt. A transport timeout or lost Worker leaves the outcome unknown: reread, never retry blindly.

ctx.domains.memory.commands.mutate
(input: MemoryMutation): Promise<MemoryMutationReceipt>
ctx.domains.memory.commands.retryGraphTask
(bookId: string, taskId: string, options?: BookGraphTaskOptions): Promise<BookGraphTaskSnapshot>
ctx.domains.memory.commands.startGraphTask
(bookId: string, mode: "catch-up" | "rebuild", options?: BookGraphTaskOptions): Promise<BookGraphTaskSnapshot>
ctx.domains.memory.commands.updateProfile
(input: UserProfileChange): Promise<UserProfileReceipt>

Replace the event-backed summary using the observed profile2 revision. Present the complete candidate for user confirmation before calling. Empty text clears the summary, not memories or historical copies.

ctx.domains.memory.events.observe
(query: MemoryObservationQuery, handler: PluginObservationHandler<MemoryObservation>): PluginDisposable

Initial snapshot, then changed results/errors; bounded polling, not an event log. Plugins 1.5 supplies a separate reaction delivery, including graph task updates.

ctx.domains.memory.queries.bookGraph
(bookId: string, query?: BookGraphQuery): Promise<BookGraphResult>

memory >=2.6 only exposes current-source digests; chapter results carry contentVersion for navigation.

ctx.domains.memory.queries.classification
(bookId: string): Promise<BookClassificationSnapshot | null>
ctx.domains.memory.queries.context.export
(query: ContextBundleReadQuery, options?: PluginCallOptions): Promise<ResourceRef>
ctx.domains.memory.queries.context.history
(query: ContextBundleHistoryQuery, options?: PluginCallOptions): Promise<ContextBundleHistoryPage>
ctx.domains.memory.queries.context.read
(query: ContextBundleReadQuery, options?: PluginCallOptions): Promise<ContextBundle | null>
ctx.domains.memory.queries.entities
(query?: EntityQuery, options?: PluginCallOptions): Promise<EntityPage>

Global explicit identities, not book-digest characters. Row-bounded, revision-pinned pages. Memory 2.2 adds canonicalDefinition from the same snapshot. Historical field sizes are not bounded. Aborted/retired callers receive no late page.

ctx.domains.memory.queries.getGraphTask
(bookId: string, taskId: string): Promise<BookGraphTaskSnapshot>
ctx.domains.memory.queries.inspect
(id: string): Promise<MemorySnapshot | null>
ctx.domains.memory.queries.listGraphTasks
(bookId: string): Promise<BookGraphTaskSnapshot[]>
ctx.domains.memory.queries.page
(input: MemoryPageQuery): Promise<MemoryPage>
ctx.domains.memory.queries.profile
(query?: UserProfileQuery): Promise<UserProfilePage>

The event-backed summary projection; read grant, bounded revision-pinned pages.

ctx.domains.memory.queries.profileContext
(query?: ProfileInspectionQuery, options?: PluginCallOptions): Promise<ProfileInspectionPage>

Memory 2.3: inspect the generated summary and provenance, separately from curated profile(). Summary pages count UTF-16 units (4000 default, 16000 max); provenance pages count rows (25 default, 100 max; historical ID sizes are unbounded). Pin every page kind to pctx1. Stale text is inspectable, never current context. Invalid blocks expose no content. Current means source-consistent, not semantic verification or completed consolidation. entityEvidence IDs include proposed no-ops, not proof of emitted events. Read grant; no source text, transcripts, raw traits, registry writes or automatic inference.

ctx.domains.memory.queries.search
(input: MemoryQuery): Promise<MemoryRecord[]>

贡献

contributions:uriHandlers

透过已注册的动作处理具命名空间的 ReadAware URI 调用。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.uriHandlers.register
(handler: PluginUriHandler): PluginActionRegistration

contributions:selectionActions

为撷取的选取内容、标注或导航器输入加入动作。

  • 开发版:v1.2.0
  • ReadAware 0.6.8:v1.2.0
  • 授权: 无
ctx.contributions.selectionActions.register
(action: PluginSelectionAction): PluginActionRegistration

contributions:headerActions

使用宿主渲染查看加入阅读器、书库或代理程式标题列动作。

  • 开发版:v1.2.0
  • ReadAware 0.6.8:v1.2.0
  • 授权: 无
ctx.contributions.headerActions.register
(action: PluginHeaderAction): PluginActionRegistration

contributions:contextActions

为支持的书籍或集合上下文界面加入具类型的动作。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.contextActions.register
(action: PluginContextAction): PluginActionRegistration

contributions:commands

加入具命名空间的命令面板动作并更新其拥有的状态。

  • 开发版:v1.1.0
  • ReadAware 0.6.8:v1.1.0
  • 授权: 无
ctx.contributions.commands.register
(command: PluginCommand): PluginActionRegistration

contributions:settingsOptions

为已声明的插件设置解析动态选项。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.settingsOptions.register
(fieldId: string, provider: (values: PluginFormValues) => PluginSelectOption[] | Promise<PluginSelectOption[]>): PluginDisposable

contributions:settingsPage

注册一个声明式页面,用于在插件自身的“设置”区域中替代其清单设置表单。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.settingsPage.register
(page: { view(): PluginView | Promise<PluginView>; }): PluginDisposable

contributions:voiceProviders

提供朗读用的语音选项与编码音讯。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.voiceProviders.register
(provider: PluginVoiceProvider): PluginDisposable

contributions:contentProviders

为存储的来源等虚拟书籍提供章节。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.contributions.contentProviders.register
(provider: { id: string; load(key: string): Promise<PluginBookContent>; }): PluginDisposable

contributions:agentTools

注册阅读助理可以探索与调用的具命名空间工具。

  • 开发版:v1.3.0
  • ReadAware 0.6.8:v1.3.0
  • 授权: agent:tools
ctx.contributions.agentTools.register
(tool: PluginToolDefinition): PluginActionRegistration

contributions:agentContextProviders

提供受限的每轮参考区块与声明的阅读意图来源。

  • 开发版:v1.1.0
  • ReadAware 0.6.8:v1.1.0
  • 授权: agent:context
ctx.contributions.agentContextProviders.register
(provider: PluginAgentContextProvider): PluginDisposable

contributions:agentRetrievalProviders

向助理公开可搜索的插件拥有来源。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: agent:retrieval
ctx.contributions.agentRetrievalProviders.register
(provider: PluginAgentRetrievalProvider): PluginDisposable

contributions:memoryCandidateProviders

提出供记忆接纳的事实、偏好、洞察或摘要。

  • 开发版:v1.1.0
  • ReadAware 0.6.8:v1.1.0
  • 授权: agent:memory
ctx.contributions.memoryCandidateProviders.register
(provider: PluginMemoryCandidateProvider): PluginDisposable

contributions:themes

在 manifest 中声明语义化应用与阅读器主题选项。

  • 开发版:v1.2.0
  • ReadAware 0.6.8:v1.2.0
  • 授权: ui:themes
ctx.contributions.themes.readerBases
(): Promise<PluginReaderThemeBase[]>

Themes 1.2: built-in and active plugin reader bases, excluding image themes. Saved copies do not change when the original theme changes.

ctx.contributions.themes.register
(theme: PluginRuntimeTheme): Promise<PluginDisposable>

contributions:fonts

声明字体中继数据与封装的字体资产。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: ui:themes

Manifest 声明

contributions:syncTransports

在外部远端存储与取回不透明的加密事件、blob 与金钥材料中继物件。

  • 开发版:v2.0.0
  • ReadAware 0.6.8:v2.0.0
  • 授权: sync:transport
ctx.contributions.syncTransports.register
(transport: PluginSyncTransport): PluginDisposable

服务

services:storage

使用私有 KV 与文件集合、页面、观察、条件式提交及配额政策。

  • 开发版:v2.6.0
  • ReadAware 0.6.8:v2.6.0
  • 授权: 无
ctx.services.storage.applyDocuments
(changes: PluginDocumentChange[]): Promise<PluginDocumentCommit>

Storage 2.1: atomically compare and apply 1..100 private document changes. Every expected revision is checked before any write. Does not include KV, core domain events, files, or another plugin's documents.

ctx.services.storage.collection
(name: string): PluginDocumentCollection

A named document collection — structured plugin-private data one tier above the KV (queryable, per-document, optionally book-anchored). Backed by the app's local store; lifecycle belongs to the plugin (uninstall clears it). bookId/anchor are provenance INDEXES, not ownership — documents survive the referenced book's deletion.

ctx.services.storage.documents(collection).delete
(id: string): Promise<void>
ctx.services.storage.documents(collection).get
<T>(id: string): Promise<PluginDocument<T> | null>
ctx.services.storage.documents(collection).list
<T>(filter?: { bookId?: string; limit?: number; oldestFirst?: boolean; }): Promise<PluginDocument<T>[]>

Newest-first by default.

ctx.services.storage.documents(collection).page
<T>(filter?: PluginDocumentPageFilter): Promise<PluginDocumentPage<T>>

Storage 2.1: 1..200 rows (default 50), 4 MiB JSON per page. Cursors bind namespace/filter/order and expire on any collection write. On stale-cursor restart rather than combining different snapshots.

ctx.services.storage.documents(collection).put
(id: string, data: unknown, options?: { bookId?: string; anchor?: string; }): Promise<void>
ctx.services.storage.flush
(): Promise<void>

Wait for outstanding writes in this plugin's namespace.

ctx.services.storage.get
<T>(key: string): T | null
ctx.services.storage.getDurable
<T>(key: string): Promise<T | null>

2.4: keys up to 1024 UTF-16 units, no NUL. Settle accepted writes, then read this private key from SQLite, not the optimistic mirror. Corrupt JSON rejects; null means absent or JSON null.

ctx.services.storage.observeDocuments
<T>(query: PluginDocumentObservationQuery, handler: PluginObservationHandler<PluginDocumentObservation<T>>): PluginDisposable

Storage 2.2: initial and changed private document query snapshots, including errors/recovery. At most 64 active observers per activation; reads and callbacks settle before the next one-second poll. Not a replayable write stream. Dispose or plugin retirement stops delivery; sequence is not CAS.

ctx.services.storage.onChange
(handler: PluginObservationHandler<{ kind: "changed"; }>, options?: { ruleId?: string; }): PluginDisposable

Fires when this plugin's namespace is written from OUTSIDE the plugin — its settings page, the reading agent, another surface editing the same object. Settings-key changes can also echo after own writes. Serial callbacks receive a reaction credential; use withEvent to preserve causes. No initial callback; intermediate changes coalesce. Use it to re-read (or re-derive from) settings you would otherwise have cached at activate().

ctx.services.storage.policy
(): Promise<PluginStoragePolicy>

Storage 2.5: own persisted usage and actual per-store policy. Null quota means no enforced total limit, not unlimited disk. Call flush first when awaiting this activation's pending writes. No names or secret values. Complete backup refers to full app backup, not reading/OPML exports.

ctx.services.storage.remove
(key: string): Promise<void>
ctx.services.storage.set
(key: string, value: unknown): Promise<void>

Reads update optimistically; resolve only after the write is durable.

services:secrets

在插件私有加密槽中读写凭据。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.services.secrets.get
(key: string): Promise<string | null>
ctx.services.secrets.remove
(key: string): Promise<void>
ctx.services.secrets.set
(key: string, value: string): Promise<void>

services:ui

发布查看、显示提示、存储或开启资源、导航工作区与命令,并控制支持的阅读器面板与窗口。

  • 开发版:v1.17.0
  • ReadAware 0.6.8:v1.17.0
  • 授权: 无
ctx.services.ui.commands.execute
(request: HostCommandRequest): Promise<HostCommandReceipt>

Library write plus each command's setting grant; opening/leaving a reader needs reading:write.

ctx.services.ui.commands.list
(): Promise<HostCommandSnapshot>
ctx.services.ui.commands.observe
(handler: PluginObservationHandler<HostCommandObservation>, options?: { ruleId?: string; }): PluginDisposable

UI 1.16: serial/coalesced snapshots with a reaction delivery and optional stable ruleId.

ctx.services.ui.exportFile
(file: PluginExportFile): Promise<boolean>
ctx.services.ui.openExternal
(url: string): Promise<void>

UI 1.7, requires service:network. Explicit user intent only; HTTP(S), no credentials or local schemes.

ctx.services.ui.publishView
(channel: PluginViewChannel, update: PluginViewUpdate): Promise<PluginViewUpdateReceipt>

Updates only this activation's visible frame. Revision is a nonnegative, increasing safe integer. Receipt confirms host acceptance, not paint; updates cannot navigate or replace the subscription.

ctx.services.ui.reader.closeReferencePreview
(id: string): Promise<ReaderReferenceCloseReceipt>

Only this activation's current preview ID; never closes a native or other owner's note.

ctx.services.ui.reader.focus
(target: ReaderFocusTarget, guard?: ReadingSessionGuard): Promise<ReaderFocusReceipt>

UI 1.14, reading:write. Focus an already visible semantic target, without opening or dismissing UI. not-focused is not success; close your own dialog before returning focus.

ctx.services.ui.reader.image.control
(request: ReaderImageRequest): Promise<ReaderImageReceipt>

reading:write; exact current viewer ID required. Pan deltas are fractions of its viewport.

ctx.services.ui.reader.image.observe
(handler: PluginObservationHandler<ReaderImageSnapshot | null>): PluginDisposable

Plugins 1.6 supplies a separate reaction delivery, including closed/null snapshots.

ctx.services.ui.reader.image.open
(query: BookImageQuery, guard?: ReadingSessionGuard): Promise<ReaderImageOpenReceipt>

UI 1.13: library read + reading write; opens an embedded image in the current book.

ctx.services.ui.reader.image.snapshot
(): Promise<ReaderImageSnapshot | null>
ctx.services.ui.reader.observe
(handler: PluginObservationHandler<ReaderPanelsSnapshot | null>): PluginDisposable

Plugins 1.6 supplies a separate reaction delivery; callbacks are serial and coalesced.

ctx.services.ui.reader.previewReference
(query: BookReferenceQuery, guard?: ReadingSessionGuard): Promise<ReaderReferencePreviewReceipt>

UI 1.8: also needs library:read. Open book only; resolved preview waits for DOM commit.

ctx.services.ui.reader.setPanel
(panel: ReaderPanel, open: boolean, guard?: ReadingSessionGuard): Promise<ReaderPanelReceipt>

Requires reading:write. Opening reveals controls; completion waits for persistence and DOM commit.

ctx.services.ui.reader.setWidth
(panel: ResizableReaderPanel, width: number, guard?: ReadingSessionGuard): Promise<ReaderPanelReceipt>

Persist a shared TOC/chat width (integer 240..640 CSS px); does not open it or focus.

ctx.services.ui.reader.snapshot
(): Promise<ReaderPanelsSnapshot | null>
ctx.services.ui.showToast
(message: PluginToast): void
ctx.services.ui.window.control
(request: HostWindowRequest): Promise<HostWindowReceipt>
ctx.services.ui.window.observe
(handler: PluginObservationHandler<HostWindowObservation>, options?: { ruleId?: string; }): PluginDisposable

UI 1.17: reaction delivery remains valid until the callback settles.

ctx.services.ui.window.snapshot
(): Promise<HostWindowSnapshot>
ctx.services.ui.workspace.navigate
(target: WorkspaceTarget, expectedRevision?: number): Promise<WorkspaceReceipt>

Library write grant; leaving an active reader additionally requires reading:write.

ctx.services.ui.workspace.observe
(query: WorkspaceQuery, handler: PluginObservationHandler<WorkspaceSnapshot | null>, options?: { ruleId?: string; }): PluginDisposable

UI 1.16: use the separate reaction delivery even for null/retired snapshots.

ctx.services.ui.workspace.snapshot
(query?: WorkspaceQuery): Promise<WorkspaceSnapshot>

services:schedules

系结声明的周期处理常式、查看与控制调度,并管理拥有的延迟请求。

  • 开发版:v2.1.0
  • ReadAware 0.6.8:v2.1.0
  • 授权: 无
ctx.services.schedules.bind
(scheduleId: string, run: (context: PluginScheduleRun, delivery?: PluginReactionEvent) => void | Promise<void>): PluginDisposable
ctx.services.schedules.cancelDeferred
(id: string, requestId: string, options?: PluginCallOptions): Promise<PluginDeferredReceipt>

Cancel exactly the queued ID, not an in-flight callback or a replacement request.

ctx.services.schedules.control
(id: string, action: "pause" | "resume" | "run"): Promise<PluginScheduleReceipt>

Pause/resume persist; run bypasses pause/cadence once. Neither pause nor cancellation undoes dispatched callback effects.

ctx.services.schedules.defer
(id: string, input: PluginDeferredRequest, options?: PluginCallOptions): Promise<PluginDeferredReceipt>

Schedules 2: enqueue one declared deferred task. Persists before acknowledgement. 1 second..7 days; idle means 5 seconds without host input. Never runs while closed. The most recent request ID is retained for retry; changed input conflicts, another queued ID is busy. A dispatched request is never automatically replayed after a crash. Inspect interrupted and decide explicitly.

ctx.services.schedules.list
(query?: Omit<PluginScheduleQuery, "pluginId">): Promise<PluginSchedulePage>

Bound schedules owned by this plugin only, with the latest persisted attempt/outcome.

ctx.services.schedules.observe
(query: Omit<PluginScheduleQuery, "pluginId">, handler: PluginObservationHandler<PluginSchedulePage>, options?: { ruleId?: string; }): PluginDisposable

services:jobs

启动、查看与控制由支持宿主操作组成的持久计划。

  • 开发版:v1.1.0
  • ReadAware 0.6.8:v1.1.0
  • 授权: 无
ctx.services.jobs.control
(id: string, action: DurableJobControl, options?: PluginCallOptions): Promise<DurableJobSnapshot>
ctx.services.jobs.get
(id: string, options?: PluginCallOptions): Promise<DurableJobSnapshot>
ctx.services.jobs.list
(query?: { offset?: number; limit?: number; }, options?: PluginCallOptions): Promise<{ jobs: DurableJobSnapshot[]; nextOffset: number | null; }>
ctx.services.jobs.start
(plan: DurableJobPlan, options?: PluginCallOptions): Promise<DurableJobSnapshot>

jobs 1.1: event-bound starts preserve their source through restart. Every causal event subscription must have a stable ruleId. Unnamed reactions and isolated service invocations cannot create saved jobs.

services:changes

开启并读取可跨重新启动持久保存的范围变更游标。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.services.changes.open
(query: ChangesQuery, options?: PluginCallOptions): Promise<{ cursor: string; }>

Open before loading a baseline. Persist the returned cursor only after processing each page. Expired cursors require a new baseline. Notices are conservative reload hints, not events or values; settings hints cover the authorized requested paths in a shared storage namespace.

ctx.services.changes.read
(query: ChangesQuery, cursor: string, limit?: number, options?: PluginCallOptions): Promise<ChangesPage>

services:transactions

预览并提交支持的本地变更、查看回执与预览条件式复原。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.services.transactions.commit
(previewId: string, options?: PluginCallOptions): Promise<AtomicReceipt>
ctx.services.transactions.preview
(operations: AtomicOperation[], options?: PluginCallOptions): Promise<AtomicPreview>
ctx.services.transactions.previewUndo
(receiptId: string, options?: PluginCallOptions): Promise<AtomicPreview>
ctx.services.transactions.receipt
(receiptId: string, options?: PluginCallOptions): Promise<AtomicReceipt | null>

services:session

读取环境中继数据并检查支持操作的可用性。

  • 开发版:v2.18.0
  • ReadAware 0.6.8:v2.18.0
  • 授权: 无
ctx.services.session.environment
(): Promise<HostEnvironmentSnapshot>

Fresh non-sensitive metadata; contains no reading or account state.

ctx.services.session.observeEnvironment
(handler: (snapshot: HostEnvironmentSnapshot, delivery?: PluginReactionEvent) => void | Promise<void>, options?: { ruleId?: string; }): PluginDisposable

Session 2.7: locale effects retain their requester; other system facts keep independent sources.

ctx.services.session.operationAvailability
(query: OperationAvailabilityQuery, options?: PluginCallOptions): Promise<OperationAvailability>

Session 2.11: inspect host command permissions/workspace guards and plugin service contract/authority/capacity (Agent approval remains required), export metadata/save entry and clipboard/browser entry availability (no OS access probe), window support/capacity/target state, sync connection/credentials/provider, inference, book-targeted playback/mode, text preparation and graph prerequisites without executing or probing. Missing permission returns only the permission condition. Unknown remote health is not a local refusal or a success guarantee.

services:plugins

查看已安装插件与注册项、观察变更,以及探索或调用具类型的插件服务。

  • 开发版:v1.10.0
  • ReadAware 0.6.8:v1.10.0
  • 授权: 无
ctx.services.plugins.callService
(request: PluginServiceCall, options?: PluginCallOptions): Promise<PluginServiceReceipt>

Executes one declared export in a fresh restricted Worker. No live-root closures, callbacks, binary handles, automatic retries, or resources surviving the call.

ctx.services.plugins.contributions
(query?: PluginContributionQuery): Promise<PluginContributionPage>

Registered identities across extension points, never provider callbacks, data, settings or a grant to invoke another plugin. Offset pages may change.

ctx.services.plugins.list
(query?: PluginDirectoryQuery): Promise<PluginDirectoryPage>

Public installed metadata only, no settings, paths, secrets or raw errors.

ctx.services.plugins.listServices
(query?: PluginServiceQuery, options?: PluginCallOptions): Promise<PluginServicePage>

Plugins 1.8: authorized service contracts; discovery does not execute providers.

ctx.services.plugins.observe
(query: PluginDirectoryQuery, handler: PluginObservationHandler<PluginDirectoryPage>, options?: { ruleId?: string; }): PluginDisposable

Plugins 1.10: serial reaction deliveries with stable rule IDs; reload offset pages after changes.

ctx.services.plugins.observeContributions
(query: PluginContributionQuery, handler: PluginObservationHandler<PluginContributionPage>, options?: { ruleId?: string; }): PluginDisposable

services:maintenance

查看维护状态并进入宿主拥有的备份、连线测试、更新或设置流程。

  • 开发版:v1.5.0
  • ReadAware 0.6.8:v1.5.0
  • 授权: 无
ctx.services.maintenance.checkForUpdates
(): Promise<HostMaintenanceSnapshot>

Requires service:network. Uses the host release feed; no caller-supplied URL or silent installation.

ctx.services.maintenance.observe
(handler: PluginObservationHandler<HostMaintenanceSnapshot>, options?: { ruleId?: string; }): PluginDisposable
ctx.services.maintenance.openSettings
(surface: "updates" | "diagnostics" | "plugins" | "backup-import" | "backup-export" | "delete-data" | "ai-connection" | "data-location"): Promise<{ status: "opened"; surface: HostMaintenanceSurface; }>

Maintenance 1.4 adds data-location: shows the directory in host UI, never returns its path or opens the file manager. Also reveals updates/diagnostics/plugins/backup-import/backup-export/delete-data/ai-connection. Does not click controls, open file dialogs, approve installation or bypass typed DELETE.

ctx.services.maintenance.requestBackup
(action: BackupAction, options?: PluginCallOptions): Promise<BackupReceipt>

Reveals a host backup button and awaits the user's click and file dialog. Both directions use the complete encrypted archive (host-only password); import adds host review and confirmation, then reload. Retired v1 JSON library backups are rejected. No passwords, bytes or paths are returned.

ctx.services.maintenance.requestConnectionTest
(options?: PluginCallOptions): Promise<ConnectionTestReceipt>

Maintenance 1.3: reveal native AI test controls; only the user's click starts inference.

ctx.services.maintenance.snapshot
(): Promise<HostMaintenanceSnapshot>

services:diagnostics

要求支持的诊断汇出或回报流程。

  • 开发版:v1.2.0
  • ReadAware 0.6.8:v1.2.0
  • 授权: service:diagnostics
ctx.services.diagnostics.requestProjectionRepair
(options?: PluginCallOptions): Promise<ProjectionRepairReceipt>

Diagnostics 1.2: opens host confirmation; a committed repair requires reload.

ctx.services.diagnostics.requestReport
(action: DiagnosticsReportAction, options?: PluginCallOptions): Promise<DiagnosticsReportReceipt>
ctx.services.diagnostics.verifyProjections
(options?: PluginCallOptions): Promise<ProjectionVerification>

services:logging

写入受限的结构化开发者事件并查看记录政策。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无
ctx.services.logging.policy
(): Promise<{ levels: PluginLogEntry["level"][]; maxEntryChars: number; maxFields: number; perPluginLimit: number; appLimit: number; windowMs: number; delivery: "best-effort"; }>
ctx.services.logging.write
(entry: PluginLogEntry): Promise<PluginLogReceipt>

Logging 1.0: accepted means forwarded to the best-effort host logger, not durably stored or uploaded. Allowed during activation and migration. Debug is development-console-only. Retired activations cannot write.

services:resources

选取文件与目录、读取或建立封装资源、汇出数据并存储私有二进位资产。

  • 开发版:v1.6.0
  • ReadAware 0.6.8:v1.6.0
  • 授权: 无
ctx.services.resources.append
(id: string, offset: number, data: ArrayBuffer | Uint8Array<ArrayBufferLike>): Promise<ResourceRef>
ctx.services.resources.assets.delete
(key: string, expectedRevision: string, options?: PluginCallOptions): Promise<{ deleted: true; cleanupPending: boolean; }>
ctx.services.resources.assets.get
(key: string, options?: PluginCallOptions): Promise<PluginAsset | null>
ctx.services.resources.assets.list
(query?: PluginAssetQuery, options?: PluginCallOptions): Promise<PluginAssetPage>
ctx.services.resources.assets.open
(key: string, expectedRevision: string, options?: PluginCallOptions): Promise<ResourceRef>
ctx.services.resources.assets.policy
(options?: PluginCallOptions): Promise<PluginAssetPolicy>
ctx.services.resources.assets.store
(resourceId: string, input: PluginAssetWrite, options?: PluginCallOptions): Promise<PluginAssetReceipt>
ctx.services.resources.commit
(id: string): Promise<ResourceRef>
ctx.services.resources.create
(options: ResourceCreateOptions): Promise<ResourceRef>
ctx.services.resources.listDirectory
(id: string, query?: ResourceDirectoryQuery): Promise<ResourceDirectoryPage>
ctx.services.resources.openAssociated
(id: string, options?: PluginCallOptions): Promise<{ opened: boolean; }>

Resources 1.5: host confirmation then OS association for a temporary document/media copy. No edit-back, arbitrary program/path, or context bundles. True is dispatch, not rendering.

ctx.services.resources.openBook
(bookId: string): Promise<ResourceRef | null>

Requires library:read. Original local file only; no implicit remote download.

ctx.services.resources.openCover
(bookId: string): Promise<ResourceRef | null>

Resources 1.1; requires library:read. No extraction/download when the cover is unavailable.

ctx.services.resources.openDirectoryFile
(id: string, relativePath: string): Promise<ResourceRef>
ctx.services.resources.pick
(options?: ResourcePickOptions): Promise<{ cancelled: boolean; resources: ResourceRef[]; }>
ctx.services.resources.pickDirectory
(): Promise<{ cancelled: boolean; directory: ResourceDirectoryRef | null; }>

Resources 1.4: reader-selected, read-only directory grants; four per activation, one hour. No ambient paths. Listings are live; openDirectoryFile seals the current file bytes.

ctx.services.resources.read
(id: string, offset: number, length: number): Promise<ResourceChunk>
ctx.services.resources.release
(id: string): Promise<void>

Also aborts uncommitted writes.

ctx.services.resources.releaseDirectory
(id: string): Promise<void>
ctx.services.resources.save
(id: string, filename?: string): Promise<{ saved: boolean; }>
ctx.services.resources.stat
(id: string): Promise<ResourceRef>

services:sync

观察同步状态与待处理伫列、要求同步并进入宿主管理的帐号或连线流程。

  • 开发版:v1.2.0
  • ReadAware 0.6.8:v1.2.0
  • 授权: service:sync
ctx.services.sync.account
(): Promise<HostSyncAccount | null>

Explicit remote read of the account's tier, usage and limits; null without an account. No email, account ID, keys, session or billing ticket.

ctx.services.sync.backlog
(): Promise<{ events: number; blobs: number; }>

Events and blobs waiting to be pushed.

ctx.services.sync.connectionOptions
(): Promise<{ ref: string; label: string; }[]>

Registered backend references and display labels, never endpoint credentials.

ctx.services.sync.observe
(handler: PluginObservationHandler<HostSyncSnapshot>, options?: { ruleId?: string; }): PluginDisposable

Delivers each new sync snapshot (state, progress, completed cycles) while the handle lives.

ctx.services.sync.openSettings
(): Promise<{ status: "opened"; surface: "dataSync"; }>

Opens the host Data & Sync page; not a login, disconnect or purchase.

ctx.services.sync.requestFlow
(request: HostSyncFlowRequest, options?: PluginCallOptions): Promise<HostSyncFlowReceipt>

Host-owned connect, disconnect, account deletion, upgrade or billing flow. Waits for the final local outcome or external handoff; cancellation cannot undo a started operation.

ctx.services.sync.requestSync
(): Promise<HostSyncReceipt>

Runs one sync round on the configured backend (relay or a transport plugin such as WebDAV) and resolves when it has finished: completed, or already-running when a round was in progress (not queued again). Rejects with a coded error when no round can start (ui/unavailable) or the round fails (classified failures carry sync/* codes).

ctx.services.sync.snapshot
(): Promise<HostSyncSnapshot>

Current sync state: backend, connection, progress, last cycle and last error code.

services:network

发出具来源范围的 HTTP 请求或读取受限串流,并选用安全重试。

  • 开发版:v2.2.0
  • ReadAware 0.6.8:v2.2.0
  • 授权: service:network
ctx.services.network.closeStream
(id: string): Promise<void>

Idempotent for this activation's released/unknown IDs. Aborts pending reads; does not undo remote effects or remove data already saved by the plugin.

ctx.services.network.fetch
(input: string | URL | Request, init?: RequestInit, options?: { retry?: "none" | "safe"; }): Promise<Response>

Native HTTP; Request/init semantics and cancellation survive the Worker bridge. Bodies are buffered up to 64 MiB per direction. Calls have a 120s deadline; an abort does not undo a remote side effect already committed by the server. Network 2.0 requires networkAccess for the initial URL and each redirect. HTTPS -> HTTP redirects are denied. At most 10 redirects; manual returns the 3xx response, error rejects. Cross-origin hops drop authorization, proxy-authorization, cookie and referer; custom secret headers are the plugin's responsibility (use redirect:error for authenticated endpoints). Host/content-length are transport-owned. No implicit retry or cookie jar. Network 2.2: options.retry="safe" opts GET/HEAD without a body into at most two retries across the whole redirect chain, before response headers are returned. Other methods and all body reads are never replayed. The original deadline includes backoff; Retry-After above 30s returns the HTTP response. Attempts/uploads/read chunks share per-owner and host cumulative quotas; reactivation does not reset owner debt. policy() reports exact limits. Transport failures carry plugin/network-failed; explicit deadlines carry plugin/network-timeout, aborts plugin/cancelled. Existing structured codes survive unchanged. Unclassified native errors are not guessed from prose. HTTP error statuses still return Response; the consumer decides success.

ctx.services.network.openStream
(input: string | URL | Request, init?: RequestInit, options?: { retry?: "none" | "safe"; }): Promise<PluginNetworkStream>

Network 2.1: headers first; download at most 1 GiB without buffering the whole response. Uploads remain capped at 64 MiB. 8 active requests per activation / 32 host-wide, shared with fetch; no hidden durable queue. Optional safe retry applies only before this opening receipt, as in fetch. init.signal cancels OPENING only; after receipt use closeStream to cancel. Close in finally if not reading to EOF. 120s absolute lifetime, including headers/redirects/reads; unload cancels and drains native resources.

ctx.services.network.policy
(): Promise<PluginNetworkAccess & { maxRedirects: number; maxBodyBytes: number; timeoutMs: number; maxStreamBytes: number; maxChunkBytes: number; maxConcurrentRequests: number; maxHostConcurrentRequests: number; cumulative: { windowMs: number; maxOwnerRequests: number; maxHostRequests: number; maxOwnerBytes: number; maxHostBytes: number; maxOwners: number; }; retry: { maxRetries: number; baseDelayMs: number; maxDelayMs: number; statuses: readonly number[]; }; }>

Network 2.0: this activation's immutable authorization and transport limits. All-origins authorization is ["*"], not a guarantee of endpoint reachability.

ctx.services.network.readStream
(id: string, offset: number, maxBytes?: number): Promise<PluginNetworkChunk>

Sequential, non-replayable reads. offset must equal bytes already delivered. One outstanding read per stream; maxBytes defaults to 64 KiB, max 1 MiB. A lost read receipt is not safely retryable: close and restart explicitly.

services:llm

要求文字、结构化或串流推论、使用封装图片资源,并追踪请求中继数据与预算。

  • 开发版:v1.6.0
  • ReadAware 0.6.8:v1.6.0
  • 授权: service:llm
ctx.services.llm.ask
(input: PluginInferenceInput & { schema?: never; onText?: (delta: string) => void; }): Promise<string>
(input: PluginInferenceInput & { schema: Record<string, unknown>; onText?: never; }): Promise<unknown>
ctx.services.llm.askDetailed
(input: PluginInferenceInput & { schema?: never; onText?: (delta: string) => void; }): Promise<InferenceResult<string>>
(input: PluginInferenceInput & { schema: Record<string, unknown>; onText?: never; }): Promise<InferenceResult<unknown>>

llm 1.3: same execution as ask, with per-attempt metadata on success. Includes structured retries; failure/cancellation rejects, not a billing receipt.

ctx.services.llm.cancelRequest
(requestId: string): Promise<InferenceRequestReceipt | null>

Requests cancellation independently of the ask RPC. The returned snapshot may still be running; query again for its outcome and provider settlement.

ctx.services.llm.getRequest
(requestId: string): Promise<InferenceRequestReceipt | null>

llm 1.6: last 64 named requests in this plugin's local private storage. Initial metadata commits before inference dispatch; no prompt/output is retained. Includes backup/rollback and uninstall cleanup, not roaming or billing history. requestAvailable identifies this activation's handle. An older unsettled record has interrupted=true: status is last observed, not proof it still runs remotely. No automatic retry/resume; historical IDs cannot control another activation. Late terminal usage is persisted; unknown/evicted IDs return null.

ctx.services.llm.listRequests
(): Promise<InferenceRequestReceipt[]>
ctx.services.llm.policy
(): Promise<{ defaultTimeoutMs: number; maxTimeoutMs: number; perPluginLimit: number; appLimit: number; maxOutputTokensLimit: number; maxImageCount: number; maxImageBytes: number; maxImageTotalBytes: number; maxTotalOutputTokensLimit: number; maxOutputCharsLimit: number; maxInputChars: number; }>

Plugin inference limits, not billing quotas. maxOutputTokensLimit since 1.3.

services:clipboard

将文字或支持的封装图片写入系统剪贴簿。

  • 开发版:v1.1.0
  • ReadAware 0.6.8:v1.1.0
  • 授权: service:clipboard
ctx.services.clipboard.writeImage
(resourceId: string): Promise<ResourceImageReceipt>

Clipboard 1.1. This activation's sealed resource; raster decode stays in the host.

ctx.services.clipboard.writeText
(text: string): Promise<void>

Schema

schemas:views

描述宿主渲染的清单、表单、详细数据、markdown 与支持的区块版面。

  • 开发版:v1.12.0
  • ReadAware 0.6.8:v1.12.0
  • 授权: 无

Manifest 声明

schemas:settings

声明具类型的插件设置、条件栏位与动态选项参照。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: 无

Manifest 声明

schemas:themes

描述语义化应用与阅读器调色盘。

  • 开发版:v1.0.0
  • ReadAware 0.6.8:v1.0.0
  • 授权: ui:themes

Manifest 声明