import assert from "node:assert/strict"; import { test } from "bun:test"; import { withWebObserveCommandRendered, withWebObserveStatusRendered } from "../hwlab-node-web-observe-render"; import { renderWebProbeScriptResult } from "./web-observe-render"; import { webProbeScriptCommandGovernance } from "./web-observe-scripts"; test("observe command renderer separates control completion from async turn terminal state", () => { const rendered = withWebObserveCommandRendered({ ok: true, status: "control-completed", command: "web-probe observe command", id: "webobs-fixture", commandId: "cmd-fixture", observerCommand: { type: "sendPrompt" }, observer: { ok: true, completedAt: "2026-07-10T01:00:01.000Z", result: { mark: "submitted" } }, control: { executionStatus: "completed", businessTurnTerminalImplied: false }, asyncTurn: { applicable: true, submissionStatus: "accepted", terminalStatus: null, terminalObserved: false, traceId: "trc_fixture" }, }); const text = String(rendered.renderedText); assert.match(text, /CONTROL.*TURN_SUBMIT.*TURN_TERMINAL/u); assert.match(text, /completed.*accepted.*not-observed.*trc_fixture/u); assert.match(text, /does not imply the asynchronous business turn reached a terminal state/u); assert.match(text, /observe status webobs-fixture --command-id cmd-fixture/u); assert.match(text, /--view turn-summary --command-id cmd-fixture/u); }); test("observe status renderer exposes the exact command phase and failed report evidence", () => { const rendered = withWebObserveStatusRendered({ ok: true, status: "running", command: "web-probe observe status", id: "webobs-fixture", node: "NC01", lane: "v03", observer: { processAlive: true, manifest: { baseUrl: "https://hwlab.example.test", targetPath: "/workbench" }, heartbeat: { status: "running", sampleSeq: 12, commandSeq: 3, updatedAt: "2026-07-10T01:00:01.000Z" }, diagnostics: { effectiveLiveness: "alive", heartbeatStale: false }, commands: { pendingCount: 0, processingCount: 0, abandonedCount: 0, failedCount: 1 }, exactCommand: { commandId: "cmd-fixture", type: "validateRealtimeFanout", phase: "failed", ok: false, error: { message: "terminal event arrived before subscriber disconnect", details: { reportPath: "artifacts/realtime-fanout/cmd-fixture/report.json", reportSha256: "sha256:fixture-report", }, }, }, tails: { samples: [], control: [], network: [] }, }, next: { status: "bun scripts/cli.ts web-probe observe status webobs-fixture", }, }); const text = String(rendered.renderedText); assert.match(text, /Exact command:/u); assert.match(text, /cmd-fixture.*validateRealtimeFanout.*failed.*false/u); assert.match(text, /sha256:fixture-report/u); assert.match(text, /terminal event arrived before subscriber disconnect/u); }); test("web-probe script render warns to promote repeated scripts into commands", () => { const commandPromotionHint = { schemaVersion: "unidesk.web-probe.command-promotion.v1", code: "prefer_repo_owned_typed_command", promotionRequiredBeforeRepeat: true, repoOwnedTypedCommand: false, sourceKind: "stdin", currentCommand: "web-probe script --node D601 --lane v03", preferredArtifact: "repo-owned-typed-command", preferredSurface: "web-probe observe command or a dedicated web-probe subcommand", action: "promote-before-repeat", message: "Before repeating this one-off script, promote the workflow to a repo-owned typed web-probe command.", valuesRedacted: true, }; const rendered = renderWebProbeScriptResult({ commandPromotionHint, ok: true, status: "pass", command: "web-probe script --node D601 --lane v03", node: "D601", lane: "v03", url: "https://hwlab.example.test", warnings: [{ code: "web_probe_script_ad_hoc_only", severity: "warning", requiredAction: "promote-before-repeat", preferredArtifact: "repo-owned-typed-command", message: "web-probe script is a one-off exploration escape hatch; before repeating it, promote the workflow to a repo-owned typed command instead of rerunning temporary scripts.", }], hints: [ "Before rerunning this script, promote the workflow to a repo-owned typed `web-probe` command.", ], preferredCommands: { typedCommandCatalog: "bun scripts/cli.ts web-probe --help", startObserver: "bun scripts/cli.ts web-probe observe start --node D601 --lane v03 --target-path /projects/mdtodo", mdtodoSummary: "bun scripts/cli.ts web-probe observe collect --view project-mdtodo-summary", }, summary: { ok: true, status: "pass" }, issueEvidence: {}, probe: { steps: [], script: { result: { ok: true } } }, reportLoad: { source: "stdout", path: ".state/web-probe-script/run.demo/web-probe-script-report.json" }, result: { exitCode: 0, timedOut: false }, }); const text = String(rendered.renderedText ?? ""); const marker = "UNIDESK_WEB_PROBE_COMMAND_PROMOTION_HINT "; const firstLine = text.split("\n", 1)[0] ?? ""; assert.ok(firstLine.startsWith(marker)); assert.deepEqual(JSON.parse(firstLine.slice(marker.length)), commandPromotionHint); assert.equal(Object.keys(rendered)[0], "commandPromotionHint"); assert.match(text, /WARNINGS/u); assert.match(text, /web_probe_script_ad_hoc_only/u); assert.match(text, /HINTS/u); assert.match(text, /repo-owned typed `web-probe` command/u); assert.match(text, /typedCommandCatalog: bun scripts\/cli\.ts web-probe --help/u); assert.match(text, /startObserver: bun scripts\/cli\.ts web-probe observe start/u); assert.match(text, /mdtodoSummary: bun scripts\/cli\.ts web-probe observe collect/u); }); test("web-probe command governance distinguishes ad-hoc scripts from repo-owned generated commands", () => { const base = { action: "script" as const, node: "D601", lane: "v03", url: "https://hwlab.example.test", timeoutMs: 30000, viewport: "1920x1080", browserProxyMode: "auto" as const, commandTimeoutSeconds: 60, scriptText: "return { ok: true };", scriptSource: { kind: "stdin" as const, path: null, byteCount: 20, sha256: "sha256:fixture", }, }; const adHoc = webProbeScriptCommandGovernance(base); assert.equal(adHoc.commandPromotionHint.promotionRequiredBeforeRepeat, true); assert.equal(adHoc.commandPromotionHint.action, "promote-before-repeat"); assert.equal(adHoc.warnings.length, 1); assert.equal(adHoc.warnings[0]?.requiredAction, "promote-before-repeat"); assert.match(adHoc.hints[0] ?? "", /repo-owned typed `web-probe` command/u); assert.deepEqual(Object.keys(adHoc.preferredCommands)[0], "typedCommandCatalog"); assert.ok(Object.values(adHoc.preferredCommands).every((command) => command.startsWith("bun scripts/cli.ts web-probe"))); const repoOwned = webProbeScriptCommandGovernance({ ...base, commandLabel: "web-probe opencode-smoke --node D601 --lane v03", suppressAdHocWarning: true, generatedHints: ["OpenCode smoke is a repo-owned typed web-probe command."], generatedPreferredCommands: { withExpectedText: "web-probe opencode-smoke --node D601 --lane v03 --expect-text ", }, scriptSource: { ...base.scriptSource, kind: "generated", path: "builtin:opencode-smoke", }, }); assert.equal(repoOwned.commandPromotionHint.promotionRequiredBeforeRepeat, false); assert.equal(repoOwned.commandPromotionHint.action, "reuse-repo-owned-typed-command"); assert.deepEqual(repoOwned.warnings, []); assert.doesNotMatch(repoOwned.hints.join("\n"), /temporary script|promote-before-repeat/iu); });