UNPKG

@commit451/salamander

Version:

Never be AFK

132 lines 4.92 kB
#!/usr/bin/env node import { Command } from 'commander'; import chalk from 'chalk'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { AuthService } from './services/auth.js'; import { ConfigService } from './services/config.js'; import { runnerSelectionFlow } from './commands/runner-selection.js'; import { createRunnerFlow } from './commands/create-runner.js'; import { deleteRunnerFlow } from './commands/delete-runner.js'; import { isVersionOutdated } from './utils/version.js'; import { generateDeviceId } from './utils/device.js'; const __dirname = dirname(fileURLToPath(import.meta.url)); const packageJsonPath = join(__dirname, '..', 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const CURRENT_VERSION = packageJson.version; const program = new Command(); program .name('salamander') .description('Salamander AI Runner CLI - Execute AI commands in your local environment') .version(CURRENT_VERSION); program .command('start') .description('Start the runner selection interface') .action(async () => { await initializeAndRun(runnerSelectionFlow); }); program .command('create') .description('Create a new runner') .action(async () => { await initializeAndRun(createRunnerFlow); }); program .command('delete') .description('Delete an existing runner') .action(async () => { await initializeAndRun(deleteRunnerFlow); }); program .command('logout') .description('Sign out from Salamander') .action(async () => { try { await AuthService.initialize(); if (AuthService.isAuthenticated) { await AuthService.signOut(); } else { console.log(chalk.yellow('⚠️ You are not currently signed in')); } } catch (error) { console.error(chalk.red('❌ Error during logout:'), error.message); process.exit(1); } }); // Default action - if no command is specified, run the main flow program.action(async () => { await initializeAndRun(runnerSelectionFlow); }); async function checkVersionAndPromptUpdate() { try { const minBuildVersion = ConfigService.getMinBuildCLI().toString(); if (isVersionOutdated(CURRENT_VERSION, minBuildVersion)) { console.log(chalk.yellow('⚠️ Update Required')); console.log(chalk.yellow(`Your CLI version (${CURRENT_VERSION}) is outdated.`)); console.log(chalk.yellow(`Minimum required version: ${minBuildVersion}`)); console.log(''); console.log(chalk.blue('Please run: npm install -g salamander-cli@latest')); process.exit(1); } } catch (error) { // If version check fails, log warning but continue console.log(chalk.yellow('⚠️ Could not check for updates')); } } async function initializeAndRun(action) { try { console.log(chalk.blue('🦎 Salamander CLI')); console.log(chalk.gray('Initializing...')); // Fetch global configuration first await ConfigService.fetchConfig(); console.log(chalk.gray('✓ Global config loaded')); // Print machine ID for debugging const machineId = generateDeviceId(); console.log(chalk.gray(`🖥️ Machine ID: ${machineId}`)); // Check if app is disabled if (ConfigService.isAppDisabled()) { console.log(chalk.red('❌ Salamander CLI is currently disabled. Please try again later.')); process.exit(1); } // Check version and prompt for update if needed await checkVersionAndPromptUpdate(); // Initialize Firebase Auth await AuthService.initialize(); // Check if user is authenticated if (!AuthService.isAuthenticated) { const success = await AuthService.loginFlow(); if (!success) { console.log(chalk.red('Authentication failed. Exiting...')); process.exit(1); } } else { const userEmail = AuthService.user?.email || 'Unknown user'; console.log(chalk.green(`✅ Signed in as: ${userEmail}`)); } // Run the specified action await action(); } catch (error) { console.error(chalk.red('❌ An error occurred:'), error.message); if (error.stack) { console.error(chalk.gray(error.stack)); } process.exit(1); } } // Export default function for the bin script export default function main() { program.parse(); } // If this file is run directly (not imported), execute main if (import.meta.url.endsWith(process.argv[1]?.replace(/\\/g, '/') || '') || process.argv[1]?.includes('src/index.ts') || process.argv[1]?.includes('src\\index.ts')) { main(); } //# sourceMappingURL=index.js.map