akshit-sharma-cli
Version:
Personal CLI tool showcasing Akshit Sharma's AI/ML engineering profile
530 lines (441 loc) ⢠17.4 kB
JavaScript
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();
}