Manage plugins
Install a plugin from a ZIP file, then enable, disable, configure, update or uninstall it from Fermo's settings.
Extend Fermo with plugins without handing each one the run of your client. Every plugin runs in its own sandbox and can only ask Venora to act, through permissions it declared up front.
Fermo is a third-party web client for Spacebar. Venora is an independent browser extension for the Fermo web client at fermo.sbar.fyi. It is not made or endorsed by Fermo or Spacebar.
await venora.ui.toast({ message: "Saved" })
ui.toast is in the fixed registryuinullnotice shown; an imported plugin's notice carries its name01 What Venora does
Venora adds a Plugins page to Fermo's settings and a runtime that keeps plugin code apart from the client. Plugins get a small API instead of the whole page.
Install a plugin from a ZIP file, then enable, disable, configure, update or uninstall it from Fermo's settings.
Every plugin, bundled ones included, runs in a dedicated worker inside its own sandboxed frame. It has no direct access to Fermo's page, your storage or the network.
A small, versioned plugin API for notices, settings, storage, mention avatars and events. It is written down as a specification, and tests check the code against it.
02 Plugins
Everything happens in Settings → Plugins inside Fermo. Nothing is stored until a plugin passes every check.
Choose Add plugin and pick a ZIP. Venora validates the manifest, permissions, settings, compatibility and file sizes before anything is saved.
Every plugin's declared permissions are listed. If it asks for a sensitive one, you have to confirm a warning first.
Plugins can declare settings: switches, text, numbers and choices. Venora draws the settings dialog and only you can change the values.
Add a newer ZIP of the same plugin. You see the old and new versions and the release notes, and your settings and data carry over.
Disable a plugin, or uninstall an imported one. Uninstalling deletes its files, settings and stored data.
Updates are manual for now. There is no plugin registry and Venora does not check for new versions. All plugin-management features
03 Built in
They run in the same sandbox as any imported plugin, with only the permissions they declare.
Shows the mentioned user's avatar beside their name, with an avatar-size setting. Venora looks the avatar up, so the plugin never receives your session token.
Layout refinements that keep Fermo's account controls, search field and related elements aligned. It is CSS only, applied under the ui permission.
Briefly confirms that Venora is running when Fermo loads, using one ui.toast call.
04 Sandboxed by design
Each plugin gets its own sandboxed extension frame with an opaque origin and a content security policy of default-src 'none'. Inside it, the plugin runs in a dedicated worker with no window, document or navigable location.
The plugin reaches Venora through a private message port. Only copies of plain data cross it. Venora decides which plugin is asking from the port a request arrives on, never from the request itself.
05 Permissions
A plugin lists its permissions in plugin.json. They are fixed for that version, and every request is checked against them. A missing permission means permission_denied, whatever the plugin sends.
storageRead its own settings, and keep its own data in a private store.
uiShow short notices, apply its declared CSS, and decorate mentions with avatars.
networkLets Venora make a web request on the plugin's behalf, inside a capability that needs it. The plugin cannot send its own requests.
accountLets Venora use your signed-in account on the plugin's behalf. The plugin never receives the token or your account record.
Sensitive permissions must be confirmed in a warning at install, and again at every update that declares them. In API v1 they are consent markers: no capability gives a plugin general network access or your account data. Today they unlock only the avatar lookup.
06 Session token
Some things need your Fermo session, such as looking up an avatar. Venora does that work itself, inside its trusted code, and gives the plugin only the outcome: {shown: true}, not the avatar URL and never the token.
As a backstop, every message Venora sends to a plugin passes through one function that checks it against your current session tokens, for every Fermo account in the browser profile. A response containing a token becomes sensitive_data_blocked. An event containing one is dropped. If the tokens cannot be read, nothing is sent.
mentions.showAvatar uses the session, if needed, for one request to your Spacebar server, then returns {shown}.{ shown: true }
sensitive_data_blocked
07 Runtime protection
Each running plugin has its own resource account. These are the limits Venora enforces today, taken from the API v1 specification.
rate_limitedSafe mode and recovery. If a plugin makes Fermo hard to use, click the Venora button in the browser toolbar. That menu is outside Fermo's page, so plugin CSS cannot hide it. Turn on safe mode to stop every imported plugin, or disable or uninstall one. Open Fermo tabs apply the change at once.
What isn't capped. Browsers give extensions no way to limit one worker's CPU time or memory. The watchdog stops plugins that stop responding, but a plugin that stays responsive can still use CPU and memory in its own worker.
08 Developer API
Your default export receives a frozen venora object. Every method returns a promise, takes one plain object, and maps to exactly one permission-checked capability.
venora.uiShort plain-text noticesvenora.settingsRead your declared settingsvenora.storageYour own key–value datavenora.mentionsAvatars beside @mentionsvenora.onsettings.changed, mentions.addedexport default async (venora) => {
const greeting = await venora.settings.get({key: "greeting"});
await venora.ui.toast({message: greeting});
const unsubscribe = await venora.on("settings.changed", ({key, value}) => {
if (key === "greeting") venora.ui.toast({message: value});
});
// Data the plugin keeps for itself, separate from the user's settings.
const runs = ((await venora.storage.get({key: "runs"})) ?? 0) + 1;
await venora.storage.set({key: "runs", value: runs});
return () => {
// Cleanup. Venora removes what it added to the page for this plugin.
unsubscribe();
};
};
{
"id": "greeter",
"name": "Greeter",
"version": "1.0.0",
"author": "Your name",
"main": "index.js",
"permissions": ["storage", "ui"],
"compatibility": {"apiVersion": 1, "minVenoraVersion": "0.1.0"},
"settings": [
{"key": "greeting", "type": "string", "default": "Hello!"}
]
}
09 Open source
Venora and its bundled plugins are licensed under the GNU General Public License, version 3. You can read, run, study, change and share the code. The repository holds the extension, the API specification, the security requirements and the test suite.
10 Status
The plugin runtime and API v1 are implemented and tested in Chromium. Work now focuses on browser support, developer experience, documentation and distribution. There are no store releases yet.
Try it
Venora installs from source in developer mode on Chromium-based desktop browsers. The install guide walks through it step by step.