UNPKG

incize

Version:

AI Commit Copilot for Power Developers

710 lines (709 loc) 41.4 kB
#!/usr/bin/env node "use strict"; 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; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const GitHookListener_1 = require("../core/git/GitHookListener"); const DiffParser_1 = require("../core/git/DiffParser"); const CLIOutputRenderer_1 = require("../core/output/CLIOutputRenderer"); const RealAIService_1 = require("../core/ai/RealAIService"); const ConfigManager_1 = require("../core/config/ConfigManager"); const GitHookManager_1 = require("../core/git/GitHookManager"); const CommitMessageGenerator_1 = require("../core/ai/CommitMessageGenerator"); const ExportManager_1 = require("../core/output/ExportManager"); const ora_1 = __importDefault(require("ora")); const chalk_1 = __importDefault(require("chalk")); const program = new commander_1.Command(); program .name('incize') .description('AI Commit Copilot for Power Developers') .version('0.2.0'); // Info command program .command('info') .description('Show system information and status') .action(async () => { await infoCommand(); }); // Status command program .command('status') .description('Show comprehensive system status') .action(async () => { await statusCommand(); }); // Analysis command program .command('analyze') .description('Analyze staged changes with AI') .option('-o, --output <format>', 'Output format (text, json, markdown)', 'text') .option('--offline', 'Run in offline mode (no AI analysis)') .option('-f, --focus <area>', 'Focus analysis on specific area (security, performance, etc.)') .option('-m, --model <model>', 'AI model to use', 'claude-3-5-sonnet') .option('--risk-threshold <threshold>', 'Risk threshold (0-100)', '50') .option('--silent', 'Silent mode (minimal output)') .action(async (options) => { await analyzeCommand(options); }); // Setup command program .command('setup') .description('Setup Incize in current repository') .action(async () => { await setupCommand(); }); // Config command program .command('config') .description('Configure Incize settings') .option('--model <model>', 'Set default AI model') .option('--telemetry <enabled>', 'Enable/disable telemetry (true/false)') .option('--set-keys', 'Set API keys interactively') .option('--anthropic-key <key>', 'Set Anthropic API key') .option('--openai-key <key>', 'Set OpenAI API key') .option('--show', 'Show current configuration') .action(async (options) => { await configCommand(options); }); // Hook command program .command('hook') .description('Manage git hooks for automatic analysis') .option('--install', 'Install git hooks') .option('--uninstall', 'Uninstall git hooks') .option('--status', 'Check hook status') .action(async (options) => { await hookCommand(options); }); // Suggest command program .command('suggest') .description('Generate commit message suggestions') .option('--conventional', 'Use conventional commit format') .option('--emoji', 'Include emojis in suggestions') .option('--length <length>', 'Message length (short/medium/long)') .action(async (options) => { await suggestCommand(options); }); // Export command program .command('export') .description('Export analysis in different formats') .option('--format <format>', 'Export format (json/markdown/html)') .option('--include-diff', 'Include diff information') .option('--include-metadata', 'Include metadata') .option('--output <file>', 'Output file path') .action(async (options) => { await exportCommand(options); }); // Auth command program .command('auth') .description('Manage authentication with Incize') .option('--login', 'Login to your account') .option('--logout', 'Logout from your account') .option('--status', 'Check authentication status') .option('--help', 'Show authentication help') .action(async (options) => { await authCommand(options); }); // Parse command line arguments program.parse(); // Command implementations async function infoCommand() { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); try { const gitListener = new GitHookListener_1.GitHookListener(); renderer.renderInfo('🔍 Incize System Information'); renderer.renderInfo('──────────────────────────'); // Check if we're in a git repository try { await gitListener.validateEnvironment(); renderer.renderSuccess('✅ Git repository detected'); const commit = await gitListener.getCurrentCommit(); renderer.renderInfo(`📝 Current commit: ${commit.hash.substring(0, 8)}`); renderer.renderInfo(`🌿 Branch: ${commit.branch}`); renderer.renderInfo(`👤 Author: ${commit.author}`); } catch (error) { renderer.renderWarning('⚠️ Not in a git repository'); renderer.renderInfo('Run `incize setup` to initialize in a git repository'); } renderer.renderInfo('🎯 CLI-only mode - No authentication required'); renderer.renderInfo('📊 Analysis results are displayed locally only'); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Failed to get system information', message); process.exit(1); } } async function statusCommand() { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); const spinner = (0, ora_1.default)('Checking system status...').start(); try { const gitListener = new GitHookListener_1.GitHookListener(); const configManager = new ConfigManager_1.ConfigManager(); spinner.text = 'Validating Git repository...'; const isGitRepo = await gitListener.isGitRepository(); if (!isGitRepo) { spinner.fail('Not in a Git repository'); console.log('\n'); console.log(chalk_1.default.hex('#ef4444').bold(' ❌ Git Repository Not Found')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Current directory is not a Git repository.')}`); console.log(` ${chalk_1.default.gray('Please run this command from within a Git repository.')}`); console.log(''); console.log(chalk_1.default.hex('#3b82f6').bold(' 💡 Next Steps:')); console.log(` ${chalk_1.default.gray('• Run')} ${chalk_1.default.hex('#6366f1')('git init')} ${chalk_1.default.gray('to initialize a new repository')}`); console.log(` ${chalk_1.default.gray('• Or navigate to an existing Git repository')}`); console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); return; } spinner.text = 'Gathering commit information...'; const commit = await gitListener.getCurrentCommit(); spinner.text = 'Checking staged changes...'; const hasStagedChanges = await gitListener.hasStagedChanges(); spinner.text = 'Checking configuration...'; const hasApiKeys = configManager.hasApiKeys(); spinner.succeed('Status check complete'); // Modern status output console.log('\n'); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize System Status')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); // Git Repository Status console.log(chalk_1.default.hex('#10b981').bold(' ✅ Git Repository')); console.log(` ${chalk_1.default.gray('Hash:')} ${chalk_1.default.hex('#6366f1')(commit.hash.substring(0, 8))}`); console.log(` ${chalk_1.default.gray('Author:')} ${chalk_1.default.hex('#8b5cf6')(commit.author)}`); console.log(` ${chalk_1.default.gray('Branch:')} ${chalk_1.default.hex('#10b981')(commit.branch)}`); console.log(` ${chalk_1.default.gray('Message:')} ${chalk_1.default.yellow(commit.message)}`); console.log(''); // Staged Changes Status if (hasStagedChanges) { console.log(chalk_1.default.hex('#10b981').bold(' ✅ Staged Changes Detected')); console.log(` ${chalk_1.default.gray('Ready for analysis with')} ${chalk_1.default.hex('#6366f1')('incize analyze')}`); } else { console.log(chalk_1.default.hex('#f59e0b').bold(' ⚠️ No Staged Changes')); console.log(` ${chalk_1.default.gray('Stage some changes with')} ${chalk_1.default.hex('#6366f1')('git add')} ${chalk_1.default.gray('then run')} ${chalk_1.default.hex('#6366f1')('incize analyze')}`); } console.log(''); // Configuration Status console.log(chalk_1.default.hex('#3b82f6').bold(' 🔧 Configuration')); if (hasApiKeys) { console.log(` ${chalk_1.default.hex('#10b981')('✅')} AI API keys configured`); console.log(` ${chalk_1.default.gray('Available models:')} ${chalk_1.default.hex('#8b5cf6')('claude-3-5-sonnet, gpt-4o, mock')}`); } else { console.log(` ${chalk_1.default.hex('#f59e0b')('⚠️')} No AI API keys configured`); console.log(` ${chalk_1.default.gray('Run')} ${chalk_1.default.hex('#6366f1')('incize config --set-keys')} ${chalk_1.default.gray('to configure AI models')}`); } console.log(''); // Mode Information console.log(chalk_1.default.hex('#8b5cf6').bold(' 🎯 Mode Information')); console.log(` ${chalk_1.default.hex('#10b981')('✅')} CLI-only mode - No authentication required`); console.log(` ${chalk_1.default.hex('#10b981')('✅')} Analysis results displayed locally only`); console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); } catch (error) { spinner.fail('Status check failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Status check failed', message); process.exit(1); } } async function analyzeCommand(options) { const spinner = options.silent ? null : (0, ora_1.default)('Analyzing commit...').start(); try { // Initialize components const gitListener = new GitHookListener_1.GitHookListener(); const diffParser = new DiffParser_1.DiffParser(); // Validate environment await gitListener.validateEnvironment(); if (spinner) spinner.text = 'Gathering commit information...'; const [commit, diff] = await Promise.all([ gitListener.getCurrentCommit(), diffParser.parseStagedDiff() ]); if (spinner) spinner.text = 'Parsing changes...'; if (options.offline) { if (spinner) spinner.text = 'Running offline analysis...'; // Simple offline analysis const analysis = { riskScore: Math.floor(Math.random() * 100), riskLevel: 'medium', summary: 'Offline analysis - no AI insights available', suggestions: ['Consider running with AI analysis for better insights'], confidence: 0.5, changelog: 'Offline analysis completed', testSuggestions: ['Add tests when AI analysis is available'] }; if (spinner) spinner.succeed('Analysis complete'); if (!options.silent) { // Modern offline output console.log('\n'); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize Analysis')); console.log(chalk_1.default.hex('#6366f1')(' AI-Powered Commit Intelligence')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); console.log(chalk_1.default.hex('#3b82f6').bold(' 📋 Commit Context')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Hash:')} ${chalk_1.default.hex('#6366f1')(commit.hash.substring(0, 8))}`); console.log(` ${chalk_1.default.gray('Author:')} ${chalk_1.default.hex('#8b5cf6')(commit.author)}`); console.log(` ${chalk_1.default.gray('Branch:')} ${chalk_1.default.hex('#10b981')(commit.branch)}`); console.log(` ${chalk_1.default.gray('Message:')} ${chalk_1.default.yellow(commit.message)}`); console.log(''); console.log(chalk_1.default.hex('#6366f1').bold(' 🤖 AI Intelligence')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#3b82f6').bold(' 📋 Analysis Summary')); console.log(` ${analysis.summary}\n`); console.log(chalk_1.default.hex('#f59e0b').bold(' ⚠️ Risk Assessment')); console.log(` ${chalk_1.default.gray('Score:')} ${chalk_1.default.hex('#f59e0b')(`${analysis.riskScore}/100`)}`); console.log(` ${chalk_1.default.gray('Level:')} ${chalk_1.default.hex('#f59e0b')(analysis.riskLevel.toUpperCase())}\n`); console.log(chalk_1.default.hex('#10b981').bold(' 💡 Smart Recommendations')); analysis.suggestions.forEach((suggestion) => { console.log(` 💡 ${suggestion}`); }); console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); } } else { if (spinner) spinner.text = 'Running AI analysis...'; const configManager = new ConfigManager_1.ConfigManager(); const aiService = new RealAIService_1.RealAIService({ maxTokens: configManager.get('maxTokens'), temperature: configManager.get('temperature'), }); const apiKeys = configManager.getApiKeys(); aiService.setApiKeys(apiKeys.anthropic, apiKeys.openai); if (!aiService.isConfigured()) { if (spinner) spinner.warn('No AI API keys configured'); if (!options.silent) { console.log('\n'); console.log(chalk_1.default.hex('#f59e0b').bold(' ⚠️ Warning')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('No AI API keys configured')}`); console.log(` ${chalk_1.default.gray('Run')} ${chalk_1.default.hex('#6366f1')('incize config --set-keys')} ${chalk_1.default.gray('to configure AI models')}`); console.log(` ${chalk_1.default.gray('Using mock analysis for now...')}\n`); } const analysis = await aiService.analyze(diff, commit, 'local', { model: 'mock' }); if (spinner) spinner.succeed('Analysis complete (mock)'); if (!options.silent) { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); renderer.renderOutput({ commit, diff, analysis, version: '0.2.0', timestamp: new Date().toISOString() }); } } else { const model = options.model || configManager.get('defaultModel'); const focus = options.focus; const analysis = await aiService.analyze(diff, commit, 'local', { model, focus }); if (spinner) spinner.succeed('Analysis complete'); if (!options.silent) { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); renderer.renderOutput({ commit, diff, analysis, version: '0.2.0', timestamp: new Date().toISOString() }); } // Sync to web dashboard if authenticated try { const { CLIAuthService } = await Promise.resolve().then(() => __importStar(require('../core/auth/CLIAuthService'))); const authService = new CLIAuthService(); const authStatus = await authService.getAuthStatus(); if (authStatus.authenticated) { if (spinner) spinner.text = 'Syncing to dashboard...'; const syncSuccess = await authService.sendCommitAnalysis({ commit, diff, analysis }); if (syncSuccess && !options.silent) { console.log(chalk_1.default.hex('#10b981')(' ✅ Synced to dashboard')); } } } catch (error) { // Don't fail the analysis if sync fails if (!options.silent) { console.log(chalk_1.default.hex('#f59e0b')(' ⚠️ Could not sync to dashboard')); } } } } } catch (error) { if (spinner) spinner.fail('Analysis failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; console.log('\n'); console.log(chalk_1.default.hex('#ef4444').bold(' ❌ Error')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${message}`); console.log(''); process.exit(1); } } async function setupCommand() { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); const spinner = (0, ora_1.default)('Setting up Incize...').start(); try { const gitListener = new GitHookListener_1.GitHookListener(); // Validate git environment await gitListener.validateEnvironment(); spinner.succeed('Git repository found'); renderer.renderSuccess('✅ Incize setup complete'); renderer.renderInfo('🎯 CLI-only mode - No authentication required'); renderer.renderInfo('📊 Analysis results are displayed locally only'); renderer.renderInfo('💡 Run `incize analyze` to analyze your commits'); } catch (error) { spinner.fail('Setup failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Setup failed', message); renderer.renderInfo('Make sure you are in a git repository'); process.exit(1); } } async function hookCommand(options) { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); const hookManager = new GitHookManager_1.GitHookManager(); try { if (options.install) { await hookManager.install(); renderer.renderSuccess('✅ Git hooks installed successfully'); renderer.renderInfo('📝 Pre-commit hook: Will analyze staged changes before commit'); renderer.renderInfo('📝 Post-commit hook: Will analyze committed changes after commit'); } else if (options.uninstall) { await hookManager.uninstall(); renderer.renderSuccess('✅ Git hooks uninstalled successfully'); } else if (options.status) { const status = await hookManager.status(); renderer.renderInfo('🔧 Git Hook Status'); renderer.renderInfo(`📝 Pre-commit hook: ${status.preCommit ? '✅ Installed' : '❌ Not installed'}`); renderer.renderInfo(`📝 Post-commit hook: ${status.postCommit ? '✅ Installed' : '❌ Not installed'}`); } else { renderer.renderInfo('🔧 Git Hook Management'); renderer.renderInfo('📝 Commands:'); renderer.renderInfo(' incize hook --install # Install git hooks'); renderer.renderInfo(' incize hook --uninstall # Uninstall git hooks'); renderer.renderInfo(' incize hook --status # Check hook status'); } } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Hook management failed', message); process.exit(1); } } async function suggestCommand(options) { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); const spinner = (0, ora_1.default)('Generating commit message suggestions...').start(); try { const gitListener = new GitHookListener_1.GitHookListener(); const diffParser = new DiffParser_1.DiffParser(); const commitMessageGenerator = new CommitMessageGenerator_1.CommitMessageGenerator(); await gitListener.validateEnvironment(); spinner.text = 'Gathering commit information...'; const [commit, diff] = await Promise.all([ gitListener.getCurrentCommit(), diffParser.parseStagedDiff() ]); spinner.text = 'Generating suggestions...'; const suggestions = await commitMessageGenerator.generateSuggestions(diff, commit, { conventional: options.conventional !== false, emoji: options.emoji || false, length: options.length || 'medium' }); spinner.succeed('Suggestions generated'); // Modern suggest output console.log('\n'); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize Commit Suggestions')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); console.log(chalk_1.default.hex('#3b82f6').bold(' 💡 Choose one of the following:')); suggestions.forEach((suggestion, index) => { const number = chalk_1.default.hex('#6366f1').bold(`${index + 1}.`); console.log(` ${number} ${suggestion}`); }); console.log(''); console.log(chalk_1.default.hex('#8b5cf6').bold(' 🚀 Usage:')); console.log(` ${chalk_1.default.gray('git commit -m "your chosen message"')}`); console.log(` ${chalk_1.default.gray('incize suggest --conventional # Conventional format')}`); console.log(` ${chalk_1.default.gray('incize suggest --emoji # Include emojis')}`); console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); } catch (error) { spinner.fail('Suggestion generation failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Suggestion generation failed', message); process.exit(1); } } async function exportCommand(options) { const renderer = new CLIOutputRenderer_1.CLIOutputRenderer(); const spinner = (0, ora_1.default)('Exporting analysis...').start(); try { const gitListener = new GitHookListener_1.GitHookListener(); const diffParser = new DiffParser_1.DiffParser(); const configManager = new ConfigManager_1.ConfigManager(); const aiService = new RealAIService_1.RealAIService(); const exportManager = new ExportManager_1.ExportManager(); await gitListener.validateEnvironment(); spinner.text = 'Gathering commit information...'; const [commit, diff] = await Promise.all([ gitListener.getCurrentCommit(), diffParser.parseStagedDiff() ]); spinner.text = 'Running analysis...'; const apiKeys = configManager.getApiKeys(); aiService.setApiKeys(apiKeys.anthropic, apiKeys.openai); let analysis; try { analysis = await aiService.analyze(diff, commit, 'local', { model: configManager.get('defaultModel') }); } catch (error) { spinner.warn('AI analysis failed, using mock data'); analysis = await aiService.analyze(diff, commit, 'local', { model: 'mock' }); } spinner.text = 'Exporting...'; const format = options.format || 'json'; const exportData = exportManager.exportAnalysis(analysis, diff, commit, { format, includeDiff: options.includeDiff || false, includeMetadata: options.includeMetadata || false }); if (options.output) { const fs = await Promise.resolve().then(() => __importStar(require('fs'))); fs.writeFileSync(options.output, exportData); spinner.succeed('Export completed'); renderer.renderSuccess(`✅ Analysis exported to ${options.output}`); } else { spinner.succeed('Export completed'); renderer.renderSuccess('✅ Analysis exported'); console.log(exportData); } } catch (error) { spinner.fail('Export failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; renderer.renderError('Export failed', message); process.exit(1); } } async function configCommand(options) { const spinner = (0, ora_1.default)('Managing configuration...').start(); try { const configManager = new ConfigManager_1.ConfigManager(); if (options.show) { spinner.succeed('Configuration loaded'); const config = configManager.getAll(); const apiKeys = configManager.getApiKeys(); console.log('\n'); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize Configuration')); console.log(chalk_1.default.hex('#6366f1')(' AI-Powered Commit Intelligence')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); console.log(chalk_1.default.hex('#3b82f6').bold(' 🔧 Current Configuration')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Config file:')} ${chalk_1.default.hex('#6366f1')(configManager.getConfigPath())}`); console.log(` ${chalk_1.default.gray('Default model:')} ${chalk_1.default.hex('#8b5cf6')(config.defaultModel)}`); console.log(` ${chalk_1.default.gray('Telemetry:')} ${config.telemetry ? chalk_1.default.hex('#10b981')('enabled') : chalk_1.default.hex('#f59e0b')('disabled')}`); console.log(` ${chalk_1.default.gray('API Keys:')} ${Object.keys(apiKeys).length > 0 ? chalk_1.default.hex('#10b981')('configured') : chalk_1.default.hex('#f59e0b')('not configured')}`); console.log(` ${chalk_1.default.gray('Available models:')} ${chalk_1.default.hex('#8b5cf6')('mock, claude-3-5-sonnet, gpt-4o')}`); if (apiKeys.anthropic) { console.log(` ${chalk_1.default.gray('Anthropic:')} ${chalk_1.default.hex('#6366f1')(apiKeys.anthropic.substring(0, 20) + '...')}`); } if (apiKeys.openai) { console.log(` ${chalk_1.default.gray('OpenAI:')} ${chalk_1.default.hex('#6366f1')(apiKeys.openai.substring(0, 20) + '...')}`); } console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); return; } if (options.setKeys) { spinner.text = 'Setting API keys interactively...'; console.log('\n'); console.log(chalk_1.default.hex('#3b82f6').bold(' 🔑 Setting API Keys')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Get your API keys from:')}`); console.log(` ${chalk_1.default.hex('#6366f1')('• Anthropic:')} ${chalk_1.default.gray('https://console.anthropic.com/')}`); console.log(` ${chalk_1.default.hex('#6366f1')('• OpenAI:')} ${chalk_1.default.gray('https://platform.openai.com/api-keys')}`); console.log(''); console.log(` ${chalk_1.default.gray('Use')} ${chalk_1.default.hex('#6366f1')('--anthropic-key')} ${chalk_1.default.gray('and')} ${chalk_1.default.hex('#6366f1')('--openai-key')} ${chalk_1.default.gray('options to set keys')}\n`); return; } if (options.anthropicKey) { spinner.text = 'Setting Anthropic API key...'; configManager.setApiKeys(options.anthropicKey); spinner.succeed('API keys updated'); console.log('\n'); console.log(chalk_1.default.hex('#10b981').bold(' ✅ Success')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Anthropic API key configured successfully')}`); console.log(` ${chalk_1.default.gray('Available models:')} ${chalk_1.default.hex('#8b5cf6')('mock, claude-3-5-sonnet, gpt-4o')}\n`); return; } if (options.openaiKey) { spinner.text = 'Setting OpenAI API key...'; configManager.setApiKeys(undefined, options.openaiKey); spinner.succeed('API keys updated'); console.log('\n'); console.log(chalk_1.default.hex('#10b981').bold(' ✅ Success')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('OpenAI API key configured successfully')}`); console.log(` ${chalk_1.default.gray('Available models:')} ${chalk_1.default.hex('#8b5cf6')('mock, claude-3-5-sonnet, gpt-4o')}\n`); return; } if (options.model) { spinner.text = 'Setting default model...'; configManager.set('defaultModel', options.model); spinner.succeed('Default model set'); console.log('\n'); console.log(chalk_1.default.hex('#10b981').bold(' ✅ Success')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Default model set to:')} ${chalk_1.default.hex('#8b5cf6')(options.model)}\n`); return; } // Default: show configuration spinner.succeed('Configuration loaded'); console.log('\n'); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize Configuration')); console.log(chalk_1.default.hex('#6366f1')(' AI-Powered Commit Intelligence')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); console.log(chalk_1.default.hex('#3b82f6').bold(' 🔧 Current Configuration')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${chalk_1.default.gray('Config file:')} ${chalk_1.default.hex('#6366f1')(configManager.getConfigPath())}`); console.log(` ${chalk_1.default.gray('Default model:')} ${chalk_1.default.hex('#8b5cf6')(configManager.get('defaultModel'))}`); console.log(` ${chalk_1.default.gray('Telemetry:')} ${configManager.get('telemetry') ? chalk_1.default.hex('#10b981')('enabled') : chalk_1.default.hex('#f59e0b')('disabled')}`); console.log(` ${chalk_1.default.gray('API Keys:')} ${configManager.hasApiKeys() ? chalk_1.default.hex('#10b981')('configured') : chalk_1.default.hex('#f59e0b')('not configured')}`); console.log(` ${chalk_1.default.gray('Available models:')} ${chalk_1.default.hex('#8b5cf6')('mock, claude-3-5-sonnet, gpt-4o')}`); const apiKeys = configManager.getApiKeys(); if (apiKeys.anthropic) { console.log(` ${chalk_1.default.gray('Anthropic:')} ${chalk_1.default.hex('#6366f1')(apiKeys.anthropic.substring(0, 20) + '...')}`); } if (apiKeys.openai) { console.log(` ${chalk_1.default.gray('OpenAI:')} ${chalk_1.default.hex('#6366f1')(apiKeys.openai.substring(0, 20) + '...')}`); } console.log(''); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(chalk_1.default.hex('#6366f1').bold(' ⚡ Incize v0.2.0')); console.log(chalk_1.default.gray(' AI-Powered Commit Intelligence for Power Developers')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(''); } catch (error) { spinner.fail('Configuration failed'); const message = error instanceof Error ? error.message : 'Unknown error occurred'; console.log('\n'); console.log(chalk_1.default.hex('#ef4444').bold(' ❌ Error')); console.log(chalk_1.default.gray(' ──────────────────────────────────────────────────────────')); console.log(` ${message}`); console.log(''); process.exit(1); } } async function authCommand(options) { const { CLIAuthService } = await Promise.resolve().then(() => __importStar(require('../core/auth/CLIAuthService'))); const authService = new CLIAuthService(); const outputRenderer = new CLIOutputRenderer_1.CLIOutputRenderer(); try { if (options.help || (!options.login && !options.logout && !options.status)) { outputRenderer.renderAuthHelp(); return; } if (options.status) { const authStatus = await authService.getAuthStatus(); outputRenderer.renderAuthStatus(authStatus); return; } if (options.login) { const success = await authService.login(); if (!success) { process.exit(1); } return; } if (options.logout) { const success = await authService.logout(); if (!success) { process.exit(1); } return; } } catch (error) { outputRenderer.renderError('Authentication error', error instanceof Error ? error.message : 'Unknown error'); process.exit(1); } }