Overview
Clarity plugins are scoped, permission-gated extensions that augment the editor, mentor, or export surface. They run in sandboxed iframes and communicate with the main app through a typed postMessage bridge. The plugin runtime, bridge protocol, developer portal, and marketplace are all implemented and available now.
Plugin Categories
- Editor enhancers — add slash commands, toolbar actions, or bubble menu items that operate on selected text or the document. Example: a readability scorer, a vocabulary expander.
- Research bridges — pull external content into the document. Example: a Notion importer, a Zotero citation fetcher.
- Export adapters — transform the document on the way out. Example: Obsidian markdown exporter, Google Docs push.
- Mentor extensions — contribute context to the AI mentor at a specific writing stage. Example: a domain-specific style guide the mentor references in Refine mode.
Plugin Manifest
Every plugin declares a clarity-plugin.json manifest at its package root.
{
"id": "com.example.citations",
"name": "Citation Manager",
"version": "1.0.0",
"permissions": ["document.read", "editor.commands", "network.fetch"],
"entrypoints": {
"editor": "./dist/editor.js",
"mentor_context": "./dist/context.js"
},
"stages": ["refine"],
"api_version": "1"
}id— reverse-domain namespaced, unique in the registry.permissions— explicit list from the permission allowlist. Anything not listed is denied.entrypoints— which surfaces the plugin participates in. A plugin that only exports does not need aneditorentrypoint.stages— which writing stages activate this plugin.api_version— must be"1"for the current bridge.
Runtime and Isolation
Plugins run inside a sandboxed <iframe> with sandbox="allow-scripts". The iframe is invisible and off-screen. All communication goes through the postMessage bridge.
Clarity main frame ←→ postMessage bridge ←→ Plugin iframe (sandboxed)
allow-same-origin is notgranted — the plugin iframe runs on a separate origin and cannot access the main app's cookies, storage, or DOM. Plugins cannot make backend calls directly; all backend access goes through the bridge and is subject to permission checks.
Permission Model
The bridge enforces permissions at call time. Calling a method without the declared permission throws immediately.
| Permission | What it allows |
|---|---|
| document.read | Read the current document's plain text body |
| document.read_json | Read the TipTap JSONContent representation |
| document.metadata | Read document title, stage, and word count |
| editor.commands | Register slash commands and bubble menu items |
| editor.toolbar | Add a button to the editor toolbar |
| editor.insert | Insert content at the cursor or a specified position |
| editor.replace_selection | Replace selected text (requires explicit user gesture) |
| mentor.context | Contribute a string of context to the mentor's stage prompt (max 500 chars) |
| network.fetch | Make outbound HTTP requests to declared external origins |
| user.profile_read | Read the user's writing profile summary |
editor.replace_selection requires an explicit user action to trigger — a plugin cannot replace text silently or programmatically without a user gesture.
Plugin Bridge API (v1)
Plugins call ClarityPlugin.connect() after load to receive the bridge context. The following methods are available, each gated by the corresponding permission.
// Called once on load — no permission required
connect() → { pluginId, name, permissions, stage }
// Document access
getDocumentText() // requires document.read
getDocumentMeta() // requires document.metadata → { title, stage, wordCount }
// Editor
registerSlashCommand({ id, title, description }) // requires editor.commands
insertContent(stringOrNode) // requires editor.insert
replaceSelection(stringOrNode) // requires editor.replace_selection
// Mentor
setMentorContext(text: string) // requires mentor.context; max 500 chars
// AI delegation (marketplace plugins only)
delegateAICheck(params) // bills the AI call against the user's token allowance
// Lifecycle events
onStageChange(handler) // no permission required
onDocumentChange(handler) // no permission requireddelegateAICheck is only available to marketplace-approved plugins. Self-hosted URL plugins cannot use it.
Plugin Lifecycle
- Install — user installs from the marketplace or (in dev mode) by URL. Clarity presents the requested permissions for review.
- Activate — on document open, the iframe is created for each active plugin whose
stagesincludes the current stage. The bridge is established and the plugin callsconnect(). - Stage change — plugins not listed in the new stage are deactivated (iframe torn down). Plugins that do include the new stage are activated if not already running.
- Deactivate — on document close or user toggle. The iframe is removed and registered commands disappear.
- Uninstall — stored permissions are deleted. Any API key the plugin held is revoked.
Dev Mode (Testing)
Enable dev mode in settings to install a plugin by URL without going through marketplace review. Dev mode shows a persistent amber warning banner while active — it does not go away until dev mode is turned off.
URL-installed plugins get the same sandboxed bridge as marketplace plugins. The trust distinction is about review status, not technical capability. Dev mode is intended for testing before marketplace submission, not as a permanent workaround.
Marketplace and Vetting
Marketplace plugins are human-reviewed before listing. A reviewer examines the manifest, permissions, plugin description, and source code. Plugins that request permissions they cannot justify, obscure their behavior, or contradict Clarity's philosophy are rejected.
After a plugin is listed it is available from the marketplace browser in settings. Clarity reserves the right to delist a plugin found to violate trust — delisting revokes the marketplace flag and removes it from new installs.
Marketplace listing carries a small recurring fee to cover registry infrastructure and the review process. It is not a revenue mechanism — it is a filter against throwaway submissions.
Applying for Developer Access
To register plugins and issue API tokens, you need a developer account. Visit the developer portal and apply — access is granted immediately via email confirmation.
What Plugins Cannot Do
- Modify the stage model — the four stages are a core product concept, not a plugin variable.
- Change how the mentor responds — plugins can add context, but the mentor's voice and question-first approach are not configurable.
- Override the clarity score algorithm or write scores.
- Surface UI outside the defined extension points (slash commands, toolbar button, bubble menu item). No floating overlays or injected modals.
- Access raw database records, other users' documents, or auth tokens.
- Make calls to undeclared external origins —
network.fetchis scoped to origins listed in the manifest. - Run at all during Explore stage unless explicitly listed in their manifest's
stagesfield.