From 33edd267356e77af6adc50771dcc03e0aec4419b Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:09:12 +0800 Subject: [PATCH] fix: retain full-window web probe alert groups (#653) Co-authored-by: Codex --- scripts/src/hwlab-node-impl.ts | 58 ++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/scripts/src/hwlab-node-impl.ts b/scripts/src/hwlab-node-impl.ts index af04e834..ed3e10bb 100644 --- a/scripts/src/hwlab-node-impl.ts +++ b/scripts/src/hwlab-node-impl.ts @@ -7602,7 +7602,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec "const takeHead = (value, limit) => Array.isArray(value) ? value.slice(0, limit) : [];", "const takeTail = (value, limit) => Array.isArray(value) ? value.slice(-limit) : [];", "const firstArray = (...values) => { for (const value of values) if (Array.isArray(value)) return value; return []; };", - "const mergeArrays = (...values) => { const out = []; const seen = new Set(); for (const value of values) { if (!Array.isArray(value)) continue; for (const item of value) { const key = JSON.stringify([item?.id ?? item?.kind ?? item?.code ?? item?.columnLabel ?? item?.traceId ?? null, item?.summary ?? item?.message ?? item?.fromSeq ?? null, item?.toSeq ?? null]); if (seen.has(key)) continue; seen.add(key); out.push(item); } } return out; };", + "const mergeArrays = (...values) => { const out = []; const seen = new Set(); for (const value of values) { if (!Array.isArray(value)) continue; for (const item of value) { const key = JSON.stringify([item?.id ?? item?.kind ?? item?.code ?? item?.columnLabel ?? item?.traceId ?? null, item?.path ?? item?.urlPath ?? null, item?.method ?? null, item?.status ?? null, item?.summary ?? item?.message ?? item?.fromSeq ?? item?.firstAt ?? null, item?.toSeq ?? item?.lastAt ?? null]); if (seen.has(key)) continue; seen.add(key); out.push(item); } } return out; };", "const clip = (value, limit = 160) => value === null || value === undefined ? null : String(value).slice(0, limit);", "const findingRank = (item) => { const id = String(item?.id ?? item?.kind ?? item?.code ?? ''); if (id === 'page-performance-slow-same-origin-api') return 0; if (id.startsWith('turn-timing-total-elapsed')) return 1; if (id.startsWith('turn-timing-recent-update')) return 2; if (id.includes('runtime-execution') || id.includes('prompt-chat-submit-failed')) return 3; return 10; };", "const severityRank = (item) => { const severity = String(item?.severity ?? item?.level ?? '').toLowerCase(); if (severity === 'red') return 0; if (severity === 'amber' || severity === 'warning') return 1; if (severity === 'info') return 3; return 2; };", @@ -7618,10 +7618,10 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec "const slimSlowApi = (item) => { const v = objectOrNull(item) || {}; return { path: clip(v.path ?? v.route, 96), route: clip(v.route ?? v.path, 96), sampleCount: v.sampleCount ?? null, p95Ms: v.p95Ms ?? v.p95 ?? null, maxMs: v.maxMs ?? v.max ?? null, overFiveSecondCount: v.overFiveSecondCount ?? null, slowSamples: Array.isArray(v.slowSamples) ? v.slowSamples.slice(0, 3).map(slimSlowSample) : [] }; };", "const slimFinding = (item) => { const v = objectOrNull(item) || {}; return { kind: clip(v.kind ?? v.id ?? v.code, 48), code: clip(v.code ?? v.id ?? v.kind, 48), severity: clip(v.severity ?? v.level, 24), level: clip(v.level ?? v.severity, 24), count: v.count ?? v.sampleCount ?? null, sampleCount: v.sampleCount ?? v.count ?? null, summary: clip(v.summary ?? v.message, 180), message: clip(v.message ?? v.summary, 180) }; };", "const slimDomGroup = (item) => { const v = objectOrNull(item) || {}; return { count: v.count ?? null, firstAt: v.firstAt ?? null, lastAt: v.lastAt ?? null, text: clip(v.text ?? v.preview, 180) }; };", - "const slimNetworkGroup = (item) => { const v = objectOrNull(item) || {}; return { count: v.count ?? null, method: clip(v.method, 12), status: v.status ?? null, path: clip(v.path, 96), firstAt: v.firstAt ?? null, lastAt: v.lastAt ?? null, promptIndexes: Array.isArray(v.promptIndexes) ? v.promptIndexes.slice(0, 6) : [], failureKinds: Array.isArray(v.failureKinds) ? v.failureKinds.slice(0, 4).map((x) => clip(x, 48)) : [] }; };", + "const slimNetworkGroup = (item) => { const v = objectOrNull(item) || {}; return { count: v.count ?? null, method: clip(v.method, 12), status: v.status ?? null, path: clip(v.path ?? v.urlPath, 96), firstAt: v.firstAt ?? null, lastAt: v.lastAt ?? null, promptIndexes: Array.isArray(v.promptIndexes) ? v.promptIndexes.slice(0, 6) : [], failureKinds: Array.isArray(v.failureKinds) ? v.failureKinds.slice(0, 4).map((x) => clip(x, 48)) : [] }; };", "const slimDomSample = (item) => { const v = objectOrNull(item) || {}; return { seq: v.seq ?? null, ts: v.ts ?? null, source: clip(v.source, 32), diagnosticCode: clip(v.diagnosticCode, 48), traceId: clip(v.traceId, 64), httpStatus: v.httpStatus ?? null, idleSeconds: v.idleSeconds ?? null, waitingFor: clip(v.waitingFor, 48), lastEventLabel: clip(v.lastEventLabel, 80), text: clip(v.text ?? v.preview, 180) }; };", - "const slimConsoleGroup = (item) => { const v = objectOrNull(item) || {}; return { count: v.count ?? null, type: clip(v.type, 24), status: v.status ?? null, path: clip(v.path, 96), lastAt: v.lastAt ?? v.firstAt ?? null, firstAt: v.firstAt ?? null, traceIds: Array.isArray(v.traceIds) ? v.traceIds.slice(0, 3).map((x) => clip(x, 64)) : [] }; };", - "const slimConsoleSample = (item) => { const v = objectOrNull(item) || {}; return { ts: v.ts ?? null, type: clip(v.type, 24), status: v.status ?? null, path: clip(v.path, 96), traceId: clip(v.traceId, 64), text: clip(v.text, 180) }; };", + "const slimConsoleGroup = (item) => { const v = objectOrNull(item) || {}; return { count: v.count ?? null, type: clip(v.type, 24), status: v.status ?? null, path: clip(v.path ?? v.urlPath, 96), lastAt: v.lastAt ?? v.firstAt ?? null, firstAt: v.firstAt ?? null, traceIds: Array.isArray(v.traceIds) ? v.traceIds.slice(0, 3).map((x) => clip(x, 64)) : [] }; };", + "const slimConsoleSample = (item) => { const v = objectOrNull(item) || {}; return { ts: v.ts ?? null, type: clip(v.type, 24), status: v.status ?? null, path: clip(v.path ?? v.urlPath, 96), traceId: clip(v.traceId, 64), text: clip(v.text ?? v.preview, 180) }; };", "const slimRunnerError = (item) => { const v = objectOrNull(item) || {}; return { ts: v.ts ?? null, type: clip(v.type, 32), commandId: clip(v.commandId, 80), sampleSeq: v.sampleSeq ?? null, message: clip(v.message, 240), retry: clip(v.retry, 24), retryExhausted: v.retryExhausted === true, lastError: clip(v.lastError, 180) }; };", "const slimJump = (item) => { const v = objectOrNull(item) || {}; return { columnLabel: v.columnLabel ?? null, promptIndex: v.promptIndex ?? null, fromSeq: v.fromSeq ?? null, toSeq: v.toSeq ?? null, fromValue: v.fromValue ?? null, toValue: v.toValue ?? null, delta: v.delta ?? null, sampleDeltaSeconds: v.sampleDeltaSeconds ?? null, allowedIncreaseSeconds: v.allowedIncreaseSeconds ?? null, traceId: v.traceId ?? null }; };", "const srcMetrics = objectOrNull(source?.sampleMetrics);", @@ -7662,12 +7662,12 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec " promptNetwork,", " pagePerformanceSlowApi: takeHead(sourceSlowApi, 4).map(slimSlowApi),", " findings: takeHead(combinedFindings, 8).map(slimFinding),", - " httpErrorGroups: takeHead(firstArray(source.httpErrorGroups, fullSource?.httpErrorGroups), 4).map(slimNetworkGroup),", - " requestFailedGroups: takeHead(firstArray(source.requestFailedGroups, fullSource?.requestFailedGroups), 5).map(slimNetworkGroup),", - " domDiagnosticGroups: takeHead(firstArray(source.domDiagnosticGroups, fullSource?.domDiagnosticGroups), 3).map(slimDomGroup),", - " domDiagnosticSamples: takeHead(firstArray(source.domDiagnosticSamples, fullSource?.domDiagnosticSamples), 5).map(slimDomSample),", - " consoleAlertGroups: takeHead(firstArray(source.consoleAlertGroups, fullSource?.consoleAlertGroups), 5).map(slimConsoleGroup),", - " consoleAlertSamples: takeHead(firstArray(source.consoleAlertSamples, fullSource?.consoleAlertSamples), 5).map(slimConsoleSample),", + " httpErrorGroups: takeHead(mergeArrays(source.httpErrorGroups, fullSource?.httpErrorGroups, fullSource?.runtimeAlerts?.networkHttpErrorsByPath), 4).map(slimNetworkGroup),", + " requestFailedGroups: takeHead(mergeArrays(source.requestFailedGroups, fullSource?.requestFailedGroups, fullSource?.runtimeAlerts?.networkRequestFailedByPath), 5).map(slimNetworkGroup),", + " domDiagnosticGroups: takeHead(mergeArrays(source.domDiagnosticGroups, fullSource?.domDiagnosticGroups, fullSource?.runtimeAlerts?.domDiagnosticsByFingerprint), 3).map(slimDomGroup),", + " domDiagnosticSamples: takeHead(mergeArrays(source.domDiagnosticSamples, fullSource?.domDiagnosticSamples, fullSource?.runtimeAlerts?.domDiagnostics), 5).map(slimDomSample),", + " consoleAlertGroups: takeHead(mergeArrays(source.consoleAlertGroups, fullSource?.consoleAlertGroups, fullSource?.runtimeAlerts?.consoleAlertsByPath), 5).map(slimConsoleGroup),", + " consoleAlertSamples: takeHead(mergeArrays(source.consoleAlertSamples, fullSource?.consoleAlertSamples, fullSource?.runtimeAlerts?.consoleAlerts), 5).map(slimConsoleSample),", " runnerErrors: takeTail(firstArray(source.runnerErrors, fullSource?.runnerErrors), 8).map(slimRunnerError),", " turnTimingRecentUpdateJumps: takeHead(mergeArrays(source.turnTimingRecentUpdateJumps, srcMetrics?.turnTimingRecentUpdateJumps, fullSource?.sampleMetrics?.turnTimingRecentUpdateSawtoothJumps, fullSource?.turnTimingRecentUpdateJumps), 5).map(slimJump),", " turnTimingElapsedZeroResets: takeHead(mergeArrays(source.turnTimingElapsedZeroResets, srcMetrics?.turnTimingElapsedZeroResets, fullSource?.sampleMetrics?.turnTimingElapsedZeroResets, fullSource?.turnTimingElapsedZeroResets), 5).map(slimJump),", @@ -7723,6 +7723,12 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec " promptNetwork: compact.promptNetwork ?? null,", " findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],", " pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ ...item, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],", + " httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 3) : [],", + " requestFailedGroups: Array.isArray(compact.requestFailedGroups) ? compact.requestFailedGroups.slice(0, 3) : [],", + " domDiagnosticGroups: Array.isArray(compact.domDiagnosticGroups) ? compact.domDiagnosticGroups.slice(0, 2) : [],", + " domDiagnosticSamples: Array.isArray(compact.domDiagnosticSamples) ? compact.domDiagnosticSamples.slice(0, 2) : [],", + " consoleAlertGroups: Array.isArray(compact.consoleAlertGroups) ? compact.consoleAlertGroups.slice(0, 3) : [],", + " consoleAlertSamples: Array.isArray(compact.consoleAlertSamples) ? compact.consoleAlertSamples.slice(0, 2) : [],", " runnerErrors: Array.isArray(compact.runnerErrors) ? compact.runnerErrors.slice(-4) : [],", " turnTimingRecentUpdateJumps: Array.isArray(compact.turnTimingRecentUpdateJumps) ? compact.turnTimingRecentUpdateJumps.slice(0, 4) : [],", " turnTimingElapsedZeroResets: Array.isArray(compact.turnTimingElapsedZeroResets) ? compact.turnTimingElapsedZeroResets.slice(0, 4) : [],", @@ -7735,6 +7741,38 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec " valuesRedacted: true", " };", " output = compactOutput(minimal);", + " if (Buffer.byteLength(output, 'utf8') > compactStdoutLimitBytes) {", + " const tiny = {", + " ok: compact.ok,", + " counts: compact.counts ?? null,", + " analysisWindow: compact.analysisWindow ?? null,", + " archiveSummary: compact.archiveSummary ?? null,", + " sampleMetrics: compact.sampleMetrics ? {", + " turnTimingRows: compact.sampleMetrics.turnTimingRows ?? null,", + " turnTimingNonMonotonicCount: compact.sampleMetrics.turnTimingNonMonotonicCount ?? null,", + " turnTimingTotalElapsedDecreaseCount: compact.sampleMetrics.turnTimingTotalElapsedDecreaseCount ?? null,", + " turnTimingTotalElapsedForwardJumpCount: compact.sampleMetrics.turnTimingTotalElapsedForwardJumpCount ?? null,", + " turnTimingTerminalElapsedGrowthCount: compact.sampleMetrics.turnTimingTerminalElapsedGrowthCount ?? null,", + " turnTimingRecentUpdateJumpCount: compact.sampleMetrics.turnTimingRecentUpdateJumpCount ?? compact.sampleMetrics.turnTimingRecentUpdateSawtoothJumpCount ?? null", + " } : null,", + " runtimeAlerts: compact.runtimeAlerts ?? null,", + " pagePerformance: compact.pagePerformance ?? null,", + " findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],", + " pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? item.p95 ?? null, maxMs: item.maxMs ?? item.max ?? null, overFiveSecondCount: item.overFiveSecondCount ?? null, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],", + " httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 2) : [],", + " requestFailedGroups: Array.isArray(compact.requestFailedGroups) ? compact.requestFailedGroups.slice(0, 2) : [],", + " consoleAlertGroups: Array.isArray(compact.consoleAlertGroups) ? compact.consoleAlertGroups.slice(0, 2) : [],", + " turnTimingRecentUpdateJumps: Array.isArray(compact.turnTimingRecentUpdateJumps) ? compact.turnTimingRecentUpdateJumps.slice(0, 3) : [],", + " turnTimingTotalElapsedForwardJumps: Array.isArray(compact.turnTimingTotalElapsedForwardJumps) ? compact.turnTimingTotalElapsedForwardJumps.slice(0, 3) : [],", + " reportJsonPath: compact.reportJsonPath ?? reportJsonPath,", + " reportJsonSha256: compact.reportJsonSha256 ?? sha256(reportJsonPath),", + " reportMdPath: compact.reportMdPath ?? reportMdPath,", + " reportMdSha256: compact.reportMdSha256 ?? sha256(reportMdPath),", + " analyzer: { ...(compact.analyzer ?? {}), compactStdoutLimited: true, compactStdoutLimitBytes, originalCompactBytes: Buffer.byteLength(compactOutput(compact), 'utf8'), originalMinimalBytes: Buffer.byteLength(output, 'utf8') },", + " valuesRedacted: true", + " };", + " output = compactOutput(tiny);", + " }", "}", "console.log(output);", "UNIDESK_WEB_OBSERVE_ANALYZE_COMPACT",