Plugin API
The APIs you can use when writing a plugin for Novelist.
Novelist plugins are written in JavaScript / TypeScript. They talk to the app through @novelist/plugin-api, a thin runtime that exposes the editor’s capabilities.
Hello, plugin
import type { Plugin } from '@novelist/plugin-api';
const plugin: Plugin = {
async onLoad(ctx) {
ctx.commands.register({
id: 'my-plugin.say-hello',
title: 'Say hello',
run: async () => {
ctx.notifications.info('Hello from my plugin!');
},
});
},
};
export default plugin;
What ctx exposes
| Namespace | Purpose |
|---|---|
ctx.commands | Register / unregister commands, execute other commands |
ctx.editor | Read and write the current document, move the cursor, batch edits |
ctx.workspace | Enumerate open documents, listen for open/close events |
ctx.ui | Add views in the sidebar, status bar, or command palette |
ctx.events | Subscribe to documentSaved, documentOpened, editorChanged, etc. |
ctx.settings | Read and write the plugin’s own settings |
ctx.notifications | Show info / progress / error toasts |
The full type definitions live in the app repo: creating-plugins.md.
Lifecycle
onLoad(ctx) // called when the plugin is enabled
onUnload(ctx) // called when the plugin is disabled / removed
When your plugin is disabled, every command and view it registered must be disposed — ctx.disposables provides a Disposable aggregator you can push onto and drain on unload.
Permission model
If your plugin needs to read document content, declare "read" in manifest.toml; for writes, add "write". ctx.editor methods only run if the plugin declared the right permission; otherwise they throw PermissionError.
Packaging
pnpm install
pnpm build # produces dist/
pnpm pack # emits <id>-<version>.zip
Attach the ZIP as a GitHub Release asset, then follow Submitting a plugin to land the manifest in the marketplace.