feat: add web probe performance hotspot analysis

This commit is contained in:
Codex
2026-07-02 07:10:21 +00:00
parent bcaff08ad7
commit 88024dd251
30 changed files with 12674 additions and 11614 deletions
+2
View File
@@ -158,6 +158,7 @@ export type NodeWebProbeObserveCommandType =
| "deleteMdtodoTask"
| "launchWorkbenchFromTask"
| "launchWorkbenchFromMdtodo"
| "performanceCapture"
| "screenshot"
| "mark"
| "stop";
@@ -214,6 +215,7 @@ export interface NodeWebProbeObserveOptions {
commandAlternateSessionStrategy: string | null;
commandExpectedSentinelRange: string | null;
commandExpectedActionWaitMs: number | null;
commandDurationMs: number | null;
commandRequireComposerReady: boolean;
commandWaitProjectManagementReady: boolean;
commandFindingId: string | null;
@@ -18,7 +18,14 @@ const alertThresholds = {
domEvaluateTimeoutRedWindowMs: 60000,
screenshotTimeoutRedCount: 99,
pageErrorRedCount: 99,
longTaskRedMs: 60000,
longAnimationFrameRedMs: 60000,
eventLoopGapRedMs: 60000,
browserProcessSampleIntervalMs: 1000,
requestRateBucketMs: 10000,
requestRateTotalRedPerMinute: 999999,
requestRatePageRedPerMinute: 999999,
requestRateApiPathRedPerMinute: 999999,
browserTotalRssRedMb: 999999,
browserProcessRssRedMb: 999999,
browserRssGrowthRedMb: 999999,
@@ -394,6 +394,7 @@ export function commandSummaryForOutput(payload: Record<string, unknown>): Recor
label: payload.label ?? null,
sessionId: payload.sessionId ?? null,
provider: payload.provider ?? null,
durationMs: payload.durationMs ?? null,
sourceId: opaque(payload.sourceId),
fileRef: opaque(payload.fileRef),
taskRef: opaque(payload.taskRef),
+30 -3
View File
@@ -271,6 +271,7 @@ export function parseNodeWebProbeObserveOptions(
"--alternate-session-strategy",
"--expected-sentinel-range",
"--expected-action-wait-ms",
"--duration-ms",
"--finding-id",
"--source-id",
"--file-ref",
@@ -369,6 +370,11 @@ export function parseNodeWebProbeObserveOptions(
if (commandExpectedActionWaitMs !== null && (!Number.isInteger(commandExpectedActionWaitMs) || commandExpectedActionWaitMs < 1000 || commandExpectedActionWaitMs > 600000)) {
throw new Error("unsafe web-probe observe --expected-action-wait-ms: expected integer 1000-600000");
}
const commandDurationMsRaw = optionValue(args, "--duration-ms") ?? null;
const commandDurationMs = commandDurationMsRaw === null ? null : Number(commandDurationMsRaw);
if (commandDurationMs !== null && (!Number.isInteger(commandDurationMs) || commandDurationMs < 100 || commandDurationMs > 600000)) {
throw new Error("unsafe web-probe observe --duration-ms: expected integer 100-600000");
}
const commandFindingId = optionValue(args, "--finding-id") ?? null;
const commandBlocking = args.includes("--blocking") ? true : args.includes("--non-blocking") ? false : null;
for (const [label, value] of [
@@ -448,6 +454,7 @@ export function parseNodeWebProbeObserveOptions(
commandAlternateSessionStrategy,
commandExpectedSentinelRange,
commandExpectedActionWaitMs,
commandDurationMs,
commandRequireComposerReady: args.includes("--require-composer-ready"),
commandWaitProjectManagementReady: args.includes("--wait-project-management-ready"),
commandFindingId,
@@ -513,11 +520,12 @@ export function parseNodeWebProbeObserveCommandType(value: string): NodeWebProbe
|| value === "deleteMdtodoTask"
|| value === "launchWorkbenchFromTask"
|| value === "launchWorkbenchFromMdtodo"
|| value === "performanceCapture"
|| value === "screenshot"
|| value === "mark"
|| value === "stop"
) return value;
throw new Error(`web-probe observe command --type must be login, loginAccount, logout, listSessions, switchSessions, preflight, goto, gotoProjectMdtodo, newSession, sendPrompt, steer, cancel, selectProvider, clickSession, refreshCurrentSession, switchAwayAndBack, assertSessionInvariant, selectProjectSource, selectMdtodoSource, selectMdtodoFile, selectMdtodoTask, expandMdtodoTask, openMdtodoReportPreview, toggleMdtodoReportFullscreen, openMdtodoSourceConfig, closeMdtodoSourceConfig, configureMdtodoHwpodSource, probeMdtodoSource, reindexMdtodoSource, editMdtodoTaskInline, editMdtodoTaskTitle, editMdtodoTaskBody, toggleMdtodoTaskStatus, addMdtodoRootTask, addMdtodoSubTask, continueMdtodoTask, deleteMdtodoTask, launchWorkbenchFromTask, launchWorkbenchFromMdtodo, screenshot, mark, or stop; got ${value}`);
throw new Error(`web-probe observe command --type must be login, loginAccount, logout, listSessions, switchSessions, preflight, goto, gotoProjectMdtodo, newSession, sendPrompt, steer, cancel, selectProvider, clickSession, refreshCurrentSession, switchAwayAndBack, assertSessionInvariant, selectProjectSource, selectMdtodoSource, selectMdtodoFile, selectMdtodoTask, expandMdtodoTask, openMdtodoReportPreview, toggleMdtodoReportFullscreen, openMdtodoSourceConfig, closeMdtodoSourceConfig, configureMdtodoHwpodSource, probeMdtodoSource, reindexMdtodoSource, editMdtodoTaskInline, editMdtodoTaskTitle, editMdtodoTaskBody, toggleMdtodoTaskStatus, addMdtodoRootTask, addMdtodoSubTask, continueMdtodoTask, deleteMdtodoTask, launchWorkbenchFromTask, launchWorkbenchFromMdtodo, performanceCapture, screenshot, mark, or stop; got ${value}`);
}
export function parseWebProbeBrowserProxyMode(value: string | undefined): WebProbeBrowserProxyMode {
@@ -1440,7 +1448,7 @@ const nodeId = process.argv[6];
const lane = process.argv[7];
const keepMs = keepHours * 60 * 60 * 1000;
const nowMs = Date.now();
const rawNames = ["samples.jsonl", "browser-process.jsonl", "network.jsonl", "console.jsonl", "artifacts.jsonl", "screenshots"];
const rawNames = ["samples.jsonl", "browser-process.jsonl", "network.jsonl", "console.jsonl", "artifacts.jsonl", "performance-events.jsonl", "screenshots", "performance"];
function jsonRead(file) {
try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return null; }
@@ -1895,6 +1903,7 @@ export function runNodeWebProbeObserveCommand(options: NodeWebProbeObserveOption
alternateSessionStrategy: options.commandAlternateSessionStrategy,
expectedSentinelRange: options.commandExpectedSentinelRange,
expectedActionWaitMs: options.commandExpectedActionWaitMs,
durationMs: options.commandDurationMs,
requireComposerReady: options.commandRequireComposerReady,
waitProjectManagementReady: options.commandWaitProjectManagementReady,
findingId: options.commandFindingId,
@@ -2167,6 +2176,7 @@ function compactObserveCollectForRaw(collect: Record<string, unknown> | null): R
anchor: observeRecord(collect.anchor),
window: observeRecord(collect.window),
counts: observeRecord(collect.counts),
summary: observeRecord(collect.summary),
...(rows === undefined ? {} : { rows }),
...(timelineRows === undefined ? {} : { timelineRows }),
renderedText: collectView === "timeline" || collectView === "workbench-triad" ? undefined : typeof collect.renderedText === "string" ? collect.renderedText : undefined,
@@ -2179,6 +2189,13 @@ function compactObserveCollectForRaw(collect: Record<string, unknown> | null): R
dom: observeRecord(collect.dom),
networkEvidence: collectView === "workbench-triad" ? slimNetworkEvidence(collect.networkEvidence) : observeRecord(collect.networkEvidence),
freeze: collectView === "workbench-triad" ? slimFreeze(collect.freeze) : observeRecord(collect.freeze),
profileHotspots: Array.isArray(collect.profileHotspots) ? collect.profileHotspots.slice(0, 8) : undefined,
profileStacks: Array.isArray(collect.profileStacks) ? collect.profileStacks.slice(0, 5) : undefined,
scriptHotspots: Array.isArray(collect.scriptHotspots) ? collect.scriptHotspots.slice(0, 8) : undefined,
longTasks: Array.isArray(collect.longTasks) ? collect.longTasks.slice(0, 8) : undefined,
longAnimationFrames: Array.isArray(collect.longAnimationFrames) ? collect.longAnimationFrames.slice(0, 8) : undefined,
eventLoopGaps: Array.isArray(collect.eventLoopGaps) ? collect.eventLoopGaps.slice(0, 8) : undefined,
captures: Array.isArray(collect.captures) ? collect.captures.slice(0, 8) : undefined,
findings: collectView === "workbench-triad" ? slimFindings : Array.isArray(collect.findings) ? collect.findings.slice(0, 8) : undefined,
valuesRedacted: true,
};
@@ -2327,6 +2344,9 @@ export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOption
"const requestRateCurve = slimRequestRateCurve(source?.requestRateCurve) || slimRequestRateCurve(sourceRequestRate) || slimRequestRateCurve(fullRecentWindow?.requestRate) || slimRequestRateCurve(fullSource?.requestRate);",
"const requestRateSummary = objectOrNull(requestRateCurve?.summary) || objectOrNull(sourceRequestRate?.summary) || sourceRequestRate || null;",
"const requestRatePeaks = takeHead(firstNonEmptyArray(source?.requestRatePeaks, requestRateCurve?.peaks, sourceRequestRate?.peaks, fullRecentWindow?.requestRate?.peaks, fullSource?.requestRate?.peaks), 12).map(slimRequestPeak);",
"const frontendPerformance = objectOrNull(source?.frontendPerformance) || objectOrNull(fullRecentWindow?.frontendPerformance) || objectOrNull(fullSource?.frontendPerformance) || null;",
"const frontendPerformanceSummary = objectOrNull(frontendPerformance?.summary) || frontendPerformance;",
"const frontendPerformanceHotspots = { scripts: takeHead(firstNonEmptyArray(source?.frontendPerformanceHotspots?.scripts, frontendPerformance?.scriptHotspots, fullRecentWindow?.frontendPerformance?.scriptHotspots, fullSource?.frontendPerformance?.scriptHotspots), 8), profileFunctions: takeHead(firstNonEmptyArray(source?.frontendPerformanceHotspots?.profileFunctions, frontendPerformance?.profileHotspots, fullRecentWindow?.frontendPerformance?.profileHotspots, fullSource?.frontendPerformance?.profileHotspots), 8), profileStacks: takeHead(firstNonEmptyArray(source?.frontendPerformanceHotspots?.profileStacks, frontendPerformance?.profileStacks, fullRecentWindow?.frontendPerformance?.profileStacks, fullSource?.frontendPerformance?.profileStacks), 5), valuesRedacted: true };",
"const runnerErrorsFromJsonl = readJsonlTail(reportJsonPath.replace(/\\/analysis\\/report\\.json$/u, '/errors.jsonl'), 8).filter((item) => item?.type === 'runner-error').map(slimRunnerErrorFromJsonl);",
"const compact = source ? {",
" ok: analyzerExit === 0,",
@@ -2342,6 +2362,8 @@ export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOption
" requestRate: requestRateSummary,",
" requestRateCurve,",
" requestRatePeaks,",
" frontendPerformance: frontendPerformanceSummary,",
" frontendPerformanceHotspots,",
" pagePerformanceSlowApi: takeHead(sourceSlowApi, 4).map(slimSlowApi),",
" archivePagePerformanceSlowApi: takeHead(archiveSlowApi, 8).map(slimSlowApi),",
" pagePerformanceSseStreams: takeHead(sourceSseStreams, 4).map((item) => ({ path: item?.path ?? item?.route ?? null, route: item?.route ?? null, sampleCount: item?.sampleCount ?? null, streamOpenSampleCount: item?.streamOpenSampleCount ?? null, streamOpenP95Ms: item?.streamOpenP95Ms ?? null, streamOpenMaxMs: item?.streamOpenMaxMs ?? null, streamOpenBudgetMs: item?.streamOpenBudgetMs ?? null, streamOpenOverBudgetCount: item?.streamOpenOverBudgetCount ?? null, streamOpenOverFiveSecondCount: item?.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item?.streamLifetimeOverFiveSecondCount ?? null })),",
@@ -2432,6 +2454,8 @@ export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOption
" requestRate: compact.requestRate ?? null,",
" requestRateCurve: compact.requestRateCurve ? { summary: compact.requestRateCurve.summary ?? null, buckets: Array.isArray(compact.requestRateCurve.buckets) ? compact.requestRateCurve.buckets.slice(-6) : [], pageCurves: Array.isArray(compact.requestRateCurve.pageCurves) ? compact.requestRateCurve.pageCurves.slice(0, 4).map((item) => ({ pageKey: item.pageKey ?? null, path: item.path ?? null, count: item.count ?? null, peakRequestPerMinute: item.peakRequestPerMinute ?? null, peakBucket: item.peakBucket ?? null, buckets: Array.isArray(item.buckets) ? item.buckets.slice(-6) : [] })) : [], apiPathCurves: Array.isArray(compact.requestRateCurve.apiPathCurves) ? compact.requestRateCurve.apiPathCurves.slice(0, 6).map((item) => ({ apiKey: item.apiKey ?? null, path: item.path ?? null, count: item.count ?? null, peakRequestPerMinute: item.peakRequestPerMinute ?? null, peakBucket: item.peakBucket ?? null, buckets: Array.isArray(item.buckets) ? item.buckets.slice(-6) : [] })) : [], valuesRedacted: true } : null,",
" requestRatePeaks: Array.isArray(compact.requestRatePeaks) ? compact.requestRatePeaks.slice(0, 6) : [],",
" frontendPerformance: compact.frontendPerformance ?? null,",
" frontendPerformanceHotspots: compact.frontendPerformanceHotspots ? { scripts: Array.isArray(compact.frontendPerformanceHotspots.scripts) ? compact.frontendPerformanceHotspots.scripts.slice(0, 6) : [], profileFunctions: Array.isArray(compact.frontendPerformanceHotspots.profileFunctions) ? compact.frontendPerformanceHotspots.profileFunctions.slice(0, 6) : [], profileStacks: Array.isArray(compact.frontendPerformanceHotspots.profileStacks) ? compact.frontendPerformanceHotspots.profileStacks.slice(0, 4) : [], valuesRedacted: true } : null,",
" projectManagement: compact.projectManagement ?? null,",
" promptNetwork: compact.promptNetwork ?? null,",
" toolFindings: Array.isArray(compact.toolFindings) ? compact.toolFindings.slice(0, 8) : [],",
@@ -2916,10 +2940,13 @@ export function recoverWebObserveAnalyzeFromArtifacts(options: NodeWebProbeObser
"const requestRateCurve = slimRequestRateCurve(source.requestRateCurve) || slimRequestRateCurve(source.requestRate) || slimRequestRateCurve(recent.requestRate);",
"const requestRateSummary = objectOrNull(requestRateCurve?.summary) || objectOrNull(source.requestRate?.summary) || objectOrNull(source.requestRate) || null;",
"const requestRatePeaks = arr(source.requestRatePeaks ?? requestRateCurve?.peaks ?? source.requestRate?.peaks ?? recent.requestRate?.peaks).slice(0, 12).map(slimRequestPeak);",
"const frontendPerformance = objectOrNull(source.frontendPerformance) || objectOrNull(recent.frontendPerformance) || null;",
"const frontendPerformanceSummary = objectOrNull(frontendPerformance?.summary) || frontendPerformance;",
"const frontendPerformanceHotspots = { scripts: arr(source.frontendPerformanceHotspots?.scripts ?? frontendPerformance?.scriptHotspots ?? recent.frontendPerformance?.scriptHotspots).slice(0, 8), profileFunctions: arr(source.frontendPerformanceHotspots?.profileFunctions ?? frontendPerformance?.profileHotspots ?? recent.frontendPerformance?.profileHotspots).slice(0, 8), profileStacks: arr(source.frontendPerformanceHotspots?.profileStacks ?? frontendPerformance?.profileStacks ?? recent.frontendPerformance?.profileStacks).slice(0, 5), valuesRedacted: true };",
"const archiveSummary = objectOrNull(source.archiveSummary) || {};",
"const archiveSampleMetrics = objectOrNull(archiveSummary.sampleMetrics) || objectOrNull(source.sampleMetrics?.summary) || objectOrNull(srcMetrics.summary) || {};",
"const slowApis = arr(source.pagePerformanceSlowApi).length > 0 ? arr(source.pagePerformanceSlowApi) : arr(pagePerformance.sameOriginApiByPath).filter((item) => Number(item?.overBudgetCount ?? item?.overFiveSecondCount ?? 0) > 0);",
"const compact = { ok: source.ok === true, command: source.command ?? 'web-probe-observe analyze', stateDir: source.stateDir ?? stateDir, jsonlScope: source.jsonlScope ?? null, alertThresholds: source.alertThresholds ?? null, counts: source.counts ?? null, archiveSummary: { ...archiveSummary, sampleMetrics: archiveSampleMetrics, pagePerformance: objectOrNull(archiveSummary.pagePerformance) || objectOrNull(pagePerformance.summary) || {}, runtimeAlerts: objectOrNull(archiveSummary.runtimeAlerts) || objectOrNull(runtimeAlerts.summary) || {}, browserProcess: objectOrNull(archiveSummary.browserProcess) || objectOrNull(browserProcess.summary) || {}, requestRate: objectOrNull(archiveSummary.requestRate) || requestRateSummary || {}, redFindings: arr(archiveSummary.redFindings).slice(0, 12).map(slimFinding) }, analysisWindow: source.analysisWindow ?? objectOrNull(recent.summary), sampleMetrics: compactMetrics(srcMetrics), pageProvenance: objectOrNull(source.pageProvenance?.summary) || source.pageProvenance ?? null, pagePerformance: objectOrNull(pagePerformance.summary) || pagePerformance, projectManagement: objectOrNull(source.projectManagement) || null, promptNetwork: objectOrNull(promptNetwork.summary) || promptNetwork, requestRate: requestRateSummary, requestRateCurve, requestRatePeaks, runtimeAlerts: objectOrNull(runtimeAlerts.summary) || runtimeAlerts, browserProcess: objectOrNull(browserProcess.summary) || browserProcess, runnerErrors: arr(source.runnerErrors).slice(-8), commandFailures: arr(source.commandFailures).slice(-8), commandState: objectOrNull(source.commandState) || null, toolFindings: arr(source.toolFindings).slice(0, 8).map(slimFinding), httpErrorGroups: arr(source.httpErrorGroups ?? runtimeAlerts.networkHttpErrorsByPath).slice(0, 8).map(slimGroup), requestFailedGroups: arr(source.requestFailedGroups ?? runtimeAlerts.networkRequestFailedByPath).slice(0, 8).map(slimGroup), domDiagnosticGroups: arr(source.domDiagnosticGroups ?? runtimeAlerts.domDiagnosticsByText).slice(0, 5).map(slimGroup), domDiagnosticSamples: arr(source.domDiagnosticSamples ?? runtimeAlerts.domDiagnostics).slice(0, 8).map(slimGroup), consoleAlertGroups: arr(source.consoleAlertGroups ?? runtimeAlerts.consoleAlertsByPath).slice(0, 8).map(slimGroup), consoleAlertSamples: arr(source.consoleAlertSamples ?? runtimeAlerts.consoleAlerts).slice(0, 8).map(slimGroup), turnTimingRecentUpdateJumps: arr(source.turnTimingRecentUpdateJumps ?? srcMetrics.turnTimingRecentUpdateSawtoothJumps).slice(0, 8), turnTimingElapsedZeroResets: arr(source.turnTimingElapsedZeroResets ?? srcMetrics.turnTimingElapsedZeroResets).slice(0, 8), turnTimingTotalElapsedForwardJumps: arr(source.turnTimingTotalElapsedForwardJumps ?? srcMetrics.turnTimingTotalElapsedForwardJumps).slice(0, 8), pagePerformanceSlowApi: slowApis.slice(0, 8).map(slimSlowApi), archivePagePerformanceSlowApi: arr(source.archivePagePerformanceSlowApi).slice(0, 8).map(slimSlowApi), pagePerformancePartialApi: arr(source.pagePerformancePartialApi).slice(0, 8), pagePerformanceSseStreams: arr(source.pagePerformanceSseStreams).slice(0, 8), findings: arr(source.findings).slice(0, 12).map(slimFinding), archiveRedFindings: arr(source.archiveRedFindings ?? archiveSummary.redFindings).slice(0, 12).map(slimFinding), reportJsonPath: source.reportJsonPath ?? reportJsonPath, reportJsonSha256: source.reportJsonSha256 ?? sha256(reportJsonPath), reportMdPath: source.reportMdPath ?? reportMdPath, reportMdSha256: source.reportMdSha256 ?? sha256(reportMdPath), analyzer: { ...(objectOrNull(source.analyzer) || {}), recoveredFrom: 'analysis-artifact-after-transport-timeout', stdoutPath, stderrPath, stdoutBytes: statSize(stdoutPath), stderrBytes: statSize(stderrPath), reportJsonBytes: statSize(reportJsonPath), reportMdBytes: statSize(reportMdPath), transportExitCode: Number(transportExitRaw), transportTimedOut: transportTimedOutRaw === 'true', valuesRedacted: true }, valuesRedacted: true };",
"const compact = { ok: source.ok === true, command: source.command ?? 'web-probe-observe analyze', stateDir: source.stateDir ?? stateDir, jsonlScope: source.jsonlScope ?? null, alertThresholds: source.alertThresholds ?? null, counts: source.counts ?? null, archiveSummary: { ...archiveSummary, sampleMetrics: archiveSampleMetrics, pagePerformance: objectOrNull(archiveSummary.pagePerformance) || objectOrNull(pagePerformance.summary) || {}, runtimeAlerts: objectOrNull(archiveSummary.runtimeAlerts) || objectOrNull(runtimeAlerts.summary) || {}, browserProcess: objectOrNull(archiveSummary.browserProcess) || objectOrNull(browserProcess.summary) || {}, requestRate: objectOrNull(archiveSummary.requestRate) || requestRateSummary || {}, frontendPerformance: objectOrNull(archiveSummary.frontendPerformance) || frontendPerformanceSummary || {}, redFindings: arr(archiveSummary.redFindings).slice(0, 12).map(slimFinding) }, analysisWindow: source.analysisWindow ?? objectOrNull(recent.summary), sampleMetrics: compactMetrics(srcMetrics), pageProvenance: objectOrNull(source.pageProvenance?.summary) || source.pageProvenance ?? null, pagePerformance: objectOrNull(pagePerformance.summary) || pagePerformance, projectManagement: objectOrNull(source.projectManagement) || null, promptNetwork: objectOrNull(promptNetwork.summary) || promptNetwork, requestRate: requestRateSummary, requestRateCurve, requestRatePeaks, frontendPerformance: frontendPerformanceSummary, frontendPerformanceHotspots, runtimeAlerts: objectOrNull(runtimeAlerts.summary) || runtimeAlerts, browserProcess: objectOrNull(browserProcess.summary) || browserProcess, runnerErrors: arr(source.runnerErrors).slice(-8), commandFailures: arr(source.commandFailures).slice(-8), commandState: objectOrNull(source.commandState) || null, toolFindings: arr(source.toolFindings).slice(0, 8).map(slimFinding), httpErrorGroups: arr(source.httpErrorGroups ?? runtimeAlerts.networkHttpErrorsByPath).slice(0, 8).map(slimGroup), requestFailedGroups: arr(source.requestFailedGroups ?? runtimeAlerts.networkRequestFailedByPath).slice(0, 8).map(slimGroup), domDiagnosticGroups: arr(source.domDiagnosticGroups ?? runtimeAlerts.domDiagnosticsByText).slice(0, 5).map(slimGroup), domDiagnosticSamples: arr(source.domDiagnosticSamples ?? runtimeAlerts.domDiagnostics).slice(0, 8).map(slimGroup), consoleAlertGroups: arr(source.consoleAlertGroups ?? runtimeAlerts.consoleAlertsByPath).slice(0, 8).map(slimGroup), consoleAlertSamples: arr(source.consoleAlertSamples ?? runtimeAlerts.consoleAlerts).slice(0, 8).map(slimGroup), turnTimingRecentUpdateJumps: arr(source.turnTimingRecentUpdateJumps ?? srcMetrics.turnTimingRecentUpdateSawtoothJumps).slice(0, 8), turnTimingElapsedZeroResets: arr(source.turnTimingElapsedZeroResets ?? srcMetrics.turnTimingElapsedZeroResets).slice(0, 8), turnTimingTotalElapsedForwardJumps: arr(source.turnTimingTotalElapsedForwardJumps ?? srcMetrics.turnTimingTotalElapsedForwardJumps).slice(0, 8), pagePerformanceSlowApi: slowApis.slice(0, 8).map(slimSlowApi), archivePagePerformanceSlowApi: arr(source.archivePagePerformanceSlowApi).slice(0, 8).map(slimSlowApi), pagePerformancePartialApi: arr(source.pagePerformancePartialApi).slice(0, 8), pagePerformanceSseStreams: arr(source.pagePerformanceSseStreams).slice(0, 8), findings: arr(source.findings).slice(0, 12).map(slimFinding), archiveRedFindings: arr(source.archiveRedFindings ?? archiveSummary.redFindings).slice(0, 12).map(slimFinding), reportJsonPath: source.reportJsonPath ?? reportJsonPath, reportJsonSha256: source.reportJsonSha256 ?? sha256(reportJsonPath), reportMdPath: source.reportMdPath ?? reportMdPath, reportMdSha256: source.reportMdSha256 ?? sha256(reportMdPath), analyzer: { ...(objectOrNull(source.analyzer) || {}), recoveredFrom: 'analysis-artifact-after-transport-timeout', stdoutPath, stderrPath, stdoutBytes: statSize(stdoutPath), stderrBytes: statSize(stderrPath), reportJsonBytes: statSize(reportJsonPath), reportMdBytes: statSize(reportMdPath), transportExitCode: Number(transportExitRaw), transportTimedOut: transportTimedOutRaw === 'true', valuesRedacted: true }, valuesRedacted: true };",
"console.log(JSON.stringify(compact));",
"UNIDESK_WEB_OBSERVE_RECOVER_ANALYZE_ARTIFACT",
].join("\n");