From 912e74500f2d687db07ab033658dc3ba55de91ce Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 21 Jun 2026 18:28:38 +0000 Subject: [PATCH] fix: parse text progress in job status --- scripts/src/jobs.ts | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/scripts/src/jobs.ts b/scripts/src/jobs.ts index cf38327b..fd6f8d21 100644 --- a/scripts/src/jobs.ts +++ b/scripts/src/jobs.ts @@ -553,13 +553,11 @@ const agentRunYamlLaneProgressEvents = [ ] as const; function hasAgentRunYamlLaneProgressEvents(text: string): boolean { - return agentRunYamlLaneProgressEvents.some(({ event }) => parseJsonLineEvents(text, event).length > 0); + return parseAgentRunYamlLaneProgressEvents(text).length > 0; } function summarizeAgentRunYamlLaneTriggerJobProgress(job: JobRecord, stdoutTail: string, stderrTail: string, nowMs = Date.now()): JobProgressSummary { - const events = agentRunYamlLaneProgressEvents - .flatMap(({ event, stage }) => parseJsonLineEvents(stderrTail, event).map((item) => ({ ...item, stage }))) - .sort((left, right) => String(left.at ?? "").localeCompare(String(right.at ?? ""))); + const events = parseAgentRunYamlLaneProgressEvents(stderrTail); const lastEvent = events.at(-1) ?? {}; const stage = stringField(lastEvent.stage); const stageStatus = agentRunYamlLaneStageStatus(lastEvent); @@ -629,6 +627,45 @@ function summarizeAgentRunYamlLaneTriggerJobProgress(job: JobRecord, stdoutTail: }; } +function parseAgentRunYamlLaneProgressEvents(text: string): Record[] { + const eventToStage = new Map(agentRunYamlLaneProgressEvents.map((item) => [item.event, item.stage])); + const events: Record[] = []; + const lines = text.split(/\r?\n/u); + for (let index = 0; index < lines.length; index += 1) { + const line = lines[index]?.trim() ?? ""; + if (line.length === 0) continue; + if (line.startsWith("{")) { + try { + const parsed = JSON.parse(line) as unknown; + if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) { + const record = parsed as Record; + const event = typeof record.event === "string" ? record.event : null; + const stage = event === null ? null : eventToStage.get(event) ?? null; + if (event !== null && stage !== null) events.push({ ...record, stage, __order: index }); + } + } catch { + // Ignore non-JSON progress noise; raw tails remain visible. + } + continue; + } + const match = line.match(/^status\s+(agentrun\.yaml-lane\.[a-z-]+\.progress)\s+([a-z-]+)(?:\s+(.*))?$/u); + if (!match) continue; + const event = match[1]!; + const stage = eventToStage.get(event); + if (stage === undefined) continue; + const payload: Record = { event, stage, status: match[2]!, __order: index }; + for (const token of (match[3] ?? "").split(/\s+/u).filter(Boolean)) { + const tokenMatch = token.match(/^([A-Za-z][A-Za-z0-9_]*)=(.+)$/u); + if (!tokenMatch) continue; + const key = tokenMatch[1]!; + const value = tokenMatch[2]!; + payload[key] = /^-?\d+$/u.test(value) ? Number(value) : value; + } + events.push(payload); + } + return events.sort((left, right) => Number(left.__order ?? 0) - Number(right.__order ?? 0)); +} + function agentRunYamlLaneStageStatus(event: Record): string | null { const explicitStatus = stringField(event.status); if (explicitStatus !== null) return explicitStatus;