@majkapp/plugin-kit 3.5.4 โ†’ 3.6.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 CHANGED
@@ -15,6 +15,7 @@ Build type-safe, production-ready MAJK plugins with excellent developer experien
15
15
  ๐Ÿ”ง **Tool Management** - Declare tools with schema validation
16
16
  ๐Ÿ’พ **Storage Integration** - Direct access to plugin storage
17
17
  ๐Ÿ“ก **Event Bus** - Subscribe to system events
18
+ ๐Ÿ”— **RPC Callbacks** - Pass callbacks across plugin boundaries with automatic serialization
18
19
  ๐Ÿงน **Auto Cleanup** - Managed lifecycle with automatic resource cleanup
19
20
  โค๏ธ **Health Checks** - Built-in health monitoring
20
21
 
@@ -365,6 +366,7 @@ The main MAJK API:
365
366
 
366
367
  ```typescript
367
368
  interface MajkInterface {
369
+ ai: AIAPI; // AI providers and LLMs
368
370
  conversations: ConversationAPI;
369
371
  todos: TodoAPI;
370
372
  projects: ProjectAPI;
@@ -379,6 +381,156 @@ interface MajkInterface {
379
381
  }
380
382
  ```
381
383
 
384
+ ### AI API
385
+
386
+ Access AI providers and language models:
387
+
388
+ ```typescript
389
+ // Get the default LLM
390
+ const llm = ctx.majk.ai.getDefaultLLM();
391
+
392
+ // Send a prompt
393
+ const result = await llm.prompt({
394
+ messages: [
395
+ { role: 'system', content: 'You are a helpful assistant' },
396
+ { role: 'user', content: 'What is 2+2?' }
397
+ ],
398
+ temperature: 0.7,
399
+ maxTokens: 100
400
+ });
401
+
402
+ console.log(result.content); // "4"
403
+
404
+ // Stream responses
405
+ const stream = llm.promptStream({
406
+ messages: [{ role: 'user', content: 'Tell me a story' }]
407
+ });
408
+
409
+ for await (const chunk of stream) {
410
+ if (chunk.type === 'content_delta') {
411
+ process.stdout.write(chunk.content);
412
+ }
413
+ }
414
+
415
+ // List available providers
416
+ const providers = ctx.majk.ai.listProviders();
417
+ console.log(`Available: ${providers.map(p => p.name).join(', ')}`);
418
+
419
+ // Get specific provider
420
+ const bedrock = ctx.majk.ai.getProvider('bedrock');
421
+ if (bedrock) {
422
+ const claude = bedrock.getLLM('anthropic.claude-3-5-sonnet-20241022-v2:0');
423
+ // Use Claude...
424
+ }
425
+
426
+ // Query by capability
427
+ const imageProviders = ctx.majk.ai.getProvidersWithCapability('imageGeneration');
428
+ if (imageProviders.length > 0) {
429
+ const image = await imageProviders[0].generateImage({
430
+ prompt: 'A beautiful sunset over mountains'
431
+ });
432
+ }
433
+ ```
434
+
435
+ **Key Features:**
436
+ - **Provider-agnostic**: Works with OpenAI, Anthropic, Bedrock, local models, etc.
437
+ - **Streaming support**: Real-time response streaming
438
+ - **Function calling**: LLM can invoke functions
439
+ - **Structured output**: JSON schema enforcement
440
+ - **Advanced capabilities**: Image generation, embeddings, transcription
441
+ - **Capability discovery**: Query providers by features
442
+
443
+ **Use Cases:**
444
+ - Add AI features to your plugin
445
+ - Create AI-powered tools
446
+ - Build custom AI workflows
447
+ - Integrate multiple AI providers
448
+ - Generate content, analyze data, summarize text
449
+
450
+ ### Plugin Management API
451
+
452
+ Generate authenticated URLs for opening plugin UIs in external browsers or creating cross-plugin links:
453
+
454
+ ```typescript
455
+ // Simple convenience method - get URL for another plugin's screen
456
+ const url = await ctx.majk.plugins.getExternalUrl(
457
+ '@analytics/dashboard', // Plugin ID (package name format)
458
+ 'main', // Screen ID (optional)
459
+ '#/overview' // Hash fragment (optional)
460
+ );
461
+
462
+ // Opens: http://localhost:9000/plugins/analytics/dashboard/ui/main?token=abc123#/overview
463
+ await ctx.shell?.openExternal(url);
464
+
465
+ // Advanced: Full control over URL generation
466
+ const customUrl = await ctx.majk.plugins.getPluginScreenUrl('@myorg/plugin', {
467
+ screenId: 'settings', // Specific screen
468
+ theme: 'dark', // Theme preference
469
+ hash: '#/advanced', // Client-side route
470
+ queryParams: { // Custom query parameters
471
+ view: 'compact',
472
+ filter: 'active'
473
+ }
474
+ });
475
+
476
+ // Direct URL with custom path (when you know the exact endpoint)
477
+ const apiUrl = await ctx.majk.plugins.getPluginExternalUrl('plugin-id', {
478
+ path: '/api/export', // Custom path within plugin
479
+ queryParams: { format: 'json' }
480
+ });
481
+ ```
482
+
483
+ **API Methods:**
484
+
485
+ - **`getExternalUrl(pluginId, screenId?, hash?)`** - Simple convenience method for getting screen URLs
486
+ - **`getPluginScreenUrl(pluginId, options)`** - Screen-aware URL generation with full options
487
+ - **`getPluginExternalUrl(pluginId, options)`** - Low-level URL generation for custom paths
488
+
489
+ **URL Format:**
490
+ ```
491
+ http://localhost:{port}/plugins/{org}/{plugin}/ui/{screen}?token={token}&theme={theme}#{hash}
492
+ ```
493
+
494
+ **Security:**
495
+ - URLs include one-time authentication tokens (60s TTL)
496
+ - After expiration, users are redirected to login if required
497
+ - Tokens are automatically validated by the plugin server
498
+
499
+ **Use Cases:**
500
+ - Open plugin screens in external browser windows
501
+ - Create shareable links to plugin functionality
502
+ - Cross-plugin navigation and deep linking
503
+ - Programmatic browser-based testing
504
+ - Integration with external tools and workflows
505
+
506
+ **Example - Cross-Plugin Integration:**
507
+
508
+ ```typescript
509
+ .apiRoute({
510
+ method: 'POST',
511
+ path: '/api/generate-report',
512
+ name: 'Generate Report',
513
+ description: 'Generates analytics report. Creates report and returns link to view.',
514
+ handler: async (req, res, { majk }) => {
515
+ // Generate report data
516
+ const reportId = await generateReport(req.body);
517
+
518
+ // Create link to analytics plugin's viewer
519
+ const viewerUrl = await majk.plugins.getExternalUrl(
520
+ '@analytics/viewer',
521
+ 'report',
522
+ `#/report/${reportId}`
523
+ );
524
+
525
+ return {
526
+ success: true,
527
+ reportId,
528
+ viewUrl: viewerUrl // User can click to view in analytics plugin
529
+ };
530
+ }
531
+ })
532
+ ```
533
+
382
534
  ### PluginStorage
383
535
 
384
536
  Simple key-value storage scoped to your plugin:
@@ -579,6 +731,69 @@ See `example.ts` for a comprehensive example showing:
579
731
  - Storage usage
580
732
  - Health checks
581
733
 
734
+ ## RPC & Callbacks
735
+
736
+ Plugins can communicate with each other using RPC services and pass callbacks across plugin boundaries:
737
+
738
+ ### Basic RPC Service
739
+
740
+ ```typescript
741
+ // Plugin A: Register a service
742
+ .onLoad(async (ctx) => {
743
+ await ctx.rpc.registerService('fileProcessor', {
744
+ async processFile(path: string, onProgress: (percent: number) => void): Promise<string> {
745
+ await onProgress(0);
746
+ await onProgress(50);
747
+ await onProgress(100);
748
+ return `Processed: ${path}`;
749
+ }
750
+ });
751
+ })
752
+ ```
753
+
754
+ ### Consuming with Callbacks
755
+
756
+ ```typescript
757
+ // Plugin B: Use the service with callbacks
758
+ .onLoad(async (ctx) => {
759
+ const processor = await ctx.rpc.createProxy<{
760
+ processFile(path: string, onProgress: (p: number) => void): Promise<string>
761
+ }>('fileProcessor');
762
+
763
+ // Pass callback - it just works!
764
+ const result = await processor.processFile('/file.txt', (progress) => {
765
+ console.log(`Progress: ${progress}%`);
766
+ });
767
+ })
768
+ ```
769
+
770
+ ### Explicit Callbacks with Cleanup
771
+
772
+ For long-lived callbacks (subscriptions, event listeners), use `createCallback()`:
773
+
774
+ ```typescript
775
+ // Auto-cleanup after 10 calls
776
+ const callback = await ctx.rpc.createCallback!(
777
+ (event) => console.log('Event:', event),
778
+ { maxCalls: 10 }
779
+ );
780
+ await eventService.subscribe(callback);
781
+
782
+ // Auto-cleanup after 5 seconds
783
+ const callback = await ctx.rpc.createCallback!(
784
+ (data) => console.log('Data:', data),
785
+ { timeout: 5000 }
786
+ );
787
+ await dataStream.subscribe(callback);
788
+
789
+ // Manual cleanup
790
+ const callback = await ctx.rpc.createCallback!((msg) => console.log(msg));
791
+ // ... later
792
+ ctx.rpc.cleanupCallback!(callback);
793
+ ```
794
+
795
+ See [docs/RPC_CALLBACKS.md](docs/RPC_CALLBACKS.md) for comprehensive documentation, patterns, and best practices.
796
+
582
797
  ## TypeScript
583
798
 
584
799
  Full TypeScript support with:
@@ -58,12 +58,24 @@ cli.addCommand('--services',
58
58
  { description: 'Organize functions by service' }
59
59
  );
60
60
 
61
+ // RPC and callbacks
62
+ cli.addCommand('--rpc',
63
+ cli.createFullDocCommand('RPC_CALLBACKS.md'),
64
+ { description: 'Inter-plugin RPC with callbacks' }
65
+ );
66
+
61
67
  // Teammates
62
68
  cli.addCommand('--teammates',
63
69
  cli.createFullDocCommand('TEAMMATES.md'),
64
70
  { description: 'AI teammates and agents' }
65
71
  );
66
72
 
73
+ // AI API
74
+ cli.addCommand('--ai',
75
+ cli.createFullDocCommand('AI.md'),
76
+ { description: 'AI providers and LLMs' }
77
+ );
78
+
67
79
  // Lifecycle hooks
68
80
  cli.addCommand('--lifecycle',
69
81
  cli.createFullDocCommand('LIFECYCLE.md'),
File without changes
package/dist/index.d.ts CHANGED
@@ -18,6 +18,6 @@ export { definePlugin, FluentBuilder, ServiceBuilder } from './plugin-kit';
18
18
  export { FunctionRegistryImpl, FunctionProviderImpl } from './registry';
19
19
  export { FilesystemResourceProvider } from './resource-provider';
20
20
  export { generateClient } from './generator/generator';
21
- 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, ServiceFunctionBinding, FunctionHandler, SubscriptionHandler, FunctionDefinition, SubscriptionDefinition, FunctionRegistry, ClientGenerationConfig, Plugin, FunctionProvider, ResourceProvider, FunctionInfo, AsyncPluginHealthStatus, ServiceCapability, ServiceMetadata, ServiceFunctionMetadata, ServiceParameterMetadata, ServiceReturnMetadata, FunctionEnrichment, IdentityDefinitionCapability, IdentityProviderInfo, IdentitySetupInstructions, IdentityTestConfig, IdentityRequirement } from './types';
22
- export type { MajkInterface, EntityId, Unsubscribe, BaseEntity, StandardEventType, PluginEventType, RepositoryEventType, EntityType as MajkEntityType, RepositoryEvent, EventFilter, EventListener, Subscription, QueryBuilder, QueryableEventChannel, EventBusAPI, PluginInfo, PluginHealth, PluginCapabilityInfo, PluginLog, InstallPluginOptions, InstallPluginResult, GetLogsOptions, PluginManagementAPI, SecretScope, SecretInfo, ScopedSecretsAPI, SecretsAPI, StartTaskRequest, TaskFilter, TaskMessage, TaskProgress, TaskResult, TaskError, TaskHandle, TaskEventHandler, TaskEvent, TaskAPI, AccountType, AccountMetadata, TimeWindow, CredentialOptions, RefreshOptions, RefreshResult, ValidationResult, TokenInfo, AutoRefreshConfig, AutoRefreshHandle, AwsSdkCredentials, CognitoTokenSet, AzureSdkCredentials, AccountJSON, AwsCognitoCredentials, AzureEntraCredentials, ApiKeyCredentials, SystemDefaultCredentials, Credentials, SystemAccount, OAuthAccount, AwsAccount, AzureAccount, AuthEvent, AuthStateChangeEvent, AuthTokenRefreshedEvent, AuthErrorEvent, AccountChangedEvent, AuthAPI, Message, Conversation, Agent, TeamMember, TeamMemberSkills, TeamMemberPersonality, TeamMemberCodeStats, TeamMemberMetadata, ServiceFunctionBinding as MajkServiceFunctionBinding, Todo, WorkStrategy, Project, MCPServer, ConversationFilter, MessageQueryOptions, ConversationHandle, ConversationAPI, CreateTeammateRequest, TeammateUpdate, TeammateFilter, TeammateHandle, TeammateAPI, CreateTodoRequest, TodoUpdate, TodoFilter, SpawnOptions, TodoHandle, TodoAPI, CreateProjectRequest, ProjectUpdate, ProjectFilter, ProjectHandle, ProjectAPI, CreateMCPServerRequest, MCPServerUpdate, MCPServerFilter, ConnectionTestResult, MCPServerHandle, MCPServerScopedHandle, DiscoveredTool, MCPServerAPI, EverywhereScope, EverywhereScopedHandle, CreateAgentRequest, AgentUpdate, AgentFilter, TestResult, AgentHandle, AgentAPI, AddKnowledgeInput, KnowledgeNode, KnowledgeTree, KnowledgeSearchOptions, KnowledgeAPI } from './majk-interface-types';
21
+ 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, ServiceFunctionBinding, CallbackHandle, CreateCallbackOptions, CallbackStats, FunctionHandler, SubscriptionHandler, FunctionDefinition, SubscriptionDefinition, FunctionRegistry, ClientGenerationConfig, Plugin, FunctionProvider, ResourceProvider, FunctionInfo, AsyncPluginHealthStatus, ServiceCapability, ServiceMetadata, ServiceFunctionMetadata, ServiceParameterMetadata, ServiceReturnMetadata, FunctionEnrichment, IdentityDefinitionCapability, IdentityProviderInfo, IdentitySetupInstructions, IdentityTestConfig, IdentityRequirement } from './types';
22
+ export type { MajkInterface, EntityId, Unsubscribe, BaseEntity, StandardEventType, PluginEventType, RepositoryEventType, EntityType as MajkEntityType, RepositoryEvent, EventFilter, EventListener, Subscription, QueryBuilder, QueryableEventChannel, EventBusAPI, PluginInfo, PluginHealth, PluginCapabilityInfo, PluginLog, InstallPluginOptions, InstallPluginResult, GetLogsOptions, PluginManagementAPI, SecretScope, SecretInfo, ScopedSecretsAPI, SecretsAPI, StartTaskRequest, TaskFilter, TaskMessage, TaskProgress, TaskResult, TaskError, TaskHandle, TaskEventHandler, TaskEvent, TaskAPI, AccountType, AccountMetadata, TimeWindow, CredentialOptions, RefreshOptions, RefreshResult, ValidationResult, TokenInfo, AutoRefreshConfig, AutoRefreshHandle, AwsSdkCredentials, CognitoTokenSet, AzureSdkCredentials, AccountJSON, AwsCognitoCredentials, AzureEntraCredentials, ApiKeyCredentials, SystemDefaultCredentials, Credentials, SystemAccount, OAuthAccount, AwsAccount, AzureAccount, AuthEvent, AuthStateChangeEvent, AuthTokenRefreshedEvent, AuthErrorEvent, AccountChangedEvent, AuthAPI, Message, Conversation, Agent, TeamMember, TeamMemberSkills, TeamMemberPersonality, TeamMemberCodeStats, TeamMemberMetadata, ServiceFunctionBinding as MajkServiceFunctionBinding, Todo, WorkStrategy, Project, MCPServer, ConversationFilter, MessageQueryOptions, ConversationHandle, ConversationAPI, CreateTeammateRequest, TeammateUpdate, TeammateFilter, TeammateHandle, TeammateAPI, CreateTodoRequest, TodoUpdate, TodoFilter, SpawnOptions, TodoHandle, TodoAPI, CreateProjectRequest, ProjectUpdate, ProjectFilter, ProjectHandle, ProjectAPI, CreateMCPServerRequest, MCPServerUpdate, MCPServerFilter, ConnectionTestResult, MCPServerHandle, MCPServerScopedHandle, DiscoveredTool, MCPServerAPI, EverywhereScope, EverywhereScopedHandle, CreateAgentRequest, AgentUpdate, AgentFilter, TestResult, AgentHandle, AgentAPI, AddKnowledgeInput, KnowledgeNode, KnowledgeTree, KnowledgeSearchOptions, KnowledgeAPI, AIAPI, AIProvider, AIProviderCapabilities, AIProviderError, LLMInterface, ModelInfo, AIMessage, ContentBlock, PromptParams, PromptResult, PromptChunk, AIFunctionDefinition, AIJsonSchema, FunctionCallParams, FunctionCallResult, ImageGenerationParams, ImageResult, TranscriptionParams, TranscriptionResult, ProviderStatus } from './majk-interface-types';
23
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}