import { PluginContext, InProcessPlugin, ToolSpec, ToolHandler, ApiRouteDef, JsonSchema, UiConfig, ReactScreen, HtmlScreen, NavPaneActionConfig, ConfigWizardDef, SettingsDef, Scope, EntityType, CleanupFn, HealthCheckFn, MCPServerEntity, TeamMemberEntity, MenuItemDeclaration, FunctionHandler, SubscriptionHandler, SecretProviderDef, ClientGenerationConfig, FunctionEnrichment, IdentityProviderInfo, IdentitySetupInstructions, IdentityTestConfig, IdentityRequirement, SkillServiceFunctionRef, ProtocolHandlerDef, MessageInterceptorConfig, ToolInterceptorConfig } from './types'; /** * Service Builder Interface - sub-builder for defining service capabilities */ export interface ServiceBuilder { /** * Require an identity for all functions in this service (simple overload) * Auto-generates ID and sets required: true * @example .requireIdentity('developer-token:github', { scopes: ['repo'] }) */ requireIdentity(identityType: string, parameters?: Record, purpose?: string): this; /** * Require an identity for all functions in this service (advanced overload) * Provide complete IdentityRequirement object for full control * @example .requireIdentity({ id: 'my-id', identityType: 'developer-token:github', ... }) */ requireIdentity(requirement: IdentityRequirement): this; /** * Declare an optional identity for this service (multi-provider support) * Auto-generates ID and sets required: false * @example .mayRequireIdentity('developer-token:aws', { region: 'us-east-1' }, 'AWS backup') */ mayRequireIdentity(identityType: string, parameters?: Record, purpose?: string): this; /** * Declare that this service implements a service interface. * This enables automatic discovery and type-safe consumption of this service. * * @param interfacePackage - The interface package identifier (e.g., "@majk/service-registry/task-service") * * @example * .service('@myorg/my-plugin:tasks', { ... }) * .implements('@majk/service-registry/task-service') * .withFunction('createTask') * .withFunction('getTask') * .endService() */ implements(interfacePackage: string | { package: string; }): this; /** Add a function to this service with optional enrichment metadata */ withFunction(functionName: string, enrichment?: FunctionEnrichment): this; /** Complete the service definition and return to main builder */ endService(): FluentBuilder; } /** * Builder for declaring interceptors with type-safe methods */ export interface InterceptorBuilder { /** * Declare a message interceptor * @param config - Message interceptor configuration * @example * .message({ * id: 'msg-intel', * phase: 'pre-send', * handler: 'interceptMessage', * priority: 100, * filters: { conversationIds: ['conv-123'] } * }) */ message(config: MessageInterceptorConfig): this; /** * Declare a tool interceptor * @param config - Tool interceptor configuration * @example * .tool({ * id: 'tool-intel', * phase: 'pre-call', * handler: 'interceptTool', * filters: { toolPattern: 'read_.*' } * }) */ tool(config: ToolInterceptorConfig): this; /** * Complete the interceptor definitions and return to main builder */ endInterceptors(): FluentBuilder; } /** * Configuration for defining a skill via the fluent builder. * Provides flexible options for static or dynamic skill configuration. */ export interface SkillDefinitionConfig { /** Unique identifier for the skill */ id: string; /** Display name for the skill */ name: string; /** One-sentence description of what the skill does */ description: string; /** * Static instructions string. * Mutually exclusive with instructionsRef. */ instructions?: string; /** * Reference to an RPC function that returns instructions dynamically. * Can be a function name string (auto-resolved to plugin's RPC service) * or explicit ServiceFunctionRef. * Mutually exclusive with instructions. */ instructionsRef?: string | SkillServiceFunctionRef; /** * Setup function to call when skill is enabled. * Can be a function name string (auto-resolved to plugin's RPC service) * or explicit ServiceFunctionRef. * Function signature: (ctx: SkillContext) => Promise */ setup?: string | SkillServiceFunctionRef; /** * Teardown function to call when skill is disabled. * Can be a function name string (auto-resolved to plugin's RPC service) * or explicit ServiceFunctionRef. * Function signature: (ctx: SkillContext) => Promise */ teardown?: string | SkillServiceFunctionRef; /** Optional tags for categorization and search */ tags?: string[]; /** Optional list of tool names this skill uses */ tools?: string[]; /** Initial enabled state (default: true) */ enabled?: boolean; /** Optional metadata for discovery */ metadata?: Record; } /** * Configuration for protocol handler definition in the builder. * Used with the .protocol() method. * * @example * .protocol({ * namespace: 'github', * handlers: [ * { pattern: '/auth/callback', rpcMethod: 'handleOAuthCallback' }, * { pattern: '/repo/:owner/:repo', rpcMethod: 'openRepository' } * ] * }) */ export interface ProtocolDefinitionConfig { /** * Namespace for URL routing. * This determines which majk:// URLs are routed to this plugin. * Example: "github" matches majk://github/... * * Must contain only letters, numbers, @, /, hyphens, and underscores. */ namespace: string; /** * Handler definitions for different URL patterns. * Each handler maps a URL pattern to an RPC method. */ handlers: ProtocolHandlerDef[]; } /** * Fluent Builder Interface */ export interface FluentBuilder { /** Add a topbar item that navigates to a screen */ topbar(route: `/plugin-screens/${Id}/${string}`, opts?: { icon?: string; id?: string; name?: string; }): this; /** Add hierarchical top bar menu items */ topBarMenu(items: MenuItemDeclaration[]): this; /** Add an action button to the NavPane footer */ navpaneAction(action: NavPaneActionConfig): this; /** Configure UI settings for React SPA */ ui(config?: UiConfig): this; /** Add a React screen */ screenReact(screen: ReactScreen): this; /** Add an HTML screen */ screenHtml(screen: HtmlScreen): this; /** Add an API route (legacy) */ apiRoute(route: ApiRouteDef): this; /** Add a function with JSON Schema (new function-first API) */ function(name: string, config: { description: string; input: JsonSchema; output: JsonSchema; handler: FunctionHandler; tags?: string[]; deprecated?: boolean; }): this; /** Add a subscription for real-time updates */ subscription(name: string, config: { description: string; input: JsonSchema; output: JsonSchema; handler: SubscriptionHandler; }): this; /** * Configure transports (DEPRECATED in v2.0.0 - kept for backward compatibility) * @deprecated HTTP serving is now managed by MAJK. This method does nothing. */ transport(transport: any): this; /** Configure client generation */ generateClient(config: ClientGenerationConfig): this; /** Add a tool */ tool(scope: Scope, spec: ToolSpec, handler: ToolHandler): this; /** Declare entities that this plugin provides (generic, untyped) */ entity(entityType: EntityType, entities: any[]): this; /** Add MCP server entities with full TypeScript validation */ mcpServer(servers: MCPServerEntity[]): this; /** Add team member entities with full TypeScript validation */ teamMember(members: TeamMemberEntity[]): this; /** Add configurable entities that are only registered after plugin config exists */ configurableEntity(entityType: EntityType, factory: (config: any) => any[]): this; /** Add configurable MCP servers (only registered after config exists) */ configurableMcp(factory: (config: any) => MCPServerEntity[]): this; /** Add configurable team members (only registered after config exists) */ configurableTeamMember(factory: (config: any) => TeamMemberEntity[]): this; /** Add secret provider */ secretProvider(def: SecretProviderDef): this; /** Define a new identity type that plugins can use for authentication */ identityDefinition(def: { identityType: string; category: string; displayName: string; description: string; version?: string; provider?: IdentityProviderInfo; tags?: string[]; configurationSchema: JsonSchema; usageSchema?: JsonSchema; setupInstructions?: IdentitySetupInstructions; testable?: boolean; testConfig?: IdentityTestConfig; }): this; /** Add config wizard */ configWizard(def: ConfigWizardDef): this; /** Add settings screen */ settings(def: SettingsDef): this; /** * Declare a skill capability that this plugin provides. * Skills are instructions on how to accomplish tasks using tools. * * Setup/teardown/instructions can be provided as: * - Static strings (for instructions) * - RPC service function references (for dynamic behavior) * - Simple function name strings (auto-resolved to plugin's RPC service) * * @example * // Simple skill with static instructions * .skill({ * id: 'code-review-mode', * name: 'Code Review Mode', * description: 'Enables thorough code review analysis', * instructions: 'You are now in Code Review Mode...', * tags: ['review', 'code-quality'] * }) * * @example * // Skill with dynamic setup via RPC * .skill({ * id: 'project-context', * name: 'Project Context', * description: 'Loads project-specific context', * instructions: 'Use the loaded project context...', * setup: 'loadProjectContext', // Function name from plugin's RPC service * teardown: 'clearProjectContext', * tags: ['context', 'project'] * }) * * @example * // Skill with explicit RPC service references * .skill({ * id: 'advanced-skill', * name: 'Advanced Skill', * description: 'Advanced skill with custom service', * instructionsRef: { serviceName: 'MyService', functionName: 'getInstructions' }, * setupRef: { serviceName: 'MyService', functionName: 'setup' }, * teardownRef: { serviceName: 'MyService', functionName: 'teardown' } * }) */ skill(def: SkillDefinitionConfig): this; /** * Declare protocol URL handlers for deep linking. * Enables this plugin to handle majk:// URLs. * * URL format: majk://{namespace}/{path}?{query} * * Handler functions receive: * - request: { rawUrl, namespace, path, query, fragment } * - pathParams: extracted from URL pattern (e.g., { owner: 'foo', repo: 'bar' }) * * @example * // Handle GitHub OAuth callback and repository URLs * definePlugin('github-plugin', 'GitHub Plugin', '1.0.0') * .packageName('@majkapp/github-plugin') * .protocol({ * namespace: 'github', * handlers: [ * { pattern: '/auth/callback', rpcMethod: 'handleOAuthCallback' }, * { pattern: '/repo/:owner/:repo', rpcMethod: 'openRepository' } * ] * }) * .function('handleOAuthCallback', { * description: 'Handle OAuth callback from GitHub', * input: { type: 'object', properties: { request: { type: 'object' }, pathParams: { type: 'object' } } }, * output: { type: 'object', properties: { success: { type: 'boolean' } } }, * handler: async ({ request, pathParams }, ctx) => { * const code = request.query.code; * // Exchange code for token... * return { success: true, action: { type: 'navigate', route: '/settings' } }; * } * }) * .build() */ protocol(def: ProtocolDefinitionConfig): this; /** * Declare interceptors for messages and tool calls using a type-safe builder. * Returns an InterceptorBuilder that allows declaring message and tool interceptors * with proper type-checking for their respective filter types. * * @example * // Intercept messages and tool calls * definePlugin('intelligence', 'Intel Plugin', '1.0.0') * .function('interceptMessage', { * description: 'Intercepts and analyzes messages', * input: { type: 'object', properties: { data: { type: 'object' }, context: { type: 'object' } } }, * output: { type: 'object' }, * handler: async ({ data, context }, ctx) => { * // Analyze message... * return data; // Return modified data * } * }) * .function('interceptTool', { * description: 'Intercepts and monitors tool calls', * input: { type: 'object', properties: { data: { type: 'object' }, context: { type: 'object' } } }, * output: { type: 'object' }, * handler: async ({ data, context }, ctx) => { * // Monitor tool call... * return data; * } * }) * .interceptors() * .message({ * id: 'msg-intel', * phase: 'pre-send', * handler: 'interceptMessage', * priority: 100 * }) * .tool({ * id: 'tool-intel', * phase: 'pre-call', * handler: 'interceptTool', * filters: { toolPattern: 'read_.*' } * }) * .endInterceptors() * .build() */ interceptors(): InterceptorBuilder; /** * Declare that the auto-generated plugin service implements a service interface. * This marks the plugin's default service (${packageName}:all) as implementing * the specified interface, enabling automatic discovery and type-safe consumption. * * @param interfacePackage - The interface package identifier (e.g., "@majk/service-registry/task-service") * * @example * import { TaskServiceSchemas } from '@majk/service-registry/task-service'; * * definePlugin('my-tasks', 'My Tasks', '1.0.0') * .interface('@majk/service-registry/task-service') * .function('createTask', { * input: TaskServiceSchemas.createTask.input, * output: TaskServiceSchemas.createTask.output, * handler: async (input, ctx) => { ... } * }) * .build() */ interface(interfacePackage: string | { package: string; }): this; /** * Declare that this plugin requires a service interface to function. * This is used for documentation and can be used by the runtime to ensure * required services are available before loading the plugin. * * @param interfacePackage - The interface package identifier * @param version - Optional semver version constraint (default: '*') * * @example * definePlugin('task-dashboard', 'Task Dashboard', '1.0.0') * .requiresInterface('@majk/service-registry/task-service', '^1.0.0') * .function('getStats', { * handler: async (input, ctx) => { * const tasks = await ctx.services.resolve('@majk/service-registry/task-service'); * // ... use tasks * } * }) * .build() */ requiresInterface(interfacePackage: string, version?: string): this; /** Create a service capability that groups functions with rich metadata */ service(serviceName: string, config: { type: string; metadata: { name: string; description: string; version: string; category?: string; tags?: string[]; }; discoverable?: boolean; }): ServiceBuilder; /** Hook called after server starts */ onReady(fn: (ctx: PluginContext, cleanup: (fn: CleanupFn) => void) => void | Promise): this; /** Custom health check */ health(fn: HealthCheckFn): this; /** * Set the plugin root directory explicitly (use __dirname from your plugin entry file). * This ensures plugin-kit can find your files in both local development and npm installed scenarios. * If not provided, falls back to the pluginRoot from MAJK's context. * * @example * const plugin = definePlugin('my-plugin', 'My Plugin', '1.0.0') * .pluginRoot(__dirname) // Use Node's __dirname * .ui({ appDir: 'dist' }) // Now resolves relative to __dirname * .build(); */ pluginRoot(dir: string): this; /** * Disable automatic plugin service generation. * By default, plugin-kit creates a service exposing all plugin functions. * Use this to manage services manually. */ noPluginService(): this; /** * Set instructions for the auto-generated default teammate. * If not provided, the default teammate will have no system instructions. * * @example * .instructions('You are an expert assistant for managing tasks...') */ instructions(text: string): this; /** * Disable automatic default teammate generation. * By default, plugin-kit creates a " Expert" teammate with all plugin functions. * Use this to manage teammates manually. */ noDefaultTeammate(): this; /** Build the plugin */ build(): InProcessPlugin; } /** * Create a plugin with fluent builder API */ export declare function definePlugin(id: Id, name: string, version: string): FluentBuilder; //# sourceMappingURL=plugin-kit.d.ts.map