* Bootstrap helper for log parser entry points. * Handles common logic for environment variable lookup, file existence checks, * content reading (file or directory), and summary emission. * * @param {Object} options - Configuration options * @param {function(string): string|{markdown: string, m
(options)
| 17 | * @returns {Promise<void>} |
| 18 | */ |
| 19 | async function runLogParser(options) { |
| 20 | const fs = require("fs"); |
| 21 | const path = require("path"); |
| 22 | const { parseLog, parserName, supportsDirectories = false } = options; |
| 23 | |
| 24 | /** |
| 25 | * Recursively searches a directory tree for the first events.jsonl file. |
| 26 | * This file is written by the Copilot CLI and contains structured session events. |
| 27 | * @param {string} dirPath - Directory to search |
| 28 | * @returns {string|null} Absolute path to events.jsonl, or null if not found |
| 29 | */ |
| 30 | function findEventsJsonlRecursive(dirPath) { |
| 31 | try { |
| 32 | const entries = fs.readdirSync(dirPath, { withFileTypes: true }); |
| 33 | for (const entry of entries) { |
| 34 | const fullPath = path.join(dirPath, entry.name); |
| 35 | if (entry.isDirectory()) { |
| 36 | const found = findEventsJsonlRecursive(fullPath); |
| 37 | if (found) return found; |
| 38 | } else if (entry.name === "events.jsonl") { |
| 39 | return fullPath; |
| 40 | } |
| 41 | } |
| 42 | } catch (e) { |
| 43 | // Ignore read errors (e.g. permission denied on subdirectories) |
| 44 | } |
| 45 | return null; |
| 46 | } |
| 47 | |
| 48 | /** |
| 49 | * Count valid JSONL entries from a safe outputs file. |
| 50 | * @param {string} content - Raw safe outputs JSONL content |
| 51 | * @returns {number} Number of valid entries |
| 52 | */ |
| 53 | function countSafeOutputEntries(content) { |
| 54 | if (!content || content.trim().length === 0) { |
| 55 | return 0; |
| 56 | } |
| 57 | |
| 58 | let count = 0; |
| 59 | const lines = content.trim().split(/\r?\n/); |
| 60 | for (const line of lines) { |
| 61 | const trimmedLine = line.trim(); |
| 62 | if (!trimmedLine) { |
| 63 | continue; |
| 64 | } |
| 65 | try { |
| 66 | JSON.parse(trimmedLine); |
| 67 | count++; |
| 68 | } catch (e) { |
| 69 | // Ignore invalid JSONL lines |
| 70 | } |
| 71 | } |
| 72 | return count; |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * Returns true if the log entries show the agent ran at least one turn. |
no test coverage detected