contributes block is how it adds surfaces to Mission
Control. The GCS half declares them under gcs.contributes; the agent
half declares its own (services, drivers, vision) under
agent.contributes. This page is the reference for the GCS-side
contribution kinds the host parses and mounts.
Every contribution is declarative. You name what you want in
manifest.yaml, request the matching capability, and the host mounts
it. There is no imperative “register this panel” call at runtime.
Each visual contribution needs the matching
ui.slot.* capability listed
under gcs.permissions. Declaring a panel in a slot without holding the
slot capability is rejected at parse time. See the
permissions reference for the full list.The shape of contributes
${pluginId}:${id} internally,
so two plugins can both ship a panel called overview without
colliding.
Slot and capability map
The full slot taxonomy is
fc.tab, hardware.tab, mission.template,
map.overlay, video.overlay, notification.channel,
settings.section, connection.protocol, recording.processor,
node.detail.tab, cockpit.panel, and flight.skill. Each slot id
maps one-to-one to its capability by replacing dots with dashes:
node.detail.tab needs ui.slot.node-detail-tab.
skills
A Skill is a flight behavior that surfaces in the cockpit Skill Bar in/fly. It can be bound to a hotkey or a gamepad button, toggled or
fired one-shot, and gated on arm state. Built-in commands (Arm, RTH,
Land) and plugin behaviors (Follow-Me, Orbit) are the same Skill shape.
What it does. Registers an entry in the Skill Bar. Activation flips
a key in the plugin’s per-drone config (activation.via: config); the
plugin’s agent half watches that key and starts or stops the behavior.
The Skill’s live state is read back over an event topic
(state.via: event), so the bar can show armed / running / lost.
/fly cockpit. The
operator binds it under the bindings editor.
Capability. ui.slot.flight-skill.
For the end-to-end design (agent config write, event read-back, the
Skill Bar dispatcher), see vision plugins
and the Follow-Me reference walkthrough on the
scaffolder walkthrough page.
tabs
A node-detail tab mounts on a node’s detail panel. It works on any node profile: drone, ground station, or compute. Use it for a configuration or status surface that belongs to one node. What it does. Adds a tab to the detail panel of the currently selected node, rendered as a sandboxed iframe scoped to that node. An optionalprofile list narrows which node profiles offer the tab.
NodeDetailPanel), in the
tab strip, when the node profile matches. With no profile the tab is
offered on every profile the host allows.
Capability. ui.slot.node-detail-tab.
The entry accepts
id or key for the stable id. A tabs entry always
resolves to the node.detail.tab slot: the host ignores any slot field
you set on a tabs entry. Declare a node tab under tabs (not as a
panels entry with a hand-set slot) so the tab is available on every node
profile, not just drones.parameters
A parameter is a native, schema-driven form field the GCS renders itself, with no iframe. The plugin declares the field’s type, bounds, and widget; the host renders a dark-themed control, validates and clamps the value, and writes it to the binding you name. What it does. Renders a typed control (number, range, boolean, enum, string, model) in the plugin’s settings panel and the cockpit quick-settings drawer. On commit the host validates against the schema, clamps to bounds, quantizes tostep, and writes the value to the
parameter’s binding.
ui.group and ordered by ui.order.
Capability. No ui.slot.* is needed for the native form itself; the
parameters render inside the surface the plugin already mounts (a
settings.section or node.detail.tab). A parameter whose binding is
engine.detector participates in the shared vision detector and needs
the agent-side vision capabilities.
The full schema, the widget set, visible_if, and the binding router
are documented on the parameter schema reference.
settings
A settings section groups native parameters under a heading in the plugin’s settings panel. Use it when a plugin has more than a handful of parameters and you want them split into labeled sections. What it does. Renders a section (heading plus nested native parameters) in the plugin’s settings surface. Each section carries its ownparameters array, parsed by the same parameter rules above.
order.
Capability. ui.slot.settings-section.
panels
A panel mounts a sandboxed iframe into a slot you name per entry. Unliketabs (which always resolves to node.detail.tab), a panel
declares its own slot, so the same array can host a flight-controller
tab, a hardware-page tab, or a settings section.
What it does. Mounts the plugin’s iframe bundle into the named slot.
The two most common are fc.tab (a tab in the per-drone flight
controller area) and hardware.tab (a tab on the Hardware page).
slot: fc.tabrenders a tab in the per-drone flight controller configuration area.slot: hardware.tabrenders a tab on the Hardware page so the operator can inspect or configure devices the plugin manages.slot: settings.sectionrenders an iframe section on the Settings page (usesettingsfor a native, no-iframe section instead).
ui.slot.fc-tab, ui.slot.hardware-tab, or
ui.slot.settings-section, matching the slot you declare.
overlays
A video overlay draws on top of the live video feed. Use it for detection boxes, a HUD, or an interactive surface like click-to-follow. What it does. Mounts the plugin’s iframe above the live video player, letterbox-corrected so plugin geometry lines up with the video pixels. The overlay can render telemetry on top of the feed or accept operator clicks.overlays entry implies the video.overlay slot, so you do not set
slot on the entry.
Where it renders. Above the live video element, in both the main
video pane and the /fly cockpit.
Capability. ui.slot.video-overlay.
A map-side overlay is a different contribution: declare it under
mapOverlays (see below), which implies the map.overlay slot.notifications
A notification channel lets the plugin push alerts into the GCS notification center. What it does. Registers a named channel. The plugin’s code (GCS half viactx.notifications.publish, agent half via an event) pushes
messages into the channel; they appear as toasts the operator can mute
or dismiss.
notifications entry implies the notification.channel slot. The host
reads only id, title, icon, and order from the manifest entry.
Severity is not a manifest field: it is set per message at publish time
on the ctx.notifications.publish payload (info | warning | error
| success | critical).
Where it renders. The GCS notification center, as a toast and in the
channel list (where it can be muted).
Capability. ui.slot.notification-channel.
missionTemplates
A mission template adds an entry to the mission template picker so an operator can start a mission pre-configured with the plugin’s parameters. What it does. Registers a template entry in the planner’s template list. Selecting it seeds a new mission from the plugin’s logic.ui.slot.mission-template.
Template metadata only registers the entry. Missions generated from a
template still go through the normal pre-upload validation and operator
approval before they reach the aircraft.
mapOverlays
A map overlay draws geometry on the map view: polygons, markers, or heatmaps. What it does. Mounts the plugin’s overlay onto the map surface, rendered in a sandboxed canvas. Use it to visualize a coverage area, a detected target, or a no-go zone.ui.slot.map-overlay.
models
A model registration adds a vision model to the catalog the agent’s vision engine selects from, with per-board variants. Use it when a plugin ships its own detector or re-id model rather than relying on the built-in catalog. What it does. Registers a model id for a vision task (detection, re-id, depth) with one or more per-board variants. The agent selects the variant whoseboard_match fits the running board, downloads it from
source, and verifies it against sha256. A model parameter (see the
parameter schema reference) then lets the
operator switch the active detector from the GCS.
model / model_upload parameter renders,
and feeds the agent’s vision engine.
Capability. No ui.slot.*. The agent half needs the vision
capabilities to consume the model (vision.frame.read,
vision.detection.subscribe, and related), and a model parameter must
bind to engine.detector to switch the active detector.
See also
- Parameter schema reference — the full schema subset, widgets, and bindings.
- Scaffolder walkthrough — build a plugin that contributes a tab, a skill, parameters, and a model.
- Manifest reference — every manifest field in dependency order.
- Permissions reference — the full capability set.