Skip to main content
This walkthrough scaffolds one hybrid plugin and reads through what the template gives you: a flight skill in the cockpit Skill Bar, a node-detail tab, native parameters (including a model picker), and a Python agent half that reads the live config and publishes its state. It then adds a target action, so the operator can click a detected person in the cockpit and follow it. By the end you have a signed archive that installs on a drone. The pattern matches the Follow-Me extension, trimmed to the parts that matter here.

Prerequisites

  • Node.js 20+ and pnpm 9+.
  • Python 3.11+ and uv for the agent-half tests, plus the cryptography package for signing.
  • bash with rsync and zip for scripts/pack.sh (Linux or macOS; on Windows use WSL).
  • Mission Control connected to a drone that runs the ADOS Drone Agent.

1. Clone and scaffold

The hybrid template lays out both halves with their tests:

2. The manifest

The generated manifest.yaml declares both halves. The parts that matter, with the template’s __PLUGIN_ID__ already filled in:
Labels such as skill.label are keys into locales/en.json. There is no supported_boards, so the plugin installs on any board; to restrict it, list board ids or SoCs from Supported hardware, or "*" for any board.
1

skills: the Skill Bar

ui.slot.flight-skill puts the entry in the cockpit Skill Bar, bound to h. Toggling it writes the per-drone config key active; the bar reads the live state from the hello.state event topic.
2

tabs: the node-detail tab

ui.slot.node-detail-tab mounts the GCS bundle as a tab on the drone’s detail panel. The bundle renders the agent’s read-back.
3

parameters: the native form

Mission Control renders these controls itself; the bundle does not draw them. binding: plugin.config writes the value to the plugin’s per-drone config, which the agent half reads live. The detector parameter binds to engine.detector, so picking a model switches the drone’s shared vision detector.
The template also carries a commented-out models block with per-board variants. Enable it only once source points at a real artifact and sha256 is that file’s digest; see Contribution points.

3. The agent half

agent/plugin.py defines a plain class with the lifecycle hooks the runner calls. It reads its per-drone config live on every cycle and publishes the read-back the Skill Bar and the tab consume:
activation.via: config means the Skill toggle is a config write the host routes to the agent; the plugin sees it on its next ctx.config_kv.get. ctx.config is the static config loaded at start; use ctx.config_kv for values that change while the plugin runs. See the Python SDK for the full context.

4. Follow a clicked target

To make the plugin follow a person the operator clicks in the cockpit video, the agent half subscribes to detections and the GCS half declares a target action. Add vision.detection.subscribe to agent.permissions, then subscribe in on_start:
Then add a target_actions block under gcs.contributes:
When the operator clicks a person and picks Follow this target, Mission Control designates that box to the drone’s vision tracker and writes active: true to the plugin’s config. The action inherits the confirm and arm gates of any skill that writes the same config_key. Mission Control performs both steps, so a target action needs no extra GCS permission. A GCS half that designates from its own UI instead calls ctx.command.send("vision.designate", { camera_id, bbox: { x, y, width, height } }). That needs vision.track.designate under gcs.permissions; command.send alone does not allow designation, and the operator confirms every designation.
A plugin that steers the vehicle needs flight capabilities on its agent half (mavlink.write, flight.guided_setpoint) and a risk of at least high. Read Safety and test on a simulator before any flight.

5. Test

From the plugin folder, the template’s test script runs both halves:
That runs vitest in gcs/ and then uv run pytest in agent/.

6. Pack, sign and install

From the monorepo root:
pack.sh builds the GCS bundle, checks that the declared entrypoints are present, and zips the result. sign.sh writes com.example.track-follow-0.1.0.signed.adosplug. The drone must trust my-publisher-2026-A: enrol its public key as described in Bench install and signing. Open the drone from the fleet, switch to its Extensions tab, choose Install from file and drop in the .signed.adosplug. Approve the permissions and enable the extension.

Verify each contribution

1

Skill Bar

Open the drone’s cockpit. The Hello skill is in the Skill Bar, bound to h. Press it; the per-drone config key active flips.
2

Node-detail tab

Open the drone’s detail panel. The Hello tab shows the live read-back from the agent half.
3

Parameters

The Behavior group shows the rate slider, the greeting dropdown and the detector picker. Edits clamp to the schema bounds.
4

Target action

With a detector running, click a person in the cockpit video. The popup offers Follow this target.

Next steps

Contribution points

Every contribution kind in detail.

Parameter schema

Widgets, bindings and validation.

Python SDK

The agent-half context.

Vision plugins

Detectors, models and the vision engine.
Last modified on October 11, 2026