UNPKG

mya-cli

Version:

AI-powered stock and options analysis CLI tool. Fully automated trading intelligence platform.

304 lines (303 loc) 11.4 kB
import { Command } from 'commander'; import chalk from 'chalk'; import ora from 'ora'; import inquirer from 'inquirer'; // Production API URL - points to deployed worker const API_BASE_URL = process.env.MYA_API_URL || 'https://mya-production.monibee-fudgekin.workers.dev'; async function makeRequest(endpoint, data = {}) { const response = await fetch(`${API_BASE_URL}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data) }); if (!response.ok) { throw new Error(`API request failed: ${response.status} ${response.statusText}`); } return response.json(); } async function loadSession() { try { const fs = await import('fs'); const path = await import('path'); const os = await import('os'); const sessionPath = path.join(os.homedir(), '.mya-session.json'); if (fs.existsSync(sessionPath)) { const sessionData = JSON.parse(fs.readFileSync(sessionPath, 'utf8')); return sessionData; } } catch (error) { // Session file doesn't exist or is invalid } return null; } async function saveSession(session) { const fs = await import('fs'); const path = await import('path'); const os = await import('os'); const sessionPath = path.join(os.homedir(), '.mya-session.json'); fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2)); } async function ensureAuthenticated() { const session = await loadSession(); if (session) { try { // Validate session with API await makeRequest('/api/validate-session', session); return session; } catch (error) { // Session is invalid, need to re-authenticate } } console.log(chalk.yellow('Authentication required. Please login.')); return null; } function getMarketStatusMessage() { const now = new Date(); const hour = now.getHours(); const day = now.getDay(); const isWeekend = day === 0 || day === 6; const isMarketHours = hour >= 9 && hour < 16; if (isWeekend) { return chalk.yellow('Market is CLOSED (Weekend) - Next open: Monday 9:30 AM EST'); } else if (!isMarketHours) { return chalk.yellow('Market is CLOSED (After-hours) - Next open: 9:30 AM EST tomorrow'); } else { return chalk.green('Market is OPEN (Regular hours)'); } } async function submitAnalysisRequest(userId, machineId, analysisType, data = {}) { return makeRequest('/api/analyze', { userId, machineId, analysisType, ...data }); } // CLI Commands const program = new Command(); program .name('mya') .description('AI-powered stock and options analysis CLI tool') .version('0.1.0'); // Login command program .command('login') .description('Authenticate with your account') .action(async () => { try { const answers = await inquirer.prompt([ { type: 'input', name: 'email', message: 'Email:', validate: (input) => input.includes('@') || 'Please enter a valid email' }, { type: 'password', name: 'password', message: 'Password:', mask: '*' } ]); const spinner = ora('Authenticating...').start(); try { const result = await makeRequest('/api/login', answers); if (result.success) { await saveSession(result.session); spinner.succeed('Authentication successful'); console.log(chalk.green('✅ Logged in successfully')); } else { spinner.fail('Authentication failed'); console.log(chalk.red('❌ Invalid credentials')); } } catch (error) { spinner.fail('Authentication error'); console.error(chalk.red('Login failed:'), error); } } catch (error) { console.error(chalk.red('Login command failed:'), error); } }); // Analysis commands program .command('analyze') .description('Perform comprehensive market analysis with CMT technical analysis') .action(async () => { try { const session = await ensureAuthenticated(); if (!session) { console.log(chalk.red('❌ Authentication required')); process.exit(1); } console.log(getMarketStatusMessage()); const spinner = ora('Analyzing market data from announcements...').start(); try { const analysisResult = await submitAnalysisRequest(session.userId, session.machineId, 'cmt_analysis', {}); if (analysisResult.success && analysisResult.result) { spinner.succeed('Market analysis completed'); console.log(chalk.green('Stock Analysis Results:')); console.log(chalk.gray('Request ID:'), analysisResult.requestId || 'N/A'); const result = analysisResult.result; if (result.aiAnalysis) { console.log('\n' + chalk.blue('Market Analysis:')); console.log(result.aiAnalysis); } if (result.symbols && result.symbols.length > 0) { console.log(chalk.white('\nAnalyzed'), chalk.cyan(result.symbols.length), chalk.white('market data points')); } } else { spinner.fail('Market analysis failed'); console.error(chalk.red('Analysis request failed:'), analysisResult.error || 'Unknown error'); } } catch (error) { spinner.fail('Market analysis error'); console.error(chalk.red('Analysis request error:'), error); } } catch (error) { console.error(chalk.red('Analyze command failed:'), error); } }); // Add other commands program .command('announcements') .description('Market news review and fundamentals data collection for analysis functions') .action(async () => { try { const session = await ensureAuthenticated(); if (!session) { console.log(chalk.red('❌ Authentication required')); process.exit(1); } console.log(getMarketStatusMessage()); const spinner = ora('Reviewing market news and fundamentals data...').start(); try { const analysisResult = await submitAnalysisRequest(session.userId, session.machineId, 'announcements_cmt', {}); if (analysisResult.success && analysisResult.result) { spinner.succeed('Market news review completed'); console.log(chalk.green('Market News Review:')); console.log(chalk.gray('Request ID:'), analysisResult.requestId || 'N/A'); const result = analysisResult.result; if (result.aiAnalysis) { console.log('\n' + chalk.blue('Market News Review:')); console.log(result.aiAnalysis); } if (result.symbols && result.symbols.length > 0) { console.log(chalk.white('\nStocks identified for analysis:'), chalk.cyan(result.symbols.join(', '))); } if (result.timestamp) { console.log(chalk.gray(`\nGenerated: ${new Date(result.timestamp).toLocaleString()}`)); } } else { spinner.fail('Market news review failed'); console.error(chalk.red('Analysis request failed:'), analysisResult.error || 'Unknown error'); } } catch (error) { spinner.fail('Market news review error'); console.error(chalk.red('Analysis request error:'), error); } } catch (error) { console.error(chalk.red('Announcements command failed:'), error); } }); program .command('earnings') .description('Earnings analysis and screening for upcoming opportunities') .action(async () => { const session = await ensureAuthenticated(); if (!session) { console.log(chalk.red('❌ Authentication required')); process.exit(1); } console.log(getMarketStatusMessage()); const spinner = ora('Analyzing earnings data...').start(); try { const result = await submitAnalysisRequest(session.userId, session.machineId, 'earnings_cmt', {}); spinner.succeed('Earnings analysis completed'); console.log(chalk.green('Earnings Analysis Results:')); if (result.result?.aiAnalysis) { console.log('\n' + result.result.aiAnalysis); } } catch (error) { spinner.fail('Earnings analysis failed'); console.error(chalk.red('Error:'), error); } }); program .command('double') .description('Double-top and double-bottom pattern analysis') .action(async () => { const session = await ensureAuthenticated(); if (!session) { console.log(chalk.red('❌ Authentication required')); process.exit(1); } console.log(getMarketStatusMessage()); const spinner = ora('Analyzing double patterns...').start(); try { const result = await submitAnalysisRequest(session.userId, session.machineId, 'double_cmt', {}); spinner.succeed('Double pattern analysis completed'); console.log(chalk.green('Double Pattern Analysis Results:')); if (result.result?.aiAnalysis) { console.log('\n' + result.result.aiAnalysis); } } catch (error) { spinner.fail('Double pattern analysis failed'); console.error(chalk.red('Error:'), error); } }); // Status command program .command('status') .description('Show system status and API information') .action(async () => { try { const session = await loadSession(); console.log(chalk.blue('🔍 MYA CLI Status Report')); console.log('═'.repeat(40)); if (session) { console.log(chalk.green('✅ Authentication: Logged in')); console.log(chalk.gray(` User ID: ${session.userId}`)); } else { console.log(chalk.yellow('⚠️ Authentication: Not logged in')); console.log(chalk.gray(' Run "mya login" to authenticate')); } console.log(chalk.blue('\n📊 Market Status:')); console.log(' ' + getMarketStatusMessage()); console.log(chalk.blue('\n🌐 API Configuration:')); console.log(chalk.gray(` Endpoint: ${API_BASE_URL}`)); console.log('\n' + chalk.green('✅ CLI is ready for use')); } catch (error) { console.error(chalk.red('Status check failed:'), error); } }); // Cache command program .command('cache') .description('Show cache status information') .action(async () => { console.log(chalk.blue('📊 Cache Status (CLI Version)')); console.log('═'.repeat(40)); console.log(chalk.gray('Cache management is handled by the backend service.')); console.log(chalk.gray(`Backend: ${API_BASE_URL}`)); console.log('\n' + chalk.green('✅ Cache is managed automatically')); }); program.parse();