UNPKG

akshit-sharma-cli

Version:

Personal CLI tool showcasing Akshit Sharma's AI/ML engineering profile

530 lines (441 loc) • 17.4 kB
#!/usr/bin/env node import readline from 'readline'; import chalk from 'chalk'; import { marked } from 'marked'; import TerminalRenderer from 'marked-terminal'; import boxen from 'boxen'; import gradient from 'gradient-string'; import { config as dotenvConfig } from 'dotenv'; // Load environment variables from .env file (for development) dotenvConfig(); // Configure marked to use terminal renderer marked.setOptions({ renderer: new TerminalRenderer({ code: chalk.yellow, blockquote: chalk.gray.italic, html: chalk.gray, heading: chalk.green.bold, firstHeading: chalk.magenta.underline.bold, hr: chalk.reset, listitem: chalk.cyan, list: (body) => chalk.cyan(body), paragraph: chalk.white, strong: chalk.bold.cyan, em: chalk.italic.yellow, codespan: chalk.yellow.dim }) }); class AkshitChatbot { constructor() { // Use auto-injected configuration or fallback to environment variables this.proxyUrl = this.resolveProxyUrl(); // Validate that we have a valid proxy URL before proceeding if (!this.proxyUrl || !this.isValidUrl(this.proxyUrl)) { this.displayConfigurationError(); process.exit(1); } console.log(chalk.green('āœ… Backend auto-configured successfully')); console.log(chalk.gray('šŸ”— Connected to:'), chalk.cyan(this.maskUrl(this.proxyUrl))); console.log(chalk.green('āœ… Backend auto-configured successfully')); console.log(chalk.gray('šŸ”— Connected to:'), chalk.cyan(this.maskUrl(this.proxyUrl))); this.conversationHistory = []; } /** * Resolves proxy URL from auto-injected config or environment variables * @returns {string|null} Valid proxy URL or null if not configured */ resolveProxyUrl() { // Priority 1: Environment variables (development/testing/production) const envSources = [ process.env.AKSHIT_CHATBOT_PROXY_URL, process.env.CHATBOT_PROXY_URL, process.env.VERCEL_URL, process.env.API_BASE_URL, process.env.BACKEND_URL ]; for (const url of envSources) { if (url && this.isValidUrl(url)) { return this.normalizeApiUrl(url); } } // Priority 2: Default Production URL (Fallback) return 'https://akshit-cli-backend-dzp6bnms7-jokers-projects-741f992f.vercel.app/api/chat'; } /** * Masks URL for display purposes (security) * @param {string} url URL to mask * @returns {string} Masked URL */ maskUrl(url) { if (!url) return 'Not configured'; try { const urlObj = new URL(url); const domain = urlObj.hostname; const maskedDomain = domain.length > 20 ? domain.substring(0, 8) + '...' + domain.substring(domain.length - 8) : domain; return `${urlObj.protocol}//${maskedDomain}${urlObj.pathname}`; } catch { return 'Invalid URL format'; } } /** * Displays comprehensive configuration error with setup instructions */ displayConfigurationError() { console.log('\n' + chalk.red.bold('āŒ CONFIGURATION ERROR: Backend URL not available')); console.log(boxen( chalk.yellow.bold('šŸ”§ Backend Connection Issue\n\n') + chalk.white('This package should work automatically without any setup!\n\n') + chalk.cyan.bold('Quick Fixes:\n') + chalk.white('1. Try the latest version: npx akshit-sharma-cli@latest --chatbot\n') + chalk.white('2. Clear npm cache: npm cache clean --force\n') + chalk.white('3. Reinstall: npm uninstall -g akshit-sharma-cli && npm install -g akshit-sharma-cli\n\n') + chalk.gray.bold('For Developers Only:\n') + chalk.gray('• Set AKSHIT_CHATBOT_PROXY_URL environment variable\n'), { padding: 1, margin: 1, borderStyle: 'double', borderColor: 'red', backgroundColor: '#1a0000' } )); console.log(chalk.yellow('\nšŸ’” Current environment status:')); console.log(chalk.gray(' AKSHIT_CHATBOT_PROXY_URL:'), process.env.AKSHIT_CHATBOT_PROXY_URL ? chalk.green('āœ“ Set') : chalk.red('āœ— Not set')); console.log(chalk.gray(' BACKEND_URL:'), process.env.BACKEND_URL ? chalk.green('āœ“ Set') : chalk.red('āœ— Not set')); } /** * Normalizes URL to ensure it has the correct API endpoint * @param {string} url Base URL * @returns {string} Normalized URL with /api/chat endpoint */ normalizeApiUrl(url) { if (!url) return url; // Remove trailing slash url = url.replace(/\/$/, ''); // Add /api/chat if not present if (!url.endsWith('/api/chat')) { if (url.endsWith('/api')) { url += '/chat'; } else { url += '/api/chat'; } } return url; } /** * Validates if the provided URL is a valid HTTP/HTTPS URL * @param {string} url The URL to validate * @returns {boolean} True if valid, false otherwise */ isValidUrl(url) { if (!url || typeof url !== 'string') { return false; } // Check for obvious invalid values if (url.toLowerCase() === 'undefined' || url.toLowerCase() === 'null' || url.toLowerCase() === 'localhost' || url === '' || url === 'PLACEHOLDER_URL_WILL_BE_REPLACED') { return false; } try { const urlObj = new URL(url); return urlObj.protocol === 'http:' || urlObj.protocol === 'https:'; } catch (error) { return false; } } // ... rest of your methods remain exactly the same createInterface() { return readline.createInterface({ input: process.stdin, output: process.stdout, prompt: chalk.cyan.bold('> ') }); } async generateResponse(userInput) { try { const payload = this.buildPayload(userInput); const response = await fetch(this.proxyUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Access-Token': 'akshit-portfolio-cli-v1' }, body: JSON.stringify(payload) }); if (!response.ok) { if (response.status === 429) { throw new Error('Rate limit exceeded. Please wait a minute before trying again.'); } if (response.status === 401) { throw new Error('Security verification failed. Please update to the latest version of the CLI.'); } const errorText = await response.text(); throw new Error(`API request failed with status ${response.status}: ${errorText}`); } const data = await response.json(); return data; } catch (error) { console.error(chalk.red('Error connecting to chatbot service:', error.message)); if (error.message.includes('fetch') || error.message.includes('URL')) { console.log(chalk.yellow('šŸ’” Connection issues detected. Verify your environment configuration.')); console.log(chalk.gray('Check that backend URL is properly configured.')); } return { response: "I'm sorry, I'm having trouble connecting to my knowledge base. Please verify the backend service is running and properly configured.", action: 'error' }; } } detectAction(input) { const lowerInput = input.toLowerCase(); if (lowerInput.includes('linkedin') || lowerInput.includes('professional profile') || lowerInput.includes('profile update') || lowerInput.includes('professional background')) { return 'linkedin'; } if (lowerInput.includes('github') || lowerInput.includes('repository') || lowerInput.includes('repo') || lowerInput.includes('projects') || lowerInput.includes('code')) { return 'github'; } if ((lowerInput.includes('job') || lowerInput.includes('position') || lowerInput.includes('role')) && (lowerInput.includes('fit') || lowerInput.includes('match') || lowerInput.includes('analysis') || lowerInput.includes('suitable') || lowerInput.includes('http'))) { return 'job-analysis'; } if (lowerInput.includes('contact') || lowerInput.includes('connect') || lowerInput.includes('reach out') || lowerInput.includes('email') || lowerInput.includes('message')) { return 'contact'; } if (lowerInput.includes('blog') || lowerInput.includes('website') || lowerInput.includes('webpage') || lowerInput.includes('latest updates') || lowerInput.includes('recent posts')) { return 'webpage'; } if (lowerInput.includes('resume') || lowerInput.includes('cv') || lowerInput.includes('education') || lowerInput.includes('experience')) { return 'resume'; } return 'chat'; } buildPayload(userInput) { const context = this.conversationHistory.slice(-3).map(msg => `${msg.role}: ${msg.content}`).join('\n'); const contextualPrompt = `You are an AI assistant representing Akshit Sharma, an AI/ML Engineering student with comprehensive knowledge about his professional profile. EDUCATION: - B.Tech Computer Science (AI & Data Science Specialization) - Maharaja Agrasen Institute of Technology - CGPA: 8.96/10 (2022-2026) RECENT ACHIEVEMENTS: - Winner of AceCloud X RTDS Hackathon '25 - Developed multiple high-accuracy ML models (89-95% accuracy) TECHNICAL SKILLS: - Programming: Python (Advanced), C/C++, Java, JavaScript, SQL - AI/ML: TensorFlow, PyTorch, BERT, Transformers, NLP, Computer Vision, RAG - Cloud: Google Cloud Platform, AWS, OpenStack SDK - Tools: Git, Linux, MongoDB, Docker, Kubernetes, Flask, React KEY PROJECTS: 1. OpenStack Cloud Management System (87% accuracy, 300ms response time) 2. SignEase ASL Video Platform (89% accuracy, optimized latency) 3. Universal Website Chatbot (90% accuracy using fine-tuned Llama 3.1) WORK EXPERIENCE: - ML Intern at CodSoft (Aug-Sep 2024): Movie recommendation (92% accuracy) - ML Intern at Cantilever.in (Jul-Aug 2024): BERT sentiment analysis (88% accuracy) CONTACT: - Email: akshitsharma7096@gmail.com - Phone: +91 8810248097 - GitHub: https://github.com/akshit7093 - LinkedIn: https://linkedin.com/in/akshitsharma - LeetCode: https://leetcode.com/akshitsharma Previous conversation: ${context} User: ${userInput} Assistant:`; return { contextualPrompt: contextualPrompt }; } formatResponse(data) { try { let formattedResponse = marked(data.response); if (data.action === 'github' && data.repositories) { formattedResponse += `\n\n${chalk.gray('šŸ“Š Analyzed ' + data.repositories.length + ' repositories • Total: ' + data.totalRepos)}`; } if (data.action === 'linkedin' && data.profileData) { formattedResponse += `\n\n${chalk.gray('šŸ’¼ Data source: LinkedIn profile • Last updated: ' + data.profileData.lastUpdated)}`; } if (data.action === 'job-analysis' && data.jobUrl) { formattedResponse += `\n\n${chalk.gray('šŸ”— Analyzed job posting: ' + data.jobUrl)}`; } if (data.action === 'contact' && data.actionUrl) { formattedResponse += `\n\n${chalk.blue.bold('šŸ”— Quick Action: ' + data.actionUrl)}`; } if (data.action === 'resume' && data.resumeData) { formattedResponse += `\n\n${chalk.gray('šŸ“„ Source: Comprehensive resume data • Last updated: ' + data.resumeData.lastUpdated)}`; } return boxen(formattedResponse, { padding: 1, margin: { top: 0, bottom: 1, left: 1, right: 1 }, borderStyle: 'round', borderColor: this.getActionColor(data.action), backgroundColor: '#0a0a0a' }); } catch (error) { return chalk.white(data.response); } } getActionColor(action) { const colors = { 'chat': 'blue', 'linkedin': 'cyan', 'github': 'green', 'job-analysis': 'yellow', 'contact': 'magenta', 'webpage': 'blue', 'resume': 'red', 'error': 'red' }; return colors[action] || 'blue'; } async startChat() { const title = gradient.rainbow.multiline(` ╔══════════════════════════════════════════════════╗ ā•‘ šŸ¤– AKSHIT'S ENHANCED AI ASSISTANT ā•‘ ā•‘ Powered by Advanced Integrations ā•‘ ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•`); console.log('\n' + title); console.log(boxen( chalk.yellow.bold('šŸš€ Enhanced Features Available:\n\n') + chalk.white('šŸ’¼ **LinkedIn Integration**\n') + chalk.gray(' • "linkedin profile updates"\n') + chalk.gray(' • "professional background"\n\n') + chalk.white('šŸ“Š **GitHub Analysis**\n') + chalk.gray(' • "show github repositories"\n') + chalk.gray(' • "analyze https://github.com/user/repo"\n\n') + chalk.white('šŸŽÆ **Job Fit Analysis**\n') + chalk.gray(' • "analyze this job: [paste URL]"\n') + chalk.gray(' • "job fit for [job description]"\n\n') + chalk.white('šŸ“± **Contact Generation**\n') + chalk.gray(' • "help me contact via email"\n') + chalk.gray(' • "linkedin connection message"\n\n') + chalk.white('🌐 **Website & Resume**\n') + chalk.gray(' • "latest blog posts"\n') + chalk.gray(' • "resume details"\n\n') + chalk.cyan.bold('šŸ’” Example Commands:\n') + chalk.white(' • "Show me Akshit\'s latest GitHub projects"\n') + chalk.white(' • "Analyze this job: https://linkedin.com/jobs/view/123"\n') + chalk.white(' • "Help me write an email to Akshit for collaboration"\n') + chalk.white(' • "What\'s in Akshit\'s resume?"\n\n') + chalk.gray('Type "exit", "quit", or press Ctrl+C to end.'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'green', backgroundColor: '#1a1a1a' } )); const rl = this.createInterface(); rl.prompt(); rl.on('line', async (input) => { const userInput = input.trim(); if (userInput.toLowerCase() === 'exit' || userInput.toLowerCase() === 'quit') { console.log(boxen( chalk.yellow.bold('šŸ‘‹ Thanks for exploring Akshit\'s Enhanced AI Assistant!\n\n') + chalk.white('šŸ¤ Ready to connect?\n\n') + chalk.cyan('šŸ“§ Email: akshitsharma7096@gmail.com\n') + chalk.cyan('šŸ’¼ LinkedIn: linkedin.com/in/akshitsharma\n') + chalk.cyan('šŸ”— GitHub: github.com/akshit7093\n') + chalk.cyan('⚔ LeetCode: leetcode.com/akshitsharma\n\n') + chalk.green('šŸš€ Perfect for AI/ML collaborations and opportunities!'), { padding: 1, borderStyle: 'double', borderColor: 'yellow', textAlignment: 'center' } )); rl.close(); return; } if (userInput === '' || userInput === 'help') { console.log(boxen( chalk.cyan.bold('šŸ”§ Available Commands:\n\n') + chalk.white('• linkedin, github, job analysis, contact, resume\n') + chalk.white('• Or just ask naturally: "Tell me about Akshit\'s projects"\n') + chalk.gray('• Type specific URLs for analysis'), { padding: 1, borderStyle: 'round', borderColor: 'cyan' } )); rl.prompt(); return; } this.conversationHistory.push({ role: 'user', content: userInput }); const frames = ['ā ‹', 'ā ™', 'ā ¹', 'ā ø', 'ā ¼', 'ā “', 'ā ¦', 'ā §', 'ā ‡', 'ā ']; const actionName = this.detectAction(userInput); const actionEmojis = { 'linkedin': 'šŸ’¼', 'github': 'šŸ“Š', 'job-analysis': 'šŸŽÆ', 'contact': 'šŸ“±', 'webpage': '🌐', 'resume': 'šŸ“„', 'chat': 'šŸ¤–' }; let i = 0; const thinking = setInterval(() => { process.stdout.write(`\r${chalk.blue.bold('šŸ¤– Assistant:')} ${chalk.gray(frames[i % frames.length] + ' processing ' + actionEmojis[actionName] + ' ' + actionName + '...')}`); i++; }, 100); const responseData = await this.generateResponse(userInput); clearInterval(thinking); process.stdout.write('\r\x1b[K'); console.log(chalk.blue.bold('\nšŸ¤– Assistant:')); console.log(this.formatResponse(responseData)); this.conversationHistory.push({ role: 'assistant', content: responseData.response }); if (this.conversationHistory.length > 20) { this.conversationHistory = this.conversationHistory.slice(-16); } rl.prompt(); }); rl.on('close', () => { console.log(chalk.gray('\nšŸ‘‹ Goodbye!\n')); process.exit(0); }); rl.on('SIGINT', () => { console.log(boxen( chalk.yellow.bold('\nšŸ‘‹ Thanks for using Akshit\'s Enhanced AI Assistant!\n\n') + chalk.white('šŸš€ Connect for AI/ML opportunities!'), { padding: 1, borderStyle: 'round', borderColor: 'yellow', textAlignment: 'center' } )); process.exit(0); }); } } export { AkshitChatbot }; if (import.meta.url.startsWith('file:') && process.argv[1] === new URL(import.meta.url).pathname) { const chatbot = new AkshitChatbot(); chatbot.startChat(); }