(projectRoot)
| 156 | } |
| 157 | |
| 158 | function detectEol(content) { |
| 159 | return content.includes('\r\n') ? '\r\n' : '\n'; |
| 160 | } |
| 161 | |
| 162 | function detectIndent(content, beginMarker) { |
| 163 | const index = content.indexOf(beginMarker); |
| 164 | if (index === -1) return ''; |
| 165 | const lineStart = content.lastIndexOf('\n', index) + 1; |
| 166 | return content.slice(lineStart, index); |
| 167 | } |
| 168 | |
| 169 | function replaceBlock(content, markers, bodyLines, label) { |
| 170 | const beginIndex = content.indexOf(markers.begin); |
| 171 | const endIndex = content.indexOf(markers.end); |
| 172 | if (beginIndex === -1 || endIndex === -1 || endIndex < beginIndex) { |
| 173 | throw new Error(`markers not found in ${label}: ${markers.begin} ... ${markers.end}`); |
| 174 | } |
| 175 | const eol = detectEol(content); |
| 176 | const indent = detectIndent(content, markers.begin); |
| 177 | const blockStart = beginIndex + markers.begin.length; |
| 178 | const body = bodyLines.map((line) => (line ? indent + line : line)).join(eol); |
| 179 | return content.slice(0, blockStart) + eol + body + eol + indent + content.slice(endIndex); |
| 180 | } |
| 181 | |
| 182 | function surfacePaths(projectRoot) { |
| 183 | return { |
| 184 | json: path.join(projectRoot, 'core', 'skills', 'routing-table.json'), |
| 185 | skillTable: path.join(projectRoot, 'skills', 'do', 'SKILL.md'), |
| 186 | demoData: path.join(projectRoot, 'docs', 'index.html'), |
| 187 | }; |
| 188 | } |
| 189 | |
| 190 | function expectedSurfaces(projectRoot) { |
| 191 | const table = buildRoutingTable(projectRoot); |
| 192 | const paths = surfacePaths(projectRoot); |
| 193 | const skillContent = fs.readFileSync(paths.skillTable, 'utf8'); |
no test coverage detected