(filePath, opts = {})
| 14 | } |
| 15 | |
| 16 | function readJsonl(filePath, opts = {}) { |
| 17 | try { |
| 18 | if (!filePath || !fs.existsSync(filePath)) return []; |
| 19 | const raw = fs.readFileSync(filePath, 'utf8'); |
| 20 | const lines = raw.split('\n').map((line) => line.trim()).filter(Boolean); |
| 21 | const selected = opts.last ? lines.slice(-toPositiveInt(opts.last, lines.length)) : lines; |
| 22 | const rows = []; |
| 23 | for (const line of selected) { |
| 24 | try { |
| 25 | rows.push(JSON.parse(line)); |
| 26 | } catch { |
| 27 | // Corrupt JSONL rows should not break the dashboard. |
| 28 | } |
| 29 | } |
| 30 | return rows; |
| 31 | } catch { |
| 32 | return []; |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | function tailText(filePath, maxLines) { |
| 37 | try { |
no test coverage detected