fix: bound mdtodo collect output (#910)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-26 00:24:55 +08:00
committed by GitHub
parent dd5c9166b8
commit 00b167b68d
2 changed files with 117 additions and 1 deletions
@@ -243,6 +243,10 @@ function renderWebObserveCollectTable(value: Record<string, unknown>): string {
" collect views are rendered from existing samples/control/analysis artifacts; they do not create a new sampling source.",
].join("\n");
}
const collectView = webObserveText(collect?.view ?? value.view);
if (collect !== null && (collectView === "project-summary" || collectView === "project-mdtodo-summary")) {
return renderWebObserveProjectCollectTable(value, collect);
}
const result = record(value.result);
const file = record(collect?.file);
@@ -455,6 +459,111 @@ function renderWebObserveCollectTable(value: Record<string, unknown>): string {
return lines.join("\n");
}
function renderWebObserveProjectCollectTable(value: Record<string, unknown>, collect: Record<string, unknown>): string {
const summary = record(collect.summary);
const sampleRows = Array.isArray(collect.sampleRows) ? collect.sampleRows.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(-6) : [];
const commands = Array.isArray(collect.commands) ? collect.commands.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(-14) : [];
const mutations = Array.isArray(collect.mutations) ? collect.mutations.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(-10) : [];
const launches = Array.isArray(collect.launches) ? collect.launches.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(-4) : [];
const findings = Array.isArray(collect.findings) ? collect.findings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 6) : [];
const lines = [
`hwlab nodes web-probe observe collect (${webObserveText(value.status)})`,
"",
...renderWebObserveWrapperContract(value),
webObserveTable(["ID", "NODE", "LANE", "VIEW", "STATE_DIR"], [[
value.id,
value.node,
value.lane,
collect.view ?? value.view,
webObserveShort(webObserveText(collect.stateDir), 88),
]]),
"",
"Project MDTODO summary:",
webObserveTable(["ENABLED", "SAMPLES", "MDTODO", "LATEST", "SRC", "FILES", "TASKS", "SELECTED"], [[
summary.enabled,
summary.projectSampleCount,
summary.mdtodoSampleCount,
webObserveShort(`${webObserveText(summary.latestPageKind)} ${webObserveText(summary.latestPath)}`, 44),
summary.latestSourceCount,
summary.latestFileCount,
summary.latestTaskCount,
webObserveShort(webObserveText(summary.latestSelectedTaskRefHash ?? summary.latestSelectedTaskRefPreview), 32),
]]),
"",
"Project command totals:",
webObserveTable(["COMMANDS", "MUTATIONS", "MUTATION_FAIL", "LAUNCH", "LAUNCH_OK", "LAUNCH_FAIL", "OTEL", "API_FAIL", "SLOW>10S"], [[
collect.commandCount ?? summary.projectCommandCount,
collect.mutationCount ?? summary.mutationCommandCount,
summary.mutationFailureCount,
collect.launchCount ?? summary.launchCommandCount,
summary.launchSuccessCount,
summary.launchFailureCount,
summary.launchWithOtelTraceHeaderCount,
`${webObserveText(summary.projectApiFailureCount)}/${webObserveText(summary.projectApiRequestFailedCount)}`,
summary.projectApiSlowPathCount,
]]),
"",
"Recent project samples:",
webObserveTable(["SEQ", "TS", "ROLE", "PATH", "KIND", "SRC", "FILES", "TASKS", "STATUS", "LAUNCH"], sampleRows.length > 0 ? sampleRows.map((item) => [
item.seq,
webObserveShort(webObserveText(item.ts), 24),
webObserveShort(webObserveText(item.pageRole), 18),
webObserveShort(webObserveText(item.path), 24),
webObserveShort(webObserveText(item.pageKind), 28),
item.sourceCount,
item.fileCount,
item.taskCount,
webObserveShort(webObserveText(item.selectedTaskStatus), 20),
item.launchButtonEnabled === true ? "yes" : "no",
]) : [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
"",
"Project commands:",
webObserveTable(["TS", "PHASE", "TYPE", "STATUS", "PATH", "TASK", "MESSAGE"], commands.length > 0 ? commands.map((item) => [
webObserveShort(webObserveText(item.ts), 24),
item.phase,
webObserveShort(webObserveText(item.type), 28),
item.status,
webObserveShort(webObserveText(item.afterPath), 36),
webObserveShort(webObserveText(item.selectedTaskHash), 24),
webObserveShort(webObserveText(item.message), 72),
]) : [["-", "-", "-", "-", "-", "-", "-"]]),
"",
"MDTODO mutations:",
webObserveTable(["TS", "PHASE", "TYPE", "STATUS", "TASK", "MESSAGE"], mutations.length > 0 ? mutations.map((item) => [
webObserveShort(webObserveText(item.ts), 24),
item.phase,
webObserveShort(webObserveText(item.type), 28),
item.status,
webObserveShort(webObserveText(item.selectedTaskHash), 24),
webObserveShort(webObserveText(item.message), 72),
]) : [["-", "-", "-", "-", "-", "-"]]),
"",
"Workbench launches:",
webObserveTable(["TS", "PHASE", "STATUS", "SESSION", "OTEL_TRACE", "TASK", "URL"], launches.length > 0 ? launches.map((item) => [
webObserveShort(webObserveText(item.ts), 24),
item.phase,
item.status,
webObserveShort(webObserveText(item.sessionId), 28),
webObserveShort(webObserveText(item.otelTraceId), 28),
webObserveShort(webObserveText(item.taskHash), 24),
webObserveShort(webObserveText(item.workbenchUrl), 52),
]) : [["-", "-", "-", "-", "-", "-", "-"]]),
"",
"Findings:",
webObserveTable(["SEVERITY", "ID", "COUNT", "SUMMARY"], findings.length > 0 ? findings.map((item) => [
webObserveShort(webObserveText(item.severity ?? item.level), 12),
webObserveShort(webObserveText(item.id ?? item.kind ?? item.code), 48),
item.count ?? item.sampleCount,
webObserveShort(webObserveText(item.summary ?? item.message), 96),
]) : [["-", "-", "-", "-"]]),
"",
"Disclosure:",
" collect project views are rendered from existing samples/control/analysis artifacts; they do not create a new sampling source.",
" row lists are bounded; use observe analyze or collect --file for artifact-level drill-down.",
];
return lines.join("\n");
}
function webObserveTable(headers: string[], rows: unknown[][]): string {
const stringRows = rows.map((row) => headers.map((_, index) => webObserveCell(row[index])));
const widths = headers.map((header, index) => Math.max(header.length, ...stringRows.map((row) => row[index]?.length ?? 0)));