Home › Plugins
Writing a plugin
For developers and AI models: what a plugin is made of, how to check one, and where the full interface lives.
Most plugins in these pages are one JSON file, a manifest, and no code. A plugin can also be an app: the same manifest plus one JavaScript file for work the manifest cannot describe. Either way the platform runs it inside each customer's own copy, through the same access rules as everything else, so a plugin only ever sees one business's records and only what its owner approved.
What a manifest holds
| Part | What it does |
|---|---|
values | Per-tenant values the owner or OPSAVOR fills in: plain configuration read as config.name, and secret tokens that can only be injected into an api_call. A secret is write-only and sealed. |
grants | What it asks the owner for: which records it reads, whether it sees people, model use and its budget, notices, proposals, approvals, its views. |
derivations | Steps over the records (sum, list, join, filter) that emit small results, each citing the documents it came from. |
views | Cards on Start or its own page, built from tables, lists, charts and figures the app draws. A table or list can be a to-do list with Mark reviewed, or a decision with Approve and Reject. |
triggers | On a schedule, when records change, or by a button: re-derive, write a brief (every figure checked), post a notice. |
flows | Automations: a trigger and steps (records, query, if, forEach, ai, propose, notify, message, webhook, app). Messages and web hooks wait for the owner unless they let a store plugin's flow send by itself. See the reference's Flows section. |
code | An app: one JavaScript file of handlers and screens. Its grants limit what it can read and do; it keeps its own storage, and every run is limited and logged. |
tools, skills | Give Savy a plugin's results, or teach Savy a way of working. A skill can declare an agent with its own scope and tests. |
Check one on your own machine
With opsavor/platform checked out beside the plugin, the kit needs nothing installed:
node ../platform/bin/plugin.mjs validate plugin.json --tier store
node ../platform/bin/plugin.mjs run plugin.json --sample
node ../platform/bin/plugin.mjs run plugin.json --plane /path/to/a/copy/of/plane.db
validate names every problem by its place in the file. --sample runs it on a small made-up business that has bills with lines, a statement and a supplier who has gone quiet.
What a manifest can do now
- More than tables and charts. A view can be a
calendarmonth grid, atimeline, or aboardgrouped into columns; any table offers Download CSV. - Ask the person for a number. Declare a
formsentry and aformblock, and a member can enter a count or reading in the app. It is kept as a manual observation, with the same review and evidence as an upload. - Notices that expire. A
readThroughplugin can give a record avalidUntil; its notice disappears when the figure is no longer true. - Propose a record. A flow's
proposestep fills in one of the plugin's forms; a person accepts or rejects it. Nothing is written before that, and the record keeps who proposed it and who accepted it. - Ask for an approval. A view block can set
approvewith the roles who may decide and an effect flow; the decision is kept per version of the record, and the effect runs once. A changed record asks again. - Ask for what only the tenant can give. Declare
valuesfor a token or a workspace name; plain values areconfig.name, and secrets are write-only and only ever sent as anapi_callheader. - Say which release you need.
requires.platformkeeps an older instance from being offered a version it cannot run. - Read one figure. A
timelinestep withwherepicks a single figure from a report. - Bring code only when the manifest cannot say it. An app runs handlers for a flow, a screen, a button or a form. It has its own key/value storage, cannot reach the network, files or core tables, and every run has time, memory and call limits plus a daily budget. The owner sees that code runs, its size and fingerprint, and can stop it; uninstalling it removes its storage.
- Offer an agent. A Savy skill can declare an
agentwith a scope and tests for missing and denied answers. It stays off until someone who manages plugins turns it on, and can be paused and resumed. - Read what is waiting. With
grants.state, a read-through plugin can see what is waiting for the viewer to decide, what was decided, and which reports are in — never more than that person may see.
The reference is the exact list and moves with the engine; check it before using one of these.
Where to go next
- The plugin guide, the reference (every field and operator), writing an app and what the records look like.
- Real plugins to copy from: the
platform-pluginsorganization, one repository each (Business Intelligence, Missing bills, Supplier price watch, Statement check, Plugin Builder, and a template). - Publishing, dev tenants and promotion are for OPSAVOR staff: Developing and promoting plugins.
- Not a developer? Build one with Savy.