@skyvexsoftware/stratos-sdk 0.1.5 → 0.1.7
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/README.md +115 -118
- package/dist/vite/plugin-config.d.ts +4 -1
- package/dist/vite/plugin-config.js +20 -9
- package/dist/vite/serve-externals.js +18 -1
- package/dist/vite/stratos-dev-server.js +30 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,169 +16,177 @@ Scaffold a new plugin project:
|
|
|
16
16
|
pnpx create-stratos-plugin
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
This generates a ready-to-develop plugin with Tailwind CSS, TypeScript, and Vite preconfigured.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
### Development
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
1. Open the Stratos app with `--dev` flag
|
|
24
|
+
2. In your plugin directory, run:
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
import type {
|
|
29
|
-
PluginManifest,
|
|
30
|
-
PluginContext,
|
|
31
|
-
PluginUIContext,
|
|
32
|
-
PluginBackgroundModule,
|
|
33
|
-
PluginUIModule,
|
|
34
|
-
} from "@skyvexsoftware/stratos-sdk";
|
|
26
|
+
```bash
|
|
27
|
+
pnpm dev
|
|
35
28
|
```
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
Your plugin auto-connects to the running Stratos app and appears in the sidebar. Code changes auto-reload.
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
### Project Structure
|
|
40
33
|
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
```
|
|
35
|
+
my-plugin/
|
|
36
|
+
├── plugin.json # Plugin manifest (name, version, author, settings)
|
|
37
|
+
├── package.json
|
|
38
|
+
├── vite.config.ts # Uses createPluginConfig from SDK
|
|
39
|
+
├── tsconfig.json
|
|
40
|
+
├── src/
|
|
41
|
+
│ ├── ui/
|
|
42
|
+
│ │ ├── index.tsx # UI entry (default export: React component)
|
|
43
|
+
│ │ └── global.css # Tailwind CSS
|
|
44
|
+
│ └── background/ # Optional: main process module
|
|
45
|
+
│ └── index.ts # Exports onStart(ctx) and onStop()
|
|
46
|
+
└── assets/
|
|
47
|
+
├── icon-light.svg # Sidebar icon (dark theme)
|
|
48
|
+
└── icon-dark.svg # Sidebar icon (light theme)
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
### Building
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pnpm build # Build for distribution
|
|
55
|
+
```
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
Produces `dist/` with bundled UI, background module (if any), manifest, and assets. Zip and upload to the Skyvex website.
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
## Vite Config
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
The SDK provides `createPluginConfig` which handles bundling, externals, dev server auto-connect, and asset copying:
|
|
58
62
|
|
|
59
63
|
```ts
|
|
60
|
-
import {
|
|
64
|
+
import { createPluginConfig } from "@skyvexsoftware/stratos-sdk/vite";
|
|
65
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
61
66
|
|
|
62
|
-
export default
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// cleanup
|
|
67
|
+
export default createPluginConfig({
|
|
68
|
+
ui: { entry: "src/ui/index.tsx" },
|
|
69
|
+
background: { entry: "src/background/index.ts" }, // optional
|
|
70
|
+
vite: {
|
|
71
|
+
plugins: [tailwindcss()],
|
|
68
72
|
},
|
|
69
73
|
});
|
|
70
74
|
```
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
Optional lightweight router for plugins that need internal multi-page navigation:
|
|
76
|
+
The `vite` option accepts any Vite config to merge in (plugins, resolve, css, etc.).
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
import { PluginRouter } from "@skyvexsoftware/stratos-sdk";
|
|
78
|
-
import TrackingPage from "./pages/TrackingPage";
|
|
79
|
-
import HistoryPage from "./pages/HistoryPage";
|
|
80
|
-
import HistoryDetailPage from "./pages/HistoryDetailPage";
|
|
78
|
+
## Plugin Manifest
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
{ path: "tracking", component: TrackingPage },
|
|
84
|
-
{ path: "history", component: HistoryPage },
|
|
85
|
-
{ path: "history/:id", component: HistoryDetailPage },
|
|
86
|
-
];
|
|
80
|
+
`plugin.json` defines your plugin's metadata:
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"$schema": "https://cdn.skyvexsoftware.com/schemas/stratos-plugin.json",
|
|
85
|
+
"id": "my-plugin",
|
|
86
|
+
"type": "airline",
|
|
87
|
+
"name": "My Plugin",
|
|
88
|
+
"version": "0.1.0",
|
|
89
|
+
"description": "A Stratos plugin",
|
|
90
|
+
"author": { "id": "my-org", "name": "My Organization" },
|
|
91
|
+
"icon_light": "icon-light.svg",
|
|
92
|
+
"icon_dark": "icon-dark.svg"
|
|
90
93
|
}
|
|
91
94
|
```
|
|
92
95
|
|
|
93
|
-
|
|
96
|
+
- `type`: `"airline"` (scoped to a virtual airline) or `"user"` (user-installed)
|
|
97
|
+
- `availableSettings`: Optional array of setting definitions (boolean, text, number, list, etc.)
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
import HomePage from "./HomePage";
|
|
97
|
-
export default HomePage;
|
|
98
|
-
```
|
|
99
|
+
## API Reference
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
### UI Context
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
Access shell services from plugin components:
|
|
103
104
|
|
|
104
105
|
```tsx
|
|
105
|
-
import {
|
|
106
|
+
import { usePluginContext } from "@skyvexsoftware/stratos-sdk";
|
|
106
107
|
|
|
107
108
|
function MyComponent() {
|
|
108
|
-
const {
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
import { usePluginParams } from "@skyvexsoftware/stratos-sdk";
|
|
119
|
-
|
|
120
|
-
function DetailPage() {
|
|
121
|
-
const { id } = usePluginParams<{ id: string }>();
|
|
122
|
-
// id === "abc123" when URL is /plugins/my-plugin/history/abc123
|
|
109
|
+
const {
|
|
110
|
+
pluginId,
|
|
111
|
+
auth, // { isAuthenticated, token, user }
|
|
112
|
+
airline, // { id, name, icao, logo_light, logo_dark }
|
|
113
|
+
config, // { get(key, defaultValue) }
|
|
114
|
+
navigation, // { navigateTo, navigateToPlugin, navigateToShell }
|
|
115
|
+
toast, // { success, error, info, warning }
|
|
116
|
+
logger, // { info, warn, error, debug }
|
|
117
|
+
} = usePluginContext();
|
|
123
118
|
}
|
|
124
119
|
```
|
|
125
120
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Access shell services from plugin components. All hooks must be used within a `PluginShellProvider` (provided by the shell at runtime).
|
|
121
|
+
Individual hooks are also available:
|
|
129
122
|
|
|
130
123
|
| Hook | Returns | Description |
|
|
131
124
|
| ---------------------- | -------------------- | ------------------------------ |
|
|
125
|
+
| `usePluginContext()` | Full PluginUIContext | All services combined |
|
|
132
126
|
| `useShellAuth()` | Auth state | Authentication state and token |
|
|
133
127
|
| `useShellConfig()` | Config store | Scoped configuration access |
|
|
134
128
|
| `useShellNavigation()` | Navigation helpers | Route navigation utilities |
|
|
135
129
|
| `useShellToast()` | Toast API | Toast/notification functions |
|
|
136
130
|
| `usePluginLogger()` | Logger | Scoped renderer-side logger |
|
|
137
|
-
| `usePluginContext()` | Full PluginUIContext | All of the above combined |
|
|
138
131
|
|
|
139
|
-
|
|
140
|
-
import { useShellAuth, useShellToast } from "@skyvexsoftware/stratos-sdk";
|
|
132
|
+
### Background Module
|
|
141
133
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
134
|
+
Optional main-process code with access to IPC, Express routes, SQLite, and more:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { createPlugin } from "@skyvexsoftware/stratos-sdk";
|
|
138
|
+
|
|
139
|
+
export default createPlugin({
|
|
140
|
+
async onStart(ctx) {
|
|
141
|
+
// ctx.logger — scoped logger
|
|
142
|
+
// ctx.config — per-plugin config store
|
|
143
|
+
// ctx.ipc — IPC handler registration
|
|
144
|
+
// ctx.auth — read-only auth token access
|
|
145
|
+
// ctx.server — Express router registration
|
|
146
|
+
// ctx.database — SQLite database access
|
|
147
|
+
ctx.logger.info("MyPlugin", "Started");
|
|
148
|
+
},
|
|
149
|
+
async onStop() {
|
|
150
|
+
// cleanup
|
|
151
|
+
},
|
|
152
|
+
});
|
|
152
153
|
```
|
|
153
154
|
|
|
154
|
-
###
|
|
155
|
+
### Routing
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
For multi-page plugins, use `PluginRouter`:
|
|
157
158
|
|
|
158
159
|
```tsx
|
|
159
|
-
import {
|
|
160
|
+
import { PluginRouter } from "@skyvexsoftware/stratos-sdk";
|
|
161
|
+
|
|
162
|
+
const routes = [
|
|
163
|
+
{ path: "home", component: HomePage },
|
|
164
|
+
{ path: "settings", component: SettingsPage },
|
|
165
|
+
{ path: "detail/:id", component: DetailPage },
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
export default function Plugin() {
|
|
169
|
+
return <PluginRouter routes={routes} defaultPath="home" />;
|
|
170
|
+
}
|
|
160
171
|
```
|
|
161
172
|
|
|
162
|
-
|
|
173
|
+
For single-page plugins, just export the component directly.
|
|
174
|
+
|
|
175
|
+
### UI Components
|
|
163
176
|
|
|
164
|
-
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- **Select** — SelectTrigger, SelectContent, SelectItem, SelectGroup, SelectValue
|
|
170
|
-
- **Badge** — with variants: default, secondary, destructive, outline
|
|
171
|
-
- **Separator** — horizontal or vertical divider
|
|
172
|
-
- **Tabs** — TabsList, TabsTrigger, TabsContent
|
|
173
|
-
- **Tooltip** — TooltipProvider, TooltipTrigger, TooltipContent
|
|
177
|
+
Pre-styled shadcn/ui components that match the Stratos design system:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { Button, Card, CardContent, Input, Dialog } from "@skyvexsoftware/stratos-sdk";
|
|
181
|
+
```
|
|
174
182
|
|
|
175
|
-
|
|
183
|
+
Available: Button, Card, Dialog, Input, Label, Select, Badge, Separator, Tabs, Tooltip, AlertDialog, RadioGroup, Slider, Switch, Textarea.
|
|
176
184
|
|
|
177
|
-
|
|
185
|
+
### Types
|
|
178
186
|
|
|
179
187
|
```ts
|
|
180
188
|
import { FlightPhase, SimulatorType } from "@skyvexsoftware/stratos-sdk";
|
|
181
|
-
import type { FlightData,
|
|
189
|
+
import type { FlightData, PluginManifest, PluginContext } from "@skyvexsoftware/stratos-sdk";
|
|
182
190
|
```
|
|
183
191
|
|
|
184
192
|
### Utilities
|
|
@@ -186,21 +194,10 @@ import type { FlightData, ThemeMode } from "@skyvexsoftware/stratos-sdk";
|
|
|
186
194
|
```ts
|
|
187
195
|
import { cn } from "@skyvexsoftware/stratos-sdk";
|
|
188
196
|
|
|
189
|
-
// Tailwind class merging
|
|
190
|
-
cn("bg-red-500",
|
|
197
|
+
// Tailwind class merging
|
|
198
|
+
cn("bg-red-500", isActive && "text-white", className);
|
|
191
199
|
```
|
|
192
200
|
|
|
193
|
-
## Peer Dependencies
|
|
194
|
-
|
|
195
|
-
The SDK expects these to be provided by the Stratos shell at runtime:
|
|
196
|
-
|
|
197
|
-
- `react` ^19.0.0
|
|
198
|
-
- `@radix-ui/react-*` (dialog, label, select, separator, slot, tabs, tooltip)
|
|
199
|
-
- `@tanstack/react-query` ^5.0.0
|
|
200
|
-
- `class-variance-authority` ^0.7.0
|
|
201
|
-
- `lucide-react` >=0.300.0
|
|
202
|
-
- `socket.io-client` ^4.0.0
|
|
203
|
-
|
|
204
201
|
## License
|
|
205
202
|
|
|
206
203
|
MIT
|
|
@@ -29,13 +29,16 @@ declare const BG_EXTERNALS: string[];
|
|
|
29
29
|
*/
|
|
30
30
|
declare function stratosExternals(): Plugin;
|
|
31
31
|
export type PluginBuildOptions = {
|
|
32
|
-
|
|
32
|
+
/** Plugin root directory. Defaults to process.cwd(). */
|
|
33
|
+
pluginDir?: string;
|
|
33
34
|
ui?: {
|
|
34
35
|
entry: string;
|
|
35
36
|
};
|
|
36
37
|
background?: {
|
|
37
38
|
entry: string;
|
|
38
39
|
};
|
|
40
|
+
/** Extra Vite config to merge (plugins, css, etc.) */
|
|
41
|
+
vite?: UserConfig;
|
|
39
42
|
};
|
|
40
43
|
/**
|
|
41
44
|
* Create a Vite config for building a Stratos plugin.
|
|
@@ -157,26 +157,20 @@ function copyDirSync(src, dest) {
|
|
|
157
157
|
* - "background" → builds the background module (Node.js, ESM)
|
|
158
158
|
*/
|
|
159
159
|
export function createPluginConfig(options) {
|
|
160
|
-
const { pluginDir, ui, background } = options;
|
|
160
|
+
const { pluginDir = process.cwd(), ui, background, vite: extraConfig, } = options;
|
|
161
161
|
const target = process.env.BUILD_TARGET;
|
|
162
162
|
if (target === "background" && background) {
|
|
163
163
|
return createBackgroundConfig(pluginDir, background.entry);
|
|
164
164
|
}
|
|
165
165
|
if (ui) {
|
|
166
|
-
return createUIConfig(pluginDir, ui.entry);
|
|
166
|
+
return createUIConfig(pluginDir, ui.entry, extraConfig);
|
|
167
167
|
}
|
|
168
168
|
throw new Error("No build target. Provide a ui entry or set BUILD_TARGET=background.");
|
|
169
169
|
}
|
|
170
|
-
function createUIConfig(pluginDir, entry) {
|
|
170
|
+
function createUIConfig(pluginDir, entry, extraConfig) {
|
|
171
171
|
const isProduction = process.env.NODE_ENV === "production";
|
|
172
172
|
return {
|
|
173
173
|
root: pluginDir,
|
|
174
|
-
plugins: [
|
|
175
|
-
serveExternals(),
|
|
176
|
-
stratosDevServer({ pluginDir }),
|
|
177
|
-
stratosExternals(),
|
|
178
|
-
copyPluginAssets(pluginDir),
|
|
179
|
-
],
|
|
180
174
|
server: {
|
|
181
175
|
cors: {
|
|
182
176
|
origin: [
|
|
@@ -185,6 +179,14 @@ function createUIConfig(pluginDir, entry) {
|
|
|
185
179
|
/^http:\/\/localhost:\d+$/,
|
|
186
180
|
],
|
|
187
181
|
},
|
|
182
|
+
hmr: {
|
|
183
|
+
// When modules are loaded via stratos-dev:// protocol, Vite's HMR
|
|
184
|
+
// client needs to connect back to THIS dev server's WebSocket directly.
|
|
185
|
+
// Without this, it would try to derive the WS URL from the custom
|
|
186
|
+
// protocol scheme, which doesn't work.
|
|
187
|
+
protocol: "ws",
|
|
188
|
+
host: "localhost",
|
|
189
|
+
},
|
|
188
190
|
},
|
|
189
191
|
optimizeDeps: {
|
|
190
192
|
exclude: [
|
|
@@ -212,6 +214,15 @@ function createUIConfig(pluginDir, entry) {
|
|
|
212
214
|
jsx: "automatic",
|
|
213
215
|
jsxImportSource: "react",
|
|
214
216
|
},
|
|
217
|
+
// Merge extra config: plugins are concatenated, other keys shallow-merged
|
|
218
|
+
...extraConfig,
|
|
219
|
+
plugins: [
|
|
220
|
+
serveExternals(),
|
|
221
|
+
stratosDevServer({ pluginDir }),
|
|
222
|
+
stratosExternals(),
|
|
223
|
+
copyPluginAssets(pluginDir),
|
|
224
|
+
...(extraConfig?.plugins ?? []),
|
|
225
|
+
],
|
|
215
226
|
};
|
|
216
227
|
}
|
|
217
228
|
function createBackgroundConfig(pluginDir, entry) {
|
|
@@ -19,7 +19,7 @@ export function serveExternals() {
|
|
|
19
19
|
return {
|
|
20
20
|
name: "stratos-serve-externals",
|
|
21
21
|
apply: "serve",
|
|
22
|
-
enforce: "
|
|
22
|
+
enforce: "post",
|
|
23
23
|
transform(code, id) {
|
|
24
24
|
// Only process JS/TS source files
|
|
25
25
|
const ext = id.slice(id.lastIndexOf("."));
|
|
@@ -69,6 +69,23 @@ export function serveExternals() {
|
|
|
69
69
|
// 6. Side-effect imports: import "pkg"
|
|
70
70
|
result = result.replace(new RegExp(`import\\s+['"]${escaped}['"]\\s*;?`, "g"), `// (stratos-serve-externals: side-effect import of "${modId}" removed)`);
|
|
71
71
|
}
|
|
72
|
+
// Second pass: catch Vite-resolved paths like
|
|
73
|
+
// import { jsxDEV } from "/node_modules/react/jsx-dev-runtime.js?v=..."
|
|
74
|
+
// These are injected by esbuild's JSX transform after our source-level pass.
|
|
75
|
+
for (const modId of EXTERNAL_PACKAGES) {
|
|
76
|
+
// Convert package name to a path pattern: "react/jsx-dev-runtime" -> "react/jsx-dev-runtime"
|
|
77
|
+
const pathPattern = modId.replace(/\//g, "/");
|
|
78
|
+
const global = `window.__stratos_modules__[${JSON.stringify(modId)}]`;
|
|
79
|
+
// Match: import { x } from "/node_modules/{pkg}.js?v=..." or "/{pkg}?..."
|
|
80
|
+
const resolvedRe = new RegExp(`import\\s*\\{([^}]+)\\}\\s+from\\s+['"][^'"]*/${escapeRegExp(pathPattern)}(?:\\.js)?(?:\\?[^'"]*)?['"]\\s*;?`, "g");
|
|
81
|
+
result = result.replace(resolvedRe, (_, names) => {
|
|
82
|
+
const destructured = names.replace(/([\w$]+)\s+as\s+([\w$]+)/g, "$1: $2");
|
|
83
|
+
return `const {${destructured}} = ${global};`;
|
|
84
|
+
});
|
|
85
|
+
// Match: import Default from "/node_modules/{pkg}.js?v=..."
|
|
86
|
+
const resolvedDefaultRe = new RegExp(`import\\s+([\\w$]+)\\s+from\\s+['"][^'"]*/${escapeRegExp(pathPattern)}(?:\\.js)?(?:\\?[^'"]*)?['"]\\s*;?`, "g");
|
|
87
|
+
result = result.replace(resolvedDefaultRe, (_, def) => `const ${def} = ${global}.default || ${global};`);
|
|
88
|
+
}
|
|
72
89
|
if (result === code)
|
|
73
90
|
return null;
|
|
74
91
|
return { code: result, map: null };
|
|
@@ -20,6 +20,9 @@ import { io as ioClient } from "socket.io-client";
|
|
|
20
20
|
*/
|
|
21
21
|
export function stratosDevServer(options) {
|
|
22
22
|
const { pluginDir } = options;
|
|
23
|
+
// Shared state between configureServer and handleHotUpdate hooks
|
|
24
|
+
let socket = null;
|
|
25
|
+
let pluginId = "unknown";
|
|
23
26
|
return {
|
|
24
27
|
name: "stratos-dev-server",
|
|
25
28
|
apply: "serve",
|
|
@@ -28,7 +31,6 @@ export function stratosDevServer(options) {
|
|
|
28
31
|
(process.env.STRATOS_PORT
|
|
29
32
|
? parseInt(process.env.STRATOS_PORT, 10)
|
|
30
33
|
: 2066);
|
|
31
|
-
let socket = null;
|
|
32
34
|
let retryTimeout = null;
|
|
33
35
|
let retryDelay = 3000;
|
|
34
36
|
const MAX_RETRY_DELAY = 30000;
|
|
@@ -41,7 +43,7 @@ export function stratosDevServer(options) {
|
|
|
41
43
|
catch {
|
|
42
44
|
console.error("[stratos-dev-server] Failed to read plugin.json at", manifestPath);
|
|
43
45
|
}
|
|
44
|
-
|
|
46
|
+
pluginId = manifest.id ?? "unknown";
|
|
45
47
|
function clearRetry() {
|
|
46
48
|
if (retryTimeout) {
|
|
47
49
|
clearTimeout(retryTimeout);
|
|
@@ -183,9 +185,35 @@ export function stratosDevServer(options) {
|
|
|
183
185
|
process.once("SIGTERM", cleanup);
|
|
184
186
|
// Start connecting after the HTTP server is listening
|
|
185
187
|
server.httpServer?.once("listening", () => {
|
|
188
|
+
// Set the HMR port dynamically so Vite's HMR client connects
|
|
189
|
+
// directly to this dev server's WebSocket (cross-origin is OK for WS).
|
|
190
|
+
const addr = server.httpServer?.address();
|
|
191
|
+
if (addr && typeof addr === "object") {
|
|
192
|
+
server.config.server.hmr =
|
|
193
|
+
typeof server.config.server.hmr === "object"
|
|
194
|
+
? {
|
|
195
|
+
...server.config.server.hmr,
|
|
196
|
+
port: addr.port,
|
|
197
|
+
clientPort: addr.port,
|
|
198
|
+
}
|
|
199
|
+
: { port: addr.port, clientPort: addr.port };
|
|
200
|
+
}
|
|
186
201
|
connect();
|
|
187
202
|
});
|
|
188
203
|
},
|
|
204
|
+
// Notify Stratos when UI source files change so it can reload the plugin
|
|
205
|
+
handleHotUpdate({ file }) {
|
|
206
|
+
// Only signal for UI source changes (not background, not config files)
|
|
207
|
+
if (file.includes("/src/") && !file.includes("/src/background/")) {
|
|
208
|
+
if (socket?.connected) {
|
|
209
|
+
console.log(`[stratos-dev-server] UI source changed: ${path.basename(file)}`);
|
|
210
|
+
socket.emit("dev:plugin-ui-updated", {
|
|
211
|
+
pluginId,
|
|
212
|
+
timestamp: Date.now(),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
},
|
|
189
217
|
};
|
|
190
218
|
}
|
|
191
219
|
//# sourceMappingURL=stratos-dev-server.js.map
|