fix: render web observe analyze as table
This commit is contained in:
@@ -7264,7 +7264,7 @@ function runNodeWebProbeObserveCollect(options: NodeWebProbeObserveOptions, spec
|
||||
};
|
||||
}
|
||||
|
||||
function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec: HwlabRuntimeLaneSpec): Record<string, unknown> {
|
||||
function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec: HwlabRuntimeLaneSpec): Record<string, unknown> | RenderedCliResult {
|
||||
const analyzerB64 = Buffer.from(nodeWebObserveAnalyzerSource(), "utf8").toString("base64");
|
||||
const script = [
|
||||
"set -eu",
|
||||
@@ -7276,7 +7276,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
].join("\n");
|
||||
const result = runTransWorkspaceStdinScript(options.node, spec.workspace, script, options.commandTimeoutSeconds);
|
||||
const analysis = parseJsonObject(result.stdout);
|
||||
return {
|
||||
return withWebObserveAnalyzeRendered({
|
||||
ok: result.exitCode === 0 && analysis?.ok === true,
|
||||
status: result.exitCode === 0 && analysis?.ok === true ? "analyzed" : "blocked",
|
||||
command: webObserveCommandLabel("analyze", options),
|
||||
@@ -7287,9 +7287,109 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
analysis,
|
||||
result: compactCommandResult(result),
|
||||
valuesRedacted: true,
|
||||
});
|
||||
}
|
||||
|
||||
function withWebObserveAnalyzeRendered(value: Record<string, unknown>): RenderedCliResult {
|
||||
return {
|
||||
ok: value.ok !== false,
|
||||
command: typeof value.command === "string" ? value.command : "hwlab nodes web-probe observe analyze",
|
||||
contentType: "text/plain",
|
||||
renderedText: renderWebObserveAnalyzeTable(value),
|
||||
};
|
||||
}
|
||||
|
||||
function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
const analysis = record(value.analysis);
|
||||
const counts = record(analysis?.counts);
|
||||
const sampleMetrics = record(analysis?.sampleMetrics);
|
||||
const runtimeAlerts = record(analysis?.runtimeAlerts);
|
||||
const pagePerformance = record(analysis?.pagePerformance);
|
||||
const promptNetwork = record(analysis?.promptNetwork);
|
||||
const slowApis = Array.isArray(analysis?.pagePerformanceSlowApi) ? analysis.pagePerformanceSlowApi.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||
const findings = Array.isArray(analysis?.findings) ? analysis.findings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||
const domDiagnostics = Array.isArray(analysis?.domDiagnosticGroups) ? analysis.domDiagnosticGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 5) : [];
|
||||
const lines = [
|
||||
`hwlab nodes web-probe observe analyze (${webObserveText(value.status)})`,
|
||||
"",
|
||||
webObserveTable(["ID", "NODE", "LANE", "SAMPLES", "CONTROL", "NETWORK", "CONSOLE", "ARTIFACTS"], [[
|
||||
webObserveText(value.id),
|
||||
webObserveText(value.node),
|
||||
webObserveText(value.lane),
|
||||
webObserveText(counts?.samples),
|
||||
webObserveText(counts?.control),
|
||||
webObserveText(counts?.network),
|
||||
webObserveText(counts?.console),
|
||||
webObserveText(counts?.artifacts),
|
||||
]]),
|
||||
"",
|
||||
"Reports:",
|
||||
webObserveTable(["KIND", "PATH", "SHA256"], [
|
||||
["json", webObserveShort(webObserveText(analysis?.reportJsonPath), 96), webObserveShort(webObserveText(analysis?.reportJsonSha256), 24)],
|
||||
["md", webObserveShort(webObserveText(analysis?.reportMdPath), 96), webObserveShort(webObserveText(analysis?.reportMdSha256), 24)],
|
||||
]),
|
||||
"",
|
||||
"Turn timing:",
|
||||
webObserveTable(["ROUNDS", "TURNS", "ROWS", "NON_MONO", "ELAPSED_DEC", "RECENT_JUMP", "MAX_RECENT_STEP"], [[
|
||||
webObserveText(sampleMetrics?.rounds),
|
||||
webObserveText(sampleMetrics?.turnColumns),
|
||||
webObserveText(sampleMetrics?.turnTimingRows),
|
||||
webObserveText(sampleMetrics?.turnTimingNonMonotonicCount),
|
||||
webObserveText(sampleMetrics?.turnTimingTotalElapsedDecreaseCount),
|
||||
webObserveText(sampleMetrics?.turnTimingRecentUpdateJumpCount ?? sampleMetrics?.turnTimingRecentUpdateSawtoothJumpCount),
|
||||
webObserveText(sampleMetrics?.turnTimingRecentUpdateMaxIncreaseSeconds),
|
||||
]]),
|
||||
"",
|
||||
"Runtime alerts:",
|
||||
webObserveTable(["HTTP_ERR", "REQUEST_FAILED", "DOM_DIAG", "CONSOLE_ALERT", "PROMPT_SEGMENTS", "PROMPT_NETWORK"], [[
|
||||
webObserveText(runtimeAlerts?.httpErrorCount),
|
||||
webObserveText(runtimeAlerts?.requestFailedCount),
|
||||
webObserveText(runtimeAlerts?.domDiagnosticSampleCount),
|
||||
webObserveText(runtimeAlerts?.consoleAlertCount),
|
||||
webObserveText(sampleMetrics?.promptSegments),
|
||||
webObserveText(promptNetwork?.promptSegments),
|
||||
]]),
|
||||
"",
|
||||
"Slow API (>5s):",
|
||||
webObserveTable(["PATH", "SAMPLES", "P95", "MAX", "OVER5S"], slowApis.length > 0 ? slowApis.map((item) => [
|
||||
webObserveShort(webObserveText(item.path ?? item.route), 52),
|
||||
webObserveText(item.sampleCount),
|
||||
webObserveText(item.p95Ms ?? item.p95),
|
||||
webObserveText(item.maxMs ?? item.max),
|
||||
webObserveText(item.overFiveSecondCount),
|
||||
]) : [["-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"DOM diagnostics:",
|
||||
webObserveTable(["COUNT", "FIRST", "LAST", "TEXT"], domDiagnostics.length > 0 ? domDiagnostics.map((item) => [
|
||||
webObserveText(item.count),
|
||||
webObserveShort(webObserveText(item.firstAt), 24),
|
||||
webObserveShort(webObserveText(item.lastAt), 24),
|
||||
webObserveShort(webObserveText(item.text), 96),
|
||||
]) : [["-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Findings:",
|
||||
webObserveTable(["KIND", "SEVERITY", "COUNT", "SUMMARY"], findings.length > 0 ? findings.map((item) => [
|
||||
webObserveShort(webObserveText(item.kind ?? item.code), 32),
|
||||
webObserveText(item.severity ?? item.level),
|
||||
webObserveText(item.count ?? item.sampleCount),
|
||||
webObserveShort(webObserveText(item.summary ?? item.message), 96),
|
||||
]) : [["-", "-", "-", "-"]]),
|
||||
];
|
||||
if (pagePerformance !== null && Object.keys(pagePerformance).length > 0) {
|
||||
lines.push("", "Page performance:", ` ${webObserveShort(JSON.stringify(pagePerformance), 180)}`);
|
||||
}
|
||||
lines.push(
|
||||
"",
|
||||
"Next:",
|
||||
` cat ${webObserveText(analysis?.reportMdPath)}`,
|
||||
` cat ${webObserveText(analysis?.reportJsonPath)}`,
|
||||
"",
|
||||
"Disclosure:",
|
||||
" default view is a bounded report summary; use report.md/report.json paths for full offline analysis.",
|
||||
);
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function nodeWebObserveResolveStateDirShell(options: Pick<NodeWebProbeObserveOptions, "stateDir" | "jobId" | "node" | "lane">): string {
|
||||
if (options.stateDir !== null) {
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user