fix: bound web-probe observe analyze output

This commit is contained in:
Codex
2026-07-02 09:13:41 +00:00
parent ff8f13f243
commit 87351278b5
2 changed files with 239 additions and 17 deletions
@@ -330,6 +330,146 @@ export function renderWebObserveAnalyzeTable(value: Record<string, unknown>): st
webObserveText(item.overBudgetCount ?? item.overFiveSecondCount),
webObserveShort(webObserveArray(item.slowSamples).map((sample) => webObserveText(record(sample)?.otelTraceId)).filter((text) => text !== "-").join(",") || "-", 36),
]);
const frontendPerformance = record(analysis?.frontendPerformance);
const frontendPerformanceSummary = nonEmptyRecord(frontendPerformance?.summary) ?? frontendPerformance;
const frontendPerformanceHotspots = record(analysis?.frontendPerformanceHotspots);
const frontendProfileFunctions = webObserveArray(frontendPerformanceHotspots?.profileFunctions ?? frontendPerformance?.profileFunctions ?? frontendPerformance?.profileHotspots).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 4);
const frontendProfileStacks = webObserveArray(frontendPerformanceHotspots?.profileStacks ?? frontendPerformance?.profileStacks).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 3);
const frontendScriptHotspots = webObserveArray(frontendPerformanceHotspots?.scripts ?? frontendPerformance?.scripts ?? frontendPerformance?.scriptHotspots).map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 4);
const highSignalFindings = dedupeWebObserveRecords(
[...toolFindings, ...findings, ...archiveRedFindings],
(item) => String(item.kind ?? item.id ?? item.code ?? ""),
).slice(0, 6);
const id = webObserveText(value.id);
const statusLine = value.ok === false
? `blocked reason=${webObserveText(record(value.failure)?.reason)} exit=${webObserveText(result.exitCode)} timeout=${webObserveText(result.timedOut)} recovered=${webObserveText(record(value.failure)?.recoveredFromArtifacts)}`
: `ok=${webObserveText(value.ok !== false)} exit=${webObserveText(result.exitCode)} timeout=${webObserveText(result.timedOut)}`;
const compactLines = [
`web-probe observe analyze (${webObserveText(value.status)})`,
"",
webObserveTable(["ID", "NODE", "LANE", "STATUS", "SCOPE", "STATE_DIR"], [[
id,
value.node,
value.lane,
statusLine,
webObserveShort([webObserveText(jsonlScope?.mode ?? "current"), webObserveText(record(jsonlScope?.focus)?.mode), jsonlScope?.archivePrefix ? webObserveText(jsonlScope.archivePrefix) : ""].filter((part) => part && part !== "-").join(":"), 36),
webObserveShort(webObserveText(analysis?.stateDir), 72),
]]),
"",
"Artifacts:",
webObserveTable(["KIND", "PATH", "SHA256"], [
["report.json", webObserveShort(webObserveText(analysis?.reportJsonPath), 72), webObserveShort(webObserveText(analysis?.reportJsonSha256), 24)],
["report.md", webObserveShort(webObserveText(analysis?.reportMdPath), 72), webObserveShort(webObserveText(analysis?.reportMdSha256), 24)],
]),
"",
"Counts:",
webObserveTable(["SAMPLES", "CONTROL", "NETWORK", "CONSOLE", "ARTIFACTS", "ARCHIVE_SAMPLES", "ARCHIVE_RED"], [[
webObserveText(counts?.samples),
webObserveText(counts?.control),
webObserveText(counts?.network),
webObserveText(counts?.console),
webObserveText(counts?.artifacts),
webObserveText(record(archiveSummary?.sampleMetrics)?.sampleCount),
webObserveText(archiveSummary?.redFindingCount),
]]),
"",
"Tool state:",
webObserveTable(["PENDING", "PROCESSING", "ABANDONED", "FAILED", "RUNNER_ERRORS", "COMMAND_FAILURES"], [[
webObserveText(commandState?.pendingCount),
webObserveText(commandState?.processingCount),
webObserveText(commandState?.abandonedCount),
webObserveText(commandState?.failedCount),
webObserveText(runnerErrors.length),
webObserveText(commandFailures.length),
]]),
"",
"Findings:",
webObserveTable(["KIND", "SEVERITY", "COUNT", "ROOT_CAUSE", "SUMMARY"], highSignalFindings.length > 0 ? highSignalFindings.map((item) => [
webObserveShort(webObserveText(item.kind ?? item.id ?? item.code), 38),
webObserveText(item.severity ?? item.level),
webObserveText(item.count ?? item.sampleCount),
webObserveShort(webObserveText(item.rootCause ?? item.rootCauseStatus), 38),
webObserveShort(webObserveText(item.summary ?? item.message), 104),
]) : [["-", "-", "-", "-", "-"]]),
"",
"Turn/loading:",
webObserveTable(["ROUNDS", "TURNS", "ROWS", "ELAPSED_JUMP", "RECENT_JUMP", "LOADING_SAMPLES", "MAX_LOADING", `OVER_${loadingBudgetLabel}`], [[
webObserveText(roundCount),
webObserveText(turnColumnCount),
webObserveText(sampleMetrics?.turnTimingRows),
webObserveText(sampleMetrics?.turnTimingTotalElapsedForwardJumpCount ?? elapsedForwardJumps.length),
webObserveText(sampleMetrics?.turnTimingRecentUpdateJumpCount ?? sampleMetrics?.turnTimingRecentUpdateSawtoothJumpCount),
webObserveText(loadingSummary?.loadingSampleCount ?? sampleMetrics?.loadingSampleCount),
webObserveText(loadingSummary?.maxSimultaneousCount ?? sampleMetrics?.loadingMaxCount),
webObserveText(loadingSummary?.overBudgetSegmentCount ?? loadingSummary?.overFiveSecondSegmentCount ?? sampleMetrics?.loadingOverFiveSecondSegmentCount),
]]),
"",
"Request/performance:",
webObserveTable(["REQUESTS", "TOTAL_PEAK", "PAGE_PEAK", "API_PEAK", "SLOW_API", "ARCHIVE_SLOW", "SSE_SLOW"], [[
webObserveText(requestRateSummary?.requestCount),
webObserveText(requestRateSummary?.totalPeakPerMinute),
webObserveText(requestRateSummary?.pagePeakPerMinute),
webObserveText(requestRateSummary?.apiPathPeakPerMinute),
webObserveText(slowApis.length),
webObserveText(archiveSlowApis.length),
webObserveText(sseStreams.length),
]]),
webObserveTable(["PATH", "SAMPLES", "P95", "MAX", "OVER"], (slowApis.length > 0 ? slowApis : archiveSlowApis).slice(0, 4).map((item) => [
webObserveShort(webObserveText(item.path ?? item.route), 56),
webObserveText(item.sampleCount),
webObserveText(item.p95Ms ?? item.p95),
webObserveText(item.maxMs ?? item.max),
webObserveText(item.overBudgetCount ?? item.overFiveSecondCount),
]).concat((slowApis.length > 0 || archiveSlowApis.length > 0) ? [] : [["-", "-", "-", "-", "-"]])),
"",
"Frontend performance:",
webObserveTable(["EVENTS", "LONGTASK", "LOAF", "GAP", "CAPTURES", "MAX_LONGTASK", "MAX_LOAF", "MAX_GAP"], [[
webObserveText(frontendPerformanceSummary?.eventCount),
webObserveText(frontendPerformanceSummary?.longTaskCount),
webObserveText(frontendPerformanceSummary?.longAnimationFrameCount),
webObserveText(frontendPerformanceSummary?.eventLoopGapCount),
webObserveText(frontendPerformanceSummary?.captureCount),
webObserveText(frontendPerformanceSummary?.maxLongTaskMs),
webObserveText(frontendPerformanceSummary?.maxLongAnimationFrameMs),
webObserveText(frontendPerformanceSummary?.maxEventLoopGapMs),
]]),
webObserveTable(["CPU_SELF_MS", "TOTAL_MS", "HITS", "FUNCTION", "URL"], frontendProfileFunctions.length > 0 ? frontendProfileFunctions.map((item) => [
webObserveText(item.selfTimeMs),
webObserveText(item.totalTimeMs),
webObserveText(item.hitCount),
webObserveShort(webObserveText(item.functionName ?? item.name), 42),
webObserveShort(webObserveText(item.url ?? item.sourceURL ?? item.scriptUrl), 64),
]) : [["-", "-", "-", "-", "-"]]),
webObserveTable(["STACK_SELF_MS", "FRAMES", "FUNCTION", "TOP_FRAME"], frontendProfileStacks.length > 0 ? frontendProfileStacks.map((item) => {
const frames = webObserveArray(item.frames).map(record).filter((frame): frame is Record<string, unknown> => frame !== null);
const topFrame = frames[0] ?? {};
return [
webObserveText(item.selfTimeMs),
webObserveText(item.frameCount ?? frames.length),
webObserveShort(webObserveText(item.functionName ?? item.name), 38),
webObserveShort(`${webObserveText(topFrame.functionName ?? "(anonymous)")}@${webObserveText(topFrame.url ?? topFrame.scriptId)}`, 68),
];
}) : [["-", "-", "-", "-"]]),
webObserveTable(["LOAF_MS", "COUNT", "FUNCTION", "URL"], frontendScriptHotspots.length > 0 ? frontendScriptHotspots.map((item) => [
webObserveText(item.totalDurationMs ?? item.durationMs),
webObserveText(item.count ?? item.hitCount),
webObserveShort(webObserveText(item.sourceFunctionName ?? item.functionName ?? item.invoker), 42),
webObserveShort(webObserveText(item.sourceURL ?? item.url), 64),
]) : [["-", "-", "-", "-"]]),
"",
"Next:",
` bun scripts/cli.ts web-probe observe collect ${id} --view turn-summary`,
` bun scripts/cli.ts web-probe observe collect ${id} --view timeline --command-id <commandId>`,
` bun scripts/cli.ts web-probe observe collect ${id} --view trace-frame --trace-id <traceId> --sample-seq <seq>`,
` bun scripts/cli.ts web-probe observe collect ${id} --view workbench-triad --trace-id <traceId>`,
` bun scripts/cli.ts web-probe observe collect ${id} --view performance-summary`,
` bun scripts/cli.ts web-probe observe collect ${id} --view files --file analysis/report.json --finding <findingId>`,
"",
"Disclosure:",
" default analyze output is a bounded index; full offline report stays in report.md/report.json artifacts.",
];
if (value.full !== true) return compactLines.join("\n");
const lines = [
`web-probe observe analyze (${webObserveText(value.status)})`,
"",