vibe-code-build
Version:
Real-time code monitoring with teaching explanations, CLAUDE.md compliance checking, and interactive chat
209 lines (189 loc) • 6.23 kB
JavaScript
import chalk from 'chalk';
import { readFile, writeFile } from 'fs/promises';
import path from 'path';
import os from 'os';
export class ThemeManager {
constructor() {
this.themes = {
dark: {
name: 'Dark Mode',
description: 'Classic dark theme (default)',
preview: '🌙 Standard terminal colors with good contrast',
colors: {
primary: chalk.cyan,
secondary: chalk.yellow,
success: chalk.green,
error: chalk.red,
warning: chalk.yellow,
info: chalk.blue,
muted: chalk.gray,
highlight: chalk.bold.cyan,
header: chalk.bold.yellow,
accent: chalk.magenta
}
},
blackBg: {
name: 'Black Background',
description: 'High contrast theme with pure black background',
preview: '⚫ Pure black background with bright colors',
colors: {
primary: chalk.cyanBright,
secondary: chalk.yellowBright,
success: chalk.greenBright,
error: chalk.redBright,
warning: chalk.yellowBright,
info: chalk.cyanBright, // Changed from blueBright to cyanBright for better readability
muted: chalk.white,
highlight: chalk.bold.cyanBright,
header: chalk.bold.yellowBright,
accent: chalk.magentaBright
}
},
light: {
name: 'Light Mode',
description: 'Clean and bright theme for well-lit environments',
preview: '☀️ Light theme with professional colors',
colors: {
primary: chalk.blue,
secondary: chalk.magenta,
success: chalk.green,
error: chalk.red,
warning: chalk.yellow,
info: chalk.cyan,
muted: chalk.gray,
highlight: chalk.bold.blue,
header: chalk.bold.magenta,
accent: chalk.cyan
}
},
neon: {
name: 'Neon',
description: 'Vibrant neon colors on dark background',
preview: '💜 Bright neon colors that pop',
colors: {
primary: chalk.hex('#00FFFF'),
secondary: chalk.hex('#FF00FF'),
success: chalk.hex('#00FF00'),
error: chalk.hex('#FF0066'),
warning: chalk.hex('#FFFF00'),
info: chalk.hex('#0099FF'),
muted: chalk.hex('#666666'),
highlight: chalk.bold.hex('#00FFFF'),
header: chalk.bold.hex('#FF00FF'),
accent: chalk.hex('#FF6600')
}
},
matrix: {
name: 'Matrix',
description: 'Green on black like the Matrix',
preview: '💊 Follow the white rabbit...',
colors: {
primary: chalk.green,
secondary: chalk.greenBright,
success: chalk.green,
error: chalk.redBright,
warning: chalk.yellowBright,
info: chalk.greenBright,
muted: chalk.green.dim,
highlight: chalk.bold.greenBright,
header: chalk.bold.greenBright,
accent: chalk.greenBright
}
}
};
this.currentTheme = 'dark';
this.themePath = path.join(os.homedir(), '.vibe-theme');
}
async loadTheme() {
try {
const savedTheme = await readFile(this.themePath, 'utf-8');
const trimmedTheme = savedTheme.trim();
if (this.themes[trimmedTheme]) {
this.currentTheme = trimmedTheme;
console.log(`Loaded theme: ${trimmedTheme}`);
} else {
// Theme no longer exists, fallback to dark
this.currentTheme = 'dark';
console.log('Theme no longer available, using dark mode');
await this.saveTheme(); // Save the fallback
}
} catch (error) {
// No saved theme, use default
this.currentTheme = 'dark';
console.log('Using default theme: dark');
}
}
async saveTheme() {
try {
await writeFile(this.themePath, this.currentTheme);
} catch (error) {
console.error('Failed to save theme preference:', error);
}
}
setTheme(themeName) {
if (this.themes[themeName]) {
this.currentTheme = themeName;
this.saveTheme();
return true;
}
return false;
}
getTheme() {
return this.themes[this.currentTheme];
}
getColors() {
return this.themes[this.currentTheme].colors;
}
getAllThemes() {
return Object.entries(this.themes).map(([key, theme]) => ({
key,
...theme,
active: key === this.currentTheme
}));
}
// Special effects for Matrix theme
async showMatrixRain(duration = 2000) {
if (this.currentTheme !== 'matrix') return;
const cols = process.stdout.columns;
const rows = process.stdout.rows;
const streams = Array(Math.floor(cols / 2)).fill(0);
const chars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン01';
console.clear();
const startTime = Date.now();
const interval = setInterval(() => {
if (Date.now() - startTime > duration) {
clearInterval(interval);
console.clear();
return;
}
// Move cursor to random position
streams.forEach((y, x) => {
if (Math.random() > 0.98 || y > rows) {
streams[x] = 0;
}
const char = chars[Math.floor(Math.random() * chars.length)];
process.stdout.cursorTo(x * 2, y);
if (y === streams[x]) {
process.stdout.write(chalk.greenBright(char));
} else {
process.stdout.write(chalk.green.dim(char));
}
if (streams[x] < rows) streams[x]++;
});
}, 50);
}
// Apply theme to text
style(text, colorType = 'primary') {
const colors = this.getColors();
return colors[colorType] ? colors[colorType](text) : text;
}
// Clear screen with theme-appropriate background
clearScreen() {
// Use standard clear for all themes
// The terminal's own background color will be used
console.clear();
process.stdout.write('\x1B[H'); // Move cursor to top
}
}
// Singleton instance
export const themeManager = new ThemeManager();