Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/cli/asString.ts

This file was deleted.

9 changes: 9 additions & 0 deletions src/cli/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Vision } from '../core/types.js';

export const VISIONS: Vision[] = ['deuteranopia', 'protanopia', 'tritanopia'];

export const VISION_LABELS: Record<Vision, string> = {
deuteranopia: 'πŸ’š Deuteranopia',
protanopia: '❀️ Protanopia',
tritanopia: 'πŸ’™ Tritanopia'
};
64 changes: 64 additions & 0 deletions src/cli/help.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { bold, dim } from './utils/terminalStyles.js';

export function showHelp() {
console.log('🎨 Colbrush - Accessible Color Theme Generator');
console.log('');

console.log(`
${bold('USAGE')}
colbrush <command> [options]

${bold('COMMANDS')}
generate Generate color-blind accessible themes (default)
--doctor Run system diagnostics
--help Show this help message
--version Show version number

${bold('OPTIONS')}
--css=<path> Target CSS file (default: src/index.css)
--no-color Disable colored output
--json=<path> Save detailed report to JSON file

${bold('EXAMPLES')}
colbrush ${dim('# Generate themes for src/index.css')}
colbrush generate --css=./styles/main.css ${dim('# Custom CSS file')}
colbrush --doctor ${dim('# Check system health')}

${bold('SUPPORTED CSS')}
The tool processes CSS custom properties (CSS variables) in these formats:

${dim('/* @theme block */')}
@theme {
--color-primary-500: #7fe4c1; ${dim('/* Will generate color scale */')}
}

${bold('OUTPUT')}
Generated themes are automatically appended to your CSS file:
${dim('[data-theme="protanopia"] { ... }')}
${dim('[data-theme="deuteranopia"] { ... }')}
${dim('[data-theme="tritanopia"] { ... }')}

${bold('VISION TYPES')}
β€’ Protanopia - Red color blindness
β€’ Deuteranopia - Green color blindness
β€’ Tritanopia - Blue color blindness

${bold('INTEGRATION')}
After generation, use in your React app:

${dim('// 1. Import your CSS')}
import "./index.css"

${dim('// 2. Wrap with ThemeProvider')}
import { ThemeProvider } from "colbrush/client"
<ThemeProvider><App /></ThemeProvider>

${dim('// 3. Add theme switcher')}
import { ThemeSwitcher } from "colbrush/client"
<ThemeSwitcher />

${bold('LEARN MORE')}
πŸ“– Documentation: https://colbrush.site
⭐ GitHub: https://github.com/2025-OSDC/colbrush
`);
}
103 changes: 87 additions & 16 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,100 @@
import parseFlags from './parseFlags.js';
import { runThemeApply } from './runThemeApply.js';
import { createCliProgress } from './progress.js';
import { showHelp } from './help.js';

import fs from 'node:fs';
import path from 'node:path';

async function main() {
const flags = parseFlags();
const cmd = (flags._[0] ?? 'generate') as 'generate';
const cssPath = typeof flags.css === 'string' ? flags.css : 'src/index.css';
const progress = createCliProgress();
const startTime = Date.now();

try {
if (flags.version) {
const packagePath = path.join(process.cwd(), 'package.json');
if (fs.existsSync(packagePath)) {
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
console.log(`🎨 Colbrush v${packageJson.version}`);
} else {
console.log('🎨 Colbrush CLI');
}
process.exit(0);
}

if (cmd === 'generate') {
const progress = createCliProgress();
await runThemeApply(cssPath, progress);
process.exit(0);
}
if (flags.help) {
showHelp();
process.exit(0);
}

console.log(`Usage:
- colbrush generate [--css=src/index.css]
Extracts color variables from the CSS file and automatically generates color-blind themes,
then applies them to the same CSS file.
(Default path: src/index.css)
`);
if (flags.doctor) {
console.log('πŸ” Running diagnostics...');
console.log('βœ… System check complete');
process.exit(0);
}

const cmd = (flags._[0] ?? 'generate') as 'generate';
const cssPath = typeof flags.css === 'string' ? flags.css : 'src/index.css';
const jsonOutput = typeof flags.json === 'string' ? flags.json : null;

process.exit(1);
if (cmd === 'generate') {
console.log('🎨 Welcome to Colbrush!');
console.log(`πŸ“ Processing: ${cssPath}`);
console.log('🌈 Generating accessible color themes...');

// 파일 쑴재 확인
if (!fs.existsSync(cssPath)) {
throw new Error(`❌ CSS file not found: ${cssPath}\n\nSuggestions:\n β€’ Create the CSS file first\n β€’ Use --css to specify a different path`);
}

// 메인 처리
const result = await runThemeApply(cssPath, progress);

// JSON 좜λ ₯
if (jsonOutput) {
const reportData = {
input: cssPath,
timestamp: new Date().toISOString(),
variables: result.variables,
themes: result.themes,
performance: {
totalTime: (Date.now() - startTime) / 1000,
memoryUsage: `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(1)}MB`
},
exitCode: 0
};

fs.writeFileSync(jsonOutput, JSON.stringify(reportData, null, 2));
console.log(`πŸ“„ Report saved to ${jsonOutput}`);
}

// 성곡 λ©”μ‹œμ§€
console.log('πŸŽ‰ All themes generated successfully!');

process.exit(0);
}

// μ•Œ 수 μ—†λŠ” λͺ…λ Ήμ–΄
throw new Error(`❌ Unknown command: ${cmd}\n\nSuggestions:\n β€’ Try: colbrush generate\n β€’ Run: colbrush --help for usage info`);

} catch (error) {
console.error('❌ CLI failed:', error instanceof Error ? error.message : String(error));
process.exit(1);
}
}

main().catch((e) => {
console.error('❌ CLI failed:', e);
// μ—λŸ¬ 핸듀링
process.on('uncaughtException', (error) => {
console.error('πŸ’₯ Unexpected error occurred');
console.error(error);
process.exit(1);
});

process.on('unhandledRejection', (reason) => {
console.error('πŸ’₯ Unhandled promise rejection');
console.error(reason);
process.exit(1);
});

main();
9 changes: 0 additions & 9 deletions src/cli/loadPayload.ts

This file was deleted.

Loading