UNPKG

cline-sdk

Version:

Comprehensive SDK for Cline - AI-powered development assistant with database integration, execution modes, and custom functions

202 lines โ€ข 6.89 kB
"use strict"; /** * Function Registry - Register and manage custom functions for Cline * * This allows users to register their own JavaScript functions that can be * called by the AI assistant like built-in tools or MCP server functions. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.FunctionRegistry = void 0; class FunctionRegistry { constructor() { this.functions = new Map(); } /** * Register a new custom function */ register(definition, implementation) { if (this.functions.has(definition.name)) { throw new Error(`Function '${definition.name}' is already registered`); } // Validate function definition this.validateDefinition(definition); const registeredFunction = { definition, implementation, metadata: { registeredAt: new Date(), callCount: 0, }, }; this.functions.set(definition.name, registeredFunction); console.log(`๐Ÿ”ง Registered custom function: ${definition.name}`); } /** * Unregister a function */ unregister(name) { const removed = this.functions.delete(name); if (removed) { console.log(`๐Ÿ—‘๏ธ Unregistered custom function: ${name}`); } return removed; } /** * Call a registered function */ async call(name, args) { const func = this.functions.get(name); if (!func) { throw new Error(`Function '${name}' is not registered`); } // Update metadata func.metadata.callCount++; func.metadata.lastCalled = new Date(); try { console.log(`๐Ÿš€ Calling custom function: ${name}`); console.log(`๐Ÿ“ฅ Args:`, args); const result = await func.implementation(...args); console.log(`๐Ÿ“ค Result:`, result); return result; } catch (error) { console.error(`โŒ Custom function '${name}' failed:`, error); throw error; } } /** * Get a function definition by name */ getFunction(name) { return this.functions.get(name); } /** * Get all registered functions */ getAllFunctions() { return Array.from(this.functions.values()); } /** * Get function names */ getFunctionNames() { return Array.from(this.functions.keys()); } /** * Get functions by category */ getFunctionsByCategory(category) { return this.getAllFunctions().filter((func) => func.definition.category === category); } /** * Get function metadata/stats */ getStats() { const functions = this.getAllFunctions(); const totalCalls = functions.reduce((sum, func) => sum + func.metadata.callCount, 0); const categories = {}; functions.forEach((func) => { const category = func.definition.category || "uncategorized"; categories[category] = (categories[category] || 0) + 1; }); const mostUsed = functions.reduce((max, func) => { return func.metadata.callCount > (max?.calls || 0) ? { name: func.definition.name, calls: func.metadata.callCount } : max; }, null); return { totalFunctions: functions.length, totalCalls, categories, mostUsed, }; } /** * Clear all registered functions */ clear() { this.functions.clear(); console.log("๐Ÿงน Cleared all custom functions"); } /** * Validate function definition */ validateDefinition(definition) { if (!definition.name || typeof definition.name !== "string") { throw new Error("Function name is required and must be a string"); } if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(definition.name)) { throw new Error("Function name must be a valid identifier (letters, numbers, underscore)"); } if (!definition.description || typeof definition.description !== "string") { throw new Error("Function description is required and must be a string"); } if (!Array.isArray(definition.parameters)) { throw new Error("Function parameters must be an array"); } // Validate each parameter definition.parameters.forEach((param, index) => { if (!param.name || typeof param.name !== "string") { throw new Error(`Parameter ${index} name is required and must be a string`); } if (!param.type || !["string", "number", "boolean", "object", "array"].includes(param.type)) { throw new Error(`Parameter ${param.name} type must be one of: string, number, boolean, object, array`); } if (!param.description || typeof param.description !== "string") { throw new Error(`Parameter ${param.name} description is required and must be a string`); } }); } /** * Convert to tool definition format for AI */ getToolDefinitions() { return this.getAllFunctions().map((func) => ({ name: func.definition.name, description: func.definition.description, inputSchema: this.parametersToSchema(func.definition.parameters), })); } /** * Convert parameters to JSON schema format */ parametersToSchema(parameters) { const properties = {}; const required = []; parameters.forEach((param) => { if (param.required !== false) { required.push(param.name); } let property = { type: param.type, description: param.description, }; if (param.enum) { property.enum = param.enum; } if (param.type === "object" && param.properties) { property.properties = {}; Object.entries(param.properties).forEach(([key, subParam]) => { property.properties[key] = { type: subParam.type, description: subParam.description, }; }); } if (param.type === "array" && param.items) { property.items = { type: param.items.type, description: param.items.description, }; } properties[param.name] = property; }); return { type: "object", properties, required, }; } } exports.FunctionRegistry = FunctionRegistry; //# sourceMappingURL=function-registry.js.map