> ## Documentation Index
> Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mission plugins

> Read and write missions from a GCS plugin and contribute a mission template.

Mission planning is an extension point the GCS exposes to plugins. A
plugin can read the active mission, write changes back, and register a
mission template the operator picks from the template list.

Higher-level flight behaviors (Follow-Me, Orbit, thermal overlay, gimbal
control, and the like) are scoped per-drone and ship through the
[extensions registry](/mission-control/installing-plugins). See
[Multi-component plugins](/developers/multi-component-plugins) for the
per-drone tab pattern those use.

## Capabilities

| Capability                 | Lets the plugin...                           |
| -------------------------- | -------------------------------------------- |
| `mission.read`             | Read the active mission and its items.       |
| `mission.write`            | Upload, edit, or replace the mission.        |
| `ui.slot.mission-template` | Add an entry to the mission template picker. |

`mission.write` is high risk; the operator sees a warning badge, because
mission changes drive autonomous flight paths.

## Reading and writing missions

The GCS context exposes `ctx.mission`. `read` takes a mission id and
returns the mission; `write` takes a single update object with the
mission id and the payload:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
// read
const mission = await ctx.mission.read("active");

// write
await ctx.mission.write({
  missionId: "active",
  payload: {
    items: [
      { kind: "waypoint", lat: 12.97, lng: 77.59, alt_agl_m: 30 },
    ],
  },
});
```

The host validates the mission against the flight controller's accepted
item types and rejects malformed writes. The validation rules are
firmware-specific (ArduPilot accepts different commands than Betaflight),
and the host applies the right rule set automatically.

## Contributing a mission template

A plugin that wants to offer the operator a new way to start a mission
declares the `ui.slot.mission-template` capability and adds a template
entry to the mission template picker. The plugin renders its own form in
its sandboxed UI, gathers the operator's input, generates the waypoints,
and writes them back with `ctx.mission.write`. The waypoint geometry runs
in the plugin's own code; the GCS provides the picker entry, the form
surface, and the validated write path.

Declare the capabilities in the manifest:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
gcs:
  permissions:
    - id: ui.slot.mission-template
    - id: mission.write
```

The `ui.slot.mission-template` capability registers the template entry;
`mission.write` lets the plugin push the generated waypoints once the
operator confirms.

## Geofence and rally points

Geofence and rally definitions ride the same `ctx.mission.write` path
with their own mission id. The host enforces a fixed schema for fence and
rally items and rejects unknown kinds, so write the items the host
accepts and let it validate them before upload.

## Testing

Exercise the mission read and write path against the in-memory harness
from `@altnautica/plugin-sdk/harness`. The harness records every RPC the
plugin issues so you can assert on the calls without a live GCS:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { createPluginHarness } from "@altnautica/plugin-sdk/harness";

const harness = createPluginHarness({
  grantedCapabilities: ["mission.read", "mission.write"],
  mount: async (ctx) => {
    await ctx.mission.write({
      missionId: "active",
      payload: { items: [] },
    });
  },
});

await harness.start();
expect(harness.calls).toContainEqual(
  expect.objectContaining({ method: "mission.write" }),
);
await harness.teardown();
```

## See also

* [Permissions](/developers/permissions)
* [Vision plugins](/developers/vision-plugins)
* [Multi-component plugins](/developers/multi-component-plugins)
* [Installing plugins](/mission-control/installing-plugins)
