skeleton-crew-runtime 0.2.0 → 0.2.1

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 CHANGED
@@ -1,459 +1,459 @@
1
- # Skeleton Crew Runtime v0.2.0
2
-
3
- **A minimal plugin runtime for building modular JavaScript applications.**
4
-
5
- Stop wiring up infrastructure. Start building features.
6
-
7
- ```bash
8
- npm install skeleton-crew-runtime@^0.2.0
9
- ```
10
-
11
- ## What's New in v0.2.0
12
-
13
- 🎯 **Generic Runtime/Context** - Full TypeScript generic support for type-safe configuration
14
- ⚡ **Sync Config Access** - Direct synchronous access to configuration via `ctx.config`
15
- 🔗 **Plugin Dependencies** - Explicit dependency resolution with validation
16
- 📝 **Enhanced Logger** - Logger available on context for all plugins
17
- 🔄 **100% Backward Compatible** - All v0.1.x code continues to work
18
-
19
- ### Quick Migration Example
20
-
21
- ```typescript
22
- // v0.1.x
23
- const runtime = new Runtime({
24
- hostContext: { config: myConfig }
25
- });
26
-
27
- // v0.2.0 - Fully typed!
28
- interface MyConfig { apiUrl: string; }
29
- const runtime = new Runtime<MyConfig>({
30
- config: { apiUrl: 'https://api.example.com' }
31
- });
32
- ```
33
-
34
- **[→ Complete Migration Guide](docs/guides/v0.1-to-v0.2-migration.md)**
35
-
36
- ---
37
- ## Documentation
38
-
39
- ### Getting Started
40
- - **[Installation](docs/getting-started/installation.md)** - Install and setup
41
- - **[API Reference](docs/api/reference.md)** - Complete TypeScript API
42
- - **[Core Concepts](docs/getting-started/README.md)** - Understand the fundamentals
43
- - **[Your First Plugin](docs/getting-started/your-first-plugin.md)** - Build your first feature
44
-
45
- ### v0.2.0 Migration & Guides
46
- - **[v0.1.x → v0.2.0 Migration](docs/guides/v0.1-to-v0.2-migration.md)** - Complete migration walkthrough
47
- - **[Plugin Dependencies](docs/guides/plugin-dependencies.md)** - Dependency patterns and best practices
48
- - **[Sync vs Async Patterns](docs/guides/sync-async-patterns.md)** - Configuration and execution patterns
49
- - **[Real-World Examples](docs/guides/real-world-examples.md)** - Production-ready implementations
50
- - **[Migration Guide](docs/guides/migration-guide.md)** - Integrate with existing apps
51
- - **[Examples Guide](docs/guides/EXAMPLES_GUIDE.md)** - Learn through code examples
52
-
53
- ### Use Cases
54
- - **[Browser Extensions](docs/use-cases/BROWSER_TOOLS.md)** - Build browser tools
55
- - **[CLI Applications](docs/use-cases/)** - Command-line tools
56
- - **[Real-Time Apps](docs/use-cases/)** - Collaboration and sync
57
-
58
- ### Advanced
59
- - **[Architecture](docs/architecture/)** - How it works under the hood
60
- - **[Troubleshooting](docs/troubleshooting/)** - Common issues and solutions
61
-
62
- ---
63
-
64
- ## What is this?
65
-
66
- Skeleton Crew Runtime is a lightweight foundation for building applications where features can be added, removed, or replaced without touching existing code. Think VS Code's extension system, but for any JavaScript application.
67
-
68
- **Core idea:** Your app is a collection of plugins. Each plugin registers actions (business logic), screens (UI definitions), and events (communication). The runtime coordinates everything.
69
-
70
- **Result:** Add features by dropping in plugins. Remove features by taking them out. No refactoring. No breaking changes.
71
-
72
- ## Why would I use this?
73
-
74
- You're building something modular and you might know these challenges:
75
-
76
- - **Wiring up infrastructure** - Event buses, plugin loaders, action registries
77
- - **Tight coupling** - Changing one feature breaks three others
78
- - **Testing nightmares** - Can't test features in isolation
79
- - **Framework lock-in** - Married to React/Vue/whatever forever
80
- - **Refactoring hell** - Adding features means touching existing code
81
-
82
- **Skeleton Crew Runtime gives you:**
83
-
84
- - **Plugin isolation** - Features don't know about each other
85
- - **Event-driven communication** - Plugins coordinate without coupling
86
- - **Framework freedom** - Business logic separate from UI
87
- - **Testability** - Mock what you need, test what matters
88
- - **Minimal core** - < 5KB, zero dependencies
89
-
90
- ## Show me code
91
-
92
- Here's a complete plugin that adds a feature to your app:
93
-
94
- ```typescript
95
- import { Runtime, PluginDefinition, RuntimeContext } from 'skeleton-crew-runtime';
96
-
97
- // v0.2.0: Define your config interface
98
- interface AppConfig {
99
- notifications: {
100
- apiKey: string;
101
- defaultTimeout: number;
102
- };
103
- features: {
104
- pushNotifications: boolean;
105
- };
106
- }
107
-
108
- // 1. Create typed runtime
109
- const runtime = new Runtime<AppConfig>({
110
- config: {
111
- notifications: {
112
- apiKey: process.env.NOTIFICATION_API_KEY!,
113
- defaultTimeout: 5000
114
- },
115
- features: {
116
- pushNotifications: true
117
- }
118
- }
119
- });
120
-
121
- await runtime.initialize();
122
- const ctx = runtime.getContext();
123
-
124
- // 2. Write a plugin (this is a complete feature)
125
- const notificationsPlugin: PluginDefinition<AppConfig> = {
126
- name: 'notifications',
127
- version: '1.0.0',
128
- dependencies: [], // v0.2.0: Explicit dependencies
129
-
130
- setup(ctx: RuntimeContext<AppConfig>) {
131
- // ✅ Fully typed config access
132
- const { notifications, features } = ctx.config;
133
-
134
- if (!features.pushNotifications) {
135
- ctx.logger.info('Push notifications disabled');
136
- return;
137
- }
138
-
139
- // Register business logic with type safety
140
- ctx.actions.registerAction<
141
- { userId: string; message: string },
142
- { success: boolean; messageId: string }
143
- >({
144
- id: 'notifications:send',
145
- handler: async ({ userId, message }, ctx) => {
146
- // ✅ Typed config access in handlers
147
- const { apiKey, defaultTimeout } = ctx.config.notifications;
148
-
149
- // Your logic here
150
- const messageId = await sendPushNotification(userId, message, {
151
- apiKey,
152
- timeout: defaultTimeout
153
- });
154
-
155
- // Let other plugins know
156
- ctx.events.emit('notification:sent', { userId, messageId });
157
-
158
- return { success: true, messageId };
159
- },
160
- timeout: notifications.defaultTimeout
161
- });
162
-
163
- // React to other plugins
164
- ctx.events.on('user:registered', async (user: any) => {
165
- await ctx.actions.runAction('notifications:send', {
166
- userId: user.id,
167
- message: 'Welcome!'
168
- });
169
- });
170
-
171
- ctx.logger.info('Notifications plugin initialized');
172
- }
173
- };
174
-
175
- // 3. Register and use
176
- ctx.plugins.registerPlugin(notificationsPlugin);
177
-
178
- // anywhere in your app - fully typed!
179
- const result = await ctx.actions.runAction('notifications:send', {
180
- userId: '123',
181
- message: 'Your order shipped!'
182
- });
183
-
184
- console.log(`Message sent: ${result.messageId}`);
185
- ```
186
-
187
- **That's it.** The plugin is isolated, testable, fully typed, and can be removed without breaking anything.
188
-
189
- ## Core concepts (5 minutes)
190
-
191
- ### 1. Plugins: Isolated Features
192
-
193
- A plugin is just an object with a name and a setup function:
194
-
195
- ```typescript
196
- import type { PluginDefinition, RuntimeContext } from 'skeleton-crew-runtime';
197
-
198
- // v0.2.0: Define your config type
199
- interface MyAppConfig {
200
- apiUrl: string;
201
- features: { analytics: boolean };
202
- }
203
-
204
- export const myPlugin: PluginDefinition<MyAppConfig> = {
205
- name: 'my-plugin',
206
- version: '1.0.0',
207
- dependencies: ['config'], // v0.2.0: Explicit dependencies
208
-
209
- setup(ctx: RuntimeContext<MyAppConfig>) {
210
- // ✅ Fully typed config access
211
- const { apiUrl, features } = ctx.config;
212
-
213
- if (features.analytics) {
214
- ctx.logger.info(`Plugin initialized for ${apiUrl}`);
215
- }
216
-
217
- // Register your feature here
218
- },
219
-
220
- dispose(ctx: RuntimeContext<MyAppConfig>) {
221
- // Optional: cleanup resources when plugin is removed
222
- // Use this for: closing connections, clearing timers, releasing memory
223
- // Event listeners auto-cleanup, so you usually don't need this
224
- }
225
- };
226
- ```
227
-
228
- ### 2. Actions: Business Logic
229
-
230
- Actions are named functions that do work:
231
-
232
- ```typescript
233
- // v0.2.0: Type-safe action registration
234
- interface CreateOrderParams {
235
- customerId: string;
236
- items: Array<{ id: string; quantity: number }>;
237
- }
238
-
239
- interface Order {
240
- id: string;
241
- customerId: string;
242
- total: number;
243
- status: 'pending' | 'confirmed';
244
- }
245
-
246
- // Register an action
247
- ctx.actions.registerAction<CreateOrderParams, Order>({
248
- id: 'orders:create',
249
- handler: async (orderData, ctx) => {
250
- // ✅ Typed config access
251
- const { apiUrl } = ctx.config;
252
-
253
- // ✅ Typed parameters
254
- const { customerId, items } = orderData;
255
-
256
- const order = await createOrder(customerId, items);
257
- ctx.events.emit('order:created', order);
258
-
259
- ctx.logger.info(`Order created: ${order.id}`);
260
- return order; // ✅ Typed return value
261
- },
262
- timeout: 10000 // Optional timeout
263
- });
264
-
265
- // Call from anywhere - fully typed!
266
- const order = await ctx.actions.runAction<CreateOrderParams, Order>(
267
- 'orders:create',
268
- { customerId: '123', items: [{ id: 'item1', quantity: 2 }] }
269
- );
270
- ```
271
-
272
- ### 3. Events: Decouple Features
273
-
274
- Plugins communicate without knowing about each other:
275
-
276
- ```typescript
277
- // Plugin A: Emit event
278
- ctx.events.emit('order:created', order);
279
-
280
- // Plugin B: React (doesn't know about Plugin A)
281
- ctx.events.on('order:created', (order) => {
282
- sendConfirmationEmail(order);
283
- });
284
-
285
- // v0.2.0: Async event handling
286
- await ctx.events.emitAsync('order:created', order); // Wait for all handlers
287
- ```
288
-
289
- ### 4. Configuration: Type-Safe Access (v0.2.0)
290
-
291
- Direct synchronous access to typed configuration:
292
-
293
- ```typescript
294
- import { Runtime } from 'skeleton-crew-runtime';
295
-
296
- interface AppConfig {
297
- database: { url: string; maxConnections: number };
298
- api: { baseUrl: string; timeout: number };
299
- features: { caching: boolean; analytics: boolean };
300
- }
301
-
302
- const runtime = new Runtime<AppConfig>({
303
- config: {
304
- database: {
305
- url: process.env.DATABASE_URL!,
306
- maxConnections: 10
307
- },
308
- api: {
309
- baseUrl: 'https://api.example.com',
310
- timeout: 5000
311
- },
312
- features: {
313
- caching: true,
314
- analytics: process.env.NODE_ENV === 'production'
315
- }
316
- }
317
- });
318
-
319
- // In plugins: direct typed access
320
- setup(ctx: RuntimeContext<AppConfig>) {
321
- // ✅ Fully typed, synchronous access
322
- const { database, api, features } = ctx.config;
323
-
324
- if (features.caching) {
325
- initializeCache();
326
- }
327
-
328
- // ✅ Available in action handlers
329
- ctx.actions.registerAction({
330
- id: 'api:request',
331
- handler: async (endpoint: string) => {
332
- const { baseUrl, timeout } = ctx.config.api;
333
- return await fetch(`${baseUrl}${endpoint}`, { timeout });
334
- }
335
- });
336
- }
337
- ```
338
-
339
- ### 5. Host Context: Bridge to Existing Code
340
-
341
- Inject your existing services so plugins can use them:
342
-
343
- ```typescript
344
- import { Runtime } from 'skeleton-crew-runtime';
345
-
346
- const runtime = new Runtime<AppConfig>({
347
- config: myTypedConfig,
348
- hostContext: {
349
- // Legacy services
350
- db: yourDatabase,
351
- cache: redisClient,
352
- logger: yourLogger
353
- }
354
- });
355
-
356
- await runtime.initialize();
357
- const ctx = runtime.getContext();
358
-
359
- // Plugins access via ctx.host (for legacy integration)
360
- const { db, logger } = ctx.host;
361
- ```
362
-
363
- ### 6. Screens (Optional): UI Definitions
364
-
365
- Define screens that any UI framework can render:
366
-
367
- ```typescript
368
- ctx.screens.registerScreen({
369
- id: 'orders:list',
370
- title: 'Orders',
371
- component: 'OrderListComponent' // string, class, function, or any type
372
- });
373
- ```
374
-
375
- ---
376
-
377
- ## What can I build?
378
-
379
- Skeleton Crew works for any modular JavaScript application:
380
-
381
- ### Developer Tools
382
- - **CLI tools** - Task runners, deployment scripts, dev environments
383
- - **Browser extensions** - Tab managers, productivity tools, dev tools
384
- - **Build tools** - Custom bundlers, code generators, linters
385
-
386
- ### Internal Applications
387
- - **Admin panels** - User management, content moderation, analytics
388
- - **Dashboards** - Monitoring, reporting, data visualization
389
- - **Workflow tools** - Approval systems, task management, automation
390
-
391
- ### Real-Time Applications
392
- - **Collaboration tools** - Shared editing, presence, chat
393
- - **Live dashboards** - Stock tickers, sports scores, IoT monitoring
394
- - **Multiplayer features** - Game state sync, player coordination
395
-
396
- ### Modular Systems
397
- - **Plugin marketplaces** - Let users extend your app
398
- - **White-label products** - Different features for different customers
399
- - **Microservices** - Coordinate distributed services
400
-
401
- **Not ideal for:** Public-facing websites (use Next.js), complex routing (use React Router), heavy state management (use Redux).
402
-
403
- ---
404
-
405
- ## Real examples
406
-
407
- ### CLI Tool (150 lines vs 500+)
408
- **What you'll see:** Interactive CLI that runs commands, shows output, handles errors. All plugin-based.
409
-
410
- ```bash
411
- # Build a command palette for Git, npm, and Docker:
412
- cd demo/dev-launcher
413
- npm install && npm start
414
- ```
415
-
416
- ### Real-Time Collaboration (130 lines vs 500+)
417
- **What you'll see:** Multiple clients syncing state in real-time. No Firebase, no Socket.io boilerplate.
418
-
419
- ```bash
420
- # Build a multi-user sync system:
421
- cd demo/collab-hub
422
- npm install && npm run build
423
- npm run server # Terminal 1
424
- npm run client # Terminal 2-3
425
- ```
426
-
427
- **[See all demos →](demo/README.md)**
428
-
429
- ---
430
-
431
- ## FAQ
432
-
433
- ### Do I need to rewrite my app?
434
-
435
- No. Skeleton Crew runs alongside your existing code. Write new features as plugins, keep old code unchanged.
436
-
437
- ### What if I want to migrate existing features later?
438
-
439
- You can gradually replace legacy code with plugins using feature flags. Or don't — both approaches work fine.
440
-
441
- ### Does this work with my UI framework?
442
-
443
- Yes. Skeleton Crew is UI-agnostic. Use React, Vue, Svelte, or no UI at all. The runtime doesn't care.
444
-
445
- ### Is this overkill for small apps?
446
-
447
- Possibly. If you have a simple app with no legacy code and no plans to grow, you might not need this. But if you're dealing with technical debt or planning for modularity, it's a good fit.
448
-
449
- ### How big is the runtime?
450
-
451
- Less than 5KB gzipped. Minimal overhead.
452
-
453
- ### Can I use this in production?
454
-
455
- Yes. The runtime is stable and tested. Start with non-critical features, then expand.
456
-
457
- ---
458
-
459
- **Built for developers who need to modernize legacy apps without the risk of a full rewrite.**
1
+ # Skeleton Crew Runtime v0.2.0
2
+
3
+ **A minimal plugin runtime for building modular JavaScript applications.**
4
+
5
+ Stop wiring up infrastructure. Start building features.
6
+
7
+ ```bash
8
+ npm install skeleton-crew-runtime@^0.2.0
9
+ ```
10
+
11
+ ## What's New in v0.2.0
12
+
13
+ 🎯 **Generic Runtime/Context** - Full TypeScript generic support for type-safe configuration
14
+ ⚡ **Sync Config Access** - Direct synchronous access to configuration via `ctx.config`
15
+ 🔗 **Plugin Dependencies** - Explicit dependency resolution with validation
16
+ 📝 **Enhanced Logger** - Logger available on context for all plugins
17
+ 🔄 **100% Backward Compatible** - All v0.1.x code continues to work
18
+
19
+ ### Quick Migration Example
20
+
21
+ ```typescript
22
+ // v0.1.x
23
+ const runtime = new Runtime({
24
+ hostContext: { config: myConfig }
25
+ });
26
+
27
+ // v0.2.0 - Fully typed!
28
+ interface MyConfig { apiUrl: string; }
29
+ const runtime = new Runtime<MyConfig>({
30
+ config: { apiUrl: 'https://api.example.com' }
31
+ });
32
+ ```
33
+
34
+ **[→ Complete Migration Guide](docs/guides/v0.1-to-v0.2-migration.md)**
35
+
36
+ ---
37
+ ## Documentation
38
+
39
+ ### Getting Started
40
+ - **[Installation](docs/getting-started/installation.md)** - Install and setup
41
+ - **[API Reference](docs/api/reference.md)** - Complete TypeScript API
42
+ - **[Core Concepts](docs/getting-started/README.md)** - Understand the fundamentals
43
+ - **[Your First Plugin](docs/getting-started/your-first-plugin.md)** - Build your first feature
44
+
45
+ ### v0.2.0 Migration & Guides
46
+ - **[v0.1.x → v0.2.0 Migration](docs/guides/v0.1-to-v0.2-migration.md)** - Complete migration walkthrough
47
+ - **[Plugin Dependencies](docs/guides/plugin-dependencies.md)** - Dependency patterns and best practices
48
+ - **[Sync vs Async Patterns](docs/guides/sync-async-patterns.md)** - Configuration and execution patterns
49
+ - **[Real-World Examples](docs/guides/real-world-examples.md)** - Production-ready implementations
50
+ - **[Migration Guide](docs/guides/migration-guide.md)** - Integrate with existing apps
51
+ - **[Examples Guide](docs/guides/EXAMPLES_GUIDE.md)** - Learn through code examples
52
+
53
+ ### Use Cases
54
+ - **[Browser Extensions](docs/use-cases/BROWSER_TOOLS.md)** - Build browser tools
55
+ - **[CLI Applications](docs/use-cases/)** - Command-line tools
56
+ - **[Real-Time Apps](docs/use-cases/)** - Collaboration and sync
57
+
58
+ ### Advanced
59
+ - **[Architecture](docs/architecture/)** - How it works under the hood
60
+ - **[Troubleshooting](docs/troubleshooting/)** - Common issues and solutions
61
+
62
+ ---
63
+
64
+ ## What is this?
65
+
66
+ Skeleton Crew Runtime is a lightweight foundation for building applications where features can be added, removed, or replaced without touching existing code. Think VS Code's extension system, but for any JavaScript application.
67
+
68
+ **Core idea:** Your app is a collection of plugins. Each plugin registers actions (business logic), screens (UI definitions), and events (communication). The runtime coordinates everything.
69
+
70
+ **Result:** Add features by dropping in plugins. Remove features by taking them out. No refactoring. No breaking changes.
71
+
72
+ ## Why would I use this?
73
+
74
+ You're building something modular and you might know these challenges:
75
+
76
+ - **Wiring up infrastructure** - Event buses, plugin loaders, action registries
77
+ - **Tight coupling** - Changing one feature breaks three others
78
+ - **Testing nightmares** - Can't test features in isolation
79
+ - **Framework lock-in** - Married to React/Vue/whatever forever
80
+ - **Refactoring hell** - Adding features means touching existing code
81
+
82
+ **Skeleton Crew Runtime gives you:**
83
+
84
+ - **Plugin isolation** - Features don't know about each other
85
+ - **Event-driven communication** - Plugins coordinate without coupling
86
+ - **Framework freedom** - Business logic separate from UI
87
+ - **Testability** - Mock what you need, test what matters
88
+ - **Minimal core** - < 5KB, zero dependencies
89
+
90
+ ## Show me code
91
+
92
+ Here's a complete plugin that adds a feature to your app:
93
+
94
+ ```typescript
95
+ import { Runtime, PluginDefinition, RuntimeContext } from 'skeleton-crew-runtime';
96
+
97
+ // v0.2.0: Define your config interface
98
+ interface AppConfig {
99
+ notifications: {
100
+ apiKey: string;
101
+ defaultTimeout: number;
102
+ };
103
+ features: {
104
+ pushNotifications: boolean;
105
+ };
106
+ }
107
+
108
+ // 1. Create typed runtime
109
+ const runtime = new Runtime<AppConfig>({
110
+ config: {
111
+ notifications: {
112
+ apiKey: process.env.NOTIFICATION_API_KEY!,
113
+ defaultTimeout: 5000
114
+ },
115
+ features: {
116
+ pushNotifications: true
117
+ }
118
+ }
119
+ });
120
+
121
+ await runtime.initialize();
122
+ const ctx = runtime.getContext();
123
+
124
+ // 2. Write a plugin (this is a complete feature)
125
+ const notificationsPlugin: PluginDefinition<AppConfig> = {
126
+ name: 'notifications',
127
+ version: '1.0.0',
128
+ dependencies: [], // v0.2.0: Explicit dependencies
129
+
130
+ setup(ctx: RuntimeContext<AppConfig>) {
131
+ // ✅ Fully typed config access
132
+ const { notifications, features } = ctx.config;
133
+
134
+ if (!features.pushNotifications) {
135
+ ctx.logger.info('Push notifications disabled');
136
+ return;
137
+ }
138
+
139
+ // Register business logic with type safety
140
+ ctx.actions.registerAction<
141
+ { userId: string; message: string },
142
+ { success: boolean; messageId: string }
143
+ >({
144
+ id: 'notifications:send',
145
+ handler: async ({ userId, message }, ctx) => {
146
+ // ✅ Typed config access in handlers
147
+ const { apiKey, defaultTimeout } = ctx.config.notifications;
148
+
149
+ // Your logic here
150
+ const messageId = await sendPushNotification(userId, message, {
151
+ apiKey,
152
+ timeout: defaultTimeout
153
+ });
154
+
155
+ // Let other plugins know
156
+ ctx.events.emit('notification:sent', { userId, messageId });
157
+
158
+ return { success: true, messageId };
159
+ },
160
+ timeout: notifications.defaultTimeout
161
+ });
162
+
163
+ // React to other plugins
164
+ ctx.events.on('user:registered', async (user: any) => {
165
+ await ctx.actions.runAction('notifications:send', {
166
+ userId: user.id,
167
+ message: 'Welcome!'
168
+ });
169
+ });
170
+
171
+ ctx.logger.info('Notifications plugin initialized');
172
+ }
173
+ };
174
+
175
+ // 3. Register and use
176
+ ctx.plugins.registerPlugin(notificationsPlugin);
177
+
178
+ // anywhere in your app - fully typed!
179
+ const result = await ctx.actions.runAction('notifications:send', {
180
+ userId: '123',
181
+ message: 'Your order shipped!'
182
+ });
183
+
184
+ console.log(`Message sent: ${result.messageId}`);
185
+ ```
186
+
187
+ **That's it.** The plugin is isolated, testable, fully typed, and can be removed without breaking anything.
188
+
189
+ ## Core concepts (5 minutes)
190
+
191
+ ### 1. Plugins: Isolated Features
192
+
193
+ A plugin is just an object with a name and a setup function:
194
+
195
+ ```typescript
196
+ import type { PluginDefinition, RuntimeContext } from 'skeleton-crew-runtime';
197
+
198
+ // v0.2.0: Define your config type
199
+ interface MyAppConfig {
200
+ apiUrl: string;
201
+ features: { analytics: boolean };
202
+ }
203
+
204
+ export const myPlugin: PluginDefinition<MyAppConfig> = {
205
+ name: 'my-plugin',
206
+ version: '1.0.0',
207
+ dependencies: ['config'], // v0.2.0: Explicit dependencies
208
+
209
+ setup(ctx: RuntimeContext<MyAppConfig>) {
210
+ // ✅ Fully typed config access
211
+ const { apiUrl, features } = ctx.config;
212
+
213
+ if (features.analytics) {
214
+ ctx.logger.info(`Plugin initialized for ${apiUrl}`);
215
+ }
216
+
217
+ // Register your feature here
218
+ },
219
+
220
+ dispose(ctx: RuntimeContext<MyAppConfig>) {
221
+ // Optional: cleanup resources when plugin is removed
222
+ // Use this for: closing connections, clearing timers, releasing memory
223
+ // Event listeners auto-cleanup, so you usually don't need this
224
+ }
225
+ };
226
+ ```
227
+
228
+ ### 2. Actions: Business Logic
229
+
230
+ Actions are named functions that do work:
231
+
232
+ ```typescript
233
+ // v0.2.0: Type-safe action registration
234
+ interface CreateOrderParams {
235
+ customerId: string;
236
+ items: Array<{ id: string; quantity: number }>;
237
+ }
238
+
239
+ interface Order {
240
+ id: string;
241
+ customerId: string;
242
+ total: number;
243
+ status: 'pending' | 'confirmed';
244
+ }
245
+
246
+ // Register an action
247
+ ctx.actions.registerAction<CreateOrderParams, Order>({
248
+ id: 'orders:create',
249
+ handler: async (orderData, ctx) => {
250
+ // ✅ Typed config access
251
+ const { apiUrl } = ctx.config;
252
+
253
+ // ✅ Typed parameters
254
+ const { customerId, items } = orderData;
255
+
256
+ const order = await createOrder(customerId, items);
257
+ ctx.events.emit('order:created', order);
258
+
259
+ ctx.logger.info(`Order created: ${order.id}`);
260
+ return order; // ✅ Typed return value
261
+ },
262
+ timeout: 10000 // Optional timeout
263
+ });
264
+
265
+ // Call from anywhere - fully typed!
266
+ const order = await ctx.actions.runAction<CreateOrderParams, Order>(
267
+ 'orders:create',
268
+ { customerId: '123', items: [{ id: 'item1', quantity: 2 }] }
269
+ );
270
+ ```
271
+
272
+ ### 3. Events: Decouple Features
273
+
274
+ Plugins communicate without knowing about each other:
275
+
276
+ ```typescript
277
+ // Plugin A: Emit event
278
+ ctx.events.emit('order:created', order);
279
+
280
+ // Plugin B: React (doesn't know about Plugin A)
281
+ ctx.events.on('order:created', (order) => {
282
+ sendConfirmationEmail(order);
283
+ });
284
+
285
+ // v0.2.0: Async event handling
286
+ await ctx.events.emitAsync('order:created', order); // Wait for all handlers
287
+ ```
288
+
289
+ ### 4. Configuration: Type-Safe Access (v0.2.0)
290
+
291
+ Direct synchronous access to typed configuration:
292
+
293
+ ```typescript
294
+ import { Runtime } from 'skeleton-crew-runtime';
295
+
296
+ interface AppConfig {
297
+ database: { url: string; maxConnections: number };
298
+ api: { baseUrl: string; timeout: number };
299
+ features: { caching: boolean; analytics: boolean };
300
+ }
301
+
302
+ const runtime = new Runtime<AppConfig>({
303
+ config: {
304
+ database: {
305
+ url: process.env.DATABASE_URL!,
306
+ maxConnections: 10
307
+ },
308
+ api: {
309
+ baseUrl: 'https://api.example.com',
310
+ timeout: 5000
311
+ },
312
+ features: {
313
+ caching: true,
314
+ analytics: process.env.NODE_ENV === 'production'
315
+ }
316
+ }
317
+ });
318
+
319
+ // In plugins: direct typed access
320
+ setup(ctx: RuntimeContext<AppConfig>) {
321
+ // ✅ Fully typed, synchronous access
322
+ const { database, api, features } = ctx.config;
323
+
324
+ if (features.caching) {
325
+ initializeCache();
326
+ }
327
+
328
+ // ✅ Available in action handlers
329
+ ctx.actions.registerAction({
330
+ id: 'api:request',
331
+ handler: async (endpoint: string) => {
332
+ const { baseUrl, timeout } = ctx.config.api;
333
+ return await fetch(`${baseUrl}${endpoint}`, { timeout });
334
+ }
335
+ });
336
+ }
337
+ ```
338
+
339
+ ### 5. Host Context: Bridge to Existing Code
340
+
341
+ Inject your existing services so plugins can use them:
342
+
343
+ ```typescript
344
+ import { Runtime } from 'skeleton-crew-runtime';
345
+
346
+ const runtime = new Runtime<AppConfig>({
347
+ config: myTypedConfig,
348
+ hostContext: {
349
+ // Legacy services
350
+ db: yourDatabase,
351
+ cache: redisClient,
352
+ logger: yourLogger
353
+ }
354
+ });
355
+
356
+ await runtime.initialize();
357
+ const ctx = runtime.getContext();
358
+
359
+ // Plugins access via ctx.host (for legacy integration)
360
+ const { db, logger } = ctx.host;
361
+ ```
362
+
363
+ ### 6. Screens (Optional): UI Definitions
364
+
365
+ Define screens that any UI framework can render:
366
+
367
+ ```typescript
368
+ ctx.screens.registerScreen({
369
+ id: 'orders:list',
370
+ title: 'Orders',
371
+ component: 'OrderListComponent' // string, class, function, or any type
372
+ });
373
+ ```
374
+
375
+ ---
376
+
377
+ ## What can I build?
378
+
379
+ Skeleton Crew works for any modular JavaScript application:
380
+
381
+ ### Developer Tools
382
+ - **CLI tools** - Task runners, deployment scripts, dev environments
383
+ - **Browser extensions** - Tab managers, productivity tools, dev tools
384
+ - **Build tools** - Custom bundlers, code generators, linters
385
+
386
+ ### Internal Applications
387
+ - **Admin panels** - User management, content moderation, analytics
388
+ - **Dashboards** - Monitoring, reporting, data visualization
389
+ - **Workflow tools** - Approval systems, task management, automation
390
+
391
+ ### Real-Time Applications
392
+ - **Collaboration tools** - Shared editing, presence, chat
393
+ - **Live dashboards** - Stock tickers, sports scores, IoT monitoring
394
+ - **Multiplayer features** - Game state sync, player coordination
395
+
396
+ ### Modular Systems
397
+ - **Plugin marketplaces** - Let users extend your app
398
+ - **White-label products** - Different features for different customers
399
+ - **Microservices** - Coordinate distributed services
400
+
401
+ **Not ideal for:** Public-facing websites (use Next.js), complex routing (use React Router), heavy state management (use Redux).
402
+
403
+ ---
404
+
405
+ ## Real examples
406
+
407
+ ### CLI Tool (150 lines vs 500+)
408
+ **What you'll see:** Interactive CLI that runs commands, shows output, handles errors. All plugin-based.
409
+
410
+ ```bash
411
+ # Build a command palette for Git, npm, and Docker:
412
+ cd demo/dev-launcher
413
+ npm install && npm start
414
+ ```
415
+
416
+ ### Real-Time Collaboration (130 lines vs 500+)
417
+ **What you'll see:** Multiple clients syncing state in real-time. No Firebase, no Socket.io boilerplate.
418
+
419
+ ```bash
420
+ # Build a multi-user sync system:
421
+ cd demo/collab-hub
422
+ npm install && npm run build
423
+ npm run server # Terminal 1
424
+ npm run client # Terminal 2-3
425
+ ```
426
+
427
+ **[See all demos →](demo/README.md)**
428
+
429
+ ---
430
+
431
+ ## FAQ
432
+
433
+ ### Do I need to rewrite my app?
434
+
435
+ No. Skeleton Crew runs alongside your existing code. Write new features as plugins, keep old code unchanged.
436
+
437
+ ### What if I want to migrate existing features later?
438
+
439
+ You can gradually replace legacy code with plugins using feature flags. Or don't — both approaches work fine.
440
+
441
+ ### Does this work with my UI framework?
442
+
443
+ Yes. Skeleton Crew is UI-agnostic. Use React, Vue, Svelte, or no UI at all. The runtime doesn't care.
444
+
445
+ ### Is this overkill for small apps?
446
+
447
+ Possibly. If you have a simple app with no legacy code and no plans to grow, you might not need this. But if you're dealing with technical debt or planning for modularity, it's a good fit.
448
+
449
+ ### How big is the runtime?
450
+
451
+ Less than 5KB gzipped. Minimal overhead.
452
+
453
+ ### Can I use this in production?
454
+
455
+ Yes. The runtime is stable and tested. Start with non-critical features, then expand.
456
+
457
+ ---
458
+
459
+ **Built for developers who need to modernize legacy apps without the risk of a full rewrite.**