ReadAware

Build a plugin

Begin with one useful action. Keep compatibility, authority, and runtime behavior visible as you add capabilities.

Get the template and types

The public plugin repository contains a template, declarations, registry, and package checks. For unreleased APIs, compare it with the current source contract and use a matching development build. The latest published app may be older than this documentation.

Use Bun for the repository scripts. Copy template/ to plugins/<your-plugin-id>/ and keep the directory name equal to the manifest ID.

A minimal command

This example registers a command during activation and performs its UI effect only when the user runs it.

json
{
  "id": "hello-reader",
  "name": "Hello Reader",
  "version": "0.1.0",
  "schemaVersion": 1,
  "main": "main.js",
  "requires": {
    "contributions": { "commands": "^1.1.0" },
    "services": { "ui": "^1.17.0" }
  }
}
typescript
export default {
  activate(ctx) {
    ctx.contributions.commands.register({
      id: "hello",
      title: "Say hello",
      run: () => ctx.services.ui.showToast("Hello, reader!"),
    });
  },
};

Compile the entry module to a self-contained main.js. The manifest above intentionally requires the current documented versions; use older ranges only after checking and testing those contracts.

Add the smallest useful authority

Use the Explorer to find a method and copy its starting manifest fragment. A fragment declares a capability; complete the grants needed by the particular operation.

  • Reading library data requires library:read; changing it requires library:write.
  • Settings use exact settingsAccess paths and operations.
  • Arbitrary HTTP needs service:network plus allowed networkAccess.origins.
  • A reader-related method in a permission-free UI service may still need reading:read or reading:write.
  • Book grants are selected through host consent and exposed in ctx.grants.book; a manifest cannot give itself access to another book.

Inspect ctx.capabilities and handle absent optional namespaces. Keep ReadAware-owned data in its domains; plugin storage is for your own records, settings, and checkpoints.

Work with observations and cancellation

Release handles when you no longer need them. For supported calls, pass an AbortSignal and await the actual outcome. Cancellation does not undo a write or remote side effect that already happened.

An automatic reaction uses ctx.withEvent(delivery) for resulting work, including after an await. Give causal subscriptions a stable ruleId where the contract requires it. User-initiated actions use the original activation context. This lets the host detect loops without conflating independent actions.

Build and install locally

Follow the checkout's package scripts. In the public plugin repository, the normal checks are:

bash
bun run build
bun run typecheck
bun test
bun run validate

Open ReadAware → Settings → Plugins → Install plugin, select the built folder, and review the consent summary. Exercise the feature in the desktop app. Rebuild and reinstall to check an update.

Version private data

schemaVersion is independent of the package version. When the stored KV or document shape changes, supply the supported upgrade and downgrade transitions through migrate(storageCtx, change).

Migration receives storage-only authority. Test a failed transition as well as success: the prior package and committed data must remain usable. Avoid adding an unnecessary schema change for ordinary code updates.

Test the boundaries your feature uses

Check its actual Worker/Tauri behavior, permission and book-scope refusals, cancellation, disable/re-enable, and failure recovery. For a UI plugin, include keyboard navigation, long text, and narrow windows. For a data-changing plugin, include concurrent edits and restart where persistence matters.

Schedules run while the app is open; durable jobs support only the host's typed plans. Neither is a general background process or arbitrary-code job runner. The API reference describes these limits.

Publish

Once the built package works with its declared minimum contracts, follow Publishing.