UNPKG

@max-black/npm-practice

Version:

This interactive CLI tutor is designed as hands-on practice for readers of the [NPM Book by Max Black](https://www.amazon.com/dp/B0FSX9TZZ1). If you're working through the book, this tool will guide you through real-world npm workflows — from initializi

100 lines (78 loc) 2.83 kB
const fs = require('fs'); const path = require('path'); const os = require('os'); const { GoogleGenerativeAI } = require('@google/generative-ai'); const CONFIG_DIR = path.join(os.homedir(), '.npm-practice'); const API_KEY_FILE = path.join(CONFIG_DIR, 'gemini-api-key'); let genAI = null; let model = null; function isAIConfigured() { return fs.existsSync(API_KEY_FILE); } function initializeAI() { if (!isAIConfigured()) { return false; } try { const apiKey = fs.readFileSync(API_KEY_FILE, 'utf8').trim(); genAI = new GoogleGenerativeAI(apiKey); model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' }); // Log initialization (only in debug mode) if (process.env.DEBUG_AI) { const timestamp = new Date().toISOString(); const logFile = path.join(CONFIG_DIR, 'ai-usage.log'); fs.appendFileSync(logFile, `${timestamp} - AI initialized\n`); } return true; } catch (error) { console.error('Failed to initialize AI:', error.message); return false; } } async function askAI(question, currentTask = null) { if (!model && !initializeAI()) { return 'AI is not configured. Please run the setup script first.'; } // Log AI usage if (process.env.DEBUG_AI) { const timestamp = new Date().toISOString(); const logFile = path.join(CONFIG_DIR, 'ai-usage.log'); fs.appendFileSync(logFile, `${timestamp} - AI request: "${question.substring(0, 50)}..."\n`); } try { // Build context-aware prompt let prompt = ''; if (currentTask) { prompt = `You are an expert npm and Node.js tutor helping a beginner learn npm commands. Current Task: ${currentTask.description} Expected Command: ${currentTask.expectedCommand} ${currentTask.explanation ? `Explanation: ${currentTask.explanation}` : ''} User Question: ${question} Provide a clear, concise, and beginner-friendly answer. Focus on: 1. Answering the specific question 2. Relating it to the current task if relevant 3. Providing practical examples 4. Keeping it under 200 words Answer:`; } else { prompt = `You are an expert npm and Node.js tutor helping a beginner learn npm commands. User Question: ${question} Provide a clear, concise, and beginner-friendly answer with practical examples. Keep it under 200 words. Answer:`; } const result = await model.generateContent(prompt); const response = await result.response; const text = response.text(); return text.trim(); } catch (error) { if (error.message && error.message.includes('API_KEY_INVALID')) { return 'Invalid API key. Please run setup-ai.js again to reconfigure.'; } return `AI Error: ${error.message || 'Unable to get response. Please try again.'}`; } } module.exports = { isAIConfigured, initializeAI, askAI };