@majkapp/plugin-kit 1.0.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/README.md ADDED
@@ -0,0 +1,636 @@
1
+ # @majk/plugin-kit
2
+
3
+ **Fluent builder framework for creating robust MAJK plugins**
4
+
5
+ Build type-safe, production-ready MAJK plugins with excellent developer experience, comprehensive validation, and clear error messages.
6
+
7
+ ## Features
8
+
9
+ โœจ **Fluent API** - Chainable builder pattern with full TypeScript support
10
+ ๐Ÿ›ก๏ธ **Type Safety** - Compile-time checks for routes, IDs, and descriptions
11
+ โœ… **Build-Time Validation** - Catches errors before runtime
12
+ ๐Ÿ“ **Clear Error Messages** - Actionable suggestions when things go wrong
13
+ ๐Ÿ”„ **Auto HTTP Server** - Built-in routing, CORS, error handling
14
+ โš›๏ธ **React & HTML Screens** - Support for both SPA and simple HTML UIs
15
+ ๐Ÿ”ง **Tool Management** - Declare tools with schema validation
16
+ ๐Ÿ’พ **Storage Integration** - Direct access to plugin storage
17
+ ๐Ÿ“ก **Event Bus** - Subscribe to system events
18
+ ๐Ÿงน **Auto Cleanup** - Managed lifecycle with automatic resource cleanup
19
+ โค๏ธ **Health Checks** - Built-in health monitoring
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @majk/plugin-kit
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { definePlugin } from '@majk/plugin-kit';
31
+
32
+ export default definePlugin('my-plugin', 'My Plugin', '1.0.0')
33
+ .ui({ appDir: 'ui/dist' })
34
+
35
+ .topbar('/plugin-screens/my-plugin/dashboard', {
36
+ icon: '๐Ÿš€'
37
+ })
38
+
39
+ .screenReact({
40
+ id: 'dashboard',
41
+ name: 'Dashboard',
42
+ description: 'Main dashboard for my plugin. Shows key metrics and actions.',
43
+ route: '/plugin-screens/my-plugin/dashboard',
44
+ reactPath: '/'
45
+ })
46
+
47
+ .apiRoute({
48
+ method: 'GET',
49
+ path: '/api/data',
50
+ name: 'Get Data',
51
+ description: 'Retrieves plugin data. Returns formatted response with metadata.',
52
+ handler: async (req, res, { majk, storage }) => {
53
+ const data = await storage.get('data') || [];
54
+ return { data, count: data.length };
55
+ }
56
+ })
57
+
58
+ .tool('global', {
59
+ name: 'myTool',
60
+ description: 'Does something useful. Processes input and returns results.',
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ param: { type: 'string' }
65
+ },
66
+ required: ['param']
67
+ }
68
+ }, async (input, { logger }) => {
69
+ logger.info(`Tool called with: ${input.param}`);
70
+ return { success: true, result: input.param.toUpperCase() };
71
+ })
72
+
73
+ .build();
74
+ ```
75
+
76
+ ## Core Concepts
77
+
78
+ ### Plugin Definition
79
+
80
+ Every plugin starts with `definePlugin(id, name, version)`:
81
+
82
+ ```typescript
83
+ definePlugin('system-explorer', 'System Explorer', '1.0.0')
84
+ ```
85
+
86
+ **Rules:**
87
+ - `id` must be unique and URL-safe (kebab-case recommended)
88
+ - `name` is the display name
89
+ - `version` follows semver
90
+
91
+ ### Screens
92
+
93
+ #### React Screens
94
+
95
+ For React SPAs, configure UI first:
96
+
97
+ ```typescript
98
+ .ui({
99
+ appDir: 'ui/dist', // Where your built React app is
100
+ base: '/', // Base URL for the SPA
101
+ history: 'browser' // 'browser' or 'hash' routing
102
+ })
103
+
104
+ .screenReact({
105
+ id: 'dashboard',
106
+ name: 'Dashboard',
107
+ description: 'Main dashboard view. Shows metrics and controls.', // 2-3 sentences
108
+ route: '/plugin-screens/my-plugin/dashboard', // Must start with /plugin-screens/{id}/
109
+ reactPath: '/' // Path within your React app
110
+ })
111
+ ```
112
+
113
+ **The React app receives:**
114
+ - `window.__MAJK_BASE_URL__` - Host base URL
115
+ - `window.__MAJK_IFRAME_BASE__` - Plugin base path
116
+ - `window.__MAJK_PLUGIN_ID__` - Your plugin ID
117
+
118
+ #### HTML Screens
119
+
120
+ For simple HTML pages:
121
+
122
+ ```typescript
123
+ .screenHtml({
124
+ id: 'about',
125
+ name: 'About',
126
+ description: 'Information about the plugin. Shows version and author.',
127
+ route: '/plugin-screens/my-plugin/about',
128
+ html: '<html>...' // OR htmlFile: 'about.html'
129
+ })
130
+ ```
131
+
132
+ ### API Routes
133
+
134
+ Define REST endpoints:
135
+
136
+ ```typescript
137
+ .apiRoute({
138
+ method: 'POST',
139
+ path: '/api/tasks/:id/complete',
140
+ name: 'Complete Task',
141
+ description: 'Marks a task as complete. Updates task status and triggers notifications.',
142
+ handler: async (req, res, { majk, storage, logger }) => {
143
+ const { id } = req.params; // Path parameters
144
+ const { note } = req.body; // Request body
145
+ const status = req.query.get('status'); // Query params
146
+
147
+ logger.info(`Completing task ${id}`);
148
+
149
+ // Access MAJK APIs
150
+ const todos = await majk.todos.list();
151
+
152
+ // Use plugin storage
153
+ await storage.set(`task:${id}`, { completed: true });
154
+
155
+ return { success: true, taskId: id };
156
+ }
157
+ })
158
+ ```
159
+
160
+ **Available Methods:** `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
161
+
162
+ **Context Provided:**
163
+ - `majk` - Full MAJK API interface
164
+ - `storage` - Plugin-scoped key-value storage
165
+ - `logger` - Scoped logger (debug, info, warn, error)
166
+ - `http` - HTTP configuration (port, baseUrl, secret)
167
+
168
+ ### Tools
169
+
170
+ Tools are functions that agents can invoke:
171
+
172
+ ```typescript
173
+ .tool(
174
+ 'conversation', // Scope: 'global' | 'conversation' | 'teammate' | 'project'
175
+ {
176
+ name: 'analyzeSentiment',
177
+ description: 'Analyzes text sentiment. Returns positive, negative, or neutral classification.',
178
+ inputSchema: {
179
+ type: 'object',
180
+ properties: {
181
+ text: { type: 'string' }
182
+ },
183
+ required: ['text']
184
+ }
185
+ },
186
+ async (input, { majk, logger }) => {
187
+ logger.info('Analyzing sentiment');
188
+
189
+ // Your implementation
190
+ const sentiment = analyzeSentiment(input.text);
191
+
192
+ return {
193
+ success: true,
194
+ data: { sentiment, confidence: 0.95 }
195
+ };
196
+ }
197
+ )
198
+ ```
199
+
200
+ **Tool Scopes:**
201
+ - `global` - Available everywhere
202
+ - `conversation` - Scoped to conversations
203
+ - `teammate` - Scoped to teammates
204
+ - `project` - Scoped to projects
205
+
206
+ ### Entities
207
+
208
+ Declare entities your plugin provides:
209
+
210
+ ```typescript
211
+ .entity('teammate', [
212
+ {
213
+ id: 'bot-assistant',
214
+ name: 'Bot Assistant',
215
+ role: 'bot',
216
+ capabilities: ['analysis', 'reporting']
217
+ }
218
+ ])
219
+
220
+ .entity('mcpServer', [
221
+ {
222
+ id: 'custom-server',
223
+ name: 'Custom MCP Server',
224
+ transport: { type: 'stdio', command: 'node', args: ['server.js'] }
225
+ }
226
+ ])
227
+ ```
228
+
229
+ **Supported Entity Types:**
230
+ - `mcpServer` - MCP servers
231
+ - `teammate` - Team members/bots
232
+ - `conversation` - Conversations
233
+ - `todo` - Tasks
234
+ - `project` - Projects
235
+ - `agent` - AI agents
236
+
237
+ ### Config Wizard & Settings
238
+
239
+ #### Config Wizard
240
+
241
+ Show a wizard on first run:
242
+
243
+ ```typescript
244
+ .configWizard({
245
+ path: '/setup',
246
+ title: 'Initial Setup',
247
+ width: 600,
248
+ height: 400,
249
+ description: 'Configure plugin settings. Set up API keys and preferences.',
250
+ shouldShow: async (ctx) => {
251
+ const config = await ctx.storage.get('config');
252
+ return !config; // Show if no config exists
253
+ }
254
+ })
255
+ ```
256
+
257
+ #### Settings Screen
258
+
259
+ Ongoing settings management:
260
+
261
+ ```typescript
262
+ .settings({
263
+ path: '/settings',
264
+ title: 'Plugin Settings',
265
+ description: 'Manage plugin configuration. Adjust behavior and display options.'
266
+ })
267
+ ```
268
+
269
+ ### Lifecycle Hooks
270
+
271
+ #### onReady
272
+
273
+ Called after server starts, before `onLoad` completes:
274
+
275
+ ```typescript
276
+ .onReady(async (ctx, cleanup) => {
277
+ // Subscribe to events
278
+ const sub = ctx.majk.eventBus.conversations().subscribe((event) => {
279
+ ctx.logger.info(`Conversation event: ${event.type}`);
280
+ });
281
+ cleanup(() => sub.unsubscribe());
282
+
283
+ // Set up timers
284
+ const timer = setInterval(() => {
285
+ ctx.logger.debug('Periodic check');
286
+ }, 60000);
287
+ cleanup(() => clearInterval(timer));
288
+
289
+ // Any other setup
290
+ await loadData(ctx.storage);
291
+ })
292
+ ```
293
+
294
+ **Cleanup Registration:**
295
+ All cleanup functions are automatically called on `onUnload()`.
296
+
297
+ #### Health Checks
298
+
299
+ Define custom health monitoring:
300
+
301
+ ```typescript
302
+ .health(async ({ majk, storage, logger }) => {
303
+ try {
304
+ // Check dependencies
305
+ await majk.conversations.list();
306
+ await storage.get('health-check');
307
+
308
+ return {
309
+ healthy: true,
310
+ details: { api: 'ok', storage: 'ok' }
311
+ };
312
+ } catch (error) {
313
+ logger.error(`Health check failed: ${error.message}`);
314
+ return {
315
+ healthy: false,
316
+ details: { error: error.message }
317
+ };
318
+ }
319
+ })
320
+ ```
321
+
322
+ ## API Reference
323
+
324
+ ### PluginContext
325
+
326
+ Provided to all handlers and hooks:
327
+
328
+ ```typescript
329
+ interface PluginContext {
330
+ pluginId: string; // Your plugin ID
331
+ pluginRoot: string; // Plugin directory path
332
+ dataDir: string; // Plugin data directory
333
+
334
+ app: {
335
+ version: string; // MAJK version
336
+ name: string; // App name
337
+ appDataDir: string; // App data directory
338
+ };
339
+
340
+ http: {
341
+ port: number; // Assigned HTTP port
342
+ secret: string; // Security secret
343
+ baseUrl: string; // Base URL for iframe
344
+ };
345
+
346
+ majk: MajkInterface; // Full MAJK API
347
+ storage: PluginStorage; // Key-value storage
348
+ logger: PluginLogger; // Scoped logger
349
+ timers?: ScopedTimers; // Managed timers
350
+ ipc?: ScopedIpcRegistry; // Electron IPC
351
+ }
352
+ ```
353
+
354
+ ### MajkInterface
355
+
356
+ The main MAJK API:
357
+
358
+ ```typescript
359
+ interface MajkInterface {
360
+ conversations: ConversationAPI;
361
+ todos: TodoAPI;
362
+ projects: ProjectAPI;
363
+ teammates: TeammateAPI;
364
+ mcpServers: MCPServerAPI;
365
+ knowledge: KnowledgeAPI;
366
+ tasks: TaskAPI;
367
+ eventBus: EventBusAPI;
368
+ auth: AuthAPI;
369
+ secrets: SecretsAPI;
370
+ plugins: PluginManagementAPI;
371
+ }
372
+ ```
373
+
374
+ ### PluginStorage
375
+
376
+ Simple key-value storage scoped to your plugin:
377
+
378
+ ```typescript
379
+ interface PluginStorage {
380
+ get<T>(key: string): Promise<T | undefined>;
381
+ set<T>(key: string, value: T): Promise<void>;
382
+ delete(key: string): Promise<void>;
383
+ clear(): Promise<void>;
384
+ keys(): Promise<string[]>;
385
+ }
386
+ ```
387
+
388
+ **Example:**
389
+
390
+ ```typescript
391
+ // Save data
392
+ await storage.set('user-preferences', {
393
+ theme: 'dark',
394
+ notifications: true
395
+ });
396
+
397
+ // Load data
398
+ const prefs = await storage.get<Preferences>('user-preferences');
399
+
400
+ // List all keys
401
+ const keys = await storage.keys();
402
+
403
+ // Delete specific key
404
+ await storage.delete('old-data');
405
+
406
+ // Clear everything
407
+ await storage.clear();
408
+ ```
409
+
410
+ ### EventBus
411
+
412
+ Subscribe to system events:
413
+
414
+ ```typescript
415
+ // Listen to conversation events
416
+ const sub = majk.eventBus.conversations().subscribe((event) => {
417
+ console.log(`Event: ${event.type}`, event.entity);
418
+ });
419
+
420
+ // Unsubscribe
421
+ sub.unsubscribe();
422
+
423
+ // Specific event types
424
+ majk.eventBus.conversations().created().subscribe(...);
425
+ majk.eventBus.conversations().updated().subscribe(...);
426
+ majk.eventBus.conversations().deleted().subscribe(...);
427
+
428
+ // Custom channels
429
+ majk.eventBus.channel('my-events').subscribe(...);
430
+ ```
431
+
432
+ ## Validation & Error Handling
433
+
434
+ ### Build-Time Validation
435
+
436
+ The kit validates at build time:
437
+
438
+ โœ… **Route Prefixes** - Screen routes must match plugin ID
439
+ โœ… **File Existence** - React dist and HTML files must exist
440
+ โœ… **Uniqueness** - No duplicate routes, tools, or API endpoints
441
+ โœ… **Dependencies** - UI must be configured for React screens
442
+ โœ… **Descriptions** - Must be 2-3 sentences ending with period
443
+
444
+ **Example Error:**
445
+
446
+ ```
447
+ โŒ Plugin Build Failed: React screen route must start with "/plugin-screens/my-plugin/"
448
+ ๐Ÿ’ก Suggestion: Change route from "/screens/dashboard" to "/plugin-screens/my-plugin/dashboard"
449
+ ๐Ÿ“‹ Context: {
450
+ "screen": "dashboard",
451
+ "route": "/screens/dashboard"
452
+ }
453
+ ```
454
+
455
+ ### Runtime Error Handling
456
+
457
+ All API route errors are automatically caught and logged:
458
+
459
+ ```typescript
460
+ .apiRoute({
461
+ method: 'POST',
462
+ path: '/api/process',
463
+ name: 'Process Data',
464
+ description: 'Processes input data. Validates and transforms the payload.',
465
+ handler: async (req, res, { logger }) => {
466
+ // Errors are automatically caught and returned as 500 responses
467
+ throw new Error('Processing failed');
468
+
469
+ // Returns:
470
+ // {
471
+ // "error": "Processing failed",
472
+ // "route": "Process Data",
473
+ // "path": "/api/process"
474
+ // }
475
+ }
476
+ })
477
+ ```
478
+
479
+ Logs show:
480
+ ```
481
+ โŒ POST /api/process - Error: Processing failed
482
+ [stack trace]
483
+ ```
484
+
485
+ ## Best Practices
486
+
487
+ ### 1. Use Storage for State
488
+
489
+ ```typescript
490
+ // โŒ Don't use in-memory state
491
+ let cache = {};
492
+
493
+ // โœ… Use storage
494
+ await ctx.storage.set('cache', data);
495
+ ```
496
+
497
+ ### 2. Register Cleanups
498
+
499
+ ```typescript
500
+ .onReady(async (ctx, cleanup) => {
501
+ // โŒ Don't forget to cleanup
502
+ const timer = setInterval(...);
503
+
504
+ // โœ… Register cleanup
505
+ const timer = setInterval(...);
506
+ cleanup(() => clearInterval(timer));
507
+
508
+ // โœ… Event subscriptions
509
+ const sub = ctx.majk.eventBus.conversations().subscribe(...);
510
+ cleanup(() => sub.unsubscribe());
511
+ })
512
+ ```
513
+
514
+ ### 3. Validate Input
515
+
516
+ ```typescript
517
+ .apiRoute({
518
+ method: 'POST',
519
+ path: '/api/create',
520
+ name: 'Create Item',
521
+ description: 'Creates a new item. Validates input before processing.',
522
+ handler: async (req, res) => {
523
+ // โœ… Validate input
524
+ if (!req.body?.name) {
525
+ res.status(400).json({ error: 'Name is required' });
526
+ return;
527
+ }
528
+
529
+ // Process...
530
+ }
531
+ })
532
+ ```
533
+
534
+ ### 4. Use Structured Logging
535
+
536
+ ```typescript
537
+ // โŒ Basic logging
538
+ logger.info('User action');
539
+
540
+ // โœ… Structured logging
541
+ logger.info('User action', { userId, action: 'create', resourceId });
542
+ ```
543
+
544
+ ### 5. Handle Errors Gracefully
545
+
546
+ ```typescript
547
+ .tool('global', spec, async (input, { logger }) => {
548
+ try {
549
+ const result = await processData(input);
550
+ return { success: true, data: result };
551
+ } catch (error) {
552
+ logger.error(`Tool failed: ${error.message}`);
553
+ return {
554
+ success: false,
555
+ error: error.message,
556
+ code: 'PROCESSING_ERROR'
557
+ };
558
+ }
559
+ })
560
+ ```
561
+
562
+ ## Examples
563
+
564
+ See `example.ts` for a comprehensive example showing:
565
+ - React and HTML screens
566
+ - API routes with parameters
567
+ - Tools in different scopes
568
+ - Entity declarations
569
+ - Config wizard
570
+ - Event subscriptions
571
+ - Storage usage
572
+ - Health checks
573
+
574
+ ## TypeScript
575
+
576
+ Full TypeScript support with:
577
+
578
+ ```typescript
579
+ import {
580
+ definePlugin,
581
+ FluentBuilder,
582
+ PluginContext,
583
+ RequestLike,
584
+ ResponseLike
585
+ } from '@majk/plugin-kit';
586
+
587
+ // Type-safe plugin ID
588
+ const plugin = definePlugin('my-plugin', 'My Plugin', '1.0.0');
589
+ // ^ Enforces route prefixes
590
+
591
+ // Type-safe routes
592
+ .screenReact({
593
+ route: '/plugin-screens/my-plugin/dashboard'
594
+ // ^^^^^^^^^ Must match plugin ID
595
+ })
596
+ ```
597
+
598
+ ## Troubleshooting
599
+
600
+ ### "React app not built"
601
+
602
+ ```
603
+ โŒ Plugin Build Failed: React app not built: /path/to/ui/dist/index.html does not exist
604
+ ๐Ÿ’ก Suggestion: Run "npm run build" in your UI directory to build the React app
605
+ ```
606
+
607
+ **Fix:** Build your React app before building the plugin.
608
+
609
+ ### "Duplicate API route"
610
+
611
+ ```
612
+ โŒ Plugin Build Failed: Duplicate API route: POST /api/data
613
+ ```
614
+
615
+ **Fix:** Each route (method + path) must be unique.
616
+
617
+ ### "Description must be 2-3 sentences"
618
+
619
+ ```
620
+ โŒ Plugin Build Failed: Description for "My Screen" must be 2-3 sentences, found 1 sentences
621
+ ๐Ÿ’ก Suggestion: Rewrite the description to have 2-3 clear sentences.
622
+ ```
623
+
624
+ **Fix:** Write 2-3 complete sentences ending with periods.
625
+
626
+ ### "Tool names must be unique"
627
+
628
+ ```
629
+ โŒ Plugin Build Failed: Duplicate tool name: "analyze"
630
+ ```
631
+
632
+ **Fix:** Each tool name must be unique within the plugin.
633
+
634
+ ## License
635
+
636
+ MIT
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @majk/plugin-kit
3
+ *
4
+ * Fluent builder framework for creating robust MAJK plugins with:
5
+ * - Type-safe route and tool definitions
6
+ * - Compile-time and build-time validation
7
+ * - Clear, actionable error messages
8
+ * - Automatic HTTP server management
9
+ * - Built-in CORS, error handling, and logging
10
+ * - React SPA and HTML screen support
11
+ * - Entity, tool, and API route declarations
12
+ * - Lifecycle hooks with cleanup management
13
+ */
14
+ export { definePlugin, FluentBuilder } from './plugin-kit';
15
+ export type { PluginContext, PluginLogger, PluginStorage, ScopedTimers, ScopedIpcRegistry, PluginCapabilities, PluginCapability, ToolImplementation, InProcessPlugin, PluginHealthStatus, ToolSpec, ToolHandler, ApiMethod, ApiRouteDef, RouteHandler, RequestLike, ResponseLike, UiConfig, HistoryMode, ScreenBase, ReactScreen, HtmlScreen, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn } from './types';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,UAAU,EACV,SAAS,EACT,aAAa,EACd,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /**
3
+ * @majk/plugin-kit
4
+ *
5
+ * Fluent builder framework for creating robust MAJK plugins with:
6
+ * - Type-safe route and tool definitions
7
+ * - Compile-time and build-time validation
8
+ * - Clear, actionable error messages
9
+ * - Automatic HTTP server management
10
+ * - Built-in CORS, error handling, and logging
11
+ * - React SPA and HTML screen support
12
+ * - Entity, tool, and API route declarations
13
+ * - Lifecycle hooks with cleanup management
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.definePlugin = void 0;
17
+ var plugin_kit_1 = require("./plugin-kit");
18
+ Object.defineProperty(exports, "definePlugin", { enumerable: true, get: function () { return plugin_kit_1.definePlugin; } });
@@ -0,0 +1,39 @@
1
+ import { PluginContext, InProcessPlugin, ToolSpec, ToolHandler, ApiRouteDef, UiConfig, ReactScreen, HtmlScreen, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn } from './types';
2
+ /**
3
+ * Fluent Builder Interface
4
+ */
5
+ export interface FluentBuilder<Id extends string> {
6
+ /** Add a topbar item that navigates to a screen */
7
+ topbar(route: `/plugin-screens/${Id}/${string}`, opts?: {
8
+ icon?: string;
9
+ id?: string;
10
+ name?: string;
11
+ }): this;
12
+ /** Configure UI settings for React SPA */
13
+ ui(config?: UiConfig): this;
14
+ /** Add a React screen */
15
+ screenReact(screen: ReactScreen<Id>): this;
16
+ /** Add an HTML screen */
17
+ screenHtml(screen: HtmlScreen<Id>): this;
18
+ /** Add an API route */
19
+ apiRoute(route: ApiRouteDef): this;
20
+ /** Add a tool */
21
+ tool(scope: Scope, spec: ToolSpec, handler: ToolHandler): this;
22
+ /** Declare entities that this plugin provides */
23
+ entity(entityType: EntityType, entities: any[]): this;
24
+ /** Add config wizard */
25
+ configWizard(def: ConfigWizardDef): this;
26
+ /** Add settings screen */
27
+ settings(def: SettingsDef): this;
28
+ /** Hook called after server starts */
29
+ onReady(fn: (ctx: PluginContext, cleanup: (fn: CleanupFn) => void) => void | Promise<void>): this;
30
+ /** Custom health check */
31
+ health(fn: HealthCheckFn): this;
32
+ /** Build the plugin */
33
+ build(): InProcessPlugin;
34
+ }
35
+ /**
36
+ * Create a plugin with fluent builder API
37
+ */
38
+ export declare function definePlugin<const Id extends string>(id: Id, name: string, version: string): FluentBuilder<Id>;
39
+ //# sourceMappingURL=plugin-kit.d.ts.map