Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.
ctx.flight (PluginFlightAccessor) lets you read live flight state, subscribe to flight-lifecycle events, write to the flight log, gate flight starts, and attach your own data to the PIREP.
// Reads (snapshots)const state = await ctx.flight.getState(); // FlightManagerPayloadconst sim = await ctx.flight.getSnapshot(); // SimDataSnapshot | nullconst phase = await ctx.flight.getPhase(); // FlightPhaseSnapshotconst landing = await ctx.flight.getLandingReport(); // LandingAnalysisSnapshot// Subscriptions: each returns an unsubscribe the shell also tears down on unloadconst 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 */});
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.
A guard runs inside startFlightbefore 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.
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.
ctx.flight.attachToPirepSubmission(handler): put your data on the PIREP
A handler runs while the airline PIREP is being assembled, after every milestone capture and immediately before the body is posted. Whatever it returns is attached to the submission under plugin_data["<your-plugin-id>"]. Return null to attach nothing for that flight.
Keying by plugin ID means two plugins can both send a score without colliding.plugin_data is a reserved top-level key on the submission body: it is added after the airline’s own custom submission fields are spread in, so an airline that names a submission field plugin_data has it silently overwritten. Avoid that name when configuring submission fields.The handler receivesflightId (local flight id), stratosFlightId, vaTrackingId, status (completed, diverted or crashed), plan and snapshot.It is fail-open. A throw, a rejection, a hang past 3s, a non-object return, or data over the size limit below omits your plugin’s key and logs a warning. The PIREP is submitted either way. A broken plugin can never cost a pilot their PIREP.The data you return is capped at 256 KB per plugin, and 512 KB across all plugins. This is measured on the JSON your handler returns, and keeps the PIREP body small enough for an airline’s server to accept. If one plugin’s data would push the total past 512 KB, that plugin’s data is dropped and the rest are still included if they fit. Files you attach with attachFile() do not count towards either limit: in the JSON, an attached file is only a short reference, and the file itself is sent separately (see Attaching files).Handlers must be idempotent. If the airline rejects a PIREP the pilot can retry, and a retry runs every handler again. Do not write records, send requests, or mutate state from a handler; read what you already captured and return it.When it does not run: cancelled flights (nothing is filed) and flights with no airline bound. Registering more than one handler is allowed; their results are shallow-merged under your single plugin key, later fields winning.
plugin_data reaches the airline only. It is not sent to Skyvex Software, so it
does not appear in Skyvex Software flight records or analytics.
The airline receives the submission as multipart/form-data: your JSON with each attachment replaced by { "$file": "<part name>" }, and each file as its own part under that name.attachFile() only records the file’s path; it doesn’t open or read the file. Stratos reads it later, when the PIREP is sent, streaming it from disk rather than loading it into memory. So calling attachFile() never throws and never slows your handler, even for a large file or one that has since been deleted. If the file can’t be read when the PIREP is sent, it is skipped, its reference becomes { "$file": null, "error": "..." }, and the flight still files.Attached files have no size or count limit. Stratos passes them straight through; your plugin and the airline’s backend own their own limits. This is separate from the 256 KB limit on the JSON data you return, which files don’t count towards.
Attaching a file changes how the PIREP is encoded for that submission, which
your airline’s backend must be built to accept. See PIREP file
attachments before shipping a plugin that uses
this, and declare "attaches_files_to_pirep": true in your plugin.json as
advisory metadata.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Skyvex Software","colors":{"primary":"#1847ED","light":"#4D7AFF","dark":"#1847ED"},"logo":{"light":"https://mintcdn.com/skyvexsoftware/6_XhdPqMDHXpebNZ/logo/light.svg?fit=max\u0026auto=format\u0026n=6_XhdPqMDHXpebNZ\u0026q=85\u0026s=b7646e33ca0db1bb774ae0adfe5f103a","dark":"https://mintcdn.com/skyvexsoftware/6_XhdPqMDHXpebNZ/logo/dark.svg?fit=max\u0026auto=format\u0026n=6_XhdPqMDHXpebNZ\u0026q=85\u0026s=61b26441250e511c3e7a739f31eedddb","href":"/introduction"},"favicon":"https://mintcdn.com/skyvexsoftware/NSjGwMiBraCrWUYE/favicon.ico?fit=max\u0026auto=format\u0026n=NSjGwMiBraCrWUYE\u0026q=85\u0026s=a1ce6302b2fe1ff044d20452445f7603","background":{"image":{"light":"https://mintcdn.com/skyvexsoftware/FOlDtkFINCHJBZH_/images/background-light.svg?fit=max\u0026auto=format\u0026n=FOlDtkFINCHJBZH_\u0026q=85\u0026s=f94dbe916d3ee8d4d95a6f36abfa7926","dark":"https://mintcdn.com/skyvexsoftware/FOlDtkFINCHJBZH_/images/background-dark.svg?fit=max\u0026auto=format\u0026n=FOlDtkFINCHJBZH_\u0026q=85\u0026s=aecbc4920e445f0aebe89ee6364f0149"},"decoration":"grid"},"navbar":{"links":[{"href":"https://skyvexsoftware.com/login","label":"Sign in"}],"primary":{"type":"button","label":"Request access","href":"https://skyvexsoftware.com/#waitlist"}},"footer":{"socials":{"website":"https://skyvexsoftware.com","discord":"https://discord.skyvexsoftware.com"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","cursor","vscode"],"display":"header"},"thumbnails":{"preset":"headline","appearance":"dark","surface":"neutral","background":"https://mintcdn.com/skyvexsoftware/tdbSYF_jOAOeZ9Zz/images/og-background.png?fit=max\u0026auto=format\u0026n=tdbSYF_jOAOeZ9Zz\u0026q=85\u0026s=e0bd2e1beaa969bbd3b8271a664afe6a","fonts":{"family":"Geist","source":"fonts/Geist-Medium.ttf","format":"ttf"},"eyebrow":{"style":"plain","color":"#9DB7FF"}},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"Skyvex Software","icon":"home","href":"https://skyvexsoftware.com"},{"anchor":"Download (v2.26.0)","icon":"download","href":"https://skyvexsoftware.com/download"},{"anchor":"Stratos SDK (v0.27.0)","icon":"npm","href":"https://www.npmjs.com/package/@skyvexsoftware/stratos-sdk"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"skyvexsoftware","hasAudioNarration":false,"actualSubdomain":"skyvexsoftware","customDomains":["docs.skyvexsoftware.com"],"gitSource":{"type":"github","owner":"skyvexsoftware","repo":"stratos","deployBranch":"main","contentDirectory":"packages/docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae7c6f56bddb0a059f6cfc2","collectionId":"99361958-8ff4-49f2-9039-0c7ebd921b40","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae7c6f56bddb0a059f6cfc2"},"feedback":{"thumbs":true,"agentFeedback":true},"entitlements":{},"buildId":"6ae7c6f56bddb0a059f6cfc2","clientVersion":"0.0.4045","searchFilterCounts":[{"language":"default","tag":"Plugin SDK","count":44},{"language":"default","tag":"Console","count":33},{"language":"default","tag":"Stratos","count":25},{"language":"default","tag":"API Reference","count":18},{"language":"default","tag":"Background Module","count":16},{"language":"default","tag":"Endpoints","count":16},{"language":"default","tag":"UI Module","count":14},{"language":"default","tag":"Plugin Context (ctx)","count":13},{"language":"default","tag":"Get Started","count":12},{"language":"default","tag":"Hooks","count":11}],"searchSettings":{"maxResults":10}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"sdk/background/context/flight","slug":"/sdk/background/context/flight","pageMetadata":{"title":"ctx.flight","description":"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.","href":"/sdk/background/context/flight"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,..._provideComponents(),...props.components},{CodeBlock,Heading,Note,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.code,{children:`ctx.flight`}),` (`,_jsx(_components.code,{children:`PluginFlightAccessor`}),`) lets you read live flight state, subscribe to flight-lifecycle events, write to the flight log, gate flight starts, and attach your own data to the PIREP.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`19`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`19`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Reads (snapshots)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` state`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getState`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// FlightManagerPayload`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` sim`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getSnapshot`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// SimDataSnapshot | null`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` phase`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getPhase`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// FlightPhaseSnapshot`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` landing`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getLandingReport`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// LandingAnalysisSnapshot`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Subscriptions: each returns an unsubscribe the shell also tears down on unload`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` off`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`onPhaseChange`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`p`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`logger`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"MyPlugin\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`Phase \"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`p`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`previousPhase`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` → `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`p`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`currentPhase`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`onUpdate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`s`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* flight-manager state changed */`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`onSimData`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`snap`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* live sim frame */`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`onLanding`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`l`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* touchdown / bounce / settled */`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`2`,id:`ctx-flight-log-pluginflightlogwriter`,children:[_jsx(_components.code,{children:`ctx.flight.log`}),`: `,_jsx(_components.code,{children:`PluginFlightLogWriter`})]}),`\n`,_jsx(_components.p,{children:`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.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` event`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`log`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`add`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` category:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` EventCategory`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`SYSTEM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` condition:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"myplugin_gate\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` message:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Departure Gate 03A\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`log`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`update`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`eventId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`message:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Departure Gate 03B\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`log`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`remove`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`eventId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`2`,id:`ctx-flight-registerstartguard-guard--gate-flight-starts`,children:[_jsx(_components.code,{children:`ctx.flight.registerStartGuard(guard)`}),`: gate flight starts`]}),`\n`,_jsxs(_components.p,{children:[`A guard runs inside `,_jsx(_components.code,{children:`startFlight`}),` `,_jsx(_components.strong,{children:`before the flight is created or persisted`}),`, covering both manual and auto-start. Returning `,_jsx(_components.code,{children:`{ allow: false, reason }`}),` vetoes the start: it appears in the pre-flight check dialog as a check `,_jsx(_components.strong,{children:`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 `,_jsx(_components.strong,{children:`Start Anyway`}),`, which bypasses every check, guards included. Guards are `,_jsx(_components.strong,{children:`fail-open`}),`: a throw or a >5s hang allows the start with a loud warning.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` off`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`registerStartGuard`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ({ `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`plan`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`snapshot`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`isAutoStart`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`hasProfileFor`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`snapshot`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`allow:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`reason:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"No aircraft profile synced\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`allow:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`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 (`,_jsx(_components.a,{href:`/sdk/hooks/use-flight-phase`,children:_jsx(_components.code,{children:`useFlightPhase`})}),`, `,_jsx(_components.a,{href:`/sdk/hooks/use-sim-data`,children:_jsx(_components.code,{children:`useSimData`})}),`, `,_jsx(_components.a,{href:`/sdk/hooks/use-tracking-session`,children:_jsx(_components.code,{children:`useTrackingSession`})}),`) are usually simpler.`]}),`\n`,_jsxs(Heading,{level:`2`,id:`ctx-flight-attachtopirepsubmission-handler--put-your-data-on-the-pirep`,children:[_jsx(_components.code,{children:`ctx.flight.attachToPirepSubmission(handler)`}),`: put your data on the PIREP`]}),`\n`,_jsxs(_components.p,{children:[`A handler runs while the airline PIREP is being assembled, after every milestone capture and immediately before the body is posted. Whatever it returns is attached to the submission under `,_jsx(_components.code,{children:`plugin_data[\"\u003cyour-plugin-id>\"]`}),`. Return `,_jsx(_components.code,{children:`null`}),` to attach nothing for that flight.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` off`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`attachToPirepSubmission`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`async`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`sub`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` report`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` getReport`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sub`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flightId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`report`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`score:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` report`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`score`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`grade:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` report`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`grade`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The airline receives:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"tracking_id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"...\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"landing_rate\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`-142`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"plugin_data\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"your-plugin-id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"score\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`87`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"grade\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"B\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Keying by plugin ID means two plugins can both send a `,_jsx(_components.code,{children:`score`}),` without colliding.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`plugin_data`}),` is a reserved top-level key on the submission body: it is added after the airline’s own custom submission fields are spread in, so an airline that names a submission field `,_jsx(_components.code,{children:`plugin_data`}),` has it silently overwritten. Avoid that name when configuring submission fields.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The handler receives`}),` `,_jsx(_components.code,{children:`flightId`}),` (local flight id), `,_jsx(_components.code,{children:`stratosFlightId`}),`, `,_jsx(_components.code,{children:`vaTrackingId`}),`, `,_jsx(_components.code,{children:`status`}),` (`,_jsx(_components.code,{children:`completed`}),`, `,_jsx(_components.code,{children:`diverted`}),` or `,_jsx(_components.code,{children:`crashed`}),`), `,_jsx(_components.code,{children:`plan`}),` and `,_jsx(_components.code,{children:`snapshot`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`It is fail-open.`}),` A throw, a rejection, a hang past 3s, a non-object return, or data over the size limit below omits your plugin’s key and logs a warning. The PIREP is submitted either way. A broken plugin can never cost a pilot their PIREP.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The data you return is capped at 256 KB per plugin, and 512 KB across all plugins.`}),` This is measured on the JSON your handler returns, and keeps the PIREP body small enough for an airline’s server to accept. If one plugin’s data would push the total past 512 KB, that plugin’s data is dropped and the rest are still included if they fit. Files you attach with `,_jsx(_components.code,{children:`attachFile()`}),` do `,_jsx(_components.strong,{children:`not`}),` count towards either limit: in the JSON, an attached file is only a short reference, and the file itself is sent separately (see `,_jsx(_components.a,{href:`#attaching-files`,children:`Attaching files`}),`).`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Handlers must be idempotent.`}),` If the airline rejects a PIREP the pilot can retry, and a retry runs every handler again. Do not write records, send requests, or mutate state from a handler; read what you already captured and return it.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When it does not run:`}),` cancelled flights (nothing is filed) and flights with no airline bound. Registering more than one handler is allowed; their results are shallow-merged under your single plugin key, later fields winning.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`plugin_data`}),` reaches the airline only. It is not sent to Skyvex Software, so it\ndoes not appear in Skyvex Software flight records or analytics.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`attaching-files`,children:`Attaching files`}),`\n`,_jsxs(_components.p,{children:[`Wrap a path in `,_jsx(_components.code,{children:`attachFile()`}),` anywhere inside the object you return, and the shell delivers the file to your airline with the PIREP.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`attachFile`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"@skyvexsoftware/stratos-sdk\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ctx`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flight`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`attachToPirepSubmission`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`async`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`sub`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` receipts`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` groundOps`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`receiptsFor`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sub`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`flightId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`receipts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:`length`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` provider_version:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"4.1\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` receipts:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` receipts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`map`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`r`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` attachFile`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`r`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`path`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The airline receives the submission as `,_jsx(_components.code,{children:`multipart/form-data`}),`: your JSON with each attachment replaced by `,_jsx(_components.code,{children:`{ \"$file\": \"\u003cpart name>\" }`}),`, and each file as its own part under that name.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`attachFile()`}),` only records the file’s path; it doesn’t open or read the file. Stratos reads it later, when the PIREP is sent, streaming it from disk rather than loading it into memory. So calling `,_jsx(_components.code,{children:`attachFile()`}),` never throws and never slows your handler, even for a large file or one that has since been deleted. If the file can’t be read when the PIREP is sent, it is skipped, its reference becomes `,_jsx(_components.code,{children:`{ \"$file\": null, \"error\": \"...\" }`}),`, and the flight still files.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Attached files have no size or count limit.`}),` Stratos passes them straight through; your plugin and the airline’s backend own their own limits. This is separate from the 256 KB limit on the JSON data you return, which files don’t count towards.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Attaching a file changes how the PIREP is encoded for that submission, which\nyour airline’s backend must be built to accept. See `,_jsx(_components.a,{href:`/sdk/pirep-file-attachments`,children:`PIREP file\nattachments`}),` before shipping a plugin that uses\nthis, and declare `,_jsx(_components.code,{children:`\"attaches_files_to_pirep\": true`}),` in your `,_jsx(_components.code,{children:`plugin.json`}),` as\nadvisory metadata.`]})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"ctx.flight","description":"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.","href":"/sdk/background/context/flight"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"ctx.flight.log: PluginFlightLogWriter","slug":"ctx-flight-log-pluginflightlogwriter","depth":2,"children":[]},{"title":"ctx.flight.registerStartGuard(guard): gate flight starts","slug":"ctx-flight-registerstartguard-guard--gate-flight-starts","depth":2,"children":[]},{"title":"ctx.flight.attachToPirepSubmission(handler): put your data on the PIREP","slug":"ctx-flight-attachtopirepsubmission-handler--put-your-data-on-the-pirep","depth":2,"children":[{"title":"Attaching files","slug":"attaching-files","depth":3,"children":[]}]}],"codeExamples":{}},"jsLinks":[],"subdomain":"skyvexsoftware","siteName":"Skyvex Software","title":"ctx.flight - Skyvex Software","navMaps":{"firstHrefInVersion":{"Stratos":{"href":"/sdk/background/context/flight","matchLevel":0}},"firstHrefInLanguage":{}},"lastModified":"2026-10-10T11:44:11.443Z","originalFileLocation":"sdk/background/context/flight.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Skyvex Software\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"ctx.flight - Skyvex Software\">\u003cmeta data-mint-head property=\"og:description\" content=\"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Skyvex Software\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.skyvexsoftware.com/sdk/background/context/flight\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://skyvexsoftware.mintlify.app/_mintlify/api/og/v2?division=Plugin+Context+%28ctx%29\u0026amp;title=ctx.flight\u0026amp;description=Live+flight+state%2C+subscriptions%2C+the+flight+log%2C+start+guards%2C+and+PIREP+attachments%2C+from+a+background+module.\u0026amp;theme=5ac93a8f3cc242debdc3501c\u0026amp;signature=4f83781f35eab32d3963f316a62eda091931fef5a318423e895cc11eedcdab09\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"ctx.flight - Skyvex Software\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://skyvexsoftware.mintlify.app/_mintlify/api/og/v2?division=Plugin+Context+%28ctx%29\u0026amp;title=ctx.flight\u0026amp;description=Live+flight+state%2C+subscriptions%2C+the+flight+log%2C+start+guards%2C+and+PIREP+attachments%2C+from+a+background+module.\u0026amp;theme=5ac93a8f3cc242debdc3501c\u0026amp;signature=4f83781f35eab32d3963f316a62eda091931fef5a318423e895cc11eedcdab09\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/skyvexsoftware/WC7Gk2NUvCVAfBEZ/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Skyvex Software\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#1847ED\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.skyvexsoftware.com/sdk/background/context/flight\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/sdk/background/context/flight.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.skyvexsoftware.com/#organization\",\"name\":\"Skyvex Software\",\"url\":\"https://docs.skyvexsoftware.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/skyvexsoftware/6_XhdPqMDHXpebNZ/logo/light.svg?fit=max\u0026auto=format\u0026n=6_XhdPqMDHXpebNZ\u0026q=85\u0026s=b7646e33ca0db1bb774ae0adfe5f103a\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.skyvexsoftware.com#website\",\"name\":\"Skyvex Software\",\"url\":\"https://docs.skyvexsoftware.com\",\"publisher\":{\"@id\":\"https://docs.skyvexsoftware.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight#webpage\",\"url\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight\",\"name\":\"ctx.flight\",\"description\":\"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\",\"dateModified\":\"2026-10-10T11:44:11.443Z\",\"isPartOf\":{\"@id\":\"https://docs.skyvexsoftware.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Background Module\",\"item\":\"https://docs.skyvexsoftware.com/sdk/background/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Plugin Context (ctx)\",\"item\":\"https://docs.skyvexsoftware.com/sdk/background/context/overview\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"ctx.flight\",\"item\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight#article\",\"headline\":\"ctx.flight\",\"name\":\"ctx.flight\",\"description\":\"Live flight state, subscriptions, the flight log, start guards, and PIREP attachments, from a background module.\",\"url\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight\",\"mainEntityOfPage\":{\"@id\":\"https://docs.skyvexsoftware.com/sdk/background/context/flight#webpage\"},\"dateModified\":\"2026-10-10T11:44:11.443Z\",\"publisher\":{\"@id\":\"https://docs.skyvexsoftware.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.skyvexsoftware.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Skyvex Software\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Skyvex Software","nav":{"global":{"anchors":[{"anchor":"Skyvex Software","icon":"home","href":"https://skyvexsoftware.com"},{"anchor":"Download (v2.26.0)","icon":"download","href":"https://skyvexsoftware.com/download"},{"anchor":"Stratos SDK (v0.27.0)","icon":"npm","href":"https://www.npmjs.com/package/@skyvexsoftware/stratos-sdk"}]},"versions":[{"version":"Stratos","tabs":[{"tab":"Stratos","pages":[{"title":"Stratos","href":"/introduction"}]},{"tab":"Console","pages":[{"title":"Console","href":"/guide/va-onboarding"}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference/introduction"}]},{"tab":"Plugin SDK","groups":[{"group":"Get Started","pages":[{"title":"Plugin SDK","href":"/sdk/overview"},{"title":"Getting Started","href":"/sdk/getting-started"},{"title":"Architecture","href":"/sdk/architecture"},{"title":"Developer Mode","href":"/sdk/developer-mode"}]},{"group":"Developer centre","pages":[{"title":"The Developer centre","href":"/sdk/developer-centre"},{"title":"How we review plugins","href":"/guide/plugin-review"},{"title":"Private plugins","href":"/guide/private-plugins"},{"title":"Listing screenshots","href":"/sdk/screenshots"},{"title":"Verified developers","href":"/sdk/verified-developers"}]},{"group":"Plugin Basics","pages":[{"title":"Plugin Manifest","href":"/sdk/manifest"},{"title":"Plugin Settings","href":"/sdk/settings"}]},{"group":"UI Module","pages":[{"title":"UI Module","href":"/sdk/ui-module"},{"title":"Sub-Page Routing","href":"/sdk/routing"},{"title":"Components","href":"/sdk/ui-components"},{"group":"Hooks","pages":[{"title":"Hooks Overview","href":"/sdk/hooks/overview"},{"title":"usePluginContext","href":"/sdk/hooks/use-plugin-context"},{"title":"useSimData \u0026 Socket Hooks","href":"/sdk/hooks/use-sim-data"},{"title":"useFlightPhase","href":"/sdk/hooks/use-flight-phase"},{"title":"useFlightEvents","href":"/sdk/hooks/use-flight-events"},{"title":"useFlightManager","href":"/sdk/hooks/use-flight-manager"},{"title":"useTrackingSession","href":"/sdk/hooks/use-tracking-session"},{"title":"useLandingAnalysis","href":"/sdk/hooks/use-landing-analysis"},{"title":"useShellAuth","href":"/sdk/hooks/use-shell-auth"},{"title":"useVaApi","href":"/sdk/hooks/use-va-api"},{"title":"Shell Utility Hooks","href":"/sdk/hooks/use-shell-hooks"}]}]},{"group":"Background Module","pages":[{"title":"Background Module","href":"/sdk/background/overview"},{"group":"Plugin Context (ctx)","pages":[{"title":"Plugin Context","href":"/sdk/background/context/overview"},{"title":"ctx.logger","href":"/sdk/background/context/logger"},{"title":"ctx.config","href":"/sdk/background/context/config"},{"title":"ctx.ipc","href":"/sdk/background/context/ipc"},{"title":"ctx.auth","href":"/sdk/background/context/auth"},{"title":"ctx.airline","href":"/sdk/background/context/airline"},{"title":"ctx.database","href":"/sdk/background/context/database"},{"title":"ctx.server","description":"Mounting Express routes on the shell's local HTTP server from a background module.","href":"/sdk/background/context/server"},{"title":"ctx.flight","href":"/sdk/background/context/flight"},{"title":"ctx.notify","description":"Fire-and-forget toasts and sounds from a background module.","href":"/sdk/background/context/notify"},{"title":"ctx.dialog","href":"/sdk/background/context/dialog"},{"title":"ctx.prompt","href":"/sdk/background/context/prompt"},{"title":"ctx.plugin","href":"/sdk/background/context/plugin"}]},{"title":"Background ↔ UI Communication","href":"/sdk/background/communication"},{"title":"PIREP File Attachments","href":"/sdk/pirep-file-attachments"}]},{"group":"Deploy","pages":[{"title":"Build \u0026 Deploy","href":"/sdk/build-and-deploy"},{"title":"Best Practices","href":"/sdk/best-practices"}]},{"group":"Type Reference","pages":[{"title":"Type Reference","href":"/sdk/type-reference"}]}]}]}]},"basePath":"","title":"ctx.flight - Skyvex Software","buildId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","deploymentId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","dynamics":[],"chunks":[]}