Skip to main content
ctx.flight (PluginFlightAccessor) lets you read live flight state, subscribe to flight-lifecycle events, write to the flight log, and gate flight starts.
// Reads (snapshots)
const state = await ctx.flight.getState(); // FlightManagerPayload
const sim = await ctx.flight.getSnapshot(); // SimDataSnapshot | null
const phase = await ctx.flight.getPhase(); // FlightPhaseSnapshot
const landing = await ctx.flight.getLandingReport(); // LandingAnalysisSnapshot

// Subscriptions — each returns an unsubscribe the shell also tears down on unload
const off = ctx.flight.onPhaseChange((p) => {
  ctx.logger.info("MyPlugin", `Phase ${p.previousPhase}${p.currentPhase}`);
});
ctx.flight.onUpdate((s) => {
  /* flight-manager state changed */
});
ctx.flight.onSimData((snap) => {
  /* live sim frame */
});
ctx.flight.onLanding((l) => {
  /* touchdown / bounce / settled */
});

ctx.flight.logPluginFlightLogWriter

Add, remove, and update flight-log events. Events added here are authoritative flight-log telemetry — they appear in the Flight Log and are submitted to the VA like any other event.
const event = await ctx.flight.log.add({
  category: EventCategory.SYSTEM,
  condition: "myplugin_gate",
  message: "Departure Gate 03A",
});

if (event) {
  await ctx.flight.log.update(event.eventId, { message: "Departure Gate 03B" });
  await ctx.flight.log.remove(event.eventId);
}

ctx.flight.registerStartGuard(guard) — gate flight starts

A guard runs inside startFlight before the flight is created or persisted, covering both manual and auto-start. Returning { allow: false, reason } vetoes the start: it appears in the pre-flight check dialog as a check titled with your plugin’s name and described by the reason, shown alongside the built-in checks (and any other plugins’ guards). The pilot can still Start Anyway, which bypasses every check, guards included. Guards are fail-open: a throw or a >5s hang allows the start with a loud warning.
const off = ctx.flight.registerStartGuard(
  async ({ plan, snapshot, isAutoStart }) => {
    if (!hasProfileFor(snapshot)) {
      return { allow: false, reason: "No aircraft profile synced" };
    }
    return { allow: true };
  },
);
When to use it: to react to the flight lifecycle from the background — logging milestones, mirroring flight data somewhere, or blocking a start until your plugin is ready. For the same data in a UI component, the renderer hooks (useFlightPhase, useSimData, useTrackingSession) are usually simpler.