| 130 | } |
| 131 | |
| 132 | private async getSpecsData(openspecDir: string): Promise<Array<{ name: string; requirementCount: number }>> { |
| 133 | const specsDir = path.join(openspecDir, 'specs'); |
| 134 | |
| 135 | if (!fs.existsSync(specsDir)) { |
| 136 | return []; |
| 137 | } |
| 138 | |
| 139 | const specs: Array<{ name: string; requirementCount: number }> = []; |
| 140 | const entries = fs.readdirSync(specsDir, { withFileTypes: true }); |
| 141 | |
| 142 | for (const entry of entries) { |
| 143 | if (entry.isDirectory()) { |
| 144 | const specFile = path.join(specsDir, entry.name, 'spec.md'); |
| 145 | |
| 146 | if (fs.existsSync(specFile)) { |
| 147 | try { |
| 148 | const content = fs.readFileSync(specFile, 'utf-8'); |
| 149 | const parser = new MarkdownParser(content); |
| 150 | const spec = parser.parseSpec(entry.name); |
| 151 | const requirementCount = spec.requirements.length; |
| 152 | specs.push({ name: entry.name, requirementCount }); |
| 153 | } catch (error) { |
| 154 | // If spec cannot be parsed, include with 0 count |
| 155 | specs.push({ name: entry.name, requirementCount: 0 }); |
| 156 | } |
| 157 | } |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | return specs; |
| 162 | } |
| 163 | |
| 164 | private displaySummary( |
| 165 | changesData: { draft: any[]; active: any[]; completed: any[] }, |