UNPKG

ctrlshiftleft

Version:

AI-powered toolkit for embedding QA and security testing into development workflows

71 lines (62 loc) 3.02 kB
import { Command } from 'commander'; import chalk from 'chalk'; import path from 'path'; import { Watcher } from '../core/watcher'; import { isValidSourcePath } from '../utils/fileUtils'; export function watchCommand(program: Command): void { program .command('watch') .description('Watch source files and auto-generate tests on changes') .argument('<source>', 'Source file or directory to watch') .option('-o, --output <directory>', 'Output directory for generated tests', './tests') .option('-i, --ignore <patterns>', 'Comma-separated glob patterns to ignore', 'node_modules,dist,build,*.test.*') .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '1000') .option('-r, --run-tests', 'Auto-run tests after generation', true) .option('-c, --generate-checklists', 'Generate security and QA checklists', true) .option('-s, --show-diffs', 'Show file diff when files change', true) .option('-b, --browser <browser>', 'Browser to use for tests', 'chromium') .option('--headless', 'Run tests in headless mode', true) .option('-w, --workers <count>', 'Number of parallel test workers', '1') .action(async (source: string, options) => { try { // Validate source path if (!await isValidSourcePath(source)) { console.error(chalk.red(`Invalid source path: ${source}`)); return; } const absoluteSourcePath = path.resolve(process.cwd(), source); const outputDir = path.resolve(process.cwd(), options.output); const ignorePatterns = options.ignore.split(',').map((pattern: string) => pattern.trim()); // Initialize watcher const watcher = new Watcher({ debounceMs: parseInt(options.delay, 10), ignorePatterns, runTests: options.runTests !== false, generateChecklists: options.generateChecklists !== false, showDiffs: options.showDiffs !== false, browser: options.browser, headless: options.headless !== false, workers: parseInt(options.workers, 10) }); console.log(chalk.blue(`Watching ${chalk.bold(source)} for changes...`)); console.log(chalk.gray(`Test output directory: ${outputDir}`)); console.log(chalk.gray(`Ignored patterns: ${ignorePatterns.join(', ')}`)); // Start watching await watcher.watch(absoluteSourcePath, outputDir); // Prevent the process from exiting process.stdin.resume(); // Handle graceful shutdown const shutdown = () => { console.log(chalk.yellow('\nStopping watcher...')); watcher.stop(); process.exit(0); }; process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown); } catch (error) { console.error(chalk.red(`Watch error: ${(error as Error).message}`)); console.error(chalk.red((error as Error).stack)); process.exit(1); } }); }