@skyvexsoftware/stratos-sdk
v0.14.0
Published
Plugin SDK for Stratos — types, hooks, and UI components
Downloads
2,058
Maintainers
Readme
@skyvexsoftware/stratos-sdk
The Stratos Plugin SDK provides typed access to shell APIs, shared UI components, and utility functions for building Stratos plugins.
Installation
pnpm add @skyvexsoftware/stratos-sdkGetting Started
Scaffold a new plugin project:
pnpx create-stratos-pluginThis generates a ready-to-develop plugin with Tailwind CSS, TypeScript, and Vite preconfigured.
Development
- Open the Stratos app with
--devflag - In your plugin directory, run:
pnpm devYour plugin auto-connects to the running Stratos app and appears in the sidebar. Code changes auto-reload.
Project Structure
my-plugin/
├── plugin.json # Plugin manifest (name, version, author, settings)
├── package.json
├── vite.config.ts # Uses createPluginConfig from SDK
├── tsconfig.json
├── src/
│ ├── ui/
│ │ ├── index.tsx # UI entry (default export: React component)
│ │ └── global.css # Tailwind CSS
│ └── background/ # Optional: main process module
│ └── index.ts # export default createPlugin({...})
└── assets/
├── icon-light.svg # Sidebar icon (dark theme)
└── icon-dark.svg # Sidebar icon (light theme)Building
pnpm build # Build for distributionProduces dist/ with bundled UI, background module (if any), manifest, and assets. Zip and upload to the Skyvex website.
Vite Config
The SDK provides createPluginConfig which handles bundling, externals, dev server auto-connect, and asset copying:
import { createPluginConfig } from "@skyvexsoftware/stratos-sdk/vite";
import tailwindcss from "@tailwindcss/vite";
export default createPluginConfig({
ui: { entry: "src/ui/index.tsx" },
background: { entry: "src/background/index.ts" }, // optional
vite: {
plugins: [tailwindcss()],
},
});The vite option accepts any Vite config to merge in (plugins, resolve, css, etc.).
Plugin Manifest
plugin.json defines your plugin's metadata. Background modules don't need manifest configuration — the shell discovers them automatically if background/index.js exists in the built output.
{
"$schema": "https://cdn.skyvexsoftware.com/schemas/stratos-plugin.json",
"id": "my-plugin",
"type": "airline",
"name": "My Plugin",
"version": "0.1.0",
"description": "A Stratos plugin",
"author": { "id": "my-org", "name": "My Organisation" },
"icon_light": "icon-light.svg",
"icon_dark": "icon-dark.svg"
}type:"airline"(scoped to a virtual airline) or"user"(user-installed)availableSettings: Optional array of setting definitions (boolean, text, number, list, etc.)
API Reference
UI Context
Access shell services from plugin components:
import { usePluginContext } from "@skyvexsoftware/stratos-sdk";
function MyComponent() {
const {
pluginId,
auth, // { isAuthenticated, token, user }
airline, // { id, name, icao, logo_light, logo_dark }
config, // { get(key, defaultValue?) } — airline-scoped settings
navigation, // { navigateTo, navigateToPlugin, navigateToShell }
toast, // { success, error, info, warning }
logger, // { info, warn, error, debug }
} = usePluginContext();
}Individual hooks are also available:
| Hook | Description |
| ---------------------- | ---------------------------------------------- |
| usePluginContext() | All shell services combined |
| useSimData() | Real-time simulator data (RAF-throttled) |
| useFlightPhase() | Current flight phase with selector support |
| useFlightEvents() | Flight event log with comment mutations |
| useFlightManager() | Low-level flight lifecycle control |
| useTrackingSession() | High-level tracking state with derived fields |
| useLandingAnalysis() | Landing rate, bounces, and settled analysis |
| useShellAuth() | Authentication state and token |
| useVaApi() | Shared axios instance for the bound VA's API |
| useShellConfig() | Scoped configuration access |
| useShellNavigation() | Route navigation utilities |
| useShellToast() | Toast/notification functions |
| usePluginLogger() | Scoped renderer-side logger |
VA API client
For HTTP calls to the bound airline's API, use useVaApi() (renderer) or ctx.airline.createClient() (background). Both return an axios instance that the shell pre-configures with the airline's base_url, the pilot's bearer token, and a 401 → refresh → retry interceptor:
import { useVaApi } from "@skyvexsoftware/stratos-sdk";
const va = useVaApi();
const { data } = await va.get("/pilot/verify");The renderer-side instance is provided by PluginShellProvider and shared across the shell and every plugin UI — concurrent 401s coalesce onto a single refresh roundtrip rather than each plugin firing its own.
About the axios dependency
axios is a regular dependency of this SDK, so plugins don't need to declare it in their own package.json if they only consume it through useVaApi() / ctx.airline.createClient(). The plugin's bundle won't ship its own copy either — the shell's instance is reused at runtime through the plugin context.
Only add axios to your plugin's deps if you import it directly — for example to call axios.isAxiosError(err) for narrowing or to build your own custom instance. If you do, pin the same major version as the SDK to avoid runtime surprises.
Background Module
Optional main-process code with access to IPC, Express routes, SQLite, and more. Must use the createPlugin helper (imported from the /helpers subpath) with a default export:
import { createPlugin } from "@skyvexsoftware/stratos-sdk/helpers";
export default createPlugin({
async onStart(ctx) {
// ctx.logger — scoped logger
// ctx.config — per-plugin config store (async)
// ctx.ipc — IPC handler registration
// ctx.auth — read-only auth token access (async)
// ctx.server — Express router registration
// ctx.database — SQLite database access
ctx.logger.info("MyPlugin", "Started");
},
async onStop(ctx) {
ctx.logger.info("MyPlugin", "Stopped");
},
});Named exports are not supported — the shell requires the createPlugin default export pattern for type safety and validation.
UI Components
Pre-styled shadcn/ui components that match the Stratos design system:
import { Button, Card, CardContent, Input, Dialog } from "@skyvexsoftware/stratos-sdk";Available: Button, Card, Dialog, Input, Label, Select, Badge, Separator, Tabs, Tooltip, AlertDialog, RadioGroup, Slider, Switch, Textarea.
Icons
Import icons directly from lucide-react — they're tree-shaken, so only the icons you use are added to your bundle:
import { Plane, Map, Settings, Helicopter } from "lucide-react";The SDK's Vite config shims react, react-dom, and their jsx subpaths so every copy of React in your plugin graph (including lucide-react's internals) resolves to the shell's single instance.
If you need dynamic lookup (e.g. icons chosen by name from a remote config), import { icons } from "lucide-react" gives you the full map — at the cost of bundling the whole set into your plugin. Prefer a curated static map when possible.
Earlier SDK versions exposed STRATOS_ICONS and STRATOS_ICON_NAMES as convenience re-exports of lucide's icons object. Those exports are still available but deprecated — prefer the patterns above in new code.
Types
import { FlightPhase, EventCategory } from "@skyvexsoftware/stratos-sdk";
import type { FlightData, PluginManifest, PluginContext } from "@skyvexsoftware/stratos-sdk";Utilities
// Tailwind class merging
import { cn } from "@skyvexsoftware/stratos-sdk";
cn("bg-red-500", isActive && "text-white", className);
// Unit conversion helpers
import { weightFromLbs, formatAltitude } from "@skyvexsoftware/stratos-sdk/helpers";Documentation
Full documentation is available at docs.skyvexsoftware.com.
Licence
MIT
