@majkapp/plugin-kit 1.0.17 → 1.1.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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/generator/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const path = __importStar(require("path"));
39
+ const fs = __importStar(require("fs"));
40
+ const child_process_1 = require("child_process");
41
+ const generator_1 = require("./generator");
42
+ commander_1.program
43
+ .name('plugin-kit')
44
+ .version('1.0.20')
45
+ .description('Plugin Kit CLI - Generate TypeScript clients from plugin definitions');
46
+ commander_1.program
47
+ .command('generate')
48
+ .description('Generate a TypeScript client from a plugin definition')
49
+ .option('-e, --entry <path>', 'Path to the compiled plugin entry file', './index.js')
50
+ .option('-o, --output <path>', 'Output directory for generated client', './ui/src/generated')
51
+ .option('-w, --watch', 'Watch for changes and regenerate', false)
52
+ .action(async (options) => {
53
+ const entryPath = path.resolve(options.entry);
54
+ const outputPath = path.resolve(options.output);
55
+ const logPath = path.join(outputPath, 'generation.log');
56
+ // Ensure output directory exists
57
+ fs.mkdirSync(outputPath, { recursive: true });
58
+ const generate = async () => {
59
+ const startTime = Date.now();
60
+ const log = [];
61
+ log.push(`=== Plugin Kit Client Generation ===`);
62
+ log.push(`Time: ${new Date().toISOString()}`);
63
+ log.push(`Entry: ${entryPath}`);
64
+ log.push(`Output: ${outputPath}`);
65
+ log.push(``);
66
+ try {
67
+ // Check if entry file exists
68
+ if (!fs.existsSync(entryPath)) {
69
+ throw new Error(`Entry file not found: ${entryPath}`);
70
+ }
71
+ log.push(`✓ Found entry file`);
72
+ // Extract metadata from plugin
73
+ const metadata = await extractMetadata(entryPath);
74
+ log.push(`✓ Extracted metadata from plugin: ${metadata.name} v${metadata.version}`);
75
+ log.push(` - ${metadata.functions.length} functions`);
76
+ log.push(` - ${metadata.screens.length} screens`);
77
+ log.push(` - ${metadata.tools.length} tools`);
78
+ log.push(``);
79
+ // Generate client files
80
+ const result = await (0, generator_1.generateClient)(metadata, outputPath, log);
81
+ const duration = Date.now() - startTime;
82
+ log.push(``);
83
+ log.push(`✓ Generation completed in ${duration}ms`);
84
+ if (result.warnings.length > 0) {
85
+ log.push(``);
86
+ log.push(`⚠ Warnings:`);
87
+ result.warnings.forEach(w => log.push(` - ${w}`));
88
+ }
89
+ // Write log file (overwrite each time)
90
+ fs.writeFileSync(logPath, log.join('\n'), 'utf-8');
91
+ console.log(`✅ Client generated successfully in ${duration}ms`);
92
+ console.log(` Output: ${outputPath}`);
93
+ console.log(` Files: ${result.files.join(', ')}`);
94
+ if (result.warnings.length > 0) {
95
+ console.log(` ⚠ ${result.warnings.length} warnings (see generation.log)`);
96
+ }
97
+ }
98
+ catch (error) {
99
+ log.push(`✗ Error: ${error.message}`);
100
+ log.push(error.stack || '');
101
+ fs.writeFileSync(logPath, log.join('\n'), 'utf-8');
102
+ console.error(`❌ Generation failed: ${error.message}`);
103
+ console.error(` See ${logPath} for details`);
104
+ if (!options.watch) {
105
+ process.exit(1);
106
+ }
107
+ }
108
+ };
109
+ if (options.watch) {
110
+ console.log(`👁 Watching for changes...`);
111
+ // Initial generation
112
+ await generate();
113
+ // Watch for changes
114
+ let timeout;
115
+ fs.watch(entryPath, () => {
116
+ clearTimeout(timeout);
117
+ timeout = setTimeout(() => {
118
+ console.log(`🔄 Changes detected, regenerating...`);
119
+ generate();
120
+ }, 500);
121
+ });
122
+ // Keep process alive
123
+ process.stdin.resume();
124
+ }
125
+ else {
126
+ await generate();
127
+ }
128
+ });
129
+ commander_1.program.parse();
130
+ async function extractMetadata(entryPath) {
131
+ // Create a temp file for the output
132
+ const tempFile = path.join(path.dirname(entryPath), `.plugin-metadata-${Date.now()}.json`);
133
+ try {
134
+ // Run the plugin in extract mode with file output
135
+ (0, child_process_1.execSync)(`node "${entryPath}"`, {
136
+ env: {
137
+ ...process.env,
138
+ PLUGIN_KIT_MODE: 'extract',
139
+ PLUGIN_KIT_OUTPUT: tempFile
140
+ },
141
+ cwd: path.dirname(entryPath),
142
+ stdio: 'inherit' // Let the plugin print its own messages
143
+ });
144
+ // Read the generated file
145
+ if (!fs.existsSync(tempFile)) {
146
+ throw new Error('Metadata file was not created');
147
+ }
148
+ const content = fs.readFileSync(tempFile, 'utf-8');
149
+ const metadata = JSON.parse(content);
150
+ // Clean up temp file
151
+ fs.unlinkSync(tempFile);
152
+ return metadata;
153
+ }
154
+ catch (error) {
155
+ // Clean up temp file if it exists
156
+ if (fs.existsSync(tempFile)) {
157
+ fs.unlinkSync(tempFile);
158
+ }
159
+ throw new Error(`Failed to extract metadata: ${error.message}`);
160
+ }
161
+ }
@@ -0,0 +1,6 @@
1
+ export interface GenerationResult {
2
+ files: string[];
3
+ warnings: string[];
4
+ }
5
+ export declare function generateClient(metadata: any, outputPath: string, log: string[]): Promise<GenerationResult>;
6
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/generator/generator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC,gBAAgB,CAAC,CAmC3B"}
@@ -0,0 +1,389 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateClient = generateClient;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ async function generateClient(metadata, outputPath, log) {
40
+ const warnings = [];
41
+ const files = [];
42
+ // Helper to write files
43
+ const writeFile = (filename, content) => {
44
+ const filePath = path.join(outputPath, filename);
45
+ fs.writeFileSync(filePath, content, 'utf-8');
46
+ files.push(filename);
47
+ log.push(` ✓ Generated ${filename}`);
48
+ };
49
+ try {
50
+ // 1. Generate TypeScript types
51
+ const types = generateTypes(metadata, warnings, log);
52
+ writeFile('types.ts', types);
53
+ // 2. Generate client class
54
+ const client = generateClientClass(metadata, warnings, log);
55
+ writeFile('client.ts', client);
56
+ // 3. Generate React hooks
57
+ const hooks = generateReactHooks(metadata, warnings, log);
58
+ writeFile('hooks.ts', hooks);
59
+ // 4. Generate index file
60
+ const index = generateIndex();
61
+ writeFile('index.ts', index);
62
+ }
63
+ catch (error) {
64
+ warnings.push(`Partial generation error: ${error.message}`);
65
+ log.push(` ⚠ Partial generation error: ${error.message}`);
66
+ }
67
+ return { files, warnings };
68
+ }
69
+ function generateTypes(metadata, warnings, log) {
70
+ const lines = [];
71
+ lines.push(`/**
72
+ * Auto-generated TypeScript types for ${metadata.name}
73
+ * Generated at: ${new Date().toISOString()}
74
+ * Plugin version: ${metadata.version}
75
+ */
76
+
77
+ `);
78
+ // Extract types from function schemas
79
+ const processedTypes = new Set();
80
+ metadata.functions.forEach((func) => {
81
+ try {
82
+ // Generate input type
83
+ const inputTypeName = `${capitalize(func.name)}Input`;
84
+ if (!processedTypes.has(inputTypeName)) {
85
+ lines.push(`export interface ${inputTypeName} ${schemaToTypeScript(func.input, 0)}\n`);
86
+ processedTypes.add(inputTypeName);
87
+ }
88
+ // Generate output type
89
+ const outputTypeName = `${capitalize(func.name)}Output`;
90
+ if (!processedTypes.has(outputTypeName)) {
91
+ // Handle array types specially - use type alias instead of interface
92
+ if (func.output.type === 'array') {
93
+ lines.push(`export type ${outputTypeName} = ${schemaToTypeScript(func.output, 0)};\n`);
94
+ }
95
+ else {
96
+ lines.push(`export interface ${outputTypeName} ${schemaToTypeScript(func.output, 0)}\n`);
97
+ }
98
+ processedTypes.add(outputTypeName);
99
+ }
100
+ }
101
+ catch (error) {
102
+ warnings.push(`Failed to generate types for ${func.name}: ${error.message}`);
103
+ }
104
+ });
105
+ // Standard response types
106
+ lines.push(`
107
+ export interface SuccessResponse<T> {
108
+ success: true;
109
+ data: T;
110
+ }
111
+
112
+ export interface ErrorResponse {
113
+ success: false;
114
+ error: string;
115
+ details?: any[];
116
+ }
117
+
118
+ export type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
119
+ `);
120
+ return lines.join('\n');
121
+ }
122
+ function generateClientClass(metadata, warnings, log) {
123
+ const lines = [];
124
+ lines.push(`/**
125
+ * Auto-generated client for ${metadata.name}
126
+ * Generated at: ${new Date().toISOString()}
127
+ * Plugin version: ${metadata.version}
128
+ */
129
+
130
+ import type {
131
+ ${metadata.functions.map((f) => ` ${capitalize(f.name)}Input,
132
+ ${capitalize(f.name)}Output`).join(',\n')}
133
+ } from './types';
134
+
135
+ export class ${capitalize(toCamelCase(metadata.id))}Client {
136
+ constructor(private baseUrl: string = '') {}
137
+
138
+ private async request<TInput, TOutput>(
139
+ functionName: string,
140
+ input: TInput
141
+ ): Promise<TOutput> {
142
+ try {
143
+ const response = await fetch(\`\${this.baseUrl}/api/fn/\${functionName}\`, {
144
+ method: 'POST',
145
+ headers: {
146
+ 'Content-Type': 'application/json',
147
+ },
148
+ body: JSON.stringify(input),
149
+ });
150
+
151
+ const result = await response.json();
152
+
153
+ // The transport wraps responses in { success: boolean, data?: T, error?: string }
154
+ // Check for errors first
155
+ if (result.success === false) {
156
+ throw new Error(result.error || \`Function \${functionName} failed\`);
157
+ }
158
+
159
+ // Return the unwrapped data
160
+ // The TypeScript output types represent the data inside the wrapper
161
+ return result.data;
162
+ } catch (error: any) {
163
+ console.error(\`Error calling \${functionName}:\`, error);
164
+ throw error;
165
+ }
166
+ }
167
+ `);
168
+ // Generate methods for each function
169
+ metadata.functions.forEach((func) => {
170
+ try {
171
+ const methodName = toCamelCase(func.name);
172
+ const inputType = `${capitalize(func.name)}Input`;
173
+ const outputType = `${capitalize(func.name)}Output`;
174
+ lines.push(`
175
+ /**
176
+ * ${func.description}${func.deprecated ? '\n * @deprecated' : ''}
177
+ */
178
+ async ${methodName}(input: ${inputType} = {}): Promise<${outputType}> {
179
+ return this.request<${inputType}, ${outputType}>('${func.name}', input);
180
+ }
181
+ `);
182
+ }
183
+ catch (error) {
184
+ warnings.push(`Failed to generate method for ${func.name}: ${error.message}`);
185
+ }
186
+ });
187
+ lines.push(`}
188
+
189
+ // Default singleton instance
190
+ export const ${toCamelCase(metadata.id)}Client = new ${capitalize(toCamelCase(metadata.id))}Client();
191
+ `);
192
+ return lines.join('');
193
+ }
194
+ function generateReactHooks(metadata, warnings, log) {
195
+ const lines = [];
196
+ lines.push(`/**
197
+ * Auto-generated React hooks for ${metadata.name}
198
+ * Generated at: ${new Date().toISOString()}
199
+ * Plugin version: ${metadata.version}
200
+ */
201
+
202
+ import { useState, useEffect, useCallback } from 'react';
203
+ import { ${toCamelCase(metadata.id)}Client } from './client';
204
+ import type {
205
+ ${metadata.functions.map((f) => ` ${capitalize(f.name)}Input,
206
+ ${capitalize(f.name)}Output`).join(',\n')}
207
+ } from './types';
208
+
209
+ export interface UseQueryResult<T> {
210
+ data: T | undefined;
211
+ error: Error | undefined;
212
+ loading: boolean;
213
+ refetch: () => void;
214
+ }
215
+
216
+ export interface UseMutationResult<TInput, TOutput> {
217
+ mutate: (input: TInput) => Promise<TOutput>;
218
+ data: TOutput | undefined;
219
+ error: Error | undefined;
220
+ loading: boolean;
221
+ }
222
+ `);
223
+ // Generate hooks for each function
224
+ metadata.functions.forEach((func) => {
225
+ try {
226
+ const hookName = `use${capitalize(func.name)}`;
227
+ const inputType = `${capitalize(func.name)}Input`;
228
+ const outputType = `${capitalize(func.name)}Output`;
229
+ // Determine if it's a query or mutation based on name/tags
230
+ const isQuery = func.name.startsWith('get') ||
231
+ func.name.startsWith('list') ||
232
+ func.name.includes('health') ||
233
+ func.name.includes('status');
234
+ if (isQuery) {
235
+ lines.push(`
236
+ /**
237
+ * React hook for ${func.description}
238
+ */
239
+ export function ${hookName}(
240
+ input: ${inputType} = {},
241
+ options?: { enabled?: boolean; refetchInterval?: number }
242
+ ): UseQueryResult<${outputType}> {
243
+ const [data, setData] = useState<${outputType} | undefined>();
244
+ const [error, setError] = useState<Error | undefined>();
245
+ const [loading, setLoading] = useState(false);
246
+
247
+ const fetch = useCallback(async () => {
248
+ if (options?.enabled === false) return;
249
+
250
+ setLoading(true);
251
+ setError(undefined);
252
+
253
+ try {
254
+ const result = await ${toCamelCase(metadata.id)}Client.${toCamelCase(func.name)}(input);
255
+ setData(result);
256
+ } catch (err: any) {
257
+ setError(err);
258
+ } finally {
259
+ setLoading(false);
260
+ }
261
+ }, [JSON.stringify(input), options?.enabled]);
262
+
263
+ useEffect(() => {
264
+ fetch();
265
+
266
+ if (options?.refetchInterval) {
267
+ const interval = setInterval(fetch, options.refetchInterval);
268
+ return () => clearInterval(interval);
269
+ }
270
+ }, [fetch, options?.refetchInterval]);
271
+
272
+ return { data, error, loading, refetch: fetch };
273
+ }
274
+ `);
275
+ }
276
+ else {
277
+ lines.push(`
278
+ /**
279
+ * React hook for ${func.description}
280
+ */
281
+ export function ${hookName}(): UseMutationResult<${inputType}, ${outputType}> {
282
+ const [data, setData] = useState<${outputType} | undefined>();
283
+ const [error, setError] = useState<Error | undefined>();
284
+ const [loading, setLoading] = useState(false);
285
+
286
+ const mutate = useCallback(async (input: ${inputType}): Promise<${outputType}> => {
287
+ setLoading(true);
288
+ setError(undefined);
289
+
290
+ try {
291
+ const result = await ${toCamelCase(metadata.id)}Client.${toCamelCase(func.name)}(input);
292
+ setData(result);
293
+ return result;
294
+ } catch (err: any) {
295
+ setError(err);
296
+ throw err;
297
+ } finally {
298
+ setLoading(false);
299
+ }
300
+ }, []);
301
+
302
+ return { mutate, data, error, loading };
303
+ }
304
+ `);
305
+ }
306
+ }
307
+ catch (error) {
308
+ warnings.push(`Failed to generate hook for ${func.name}: ${error.message}`);
309
+ }
310
+ });
311
+ return lines.join('');
312
+ }
313
+ function generateIndex() {
314
+ return `/**
315
+ * Auto-generated client exports
316
+ * Generated at: ${new Date().toISOString()}
317
+ */
318
+
319
+ export * from './types';
320
+ export * from './client';
321
+ export * from './hooks';
322
+ `;
323
+ }
324
+ // Helper functions
325
+ function schemaToTypeScript(schema, indent) {
326
+ if (!schema)
327
+ return 'any';
328
+ const spaces = ' '.repeat(indent);
329
+ if (schema.type === 'object') {
330
+ const props = schema.properties || {};
331
+ const required = schema.required || [];
332
+ const lines = ['{'];
333
+ Object.entries(props).forEach(([key, prop]) => {
334
+ const optional = !required.includes(key) ? '?' : '';
335
+ const type = schemaToTypeScript(prop, indent + 1);
336
+ const description = prop.description ? `\n${spaces} /** ${prop.description} */\n${spaces} ` : '\n' + spaces + ' ';
337
+ lines.push(`${description}${key}${optional}: ${type};`);
338
+ });
339
+ if (Object.keys(props).length === 0) {
340
+ lines.push(`${spaces} [key: string]: any;`);
341
+ }
342
+ lines.push(spaces + '}');
343
+ return lines.join('');
344
+ }
345
+ if (schema.type === 'array') {
346
+ return `${schemaToTypeScript(schema.items, indent)}[]`;
347
+ }
348
+ if (schema.type === 'string') {
349
+ if (schema.enum) {
350
+ return schema.enum.map((e) => `'${e}'`).join(' | ');
351
+ }
352
+ return 'string';
353
+ }
354
+ if (schema.type === 'number' || schema.type === 'integer') {
355
+ return 'number';
356
+ }
357
+ if (schema.type === 'boolean') {
358
+ return 'boolean';
359
+ }
360
+ if (schema.type === 'null') {
361
+ return 'null';
362
+ }
363
+ // Handle union types
364
+ if (Array.isArray(schema.type)) {
365
+ return schema.type.map((t) => {
366
+ if (t === 'null')
367
+ return 'null';
368
+ if (t === 'string')
369
+ return 'string';
370
+ if (t === 'number' || t === 'integer')
371
+ return 'number';
372
+ if (t === 'boolean')
373
+ return 'boolean';
374
+ return 'any';
375
+ }).join(' | ');
376
+ }
377
+ // Handle anyOf/oneOf
378
+ if (schema.anyOf || schema.oneOf) {
379
+ const schemas = schema.anyOf || schema.oneOf;
380
+ return schemas.map((s) => schemaToTypeScript(s, indent)).join(' | ');
381
+ }
382
+ return 'any';
383
+ }
384
+ function capitalize(str) {
385
+ return str.charAt(0).toUpperCase() + str.slice(1);
386
+ }
387
+ function toCamelCase(str) {
388
+ return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
389
+ }
package/dist/index.d.ts CHANGED
@@ -12,5 +12,8 @@
12
12
  * - Lifecycle hooks with cleanup management
13
13
  */
14
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, MCPServerEntity, TeamMemberEntity } from './types';
15
+ export { HttpTransport, WebSocketTransport, MCPTransport } from './transports';
16
+ export { FunctionRegistryImpl } from './registry';
17
+ export { generateClient } from './generator/generator';
18
+ export type { PluginContext, PluginLogger, PluginStorage, ScopedTimers, ScopedIpcRegistry, PluginCapabilities, PluginCapability, ToolImplementation, InProcessPlugin, PluginHealthStatus, ToolSpec, ToolHandler, ApiMethod, ApiRouteDef, JsonSchema, RouteHandler, RequestLike, ResponseLike, UiConfig, HistoryMode, ScreenBase, ReactScreen, HtmlScreen, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn, MCPServerEntity, TeamMemberEntity, FunctionHandler, SubscriptionHandler, FunctionDefinition, SubscriptionDefinition, Transport, TransportMetadata, FunctionRegistry, ClientGenerationConfig } from './types';
16
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC"}
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;AAC3D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,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,UAAU,EACV,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,EACb,eAAe,EACf,gBAAgB,EAEhB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -13,6 +13,14 @@
13
13
  * - Lifecycle hooks with cleanup management
14
14
  */
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.definePlugin = void 0;
16
+ exports.generateClient = exports.FunctionRegistryImpl = exports.MCPTransport = exports.WebSocketTransport = exports.HttpTransport = exports.definePlugin = void 0;
17
17
  var plugin_kit_1 = require("./plugin-kit");
18
18
  Object.defineProperty(exports, "definePlugin", { enumerable: true, get: function () { return plugin_kit_1.definePlugin; } });
19
+ var transports_1 = require("./transports");
20
+ Object.defineProperty(exports, "HttpTransport", { enumerable: true, get: function () { return transports_1.HttpTransport; } });
21
+ Object.defineProperty(exports, "WebSocketTransport", { enumerable: true, get: function () { return transports_1.WebSocketTransport; } });
22
+ Object.defineProperty(exports, "MCPTransport", { enumerable: true, get: function () { return transports_1.MCPTransport; } });
23
+ var registry_1 = require("./registry");
24
+ Object.defineProperty(exports, "FunctionRegistryImpl", { enumerable: true, get: function () { return registry_1.FunctionRegistryImpl; } });
25
+ var generator_1 = require("./generator/generator");
26
+ Object.defineProperty(exports, "generateClient", { enumerable: true, get: function () { return generator_1.generateClient; } });
@@ -1,4 +1,4 @@
1
- import { PluginContext, InProcessPlugin, ToolSpec, ToolHandler, ApiRouteDef, UiConfig, ReactScreen, HtmlScreen, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn, MCPServerEntity, TeamMemberEntity, MenuItemDeclaration } from './types';
1
+ import { PluginContext, InProcessPlugin, ToolSpec, ToolHandler, ApiRouteDef, JsonSchema, UiConfig, ReactScreen, HtmlScreen, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn, MCPServerEntity, TeamMemberEntity, MenuItemDeclaration, FunctionHandler, SubscriptionHandler, Transport, ClientGenerationConfig } from './types';
2
2
  /**
3
3
  * Fluent Builder Interface
4
4
  */
@@ -17,8 +17,28 @@ export interface FluentBuilder<Id extends string> {
17
17
  screenReact(screen: ReactScreen<Id>): this;
18
18
  /** Add an HTML screen */
19
19
  screenHtml(screen: HtmlScreen<Id>): this;
20
- /** Add an API route */
20
+ /** Add an API route (legacy) */
21
21
  apiRoute(route: ApiRouteDef): this;
22
+ /** Add a function with JSON Schema (new function-first API) */
23
+ function(name: string, config: {
24
+ description: string;
25
+ input: JsonSchema;
26
+ output: JsonSchema;
27
+ handler: FunctionHandler;
28
+ tags?: string[];
29
+ deprecated?: boolean;
30
+ }): this;
31
+ /** Add a subscription for real-time updates */
32
+ subscription(name: string, config: {
33
+ description: string;
34
+ input: JsonSchema;
35
+ output: JsonSchema;
36
+ handler: SubscriptionHandler;
37
+ }): this;
38
+ /** Configure transports */
39
+ transport(transport: Transport): this;
40
+ /** Configure client generation */
41
+ generateClient(config: ClientGenerationConfig): this;
22
42
  /** Add a tool */
23
43
  tool(scope: Scope, spec: ToolSpec, handler: ToolHandler): this;
24
44
  /** Declare entities that this plugin provides (generic, untyped) */
@@ -27,6 +47,12 @@ export interface FluentBuilder<Id extends string> {
27
47
  mcpServer(servers: MCPServerEntity[]): this;
28
48
  /** Add team member entities with full TypeScript validation */
29
49
  teamMember(members: TeamMemberEntity[]): this;
50
+ /** Add configurable entities that are only registered after plugin config exists */
51
+ configurableEntity(entityType: EntityType, factory: (config: any) => any[]): this;
52
+ /** Add configurable MCP servers (only registered after config exists) */
53
+ configurableMcp(factory: (config: any) => MCPServerEntity[]): this;
54
+ /** Add configurable team members (only registered after config exists) */
55
+ configurableTeamMember(factory: (config: any) => TeamMemberEntity[]): this;
30
56
  /** Add config wizard */
31
57
  configWizard(def: ConfigWizardDef): this;
32
58
  /** Add settings screen */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-kit.d.ts","sourceRoot":"","sources":["../src/plugin-kit.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,UAAU,EACV,SAAS,EACT,aAAa,EAIb,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAmtBjB;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,EAAE,SAAS,MAAM;IAC9C,mDAAmD;IACnD,MAAM,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAE7G,0CAA0C;IAC1C,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;IAE/C,0CAA0C;IAC1C,EAAE,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAE5B,yBAAyB;IACzB,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAE3C,yBAAyB;IACzB,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAEzC,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAEnC,iBAAiB;IACjB,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAE/D,oEAAoE;IACpE,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAEtD,8DAA8D;IAC9D,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAE5C,+DAA+D;IAC/D,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAE9C,wBAAwB;IACxB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAAC;IAEzC,0BAA0B;IAC1B,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAEjC,sCAAsC;IACtC,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAElG,0BAA0B;IAC1B,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAAC;IAEhC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B,uBAAuB;IACvB,KAAK,IAAI,eAAe,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAClD,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,EAAE,CAAC,CA+YnB"}
1
+ {"version":3,"file":"plugin-kit.d.ts","sourceRoot":"","sources":["../src/plugin-kit.ts"],"names":[],"mappings":"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"}