Plugins
Every operation in Sealpixel is a plugin: a schema, a reducer and a kernel. The first-party set:
| Plugin | Ops | Stage |
|---|---|---|
| assist¹ ² | none | assist 190 (never planned) |
| redact | redact.add/update/remove/clear | redact 200 |
| annotate | annotate.add/update/remove/reorder/clear | annotate 300 |
| crop | crop.set, crop.reset | crop 400 |
| fill | fill.set | crop 410 (merged) |
| finetune | finetune.set, finetune.reset | color 450 |
| filter | filter.set | color 460 (merged with finetune) |
| sticker¹ | sticker.add/update/remove/clear | sticker 500 |
| frame | frame.set, frame.clear | frame 600 |
| watermark¹ | watermark.set, watermark.clear | watermark 700 |
| resize | resize.set, resize.clear | resize 800 |
Stages run in this order, whatever the order of the ops in the log. The colour stage (finetune and filter) runs after crop, so it works on the output frame: the vignette is centred on the cropped image and the clarity radius follows its shorter side. It also grades what the stages before it drew: annotations take the colour grade, and clarity sharpens redacted regions as the redaction left them, which cannot bring back what a region hides. Stickers, frames and watermarks come after it and keep their own colours.
¹ Published and supported, but not in defaultPlugins: a plain editor starts without them. Pass them to switch them on, on the client and on the server alike, and the default UI supplies the matching tool:
import { defaultPlugins, stickerPlugin, watermarkPlugin } from '@sealpixel/plugins';
editor.plugins = [...defaultPlugins, stickerPlugin, watermarkPlugin];² Its toolbar button appears only when the host also installs a tool with a detector: editor.tools = { assist: createAssistTool(detector) }. Registering it costs nothing else — a plugin without operations never reaches the renderer, so the bundled worker still applies. Suggestions live outside the edit log; accepting one dispatches a plain redact.add. See Assisted redaction.
allPlugins is the whole first-party set in one array, for a host that wants all of them.
See the operations reference for every field, generated from the zod schemas, and Writing a plugin to add your own.
Regions, shapes and stickers are selected by tapping them on the stage. A trash handle floats above the selection and deletes it; a selected redaction or annotation also carries handles to resize it and one below to turn it (redact.transform, annotate.transform). A turned redaction is written to the log as a four-point path, so no renderer needs to know; a turned rect, ellipse or text annotation carries a rotation in radians about its centre, and a line or an arrow moves by its ends; the panels keep only the settings of the selected element, so the image keeps the room. Strengths are configuration rather than controls: a new redaction uses redact.defaultAmount, a preset blends with filter.defaultStrength (set filter.strength: true to show a slider anyway), a watermark uses watermark.defaults.opacity and a frame frame.defaults.thickness.