(targetPath: string = '.')
| 6 | |
| 7 | export class ViewCommand { |
| 8 | async execute(targetPath: string = '.'): Promise<void> { |
| 9 | const openspecDir = path.join(targetPath, 'openspec'); |
| 10 | |
| 11 | if (!fs.existsSync(openspecDir)) { |
| 12 | console.error(chalk.red('No openspec directory found')); |
| 13 | process.exit(1); |
| 14 | } |
| 15 | |
| 16 | console.log(chalk.bold('\nOpenSpec Dashboard\n')); |
| 17 | console.log('═'.repeat(60)); |
| 18 | |
| 19 | // Get changes and specs data |
| 20 | const changesData = await this.getChangesData(openspecDir); |
| 21 | const specsData = await this.getSpecsData(openspecDir); |
| 22 | |
| 23 | // Display summary metrics |
| 24 | this.displaySummary(changesData, specsData); |
| 25 | |
| 26 | // Display draft changes |
| 27 | if (changesData.draft.length > 0) { |
| 28 | console.log(chalk.bold.gray('\nDraft Changes')); |
| 29 | console.log('─'.repeat(60)); |
| 30 | changesData.draft.forEach((change) => { |
| 31 | console.log(` ${chalk.gray('○')} ${change.name}`); |
| 32 | }); |
| 33 | } |
| 34 | |
| 35 | // Display active changes |
| 36 | if (changesData.active.length > 0) { |
| 37 | console.log(chalk.bold.cyan('\nActive Changes')); |
| 38 | console.log('─'.repeat(60)); |
| 39 | changesData.active.forEach((change) => { |
| 40 | const progressBar = this.createProgressBar(change.progress.completed, change.progress.total); |
| 41 | const percentage = |
| 42 | change.progress.total > 0 |
| 43 | ? Math.round((change.progress.completed / change.progress.total) * 100) |
| 44 | : 0; |
| 45 | |
| 46 | console.log( |
| 47 | ` ${chalk.yellow('◉')} ${chalk.bold(change.name.padEnd(30))} ${progressBar} ${chalk.dim(`${percentage}%`)}` |
| 48 | ); |
| 49 | }); |
| 50 | } |
| 51 | |
| 52 | // Display completed changes |
| 53 | if (changesData.completed.length > 0) { |
| 54 | console.log(chalk.bold.green('\nCompleted Changes')); |
| 55 | console.log('─'.repeat(60)); |
| 56 | changesData.completed.forEach((change) => { |
| 57 | console.log(` ${chalk.green('✓')} ${change.name}`); |
| 58 | }); |
| 59 | } |
| 60 | |
| 61 | // Display specifications |
| 62 | if (specsData.length > 0) { |
| 63 | console.log(chalk.bold.blue('\nSpecifications')); |
| 64 | console.log('─'.repeat(60)); |
| 65 |
no test coverage detected