UNPKG

@codejoy/terminal-pet

Version:

A virtual pet that lives in your terminal and grows with your coding activity

354 lines (299 loc) • 10.6 kB
#!/usr/bin/env node const { Command } = require('commander'); const inquirer = require('inquirer'); const figlet = require('figlet'); const chalk = require('chalk'); const Pet = require('../lib/Pet'); const PetDisplay = require('../lib/PetDisplay'); const GitIntegration = require('../lib/GitIntegration'); const program = new Command(); const git = new GitIntegration(); program .name('pet') .description('A virtual pet that lives in your terminal') .version('1.0.0'); // Main status command program .command('status') .description('View your pet\'s current status') .action(async () => { const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" to get your first pet.', 'warning')); return; } if (!pet.isAlive) { console.log(PetDisplay.displayMessage('Your pet has died! šŸ’€ Use "pet adopt" to get a new one.', 'error')); console.log(PetDisplay.displayPet(pet)); return; } console.log(PetDisplay.displayPet(pet)); // Show git integration status const isGitRepo = await git.isGitRepository(); if (isGitRepo) { const todaysCommits = await git.getTodaysCommits(); console.log(PetDisplay.displayMessage(`Today's commits: ${todaysCommits}`, 'info')); } else { console.log(PetDisplay.displayMessage('Not in a git repository. Your pet won\'t get commit bonuses!', 'warning')); } }); // Feed command program .command('feed') .description('Feed your pet') .action(() => { const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" to get your first pet.', 'warning')); return; } if (!pet.isAlive) { console.log(PetDisplay.displayMessage('Your pet is dead and cannot be fed. šŸ’€', 'error')); return; } const success = pet.feed(); if (success) { console.log(PetDisplay.displayMessage(`${pet.name} enjoyed the meal! šŸ–`, 'success')); pet.save(); console.log(PetDisplay.displayPet(pet)); } else { console.log(PetDisplay.displayMessage('Something went wrong while feeding your pet.', 'error')); } }); // Play command program .command('play') .description('Play with your pet') .action(() => { const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" to get your first pet.', 'warning')); return; } if (!pet.isAlive) { console.log(PetDisplay.displayMessage('Your pet is dead and cannot play. šŸ’€', 'error')); return; } const success = pet.play(); if (success) { console.log(PetDisplay.displayMessage(`${pet.name} had fun playing! šŸŽ¾`, 'success')); pet.save(); console.log(PetDisplay.displayPet(pet)); } else { console.log(PetDisplay.displayMessage(`${pet.name} is too tired to play. Let them sleep first! 😓`, 'warning')); } }); // Sleep command program .command('sleep') .description('Let your pet sleep and recover energy') .action(() => { const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" to get your first pet.', 'warning')); return; } if (!pet.isAlive) { console.log(PetDisplay.displayMessage('Your pet is dead and cannot sleep. šŸ’€', 'error')); return; } const success = pet.sleep(); if (success) { console.log(PetDisplay.displayMessage(`${pet.name} had a refreshing nap! 😓`, 'success')); pet.save(); console.log(PetDisplay.displayPet(pet)); } else { console.log(PetDisplay.displayMessage('Something went wrong while your pet was sleeping.', 'error')); } }); // Stats command program .command('stats') .description('View detailed stats and achievements') .action(async () => { const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" to get your first pet.', 'warning')); return; } console.log(PetDisplay.displayStats(pet)); // Show git stats if available const isGitRepo = await git.isGitRepository(); if (isGitRepo) { const analysis = await git.analyzeCommitActivity(); if (analysis) { console.log(chalk.bold.cyan('\nšŸ“ˆ Git Activity Analysis')); console.log(chalk.gray('Recent Commits:'), chalk.green(analysis.totalCommits)); console.log(chalk.gray('Bug Fixes:'), chalk.red(analysis.bugFixes)); console.log(chalk.gray('Features:'), chalk.blue(analysis.features)); console.log(chalk.gray('Refactors:'), chalk.yellow(analysis.refactors)); console.log(chalk.gray('Avg Message Length:'), chalk.white(analysis.averageMessageLength)); } } }); // Adopt command program .command('adopt') .description('Adopt a new pet (this will replace your current pet!)') .action(async () => { const existingPet = Pet.load(); if (existingPet && existingPet.isAlive) { const { confirm } = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: `This will replace your current pet "${existingPet.name}". Are you sure?`, default: false } ]); if (!confirm) { console.log(PetDisplay.displayMessage('Adoption cancelled.', 'info')); return; } } // Show adoption center const petTypes = ['cat', 'dog', 'dragon']; console.log(PetDisplay.displayAdoption(petTypes)); const { petType } = await inquirer.prompt([ { type: 'list', name: 'petType', message: 'Choose your pet type:', choices: petTypes.map((type, index) => ({ name: `${type.charAt(0).toUpperCase() + type.slice(1)}`, value: type })) } ]); const { petName } = await inquirer.prompt([ { type: 'input', name: 'petName', message: 'What would you like to name your pet?', default: 'CodeBuddy', validate: (input) => { if (input.trim().length === 0) { return 'Pet name cannot be empty!'; } if (input.length > 20) { return 'Pet name must be 20 characters or less!'; } return true; } } ]); // Create new pet Pet.reset(); const newPet = new Pet(petName.trim(), petType); newPet.save(); console.log(figlet.textSync('Welcome!', { horizontalLayout: 'full' })); console.log(PetDisplay.displayMessage(`šŸŽ‰ Congratulations! You've adopted ${petName}!`, 'success')); console.log(PetDisplay.displayPet(newPet)); // Offer to set up git hooks const isGitRepo = await git.isGitRepository(); if (isGitRepo) { const { setupHooks } = await inquirer.prompt([ { type: 'confirm', name: 'setupHooks', message: 'Would you like to set up git hooks so your pet gets fed automatically on commits?', default: true } ]); if (setupHooks) { const success = await git.setupGitHooks(newPet); if (success) { console.log(PetDisplay.displayMessage('Git hooks set up successfully! Your pet will now get rewards for commits! šŸŽ£', 'success')); } else { console.log(PetDisplay.displayMessage('Failed to set up git hooks. You can still feed your pet manually!', 'warning')); } } } console.log(PetDisplay.displayMessage('Use "pet help" to see all available commands!', 'info')); }); // Hidden commit command (called by git hooks) program .command('commit') .argument('[message]', 'commit message') .description('Handle commit event (internal use)') .action((message = '') => { const pet = Pet.load(); if (!pet || !pet.isAlive) { return; } const leveledUp = pet.checkLevelUp(); pet.onCommit(message); const newAchievements = pet.checkAchievements('commit'); pet.save(); // Show notifications if (leveledUp) { console.log(PetDisplay.displayLevelUp(pet)); } if (newAchievements.length > 0) { console.log(PetDisplay.displayNewAchievements(newAchievements)); } console.log(PetDisplay.displayMessage(`${pet.name} is happy about your commit! (+${10 + Math.min(pet.streak * 2, 20)} XP)`, 'success')); }); // Help command program .command('help') .description('Show help information') .action(() => { console.log(PetDisplay.displayHelp()); }); // Git integration commands program .command('git-setup') .description('Set up git hooks for automatic pet feeding') .action(async () => { const isGitRepo = await git.isGitRepository(); if (!isGitRepo) { console.log(PetDisplay.displayMessage('Not in a git repository!', 'error')); return; } const pet = Pet.load(); if (!pet) { console.log(PetDisplay.displayMessage('No pet found! Use "pet adopt" first.', 'warning')); return; } const success = await git.setupGitHooks(pet); if (success) { console.log(PetDisplay.displayMessage('Git hooks set up successfully! šŸŽ£', 'success')); } else { console.log(PetDisplay.displayMessage('Failed to set up git hooks.', 'error')); } }); program .command('git-remove') .description('Remove git hooks') .action(async () => { const success = await git.removeGitHooks(); if (success) { console.log(PetDisplay.displayMessage('Git hooks removed successfully.', 'success')); } else { console.log(PetDisplay.displayMessage('No terminal pet git hooks found.', 'info')); } }); // Default action when no command is provided program.action(() => { const pet = Pet.load(); if (!pet) { console.log(figlet.textSync('Terminal Pet', { horizontalLayout: 'full' })); console.log(PetDisplay.displayMessage('Welcome to Terminal Pet! 🐾', 'info')); console.log(PetDisplay.displayMessage('Use "pet adopt" to get your first pet!', 'info')); return; } // Show status by default program.commands.find(cmd => cmd.name() === 'status').action(); }); // Error handling program.on('command:*', () => { console.log(PetDisplay.displayMessage(`Unknown command: ${program.args.join(' ')}`, 'error')); console.log(PetDisplay.displayMessage('Use "pet help" to see available commands.', 'info')); }); // Parse command line arguments program.parse(); // If no arguments provided, show default action if (!process.argv.slice(2).length) { program.action(); }