Linen Linen

Build a plugin

A plugin is a folder with a manifest and a JavaScript file. It runs on the desktop clients inside a sandbox with an empty global scope: no DOM, no filesystem, no network, and nothing it has not declared.

The shape of one

my-plugin/
  manifest.json
  main.js
{
  "id": "com.example.my-plugin",
  "name": "My Plugin",
  "version": "1.0.0",
  "apiVersion": 1,
  "entry": "main.js",
  "description": "One sentence about what it does.",
  "permissions": ["mail.read", "ui.actions"],
  "hosts": ["api.example.com"]
}

The id is reverse DNS and lowercase. It is also your plugin's private storage namespace on every machine that installs it, so it is claimed once and cannot be shared with another listing.

What you can ask for

Only these, because only these exist. A permission with nothing behind it would appear on somebody's consent prompt as though it were real.

Anything you do not ask for is refused while your plugin runs, not merely discouraged. Storage is always available and namespaced to you.

Submitting

  1. Zip the folder, with manifest.json at its root.
  2. Create a listing and upload the zip.
  3. We check it: the manifest parses, the entry point is in the archive, nothing points outside the plugin folder, and the permissions are ones a person could reasonably agree to.
  4. Once approved, it appears in the directory and can be installed.

Approved versions never change. A correction is a new version with a new number, reviewed again, because the permissions somebody agreed to belong to the version they installed.

Updates

An update that asks for no more than the reader already granted installs quietly. One that wants more has to ask again, and they can say no and stay on what they have.

The full API reference ships with the client, in docs/PLUGIN_DEVELOPMENT.md.