MCPcopy Create free account
hub / github.com/github/gh-aw / parsePrettyPrintFormat

Function parsePrettyPrintFormat

actions/setup/js/parse_copilot_log.cjs:217–420  ·  view source on GitHub ↗

* Parses the "pretty-print" stdout format emitted by the Copilot CLI when * debug logs are written to a --log-dir directory (not captured on stdout). * This format uses ✗ for failed tool calls and ● or ✓ for successful ones. * @param {string} logContent - Raw log content as a string * @returns {

(logContent)

Source from the content-addressed store, hash-verified

215 * @returns {Array} Array of log entries in structured format, or empty array if not detected
216 */
217function parsePrettyPrintFormat(logContent) {
218 // Only attempt this format if the characteristic markers are present
219 if (!/^[✗●✓]/m.test(logContent)) {
220 return [];
221 }
222
223 const INFRA_LINE_RE = AWF_INFRA_LINE_RE;
224 const FAILED_TOOL_RE = /^✗\s+(\S+)/;
225 const SUCCESS_TOOL_RE = /^(?:●|✓)\s+(\S+)/;
226 const CONTINUATION_RE = /^\s+[└│]/;
227 const DEEP_INDENT_RE = /^ {4,}/;
228 const MODEL_BREAKDOWN_RE = /^Breakdown by AI model:/;
229 const MODEL_LINE_RE = /^ +(\S+)\s+([\d.]+k?)\s+in,\s+([\d.]+k?)\s+out(?:,\s+([\d.]+k?)\s+cached)?/;
230 // Recognise both legacy ("Total usage est:" / "API time spent:" / …) and the
231 // newer Copilot CLI footer ("Changes +N -N", "Duration Ns", "Tokens ↑N ↓N (cached)").
232 // The newer footer omits a colon and uses arrow glyphs, so we extend the regex rather than
233 // relying on the legacy "Total …:" prefix alone.
234 const USAGE_LINES_RE = /^(?:Total usage est:|API time spent:|Total session time:|Total code changes:|Changes\s+[+-]?\d|Duration\s+\d|Tokens\s+[↑↓])/;
235
236 const parseTokenCount = s => {
237 const n = parseFloat(s);
238 return s.endsWith("k") ? Math.round(n * 1000) : n;
239 };
240
241 const lines = logContent.split("\n").filter(line => !INFRA_LINE_RE.test(line));
242
243 const toolEntries = [];
244 const agentTextLines = [];
245 let inputTokens = 0;
246 let outputTokens = 0;
247 let cacheReadTokens = 0;
248 let modelName = "unknown";
249 let inModelBreakdown = false;
250 let i = 0;
251
252 while (i < lines.length) {
253 const line = lines[i];
254 const trimmed = line.trim();
255
256 if (!trimmed) {
257 inModelBreakdown = false;
258 i++;
259 continue;
260 }
261
262 // Failed tool call: ✗ tool_name
263 const failedMatch = trimmed.match(FAILED_TOOL_RE);
264 if (failedMatch) {
265 inModelBreakdown = false;
266 const toolName = failedMatch[1];
267 const outputLines = [];
268 i++;
269 while (i < lines.length && (CONTINUATION_RE.test(lines[i]) || DEEP_INDENT_RE.test(lines[i]))) {
270 outputLines.push(lines[i].replace(/^\s*[└│]\s?/, "").replace(/^ {4}/, ""));
271 i++;
272 }
273 toolEntries.push({ name: toolName, success: false, output: outputLines.join("\n").trim() });
274 continue;

Callers 1

parseCopilotLogFunction · 0.85

Calls 1

parseTokenCountFunction · 0.85

Tested by

no test coverage detected