fix: compile recovered analyze heredoc

This commit is contained in:
AgentRun Codex
2026-07-12 22:08:08 +00:00
parent 107c0e9980
commit 5fd3a1f07d
2 changed files with 19 additions and 3 deletions
@@ -1,4 +1,8 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "bun:test";
import { hwlabRuntimeLaneSpecForNode } from "../hwlab-node-lanes";
@@ -25,8 +29,21 @@ test("artifact recovery helper projects report time without filesystem mtime", (
});
assert.equal(recovered?.reportUpdatedAt, "2026-07-12T00:00:00.000Z");
assert.match(recoveryScript, /const reportJson = objectOrNull\(readJson\(reportJsonPath\)\) \|\| \{\};/u);
assert.equal((recoveryScript.match(/const reportJson =/gu) ?? []).length, 1);
assert.match(recoveryScript, /source\.reportUpdatedAt \?\? source\.updatedAt \?\? source\.analyzedAt \?\? reportJson\.reportUpdatedAt \?\? reportJson\.updatedAt \?\? reportJson\.analyzedAt/u);
assert.doesNotMatch(recoveryScript, /mtime/u);
const marker = "UNIDESK_WEB_OBSERVE_RECOVER_ANALYZE_ARTIFACT";
const start = recoveryScript.indexOf(`<<'${marker}'\n`) + marker.length + 5;
const end = recoveryScript.indexOf(`\n${marker}`, start);
const directory = mkdtempSync(join(tmpdir(), "web-observe-recovery-"));
try {
const programPath = join(directory, "recovery.js");
writeFileSync(programPath, recoveryScript.slice(start, end));
const syntax = spawnSync(process.execPath, ["--check", programPath], { encoding: "utf8" });
assert.equal(syntax.status, 0, syntax.stderr);
} finally {
rmSync(directory, { recursive: true, force: true });
}
});
test("validateRealtimeFanout parses the YAML profile and two independent prompts", () => {
+2 -3
View File
@@ -2451,7 +2451,6 @@ export function recoverWebObserveAnalyzeFromArtifacts(options: NodeWebProbeObser
"const statSize = (path) => { try { return fs.statSync(path).size; } catch { return 0; } };",
"const sha256 = (path) => { const text = readText(path); return text ? 'sha256:' + crypto.createHash('sha256').update(text).digest('hex') : null; };",
"const objectOrNull = (value) => value && typeof value === 'object' && !Array.isArray(value) ? value : null;",
"const reportJson = objectOrNull(readJson(reportJsonPath)) || {};",
"const arr = (value) => Array.isArray(value) ? value : [];",
"const clip = (value, limit = 160) => value === null || value === undefined ? null : String(value).slice(0, limit);",
"const numberish = (...values) => { for (const value of values) { const n = Number(value); if (Number.isFinite(n)) return value; } return null; };",
@@ -2471,7 +2470,7 @@ export function recoverWebObserveAnalyzeFromArtifacts(options: NodeWebProbeObser
"const compactTraceOrder = (value) => { const v = objectOrNull(value); if (!v) return null; const s = objectOrNull(v.summary) || {}; return { summary: { sampleCount: v.sampleCount ?? s.sampleCount ?? null, traceRowCount: v.traceRowCount ?? s.traceRowCount ?? null, orderAnomalyCount: v.orderAnomalyCount ?? s.orderAnomalyCount ?? arr(v.orderAnomalies).length, completionNotLastCount: v.completionNotLastCount ?? s.completionNotLastCount ?? arr(v.completionNotLast).length }, orderAnomalies: arr(v.orderAnomalies).slice(0, 8) }; };",
"const compactMetrics = (value) => { const v = objectOrNull(value) || {}; const s = objectOrNull(v.summary) || {}; return { sampleCount: numberish(v.sampleCount, s.sampleCount), rounds: arr(v.rounds ?? v.roundItems).slice(-8).map(slimRound), roundItems: arr(v.roundItems ?? v.rounds).slice(-8).map(slimRound), turnColumns: arr(v.turnColumns).slice(-12).map(slimTurnColumn), turnTimingRows: numberish(v.turnTimingRows, s.turnTimingRows), turnTimingNonMonotonicCount: numberish(v.turnTimingNonMonotonicCount, s.turnTimingNonMonotonicCount), turnTimingTotalElapsedDecreaseCount: numberish(v.turnTimingTotalElapsedDecreaseCount, s.turnTimingTotalElapsedDecreaseCount), turnTimingTotalElapsedZeroResetCount: numberish(v.turnTimingTotalElapsedZeroResetCount, s.turnTimingTotalElapsedZeroResetCount), turnTimingTotalElapsedForwardJumpCount: numberish(v.turnTimingTotalElapsedForwardJumpCount, s.turnTimingTotalElapsedForwardJumpCount), turnTimingTerminalElapsedGrowthCount: numberish(v.turnTimingTerminalElapsedGrowthCount, s.turnTimingTerminalElapsedGrowthCount), turnTimingRecentUpdateJumpCount: numberish(v.turnTimingRecentUpdateJumpCount, v.turnTimingRecentUpdateSawtoothJumpCount, s.turnTimingRecentUpdateJumpCount, s.turnTimingRecentUpdateSawtoothJumpCount), turnTimingRecentUpdateMaxIncreaseSeconds: numberish(v.turnTimingRecentUpdateMaxIncreaseSeconds, s.turnTimingRecentUpdateMaxIncreaseSeconds), loading: compactLoading(v.loading), traceOrder: compactTraceOrder(v.traceOrder), sessionRailTitles: compactSessionRailTitles(v.sessionRailTitles), promptSegments: numberish(v.promptSegments, s.promptSegments), loadingSampleCount: numberish(v.loadingSampleCount, s.loadingSampleCount), loadingMaxCount: numberish(v.loadingMaxCount, s.loadingMaxCount), loadingMaxOwnerCount: numberish(v.loadingMaxOwnerCount, s.loadingMaxOwnerCount), loadingOwnerCount: numberish(v.loadingOwnerCount, s.loadingOwnerCount), loadingLongestContinuousSeconds: numberish(v.loadingLongestContinuousSeconds, s.loadingLongestContinuousSeconds), loadingCurrentContinuousSeconds: numberish(v.loadingCurrentContinuousSeconds, s.loadingCurrentContinuousSeconds), loadingOverFiveSecondSegmentCount: numberish(v.loadingOverFiveSecondSegmentCount, s.loadingOverFiveSecondSegmentCount) }; };",
"const stdoutJson = readJson(stdoutPath);",
"const reportJson = readJson(reportJsonPath);",
"const reportJson = objectOrNull(readJson(reportJsonPath)) || {};",
"const source = objectOrNull(stdoutJson) || objectOrNull(reportJson);",
"if (!source) { console.log(JSON.stringify({ ok: false, command: 'web-probe-observe analyze', stateDir, error: 'web-probe-analyzer-artifacts-missing', analyzer: { recoveredFrom: 'analysis-artifact-after-transport-timeout', stdoutPath, stderrPath, reportJsonPath, reportMdPath, stdoutBytes: statSize(stdoutPath), stderrBytes: statSize(stderrPath), reportJsonBytes: statSize(reportJsonPath), reportMdBytes: statSize(reportMdPath), transportExitCode: Number(transportExitRaw), transportTimedOut: transportTimedOutRaw === 'true', valuesRedacted: true }, valuesRedacted: true })); process.exit(0); }",
"const recent = objectOrNull(source.windows?.recent) || {};",
@@ -2489,7 +2488,7 @@ export function recoverWebObserveAnalyzeFromArtifacts(options: NodeWebProbeObser
"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 || {}, 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 };",
"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 };",
"compact.reportUpdatedAt = source.reportUpdatedAt ?? source.updatedAt ?? source.analyzedAt ?? reportJson.reportUpdatedAt ?? reportJson.updatedAt ?? reportJson.analyzedAt ?? null;",
"console.log(JSON.stringify(compact));",
"UNIDESK_WEB_OBSERVE_RECOVER_ANALYZE_ARTIFACT",