From 8c8976ed645c361f9754c0c6b0809700d6dc645e Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Wed, 29 Jul 2026 06:51:10 -0700 Subject: [PATCH] fix(miner-ui): type a chat-dispatch mock against the union #9815 closed main is red on ui:typecheck, which blocks every open PR. #9659/#9815 correctly tightened ChatActionDispatchResult from a loose `{ ok: boolean; status: string; ... }` into a union discriminated on `ok`, so the miner MCP server's refusal -> error-code mapping could finally be checked. But this miner-UI test mocks the dispatcher with a bare object literal, whose `ok`/`status` widen to boolean/string on inference -- and a widened literal no longer satisfies the closed union. Annotate the mock's return type (and import the real type) so it is validated against the shipped contract instead of inference. That also stops the mock drifting from the union the next time it changes -- the widened version would have kept compiling against any shape at all. --- apps/loopover-miner-ui/src/chat-conversation.test.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/loopover-miner-ui/src/chat-conversation.test.tsx b/apps/loopover-miner-ui/src/chat-conversation.test.tsx index 2bfaa53a74..9cda3d0fd5 100644 --- a/apps/loopover-miner-ui/src/chat-conversation.test.tsx +++ b/apps/loopover-miner-ui/src/chat-conversation.test.tsx @@ -1,6 +1,7 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; +import type { ChatActionDispatchResult } from "../../../packages/loopover-miner/lib/chat-action-dispatch.js"; import { createChatActionRegistry } from "../../../packages/loopover-miner/lib/chat-action-registry.js"; import { ChatConversation } from "./components/chat/conversation"; import { GOVERNOR_CHAT_ACTION_PENDING_MESSAGE } from "./lib/chat-governor-action-copy"; @@ -288,7 +289,11 @@ describe("ChatConversation governor pause/resume chat actions (#8670)", () => { }); it("surfaces a non-executed dispatch (flag off / gated) as a system note instead of an empty turn", async () => { - const runGovernorChatActionImpl = vi.fn(async () => ({ ok: false, status: "disabled", action: null })); + const runGovernorChatActionImpl = vi.fn(async (): Promise => ({ + ok: false, + status: "disabled", + action: null, + })); render(