@skyvexsoftware/stratos-sdk 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { PluginAuthor, PluginManifest } from "./types/manifest";
2
- export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginVaApiClient, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginPilotUser, PluginServerRegistrar, PluginToastAPI, PluginUIContext, PluginSettingType, PluginSettingOption, PluginSettingDefinition, PluginAvailableSettings, BooleanSettingDef, TextSettingDef, LongtextSettingDef, NumberSettingDef, RangeSettingDef, ListSettingDef, RadioSettingDef, DateSettingDef, JsonSettingDef, } from "./types/context";
2
+ export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginVaApiClient, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginPilotUser, PluginServerRegistrar, PluginToastAPI, PluginUIContext, PluginFlightAccessor, PluginFlightLogWriter, PluginFlightLogInput, PluginFlightLogPatch, PluginStartGuard, PluginStartContext, PluginStartDecision, PluginNotifier, PluginToastInput, PluginAlertSound, PluginDialogApi, PluginPromptApi, PluginDialogAlertInput, PluginDialogConfirmInput, PluginPromptTextInput, PluginPromptNumberInput, PluginPromptSelectInput, PluginSettingType, PluginSettingOption, PluginSettingDefinition, PluginAvailableSettings, BooleanSettingDef, TextSettingDef, LongtextSettingDef, NumberSettingDef, RangeSettingDef, ListSettingDef, RadioSettingDef, DateSettingDef, JsonSettingDef, } from "./types/context";
3
3
  export type { PluginBackgroundModule, PluginRouteComponent, PluginUIModule, } from "./types/module";
4
4
  export { FlightPhase, SimulatorType, EventCategory, } from "./shared-types/simulator";
5
5
  export type { BounceData, CapturePoint, FlightData, FlightDataSnapshot, FlightEventPayload, FlightEventsSnapshot, FlightLandingPayload, FlightLogEvent, FlightPhasePayload, FlightPhaseSnapshot, FlightStateDebugInfo, FlightTrends, GateCapture, HistoryReportEntry, LandingAnalysis, LandingAnalysisSnapshot, LandingAnalyzerDebugState, LandingSample, PendingPhaseTransition, SimDataSnapshot, SimulatorStatus, } from "./shared-types/simulator";
@@ -30,6 +30,7 @@ export { useShellToast } from "./hooks/useShellToast";
30
30
  export { useSocket, useSimulatorData, useProtocolUrl, useNotifications, useSystemMetrics, } from "./hooks/useSimulatorData";
31
31
  export { SOCKET_EVENTS } from "./shared-types/socket-events";
32
32
  export type { AutoStartConfirmPayload, ConnectionState, LogEntryPayload, NotificationPayload, ProtocolUrlPayload, SimulatorDataPayload, SimulatorStatusPayload, SocketEventName, SystemMetricsPayload, } from "./shared-types/socket-events";
33
+ export type { PluginDialogKind, PluginDialogSelectOption, PluginDialogSpec, PluginDialogResult, PluginDialogClosePayload, } from "./shared-types/plugin-dialogs";
33
34
  export { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, Badge, badgeVariants, Button, buttonVariants, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Combobox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Input, Label, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RadioGroup, RadioGroupItem, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "./ui";
34
35
  export type { BadgeProps, ButtonProps, ComboboxOption, ComboboxProps, } from "./ui";
35
36
  export { STRATOS_ICONS, STRATOS_ICON_NAMES } from "./icons";
@@ -79,6 +79,8 @@ export type PreflightCheckResult = {
79
79
  /** Options for startFlight */
80
80
  export type StartFlightOptions = {
81
81
  forceStart?: boolean;
82
+ /** True when the start was triggered by auto-start (not a manual click). Surfaced to plugin start guards. */
83
+ isAutoStart?: boolean;
82
84
  };
83
85
  /** Lean subset of stored flight data for recovery prompt in the renderer */
84
86
  export type RecoverableFlight = {
@@ -6,4 +6,5 @@ export type { AdditionalFieldsConfig, FieldDelivery, } from "./additional-fields
6
6
  export type { FlightPlan, FlightStatus, CurrentFlight, FlightComment, PreflightCheck, PreflightCheckResult, StartFlightOptions, FlightManagerPayload, StartFlightResult, RecoverableFlight, } from "./flight-manager";
7
7
  export { SOCKET_EVENTS } from "./socket-events";
8
8
  export type { ConnectionState, LogEntryPayload, NotificationPayload, ProtocolUrlPayload, SimulatorDataPayload, SimulatorStatusPayload, SocketEventName, SystemMetricsPayload, } from "./socket-events";
9
+ export type { PluginDialogKind, PluginDialogSelectOption, PluginDialogSpec, PluginDialogResult, PluginDialogClosePayload, } from "./plugin-dialogs";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Wire types for the background-plugin dialog/prompt surface.
3
+ *
4
+ * A `PluginDialogSpec` is broadcast to the renderer (SOCKET_EVENTS.DIALOG_OPEN)
5
+ * and also served by GET /api/plugin-dialogs for hydrate. The renderer posts a
6
+ * `PluginDialogResult` back. The wire value is always a string (or absent) — the
7
+ * typed coercion to boolean/number/null lives in the loader wrappers.
8
+ */
9
+ export type PluginDialogKind = "alert" | "confirm" | "text" | "number" | "select";
10
+ export type PluginDialogSelectOption = {
11
+ value: string;
12
+ label: string;
13
+ };
14
+ /** Fully-resolved spec for one open dialog. */
15
+ export type PluginDialogSpec = {
16
+ requestId: string;
17
+ pluginId: string;
18
+ pluginName: string;
19
+ kind: PluginDialogKind;
20
+ title: string;
21
+ /** Body text (dialogs) or helper text above the field (prompts). */
22
+ message?: string;
23
+ /** Field label (prompts only). */
24
+ label?: string;
25
+ placeholder?: string;
26
+ /** Pre-filled value (always a string on the wire; number prompts stringify it). */
27
+ defaultValue?: string;
28
+ required?: boolean;
29
+ maxLength?: number;
30
+ min?: number;
31
+ max?: number;
32
+ step?: number;
33
+ options?: PluginDialogSelectOption[];
34
+ okLabel?: string;
35
+ confirmLabel?: string;
36
+ cancelLabel?: string;
37
+ submitLabel?: string;
38
+ timeoutMs?: number;
39
+ };
40
+ /** Result posted back from the renderer / used to settle the pending promise. */
41
+ export type PluginDialogResult = {
42
+ submitted: boolean;
43
+ value?: string;
44
+ };
45
+ /** Payload for SOCKET_EVENTS.DIALOG_CLOSE. */
46
+ export type PluginDialogClosePayload = {
47
+ requestId: string;
48
+ };
49
+ //# sourceMappingURL=plugin-dialogs.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wire types for the background-plugin dialog/prompt surface.
3
+ *
4
+ * A `PluginDialogSpec` is broadcast to the renderer (SOCKET_EVENTS.DIALOG_OPEN)
5
+ * and also served by GET /api/plugin-dialogs for hydrate. The renderer posts a
6
+ * `PluginDialogResult` back. The wire value is always a string (or absent) — the
7
+ * typed coercion to boolean/number/null lives in the loader wrappers.
8
+ */
9
+ export {};
@@ -68,6 +68,10 @@ export declare const SOCKET_EVENTS: {
68
68
  readonly PLUGIN_LOADED: "plugin:loaded";
69
69
  readonly PLUGIN_UNLOADED: "plugin:unloaded";
70
70
  readonly PLUGIN_EVENT: "plugin:event";
71
+ /** A background plugin opened a dialog/prompt. Payload: PluginDialogSpec */
72
+ readonly DIALOG_OPEN: "plugin:dialog:open";
73
+ /** A dialog/prompt was settled (answered/cancelled/timed out/unloaded). Payload: PluginDialogClosePayload */
74
+ readonly DIALOG_CLOSE: "plugin:dialog:close";
71
75
  };
72
76
  /** Union of all event name strings. */
73
77
  export type SocketEventName = (typeof SOCKET_EVENTS)[keyof typeof SOCKET_EVENTS];
@@ -78,4 +78,8 @@ export const SOCKET_EVENTS = {
78
78
  PLUGIN_LOADED: "plugin:loaded",
79
79
  PLUGIN_UNLOADED: "plugin:unloaded",
80
80
  PLUGIN_EVENT: "plugin:event",
81
+ /** A background plugin opened a dialog/prompt. Payload: PluginDialogSpec */
82
+ DIALOG_OPEN: "plugin:dialog:open",
83
+ /** A dialog/prompt was settled (answered/cancelled/timed out/unloaded). Payload: PluginDialogClosePayload */
84
+ DIALOG_CLOSE: "plugin:dialog:close",
81
85
  };
@@ -5,6 +5,8 @@
5
5
  * for both background (main process) and UI (renderer) usage.
6
6
  */
7
7
  import type { AxiosInstance } from "axios";
8
+ import type { EventCategory, FlightLogEvent, FlightPhasePayload, FlightPhaseSnapshot, FlightLandingPayload, LandingAnalysisSnapshot, SimDataSnapshot } from "../shared-types/simulator";
9
+ import type { FlightManagerPayload, FlightPlan } from "../shared-types/flight-manager";
8
10
  /** All supported setting control types */
9
11
  export type PluginSettingType = "boolean" | "text" | "longtext" | "number" | "range" | "list" | "radio" | "date" | "json";
10
12
  /** Option entry for list and radio settings */
@@ -171,6 +173,194 @@ export type PluginDatabaseAccessor = {
171
173
  */
172
174
  open(filename: string): unknown;
173
175
  };
176
+ /**
177
+ * Writer for the authoritative flight log. Backs `ctx.flight.log`.
178
+ *
179
+ * Replaces the rejected pattern of importing core's FlightEventManager and
180
+ * mutating its private `flightLog` array. All mutations are routed through the
181
+ * shell so persistence, the event bus, and the pirep split stay consistent.
182
+ */
183
+ export type PluginFlightLogWriter = {
184
+ /**
185
+ * Append an event to the flight log. Returns the created event, or null when
186
+ * there is no active tracking session (mirrors `addComment`).
187
+ */
188
+ add(event: PluginFlightLogInput): Promise<FlightLogEvent | null>;
189
+ /** Remove a previously-added event by id. Returns true if it existed. */
190
+ remove(eventId: string): Promise<boolean>;
191
+ /** Patch an existing event in place. Returns true if it existed. */
192
+ update(eventId: string, patch: PluginFlightLogPatch): Promise<boolean>;
193
+ };
194
+ /** Input for `ctx.flight.log.add`. */
195
+ export type PluginFlightLogInput = {
196
+ category: EventCategory;
197
+ condition: string;
198
+ message: string;
199
+ data?: Record<string, unknown>;
200
+ };
201
+ /** Patch shape for `ctx.flight.log.update`. */
202
+ export type PluginFlightLogPatch = Partial<Pick<PluginFlightLogInput, "category" | "message" | "data">>;
203
+ /**
204
+ * Read/subscribe accessor for live flight state. Backs `ctx.flight`.
205
+ *
206
+ * Reads return serialisable snapshots; subscriptions deliver the same payloads
207
+ * the shell broadcasts over Socket.io. Every `onX` returns an unsubscribe.
208
+ */
209
+ export type PluginFlightAccessor = {
210
+ /** Current flight-manager state (flight, pending recovery, sim-disconnect). */
211
+ getState(): Promise<FlightManagerPayload>;
212
+ /** Latest simulator data snapshot, or null when no sim is connected. */
213
+ getSnapshot(): Promise<SimDataSnapshot | null>;
214
+ /** Current flight-phase snapshot. */
215
+ getPhase(): Promise<FlightPhaseSnapshot>;
216
+ /** Current landing-analysis snapshot. */
217
+ getLandingReport(): Promise<LandingAnalysisSnapshot>;
218
+ /** Subscribe to flight-manager state changes. Returns an unsubscribe. */
219
+ onUpdate(cb: (state: FlightManagerPayload) => void): () => void;
220
+ /** Subscribe to flight-phase changes. Returns an unsubscribe. */
221
+ onPhaseChange(cb: (payload: FlightPhasePayload) => void): () => void;
222
+ /** Subscribe to live simulator data frames. Returns an unsubscribe. */
223
+ onSimData(cb: (snapshot: SimDataSnapshot) => void): () => void;
224
+ /** Subscribe to landing events (touchdown/bounce/settled). Returns an unsubscribe. */
225
+ onLanding(cb: (payload: FlightLandingPayload) => void): () => void;
226
+ /** Authoritative flight-log writer. */
227
+ log: PluginFlightLogWriter;
228
+ /**
229
+ * Register a guard consulted inside `startFlight` BEFORE the flight is
230
+ * created or persisted. A guard returning `{ allow: false, reason }` vetoes
231
+ * the start (surfaced via the existing preflight-failure path). Guards are
232
+ * fail-open: a throw or timeout (~5s) allows the start with a loud warning.
233
+ * Multiple guards: the first `allow: false` wins. Returns an unsubscribe.
234
+ */
235
+ registerStartGuard(guard: PluginStartGuard): () => void;
236
+ };
237
+ /** Context handed to a start guard. */
238
+ export type PluginStartContext = {
239
+ plan: FlightPlan;
240
+ snapshot: SimDataSnapshot | null;
241
+ isAutoStart: boolean;
242
+ };
243
+ /** Decision returned by a start guard. */
244
+ export type PluginStartDecision = {
245
+ allow: true;
246
+ } | {
247
+ allow: false;
248
+ reason: string;
249
+ };
250
+ /** Guard run inside `startFlight` before the flight is created/persisted. */
251
+ export type PluginStartGuard = (ctx: PluginStartContext) => PluginStartDecision | Promise<PluginStartDecision>;
252
+ /**
253
+ * Toast + sound surface. Backs `ctx.notify`.
254
+ *
255
+ * Replaces the rejected pattern of `webContents.executeJavaScript` to build
256
+ * DOM toasts and play `new Audio(...)`. The shell owns the DOM and the sound
257
+ * catalogue; the plugin only describes what to show / which sound to play.
258
+ */
259
+ export type PluginNotifier = {
260
+ /** Show a toast in the renderer. */
261
+ toast(n: PluginToastInput): Promise<void>;
262
+ /** Play a shell-bundled sound by name (no plugin-supplied audio). */
263
+ sound(name: PluginAlertSound): Promise<void>;
264
+ };
265
+ /** Input for `ctx.notify.toast`. */
266
+ export type PluginToastInput = {
267
+ type: "info" | "success" | "warning" | "error";
268
+ title: string;
269
+ message: string;
270
+ durationMs?: number;
271
+ id?: string;
272
+ };
273
+ /** Fixed shell-bundled sound catalogue. No plugin-supplied audio. */
274
+ export type PluginAlertSound = "alert" | "warning" | "error" | "success" | "chime";
275
+ /** Input for `ctx.dialog.alert`. */
276
+ export type PluginDialogAlertInput = {
277
+ title: string;
278
+ message: string;
279
+ /** Acknowledge-button label. Default "OK". */
280
+ okLabel?: string;
281
+ /** Optional auto-cancel; on expiry the call resolves (void). */
282
+ timeoutMs?: number;
283
+ };
284
+ /** Input for `ctx.dialog.confirm`. */
285
+ export type PluginDialogConfirmInput = {
286
+ title: string;
287
+ message: string;
288
+ /** Confirm-button label. Default "Confirm". */
289
+ confirmLabel?: string;
290
+ /** Cancel-button label. Default "Cancel". */
291
+ cancelLabel?: string;
292
+ /** Optional auto-cancel; on expiry the call resolves false. */
293
+ timeoutMs?: number;
294
+ };
295
+ /** Input for `ctx.prompt.text`. */
296
+ export type PluginPromptTextInput = {
297
+ title: string;
298
+ /** Field label, e.g. "What gate are you departing from?". */
299
+ label: string;
300
+ /** Optional helper/body text shown above the field. */
301
+ message?: string;
302
+ placeholder?: string;
303
+ defaultValue?: string;
304
+ /** When true, Submit is disabled until the field is non-empty. */
305
+ required?: boolean;
306
+ maxLength?: number;
307
+ submitLabel?: string;
308
+ cancelLabel?: string;
309
+ timeoutMs?: number;
310
+ };
311
+ /** Input for `ctx.prompt.number`. */
312
+ export type PluginPromptNumberInput = {
313
+ title: string;
314
+ label: string;
315
+ message?: string;
316
+ placeholder?: string;
317
+ defaultValue?: number;
318
+ required?: boolean;
319
+ min?: number;
320
+ max?: number;
321
+ step?: number;
322
+ submitLabel?: string;
323
+ cancelLabel?: string;
324
+ timeoutMs?: number;
325
+ };
326
+ /** Input for `ctx.prompt.select`. */
327
+ export type PluginPromptSelectInput = {
328
+ title: string;
329
+ label: string;
330
+ message?: string;
331
+ options: {
332
+ value: string;
333
+ label: string;
334
+ }[];
335
+ /** Pre-selected option value. */
336
+ defaultValue?: string;
337
+ required?: boolean;
338
+ submitLabel?: string;
339
+ cancelLabel?: string;
340
+ timeoutMs?: number;
341
+ };
342
+ /**
343
+ * Message-centric dialogs. The pilot reads a message and clicks a button.
344
+ * Backs `ctx.dialog`.
345
+ */
346
+ export type PluginDialogApi = {
347
+ /** Show a blocking message with a single acknowledge button. */
348
+ alert(input: PluginDialogAlertInput): Promise<void>;
349
+ /** Ask a yes/no question. Resolves false on cancel/dismiss/timeout. */
350
+ confirm(input: PluginDialogConfirmInput): Promise<boolean>;
351
+ };
352
+ /**
353
+ * Input-centric prompts. The pilot provides a value. Backs `ctx.prompt`.
354
+ * All resolve null on cancel/dismiss/timeout.
355
+ */
356
+ export type PluginPromptApi = {
357
+ /** Ask for free text. */
358
+ text(input: PluginPromptTextInput): Promise<string | null>;
359
+ /** Ask for a number. A non-numeric/blank submit resolves null. */
360
+ number(input: PluginPromptNumberInput): Promise<number | null>;
361
+ /** Ask the pilot to pick one of the supplied options. Returns the value. */
362
+ select(input: PluginPromptSelectInput): Promise<string | null>;
363
+ };
174
364
  /**
175
365
  * Context passed to a plugin's background onStart() function.
176
366
  * Provides scoped access to shell infrastructure.
@@ -190,6 +380,17 @@ export type PluginContext = {
190
380
  server: PluginServerRegistrar;
191
381
  /** SQLite database accessor (files stored in plugin's data directory) */
192
382
  database: PluginDatabaseAccessor;
383
+ /**
384
+ * Live flight state: reads, subscriptions, the authoritative flight-log
385
+ * writer, and start guards.
386
+ */
387
+ flight: PluginFlightAccessor;
388
+ /** Toast + sound surface. */
389
+ notify: PluginNotifier;
390
+ /** Blocking, awaited message dialogs (alert/confirm). */
391
+ dialog: PluginDialogApi;
392
+ /** Blocking, awaited input prompts (text/number/select). */
393
+ prompt: PluginPromptApi;
193
394
  };
194
395
  /** Pilot user profile provided by the shell's auth system */
195
396
  export type PluginPilotUser = {
@@ -1,4 +1,4 @@
1
1
  export type { PluginAuthor, PluginManifest } from "./manifest";
2
- export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginServerRegistrar, PluginToastAPI, PluginUIContext, } from "./context";
2
+ export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginServerRegistrar, PluginToastAPI, PluginUIContext, PluginFlightAccessor, PluginFlightLogWriter, PluginFlightLogInput, PluginFlightLogPatch, PluginStartGuard, PluginStartContext, PluginStartDecision, PluginNotifier, PluginToastInput, PluginAlertSound, } from "./context";
3
3
  export type { PluginBackgroundModule, PluginRouteComponent, PluginUIModule, } from "./module";
4
4
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyvexsoftware/stratos-sdk",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "description": "Plugin SDK for Stratos — types, hooks, and UI components",
5
5
  "author": {
6
6
  "name": "Skyvex Software Pty Ltd",