diff --git a/.agents/skills/unidesk-webdev/references/web-probe.md b/.agents/skills/unidesk-webdev/references/web-probe.md index 73d354a8..ebd98210 100644 --- a/.agents/skills/unidesk-webdev/references/web-probe.md +++ b/.agents/skills/unidesk-webdev/references/web-probe.md @@ -12,6 +12,10 @@ - 默认 profile 由同一 YAML 的 `defaultConsoleVerificationProfile` 选择,CLI `--profile` 只做显式 profile 选择; - 该命令用于已部署页面人工 closeout,不作为 CI/CD gate,不替代 Workbench Kafka、Trace 和性能专项 validator; - 成功或失败均以有界 `issueEvidence`、report SHA、screenshot SHA 和失败摘要收口,不再重复创建 `.state/probes/*.mjs`。 +- WebProbe 远程命令错误可见性: + - 默认文本输出必须在独立 `COMMAND_OUTPUT` 段完整展示已经脱敏并限长的 `stderrTail` 与 `stdoutTail`; + - 摘要表可以继续提供单行预览,但不得用表格宽度裁剪替代完整的有界错误证据; + - `exitCode` 非零且命令输出为空时按可观测性故障处理,先修复探针输出合同,再判断浏览器或业务根因。 - Workbench 与 Performance 调查规则: - 先使用专用 collect/analyze view; - 不要先检索原始 JSONL artifact。 diff --git a/scripts/src/hwlab-node/web-observe-render.test.ts b/scripts/src/hwlab-node/web-observe-render.test.ts index 221ed00e..c801d5cd 100644 --- a/scripts/src/hwlab-node/web-observe-render.test.ts +++ b/scripts/src/hwlab-node/web-observe-render.test.ts @@ -476,6 +476,7 @@ test("web-probe script renders bounded command tails when report output is missi const text = String(rendered.renderedText ?? ""); assert.match(text, /stderrTail\s+Error: browser launch failed at runner\.mjs:1:1/u); assert.match(text, /stdoutTail\s+partial output/u); + assert.match(text, /COMMAND_OUTPUT\nstderrTail: Error: browser launch failed at runner\.mjs:1:1\nstdoutTail: partial output/u); }); test("web-probe command governance distinguishes ad-hoc scripts from repo-owned generated commands", () => { diff --git a/scripts/src/hwlab-node/web-observe-render.ts b/scripts/src/hwlab-node/web-observe-render.ts index 44d32df9..1d916b01 100644 --- a/scripts/src/hwlab-node/web-observe-render.ts +++ b/scripts/src/hwlab-node/web-observe-render.ts @@ -1721,6 +1721,14 @@ export function renderWebProbeScriptResult(result: Record): Rec if (typeof commandResult.stdoutTail === "string" && commandResult.stdoutTail.trim()) { summaryRows.push(["stdoutTail", webProbeScriptPreview(commandResult.stdoutTail)]); } + const commandOutputLines = [ + typeof commandResult.stderrTail === "string" && commandResult.stderrTail.trim() + ? `stderrTail: ${webProbeScriptPreview(commandResult.stderrTail)}` + : null, + typeof commandResult.stdoutTail === "string" && commandResult.stdoutTail.trim() + ? `stdoutTail: ${webProbeScriptPreview(commandResult.stdoutTail)}` + : null, + ].filter((line): line is string => line !== null); const renderedText = [ `UNIDESK_WEB_PROBE_COMMAND_PROMOTION_HINT ${JSON.stringify(commandPromotionHint)}`, "", @@ -1731,6 +1739,10 @@ export function renderWebProbeScriptResult(result: Record): Rec "", webObserveTable(["FIELD", "VALUE"], summaryRows), "", + commandOutputLines.length === 0 + ? "COMMAND_OUTPUT\n-" + : ["COMMAND_OUTPUT", ...commandOutputLines].join("\n"), + "", resultRows.length === 0 ? "SCRIPT_RESULT\n-" : webObserveTable(["KEY", "VALUE"], resultRows),