From 45abd21c959b8ebc8c995446df40608005ec44d7 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 11:11:08 -0500 Subject: [PATCH 1/6] feat: add hook for sending data to client --- src/ui/hooks/index.ts | 1 + src/ui/hooks/useUIActions.ts | 199 +++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 src/ui/hooks/useUIActions.ts diff --git a/src/ui/hooks/index.ts b/src/ui/hooks/index.ts index e9d3be4c8..9de28c16e 100644 --- a/src/ui/hooks/index.ts +++ b/src/ui/hooks/index.ts @@ -1 +1,2 @@ export { useRenderData } from "./useRenderData.js"; +export { useUIActions } from "./useUIActions.js"; diff --git a/src/ui/hooks/useUIActions.ts b/src/ui/hooks/useUIActions.ts new file mode 100644 index 000000000..a249ec97a --- /dev/null +++ b/src/ui/hooks/useUIActions.ts @@ -0,0 +1,199 @@ +import { useCallback, useMemo } from "react"; + +/** Options for sending a message */ +interface SendMessageOptions { + /** Target origin for postMessage. Defaults to "*" */ + targetOrigin?: string; +} + +/** Return type for the useUIActions hook */ +interface UseUIActionsResult { + /** + * Sends an intent message to the host. + * Indicates the user has interacted with the UI and expressed an intent for the host to act on. + * @param intent - The intent identifier + * @param params - Optional parameters for the intent + */ + intent: (intent: string, params?: T) => void; + + /** + * Sends a notify message to the host. + * Indicates the iframe already acted upon user interaction and is notifying the host. + * @param message - The notification message + */ + notify: (message: string) => void; + + /** + * Sends a prompt message to the host. + * Asks the host to run a prompt. + * @param prompt - The prompt text to run + */ + prompt: (prompt: string) => void; + + /** + * Sends a tool call message to the host. + * Asks the host to execute a tool. + * @param toolName - The name of the tool to call + * @param params - Optional parameters for the tool + */ + tool: (toolName: string, params?: T) => void; + + /** + * Sends a link message to the host. + * Asks the host to navigate to a URL. + * @param url - The URL to navigate to + */ + link: (url: string) => void; + + /** + * Reports a size change to the host. + * Used for auto-resizing iframes. + * @param dimensions - The new dimensions (width and/or height) + */ + reportSizeChange: (dimensions: { width?: number; height?: number }) => void; +} + +/** + * Hook for sending UI actions to the parent window via postMessage. + * This is used by iframe-based UI components to communicate back to an MCP client. + * + * Implements the MCP-UI embeddable UI communication protocol. + * All actions are fire-and-forget - use `useRenderData` to receive responses from the host. + * + * @param defaultOptions - Default options applied to all messages + * @returns An object containing action methods: + * - intent: Send an intent for the host to act on + * - notify: Notify the host of something that happened + * - prompt: Ask the host to run a prompt + * - tool: Ask the host to run a tool call + * - link: Ask the host to navigate to a URL + * - reportSizeChange: Report iframe size changes + * + * @example + * ```tsx + * function MyComponent() { + * const { data } = useRenderData(); + * const { intent, tool, link } = useUIActions(); + * + * const handleCreateTask = () => { + * intent("create-task", { title: "Buy groceries" }); + * }; + * + * const handleRefresh = () => { + * // Ask host to run a tool, host will send new data via render data + * tool("refresh-data", { id: data?.id }); + * }; + * + * const handleOpenDocs = () => { + * link("https://docs.example.com"); + * }; + * + * return ; + * } + * ``` + */ +export function useUIActions(defaultOptions?: SendMessageOptions): UseUIActionsResult { + const targetOrigin = defaultOptions?.targetOrigin ?? "*"; + + const intent = useCallback( + (intentName: string, params?: T): void => { + window.parent.postMessage( + { + type: "intent", + payload: { + intent: intentName, + params, + }, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + const notify = useCallback( + (message: string): void => { + window.parent.postMessage( + { + type: "notify", + payload: { + message, + }, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + const prompt = useCallback( + (promptText: string): void => { + window.parent.postMessage( + { + type: "prompt", + payload: { + prompt: promptText, + }, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + const tool = useCallback( + (toolName: string, params?: T): void => { + window.parent.postMessage( + { + type: "tool", + payload: { + toolName, + params, + }, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + const link = useCallback( + (url: string): void => { + window.parent.postMessage( + { + type: "link", + payload: { + url, + }, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + const reportSizeChange = useCallback( + (dimensions: { width?: number; height?: number }): void => { + window.parent.postMessage( + { + type: "ui-size-change", + payload: dimensions, + }, + targetOrigin + ); + }, + [targetOrigin] + ); + + return useMemo( + () => ({ + intent, + notify, + prompt, + tool, + link, + reportSizeChange, + }), + [intent, notify, prompt, tool, link, reportSizeChange] + ); +} From 1ded598359dfa667d6d980c2c96787d2b51c1e99 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 11:38:44 -0500 Subject: [PATCH 2/6] chore: deslop --- src/ui/hooks/useUIActions.ts | 77 +++++------------------------------- 1 file changed, 9 insertions(+), 68 deletions(-) diff --git a/src/ui/hooks/useUIActions.ts b/src/ui/hooks/useUIActions.ts index a249ec97a..51fd28b64 100644 --- a/src/ui/hooks/useUIActions.ts +++ b/src/ui/hooks/useUIActions.ts @@ -1,94 +1,35 @@ import { useCallback, useMemo } from "react"; -/** Options for sending a message */ interface SendMessageOptions { - /** Target origin for postMessage. Defaults to "*" */ targetOrigin?: string; } /** Return type for the useUIActions hook */ interface UseUIActionsResult { - /** - * Sends an intent message to the host. - * Indicates the user has interacted with the UI and expressed an intent for the host to act on. - * @param intent - The intent identifier - * @param params - Optional parameters for the intent - */ + /** Sends an intent message for the host to act on */ intent: (intent: string, params?: T) => void; - - /** - * Sends a notify message to the host. - * Indicates the iframe already acted upon user interaction and is notifying the host. - * @param message - The notification message - */ + /** Notifies the host of something that happened */ notify: (message: string) => void; - - /** - * Sends a prompt message to the host. - * Asks the host to run a prompt. - * @param prompt - The prompt text to run - */ + /** Asks the host to run a prompt */ prompt: (prompt: string) => void; - - /** - * Sends a tool call message to the host. - * Asks the host to execute a tool. - * @param toolName - The name of the tool to call - * @param params - Optional parameters for the tool - */ + /** Asks the host to execute a tool */ tool: (toolName: string, params?: T) => void; - - /** - * Sends a link message to the host. - * Asks the host to navigate to a URL. - * @param url - The URL to navigate to - */ + /** Asks the host to navigate to a URL */ link: (url: string) => void; - - /** - * Reports a size change to the host. - * Used for auto-resizing iframes. - * @param dimensions - The new dimensions (width and/or height) - */ + /** Reports iframe size changes to the host */ reportSizeChange: (dimensions: { width?: number; height?: number }) => void; } /** - * Hook for sending UI actions to the parent window via postMessage. - * This is used by iframe-based UI components to communicate back to an MCP client. - * - * Implements the MCP-UI embeddable UI communication protocol. - * All actions are fire-and-forget - use `useRenderData` to receive responses from the host. - * - * @param defaultOptions - Default options applied to all messages - * @returns An object containing action methods: - * - intent: Send an intent for the host to act on - * - notify: Notify the host of something that happened - * - prompt: Ask the host to run a prompt - * - tool: Ask the host to run a tool call - * - link: Ask the host to navigate to a URL - * - reportSizeChange: Report iframe size changes + * Hook for sending UI actions to the parent window via postMessage + * This is used by iframe-based UI components to communicate back to an MCP client * * @example * ```tsx * function MyComponent() { - * const { data } = useRenderData(); * const { intent, tool, link } = useUIActions(); * - * const handleCreateTask = () => { - * intent("create-task", { title: "Buy groceries" }); - * }; - * - * const handleRefresh = () => { - * // Ask host to run a tool, host will send new data via render data - * tool("refresh-data", { id: data?.id }); - * }; - * - * const handleOpenDocs = () => { - * link("https://docs.example.com"); - * }; - * - * return ; + * return ; * } * ``` */ From 4ceaf2b9dfa7401e0063ceadbf9324b7a8704439 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 12:50:54 -0500 Subject: [PATCH 3/6] test: add tests for useUIActions --- tests/unit/ui/useUIActions.test.ts | 235 +++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 tests/unit/ui/useUIActions.test.ts diff --git a/tests/unit/ui/useUIActions.test.ts b/tests/unit/ui/useUIActions.test.ts new file mode 100644 index 000000000..920793ef2 --- /dev/null +++ b/tests/unit/ui/useUIActions.test.ts @@ -0,0 +1,235 @@ +import { describe, it, expect, beforeEach, afterEach, vi, type Mock } from "vitest"; +import { createElement, type FunctionComponent } from "react"; +import { renderToString } from "react-dom/server"; +import { useUIActions } from "../../../src/ui/hooks/useUIActions.js"; + +type UseUIActionsResult = ReturnType; + +interface HookOptions { + targetOrigin?: string; +} + +/** + * Simple hook testing utility that renders a component using the hook + * and captures the result for assertions. + */ +function testHook(options?: HookOptions): UseUIActionsResult { + let hookResult: UseUIActionsResult | undefined; + + const TestComponent: FunctionComponent = () => { + hookResult = useUIActions(options); + return null; + }; + + renderToString(createElement(TestComponent)); + + if (!hookResult) { + throw new Error("Hook did not return a result"); + } + + return hookResult; +} + +describe("useUIActions", () => { + let postMessageMock: Mock; + let originalWindow: typeof globalThis.window; + + beforeEach(() => { + originalWindow = globalThis.window; + postMessageMock = vi.fn(); + + // Create a minimal window mock with parent.postMessage + globalThis.window = { + parent: { + postMessage: postMessageMock, + }, + } as unknown as typeof globalThis.window; + }); + + afterEach(() => { + globalThis.window = originalWindow; + vi.restoreAllMocks(); + }); + + it("intent() sends a message with name and params", () => { + const actions = testHook(); + + actions.intent("create-task", { title: "Test Task" }); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "intent", + payload: { + intent: "create-task", + params: { title: "Test Task" }, + }, + }, + "*" + ); + }); + + it("intent() sends a message without params when not provided", () => { + const actions = testHook(); + + actions.intent("cancel"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "intent", + payload: { + intent: "cancel", + params: undefined, + }, + }, + "*" + ); + }); + + it("notify() sends a notification message", () => { + const actions = testHook(); + + actions.notify("Operation completed successfully"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "notify", + payload: { + message: "Operation completed successfully", + }, + }, + "*" + ); + }); + + it("prompt() sends a prompt message", () => { + const actions = testHook(); + + actions.prompt("What is the status of my database?"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "prompt", + payload: { + prompt: "What is the status of my database?", + }, + }, + "*" + ); + }); + + it("tool() sends a tool message with name and params", () => { + const actions = testHook(); + + actions.tool("listDatabases", { connectionString: "mongodb://localhost" }); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "tool", + payload: { + toolName: "listDatabases", + params: { connectionString: "mongodb://localhost" }, + }, + }, + "*" + ); + }); + + it("tool() sends a tool message without params when not provided", () => { + const actions = testHook(); + + actions.tool("getServerInfo"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "tool", + payload: { + toolName: "getServerInfo", + params: undefined, + }, + }, + "*" + ); + }); + + it("link() sends a link message with a URL", () => { + const actions = testHook(); + + actions.link("https://mongodb.com/docs"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "link", + payload: { + url: "https://mongodb.com/docs", + }, + }, + "*" + ); + }); + + it("reportSizeChange() sends size change with both dimensions", () => { + const actions = testHook(); + + actions.reportSizeChange({ width: 400, height: 300 }); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "ui-size-change", + payload: { width: 400, height: 300 }, + }, + "*" + ); + }); + + it("reportSizeChange() sends size change with only width", () => { + const actions = testHook(); + + actions.reportSizeChange({ width: 500 }); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "ui-size-change", + payload: { width: 500 }, + }, + "*" + ); + }); + + it("reportSizeChange() sends size change with only height", () => { + const actions = testHook(); + + actions.reportSizeChange({ height: 250 }); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "ui-size-change", + payload: { height: 250 }, + }, + "*" + ); + }); + + it("uses custom targetOrigin when provided in options", () => { + const actions = testHook({ targetOrigin: "https://example.com" }); + + actions.notify("test message"); + + expect(postMessageMock).toHaveBeenCalledWith( + { + type: "notify", + payload: { + message: "test message", + }, + }, + "https://example.com" + ); + }); + + it("defaults targetOrigin to '*' when not provided", () => { + const actions = testHook(); + + actions.notify("test message"); + + expect(postMessageMock).toHaveBeenCalledWith(expect.any(Object), "*"); + }); +}); From 7bf7edb21532912d4fd017d73d3e8aca48f727e4 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 13:07:42 -0500 Subject: [PATCH 4/6] feat: capture parent origin when possible --- src/ui/hooks/useRenderData.ts | 12 +++- tests/unit/ui/useRenderData.test.ts | 87 +++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 tests/unit/ui/useRenderData.test.ts diff --git a/src/ui/hooks/useRenderData.ts b/src/ui/hooks/useRenderData.ts index 461bbc983..c187f536a 100644 --- a/src/ui/hooks/useRenderData.ts +++ b/src/ui/hooks/useRenderData.ts @@ -13,6 +13,8 @@ interface UseRenderDataResult { data: T | null; isLoading: boolean; error: string | null; + /** The origin of the parent window, captured from the first valid message */ + parentOrigin: string | null; } /** @@ -24,6 +26,7 @@ interface UseRenderDataResult { * - data: The received render data (or null if not yet received) * - isLoading: Whether data is still being loaded * - error: Error message if message validation failed + * - parentOrigin: The origin of the parent window (for secure postMessage calls) * * @example * ```tsx @@ -32,8 +35,9 @@ interface UseRenderDataResult { * } * * function MyComponent() { - * const { data, isLoading, error } = useRenderData(); - * // ... + * const { data, isLoading, error, parentOrigin } = useRenderData(); + * const { intent } = useUIActions({ targetOrigin: parentOrigin ?? undefined }); + * return ; * } * ``` */ @@ -41,6 +45,7 @@ export function useRenderData(): UseRenderDataResult { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); + const [parentOrigin, setParentOrigin] = useState(null); useEffect(() => { const handleMessage = (event: MessageEvent): void => { @@ -49,6 +54,8 @@ export function useRenderData(): UseRenderDataResult { return; } + setParentOrigin((current) => current ?? event.origin); + if (!event.data.payload || typeof event.data.payload !== "object") { const errorMsg = "Invalid payload structure received"; setError(errorMsg); @@ -88,5 +95,6 @@ export function useRenderData(): UseRenderDataResult { data, isLoading, error, + parentOrigin, }; } diff --git a/tests/unit/ui/useRenderData.test.ts b/tests/unit/ui/useRenderData.test.ts new file mode 100644 index 000000000..3cc74bbf6 --- /dev/null +++ b/tests/unit/ui/useRenderData.test.ts @@ -0,0 +1,87 @@ +import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; +import { createElement, type FunctionComponent } from "react"; +import { renderToString } from "react-dom/server"; +import { useRenderData } from "../../../src/ui/hooks/useRenderData.js"; + +type UseRenderDataResult = ReturnType>; + +interface TestData { + items: string[]; +} + +/** + * Simple hook testing utility that renders a component using the hook + * and captures the result for assertions. + */ +function testHook(): UseRenderDataResult { + let hookResult: UseRenderDataResult | undefined; + + const TestComponent: FunctionComponent = () => { + hookResult = useRenderData(); + return null; + }; + + renderToString(createElement(TestComponent)); + + if (!hookResult) { + throw new Error("Hook did not return a result"); + } + + return hookResult; +} + +describe("useRenderData", () => { + let postMessageMock: ReturnType; + let originalWindow: typeof globalThis.window; + + beforeEach(() => { + originalWindow = globalThis.window; + postMessageMock = vi.fn(); + + globalThis.window = { + parent: { + postMessage: postMessageMock, + }, + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + } as unknown as typeof globalThis.window; + }); + + afterEach(() => { + globalThis.window = originalWindow; + vi.restoreAllMocks(); + }); + + it("returns initial state with isLoading true", () => { + const result = testHook(); + + expect(result.data).toBeNull(); + expect(result.isLoading).toBe(true); + expect(result.error).toBeNull(); + }); + + it("returns parentOrigin as null initially", () => { + const result = testHook(); + + expect(result.parentOrigin).toBeNull(); + }); + + it("includes parentOrigin in return type", () => { + const result = testHook(); + + // Verify the hook returns the expected shape with parentOrigin + expect(result).toHaveProperty("data"); + expect(result).toHaveProperty("isLoading"); + expect(result).toHaveProperty("error"); + expect(result).toHaveProperty("parentOrigin"); + }); + + it("returns a stable object shape for destructuring", () => { + const { data, isLoading, error, parentOrigin } = testHook(); + + expect(data).toBeNull(); + expect(isLoading).toBe(true); + expect(error).toBeNull(); + expect(parentOrigin).toBeNull(); + }); +}); From fad293fa7b50cde8451ed67f58ab7430f2706762 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 14:39:15 -0500 Subject: [PATCH 5/6] refactor: update host comm hook naming --- src/ui/hooks/index.ts | 2 +- .../{useUIActions.ts => useHostCommunication.ts} | 9 +++++---- src/ui/hooks/useRenderData.ts | 2 +- ...Actions.test.ts => useHostCommunication.test.ts} | 13 +++++++------ 4 files changed, 14 insertions(+), 12 deletions(-) rename src/ui/hooks/{useUIActions.ts => useHostCommunication.ts} (93%) rename tests/unit/ui/{useUIActions.test.ts => useHostCommunication.test.ts} (93%) diff --git a/src/ui/hooks/index.ts b/src/ui/hooks/index.ts index 9de28c16e..168af5dd2 100644 --- a/src/ui/hooks/index.ts +++ b/src/ui/hooks/index.ts @@ -1,2 +1,2 @@ export { useRenderData } from "./useRenderData.js"; -export { useUIActions } from "./useUIActions.js"; +export { useHostCommunication } from "./useHostCommunication.js"; diff --git a/src/ui/hooks/useUIActions.ts b/src/ui/hooks/useHostCommunication.ts similarity index 93% rename from src/ui/hooks/useUIActions.ts rename to src/ui/hooks/useHostCommunication.ts index 51fd28b64..9d341dcb1 100644 --- a/src/ui/hooks/useUIActions.ts +++ b/src/ui/hooks/useHostCommunication.ts @@ -4,8 +4,8 @@ interface SendMessageOptions { targetOrigin?: string; } -/** Return type for the useUIActions hook */ -interface UseUIActionsResult { +/** Return type for the useHostCommunication hook */ +interface UseHostCommunicationResult { /** Sends an intent message for the host to act on */ intent: (intent: string, params?: T) => void; /** Notifies the host of something that happened */ @@ -27,13 +27,13 @@ interface UseUIActionsResult { * @example * ```tsx * function MyComponent() { - * const { intent, tool, link } = useUIActions(); + * const { intent, tool, link } = useHostCommunication(); * * return ; * } * ``` */ -export function useUIActions(defaultOptions?: SendMessageOptions): UseUIActionsResult { +export function useHostCommunication(defaultOptions?: SendMessageOptions): UseHostCommunicationResult { const targetOrigin = defaultOptions?.targetOrigin ?? "*"; const intent = useCallback( @@ -138,3 +138,4 @@ export function useUIActions(defaultOptions?: SendMessageOptions): UseUIActionsR [intent, notify, prompt, tool, link, reportSizeChange] ); } + diff --git a/src/ui/hooks/useRenderData.ts b/src/ui/hooks/useRenderData.ts index c187f536a..3c304c02f 100644 --- a/src/ui/hooks/useRenderData.ts +++ b/src/ui/hooks/useRenderData.ts @@ -36,7 +36,7 @@ interface UseRenderDataResult { * * function MyComponent() { * const { data, isLoading, error, parentOrigin } = useRenderData(); - * const { intent } = useUIActions({ targetOrigin: parentOrigin ?? undefined }); + * const { intent } = useHostCommunication({ targetOrigin: parentOrigin ?? undefined }); * return ; * } * ``` diff --git a/tests/unit/ui/useUIActions.test.ts b/tests/unit/ui/useHostCommunication.test.ts similarity index 93% rename from tests/unit/ui/useUIActions.test.ts rename to tests/unit/ui/useHostCommunication.test.ts index 920793ef2..1f7453b15 100644 --- a/tests/unit/ui/useUIActions.test.ts +++ b/tests/unit/ui/useHostCommunication.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect, beforeEach, afterEach, vi, type Mock } from "vitest"; import { createElement, type FunctionComponent } from "react"; import { renderToString } from "react-dom/server"; -import { useUIActions } from "../../../src/ui/hooks/useUIActions.js"; +import { useHostCommunication } from "../../../src/ui/hooks/useHostCommunication.js"; -type UseUIActionsResult = ReturnType; +type UseHostCommunicationResult = ReturnType; interface HookOptions { targetOrigin?: string; @@ -13,11 +13,11 @@ interface HookOptions { * Simple hook testing utility that renders a component using the hook * and captures the result for assertions. */ -function testHook(options?: HookOptions): UseUIActionsResult { - let hookResult: UseUIActionsResult | undefined; +function testHook(options?: HookOptions): UseHostCommunicationResult { + let hookResult: UseHostCommunicationResult | undefined; const TestComponent: FunctionComponent = () => { - hookResult = useUIActions(options); + hookResult = useHostCommunication(options); return null; }; @@ -30,7 +30,7 @@ function testHook(options?: HookOptions): UseUIActionsResult { return hookResult; } -describe("useUIActions", () => { +describe("useHostCommunication", () => { let postMessageMock: Mock; let originalWindow: typeof globalThis.window; @@ -233,3 +233,4 @@ describe("useUIActions", () => { expect(postMessageMock).toHaveBeenCalledWith(expect.any(Object), "*"); }); }); + From eb4138d2931827626cab1669989e4c5e740f0681 Mon Sep 17 00:00:00 2001 From: Terrence Keane Date: Thu, 18 Dec 2025 14:40:09 -0500 Subject: [PATCH 6/6] chore: fix check --- src/ui/hooks/useHostCommunication.ts | 1 - tests/unit/ui/useHostCommunication.test.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/ui/hooks/useHostCommunication.ts b/src/ui/hooks/useHostCommunication.ts index 9d341dcb1..a212c82e3 100644 --- a/src/ui/hooks/useHostCommunication.ts +++ b/src/ui/hooks/useHostCommunication.ts @@ -138,4 +138,3 @@ export function useHostCommunication(defaultOptions?: SendMessageOptions): UseHo [intent, notify, prompt, tool, link, reportSizeChange] ); } - diff --git a/tests/unit/ui/useHostCommunication.test.ts b/tests/unit/ui/useHostCommunication.test.ts index 1f7453b15..999160b0d 100644 --- a/tests/unit/ui/useHostCommunication.test.ts +++ b/tests/unit/ui/useHostCommunication.test.ts @@ -233,4 +233,3 @@ describe("useHostCommunication", () => { expect(postMessageMock).toHaveBeenCalledWith(expect.any(Object), "*"); }); }); -