UNPKG

claude-code-tamagotchi

Version:

A virtual pet that lives in your Claude Code statusline

158 lines (137 loc) 5.67 kB
import * as dotenv from 'dotenv'; import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; // Load .env file const envPath = path.join(__dirname, '../../.env'); if (fs.existsSync(envPath)) { dotenv.config({ path: envPath }); } // Helper to resolve tilde in paths function resolvePath(filepath: string): string { if (filepath.startsWith('~')) { return path.join(os.homedir(), filepath.slice(1)); } return filepath; } export interface Config { // Pet settings petName: string; petType: 'dog' | 'cat' | 'dragon' | 'robot'; petColor: string; // Animation animationSpeed: number; enableBlinking: boolean; idleAnimationChance: number; walkingAnimationChance: number; // Environment weather: 'sunny' | 'rainy' | 'snowy' | 'cloudy'; season: 'spring' | 'summer' | 'fall' | 'winter'; // Decay rates (per minute) hungerDecayRate: number; happinessDecayRate: number; energyDecayRate: number; cleanlinessDecayRate: number; // Features enableEvolution: boolean; enableAccessories: boolean; enableSounds: boolean; enableWeatherEffects: boolean; // Thought system conversationThoughtRatio: number; // Feedback system feedbackEnabled: boolean; feedbackMode: 'full' | 'passive' | 'off'; feedbackCheckInterval: number; feedbackBatchSize: number; feedbackMinMessages: number; feedbackStaleLockTime: number; feedbackDbPath: string; feedbackDbMaxSize: number; groqApiKey?: string; groqModel: string; groqTimeout: number; groqMaxRetries: number; moodDecayRate: number; annoyedThreshold: number; angryThreshold: number; furiousThreshold: number; praiseBoost: number; feedbackIconStyle: 'emoji' | 'ascii' | 'minimal'; feedbackRemarkLength: number; showComplianceScore: boolean; feedbackMaxHistory: number; // Paths stateFile: string; actionFile: string; logFile: string; // Debug debugMode: boolean; verboseLogging: boolean; enableLogging: boolean; } export const config: Config = { // Pet settings petName: process.env.PET_NAME || 'Buddy', petType: (process.env.PET_TYPE as any) || 'dog', petColor: process.env.PET_COLOR || 'default', // Animation animationSpeed: parseInt(process.env.ANIMATION_SPEED || '300'), enableBlinking: process.env.ENABLE_BLINKING !== 'false', idleAnimationChance: parseFloat(process.env.IDLE_ANIMATION_CHANCE || '0.1'), walkingAnimationChance: parseFloat(process.env.WALKING_ANIMATION_CHANCE || '0.05'), // Environment weather: (process.env.WEATHER as any) || 'sunny', season: (process.env.SEASON as any) || 'spring', // Decay rates hungerDecayRate: parseFloat(process.env.HUNGER_DECAY_RATE || '0.5'), happinessDecayRate: parseFloat(process.env.HAPPINESS_DECAY_RATE || '0.2'), energyDecayRate: parseFloat(process.env.ENERGY_DECAY_RATE || '0.3'), cleanlinessDecayRate: parseFloat(process.env.CLEANLINESS_DECAY_RATE || '0.1'), // Features enableEvolution: process.env.ENABLE_EVOLUTION !== 'false', enableAccessories: process.env.ENABLE_ACCESSORIES !== 'false', enableSounds: process.env.ENABLE_SOUNDS === 'true', enableWeatherEffects: process.env.ENABLE_WEATHER_EFFECTS !== 'false', // Thought system conversationThoughtRatio: parseFloat(process.env.PET_CONVERSATION_THOUGHT_RATIO || '1.0'), // Feedback system feedbackEnabled: process.env.PET_FEEDBACK_ENABLED === 'true', feedbackMode: (process.env.PET_FEEDBACK_MODE as any) || 'full', feedbackCheckInterval: parseInt(process.env.PET_FEEDBACK_CHECK_INTERVAL || '5'), feedbackBatchSize: parseInt(process.env.PET_FEEDBACK_BATCH_SIZE || '10'), feedbackMinMessages: parseInt(process.env.PET_FEEDBACK_MIN_MESSAGES || '3'), feedbackStaleLockTime: parseInt(process.env.PET_FEEDBACK_STALE_LOCK_TIME || '30000'), feedbackDbPath: resolvePath(process.env.PET_FEEDBACK_DB_PATH || '~/.claude/pets/feedback.db'), feedbackDbMaxSize: parseInt(process.env.PET_FEEDBACK_DB_MAX_SIZE || '50'), groqApiKey: process.env.PET_GROQ_API_KEY || process.env.GROQ_API_KEY, groqModel: process.env.PET_GROQ_MODEL || 'openai/gpt-oss-20b', groqTimeout: parseInt(process.env.PET_GROQ_TIMEOUT || '2000'), groqMaxRetries: parseInt(process.env.PET_GROQ_MAX_RETRIES || '2'), moodDecayRate: parseInt(process.env.PET_MOOD_DECAY_RATE || '5'), annoyedThreshold: parseInt(process.env.PET_ANNOYED_THRESHOLD || '3'), angryThreshold: parseInt(process.env.PET_ANGRY_THRESHOLD || '5'), furiousThreshold: parseInt(process.env.PET_FURIOUS_THRESHOLD || '8'), praiseBoost: parseInt(process.env.PET_PRAISE_BOOST || '10'), feedbackIconStyle: (process.env.PET_FEEDBACK_ICON_STYLE as any) || 'emoji', feedbackRemarkLength: parseInt(process.env.PET_FEEDBACK_REMARK_LENGTH || '50'), showComplianceScore: process.env.PET_SHOW_COMPLIANCE_SCORE === 'true', feedbackMaxHistory: parseInt(process.env.PET_FEEDBACK_MAX_HISTORY || '200'), // Paths stateFile: resolvePath(process.env.PET_STATE_FILE || '~/.claude/pets/claude-pet-state.json'), actionFile: resolvePath(process.env.PET_ACTION_FILE || '/tmp/pet-action.json'), logFile: process.env.LOG_FILE || '/tmp/claude-pet.log', // Debug debugMode: process.env.DEBUG_MODE === 'true', verboseLogging: process.env.VERBOSE_LOGGING === 'true', enableLogging: process.env.ENABLE_LOGGING === 'true', // Off by default }; export function getWeatherEffects() { const effects = { sunny: { happiness: 0.1, energy: 0.2 }, rainy: { happiness: -0.1, cleanliness: -0.3 }, snowy: { energy: -0.2, happiness: 0.05 }, cloudy: { energy: -0.05, happiness: -0.05 } }; return effects[config.weather] || { happiness: 0, energy: 0 }; }