export interface LLMConfig { readonly provider: 'openai' | 'ollama' | 'gemini'; readonly model?: string; readonly temperature?: number; readonly maxTokens?: number; readonly timeout?: number; } export interface OpenAIConfig { readonly apiKey: string; readonly baseUrl?: string; readonly organization?: string; } export interface OllamaConfig { readonly enabled: boolean; readonly baseUrl?: string; readonly model?: string; } export interface GeminiConfig { readonly apiKey: string; readonly model?: string; readonly temperature?: number; readonly maxTokens?: number; } export interface GitHubConfig { readonly token?: string; readonly baseUrl?: string; readonly apiVersion?: string; } export interface GitConfig { readonly repoPath?: string; readonly defaultBranch?: string; readonly includeStaged?: boolean; readonly includeUnstaged?: boolean; } export interface OutputConfig { readonly format: 'console' | 'markdown' | 'json' | 'html' | 'file'; readonly colorize?: boolean; readonly verbose?: boolean; readonly outputPath?: string; } export interface SecurityConfig { readonly enabled: boolean; readonly severity: ('low' | 'medium' | 'high' | 'critical')[]; readonly categories: ('injection' | 'authentication' | 'authorization' | 'cryptography' | 'data_exposure' | 'input_validation' | 'dependency' | 'configuration' | 'logging' | 'other')[]; readonly includeDependencies?: boolean; readonly packageJsonPath?: string; readonly lockFilePath?: string; } export interface TestConfig { readonly enabled: boolean; readonly framework: 'jest' | 'mocha' | 'vitest' | 'cypress' | 'playwright' | 'generic'; readonly testType: 'unit' | 'integration' | 'e2e' | 'performance' | 'security'; readonly language?: string; readonly includeSetup?: boolean; readonly includeTeardown?: boolean; readonly coverageTarget?: number; } export interface DocumentationConfig { readonly enabled: boolean; readonly format: 'markdown' | 'jsdoc' | 'tsdoc' | 'asciidoc' | 'rst' | 'plain'; readonly language?: string; readonly includeExamples?: boolean; readonly includeParameters?: boolean; readonly includeReturnTypes?: boolean; readonly includeSeeAlso?: boolean; readonly style?: 'formal' | 'casual' | 'technical' | 'beginner'; } export interface ReviewConfig { readonly enabled: boolean; readonly severity: ('info' | 'warning' | 'error' | 'suggestion')[]; readonly categories: ('style' | 'logic' | 'security' | 'performance' | 'maintainability' | 'documentation' | 'testing' | 'accessibility')[]; readonly outputFormat?: 'console' | 'markdown' | 'json' | 'html' | 'github' | 'file'; readonly postToGitHub?: boolean; } export interface Configuration { readonly llm: LLMConfig; readonly openai?: OpenAIConfig; readonly ollama?: OllamaConfig; readonly gemini?: GeminiConfig; readonly github?: GitHubConfig; readonly git: GitConfig; readonly output: OutputConfig; readonly security: SecurityConfig; readonly test: TestConfig; readonly documentation: DocumentationConfig; readonly review: ReviewConfig; readonly filePatterns?: string[]; readonly excludePatterns?: string[]; readonly verbose?: boolean; readonly debug?: boolean; } export class ConfigurationBuilder { private config: any = {}; llm(llm: LLMConfig): ConfigurationBuilder { this.config.llm = llm; return this; } openai(openai: OpenAIConfig): ConfigurationBuilder { this.config.openai = openai; return this; } ollama(ollama: OllamaConfig): ConfigurationBuilder { this.config.ollama = ollama; return this; } gemini(gemini: GeminiConfig): ConfigurationBuilder { this.config.gemini = gemini; return this; } github(github: GitHubConfig): ConfigurationBuilder { this.config.github = github; return this; } git(git: GitConfig): ConfigurationBuilder { this.config.git = git; return this; } output(output: OutputConfig): ConfigurationBuilder { this.config.output = output; return this; } security(security: SecurityConfig): ConfigurationBuilder { this.config.security = security; return this; } test(test: TestConfig): ConfigurationBuilder { this.config.test = test; return this; } documentation(documentation: DocumentationConfig): ConfigurationBuilder { this.config.documentation = documentation; return this; } review(review: ReviewConfig): ConfigurationBuilder { this.config.review = review; return this; } filePatterns(filePatterns: string[]): ConfigurationBuilder { this.config.filePatterns = filePatterns; return this; } excludePatterns(excludePatterns: string[]): ConfigurationBuilder { this.config.excludePatterns = excludePatterns; return this; } verbose(verbose: boolean): ConfigurationBuilder { this.config.verbose = verbose; return this; } debug(debug: boolean): ConfigurationBuilder { this.config.debug = debug; return this; } build(): Configuration { // Set default values const defaultConfig: Configuration = { llm: { provider: 'openai', model: 'gpt-4', temperature: 0.7, maxTokens: 2000, timeout: 30000, }, openai: { apiKey: process.env.OPENAI_API_KEY || '', baseUrl: 'https://api.openai.com/v1', }, ollama: { enabled: false, baseUrl: 'http://localhost:11434', model: 'llama2', }, github: { token: process.env.GITHUB_TOKEN || '', baseUrl: 'https://api.github.com', apiVersion: '2022-11-28', }, git: { repoPath: process.cwd(), defaultBranch: 'main', includeStaged: true, includeUnstaged: true, }, output: { format: 'console', colorize: true, verbose: false, }, security: { enabled: true, severity: ['low', 'medium', 'high', 'critical'], categories: ['injection', 'authentication', 'authorization', 'cryptography', 'data_exposure', 'input_validation', 'dependency', 'configuration', 'logging', 'other'], includeDependencies: true, }, test: { enabled: true, framework: 'jest', testType: 'unit', language: 'typescript', includeSetup: true, includeTeardown: true, coverageTarget: 80, }, documentation: { enabled: true, format: 'markdown', language: 'typescript', includeExamples: true, includeParameters: true, includeReturnTypes: true, includeSeeAlso: true, style: 'technical', }, review: { enabled: true, severity: ['info', 'warning', 'error', 'suggestion'], categories: ['style', 'logic', 'security', 'performance', 'maintainability', 'documentation', 'testing', 'accessibility'], outputFormat: 'console', postToGitHub: false, }, filePatterns: ['**/*.ts', '**/*.js', '**/*.tsx', '**/*.jsx', '**/*.py', '**/*.java', '**/*.cpp', '**/*.c', '**/*.cs', '**/*.php', '**/*.rb', '**/*.go', '**/*.rs'], excludePatterns: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/coverage/**'], verbose: false, debug: false, }; // Merge with provided config return { ...defaultConfig, ...this.config, llm: { ...defaultConfig.llm, ...this.config.llm }, openai: this.config.openai ? { ...defaultConfig.openai, ...this.config.openai } : defaultConfig.openai, ollama: this.config.ollama ? { ...defaultConfig.ollama, ...this.config.ollama } : defaultConfig.ollama, github: this.config.github ? { ...defaultConfig.github, ...this.config.github } : defaultConfig.github, git: { ...defaultConfig.git, ...this.config.git }, output: { ...defaultConfig.output, ...this.config.output }, security: { ...defaultConfig.security, ...this.config.security }, test: { ...defaultConfig.test, ...this.config.test }, documentation: { ...defaultConfig.documentation, ...this.config.documentation }, review: { ...defaultConfig.review, ...this.config.review }, }; } } export function createDefaultConfiguration(): Configuration { return new ConfigurationBuilder().build(); } export function createConfigurationFromEnv(): Configuration { const builder = new ConfigurationBuilder(); // LLM Configuration if (process.env.LLM_PROVIDER) { const llmConfig: any = { provider: process.env.LLM_PROVIDER as 'openai' | 'ollama' | 'gemini', }; if (process.env.LLM_MODEL) { llmConfig.model = process.env.LLM_MODEL; } if (process.env.LLM_TEMPERATURE) { llmConfig.temperature = parseFloat(process.env.LLM_TEMPERATURE); } if (process.env.LLM_MAX_TOKENS) { llmConfig.maxTokens = parseInt(process.env.LLM_MAX_TOKENS); } if (process.env.LLM_TIMEOUT) { llmConfig.timeout = parseInt(process.env.LLM_TIMEOUT); } builder.llm(llmConfig); } // OpenAI Configuration if (process.env.OPENAI_API_KEY) { const openaiConfig: any = { apiKey: process.env.OPENAI_API_KEY, }; if (process.env.OPENAI_BASE_URL) { openaiConfig.baseUrl = process.env.OPENAI_BASE_URL; } if (process.env.OPENAI_ORGANIZATION) { openaiConfig.organization = process.env.OPENAI_ORGANIZATION; } builder.openai(openaiConfig); } // Ollama Configuration if (process.env.OLLAMA_ENABLED === 'true') { const ollamaConfig: any = { enabled: true, }; if (process.env.OLLAMA_BASE_URL) { ollamaConfig.baseUrl = process.env.OLLAMA_BASE_URL; } if (process.env.OLLAMA_MODEL) { ollamaConfig.model = process.env.OLLAMA_MODEL; } builder.ollama(ollamaConfig); } // Gemini Configuration if (process.env.GEMINI_API_KEY) { const geminiConfig: any = { apiKey: process.env.GEMINI_API_KEY, }; if (process.env.GEMINI_MODEL) { geminiConfig.model = process.env.GEMINI_MODEL; } if (process.env.GEMINI_TEMPERATURE) { geminiConfig.temperature = parseFloat(process.env.GEMINI_TEMPERATURE); } if (process.env.GEMINI_MAX_TOKENS) { geminiConfig.maxTokens = parseInt(process.env.GEMINI_MAX_TOKENS); } builder.gemini(geminiConfig); } // GitHub Configuration if (process.env.GITHUB_TOKEN) { const githubConfig: any = { token: process.env.GITHUB_TOKEN, }; if (process.env.GITHUB_BASE_URL) { githubConfig.baseUrl = process.env.GITHUB_BASE_URL; } if (process.env.GITHUB_API_VERSION) { githubConfig.apiVersion = process.env.GITHUB_API_VERSION; } builder.github(githubConfig); } // Git Configuration if (process.env.GIT_REPO_PATH) { const gitConfig: any = { repoPath: process.env.GIT_REPO_PATH, includeStaged: process.env.GIT_INCLUDE_STAGED === 'true', includeUnstaged: process.env.GIT_INCLUDE_UNSTAGED === 'true', }; if (process.env.GIT_DEFAULT_BRANCH) { gitConfig.defaultBranch = process.env.GIT_DEFAULT_BRANCH; } builder.git(gitConfig); } // Output Configuration if (process.env.OUTPUT_FORMAT) { const outputConfig: any = { format: process.env.OUTPUT_FORMAT as any, colorize: process.env.OUTPUT_COLORIZE === 'true', verbose: process.env.OUTPUT_VERBOSE === 'true', }; if (process.env.OUTPUT_PATH) { outputConfig.outputPath = process.env.OUTPUT_PATH; } builder.output(outputConfig); } // Security Configuration if (process.env.SECURITY_ENABLED === 'true') { const securityConfig: any = { enabled: true, includeDependencies: process.env.SECURITY_INCLUDE_DEPENDENCIES === 'true', }; if (process.env.SECURITY_SEVERITY) { securityConfig.severity = process.env.SECURITY_SEVERITY.split(',') as any; } if (process.env.SECURITY_CATEGORIES) { securityConfig.categories = process.env.SECURITY_CATEGORIES.split(',') as any; } if (process.env.SECURITY_PACKAGE_JSON_PATH) { securityConfig.packageJsonPath = process.env.SECURITY_PACKAGE_JSON_PATH; } if (process.env.SECURITY_LOCK_FILE_PATH) { securityConfig.lockFilePath = process.env.SECURITY_LOCK_FILE_PATH; } builder.security(securityConfig); } // Test Configuration if (process.env.TEST_ENABLED === 'true') { const testConfig: any = { enabled: true, framework: process.env.TEST_FRAMEWORK as any, testType: process.env.TEST_TYPE as any, includeSetup: process.env.TEST_INCLUDE_SETUP === 'true', includeTeardown: process.env.TEST_INCLUDE_TEARDOWN === 'true', }; if (process.env.TEST_LANGUAGE) { testConfig.language = process.env.TEST_LANGUAGE; } if (process.env.TEST_COVERAGE_TARGET) { testConfig.coverageTarget = parseInt(process.env.TEST_COVERAGE_TARGET); } builder.test(testConfig); } // Documentation Configuration if (process.env.DOCUMENTATION_ENABLED === 'true') { const docConfig: any = { enabled: true, format: process.env.DOCUMENTATION_FORMAT as any, includeExamples: process.env.DOCUMENTATION_INCLUDE_EXAMPLES === 'true', includeParameters: process.env.DOCUMENTATION_INCLUDE_PARAMETERS === 'true', includeReturnTypes: process.env.DOCUMENTATION_INCLUDE_RETURN_TYPES === 'true', includeSeeAlso: process.env.DOCUMENTATION_INCLUDE_SEE_ALSO === 'true', style: process.env.DOCUMENTATION_STYLE as any, }; if (process.env.DOCUMENTATION_LANGUAGE) { docConfig.language = process.env.DOCUMENTATION_LANGUAGE; } builder.documentation(docConfig); } // Review Configuration if (process.env.REVIEW_ENABLED === 'true') { const reviewConfig: any = { enabled: true, outputFormat: process.env.REVIEW_OUTPUT_FORMAT as any, postToGitHub: process.env.REVIEW_POST_TO_GITHUB === 'true', }; if (process.env.REVIEW_SEVERITY) { reviewConfig.severity = process.env.REVIEW_SEVERITY.split(',') as any; } if (process.env.REVIEW_CATEGORIES) { reviewConfig.categories = process.env.REVIEW_CATEGORIES.split(',') as any; } builder.review(reviewConfig); } // Global Configuration if (process.env.FILE_PATTERNS) { builder.filePatterns(process.env.FILE_PATTERNS.split(',')); } if (process.env.EXCLUDE_PATTERNS) { builder.excludePatterns(process.env.EXCLUDE_PATTERNS.split(',')); } if (process.env.VERBOSE === 'true') { builder.verbose(true); } if (process.env.DEBUG === 'true') { builder.debug(true); } return builder.build(); }