WrengleWrengle
Plugins overview

Plugins overview

Beta

Wrengle's current beta plugin surface has three local contribution types: WASM actions that run from the editor Actions menu, view-only plugins that open sandboxed iframe tabs, and manifest-declared UI contributions that add host-rendered rows to existing app surfaces. Plugins are discovered from local folders and validated from plugin.toml; WASM actions run in a sandboxed runtime and register in the same action registry as built-in and configured actions.

No marketplace, remote installation flow, public publishing flow, process-plugin runtime, or long-term ABI compatibility guarantee exists yet. See Adoption evidence and gate review for the current gate decision before broader plugin work. Local plugin code remains trusted local code: load only folders you trust. Plugins can act on Wrengle data only through granted host APIs, and those grants are local to this app install.

Current runtime

Wrengle currently supports trusted local developer plugin folders. A folder must contain plugin.toml and at least one contribution:

  • a WASM action that runs in a sandboxed runtime from the editor Actions menu;
  • a view-only plugin that opens a sandboxed iframe tab from a single HTML entry file; or
  • a UI contribution that places a manifest-declared entry in the command palette, slash menu, context menu, keybinding registry, status bar, plugin settings pages, or docked panels.

WASM action plugins need the built plugin.wasm named by their [runtime] entry. View-only and UI-only plugins do not need [runtime], plugin.wasm, a build toolchain, or just plugin-build unless the author chooses to use their own bundler before producing single-file HTML views.

Wrengle discovers configured local developer paths, watched plugin collection roots, and a legacy internal plugin directory. A configured developer path points at one plugin folder. A watched plugin root points at a parent folder, and Wrengle auto-loads immediate child folders that contain plugin manifests. If two discovered folders declare the same plugin id, the configured developer path takes precedence during discovery.

If a manifest is invalid, a WASM action's runtime entry is missing, a view entry cannot be read, a plugin action's id or short_scheme conflicts with an existing action, or a UI contribution target is invalid, Wrengle records a reload diagnostic and skips the affected plugin or contribution. WASM load, export, and run_action failures surface when the action runs.

Write your first local WASM action plugin

Use the generated WASM action scaffold when you want to start from the app instead of copying the echo example:

  1. Open Settings -> Plugins.

  2. Enter a plugin name and click Create plugin.

  3. From the repository root, build and smoke-test the generated folder:

    sh
    just plugin-build "<generated_plugin_dir>"
    just plugin-smoke "<generated_plugin_dir>"
  4. Return to Settings -> Plugins and click Reload.

  5. Select text in a note.

  6. Open Actions, choose the generated action, review the local plugin disclosure, and click Confirm. If the action requests capabilities you have not decided yet, Wrengle opens a first-use permissions dialog before the action runs.

Local WASM action plugins execute WASM. View-only plugins execute local HTML and JavaScript in sandboxed tabs when loaded as manual/developer local plugin views. Load only local plugin code you trust.

For creator templates, SDK imports, exact grant examples, host error handling, and the write proposal flow, see SDK and plugin creator. You can also open Plugin Builder from any New tab (+) menu or the command palette entry Plugin Builder and use the Plugin Builder to create or iterate on a local custom-view plugin from plain-language prompts. Plugin Builder currently supports static custom views and offline feature apps with automatic plugin-scoped JSON state. Builder-created offline apps cannot read or write Wrengle workspace content, use external network access, store secrets, run shell commands, or ship generated WASM actions. Workspace-aware Builder plugins that read bounded workspace data or request app-mediated write proposals remain future work, and prompts that need recent notes, project data, note writes, block writes, external APIs, credentials, or secrets are blocked instead of being turned into fixture-backed previews.

Builder-created offline feature apps can use window.wrengle.state.get, window.wrengle.state.set, and window.wrengle.state.delete for plugin-scoped local JSON state. Builder drafts declare expected state keys and generated code is checked against that draft contract before Apply. Installed Builder app calls remain scoped to the plugin and limited to those declared state keys. They do not receive state.list or state.clear; reset is a Wrengle-owned action from Plugin Builder. For stateful edits, edit-preview state is temporary; preview interactions test the draft only, and applying an edit preserves installed app state.

Plugin Builder handles checks and smoke preview behind the scenes, shows concise build status in chat beside the generated preview, and applies the plugin only after you approve Apply changes. Installed-plugin lifecycle actions are available from the project header instead of a permanent controls rail: Open and History stay visible, while edit, Reset app state for stateful apps, enable or disable, and delete stay in the actions menu.

When a supported static custom-view create prompt with clear static/sample/mock UI intent receives malformed, invalid, or locally blocked provider output, Plugin Builder can discard that output and create a safe starter draft using platform-owned static templates.

The recovered draft is marked in details and still must pass the normal checks, smoke preview, and explicit Apply step. This recovery does not apply to unsupported prompts, network/API/remote-service prompts, live/real/actual/production data requests, workspace data prompts, edit drafts, provider connection/auth/rate-limit failures, or local write, metadata, or fingerprint failures. Use Refine prompt from review to iterate before applying.

For installed Builder-created plugins, History opens a prompt-first approved timeline with rollback available from older approved entries. If checks or preview preparation need attention, the same review surface shows Needs attention and Try again without exposing manual build steps. Smoke preview blocks hidden-only, placeholder-only, or runtime-dependent custom-view drafts instead of applying them; static generated visuals should use renderable SVG or scanner-recognized non-interlaced PNG data images.

Generated views have no network, secrets, shell, filesystem, or Tauri IPC access. Plugin Builder creates local offline custom views and stateful offline feature apps. It does not create networked plugins, workspace readers, workspace writers, marketplace listings, or generated WASM tools in this release.

For palette rows, slash menu items, context menus, keybindings, status-bar items, settings pages, panels, host commands, and policy controls, see UI contributions.

Quick start with the echo plugin

From a source checkout:

sh
rustup target add wasm32-unknown-unknown
just plugin-echo-build
just plugin-echo-smoke

Then try it in the app:

  1. Start Wrengle with just dev.
  2. Open Settings → Plugins → Developer → Dev plugin paths.
  3. Add the absolute path to examples/plugins/echo-action.
  4. Click Reload.
  5. Confirm Loaded plugins lists Echo selection.
  6. Open a note and select text.
  7. Open the floating toolbar's Actions menu.
  8. Choose Echo selection and click Confirm.

The echo plugin returns a summary toast such as Echoed 10 characters. It does not insert a link because the example returns reference: null.

App surfaces

SurfacePurpose
Settings → Plugins → Developer → Plugin creatorGenerate a local action or view plugin folder from a typed template, with manifest ids and requested capability grants previewed before creation.
New tab (+) menu or command palette -> Plugin BuilderOpen a focused project workspace for Builder-created plugins, create or iterate on static custom views and offline feature apps from plain-language prompts, use automatic plugin-scoped JSON state for offline apps, reset app state from the actions menu for stateful installed apps without removing plugin files or history, automatically run checks and smoke preview before Apply, apply approved offline changes on this device, open the installed view tab, review prompt-first approved history, roll back to a prior approved version after confirmation, enable or disable Builder-created plugins, and delete installed Builder-created apps with their managed plugin files, approved prompt history, rollback points, linked Builder conversations, and installed app state.
Settings → Plugins → My pluginsReview, enable, disable, or delete Builder-created plugins installed on this device and link back to Plugin Builder; broader developer controls remain in Settings.
Settings → Plugins → Developer → Dev plugin pathsAdd trusted local plugin folders and reload.
Settings → Plugins → Developer → Watched plugin foldersAdd trusted parent folders whose immediate child plugin folders are loaded automatically, with root diagnostics shown after reload.
Settings → Plugins → Loaded pluginsConfirm registered plugin actions, plugin views, and accepted UI contributions.
Settings → Plugins → Management → Plugin permissionsReview, grant, deny, or revoke plugin capability decisions for each local plugin installation.
Settings → Plugins → Management → Plugin keysSet, update, or delete OS-keychain secret values for aliases declared by plugin manifests; secret values are not displayed after entry.
Settings → Plugins → Management → Plugin stateReset plugin-scoped local JSON state for developer/manual plugin installations; stateful Builder-created apps use Reset app state from Plugin Builder.
Settings → Plugins → Developer → Plugin diagnosticsInspect manifest, missing-WASM, view-entry, action registration, and UI contribution errors.
Editor selection toolbar -> ActionsRun WASM actions against selected text, or send selected text to views with accepts_selection = true.
Command paletteOpen plugin views as Open <label> commands with plugin-name attribution, and run accepted plugin palette contributions.
Slash menuRun accepted plugin slash-menu contributions from the editor.
Context menusRun accepted plugin file-tree and editor-selection context menu rows.
KeybindingsDispatch conflict-checked plugin keybindings for reusable plugin commands.
Status barShow accepted static plugin status buttons.
Settings → Plugins subpages and docked panelsRender sandboxed plugin views in host-owned settings or dock placements.

Declarations are not grants. Manifest [[capabilities]] entries describe the host APIs a plugin may ask to use, but Wrengle does not grant those APIs just because they appear in plugin.toml. Grants are explicit user decisions scoped to this app install, the plugin id, the canonical local path identity, and the currently declared grant keys.

Plugin actions do not receive declared host capabilities automatically. When a local action is confirmed, Wrengle checks its capability grants. If any requested grant is pending, denied, or revoked, the editor shows Plugin permissions with the action's requested capabilities. You can grant the selected capabilities and run, run without changing grants, or cancel without running the action. Running without grants leaves enforcement to the host API: calls that need missing grants return capability-denied errors instead of bypassing consent.

Write host functions do not mutate notes or blocks directly. They create app-mediated write proposals scoped to the plugin id and canonical path identity. After a plugin action returns, the editor can keep the preview open with pending write proposals. Note proposals show unified diff rows; block proposals summarize the queued block operations. The user approves or denies each proposal from the editor before any write is applied; nothing changes until you approve the proposal in Wrengle.

Settings trims leading/trailing whitespace and stores the path string without resolving it. After reload, the UI may also show a canonical display path. Prefer absolute paths unless the app process is running from the repository root.

Current limits

  • No marketplace or remote installation flow is available.
  • Plugin Builder creates local offline custom views and stateful offline feature apps. It does not create networked plugins, workspace readers, workspace writers, marketplace listings, or generated WASM tools in this release.
  • Workspace-aware generated Builder plugins remain future work.
  • No public stability guarantee exists for plugin manifests, SDK APIs, host functions, view bridge messages, UI contribution schemas, or generated creator templates.
  • Runtime dynamic UI contribution registration is not available. Contributions are manifest-declared and visible after plugin reload or app reload.
  • Host-command UI targets are limited to openSearch, newNote, toggleTerminal, focusEditor, openSettings, and showNotification.
  • Plugins cannot inject React components or arbitrary host chrome; custom UI stays in sandboxed plugin views.
  • Arbitrary process execution is not available.
  • Process-plugin manifests are not supported.
  • WASM action plugin folders must contain both plugin.toml and the built plugin.wasm named by [runtime].entry.
  • View-only plugin folders must contain plugin.toml and the declared single HTML entry file for each view.
  • Watched plugin roots load immediate child plugin folders only. The root folder itself is not treated as a plugin unless it is also added as an individual developer plugin path.
  • plugin.wasm is generated by the plugin author and is not committed for the WASM examples.
  • Host access is capability-gated; plugins do not get direct filesystem, process, or keychain access outside declared host functions.
  • Manual/developer local plugin view JavaScript direct network access is not controlled by httpHosts; only Wrengle host bridge HTTP calls made by WASM actions are grant-gated. Builder-created offline apps are checked against network access and remain offline.
  • Plugin secrets are stored in the OS keychain under plugin-id and canonical path identity namespaces. Plugin JSON state is isolated by the same plugin id and canonical path identity. At startup, Wrengle preloads only aliases for the current installed identity that already have a secret grant. Removed, revoked, or differently rooted plugin identities are excluded. Preloading does not run the plugin or grant any declared capability. A denied or locked item leaves that plugin's secret-dependent work unavailable in Limited mode without showing a Keychain prompt when the action runs. Builder-created offline apps receive plugin-scoped JSON state automatically, and Wrengle keeps that local app data with the installed Builder app until the user resets app state or deletes the app. Builder drafts declare expected state keys before Apply, and installed Builder app calls are limited to those declared state keys. Manual local plugins use the same isolated plugin state host API when their manifest requests it and the user grants it. Plugin state is local to this device and is not a sync or backup boundary.

Secret-alias changes made while Wrengle is open use non-interactive Keychain operations. If the operating system would need to ask again, the change fails closed, the plugin cannot use the old session authority, and Settings requires an explicit reconnect, or a new launch when the current plugin configuration still authorizes preflight, instead of presenting a dialog over the plugin.

Views

Plugins can also declare custom-UI views — single self-contained HTML files that Wrengle renders in a sandboxed iframe tab. Views are a deliberate first-party extension of the developer preview. The first view plugin, examples/plugins/json-compare, provides side-by-side JSON diffing with no build step.

See Views (custom plugin UI) for the [[views]] manifest block, the bridge protocol, and constraints, and the JSON Compare tutorial for an annotated walkthrough of the reference plugin.

UI contributions

Plugins can declare host-rendered entries for the command palette, slash menu, context menus, keybindings, status bar, plugin settings pages, and docked panels. Contributions can target same-plugin actions and views or the small explicit host-command allowlist. Settings pages and panels render sandboxed plugin views; they are structured plugin targets, not generic host commands.

See UI contributions for the surface table, target syntax, host-command allowlist, reload behavior, disable policy, audit behavior, and examples.

Adoption gate

Wrengle is not starting broader plugin platform pillars by default. Distribution, public stability promises, additional contribution points, and expanded permission UX remain gated until the conditions in Adoption evidence and gate review are met.

docs / plugins/overviewAll documentation