UNPKG

cline-sdk

Version:

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

467 lines 19.3 kB
"use strict"; /** * Cline SDK Configuration System * Handles API keys, settings, and tool configurations */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ClineConfigManager = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const os = __importStar(require("os")); class ClineConfigManager { constructor(configDir) { const defaultConfigDir = configDir || path.join(os.homedir(), ".cline-sdk"); this.configPath = path.join(defaultConfigDir, "config.json"); // Ensure config directory exists if (!fs.existsSync(defaultConfigDir)) { fs.mkdirSync(defaultConfigDir, { recursive: true }); } // Load or create default config this.config = this.loadConfig(); } loadConfig() { try { if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, "utf8"); const loadedConfig = JSON.parse(configData); return { ...this.getDefaultConfig(), ...loadedConfig }; } } catch (error) { console.warn("Failed to load config, using defaults:", error); } return this.getDefaultConfig(); } getDefaultConfig() { return { apiProvider: "anthropic", apiKey: process.env.ANTHROPIC_API_KEY || process.env.CLINE_API_KEY, model: "claude-3-sonnet-20240229", enabledTools: ["Write", "Read", "Bash"], enableCustomFunctions: true, enableDatabase: false, maxRequestsPerTask: 50, timeout: 30000, executionMode: "act", storageType: "local", workingDirectory: process.cwd(), alwaysAllowReadOnly: false, supabase: process.env.SUPABASE_URL && process.env.SUPABASE_ANON_KEY ? { url: process.env.SUPABASE_URL, anonKey: process.env.SUPABASE_ANON_KEY, serviceKey: process.env.SUPABASE_SERVICE_KEY, // Optional admin key bucketName: process.env.SUPABASE_BUCKET || "cline-files", projectPath: process.env.SUPABASE_PROJECT_PATH, } : undefined, database: process.env.DATABASE_URL || (process.env.DB_HOST && process.env.DB_NAME && process.env.DB_USER && process.env.DB_PASSWORD) ? { host: process.env.DB_HOST || "localhost", port: parseInt(process.env.DB_PORT || "5432", 10), database: process.env.DB_NAME || process.env.DB_DATABASE || "postgres", username: process.env.DB_USER || process.env.DB_USERNAME || "postgres", password: process.env.DB_PASSWORD || "", ssl: process.env.DB_SSL === "true" || process.env.DATABASE_SSL === "true", maxConnections: parseInt(process.env.DB_MAX_CONNECTIONS || "20", 10), idleTimeoutMillis: parseInt(process.env.DB_IDLE_TIMEOUT || "30000", 10), connectionTimeoutMillis: parseInt(process.env.DB_CONNECTION_TIMEOUT || "10000", 10), permissions: { allowRead: process.env.DB_ALLOW_READ !== "false", allowWrite: process.env.DB_ALLOW_WRITE === "true", allowDelete: process.env.DB_ALLOW_DELETE === "true", allowSchemaChanges: process.env.DB_ALLOW_SCHEMA_CHANGES === "true", allowRLSManagement: process.env.DB_ALLOW_RLS === "true", restrictedTables: process.env.DB_RESTRICTED_TABLES ? process.env.DB_RESTRICTED_TABLES.split(",") : [], allowedTables: process.env.DB_ALLOWED_TABLES ? process.env.DB_ALLOWED_TABLES.split(",") : [], }, } : undefined, temperature: 0.7, maxTokens: 4000, useCache: true, anthropicVersion: "2023-06-01", streaming: false, reasoning: false, imageSupport: false, functionCalling: true, requestTimeout: 30000, rateLimiting: { enabled: false, requestsPerMinute: 60, requestsPerHour: 1000 }, costLimits: { maxCostPerTask: 1.0, maxCostPerDay: 10.0, alertThreshold: 5.0 }, retry: { enabled: true, maxAttempts: 3, waitTimeMs: 6000, // 6 seconds as requested exponentialBackoff: false, retryOnErrors: ["llm_error", "api_error", "timeout_error"] }, }; } getConfig() { return { ...this.config }; } updateConfig(updates) { this.config = { ...this.config, ...updates }; this.saveConfig(); } setApiKey(apiKey) { this.config.apiKey = apiKey; this.saveConfig(); } setWorkingDirectory(directory) { if (fs.existsSync(directory)) { this.config.workingDirectory = path.resolve(directory); this.saveConfig(); } else { throw new Error(`Directory does not exist: ${directory}`); } } enableTool(toolName) { if (!this.config.enabledTools.includes(toolName)) { this.config.enabledTools.push(toolName); this.saveConfig(); } } disableTool(toolName) { this.config.enabledTools = this.config.enabledTools.filter((tool) => tool !== toolName); this.saveConfig(); } saveConfig() { try { fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), "utf8"); } catch (error) { console.error("Failed to save config:", error); } } getConfigPath() { return this.configPath; } // Model validation helper validateModel() { const errors = []; if (!this.config.model) { errors.push("Model is required"); return { valid: false, errors }; } // Basic model validation based on provider const modelValidation = this.getModelValidation(); if (!modelValidation.valid) { errors.push(...modelValidation.errors); } return { valid: errors.length === 0, errors, }; } getModelValidation() { const errors = []; const model = this.config.model; const provider = this.config.apiProvider; // Skip validation for custom models (allow any string) if (typeof model === "string" && model.includes("custom")) { return { valid: true, errors: [] }; } // Provider-specific model validation switch (provider) { case "anthropic": const anthropicModels = [ "claude-3-sonnet-20240229", "claude-3-haiku-20240307", "claude-3-opus-20240229", "claude-3-5-sonnet-20241022", "claude-3-5-haiku-20241022" ]; if (model && !anthropicModels.includes(model)) { errors.push(`Invalid Anthropic model: ${model}. Supported models: ${anthropicModels.join(", ")}`); } break; case "openai": const openaiModels = [ "gpt-4", "gpt-4-turbo", "gpt-4o", "gpt-4o-mini", "gpt-3.5-turbo" ]; if (model && !openaiModels.includes(model)) { errors.push(`Invalid OpenAI model: ${model}. Supported models: ${openaiModels.join(", ")}`); } break; case "ollama": const ollamaModels = [ "llama3", "llama3.1", "llama3.2", "codellama", "mistral", "gemma", "qwen", "deepseek-coder" ]; if (model && !ollamaModels.includes(model)) { errors.push(`Invalid Ollama model: ${model}. Supported models: ${ollamaModels.join(", ")}`); } break; case "bedrock": const bedrockModels = [ "anthropic.claude-3-sonnet-20240229-v1:0", "anthropic.claude-3-haiku-20240307-v1:0", "anthropic.claude-3-opus-20240229-v1:0", "anthropic.claude-3-5-sonnet-20241022-v2:0" ]; if (model && !bedrockModels.includes(model)) { errors.push(`Invalid Bedrock model: ${model}. Supported models: ${bedrockModels.join(", ")}`); } break; case "vertex": const vertexModels = [ "gemini-1.5-pro", "gemini-1.5-flash", "gemini-1.0-pro" ]; if (model && !vertexModels.includes(model)) { errors.push(`Invalid Vertex model: ${model}. Supported models: ${vertexModels.join(", ")}`); } break; } return { valid: errors.length === 0, errors, }; } // Enhanced validation methods validateConfig() { const errors = []; if (!this.config.apiKey) { errors.push("API key is required"); } if (!fs.existsSync(this.config.workingDirectory)) { errors.push(`Working directory does not exist: ${this.config.workingDirectory}`); } if (this.config.maxRequestsPerTask < 1) { errors.push("maxRequestsPerTask must be at least 1"); } if (this.config.timeout < 1000) { errors.push("timeout must be at least 1000ms"); } // Validate execution mode if (this.config.executionMode && !["ask", "plan", "act"].includes(this.config.executionMode)) { errors.push(`Invalid execution mode: ${this.config.executionMode}. Must be 'ask', 'plan', or 'act'`); } // Validate temperature if (this.config.temperature !== undefined && (this.config.temperature < 0 || this.config.temperature > 2)) { errors.push("temperature must be between 0 and 2"); } // Validate maxTokens if (this.config.maxTokens !== undefined && this.config.maxTokens < 1) { errors.push("maxTokens must be at least 1"); } // Validate model const modelValidation = this.validateModel(); if (!modelValidation.valid) { errors.push(...modelValidation.errors); } return { valid: errors.length === 0, errors, }; } // Environment-based configuration static fromEnvironment() { const config = new ClineConfigManager(); // Override with environment variables const envConfig = {}; if (process.env.ANTHROPIC_API_KEY) { envConfig.apiKey = process.env.ANTHROPIC_API_KEY; envConfig.apiProvider = "anthropic"; } if (process.env.OPENAI_API_KEY) { envConfig.apiKey = process.env.OPENAI_API_KEY; envConfig.apiProvider = "openai"; } if (process.env.OPENROUTER_API_KEY) { envConfig.apiKey = process.env.OPENROUTER_API_KEY; envConfig.apiProvider = "openrouter"; } // Provider-specific configurations if (process.env.AWS_REGION || process.env.AWS_ACCESS_KEY_ID) { envConfig.providerConfig = { ...envConfig.providerConfig, bedrock: { region: process.env.AWS_REGION || "us-east-1", accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, modelId: process.env.BEDROCK_MODEL_ID } }; } if (process.env.GOOGLE_PROJECT_ID) { envConfig.providerConfig = { ...envConfig.providerConfig, vertex: { projectId: process.env.GOOGLE_PROJECT_ID, location: process.env.GOOGLE_LOCATION || "us-central1" } }; } if (process.env.OLLAMA_HOST) { envConfig.providerConfig = { ...envConfig.providerConfig, ollama: { host: process.env.OLLAMA_HOST, port: process.env.OLLAMA_PORT ? parseInt(process.env.OLLAMA_PORT, 10) : 11434 } }; } if (process.env.CLINE_WORKING_DIR) { envConfig.workingDirectory = process.env.CLINE_WORKING_DIR; } if (process.env.CLINE_MODEL) { envConfig.model = process.env.CLINE_MODEL; } if (process.env.CLINE_MAX_REQUESTS) { envConfig.maxRequestsPerTask = parseInt(process.env.CLINE_MAX_REQUESTS, 10); } if (process.env.CLINE_EXECUTION_MODE) { const mode = process.env.CLINE_EXECUTION_MODE.toLowerCase(); if (mode === "ask" || mode === "plan" || mode === "act") { envConfig.executionMode = mode; } } // Retry configuration from environment variables if (process.env.RETRY_ENABLED !== undefined) { envConfig.retry = { ...(envConfig.retry || { enabled: false }), enabled: process.env.RETRY_ENABLED === "true" }; } if (process.env.RETRY_MAX_ATTEMPTS) { envConfig.retry = { ...(envConfig.retry || { enabled: false }), maxAttempts: parseInt(process.env.RETRY_MAX_ATTEMPTS, 10) }; } if (process.env.RETRY_WAIT_TIME_MS) { envConfig.retry = { ...(envConfig.retry || { enabled: false }), waitTimeMs: parseInt(process.env.RETRY_WAIT_TIME_MS, 10) }; } if (process.env.RETRY_EXPONENTIAL_BACKOFF !== undefined) { envConfig.retry = { ...(envConfig.retry || { enabled: false }), exponentialBackoff: process.env.RETRY_EXPONENTIAL_BACKOFF === "true" }; } if (process.env.RETRY_ON_ERRORS) { envConfig.retry = { ...(envConfig.retry || { enabled: false }), retryOnErrors: process.env.RETRY_ON_ERRORS.split(",").map(e => e.trim()) }; } // Advanced API settings from environment variables if (process.env.CLINE_TEMPERATURE) { envConfig.temperature = parseFloat(process.env.CLINE_TEMPERATURE); } if (process.env.CLINE_MAX_TOKENS) { envConfig.maxTokens = parseInt(process.env.CLINE_MAX_TOKENS, 10); } if (process.env.CLINE_USE_CACHE !== undefined) { envConfig.useCache = process.env.CLINE_USE_CACHE === "true"; } if (process.env.ANTHROPIC_VERSION) { envConfig.anthropicVersion = process.env.ANTHROPIC_VERSION; } // Advanced API features from environment variables if (process.env.CLINE_STREAMING !== undefined) { envConfig.streaming = process.env.CLINE_STREAMING === "true"; } if (process.env.CLINE_REASONING !== undefined) { envConfig.reasoning = process.env.CLINE_REASONING === "true"; } if (process.env.CLINE_IMAGE_SUPPORT !== undefined) { envConfig.imageSupport = process.env.CLINE_IMAGE_SUPPORT === "true"; } if (process.env.CLINE_FUNCTION_CALLING !== undefined) { envConfig.functionCalling = process.env.CLINE_FUNCTION_CALLING === "true"; } if (process.env.CLINE_REQUEST_TIMEOUT) { envConfig.requestTimeout = parseInt(process.env.CLINE_REQUEST_TIMEOUT, 10); } // Rate limiting configuration if (process.env.CLINE_RATE_LIMITING_ENABLED !== undefined) { envConfig.rateLimiting = { ...(envConfig.rateLimiting || { enabled: false }), enabled: process.env.CLINE_RATE_LIMITING_ENABLED === "true" }; } if (process.env.CLINE_REQUESTS_PER_MINUTE) { envConfig.rateLimiting = { ...(envConfig.rateLimiting || { enabled: false }), requestsPerMinute: parseInt(process.env.CLINE_REQUESTS_PER_MINUTE, 10) }; } if (process.env.CLINE_REQUESTS_PER_HOUR) { envConfig.rateLimiting = { ...(envConfig.rateLimiting || { enabled: false }), requestsPerHour: parseInt(process.env.CLINE_REQUESTS_PER_HOUR, 10) }; } // Cost limits configuration if (process.env.CLINE_MAX_COST_PER_TASK) { envConfig.costLimits = { ...(envConfig.costLimits || {}), maxCostPerTask: parseFloat(process.env.CLINE_MAX_COST_PER_TASK) }; } if (process.env.CLINE_MAX_COST_PER_DAY) { envConfig.costLimits = { ...(envConfig.costLimits || {}), maxCostPerDay: parseFloat(process.env.CLINE_MAX_COST_PER_DAY) }; } if (process.env.CLINE_COST_ALERT_THRESHOLD) { envConfig.costLimits = { ...(envConfig.costLimits || {}), alertThreshold: parseFloat(process.env.CLINE_COST_ALERT_THRESHOLD) }; } config.updateConfig(envConfig); return config; } } exports.ClineConfigManager = ClineConfigManager; //# sourceMappingURL=cline-config.js.map